Defs: Add "copytile" token that allows you to copy existing 8-bit tiles from one slot to another, along with their x/yoffsets and flags. ART animation values are not copied.

Examples: (assuming stock Duke palswaps)
copytile 10000 { tile 0 } // tile #10000 is now the same as #0
copytile 10001 { tile 1 pal 8 } // tile #10001 is now #1 with a full-green tint
copytile 0 { pal 1 pal 23 } // tile #0 now has a full-yellow tint

git-svn-id: https://svn.eduke32.com/eduke32@5139 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
hendricks266 2015-04-12 08:07:30 +00:00
parent f15199cb79
commit 9a8941ef41
4 changed files with 167 additions and 15 deletions

View File

@ -1013,6 +1013,7 @@ int32_t loadpics(const char *filename, int32_t askedsize);
void E_MapArt_Clear(void); void E_MapArt_Clear(void);
void E_MapArt_Setup(const char *filename); void E_MapArt_Setup(const char *filename);
void loadtile(int16_t tilenume); void loadtile(int16_t tilenume);
void E_LoadTileIntoBuffer(int16_t tilenume, int32_t dasiz, char *buffer);
int32_t qloadkvx(int32_t voxindex, const char *filename); int32_t qloadkvx(int32_t voxindex, const char *filename);
intptr_t allocatepermanenttile(int16_t tilenume, int32_t xsiz, int32_t ysiz); intptr_t allocatepermanenttile(int16_t tilenume, int32_t xsiz, int32_t ysiz);

View File

@ -949,6 +949,15 @@ FORCE_INLINE void *xaligned_malloc(const bsize_t alignment, const bsize_t size)
# define Baligned_free(ptr) Bfree(ptr) # define Baligned_free(ptr) Bfree(ptr)
#endif #endif
static inline void maybe_grow_buffer(char ** const buffer, int32_t * const buffersize, int32_t const newsize)
{
if (newsize > *buffersize)
{
*buffer = (char *)Xrealloc(*buffer, newsize);
*buffersize = newsize;
}
}
////////// //////////
#endif // compat_h_ #endif // compat_h_

View File

@ -101,6 +101,7 @@ enum scripttoken_t
T_ECHO, T_ECHO,
T_GLOBALFLAGS, T_GLOBALFLAGS,
T_RENAMEFILE, T_RENAMEFILE,
T_COPYTILE,
}; };
static int32_t lastmodelid = -1, lastvoxid = -1, modelskin = -1, lastmodelskin = -1, seenframe = 0; static int32_t lastmodelid = -1, lastvoxid = -1, modelskin = -1, lastmodelskin = -1, seenframe = 0;
@ -188,11 +189,7 @@ static void tile_from_truecolpic(int32_t tile, const palette_t *picptr, int32_t
const vec2_t siz = tilesiz[tile]; const vec2_t siz = tilesiz[tile];
int32_t i, j, tsiz = siz.x * siz.y; int32_t i, j, tsiz = siz.x * siz.y;
if (tsiz > faketilebuffersiz) maybe_grow_buffer(&faketilebuffer, &faketilebuffersiz, tsiz);
{
faketilebuffer = (char *)Xrealloc(faketilebuffer, tsiz);
faketilebuffersiz = tsiz;
}
getclosestcol_flush(); getclosestcol_flush();
@ -210,6 +207,27 @@ static void tile_from_truecolpic(int32_t tile, const palette_t *picptr, int32_t
E_CreateFakeTile(tile, tsiz, faketilebuffer); E_CreateFakeTile(tile, tsiz, faketilebuffer);
} }
static int32_t Defs_LoadTileIntoBuffer(int32_t const tile)
{
vec2_t const siz = tilesiz[tile];
int32_t const tsiz = siz.x * siz.y;
if (EDUKE32_PREDICT_FALSE(tilesiz[tile].x <= 0 || tilesiz[tile].y <= 0))
return 0;
maybe_grow_buffer(&faketilebuffer, &faketilebuffersiz, tsiz);
E_LoadTileIntoBuffer(tile, tsiz, faketilebuffer);
return tsiz;
}
static void Defs_ApplyPaletteToTileBuffer(int32_t const tsiz, int32_t const pal)
{
for (int32_t i = 0; i < tsiz; i++)
faketilebuffer[i] = palookup[pal][faketilebuffer[i]];
}
#undef USE_DEF_PROGRESS #undef USE_DEF_PROGRESS
#if defined _WIN32 || defined HAVE_GTK2 #if defined _WIN32 || defined HAVE_GTK2
# define USE_DEF_PROGRESS # define USE_DEF_PROGRESS
@ -286,6 +304,7 @@ static int32_t defsparser(scriptfile *script)
{ "echo", T_ECHO }, { "echo", T_ECHO },
{ "globalflags", T_GLOBALFLAGS }, { "globalflags", T_GLOBALFLAGS },
{ "renamefile", T_RENAMEFILE }, { "renamefile", T_RENAMEFILE },
{ "copytile", T_COPYTILE },
}; };
while (1) while (1)
@ -683,6 +702,117 @@ static int32_t defsparser(scriptfile *script)
} }
} }
break; break;
case T_COPYTILE:
{
char *blockend;
int32_t tile = -1, source;
int32_t havetile = 0, havexoffset = 0, haveyoffset = 0;
int32_t xoffset = 0, yoffset = 0;
int32_t flags = 0;
int32_t tsiz = 0;
static const tokenlist copytiletokens[] =
{
{ "tile", T_TILE },
{ "pal", T_PAL },
{ "xoffset", T_XOFFSET },
{ "xoff", T_XOFFSET },
{ "yoffset", T_YOFFSET },
{ "yoff", T_YOFFSET },
{ "texhitscan", T_TEXHITSCAN },
{ "nofullbright", T_NOFULLBRIGHT },
};
if (scriptfile_getsymbol(script,&tile)) break;
source = tile; // without a "tile" token, we still palettize self by default
if (scriptfile_getbraces(script,&blockend)) break;
while (script->textptr < blockend)
{
int32_t token = getatoken(script,copytiletokens,ARRAY_SIZE(copytiletokens));
switch (token)
{
case T_TILE:
{
int32_t tempsource;
scriptfile_getsymbol(script,&tempsource);
if (check_tile("copytile", tempsource, script, cmdtokptr))
break;
if ((tsiz = Defs_LoadTileIntoBuffer(tempsource)) <= 0)
break;
source = tempsource;
havetile = 1;
break;
}
case T_PAL:
{
int32_t temppal;
scriptfile_getsymbol(script,&temppal);
// palettize self case
if (!havetile)
{
if (check_tile("copytile", source, script, cmdtokptr))
break;
if ((tsiz = Defs_LoadTileIntoBuffer(source)) <= 0)
break;
havetile = 1;
}
if (EDUKE32_PREDICT_FALSE((unsigned)temppal >= MAXPALOOKUPS-RESERVEDPALS))
{
initprintf("Error: copytile 'palette number' out of range (max=%d)\n",
MAXPALOOKUPS-RESERVEDPALS-1);
break;
}
Defs_ApplyPaletteToTileBuffer(tsiz, temppal);
break;
}
case T_XOFFSET:
havexoffset = 1;
scriptfile_getsymbol(script,&xoffset); break;
case T_YOFFSET:
haveyoffset = 1;
scriptfile_getsymbol(script,&yoffset); break;
case T_TEXHITSCAN:
flags |= PICANM_TEXHITSCAN_BIT;
break;
case T_NOFULLBRIGHT:
flags |= PICANM_NOFULLBRIGHT_BIT;
break;
default:
break;
}
}
if (check_tile("copytile", tile, script, cmdtokptr))
break;
if (havetile)
{
E_CreateFakeTile(tile, tsiz, faketilebuffer);
}
else // if !havetile, we have never confirmed a valid source
{
if (check_tile("copytile", source, script, cmdtokptr))
break;
}
if (tsiz <= 0)
{
E_UndefineTile(tile);
break;
}
set_tilesiz(tile, tilesiz[source].x, tilesiz[source].y);
picanm[tile].xofs = havexoffset ? clamp(xoffset, -128, 127) : picanm[source].xofs;
picanm[tile].yofs = haveyoffset ? clamp(yoffset, -128, 127) : picanm[source].yofs;
picanm[tile].sf = (picanm[tile].sf & ~PICANM_MISC_MASK) | (picanm[source].sf & PICANM_MISC_MASK) | flags;
}
break;
case T_IMPORTTILE: case T_IMPORTTILE:
{ {
int32_t tile, xsiz, ysiz; int32_t tile, xsiz, ysiz;

View File

@ -11981,11 +11981,8 @@ void E_ReadArtFileIntoFakeData(int32_t const fil, artheader_t const * const loca
E_UndefineTile(i); E_UndefineTile(i);
continue; continue;
} }
else if (dasiz > buffersize)
{ maybe_grow_buffer(&buffer, &buffersize, dasiz);
buffer = (char *)Xrealloc(buffer, dasiz);
buffersize = dasiz;
}
kread(fil, buffer, dasiz); kread(fil, buffer, dasiz);
@ -12146,15 +12143,15 @@ int32_t loadpics(const char *filename, int32_t askedsize)
// //
// loadtile // loadtile
// //
static void postloadtile(int16_t tilenume);
void loadtile(int16_t tilenume) void loadtile(int16_t tilenume)
{ {
int32_t i, dasiz; int32_t dasiz;
if ((unsigned)tilenume >= (unsigned)MAXTILES) return; if ((unsigned)tilenume >= (unsigned)MAXTILES) return;
if ((dasiz = tilesiz[tilenume].x*tilesiz[tilenume].y) <= 0) return; if ((dasiz = tilesiz[tilenume].x*tilesiz[tilenume].y) <= 0) return;
i = tilefilenum[tilenume];
// Allocate storage if necessary. // Allocate storage if necessary.
if (waloff[tilenume] == 0) if (waloff[tilenume] == 0)
{ {
@ -12162,17 +12159,26 @@ void loadtile(int16_t tilenume)
allocache(&waloff[tilenume],dasiz,&walock[tilenume]); allocache(&waloff[tilenume],dasiz,&walock[tilenume]);
} }
E_LoadTileIntoBuffer(tilenume, dasiz, (char *)waloff[tilenume]);
postloadtile(tilenume);
}
void E_LoadTileIntoBuffer(int16_t tilenume, int32_t dasiz, char *buffer)
{
// dummy tiles for highres replacements and tilefromtexture definitions // dummy tiles for highres replacements and tilefromtexture definitions
if (faketile[tilenume>>3] & pow2char[tilenume&7]) if (faketile[tilenume>>3] & pow2char[tilenume&7])
{ {
if (faketiledata[tilenume] != NULL) if (faketiledata[tilenume] != NULL)
LZ4_decompress_fast(faketiledata[tilenume], (char *) waloff[tilenume], dasiz); LZ4_decompress_fast(faketiledata[tilenume], buffer, dasiz);
faketimerhandler(); faketimerhandler();
return; return;
} }
int32_t const i = tilefilenum[tilenume];
// Potentially switch open ART file. // Potentially switch open ART file.
if (i != artfilnum) if (i != artfilnum)
{ {
@ -12204,10 +12210,16 @@ void loadtile(int16_t tilenume)
faketimerhandler(); faketimerhandler();
} }
kread(artfil, (char *)waloff[tilenume], dasiz); kread(artfil, buffer, dasiz);
faketimerhandler(); faketimerhandler();
artfilplc = tilefileoffs[tilenume]+dasiz; artfilplc = tilefileoffs[tilenume]+dasiz;
}
static void postloadtile(int16_t tilenume)
{
#if !defined DEBUG_TILESIZY_512 && !defined DEBUG_TILEOFFSETS
UNREFERENCED_PARAMETER(tilenume);
#endif
#ifdef DEBUG_TILESIZY_512 #ifdef DEBUG_TILESIZY_512
if (tilesizy[tilenume] >= 512) if (tilesizy[tilenume] >= 512)
{ {