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_Setup(const char *filename);
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);
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)
#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_

View file

@ -101,6 +101,7 @@ enum scripttoken_t
T_ECHO,
T_GLOBALFLAGS,
T_RENAMEFILE,
T_COPYTILE,
};
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];
int32_t i, j, tsiz = siz.x * siz.y;
if (tsiz > faketilebuffersiz)
{
faketilebuffer = (char *)Xrealloc(faketilebuffer, tsiz);
faketilebuffersiz = tsiz;
}
maybe_grow_buffer(&faketilebuffer, &faketilebuffersiz, tsiz);
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);
}
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
#if defined _WIN32 || defined HAVE_GTK2
# define USE_DEF_PROGRESS
@ -286,6 +304,7 @@ static int32_t defsparser(scriptfile *script)
{ "echo", T_ECHO },
{ "globalflags", T_GLOBALFLAGS },
{ "renamefile", T_RENAMEFILE },
{ "copytile", T_COPYTILE },
};
while (1)
@ -683,6 +702,117 @@ static int32_t defsparser(scriptfile *script)
}
}
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:
{
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);
continue;
}
else if (dasiz > buffersize)
{
buffer = (char *)Xrealloc(buffer, dasiz);
buffersize = dasiz;
}
maybe_grow_buffer(&buffer, &buffersize, dasiz);
kread(fil, buffer, dasiz);
@ -12146,15 +12143,15 @@ int32_t loadpics(const char *filename, int32_t askedsize)
//
// loadtile
//
static void postloadtile(int16_t tilenume);
void loadtile(int16_t tilenume)
{
int32_t i, dasiz;
int32_t dasiz;
if ((unsigned)tilenume >= (unsigned)MAXTILES) return;
if ((dasiz = tilesiz[tilenume].x*tilesiz[tilenume].y) <= 0) return;
i = tilefilenum[tilenume];
// Allocate storage if necessary.
if (waloff[tilenume] == 0)
{
@ -12162,17 +12159,26 @@ void loadtile(int16_t 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
if (faketile[tilenume>>3] & pow2char[tilenume&7])
{
if (faketiledata[tilenume] != NULL)
LZ4_decompress_fast(faketiledata[tilenume], (char *) waloff[tilenume], dasiz);
LZ4_decompress_fast(faketiledata[tilenume], buffer, dasiz);
faketimerhandler();
return;
}
int32_t const i = tilefilenum[tilenume];
// Potentially switch open ART file.
if (i != artfilnum)
{
@ -12204,10 +12210,16 @@ void loadtile(int16_t tilenume)
faketimerhandler();
}
kread(artfil, (char *)waloff[tilenume], dasiz);
kread(artfil, buffer, dasiz);
faketimerhandler();
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
if (tilesizy[tilenume] >= 512)
{