From afba4b2abd37b3de7d29a3be1f7e6ffad7db29de Mon Sep 17 00:00:00 2001 From: Nevur Date: Sun, 30 Apr 2017 14:49:33 +0200 Subject: [PATCH 01/35] Started to work towards PK3 support. -Tweaked compression conditional to a switch-case format, looking towards adding several comrpession algorithms; haven't removed the previous "compressed" boolean yet. -Added dynamically allocated name strings for lumps; haven't removed the previous name field. -Added rudimentary PK3 central directory recognition; nothing is actually loaded in the end. --- src/p_setup.c | 2 +- src/w_wad.c | 134 +++++++++++++++++++++++++++++++++++++++++++++----- src/w_wad.h | 9 ++++ 3 files changed, 133 insertions(+), 12 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index a0c745e60..2e8822e60 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2881,7 +2881,7 @@ boolean P_SetupLevel(boolean skipprecip) camera.angle = FixedAngle((fixed_t)thing->angle << FRACBITS); } } - + // Salt: CV_ClearChangedFlags() messes with your settings :( /*if (!cv_cam_height.changed) CV_Set(&cv_cam_height, cv_cam_height.defaultvalue); diff --git a/src/w_wad.c b/src/w_wad.c index b1b72eec1..678463580 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -115,6 +115,8 @@ void W_Shutdown(void) fclose(wadfiles[numwadfiles]->handle); Z_Free(wadfiles[numwadfiles]->lumpinfo); Z_Free(wadfiles[numwadfiles]->filename); + while (wadfiles[numwadfiles]->numlumps--) + Z_Free(wadfiles[numwadfiles]->lumpinfo[wadfiles[numwadfiles]->numlumps].name2); Z_Free(wadfiles[numwadfiles]); } } @@ -340,6 +342,8 @@ UINT16 W_LoadWadFile(const char *filename) // This code emulates a wadfile with one lump name "OBJCTCFG" // at position 0 and size of the whole file. // This allows soc files to be like all wads, copied by network and loaded at the console. + //wadfile->restype = RET_WAD; + numlumps = 1; lumpinfo = Z_Calloc(sizeof (*lumpinfo), PU_STATIC, NULL); lumpinfo->position = 0; @@ -347,6 +351,10 @@ UINT16 W_LoadWadFile(const char *filename) lumpinfo->size = ftell(handle); fseek(handle, 0, SEEK_SET); strcpy(lumpinfo->name, "OBJCTCFG"); + // Allocate the lump's full name. + lumpinfo->name2 = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL); + strcpy(lumpinfo->name2, "OBJCTCFG"); + lumpinfo->name2[8] = '\0'; } #ifdef HAVE_BLUA // detect lua script with the "lua" extension @@ -355,6 +363,8 @@ UINT16 W_LoadWadFile(const char *filename) // This code emulates a wadfile with one lump name "LUA_INIT" // at position 0 and size of the whole file. // This allows soc files to be like all wads, copied by network and loaded at the console. + //wadfile->restype = RET_WAD; + numlumps = 1; lumpinfo = Z_Calloc(sizeof (*lumpinfo), PU_STATIC, NULL); lumpinfo->position = 0; @@ -362,11 +372,99 @@ UINT16 W_LoadWadFile(const char *filename) lumpinfo->size = ftell(handle); fseek(handle, 0, SEEK_SET); strcpy(lumpinfo->name, "LUA_INIT"); + // Allocate the lump's full name. + lumpinfo->name2 = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL); + strcpy(lumpinfo->name2, "LUA_INIT"); + lumpinfo->name2[8] = '\0'; } #endif + else if (!stricmp(&filename[strlen(filename) - 4], ".pk3")) + { + long centralDirPos; + long handlePos; + long size; + char *sigBuffer; + + //wadfile->restype = RET_PK3; + CONS_Alert(CONS_NOTICE, "PK3 file detected.\n"); + + // Obtain the file's size. + fseek(handle, 0, SEEK_END); + size = ftell(handle); + CONS_Printf("PK3 size is: %ld\n", size); + + // We must look for the central directory through the file. + rewind(handle); + sigBuffer = malloc(sizeof(char)*4); + for (centralDirPos = 0; centralDirPos < size - 4; centralDirPos++) + { + fread(sigBuffer, 1, 4, handle); + if (memcmp(sigBuffer, "\x50\x4b\x01\x02", 4) == 0) + { + CONS_Printf("Found PK3 central directory at position %ld.\n", centralDirPos); + fseek(handle, -4, SEEK_CUR); + break; + } + else + fseek(handle, -3, SEEK_CUR); // Backwards 3 steps, since fread advances after giving the data. + } + + // Error if we couldn't find the central directory at all. It likely means this is not a ZIP/PK3 file. + if (centralDirPos + 4 == size) + { + CONS_Alert(CONS_ERROR, "No central directory inside PK3! File may be corrupted or incomplete.\n"); + free(sigBuffer); + return INT16_MAX; + } + + // Since we found the central directory, now we can map our lumpinfo table. + // We will look for file headers inside it, until we reach the central directory end signature. + CONS_Printf("Now finding central directory file headers...\n"); + for (handlePos = centralDirPos; handlePos < size - 3; handlePos++) + { + fread(sigBuffer, 1, 4, handle); + if (!memcmp(sigBuffer, "\x50\x4b\x01\x02", 4)) // Got a central dir file header. + { + char *eName; + unsigned short int eNameLen = 0; + unsigned short int eXFieldLen = 0; + unsigned short int eCommentLen = 0; + CONS_Printf("Entry at %ld:\n", handlePos); + // We get the variable length fields. + fseek(handle, 24, SEEK_CUR); + fscanf(handle, "%hu %hu %hu", &eNameLen, &eXFieldLen, &eCommentLen); + CONS_Printf("Name length is %u.\n", eNameLen); + + // We jump straight to the name field now. + fseek(handle, 10, SEEK_CUR); + eName = malloc(sizeof(char)*(eNameLen + 1)); + fgets(eName, eNameLen, handle); + CONS_Printf("%s\n", eName); + free(eName); + } + else if (!memcmp(sigBuffer, "\x50\x4b\x05\x06", 4)) // Found the central dir end signature, stop seeking. + { + CONS_Printf("Found central directory end at position %ld.\n", handlePos); + break; + } + fseek(handle, -3, SEEK_CUR); + } + // We reached way past beyond the file size. + // This means we couldn't find the central directory end signature, and thus the file might be broken. + if (handlePos + 3 == size) + { + CONS_Alert(CONS_ERROR, "No central dir end inside PK3! File may be corrupted or incomplete.\n"); + free(sigBuffer); + return INT16_MAX; + } + free(sigBuffer); + return INT16_MAX; + } + // assume wad file else { - // assume wad file + //wadfile->restype = RET_WAD; + wadinfo_t header; lumpinfo_t *lump_p; filelump_t *fileinfo; @@ -427,19 +525,29 @@ UINT16 W_LoadWadFile(const char *filename) { lump_p->size = realsize; lump_p->compressed = 1; + lump_p->compression = CM_LZF; } else { lump_p->size -= 4; lump_p->compressed = 0; + lump_p->compression = CM_NONE; } lump_p->position += 4; lump_p->disksize -= 4; } - else lump_p->compressed = 0; + else + { + lump_p->compressed = 0; + lump_p->compression = CM_NONE; + } memset(lump_p->name, 0x00, 9); strncpy(lump_p->name, fileinfo->name, 8); + // Allocate the lump's full name. + lump_p->name2 = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL); + strncpy(lump_p->name2, fileinfo->name, 8); + lump_p->name2[8] = '\0'; } free(fileinfov); } @@ -843,17 +951,21 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si if (!size || size+offset > lumpsize) size = lumpsize - offset; - if (wadfiles[wad]->lumpinfo[lump].compressed) + // + switch(wadfiles[wad]->lumpinfo[lump].compressed) { - UINT8 *data; - data = W_ReadCompressedLump(wad, lump); - if (!data) return 0; - M_Memcpy(dest, data+offset, size); - Z_Free(data); - return size; - } - else + case CM_LZF: + { + UINT8 *data; + data = W_ReadCompressedLump(wad, lump); + if (!data) return 0; + M_Memcpy(dest, data+offset, size); + Z_Free(data); + return size; + } + default: return W_RawReadLumpHeader(wad, lump, dest, size, offset); + } } size_t W_ReadLumpHeader(lumpnum_t lumpnum, void *dest, size_t size, size_t offset) diff --git a/src/w_wad.h b/src/w_wad.h index f7ea64a56..a882fb936 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -34,14 +34,19 @@ typedef struct UINT32 infotableofs; // the 'directory' of resources } wadinfo_t; +// Available compression methods for lumps. +enum compmethod{CM_NONE, CM_LZF}; + // a memory entry of the wad directory typedef struct { unsigned long position; // filelump_t filepos unsigned long disksize; // filelump_t size char name[9]; // filelump_t name[] + char *name2; // Dynamically allocated name. size_t size; // real (uncompressed) size INT32 compressed; // i + enum compmethod compression; // lump compression method } lumpinfo_t; // ========================================================================= @@ -58,9 +63,13 @@ typedef struct #include "m_aatree.h" #endif +// Resource type of the WAD. Yeah, I know this sounds dumb, but I'll leave it like this until I clean up the code further. +enum restype {RET_WAD, RET_PK3}; + typedef struct wadfile_s { char *filename; + enum restype restype; lumpinfo_t *lumpinfo; lumpcache_t *lumpcache; #ifdef HWRENDER From 376d2a2da30f32ca67b2726dae24f6d8ca9fc6aa Mon Sep 17 00:00:00 2001 From: Nevur Date: Sun, 30 Apr 2017 17:43:11 +0200 Subject: [PATCH 02/35] Further work on PK3 support. -PK3 files are now properly loaded as files. -PK3 lumps are still being treated the same way as WAD files. It means they're dependant on markers, if that makes any sense in the context of a ZIP file (it doesn't). I haven't worked out this part yet but I obviously intend to do so. -I don't know if the lumps' position address is correct, we'll figure out when I fix the thing from above. --- src/w_wad.c | 76 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 61 insertions(+), 15 deletions(-) diff --git a/src/w_wad.c b/src/w_wad.c index 678463580..e1539af4b 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -380,11 +380,13 @@ UINT16 W_LoadWadFile(const char *filename) #endif else if (!stricmp(&filename[strlen(filename) - 4], ".pk3")) { - long centralDirPos; - long handlePos; - long size; + unsigned long centralDirPos; + unsigned long handlePos; + unsigned long size; char *sigBuffer; + numlumps = 0; + //wadfile->restype = RET_PK3; CONS_Alert(CONS_NOTICE, "PK3 file detected.\n"); @@ -423,23 +425,63 @@ UINT16 W_LoadWadFile(const char *filename) for (handlePos = centralDirPos; handlePos < size - 3; handlePos++) { fread(sigBuffer, 1, 4, handle); - if (!memcmp(sigBuffer, "\x50\x4b\x01\x02", 4)) // Got a central dir file header. + if (!memcmp(sigBuffer, "\x50\x4b\x01\x02", 4)) // Found a central dir file header. { char *eName; - unsigned short int eNameLen = 0; + unsigned short int eNameLen = 8; unsigned short int eXFieldLen = 0; unsigned short int eCommentLen = 0; - CONS_Printf("Entry at %ld:\n", handlePos); - // We get the variable length fields. - fseek(handle, 24, SEEK_CUR); - fscanf(handle, "%hu %hu %hu", &eNameLen, &eXFieldLen, &eCommentLen); - CONS_Printf("Name length is %u.\n", eNameLen); + unsigned int eSize = 0; + unsigned int eCompSize = 0; + unsigned int eLocalHeaderOffset = 0; + + fseek(handle, 16, SEEK_CUR); + fread(&eSize, 1, 4, handle); + fread(&eCompSize, 1, 4, handle); + + // We get the variable length fields. + fread(&eNameLen, 1, 2, handle); + fread(&eXFieldLen, 1, 2, handle); + fread(&eCommentLen, 1, 2, handle); + fseek(handle, 8, SEEK_CUR); + fread(&eLocalHeaderOffset, 1, 4, handle); // Get the offset. - // We jump straight to the name field now. - fseek(handle, 10, SEEK_CUR); eName = malloc(sizeof(char)*(eNameLen + 1)); - fgets(eName, eNameLen, handle); - CONS_Printf("%s\n", eName); + fgets(eName, eNameLen + 1, handle); + if (eSize == 0) // Is this entry a folder? + { + CONS_Printf("Folder %s at %ld:\n", eName, handlePos); + } + else // If not, then it is a normal file. Let's arrange its lumpinfo structure then! + { + CONS_Printf("File %s at %ld:\n", eName, handlePos); + + if (numlumps == 0) // First lump? Let's allocate the first lumpinfo block. + lumpinfo = Z_Malloc(sizeof(*lumpinfo), PU_STATIC, NULL); + else // Otherwise, reallocate and increase by 1. Might not be optimal, though... + lumpinfo = (lumpinfo_t*) Z_Realloc(lumpinfo, (numlumps + 1)*sizeof(*lumpinfo), PU_STATIC, NULL); + + lumpinfo[numlumps].position = eLocalHeaderOffset + 30 + eNameLen + eXFieldLen; + lumpinfo[numlumps].disksize = eCompSize; + + strncpy(lumpinfo[numlumps].name, eName + eNameLen - 8, 8); + lumpinfo[numlumps].name[8] = '\0'; + + lumpinfo[numlumps].name2 = Z_Malloc((eNameLen+1)*sizeof(char), PU_STATIC, NULL); + strncpy(lumpinfo[numlumps].name2, eName, eNameLen); + lumpinfo[numlumps].name2[eNameLen] = '\0'; + + lumpinfo[numlumps].size = eSize; + + lumpinfo[numlumps].compressed = 0; + + lumpinfo[numlumps].compression = CM_NONE; + + //CONS_Printf("The lump's current long name is %s\n", lumpinfo[numlumps].name2); + //CONS_Printf("The lump's current short name is %s\n", lumpinfo[numlumps].name); + numlumps++; + } + free(eName); } else if (!memcmp(sigBuffer, "\x50\x4b\x05\x06", 4)) // Found the central dir end signature, stop seeking. @@ -457,8 +499,12 @@ UINT16 W_LoadWadFile(const char *filename) free(sigBuffer); return INT16_MAX; } + + // If we've reached this far, then it means our dynamically stored lumpinfo has to be ready. + // Now we finally build our... incorrectly called wadfile. + // TODO: Maybe we should give them more generalized names, like resourcefile or resfile or something. + // Mostly for clarity and better understanding when reading the code. free(sigBuffer); - return INT16_MAX; } // assume wad file else From 448ceefe84426e88f77344fbb0ff4f955cef0851 Mon Sep 17 00:00:00 2001 From: Nevur Date: Sun, 30 Apr 2017 20:05:26 +0200 Subject: [PATCH 03/35] Little progress made. The code from everywhere still looks for the basic WAD structure of the lumps. -Removed a redundant boolean related to texture loading in P_AddWadFile. -Started working on handling PK3s differently, except that I'm not sure about what I'm doing. I don't know what to do from now on for today, so I'll leave it here for now. --- src/p_setup.c | 84 +++++++++++++++++++++++++++++++-------------------- src/w_wad.c | 22 +++++++++++--- src/w_wad.h | 2 +- 3 files changed, 70 insertions(+), 38 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 2e8822e60..1505e8c73 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3027,8 +3027,8 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname) UINT16 numlumps, wadnum; INT16 firstmapreplaced = 0, num; char *name; + char *fullName; lumpinfo_t *lumpinfo; - boolean texturechange = false; boolean replacedcurrentmap = false; if ((numlumps = W_LoadWadFile(wadfilename)) == INT16_MAX) @@ -3036,49 +3036,72 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname) CONS_Printf(M_GetText("Errors occured while loading %s; not added.\n"), wadfilename); return false; } - else wadnum = (UINT16)(numwadfiles-1); + else + wadnum = (UINT16)(numwadfiles-1); + + lumpinfo = wadfiles[wadnum]->lumpinfo; // // search for sound replacements // - lumpinfo = wadfiles[wadnum]->lumpinfo; - for (i = 0; i < numlumps; i++, lumpinfo++) + switch(wadfiles[wadnum]->type) { - name = lumpinfo->name; - if (name[0] == 'D') + case RET_PK3: + for (i = 0; i < numlumps; i++, lumpinfo++) { - if (name[1] == 'S') for (j = 1; j < NUMSFX; j++) + name = lumpinfo->name; + fullName = lumpinfo->name2; + if (!strnicmp(fullName, "sounds", 6)) { - if (S_sfx[j].name && !strnicmp(S_sfx[j].name, name + 2, 6)) + // 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++) { - // the sound will be reloaded when needed, - // since sfx->data will be NULL - CONS_Debug(DBG_SETUP, "Sound %.8s replaced\n", name); + if (S_sfx[j].name && !strnicmp(S_sfx[j].name, name, 6)) + { + // 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]); + I_FreeSfx(&S_sfx[j]); - sreplaces++; + sreplaces++; + } } } - else if (name[1] == '_') + } + break; + default: + for (i = 0; i < numlumps; i++, lumpinfo++) + { + name = lumpinfo->name; + if (name[0] == 'D') + { + if (name[1] == 'S') for (j = 1; j < NUMSFX; j++) + { + if (S_sfx[j].name && !strnicmp(S_sfx[j].name, name + 2, 6)) + { + // 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++; + } + } + else if (name[1] == '_') + { + CONS_Debug(DBG_SETUP, "Music %.8s replaced\n", name); + mreplaces++; + } + } + else if (name[0] == 'O' && name[1] == '_') { CONS_Debug(DBG_SETUP, "Music %.8s replaced\n", name); - mreplaces++; + digmreplaces++; } } - else if (name[0] == 'O' && name[1] == '_') - { - CONS_Debug(DBG_SETUP, "Music %.8s replaced\n", name); - digmreplaces++; - } -#if 0 - // - // search for texturechange replacements - // - else if (!memcmp(name, "TEXTURE1", 8) || !memcmp(name, "TEXTURE2", 8) - || !memcmp(name, "PNAMES", 6)) -#endif - texturechange = true; + break; } if (!devparm && sreplaces) CONS_Printf(M_GetText("%s sounds replaced\n"), sizeu1(sreplaces)); @@ -3095,10 +3118,7 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname) // Reload it all anyway, just in case they // added some textures but didn't insert a // TEXTURE1/PNAMES/etc. list. - if (texturechange) // initialized in the sound check - R_LoadTextures(); // numtexture changes - else - R_FlushTextureCache(); // just reload it from file + R_LoadTextures(); // numtexture changes // Reload ANIMATED / ANIMDEFS P_InitPicAnims(); diff --git a/src/w_wad.c b/src/w_wad.c index e1539af4b..9c935e36e 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -293,6 +293,7 @@ UINT16 W_LoadWadFile(const char *filename) FILE *handle; lumpinfo_t *lumpinfo; wadfile_t *wadfile; + enum restype type; UINT32 numlumps; size_t i; INT32 compressed = 0; @@ -342,7 +343,7 @@ UINT16 W_LoadWadFile(const char *filename) // This code emulates a wadfile with one lump name "OBJCTCFG" // at position 0 and size of the whole file. // This allows soc files to be like all wads, copied by network and loaded at the console. - //wadfile->restype = RET_WAD; + type = RET_WAD; numlumps = 1; lumpinfo = Z_Calloc(sizeof (*lumpinfo), PU_STATIC, NULL); @@ -363,7 +364,7 @@ UINT16 W_LoadWadFile(const char *filename) // This code emulates a wadfile with one lump name "LUA_INIT" // at position 0 and size of the whole file. // This allows soc files to be like all wads, copied by network and loaded at the console. - //wadfile->restype = RET_WAD; + type = RET_WAD; numlumps = 1; lumpinfo = Z_Calloc(sizeof (*lumpinfo), PU_STATIC, NULL); @@ -387,7 +388,7 @@ UINT16 W_LoadWadFile(const char *filename) numlumps = 0; - //wadfile->restype = RET_PK3; + type = RET_PK3; CONS_Alert(CONS_NOTICE, "PK3 file detected.\n"); // Obtain the file's size. @@ -454,6 +455,7 @@ UINT16 W_LoadWadFile(const char *filename) } else // If not, then it is a normal file. Let's arrange its lumpinfo structure then! { + int namePos = eNameLen - 1; CONS_Printf("File %s at %ld:\n", eName, handlePos); if (numlumps == 0) // First lump? Let's allocate the first lumpinfo block. @@ -464,7 +466,16 @@ UINT16 W_LoadWadFile(const char *filename) lumpinfo[numlumps].position = eLocalHeaderOffset + 30 + eNameLen + eXFieldLen; lumpinfo[numlumps].disksize = eCompSize; - strncpy(lumpinfo[numlumps].name, eName + eNameLen - 8, 8); + // We will trim the file's full name so that only the filename is left. + while(namePos--) + { + if(eName[namePos] == '/') + { + namePos++; + break; + } + } + strncpy(lumpinfo[numlumps].name, eName + namePos, 8); lumpinfo[numlumps].name[8] = '\0'; lumpinfo[numlumps].name2 = Z_Malloc((eNameLen+1)*sizeof(char), PU_STATIC, NULL); @@ -509,7 +520,7 @@ UINT16 W_LoadWadFile(const char *filename) // assume wad file else { - //wadfile->restype = RET_WAD; + type = RET_WAD; wadinfo_t header; lumpinfo_t *lump_p; @@ -621,6 +632,7 @@ UINT16 W_LoadWadFile(const char *filename) // wadfile = Z_Malloc(sizeof (*wadfile), PU_STATIC, NULL); wadfile->filename = Z_StrDup(filename); + wadfile->type = type; wadfile->handle = handle; wadfile->numlumps = (UINT16)numlumps; wadfile->lumpinfo = lumpinfo; diff --git a/src/w_wad.h b/src/w_wad.h index a882fb936..c69c2e626 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -69,7 +69,7 @@ enum restype {RET_WAD, RET_PK3}; typedef struct wadfile_s { char *filename; - enum restype restype; + enum restype type; lumpinfo_t *lumpinfo; lumpcache_t *lumpcache; #ifdef HWRENDER From 2c614f8f2c75cff9e67be9269e41c2e02d5a9806 Mon Sep 17 00:00:00 2001 From: Nevur Date: Mon, 1 May 2017 16:37:32 +0200 Subject: [PATCH 04/35] More work on PK3 handling. -Moved the MD5 check for added files up so it avoids unnecessary work when you mess up and re-add a file. -Using compression enum for compressed lumps now. -Vastly improved central directory seeking algorithm, big files are read fine now. Thanks a lot JTE! -Improved remaining central directory navigation algorithm, we know and expect what data is coming from now on, after all. -TX_ textures and sounds are replaced, but textures crash the game on mapload, and sounds are simply mute when replaced. Might have to do something with caching, I don't know yet. --- src/p_setup.c | 2 +- src/r_data.c | 26 +++++-- src/w_wad.c | 206 +++++++++++++++++++++++++++++++++----------------- src/w_wad.h | 6 +- 4 files changed, 163 insertions(+), 77 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 1505e8c73..2109c5086 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3046,7 +3046,7 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname) // switch(wadfiles[wadnum]->type) { - case RET_PK3: + case 2342342: for (i = 0; i < numlumps; i++, lumpinfo++) { name = lumpinfo->name; diff --git a/src/r_data.c b/src/r_data.c index d29c625e7..fafa67c63 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -567,8 +567,16 @@ void R_LoadTextures(void) // but the alternative is to spend a ton of time checking and re-checking all previous entries just to skip any potentially patched textures. for (w = 0, numtextures = 0; w < numwadfiles; w++) { - texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0) + 1; - texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0); + if (wadfiles[w]->type == RET_PK3) + { + texstart = W_CheckNumForFullNamePK3("txturs/", (UINT16)w, 0) + 1; + texend = W_CheckNumForFolderEndPK3("txturs/", (UINT16)w, texstart); + } + else + { + texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0) + 1; + texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0); + } texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0); if (texturesLumpPos != INT16_MAX) @@ -588,7 +596,7 @@ void R_LoadTextures(void) I_Error("No textures detected in any WADs!\n"); } } - + CONS_Printf("We got a number of %d textures.\n", numtextures); // Allocate memory and initialize to 0 for all the textures we are initialising. // There are actually 5 buffers allocated in one for convenience. textures = Z_Calloc((numtextures * sizeof(void *)) * 5, PU_STATIC, NULL); @@ -610,8 +618,16 @@ void R_LoadTextures(void) for (i = 0, w = 0; w < numwadfiles; w++) { // Get the lump numbers for the markers in the WAD, if they exist. - texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0) + 1; - texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0); + if (wadfiles[w]->type == RET_PK3) + { + texstart = W_CheckNumForFullNamePK3("txturs/", (UINT16)w, 0) + 1; + texend = W_CheckNumForFolderEndPK3("txturs/", (UINT16)w, texstart); + } + else + { + texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0) + 1; + texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0); + } texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0); if (texturesLumpPos != INT16_MAX) diff --git a/src/w_wad.c b/src/w_wad.c index 9c935e36e..4645e87d5 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -337,6 +337,24 @@ UINT16 W_LoadWadFile(const char *filename) return INT16_MAX; } +#ifndef NOMD5 + // + // w-waiiiit! + // Let's not add a wad file if the MD5 matches + // an MD5 of an already added WAD file! + // + W_MakeFileMD5(filename, md5sum); + + for (i = 0; i < numwadfiles; i++) + { + if (!memcmp(wadfiles[i]->md5sum, md5sum, 16)) + { + CONS_Alert(CONS_ERROR, M_GetText("%s is already loaded\n"), filename); + return INT16_MAX; + } + } +#endif + // detect dehacked file with the "soc" extension if (!stricmp(&filename[strlen(filename) - 4], ".soc")) { @@ -381,11 +399,13 @@ UINT16 W_LoadWadFile(const char *filename) #endif else if (!stricmp(&filename[strlen(filename) - 4], ".pk3")) { - unsigned long centralDirPos; - unsigned long handlePos; + char curHeader[4]; unsigned long size; - char *sigBuffer; - + char seekPat[] = {0x50, 0x4b, 0x01, 0x02, 0x00}; + char endPat[] = {0x50, 0x4b, 0x05, 0x06, 0xff}; + char *s; + int c; + boolean matched = FALSE; numlumps = 0; type = RET_PK3; @@ -397,49 +417,63 @@ UINT16 W_LoadWadFile(const char *filename) CONS_Printf("PK3 size is: %ld\n", size); // We must look for the central directory through the file. + // All of the central directory entry headers have a signature of 0x50 0x4b 0x01 0x02. + // The first entry found means the beginning of the central directory. rewind(handle); - sigBuffer = malloc(sizeof(char)*4); - for (centralDirPos = 0; centralDirPos < size - 4; centralDirPos++) + s = seekPat; + while((c = fgetc(handle)) != EOF) { - fread(sigBuffer, 1, 4, handle); - if (memcmp(sigBuffer, "\x50\x4b\x01\x02", 4) == 0) + if (*s != c && s > seekPat) // No match? + s = seekPat; // We "reset" the counter by sending the s pointer back to the start of the array. + if (*s == c) { - CONS_Printf("Found PK3 central directory at position %ld.\n", centralDirPos); - fseek(handle, -4, SEEK_CUR); - break; + s++; + if (*s == 0x00) // The array pointer has reached the key char which marks the end. It means we have matched the signature. + { + matched = TRUE; + fseek(handle, -4, SEEK_CUR); + CONS_Printf("Found PK3 central directory at position %ld.\n", ftell(handle)); + break; + } } - else - fseek(handle, -3, SEEK_CUR); // Backwards 3 steps, since fread advances after giving the data. } // Error if we couldn't find the central directory at all. It likely means this is not a ZIP/PK3 file. - if (centralDirPos + 4 == size) + if (matched == FALSE) { CONS_Alert(CONS_ERROR, "No central directory inside PK3! File may be corrupted or incomplete.\n"); - free(sigBuffer); return INT16_MAX; } // Since we found the central directory, now we can map our lumpinfo table. // We will look for file headers inside it, until we reach the central directory end signature. + // We exactly know what data to expect this time, so now we don't need to do a byte-by-byte search. CONS_Printf("Now finding central directory file headers...\n"); - for (handlePos = centralDirPos; handlePos < size - 3; handlePos++) + while(ftell(handle) < size - 4) // Make sure we don't go past the file size! { - fread(sigBuffer, 1, 4, handle); - if (!memcmp(sigBuffer, "\x50\x4b\x01\x02", 4)) // Found a central dir file header. + fread(curHeader, 1, 4, handle); + + // We found a central directory entry signature? + if (!strncmp(curHeader, seekPat, 3)) { + // Let's fill in the fields that we actually need. + // (Declaring all those vars might not be the optimal way to do this, sorry.) char *eName; unsigned short int eNameLen = 8; unsigned short int eXFieldLen = 0; unsigned short int eCommentLen = 0; + unsigned short int eCompression = 0; unsigned int eSize = 0; unsigned int eCompSize = 0; unsigned int eLocalHeaderOffset = 0; - fseek(handle, 16, SEEK_CUR); + // We get the compression type indicator value. + fseek(handle, 6, SEEK_CUR); + fread(&eCompression, 1, 2, handle); + // Get the + fseek(handle, 8, SEEK_CUR); fread(&eSize, 1, 4, handle); fread(&eCompSize, 1, 4, handle); - // We get the variable length fields. fread(&eNameLen, 1, 2, handle); fread(&eXFieldLen, 1, 2, handle); @@ -449,15 +483,14 @@ UINT16 W_LoadWadFile(const char *filename) eName = malloc(sizeof(char)*(eNameLen + 1)); fgets(eName, eNameLen + 1, handle); - if (eSize == 0) // Is this entry a folder? + if (0)//(eSize == 0) // Is this entry a folder? { - CONS_Printf("Folder %s at %ld:\n", eName, handlePos); + CONS_Printf("Folder %s at %ld:\n", eName, ftell(handle)); } else // If not, then it is a normal file. Let's arrange its lumpinfo structure then! { int namePos = eNameLen - 1; - CONS_Printf("File %s at %ld:\n", eName, handlePos); - + CONS_Printf("File %s at: %ld\n", eName, ftell(handle)); if (numlumps == 0) // First lump? Let's allocate the first lumpinfo block. lumpinfo = Z_Malloc(sizeof(*lumpinfo), PU_STATIC, NULL); else // Otherwise, reallocate and increase by 1. Might not be optimal, though... @@ -465,7 +498,8 @@ UINT16 W_LoadWadFile(const char *filename) lumpinfo[numlumps].position = eLocalHeaderOffset + 30 + eNameLen + eXFieldLen; lumpinfo[numlumps].disksize = eCompSize; - + lumpinfo[numlumps].size = eSize; + CONS_Printf("Address: %ld, Full: %ld, Comp: %ld\n", lumpinfo[numlumps].position, lumpinfo[numlumps].size, lumpinfo[numlumps].disksize); // We will trim the file's full name so that only the filename is left. while(namePos--) { @@ -475,47 +509,65 @@ UINT16 W_LoadWadFile(const char *filename) break; } } + memset(lumpinfo[numlumps].name, '\0', 9) strncpy(lumpinfo[numlumps].name, eName + namePos, 8); - lumpinfo[numlumps].name[8] = '\0'; lumpinfo[numlumps].name2 = Z_Malloc((eNameLen+1)*sizeof(char), PU_STATIC, NULL); strncpy(lumpinfo[numlumps].name2, eName, eNameLen); lumpinfo[numlumps].name2[eNameLen] = '\0'; - lumpinfo[numlumps].size = eSize; - - lumpinfo[numlumps].compressed = 0; - - lumpinfo[numlumps].compression = CM_NONE; - - //CONS_Printf("The lump's current long name is %s\n", lumpinfo[numlumps].name2); - //CONS_Printf("The lump's current short name is %s\n", lumpinfo[numlumps].name); + // We set the compression type from what we're supporting so far. + switch(eCompression) + { + case 0: + lumpinfo[numlumps].compression = CM_NONE; + break; + case 8: + lumpinfo[numlumps].compression = CM_DEFLATE; + break; + case 14: + lumpinfo[numlumps].compression = CM_LZF; + break; + default: + CONS_Alert(CONS_WARNING, "Lump has an unsupported compression type!\n"); + lumpinfo[numlumps].compression = CM_NONE; + break; + } + fseek(handle, eXFieldLen + eCommentLen, SEEK_CUR); // We skip to where we expect the next central directory entry or end marker to be. numlumps++; } - free(eName); } - else if (!memcmp(sigBuffer, "\x50\x4b\x05\x06", 4)) // Found the central dir end signature, stop seeking. + // We found the central directory end signature? + else if (!strncmp(curHeader, endPat, 4)) { - CONS_Printf("Found central directory end at position %ld.\n", handlePos); + CONS_Printf("Central directory end signature found at: %ld\n", ftell(handle)); + + // We will create a "virtual" marker lump at the very end of lumpinfo for convenience. + // This marker will be used by the different lump-seeking (eg. textures, sprites, etc.) in PK3-specific cases in an auxiliary way. + lumpinfo = (lumpinfo_t*) Z_Realloc(lumpinfo, (numlumps + 1)*sizeof(*lumpinfo), PU_STATIC, NULL); + strcpy(lumpinfo[numlumps].name, "PK3_ENDM\0"); + lumpinfo[numlumps].name2 = Z_Malloc(14 * sizeof(char), PU_STATIC, NULL); + strcpy(lumpinfo[numlumps].name2, "PK3_ENDMARKER\0"); + lumpinfo[numlumps].position = 0; + lumpinfo[numlumps].size = 0; + lumpinfo[numlumps].disksize = 0; + lumpinfo[numlumps].compression = CM_NONE; + numlumps++; break; } - fseek(handle, -3, SEEK_CUR); + // ... None of them? We're only expecting either a central directory signature entry or the central directory end signature. + // The file may be broken or incomplete... + else + { + CONS_Alert(CONS_WARNING, "Expected central directory header signature, got something else!"); + return INT16_MAX; + } } - // We reached way past beyond the file size. - // This means we couldn't find the central directory end signature, and thus the file might be broken. - if (handlePos + 3 == size) - { - CONS_Alert(CONS_ERROR, "No central dir end inside PK3! File may be corrupted or incomplete.\n"); - free(sigBuffer); - return INT16_MAX; - } - // If we've reached this far, then it means our dynamically stored lumpinfo has to be ready. // Now we finally build our... incorrectly called wadfile. // TODO: Maybe we should give them more generalized names, like resourcefile or resfile or something. // Mostly for clarity and better understanding when reading the code. - free(sigBuffer); } // assume wad file else @@ -581,13 +633,11 @@ UINT16 W_LoadWadFile(const char *filename) if (realsize != 0) { lump_p->size = realsize; - lump_p->compressed = 1; lump_p->compression = CM_LZF; } else { lump_p->size -= 4; - lump_p->compressed = 0; lump_p->compression = CM_NONE; } @@ -596,7 +646,6 @@ UINT16 W_LoadWadFile(const char *filename) } else { - lump_p->compressed = 0; lump_p->compression = CM_NONE; } memset(lump_p->name, 0x00, 9); @@ -609,24 +658,6 @@ UINT16 W_LoadWadFile(const char *filename) free(fileinfov); } -#ifndef NOMD5 - // - // w-waiiiit! - // Let's not add a wad file if the MD5 matches - // an MD5 of an already added WAD file! - // - W_MakeFileMD5(filename, md5sum); - - for (i = 0; i < numwadfiles; i++) - { - if (!memcmp(wadfiles[i]->md5sum, md5sum, 16)) - { - CONS_Alert(CONS_ERROR, M_GetText("%s is already loaded\n"), filename); - return INT16_MAX; - } - } -#endif - // // link wad file to search files // @@ -797,6 +828,41 @@ UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump) return INT16_MAX; } +// In a PK3 type of resource file, it looks for the next lumpinfo entry that doesn't share the specified pathfile. +// Useful for finding folder ends. +// Returns the position of the lumpinfo entry. +UINT16 W_CheckNumForFolderEndPK3(const char *name, UINT16 wad, UINT16 startlump) +{ + INT32 i; + lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump; + for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++) + { + if (strnicmp(name, lump_p->name2, strlen(name))) + break; + } + // Not found at all? + CONS_Printf("W_CheckNumForFolderEndPK3: Folder %s end at %d.\n", name, i); + return i; +} + +// In a PK3 type of resource file, it looks for +// Returns lump position in PK3's lumpinfo, or INT16_MAX if not found. +UINT16 W_CheckNumForFullNamePK3(const char *name, UINT16 wad, UINT16 startlump) +{ + INT32 i; + lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump; + for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++) + { + if (!strnicmp(name, lump_p->name2, strlen(name))) + { + CONS_Printf("W_CheckNumForNamePK3: Found %s at %d.\n", name, i); + return i; + } + } + // Not found at all? + return INT16_MAX; +} + // // W_CheckNumForName // Returns LUMPERROR if name not found. @@ -1010,7 +1076,7 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si size = lumpsize - offset; // - switch(wadfiles[wad]->lumpinfo[lump].compressed) + switch(wadfiles[wad]->lumpinfo[lump].compression) { case CM_LZF: { diff --git a/src/w_wad.h b/src/w_wad.h index c69c2e626..1ddcd5a55 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -35,7 +35,7 @@ typedef struct } wadinfo_t; // Available compression methods for lumps. -enum compmethod{CM_NONE, CM_LZF}; +enum compmethod{CM_NONE, CM_DEFLATE, CM_LZF}; // a memory entry of the wad directory typedef struct @@ -107,6 +107,10 @@ const char *W_CheckNameForNumPwad(UINT16 wad, UINT16 lump); const char *W_CheckNameForNum(lumpnum_t lumpnum); UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump); // checks only in one pwad + +UINT16 W_CheckNumForFullNamePK3(const char *name, UINT16 wad, UINT16 startlump); +UINT16 W_CheckNumForFolderEndPK3(const char *name, UINT16 wad, UINT16 startlump); + lumpnum_t W_CheckNumForName(const char *name); lumpnum_t W_GetNumForName(const char *name); // like W_CheckNumForName but I_Error on LUMPERROR lumpnum_t W_CheckNumForNameInBlock(const char *name, const char *blockstart, const char *blockend); From 65b89f6c0f046b91a9abc9e807e205f3c6949313 Mon Sep 17 00:00:00 2001 From: Nevur Date: Mon, 1 May 2017 16:43:52 +0200 Subject: [PATCH 05/35] Oops. It should compile now. --- src/w_wad.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/w_wad.c b/src/w_wad.c index 4645e87d5..c9d4d6534 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -509,7 +509,7 @@ UINT16 W_LoadWadFile(const char *filename) break; } } - memset(lumpinfo[numlumps].name, '\0', 9) + memset(lumpinfo[numlumps].name, '\0', 9); strncpy(lumpinfo[numlumps].name, eName + namePos, 8); lumpinfo[numlumps].name2 = Z_Malloc((eNameLen+1)*sizeof(char), PU_STATIC, NULL); From 146c7485f5ab3c6e033453200d8225316a0acd07 Mon Sep 17 00:00:00 2001 From: Nevur Date: Mon, 1 May 2017 16:59:59 +0200 Subject: [PATCH 06/35] Cleaned up a little bit of unused code. --- src/w_wad.c | 90 +++++++++++++++++++++++++---------------------------- 1 file changed, 42 insertions(+), 48 deletions(-) diff --git a/src/w_wad.c b/src/w_wad.c index 4645e87d5..96fae8927 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -466,6 +466,7 @@ UINT16 W_LoadWadFile(const char *filename) unsigned int eSize = 0; unsigned int eCompSize = 0; unsigned int eLocalHeaderOffset = 0; + int namePos; // We get the compression type indicator value. fseek(handle, 6, SEEK_CUR); @@ -481,61 +482,54 @@ UINT16 W_LoadWadFile(const char *filename) fseek(handle, 8, SEEK_CUR); fread(&eLocalHeaderOffset, 1, 4, handle); // Get the offset. + if (numlumps == 0) // First lump? Let's allocate the first lumpinfo block. + lumpinfo = Z_Malloc(sizeof(*lumpinfo), PU_STATIC, NULL); + else // Otherwise, reallocate and increase by 1. Might not be optimal, though... + lumpinfo = (lumpinfo_t*) Z_Realloc(lumpinfo, (numlumps + 1)*sizeof(*lumpinfo), PU_STATIC, NULL); + eName = malloc(sizeof(char)*(eNameLen + 1)); fgets(eName, eNameLen + 1, handle); - if (0)//(eSize == 0) // Is this entry a folder? + namePos = eNameLen - 1; + lumpinfo[numlumps].position = eLocalHeaderOffset + 30 + eNameLen + eXFieldLen; + lumpinfo[numlumps].disksize = eCompSize; + lumpinfo[numlumps].size = eSize; + CONS_Printf("File %s at: %ld\n", eName, ftell(handle)); + CONS_Printf("Address: %ld, Full: %ld, Comp: %ld\n", lumpinfo[numlumps].position, lumpinfo[numlumps].size, lumpinfo[numlumps].disksize); + // We will trim the file's full name so that only the filename is left. + while(namePos--) { - CONS_Printf("Folder %s at %ld:\n", eName, ftell(handle)); - } - else // If not, then it is a normal file. Let's arrange its lumpinfo structure then! - { - int namePos = eNameLen - 1; - CONS_Printf("File %s at: %ld\n", eName, ftell(handle)); - if (numlumps == 0) // First lump? Let's allocate the first lumpinfo block. - lumpinfo = Z_Malloc(sizeof(*lumpinfo), PU_STATIC, NULL); - else // Otherwise, reallocate and increase by 1. Might not be optimal, though... - lumpinfo = (lumpinfo_t*) Z_Realloc(lumpinfo, (numlumps + 1)*sizeof(*lumpinfo), PU_STATIC, NULL); - - lumpinfo[numlumps].position = eLocalHeaderOffset + 30 + eNameLen + eXFieldLen; - lumpinfo[numlumps].disksize = eCompSize; - lumpinfo[numlumps].size = eSize; - CONS_Printf("Address: %ld, Full: %ld, Comp: %ld\n", lumpinfo[numlumps].position, lumpinfo[numlumps].size, lumpinfo[numlumps].disksize); - // We will trim the file's full name so that only the filename is left. - while(namePos--) + if(eName[namePos] == '/') { - if(eName[namePos] == '/') - { - namePos++; - break; - } - } - memset(lumpinfo[numlumps].name, '\0', 9) - strncpy(lumpinfo[numlumps].name, eName + namePos, 8); - - lumpinfo[numlumps].name2 = Z_Malloc((eNameLen+1)*sizeof(char), PU_STATIC, NULL); - strncpy(lumpinfo[numlumps].name2, eName, eNameLen); - lumpinfo[numlumps].name2[eNameLen] = '\0'; - - // We set the compression type from what we're supporting so far. - switch(eCompression) - { - case 0: - lumpinfo[numlumps].compression = CM_NONE; - break; - case 8: - lumpinfo[numlumps].compression = CM_DEFLATE; - break; - case 14: - lumpinfo[numlumps].compression = CM_LZF; - break; - default: - CONS_Alert(CONS_WARNING, "Lump has an unsupported compression type!\n"); - lumpinfo[numlumps].compression = CM_NONE; + namePos++; break; } - fseek(handle, eXFieldLen + eCommentLen, SEEK_CUR); // We skip to where we expect the next central directory entry or end marker to be. - numlumps++; } + memset(lumpinfo[numlumps].name, '\0', 9); + strncpy(lumpinfo[numlumps].name, eName + namePos, 8); + + lumpinfo[numlumps].name2 = Z_Malloc((eNameLen+1)*sizeof(char), PU_STATIC, NULL); + strncpy(lumpinfo[numlumps].name2, eName, eNameLen); + lumpinfo[numlumps].name2[eNameLen] = '\0'; + + // We set the compression type from what we're supporting so far. + switch(eCompression) + { + case 0: + lumpinfo[numlumps].compression = CM_NONE; + break; + case 8: + lumpinfo[numlumps].compression = CM_DEFLATE; + break; + case 14: + lumpinfo[numlumps].compression = CM_LZF; + break; + default: + CONS_Alert(CONS_WARNING, "Lump has an unsupported compression type!\n"); + lumpinfo[numlumps].compression = CM_NONE; + break; + } + fseek(handle, eXFieldLen + eCommentLen, SEEK_CUR); // We skip to where we expect the next central directory entry or end marker to be. + numlumps++; free(eName); } // We found the central directory end signature? From 8f2025ab5fb026a401bd6a3c65407fd0e32983fb Mon Sep 17 00:00:00 2001 From: Nevur Date: Mon, 1 May 2017 18:30:20 +0200 Subject: [PATCH 07/35] dsa --- src/w_wad.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/w_wad.c b/src/w_wad.c index 96fae8927..72e63f2f4 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -459,6 +459,7 @@ UINT16 W_LoadWadFile(const char *filename) // Let's fill in the fields that we actually need. // (Declaring all those vars might not be the optimal way to do this, sorry.) char *eName; + int namePos; unsigned short int eNameLen = 8; unsigned short int eXFieldLen = 0; unsigned short int eCommentLen = 0; @@ -466,7 +467,6 @@ UINT16 W_LoadWadFile(const char *filename) unsigned int eSize = 0; unsigned int eCompSize = 0; unsigned int eLocalHeaderOffset = 0; - int namePos; // We get the compression type indicator value. fseek(handle, 6, SEEK_CUR); @@ -482,20 +482,20 @@ UINT16 W_LoadWadFile(const char *filename) fseek(handle, 8, SEEK_CUR); fread(&eLocalHeaderOffset, 1, 4, handle); // Get the offset. + eName = malloc(sizeof(char)*(eNameLen + 1)); + fgets(eName, eNameLen + 1, handle); + CONS_Printf("File %s at: %ld\n", eName, ftell(handle)); if (numlumps == 0) // First lump? Let's allocate the first lumpinfo block. lumpinfo = Z_Malloc(sizeof(*lumpinfo), PU_STATIC, NULL); else // Otherwise, reallocate and increase by 1. Might not be optimal, though... lumpinfo = (lumpinfo_t*) Z_Realloc(lumpinfo, (numlumps + 1)*sizeof(*lumpinfo), PU_STATIC, NULL); - eName = malloc(sizeof(char)*(eNameLen + 1)); - fgets(eName, eNameLen + 1, handle); - namePos = eNameLen - 1; lumpinfo[numlumps].position = eLocalHeaderOffset + 30 + eNameLen + eXFieldLen; lumpinfo[numlumps].disksize = eCompSize; lumpinfo[numlumps].size = eSize; - CONS_Printf("File %s at: %ld\n", eName, ftell(handle)); CONS_Printf("Address: %ld, Full: %ld, Comp: %ld\n", lumpinfo[numlumps].position, lumpinfo[numlumps].size, lumpinfo[numlumps].disksize); // We will trim the file's full name so that only the filename is left. + namePos = eNameLen - 1; while(namePos--) { if(eName[namePos] == '/') @@ -839,7 +839,7 @@ UINT16 W_CheckNumForFolderEndPK3(const char *name, UINT16 wad, UINT16 startlump) return i; } -// In a PK3 type of resource file, it looks for +// In a PK3 type of resource file, it looks for an entry with the specified full name. // Returns lump position in PK3's lumpinfo, or INT16_MAX if not found. UINT16 W_CheckNumForFullNamePK3(const char *name, UINT16 wad, UINT16 startlump) { From e125dedbe9271e0f705ae9e4c798d567b073b4d9 Mon Sep 17 00:00:00 2001 From: Nevur Date: Mon, 1 May 2017 18:33:41 +0200 Subject: [PATCH 08/35] sdad --- src/w_wad.c | 92 +++++++++++++++++++++++++---------------------------- 1 file changed, 43 insertions(+), 49 deletions(-) diff --git a/src/w_wad.c b/src/w_wad.c index c9d4d6534..72e63f2f4 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -459,6 +459,7 @@ UINT16 W_LoadWadFile(const char *filename) // Let's fill in the fields that we actually need. // (Declaring all those vars might not be the optimal way to do this, sorry.) char *eName; + int namePos; unsigned short int eNameLen = 8; unsigned short int eXFieldLen = 0; unsigned short int eCommentLen = 0; @@ -483,59 +484,52 @@ UINT16 W_LoadWadFile(const char *filename) eName = malloc(sizeof(char)*(eNameLen + 1)); fgets(eName, eNameLen + 1, handle); - if (0)//(eSize == 0) // Is this entry a folder? + CONS_Printf("File %s at: %ld\n", eName, ftell(handle)); + if (numlumps == 0) // First lump? Let's allocate the first lumpinfo block. + lumpinfo = Z_Malloc(sizeof(*lumpinfo), PU_STATIC, NULL); + else // Otherwise, reallocate and increase by 1. Might not be optimal, though... + lumpinfo = (lumpinfo_t*) Z_Realloc(lumpinfo, (numlumps + 1)*sizeof(*lumpinfo), PU_STATIC, NULL); + + lumpinfo[numlumps].position = eLocalHeaderOffset + 30 + eNameLen + eXFieldLen; + lumpinfo[numlumps].disksize = eCompSize; + lumpinfo[numlumps].size = eSize; + CONS_Printf("Address: %ld, Full: %ld, Comp: %ld\n", lumpinfo[numlumps].position, lumpinfo[numlumps].size, lumpinfo[numlumps].disksize); + // We will trim the file's full name so that only the filename is left. + namePos = eNameLen - 1; + while(namePos--) { - CONS_Printf("Folder %s at %ld:\n", eName, ftell(handle)); - } - else // If not, then it is a normal file. Let's arrange its lumpinfo structure then! - { - int namePos = eNameLen - 1; - CONS_Printf("File %s at: %ld\n", eName, ftell(handle)); - if (numlumps == 0) // First lump? Let's allocate the first lumpinfo block. - lumpinfo = Z_Malloc(sizeof(*lumpinfo), PU_STATIC, NULL); - else // Otherwise, reallocate and increase by 1. Might not be optimal, though... - lumpinfo = (lumpinfo_t*) Z_Realloc(lumpinfo, (numlumps + 1)*sizeof(*lumpinfo), PU_STATIC, NULL); - - lumpinfo[numlumps].position = eLocalHeaderOffset + 30 + eNameLen + eXFieldLen; - lumpinfo[numlumps].disksize = eCompSize; - lumpinfo[numlumps].size = eSize; - CONS_Printf("Address: %ld, Full: %ld, Comp: %ld\n", lumpinfo[numlumps].position, lumpinfo[numlumps].size, lumpinfo[numlumps].disksize); - // We will trim the file's full name so that only the filename is left. - while(namePos--) + if(eName[namePos] == '/') { - if(eName[namePos] == '/') - { - namePos++; - break; - } - } - memset(lumpinfo[numlumps].name, '\0', 9); - strncpy(lumpinfo[numlumps].name, eName + namePos, 8); - - lumpinfo[numlumps].name2 = Z_Malloc((eNameLen+1)*sizeof(char), PU_STATIC, NULL); - strncpy(lumpinfo[numlumps].name2, eName, eNameLen); - lumpinfo[numlumps].name2[eNameLen] = '\0'; - - // We set the compression type from what we're supporting so far. - switch(eCompression) - { - case 0: - lumpinfo[numlumps].compression = CM_NONE; - break; - case 8: - lumpinfo[numlumps].compression = CM_DEFLATE; - break; - case 14: - lumpinfo[numlumps].compression = CM_LZF; - break; - default: - CONS_Alert(CONS_WARNING, "Lump has an unsupported compression type!\n"); - lumpinfo[numlumps].compression = CM_NONE; + namePos++; break; } - fseek(handle, eXFieldLen + eCommentLen, SEEK_CUR); // We skip to where we expect the next central directory entry or end marker to be. - numlumps++; } + memset(lumpinfo[numlumps].name, '\0', 9); + strncpy(lumpinfo[numlumps].name, eName + namePos, 8); + + lumpinfo[numlumps].name2 = Z_Malloc((eNameLen+1)*sizeof(char), PU_STATIC, NULL); + strncpy(lumpinfo[numlumps].name2, eName, eNameLen); + lumpinfo[numlumps].name2[eNameLen] = '\0'; + + // We set the compression type from what we're supporting so far. + switch(eCompression) + { + case 0: + lumpinfo[numlumps].compression = CM_NONE; + break; + case 8: + lumpinfo[numlumps].compression = CM_DEFLATE; + break; + case 14: + lumpinfo[numlumps].compression = CM_LZF; + break; + default: + CONS_Alert(CONS_WARNING, "Lump has an unsupported compression type!\n"); + lumpinfo[numlumps].compression = CM_NONE; + break; + } + fseek(handle, eXFieldLen + eCommentLen, SEEK_CUR); // We skip to where we expect the next central directory entry or end marker to be. + numlumps++; free(eName); } // We found the central directory end signature? @@ -845,7 +839,7 @@ UINT16 W_CheckNumForFolderEndPK3(const char *name, UINT16 wad, UINT16 startlump) return i; } -// In a PK3 type of resource file, it looks for +// In a PK3 type of resource file, it looks for an entry with the specified full name. // Returns lump position in PK3's lumpinfo, or INT16_MAX if not found. UINT16 W_CheckNumForFullNamePK3(const char *name, UINT16 wad, UINT16 startlump) { From 1b881afb99738626a9358a5dae82348512c0e542 Mon Sep 17 00:00:00 2001 From: Nevur Date: Mon, 1 May 2017 19:16:30 +0200 Subject: [PATCH 09/35] Remember when I said I'd stop for today? I lied. -Lumps are loaded fine now. Essentially non-compressed PK3s are supported now. --- src/w_wad.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/w_wad.c b/src/w_wad.c index 72e63f2f4..661e5acc3 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -462,11 +462,14 @@ UINT16 W_LoadWadFile(const char *filename) int namePos; unsigned short int eNameLen = 8; unsigned short int eXFieldLen = 0; + unsigned short int lNameLen = 0; + unsigned short int lXFieldLen = 0; unsigned short int eCommentLen = 0; unsigned short int eCompression = 0; unsigned int eSize = 0; unsigned int eCompSize = 0; unsigned int eLocalHeaderOffset = 0; + unsigned long int rememberPos = 0; // We get the compression type indicator value. fseek(handle, 6, SEEK_CUR); @@ -490,7 +493,15 @@ UINT16 W_LoadWadFile(const char *filename) else // Otherwise, reallocate and increase by 1. Might not be optimal, though... lumpinfo = (lumpinfo_t*) Z_Realloc(lumpinfo, (numlumps + 1)*sizeof(*lumpinfo), PU_STATIC, NULL); - lumpinfo[numlumps].position = eLocalHeaderOffset + 30 + eNameLen + eXFieldLen; + // We must calculate the position for the actual data. + // Why not eLocalHeaderOffset + 30 + eNameLen + eXFieldLen? That's because the extra field and name lengths MAY be different in the local headers. + rememberPos = ftell(handle); + fseek(handle, eLocalHeaderOffset + 26, SEEK_SET); + fread(&lNameLen, 1, 2, handle); + fread(&lXFieldLen, 1, 2, handle); + lumpinfo[numlumps].position = ftell(handle) + lNameLen + lXFieldLen; + + fseek(handle, rememberPos, SEEK_SET); // Let's go back to the central dir. lumpinfo[numlumps].disksize = eCompSize; lumpinfo[numlumps].size = eSize; CONS_Printf("Address: %ld, Full: %ld, Comp: %ld\n", lumpinfo[numlumps].position, lumpinfo[numlumps].size, lumpinfo[numlumps].disksize); From 9246ab84290291c90fc0dc2b00d6b5eb36d66ec8 Mon Sep 17 00:00:00 2001 From: Nevur Date: Tue, 2 May 2017 15:40:31 +0200 Subject: [PATCH 10/35] Tweaked lump reading functionality. -Removed functions exclusively used by W_ReadLumpHeaderPwad. -Merged those functions into the main one, optimized the structure. --- src/w_wad.c | 128 ++++++++++++++++++++-------------------------------- 1 file changed, 49 insertions(+), 79 deletions(-) diff --git a/src/w_wad.c b/src/w_wad.c index 661e5acc3..f1057d7b4 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -983,80 +983,10 @@ size_t W_LumpLength(lumpnum_t lumpnum) return W_LumpLengthPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum)); } -/** Reads bytes from the head of a lump, without doing decompression. - * - * \param wad Wad number to read from. - * \param lump Lump number to read from, within wad. - * \param dest Buffer in memory to serve as destination. - * \param size Number of bytes to read. - * \param offest Number of bytes to offset. - * \return Number of bytes read (should equal size). - * \sa W_ReadLumpHeader - */ -static size_t W_RawReadLumpHeader(UINT16 wad, UINT16 lump, void *dest, size_t size, size_t offset) -{ - size_t bytesread; - lumpinfo_t *l; - FILE *handle; - - l = wadfiles[wad]->lumpinfo + lump; - - handle = wadfiles[wad]->handle; - - fseek(handle, (long)(l->position + offset), SEEK_SET); - bytesread = fread(dest, 1, size, handle); - - return bytesread; -} - -// Read a compressed lump; return it in newly Z_Malloc'd memory. -// wad is number of wad file, lump is number of lump in wad. -static void *W_ReadCompressedLump(UINT16 wad, UINT16 lump) -{ -#ifdef ZWAD - char *compressed, *data; - const lumpinfo_t *l = &wadfiles[wad]->lumpinfo[lump]; - size_t retval; - - compressed = Z_Malloc(l->disksize, PU_STATIC, NULL); - data = Z_Malloc(l->size, PU_STATIC, NULL); - if (W_RawReadLumpHeader(wad, lump, compressed, l->disksize, 0) - < l->disksize) - { - I_Error("wad %d, lump %d: cannot read compressed data", - wad, lump); - } - - retval = lzf_decompress(compressed, l->disksize, data, l->size); -#ifndef AVOID_ERRNO - if (retval == 0 && errno == E2BIG) - { - I_Error("wad %d, lump %d: compressed data too big " - "(bigger than %s)", wad, lump, sizeu1(l->size)); - } - else if (retval == 0 && errno == EINVAL) - I_Error("wad %d, lump %d: invalid compressed data", wad, lump); - else -#endif - if (retval != l->size) - { - I_Error("wad %d, lump %d: decompressed to wrong number of " - "bytes (expected %s, got %s)", wad, lump, - sizeu1(l->size), sizeu2(retval)); - } - Z_Free(compressed); - return data; -#else - (void)wad; - (void)lump; - //I_Error("ZWAD files not supported on this platform."); - return NULL; -#endif -} - /** Reads bytes from the head of a lump. * Note: If the lump is compressed, the whole thing has to be read anyway. * + * \param wad Wad number to read from. * \param lump Lump number to read from. * \param dest Buffer in memory to serve as destination. * \param size Number of bytes to read. @@ -1067,6 +997,9 @@ static void *W_ReadCompressedLump(UINT16 wad, UINT16 lump) size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, size_t offset) { size_t lumpsize; + size_t bytesread; + lumpinfo_t *l; + FILE *handle; if (!TestValidLump(wad,lump)) return 0; @@ -1080,20 +1013,57 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si if (!size || size+offset > lumpsize) size = lumpsize - offset; - // + // Let's get the raw lump data. + // We setup the desired file handle to read the lump data. + l = wadfiles[wad]->lumpinfo + lump; + handle = wadfiles[wad]->handle; + fseek(handle, (long)(l->position + offset), SEEK_SET); + switch(wadfiles[wad]->lumpinfo[lump].compression) { - case CM_LZF: + case CM_NONE: // If it's uncompressed, we directly write the data into our destination, and return the bytes read. + return fread(dest, 1, size, handle); + case CM_LZF: // Is it LZF compressed? { - UINT8 *data; - data = W_ReadCompressedLump(wad, lump); - if (!data) return 0; - M_Memcpy(dest, data+offset, size); - Z_Free(data); +#ifdef ZWAD + char *rawData; // The lump's raw data. + char *decData; // Lump's decompressed real data. + size_t retval; // Helper var, lzf_decompress 0 when an error occurs. + + rawData = Z_Malloc(l->disksize, PU_STATIC, NULL); + decData = Z_Malloc(l->size, PU_STATIC, NULL); + + if (fread(rawData, 1, l->disksize, handle) < l->disksize) + I_Error("wad %d, lump %d: cannot read compressed data", wad, lump); + retval = lzf_decompress(rawData, l->disksize, decData, l->size); +#ifndef AVOID_ERRNO + if (retval == 0 && errno == E2BIG) // errno is a global var set by the lzf functions when something goes wrong. + { + I_Error("wad %d, lump %d: compressed data too big (bigger than %s)", wad, lump, sizeu1(l->size)); + } + else if (retval == 0 && errno == EINVAL) + I_Error("wad %d, lump %d: invalid compressed data", wad, lump); + else +#endif + if (retval != l->size) + { + I_Error("wad %d, lump %d: decompressed to wrong number of bytes (expected %s, got %s)", wad, lump, sizeu1(l->size), sizeu2(retval)); + } +#else + (void)wad; + (void)lump; + //I_Error("ZWAD files not supported on this platform."); + return NULL; +#endif + if (!decData) // Did we get no data at all? + return 0; + M_Memcpy(dest, decData + offset, size); + Z_Free(rawData); + Z_Free(decData); return size; } default: - return W_RawReadLumpHeader(wad, lump, dest, size, offset); + return fread(dest, 1, size, handle); } } From 0c73dae57d13c7a946ec59ae2783793e302581ac Mon Sep 17 00:00:00 2001 From: Nevur Date: Tue, 2 May 2017 18:04:16 +0200 Subject: [PATCH 11/35] Submitted changes so far. Deflate doesn't work yet, apparently. --- src/w_wad.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 64 insertions(+), 5 deletions(-) diff --git a/src/w_wad.c b/src/w_wad.c index f1057d7b4..59e9a7210 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -25,6 +25,9 @@ #endif #include "lzf.h" #endif +//#ifdef HAVE_ZLIB +#include "zlib.h" +//#endif // HAVE_ZLIB #include "doomdef.h" #include "doomstat.h" @@ -504,7 +507,6 @@ UINT16 W_LoadWadFile(const char *filename) fseek(handle, rememberPos, SEEK_SET); // Let's go back to the central dir. lumpinfo[numlumps].disksize = eCompSize; lumpinfo[numlumps].size = eSize; - CONS_Printf("Address: %ld, Full: %ld, Comp: %ld\n", lumpinfo[numlumps].position, lumpinfo[numlumps].size, lumpinfo[numlumps].disksize); // We will trim the file's full name so that only the filename is left. namePos = eNameLen - 1; while(namePos--) @@ -997,7 +999,6 @@ size_t W_LumpLength(lumpnum_t lumpnum) size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, size_t offset) { size_t lumpsize; - size_t bytesread; lumpinfo_t *l; FILE *handle; @@ -1019,16 +1020,17 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si handle = wadfiles[wad]->handle; fseek(handle, (long)(l->position + offset), SEEK_SET); + // But let's not copy it yet. We support different compression formats on lumps, so we need to take that into account. switch(wadfiles[wad]->lumpinfo[lump].compression) { case CM_NONE: // If it's uncompressed, we directly write the data into our destination, and return the bytes read. return fread(dest, 1, size, handle); - case CM_LZF: // Is it LZF compressed? + case CM_LZF: // Is it LZF compressed? Used by ZWADs. { #ifdef ZWAD char *rawData; // The lump's raw data. char *decData; // Lump's decompressed real data. - size_t retval; // Helper var, lzf_decompress 0 when an error occurs. + size_t retval; // Helper var, lzf_decompress returns 0 when an error occurs. rawData = Z_Malloc(l->disksize, PU_STATIC, NULL); decData = Z_Malloc(l->size, PU_STATIC, NULL); @@ -1062,8 +1064,65 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si Z_Free(decData); return size; } + case CM_DEFLATE: // Is it compressed via DEFLATE? Very common in ZIPs/PK3s, also what most doom-related editors support. + { + int ret; + unsigned have; + z_stream strm; + unsigned char in[16384]; + unsigned char out[16384]; + + /* allocate inflate state */ + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = inflateInit(&strm); + if (ret != Z_OK) + return ret; + + /* decompress until deflate stream ends or end of file */ + do { + strm.avail_in = fread(in, 1, 16384, handle); + if (ferror(handle)) { + (void)inflateEnd(&strm); + return Z_ERRNO; + } + if (strm.avail_in == 0) + break; + strm.next_in = in; + + /* run inflate() on input until output buffer not full */ + do { + + strm.avail_out = 16384; + strm.next_out = out; + + ret = inflate(&strm, Z_NO_FLUSH); + //assert(ret != Z_STREAM_ERROR); /* state not clobbered */ + switch (ret) { + case Z_NEED_DICT: + ret = Z_DATA_ERROR; /* and fall through */ + case Z_DATA_ERROR: + case Z_MEM_ERROR: + (void)inflateEnd(&strm); + return ret; + } + + have = 16384 - strm.avail_out; + memcpy(dest, out, have); + } while (strm.avail_out == 0); + + /* done when inflate() says it's done */ + } while (ret != Z_STREAM_END); + + /* clean up and return */ + (void)inflateEnd(&strm); + return size; + } default: - return fread(dest, 1, size, handle); + return 0; } } From b60010f0f1a8bd439c1f538859308a2ce9f9ff63 Mon Sep 17 00:00:00 2001 From: Nevur Date: Tue, 2 May 2017 19:20:29 +0200 Subject: [PATCH 12/35] Tweaked so that it spits out an error for unsupported compression formats. --- src/w_wad.c | 4 ++-- src/w_wad.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/w_wad.c b/src/w_wad.c index 59e9a7210..2d717d12a 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -538,7 +538,7 @@ UINT16 W_LoadWadFile(const char *filename) break; default: CONS_Alert(CONS_WARNING, "Lump has an unsupported compression type!\n"); - lumpinfo[numlumps].compression = CM_NONE; + lumpinfo[numlumps].compression = CM_UNSUPPORTED; break; } fseek(handle, eXFieldLen + eCommentLen, SEEK_CUR); // We skip to where we expect the next central directory entry or end marker to be. @@ -1122,7 +1122,7 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si return size; } default: - return 0; + I_Error("wad %d, lump %d: unsupported compression type!", wad, lump); } } diff --git a/src/w_wad.h b/src/w_wad.h index 1ddcd5a55..35d060279 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -35,7 +35,7 @@ typedef struct } wadinfo_t; // Available compression methods for lumps. -enum compmethod{CM_NONE, CM_DEFLATE, CM_LZF}; +enum compmethod{CM_NONE, CM_DEFLATE, CM_LZF, CM_UNSUPPORTED}; // a memory entry of the wad directory typedef struct From 8ef6d6fd9e518b18619a7e31a69d973472f6714a Mon Sep 17 00:00:00 2001 From: Nevur Date: Sat, 6 May 2017 16:52:53 +0200 Subject: [PATCH 13/35] A bit more work on PK3. -Expanded folder recognition for PK3s. Some resources are still not loaded from them yet. -Took a glimpse at how maps are loaded, since the flat recognition is rooted somewhere there; did nothing yet about it though. -Working towards "generalizing" how new resources are handled. Some var and functionality redundancy is still present. --- src/p_setup.c | 205 +++++++++++++++++++++++++++++++++++++------------ src/r_data.c | 8 +- src/r_things.c | 32 ++++++++ src/r_things.h | 2 + src/w_wad.c | 5 +- src/w_wad.h | 2 + 6 files changed, 200 insertions(+), 54 deletions(-) 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); From ea2846394e87c9f89bb613dc63f7056bbabdf1de Mon Sep 17 00:00:00 2001 From: Nevur Date: Sun, 7 May 2017 12:30:06 +0200 Subject: [PATCH 14/35] More PK3 work. Now we're getting somewhere. -DEFLATE-compressed lumps work properly now. -All "big" lumps are supported now with the exception of WAD maps. Notes: -Compiler spits out a shitload of warnings still. -Individual lump reading clashes with folders of the same name (see TEXTURES lump, and the Textures/ folder). Signed-off-by: Nevur --- src/p_setup.c | 8 +-- src/r_data.c | 63 +++++++++++++++++++-- src/w_wad.c | 154 ++++++++++++++++++++++++++++---------------------- src/w_wad.h | 4 +- 4 files changed, 152 insertions(+), 77 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index f82ee5ee2..fcc2ae591 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3105,9 +3105,7 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname) // UINT16 flaPos, flaNum = 0; // UINT16 mapPos, mapNum = 0; - - - if ((numlumps = W_LoadWadFile(wadfilename)) == INT16_MAX) + if ((numlumps = W_InitFile(wadfilename)) == INT16_MAX) { CONS_Printf(M_GetText("Errors occured while loading %s; not added.\n"), wadfilename); return false; @@ -3126,7 +3124,7 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname) { lumpinfo++; *start = ++i; - for (i; i < numlumps; i++, lumpinfo++) + for (; i < numlumps; i++, lumpinfo++) { if (strnicmp(lumpinfo->name2, folName, strlen(folName))) { @@ -3172,6 +3170,8 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname) R_LoadSpritsRange(wadnum, sprPos, sprNum); if (texNum) // Textures. TODO: R_LoadTextures() does the folder positioning once again. New function maybe? R_LoadTextures(); +// if (mapNum) // Maps. TODO: Actually implement the map WAD loading code, lulz. +// P_LoadWadMapRange(); } break; default: diff --git a/src/r_data.c b/src/r_data.c index 3bc93831d..d7ac38974 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -571,13 +571,14 @@ void R_LoadTextures(void) { texstart = W_CheckNumForFullNamePK3("textures/", (UINT16)w, 0) + 1; texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart); + texturesLumpPos = W_CheckNumForFullNamePK3("textures", (UINT16)w, 0); } else { texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0) + 1; texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0); + texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0); } - texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0); if (texturesLumpPos != INT16_MAX) { @@ -1190,12 +1191,64 @@ static void R_InitExtraColormaps(void) CONS_Printf(M_GetText("Number of Extra Colormaps: %s\n"), sizeu1(numcolormaplumps)); } -// 12/14/14 -- only take flats in F_START/F_END +// Search for flat name through all lumpnum_t R_GetFlatNumForName(const char *name) { - lumpnum_t lump = W_CheckNumForNameInBlock(name, "F_START", "F_END"); - if (lump == LUMPERROR) - lump = W_CheckNumForNameInBlock(name, "FF_START", "FF_END"); // deutex, some other old things + INT32 i; + lumpnum_t lump; + lumpnum_t start; + lumpnum_t end; + + // Scan wad files backwards so patched flats take preference. + for (i = numwadfiles - 1; i >= 0; i--) + { + // WAD type? use markers. + if (wadfiles[i]->type == RET_WAD) + { + // Find the ranges to work with. + start = W_CheckNumForNamePwad("F_START", (UINT16)i, 0); + if (start == INT16_MAX) + { + start = W_CheckNumForNamePwad("FF_START", (UINT16)i, 0); + if (start == INT16_MAX) + { + continue; + } + else + { + end = W_CheckNumForNamePwad("FF_END", (UINT16)i, start); + if (end == INT16_MAX) + { + continue; + } + } + } + else + { + end = W_CheckNumForNamePwad("F_END", (UINT16)i, start); + if (end == INT16_MAX) + continue; + } + } + else if (wadfiles[i]->type == RET_PK3) + { + start = W_CheckNumForFullNamePK3("Flats/", i, 0); + if (start == INT16_MAX) + continue; + end = W_CheckNumForFolderEndPK3("Flats/", i, start); + if (end == INT16_MAX) + continue; + } + // Now find lump with specified name in that range. + lump = W_CheckNumForNamePwad(name, (UINT16)i, start); + if (lump < end) + { + lump += (i<<16); // found it, in our constraints + break; + } + lump = LUMPERROR; + } + if (lump == LUMPERROR) { if (strcmp(name, SKYFLATNAME)) diff --git a/src/w_wad.c b/src/w_wad.c index e410e4bde..65f0ee214 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -291,7 +291,7 @@ static void W_InvalidateLumpnumCache(void) // // Can now load dehacked files (.soc) // -UINT16 W_LoadWadFile(const char *filename) +UINT16 W_InitFile(const char *filename) { FILE *handle; lumpinfo_t *lumpinfo; @@ -412,12 +412,11 @@ UINT16 W_LoadWadFile(const char *filename) numlumps = 0; type = RET_PK3; - CONS_Alert(CONS_NOTICE, "PK3 file detected.\n"); // Obtain the file's size. fseek(handle, 0, SEEK_END); size = ftell(handle); - CONS_Printf("PK3 size is: %ld\n", size); + CONS_Debug(DBG_SETUP, "PK3 size is: %ld\n", size); // We must look for the central directory through the file. // All of the central directory entry headers have a signature of 0x50 0x4b 0x01 0x02. @@ -435,7 +434,7 @@ UINT16 W_LoadWadFile(const char *filename) { matched = TRUE; fseek(handle, -4, SEEK_CUR); - CONS_Printf("Found PK3 central directory at position %ld.\n", ftell(handle)); + CONS_Debug(DBG_SETUP, "Found PK3 central directory at position %ld.\n", ftell(handle)); break; } } @@ -451,7 +450,7 @@ UINT16 W_LoadWadFile(const char *filename) // Since we found the central directory, now we can map our lumpinfo table. // We will look for file headers inside it, until we reach the central directory end signature. // We exactly know what data to expect this time, so now we don't need to do a byte-by-byte search. - CONS_Printf("Now finding central directory file headers...\n"); + CONS_Debug(DBG_SETUP, "Now finding central directory file headers...\n"); while(ftell(handle) < size - 4) // Make sure we don't go past the file size! { fread(curHeader, 1, 4, handle); @@ -477,10 +476,10 @@ UINT16 W_LoadWadFile(const char *filename) // We get the compression type indicator value. fseek(handle, 6, SEEK_CUR); fread(&eCompression, 1, 2, handle); - // Get the + // Get the size fseek(handle, 8, SEEK_CUR); - fread(&eSize, 1, 4, handle); fread(&eCompSize, 1, 4, handle); + fread(&eSize, 1, 4, handle); // We get the variable length fields. fread(&eNameLen, 1, 2, handle); fread(&eXFieldLen, 1, 2, handle); @@ -490,7 +489,6 @@ UINT16 W_LoadWadFile(const char *filename) eName = malloc(sizeof(char)*(eNameLen + 1)); fgets(eName, eNameLen + 1, handle); - CONS_Printf("File %s at: %ld\n", eName, ftell(handle)); if (numlumps == 0) // First lump? Let's allocate the first lumpinfo block. lumpinfo = Z_Malloc(sizeof(*lumpinfo), PU_STATIC, NULL); else // Otherwise, reallocate and increase by 1. Might not be optimal, though... @@ -541,6 +539,7 @@ UINT16 W_LoadWadFile(const char *filename) lumpinfo[numlumps].compression = CM_UNSUPPORTED; break; } + CONS_Debug(DBG_SETUP, "File %s, data begins at: %ld\n", eName, lumpinfo[numlumps].position); fseek(handle, eXFieldLen + eCommentLen, SEEK_CUR); // We skip to where we expect the next central directory entry or end marker to be. numlumps++; free(eName); @@ -548,7 +547,7 @@ UINT16 W_LoadWadFile(const char *filename) // We found the central directory end signature? else if (!strncmp(curHeader, endPat, 4)) { - CONS_Printf("Central directory end signature found at: %ld\n", ftell(handle)); + CONS_Debug(DBG_SETUP, "Central directory end signature found at: %ld\n", ftell(handle)); // We will create a "virtual" marker lump at the very end of lumpinfo for convenience. // This marker will be used by the different lump-seeking (eg. textures, sprites, etc.) in PK3-specific cases in an auxiliary way. @@ -760,7 +759,7 @@ INT32 W_InitMultipleFiles(char **filenames) for (; *filenames; filenames++) { //CONS_Debug(DBG_SETUP, "Loading %s\n", *filenames); - rc &= (W_LoadWadFile(*filenames) != INT16_MAX) ? 1 : 0; + rc &= (W_InitFile(*filenames) != INT16_MAX) ? 1 : 0; } if (!numwadfiles) @@ -850,8 +849,6 @@ UINT16 W_CheckNumForFolderEndPK3(const char *name, UINT16 wad, UINT16 startlump) if (strnicmp(name, lump_p->name2, strlen(name))) break; } - // Not found at all? - CONS_Printf("W_CheckNumForFolderEndPK3: Folder %s end at %d.\n", name, i); return i; } @@ -865,7 +862,6 @@ UINT16 W_CheckNumForFullNamePK3(const char *name, UINT16 wad, UINT16 startlump) { if (!strnicmp(name, lump_p->name2, strlen(name))) { - CONS_Printf("W_CheckNumForNamePK3: Found %s at %d.\n", name, i); return i; } } @@ -943,15 +939,20 @@ lumpnum_t W_CheckNumForNameInBlock(const char *name, const char *blockstart, con // scan wad files backwards so patch lump files take precedence for (i = numwadfiles - 1; i >= 0; i--) { - bsid = W_CheckNumForNamePwad(blockstart,(UINT16)i,0); - if (bsid == INT16_MAX) - continue; // block doesn't exist, keep going - beid = W_CheckNumForNamePwad(blockend,(UINT16)i,0); - // if block end doesn't exist, just search through everything + if (wadfiles[i]->type == RET_WAD) + { + bsid = W_CheckNumForNamePwad(blockstart, (UINT16)i, 0); + if (bsid == INT16_MAX) + continue; // Start block doesn't exist? + beid = W_CheckNumForNamePwad(blockend, (UINT16)i, 0); + if (beid == INT16_MAX) + continue; // End block doesn't exist? + + check = W_CheckNumForNamePwad(name, (UINT16)i, bsid); + if (check < beid) + return (i<<16)+check; // found it, in our constraints + } - check = W_CheckNumForNamePwad(name,(UINT16)i,bsid); - if (check < beid) - return (i<<16)+check; // found it, in our constraints } return LUMPERROR; } @@ -988,6 +989,31 @@ size_t W_LumpLength(lumpnum_t lumpnum) return W_LumpLengthPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum)); } +/* report a zlib or i/o error */ +void zerr(int ret) +{ + CONS_Printf("zpipe: ", stderr); + switch (ret) { + case Z_ERRNO: + if (ferror(stdin)) + CONS_Printf("error reading stdin\n", stderr); + if (ferror(stdout)) + CONS_Printf("error writing stdout\n", stderr); + break; + case Z_STREAM_ERROR: + CONS_Printf("invalid compression level\n", stderr); + break; + case Z_DATA_ERROR: + CONS_Printf("invalid or incomplete deflate data\n", stderr); + break; + case Z_MEM_ERROR: + CONS_Printf("out of memory\n", stderr); + break; + case Z_VERSION_ERROR: + CONS_Printf("zlib version mismatch!\n", stderr); + } +} + /** Reads bytes from the head of a lump. * Note: If the lump is compressed, the whole thing has to be read anyway. * @@ -1069,59 +1095,55 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si } case CM_DEFLATE: // Is it compressed via DEFLATE? Very common in ZIPs/PK3s, also what most doom-related editors support. { - int ret; - unsigned have; - z_stream strm; - unsigned char in[16384]; - unsigned char out[16384]; + char *rawData; // The lump's raw data. + char *decData; // Lump's decompressed real data. + + int zErr; // Helper var. + z_stream strm; + unsigned long rawSize = l->disksize; + unsigned long decSize = l->size; + + rawData = Z_Malloc(rawSize, PU_STATIC, NULL); + decData = Z_Malloc(decSize, PU_STATIC, NULL); + + if (fread(rawData, 1, rawSize, handle) < rawSize) + I_Error("wad %d, lump %d: cannot read compressed data", wad, lump); - /* allocate inflate state */ strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; - strm.avail_in = 0; - strm.next_in = Z_NULL; - ret = inflateInit(&strm); - if (ret != Z_OK) - return ret; - /* decompress until deflate stream ends or end of file */ - do { - strm.avail_in = fread(in, 1, 16384, handle); - if (ferror(handle)) { - (void)inflateEnd(&strm); - return Z_ERRNO; + strm.total_in = strm.avail_in = rawSize; + strm.total_out = strm.avail_out = decSize; + + strm.next_in = rawData; + strm.next_out = decData; + + zErr = inflateInit2(&strm, -15); + if (zErr == Z_OK) + { + zErr = inflate(&strm, Z_FINISH); + if (zErr == Z_STREAM_END) + { + M_Memcpy(dest, decData, size); } - if (strm.avail_in == 0) - break; - strm.next_in = in; + else + { + size = 0; + zerr(zErr); + (void)inflateEnd(&strm); + } + } + else + { + CONS_Printf("whopet\n"); + size = 0; + zerr(zErr); + } - /* run inflate() on input until output buffer not full */ - do { + Z_Free(rawData); + Z_Free(decData); - strm.avail_out = 16384; - strm.next_out = out; - - ret = inflate(&strm, Z_NO_FLUSH); - //assert(ret != Z_STREAM_ERROR); /* state not clobbered */ - switch (ret) { - case Z_NEED_DICT: - ret = Z_DATA_ERROR; /* and fall through */ - case Z_DATA_ERROR: - case Z_MEM_ERROR: - (void)inflateEnd(&strm); - return ret; - } - - have = 16384 - strm.avail_out; - memcpy(dest, out, have); - } while (strm.avail_out == 0); - - /* done when inflate() says it's done */ - } while (ret != Z_STREAM_END); - - /* clean up and return */ - (void)inflateEnd(&strm); return size; } default: diff --git a/src/w_wad.h b/src/w_wad.h index 58b3b322c..5f1af6aad 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -43,7 +43,7 @@ typedef struct unsigned long position; // filelump_t filepos unsigned long disksize; // filelump_t size char name[9]; // filelump_t name[] - char *name2; // Dynamically allocated name. + char *name2; // Used by PK3s. Dynamically allocated name. size_t size; // real (uncompressed) size INT32 compressed; // i enum compmethod compression; // lump compression method @@ -94,7 +94,7 @@ void W_Shutdown(void); // Opens a WAD file. Returns the FILE * handle for the file, or NULL if not found or could not be opened FILE *W_OpenWadFile(const char **filename, boolean useerrors); // Load and add a wadfile to the active wad files, returns numbers of lumps, INT16_MAX on error -UINT16 W_LoadWadFile(const char *filename); +UINT16 W_InitFile(const char *filename); #ifdef DELFILE void W_UnloadWadFile(UINT16 num); #endif From d4c324eb30f8533b985d0bd832f4df8a2a27df08 Mon Sep 17 00:00:00 2001 From: Nevur Date: Tue, 16 May 2017 21:10:02 +0200 Subject: [PATCH 15/35] PK3 stuff again. -Now can load map WAD files inside Maps/ directory, but they must only contain map data explicitly! Known problems: -There's an issue causing a crash with palettes and colormaps in PK3s. -SS_START and SS_END don't work now. Will check later. -Standalone lumps for maps in the Maps/ folder don't work anymore; perhaps I should keep that functionality? Notes: -It's now a mashup of something dumb that I wanted to do and yet piling hacks again. -A lot of code duplicity with map lump loading functions. --- src/p_setup.c | 828 ++++++++++++++++++++++++++++++++++++++++++++++--- src/p_spec.c | 5 +- src/r_data.c | 29 +- src/r_things.c | 35 ++- src/r_things.h | 2 +- src/w_wad.c | 54 ++-- src/w_wad.h | 10 +- 7 files changed, 872 insertions(+), 91 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index fcc2ae591..3aea666da 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -418,6 +418,31 @@ static inline void P_LoadVertexes(lumpnum_t lumpnum) Z_Free(data); } +static inline void P_LoadRawVertexes(UINT8 *data, size_t i) +{ + mapvertex_t *ml; + vertex_t *li; + + numvertexes = i / sizeof (mapvertex_t); + + if (numvertexes <= 0) + I_Error("Level has no vertices"); // instead of crashing + + // Allocate zone memory for buffer. + vertexes = Z_Calloc(numvertexes * sizeof (*vertexes), PU_LEVEL, NULL); + + ml = (mapvertex_t *)data; + li = vertexes; + + // Copy and convert vertex coordinates, internal representation as fixed. + for (i = 0; i < numvertexes; i++, li++, ml++) + { + li->x = SHORT(ml->x)<y = SHORT(ml->y)<v1 = &vertexes[SHORT(ml->v1)]; + li->v2 = &vertexes[SHORT(ml->v2)]; + +#ifdef HWRENDER // not win32 only 19990829 by Kin + // used for the hardware render + if (rendermode != render_soft && rendermode != render_none) + { + li->flength = P_SegLengthf(li); + //Hurdler: 04/12/2000: for now, only used in hardware mode + li->lightmaps = NULL; // list of static lightmap for this seg + } +#endif + + li->angle = (SHORT(ml->angle))<offset = (SHORT(ml->offset))<linedef); + ldef = &lines[linedef]; + li->linedef = ldef; + li->side = side = SHORT(ml->side); + li->sidedef = &sides[ldef->sidenum[side]]; + li->frontsector = sides[ldef->sidenum[side]].sector; + if (ldef-> flags & ML_TWOSIDED) + li->backsector = sides[ldef->sidenum[side^1]].sector; + else + li->backsector = 0; + + li->numlights = 0; + li->rlights = NULL; + } +} + + /** Loads the SSECTORS resource from a level. * * \param lump Lump number of the SSECTORS resource. @@ -543,6 +616,30 @@ static inline void P_LoadSubsectors(lumpnum_t lumpnum) Z_Free(data); } +static inline void P_LoadRawSubsectors(void *data, size_t i) +{ + mapsubsector_t *ms; + subsector_t *ss; + + numsubsectors = i / sizeof (mapsubsector_t); + if (numsubsectors <= 0) + I_Error("Level has no subsectors (did you forget to run it through a nodesbuilder?)"); + ss = subsectors = Z_Calloc(numsubsectors * sizeof (*subsectors), PU_LEVEL, NULL); + + ms = (mapsubsector_t *)data; + + for (i = 0; i < numsubsectors; i++, ss++, ms++) + { + ss->sector = NULL; + ss->numlines = SHORT(ms->numsegs); + ss->firstline = SHORT(ms->firstseg); +#ifdef FLOORSPLATS + ss->splats = NULL; +#endif + ss->validcount = 0; + } +} + // // levelflats // @@ -780,6 +877,111 @@ static void P_LoadSectors(lumpnum_t lumpnum) P_SetupLevelFlatAnims(); } +static void P_LoadRawSectors(UINT8 *data, size_t i) +{ + mapsector_t *ms; + sector_t *ss; + levelflat_t *foundflats; + + // We count how many sectors we got. + numsectors = i / 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); + + // 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++) + { + ss->floorheight = SHORT(ms->floorheight)<ceilingheight = SHORT(ms->ceilingheight)<floorpic = P_AddLevelFlat(ms->floorpic, foundflats); + ss->ceilingpic = P_AddLevelFlat(ms->ceilingpic, foundflats); + + ss->lightlevel = SHORT(ms->lightlevel); + ss->special = SHORT(ms->special); + ss->tag = SHORT(ms->tag); + ss->nexttag = ss->firsttag = -1; + ss->spawn_nexttag = ss->spawn_firsttag = -1; + + memset(&ss->soundorg, 0, sizeof(ss->soundorg)); + ss->validcount = 0; + + ss->thinglist = NULL; + ss->touching_thinglist = NULL; + ss->preciplist = NULL; + ss->touching_preciplist = NULL; + + ss->floordata = NULL; + ss->ceilingdata = NULL; + ss->lightingdata = NULL; + + ss->linecount = 0; + ss->lines = NULL; + + ss->heightsec = -1; + ss->camsec = -1; + ss->floorlightsec = -1; + ss->ceilinglightsec = -1; + ss->crumblestate = 0; + ss->ffloors = NULL; + ss->lightlist = NULL; + ss->numlights = 0; + ss->attached = NULL; + ss->attachedsolid = NULL; + ss->numattached = 0; + ss->maxattached = 1; + ss->moved = true; + + ss->extra_colormap = NULL; + + ss->floor_xoffs = ss->ceiling_xoffs = ss->floor_yoffs = ss->ceiling_yoffs = 0; + ss->spawn_flr_xoffs = ss->spawn_ceil_xoffs = ss->spawn_flr_yoffs = ss->spawn_ceil_yoffs = 0; + ss->floorpic_angle = ss->ceilingpic_angle = 0; + ss->spawn_flrpic_angle = ss->spawn_ceilpic_angle = 0; + ss->bottommap = ss->midmap = ss->topmap = -1; + ss->gravity = NULL; + ss->cullheight = NULL; + ss->verticalflip = false; + ss->flags = 0; + ss->flags |= SF_FLIPSPECIAL_FLOOR; + + ss->floorspeed = 0; + ss->ceilspeed = 0; + +#ifdef HWRENDER // ----- for special tricks with HW renderer ----- + ss->pseudoSector = false; + ss->virtualFloor = false; + ss->virtualCeiling = false; + ss->sectorLines = NULL; + ss->stackList = NULL; + ss->lineoutLength = -1.0l; +#endif // ----- end special tricks ----- + } + + // set the sky flat num + skyflatnum = P_AddLevelFlat(SKYFLATNAME, foundflats); + + // copy table for global usage + levelflats = M_Memcpy(Z_Calloc(numlevelflats * sizeof (*levelflats), PU_LEVEL, NULL), foundflats, numlevelflats * sizeof (levelflat_t)); + free(foundflats); + + // search for animated flats and set up + P_SetupLevelFlatAnims(); +} + // // P_LoadNodes // @@ -817,6 +1019,36 @@ static void P_LoadNodes(lumpnum_t lumpnum) Z_Free(data); } +static void P_LoadRawNodes(UINT8 *data, size_t i) +{ + UINT8 j, k; + mapnode_t *mn; + node_t *no; + + numnodes = i / sizeof (mapnode_t); + if (numnodes <= 0) + I_Error("Level has no nodes"); + nodes = Z_Calloc(numnodes * sizeof (*nodes), PU_LEVEL, NULL); + + mn = (mapnode_t *)data; + no = nodes; + + for (i = 0; i < numnodes; i++, no++, mn++) + { + no->x = SHORT(mn->x)<y = SHORT(mn->y)<dx = SHORT(mn->dx)<dy = SHORT(mn->dy)<children[j] = SHORT(mn->children[j]); + for (k = 0; k < 4; k++) + no->bbox[j][k] = SHORT(mn->bbox[j][k])<x = READINT16(data); + mt->y = READINT16(data); + mt->angle = READINT16(data); + mt->type = READUINT16(data); + mt->options = READUINT16(data); + mt->extrainfo = (UINT8)(mt->type >> 12); + + mt->type &= 4095; + + switch (mt->type) + { + case 1700: // MT_AXIS + case 1701: // MT_AXISTRANSFER + case 1702: // MT_AXISTRANSFERLINE + mt->mobj = NULL; + P_SpawnMapThing(mt); + break; + default: + break; + } + } +} + static void P_LoadThings(void) { size_t i; @@ -1287,6 +1556,113 @@ static void P_LoadLineDefs(lumpnum_t lumpnum) Z_Free(data); } +static void P_LoadRawLineDefs(UINT8 *data, size_t i) +{ + maplinedef_t *mld; + line_t *ld; + vertex_t *v1, *v2; + + numlines = i / sizeof (maplinedef_t); + if (numlines <= 0) + I_Error("Level has no linedefs"); + lines = Z_Calloc(numlines * sizeof (*lines), PU_LEVEL, NULL); + + mld = (maplinedef_t *)data; + ld = lines; + for (i = 0; i < numlines; i++, mld++, ld++) + { + ld->flags = SHORT(mld->flags); + ld->special = SHORT(mld->special); + ld->tag = SHORT(mld->tag); + v1 = ld->v1 = &vertexes[SHORT(mld->v1)]; + v2 = ld->v2 = &vertexes[SHORT(mld->v2)]; + ld->dx = v2->x - v1->x; + ld->dy = v2->y - v1->y; + +#ifdef WALLSPLATS + ld->splats = NULL; +#endif + + if (!ld->dx) + ld->slopetype = ST_VERTICAL; + else if (!ld->dy) + ld->slopetype = ST_HORIZONTAL; + else if (FixedDiv(ld->dy, ld->dx) > 0) + ld->slopetype = ST_POSITIVE; + else + ld->slopetype = ST_NEGATIVE; + + if (v1->x < v2->x) + { + ld->bbox[BOXLEFT] = v1->x; + ld->bbox[BOXRIGHT] = v2->x; + } + else + { + ld->bbox[BOXLEFT] = v2->x; + ld->bbox[BOXRIGHT] = v1->x; + } + + if (v1->y < v2->y) + { + ld->bbox[BOXBOTTOM] = v1->y; + ld->bbox[BOXTOP] = v2->y; + } + else + { + ld->bbox[BOXBOTTOM] = v2->y; + ld->bbox[BOXTOP] = v1->y; + } + + ld->sidenum[0] = SHORT(mld->sidenum[0]); + ld->sidenum[1] = SHORT(mld->sidenum[1]); + + { + // cph 2006/09/30 - fix sidedef errors right away. + // cph 2002/07/20 - these errors are fatal if not fixed, so apply them + UINT8 j; + + for (j=0; j < 2; j++) + { + if (ld->sidenum[j] != 0xffff && ld->sidenum[j] >= (UINT16)numsides) + { + ld->sidenum[j] = 0xffff; + CONS_Debug(DBG_SETUP, "P_LoadLineDefs: linedef %s has out-of-range sidedef number\n", sizeu1(numlines-i-1)); + } + } + } + + ld->frontsector = ld->backsector = NULL; + ld->validcount = 0; + ld->firsttag = ld->nexttag = -1; + ld->callcount = 0; + // killough 11/98: fix common wad errors (missing sidedefs): + + if (ld->sidenum[0] == 0xffff) + { + ld->sidenum[0] = 0; // Substitute dummy sidedef for missing right side + // cph - print a warning about the bug + CONS_Debug(DBG_SETUP, "P_LoadLineDefs: linedef %s missing first sidedef\n", sizeu1(numlines-i-1)); + } + + if ((ld->sidenum[1] == 0xffff) && (ld->flags & ML_TWOSIDED)) + { + ld->flags &= ~ML_TWOSIDED; // Clear 2s flag for missing left side + // cph - print a warning about the bug + CONS_Debug(DBG_SETUP, "P_LoadLineDefs: linedef %s has two-sided flag set, but no second sidedef\n", sizeu1(numlines-i-1)); + } + + if (ld->sidenum[0] != 0xffff && ld->special) + sides[ld->sidenum[0]].special = ld->special; + if (ld->sidenum[1] != 0xffff && ld->special) + sides[ld->sidenum[1]].special = ld->special; + +#ifdef POLYOBJECTS + ld->polyobj = NULL; +#endif + } +} + static void P_LoadLineDefs2(void) { size_t i = numlines; @@ -1396,6 +1772,14 @@ static inline void P_LoadSideDefs(lumpnum_t lumpnum) sides = Z_Calloc(numsides * sizeof (*sides), PU_LEVEL, NULL); } +static inline void P_LoadRawSideDefs(size_t i) +{ + numsides = i / sizeof (mapsidedef_t); + if (numsides <= 0) + I_Error("Level has no sidedefs"); + sides = Z_Calloc(numsides * sizeof (*sides), PU_LEVEL, NULL); +} + // Delay loading texture names until after loaded linedefs. static void P_LoadSideDefs2(lumpnum_t lumpnum) @@ -1636,6 +2020,244 @@ static void P_LoadSideDefs2(lumpnum_t lumpnum) R_ClearTextureNumCache(true); } +// I'm sorry about all this duplicity with little change :( -Nev3r +static void P_LoadRawSideDefs2(void *data) +{ + UINT16 i; + INT32 num; + + for (i = 0; i < numsides; i++) + { + register mapsidedef_t *msd = (mapsidedef_t *)data + i; + register side_t *sd = sides + i; + register sector_t *sec; + + sd->textureoffset = SHORT(msd->textureoffset)<rowoffset = SHORT(msd->rowoffset)<sector); + + if (sector_num >= numsectors) + { + CONS_Debug(DBG_SETUP, "P_LoadSideDefs2: sidedef %u has out-of-range sector num %u\n", i, sector_num); + sector_num = 0; + } + sd->sector = sec = §ors[sector_num]; + } + + // refined to allow colormaps to work as wall textures if invalid as colormaps + // but valid as textures. + + sd->sector = sec = §ors[SHORT(msd->sector)]; + + // Colormaps! + switch (sd->special) + { + case 63: // variable colormap via 242 linedef + case 606: //SoM: 4/4/2000: Just colormap transfer + // SoM: R_CreateColormap will only create a colormap in software mode... + // Perhaps we should just call it instead of doing the calculations here. + if (rendermode == render_soft || rendermode == render_none) + { + if (msd->toptexture[0] == '#' || msd->bottomtexture[0] == '#') + { + sec->midmap = R_CreateColormap(msd->toptexture, msd->midtexture, + msd->bottomtexture); + sd->toptexture = sd->bottomtexture = 0; + } + else + { + if ((num = R_CheckTextureNumForName(msd->toptexture)) == -1) + sd->toptexture = 0; + else + sd->toptexture = num; + if ((num = R_CheckTextureNumForName(msd->midtexture)) == -1) + sd->midtexture = 0; + else + sd->midtexture = num; + if ((num = R_CheckTextureNumForName(msd->bottomtexture)) == -1) + sd->bottomtexture = 0; + else + sd->bottomtexture = num; + } + break; + } +#ifdef HWRENDER + else + { + // for now, full support of toptexture only + if ((msd->toptexture[0] == '#' && msd->toptexture[1] && msd->toptexture[2] && msd->toptexture[3] && msd->toptexture[4] && msd->toptexture[5] && msd->toptexture[6]) + || (msd->bottomtexture[0] == '#' && msd->bottomtexture[1] && msd->bottomtexture[2] && msd->bottomtexture[3] && msd->bottomtexture[4] && msd->bottomtexture[5] && msd->bottomtexture[6])) + { + char *col; + + sec->midmap = R_CreateColormap(msd->toptexture, msd->midtexture, + msd->bottomtexture); + sd->toptexture = sd->bottomtexture = 0; +#define HEX2INT(x) (x >= '0' && x <= '9' ? x - '0' : x >= 'a' && x <= 'f' ? x - 'a' + 10 : x >= 'A' && x <= 'F' ? x - 'A' + 10 : 0) +#define ALPHA2INT(x) (x >= 'a' && x <= 'z' ? x - 'a' : x >= 'A' && x <= 'Z' ? x - 'A' : x >= '0' && x <= '9' ? 25 : 0) + sec->extra_colormap = &extra_colormaps[sec->midmap]; + + if (msd->toptexture[0] == '#' && msd->toptexture[1] && msd->toptexture[2] && msd->toptexture[3] && msd->toptexture[4] && msd->toptexture[5] && msd->toptexture[6]) + { + col = msd->toptexture; + + sec->extra_colormap->rgba = + (HEX2INT(col[1]) << 4) + (HEX2INT(col[2]) << 0) + + (HEX2INT(col[3]) << 12) + (HEX2INT(col[4]) << 8) + + (HEX2INT(col[5]) << 20) + (HEX2INT(col[6]) << 16); + + // alpha + if (msd->toptexture[7]) + sec->extra_colormap->rgba += (ALPHA2INT(col[7]) << 24); + else + sec->extra_colormap->rgba += (25 << 24); + } + else + sec->extra_colormap->rgba = 0; + + if (msd->bottomtexture[0] == '#' && msd->bottomtexture[1] && msd->bottomtexture[2] && msd->bottomtexture[3] && msd->bottomtexture[4] && msd->bottomtexture[5] && msd->bottomtexture[6]) + { + col = msd->bottomtexture; + + sec->extra_colormap->fadergba = + (HEX2INT(col[1]) << 4) + (HEX2INT(col[2]) << 0) + + (HEX2INT(col[3]) << 12) + (HEX2INT(col[4]) << 8) + + (HEX2INT(col[5]) << 20) + (HEX2INT(col[6]) << 16); + + // alpha + if (msd->bottomtexture[7]) + sec->extra_colormap->fadergba += (ALPHA2INT(col[7]) << 24); + else + sec->extra_colormap->fadergba += (25 << 24); + } + else + sec->extra_colormap->fadergba = 0x19000000; // default alpha, (25 << 24) +#undef ALPHA2INT +#undef HEX2INT + } + else + { + if ((num = R_CheckTextureNumForName(msd->toptexture)) == -1) + sd->toptexture = 0; + else + sd->toptexture = num; + + if ((num = R_CheckTextureNumForName(msd->midtexture)) == -1) + sd->midtexture = 0; + else + sd->midtexture = num; + + if ((num = R_CheckTextureNumForName(msd->bottomtexture)) == -1) + sd->bottomtexture = 0; + else + sd->bottomtexture = num; + } + break; + } +#endif + + case 413: // Change music + { + char process[8+1]; + + sd->toptexture = sd->midtexture = sd->bottomtexture = 0; + if (msd->bottomtexture[0] != '-' || msd->bottomtexture[1] != '\0') + { + M_Memcpy(process,msd->bottomtexture,8); + process[8] = '\0'; + sd->bottomtexture = get_number(process)-1; + } + M_Memcpy(process,msd->toptexture,8); + process[8] = '\0'; + sd->text = Z_Malloc(7, PU_LEVEL, NULL); + + // If they type in O_ or D_ and their music name, just shrug, + // then copy the rest instead. + if ((process[0] == 'O' || process[0] == 'D') && process[7]) + M_Memcpy(sd->text, process+2, 6); + else // Assume it's a proper music name. + M_Memcpy(sd->text, process, 6); + sd->text[6] = 0; + break; + } + + case 4: // Speed pad parameters + case 414: // Play SFX + { + sd->toptexture = sd->midtexture = sd->bottomtexture = 0; + if (msd->toptexture[0] != '-' || msd->toptexture[1] != '\0') + { + char process[8+1]; + M_Memcpy(process,msd->toptexture,8); + process[8] = '\0'; + sd->toptexture = get_number(process); + } + break; + } + + case 14: // Bustable block parameters + case 15: // Fan particle spawner parameters + case 425: // Calls P_SetMobjState on calling mobj + case 434: // Custom Power + case 442: // Calls P_SetMobjState on mobjs of a given type in the tagged sectors + { + char process[8*3+1]; + memset(process,0,8*3+1); + sd->toptexture = sd->midtexture = sd->bottomtexture = 0; + if (msd->toptexture[0] == '-' && msd->toptexture[1] == '\0') + break; + else + M_Memcpy(process,msd->toptexture,8); + if (msd->midtexture[0] != '-' || msd->midtexture[1] != '\0') + M_Memcpy(process+strlen(process), msd->midtexture, 8); + if (msd->bottomtexture[0] != '-' || msd->bottomtexture[1] != '\0') + M_Memcpy(process+strlen(process), msd->bottomtexture, 8); + sd->toptexture = get_number(process); + break; + } + + case 443: // Calls a named Lua function + { + char process[8*3+1]; + memset(process,0,8*3+1); + sd->toptexture = sd->midtexture = sd->bottomtexture = 0; + if (msd->toptexture[0] == '-' && msd->toptexture[1] == '\0') + break; + else + M_Memcpy(process,msd->toptexture,8); + if (msd->midtexture[0] != '-' || msd->midtexture[1] != '\0') + M_Memcpy(process+strlen(process), msd->midtexture, 8); + if (msd->bottomtexture[0] != '-' || msd->bottomtexture[1] != '\0') + M_Memcpy(process+strlen(process), msd->bottomtexture, 8); + sd->text = Z_Malloc(strlen(process)+1, PU_LEVEL, NULL); + M_Memcpy(sd->text, process, strlen(process)+1); + break; + } + + default: // normal cases + if (msd->toptexture[0] == '#') + { + char *col = msd->toptexture; + sd->toptexture = sd->bottomtexture = + ((col[1]-'0')*100 + (col[2]-'0')*10 + col[3]-'0') + 1; + sd->midtexture = R_TextureNumForName(msd->midtexture); + } + else + { + sd->midtexture = R_TextureNumForName(msd->midtexture); + sd->toptexture = R_TextureNumForName(msd->toptexture); + sd->bottomtexture = R_TextureNumForName(msd->bottomtexture); + } + break; + } + } + + R_ClearTextureNumCache(true); +} + + static boolean LineInBlock(fixed_t cx1, fixed_t cy1, fixed_t cx2, fixed_t cy2, fixed_t bx1, fixed_t by1) { fixed_t bbox[4]; @@ -2524,6 +3146,7 @@ boolean P_SetupLevel(boolean skipprecip) // use gamemap to get map number. // 99% of the things already did, so. // Map header should always be in place at this point + boolean isLumpWad = false; // Is the lump a marker or actually a WAD file of its own? (For PK3s) INT32 i, loadprecip = 1, ranspecialwipe = 0; INT32 loademblems = 1; INT32 fromnetsave = 0; @@ -2685,7 +3308,54 @@ boolean P_SetupLevel(boolean skipprecip) } // internal game map - lastloadedmaplumpnum = W_GetNumForName(maplumpname = G_BuildMapName(gamemap)); + maplumpname = G_BuildMapName(gamemap); + lastloadedmaplumpnum = LUMPERROR; + + // Look for valid map data through all added files in descendant order. + // Get a map marker for WADs, and a standalone WAD file lump inside PK3s. + // TODO: Make it search through cache first, maybe...? + // TODO: Also move it to w_wad.c as a function...? + for (i = numwadfiles - 1; i >= 0; i--) + { + if (wadfiles[i]->type == RET_WAD) + { + UINT16 lumpNum; + for (lumpNum = 0; lumpNum < wadfiles[i]->numlumps; lumpNum++) + { + if (!strncmp(maplumpname, (wadfiles[i]->lumpinfo + lumpNum)->name, 8)) + { + lastloadedmaplumpnum = (i<<16) + lumpNum; + CONS_Printf("WAD %s has a map marker named %s.\n", wadfiles[i]->filename, maplumpname); + break; + } + } + } + else if (wadfiles[i]->type == RET_PK3) + { + // Look for the maps folder. + UINT16 lumpNum, end; + lumpNum = W_CheckNumForFullNamePK3("maps/", i, 0); + if (lumpNum != INT16_MAX) + end = W_CheckNumForFolderEndPK3("maps/", i, lumpNum); + else + continue; + + // Now look for the specified map. + for (++lumpNum; lumpNum < end; lumpNum++) + if (!strnicmp(maplumpname, (wadfiles[i]->lumpinfo + lumpNum)->name, 5)) + { + isLumpWad = true; + lastloadedmaplumpnum = (i<<16) + lumpNum; + CONS_Printf("PK3 %s has a map WAD named %s.\n", wadfiles[i]->filename, maplumpname); + break; + } + } + if (!(lastloadedmaplumpnum == LUMPERROR)) // Stop looking if we found a valid lump. + break; + } + + if (lastloadedmaplumpnum == INT16_MAX) + I_Error("Map %s not found.\n", maplumpname); R_ReInitColormaps(mapheaderinfo[gamemap-1]->palette); CON_SetupBackColormap(); @@ -2695,39 +3365,93 @@ boolean P_SetupLevel(boolean skipprecip) P_MakeMapMD5(lastloadedmaplumpnum, &mapmd5); - // note: most of this ordering is important - loadedbm = P_LoadBlockMap(lastloadedmaplumpnum + ML_BLOCKMAP); - P_LoadVertexes(lastloadedmaplumpnum + ML_VERTEXES); - P_LoadSectors(lastloadedmaplumpnum + ML_SECTORS); + // HACK ALERT: Cache the WAD, get the map data into the table, free memory. + // As it is implemented right now, we're assuming an uncompressed WAD. + // (As in, a normal PWAD, not ZWAD or anything. The lump itself can be compressed.) + // Basically this is a nerfed&modified version of W_InitFile from w_wad. + if (isLumpWad) + { + UINT16 i; + wadinfo_t *header; + filelump_t *fileinfo; + UINT8 *wadData = W_CacheLumpNum(lastloadedmaplumpnum, PU_STATIC); + header = (wadinfo_t *)wadData; + CONS_Printf("This map WAD contains %lu lumps.\n", header->numlumps); - P_LoadSideDefs(lastloadedmaplumpnum + ML_SIDEDEFS); + fileinfo = wadData + header->infotableofs; + for(i = 0; i < header->numlumps; i++, fileinfo++) + { + char name[9]; + memcpy(name, fileinfo->name, 8); + name[8] = '\0'; + CONS_Printf("%s, size %lu\n", name, fileinfo->size); + } + fileinfo = wadData + header->infotableofs; - P_LoadLineDefs(lastloadedmaplumpnum + ML_LINEDEFS); - if (!loadedbm) - P_CreateBlockMap(); // Graue 02-29-2004 - P_LoadSideDefs2(lastloadedmaplumpnum + ML_SIDEDEFS); + P_LoadRawVertexes(wadData + (fileinfo + ML_VERTEXES)->filepos, (fileinfo + ML_VERTEXES)->size); + P_LoadRawSectors(wadData + (fileinfo + ML_SECTORS)->filepos, (fileinfo + ML_SECTORS)->size); + P_LoadRawSideDefs((fileinfo + ML_SIDEDEFS)->size); + P_LoadRawLineDefs(wadData + (fileinfo + ML_LINEDEFS)->filepos, (fileinfo + ML_LINEDEFS)->size); + P_LoadRawSideDefs2(wadData + (fileinfo + ML_SIDEDEFS)->filepos); + P_LoadRawSubsectors(wadData + (fileinfo + ML_SSECTORS)->filepos, (fileinfo + ML_SSECTORS)->size); + P_LoadRawNodes(wadData + (fileinfo + ML_NODES)->filepos, (fileinfo + ML_NODES)->size); + P_LoadRawSegs(wadData + (fileinfo + ML_SEGS)->filepos, (fileinfo + ML_SEGS)->size); +// P_LoadReject(lastloadedmaplumpnum + ML_REJECT); - R_MakeColormaps(); - P_LoadLineDefs2(); - P_LoadSubsectors(lastloadedmaplumpnum + ML_SSECTORS); - P_LoadNodes(lastloadedmaplumpnum + ML_NODES); - P_LoadSegs(lastloadedmaplumpnum + ML_SEGS); - P_LoadReject(lastloadedmaplumpnum + ML_REJECT); - P_GroupLines(); + // Important: take care of the ordering of the next functions. + if (!loadedbm) + P_CreateBlockMap(); // Graue 02-29-2004 + R_MakeColormaps(); + P_LoadLineDefs2(); + P_GroupLines(); + numdmstarts = numredctfstarts = numbluectfstarts = 0; - numdmstarts = numredctfstarts = numbluectfstarts = 0; + // reset the player starts + for (i = 0; i < MAXPLAYERS; i++) + playerstarts[i] = NULL; - // reset the player starts - for (i = 0; i < MAXPLAYERS; i++) - playerstarts[i] = NULL; + for (i = 0; i < 2; i++) + skyboxmo[i] = NULL; - for (i = 0; i < 2; i++) - skyboxmo[i] = NULL; + P_MapStart(); - P_MapStart(); + P_PrepareRawThings(wadData + (fileinfo + ML_THINGS)->filepos, (fileinfo + ML_THINGS)->size); + Z_Free(wadData); + } + else + { + // Important: take care of the ordering of the next functions. + loadedbm = P_LoadBlockMap(lastloadedmaplumpnum + ML_BLOCKMAP); + P_LoadVertexes(lastloadedmaplumpnum + ML_VERTEXES); + P_LoadSectors(lastloadedmaplumpnum + ML_SECTORS); + P_LoadSideDefs(lastloadedmaplumpnum + ML_SIDEDEFS); + P_LoadLineDefs(lastloadedmaplumpnum + ML_LINEDEFS); + P_LoadSideDefs2(lastloadedmaplumpnum + ML_SIDEDEFS); + P_LoadSubsectors(lastloadedmaplumpnum + ML_SSECTORS); + P_LoadNodes(lastloadedmaplumpnum + ML_NODES); + P_LoadSegs(lastloadedmaplumpnum + ML_SEGS); + P_LoadReject(lastloadedmaplumpnum + ML_REJECT); - P_PrepareThings(lastloadedmaplumpnum + ML_THINGS); + // Important: take care of the ordering of the next functions. + if (!loadedbm) + P_CreateBlockMap(); // Graue 02-29-2004 + R_MakeColormaps(); + P_LoadLineDefs2(); + P_GroupLines(); + numdmstarts = numredctfstarts = numbluectfstarts = 0; + + // reset the player starts + for (i = 0; i < MAXPLAYERS; i++) + playerstarts[i] = NULL; + + for (i = 0; i < 2; i++) + skyboxmo[i] = NULL; + + P_MapStart(); + + P_PrepareThings(lastloadedmaplumpnum + ML_THINGS); + } #ifdef ESLOPE P_ResetDynamicSlopes(); @@ -3079,6 +3803,32 @@ void P_LoadMusicsRange(UINT16 wadnum, UINT16 first, UINT16 num) return; } +// Auxiliary function for PK3 loading - adds extra lumps +// NOTE: does nothing but print debug messages. +/*void P_LoadWadMapRange(UINT16 wadnum, UINT16 first, UINT16 num) +{ + lumpinfo_t *lumpinfo = wadfiles[wadnum]->lumpinfo + first; + CONS_Printf("First %s\n", lumpinfo->name2); + for (; num > 0; num--, first++, lumpinfo++) + { + wadinfo_t header; + void* wadCache = Z_Malloc(W_LumpLengthPwad(wadnum, first), PU_STATIC, NULL); + W_ReadLumpHeaderPwad(wadnum, first, wadCache, 0, 0); + // We put the header info into our header var. + memcpy(header, wadCache, sizeof header); + + header.numlumps = LONG(header.numlumps); + header.infotableofs = LONG(header.infotableofs); + lumpinfo = (lumpinfo_t*) Z_Realloc(lumpinfo, (numlumps + 1)*sizeof(*lumpinfo), PU_STATIC, NULL); + + + Z_Free(wadCache); + CONS_Printf("Decached map WAD stuff.\n"); + } + return; +}*/ + + // // Add a wadfile to the active wad files, // replace sounds, musics, patches, textures, sprites and maps @@ -3095,16 +3845,17 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname) // 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 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; + UINT16 mapPos, mapNum = 0; + // Init file. if ((numlumps = W_InitFile(wadfilename)) == INT16_MAX) { CONS_Printf(M_GetText("Errors occured while loading %s; not added.\n"), wadfilename); @@ -3133,7 +3884,6 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname) } lumpinfo--; *end = i-- - *start; - CONS_Printf("Folder %s, first lump %lu, total: %lu.\n", folName, *start, *end); return; } return; @@ -3143,35 +3893,35 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname) lumpinfo = wadfiles[wadnum]->lumpinfo; for (i = 0; i < numlumps; i++, lumpinfo++) { - FindFolder("Lua/", &luaPos, &luaNum); - FindFolder("Soc/", &socPos, &socNum); +// FindFolder("Lua/", &luaPos, &luaNum); +// FindFolder("SOCs/", &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); + 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); +// if (luaNum) // Lua scripts. +// P_LoadLuaScrRange(wadnum, luaPos, luaNum); #endif - if (socNum) // SOCs. - P_LoadDehackRange(wadnum, socPos, socNum); +// 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(); +// if (texNum) // Textures. TODO: R_LoadTextures() does the folder positioning once again. New function maybe? +// R_LoadTextures(); // if (mapNum) // Maps. TODO: Actually implement the map WAD loading code, lulz. -// P_LoadWadMapRange(); +// P_LoadWadMapRange(wadnum, mapPos, mapNum); } break; default: diff --git a/src/p_spec.c b/src/p_spec.c index db7b852f5..7d27070da 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -284,7 +284,10 @@ void P_InitPicAnims(void) } // Now find ANIMDEFS - animdefsLumpNum = W_CheckNumForNamePwad("ANIMDEFS", w, 0); + if (wadfiles[w]->type == RET_WAD) + animdefsLumpNum = W_CheckNumForNamePwad("ANIMDEFS", w, 0); + else if (wadfiles[w]->type == RET_PK3) + animdefsLumpNum = W_CheckNumForFullNamePK3("ANIMDEFS", w, 0); if (animdefsLumpNum != INT16_MAX) P_ParseANIMDEFSLump(w, animdefsLumpNum); } diff --git a/src/r_data.c b/src/r_data.c index d7ac38974..4f1be210f 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -528,8 +528,8 @@ void R_FlushTextureCache(void) } // Need these prototypes for later; defining them here instead of r_data.h so they're "private" -int R_CountTexturesInTEXTURESLump(UINT16 wadNum); -void R_ParseTEXTURESLump(UINT16 wadNum, INT32 *index); +int R_CountTexturesInTEXTURESLump(UINT16 wadNum, UINT16 lumpNum); +void R_ParseTEXTURESLump(UINT16 wadNum, UINT16 lumpNum, INT32 *index); // // R_LoadTextures @@ -582,7 +582,7 @@ void R_LoadTextures(void) if (texturesLumpPos != INT16_MAX) { - numtextures += R_CountTexturesInTEXTURESLump((UINT16)w); + numtextures += R_CountTexturesInTEXTURESLump((UINT16)w, (UINT16)texturesLumpPos); } // Add all the textures between TX_START and TX_END @@ -623,16 +623,17 @@ void R_LoadTextures(void) { texstart = W_CheckNumForFullNamePK3("textures/", (UINT16)w, 0) + 1; texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart); + texturesLumpPos = W_CheckNumForFullNamePK3("textures", (UINT16)w, 0); } else { texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0) + 1; texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0); + texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0); } - texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0); if (texturesLumpPos != INT16_MAX) - R_ParseTEXTURESLump(w,&i); + R_ParseTEXTURESLump(w, texturesLumpPos, &i); if (texstart == INT16_MAX || texend == INT16_MAX) continue; @@ -1041,7 +1042,7 @@ static texture_t *R_ParseTexture(boolean actuallyLoadTexture) } // Parses the TEXTURES lump... but just to count the number of textures. -int R_CountTexturesInTEXTURESLump(UINT16 wadNum) +int R_CountTexturesInTEXTURESLump(UINT16 wadNum, UINT16 lumpNum) { char *texturesLump; size_t texturesLumpLength; @@ -1052,11 +1053,11 @@ int R_CountTexturesInTEXTURESLump(UINT16 wadNum) // Since lumps AREN'T \0-terminated like I'd assumed they should be, I'll // need to make a space of memory where I can ensure that it will terminate // correctly. Start by loading the relevant data from the WAD. - texturesLump = (char *)W_CacheLumpNumPwad(wadNum,W_CheckNumForNamePwad("TEXTURES", wadNum, 0),PU_STATIC); + texturesLump = (char *)W_CacheLumpNumPwad(wadNum, lumpNum, PU_STATIC); // If that didn't exist, we have nothing to do here. if (texturesLump == NULL) return 0; // If we're still here, then it DOES exist; figure out how long it is, and allot memory accordingly. - texturesLumpLength = W_LumpLengthPwad(wadNum,W_CheckNumForNamePwad("TEXTURES",wadNum,0)); + texturesLumpLength = W_LumpLengthPwad(wadNum, lumpNum); texturesText = (char *)Z_Malloc((texturesLumpLength+1)*sizeof(char),PU_STATIC,NULL); // Now move the contents of the lump into this new location. memmove(texturesText,texturesLump,texturesLumpLength); @@ -1088,7 +1089,7 @@ int R_CountTexturesInTEXTURESLump(UINT16 wadNum) } // Parses the TEXTURES lump... for real, this time. -void R_ParseTEXTURESLump(UINT16 wadNum, INT32 *texindex) +void R_ParseTEXTURESLump(UINT16 wadNum, UINT16 lumpNum, INT32 *texindex) { char *texturesLump; size_t texturesLumpLength; @@ -1101,11 +1102,11 @@ void R_ParseTEXTURESLump(UINT16 wadNum, INT32 *texindex) // Since lumps AREN'T \0-terminated like I'd assumed they should be, I'll // need to make a space of memory where I can ensure that it will terminate // correctly. Start by loading the relevant data from the WAD. - texturesLump = (char *)W_CacheLumpNumPwad(wadNum,W_CheckNumForNamePwad("TEXTURES", wadNum, 0),PU_STATIC); + texturesLump = (char *)W_CacheLumpNumPwad(wadNum, lumpNum, PU_STATIC); // If that didn't exist, we have nothing to do here. if (texturesLump == NULL) return; // If we're still here, then it DOES exist; figure out how long it is, and allot memory accordingly. - texturesLumpLength = W_LumpLengthPwad(wadNum,W_CheckNumForNamePwad("TEXTURES",wadNum,0)); + texturesLumpLength = W_LumpLengthPwad(wadNum, lumpNum); texturesText = (char *)Z_Malloc((texturesLumpLength+1)*sizeof(char),PU_STATIC,NULL); // Now move the contents of the lump into this new location. memmove(texturesText,texturesLump,texturesLumpLength); @@ -1211,16 +1212,12 @@ lumpnum_t R_GetFlatNumForName(const char *name) { start = W_CheckNumForNamePwad("FF_START", (UINT16)i, 0); if (start == INT16_MAX) - { continue; - } else { end = W_CheckNumForNamePwad("FF_END", (UINT16)i, start); if (end == INT16_MAX) - { continue; - } } } else @@ -1297,7 +1294,7 @@ void R_ReInitColormaps(UINT16 num) { char colormap[9] = "COLORMAP"; lumpnum_t lump; - + CONS_Printf("Reinitting colormaps...\n"); if (num > 0 && num <= 10000) snprintf(colormap, 8, "CLM%04u", num-1); diff --git a/src/r_things.c b/src/r_things.c index e1b4d66b0..54a0d2b26 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -409,31 +409,42 @@ void R_AddSpriteDefs(UINT16 wadnum) UINT16 start, end; char wadname[MAX_WADPATH]; - // find the sprites section in this pwad - // we need at least the S_END - // (not really, but for speedup) + // Find the sprites section in this resource file. + if (wadfiles[wadnum]->type == RET_WAD) + { + start = W_CheckNumForNamePwad("S_START", wadnum, 0); + if (start == UINT16_MAX) + start = W_CheckNumForNamePwad("SS_START", wadnum, 0); //deutex compatib. + } + else if (wadfiles[wadnum]->type == RET_PK3) + start = W_CheckNumForFullNamePK3("Sprites/", wadnum, 0); - start = W_CheckNumForNamePwad("S_START", wadnum, 0); - if (start == INT16_MAX) - start = W_CheckNumForNamePwad("SS_START", wadnum, 0); //deutex compatib. - if (start == INT16_MAX) + if (start == UINT16_MAX) start = 0; //let say S_START is lump 0 else start++; // just after S_START + // ignore skin wads (we don't want skin sprites interfering with vanilla sprites) - if (start == 0 && W_CheckNumForNamePwad("S_SKIN", wadnum, 0) != INT16_MAX) + if (start == 0 && W_CheckNumForNamePwad("S_SKIN", wadnum, 0) != UINT16_MAX) return; - end = W_CheckNumForNamePwad("S_END",wadnum,start); - if (end == INT16_MAX) - end = W_CheckNumForNamePwad("SS_END",wadnum,start); //deutex compatib. - if (end == INT16_MAX) + if (wadfiles[wadnum]->type == RET_WAD) + { + end = W_CheckNumForNamePwad("S_END",wadnum,start); + if (end == UINT16_MAX) + end = W_CheckNumForNamePwad("SS_END",wadnum,start); //deutex compatib. + } + else if (wadfiles[wadnum]->type == RET_PK3) + end = W_CheckNumForFolderEndPK3("Sprites/", wadnum, start); + + if (end == UINT16_MAX) { CONS_Debug(DBG_SETUP, "no sprites in pwad %d\n", wadnum); return; } + // // scan through lumps, for each sprite, find all the sprite frames // diff --git a/src/r_things.h b/src/r_things.h index b3f1f4b4c..441d32087 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -50,7 +50,7 @@ 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); +void R_LoadSpritsRange(UINT16 wadnum, UINT16 first, UINT16 num); #ifdef DELFILE diff --git a/src/w_wad.c b/src/w_wad.c index 65f0ee214..b86d8bd28 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -70,14 +70,6 @@ int snprintf(char *str, size_t n, const char *fmt, ...); #pragma pack(1) #endif -// a raw entry of the wad directory -typedef struct -{ - UINT32 filepos; // file offset of the resource - UINT32 size; // size of the resource - char name[8]; // name of the resource -} ATTRPACK filelump_t; - #if defined(_MSC_VER) #pragma pack() #endif @@ -179,6 +171,26 @@ FILE *W_OpenWadFile(const char **filename, boolean useerrors) return handle; } +// Look for all DEHACKED and Lua scripts inside a PK3 archive. +static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum) +{ + UINT16 posStart, posEnd; + posStart = W_CheckNumForFullNamePK3("Lua/", wadnum, 0); + if (posStart != INT16_MAX) + { + posEnd = W_CheckNumForFolderEndPK3("Lua/", wadnum, posStart); + for (++posStart; posStart < posEnd; posStart++) + LUA_LoadLump(wadnum, posStart); + } + posStart = W_CheckNumForFullNamePK3("SOCs/", wadnum, 0); + if (posStart != INT16_MAX) + { + posEnd = W_CheckNumForFolderEndPK3("SOCs/", wadnum, posStart); + for(++posStart; posStart < posEnd; posStart++) + DEH_LoadDehackedLumpPwad(wadnum, posStart); + } +} + // search for all DEHACKED lump in all wads and load it static inline void W_LoadDehackedLumps(UINT16 wadnum) { @@ -539,6 +551,7 @@ UINT16 W_InitFile(const char *filename) lumpinfo[numlumps].compression = CM_UNSUPPORTED; break; } + CONS_Printf("File %s, Shortname %s, data begins at: %ld\n", eName, lumpinfo[numlumps].name, lumpinfo[numlumps].position); CONS_Debug(DBG_SETUP, "File %s, data begins at: %ld\n", eName, lumpinfo[numlumps].position); fseek(handle, eXFieldLen + eCommentLen, SEEK_CUR); // We skip to where we expect the next central directory entry or end marker to be. numlumps++; @@ -696,9 +709,12 @@ UINT16 W_InitFile(const char *filename) 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 - // TODO: HACK ALERT - Load Lua & SOC stuff right here for WADs. Avoids crash on startup since WADs are loaded using W_InitMultipleFiles. + // TODO: HACK ALERT - Load Lua & SOC stuff right here. I feel like this should be out of this place, but... Let's stick with this for now. if (wadfile->type == RET_WAD) W_LoadDehackedLumps(numwadfiles - 1); + else if (wadfile->type == RET_PK3) + W_LoadDehackedLumpsPK3(numwadfiles - 1); + W_InvalidateLumpnumCache(); @@ -827,10 +843,8 @@ UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump) { lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump; for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++) - { if (memcmp(lump_p->name,uname,8) == 0) return i; - } } // not found. @@ -992,25 +1006,25 @@ size_t W_LumpLength(lumpnum_t lumpnum) /* report a zlib or i/o error */ void zerr(int ret) { - CONS_Printf("zpipe: ", stderr); + CONS_Printf("zpipe: "); switch (ret) { case Z_ERRNO: if (ferror(stdin)) - CONS_Printf("error reading stdin\n", stderr); + CONS_Printf("error reading stdin\n"); if (ferror(stdout)) - CONS_Printf("error writing stdout\n", stderr); + CONS_Printf("error writing stdout\n"); break; case Z_STREAM_ERROR: - CONS_Printf("invalid compression level\n", stderr); + CONS_Printf("invalid compression level\n"); break; case Z_DATA_ERROR: - CONS_Printf("invalid or incomplete deflate data\n", stderr); + CONS_Printf("invalid or incomplete deflate data\n"); break; case Z_MEM_ERROR: - CONS_Printf("out of memory\n", stderr); + CONS_Printf("out of memory\n"); break; case Z_VERSION_ERROR: - CONS_Printf("zlib version mismatch!\n", stderr); + CONS_Printf("zlib version mismatch!\n"); } } @@ -1095,8 +1109,8 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si } case CM_DEFLATE: // Is it compressed via DEFLATE? Very common in ZIPs/PK3s, also what most doom-related editors support. { - char *rawData; // The lump's raw data. - char *decData; // Lump's decompressed real data. + z_const Bytef *rawData; // The lump's raw data. + Bytef *decData; // Lump's decompressed real data. int zErr; // Helper var. z_stream strm; diff --git a/src/w_wad.h b/src/w_wad.h index 5f1af6aad..d5e6e9017 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -34,6 +34,14 @@ typedef struct UINT32 infotableofs; // the 'directory' of resources } wadinfo_t; +// a raw entry of the wad directory +typedef struct +{ + UINT32 filepos; // file offset of the resource + UINT32 size; // size of the resource + char name[8]; // name of the resource +} ATTRPACK filelump_t; + // Available compression methods for lumps. enum compmethod{CM_NONE, CM_DEFLATE, CM_LZF, CM_UNSUPPORTED}; @@ -99,8 +107,6 @@ UINT16 W_InitFile(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); From 19c46f3732e3d745e9c96848f1ffaf227d09b996 Mon Sep 17 00:00:00 2001 From: Nevur Date: Thu, 18 May 2017 21:13:18 +0200 Subject: [PATCH 16/35] More PK3 work. -Removed code duplicity on map resource reading. -Fixed all known PK3-related bugs so far except for the ones mentioned below. Issues: -Blockmap and reject matrix still aren't loaded yet when using a map WAD. -Palettes and colormaps aren't loaded (by extension, TRANS tables might not work either). --- src/d_main.c | 2 + src/d_netcmd.c | 6 - src/p_setup.c | 787 ++++--------------------------------------------- src/w_wad.c | 40 ++- src/w_wad.h | 1 + 5 files changed, 106 insertions(+), 730 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 0bba9dc06..be06acb2e 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1385,7 +1385,9 @@ void D_SRB2Main(void) else if (!dedicated && M_MapLocked(pstartmap)) I_Error("You need to unlock this level before you can warp to it!\n"); else + { D_MapChange(pstartmap, gametype, ultimatemode, true, 0, false, false); + } } } else if (M_CheckParm("-skipintro")) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 12aeac6ae..1c1ac2aa8 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1545,16 +1545,12 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pultmode, boolean rese { static char buf[2+MAX_WADPATH+1+4]; static char *buf_p = buf; - // The supplied data are assumed to be good. I_Assert(delay >= 0 && delay <= 2); - if (mapnum != -1) CV_SetValue(&cv_nextmap, mapnum); - CONS_Debug(DBG_GAMELOGIC, "Map change: mapnum=%d gametype=%d ultmode=%d resetplayers=%d delay=%d skipprecutscene=%d\n", mapnum, newgametype, pultmode, resetplayers, delay, skipprecutscene); - if ((netgame || multiplayer) && !((gametype == newgametype) && (newgametype == GT_COOP))) FLS = false; @@ -1562,9 +1558,7 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pultmode, boolean rese { UINT8 flags = 0; const char *mapname = G_BuildMapName(mapnum); - I_Assert(W_CheckNumForName(mapname) != LUMPERROR); - buf_p = buf; if (pultmode) flags |= 1; diff --git a/src/p_setup.c b/src/p_setup.c index 3aea666da..2cc70e6a0 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -482,58 +482,6 @@ static inline float P_SegLengthf(seg_t *seg) * \param lump Lump number of the SEGS resource. * \sa ::ML_SEGS */ -static void P_LoadSegs(lumpnum_t lumpnum) -{ - UINT8 *data; - size_t i; - INT32 linedef, side; - mapseg_t *ml; - seg_t *li; - line_t *ldef; - - numsegs = W_LumpLength(lumpnum) / sizeof (mapseg_t); - if (numsegs <= 0) - I_Error("Level has no segs"); // instead of crashing - segs = Z_Calloc(numsegs * sizeof (*segs), PU_LEVEL, NULL); - data = W_CacheLumpNum(lumpnum, PU_STATIC); - - ml = (mapseg_t *)data; - li = segs; - for (i = 0; i < numsegs; i++, li++, ml++) - { - li->v1 = &vertexes[SHORT(ml->v1)]; - li->v2 = &vertexes[SHORT(ml->v2)]; - -#ifdef HWRENDER // not win32 only 19990829 by Kin - // used for the hardware render - if (rendermode != render_soft && rendermode != render_none) - { - li->flength = P_SegLengthf(li); - //Hurdler: 04/12/2000: for now, only used in hardware mode - li->lightmaps = NULL; // list of static lightmap for this seg - } -#endif - - li->angle = (SHORT(ml->angle))<offset = (SHORT(ml->offset))<linedef); - ldef = &lines[linedef]; - li->linedef = ldef; - li->side = side = SHORT(ml->side); - li->sidedef = &sides[ldef->sidenum[side]]; - li->frontsector = sides[ldef->sidenum[side]].sector; - if (ldef-> flags & ML_TWOSIDED) - li->backsector = sides[ldef->sidenum[side^1]].sector; - else - li->backsector = 0; - - li->numlights = 0; - li->rlights = NULL; - } - - Z_Free(data); -} - static void P_LoadRawSegs(UINT8 *data, size_t i) { INT32 linedef, side; @@ -581,41 +529,19 @@ static void P_LoadRawSegs(UINT8 *data, size_t i) } } +static void P_LoadSegs(lumpnum_t lumpnum) +{ + UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC); + P_LoadRawSegs(data, W_LumpLength(lumpnum)); + Z_Free(data); +} + /** Loads the SSECTORS resource from a level. * * \param lump Lump number of the SSECTORS resource. * \sa ::ML_SSECTORS */ -static inline void P_LoadSubsectors(lumpnum_t lumpnum) -{ - void *data; - size_t i; - mapsubsector_t *ms; - subsector_t *ss; - - numsubsectors = W_LumpLength(lumpnum) / sizeof (mapsubsector_t); - if (numsubsectors <= 0) - I_Error("Level has no subsectors (did you forget to run it through a nodesbuilder?)"); - ss = subsectors = Z_Calloc(numsubsectors * sizeof (*subsectors), PU_LEVEL, NULL); - data = W_CacheLumpNum(lumpnum,PU_STATIC); - - ms = (mapsubsector_t *)data; - - for (i = 0; i < numsubsectors; i++, ss++, ms++) - { - ss->sector = NULL; - ss->numlines = SHORT(ms->numsegs); - ss->firstline = SHORT(ms->firstseg); -#ifdef FLOORSPLATS - ss->splats = NULL; -#endif - ss->validcount = 0; - } - - Z_Free(data); -} - static inline void P_LoadRawSubsectors(void *data, size_t i) { mapsubsector_t *ms; @@ -640,6 +566,13 @@ static inline void P_LoadRawSubsectors(void *data, size_t i) } } +static void P_LoadSubsectors(lumpnum_t lumpnum) +{ + UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC); + P_LoadRawSubsectors(data, W_LumpLength(lumpnum)); + Z_Free(data); +} + // // levelflats // @@ -765,118 +698,6 @@ INT32 P_CheckLevelFlat(const char *flatname) // Sets up the ingame sectors structures. // Lumpnum is the lumpnum of a SECTORS lump. -static void P_LoadSectors(lumpnum_t lumpnum) -{ - UINT8 *data; - size_t i; - mapsector_t *ms; - 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); - - // 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++) - { - ss->floorheight = SHORT(ms->floorheight)<ceilingheight = SHORT(ms->ceilingheight)<floorpic = P_AddLevelFlat(ms->floorpic, foundflats); - ss->ceilingpic = P_AddLevelFlat(ms->ceilingpic, foundflats); - - ss->lightlevel = SHORT(ms->lightlevel); - ss->special = SHORT(ms->special); - ss->tag = SHORT(ms->tag); - ss->nexttag = ss->firsttag = -1; - ss->spawn_nexttag = ss->spawn_firsttag = -1; - - memset(&ss->soundorg, 0, sizeof(ss->soundorg)); - ss->validcount = 0; - - ss->thinglist = NULL; - ss->touching_thinglist = NULL; - ss->preciplist = NULL; - ss->touching_preciplist = NULL; - - ss->floordata = NULL; - ss->ceilingdata = NULL; - ss->lightingdata = NULL; - - ss->linecount = 0; - ss->lines = NULL; - - ss->heightsec = -1; - ss->camsec = -1; - ss->floorlightsec = -1; - ss->ceilinglightsec = -1; - ss->crumblestate = 0; - ss->ffloors = NULL; - ss->lightlist = NULL; - ss->numlights = 0; - ss->attached = NULL; - ss->attachedsolid = NULL; - ss->numattached = 0; - ss->maxattached = 1; - ss->moved = true; - - ss->extra_colormap = NULL; - - ss->floor_xoffs = ss->ceiling_xoffs = ss->floor_yoffs = ss->ceiling_yoffs = 0; - ss->spawn_flr_xoffs = ss->spawn_ceil_xoffs = ss->spawn_flr_yoffs = ss->spawn_ceil_yoffs = 0; - ss->floorpic_angle = ss->ceilingpic_angle = 0; - ss->spawn_flrpic_angle = ss->spawn_ceilpic_angle = 0; - ss->bottommap = ss->midmap = ss->topmap = -1; - ss->gravity = NULL; - ss->cullheight = NULL; - ss->verticalflip = false; - ss->flags = 0; - ss->flags |= SF_FLIPSPECIAL_FLOOR; - - ss->floorspeed = 0; - ss->ceilspeed = 0; - -#ifdef HWRENDER // ----- for special tricks with HW renderer ----- - ss->pseudoSector = false; - ss->virtualFloor = false; - ss->virtualCeiling = false; - ss->sectorLines = NULL; - ss->stackList = NULL; - ss->lineoutLength = -1.0l; -#endif // ----- end special tricks ----- - } - - Z_Free(data); - - // set the sky flat num - skyflatnum = P_AddLevelFlat(SKYFLATNAME, foundflats); - - // copy table for global usage - levelflats = M_Memcpy(Z_Calloc(numlevelflats * sizeof (*levelflats), PU_LEVEL, NULL), foundflats, numlevelflats * sizeof (levelflat_t)); - free(foundflats); - - // search for animated flats and set up - P_SetupLevelFlatAnims(); -} - static void P_LoadRawSectors(UINT8 *data, size_t i) { mapsector_t *ms; @@ -982,43 +803,16 @@ static void P_LoadRawSectors(UINT8 *data, size_t i) P_SetupLevelFlatAnims(); } -// -// P_LoadNodes -// -static void P_LoadNodes(lumpnum_t lumpnum) +static void P_LoadSectors(lumpnum_t lumpnum) { - UINT8 *data; - size_t i; - UINT8 j, k; - mapnode_t *mn; - node_t *no; - - numnodes = W_LumpLength(lumpnum) / sizeof (mapnode_t); - if (numnodes <= 0) - I_Error("Level has no nodes"); - nodes = Z_Calloc(numnodes * sizeof (*nodes), PU_LEVEL, NULL); - data = W_CacheLumpNum(lumpnum, PU_STATIC); - - mn = (mapnode_t *)data; - no = nodes; - - for (i = 0; i < numnodes; i++, no++, mn++) - { - no->x = SHORT(mn->x)<y = SHORT(mn->y)<dx = SHORT(mn->dx)<dy = SHORT(mn->dy)<children[j] = SHORT(mn->children[j]); - for (k = 0; k < 4; k++) - no->bbox[j][k] = SHORT(mn->bbox[j][k])<x = READINT16(data); - mt->y = READINT16(data); - mt->angle = READINT16(data); - mt->type = READUINT16(data); - mt->options = READUINT16(data); - mt->extrainfo = (UINT8)(mt->type >> 12); - - mt->type &= 4095; - - switch (mt->type) - { - case 1700: // MT_AXIS - case 1701: // MT_AXISTRANSFER - case 1702: // MT_AXISTRANSFERLINE - mt->mobj = NULL; - P_SpawnMapThing(mt); - break; - default: - break; - } - } - Z_Free(datastart); - -} static void P_PrepareRawThings(UINT8 *data, size_t i) { mapthing_t *mt; - UINT8 *datastart; nummapthings = i / (5 * sizeof (INT16)); mapthings = Z_Calloc(nummapthings * sizeof (*mapthings), PU_LEVEL, NULL); // Spawn axis points first so they are // at the front of the list for fast searching. - datastart = data; mt = mapthings; for (i = 0; i < nummapthings; i++, mt++) { @@ -1257,6 +1016,13 @@ static void P_PrepareRawThings(UINT8 *data, size_t i) } } +static void P_PrepareThings(lumpnum_t lumpnum) +{ + UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC); + P_PrepareRawThings(data, W_LumpLength(lumpnum)); + Z_Free(data); +} + static void P_LoadThings(void) { size_t i; @@ -1441,121 +1207,6 @@ void P_WriteThings(lumpnum_t lumpnum) CONS_Printf(M_GetText("newthings%d.lmp saved.\n"), gamemap); } -// -// P_LoadLineDefs -// -static void P_LoadLineDefs(lumpnum_t lumpnum) -{ - UINT8 *data; - size_t i; - maplinedef_t *mld; - line_t *ld; - vertex_t *v1, *v2; - - numlines = W_LumpLength(lumpnum) / sizeof (maplinedef_t); - if (numlines <= 0) - I_Error("Level has no linedefs"); - lines = Z_Calloc(numlines * sizeof (*lines), PU_LEVEL, NULL); - data = W_CacheLumpNum(lumpnum, PU_STATIC); - - mld = (maplinedef_t *)data; - ld = lines; - for (i = 0; i < numlines; i++, mld++, ld++) - { - ld->flags = SHORT(mld->flags); - ld->special = SHORT(mld->special); - ld->tag = SHORT(mld->tag); - v1 = ld->v1 = &vertexes[SHORT(mld->v1)]; - v2 = ld->v2 = &vertexes[SHORT(mld->v2)]; - ld->dx = v2->x - v1->x; - ld->dy = v2->y - v1->y; - -#ifdef WALLSPLATS - ld->splats = NULL; -#endif - - if (!ld->dx) - ld->slopetype = ST_VERTICAL; - else if (!ld->dy) - ld->slopetype = ST_HORIZONTAL; - else if (FixedDiv(ld->dy, ld->dx) > 0) - ld->slopetype = ST_POSITIVE; - else - ld->slopetype = ST_NEGATIVE; - - if (v1->x < v2->x) - { - ld->bbox[BOXLEFT] = v1->x; - ld->bbox[BOXRIGHT] = v2->x; - } - else - { - ld->bbox[BOXLEFT] = v2->x; - ld->bbox[BOXRIGHT] = v1->x; - } - - if (v1->y < v2->y) - { - ld->bbox[BOXBOTTOM] = v1->y; - ld->bbox[BOXTOP] = v2->y; - } - else - { - ld->bbox[BOXBOTTOM] = v2->y; - ld->bbox[BOXTOP] = v1->y; - } - - ld->sidenum[0] = SHORT(mld->sidenum[0]); - ld->sidenum[1] = SHORT(mld->sidenum[1]); - - { - // cph 2006/09/30 - fix sidedef errors right away. - // cph 2002/07/20 - these errors are fatal if not fixed, so apply them - UINT8 j; - - for (j=0; j < 2; j++) - { - if (ld->sidenum[j] != 0xffff && ld->sidenum[j] >= (UINT16)numsides) - { - ld->sidenum[j] = 0xffff; - CONS_Debug(DBG_SETUP, "P_LoadLineDefs: linedef %s has out-of-range sidedef number\n", sizeu1(numlines-i-1)); - } - } - } - - ld->frontsector = ld->backsector = NULL; - ld->validcount = 0; - ld->firsttag = ld->nexttag = -1; - ld->callcount = 0; - // killough 11/98: fix common wad errors (missing sidedefs): - - if (ld->sidenum[0] == 0xffff) - { - ld->sidenum[0] = 0; // Substitute dummy sidedef for missing right side - // cph - print a warning about the bug - CONS_Debug(DBG_SETUP, "P_LoadLineDefs: linedef %s missing first sidedef\n", sizeu1(numlines-i-1)); - } - - if ((ld->sidenum[1] == 0xffff) && (ld->flags & ML_TWOSIDED)) - { - ld->flags &= ~ML_TWOSIDED; // Clear 2s flag for missing left side - // cph - print a warning about the bug - CONS_Debug(DBG_SETUP, "P_LoadLineDefs: linedef %s has two-sided flag set, but no second sidedef\n", sizeu1(numlines-i-1)); - } - - if (ld->sidenum[0] != 0xffff && ld->special) - sides[ld->sidenum[0]].special = ld->special; - if (ld->sidenum[1] != 0xffff && ld->special) - sides[ld->sidenum[1]].special = ld->special; - -#ifdef POLYOBJECTS - ld->polyobj = NULL; -#endif - } - - Z_Free(data); -} - static void P_LoadRawLineDefs(UINT8 *data, size_t i) { maplinedef_t *mld; @@ -1663,6 +1314,13 @@ static void P_LoadRawLineDefs(UINT8 *data, size_t i) } } +static void P_LoadLineDefs(lumpnum_t lumpnum) +{ + UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC); + P_LoadRawLineDefs(data, W_LumpLength(lumpnum)); + Z_Free(data); +} + static void P_LoadLineDefs2(void) { size_t i = numlines; @@ -1761,16 +1419,7 @@ static void P_LoadLineDefs2(void) } } -// -// P_LoadSideDefs -// -static inline void P_LoadSideDefs(lumpnum_t lumpnum) -{ - numsides = W_LumpLength(lumpnum) / sizeof (mapsidedef_t); - if (numsides <= 0) - I_Error("Level has no sidedefs"); - sides = Z_Calloc(numsides * sizeof (*sides), PU_LEVEL, NULL); -} + static inline void P_LoadRawSideDefs(size_t i) { @@ -1780,247 +1429,12 @@ static inline void P_LoadRawSideDefs(size_t i) sides = Z_Calloc(numsides * sizeof (*sides), PU_LEVEL, NULL); } -// Delay loading texture names until after loaded linedefs. - -static void P_LoadSideDefs2(lumpnum_t lumpnum) +static inline void P_LoadSideDefs(lumpnum_t lumpnum) { - UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC); - UINT16 i; - INT32 num; - - for (i = 0; i < numsides; i++) - { - register mapsidedef_t *msd = (mapsidedef_t *)data + i; - register side_t *sd = sides + i; - register sector_t *sec; - - sd->textureoffset = SHORT(msd->textureoffset)<rowoffset = SHORT(msd->rowoffset)<sector); - - if (sector_num >= numsectors) - { - CONS_Debug(DBG_SETUP, "P_LoadSideDefs2: sidedef %u has out-of-range sector num %u\n", i, sector_num); - sector_num = 0; - } - sd->sector = sec = §ors[sector_num]; - } - - // refined to allow colormaps to work as wall textures if invalid as colormaps - // but valid as textures. - - sd->sector = sec = §ors[SHORT(msd->sector)]; - - // Colormaps! - switch (sd->special) - { - case 63: // variable colormap via 242 linedef - case 606: //SoM: 4/4/2000: Just colormap transfer - // SoM: R_CreateColormap will only create a colormap in software mode... - // Perhaps we should just call it instead of doing the calculations here. - if (rendermode == render_soft || rendermode == render_none) - { - if (msd->toptexture[0] == '#' || msd->bottomtexture[0] == '#') - { - sec->midmap = R_CreateColormap(msd->toptexture, msd->midtexture, - msd->bottomtexture); - sd->toptexture = sd->bottomtexture = 0; - } - else - { - if ((num = R_CheckTextureNumForName(msd->toptexture)) == -1) - sd->toptexture = 0; - else - sd->toptexture = num; - if ((num = R_CheckTextureNumForName(msd->midtexture)) == -1) - sd->midtexture = 0; - else - sd->midtexture = num; - if ((num = R_CheckTextureNumForName(msd->bottomtexture)) == -1) - sd->bottomtexture = 0; - else - sd->bottomtexture = num; - } - break; - } -#ifdef HWRENDER - else - { - // for now, full support of toptexture only - if ((msd->toptexture[0] == '#' && msd->toptexture[1] && msd->toptexture[2] && msd->toptexture[3] && msd->toptexture[4] && msd->toptexture[5] && msd->toptexture[6]) - || (msd->bottomtexture[0] == '#' && msd->bottomtexture[1] && msd->bottomtexture[2] && msd->bottomtexture[3] && msd->bottomtexture[4] && msd->bottomtexture[5] && msd->bottomtexture[6])) - { - char *col; - - sec->midmap = R_CreateColormap(msd->toptexture, msd->midtexture, - msd->bottomtexture); - sd->toptexture = sd->bottomtexture = 0; -#define HEX2INT(x) (x >= '0' && x <= '9' ? x - '0' : x >= 'a' && x <= 'f' ? x - 'a' + 10 : x >= 'A' && x <= 'F' ? x - 'A' + 10 : 0) -#define ALPHA2INT(x) (x >= 'a' && x <= 'z' ? x - 'a' : x >= 'A' && x <= 'Z' ? x - 'A' : x >= '0' && x <= '9' ? 25 : 0) - sec->extra_colormap = &extra_colormaps[sec->midmap]; - - if (msd->toptexture[0] == '#' && msd->toptexture[1] && msd->toptexture[2] && msd->toptexture[3] && msd->toptexture[4] && msd->toptexture[5] && msd->toptexture[6]) - { - col = msd->toptexture; - - sec->extra_colormap->rgba = - (HEX2INT(col[1]) << 4) + (HEX2INT(col[2]) << 0) + - (HEX2INT(col[3]) << 12) + (HEX2INT(col[4]) << 8) + - (HEX2INT(col[5]) << 20) + (HEX2INT(col[6]) << 16); - - // alpha - if (msd->toptexture[7]) - sec->extra_colormap->rgba += (ALPHA2INT(col[7]) << 24); - else - sec->extra_colormap->rgba += (25 << 24); - } - else - sec->extra_colormap->rgba = 0; - - if (msd->bottomtexture[0] == '#' && msd->bottomtexture[1] && msd->bottomtexture[2] && msd->bottomtexture[3] && msd->bottomtexture[4] && msd->bottomtexture[5] && msd->bottomtexture[6]) - { - col = msd->bottomtexture; - - sec->extra_colormap->fadergba = - (HEX2INT(col[1]) << 4) + (HEX2INT(col[2]) << 0) + - (HEX2INT(col[3]) << 12) + (HEX2INT(col[4]) << 8) + - (HEX2INT(col[5]) << 20) + (HEX2INT(col[6]) << 16); - - // alpha - if (msd->bottomtexture[7]) - sec->extra_colormap->fadergba += (ALPHA2INT(col[7]) << 24); - else - sec->extra_colormap->fadergba += (25 << 24); - } - else - sec->extra_colormap->fadergba = 0x19000000; // default alpha, (25 << 24) -#undef ALPHA2INT -#undef HEX2INT - } - else - { - if ((num = R_CheckTextureNumForName(msd->toptexture)) == -1) - sd->toptexture = 0; - else - sd->toptexture = num; - - if ((num = R_CheckTextureNumForName(msd->midtexture)) == -1) - sd->midtexture = 0; - else - sd->midtexture = num; - - if ((num = R_CheckTextureNumForName(msd->bottomtexture)) == -1) - sd->bottomtexture = 0; - else - sd->bottomtexture = num; - } - break; - } -#endif - - case 413: // Change music - { - char process[8+1]; - - sd->toptexture = sd->midtexture = sd->bottomtexture = 0; - if (msd->bottomtexture[0] != '-' || msd->bottomtexture[1] != '\0') - { - M_Memcpy(process,msd->bottomtexture,8); - process[8] = '\0'; - sd->bottomtexture = get_number(process)-1; - } - M_Memcpy(process,msd->toptexture,8); - process[8] = '\0'; - sd->text = Z_Malloc(7, PU_LEVEL, NULL); - - // If they type in O_ or D_ and their music name, just shrug, - // then copy the rest instead. - if ((process[0] == 'O' || process[0] == 'D') && process[7]) - M_Memcpy(sd->text, process+2, 6); - else // Assume it's a proper music name. - M_Memcpy(sd->text, process, 6); - sd->text[6] = 0; - break; - } - - case 4: // Speed pad parameters - case 414: // Play SFX - { - sd->toptexture = sd->midtexture = sd->bottomtexture = 0; - if (msd->toptexture[0] != '-' || msd->toptexture[1] != '\0') - { - char process[8+1]; - M_Memcpy(process,msd->toptexture,8); - process[8] = '\0'; - sd->toptexture = get_number(process); - } - break; - } - - case 14: // Bustable block parameters - case 15: // Fan particle spawner parameters - case 425: // Calls P_SetMobjState on calling mobj - case 434: // Custom Power - case 442: // Calls P_SetMobjState on mobjs of a given type in the tagged sectors - { - char process[8*3+1]; - memset(process,0,8*3+1); - sd->toptexture = sd->midtexture = sd->bottomtexture = 0; - if (msd->toptexture[0] == '-' && msd->toptexture[1] == '\0') - break; - else - M_Memcpy(process,msd->toptexture,8); - if (msd->midtexture[0] != '-' || msd->midtexture[1] != '\0') - M_Memcpy(process+strlen(process), msd->midtexture, 8); - if (msd->bottomtexture[0] != '-' || msd->bottomtexture[1] != '\0') - M_Memcpy(process+strlen(process), msd->bottomtexture, 8); - sd->toptexture = get_number(process); - break; - } - - case 443: // Calls a named Lua function - { - char process[8*3+1]; - memset(process,0,8*3+1); - sd->toptexture = sd->midtexture = sd->bottomtexture = 0; - if (msd->toptexture[0] == '-' && msd->toptexture[1] == '\0') - break; - else - M_Memcpy(process,msd->toptexture,8); - if (msd->midtexture[0] != '-' || msd->midtexture[1] != '\0') - M_Memcpy(process+strlen(process), msd->midtexture, 8); - if (msd->bottomtexture[0] != '-' || msd->bottomtexture[1] != '\0') - M_Memcpy(process+strlen(process), msd->bottomtexture, 8); - sd->text = Z_Malloc(strlen(process)+1, PU_LEVEL, NULL); - M_Memcpy(sd->text, process, strlen(process)+1); - break; - } - - default: // normal cases - if (msd->toptexture[0] == '#') - { - char *col = msd->toptexture; - sd->toptexture = sd->bottomtexture = - ((col[1]-'0')*100 + (col[2]-'0')*10 + col[3]-'0') + 1; - sd->midtexture = R_TextureNumForName(msd->midtexture); - } - else - { - sd->midtexture = R_TextureNumForName(msd->midtexture); - sd->toptexture = R_TextureNumForName(msd->toptexture); - sd->bottomtexture = R_TextureNumForName(msd->bottomtexture); - } - break; - } - } - - Z_Free(data); - R_ClearTextureNumCache(true); + P_LoadRawSideDefs(W_LumpLength(lumpnum)); } -// I'm sorry about all this duplicity with little change :( -Nev3r + static void P_LoadRawSideDefs2(void *data) { UINT16 i; @@ -2253,7 +1667,15 @@ static void P_LoadRawSideDefs2(void *data) break; } } + R_ClearTextureNumCache(true); +} +// Delay loading texture names until after loaded linedefs. +static void P_LoadSideDefs2(lumpnum_t lumpnum) +{ + UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC); + P_LoadRawSideDefs2(data); + Z_Free(data); R_ClearTextureNumCache(true); } @@ -3146,7 +2568,7 @@ boolean P_SetupLevel(boolean skipprecip) // use gamemap to get map number. // 99% of the things already did, so. // Map header should always be in place at this point - boolean isLumpWad = false; // Is the lump a marker or actually a WAD file of its own? (For PK3s) + char *lumpfullName; INT32 i, loadprecip = 1, ranspecialwipe = 0; INT32 loademblems = 1; INT32 fromnetsave = 0; @@ -3309,50 +2731,8 @@ boolean P_SetupLevel(boolean skipprecip) // internal game map maplumpname = G_BuildMapName(gamemap); - lastloadedmaplumpnum = LUMPERROR; - - // Look for valid map data through all added files in descendant order. - // Get a map marker for WADs, and a standalone WAD file lump inside PK3s. - // TODO: Make it search through cache first, maybe...? - // TODO: Also move it to w_wad.c as a function...? - for (i = numwadfiles - 1; i >= 0; i--) - { - if (wadfiles[i]->type == RET_WAD) - { - UINT16 lumpNum; - for (lumpNum = 0; lumpNum < wadfiles[i]->numlumps; lumpNum++) - { - if (!strncmp(maplumpname, (wadfiles[i]->lumpinfo + lumpNum)->name, 8)) - { - lastloadedmaplumpnum = (i<<16) + lumpNum; - CONS_Printf("WAD %s has a map marker named %s.\n", wadfiles[i]->filename, maplumpname); - break; - } - } - } - else if (wadfiles[i]->type == RET_PK3) - { - // Look for the maps folder. - UINT16 lumpNum, end; - lumpNum = W_CheckNumForFullNamePK3("maps/", i, 0); - if (lumpNum != INT16_MAX) - end = W_CheckNumForFolderEndPK3("maps/", i, lumpNum); - else - continue; - - // Now look for the specified map. - for (++lumpNum; lumpNum < end; lumpNum++) - if (!strnicmp(maplumpname, (wadfiles[i]->lumpinfo + lumpNum)->name, 5)) - { - isLumpWad = true; - lastloadedmaplumpnum = (i<<16) + lumpNum; - CONS_Printf("PK3 %s has a map WAD named %s.\n", wadfiles[i]->filename, maplumpname); - break; - } - } - if (!(lastloadedmaplumpnum == LUMPERROR)) // Stop looking if we found a valid lump. - break; - } + //lastloadedmaplumpnum = LUMPERROR; + lastloadedmaplumpnum = W_CheckNumForName(maplumpname); if (lastloadedmaplumpnum == INT16_MAX) I_Error("Map %s not found.\n", maplumpname); @@ -3370,24 +2750,12 @@ boolean P_SetupLevel(boolean skipprecip) // As it is implemented right now, we're assuming an uncompressed WAD. // (As in, a normal PWAD, not ZWAD or anything. The lump itself can be compressed.) // Basically this is a nerfed&modified version of W_InitFile from w_wad. - if (isLumpWad) + lumpfullName = (wadfiles[WADFILENUM(lastloadedmaplumpnum)]->lumpinfo + LUMPNUM(lastloadedmaplumpnum))->name2; + if (!strnicmp(lumpfullName + strlen(lumpfullName) - 4, ".wad", 4)) { - UINT16 i; - wadinfo_t *header; - filelump_t *fileinfo; + // Remember that we're assuming that the WAD will have a specific set of lumps in a specific order. UINT8 *wadData = W_CacheLumpNum(lastloadedmaplumpnum, PU_STATIC); - header = (wadinfo_t *)wadData; - CONS_Printf("This map WAD contains %lu lumps.\n", header->numlumps); - - fileinfo = wadData + header->infotableofs; - for(i = 0; i < header->numlumps; i++, fileinfo++) - { - char name[9]; - memcpy(name, fileinfo->name, 8); - name[8] = '\0'; - CONS_Printf("%s, size %lu\n", name, fileinfo->size); - } - fileinfo = wadData + header->infotableofs; + filelump_t *fileinfo = wadData + ((wadinfo_t *)wadData)->infotableofs; P_LoadRawVertexes(wadData + (fileinfo + ML_VERTEXES)->filepos, (fileinfo + ML_VERTEXES)->size); P_LoadRawSectors(wadData + (fileinfo + ML_SECTORS)->filepos, (fileinfo + ML_SECTORS)->size); @@ -3803,32 +3171,6 @@ void P_LoadMusicsRange(UINT16 wadnum, UINT16 first, UINT16 num) return; } -// Auxiliary function for PK3 loading - adds extra lumps -// NOTE: does nothing but print debug messages. -/*void P_LoadWadMapRange(UINT16 wadnum, UINT16 first, UINT16 num) -{ - lumpinfo_t *lumpinfo = wadfiles[wadnum]->lumpinfo + first; - CONS_Printf("First %s\n", lumpinfo->name2); - for (; num > 0; num--, first++, lumpinfo++) - { - wadinfo_t header; - void* wadCache = Z_Malloc(W_LumpLengthPwad(wadnum, first), PU_STATIC, NULL); - W_ReadLumpHeaderPwad(wadnum, first, wadCache, 0, 0); - // We put the header info into our header var. - memcpy(header, wadCache, sizeof header); - - header.numlumps = LONG(header.numlumps); - header.infotableofs = LONG(header.infotableofs); - lumpinfo = (lumpinfo_t*) Z_Realloc(lumpinfo, (numlumps + 1)*sizeof(*lumpinfo), PU_STATIC, NULL); - - - Z_Free(wadCache); - CONS_Printf("Decached map WAD stuff.\n"); - } - return; -}*/ - - // // Add a wadfile to the active wad files, // replace sounds, musics, patches, textures, sprites and maps @@ -3962,12 +3304,6 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname) // 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) @@ -3977,6 +3313,11 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname) if (!devparm && digmreplaces) CONS_Printf(M_GetText("%s digital musics replaced\n"), sizeu1(digmreplaces)); + // 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/w_wad.c b/src/w_wad.c index b86d8bd28..3fe580d71 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -474,6 +474,7 @@ UINT16 W_InitFile(const char *filename) // (Declaring all those vars might not be the optimal way to do this, sorry.) char *eName; int namePos; + int nameEnd; unsigned short int eNameLen = 8; unsigned short int eXFieldLen = 0; unsigned short int lNameLen = 0; @@ -527,8 +528,14 @@ UINT16 W_InitFile(const char *filename) break; } } + // We will remove the file extension too. + nameEnd = 0; + while(nameEnd++ < 8) + if(eName[namePos + nameEnd] == '.') + break; + memset(lumpinfo[numlumps].name, '\0', 9); - strncpy(lumpinfo[numlumps].name, eName + namePos, 8); + strncpy(lumpinfo[numlumps].name, eName + namePos, nameEnd); lumpinfo[numlumps].name2 = Z_Malloc((eNameLen+1)*sizeof(char), PU_STATIC, NULL); strncpy(lumpinfo[numlumps].name2, eName, eNameLen); @@ -923,6 +930,37 @@ lumpnum_t W_CheckNumForName(const char *name) } } +// Look for valid map data through all added files in descendant order. +// Get a map marker for WADs, and a standalone WAD file lump inside PK3s. +// TODO: Make it search through cache first, maybe...? +lumpnum_t W_CheckNumForMap(const char *name) +{ + UINT16 lumpNum, end; + UINT32 i; + for (i = numwadfiles - 1; i >= 0; i--) + { + if (wadfiles[i]->type == RET_WAD) + { + for (lumpNum = 0; lumpNum < wadfiles[i]->numlumps; lumpNum++) + if (!strncmp(name, (wadfiles[i]->lumpinfo + lumpNum)->name, 8)) + return (i<<16) + lumpNum; + } + else if (wadfiles[i]->type == RET_PK3) + { + lumpNum = W_CheckNumForFullNamePK3("maps/", i, 0); + if (lumpNum != INT16_MAX) + end = W_CheckNumForFolderEndPK3("maps/", i, lumpNum); + else + continue; + // Now look for the specified map. + for (++lumpNum; lumpNum < end; lumpNum++) + if (!strnicmp(name, (wadfiles[i]->lumpinfo + lumpNum)->name, 8)) + return (i<<16) + lumpNum; + } + } + return LUMPERROR; +} + // // W_GetNumForName // diff --git a/src/w_wad.h b/src/w_wad.h index d5e6e9017..b0b0ca951 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -119,6 +119,7 @@ UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump); // UINT16 W_CheckNumForFullNamePK3(const char *name, UINT16 wad, UINT16 startlump); UINT16 W_CheckNumForFolderEndPK3(const char *name, UINT16 wad, UINT16 startlump); +lumpnum_t W_CheckNumForMap(const char *name); lumpnum_t W_CheckNumForName(const char *name); lumpnum_t W_GetNumForName(const char *name); // like W_CheckNumForName but I_Error on LUMPERROR lumpnum_t W_CheckNumForNameInBlock(const char *name, const char *blockstart, const char *blockend); From 16336dbe22689d584b19ff9395da2dfe357778e4 Mon Sep 17 00:00:00 2001 From: Nevur Date: Sun, 28 May 2017 21:47:15 +0200 Subject: [PATCH 17/35] I'm pushing this because I'm having issues. Changes so far: -Folders aren't loaded as lumps anymore -Can now load an arbitrary number of TEXTURES lumps in PK3s. Name them textures.gfz, textures.thz, ..., for example. --- src/r_data.c | 34 ++++++++++++++++++++-------------- src/r_things.c | 12 +++++------- src/w_wad.c | 35 ++++++++++++++++++++++++++--------- src/w_wad.h | 1 + 4 files changed, 52 insertions(+), 30 deletions(-) diff --git a/src/r_data.c b/src/r_data.c index 4f1be210f..65ec67bc1 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -569,20 +569,23 @@ void R_LoadTextures(void) { if (wadfiles[w]->type == RET_PK3) { - texstart = W_CheckNumForFullNamePK3("textures/", (UINT16)w, 0) + 1; + texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0); texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart); - texturesLumpPos = W_CheckNumForFullNamePK3("textures", (UINT16)w, 0); + texturesLumpPos = W_CheckNumForFullNamePK3("TEXTURES", (UINT16)w, 0); + while (texturesLumpPos != INT16_MAX) + { + CONS_Printf("AAA\n"); + numtextures += R_CountTexturesInTEXTURESLump((UINT16)w, (UINT16)texturesLumpPos); + texturesLumpPos = W_CheckNumForFullNamePK3("TEXTURES", (UINT16)w, texturesLumpPos + 1); + } } else { texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0) + 1; texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0); texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0); - } - - if (texturesLumpPos != INT16_MAX) - { - numtextures += R_CountTexturesInTEXTURESLump((UINT16)w, (UINT16)texturesLumpPos); + if (texturesLumpPos != INT16_MAX) + numtextures += R_CountTexturesInTEXTURESLump((UINT16)w, (UINT16)texturesLumpPos); } // Add all the textures between TX_START and TX_END @@ -597,7 +600,6 @@ void R_LoadTextures(void) I_Error("No textures detected in any WADs!\n"); } } - CONS_Printf("We got a number of %d textures.\n", numtextures); // Allocate memory and initialize to 0 for all the textures we are initialising. // There are actually 5 buffers allocated in one for convenience. textures = Z_Calloc((numtextures * sizeof(void *)) * 5, PU_STATIC, NULL); @@ -621,20 +623,24 @@ 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("textures/", (UINT16)w, 0) + 1; + texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0); texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart); - texturesLumpPos = W_CheckNumForFullNamePK3("textures", (UINT16)w, 0); + texturesLumpPos = W_CheckNumForFullNamePK3("TEXTURES", (UINT16)w, 0); + while (texturesLumpPos != INT16_MAX) + { + R_ParseTEXTURESLump(w, texturesLumpPos, &i); + texturesLumpPos = W_CheckNumForFullNamePK3("TEXTURES", (UINT16)w, texturesLumpPos + 1); + } } else { texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0) + 1; texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0); texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0); + if (texturesLumpPos != INT16_MAX) + R_ParseTEXTURESLump(w, texturesLumpPos, &i); } - if (texturesLumpPos != INT16_MAX) - R_ParseTEXTURESLump(w, texturesLumpPos, &i); - if (texstart == INT16_MAX || texend == INT16_MAX) continue; @@ -1229,7 +1235,7 @@ lumpnum_t R_GetFlatNumForName(const char *name) } else if (wadfiles[i]->type == RET_PK3) { - start = W_CheckNumForFullNamePK3("Flats/", i, 0); + start = W_CheckNumForFolderStartPK3("Flats/", i, 0); if (start == INT16_MAX) continue; end = W_CheckNumForFolderEndPK3("Flats/", i, start); diff --git a/src/r_things.c b/src/r_things.c index 54a0d2b26..44b5ce536 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -415,15 +415,13 @@ void R_AddSpriteDefs(UINT16 wadnum) start = W_CheckNumForNamePwad("S_START", wadnum, 0); if (start == UINT16_MAX) start = W_CheckNumForNamePwad("SS_START", wadnum, 0); //deutex compatib. + if (start == UINT16_MAX) + start = 0; //let say S_START is lump 0 + else + start++; // just after S_START } else if (wadfiles[wadnum]->type == RET_PK3) - start = W_CheckNumForFullNamePK3("Sprites/", wadnum, 0); - - if (start == UINT16_MAX) - start = 0; //let say S_START is lump 0 - else - start++; // just after S_START - + start = W_CheckNumForFolderStartPK3("Sprites/", wadnum, 0); // ignore skin wads (we don't want skin sprites interfering with vanilla sprites) if (start == 0 && W_CheckNumForNamePwad("S_SKIN", wadnum, 0) != UINT16_MAX) diff --git a/src/w_wad.c b/src/w_wad.c index 3fe580d71..209578f62 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -175,18 +175,18 @@ FILE *W_OpenWadFile(const char **filename, boolean useerrors) static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum) { UINT16 posStart, posEnd; - posStart = W_CheckNumForFullNamePK3("Lua/", wadnum, 0); + posStart = W_CheckNumForFolderStartPK3("Lua/", wadnum, 0); if (posStart != INT16_MAX) { posEnd = W_CheckNumForFolderEndPK3("Lua/", wadnum, posStart); - for (++posStart; posStart < posEnd; posStart++) + for (posStart; posStart < posEnd; posStart++) LUA_LoadLump(wadnum, posStart); } - posStart = W_CheckNumForFullNamePK3("SOCs/", wadnum, 0); + posStart = W_CheckNumForFolderStartPK3("SOCs/", wadnum, 0); if (posStart != INT16_MAX) { posEnd = W_CheckNumForFolderEndPK3("SOCs/", wadnum, posStart); - for(++posStart; posStart < posEnd; posStart++) + for(posStart; posStart < posEnd; posStart++) DEH_LoadDehackedLumpPwad(wadnum, posStart); } } @@ -430,7 +430,7 @@ UINT16 W_InitFile(const char *filename) size = ftell(handle); CONS_Debug(DBG_SETUP, "PK3 size is: %ld\n", size); - // We must look for the central directory through the file. + // We must look for the central directory through the file. (Thanks to JTE for this algorithm.) // All of the central directory entry headers have a signature of 0x50 0x4b 0x01 0x02. // The first entry found means the beginning of the central directory. rewind(handle); @@ -502,6 +502,11 @@ UINT16 W_InitFile(const char *filename) eName = malloc(sizeof(char)*(eNameLen + 1)); fgets(eName, eNameLen + 1, handle); + + // Don't load lump if folder. + if (*(eName + eNameLen - 1) == '/') + continue; + if (numlumps == 0) // First lump? Let's allocate the first lumpinfo block. lumpinfo = Z_Malloc(sizeof(*lumpinfo), PU_STATIC, NULL); else // Otherwise, reallocate and increase by 1. Might not be optimal, though... @@ -558,7 +563,6 @@ UINT16 W_InitFile(const char *filename) lumpinfo[numlumps].compression = CM_UNSUPPORTED; break; } - CONS_Printf("File %s, Shortname %s, data begins at: %ld\n", eName, lumpinfo[numlumps].name, lumpinfo[numlumps].position); CONS_Debug(DBG_SETUP, "File %s, data begins at: %ld\n", eName, lumpinfo[numlumps].position); fseek(handle, eXFieldLen + eCommentLen, SEEK_CUR); // We skip to where we expect the next central directory entry or end marker to be. numlumps++; @@ -569,7 +573,7 @@ UINT16 W_InitFile(const char *filename) { CONS_Debug(DBG_SETUP, "Central directory end signature found at: %ld\n", ftell(handle)); - // We will create a "virtual" marker lump at the very end of lumpinfo for convenience. + /*// We will create a "virtual" marker lump at the very end of lumpinfo for convenience. // This marker will be used by the different lump-seeking (eg. textures, sprites, etc.) in PK3-specific cases in an auxiliary way. lumpinfo = (lumpinfo_t*) Z_Realloc(lumpinfo, (numlumps + 1)*sizeof(*lumpinfo), PU_STATIC, NULL); strcpy(lumpinfo[numlumps].name, "PK3_ENDM\0"); @@ -579,7 +583,7 @@ UINT16 W_InitFile(const char *filename) lumpinfo[numlumps].size = 0; lumpinfo[numlumps].disksize = 0; lumpinfo[numlumps].compression = CM_NONE; - numlumps++; + numlumps++;*/ break; } // ... None of them? We're only expecting either a central directory signature entry or the central directory end signature. @@ -858,6 +862,19 @@ UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump) return INT16_MAX; } +// Look for the first lump from a folder. +UINT16 W_CheckNumForFolderStartPK3(const char *name, UINT16 wad, UINT16 startlump) +{ + INT32 i; + lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump; + for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++) + { + if (strnicmp(name, lump_p->name2, strlen(name)) == 0) + break; + } + return i; +} + // In a PK3 type of resource file, it looks for the next lumpinfo entry that doesn't share the specified pathfile. // Useful for finding folder ends. // Returns the position of the lumpinfo entry. @@ -947,7 +964,7 @@ lumpnum_t W_CheckNumForMap(const char *name) } else if (wadfiles[i]->type == RET_PK3) { - lumpNum = W_CheckNumForFullNamePK3("maps/", i, 0); + lumpNum = W_CheckNumForFolderStartPK3("maps/", i, 0); if (lumpNum != INT16_MAX) end = W_CheckNumForFolderEndPK3("maps/", i, lumpNum); else diff --git a/src/w_wad.h b/src/w_wad.h index b0b0ca951..2c50da5cc 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -117,6 +117,7 @@ const char *W_CheckNameForNum(lumpnum_t lumpnum); UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump); // checks only in one pwad UINT16 W_CheckNumForFullNamePK3(const char *name, UINT16 wad, UINT16 startlump); +UINT16 W_CheckNumForFolderStartPK3(const char *name, UINT16 wad, UINT16 startlump); UINT16 W_CheckNumForFolderEndPK3(const char *name, UINT16 wad, UINT16 startlump); lumpnum_t W_CheckNumForMap(const char *name); From 35189dc21902e73ebe041ebff2ddb9ae07493d1f Mon Sep 17 00:00:00 2001 From: Nevur Date: Sun, 25 Jun 2017 14:02:39 +0200 Subject: [PATCH 18/35] Fixed PK3s. -Colormaps, palettes and other stuff are properly loaded now. It was a bug related to the generation of the lump name with files in the root of the PK3. Known issues: -Map WADs' REJECT and BLOCKMAP are still not loaded. --- src/p_setup.c | 38 ++++++-------------------------------- src/r_data.c | 10 ++++------ src/w_wad.c | 8 ++------ 3 files changed, 12 insertions(+), 44 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 2cc70e6a0..896f38ba9 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2746,10 +2746,10 @@ boolean P_SetupLevel(boolean skipprecip) P_MakeMapMD5(lastloadedmaplumpnum, &mapmd5); - // HACK ALERT: Cache the WAD, get the map data into the table, free memory. + // HACK ALERT: Cache the WAD, get the map data into the tables, free memory. // As it is implemented right now, we're assuming an uncompressed WAD. // (As in, a normal PWAD, not ZWAD or anything. The lump itself can be compressed.) - // Basically this is a nerfed&modified version of W_InitFile from w_wad. + // We're not accounting for extra lumps and scrambled lump positions. Any additional data will cause an error. lumpfullName = (wadfiles[WADFILENUM(lastloadedmaplumpnum)]->lumpinfo + LUMPNUM(lastloadedmaplumpnum))->name2; if (!strnicmp(lumpfullName + strlen(lumpfullName) - 4, ".wad", 4)) { @@ -2765,7 +2765,6 @@ boolean P_SetupLevel(boolean skipprecip) P_LoadRawSubsectors(wadData + (fileinfo + ML_SSECTORS)->filepos, (fileinfo + ML_SSECTORS)->size); P_LoadRawNodes(wadData + (fileinfo + ML_NODES)->filepos, (fileinfo + ML_NODES)->size); P_LoadRawSegs(wadData + (fileinfo + ML_SEGS)->filepos, (fileinfo + ML_SEGS)->size); -// P_LoadReject(lastloadedmaplumpnum + ML_REJECT); // Important: take care of the ordering of the next functions. if (!loadedbm) @@ -3106,27 +3105,6 @@ 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) @@ -3150,8 +3128,8 @@ void P_LoadSoundsRange(UINT16 wadnum, UINT16 first, UINT16 num) } } -// Auxiliary function for PK3 loading - looks for sound replacements. -// NOTE: does nothing but print debug messages. +// Auxiliary function for PK3 loading - looks for music and music replacements. +// NOTE: does nothing but print debug messages. The code is handled somewhere else. void P_LoadMusicsRange(UINT16 wadnum, UINT16 first, UINT16 num) { lumpinfo_t *lumpinfo = wadfiles[wadnum]->lumpinfo + first; @@ -3195,7 +3173,7 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname) UINT16 texPos, texNum = 0; // UINT16 patPos, patNum = 0; // UINT16 flaPos, flaNum = 0; - UINT16 mapPos, mapNum = 0; +// UINT16 mapPos, mapNum = 0; // Init file. if ((numlumps = W_InitFile(wadfilename)) == INT16_MAX) @@ -3218,12 +3196,8 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname) lumpinfo++; *start = ++i; for (; i < numlumps; i++, lumpinfo++) - { if (strnicmp(lumpinfo->name2, folName, strlen(folName))) - { break; - } - } lumpinfo--; *end = i-- - *start; return; @@ -3243,7 +3217,7 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname) FindFolder("Textures/", &texPos, &texNum); // FindFolder("Patches/", &patPos, &patNum); // FindFolder("Flats/", &flaPos, &flaNum); - FindFolder("Maps/", &mapPos, &mapNum); +// FindFolder("Maps/", &mapPos, &mapNum); } // Update the detected resources. diff --git a/src/r_data.c b/src/r_data.c index 65ec67bc1..dcfdb27a5 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -571,12 +571,11 @@ void R_LoadTextures(void) { texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0); texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart); - texturesLumpPos = W_CheckNumForFullNamePK3("TEXTURES", (UINT16)w, 0); + texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0); while (texturesLumpPos != INT16_MAX) { - CONS_Printf("AAA\n"); numtextures += R_CountTexturesInTEXTURESLump((UINT16)w, (UINT16)texturesLumpPos); - texturesLumpPos = W_CheckNumForFullNamePK3("TEXTURES", (UINT16)w, texturesLumpPos + 1); + texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, texturesLumpPos + 1); } } else @@ -625,11 +624,11 @@ void R_LoadTextures(void) { texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0); texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart); - texturesLumpPos = W_CheckNumForFullNamePK3("TEXTURES", (UINT16)w, 0); + texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0); while (texturesLumpPos != INT16_MAX) { R_ParseTEXTURESLump(w, texturesLumpPos, &i); - texturesLumpPos = W_CheckNumForFullNamePK3("TEXTURES", (UINT16)w, texturesLumpPos + 1); + texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, texturesLumpPos + 1); } } else @@ -1300,7 +1299,6 @@ void R_ReInitColormaps(UINT16 num) { char colormap[9] = "COLORMAP"; lumpnum_t lump; - CONS_Printf("Reinitting colormaps...\n"); if (num > 0 && num <= 10000) snprintf(colormap, 8, "CLM%04u", num-1); diff --git a/src/w_wad.c b/src/w_wad.c index 209578f62..4b0665679 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -523,22 +523,18 @@ UINT16 W_InitFile(const char *filename) fseek(handle, rememberPos, SEEK_SET); // Let's go back to the central dir. lumpinfo[numlumps].disksize = eCompSize; lumpinfo[numlumps].size = eSize; + // We will trim the file's full name so that only the filename is left. namePos = eNameLen - 1; while(namePos--) - { if(eName[namePos] == '/') - { - namePos++; break; - } - } + namePos++; // We will remove the file extension too. nameEnd = 0; while(nameEnd++ < 8) if(eName[namePos + nameEnd] == '.') break; - memset(lumpinfo[numlumps].name, '\0', 9); strncpy(lumpinfo[numlumps].name, eName + namePos, nameEnd); From d3a652aa152f6b519f7ad6a27e9f0564d2c89bde Mon Sep 17 00:00:00 2001 From: Nevur Date: Sun, 25 Jun 2017 15:39:45 +0200 Subject: [PATCH 19/35] Fix merge issue. --- src/p_setup.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/p_setup.c b/src/p_setup.c index 896f38ba9..457732e50 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2781,6 +2781,9 @@ boolean P_SetupLevel(boolean skipprecip) for (i = 0; i < 2; i++) skyboxmo[i] = NULL; + for (i = 0; i < 16; i++) + skyboxviewpnts[i] = skyboxcenterpnts[i] = NULL; + P_MapStart(); P_PrepareRawThings(wadData + (fileinfo + ML_THINGS)->filepos, (fileinfo + ML_THINGS)->size); @@ -2815,16 +2818,25 @@ boolean P_SetupLevel(boolean skipprecip) for (i = 0; i < 2; i++) skyboxmo[i] = NULL; + for (i = 0; i < 16; i++) + skyboxviewpnts[i] = skyboxcenterpnts[i] = NULL; + P_MapStart(); P_PrepareThings(lastloadedmaplumpnum + ML_THINGS); } + // init gravity, tag lists, + // anything that P_ResetDynamicSlopes/P_LoadThings needs to know + P_InitSpecials(); + #ifdef ESLOPE P_ResetDynamicSlopes(); #endif P_LoadThings(); + skyboxmo[0] = skyboxviewpnts[0]; + skyboxmo[1] = skyboxcenterpnts[0]; P_SpawnSecretItems(loademblems); From f6bd414f355daeb06ef2aaa190a6747895ebf708 Mon Sep 17 00:00:00 2001 From: Nevur Date: Sun, 25 Jun 2017 18:30:53 +0200 Subject: [PATCH 20/35] Fixed stuff which I removed accidentally when manually tweaking p_setup.c on the merge. --- src/p_setup.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 457732e50..216188827 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2317,6 +2317,18 @@ void P_LoadThingsOnly(void) // Search through all the thinkers. mobj_t *mo; thinker_t *think; + INT32 i, viewid = -1, centerid = -1; // for skyboxes + + // check if these are any of the normal viewpoint/centerpoint mobjs in the level or not + if (skyboxmo[0] || skyboxmo[1]) + for (i = 0; i < 16; i++) + { + if (skyboxmo[0] && skyboxmo[0] == skyboxviewpnts[i]) + viewid = i; // save id just in case + if (skyboxmo[1] && skyboxmo[1] == skyboxcenterpnts[i]) + centerid = i; // save id just in case + } + for (think = thinkercap.next; think != &thinkercap; think = think->next) { @@ -2334,6 +2346,10 @@ void P_LoadThingsOnly(void) P_PrepareThings(lastloadedmaplumpnum + ML_THINGS); P_LoadThings(); + + // restore skybox viewpoint/centerpoint if necessary, set them to defaults if we can't do that + skyboxmo[0] = skyboxviewpnts[(viewid >= 0) ? viewid : 0]; + skyboxmo[1] = skyboxcenterpnts[(centerid >= 0) ? centerid : 0]; P_SpawnSecretItems(true); } @@ -2616,8 +2632,7 @@ boolean P_SetupLevel(boolean skipprecip) postimgtype = postimgtype2 = postimg_none; - if (mapheaderinfo[gamemap-1]->forcecharacter[0] != '\0' - && atoi(mapheaderinfo[gamemap-1]->forcecharacter) != 255) + if (mapheaderinfo[gamemap-1]->forcecharacter[0] != '\0') P_ForceCharacter(mapheaderinfo[gamemap-1]->forcecharacter); // chasecam on in chaos, race, coop @@ -2850,8 +2865,6 @@ boolean P_SetupLevel(boolean skipprecip) if (loadprecip) // ugly hack for P_NetUnArchiveMisc (and P_LoadNetGame) P_SpawnPrecipitation(); - globalweather = mapheaderinfo[gamemap-1]->weather; - #ifdef HWRENDER // not win32 only 19990829 by Kin if (rendermode != render_soft && rendermode != render_none) { From 677c1045a15eb7570ec6d1724f180353300e1ba3 Mon Sep 17 00:00:00 2001 From: Nevur Date: Sun, 25 Jun 2017 23:04:51 +0200 Subject: [PATCH 21/35] The sprites stuff is changed now. -PK3 loadtime drastically reduced, even for very big files. -Looks for srb2.pk3 now instead. -"flipped the switch" for sprites. --- src/d_main.c | 2 +- src/r_things.h | 4 ++-- src/w_wad.c | 61 +++++++++++++++++++++++++------------------------- 3 files changed, 34 insertions(+), 33 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index be06acb2e..98411f28f 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -819,7 +819,7 @@ static void IdentifyVersion(void) if (srb2wad1 == NULL && srb2wad2 == NULL) I_Error("No more free memory to look in %s", srb2waddir); if (srb2wad1 != NULL) - sprintf(srb2wad1, pandf, srb2waddir, "srb2.srb"); + sprintf(srb2wad1, pandf, srb2waddir, "srb2.pk3"); if (srb2wad2 != NULL) sprintf(srb2wad2, pandf, srb2waddir, "srb2.wad"); diff --git a/src/r_things.h b/src/r_things.h index 441d32087..eb4f9bbf5 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -227,7 +227,7 @@ char *GetPlayerFacePic(INT32 skinnum); // Future: [[ ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz!@ ]] FUNCMATH FUNCINLINE static ATTRINLINE char R_Frame2Char(UINT8 frame) { -#if 1 // 2.1 compat +#if 0 // 2.1 compat return 'A' + frame; #else if (frame < 26) return 'A' + frame; @@ -241,7 +241,7 @@ FUNCMATH FUNCINLINE static ATTRINLINE char R_Frame2Char(UINT8 frame) FUNCMATH FUNCINLINE static ATTRINLINE UINT8 R_Char2Frame(char cn) { -#if 1 // 2.1 compat +#if 0 // 2.1 compat return cn - 'A'; #else if (cn >= 'A' && cn <= 'Z') return cn - 'A'; diff --git a/src/w_wad.c b/src/w_wad.c index 4b0665679..91eaba81b 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -309,7 +309,7 @@ UINT16 W_InitFile(const char *filename) lumpinfo_t *lumpinfo; wadfile_t *wadfile; enum restype type; - UINT32 numlumps; + UINT16 numlumps; size_t i; INT32 compressed = 0; size_t packetsize = 0; @@ -417,11 +417,12 @@ UINT16 W_InitFile(const char *filename) char curHeader[4]; unsigned long size; char seekPat[] = {0x50, 0x4b, 0x01, 0x02, 0x00}; - char endPat[] = {0x50, 0x4b, 0x05, 0x06, 0xff}; + char endPat[] = {0x50, 0x4b, 0x05, 0x06, 0x00}; char *s; int c; + UINT32 position; boolean matched = FALSE; - numlumps = 0; + lumpinfo_t *lump_p; type = RET_PK3; @@ -433,19 +434,18 @@ UINT16 W_InitFile(const char *filename) // We must look for the central directory through the file. (Thanks to JTE for this algorithm.) // All of the central directory entry headers have a signature of 0x50 0x4b 0x01 0x02. // The first entry found means the beginning of the central directory. - rewind(handle); - s = seekPat; + fseek(handle, -min(size, (22 + 65536)), SEEK_CUR); + s = endPat; while((c = fgetc(handle)) != EOF) { - if (*s != c && s > seekPat) // No match? - s = seekPat; // We "reset" the counter by sending the s pointer back to the start of the array. + if (*s != c && s > endPat) // No match? + s = endPat; // We "reset" the counter by sending the s pointer back to the start of the array. if (*s == c) { s++; if (*s == 0x00) // The array pointer has reached the key char which marks the end. It means we have matched the signature. { matched = TRUE; - fseek(handle, -4, SEEK_CUR); CONS_Debug(DBG_SETUP, "Found PK3 central directory at position %ld.\n", ftell(handle)); break; } @@ -459,11 +459,18 @@ UINT16 W_InitFile(const char *filename) return INT16_MAX; } + fseek(handle, 4, SEEK_CUR); + fread(&numlumps, 1, 2, handle); + fseek(handle, 6, SEEK_CUR); + fread(&position, 1, 4, handle); + lump_p = lumpinfo = Z_Malloc(numlumps * sizeof (*lumpinfo), PU_STATIC, NULL); + fseek(handle, position, SEEK_SET); + // Since we found the central directory, now we can map our lumpinfo table. // We will look for file headers inside it, until we reach the central directory end signature. // We exactly know what data to expect this time, so now we don't need to do a byte-by-byte search. CONS_Debug(DBG_SETUP, "Now finding central directory file headers...\n"); - while(ftell(handle) < size - 4) // Make sure we don't go past the file size! + for (i = 0; i < numlumps; i++, lump_p++) { fread(curHeader, 1, 4, handle); @@ -504,13 +511,8 @@ UINT16 W_InitFile(const char *filename) fgets(eName, eNameLen + 1, handle); // Don't load lump if folder. - if (*(eName + eNameLen - 1) == '/') - continue; - - if (numlumps == 0) // First lump? Let's allocate the first lumpinfo block. - lumpinfo = Z_Malloc(sizeof(*lumpinfo), PU_STATIC, NULL); - else // Otherwise, reallocate and increase by 1. Might not be optimal, though... - lumpinfo = (lumpinfo_t*) Z_Realloc(lumpinfo, (numlumps + 1)*sizeof(*lumpinfo), PU_STATIC, NULL); +// if (*(eName + eNameLen - 1) == '/') +// continue; // We must calculate the position for the actual data. // Why not eLocalHeaderOffset + 30 + eNameLen + eXFieldLen? That's because the extra field and name lengths MAY be different in the local headers. @@ -518,11 +520,11 @@ UINT16 W_InitFile(const char *filename) fseek(handle, eLocalHeaderOffset + 26, SEEK_SET); fread(&lNameLen, 1, 2, handle); fread(&lXFieldLen, 1, 2, handle); - lumpinfo[numlumps].position = ftell(handle) + lNameLen + lXFieldLen; + lump_p->position = ftell(handle) + lNameLen + lXFieldLen; fseek(handle, rememberPos, SEEK_SET); // Let's go back to the central dir. - lumpinfo[numlumps].disksize = eCompSize; - lumpinfo[numlumps].size = eSize; + lump_p->disksize = eCompSize; + lump_p->size = eSize; // We will trim the file's full name so that only the filename is left. namePos = eNameLen - 1; @@ -535,33 +537,32 @@ UINT16 W_InitFile(const char *filename) while(nameEnd++ < 8) if(eName[namePos + nameEnd] == '.') break; - memset(lumpinfo[numlumps].name, '\0', 9); - strncpy(lumpinfo[numlumps].name, eName + namePos, nameEnd); + memset(lump_p->name, '\0', 9); + strncpy(lump_p->name, eName + namePos, nameEnd); - lumpinfo[numlumps].name2 = Z_Malloc((eNameLen+1)*sizeof(char), PU_STATIC, NULL); - strncpy(lumpinfo[numlumps].name2, eName, eNameLen); - lumpinfo[numlumps].name2[eNameLen] = '\0'; + lump_p->name2 = Z_Malloc((eNameLen+1)*sizeof(char), PU_STATIC, NULL); + strncpy(lump_p->name2, eName, eNameLen); + lump_p->name2[eNameLen] = '\0'; // We set the compression type from what we're supporting so far. switch(eCompression) { case 0: - lumpinfo[numlumps].compression = CM_NONE; + lump_p->compression = CM_NONE; break; case 8: - lumpinfo[numlumps].compression = CM_DEFLATE; + lump_p->compression = CM_DEFLATE; break; case 14: - lumpinfo[numlumps].compression = CM_LZF; + lump_p->compression = CM_LZF; break; default: CONS_Alert(CONS_WARNING, "Lump has an unsupported compression type!\n"); - lumpinfo[numlumps].compression = CM_UNSUPPORTED; + lump_p->compression = CM_UNSUPPORTED; break; } - CONS_Debug(DBG_SETUP, "File %s, data begins at: %ld\n", eName, lumpinfo[numlumps].position); + CONS_Debug(DBG_SETUP, "File %s, data begins at: %ld\n", eName, lump_p->position); fseek(handle, eXFieldLen + eCommentLen, SEEK_CUR); // We skip to where we expect the next central directory entry or end marker to be. - numlumps++; free(eName); } // We found the central directory end signature? From bb3365a904e8f6051d62ea479a2a31b152dea00e Mon Sep 17 00:00:00 2001 From: Nevur Date: Tue, 8 Aug 2017 10:39:25 +0200 Subject: [PATCH 22/35] We use srb2.pk3 instead. --- src/d_main.c | 4 ---- src/d_netfil.c | 3 +-- src/sdl/i_system.c | 2 +- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 98411f28f..26abcbde3 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -849,9 +849,6 @@ static void IdentifyVersion(void) // Add the players D_AddFile(va(pandf,srb2waddir, "player.dta")); - // Add the weapons - D_AddFile(va(pandf,srb2waddir,"rings.dta")); - #ifdef USE_PATCH_DTA // Add our crappy patches to fix our bugs D_AddFile(va(pandf,srb2waddir,"patch.dta")); @@ -1158,7 +1155,6 @@ void D_SRB2Main(void) //W_VerifyFileMD5(0, ASSET_HASH_SRB2_SRB); // srb2.srb/srb2.wad //W_VerifyFileMD5(1, ASSET_HASH_ZONES_DTA); // zones.dta //W_VerifyFileMD5(2, ASSET_HASH_PLAYER_DTA); // player.dta - //W_VerifyFileMD5(3, ASSET_HASH_RINGS_DTA); // rings.dta #ifdef USE_PATCH_DTA W_VerifyFileMD5(4, ASSET_HASH_PATCH_DTA); // patch.dta #endif diff --git a/src/d_netfil.c b/src/d_netfil.c index 172624ad2..db0bf8055 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -793,11 +793,10 @@ void Got_Filetxpak(void) char *filename = file->filename; static INT32 filetime = 0; - if (!(strcmp(filename, "srb2.srb") + if (!(strcmp(filename, "srb2.pk3") && strcmp(filename, "srb2.wad") && strcmp(filename, "zones.dta") && strcmp(filename, "player.dta") - && strcmp(filename, "rings.dta") && strcmp(filename, "patch.dta") && strcmp(filename, "music.dta") )) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index f72a9857d..fdf96bae7 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -224,7 +224,7 @@ void __set_fpscr(long); // in libgcc / kernel's startup.s? /** \brief WAD file to look for */ -#define WADKEYWORD1 "srb2.srb" +#define WADKEYWORD1 "srb2.pk3" #define WADKEYWORD2 "srb2.wad" /** \brief holds wad path */ From 4f8d53b329cd115562621756be826e3dd2d454a5 Mon Sep 17 00:00:00 2001 From: Nevur Date: Fri, 11 Aug 2017 15:46:46 +0200 Subject: [PATCH 23/35] Got rid of functions I added once but turned out to be unnecessary. --- src/p_setup.c | 17 +++++++---------- src/r_things.c | 32 -------------------------------- src/r_things.h | 1 - 3 files changed, 7 insertions(+), 43 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 2feba84d5..b6c8f75ca 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2599,7 +2599,7 @@ static boolean CanSaveLevel(INT32 mapnum) if (G_IsSpecialStage(mapnum) // don't save in special stages || mapnum == lastmaploaded) // don't save if the last map loaded was this one return false; - + // Any levels that have the savegame flag can save normally. // If the game is complete for this save slot, then any level can save! // On the other side of the spectrum, if lastmaploaded is 0, then the save file has only just been created and needs to save ASAP! @@ -3271,7 +3271,7 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname) // FindFolder("SOCs/", &socPos, &socNum); FindFolder("Sounds/", &sfxPos, &sfxNum); FindFolder("Music/", &musPos, &musNum); - FindFolder("Sprites/", &sprPos, &sprNum); +// FindFolder("Sprites/", &sprPos, &sprNum); FindFolder("Textures/", &texPos, &texNum); // FindFolder("Patches/", &patPos, &patNum); // FindFolder("Flats/", &flaPos, &flaNum); @@ -3290,8 +3290,8 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname) 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 (sprNum) // Sprites. +// R_LoadSpritsRange(wadnum, sprPos, sprNum); // if (texNum) // Textures. TODO: R_LoadTextures() does the folder positioning once again. New function maybe? // R_LoadTextures(); // if (mapNum) // Maps. TODO: Actually implement the map WAD loading code, lulz. @@ -3330,12 +3330,6 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname) digmreplaces++; } } - - // - // search for sprite replacements - // - R_AddSpriteDefs(wadnum); - break; } if (!devparm && sreplaces) @@ -3359,6 +3353,9 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname) ST_LoadGraphics(); ST_ReloadSkinFaceGraphics(); + // Search for sprite replacements. + R_AddSpriteDefs(wadnum); + // // look for skins // diff --git a/src/r_things.c b/src/r_things.c index 5b5d7527f..299c2dac7 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -368,38 +368,6 @@ 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 f5b863022..3b7d6ba3f 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -50,7 +50,6 @@ 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_LoadSpritsRange(UINT16 wadnum, UINT16 first, UINT16 num); #ifdef DELFILE From efb30f93abb5bbf842893059e17561db6e6e0516 Mon Sep 17 00:00:00 2001 From: wolfy852 Date: Sat, 7 Oct 2017 14:48:49 -0500 Subject: [PATCH 24/35] Fixes from toaster, plus some other things --- src/filesrch.c | 2 +- src/filesrch.h | 1 + src/m_menu.c | 5 +++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/filesrch.c b/src/filesrch.c index a28c4d83c..f8bf15293 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -520,7 +520,7 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want char exttable[NUM_EXT_TABLE][5] = { ".txt", ".cfg", // exec - ".wad", ".soc", ".lua"}; // addfile + ".wad", ".pk3", ".soc", ".lua"}; // addfile char filenamebuf[MAX_WADFILES][MAX_WADPATH]; diff --git a/src/filesrch.h b/src/filesrch.h index c2201b453..e88242698 100644 --- a/src/filesrch.h +++ b/src/filesrch.h @@ -54,6 +54,7 @@ typedef enum EXT_CFG, EXT_LOADSTART, EXT_WAD = EXT_LOADSTART, + EXT_PK3, EXT_SOC, EXT_LUA, // allowed even if not HAVE_BLUA so that we can yell on load attempt NUM_EXT, diff --git a/src/m_menu.c b/src/m_menu.c index 64255e71a..caf56fd8c 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -64,6 +64,9 @@ // And just some randomness for the exits. #include "m_random.h" +// P_GetSkinSprite2 +#include "r_things.h" + #ifdef PC_DOS #include // for snprintf int snprintf(char *str, size_t n, const char *fmt, ...); @@ -4758,6 +4761,7 @@ static void M_Addons(INT32 choice) addonsp[EXT_TXT] = W_CachePatchName("M_FTXT", PU_STATIC); addonsp[EXT_CFG] = W_CachePatchName("M_FCFG", PU_STATIC); addonsp[EXT_WAD] = W_CachePatchName("M_FWAD", PU_STATIC); + addonsp[EXT_PK3] = W_CachePatchName("M_FPK3", PU_STATIC); addonsp[EXT_SOC] = W_CachePatchName("M_FSOC", PU_STATIC); addonsp[EXT_LUA] = W_CachePatchName("M_FLUA", PU_STATIC); addonsp[NUM_EXT] = W_CachePatchName("M_FUNKN", PU_STATIC); @@ -5165,6 +5169,7 @@ static void M_HandleAddons(INT32 choice) // else intentional fallthrough case EXT_SOC: case EXT_WAD: + case EXT_PK3: COM_BufAddText(va("addfile %s%s", menupath, dirmenu[dir_on[menudepthleft]]+DIR_STRING)); addonsresponselimit = 5; break; From a3cfa8dd5c22d9e3ca3a7ec7f71ebc4436129079 Mon Sep 17 00:00:00 2001 From: wolfy852 Date: Sat, 7 Oct 2017 14:52:27 -0500 Subject: [PATCH 25/35] Fixes from toaster, plus some other stuff --- src/w_wad.c | 10 +++++----- src/w_wad.h | 10 ++++++++-- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/w_wad.c b/src/w_wad.c index cf7034958..3c0c2eb4f 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -553,7 +553,7 @@ UINT16 W_InitFile(const char *filename) switch(eCompression) { case 0: - lump_p->compression = CM_NONE; + lump_p->compression = CM_NOCOMPRESSION; break; case 8: lump_p->compression = CM_DEFLATE; @@ -584,7 +584,7 @@ UINT16 W_InitFile(const char *filename) lumpinfo[numlumps].position = 0; lumpinfo[numlumps].size = 0; lumpinfo[numlumps].disksize = 0; - lumpinfo[numlumps].compression = CM_NONE; + lumpinfo[numlumps].compression = CM_NOCOMPRESSION; numlumps++;*/ break; } @@ -670,7 +670,7 @@ UINT16 W_InitFile(const char *filename) else { lump_p->size -= 4; - lump_p->compression = CM_NONE; + lump_p->compression = CM_NOCOMPRESSION; } lump_p->position += 4; @@ -678,7 +678,7 @@ UINT16 W_InitFile(const char *filename) } else { - lump_p->compression = CM_NONE; + lump_p->compression = CM_NOCOMPRESSION; } memset(lump_p->name, 0x00, 9); strncpy(lump_p->name, fileinfo->name, 8); @@ -1092,7 +1092,7 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si // But let's not copy it yet. We support different compression formats on lumps, so we need to take that into account. switch(wadfiles[wad]->lumpinfo[lump].compression) { - case CM_NONE: // If it's uncompressed, we directly write the data into our destination, and return the bytes read. + case CM_NOCOMPRESSION: // If it's uncompressed, we directly write the data into our destination, and return the bytes read. return fread(dest, 1, size, handle); case CM_LZF: // Is it LZF compressed? Used by ZWADs. { diff --git a/src/w_wad.h b/src/w_wad.h index 1c81f2587..429c12c41 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -43,7 +43,13 @@ typedef struct } ATTRPACK filelump_t; // Available compression methods for lumps. -enum compmethod{CM_NONE, CM_DEFLATE, CM_LZF, CM_UNSUPPORTED}; +typedef enum +{ + CM_NOCOMPRESSION, + CM_DEFLATE, + CM_LZF, + CM_UNSUPPORTED +} compmethod; // a memory entry of the wad directory typedef struct @@ -54,7 +60,7 @@ typedef struct char *name2; // Used by PK3s. Dynamically allocated name. size_t size; // real (uncompressed) size INT32 compressed; // i - enum compmethod compression; // lump compression method + compmethod compression; // lump compression method } lumpinfo_t; // ========================================================================= From b298c7a541f18a4c13c7e707b60d6cab6ebb53fe Mon Sep 17 00:00:00 2001 From: wolfy852 Date: Sat, 7 Oct 2017 17:18:25 -0500 Subject: [PATCH 26/35] Fix p_spec.c and r_things.h, get the compiler to shut up This compiles with no errors or warnings, but hasn't been tested yet. Please review/test when you can. --- src/p_setup.c | 7 +- src/p_setup.h | 2 + src/p_spec.c | 174 ++++++------------------------------------------- src/r_data.c | 22 +++---- src/r_things.c | 12 ++-- src/r_things.h | 14 ++-- src/w_wad.c | 23 +++++-- src/w_wad.h | 5 +- 8 files changed, 67 insertions(+), 192 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 753c4f6e0..ff263c052 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2796,7 +2796,8 @@ boolean P_SetupLevel(boolean skipprecip) { // Remember that we're assuming that the WAD will have a specific set of lumps in a specific order. UINT8 *wadData = W_CacheLumpNum(lastloadedmaplumpnum, PU_STATIC); - filelump_t *fileinfo = wadData + ((wadinfo_t *)wadData)->infotableofs; + //filelump_t *fileinfo = wadData + ((wadinfo_t *)wadData)->infotableofs; + filelump_t *fileinfo = (filelump_t *)(wadData + ((wadinfo_t *)wadData)->infotableofs); P_LoadRawVertexes(wadData + (fileinfo + ML_VERTEXES)->filepos, (fileinfo + ML_VERTEXES)->size); P_LoadRawSectors(wadData + (fileinfo + ML_SECTORS)->filepos, (fileinfo + ML_SECTORS)->size); @@ -3233,7 +3234,7 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname) // UINT16 socPos, socNum = 0; UINT16 sfxPos, sfxNum = 0; UINT16 musPos, musNum = 0; - UINT16 sprPos, sprNum = 0; +// UINT16 sprPos, sprNum = 0; UINT16 texPos, texNum = 0; // UINT16 patPos, patNum = 0; // UINT16 flaPos, flaNum = 0; @@ -3254,7 +3255,7 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname) case RET_PK3: { // Auxiliary function - input a folder name and gives us the resource markers positions. - void FindFolder(char *folName, UINT16 *start, UINT16 *end) + void FindFolder(const char *folName, UINT16 *start, UINT16 *end) { if (!stricmp(lumpinfo->name2, folName)) { diff --git a/src/p_setup.h b/src/p_setup.h index 3443ffdb7..de763bed0 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -61,6 +61,8 @@ void P_LoadThingsOnly(void); boolean P_SetupLevel(boolean skipprecip); boolean P_AddWadFile(const char *wadfilename, char **firstmapname); boolean P_RunSOC(const char *socfilename); +void P_LoadSoundsRange(UINT16 wadnum, UINT16 first, UINT16 num); +void P_LoadMusicsRange(UINT16 wadnum, UINT16 first, UINT16 num); void P_WriteThings(lumpnum_t lump); size_t P_PrecacheLevelFlats(void); void P_AllocMapHeader(INT16 i); diff --git a/src/p_spec.c b/src/p_spec.c index 97990eb26..2d17330d4 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -74,7 +74,7 @@ typedef struct #endif /** Animated texture definition. - * Used for ::harddefs and for loading an ANIMATED lump from a wad. + * Used for loading an ANIMDEFS lump from a wad. * * Animations are defined by the first and last frame (i.e., flat or texture). * The animation sequence uses all flats between the start and end entry, in @@ -121,104 +121,6 @@ static anim_t *lastanim; static anim_t *anims = NULL; /// \todo free leak static size_t maxanims; -// -// P_InitPicAnims -// -/** Hardcoded animation sequences. - * Used if no ANIMATED lump is found in a loaded wad. - */ -static animdef_t harddefs[] = -{ - // flat animations. - {false, "LITEY3", "LITEY1", 4}, - {false, "FWATER16", "FWATER1", 4}, - {false, "BWATER16", "BWATER01", 4}, - {false, "LWATER16", "LWATER1", 4}, - {false, "WATER7", "WATER0", 4}, - {false, "LAVA4", "LAVA1", 8}, - {false, "DLAVA4", "DLAVA1", 8}, - {false, "RLAVA8", "RLAVA1", 8}, - {false, "LITER3", "LITER1", 8}, - {false, "SURF08", "SURF01", 4}, - - {false, "CHEMG16", "CHEMG01", 4}, // THZ Chemical gunk - {false, "GOOP16", "GOOP01", 4}, // Green chemical gunk - {false, "OIL16", "OIL01", 4}, // Oil - {false, "THZBOXF4", "THZBOXF1", 2}, // Moved up with the flats - {false, "ALTBOXF4", "ALTBOXF1", 2}, - - {false, "LITEB3", "LITEB1", 4}, - {false, "LITEN3", "LITEN1", 4}, - {false, "ACZRFL1H", "ACZRFL1A", 4}, - {false, "ACZRFL2H", "ACZRFL2A", 4}, - {false, "EGRIDF3", "EGRIDF1", 4}, - {false, "ERZFAN4", "ERZFAN1", 1}, - {false, "ERZFANR4", "ERZFANR1", 1}, - {false, "DISCO4", "DISCO1", 15}, - - // animated textures - {true, "GFALL4", "GFALL1", 2}, // Short waterfall - {true, "CFALL4", "CFALL1", 2}, // Long waterfall - {true, "TFALL4", "TFALL1", 2}, // THZ Chemical fall - {true, "AFALL4", "AFALL1", 2}, // Green Chemical fall - {true, "QFALL4", "QFALL1", 2}, // Quicksand fall - {true, "Q2FALL4", "Q2FALL1", 2}, - {true, "Q3FALL4", "Q3FALL1", 2}, - {true, "Q4FALL4", "Q4FALL1", 2}, - {true, "Q5FALL4", "Q5FALL1", 2}, - {true, "Q6FALL4", "Q6FALL1", 2}, - {true, "Q7FALL4", "Q7FALL1", 2}, - {true, "LFALL4", "LFALL1", 2}, - {true, "MFALL4", "MFALL1", 2}, - {true, "OFALL4", "OFALL1", 2}, - {true, "DLAVA4", "DLAVA1", 8}, - {true, "ERZLASA2", "ERZLASA1", 1}, - {true, "ERZLASB4", "ERZLASB1", 1}, - {true, "ERZLASC4", "ERZLASC1", 1}, - {true, "THZBOX04", "THZBOX01", 2}, - {true, "ALTBOX04", "ALTBOX01", 2}, - {true, "SFALL4", "SFALL1", 4}, // Lava fall - {true, "RVZFALL8", "RVZFALL1", 4}, - {true, "BFALL4", "BFALL1", 2}, // HPZ waterfall - {true, "GREYW3", "GREYW1", 4}, - {true, "BLUEW3", "BLUEW1", 4}, - {true, "COMP6", "COMP4", 4}, - {true, "RED3", "RED1", 4}, - {true, "YEL3", "YEL1", 4}, - {true, "ACWRFL1D", "ACWRFL1A", 1}, - {true, "ACWRFL2D", "ACWRFL2A", 1}, - {true, "ACWRFL3D", "ACWRFL3A", 1}, - {true, "ACWRFL4D", "ACWRFL4A", 1}, - {true, "ACWRP1D", "ACWRP1A", 1}, - {true, "ACWRP2D", "ACWRP2A", 1}, - {true, "ACZRP1D", "ACZRP1A", 1}, - {true, "ACZRP2D", "ACZRP2A", 1}, - {true, "OILFALL4", "OILFALL1", 2}, - {true, "SOLFALL4", "SOLFALL1", 2}, - {true, "DOWN1C", "DOWN1A", 4}, - {true, "DOWN2C", "DOWN2A", 4}, - {true, "DOWN3D", "DOWN3A", 4}, - {true, "DOWN4C", "DOWN4A", 4}, - {true, "DOWN5C", "DOWN5A", 4}, - {true, "UP1C", "UP1A", 4}, - {true, "UP2C", "UP2A", 4}, - {true, "UP3D", "UP3A", 4}, - {true, "UP4C", "UP4A", 4}, - {true, "UP5C", "UP5A", 4}, - {true, "EGRID3", "EGRID1", 4}, - {true, "ERFANW4", "ERFANW1", 1}, - {true, "ERFANX4", "ERFANX1", 1}, - {true, "DISCOD4", "DISCOD1", 15}, - {true, "DANCE4", "DANCE1", 8}, - {true, "SKY135", "SKY132", 2}, - {true, "APPLMS4", "APPLMS1", 2}, - {true, "APBOXW3", "APBOXW1", 2}, - {true, "ERZLAZC4", "ERZLAZC1", 4}, - - // End of line - { -1, "", "", 0}, -}; - // Animating line specials // Init animated textures @@ -232,7 +134,7 @@ void P_ParseAnimationDefintion(SINT8 istexture); /** Sets up texture and flat animations. * - * Converts an ::animdef_t array loaded from ::harddefs or a lump into + * Converts an ::animdef_t array loaded from a lump into * ::anim_t format. * * Issues an error if any animation cycles are invalid. @@ -244,73 +146,41 @@ void P_InitPicAnims(void) { // Init animation INT32 w; // WAD - UINT8 *animatedLump; - UINT8 *currentPos; size_t i; I_Assert(animdefs == NULL); + + maxanims = 0; - if (W_CheckNumForName("ANIMATED") != LUMPERROR || W_CheckNumForName("ANIMDEFS") != LUMPERROR) + if (W_CheckNumForName("ANIMDEFS") != LUMPERROR) { - for (w = numwadfiles-1, maxanims = 0; w >= 0; w--) + for (w = numwadfiles-1; w >= 0; w--) { - UINT16 animatedLumpNum; UINT16 animdefsLumpNum; - // Find ANIMATED lump in the WAD - animatedLumpNum = W_CheckNumForNamePwad("ANIMATED", w, 0); - if (animatedLumpNum != INT16_MAX) - { - animatedLump = (UINT8 *)W_CacheLumpNumPwad(w, animatedLumpNum, PU_STATIC); - - // Get the number of animations in the file - i = maxanims; - for (currentPos = animatedLump; *currentPos != UINT8_MAX; maxanims++, currentPos+=23); - - // Resize animdefs (or if it hasn't been created, create it) - animdefs = (animdef_t *)Z_Realloc(animdefs, sizeof(animdef_t)*(maxanims + 1), PU_STATIC, NULL); - // Sanity check it - if (!animdefs) - I_Error("Not enough free memory for ANIMATED data"); - - // Populate the new array - for (currentPos = animatedLump; *currentPos != UINT8_MAX; i++, currentPos+=23) - { - M_Memcpy(&(animdefs[i].istexture), currentPos, 1); // istexture, 1 byte - M_Memcpy(animdefs[i].endname, (currentPos + 1), 9); // endname, 9 bytes - M_Memcpy(animdefs[i].startname, (currentPos + 10), 9); // startname, 9 bytes - M_Memcpy(&(animdefs[i].speed), (currentPos + 19), 4); // speed, 4 bytes - } - - Z_Free(animatedLump); - } - - // Now find ANIMDEFS - if (wadfiles[w]->type == RET_WAD) - animdefsLumpNum = W_CheckNumForNamePwad("ANIMDEFS", w, 0); - else if (wadfiles[w]->type == RET_PK3) + // Find ANIMDEFS lump in the WAD + if (wadfiles[w]->type == RET_PK3) animdefsLumpNum = W_CheckNumForFullNamePK3("ANIMDEFS", w, 0); + else + animdefsLumpNum = W_CheckNumForNamePwad("ANIMDEFS", w, 0); + if (animdefsLumpNum != INT16_MAX) P_ParseANIMDEFSLump(w, animdefsLumpNum); } - // Define the last one - animdefs[maxanims].istexture = -1; - strncpy(animdefs[maxanims].endname, "", 9); - strncpy(animdefs[maxanims].startname, "", 9); - animdefs[maxanims].speed = 0; - } - else - { - animdefs = harddefs; - for (maxanims = 0; animdefs[maxanims].istexture != -1; maxanims++); } + + // Define the last one + animdefs[maxanims].istexture = -1; + strncpy(animdefs[maxanims].endname, "", 9); + strncpy(animdefs[maxanims].startname, "", 9); + animdefs[maxanims].speed = 0; if (anims) free(anims); anims = (anim_t *)malloc(sizeof (*anims)*(maxanims + 1)); if (!anims) - I_Error("Not enough free memory for ANIMATED data"); + I_Error("Not enough free memory for ANIMDEFS data"); lastanim = anims; for (i = 0; animdefs[i].istexture != -1; i++) @@ -342,10 +212,7 @@ void P_InitPicAnims(void) animdefs[i].startname, animdefs[i].endname); } - if (animdefs == harddefs) - lastanim->speed = animdefs[i].speed; - else - lastanim->speed = LONG(animdefs[i].speed); + lastanim->speed = LONG(animdefs[i].speed); lastanim++; } lastanim->istexture = -1; @@ -353,8 +220,7 @@ void P_InitPicAnims(void) // Clear animdefs now that we're done with it. // We'll only be using anims from now on. - if (animdefs != harddefs) - Z_Free(animdefs); + Z_Free(animdefs); animdefs = NULL; } diff --git a/src/r_data.c b/src/r_data.c index e3933a950..e224457bb 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -1198,8 +1198,17 @@ lumpnum_t R_GetFlatNumForName(const char *name) // Scan wad files backwards so patched flats take preference. for (i = numwadfiles - 1; i >= 0; i--) { - // WAD type? use markers. - if (wadfiles[i]->type == RET_WAD) + + if (wadfiles[i]->type == RET_PK3) + { + start = W_CheckNumForFolderStartPK3("Flats/", i, 0); + if (start == INT16_MAX) + continue; + end = W_CheckNumForFolderEndPK3("Flats/", i, start); + if (end == INT16_MAX) + continue; + } + else // WAD type? use markers. { // Find the ranges to work with. start = W_CheckNumForNamePwad("F_START", (UINT16)i, 0); @@ -1222,15 +1231,6 @@ lumpnum_t R_GetFlatNumForName(const char *name) continue; } } - else if (wadfiles[i]->type == RET_PK3) - { - start = W_CheckNumForFolderStartPK3("Flats/", i, 0); - if (start == INT16_MAX) - continue; - end = W_CheckNumForFolderEndPK3("Flats/", i, start); - if (end == INT16_MAX) - continue; - } // Now find lump with specified name in that range. lump = W_CheckNumForNamePwad(name, (UINT16)i, start); if (lump < end) diff --git a/src/r_things.c b/src/r_things.c index ab896f8e8..06ae16fb1 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -380,7 +380,9 @@ void R_AddSpriteDefs(UINT16 wadnum) char wadname[MAX_WADPATH]; // Find the sprites section in this resource file. - if (wadfiles[wadnum]->type == RET_WAD) + if (wadfiles[wadnum]->type == RET_PK3) + start = W_CheckNumForFolderStartPK3("Sprites/", wadnum, 0); + else { start = W_CheckNumForNamePwad("S_START", wadnum, 0); if (start == UINT16_MAX) @@ -390,21 +392,19 @@ void R_AddSpriteDefs(UINT16 wadnum) else start++; // just after S_START } - else if (wadfiles[wadnum]->type == RET_PK3) - start = W_CheckNumForFolderStartPK3("Sprites/", wadnum, 0); // ignore skin wads (we don't want skin sprites interfering with vanilla sprites) if (start == 0 && W_CheckNumForNamePwad("S_SKIN", wadnum, 0) != UINT16_MAX) return; - if (wadfiles[wadnum]->type == RET_WAD) + if (wadfiles[wadnum]->type == RET_PK3) + end = W_CheckNumForFolderEndPK3("Sprites/", wadnum, start); + else { end = W_CheckNumForNamePwad("S_END",wadnum,start); if (end == UINT16_MAX) end = W_CheckNumForNamePwad("SS_END",wadnum,start); //deutex compatib. } - else if (wadfiles[wadnum]->type == RET_PK3) - end = W_CheckNumForFolderEndPK3("Sprites/", wadnum, start); if (end == UINT16_MAX) { diff --git a/src/r_things.h b/src/r_things.h index 3b7d6ba3f..18cc701ab 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -51,11 +51,6 @@ void R_SortVisSprites(void); // (only sprites from namelist are added or replaced) void R_AddSpriteDefs(UINT16 wadnum); - -#ifdef DELFILE -void R_DelSpriteDefs(UINT16 wadnum); -#endif - //SoM: 6/5/2000: Light sprites correctly! void R_AddSprites(sector_t *sec, INT32 lightlevel); void R_InitSprites(void); @@ -217,11 +212,10 @@ void SetPlayerSkinByNum(INT32 playernum,INT32 skinnum); // Tails 03-16-2002 boolean R_SkinUsable(INT32 playernum, INT32 skinnum); UINT32 R_GetSkinAvailabilities(void); INT32 R_SkinAvailable(const char *name); +void R_PatchSkins(UINT16 wadnum); void R_AddSkins(UINT16 wadnum); -#ifdef DELFILE -void R_DelSkins(UINT16 wadnum); -#endif +UINT8 P_GetSkinSprite2(skin_t *skin, UINT8 spr2, player_t *player); void R_InitDrawNodes(void); @@ -236,7 +230,7 @@ char *GetPlayerFacePic(INT32 skinnum); // Future: [[ ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz!@ ]] FUNCMATH FUNCINLINE static ATTRINLINE char R_Frame2Char(UINT8 frame) { -#if 0 // 2.1 compat +#if 1 // 2.1 compat return 'A' + frame; #else if (frame < 26) return 'A' + frame; @@ -250,7 +244,7 @@ FUNCMATH FUNCINLINE static ATTRINLINE char R_Frame2Char(UINT8 frame) FUNCMATH FUNCINLINE static ATTRINLINE UINT8 R_Char2Frame(char cn) { -#if 0 // 2.1 compat +#if 1 // 2.1 compat return cn - 'A'; #else if (cn >= 'A' && cn <= 'Z') return cn - 'A'; diff --git a/src/w_wad.c b/src/w_wad.c index 3c0c2eb4f..b4372ec15 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -25,6 +25,19 @@ #endif #include "lzf.h" #endif + +#ifndef _FILE_OFFSET_BITS +#define _FILE_OFFSET_BITS 0 +#endif + +#ifndef _LARGEFILE64_SOURCE +#define _LARGEFILE64_SOURCE +#endif + +#ifndef _LFS64_LARGEFILE +#define _LFS64_LARGEFILE +#endif + //#ifdef HAVE_ZLIB #include "zlib.h" //#endif // HAVE_ZLIB @@ -181,14 +194,14 @@ static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum) if (posStart != INT16_MAX) { posEnd = W_CheckNumForFolderEndPK3("Lua/", wadnum, posStart); - for (posStart; posStart < posEnd; posStart++) + for (; posStart < posEnd; posStart++) LUA_LoadLump(wadnum, posStart); } posStart = W_CheckNumForFolderStartPK3("SOCs/", wadnum, 0); if (posStart != INT16_MAX) { posEnd = W_CheckNumForFolderEndPK3("SOCs/", wadnum, posStart); - for(posStart; posStart < posEnd; posStart++) + for(; posStart < posEnd; posStart++) DEH_LoadDehackedLumpPwad(wadnum, posStart); } } @@ -604,12 +617,12 @@ UINT16 W_InitFile(const char *filename) // assume wad file else { - type = RET_WAD; - wadinfo_t header; lumpinfo_t *lump_p; filelump_t *fileinfo; void *fileinfov; + + type = RET_WAD; // read the header if (fread(&header, 1, sizeof header, handle) < sizeof header) @@ -925,7 +938,7 @@ lumpnum_t W_CheckNumForMap(const char *name) { UINT16 lumpNum, end; UINT32 i; - for (i = numwadfiles - 1; i >= 0; i--) + for (i = numwadfiles - 1; i < numwadfiles; i--) { if (wadfiles[i]->type == RET_WAD) { diff --git a/src/w_wad.h b/src/w_wad.h index 429c12c41..14bf4d85f 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -110,9 +110,6 @@ void W_Shutdown(void); FILE *W_OpenWadFile(const char **filename, boolean useerrors); // Load and add a wadfile to the active wad files, returns numbers of lumps, INT16_MAX on error UINT16 W_InitFile(const char *filename); -#ifdef DELFILE -void W_UnloadWadFile(UINT16 num); -#endif // 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. @@ -136,6 +133,8 @@ UINT8 W_LumpExists(const char *name); // Lua uses this. size_t W_LumpLengthPwad(UINT16 wad, UINT16 lump); size_t W_LumpLength(lumpnum_t lumpnum); +void zerr(int ret); // zlib error checking + size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, size_t offset); size_t W_ReadLumpHeader(lumpnum_t lump, void *dest, size_t size, size_t offest); // read all or a part of a lump void W_ReadLumpPwad(UINT16 wad, UINT16 lump, void *dest); From 021417500e179bda49e08b9a686c45b232958eb0 Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Sat, 7 Oct 2017 19:08:29 -0400 Subject: [PATCH 27/35] Do not use Win32's TRUE/FALSE is OS independent code --- src/w_wad.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/w_wad.c b/src/w_wad.c index b4372ec15..4b0eb1918 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -439,7 +439,7 @@ UINT16 W_InitFile(const char *filename) char *s; int c; UINT32 position; - boolean matched = FALSE; + boolean matched = false; lumpinfo_t *lump_p; type = RET_PK3; @@ -463,7 +463,7 @@ UINT16 W_InitFile(const char *filename) s++; if (*s == 0x00) // The array pointer has reached the key char which marks the end. It means we have matched the signature. { - matched = TRUE; + matched = true; CONS_Debug(DBG_SETUP, "Found PK3 central directory at position %ld.\n", ftell(handle)); break; } @@ -471,7 +471,7 @@ UINT16 W_InitFile(const char *filename) } // Error if we couldn't find the central directory at all. It likely means this is not a ZIP/PK3 file. - if (matched == FALSE) + if (matched == false) { CONS_Alert(CONS_ERROR, "No central directory inside PK3! File may be corrupted or incomplete.\n"); return INT16_MAX; From 79879bbd7b323657d8ea5ef3a5ff1bd42feee72d Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Sat, 7 Oct 2017 19:10:29 -0400 Subject: [PATCH 28/35] Need to handle that FindFolder() does not fill musPos --- src/p_setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_setup.c b/src/p_setup.c index ff263c052..35a64ded8 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3233,7 +3233,7 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname) // UINT16 luaPos, luaNum = 0; // UINT16 socPos, socNum = 0; UINT16 sfxPos, sfxNum = 0; - UINT16 musPos, musNum = 0; + UINT16 musPos = 0, musNum = 0; // UINT16 sprPos, sprNum = 0; UINT16 texPos, texNum = 0; // UINT16 patPos, patNum = 0; From ec9d47cb34810483c6fa155b181b038b50a63b26 Mon Sep 17 00:00:00 2001 From: Wolfy Date: Mon, 9 Oct 2017 14:24:04 -0500 Subject: [PATCH 29/35] Use the new sprite system --- src/r_things.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/r_things.h b/src/r_things.h index 18cc701ab..65b7775e5 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -230,7 +230,7 @@ char *GetPlayerFacePic(INT32 skinnum); // Future: [[ ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz!@ ]] FUNCMATH FUNCINLINE static ATTRINLINE char R_Frame2Char(UINT8 frame) { -#if 1 // 2.1 compat +#if 0 // 2.1 compat return 'A' + frame; #else if (frame < 26) return 'A' + frame; @@ -244,7 +244,7 @@ FUNCMATH FUNCINLINE static ATTRINLINE char R_Frame2Char(UINT8 frame) FUNCMATH FUNCINLINE static ATTRINLINE UINT8 R_Char2Frame(char cn) { -#if 1 // 2.1 compat +#if 0 // 2.1 compat return cn - 'A'; #else if (cn >= 'A' && cn <= 'Z') return cn - 'A'; From 2fff5e9f6d2bbbbc7feeeabaaa102245b94692dc Mon Sep 17 00:00:00 2001 From: Wolfy Date: Tue, 10 Oct 2017 01:41:28 -0500 Subject: [PATCH 30/35] Fix empty WAD files printing the wrong sprite count. --- src/r_things.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 06ae16fb1..62a235427 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -385,9 +385,9 @@ void R_AddSpriteDefs(UINT16 wadnum) else { start = W_CheckNumForNamePwad("S_START", wadnum, 0); - if (start == UINT16_MAX) + if (start == INT16_MAX) start = W_CheckNumForNamePwad("SS_START", wadnum, 0); //deutex compatib. - if (start == UINT16_MAX) + if (start == INT16_MAX) start = 0; //let say S_START is lump 0 else start++; // just after S_START @@ -402,11 +402,11 @@ void R_AddSpriteDefs(UINT16 wadnum) else { end = W_CheckNumForNamePwad("S_END",wadnum,start); - if (end == UINT16_MAX) + if (end == INT16_MAX) end = W_CheckNumForNamePwad("SS_END",wadnum,start); //deutex compatib. } - if (end == UINT16_MAX) + if (end == INT16_MAX) { CONS_Debug(DBG_SETUP, "no sprites in pwad %d\n", wadnum); return; From 3a96c507a209be02f3b7bbc3488de256a9018996 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 21 Oct 2017 16:18:28 +0100 Subject: [PATCH 31/35] * Made PK3s fail the music lump check, because... that method of checking doesn't really work with it. * Improve the output of listwad to identify unimportant, non-networked files. https://cdn.discordapp.com/attachments/237467298590490625/371314970002063370/srb20044.png * Fixed mainwads being one too high due to the removal of rings.dta. --- src/d_main.c | 4 ++-- src/d_netcmd.c | 2 ++ src/w_wad.c | 8 ++++---- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 2d89770db..5a86cc7a6 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1135,14 +1135,14 @@ void D_SRB2Main(void) //W_VerifyFileMD5(1, ASSET_HASH_ZONES_DTA); // zones.dta //W_VerifyFileMD5(2, ASSET_HASH_PLAYER_DTA); // player.dta #ifdef USE_PATCH_DTA - W_VerifyFileMD5(4, ASSET_HASH_PATCH_DTA); // patch.dta + W_VerifyFileMD5(3, ASSET_HASH_PATCH_DTA); // patch.dta #endif // don't check music.dta because people like to modify it, and it doesn't matter if they do // ...except it does if they slip maps in there, and that's what W_VerifyNMUSlumps is for. #endif //ifndef DEVELOP - mainwads = 4; // there are 4 wads not to unload + mainwads = 3; // there are 3 wads not to unload #ifdef USE_PATCH_DTA ++mainwads; // patch.dta adds one more #endif diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 1a80f4dc0..5cf83fa3e 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -3242,6 +3242,8 @@ static void Command_ListWADS_f(void) CONS_Printf("\x82 IWAD\x80: %s\n", tempname); else if (i <= mainwads) CONS_Printf("\x82 * %.2d\x80: %s\n", i, tempname); + else if (!wadfiles[i]->important) + CONS_Printf("\x86 %.2d: %s\n", i, tempname); else CONS_Printf(" %.2d: %s\n", i, tempname); } diff --git a/src/w_wad.c b/src/w_wad.c index f7261e5f0..c8701f98f 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1481,12 +1481,12 @@ static int W_VerifyFile(const char *filename, lumpchecklist_t *checklist, if ((handle = W_OpenWadFile(&filename, false)) == NULL) return -1; - // detect dehacked file with the "soc" extension - if (stricmp(&filename[strlen(filename) - 4], ".soc") != 0 + // detect wad file by the absence of the other supported extensions + if (stricmp(&filename[strlen(filename) - 4], ".soc") #ifdef HAVE_BLUA - && stricmp(&filename[strlen(filename) - 4], ".lua") != 0 + && stricmp(&filename[strlen(filename) - 4], ".lua") #endif - ) + && stricmp(&filename[strlen(filename) - 4], ".pk3")) { // assume wad file wadinfo_t header; From ee4b891318320373fac52759f409a0685a772d30 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 26 Oct 2017 16:58:18 +0100 Subject: [PATCH 32/35] Since I'm on the branch: bugfix a thing with introchanged/titlechanged. --- src/dehacked.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index 774257d4d..b1136c2cf 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -3346,9 +3346,15 @@ static void DEH_LoadDehackedFile(MYFILE *f) if (gamestate == GS_TITLESCREEN) { if (introchanged) + { + menuactive = false; COM_BufAddText("playintro"); + } else if (titlechanged) + { + menuactive = false; COM_BufAddText("exitgame"); // Command_ExitGame_f() but delayed + } } dbg_line = -1; From efc4d2f81d5a6c9c1f4fce2a9316fc9116882141 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 26 Oct 2017 16:58:18 +0100 Subject: [PATCH 33/35] * Make multiple ANIMDEFS lumps get loaded. * Refactor the multiple TEXTURES lump code. --- src/p_spec.c | 21 +++++++++------------ src/r_data.c | 16 +++++++--------- 2 files changed, 16 insertions(+), 21 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index 7da411580..803c1ab86 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -148,20 +148,17 @@ void P_InitPicAnims(void) maxanims = 0; - if (W_CheckNumForName("ANIMDEFS") != LUMPERROR) + for (w = numwadfiles-1; w >= 0; w--) { - for (w = numwadfiles-1; w >= 0; w--) - { - UINT16 animdefsLumpNum; + UINT16 animdefsLumpNum; - // Find ANIMDEFS lump in the WAD - if (wadfiles[w]->type == RET_PK3) - animdefsLumpNum = W_CheckNumForFullNamePK3("ANIMDEFS", w, 0); - else - animdefsLumpNum = W_CheckNumForNamePwad("ANIMDEFS", w, 0); - - if (animdefsLumpNum != INT16_MAX) - P_ParseANIMDEFSLump(w, animdefsLumpNum); + // Find ANIMDEFS lump in the WAD + animdefsLumpNum = W_CheckNumForNamePwad("ANIMDEFS", w, 0); + + while (animdefsLumpNum != INT16_MAX) + { + P_ParseANIMDEFSLump(w, animdefsLumpNum); + animdefsLumpNum = W_CheckNumForNamePwad("ANIMDEFS", (UINT16)w, animdefsLumpNum + 1); } } diff --git a/src/r_data.c b/src/r_data.c index 07db46aa3..1a6162dc2 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -571,20 +571,18 @@ void R_LoadTextures(void) { texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0); texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart); - texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0); - while (texturesLumpPos != INT16_MAX) - { - numtextures += R_CountTexturesInTEXTURESLump((UINT16)w, (UINT16)texturesLumpPos); - texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, texturesLumpPos + 1); - } } else { texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0) + 1; texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0); - texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0); - if (texturesLumpPos != INT16_MAX) - numtextures += R_CountTexturesInTEXTURESLump((UINT16)w, (UINT16)texturesLumpPos); + } + + texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0); + while (texturesLumpPos != INT16_MAX) + { + numtextures += R_CountTexturesInTEXTURESLump((UINT16)w, (UINT16)texturesLumpPos); + texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, texturesLumpPos + 1); } // Add all the textures between TX_START and TX_END From d4e08551bfbd506f6c6180566e9ceeef54f9f161 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 30 Oct 2017 20:54:14 +0000 Subject: [PATCH 34/35] * Make P_LoadVertexes a wrapper for P_LoadRawVertexes. * Remove extraenous R_ClearTextureNumCache from P_LoadSidedefs2. * Remove regressions in comments/#includes. --- src/m_menu.c | 3 --- src/p_setup.c | 53 +++++++++++++-------------------------------------- 2 files changed, 13 insertions(+), 43 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 72ebafc03..de36c1859 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -64,9 +64,6 @@ // And just some randomness for the exits. #include "m_random.h" -// P_GetSkinSprite2 -#include "r_things.h" - #ifdef PC_DOS #include // for snprintf int snprintf(char *str, size_t n, const char *fmt, ...); diff --git a/src/p_setup.c b/src/p_setup.c index 6d60ea3bd..1506145fa 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -354,39 +354,6 @@ UINT32 P_GetScoreForGrade(INT16 map, UINT8 mare, UINT8 grade) * \param lump VERTEXES lump number. * \sa ML_VERTEXES */ -static inline void P_LoadVertexes(lumpnum_t lumpnum) -{ - UINT8 *data; - size_t i; - mapvertex_t *ml; - vertex_t *li; - - // Determine number of lumps: - // total lump length / vertex record length. - numvertexes = W_LumpLength(lumpnum) / sizeof (mapvertex_t); - - if (numvertexes <= 0) - I_Error("Level has no vertices"); // instead of crashing - - // Allocate zone memory for buffer. - vertexes = Z_Calloc(numvertexes * sizeof (*vertexes), PU_LEVEL, NULL); - - // Load data into cache. - data = W_CacheLumpNum(lumpnum, PU_STATIC); - - ml = (mapvertex_t *)data; - li = vertexes; - - // Copy and convert vertex coordinates, internal representation as fixed. - for (i = 0; i < numvertexes; i++, li++, ml++) - { - li->x = SHORT(ml->x)<y = SHORT(ml->y)<sidenum[j] != 0xffff && ld->sidenum[j] >= (UINT16)numsides) { ld->sidenum[j] = 0xffff; - CONS_Debug(DBG_SETUP, "P_LoadLineDefs: linedef %s has out-of-range sidedef number\n", sizeu1(numlines-i-1)); + CONS_Debug(DBG_SETUP, "P_LoadRawLineDefs: linedef %s has out-of-range sidedef number\n", sizeu1(numlines-i-1)); } } } @@ -1277,14 +1251,14 @@ static void P_LoadRawLineDefs(UINT8 *data, size_t i) { ld->sidenum[0] = 0; // Substitute dummy sidedef for missing right side // cph - print a warning about the bug - CONS_Debug(DBG_SETUP, "P_LoadLineDefs: linedef %s missing first sidedef\n", sizeu1(numlines-i-1)); + CONS_Debug(DBG_SETUP, "P_LoadRawLineDefs: linedef %s missing first sidedef\n", sizeu1(numlines-i-1)); } if ((ld->sidenum[1] == 0xffff) && (ld->flags & ML_TWOSIDED)) { ld->flags &= ~ML_TWOSIDED; // Clear 2s flag for missing left side // cph - print a warning about the bug - CONS_Debug(DBG_SETUP, "P_LoadLineDefs: linedef %s has two-sided flag set, but no second sidedef\n", sizeu1(numlines-i-1)); + CONS_Debug(DBG_SETUP, "P_LoadRawLineDefs: linedef %s has two-sided flag set, but no second sidedef\n", sizeu1(numlines-i-1)); } if (ld->sidenum[0] != 0xffff && ld->special) @@ -1438,7 +1412,7 @@ static void P_LoadRawSideDefs2(void *data) if (sector_num >= numsectors) { - CONS_Debug(DBG_SETUP, "P_LoadSideDefs2: sidedef %u has out-of-range sector num %u\n", i, sector_num); + CONS_Debug(DBG_SETUP, "P_LoadRawSideDefs2: sidedef %u has out-of-range sector num %u\n", i, sector_num); sector_num = 0; } sd->sector = sec = §ors[sector_num]; @@ -1661,7 +1635,6 @@ static void P_LoadSideDefs2(lumpnum_t lumpnum) UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC); P_LoadRawSideDefs2(data); Z_Free(data); - R_ClearTextureNumCache(true); } @@ -3349,10 +3322,10 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname) // Reload it all anyway, just in case they // added some textures but didn't insert a - // TEXTURE1/PNAMES/etc. list. + // TEXTURES/etc. list. R_LoadTextures(); // numtexture changes - // Reload ANIMATED / ANIMDEFS + // Reload ANIMDEFS P_InitPicAnims(); // Flush and reload HUD graphics From 4d82a76e5b49f73eb1d1a0215e4a0d066e506fa9 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 30 Oct 2017 21:07:17 +0000 Subject: [PATCH 35/35] Move R_AddSpriteDefs back into place. --- src/p_setup.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 1506145fa..26234bccb 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3320,6 +3320,9 @@ 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 // TEXTURES/etc. list. @@ -3334,9 +3337,6 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname) ST_LoadGraphics(); ST_ReloadSkinFaceGraphics(); - // Search for sprite replacements. - R_AddSpriteDefs(wadnum); - // // look for skins //