mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-25 03:00:46 +00:00
Engine-side per-map ART file support.
When a map named <filename>.map is loaded (<filename> may also contain directory separators), the engine checks for existence of <filename>_XX.art in the virtual file system, where XX is a 0-padded number from 00 to 19. It loads a consecutive sequence of these ART files, i.e. aborts whenever a number in the sequence isn't found (in contrast to normal ART loading). Restrictions: - the per-map ART files must not reside in ZIP files - if a tile number is attempted to be overridden that has a dummytile or is cache1d-locked, per-map ART loading fails On failure, the map is still loaded, but a diagnostic message is output to the log/OSD. Loaded per-map ART data are cleared whenever the map is "left". In particular: - whenever another map is loaded - in the editor: when a new map is started - in the game: after the bonus ending screen of a finished level, after going to the title screen via the menu A final note: file names are supposed to be looked up and compared case-sensitively. That is, <filename> must match EXACTLY between the map's and per-map ART one; 'art' must be lowercase. Otherwise, the cookie monster will come and eat you! BUILD_LUNATIC. git-svn-id: https://svn.eduke32.com/eduke32@4257 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
8d47e476c7
commit
4881a13f99
8 changed files with 322 additions and 104 deletions
|
@ -1060,6 +1060,8 @@ int32_t saveboard(const char *filename, const vec3_t *dapos, int16_t daang, in
|
|||
void set_tilesiz(int32_t picnum, int16_t dasizx, int16_t dasizy);
|
||||
int32_t tile_exists(int32_t picnum);
|
||||
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);
|
||||
int32_t qloadkvx(int32_t voxindex, const char *filename);
|
||||
intptr_t allocatepermanenttile(int16_t tilenume, int32_t xsiz, int32_t ysiz);
|
||||
|
|
|
@ -433,7 +433,7 @@ static void reset_default_mapstate(void)
|
|||
|
||||
initspritelists();
|
||||
taglab_init();
|
||||
|
||||
E_MapArt_Clear();
|
||||
#ifdef YAX_ENABLE
|
||||
yax_resetbunchnums();
|
||||
#endif
|
||||
|
|
|
@ -186,20 +186,31 @@ static intptr_t slopalookup[16384]; // was 2048
|
|||
palette_t palookupfog[MAXPALOOKUPS];
|
||||
#endif
|
||||
|
||||
static int32_t artversion;
|
||||
static void *pic = NULL;
|
||||
|
||||
// The tile file number (tilesXXX <- this) of each tile:
|
||||
// 0 <= . < MAXARTFILES_BASE: tile is in a "base" ART file
|
||||
// MAXARTFILES_BASE <= . < MAXARTFILES_TOTAL: tile is in a map-specific ART file
|
||||
static uint8_t tilefilenum[MAXTILES];
|
||||
EDUKE32_STATIC_ASSERT(MAXTILEFILES <= 256);
|
||||
EDUKE32_STATIC_ASSERT(MAXARTFILES_TOTAL <= 256);
|
||||
|
||||
static int32_t tilefileoffs[MAXTILES];
|
||||
static int32_t lastageclock;
|
||||
|
||||
static int32_t artsize = 0, cachesize = 0;
|
||||
// Backup tilefilenum[] and tilefileoffs[]. These get allocated only when
|
||||
// necessary (have per-map ART files).
|
||||
static uint8_t *g_bakTileFileNum;
|
||||
static int32_t *g_bakTileFileOffs;
|
||||
static int16_t *g_bakTileSizX;
|
||||
static int16_t *g_bakTileSizY;
|
||||
static picanm_t *g_bakPicAnm;
|
||||
// NOTE: picsiz[] is not backed up, but recalculated when necessary.
|
||||
|
||||
//static int32_t artsize = 0;
|
||||
static int32_t cachesize = 0;
|
||||
|
||||
// Whole ART file contents loaded from ZIPs in memory.
|
||||
static char *artptrs[MAXTILEFILES];
|
||||
static char *artptrs[MAXARTFILES_TOTAL];
|
||||
|
||||
static int32_t no_radarang2 = 0;
|
||||
static int16_t radarang[1280], radarang2[MAXXDIM];
|
||||
|
@ -2422,6 +2433,8 @@ int16_t searchbottomwall, searchisbottom;
|
|||
double msens = 1.0;
|
||||
|
||||
static char artfilename[20];
|
||||
static char mapartfilename[BMAX_PATH]; // map-specific ART file name
|
||||
static int32_t mapartfnXXofs; // byte offset to 'XX' (the number part) in the above
|
||||
static int32_t artfil = -1, artfilnum, artfilplc;
|
||||
|
||||
char inpreparemirror = 0;
|
||||
|
@ -8716,7 +8729,7 @@ void uninitengine(void)
|
|||
kclose(artfil);
|
||||
|
||||
// this leaves a bunch of invalid pointers in waloff... fixme?
|
||||
for (i=0; i<MAXTILEFILES; i++)
|
||||
for (i=0; i<MAXARTFILES_TOTAL; i++)
|
||||
DO_FREE_AND_NULL(artptrs[i]);
|
||||
|
||||
DO_FREE_AND_NULL(transluc);
|
||||
|
@ -9704,6 +9717,130 @@ void drawmapview(int32_t dax, int32_t day, int32_t zoome, int16_t ang)
|
|||
setaspect(65536, divscale16(ydim*320, xdim*200));
|
||||
}
|
||||
|
||||
////////// Per-map ART file loading //////////
|
||||
|
||||
// Some forward declarations.
|
||||
static void set_picsiz(int32_t picnum);
|
||||
static const char *E_GetArtFileName(int32_t tilefilei);
|
||||
static int32_t E_ReadArtFile(int32_t tilefilei);
|
||||
|
||||
static void clearmapartfilename(void)
|
||||
{
|
||||
Bmemset(mapartfilename, 0, sizeof(mapartfilename));
|
||||
mapartfnXXofs = 0;
|
||||
}
|
||||
|
||||
static void E_RecalcPicSiz(void)
|
||||
{
|
||||
int32_t i;
|
||||
for (i=0; i<MAXTILES; i++)
|
||||
set_picsiz(i);
|
||||
}
|
||||
|
||||
#define RESTORE_MAPART_ARRAY(origar, bakar) do { \
|
||||
Bmemcpy(origar, bakar, sizeof(origar)); \
|
||||
DO_FREE_AND_NULL(bakar); \
|
||||
} while (0)
|
||||
|
||||
// Allocate per-map ART backup array and back up the original!
|
||||
#define ALLOC_MAPART_ARRAY(origar, bakar) do { \
|
||||
bakar = Bmalloc(sizeof(origar)); \
|
||||
if (bakar == NULL) \
|
||||
{ \
|
||||
initprintf("OUT OF MEMORY allocating per-map ART backup arrays!\n"); \
|
||||
uninitengine(); \
|
||||
exit(12); \
|
||||
} \
|
||||
Bmemcpy(bakar, origar, sizeof(origar)); \
|
||||
} while (0)
|
||||
|
||||
void E_MapArt_Clear(void)
|
||||
{
|
||||
int32_t i;
|
||||
|
||||
if (g_bakTileFileNum == NULL)
|
||||
return; // per-map ART N/A
|
||||
|
||||
clearmapartfilename();
|
||||
|
||||
if (artfilnum >= MAXARTFILES_BASE)
|
||||
{
|
||||
kclose(artfil);
|
||||
|
||||
artfil = -1;
|
||||
artfilnum = -1;
|
||||
artfilplc = 0L;
|
||||
}
|
||||
|
||||
for (i=0; i<MAXTILES; i++)
|
||||
if (tilefilenum[i] >= MAXARTFILES_BASE)
|
||||
{
|
||||
// XXX: OK way to free it? Better: cache1d API. CACHE1D_FREE
|
||||
walock[i] = 1;
|
||||
waloff[i] = 0;
|
||||
}
|
||||
|
||||
// Restore original per-tile arrays
|
||||
RESTORE_MAPART_ARRAY(tilefilenum, g_bakTileFileNum);
|
||||
RESTORE_MAPART_ARRAY(tilefileoffs, g_bakTileFileOffs);
|
||||
RESTORE_MAPART_ARRAY(tilesizx, g_bakTileSizX);
|
||||
RESTORE_MAPART_ARRAY(tilesizy, g_bakTileSizY);
|
||||
RESTORE_MAPART_ARRAY(picanm, g_bakPicAnm);
|
||||
|
||||
E_RecalcPicSiz();
|
||||
}
|
||||
|
||||
void E_MapArt_Setup(const char *filename)
|
||||
{
|
||||
int32_t i;
|
||||
|
||||
if (Bstrlen(filename) + 7 >= sizeof(mapartfilename))
|
||||
return;
|
||||
|
||||
E_MapArt_Clear();
|
||||
|
||||
Bstrcpy(mapartfilename, filename);
|
||||
append_ext_UNSAFE(mapartfilename, "_XX.art");
|
||||
mapartfnXXofs = Bstrlen(mapartfilename) - 6;
|
||||
|
||||
// Check for first per-map ART file: if that one doesn't exist, don't load any.
|
||||
{
|
||||
int32_t fil = kopen4load(E_GetArtFileName(MAXARTFILES_BASE), 0);
|
||||
|
||||
if (fil == -1)
|
||||
{
|
||||
clearmapartfilename();
|
||||
return;
|
||||
}
|
||||
|
||||
kclose(fil);
|
||||
}
|
||||
|
||||
// Allocate backup arrays.
|
||||
ALLOC_MAPART_ARRAY(tilefilenum, g_bakTileFileNum);
|
||||
ALLOC_MAPART_ARRAY(tilefileoffs, g_bakTileFileOffs);
|
||||
ALLOC_MAPART_ARRAY(tilesizx, g_bakTileSizX);
|
||||
ALLOC_MAPART_ARRAY(tilesizy, g_bakTileSizY);
|
||||
ALLOC_MAPART_ARRAY(picanm, g_bakPicAnm);
|
||||
|
||||
for (i=MAXARTFILES_BASE; i<MAXARTFILES_TOTAL; i++)
|
||||
{
|
||||
int32_t ret = E_ReadArtFile(i);
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
// NOTE: i == MAXARTFILES_BASE && ret == -1 can only have happened
|
||||
// if the file was deleted between the above file existence check
|
||||
// and now. Very cornerly... but I like my code to be prepared to
|
||||
// any eventuality.
|
||||
if (i == MAXARTFILES_BASE || ret != -1)
|
||||
E_MapArt_Clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
E_RecalcPicSiz();
|
||||
}
|
||||
|
||||
//////////////////// LOADING AND SAVING ROUTINES ////////////////////
|
||||
|
||||
|
@ -10052,6 +10189,9 @@ skip_reading_mapbin:
|
|||
OSD_Exec(fn);
|
||||
|
||||
system_getcvars();
|
||||
|
||||
// Per-map ART
|
||||
E_MapArt_Setup(filename);
|
||||
}
|
||||
|
||||
return finish_loadboard(dapos, dacursectnum, numsprites, myflags);
|
||||
|
@ -10988,45 +11128,58 @@ int32_t tile_exists(int32_t picnum)
|
|||
return (waloff[picnum] != 0 && tilesizx[picnum] > 0 && tilesizy[picnum] > 0);
|
||||
}
|
||||
|
||||
static void artfilename_setnumber(int32_t tilefilei)
|
||||
static const char *E_GetArtFileName(int32_t tilefilei)
|
||||
{
|
||||
if (tilefilei >= MAXARTFILES_BASE)
|
||||
{
|
||||
int32_t o = mapartfnXXofs;
|
||||
tilefilei -= MAXARTFILES_BASE;
|
||||
|
||||
mapartfilename[o+1] = '0' + tilefilei%10;
|
||||
mapartfilename[o+0] = '0' + (tilefilei/10)%10;
|
||||
|
||||
return mapartfilename;
|
||||
}
|
||||
else
|
||||
{
|
||||
artfilename[7] = '0' + tilefilei%10;
|
||||
artfilename[6] = '0' + (tilefilei/10)%10;
|
||||
artfilename[5] = '0' + (tilefilei/100)%10;
|
||||
|
||||
return artfilename;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// loadpics
|
||||
//
|
||||
int32_t loadpics(const char *filename, int32_t askedsize)
|
||||
// Returns:
|
||||
// 0: successfully read ART file
|
||||
// >0: error with the ART file
|
||||
// -1: ART file does not exist
|
||||
//<-1: per-map ART issue
|
||||
static int32_t E_ReadArtFile(int32_t tilefilei)
|
||||
{
|
||||
int32_t i, tilefilei;
|
||||
|
||||
Bstrncpyz(artfilename, filename, sizeof(artfilename));
|
||||
|
||||
Bmemset(tilesizx, 0, sizeof(tilesizx));
|
||||
Bmemset(tilesizy, 0, sizeof(tilesizy));
|
||||
Bmemset(picanm, 0, sizeof(picanm));
|
||||
|
||||
artsize = 0;
|
||||
|
||||
for (tilefilei=0; tilefilei<MAXTILEFILES; tilefilei++)
|
||||
{
|
||||
int32_t fil;
|
||||
|
||||
artfilename_setnumber(tilefilei);
|
||||
const char *fn = E_GetArtFileName(tilefilei);
|
||||
const int32_t permap = (tilefilei >= MAXARTFILES_BASE); // is it a per-map ART file?
|
||||
|
||||
if ((fil = kopen4load(artfilename,0)) != -1)
|
||||
if ((fil = kopen4load(fn,0)) != -1)
|
||||
{
|
||||
int32_t localtilestart, localtileend, localnumtiles;
|
||||
int32_t offscount, numtiles_dummy;
|
||||
|
||||
int32_t i, offscount, numtiles_dummy, artversion;
|
||||
#ifdef WITHKPLIB
|
||||
if (permap && cache1d_file_fromzip(fil))
|
||||
{
|
||||
initprintf("loadpics: per-map ART file \"%s\": can't be read from a ZIP file\n", fn);
|
||||
kclose(fil);
|
||||
return -2;
|
||||
}
|
||||
#endif
|
||||
kread(fil,&artversion,4); artversion = B_LITTLE32(artversion);
|
||||
if (artversion != 1)
|
||||
{
|
||||
initprintf("loadpics: Invalid art file version in %s\n", artfilename);
|
||||
initprintf("loadpics: Invalid art file version in %s\n", fn);
|
||||
kclose(fil);
|
||||
continue;
|
||||
return 1;
|
||||
}
|
||||
|
||||
kread(fil,&numtiles_dummy,4);
|
||||
|
@ -11035,22 +11188,44 @@ int32_t loadpics(const char *filename, int32_t askedsize)
|
|||
|
||||
if ((uint32_t)localtilestart >= MAXUSERTILES || (uint32_t)localtileend >= MAXUSERTILES)
|
||||
{
|
||||
initprintf("loadpics: Invalid localtilestart or localtileend in %s\n", artfilename);
|
||||
initprintf("loadpics: Invalid localtilestart or localtileend in %s\n", fn);
|
||||
kclose(fil);
|
||||
continue;
|
||||
return 1;
|
||||
}
|
||||
if (localtileend <= localtilestart)
|
||||
{
|
||||
initprintf("loadpics: localtileend <= localtilestart in %s\n", artfilename);
|
||||
initprintf("loadpics: localtileend <= localtilestart in %s\n", fn);
|
||||
kclose(fil);
|
||||
continue;
|
||||
return 1;
|
||||
}
|
||||
|
||||
localnumtiles = (localtileend-localtilestart+1);
|
||||
|
||||
kread(fil,&tilesizx[localtilestart], localnumtiles<<1);
|
||||
kread(fil,&tilesizy[localtilestart], localnumtiles<<1);
|
||||
kread(fil,&picanm[localtilestart], localnumtiles<<2);
|
||||
if (permap)
|
||||
{
|
||||
// Check whether we can evict existing tiles to make place for
|
||||
// per-map ART ones.
|
||||
for (i=localtilestart; i<=localtileend; i++)
|
||||
{
|
||||
// Tiles having dummytile replacements or those that are
|
||||
// cache1d-locked can't be replaced.
|
||||
if (faketilesiz[i] || walock[i] >= 200)
|
||||
{
|
||||
initprintf("loadpics: per-map ART file \"%s\": "
|
||||
"tile %d has dummytile or is locked\n", fn, i);
|
||||
kclose(fil);
|
||||
return -3;
|
||||
}
|
||||
}
|
||||
|
||||
// Free existing tiles from the cache1d. CACHE1D_FREE
|
||||
Bmemset(&waloff[localtilestart], 0, localnumtiles*sizeof(intptr_t));
|
||||
Bmemset(&walock[localtilestart], 1, localnumtiles*sizeof(walock[0]));
|
||||
}
|
||||
|
||||
kread(fil, &tilesizx[localtilestart], localnumtiles*sizeof(int16_t));
|
||||
kread(fil, &tilesizy[localtilestart], localnumtiles*sizeof(int16_t));
|
||||
kread(fil, &picanm[localtilestart], localnumtiles*sizeof(picanm_t));
|
||||
|
||||
for (i=localtilestart; i<=localtileend; i++)
|
||||
{
|
||||
|
@ -11078,7 +11253,7 @@ int32_t loadpics(const char *filename, int32_t askedsize)
|
|||
tilefileoffs[i] = offscount;
|
||||
|
||||
offscount += dasiz;
|
||||
artsize += ((dasiz+15)&0xfffffff0);
|
||||
// artsize += ((dasiz+15)&0xfffffff0);
|
||||
}
|
||||
|
||||
#ifdef WITHKPLIB
|
||||
|
@ -11089,10 +11264,35 @@ int32_t loadpics(const char *filename, int32_t askedsize)
|
|||
klseek(fil, 0, BSEEK_SET);
|
||||
kread(fil, artptrs[tilefilei], i);
|
||||
}
|
||||
#endif
|
||||
#ifdef DEBUGGINGAIDS
|
||||
if (permap)
|
||||
initprintf("Read in per-map ART file \"%s\"\n", fn);
|
||||
#endif
|
||||
kclose(fil);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
//
|
||||
// loadpics
|
||||
//
|
||||
int32_t loadpics(const char *filename, int32_t askedsize)
|
||||
{
|
||||
int32_t tilefilei;
|
||||
|
||||
Bstrncpyz(artfilename, filename, sizeof(artfilename));
|
||||
|
||||
Bmemset(tilesizx, 0, sizeof(tilesizx));
|
||||
Bmemset(tilesizy, 0, sizeof(tilesizy));
|
||||
Bmemset(picanm, 0, sizeof(picanm));
|
||||
|
||||
// artsize = 0;
|
||||
|
||||
for (tilefilei=0; tilefilei<MAXARTFILES_BASE; tilefilei++)
|
||||
E_ReadArtFile(tilefilei);
|
||||
|
||||
Bmemset(gotpic, 0, sizeof(gotpic));
|
||||
|
||||
|
@ -11105,18 +11305,18 @@ int32_t loadpics(const char *filename, int32_t askedsize)
|
|||
while ((pic = Bmalloc(cachesize)) == NULL)
|
||||
{
|
||||
cachesize -= 65536;
|
||||
if (cachesize < 65536) return(-1);
|
||||
if (cachesize < 65536)
|
||||
return -1;
|
||||
}
|
||||
initcache((intptr_t)pic, cachesize);
|
||||
|
||||
for (i=0; i<MAXTILES; i++)
|
||||
set_picsiz(i);
|
||||
E_RecalcPicSiz();
|
||||
|
||||
artfil = -1;
|
||||
artfilnum = -1;
|
||||
artfilplc = 0L;
|
||||
|
||||
return(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -11174,15 +11374,24 @@ void loadtile(int16_t tilenume)
|
|||
// Potentially switch open ART file.
|
||||
if (i != artfilnum)
|
||||
{
|
||||
const char *fn;
|
||||
|
||||
if (artfil != -1)
|
||||
kclose(artfil);
|
||||
|
||||
fn = E_GetArtFileName(i);
|
||||
|
||||
artfil = kopen4load(fn, 0);
|
||||
if (artfil == -1)
|
||||
{
|
||||
initprintf("Failed opening ART file \"%s\"!\n", fn);
|
||||
uninitengine();
|
||||
exit(11);
|
||||
}
|
||||
|
||||
artfilnum = i;
|
||||
artfilplc = 0L;
|
||||
|
||||
artfilename_setnumber(i);
|
||||
artfil = kopen4load(artfilename, 0);
|
||||
|
||||
faketimerhandler();
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
|
||||
#define MAXCLIPNUM 1024
|
||||
#define MAXPERMS 512
|
||||
#define MAXTILEFILES 256
|
||||
#define MAXARTFILES_BASE 200
|
||||
#define MAXARTFILES_TOTAL 220
|
||||
// MAXYSAVES is 983040 (!) right now:
|
||||
#define MAXYSAVES ((MAXXDIM*MAXSPRITES)>>7)
|
||||
#define MAXNODESPERLINE (MAXYSAVES/MAXYDIM) // 307
|
||||
|
|
|
@ -11005,6 +11005,10 @@ static int32_t G_EndOfLevel(void)
|
|||
ud.screen_size = i;
|
||||
G_BonusScreen(0);
|
||||
}
|
||||
|
||||
// Clear potentially loaded per-map ART only after the bonus screens.
|
||||
E_MapArt_Clear();
|
||||
|
||||
if (ud.eog)
|
||||
{
|
||||
ud.eog = 0;
|
||||
|
|
|
@ -5031,6 +5031,7 @@ VOLUME_ALL_40x:
|
|||
g_player[myconnectindex].ps->gm = MODE_DEMO;
|
||||
if (ud.recstat == 1)
|
||||
G_CloseDemoWrite();
|
||||
E_MapArt_Clear();
|
||||
M_ChangeMenu(MENU_MAIN);
|
||||
}
|
||||
|
||||
|
|
|
@ -548,7 +548,7 @@ void G_CacheMapData(void)
|
|||
}
|
||||
}
|
||||
|
||||
clearbufbyte(gotpic,sizeof(gotpic),0L);
|
||||
Bmemset(gotpic, 0, sizeof(gotpic));
|
||||
|
||||
endtime = getticks();
|
||||
OSD_Printf("Cache time: %dms\n", endtime-starttime);
|
||||
|
|
|
@ -282,6 +282,7 @@ int32_t G_LoadPlayer(int32_t spot)
|
|||
ud.m_player_skill = h.skill;
|
||||
|
||||
Bstrcpy(boardfilename, h.boardfn);
|
||||
E_MapArt_Setup(h.boardfn); // XXX: Better after the following filename tweaking?
|
||||
|
||||
if (boardfilename[0])
|
||||
Bstrcpy(currentboardfilename, boardfilename);
|
||||
|
|
Loading…
Reference in a new issue