- split the worker part for tileImportTexture out of the parser.

This commit is contained in:
Christoph Oelckers 2020-09-15 01:21:17 +02:00
parent 09a6534270
commit bc5d3eea88
4 changed files with 104 additions and 135 deletions

View file

@ -42,6 +42,14 @@ inline int32_t scriptfile_getsymbol(scriptfile *sf, int32_t *num)
return !res; return !res;
} }
inline int32_t scriptfile_getsymbol(scriptfile* sf, int64_t* num)
{
bool res = sf->GetNumber(true);
if (res) *num = sf->BigNumber;
else *num = 0;
return !res;
}
inline FScriptPosition scriptfile_getposition(scriptfile *sf) inline FScriptPosition scriptfile_getposition(scriptfile *sf)
{ {
return FScriptPosition(*sf); return FScriptPosition(*sf);

View file

@ -651,18 +651,7 @@ static int32_t defsparser(scriptfile *script)
{ {
auto texturepos = scriptfile_getposition(script); auto texturepos = scriptfile_getposition(script);
FScanner::SavedPos textureend; FScanner::SavedPos textureend;
FString fn; TileImport imp;
int32_t tile = -1;
int32_t alphacut = 255, flags = 0;
int32_t havexoffset = 0, haveyoffset = 0, haveextra = 0;
int32_t xoffset = 0, yoffset = 0;
int32_t istexture = 0;
int32_t tile_crc32 = 0;
vec2_t tile_size{};
uint8_t have_crc32 = 0;
uint8_t have_size = 0;
int32_t extra = 0;
int havesurface = 0, surface = 0, havevox = 0, vox = 0, haveview = 0, view = 0, haveshade = 0, shade = 0;
static const tokenlist tilefromtexturetokens[] = static const tokenlist tilefromtexturetokens[] =
{ {
@ -687,7 +676,7 @@ static int32_t defsparser(scriptfile *script)
}; };
if (scriptfile_getsymbol(script,&tile)) break; if (scriptfile_getsymbol(script,&imp.tile)) break;
if (scriptfile_getbraces(script,&textureend)) break; if (scriptfile_getbraces(script,&textureend)) break;
while (!scriptfile_endofblock(script, textureend)) while (!scriptfile_endofblock(script, textureend))
{ {
@ -695,25 +684,22 @@ static int32_t defsparser(scriptfile *script)
switch (token) switch (token)
{ {
case T_FILE: case T_FILE:
scriptfile_getstring(script,&fn); scriptfile_getstring(script,&imp.fn);
break; break;
case T_ALPHACUT: case T_ALPHACUT:
scriptfile_getsymbol(script,&alphacut); scriptfile_getsymbol(script,&imp.alphacut);
alphacut = clamp(alphacut, 0, 255); imp.alphacut = clamp(imp.alphacut, 0, 255);
break; break;
case T_XOFFSET: case T_XOFFSET:
havexoffset = 1; scriptfile_getsymbol(script,&imp.xoffset);
scriptfile_getsymbol(script,&xoffset); imp.xoffset = clamp(imp.xoffset, -128, 127);
xoffset = clamp(xoffset, -128, 127);
break; break;
case T_YOFFSET: case T_YOFFSET:
haveyoffset = 1; scriptfile_getsymbol(script,&imp.yoffset);
scriptfile_getsymbol(script,&yoffset); imp.yoffset = clamp(imp.yoffset, -128, 127);
yoffset = clamp(yoffset, -128, 127);
break; break;
case T_IFCRC: case T_IFCRC:
scriptfile_getsymbol(script, &tile_crc32); scriptfile_getsymbol(script, &imp.crc32);
have_crc32 = 1;
break; break;
case T_IFMATCH: case T_IFMATCH:
{ {
@ -732,13 +718,11 @@ static int32_t defsparser(scriptfile *script)
switch (token) switch (token)
{ {
case T_CRC32: case T_CRC32:
scriptfile_getsymbol(script, &tile_crc32); scriptfile_getsymbol(script, &imp.crc32);
have_crc32 = 1;
break; break;
case T_SIZE: case T_SIZE:
scriptfile_getsymbol(script, &tile_size.x); scriptfile_getsymbol(script, &imp.sizex);
scriptfile_getsymbol(script, &tile_size.y); scriptfile_getsymbol(script, &imp.sizey);
have_size = 1;
break; break;
default: default:
break; break;
@ -747,132 +731,36 @@ static int32_t defsparser(scriptfile *script)
break; break;
} }
case T_TEXHITSCAN: case T_TEXHITSCAN:
flags |= PICANM_TEXHITSCAN_BIT; imp.flags |= PICANM_TEXHITSCAN_BIT;
break; break;
case T_NOFULLBRIGHT: case T_NOFULLBRIGHT:
flags |= PICANM_NOFULLBRIGHT_BIT; imp.flags |= PICANM_NOFULLBRIGHT_BIT;
break; break;
case T_TEXTURE: case T_TEXTURE:
istexture = 1; imp.istexture = 1;
break; break;
case T_EXTRA: case T_EXTRA:
haveextra = 1; scriptfile_getsymbol(script, &imp.extra);
scriptfile_getsymbol(script, &extra);
break; break;
case T_SURFACE: case T_SURFACE:
havesurface = 1; scriptfile_getsymbol(script, &imp.surface);
scriptfile_getsymbol(script, &surface);
break; break;
case T_VOXEL: case T_VOXEL:
havevox = 1; scriptfile_getsymbol(script, &imp.vox);
scriptfile_getsymbol(script, &vox);
break; break;
case T_VIEW: case T_VIEW:
haveview = 1; scriptfile_getsymbol(script, &imp.extra);
scriptfile_getsymbol(script, &view); imp.extra &= 7;
break; break;
case T_SHADE: case T_SHADE:
haveshade = 1; scriptfile_getsymbol(script, &imp.shade);
scriptfile_getsymbol(script, &shade);
break; break;
default: default:
break; break;
} }
} }
tileImport(pos, imp);
if ((unsigned)tile >= MAXUSERTILES)
{
pos.Message(MSG_ERROR, "missing or invalid 'tile number' for texture definition");
break;
}
if (have_crc32)
{
int32_t const orig_crc32 = tileGetCRC32(tile);
if (orig_crc32 != tile_crc32)
{
pos.Message(MSG_DEBUGMSG, "CRC32 of tile %d doesn't match! CRC32: %d, Expected: %d\n", tile, orig_crc32, tile_crc32);
break;
}
}
if (have_size)
{
vec2_16_t const orig_size = tilesiz[tile];
if (orig_size.x != tile_size.x && orig_size.y != tile_size.y)
{
pos.Message(MSG_DEBUGMSG, "Size of tile %d doesn't match! Size: (%d, %d), Expected: (%d, %d)\n", tile, orig_size.x, orig_size.y, tile_size.x, tile_size.y);
break;
}
}
// fixme - forward to the game code. These are Blood specific.
if (havesurface)
;// gi->SetSurfType(tile, surface);
if (havevox)
;// gi->SetVoxel(tile, vox);
if (haveshade)
;// gi->SetShade(tile, shade);
if (haveview)
picanm[tile].extra = view & 7;
if (fn.IsEmpty())
{
// tilefromtexture <tile> { texhitscan } sets the bit but doesn't change tile data
picanm[tile].sf |= flags;
int xo, yo;
if (havexoffset)
xo = xoffset;
else
xo = tileLeftOffset(tile);
if (haveyoffset)
yo = yoffset;
else
yo = tileTopOffset(tile);
auto tex = tileGetTexture(tile);
if (tex) tex->SetOffsets(xo, yo);
if (haveextra)
picanm[tile].extra = extra;
if (flags == 0 && !havexoffset && !haveyoffset && !haveextra)
pos.Message(MSG_ERROR, "missing 'file name' for tilefromtexture definitiond");
break;
}
int32_t const texstatus = tileImportFromTexture(fn, tile, alphacut, istexture);
if (texstatus == -3)
pos.Message(MSG_ERROR, "No palette loaded, in tilefromtexture definition");
if (texstatus == -(3<<8))
pos.Message(MSG_ERROR, "\"%s\" has more than one tile, in tilefromtexture definition", fn.GetChars());
if (texstatus < 0)
break;
picanm[tile].sf |= flags;
int xo;
if (havexoffset)
xo = xoffset;
else if (texstatus == 0)
xo = 0;
else
xo = tileLeftOffset(tile);
int yo;
if (haveyoffset)
yo = yoffset;
else if (texstatus == 0)
yo = 0;
else
yo = tileTopOffset(tile);
auto tex = tileGetTexture(tile);
if (tex) tex->SetOffsets(xo, yo);
if (haveextra)
picanm[tile].extra = extra;
} }
break; break;
case T_COPYTILE: case T_COPYTILE:

View file

@ -45,6 +45,7 @@
#include "palettecontainer.h" #include "palettecontainer.h"
#include "texturemanager.h" #include "texturemanager.h"
#include "c_dispatch.h" #include "c_dispatch.h"
#include "sc_man.h"
enum enum
{ {
@ -1067,7 +1068,60 @@ bool PickTexture(int picnum, FGameTexture* tex, int paletteid, TexturePick& pick
return true; return true;
} }
//===========================================================================
//
// Internal worker for tileImportTexture
//
//===========================================================================
void tileImport(FScriptPosition& pos, TileImport& imp)
{
if (imp.tile == -1)
{
pos.Message(MSG_ERROR, "missing tile number in import declaration");
return;
}
if ((unsigned)imp.tile >= MAXUSERTILES)
{
pos.Message(MSG_ERROR, "Invalid tile number %d in import declaration", imp.tile);
return;
}
if (imp.crc32 != INT64_MAX && int(imp.crc32) != tileGetCRC32(imp.tile))
{
// Only print as developer diagnostic if that mode is enabled.
pos.Message(MSG_DEBUGMSG, "CRC32 mismatch for tile %d.", imp.tile);
return;
}
if (imp.sizex != INT_MAX && tileWidth(imp.tile) != imp.sizex && tileHeight(imp.tile) != imp.sizey)
{
pos.Message(MSG_DEBUGMSG, "Size mismatch for tile %d", imp.tile);
return;
}
#if 0
// fixme - forward to the game code. These are Blood specific.
if (imp.havesurface)
;// gi->SetSurfType(tile, surface);
if (imp.havevox)
;// gi->SetVoxel(tile, vox);
if (imp.haveshade)
;// gi->SetShade(tile, shade);
#endif
if (imp.fn.IsNotEmpty() && tileImportFromTexture(imp.fn, imp.tile, imp.alphacut, imp.istexture) < 0) return;
picanm[imp.tile].sf |= imp.flags;
// This is not quite the same as originally, for two reasons:
// 1: Since these are texture properties now, there's no need to clear them.
// 2: The original code assumed that an imported texture cannot have an offset. But this can import Doom patches and PNGs with grAb, so the situation is very different.
if (imp.xoffset == INT_MAX) imp.xoffset = tileLeftOffset(imp.tile);
if (imp.yoffset == INT_MAX) imp.yoffset = tileTopOffset(imp.tile);
auto tex = tileGetTexture(imp.tile);
if (tex) tex->SetOffsets(imp.xoffset, imp.yoffset);
if (imp.extra != INT_MAX) picanm[imp.tile].extra = imp.extra;
}
TileSiz tilesiz; TileSiz tilesiz;
PicAnm picanm; PicAnm picanm;

View file

@ -1,5 +1,6 @@
#pragma once #pragma once
#include <limits.h>
#include "textures.h" #include "textures.h"
#include "image.h" #include "image.h"
#include "i_time.h" #include "i_time.h"
@ -500,3 +501,21 @@ inline FGameTexture* tileGetTexture(int tile, bool animate = false)
} }
bool PickTexture(int picnum, FGameTexture* tex, int paletteid, TexturePick& pick); bool PickTexture(int picnum, FGameTexture* tex, int paletteid, TexturePick& pick);
struct TileImport
{
FString fn;
int tile = -1;
int alphacut = 128, flags = 0;
int haveextra = 0;
int xoffset = INT_MAX, yoffset = INT_MAX;
int istexture = 0, extra = INT_MAX;
int64_t crc32 = INT64_MAX;
int sizex = INT_MAX, sizey;
// Blood extensions
int surface = INT_MAX, vox = INT_MAX, shade = INT_MAX;
};
void tileImport(FScriptPosition& pos, TileImport& imp);