Engine: mapart doesn't load if a TILES0XX.ART file is loaded from an archive prior
Test package: permap_test.zip
To reproduce the problem, simply attempt to load the above zip file with the command line parameter eduke32.exe -g permap_test.zip
, or by placing it in the autoload
folder. Then start the first episode, and open the console. You will see an error message that the permap art could not be loaded (due to issue #222 make sure to use a MinGW64-compiled build to test this).
This occurs due to the following code inside tiles.cpp
at line 543
:
#ifndef USE_PHYSFS
if (cache1d_file_fromzip(fil))
#else
if (1)
#endif
{
if (permap)
artPreloadFileSafe(fil, &local);
else
artPreloadFile(fil, &local);
}
else
{
int offscount = ktell(fil);
for (bssize_t i=local.tilestart; i<=local.tileend; ++i)
{
int const dasiz = tilesiz[i].x * tilesiz[i].y;
tilefilenum[i] = tilefilei;
tilefileoffs[i] = offscount;
offscount += dasiz;
// artsize += ((dasiz+15)&0xfffffff0);
}
}
artPreloadFile();
calls the function tileSetData()
, which contains the following:
void tileSetData(int32_t const tile, int32_t tsiz, char const * const buffer)
{
int const compressed_tsiz = LZ4_compressBound(tsiz);
faketiledata[tile] = (char *) Xrealloc(faketiledata[tile], compressed_tsiz);
if ((tsiz = LZ4_compress_default(buffer, faketiledata[tile], tsiz, compressed_tsiz)) != -1)
{
faketilesize[tile] = tsiz;
faketiledata[tile] = (char *) Xrealloc(faketiledata[tile], tsiz);
faketile[tile>>3] |= pow2char[tile&7];
tilefilenum[tile] = MAXARTFILES_TOTAL;
}
else
{
DO_FREE_AND_NULL(faketiledata[tile]);
faketile[tile>>3] &= ~pow2char[tile&7];
}
}
The problem here is the line:
faketile[tile>>3] |= pow2char[tile&7];
If this is executed, then the following conditional will trigger once the mapart is loaded:
// Tiles having dummytile replacements or those that are
// cache1d-locked can't be replaced.
if (faketile[i>>3] & pow2char[i&7] || walock[i] >= CACHE1D_LOCKED)
{
initprintf("loadpics: per-map ART file \"%s\": "
"tile %d has dummytile or is locked\n", fn, i);
kclose(fil);
return -3;
}
And as a result, the mapart loading will fail.
From what I can tell, the faketile array is intended for dummy tiles, i.e. highres tiles, tiles that are loaded through tilefromtexture
etc.. But this is not the case here -- the faketile
array entry will be set even if the zip only contains the ART file itself.
What was the intention here?