diff --git a/src/p_setup.c b/src/p_setup.c index 2109c5086..f82ee5ee2 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -543,10 +543,6 @@ static inline void P_LoadSubsectors(lumpnum_t lumpnum) Z_Free(data); } -// -// P_LoadSectors -// - // // levelflats // @@ -572,24 +568,21 @@ size_t P_PrecacheLevelFlats(void) return flatmemory; } -// help function for P_LoadSectors, find a flat in the active wad files, +// Auxiliary function. Find a flat in the active wad files, // allocate an id for it, and set the levelflat (to speedup search) -// INT32 P_AddLevelFlat(const char *flatname, levelflat_t *levelflat) { size_t i; - // - // first scan through the already found flats - // + // Scan through the already found flats, break if it matches. for (i = 0; i < numlevelflats; i++, levelflat++) - if (strnicmp(levelflat->name,flatname,8)==0) + if (strnicmp(levelflat->name, flatname, 8) == 0) break; - // that flat was already found in the level, return the id + // If there is no match, make room for a new flat. if (i == numlevelflats) { - // store the name + // Store the name. strlcpy(levelflat->name, flatname, sizeof (levelflat->name)); strupr(levelflat->name); @@ -673,6 +666,8 @@ INT32 P_CheckLevelFlat(const char *flatname) return (INT32)i; } +// Sets up the ingame sectors structures. +// Lumpnum is the lumpnum of a SECTORS lump. static void P_LoadSectors(lumpnum_t lumpnum) { UINT8 *data; @@ -681,21 +676,26 @@ static void P_LoadSectors(lumpnum_t lumpnum) sector_t *ss; levelflat_t *foundflats; + // We count how many sectors we got. numsectors = W_LumpLength(lumpnum) / sizeof (mapsector_t); if (numsectors <= 0) I_Error("Level has no sectors"); + + // Allocate as much memory as we need into the global sectors table. sectors = Z_Calloc(numsectors*sizeof (*sectors), PU_LEVEL, NULL); - data = W_CacheLumpNum(lumpnum,PU_STATIC); - //Fab : FIXME: allocate for whatever number of flats - // 512 different flats per level should be plenty + // Cache the data from the lump. + data = W_CacheLumpNum(lumpnum, PU_STATIC); + // Allocate a big chunk of memory as big as our MAXLEVELFLATS limit. + //Fab : FIXME: allocate for whatever number of flats - 512 different flats per level should be plenty foundflats = calloc(MAXLEVELFLATS, sizeof (*foundflats)); if (foundflats == NULL) I_Error("Ran out of memory while loading sectors\n"); numlevelflats = 0; + // For each counted sector, copy the sector raw data from our cache pointer ms, to the global table pointer ss. ms = (mapsector_t *)data; ss = sectors; for (i = 0; i < numsectors; i++, ss++, ms++) @@ -703,9 +703,6 @@ static void P_LoadSectors(lumpnum_t lumpnum) ss->floorheight = SHORT(ms->floorheight)<ceilingheight = SHORT(ms->ceilingheight)<floorpic = P_AddLevelFlat(ms->floorpic, foundflats); ss->ceilingpic = P_AddLevelFlat(ms->ceilingpic, foundflats); @@ -3017,6 +3014,71 @@ boolean P_RunSOC(const char *socfilename) return true; } +#ifdef HAVE_BLUA +// Auxiliary function for PK3 loading - runs Lua scripts from range. +void P_LoadLuaScrRange(UINT16 wadnum, UINT16 first, UINT16 num) +{ + for (; num > 0; num--, first++) + { + LUA_LoadLump(wadnum, first); + } +} +#endif + +// Auxiliary function for PK3 loading - runs SOCs from range. +void P_LoadDehackRange(UINT16 wadnum, UINT16 first, UINT16 num) +{ + for (; num > 0; num--, first++) + { + CONS_Printf(M_GetText("Loading SOC from %s\n"), wadfiles[wadnum]->filename); + DEH_LoadDehackedLumpPwad(wadnum, first); + } +} + +// Auxiliary function for PK3 loading - looks for sound replacements. +// NOTE: it does not really add any new sound entry or anything. +void P_LoadSoundsRange(UINT16 wadnum, UINT16 first, UINT16 num) +{ + size_t j; + lumpinfo_t *lumpinfo = wadfiles[wadnum]->lumpinfo + first; + for (; num > 0; num--, lumpinfo++) + { + // Let's check whether it's replacing an existing sound or it's a brand new one. + for (j = 1; j < NUMSFX; j++) + { + if (S_sfx[j].name && !strnicmp(S_sfx[j].name, lumpinfo->name + 2, 6)) + { + // the sound will be reloaded when needed, + // since sfx->data will be NULL + CONS_Debug(DBG_SETUP, "Sound %.8s replaced\n", lumpinfo->name); + + I_FreeSfx(&S_sfx[j]); + } + } + } +} + +// Auxiliary function for PK3 loading - looks for sound replacements. +// NOTE: does nothing but print debug messages. +void P_LoadMusicsRange(UINT16 wadnum, UINT16 first, UINT16 num) +{ + lumpinfo_t *lumpinfo = wadfiles[wadnum]->lumpinfo + first; + char *name; + for (; num > 0; num--, lumpinfo++) + { + name = lumpinfo->name; + if (name[0] == 'O' && name[1] == '_') + { + CONS_Debug(DBG_SETUP, "Music %.8s replaced\n", name); + } + else if (name[0] == 'D' && name[1] == '_') + { + CONS_Debug(DBG_SETUP, "Music %.8s replaced\n", name); + } + } + return; +} + // // Add a wadfile to the active wad files, // replace sounds, musics, patches, textures, sprites and maps @@ -3027,10 +3089,24 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname) UINT16 numlumps, wadnum; INT16 firstmapreplaced = 0, num; char *name; - char *fullName; lumpinfo_t *lumpinfo; boolean replacedcurrentmap = false; + // Vars to help us with the position start and amount of each resource type. + // Useful for PK3s since they use folders. + // WADs use markers for some resources, but others such as sounds are checked lump-by-lump anyway. + UINT16 luaPos, luaNum = 0; + UINT16 socPos, socNum = 0; + UINT16 sfxPos, sfxNum = 0; + UINT16 musPos, musNum = 0; + UINT16 sprPos, sprNum = 0; + UINT16 texPos, texNum = 0; +// UINT16 patPos, patNum = 0; +// UINT16 flaPos, flaNum = 0; +// UINT16 mapPos, mapNum = 0; + + + if ((numlumps = W_LoadWadFile(wadfilename)) == INT16_MAX) { CONS_Printf(M_GetText("Errors occured while loading %s; not added.\n"), wadfilename); @@ -3039,38 +3115,67 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname) else wadnum = (UINT16)(numwadfiles-1); - lumpinfo = wadfiles[wadnum]->lumpinfo; - - // - // search for sound replacements - // switch(wadfiles[wadnum]->type) { - case 2342342: - for (i = 0; i < numlumps; i++, lumpinfo++) + case RET_PK3: { - name = lumpinfo->name; - fullName = lumpinfo->name2; - if (!strnicmp(fullName, "sounds", 6)) + // Auxiliary function - input a folder name and gives us the resource markers positions. + void FindFolder(char *folName, UINT16 *start, UINT16 *end) { - // We found a sound. Let's check whether it's replacing an existing sound or it's a brand new one. - for (j = 1; j < NUMSFX; j++) + if (!stricmp(lumpinfo->name2, folName)) { - if (S_sfx[j].name && !strnicmp(S_sfx[j].name, name, 6)) + lumpinfo++; + *start = ++i; + for (i; i < numlumps; i++, lumpinfo++) { - // the sound will be reloaded when needed, - // since sfx->data will be NULL - CONS_Debug(DBG_SETUP, "Sound %.8s replaced\n", name); - - I_FreeSfx(&S_sfx[j]); - - sreplaces++; + if (strnicmp(lumpinfo->name2, folName, strlen(folName))) + { + break; + } } + lumpinfo--; + *end = i-- - *start; + CONS_Printf("Folder %s, first lump %lu, total: %lu.\n", folName, *start, *end); + return; } + return; } + + // Look for the lumps that act as resource delimitation markers. + lumpinfo = wadfiles[wadnum]->lumpinfo; + for (i = 0; i < numlumps; i++, lumpinfo++) + { + FindFolder("Lua/", &luaPos, &luaNum); + FindFolder("Soc/", &socPos, &socNum); + FindFolder("Sounds/", &sfxPos, &sfxNum); + FindFolder("Music/", &musPos, &musNum); + FindFolder("Sprites/", &sprPos, &sprNum); + FindFolder("Textures/", &texPos, &texNum); +// FindFolder("Patches/", &patPos, &patNum); +// FindFolder("Flats/", &flaPos, &flaNum); +// FindFolder("Maps/", &mapPos, &mapNum); + } + + // Update the detected resources. + // Note: ALWAYS load Lua scripts first, SOCs right after, and the remaining resources afterwards. +#ifdef HAVE_BLUA + if (luaNum) // Lua scripts. + P_LoadLuaScrRange(wadnum, luaPos, luaNum); +#endif + if (socNum) // SOCs. + P_LoadDehackRange(wadnum, socPos, socNum); + if (sfxNum) // Sounds. TODO: Function currently only updates already existing sounds, the rest is handled somewhere else. + P_LoadSoundsRange(wadnum, sfxPos, sfxNum); + if (musNum) // Music. TODO: Useless function right now. + P_LoadMusicsRange(wadnum, musPos, musNum); + if (sprNum) // Sprites. + R_LoadSpritsRange(wadnum, sprPos, sprNum); + if (texNum) // Textures. TODO: R_LoadTextures() does the folder positioning once again. New function maybe? + R_LoadTextures(); } break; default: + lumpinfo = wadfiles[wadnum]->lumpinfo; for (i = 0; i < numlumps; i++, lumpinfo++) { name = lumpinfo->name; @@ -3101,6 +3206,18 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname) digmreplaces++; } } + + // + // search for sprite replacements + // + R_AddSpriteDefs(wadnum); + + // Reload it all anyway, just in case they + // added some textures but didn't insert a + // TEXTURE1/PNAMES/etc. list. + R_LoadTextures(); // numtexture changes + + break; } if (!devparm && sreplaces) @@ -3110,16 +3227,6 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname) if (!devparm && digmreplaces) CONS_Printf(M_GetText("%s digital musics replaced\n"), sizeu1(digmreplaces)); - // - // search for sprite replacements - // - R_AddSpriteDefs(wadnum); - - // Reload it all anyway, just in case they - // added some textures but didn't insert a - // TEXTURE1/PNAMES/etc. list. - R_LoadTextures(); // numtexture changes - // Reload ANIMATED / ANIMDEFS P_InitPicAnims(); diff --git a/src/r_data.c b/src/r_data.c index fafa67c63..3bc93831d 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -569,8 +569,8 @@ void R_LoadTextures(void) { if (wadfiles[w]->type == RET_PK3) { - texstart = W_CheckNumForFullNamePK3("txturs/", (UINT16)w, 0) + 1; - texend = W_CheckNumForFolderEndPK3("txturs/", (UINT16)w, texstart); + texstart = W_CheckNumForFullNamePK3("textures/", (UINT16)w, 0) + 1; + texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart); } else { @@ -620,8 +620,8 @@ void R_LoadTextures(void) // Get the lump numbers for the markers in the WAD, if they exist. if (wadfiles[w]->type == RET_PK3) { - texstart = W_CheckNumForFullNamePK3("txturs/", (UINT16)w, 0) + 1; - texend = W_CheckNumForFolderEndPK3("txturs/", (UINT16)w, texstart); + texstart = W_CheckNumForFullNamePK3("textures/", (UINT16)w, 0) + 1; + texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart); } else { diff --git a/src/r_things.c b/src/r_things.c index 2f8e7c91a..e1b4d66b0 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -368,6 +368,38 @@ static boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, return true; } +// Auxiliary function for PK3 loading - Loads sprites from a specified range. +void R_LoadSpritsRange(UINT16 wadnum, UINT16 first, UINT16 num) +{ + size_t i, addsprites = 0; + char wadname[MAX_WADPATH]; + // + // scan through lumps, for each sprite, find all the sprite frames + // + for (i = 0; i < numsprites; i++) + { + spritename = sprnames[i]; + if (spritename[4] && wadnum >= (UINT16)spritename[4]) + continue; + + if (R_AddSingleSpriteDef(spritename, &sprites[i], wadnum, first, first + num + 1)) + { +#ifdef HWRENDER + if (rendermode == render_opengl) + HWR_AddSpriteMD2(i); +#endif + // if a new sprite was added (not just replaced) + addsprites++; +#ifndef ZDEBUG + CONS_Debug(DBG_SETUP, "sprite %s set in pwad %d\n", spritename, wadnum); +#endif + } + } + + nameonly(strcpy(wadname, wadfiles[wadnum]->filename)); + CONS_Printf(M_GetText("%s added %d frames in %s sprites\n"), wadname, num, sizeu1(addsprites)); +} + // // Search for sprites replacements in a wad whose names are in namelist // diff --git a/src/r_things.h b/src/r_things.h index 3907fd2ae..b3f1f4b4c 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -50,6 +50,8 @@ void R_SortVisSprites(void); //faB: find sprites in wadfile, replace existing, add new ones // (only sprites from namelist are added or replaced) void R_AddSpriteDefs(UINT16 wadnum); +void R_AddSpriteDefsRange(UINT16 wadnum, UINT16 start, UINT16 end); + #ifdef DELFILE void R_DelSpriteDefs(UINT16 wadnum); diff --git a/src/w_wad.c b/src/w_wad.c index 2d717d12a..e410e4bde 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -696,7 +696,10 @@ UINT16 W_LoadWadFile(const char *filename) CONS_Printf(M_GetText("Added file %s (%u lumps)\n"), filename, numlumps); wadfiles[numwadfiles] = wadfile; numwadfiles++; // must come BEFORE W_LoadDehackedLumps, so any addfile called by COM_BufInsertText called by Lua doesn't overwrite what we just loaded - W_LoadDehackedLumps(numwadfiles-1); + + // TODO: HACK ALERT - Load Lua & SOC stuff right here for WADs. Avoids crash on startup since WADs are loaded using W_InitMultipleFiles. + if (wadfile->type == RET_WAD) + W_LoadDehackedLumps(numwadfiles - 1); W_InvalidateLumpnumCache(); diff --git a/src/w_wad.h b/src/w_wad.h index 35d060279..58b3b322c 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -99,6 +99,8 @@ UINT16 W_LoadWadFile(const char *filename); void W_UnloadWadFile(UINT16 num); #endif +static inline void W_LoadDehackedLumps(UINT16 wadnum); + // W_InitMultipleFiles returns 1 if all is okay, 0 otherwise, // so that it stops with a message if a file was not found, but not if all is okay. INT32 W_InitMultipleFiles(char **filenames);