diff --git a/d_main.c b/d_main.c index c8da30e7f..565b985e3 100644 --- a/d_main.c +++ b/d_main.c @@ -567,14 +567,13 @@ void START_Title(void) l = gameinfo.titlePage; if (*l) { - W_Push(); W_LoadPWAD(); int lump = W_CheckNumForName(l); if (lump >= 0) titlepic = W_CacheLumpNum(lump, PU_STATIC); - W_Pop(); + W_UnloadPWAD(); } #ifdef MARS @@ -613,9 +612,8 @@ static void START_Credits (void) { #ifdef MARS int i; - int lumps[2]; + VINT lumps[2]; lumpinfo_t li[2]; - wadinfo_t pwad; credits[0] = credits[1] = NULL; titlepic = NULL; @@ -623,7 +621,6 @@ static void START_Credits (void) if (!*gameinfo.creditsPage) return; - W_Push(); W_LoadPWAD(); /* build a temp in-memory PWAD */ @@ -637,13 +634,12 @@ static void START_Credits (void) lumps[i] = W_CheckNumForName(name); } - pwad.numlumps = W_GetLumpInfoSubset(li, W_GetLumpInfo(), i, lumps); - W_SetPWAD(&pwad, li); + W_CacheWADLumps(li, i, lumps, true); for (i = 0; i < 2; i++) credits[i] = W_CacheLumpName(li[i].name, PU_STATIC); - W_Pop(); + W_UnloadPWAD(); if (!credits[0]) return; @@ -866,8 +862,6 @@ static void RunAttractDemos (void) // Z_Malloc failure Z_FreeTags(mainzone); - W_Push(); - W_LoadPWAD(); demo = NULL; @@ -877,7 +871,7 @@ static void RunAttractDemos (void) if (l >= 0) demo = W_CacheLumpNum(l, PU_STATIC); - W_Pop(); + W_UnloadPWAD(); if (!first) I_RestoreScreenCopy(); diff --git a/d_mapinfo.c b/d_mapinfo.c index 99bca56bb..6735cb684 100644 --- a/d_mapinfo.c +++ b/d_mapinfo.c @@ -39,7 +39,7 @@ int G_BuiltinMapNumForMapName(const char* map) return (map[3] - '0') * 10 + (map[4] - '0'); return 0; } -extern void I_Debug(void); + static char* G_LoadMapinfoLump(void) { int len; @@ -47,7 +47,7 @@ static char* G_LoadMapinfoLump(void) char *buf; buf = (char*)I_WorkBuffer(); -I_Debug(); + lump = W_CheckNumForName("DMAPINFO"); if (lump < 0) { return NULL; diff --git a/doomdef.h b/doomdef.h index 1881ddb5a..009ab675f 100644 --- a/doomdef.h +++ b/doomdef.h @@ -684,16 +684,13 @@ typedef struct void W_Init (void); -int W_Push (void); -int W_Pop (void); void W_LoadPWAD(void); -void W_SetPWAD (wadinfo_t *wad, void *lumpinfo); -lumpinfo_t *W_GetLumpInfo (void); -int W_GetLumpInfoSubset(lumpinfo_t *out, const lumpinfo_t *in, int numlumps, int *lumps); +void W_UnloadPWAD (void); +int W_CacheWADLumps (lumpinfo_t *li, int numlumps, VINT *lumps, boolean setpwad); int W_CheckNumForName (const char *name); int W_GetNumForName (const char *name); -int W_CheckNumForNameExt (const char *name, int start, int end); +int W_CheckRangeForName (const char *name, int start, int end); int W_LumpLength (int lump); int W_ReadLump (int lump, void *dest); diff --git a/g_game.c b/g_game.c index 41eb0e9dd..0b41fd42c 100644 --- a/g_game.c +++ b/g_game.c @@ -384,7 +384,6 @@ void G_Init(void) // copy mapnumbers to a temp buffer, then free, then allocate again // to avoid zone memory fragmentation - W_Push(); W_LoadPWAD(); maplist = G_LoadMaplist(&mapcount, &gameinfo); @@ -451,9 +450,9 @@ void G_Init(void) gamemapcount = mapcount; } - G_InitPlayerResp(); + W_UnloadPWAD(); - W_Pop(); + G_InitPlayerResp(); if (!*gameinfo.borderFlat) gameinfo.borderFlat = "ROCKS"; diff --git a/in_main.c b/in_main.c index a6ad16a68..c0b2c7c02 100644 --- a/in_main.c +++ b/in_main.c @@ -320,9 +320,8 @@ void IN_SingleDrawer(void) void IN_Start (void) { int i,l; - int lumps[7]; + VINT lumps[7]; lumpinfo_t li[7]; - wadinfo_t pwad; interm = Z_Malloc(sizeof(*interm), PU_STATIC); D_memset(interm, 0, sizeof(*interm)); @@ -367,7 +366,6 @@ void IN_Start (void) #ifdef MARS Z_FreeTags (mainzone); - W_Push(); W_LoadPWAD(); /* build a temp in-memory PWAD */ @@ -378,9 +376,8 @@ void IN_Start (void) lumps[4] = W_CheckNumForName("I_KILLS"); lumps[5] = W_CheckNumForName("I_ITEMS"); lumps[6] = W_CheckNumForName("I_FINISH"); - pwad.numlumps = W_GetLumpInfoSubset(li, W_GetLumpInfo(), 7, lumps); - W_SetPWAD(&pwad, li); + W_CacheWADLumps(li, 7, lumps, true); l = W_CheckNumForName("INTERPIC"); if (l != -1) @@ -404,7 +401,7 @@ void IN_Start (void) #endif #ifdef MARS - W_Pop(); + W_UnloadPWAD(); #endif snums = W_CheckNumForName("NUM_0"); diff --git a/m_main.c b/m_main.c index 367ed4436..602aff77b 100644 --- a/m_main.c +++ b/m_main.c @@ -102,13 +102,12 @@ void M_Start2 (boolean startup_) startup = startup_; if (startup) { - W_Push(); W_LoadPWAD(); i = W_CheckNumForName("M_DOOM"); m_doom = i != -1 ? W_CacheLumpNum(i, PU_STATIC) : NULL; - W_Pop(); + W_UnloadPWAD(); } else { diff --git a/marssound.c b/marssound.c index a644d9d6f..c00fa39a2 100644 --- a/marssound.c +++ b/marssound.c @@ -125,8 +125,7 @@ void S_Init(void) int i; int initmusictype; int start, end; - int lumps[NUMSFX > 99 ? NUMSFX : 99]; - int sfxol[NUMSFX*2]; + VINT lumps[NUMSFX > 99 ? NUMSFX : 99]; for (i = 0; i < SFXCHANNELS; i++) sfxchannels[i].data = NULL; @@ -149,7 +148,6 @@ void S_Init(void) muslooping = 0; S_StopSong(); - W_Push(); W_LoadPWAD(); /* build an in-memory PWAD with all music */ @@ -163,7 +161,7 @@ void S_Init(void) for (i = 0; i < num_music; i++) lumps[i] = start + i + 1; vgm_tracks = Z_Malloc(sizeof(*vgm_tracks) * num_music, PU_STATIC); - W_GetLumpInfoSubset(vgm_tracks, W_GetLumpInfo(), num_music, lumps); + W_CacheWADLumps(vgm_tracks, num_music, lumps, false); } /* build an in-memory PWAD with all SFX */ @@ -177,25 +175,35 @@ void S_Init(void) for (i=1 ; i < NUMSFX ; i++) { - S_sfx[i].lump = W_CheckNumForNameExt(S_sfxnames[i], start, end) - start; + S_sfx[i].lump = W_CheckRangeForName(S_sfxnames[i], start, end); } if (mcd_avail) { - lumpinfo_t *li = W_GetLumpInfo(); + lumpinfo_t li[NUMSFX]; + int sfxol[NUMSFX*2]; + + for (i = 0; i < numsfx; i++) + { + if (S_sfx[i].lump >= 0) + S_sfx[i].lump -= start; + lumps[i] = start + 1 + i; + } + + W_CacheWADLumps(li, numsfx, lumps, false); /* load all SFX in a single batch */ for (i = 0; i < numsfx; i++) { - sfxol[i*2] = li[start + 1 + i].filepos; - sfxol[i*2+1] = li[start + 1 + i].size; + sfxol[i*2] = li[i].filepos; + sfxol[i*2+1] = li[i].size; } Mars_MCDLoadSfxFileOfs(1, numsfx, PWAD_NAME, sfxol); } } - W_Pop(); + W_UnloadPWAD(); Mars_SetPriCmdCallback(&S_Pri_CmdHandler); @@ -619,20 +627,11 @@ int S_CDAvailable(void) int S_SongForMapnum(int mapnum) { - int i; - VINT songs[100]; - VINT numsongs; - - numsongs = 0; - for (i = 0; i < num_music + cdtrack_lastmap; i++) { - songs[numsongs++] = i + 1; - if (numsongs == sizeof(songs) / sizeof(songs[0])) - break; - } - - if (numsongs == 0) + int numsongs; + numsongs = num_music + cdtrack_lastmap; + if (numsongs <= 0) return mus_none; - return songs[(mapnum - 1) % numsongs]; + return (mapnum - 1) % numsongs + 1; } int S_SongForName(const char *str) diff --git a/p_setup.c b/p_setup.c index 0e2191889..5d1d9d4bd 100644 --- a/p_setup.c +++ b/p_setup.c @@ -167,10 +167,6 @@ void P_LoadSectors (int lump) D_memset (sectors, 0, numsectors*sizeof(sector_t)); data = W_GetLumpData(lump); - // pop the WAD stack to point to the IWAD, - // otherwise R_FlatNumForName is going to break - W_Pop(); - ms = (mapsector_t *)data; ss = sectors; for (i=0 ; itag = LITTLESHORT(ms->tag); } - - W_Push(); } @@ -642,8 +636,7 @@ void P_SetupLevel (const char *lumpname, skill_t skill) mobj_t *mobj; #endif extern int cy; - int lumpnum, lumps[ML_BLOCKMAP+1]; - wadinfo_t pwad; + VINT lumpnum, lumps[ML_BLOCKMAP+1]; lumpinfo_t li[ML_BLOCKMAP+1]; M_ClearRandom (); @@ -654,32 +647,32 @@ D_printf ("P_SetupLevel(%s,%i)\n",lumpname,skill); P_InitThinkers (); - W_Push(); W_LoadPWAD(); - lumpnum = W_GetNumForName(lumpname); + lumpnum = W_CheckNumForName(lumpname); if (lumpnum < 0) I_Error("Map %s not found!", lumpname); /* build a temp in-memory PWAD */ for (i = 0; i < ML_BLOCKMAP+1; i++) lumps[i] = lumpnum+i; - pwad.numlumps = W_GetLumpInfoSubset(li, W_GetLumpInfo(), ML_BLOCKMAP+1, lumps); - W_SetPWAD(&pwad, li); + W_CacheWADLumps(li, ML_BLOCKMAP+1, lumps, true); + + lumpnum = W_GetNumForName(lumpname); /* note: most of this ordering is important */ - P_LoadBlockMap (ML_BLOCKMAP); - P_LoadVertexes (ML_VERTEXES); - P_LoadSectors (ML_SECTORS); - P_LoadSideDefs (ML_SIDEDEFS); - P_LoadLineDefs (ML_LINEDEFS); - P_LoadSubsectors (ML_SSECTORS); - P_LoadNodes (ML_NODES); - P_LoadSegs (ML_SEGS); - - rejectmatrix = Z_Malloc (W_LumpLength (ML_REJECT),PU_LEVEL); - W_ReadLump (ML_REJECT,rejectmatrix); + P_LoadBlockMap (lumpnum+ML_BLOCKMAP); + P_LoadVertexes (lumpnum+ML_VERTEXES); + P_LoadSectors (lumpnum+ML_SECTORS); + P_LoadSideDefs (lumpnum+ML_SIDEDEFS); + P_LoadLineDefs (lumpnum+ML_LINEDEFS); + P_LoadSubsectors (lumpnum+ML_SSECTORS); + P_LoadNodes (lumpnum+ML_NODES); + P_LoadSegs (lumpnum+ML_SEGS); + + rejectmatrix = Z_Malloc (W_LumpLength (lumpnum+ML_REJECT),PU_LEVEL); + W_ReadLump (lumpnum+ML_REJECT,rejectmatrix); validcount = Z_Malloc((numlines + 1) * sizeof(*validcount) * 2, PU_LEVEL); D_memset(validcount, 0, (numlines + 1) * sizeof(*validcount) * 2); @@ -704,9 +697,9 @@ D_printf ("P_SetupLevel(%s,%i)\n",lumpname,skill); bodyqueslot = 0; deathmatch_p = deathmatchstarts; - P_LoadThings (ML_THINGS); + P_LoadThings (lumpnum+ML_THINGS); - W_Pop(); + W_UnloadPWAD(); /* */ /* if deathmatch, randomly spawn the active players */ diff --git a/r_data.c b/r_data.c index 3ff3b0208..22144838b 100644 --- a/r_data.c +++ b/r_data.c @@ -81,7 +81,7 @@ void R_InitTextures (void) for (j = 0; j < MIPLEVELS; j++) texture->data[j] = NULL; /* not cached yet */ if (start >= 0 && end > 0) - texture->lumpnum = W_CheckNumForNameExt(texture->name, start, end); + texture->lumpnum = W_CheckRangeForName(texture->name, start, end); else texture->lumpnum = W_CheckNumForName(texture->name); if (texture->lumpnum == -1) @@ -253,7 +253,7 @@ void R_InitData (void) int R_FlatNumForName (const char *name) { - int f = W_CheckNumForNameExt (name, firstflat, lastflat+1); + int f = W_CheckRangeForName (name, firstflat, lastflat+1); if (f < 0) return f; return f - firstflat; diff --git a/w_wad.c b/w_wad.c index 52999395b..637f8afe7 100644 --- a/w_wad.c +++ b/w_wad.c @@ -18,6 +18,7 @@ typedef struct int cdlength, cdoffset; lumpinfo_t *lumpinfo; /* points directly to rom image */ + int firstlump; int numlumps; int infotableofs; #ifndef MARS @@ -93,6 +94,7 @@ static void W_InitCDPWAD (void) wadfile_t *wad; wad = &wadfile[1]; + wad->firstlump = wadfile[0].numlumps; wad->cdlength = I_OpenCDFileByName(PWAD_NAME, &wad->cdoffset); if (wad->cdlength <= 0) I_Error ("Failed to open %s", PWAD_NAME); @@ -144,18 +146,57 @@ void W_Init (void) /* ==================== = -= W_SetPWAD += W_GetWadForLump = ==================== */ -void W_SetPWAD (wadinfo_t *wadi, void *lumpinfo) +static wadfile_t *W_GetWadForLump (int lumpnum) { - wadfile_t *wad; - wad = &wadfile[wadnum]; - wad->cdlength = wadfile[1].cdlength; - wad->cdoffset = wadfile[1].cdoffset; - wad->lumpinfo = lumpinfo; - wad->numlumps = wadi->numlumps; + int i; + + if (lumpnum < 0) + return &wadfile[0]; + + for (i = wadnum; i > 0; i--) { + if (lumpnum >= wadfile[i].firstlump && lumpnum < wadfile[i].firstlump+wadfile[i].numlumps) + break; + } + return &wadfile[i]; +} + +/* +==================== += += W_CacheWADLumps += +==================== +*/ +int W_CacheWADLumps (lumpinfo_t *li, int numlumps, VINT *lumps, boolean setpwad) +{ + int n; + wadfile_t *wad; + + n = 0; + if (numlumps > 0) + { + int i, l; + for (i = 0; i < numlumps; i++) { + l = lumps[i]; + if (l < 0) + continue; + wad = W_GetWadForLump(lumps[i]); + D_memcpy(&li[n], &wad->lumpinfo[l - wad->firstlump], sizeof(lumpinfo_t)); + n++; + } + } + + if (!setpwad) + return n; + + wad = &wadfile[1]; + wad->numlumps = n; + wad->lumpinfo = li; + return n; } /* @@ -173,6 +214,8 @@ void W_LoadPWAD (void) static int cache_size = -1; static int cache_num_lumps = 0; + wadnum = 1; + I_OpenCDFileByOffset(wad->cdlength, wad->cdoffset); if (cache_size != -1) { @@ -203,70 +246,26 @@ void W_LoadPWAD (void) /* ==================== = -= W_Push -= -==================== -*/ -int W_Push (void) -{ - if (wadnum >= MAXWADS-1) - return -1; - wadnum++; - return 0; -} - -/* -==================== -= -= W_Pop -= -==================== -*/ -int W_Pop (void) -{ - if (wadnum == 0) - return -1; - --wadnum; - return 0; -} - -lumpinfo_t *W_GetLumpInfo (void) -{ - return wadfile[wadnum].lumpinfo; -} - -/* -==================== += W_UnloadPWAD = -= W_GetLumpInfoSubset ==================== */ -int W_GetLumpInfoSubset(lumpinfo_t *out, const lumpinfo_t *in, int numlumps, int *lumps) +void W_UnloadPWAD (void) { - int i, n; - - n = 0; - for (i = 0; i < numlumps; i++) { - int l = lumps[i]; - if (l < 0) - continue; - D_memcpy(&out[n], &in[l], sizeof(lumpinfo_t)); - n++; - } - return n; + wadnum = 0; } /* ==================== = -= W_CheckNumForName += W_CheckWadForName = = Returns -1 if name not found = ==================== */ -int W_CheckNumForNameExt (const char *name, int start, int end) +static int W_CheckWadForName (wadfile_t *wad, const char *name, int start, int end) { char name8[12]; int v1,v2; @@ -283,8 +282,7 @@ int W_CheckNumForNameExt (const char *name, int start, int end) /* scan backwards so patch lump files take precedence */ - - lump_p = wadfile[wadnum].lumpinfo + end; + lump_p = wad->lumpinfo + end; /* used for stripping out the hi bit of the first character of the */ /* name of the lump */ @@ -295,18 +293,40 @@ int W_CheckNumForNameExt (const char *name, int start, int end) #define HIBIT (1<<31) #endif - while (lump_p-- != wadfile[wadnum].lumpinfo + start) + while (lump_p-- != wad->lumpinfo + start) if (*(int *)&lump_p->name[4] == v2 && (*(int *)lump_p->name & ~HIBIT) == v1) - return lump_p - wadfile[wadnum].lumpinfo; + return lump_p - wad->lumpinfo; return -1; } +int W_CheckRangeForName (const char *name, int start, int end) +{ + int l; + wadfile_t *wad; + + wad = W_GetWadForLump(start); + if (start < 0 || end < 0) + return -1; + + l = W_CheckWadForName(wad, name, start - wad->firstlump, end - wad->firstlump); + if (l < 0) + return l; + return wad->firstlump + l; +} + int W_CheckNumForName (const char *name) { - return W_CheckNumForNameExt(name, 0, wadfile[wadnum].numlumps); + int i; + for (i = wadnum; i >= 0; i--) { + int l = W_CheckWadForName(&wadfile[i], name, 0, wadfile[i].numlumps); + if (l >= 0) { + return wadfile[i].firstlump + l; + } + } + return -1; } @@ -345,11 +365,15 @@ int W_GetNumForName (const char *name) int W_LumpLength (int lump) { + wadfile_t *wad; + if (lump < 0) I_Error("W_LumpLength: %i < 0", lump); - if (lump >= wadfile[wadnum].numlumps) + + wad = W_GetWadForLump(lump); + if (lump >= wad->firstlump+wad->numlumps) I_Error ("W_LumpLength: %i >= numlumps",lump); - return BIGLONG(wadfile[wadnum].lumpinfo[lump].size); + return BIGLONG(wad->lumpinfo[lump-wad->firstlump].size); } @@ -367,24 +391,28 @@ int W_ReadLump (int lump, void *dest) { lumpinfo_t *l; volatile int size; + wadfile_t *wad; + void *data; + volatile boolean compressed; if (lump < 0) I_Error("W_ReadLump: %i < 0", lump); - if (lump >= wadfile[wadnum].numlumps) + wad = W_GetWadForLump(lump); + if (lump >= wad->firstlump+wad->numlumps) I_Error ("W_ReadLump: %i >= numlumps",lump); - l = wadfile[wadnum].lumpinfo+lump; + + l = &wad->lumpinfo[lump-wad->firstlump]; // cache the file size because W_GetLumpData can overwrite // the memory region that stores the lump info - the l pointer size = BIGLONG(l->size); - if (l->name[0] & 0x80) /* compressed */ - { - decode((unsigned char *)W_GetLumpData(lump), - (unsigned char *) dest); - } - else - { - D_memcpy (dest, W_GetLumpData(lump), size); - } + compressed = l->name[0] & 0x80; + + data = W_GetLumpData(lump); + + if (compressed) /* compressed */ + decode(data, (unsigned char *) dest); + else if (dest != data) + D_memcpy (dest, data, size); return size; } @@ -402,18 +430,33 @@ void *W_CacheLumpNum (int lump, int tag) { #ifdef MARS void* cache; - int len; + volatile int len; + volatile boolean compressed; + wadfile_t *wad; + lumpinfo_t *l; + void *data; if (lump < 0) I_Error("W_CacheLumpNum: %i < 0", lump); - if (lump >= wadfile[wadnum].numlumps) + wad = W_GetWadForLump(lump); + if (lump >= wad->firstlump+wad->numlumps) I_Error ("W_CacheLumpNum: %i >= numlumps",lump); if (tag != PU_STATIC) I_Error("W_CacheLumpNum: %i tag != PU_STATIC", lump); - len = W_LumpLength(lump); + l = &wad->lumpinfo[lump-wad->firstlump]; + // cache the file size because W_GetLumpData can overwrite + // the memory region that stores the lump info - the l pointer + len = BIGLONG(l->size); + compressed = l->name[0] & 0x80; + cache = Z_Malloc(len+1, tag); - W_ReadLump(lump, cache); + data = W_GetLumpData(lump); + + if (compressed) /* compressed */ + decode(data, (unsigned char *) cache); + else + D_memcpy (cache, data, len); ((char *)cache)[len] = '\0'; return cache; @@ -463,9 +506,15 @@ void *W_CacheLumpName (const char *name, int tag) const char *W_GetNameForNum (int lump) { - if (lump >= wadfile[wadnum].numlumps) + wadfile_t *wad; + + if (lump < 0) + I_Error("W_GetNameForNum: %i < 0", lump); + wad = W_GetWadForLump(lump); + if (lump >= wad->firstlump+wad->numlumps) I_Error ("W_GetNameForNum: %i >= numlumps",lump); - return wadfile[wadnum].lumpinfo[lump].name; + + return wad->lumpinfo[lump-wad->firstlump].name; } /* @@ -477,16 +526,21 @@ const char *W_GetNameForNum (int lump) void * W_GetLumpData(int lump) { - wadfile_t *wad = &wadfile[wadnum]; - lumpinfo_t* l = wad->lumpinfo + lump; + wadfile_t *wad; + lumpinfo_t* l; + + if (lump < 0) + I_Error("W_GetLumpData: %i < 0", lump); - if (lump >= wad->numlumps) - I_Error("W_GetLumpData: %i >= numlumps", lump); + wad = W_GetWadForLump(lump); + if (lump >= wad->firstlump+wad->numlumps) + I_Error ("W_GetLumpData: %i >= numlumps",lump); + l = &wad->lumpinfo[lump-wad->firstlump]; if (wad->cdlength) { - int pos = BIGLONG(l->filepos); - int len = BIGLONG(l->size); + volatile int pos = BIGLONG(l->filepos); + volatile int len = BIGLONG(l->size); I_SeekCDFile(pos, SEEK_SET);