From 3e99f4d1426c19785725634437ef07699dec5803 Mon Sep 17 00:00:00 2001 From: Alug Date: Sun, 3 Aug 2025 00:35:46 +0200 Subject: [PATCH 01/66] Do not reload every texture when adding a wad (squashed) port of https://git.do.srb2.org/STJr/SRB2/-/merge_requests/1725#c829d21709a4f5cd81d140271e883bc40dd00b1b --- src/p_setup.c | 16 +-- src/r_data.c | 376 ++++++++++++++++++++++++++++++-------------------- src/r_data.h | 3 +- src/w_wad.c | 60 ++++++-- src/w_wad.h | 1 + 5 files changed, 287 insertions(+), 169 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index e034c35b8..05ad8fc93 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3311,8 +3311,11 @@ UINT16 P_PartialAddWadFile(const char *wadfilename, boolean local) if (!devparm && digmreplaces) CONS_Printf(M_GetText("%s digital musics replaced\n"), sizeu1(digmreplaces)); - if (!mapsadded) - CONS_Printf(M_GetText("No maps added\n")); +#ifdef HWRENDER + // Free GPU textures before freeing patches. + if (rendermode == render_opengl && (vid.glstate == VID_GL_LIBRARY_LOADED)) + HWR_ClearAllTextures(); +#endif // // search for sprite replacements @@ -3324,7 +3327,7 @@ UINT16 P_PartialAddWadFile(const char *wadfilename, boolean local) // Reload it all anyway, just in case they // added some textures but didn't insert a // TEXTURES/etc. list. - //R_LoadTexturesPwad(wadnum); + R_LoadTexturesPwad(wadnum); // everything from MultiSetupWadFile until ST_Start was here originally @@ -3388,13 +3391,8 @@ boolean P_MultiSetupWadFiles(boolean fullsetup) if (partadd_stage == 1) { -#ifdef HWRENDER - // Free GPU textures before freeing patches. - if (rendermode == render_opengl && (vid.glstate == VID_GL_LIBRARY_LOADED)) - HWR_ClearAllTextures(); -#endif // Reload all textures, unconditionally for better or worse. - R_LoadTextures(); + //R_LoadTextures(); if (fullsetup) ++partadd_stage; diff --git a/src/r_data.c b/src/r_data.c index 688b03972..90dab0b83 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -235,6 +235,7 @@ UINT32 ASTBlendTexturePixel(RGBA_t background, RGBA_t foreground, int style, UIN // Painfully simple texture id cacheing to make maps load faster. :3 static struct { char name[9]; + UINT32 hash; INT32 id; } *tidcache = NULL; static INT32 tidcachelen = 0; @@ -520,32 +521,136 @@ void R_FlushTextureCache(void) int R_CountTexturesInTEXTURESLump(UINT16 wadNum, UINT16 lumpNum); void R_ParseTEXTURESLump(UINT16 wadNum, UINT16 lumpNum, INT32 *index); -// -// R_LoadTextures -// Initializes the texture list with the textures from the world map. -// #define TX_START "TX_START" #define TX_END "TX_END" -void R_LoadTextures(void) + +static INT32 +Rloadtextures (INT32 i, INT32 w) { - INT32 i, k, w; UINT16 j; + INT32 k; UINT16 texstart, texend, texturesLumpPos; softwarepatch_t *patchlump; texpatch_t *patch; texture_t *texture; - // Free previous memory before numtextures change. - if (numtextures) + // Get the lump numbers for the markers in the WAD, if they exist. + if (W_FileHasFolders(wadfiles[w])) { - for (i = 0; i < numtextures; i++) + 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) { - Z_Free(textures[i]); - Z_Free(texturecache[i]); + R_ParseTEXTURESLump(w, texturesLumpPos, &i); + texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, texturesLumpPos + 1); } - Z_Free(texturetranslation); - Z_Free(textures); } + else + { + texstart = W_CheckNumForMarkerStartPwad(TX_START, (UINT16)w, 0); + 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 (texstart == INT16_MAX || texend == INT16_MAX) + return i; + + // Work through each lump between the markers in the WAD. + for (j = 0; j < (texend - texstart); j++) + { + UINT16 wadnum = (UINT16)w; + lumpnum_t lumpnum = texstart + j; + + if (W_FileHasFolders(wadfiles[w])) + { + if (W_IsLumpFolder(wadnum, lumpnum)) // Check if lump is a folder + continue; // If it is then SKIP IT + } + + patchlump = (softwarepatch_t *)W_CacheLumpNumPwad(wadnum, lumpnum, PU_STATIC); + + //CONS_Printf("\n\"%s\" is a single patch, dimensions %d x %d",W_CheckNameForNumPwad((wadnum, lumpnum), patchlump->width, patchlump->height); + texture = textures[i] = Z_Calloc(sizeof(texture_t) + sizeof(texpatch_t), PU_STATIC, NULL); + + // Set texture properties. + M_Memcpy(texture->name, W_CheckNameForNumPwad(wadnum, lumpnum), sizeof(texture->name)); + texture->hash = quickncasehash(texture->name, 8); + texture->width = SHORT(patchlump->width); + texture->height = SHORT(patchlump->height); + texture->patchcount = 1; + texture->holes = false; + + // Allocate information for the texture's patches. + patch = &texture->patches[0]; + + patch->originx = patch->originy = 0; + patch->wad = wadnum; + patch->lump = texstart + j; + + Z_Free(patchlump); + + k = 1; + while (k << 1 <= texture->width) + k <<= 1; + + texturewidthmask[i] = k - 1; + textureheight[i] = texture->height << FRACBITS; + i++; + } + + return i; +} + +static INT32 +count_range +( const char * marker_start, + const char * marker_end, + const char * folder, + UINT16 wadnum) +{ + UINT16 j; + UINT16 texstart, texend; + INT32 count = 0; + + // Count flats + if (W_FileHasFolders(wadfiles[wadnum])) + { + texstart = W_CheckNumForFolderStartPK3(folder, wadnum, 0); + texend = W_CheckNumForFolderEndPK3(folder, wadnum, texstart); + } + else + { + texstart = W_CheckNumForMarkerStartPwad(marker_start, wadnum, 0); + texend = W_CheckNumForNamePwad(marker_end, wadnum, texstart); + } + + if (texstart != INT16_MAX && texend != INT16_MAX) + { + // PK3s have subfolders, so we can't just make a simple sum + if (W_FileHasFolders(wadfiles[wadnum])) + { + for (j = texstart; j < texend; j++) + { + if (!W_IsLumpFolder(wadnum, j)) // Check if lump is a folder; if not, then count it + count++; + } + } + else // Add all the textures between markers + { + count += (texend - texstart); + } + } + + return count; +} + +static INT32 R_CountTextures(UINT16 wadnum) +{ + UINT16 texturesLumpPos; + INT32 count = 0; // Load patches and textures. @@ -554,159 +659,127 @@ void R_LoadTextures(void) // the markers. // This system will allocate memory for all duplicate/patched textures even if it never uses them, // 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++) + + // Count the textures from TEXTURES lumps + texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", wadnum, 0); + + while (texturesLumpPos != INT16_MAX) { - if (W_FileHasFolders(wadfiles[w])) - { - texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0); - texend = W_CheckNumForFolderEndPK3("textures/", (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); - 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 - if (texstart == INT16_MAX || texend == INT16_MAX) - continue; - - // PK3s have subfolders, so we can't just make a simple sum - if (W_FileHasFolders(wadfiles[w])) - { - for (j = texstart; j < texend; j++) - { - if (W_IsLumpFolder((UINT16)w, j)) // Check if lump is a folder; if not, then count it - continue; - - numtextures++; - } - } - else - { - numtextures += (UINT32)(texend - texstart); - } + count += R_CountTexturesInTEXTURESLump(wadnum, texturesLumpPos); + texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", wadnum, texturesLumpPos + 1); } - // If no textures found by this point, bomb out - if (!numtextures) - I_Error("No textures detected in any WADs!\n"); + // Count single-patch textures + count += count_range(TX_START, TX_END, "textures/", wadnum); + + return count; +} + +static void +recallocuser +( void * user, + size_t old, + size_t new) +{ + char *p = Z_Realloc(*(void**)user, + new, PU_STATIC, user); + + if (new > old) + memset(&p[old], 0, (new - old)); +} + +static void R_AllocateTextures(INT32 add) +{ + const INT32 newtextures = (numtextures + add); + const size_t newsize = newtextures * sizeof (void*); + const size_t oldsize = numtextures * sizeof (void*); + + INT32 i; // 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); + recallocuser(&textures, oldsize, newsize); // Allocate texture column offset table. - texturecolumnofs = (void *)((UINT8 *)textures + (numtextures * sizeof(void *))); + recallocuser(&texturecolumnofs, oldsize, newsize); // Allocate texture referencing cache. - texturecache = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 2)); - // Allocate texture width mask table. - texturewidthmask = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 3)); - // Allocate texture height mask table. - textureheight = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 4)); + recallocuser(&texturecache, oldsize, newsize); + // Allocate texture width table. + recallocuser(&texturewidthmask, oldsize, newsize); + // Allocate texture height table. + recallocuser(&textureheight, oldsize, newsize); // Create translation table for global animation. - texturetranslation = Z_Malloc((numtextures + 1) * sizeof(*texturetranslation), PU_STATIC, NULL); + Z_Realloc(texturetranslation, (newtextures + 1) * sizeof(*texturetranslation), PU_STATIC, &texturetranslation); - for (i = 0; i < numtextures; i++) - texturetranslation[i] = i; - - for (i = 0, w = 0; w < numwadfiles; w++) + for (i = 0; i < numtextures; ++i) { - // Get the lump numbers for the markers in the WAD, if they exist. - if (W_FileHasFolders(wadfiles[w])) - { - 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) - { - R_ParseTEXTURESLump(w, texturesLumpPos, &i); - 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) - R_ParseTEXTURESLump(w, texturesLumpPos, &i); - } - - if (texstart == INT16_MAX || texend == INT16_MAX) - continue; - - // Work through each lump between the markers in the WAD. - for (j = 0; j < (texend - texstart); j++) - { - UINT16 wadnum = (UINT16)w; - lumpnum_t lumpnum = texstart + j; - - if (W_FileHasFolders(wadfiles[w])) - { - if (W_IsLumpFolder(wadnum, lumpnum)) // Check if lump is a folder - continue; // If it is then SKIP IT - } - - patchlump = (softwarepatch_t *)W_CacheLumpNumPwad(wadnum, lumpnum, PU_STATIC); - - //CONS_Printf("\n\"%s\" is a single patch, dimensions %d x %d",W_CheckNameForNumPwad(wadnum, lumpnum), patchlump->width, patchlump->height); - texture = textures[i] = Z_Calloc(sizeof(texture_t) + sizeof(texpatch_t), PU_STATIC, NULL); - - // Set texture properties. - M_Memcpy(texture->name, W_CheckNameForNumPwad(wadnum, lumpnum), sizeof(texture->name)); - texture->width = SHORT(patchlump->width); - texture->height = SHORT(patchlump->height); - texture->type = TEXTURETYPE_SINGLEPATCH; - texture->patchcount = 1; - texture->holes = false; - - // Allocate information for the texture's patches. - patch = &texture->patches[0]; - - patch->originx = patch->originy = 0; - patch->wad = wadnum; - patch->lump = texstart + j; - - Z_Free(patchlump); - - // determine width power of 2 -#if 1 - // [WDJ] only need to determine if exact power of 2. - k = 1; - while (k < texture->width) - k<<=1; -#else - // Largest power of 2 that fits within width. - k = 1; - while (k << 1 <= texture->width) - k <<= 1; -#endif - if (k != texture->width) - { - // Odd width - k = 1; // make texturewidthmask = 0 - } - - texturewidthmask[i] = k - 1; - textureheight[i] = texture->height << FRACBITS; - i++; - } + // R_FlushTextureCache relies on the user for + // Z_Free, texturecache has been reallocated so the + // user is now garbage memory. + Z_SetUser(texturecache[i], (void**)&texturecache[i]); } + while (i < newtextures) + { + texturetranslation[i] = i; + i++; + } +} + +static INT32 R_DefineTextures(INT32 i, UINT16 w) +{ + return Rloadtextures(i, w); +} + +static void R_FinishLoadingTextures(INT32 add) +{ + numtextures += add; + #ifdef HWRENDER if (rendermode == render_opengl) HWR_LoadMapTextures(numtextures); #endif } +// +// R_LoadTextures +// Initializes the texture list with the textures from the world map. +// +void R_LoadTextures(void) +{ + INT32 i, w; + INT32 newtextures = 0; + + for (w = 0; w < numwadfiles; w++) + { + newtextures += R_CountTextures((UINT16)w); + } + + // If no textures found by this point, bomb out + if (!newtextures) + I_Error("No textures detected in any WADs!\n"); + + R_AllocateTextures(newtextures); + + for (i = 0, w = 0; w < numwadfiles; w++) + { + i = R_DefineTextures(i, w); + } + + R_FinishLoadingTextures(i); +} + +void R_LoadTexturesPwad(UINT16 wadnum) +{ + INT32 newtextures = R_CountTextures(wadnum); + + if (!newtextures) + return; + + R_AllocateTextures(newtextures); + newtextures = R_DefineTextures(numtextures, wadnum) - numtextures; + R_FinishLoadingTextures(newtextures); +} + static texpatch_t *R_ParsePatch(boolean actuallyLoadPatch) { char *texturesToken; @@ -958,6 +1031,7 @@ static texture_t *R_ParseTexture(boolean actuallyLoadTexture) // Allocate memory for a zero-patch texture. Obviously, we'll be adding patches momentarily. resultTexture = (texture_t *)Z_Calloc(sizeof(texture_t), PU_STATIC, NULL); M_Memcpy(resultTexture->name, newTextureName, 8); + resultTexture->hash = quickncasehash(newTextureName, 8); resultTexture->width = newTextureWidth; resultTexture->height = newTextureHeight; resultTexture->type = TEXTURETYPE_COMPOSITE; @@ -1741,19 +1815,22 @@ void R_ClearTextureNumCache(boolean btell) INT32 R_CheckTextureNumForName(const char *name) { INT32 i; + UINT32 hash; // "NoTexture" marker. if (name[0] == '-') return 0; + hash = quickncasehash(name, 8); + for (i = 0; i < tidcachelen; i++) - if (!strncasecmp(tidcache[i].name, name, 8)) + if (tidcache[i].hash == hash && !strncasecmp(tidcache[i].name, name, 8)) return tidcache[i].id; // Need to parse the list backwards, so textures loaded more recently are used in lieu of ones loaded earlier //for (i = 0; i < numtextures; i++) <- old for (i = (numtextures - 1); i >= 0; i--) // <- new - if (!strncasecmp(textures[i]->name, name, 8)) + if (textures[i]->hash == hash && !strncasecmp(textures[i]->name, name, 8)) { tidcachelen++; Z_Realloc(tidcache, tidcachelen * sizeof(*tidcache), PU_STATIC, &tidcache); @@ -1762,6 +1839,7 @@ INT32 R_CheckTextureNumForName(const char *name) #ifndef ZDEBUG CONS_Debug(DBG_SETUP, "texture #%s: %s\n", sizeu1(tidcachelen), tidcache[tidcachelen-1].name); #endif + tidcache[tidcachelen-1].hash = hash; tidcache[tidcachelen-1].id = i; return i; } diff --git a/src/r_data.h b/src/r_data.h index 58afc34d0..7c0910b31 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -52,7 +52,7 @@ typedef struct { // Keep name for switch changing, etc. char name[8]; - UINT8 type; // TEXTURETYPE_ + UINT32 hash; INT16 width, height; boolean holes; // All the patches[patchcount] are drawn back to front into the cached texture. @@ -76,6 +76,7 @@ extern CV_PossibleValue_t Color_cons_t[]; // Load TEXTURE1/TEXTURE2/PNAMES definitions, create lookup tables void R_LoadTextures(void); +void R_LoadTexturesPwad(UINT16 wadnum); void R_FlushTextureCache(void); UINT8 *R_GenerateTexture(size_t texnum); diff --git a/src/w_wad.c b/src/w_wad.c index 5c774aa60..65e08f4c1 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -371,6 +371,8 @@ static lumpinfo_t* ResGetLumpsStandalone (FILE* handle, UINT16* numlumps, const fseek(handle, 0, SEEK_END); lumpinfo->size = ftell(handle); fseek(handle, 0, SEEK_SET); + strlcpy(lumpinfo->name, lumpname, 9); + lumpinfo->hash = quickncasehash(lumpname, 8); strlcpy(lumpinfo->name, lumpname, sizeof(lumpinfo->name)); lumpinfo->namelength = strlen(lumpinfo->name); @@ -476,8 +478,7 @@ static lumpinfo_t* ResGetLumpsWad (FILE* handle, UINT16* nlmp, const char* filen lump_p->compression = CM_NOCOMPRESSION; memset(lump_p->name, 0x00, 9); strncpy(lump_p->name, fileinfo->name, 8); - lump_p->namelength = strlen(lump_p->name); - lump_p->hash.name = W_HashLumpName(lump_p->name); + lump_p->hash = quickncasehash(lump_p->name, 8); // Allocate the lump's long name. lump_p->longname = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL); @@ -684,8 +685,7 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp) memset(lump_p->name, '\0', 9); // Making sure they're initialized to 0. Is it necessary? strncpy(lump_p->name, trimname, min(8, dotpos - trimname)); - lump_p->namelength = strlen(lump_p->name); - lump_p->hash.name = W_HashLumpName(lump_p->name); + lump_p->hash = quickncasehash(lump_p->name, 8); lump_p->longname = Z_Calloc(dotpos - trimname + 1, PU_STATIC, NULL); strlcpy(lump_p->longname, trimname, dotpos - trimname + 1); @@ -1012,7 +1012,6 @@ UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump) UINT16 i; static char uname[9]; UINT32 hash; - size_t namelen; if (!TestValidLump(wad,0)) return INT16_MAX; @@ -1020,8 +1019,7 @@ UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump) memset(uname, 0, sizeof uname); strncpy(uname, name, sizeof(uname)-1); strupr(uname); - namelen = strlen(uname); - hash = W_HashLumpName(uname); + hash = quickncasehash(uname, 8); // // scan forward @@ -1032,9 +1030,7 @@ 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 (lump_p->namelength == namelen - && lump_p->hash.name == hash - && !memcmp(lump_p->name, uname, sizeof(uname) - 1)) + if (lump_p->hash == hash && memcmp(lump_p->name, uname, sizeof(uname) - 1) == 0) return i; } @@ -1264,6 +1260,50 @@ lumpnum_t W_CheckNumForLongName(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) +{ + UINT32 hash = name ? quickncasehash(name, 8) : 0; + UINT16 lumpNum, end; + UINT32 i; + lumpinfo_t *p; + for (i = numwadfiles - 1; i < numwadfiles; i--) + { + if (wadfiles[i]->type == RET_WAD) + { + for (lumpNum = 0; lumpNum < wadfiles[i]->numlumps; lumpNum++) + { + p = wadfiles[i]->lumpinfo + lumpNum; + if (p->hash == hash && !strncmp(name, p->name, 8)) + return (i<<16) + lumpNum; + } + } + else if (wadfiles[i]->type == RET_PK3) + { + lumpNum = W_CheckNumForFolderStartPK3("maps/", i, 0); + if (lumpNum != INT16_MAX) + end = W_CheckNumForFolderEndPK3("maps/", i, lumpNum); + else + continue; + // Now look for the specified map. + for (; lumpNum < end; lumpNum++) + { + p = wadfiles[i]->lumpinfo + lumpNum; + + if (p->hash == hash && !strnicmp(name, p->name, 8)) + { + const char *extension = strrchr(p->fullname, '.'); + if (!(extension && stricmp(extension, ".wad"))) + return (i<<16) + lumpNum; + } + } + } + } + return LUMPERROR; +} + // // W_GetNumForName // diff --git a/src/w_wad.h b/src/w_wad.h index 196fd7893..cfdb5c4b1 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -75,6 +75,7 @@ typedef struct unsigned long position; // filelump_t filepos unsigned long disksize; // filelump_t size char name[9]; // filelump_t name[] e.g. "LongEntr" + UINT32 hash; char *longname; // e.g. "LongEntryName" char *fullname; // e.g. "Folder/Subfolder/LongEntryName.extension" -- 2.54.0 From 44ecb677ad7f2c47a98dd7b9a7de4983276f391b Mon Sep 17 00:00:00 2001 From: Alug Date: Sun, 3 Aug 2025 00:37:28 +0200 Subject: [PATCH 02/66] fix merge conflicts texturehashing --- src/p_setup.c | 7 +++--- src/r_data.c | 15 +++++++++++++ src/r_data.h | 1 + src/w_wad.c | 60 +++++++++------------------------------------------ src/w_wad.h | 1 - 5 files changed, 30 insertions(+), 54 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 05ad8fc93..3cacbca54 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2345,9 +2345,7 @@ static void P_RunLevelScript(const char *scriptname) lumpnum_t lumpnum; char newname[9]; - strncpy(newname, scriptname, 8); - - newname[8] = '\0'; + strlcpy(newname, scriptname, sizeof(newname)); lumpnum = W_CheckNumForName(newname); @@ -3311,6 +3309,9 @@ UINT16 P_PartialAddWadFile(const char *wadfilename, boolean local) if (!devparm && digmreplaces) CONS_Printf(M_GetText("%s digital musics replaced\n"), sizeu1(digmreplaces)); + if (!mapsadded) + CONS_Printf(M_GetText("No maps added\n")); + #ifdef HWRENDER // Free GPU textures before freeing patches. if (rendermode == render_opengl && (vid.glstate == VID_GL_LIBRARY_LOADED)) diff --git a/src/r_data.c b/src/r_data.c index 90dab0b83..ce0965e0d 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -580,6 +580,7 @@ Rloadtextures (INT32 i, INT32 w) texture->hash = quickncasehash(texture->name, 8); texture->width = SHORT(patchlump->width); texture->height = SHORT(patchlump->height); + texture->type = TEXTURETYPE_SINGLEPATCH; texture->patchcount = 1; texture->holes = false; @@ -592,9 +593,23 @@ Rloadtextures (INT32 i, INT32 w) Z_Free(patchlump); + // determine width power of 2 +#if 1 + // [WDJ] only need to determine if exact power of 2. + k = 1; + while (k < texture->width) + k<<=1; +#else + // Largest power of 2 that fits within width. k = 1; while (k << 1 <= texture->width) k <<= 1; +#endif + if (k != texture->width) + { + // Odd width + k = 1; // make texturewidthmask = 0 + } texturewidthmask[i] = k - 1; textureheight[i] = texture->height << FRACBITS; diff --git a/src/r_data.h b/src/r_data.h index 7c0910b31..295cff401 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -52,6 +52,7 @@ typedef struct { // Keep name for switch changing, etc. char name[8]; + UINT8 type; // TEXTURETYPE_ UINT32 hash; INT16 width, height; boolean holes; diff --git a/src/w_wad.c b/src/w_wad.c index 65e08f4c1..5c774aa60 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -371,8 +371,6 @@ static lumpinfo_t* ResGetLumpsStandalone (FILE* handle, UINT16* numlumps, const fseek(handle, 0, SEEK_END); lumpinfo->size = ftell(handle); fseek(handle, 0, SEEK_SET); - strlcpy(lumpinfo->name, lumpname, 9); - lumpinfo->hash = quickncasehash(lumpname, 8); strlcpy(lumpinfo->name, lumpname, sizeof(lumpinfo->name)); lumpinfo->namelength = strlen(lumpinfo->name); @@ -478,7 +476,8 @@ static lumpinfo_t* ResGetLumpsWad (FILE* handle, UINT16* nlmp, const char* filen lump_p->compression = CM_NOCOMPRESSION; memset(lump_p->name, 0x00, 9); strncpy(lump_p->name, fileinfo->name, 8); - lump_p->hash = quickncasehash(lump_p->name, 8); + lump_p->namelength = strlen(lump_p->name); + lump_p->hash.name = W_HashLumpName(lump_p->name); // Allocate the lump's long name. lump_p->longname = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL); @@ -685,7 +684,8 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp) memset(lump_p->name, '\0', 9); // Making sure they're initialized to 0. Is it necessary? strncpy(lump_p->name, trimname, min(8, dotpos - trimname)); - lump_p->hash = quickncasehash(lump_p->name, 8); + lump_p->namelength = strlen(lump_p->name); + lump_p->hash.name = W_HashLumpName(lump_p->name); lump_p->longname = Z_Calloc(dotpos - trimname + 1, PU_STATIC, NULL); strlcpy(lump_p->longname, trimname, dotpos - trimname + 1); @@ -1012,6 +1012,7 @@ UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump) UINT16 i; static char uname[9]; UINT32 hash; + size_t namelen; if (!TestValidLump(wad,0)) return INT16_MAX; @@ -1019,7 +1020,8 @@ UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump) memset(uname, 0, sizeof uname); strncpy(uname, name, sizeof(uname)-1); strupr(uname); - hash = quickncasehash(uname, 8); + namelen = strlen(uname); + hash = W_HashLumpName(uname); // // scan forward @@ -1030,7 +1032,9 @@ 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 (lump_p->hash == hash && memcmp(lump_p->name, uname, sizeof(uname) - 1) == 0) + if (lump_p->namelength == namelen + && lump_p->hash.name == hash + && !memcmp(lump_p->name, uname, sizeof(uname) - 1)) return i; } @@ -1260,50 +1264,6 @@ lumpnum_t W_CheckNumForLongName(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) -{ - UINT32 hash = name ? quickncasehash(name, 8) : 0; - UINT16 lumpNum, end; - UINT32 i; - lumpinfo_t *p; - for (i = numwadfiles - 1; i < numwadfiles; i--) - { - if (wadfiles[i]->type == RET_WAD) - { - for (lumpNum = 0; lumpNum < wadfiles[i]->numlumps; lumpNum++) - { - p = wadfiles[i]->lumpinfo + lumpNum; - if (p->hash == hash && !strncmp(name, p->name, 8)) - return (i<<16) + lumpNum; - } - } - else if (wadfiles[i]->type == RET_PK3) - { - lumpNum = W_CheckNumForFolderStartPK3("maps/", i, 0); - if (lumpNum != INT16_MAX) - end = W_CheckNumForFolderEndPK3("maps/", i, lumpNum); - else - continue; - // Now look for the specified map. - for (; lumpNum < end; lumpNum++) - { - p = wadfiles[i]->lumpinfo + lumpNum; - - if (p->hash == hash && !strnicmp(name, p->name, 8)) - { - const char *extension = strrchr(p->fullname, '.'); - if (!(extension && stricmp(extension, ".wad"))) - return (i<<16) + lumpNum; - } - } - } - } - return LUMPERROR; -} - // // W_GetNumForName // diff --git a/src/w_wad.h b/src/w_wad.h index cfdb5c4b1..196fd7893 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -75,7 +75,6 @@ typedef struct unsigned long position; // filelump_t filepos unsigned long disksize; // filelump_t size char name[9]; // filelump_t name[] e.g. "LongEntr" - UINT32 hash; char *longname; // e.g. "LongEntryName" char *fullname; // e.g. "Folder/Subfolder/LongEntryName.extension" -- 2.54.0 From eba596522088fe3437d672d5395eb017bd2784fc Mon Sep 17 00:00:00 2001 From: Alug Date: Sun, 3 Aug 2025 14:42:37 +0200 Subject: [PATCH 03/66] move rainbow color calc into K_Rainbowcolor --- src/k_hud.c | 4 ++-- src/k_kart.c | 23 +++++++++++++++++++++-- src/k_kart.h | 1 + src/p_mobj.c | 6 +++--- src/p_user.c | 2 +- 5 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/k_hud.c b/src/k_hud.c index 64f1680a8..e8e3bcad7 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -1699,7 +1699,7 @@ static void K_drawKartItem(void) switch (stplyr->kartstuff[k_itemblinkmode]) { case 2: - localcolor = (UINT8)(1 + (leveltime % (MAXSKINCOLORS-1))); + localcolor = K_RainbowColor(); break; case 1: localcolor = SKINCOLOR_RED; @@ -4098,7 +4098,7 @@ static void K_drawKartFirstPerson(void) // drift sparks! if ((leveltime & 1) && (stplyr->kartstuff[k_driftcharge] >= dsthree)) - colmap = R_GetTranslationColormap(TC_RAINBOW, (UINT8)(1 + (leveltime % (MAXSKINCOLORS-1))), GTC_CACHE); + colmap = R_GetTranslationColormap(TC_RAINBOW, K_RainbowColor(), GTC_CACHE); else if ((leveltime & 1) && (stplyr->kartstuff[k_driftcharge] >= dstwo)) colmap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_KETCHUP, GTC_CACHE); else if ((leveltime & 1) && (stplyr->kartstuff[k_driftcharge] >= dsone)) diff --git a/src/k_kart.c b/src/k_kart.c index d8d4a3a86..a699c5603 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -484,6 +484,15 @@ UINT8 colortranslations[MAXTRANSLATIONS][16] = { {120, 120, 96, 96, 97, 98, 98, 99, 81, 81, 69, 71, 73, 75, 77, 79}, // SKINCOLOR_CSUPER5 }; +// +// Gives you a color to use for rainbow effects (like invincibility). +// Return: Skincolor value. +// +UINT8 K_RainbowColor(void) +{ + return (UINT8)(1 + (leveltime % (MAXSKINCOLORS-1))); +} + // Define for getting accurate color brightness readings according to how the human eye sees them. // https://en.wikipedia.org/wiki/Relative_luminance // 0.2126 to red @@ -645,36 +654,46 @@ UINT8 K_GetKartColorByName(const char *name) return 0; } +// // returns the players skinnumber // accounts for localskins +// INT32 K_GetSkinNum(player_t *player) { return player->localskin ? (player->localskin - 1) : player->skin; } +// // returns the mobj skinnumber // accounts for localskins +// INT32 K_GetMobjSkinNum(const skin_t *skin, boolean local) { return skin - K_GetSkinArray(local); } +// // returns the players skinnumber // accounts for localskins +// skin_t *K_GetMobjSkin(const mobj_t *mobj) { return mobj->localskin ? mobj->localskin : mobj->skin; } +// // returns the skin array to use // accounts for localskins +// skin_t *K_GetSkinArray(boolean local) { return local ? localskins : skins; } +// // returns the players skin // accounts for localskins +// skin_t *K_GetPlayerSkin(player_t *player) { return &K_GetSkinArray(player->skinlocal)[K_GetSkinNum(player)]; @@ -3084,7 +3103,7 @@ static UINT16 K_DriftSparkColor(player_t *player, INT32 charge) if (charge >= K_GetKartDriftSparkValue(player)*4) { - color = (UINT8)(1 + (leveltime % (MAXSKINCOLORS-1))); + color = K_RainbowColor(); } else if (charge >= K_GetKartDriftSparkValue(player)*2) { @@ -5371,7 +5390,7 @@ static UINT8 K_GetSpeedLineColor(player_t *player, boolean colorSpeed) else if (player->kartstuff[k_driftboost] <= 50) speedcolor = SKINCOLOR_RASPBERRY; else if (player->kartstuff[k_driftboost] <= 125) - speedcolor = (UINT8)(1 + (leveltime % (MAXSKINCOLORS-1))); + speedcolor = K_RainbowColor(); if (cv_coloredspeedlines.value == 2) speedcolor = (leveltime & 1) ? playercolor : speedcolor; diff --git a/src/k_kart.h b/src/k_kart.h index 012cd48ac..1dda3d960 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -19,6 +19,7 @@ extern "C" { extern UINT8 colortranslations[MAXTRANSLATIONS][16]; extern const char *KartColor_Names[MAXSKINCOLORS]; extern const UINT8 KartColor_Opposite[MAXSKINCOLORS*2]; +UINT8 K_RainbowColor(void); void K_RainbowColormap(UINT8 *dest_colormap, UINT8 skincolor); void K_GenerateKartColormap(UINT8 *dest_colormap, INT32 skinnum, UINT8 color, boolean local); UINT8 K_GetKartColorByName(const char *name); diff --git a/src/p_mobj.c b/src/p_mobj.c index de185468a..ff0a35949 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6964,7 +6964,7 @@ static boolean P_MobjDeadThink(mobj_t *mobj) if (mobj->flags2 & MF2_AMBUSH) { mobj->colorized = true; - mobj->color = (1 + (leveltime % (MAXSKINCOLORS-1))); + mobj->color = K_RainbowColor(); mobj->frame |= FF_FULLBRIGHT; } else @@ -7806,7 +7806,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) P_SetScale(mobj, (mobj->destscale = mobj->target->scale)); if (mobj->target->player->kartstuff[k_driftcharge] >= K_GetKartDriftSparkValue(mobj->target->player)*4) - mobj->color = (UINT8)(1 + (leveltime % (MAXSKINCOLORS-1))); + mobj->color = K_RainbowColor(); else if (mobj->target->player->kartstuff[k_driftcharge] >= K_GetKartDriftSparkValue(mobj->target->player)*2) mobj->color = SKINCOLOR_KETCHUP; else if (mobj->target->player->kartstuff[k_driftcharge] >= K_GetKartDriftSparkValue(mobj->target->player)) @@ -8505,7 +8505,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) if (mobj->flags2 & MF2_AMBUSH) { mobj->colorized = true; - mobj->color = (1 + (leveltime % (MAXSKINCOLORS-1))); + mobj->color = K_RainbowColor(); mobj->frame |= FF_FULLBRIGHT; } else diff --git a/src/p_user.c b/src/p_user.c index 52e390885..731135ebd 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1641,7 +1641,7 @@ static void P_CheckInvincibilityTimer(player_t *player) if (!player->powers[pw_invulnerability] && !player->kartstuff[k_invincibilitytimer]) return; - player->mo->color = (UINT8)(1 + (leveltime % (MAXSKINCOLORS-1))); + player->mo->color = K_RainbowColor(); // Resume normal music stuff. if (player->powers[pw_invulnerability] == 1 || player->kartstuff[k_invincibilitytimer] == 1) -- 2.54.0 From 91a4646f194ecf8fbb551077fffa5085adf4570e Mon Sep 17 00:00:00 2001 From: Alug Date: Sun, 3 Aug 2025 15:51:15 +0200 Subject: [PATCH 04/66] dont PU_CACHE our planeflats --- src/r_plane.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/r_plane.cpp b/src/r_plane.cpp index 0e2e563ff..dd4813794 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -1182,7 +1182,7 @@ void R_DrawSinglePlane(drawspandata_t* ds, visplane_t *pl, boolean allow_paralle levelflat = &levelflats[pl->picnum]; // Get the texture - ds->source = (UINT8 *)W_CacheLumpNum(levelflat->lumpnum, PU_STATIC); // Stay here until Z_ChangeTag + ds->source = R_GetFlat(levelflat->lumpnum); if (ds->source == NULL) return; @@ -1387,8 +1387,6 @@ using the palette colors. } } #endif - - Z_ChangeTag(ds->source, PU_CACHE); } void R_PlaneBounds(visplane_t *plane) -- 2.54.0 From dac70267395de1e9ee19d6ddaee6d0dee7dfbaf7 Mon Sep 17 00:00:00 2001 From: Alug Date: Sun, 3 Aug 2025 15:53:47 +0200 Subject: [PATCH 05/66] use R_GetFlat here does the exact same thing --- src/p_setup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index e034c35b8..59d7f84e5 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -678,7 +678,7 @@ INT32 P_AddLevelFlat(const char *flatname, levelflat_t *levelflat) // check if our flat contains cyan pixels // not sure if this is the best way to do it but it works { - const UINT8 *flat = (UINT8 *)W_CacheLumpNum(levelflat->lumpnum, PU_LEVEL); + const UINT8 *flat = R_GetFlat(levelflat->lumpnum); size_t size = W_LumpLength(levelflat->lumpnum); for (size_t steppy = 0; steppy < size; steppy++) { @@ -738,7 +738,7 @@ INT32 P_AddLevelFlatRuntime(const char *flatname) // check if our flat contains cyan pixels // not sure if this is the best way to do it but it works { - const UINT8 *flat = (UINT8 *)W_CacheLumpNum(levelflat->lumpnum, PU_LEVEL); + const UINT8 *flat = R_GetFlat(levelflat->lumpnum); size_t size = W_LumpLength(levelflat->lumpnum); for (size_t steppy = 0; steppy < size; steppy++) { -- 2.54.0 From b0c217201e69127bc9e336a4a52c010087595bba Mon Sep 17 00:00:00 2001 From: Alug Date: Sun, 3 Aug 2025 15:59:57 +0200 Subject: [PATCH 06/66] move flat cyan check into a function and also limit it to software renderer only we dont need this anywhere else, so can save a bit of work --- src/p_setup.c | 53 +++++++++++++++++++++++---------------------------- 1 file changed, 24 insertions(+), 29 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 59d7f84e5..0958054cf 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -650,6 +650,27 @@ size_t P_PrecacheLevelFlats(void) return flatmem; } +// check if our flat contains cyan pixels +// not sure if this is the best way to do it but it works +static void P_CheckCyanFlat(levelflat_t *levelflat) +{ + // only need this for software + if (rendermode != render_soft) + return; + + const UINT8 *flat = R_GetFlat(levelflat->lumpnum); + const size_t size = W_LumpLength(levelflat->lumpnum); + + for (size_t steppy = 0; steppy < size; steppy++) + { + if (flat[steppy] == TRANSPARENTPIXEL) + { + levelflat->cyan = true; + break; + } + } +} + // help function for P_LoadSectors, find a flat in the active wad files, // allocate an id for it, and set the levelflat (to speedup search) // @@ -661,7 +682,7 @@ INT32 P_AddLevelFlat(const char *flatname, levelflat_t *levelflat) // first scan through the already found flats // 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 @@ -675,20 +696,7 @@ INT32 P_AddLevelFlat(const char *flatname, levelflat_t *levelflat) levelflat->lumpnum = R_GetFlatNumForName(flatname); levelflat->baselumpnum = LUMPERROR; - // check if our flat contains cyan pixels - // not sure if this is the best way to do it but it works - { - const UINT8 *flat = R_GetFlat(levelflat->lumpnum); - size_t size = W_LumpLength(levelflat->lumpnum); - for (size_t steppy = 0; steppy < size; steppy++) - { - if (flat[steppy] == TRANSPARENTPIXEL) - { - levelflat->cyan = true; - break; - } - } - } + P_CheckCyanFlat(levelflat); #ifndef ZDEBUG CONS_Debug(DBG_SETUP, "flat #%03d: %s\n", atoi(sizeu1(numlevelflats)), levelflat->name); @@ -735,20 +743,7 @@ INT32 P_AddLevelFlatRuntime(const char *flatname) levelflat->lumpnum = R_GetFlatNumForName(flatname); levelflat->baselumpnum = LUMPERROR; - // check if our flat contains cyan pixels - // not sure if this is the best way to do it but it works - { - const UINT8 *flat = R_GetFlat(levelflat->lumpnum); - size_t size = W_LumpLength(levelflat->lumpnum); - for (size_t steppy = 0; steppy < size; steppy++) - { - if (flat[steppy] == TRANSPARENTPIXEL) - { - levelflat->cyan = true; - break; - } - } - } + P_CheckCyanFlat(levelflat); #ifndef ZDEBUG CONS_Debug(DBG_SETUP, "flat #%03d: %s\n", atoi(sizeu1(numlevelflats)), levelflat->name); -- 2.54.0 From e120907e0fc59092aa4797adb3b0ba3a38d6ea44 Mon Sep 17 00:00:00 2001 From: Alug Date: Sun, 3 Aug 2025 20:11:16 +0200 Subject: [PATCH 07/66] make driftgauge stuff a bit more readable --- src/k_hud.c | 106 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 71 insertions(+), 35 deletions(-) diff --git a/src/k_hud.c b/src/k_hud.c index e8e3bcad7..520c6ae33 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -1138,6 +1138,33 @@ static boolean K_UseColorSpeedo(int speedostyle) } } +enum +{ + GAUGE_DEFAULT = 1, + GAUGE_SMALL, + GAUGE_BIGNUM, + GAUGE_NUMONLY, + GAUGE_EXTRA, +}; + +static SINT8 K_GetDriftgaugeStyle(void) +{ + if (driftgaugegfx) + { + if (cv_driftgaugestyle.value == 1) + return GAUGE_DEFAULT; + else if (cv_driftgaugestyle.value == 2) + return GAUGE_SMALL; + else if (cv_driftgaugestyle.value == 3) + return GAUGE_BIGNUM; + else if (cv_driftgaugestyle.value == 5 && xtra_speedo3) + return GAUGE_EXTRA; + } + + // Fallback + return GAUGE_NUMONLY; // (cv_driftgaugestyle.value == 4) +} + static boolean K_IsHighResolution(void) { return (vid.width >= 640 && vid.height >= 400); @@ -3149,7 +3176,7 @@ static void K_drawDriftGauge(void) fixed_t basex, basey; const int dup = vid.dupx; int i; - UINT8 *cmap; + UINT8 *colormap = NULL; static const UINT8 driftcolors[3][4] = { {0, 0, 10, 16}, // no drift @@ -3195,23 +3222,21 @@ skipcrap: const INT32 driftcharge = min(driftval*4, stplyr->kartstuff[k_driftcharge]); const INT32 driftlevel = min(driftcharge / driftval, 2); const INT32 drifttrans = ((cv_driftgaugetrans.value) ? V_LocalTransFlag() : 0); + const SINT8 gaugestyle = K_GetDriftgaugeStyle(); basex = pos.x>>FRACBITS; basey = pos.y>>FRACBITS; - switch (cv_driftgaugestyle.value) + switch (gaugestyle) { - case 1: - case 2: - case 3: - case 5: + case GAUGE_DEFAULT: + case GAUGE_SMALL: + case GAUGE_EXTRA: + case GAUGE_BIGNUM: { - if (!driftgaugegfx) - break; + patch_t *driftpatch = NULL; - const boolean usescaledpatch = (cv_driftgaugestyle.value == 5 && xtra_speedo3); - - if (cv_driftgaugestyle.value == 1 || cv_driftgaugestyle.value == 3 || usescaledpatch) + if (gaugestyle == GAUGE_DEFAULT || gaugestyle == GAUGE_BIGNUM || gaugestyle == GAUGE_EXTRA) { barx = basex - dup*23; BAR_WIDTH = dup*47; @@ -3224,40 +3249,44 @@ skipcrap: bary = basey - dup*2; - if (usescaledpatch) // i hate hud code i hate hud code i hate hud code i hate hud code i hate hud code..... + if (gaugestyle == GAUGE_EXTRA) // i hate hud code i hate hud code i hate hud code i hate hud code i hate hud code..... { - if (K_UseColorSpeedo(SPEEDO_EXTRA3)) // Colourized hud + if (K_UseColorSpeedo(SPEEDO_EXTRA3)) // We reuse the extra speedometer patch hence this check { - UINT8 *colormap = R_GetTranslationColormap(TC_DEFAULT, K_GetHudColor(), GTC_CACHE); - V_DrawStretchyFixedPatch((basex - dup*30)<= driftval*4) // rainbow sparks { - cmap = R_GetTranslationColormap(TC_RAINBOW, 1 + leveltime % (MAXSKINCOLORS-1),GTC_CACHE); + colormap = R_GetTranslationColormap(TC_RAINBOW, K_RainbowColor(), GTC_CACHE); for (i = 0; i < 4; i++) - V_DrawFill(barx, bary+dup*1+dup*i, BAR_WIDTH, dup, (driftrainbow[min((leveltime % 18) + 1, 18 - 1)] + i*2) | V_NOSCALESTART|drifttrans); + V_DrawFill(barx, bary+dup*1+dup*i, BAR_WIDTH, dup, (driftrainbow[min((leveltime % 18) + 1, 17)] + i*2) | V_NOSCALESTART|drifttrans); } else // none/blue/red { const INT32 limit = (driftval * (driftcharge >= driftval*2 ? 2 : 1)); const INT32 width = ((driftcharge - (driftcharge >= driftval ? limit : 0)) * BAR_WIDTH) / limit; - cmap = R_GetTranslationColormap(TC_RAINBOW, driftskins[driftlevel],GTC_CACHE); + colormap = R_GetTranslationColormap(TC_RAINBOW, driftskins[driftlevel], GTC_CACHE); for (i = 0; i < 4; i++) { @@ -3269,20 +3298,20 @@ skipcrap: } // right, also draw a cool number - if (cv_driftgaugestyle.value == 3) - V_DrawPaddedTallColorNum(basex + (dup*32), basey, V_NOSCALESTART|V_OFFSET|drifttrans, driftcharge*100 / driftval, 3, cmap); + if (gaugestyle == GAUGE_BIGNUM) + V_DrawPaddedTallColorNum(basex + (dup*32), basey, V_NOSCALESTART|V_OFFSET|drifttrans, driftcharge*100 / driftval, 3, colormap); else - V_DrawPingNum(cv_driftgaugestyle.value == 2 ? basex + (dup*22) : basex + (dup*32), basey, V_NOSCALESTART|V_OFFSET|drifttrans, driftcharge*100 / driftval, cmap); + V_DrawPingNum((gaugestyle == GAUGE_SMALL ? basex + (dup*22) : basex + (dup*32)), basey, V_NOSCALESTART|V_OFFSET|drifttrans, driftcharge*100 / driftval, colormap); } break; - case 4: + case GAUGE_NUMONLY: { if (driftcharge >= driftval*4) - cmap = R_GetTranslationColormap(TC_RAINBOW, 1 + leveltime % (MAXSKINCOLORS-1),GTC_CACHE); + colormap = R_GetTranslationColormap(TC_RAINBOW, K_RainbowColor(), GTC_CACHE); else - cmap = R_GetTranslationColormap(TC_RAINBOW, driftskins[driftlevel],GTC_CACHE); + colormap = R_GetTranslationColormap(TC_RAINBOW, driftskins[driftlevel], GTC_CACHE); - V_DrawPaddedTallColorNum(basex + (dup*16), basey, V_NOSCALESTART|V_OFFSET|drifttrans, driftcharge*100 / driftval, 3, cmap); + V_DrawPaddedTallColorNum(basex + (dup*16), basey, V_NOSCALESTART|V_OFFSET|drifttrans, driftcharge*100 / driftval, 3, colormap); } break; default: @@ -3343,6 +3372,7 @@ static void K_drawKartWanted(void) { basex = WANT_X; basey = WANT_Y; + if (splitscreen == 2) { basey += 16; // slight adjust for 3P @@ -4092,17 +4122,23 @@ static void K_drawKartFirstPerson(void) x -= xoffs; else x += xoffs; + if (!splitscreen) y += yoffs; } + const INT32 driftcharge = stplyr->kartstuff[k_driftcharge]; + // drift sparks! - if ((leveltime & 1) && (stplyr->kartstuff[k_driftcharge] >= dsthree)) - colmap = R_GetTranslationColormap(TC_RAINBOW, K_RainbowColor(), GTC_CACHE); - else if ((leveltime & 1) && (stplyr->kartstuff[k_driftcharge] >= dstwo)) - colmap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_KETCHUP, GTC_CACHE); - else if ((leveltime & 1) && (stplyr->kartstuff[k_driftcharge] >= dsone)) - colmap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_SAPPHIRE, GTC_CACHE); + if ((leveltime & 1) && driftcharge) + { + if (driftcharge >= dsthree) + colmap = R_GetTranslationColormap(TC_RAINBOW, K_RainbowColor(), GTC_CACHE); + else if (driftcharge >= dstwo) + colmap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_KETCHUP, GTC_CACHE); + else if (driftcharge >= dsone) + colmap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_SAPPHIRE, GTC_CACHE); + } else #endif // invincibility/grow/shrink! -- 2.54.0 From ad1b1eabe40042105371a29f2239587e9351e14c Mon Sep 17 00:00:00 2001 From: Alug Date: Wed, 6 Aug 2025 00:03:31 +0200 Subject: [PATCH 08/66] fix levelstuff not being interpolated on netgame join or resynch i love polyobjects --- src/p_polyobj.c | 2 +- src/p_polyobj.h | 1 + src/p_saveg.c | 116 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 118 insertions(+), 1 deletion(-) diff --git a/src/p_polyobj.c b/src/p_polyobj.c index 7842cfad3..27463fbac 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -1511,7 +1511,7 @@ static polyobj_t *Polyobj_GetParent(polyobj_t *po) // Iteratively retrieves the children POs of a parent, // sorta like P_FindSectorSpecialFromTag. // -static polyobj_t *Polyobj_GetChild(polyobj_t *po, INT32 *start) +polyobj_t *Polyobj_GetChild(polyobj_t *po, INT32 *start) { for (; *start < numPolyObjects; (*start)++) { diff --git a/src/p_polyobj.h b/src/p_polyobj.h index 9a47cd150..92f46dd69 100644 --- a/src/p_polyobj.h +++ b/src/p_polyobj.h @@ -269,6 +269,7 @@ typedef struct polydisplacedata_s // polyobj_t *Polyobj_GetForNum(INT32 id); +polyobj_t *Polyobj_GetChild(polyobj_t *po, INT32 *start); void Polyobj_InitLevel(void); void Polyobj_MoveOnLoad(polyobj_t *po, angle_t angle, fixed_t x, fixed_t y); boolean P_PointInsidePolyobj(polyobj_t *po, fixed_t x, fixed_t y); diff --git a/src/p_saveg.c b/src/p_saveg.c index 8dc50e1f6..624a3badf 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -2234,6 +2234,12 @@ static void LoadSpecialLevelThinker(savebuffer_t *save, actionf_p1 thinker, UINT } P_AddThinker(&ht->thinker); + + // interpolation + if (floorOrCeiling & 2) + R_CreateInterpolator_SectorPlane(&ht->thinker, ht->sector, true); + if (floorOrCeiling & 1) + R_CreateInterpolator_SectorPlane(&ht->thinker, ht->sector, false); } // @@ -2263,6 +2269,9 @@ static void LoadCeilingThinker(savebuffer_t *save, actionf_p1 thinker) if (ht->sector) ht->sector->ceilingdata = ht; P_AddThinker(&ht->thinker); + + // interpolation + R_CreateInterpolator_SectorPlane(&ht->thinker, ht->sector, true); } // @@ -2287,6 +2296,9 @@ static void LoadFloormoveThinker(savebuffer_t *save, actionf_p1 thinker) if (ht->sector) ht->sector->floordata = ht; P_AddThinker(&ht->thinker); + + // interpolation + R_CreateInterpolator_SectorPlane(&ht->thinker, ht->sector, false); } // @@ -2400,6 +2412,9 @@ static void LoadElevatorThinker(savebuffer_t *save, actionf_p1 thinker, UINT8 fl } P_AddThinker(&ht->thinker); + + // interpolation + R_CreateInterpolator_SectorPlane(&ht->thinker, ht->sector, (floorOrCeiling & 2)); } // @@ -2422,6 +2437,22 @@ static void LoadScrollThinker(savebuffer_t *save, actionf_p1 thinker) ht->exclusive = READINT32(save->p); ht->type = READUINT8(save->p); P_AddThinker(&ht->thinker); + + // interpolation + switch (ht->type) + { + case sc_side: + R_CreateInterpolator_SideScroll(&ht->thinker, &sides[ht->affectee]); + break; + case sc_floor: + R_CreateInterpolator_SectorScroll(&ht->thinker, §ors[ht->affectee], false); + break; + case sc_ceiling: + R_CreateInterpolator_SectorScroll(&ht->thinker, §ors[ht->affectee], true); + break; + default: + break; + } } // @@ -2553,6 +2584,17 @@ static inline void LoadPolyrotatetThinker(savebuffer_t *save, actionf_p1 thinker ht->distance = READINT32(save->p); ht->turnobjs = READUINT8(save->p); P_AddThinker(&ht->thinker); + + // interpolation + polyobj_t *po; + + if (!(po = Polyobj_GetForNum(ht->polyObjNum))) + { + CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjRotate: bad polyobj %d\n", ht->polyObjNum); + return; + } + + R_CreateInterpolator_Polyobj(&ht->thinker, po); } // @@ -2571,6 +2613,17 @@ static void LoadPolymoveThinker(savebuffer_t *save, actionf_p1 thinker) ht->distance = READINT32(save->p); ht->angle = READANGLE(save->p); P_AddThinker(&ht->thinker); + + // interpolation + polyobj_t *po; + + if (!(po = Polyobj_GetForNum(ht->polyObjNum))) + { + CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjRotate: bad polyobj %d\n", ht->polyObjNum); + return; + } + + R_CreateInterpolator_Polyobj(&ht->thinker, po); } // @@ -2595,6 +2648,36 @@ static inline void LoadPolywaypointThinker(savebuffer_t *save, actionf_p1 thinke ht->diffy = READFIXED(save->p); ht->diffz = READFIXED(save->p); P_AddThinker(&ht->thinker); + + // interpolation + polyobj_t *po; + polyobj_t *oldpo; + INT32 start; + + if (!(po = Polyobj_GetForNum(ht->polyObjNum))) + { + CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjRotate: bad polyobj %d\n", ht->polyObjNum); + return; + } + + R_CreateInterpolator_Polyobj(&ht->thinker, po); + // T_PolyObjWaypoint is the only polyobject movement + // that can adjust z, so we add these ones too. + R_CreateInterpolator_SectorPlane(&ht->thinker, po->lines[0]->backsector, false); + R_CreateInterpolator_SectorPlane(&ht->thinker, po->lines[0]->backsector, true); + + // Most other polyobject functions handle children by recursively + // giving each child another thinker. T_PolyObjWaypoint handles + // it manually though, which means we need to manually give them + // interpolation here instead. + start = 0; + oldpo = po; + while ((po = Polyobj_GetChild(oldpo, &start))) + { + R_CreateInterpolator_Polyobj(&ht->thinker, po); + R_CreateInterpolator_SectorPlane(&ht->thinker, po->lines[0]->backsector, false); + R_CreateInterpolator_SectorPlane(&ht->thinker, po->lines[0]->backsector, true); + } } // @@ -2620,6 +2703,17 @@ static inline void LoadPolyslidedoorThinker(savebuffer_t *save, actionf_p1 think ht->momy = READFIXED(save->p); ht->closing = READUINT8(save->p); P_AddThinker(&ht->thinker); + + // interpolation + polyobj_t *po; + + if (!(po = Polyobj_GetForNum(ht->polyObjNum))) + { + CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjRotate: bad polyobj %d\n", ht->polyObjNum); + return; + } + + R_CreateInterpolator_Polyobj(&ht->thinker, po); } // @@ -2640,6 +2734,17 @@ static inline void LoadPolyswingdoorThinker(savebuffer_t *save, actionf_p1 think ht->distance = READINT32(save->p); ht->closing = READUINT8(save->p); P_AddThinker(&ht->thinker); + + // interpolation + polyobj_t *po; + + if (!(po = Polyobj_GetForNum(ht->polyObjNum))) + { + CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjRotate: bad polyobj %d\n", ht->polyObjNum); + return; + } + + R_CreateInterpolator_Polyobj(&ht->thinker, po); } // @@ -2657,6 +2762,17 @@ static inline void LoadPolydisplaceThinker(savebuffer_t *save, actionf_p1 thinke ht->dy = READFIXED(save->p); ht->oldHeights = READFIXED(save->p); P_AddThinker(&ht->thinker); + + // interpolation + polyobj_t *po; + + if (!(po = Polyobj_GetForNum(ht->polyObjNum))) + { + CONS_Debug(DBG_POLYOBJ, "EV_DoPolyObjRotate: bad polyobj %d\n", ht->polyObjNum); + return; + } + + R_CreateInterpolator_Polyobj(&ht->thinker, po); } // -- 2.54.0 From bd537868878df8f53c5e61e18876ac1d2b94a132 Mon Sep 17 00:00:00 2001 From: Alug Date: Wed, 6 Aug 2025 00:12:26 +0200 Subject: [PATCH 09/66] fix LoadElevatorThinker interp oopsie --- src/p_saveg.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/p_saveg.c b/src/p_saveg.c index 624a3badf..b95e1a09e 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -2414,7 +2414,10 @@ static void LoadElevatorThinker(savebuffer_t *save, actionf_p1 thinker, UINT8 fl P_AddThinker(&ht->thinker); // interpolation - R_CreateInterpolator_SectorPlane(&ht->thinker, ht->sector, (floorOrCeiling & 2)); + if (floorOrCeiling & 2) + R_CreateInterpolator_SectorPlane(&ht->thinker, ht->sector, true); + if (floorOrCeiling & 1) + R_CreateInterpolator_SectorPlane(&ht->thinker, ht->sector, false); } // -- 2.54.0 From 27e734bde01f61bfb7647211552e7f5da0473efc Mon Sep 17 00:00:00 2001 From: Alug Date: Wed, 6 Aug 2025 18:19:37 +0200 Subject: [PATCH 10/66] make music toggle/volume handling less of a mess based on work in srb2 from sphere this gets rid of all the duplicated midi stuff since we dont really have a whole midi soundtrack like srb2, S_GetMusicLumpNum will always prefer non midi music --- src/d_main.c | 41 ++------ src/doomstat.h | 7 +- src/m_menu.c | 12 +-- src/s_sound.c | 222 ++++++++++---------------------------------- src/s_sound.h | 11 +-- src/sdl/i_video.c | 4 +- src/sdl/sdl_sound.c | 12 +-- 7 files changed, 72 insertions(+), 237 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 50c220115..add5b6f5a 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -121,11 +121,8 @@ INT32 postimgparam[MAXSPLITSCREENPLAYERS]; // These variables are only true if // whether the respective sound system is disabled // or they're init'ed, but the player just toggled them -#ifndef NO_MIDI -boolean midi_disabled = false; -#endif boolean sound_disabled = false; -boolean digital_disabled = false; +boolean music_disabled = false; #ifdef DEBUGFILE INT32 debugload = 0; @@ -1989,45 +1986,23 @@ void D_SRB2Main(void) if (dedicated) { sound_disabled = true; - digital_disabled = true; -#ifndef NO_MIDI - midi_disabled = true; -#endif + music_disabled = true; } + if (M_CheckParm("-noaudio")) // combines -nosound and -nomusic { sound_disabled = true; - digital_disabled = true; -#ifndef NO_MIDI - midi_disabled = true; -#endif + music_disabled = true; } else { if (M_CheckParm("-nosound")) sound_disabled = true; - if (M_CheckParm("-nomusic")) // combines -nomidimusic and -nodigmusic - { - digital_disabled = true; -#ifndef NO_MIDI - midi_disabled = true; -#endif - } - else - { -#ifndef NO_MIDI - if (M_CheckParm("-nomidimusic")) - midi_disabled = true; // WARNING: DOS version initmusic in I_StartupSound -#endif - if (M_CheckParm("-nodigmusic")) - digital_disabled = true; // WARNING: DOS version initmusic in I_StartupSound - } + if (M_CheckParm("-nomusic")) + music_disabled = true; } - if (!( sound_disabled && digital_disabled -#ifndef NO_MIDI - && midi_disabled -#endif - )) + + if (!(sound_disabled && music_disabled)) { CONS_Printf("S_InitSfxChannels(): Setting up sound channels.\n"); I_StartupSound(); diff --git a/src/doomstat.h b/src/doomstat.h index f92e3faeb..87accd1d3 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -102,13 +102,8 @@ extern boolean forceresetplayers, deferencoremode; // Internal parameters for sound rendering. // ======================================== -#ifdef NO_MIDI -#define midi_disabled true -#else -extern boolean midi_disabled; -#endif extern boolean sound_disabled; -extern boolean digital_disabled; +extern boolean music_disabled; // ========================= // Status flags for refresh. diff --git a/src/m_menu.c b/src/m_menu.c index 180a73332..fdbc68e55 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -5271,23 +5271,23 @@ static void M_DrawSkyRoom(void) V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y+currentMenu->menuitems[2].alphaKey, - (digital_disabled ? warningflags : highlightflags), - (digital_disabled ? "OFF" : "ON")); + (music_disabled ? warningflags : highlightflags), + (music_disabled ? "OFF" : "ON")); #ifndef NO_MIDI V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y+currentMenu->menuitems[5].alphaKey, - (midi_disabled ? warningflags : highlightflags), - (midi_disabled ? "OFF" : "ON")); + (music_disabled ? warningflags : highlightflags), + (music_disabled ? "OFF" : "ON")); #endif if (itemOn == 0) lengthstring = 8*(sound_disabled ? 3 : 2); else if (itemOn == 2) - lengthstring = 8*(digital_disabled ? 3 : 2); + lengthstring = 8*(music_disabled ? 3 : 2); #ifndef NO_MIDI else if (itemOn == 5) - lengthstring = 8*(midi_disabled ? 3 : 2); + lengthstring = 8*(music_disabled ? 3 : 2); #endif } diff --git a/src/s_sound.c b/src/s_sound.c index 4ee54e210..7e2a8e40b 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -42,12 +42,10 @@ static void Command_RestartMusic_f(void); //mhhhm amiga type filters here i come static void Command_ShowMusicCredit_f(void); // Sound system toggles -#ifndef NO_MIDI -static void GameMIDIMusic_OnChange(void); -#endif static void GameSounds_OnChange(void); +static void GameMusic_OnChange(void); + static void SoundPrecache_OnChange(void); -static void GameDigiMusic_OnChange(void); static void BufferSize_OnChange(void); #ifdef HAVE_OPENMPT @@ -90,11 +88,8 @@ consvar_t cv_samesoundlimit = {"samesoundlimit", "0", CV_SAVE, samesoundlimit_co //consvar_t cv_resetmusic = {"resetmusic", "No", CV_SAVE|CV_NOSHOWHELP, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; // Sound system toggles, saved into the config -consvar_t cv_gamedigimusic = {"digimusic", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, GameDigiMusic_OnChange, 0, NULL, NULL, 0, 0, NULL}; -#ifndef NO_MIDI -consvar_t cv_gamemidimusic = {"midimusic", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, GameMIDIMusic_OnChange, 0, NULL, NULL, 0, 0, NULL}; -#endif -consvar_t cv_gamesounds = {"sounds", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, GameSounds_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_gamedigimusic = {"digimusic", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, GameMusic_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_gamesounds = {"sounds", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, GameSounds_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_playmusicifunfocused = {"playmusicifunfocused", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_playsoundifunfocused = {"playsoundsifunfocused", "No", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -286,9 +281,6 @@ void S_RegisterSoundStuff(void) //CV_RegisterVar(&cv_resetmusic); CV_RegisterVar(&cv_gamesounds); CV_RegisterVar(&cv_gamedigimusic); -#ifndef NO_MIDI - CV_RegisterVar(&cv_gamemidimusic); -#endif CV_RegisterVar(&cv_samesoundlimit); @@ -367,10 +359,7 @@ lumpnum_t S_GetSfxLumpNum(sfxinfo_t *sfx) boolean S_SoundDisabled(void) { - return ( - sound_disabled || - ( window_notinfocus && ! cv_playsoundifunfocused.value ) - ); + return (sound_disabled || (window_notinfocus && !cv_playsoundifunfocused.value)); } boolean S_PrecacheSound(void) @@ -689,10 +678,7 @@ void S_StopSound(void *origin) // Updates music & sounds // static INT32 actualsfxvolume; // check for change through console -static INT32 actualdigmusicvolume; -#ifndef NO_MIDI -static INT32 actualmidimusicvolume; -#endif +static INT32 actualmusicvolume; void S_UpdateSounds(void) { @@ -704,15 +690,19 @@ void S_UpdateSounds(void) listener_t listener[MAXSPLITSCREENPLAYERS]; mobj_t *listenmobj[MAXSPLITSCREENPLAYERS]; +#ifndef NO_MIDI + const boolean currentmidi = (I_SongType() == MU_MID); +#endif + // Update sound/music volumes, if changed manually at console if (actualsfxvolume != cv_soundvolume.value) S_SetSfxVolume(cv_soundvolume.value); - if (actualdigmusicvolume != cv_digmusicvolume.value) - S_SetDigMusicVolume(cv_digmusicvolume.value); #ifndef NO_MIDI - if (actualmidimusicvolume != cv_midimusicvolume.value) - S_SetMIDIMusicVolume(cv_midimusicvolume.value); + if (actualmusicvolume != (currentmidi ? cv_midimusicvolume.value : cv_digmusicvolume.value)) +#else + if (actualmusicvolume != cv_digmusicvolume.value) #endif + S_SetMusicVolume(-1); memset(listener, 0, sizeof(listener)); @@ -1512,7 +1502,8 @@ void S_ShowSpecifiedMusicCredit(const char *musname) { musicdef_t *def; - if (digital_disabled) return; + if (music_disabled) + return; if (!cv_songcredits.value || demo.rewinding) return; @@ -1542,19 +1533,9 @@ void S_ShowMusicCredit(void) /// Music Status /// ------------------------ -boolean S_DigMusicDisabled(void) -{ - return digital_disabled; -} - -boolean S_MIDIMusicDisabled(void) -{ - return midi_disabled; // SRB2Kart: defined as "true" w/ NO_MIDI -} - boolean S_MusicDisabled(void) { - return (midi_disabled && digital_disabled); + return (music_disabled); } boolean S_MusicPlaying(void) @@ -1643,6 +1624,15 @@ UINT32 S_GetMusicPosition(void) /// Music Playback /// ------------------------ +static lumpnum_t S_GetMusicLumpNum(const char *mname) +{ + if (S_MusicExists(mname, false, true)) // check non midis first + return W_GetNumForName(va("o_%s", mname)); + else if (S_MusicExists(mname, true, false)) + return W_GetNumForName(va("d_%s", mname)); + + return LUMPERROR; +} static boolean S_LoadMusic(const char *mname) { lumpnum_t mlumpnum; @@ -1651,27 +1641,11 @@ static boolean S_LoadMusic(const char *mname) if (S_MusicDisabled()) return false; - if (!S_DigMusicDisabled() && S_DigExists(mname)) - mlumpnum = W_GetNumForName(va("o_%s", mname)); - else if (!S_MIDIMusicDisabled() && S_MIDIExists(mname)) - mlumpnum = W_GetNumForName(va("d_%s", mname)); - else if (S_DigMusicDisabled() && S_DigExists(mname)) + mlumpnum = S_GetMusicLumpNum(mname); + + if (mlumpnum == LUMPERROR) { - CONS_Alert(CONS_NOTICE, "Digital music is disabled!\n"); - return false; - } - else if (S_MIDIMusicDisabled() && S_MIDIExists(mname)) - { -#ifdef NO_MIDI - CONS_Alert(CONS_ERROR, "A MIDI music lump %.6s was found,\nbut SRB2Kart does not support MIDI output.\nWe apologise for the inconvenience.\n", mname); -#else - CONS_Alert(CONS_NOTICE, "MIDI music is disabled!\n"); -#endif - return false; - } - else - { - CONS_Alert(CONS_ERROR, M_GetText("Music lump %.6s not found!\n"), mname); + CONS_Alert(CONS_ERROR, "Music %.6s could not be loaded: lump not found!\n", mname); return false; } @@ -1719,7 +1693,7 @@ static boolean S_PlayMusic(boolean looping, UINT32 fadeinms) return false; } - S_InitMusicVolume(); // switch between digi and sequence volume + S_SetMusicVolume(-1); // initialize music volume if (S_MusicNotInFocus()) I_SetMusicVolume(0); @@ -1875,47 +1849,24 @@ void S_ResumeAudio(void) I_ResumeSong(); } -void S_SetMusicVolume(INT32 digvolume, INT32 seqvolume) +void S_SetMusicVolume(INT32 volume) { - if (digvolume < 0) - digvolume = cv_digmusicvolume.value; - #ifdef NO_MIDI - (void)seqvolume; + consvar_t *musicvolume = &cv_digmusicvolume; #else - if (seqvolume < 0) - seqvolume = cv_midimusicvolume.value; + consvar_t *musicvolume = (I_SongType() == MU_MID) ? &cv_midimusicvolume : &cv_digmusicvolume; #endif - if (digvolume < 0 || digvolume > 31) - CONS_Alert(CONS_WARNING, "digmusicvolume should be between 0-31\n"); - CV_SetValue(&cv_digmusicvolume, digvolume&31); - actualdigmusicvolume = cv_digmusicvolume.value; //check for change of var + if (volume < 0) + volume = musicvolume->value; -#ifndef NO_MIDI - if (seqvolume < 0 || seqvolume > 31) - CONS_Alert(CONS_WARNING, "midimusicvolume should be between 0-31\n"); - CV_SetValue(&cv_midimusicvolume, seqvolume&31); - actualmidimusicvolume = cv_midimusicvolume.value; //check for change of var -#endif + if (volume < 0 || volume > 31) + CONS_Alert(CONS_WARNING, "Music volume should be between 0-31\n"); -#ifndef NO_MIDI - seqvolume = 31; -#endif + CV_SetValue(musicvolume, volume&31); + actualmusicvolume = musicvolume->value; //check for change of var - switch(I_SongType()) - { -#ifndef NO_MIDI - case MU_MID: - //case MU_MOD: - //case MU_GME: - I_SetMusicVolume(seqvolume&31); - break; -#endif - default: - I_SetMusicVolume(digvolume&31); - break; - } + I_SetMusicVolume(volume&31); } void S_SetRestoreMusicFadeInCvar(consvar_t *cv) @@ -2156,11 +2107,7 @@ void S_RestartMusic(void) I_ShutdownMusic(); I_InitMusic(); -#ifdef NO_MIDI - S_SetMusicVolume(cv_digmusicvolume.value, -1); -#else - S_SetMusicVolume(cv_digmusicvolume.value, cv_midimusicvolume.value); -#endif + S_SetMusicVolume(-1); S_ResetKeepAndSpecialMus(); @@ -2261,11 +2208,7 @@ static void Command_RestartAudio_f(void) // These must be called or no sound and music until manually set. I_SetSfxVolume(cv_soundvolume.value); -#ifdef NO_MIDI - S_SetMusicVolume(cv_digmusicvolume.value, -1); -#else - S_SetMusicVolume(cv_digmusicvolume.value, cv_midimusicvolume.value); -#endif + S_SetMusicVolume(-1); S_StartSound(NULL, sfx_strpst); @@ -2335,16 +2278,14 @@ static void SoundPrecache_OnChange(void) } } -static void GameDigiMusic_OnChange(void) +void GameMusic_OnChange(void) { if (M_CheckParm("-nomusic") || M_CheckParm("-noaudio")) return; - else if (M_CheckParm("-nodigmusic")) - return; - if (digital_disabled && cv_gamedigimusic.value) + if (music_disabled && cv_gamedigimusic.value) { - digital_disabled = false; + music_disabled = false; I_StartupSound(); // will return early if initialised I_InitMusic(); @@ -2355,32 +2296,13 @@ static void GameDigiMusic_OnChange(void) else S_ChangeMusicInternal("titles", looptitle); } - else if (!digital_disabled && !cv_gamedigimusic.value) + else if (!music_disabled && !cv_gamedigimusic.value) { - digital_disabled = true; - if (S_MusicType() != MU_MID) - { - if (midi_disabled) - S_StopMusic(); - else - { - char mmusic[7]; - UINT16 mflags; - boolean looping; - - if (S_MusicInfo(mmusic, &mflags, &looping) && S_MIDIExists(mmusic)) - { - S_StopMusic(); - S_ChangeMusic(mmusic, mflags, looping); - } - else - S_StopMusic(); - } - } + music_disabled = true; + S_StopMusic(); } } - #ifdef HAVE_OPENMPT static void ModFilter_OnChange(void) { @@ -2422,49 +2344,3 @@ static void BufferSize_OnChange(void) if (sound_started) COM_ImmedExecute("restartaudio"); } - -#ifndef NO_MIDI -static void GameMIDIMusic_OnChange(void) -{ - if (M_CheckParm("-nomusic") || M_CheckParm("-noaudio")) - return; - else if (M_CheckParm("-nomidimusic")) - return; - - if (midi_disabled && cv_gamemidimusic.value) - { - midi_disabled = false; - I_InitMusic(); - - S_ResetKeepAndSpecialMus(); - - if (Playing()) - P_RestoreMusic(&players[consoleplayer]); - else - S_ChangeMusicInternal("titles", looptitle); - } - else if (!midi_disabled && !cv_gamemidimusic.value) - { - midi_disabled = true; - if (S_MusicType() == MU_MID) - { - if (digital_disabled) - S_StopMusic(); - else - { - char mmusic[7]; - UINT16 mflags; - boolean looping; - - if (S_MusicInfo(mmusic, &mflags, &looping) && S_DigExists(mmusic)) - { - S_StopMusic(); - S_ChangeMusic(mmusic, mflags, looping); - } - else - S_StopMusic(); - } - } - } -} -#endif diff --git a/src/s_sound.h b/src/s_sound.h index 924259a27..7aa218062 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -38,7 +38,7 @@ extern consvar_t cv_audbuffersize; //extern consvar_t cv_resetmusic; extern consvar_t cv_gamedigimusic; #ifndef NO_MIDI -extern consvar_t cv_gamemidimusic, cv_midimusicvolume; +extern consvar_t cv_midimusicvolume; #endif extern consvar_t cv_gamesounds; extern consvar_t cv_playmusicifunfocused; @@ -148,8 +148,6 @@ void S_StopSound(void *origin); // Music Status // -boolean S_DigMusicDisabled(void); -boolean S_MIDIMusicDisabled(void); boolean S_MusicDisabled(void); boolean S_MusicPlaying(void); boolean S_MusicPaused(void); @@ -159,8 +157,6 @@ musictype_t S_MusicType(void); const char *S_MusicName(void); boolean S_MusicInfo(char *mname, UINT16 *mflags, boolean *looping); boolean S_MusicExists(const char *mname, boolean checkMIDI, boolean checkDigi); -#define S_DigExists(a) S_MusicExists(a, false, true) -#define S_MIDIExists(a) S_MusicExists(a, true, false) // // Music Effects @@ -281,10 +277,7 @@ void S_UpdateSounds(void); FUNCMATH fixed_t S_CalculateSoundDistance(fixed_t px1, fixed_t py1, fixed_t pz1, fixed_t px2, fixed_t py2, fixed_t pz2); void S_SetSfxVolume(INT32 volume); -void S_SetMusicVolume(INT32 digvolume, INT32 seqvolume); -#define S_SetDigMusicVolume(a) S_SetMusicVolume(a,-1) -#define S_SetMIDIMusicVolume(a) S_SetMusicVolume(-1,a) -#define S_InitMusicVolume() S_SetMusicVolume(-1,-1) +void S_SetMusicVolume(INT32 volume); INT32 S_OriginPlaying(void *origin); INT32 S_IdPlaying(sfxenum_t id); diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index c37445596..798be9593 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -718,10 +718,10 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt) // Tell game we got focus back, resume music if necessary window_notinfocus = false; - S_InitMusicVolume(); + S_SetMusicVolume(-1); if (cv_gamesounds.value) - S_ResumeAudio(); //resume it + S_ResumeAudio(); // resume it if (!firsttimeonmouse) { diff --git a/src/sdl/sdl_sound.c b/src/sdl/sdl_sound.c index 07f81d7b7..4afd26a04 100644 --- a/src/sdl/sdl_sound.c +++ b/src/sdl/sdl_sound.c @@ -189,7 +189,7 @@ static void Snd_LockAudio(void) //Alam: Lock audio data and uninstall audio call { if (Snd_Mutex) SDL_LockMutex(Snd_Mutex); else if (sound_disabled) return; - else if (midi_disabled && digital_disabled) SDL_LockAudio(); + else if (music_disabled) SDL_LockAudio(); #ifdef HAVE_MIXER else if (musicStarted) Mix_SetPostMix(NULL, NULL); #endif @@ -199,7 +199,7 @@ static void Snd_UnlockAudio(void) //Alam: Unlock audio data and reinstall audio { if (Snd_Mutex) SDL_UnlockMutex(Snd_Mutex); else if (sound_disabled) return; - else if (midi_disabled && digital_disabled) SDL_UnlockAudio(); + else if (music_disabled) SDL_UnlockAudio(); #ifdef HAVE_MIXER else if (musicStarted) Mix_SetPostMix(audio.callback, audio.userdata); #endif @@ -1061,7 +1061,7 @@ void I_ShutdownSound(void) CONS_Printf("I_ShutdownSound: "); - if (midi_disabled && digital_disabled) + if (music_disabled) SDL_CloseAudio(); CONS_Printf("%s", M_GetText("shut down\n")); sound_started = false; @@ -1078,11 +1078,7 @@ void I_UpdateSound(void) void I_StartupSound(void) { #ifndef HAVE_MIXER -#ifndef NO_MIDI - midi_disabled = -#endif - digital_disabled = true; -#endif + music_disabled = true; memset(channels, 0, sizeof (channels)); //Alam: Clean it -- 2.54.0 From 525e19566ed3853bfbd24827c8652f4201d73a91 Mon Sep 17 00:00:00 2001 From: Alug Date: Thu, 7 Aug 2025 13:15:16 +0200 Subject: [PATCH 11/66] smol refactor hwr precache not faster or anything real time consuming thing is he actual calls to getetxture and getflat --- src/hardware/hw_cache.c | 134 +++++++++++++++------------------------- 1 file changed, 51 insertions(+), 83 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 79859686f..00eba196b 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -600,7 +600,6 @@ void HWR_FreeMapTextures(void) static void HWR_PrecacheLevelFlats(void) { - levelflat_t levelflat; lumpnum_t lump; size_t i, j; INT32 k; @@ -614,28 +613,22 @@ static void HWR_PrecacheLevelFlats(void) { sector_t *sec = §ors[i]; - // sector checked already? - if (sec->validcount == validcount) - continue; - - sec->validcount = validcount; - // gotta check sector floor and ceiling for (j = 0; j < 2; j++) { const boolean ceiling = (j == 0); - INT32 pic = ceiling ? sec->ceilingpic : sec->floorpic; + const INT32 pic = ceiling ? sec->ceilingpic : sec->floorpic; - levelflat = levelflats[pic]; + const levelflat_t *levelflat = &levelflats[pic]; - lump = levelflat.lumpnum; + lump = levelflat->lumpnum; HWR_GetFlat(lump, R_NoEncore(sec, ceiling)); - if (levelflat.speed) // it is an animated flat + if (levelflat->speed) // it is an animated flat { - for (k = 1; k < levelflat.numpics; k++) + for (k = 1; k < levelflat->numpics; k++) { - lump = levelflat.baselumpnum + k; + lump = levelflat->baselumpnum + k; HWR_GetFlat(lump, R_NoEncore(sec, ceiling)); } } @@ -649,18 +642,18 @@ static void HWR_PrecacheLevelFlats(void) // just load every flat in the level for (i = 0; i < numlevelflats; i++) { - levelflat = levelflats[i]; - lump = levelflat.lumpnum; + const levelflat_t *levelflat = &levelflats[i]; + lump = levelflat->lumpnum; HWR_GetFlat(lump, false); - if (levelflat.speed) // it is an animated flat + if (!levelflat->speed) // is it an animated flat ? + continue; + + for (k = 1; k < levelflat->numpics; k++) { - for (k = 1; k < levelflat.numpics; k++) - { - lump = levelflat.baselumpnum + k; - HWR_GetFlat(lump, false); - } + lump = levelflat->baselumpnum + k; + HWR_GetFlat(lump, false); } } } @@ -670,52 +663,55 @@ static void HWR_PrecacheLevelTextures(void) { char *texturepresent; anim_t *anim; - size_t i, j; + size_t i, j, f; INT32 h; texturepresent = calloc(numtextures, sizeof (*texturepresent)); - if (texturepresent == NULL) I_Error("%s: Out of memory looking up textures", "HWR_PrecacheLevel"); + if (texturepresent == NULL) + I_Error("%s: Out of memory looking up textures", "HWR_PrecacheLevel"); + + // Sky texture is always present. + // Note that F_SKY1 is the name used to indicate a sky floor/ceiling as a flat, + // while the sky texture is stored like a wall texture, with a skynum dependent name. + texturepresent[skytexture] = 1; + HWR_GetTexture(skytexture, false); for (i = 0; i < numlines; i++) { - line_t *line = &lines[i]; + const line_t *line = &lines[i]; #ifdef GLENCORE - const int noencoremap = ((line->flags & ML_TFERLINE) ? 2 : 1); + const int noencoremap = ((encoremap && (line->flags & ML_TFERLINE)) ? 2 : 1); #else const int noencoremap = 1; #endif - - // line checked already? - if (line->validcount == validcount) - continue; - - line->validcount = validcount; - // two sides for (j = 0; j < 2; j++) { - side_t *side = &sides[line->sidenum[j]]; - - // Single-side linedef + // check if single-sided linedef if (line->sidenum[j] == 0xffff) continue; - if (side->toptexture >= 0 && side->toptexture < numtextures) + const side_t *side = &sides[line->sidenum[j]]; + const INT32 sidetex[] = {side->toptexture, side->midtexture, side->bottomtexture}; + + // gotta check from top to bottom uwu + for (f = 0; f < 3; f++) { - texturepresent[side->toptexture] = 1|noencoremap; - } - if (side->midtexture >= 0 && side->midtexture < numtextures) - { - texturepresent[side->midtexture] = 1|noencoremap; - } - if (side->bottomtexture >= 0 && side->bottomtexture < numtextures) - { - texturepresent[side->bottomtexture] = 1|noencoremap; + const INT32 texnum = sidetex[f]; + if (texnum < 0 || texnum >= numtextures || texturepresent[texnum]) + continue; + + texturepresent[texnum] = 1|noencoremap; + + HWR_GetTexture(texnum, false); +#ifdef GLENCORE + if (noencoremap & 2) + HWR_GetTexture(texnum, true); +#endif } } } - // check for animated textures for (anim = anims; anim < lastanim; anim++) { if (!anim->istexture) @@ -726,47 +722,21 @@ static void HWR_PrecacheLevelTextures(void) if (!texpresent) continue; - if (texpresent & 1) + for (h = 1; h < anim->numpics; h++) { - for (h = 1; h < anim->numpics; h++) + if (texpresent & 1) { HWR_GetTexture(anim->basepic+h, false); } - } #ifdef GLENCORE - if (texpresent & 2) - { - for (h = 1; h < anim->numpics; h++) + if (texpresent & 2) { HWR_GetTexture(anim->basepic+h, true); } - } #endif + } } - // Sky texture is always present. - // Note that F_SKY1 is the name used to indicate a sky floor/ceiling as a flat, - // while the sky texture is stored like a wall texture, with a skynum dependent name. - texturepresent[skytexture] = 1; - - for (i = 0; i < (unsigned)numtextures; i++) - { - const char texpresent = texturepresent[i]; - - if (!texpresent) - continue; - - if (texpresent & 1) - { - HWR_GetTexture(i, false); - } -#ifdef GLENCORE - if (texpresent & 2) - { - HWR_GetTexture(i, true); - } -#endif - } free(texturepresent); } @@ -775,21 +745,19 @@ static void HWR_PrecacheLevelSprites(void) patch_t *spritepatch; char *spritepresent; size_t i, j, k; - lumpnum_t lump; thinker_t *th; - mobj_t *mo; - spriteframe_t *sf; spritepresent = calloc(numsprites, sizeof (*spritepresent)); - if (spritepresent == NULL) I_Error("%s: Out of memory looking up sprites", "HWR_PrecacheLevel"); + if (spritepresent == NULL) + I_Error("%s: Out of memory looking up sprites", "HWR_PrecacheLevel"); for (th = thinkercap.next; th != &thinkercap; th = th->next) { if (th->function != (actionf_p1)P_MobjThinker) continue; - mo = (mobj_t *)th; + const mobj_t *mo = (mobj_t *)th; // ogl is weird // for some reason it does not want to preload sprites with colormaps @@ -807,10 +775,10 @@ static void HWR_PrecacheLevelSprites(void) for (j = 0; j < sprites[i].numframes; j++) { - sf = &sprites[i].spriteframes[j]; + const spriteframe_t *sf = &sprites[i].spriteframes[j]; #define cacheang(a) {\ - lump = sf->lumppat[a];\ + const lumpnum_t lump = sf->lumppat[a];\ spritepatch = (patch_t *)W_CachePatchNum(lump, PU_SPRITE);\ if (spritepatch != NULL)\ HWR_GetPatch(spritepatch);\ -- 2.54.0 From c701e1fe7ef1a47682e52888670b95af91846e6e Mon Sep 17 00:00:00 2001 From: Alug Date: Thu, 7 Aug 2025 17:57:56 +0200 Subject: [PATCH 12/66] make inputdisplay colour match the rest of colourhud better --- src/k_hud.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/k_hud.c b/src/k_hud.c index 520c6ae33..deae2c028 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -4167,7 +4167,7 @@ static void K_drawInput(void) const UINT8 hudcolor = K_GetHudColor(); const INT32 accent1 = splitflags|colortranslations[hudcolor][5]; - const INT32 accent2 = splitflags|colortranslations[hudcolor][9]; + const INT32 accent2 = splitflags|colortranslations[hudcolor][7]; const UINT8 *hudcolormap = R_GetTranslationColormap(0, hudcolor, GTC_CACHE); const ticcmd_t *cmd = &stplyr->cmd; -- 2.54.0 From 40165fd6dbb2db5af50a03c7eae4789fd1325e2e Mon Sep 17 00:00:00 2001 From: Alug Date: Thu, 7 Aug 2025 17:46:03 +0200 Subject: [PATCH 13/66] make leveltitlecard be affected by colour hud --- src/st_stuff.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index 0ca8c562c..680127286 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -438,9 +438,21 @@ static void ST_drawLevelTitle(void) zonttl = mapheaderinfo[gamemap-1]->zonttl; // SRB2kart actnum = mapheaderinfo[gamemap-1]->actnum; dupcalc = (vid.width/vid.dupx); - gtc = G_GetGametypeColor(gametype); + bary = (splitscreen) ? BASEVIDHEIGHT/2 : 163; + if (K_UseColorHud()) + { + if (gametype == GT_RACE) + gtc = colortranslations[K_GetHudColor()][7]; // idk if this should also apply to other gametypes? + else if (modeattacking || gamestate == GS_TIMEATTACK) + gtc = colortranslations[K_GetHudColor()][4]; + else + gtc = G_GetGametypeColor(gametype); + } + else + gtc = G_GetGametypeColor(gametype); + lvlw = V_LevelNameWidth(lvlttl); if (actnum[0]) -- 2.54.0 From caff071a1b62a2d8bc469e211d617fcadd1d25bf Mon Sep 17 00:00:00 2001 From: Alug Date: Thu, 7 Aug 2025 22:09:43 +0200 Subject: [PATCH 14/66] fix spacing in Z_CheckHeap errors --- src/z_zone.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/z_zone.c b/src/z_zone.c index 8647f91fa..b9150115a 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -503,7 +503,7 @@ void Z_CheckHeap(INT32 tag) { I_Error("Z_CheckHeap %d: block %u" #ifdef ZDEBUG - "(owned by %s:%d)" + " (owned by %s:%d)" #endif " should not exist", i, blocknumon #ifdef ZDEBUG @@ -514,13 +514,13 @@ void Z_CheckHeap(INT32 tag) #endif if (block->user != NULL && *(block->user) != given) { - I_Error("Z_CheckHeap" + I_Error("Z_CheckHeap :" #ifdef ZDEBUG - "at %s %d :" + " %s %d" #endif - "block %u" + " block %u" #ifdef ZDEBUG - "(owned by %s:%d)" + " (owned by %s:%d)" #endif " doesn't have a proper user" #ifdef ZDEBUG @@ -534,13 +534,13 @@ void Z_CheckHeap(INT32 tag) } if (block->next->prev != block) { - I_Error("Z_CheckHeap" + I_Error("Z_CheckHeap :" #ifdef ZDEBUG - "at %s %d :" + " %s %d" #endif - "block %u" + " block %u" #ifdef ZDEBUG - "(owned by %s:%d)" + " (owned by %s:%d)" #endif " lacks proper backlink" #ifdef ZDEBUG @@ -554,13 +554,13 @@ void Z_CheckHeap(INT32 tag) } if (block->prev->next != block) { - I_Error("Z_CheckHeap" + I_Error("Z_CheckHeap :" #ifdef ZDEBUG - "at %s %d :" + " %s %d" #endif - "block %u" + " block %u" #ifdef ZDEBUG - "(owned by %s:%d)" + " (owned by %s:%d)" #endif " lacks proper forward link" #ifdef ZDEBUG @@ -574,13 +574,13 @@ void Z_CheckHeap(INT32 tag) } if (block->id != ZONEID) { - I_Error("Z_CheckHeap" + I_Error("Z_CheckHeap :" #ifdef ZDEBUG - "at %s %d :" + " %s %d" #endif - "block %u" + " block %u" #ifdef ZDEBUG - "(owned by %s:%d)" + " (owned by %s:%d)" #endif " have the wrong ID" #ifdef ZDEBUG -- 2.54.0 From 2653b59af45e22664ca8bc51fc47bea19d893f7c Mon Sep 17 00:00:00 2001 From: Alug Date: Thu, 7 Aug 2025 22:22:56 +0200 Subject: [PATCH 15/66] dont double free our vote patches those may point to the same thing so uhhhh PU_PATCH_LOWPRIORITY will ensure the memory will be freed on mapload --- src/y_inter.c | 76 ++++++++++----------------------------------------- 1 file changed, 15 insertions(+), 61 deletions(-) diff --git a/src/y_inter.c b/src/y_inter.c index 068115f4f..0c096127a 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -73,7 +73,6 @@ static huddrawlist_h luahuddrawlist_intermission = NULL; static huddrawlist_h luahuddrawlist_vote = NULL; static void Y_FollowIntermission(void); -static void Y_UnloadData(void); // SRB2Kart: voting stuff // Level images @@ -112,8 +111,6 @@ static y_voteclient voteclient; static INT32 votetic; static INT32 voteendtic = -1; -static void Y_UnloadVoteData(void); - // // SRB2Kart - Y_CalculateMatchData and ancillary functions // @@ -789,7 +786,7 @@ void Y_StartIntermission(void) break; } - bgtile = W_CachePatchName("SRB2BACK", PU_PATCH); + bgtile = W_CachePatchName("SRB2BACK", PU_PATCH_LOWPRIORITY); LUA_HUD_DestroyDrawList(luahuddrawlist_intermission); luahuddrawlist_intermission = LUA_HUD_CreateDrawList(); @@ -802,9 +799,6 @@ void Y_StartIntermission(void) // void Y_EndIntermission(void) { - if (!dedicated) - Y_UnloadData(); - endtic = -1; sorttic = -1; intertype = int_none; @@ -821,20 +815,6 @@ static void Y_FollowIntermission(void) G_AfterIntermission(); } -#define UNLOAD(x) {if ((x) != NULL) {Patch_Free(x);} x = NULL;} - -// -// Y_UnloadData -// -static void Y_UnloadData(void) -{ - // unload the background patches - UNLOAD(VoteScreen.bgpatch); - UNLOAD(VoteScreen.widebgpatch); - UNLOAD(bgtile); - //UNLOAD(interpic); -} - // SRB2Kart: Voting! // @@ -877,8 +857,8 @@ static void Y_VoteScreenCheck(void) // non lua vote background handling boolean prefbattletype = ((votelevels[0][1] & ~0x80) == GT_MATCH); - VoteScreen.widebgpatch = W_CachePatchName((prefbattletype ? "BATTLSCW" : "INTERSCW"), PU_PATCH); - VoteScreen.bgpatch = W_CachePatchName((prefbattletype ? "BATTLSCR" : "INTERSCR"), PU_PATCH); + VoteScreen.widebgpatch = W_CachePatchName((prefbattletype ? "BATTLSCW" : "INTERSCW"), PU_PATCH_LOWPRIORITY); + VoteScreen.bgpatch = W_CachePatchName((prefbattletype ? "BATTLSCR" : "INTERSCR"), PU_PATCH_LOWPRIORITY); } // @@ -926,7 +906,7 @@ static void Y_DrawLuaVoteScreenPatch(boolean widePatch) // Draw non animated patch if (!tempfoundAnimLuaVoteFrames) { - votebg = W_CachePatchName(va("%s1", tempPrefix), PU_PATCH); + votebg = W_CachePatchName(va("%s1", tempPrefix), PU_PATCH_LOWPRIORITY); Y_VoteBackgroundDrawer(votebg); return; } @@ -939,7 +919,7 @@ static void Y_DrawLuaVoteScreenPatch(boolean widePatch) nextframe = (VoteScreen.currentAnimFrame + 1); - votebg = W_CachePatchName(va("%s%d", tempPrefix, nextframe), PU_PATCH); + votebg = W_CachePatchName(va("%s%d", tempPrefix, nextframe), PU_PATCH_LOWPRIORITY); Y_VoteBackgroundDrawer(votebg); @@ -1481,14 +1461,14 @@ static void Y_InitVoteDrawing(void) // setup the background patches Y_VoteScreenCheck(); - VoteScreen.cursor[0] = W_CachePatchName("M_CURSOR", PU_PATCH); - VoteScreen.cursor[1] = W_CachePatchName("P1CURSOR", PU_PATCH); - VoteScreen.cursor[2] = W_CachePatchName("P2CURSOR", PU_PATCH); - VoteScreen.cursor[3] = W_CachePatchName("P3CURSOR", PU_PATCH); - VoteScreen.cursor[4] = W_CachePatchName("P4CURSOR", PU_PATCH); + VoteScreen.cursor[0] = W_CachePatchName("M_CURSOR", PU_PATCH_LOWPRIORITY); + VoteScreen.cursor[1] = W_CachePatchName("P1CURSOR", PU_PATCH_LOWPRIORITY); + VoteScreen.cursor[2] = W_CachePatchName("P2CURSOR", PU_PATCH_LOWPRIORITY); + VoteScreen.cursor[3] = W_CachePatchName("P3CURSOR", PU_PATCH_LOWPRIORITY); + VoteScreen.cursor[4] = W_CachePatchName("P4CURSOR", PU_PATCH_LOWPRIORITY); - VoteScreen.randomlvl = W_CachePatchName("RANDOMLV", PU_PATCH); - VoteScreen.rubyicon = W_CachePatchName("RUBYICON", PU_PATCH); + VoteScreen.randomlvl = W_CachePatchName("RANDOMLV", PU_PATCH_LOWPRIORITY); + VoteScreen.rubyicon = W_CachePatchName("RUBYICON", PU_PATCH_LOWPRIORITY); } void Y_StartVote(void) @@ -1573,9 +1553,9 @@ void Y_StartVote(void) { lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(votelevels[i][0]+1))); if (lumpnum != LUMPERROR) - levelinfo[i].pic = W_CachePatchName(va("%sP", G_BuildMapName(votelevels[i][0]+1)), PU_PATCH); + levelinfo[i].pic = W_CachePatchName(va("%sP", G_BuildMapName(votelevels[i][0]+1)), PU_PATCH_LOWPRIORITY); else - levelinfo[i].pic = W_CachePatchName("BLANKLVL", PU_PATCH); + levelinfo[i].pic = W_CachePatchName("BLANKLVL", PU_PATCH_LOWPRIORITY); } } @@ -1589,35 +1569,9 @@ void Y_StartVote(void) // Y_EndVote // void Y_EndVote(void) -{ - Y_UnloadVoteData(); - voteendtic = -1; -} - -// -// Y_UnloadVoteData -// -static void Y_UnloadVoteData(void) { voteclient.loaded = false; - - if (dedicated) - return; - - UNLOAD(VoteScreen.widebgpatch); - UNLOAD(VoteScreen.bgpatch); - UNLOAD(VoteScreen.cursor[0]); - UNLOAD(VoteScreen.cursor[1]); - UNLOAD(VoteScreen.cursor[2]); - UNLOAD(VoteScreen.cursor[3]); - UNLOAD(VoteScreen.cursor[4]); - UNLOAD(VoteScreen.randomlvl); - UNLOAD(VoteScreen.rubyicon); - - UNLOAD(levelinfo[3].pic); - UNLOAD(levelinfo[2].pic); - UNLOAD(levelinfo[1].pic); - UNLOAD(levelinfo[0].pic); + voteendtic = -1; } // -- 2.54.0 From e85d91e68245bb5296443598c68c6188ca595a19 Mon Sep 17 00:00:00 2001 From: Alug Date: Thu, 7 Aug 2025 22:27:19 +0200 Subject: [PATCH 16/66] save a few checks for st debug drawer if we dont use it --- src/st_stuff.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index 680127286..aa1d6a81e 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -367,7 +367,7 @@ static void ST_drawDebugInfo(void) { INT32 height = 192; - if (!stplyr->mo) + if (!cv_debug || !stplyr->mo) return; if (cv_debug & DBG_BASIC) @@ -803,5 +803,6 @@ void ST_Drawer(void) else V_DrawFadeScreen(120, 15-timeinmap); // Then gradually fade out from there } + ST_drawDebugInfo(); } -- 2.54.0 From cb3638e3abb84d6ce0eb768ac54d86912877e4f4 Mon Sep 17 00:00:00 2001 From: Indev Date: Thu, 7 Aug 2025 23:48:03 +0300 Subject: [PATCH 17/66] Add SetupVote hook --- LUASTUFF.md | 12 ++++++++++++ src/d_netcmd.c | 13 ++++++++++++- src/lua_hook.h | 6 ++++++ src/lua_hooklib.c | 40 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 70 insertions(+), 1 deletion(-) diff --git a/LUASTUFF.md b/LUASTUFF.md index 83ec76545..28e77bed8 100644 --- a/LUASTUFF.md +++ b/LUASTUFF.md @@ -192,6 +192,18 @@ from `0` to `#musicdefs-1`, or string indices (which is equal to calling `S_Find Hook is called whenever `S_ShowMusicCredit` (either from game or mod) is called. Takes musicdef as only argument, returning true will overwrite vanilla behavior (not show music credit), can be used to implement custom music credit pop-ups. +## addHook("SetupVote", function(result, gt, secondgt, prevmap)) + +Hook is called whenever server sets up options for vote screen. `result` is table where lua can store options to, +(for example, `result[1] = 1` will force green hills as first option), gt is current gametype, secondgt is +alternative gametype picked for 3rd entry (for example, gt can be `GT_RACE`, and secondgt can be `GT_MATCH`) +prevmap is the previous map that was played (small note - in game code, it is offset by -1, but for lua its offset back, +so if previous gamemap was 1, prevmap would also be 1. Which means you can safely do mapheaderinfo[prevmap] to get info on previous map) + +Limitations: currently, game can only change gametype for 3rd option in map (meaning for example, if current gametype is race, and you +put battle map in first option, when it gets picked that map will be still run in race gametype). That means, game will only handle maps with +different gametype if it is put in 3rd vote option. + # Other changes ## P_PlayRinglossSound(source, damager) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index c358c3b2c..d60d87ba6 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2505,6 +2505,14 @@ void D_SetupVote(void) UINT8 gt = (cv_kartgametypepreference.value == -1) ? gametype : cv_kartgametypepreference.value; UINT8 secondgt = G_SometimesGetDifferentGametype(gt); INT16 votebuffer[4] = {-1,-1,-1,0}; + INT16 luamaps[4] = {0, 0, 0, 0}; + + LUA_HookSetupVote(luamaps, sizeof(luamaps)/sizeof(luamaps[0]), gt, secondgt); + + // Correct secondgt if needed + UINT8 typeoflevel = mapheaderinfo[luamaps[2]-1]->typeoflevel; + if (luamaps[2] && (typeoflevel & G_TOLFlag(secondgt&(~0x80))) == 0) + secondgt = ((typeoflevel & TOL_RACE) ? GT_RACE : GT_MATCH)|(secondgt&0x80); if (cv_kartencore.value && gt == GT_RACE) WRITEUINT8(p, (gt|0x80)); @@ -2513,10 +2521,13 @@ void D_SetupVote(void) WRITEUINT8(p, secondgt); secondgt &= ~0x80; + for (i = 0; i < 4; i++) { UINT16 m; - if (i == 2) // sometimes a different gametype + if (luamaps[i]) + m = luamaps[i]-1; + else if (i == 2) // sometimes a different gametype m = G_RandMap(G_TOLFlag(secondgt), prevmap, false, 0, true, votebuffer); else if (i >= 3) // unknown-random and force-unknown MAP HELL m = G_RandMap(G_TOLFlag(gt), prevmap, false, (i-2), (i < 4), votebuffer); diff --git a/src/lua_hook.h b/src/lua_hook.h index c31a58a67..64c91cc24 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -66,6 +66,7 @@ X (IntermissionThinker),/* Y_Ticker */\ X (VoteThinker),/*SRB2KART*/\ X (ServerJoin),/* SRB2KART - Saturn 32p*/\ + X (SetupVote),/*SRB2KART - Saturn*/ #define STRING_HOOK_LIST(X) \ X (BotAI),/* B_BuildTailsTiccmd by skin name */\ @@ -140,3 +141,8 @@ int LUA_HookShouldSquish(player_t *player, mobj_t *inflictor, mobj_t *source); / boolean LUA_HookPlayerSpin(player_t *player, mobj_t *inflictor, mobj_t *source); // SRB2KART: Hook for K_SpinPlayer. Allows Lua to execute code and/or overwrite its behavior. boolean LUA_HookPlayerExplode(player_t *player, mobj_t *inflictor, mobj_t *source); // SRB2KART: Hook for K_ExplodePlayer. Allows Lua to execute code and/or overwrite its behavior. boolean LUA_HookPlayerSquish(player_t *player, mobj_t *inflictor, mobj_t *source); // SRB2KART: Hook for K_SquishPlayer. Allows Lua to execute code and/or overwrite its behavior. + +// SRB2KART - Saturn: Allows changing vote level picks +// (note: function format in lua doesn't include maxresults, so its function(result, gametype, secondgametype, prevmap) +// to get maxresults use #result) +void LUA_HookSetupVote(INT16 result[], INT16 maxresults, UINT8 gt, UINT8 secondgt); diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 97b86e1bf..98c873a1a 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -1138,3 +1138,43 @@ boolean LUA_HookPlayerExplode(player_t *player, mobj_t *inflictor, mobj_t *sourc { return kartdamage_hook(player, inflictor, source, HOOK(PlayerExplode), res_true); } + +void LUA_HookSetupVote(INT16 result[], INT16 maxresults, UINT8 gt, UINT8 secondgt) +{ + Hook_State hook; + if (prepare_hook(&hook, 0, HOOK(SetupVote))) + { + // { 0, 0, 0, 0, } + lua_newtable(gL); + for (int i = 1; i <= maxresults; ++i) + { + lua_pushinteger(gL, 0); + lua_rawseti(gL, -2, i); + } + + // call_hooks does lua_settop(gL, 0) so we need to store our table somewhere + lua_pushvalue(gL, -1); + lua_setfield(gL, LUA_REGISTRYINDEX, "SetupVoteResults"); + + lua_pushinteger(gL, gt); + lua_pushinteger(gL, secondgt); + lua_pushinteger(gL, prevmap+1); // prevmap is gamemap-1 so we offset it back + + call_hooks(&hook, 0, res_none); + + lua_getfield(gL, LUA_REGISTRYINDEX, "SetupVoteResults"); + for (int i = 1; i <= maxresults; ++i) + { + lua_rawgeti(gL, -1, i); + result[i-1] = lua_tointeger(gL, -1); + lua_pop(gL, 1); + + if (result[i-1] && (result[i-1] < 0 || !mapheaderinfo[result[i-1]-1])) + { + CONS_Alert(CONS_WARNING, "Unknown map #%d for vote\n", result[i-1]); + result[i-1] = 0; + } + } + lua_pop(gL, 1); + } +} -- 2.54.0 From b76fc9699aaa40f12ae78a7904a7223f796261ed Mon Sep 17 00:00:00 2001 From: Alug Date: Fri, 8 Aug 2025 00:34:33 +0200 Subject: [PATCH 18/66] fixup midi menu stuff i love M_DrawSkyRoom --- src/m_menu.c | 11 ----------- src/m_menudefs.c | 27 +++++++++++---------------- 2 files changed, 11 insertions(+), 27 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index fdbc68e55..02a1bee87 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -5274,21 +5274,10 @@ static void M_DrawSkyRoom(void) (music_disabled ? warningflags : highlightflags), (music_disabled ? "OFF" : "ON")); -#ifndef NO_MIDI - V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, - currentMenu->y+currentMenu->menuitems[5].alphaKey, - (music_disabled ? warningflags : highlightflags), - (music_disabled ? "OFF" : "ON")); -#endif - if (itemOn == 0) lengthstring = 8*(sound_disabled ? 3 : 2); else if (itemOn == 2) lengthstring = 8*(music_disabled ? 3 : 2); -#ifndef NO_MIDI - else if (itemOn == 5) - lengthstring = 8*(music_disabled ? 3 : 2); -#endif } for (i = 0; i < currentMenu->numitems; ++i) diff --git a/src/m_menudefs.c b/src/m_menudefs.c index 7029a212b..998c457ae 100644 --- a/src/m_menudefs.c +++ b/src/m_menudefs.c @@ -1070,29 +1070,25 @@ enum static menuitem_t OP_SoundOptionsMenu[] = { {IT_STRING|IT_CVAR|IT_CV_NOPRINT, NULL, "SFX", &cv_gamesounds, 10}, - {IT_STRING|IT_CVAR|IT_CV_SLIDER, - NULL, "SFX Volume", &cv_soundvolume, 18}, + {IT_STRING|IT_CVAR|IT_CV_SLIDER, NULL, "SFX Volume", &cv_soundvolume, 18}, {IT_STRING|IT_CVAR|IT_CV_NOPRINT, NULL, "Music", &cv_gamedigimusic, 30}, - {IT_STRING|IT_CVAR|IT_CV_SLIDER, - NULL, "Music Volume", &cv_digmusicvolume, 38}, + {IT_STRING|IT_CVAR|IT_CV_SLIDER, NULL, "Music Volume", &cv_digmusicvolume, 38}, #ifndef NO_MIDI - {IT_STRING|IT_CVAR, NULL, "MIDI", &cv_gamemidimusic, 50}, - {IT_STRING|IT_CVAR|IT_CV_SLIDER, - NULL, "MIDI Volume", &cv_midimusicvolume, 58}, + {IT_STRING|IT_CVAR|IT_CV_SLIDER, NULL, "MIDI Volume", &cv_midimusicvolume, 46}, - {IT_STRING|IT_CVAR, NULL, "Reverse L/R Channels", &stereoreverse, 50}, + {IT_STRING|IT_CVAR, NULL, "Reverse L/R Channels", &stereoreverse, 60}, - {IT_STRING|IT_CVAR, NULL, "Chat Notifications", &cv_chatnotifications, 65}, - {IT_STRING|IT_CVAR, NULL, "Character voices", &cv_kartvoices, 75}, - {IT_STRING|IT_CVAR, NULL, "Hit Em Delay", &cv_karthitemdialog, 85}, - {IT_STRING|IT_CVAR, NULL, "Powerup Warning", &cv_kartinvinsfx, 95}, + {IT_STRING|IT_CVAR, NULL, "Chat Notifications", &cv_chatnotifications, 75}, + {IT_STRING|IT_CVAR, NULL, "Character voices", &cv_kartvoices, 85}, + {IT_STRING|IT_CVAR, NULL, "Hit Em Delay", &cv_karthitemdialog, 95}, + {IT_STRING|IT_CVAR, NULL, "Powerup Warning", &cv_kartinvinsfx, 105}, - {IT_KEYHANDLER|IT_STRING, NULL, "Sound Test", M_HandleSoundTest, 105}, - {IT_STRING|IT_CALL, NULL, "Music Test", M_MusicTest, 115}, + {IT_KEYHANDLER|IT_STRING, NULL, "Sound Test", M_HandleSoundTest, 115}, + {IT_STRING|IT_CALL, NULL, "Music Test", M_MusicTest, 125}, - {IT_STRING|IT_SUBMENU, NULL, "Advanced Settings...", &OP_SoundAdvancedDef, 125} + {IT_STRING|IT_SUBMENU, NULL, "Advanced Settings...", &OP_SoundAdvancedDef, 135} #else {IT_STRING|IT_CVAR, NULL, "Reverse L/R Channels", &stereoreverse, 60}, @@ -1115,7 +1111,6 @@ static const char* OP_SoundTooltips[] = "Turn Music on or off.", "Volume of Music.", #ifndef NO_MIDI - "Turn Midi Music on or off.", "Volume of Midi Music.", #endif "Reverse left and right channels of audio.", -- 2.54.0 From 16e1e00c678f7835b9d68659105de00f0aaf6c94 Mon Sep 17 00:00:00 2001 From: Alug Date: Fri, 8 Aug 2025 00:48:41 +0200 Subject: [PATCH 19/66] "reenable" midi support well it was never really disabled, but like this we can atleast change its volume lel menu entry is still disabled, i dont think theres a single map with midi music, so this would just clutter the menu --- src/doomdef.h | 3 ++- src/m_menudefs.c | 6 ++++-- src/s_sound.c | 11 ++++++++++- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index 9797c643e..1f7dcb4d8 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -650,7 +650,8 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; #define NOCLIPCAM /// SRB2Kart: MIDI support is shitty and busted and we don't want it, lets throw it behind a define -#define NO_MIDI +// yall didnt properly disable it so it always worked lol (: +//#define NO_MIDI /// Sprite rotation #define ROTSPRITE diff --git a/src/m_menudefs.c b/src/m_menudefs.c index 998c457ae..28b8b94bf 100644 --- a/src/m_menudefs.c +++ b/src/m_menudefs.c @@ -1075,7 +1075,8 @@ static menuitem_t OP_SoundOptionsMenu[] = {IT_STRING|IT_CVAR|IT_CV_NOPRINT, NULL, "Music", &cv_gamedigimusic, 30}, {IT_STRING|IT_CVAR|IT_CV_SLIDER, NULL, "Music Volume", &cv_digmusicvolume, 38}, -#ifndef NO_MIDI +//#ifndef NO_MIDI +#if 0 {IT_STRING|IT_CVAR|IT_CV_SLIDER, NULL, "MIDI Volume", &cv_midimusicvolume, 46}, {IT_STRING|IT_CVAR, NULL, "Reverse L/R Channels", &stereoreverse, 60}, @@ -1110,7 +1111,8 @@ static const char* OP_SoundTooltips[] = "Volume of Sound effects.", "Turn Music on or off.", "Volume of Music.", -#ifndef NO_MIDI +//#ifndef NO_MIDI +#if 0 "Volume of Midi Music.", #endif "Reverse left and right channels of audio.", diff --git a/src/s_sound.c b/src/s_sound.c index 7e2a8e40b..aead25f0c 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1629,10 +1629,20 @@ static lumpnum_t S_GetMusicLumpNum(const char *mname) if (S_MusicExists(mname, false, true)) // check non midis first return W_GetNumForName(va("o_%s", mname)); else if (S_MusicExists(mname, true, false)) + { +#ifdef NO_MIDI + CONS_Alert(CONS_ERROR, "A MIDI music lump %.6s was found,\nbut SRB2Kart does not support MIDI output.\nWe apologise for the inconvenience.\n", mname); + return LUMPERROR; +#else return W_GetNumForName(va("d_%s", mname)); +#endif + } + + CONS_Alert(CONS_ERROR, "Music %.6s could not be loaded: lump not found!\n", mname); return LUMPERROR; } + static boolean S_LoadMusic(const char *mname) { lumpnum_t mlumpnum; @@ -1645,7 +1655,6 @@ static boolean S_LoadMusic(const char *mname) if (mlumpnum == LUMPERROR) { - CONS_Alert(CONS_ERROR, "Music %.6s could not be loaded: lump not found!\n", mname); return false; } -- 2.54.0 From a1d16b46133a5737ed8312f7dc48a45773475466 Mon Sep 17 00:00:00 2001 From: Indev Date: Fri, 8 Aug 2025 17:43:40 +0300 Subject: [PATCH 20/66] Update dedicated/i_sound.c I_StartSound and I_UpdateSoundParams --- src/dedicated/i_sound.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/dedicated/i_sound.c b/src/dedicated/i_sound.c index de43aab85..d2cf53a28 100644 --- a/src/dedicated/i_sound.c +++ b/src/dedicated/i_sound.c @@ -69,13 +69,11 @@ void I_ShutdownSound(void){} \return sfx handle */ -INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel) +INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, INT32 channel) { (void)id; (void)vol; (void)sep; - (void)pitch; - (void)priority; (void)channel; return 0; } @@ -116,12 +114,11 @@ boolean I_SoundIsPlaying(INT32 handle) \return void */ -void I_UpdateSoundParams(INT32 handle, UINT8 vol, UINT8 sep, UINT8 pitch) +void I_UpdateSoundParams(INT32 handle, UINT8 vol, UINT8 sep) { (void)handle; (void)vol; (void)sep; - (void)pitch; } /** \brief The I_SetSfxVolume function -- 2.54.0 From 4c97a4f9e05965222d3852f838eb8172ec019d67 Mon Sep 17 00:00:00 2001 From: Indev Date: Fri, 8 Aug 2025 17:53:46 +0300 Subject: [PATCH 21/66] Fix potential buffer overflow in DEH_LoadDehackedFile --- src/dehacked.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/dehacked.c b/src/dehacked.c index ff03e3694..6b774204c 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -2855,7 +2855,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad) dbg_line = -1; // start at -1 so the first line is 0. while (!myfeof(f)) { - char origpos[128]; + char origpos[256]; INT32 size = 0; char *traverse; @@ -2871,6 +2871,12 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad) size++; } + if (size > (int)sizeof(origpos)) + { + deh_warning("Line is too long"); + size = sizeof(origpos)-1; + } + strncpy(origpos, s, size); origpos[size] = '\0'; -- 2.54.0 From 932a08b2da146907e1c0e10a41e0ff27e4cb231c Mon Sep 17 00:00:00 2001 From: Indev Date: Fri, 8 Aug 2025 18:29:05 +0300 Subject: [PATCH 22/66] Fix makefiles checking for NOLIBGME instead of NOGME --- src/Makefile.d/features.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile.d/features.mk b/src/Makefile.d/features.mk index cf6a728db..456b10163 100644 --- a/src/Makefile.d/features.mk +++ b/src/Makefile.d/features.mk @@ -97,7 +97,7 @@ opts+=-DHAVE_VALGRIND endif default_packages:=\ - LIBGME/libgme/LIBGME\ + GME/libgme/LIBGME\ OPENMPT/libopenmpt/LIBOPENMPT\ ZLIB/zlib\ -- 2.54.0 From 3901c7c7da01dc68202ea73983ce3cf083f30ce1 Mon Sep 17 00:00:00 2001 From: Indev Date: Fri, 8 Aug 2025 18:31:45 +0300 Subject: [PATCH 23/66] Revert "Fix makefiles checking for NOLIBGME instead of NOGME" This reverts commit 932a08b2da146907e1c0e10a41e0ff27e4cb231c. --- src/Makefile.d/features.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile.d/features.mk b/src/Makefile.d/features.mk index 456b10163..cf6a728db 100644 --- a/src/Makefile.d/features.mk +++ b/src/Makefile.d/features.mk @@ -97,7 +97,7 @@ opts+=-DHAVE_VALGRIND endif default_packages:=\ - GME/libgme/LIBGME\ + LIBGME/libgme/LIBGME\ OPENMPT/libopenmpt/LIBOPENMPT\ ZLIB/zlib\ -- 2.54.0 From a7c41b458a3247c76f48bfdb0074c1b8cfcad9d8 Mon Sep 17 00:00:00 2001 From: Indev Date: Fri, 8 Aug 2025 18:33:24 +0300 Subject: [PATCH 24/66] Use NOLIBGME instead of NOGME --- src/Makefile | 2 +- src/Makefile.d/dedicated.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Makefile b/src/Makefile index dcb2eecc6..9b8a92f55 100644 --- a/src/Makefile +++ b/src/Makefile @@ -49,7 +49,7 @@ # Already enabled by default for 32-bit # Windows. # NOCURL=1 - Disable libcurl--HTTP capability. -# NOGME=1 - Disable game music emu, retro VGM support. +# NOLIBGME=1 - Disable game music emu, retro VGM support. # NOOPENMPT=1 - Disable module (tracker) music support. # NOMIXER=1 - Disable SDL Mixer (audio playback). # NOTHREADS=1 - Disable multithreading. diff --git a/src/Makefile.d/dedicated.mk b/src/Makefile.d/dedicated.mk index a421b465d..d50b3b57e 100644 --- a/src/Makefile.d/dedicated.mk +++ b/src/Makefile.d/dedicated.mk @@ -14,6 +14,6 @@ sources+=dedicated/i_threads.c endif NOOPENMPT=1 -NOGME=1 +NOLIBGME=1 NOHW=1 NOUPNP=1 -- 2.54.0 From 222b63d2c38a7b02b2b39a68b287a94957cd2d5a Mon Sep 17 00:00:00 2001 From: Alug Date: Fri, 8 Aug 2025 17:53:13 +0200 Subject: [PATCH 25/66] move the windoze thing to windoze makefile --- src/Makefile.d/features.mk | 7 ------- src/Makefile.d/win32.mk | 4 ++++ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/Makefile.d/features.mk b/src/Makefile.d/features.mk index cf6a728db..d79a3816b 100644 --- a/src/Makefile.d/features.mk +++ b/src/Makefile.d/features.mk @@ -73,13 +73,6 @@ libs+=-lbacktrace opts+=-DHAVE_LIBBACKTRACE endif -#windoze hack -ifdef MINGW -ifndef NODISCORDRPC -HAVE_DISCORDRPC=1 -endif -endif - ifdef HAVE_DISCORDRPC $(eval $(call Propogate_flags,DISCORDRPC)) libs+=-ldiscord-rpc diff --git a/src/Makefile.d/win32.mk b/src/Makefile.d/win32.mk index fa411416e..db2b99a84 100644 --- a/src/Makefile.d/win32.mk +++ b/src/Makefile.d/win32.mk @@ -42,6 +42,10 @@ libs+=-Wl,--large-address-aware NOLIBBACKTRACE=1 endif +ifndef NODISCORDRPC +HAVE_DISCORDRPC=1 +endif + ifndef MINGW64 32=32 x86=x86 -- 2.54.0 From 1fe79fe236b895a031eb8f6c008be159ceb1b0f0 Mon Sep 17 00:00:00 2001 From: Indev Date: Fri, 8 Aug 2025 18:57:58 +0300 Subject: [PATCH 26/66] Add -strict, -strict-soc and -strict-lua cli params Both trigger I_Error if a warning occurs during addon load in a SOC or lua script --- src/dehacked.c | 3 +++ src/lua_script.c | 7 ++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/dehacked.c b/src/dehacked.c index 6b774204c..44f0b5275 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -178,6 +178,9 @@ FUNCPRINTF static void deh_warning(const char *first, ...) else CONS_Alert(CONS_WARNING, "Line %u: %s\n", dbg_line, buf); + if (dbg_line != -1 && (M_CheckParm("-strict") || M_CheckParm("-strict-soc"))) + I_Error("deh_warning: %s", buf); + deh_num_warning++; Z_Free(buf); diff --git a/src/lua_script.c b/src/lua_script.c index 332353bfb..ef095a9b1 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -24,6 +24,7 @@ #include "p_slopes.h" // for P_SlopeById #include "s_sound.h" #include "m_menu.h" +#include "m_argv.h" #ifdef LUA_ALLOW_BYTECODE #include "d_netfil.h" // for LUA_DumpFile #endif @@ -252,7 +253,11 @@ static inline void LUA_LoadFile(MYFILE *f, char *name) lua_pushcfunction(gL, LUA_GetErrorMessage); if (luaL_loadbuffer(gL, f->data, f->size, va("@%s",name)) || lua_pcall(gL, 0, 0, lua_gettop(gL) - 1)) { - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1)); + if (M_CheckParm("-strict") || M_CheckParm("-strict-lua")) + I_Error("Lua error: %s", lua_tostring(gL, -1)); + else + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1)); + lua_pop(gL,1); } lua_gc(gL, LUA_GCCOLLECT, 0); -- 2.54.0 From 43b74923009f97c589fa6c544da67b8201286409 Mon Sep 17 00:00:00 2001 From: Alug Date: Fri, 8 Aug 2025 21:50:13 +0200 Subject: [PATCH 27/66] disable pointless "Couldn't read mobj_t" warnings in replays mobjs just cannot be unarchived in replays ever so this will always spam those for something that WILL never work in kart maybe if i decide to fix this for 32p or smth those become useful again --- src/lua_script.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/lua_script.c b/src/lua_script.c index ef095a9b1..d2cddf125 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -1028,8 +1028,8 @@ static UINT8 UnArchiveValue(UINT8 **p, int TABLESINDEX, boolean network) case ARCH_MOBJ: if (network == false) // for replays :chaosleep: { - *p += sizeof(UINT32); // Skip this data, we can't read a mobj here, it'd point to garbage and crash the game. - return 3; // Don't set the field + *p += sizeof(UINT32); // Skip this data, we can't read a mobj here, it'd point to garbage and crash the game. + return 3; // Don't set the field } LUA_PushUserdata(gL, P_FindNewPosition(READUINT32(*p)), META_MOBJ); @@ -1104,9 +1104,9 @@ static void UnArchiveExtVars(UINT8 **p, void *pointer, boolean network) CONS_Alert(CONS_ERROR, "Unexpected end marker when reading ExtVars (field '%s')\n", field); break; } - else if (ret == 3) // This will return 3 if we shouldn't set this field. + else if (ret == 3) // This will return 3 if we shouldn't set this field. { - CONS_Alert(CONS_WARNING,"Cannot read mobj_t stored in player variable \'%s\'. Desyncs may occur.\n", field); + //CONS_Alert(CONS_WARNING,"Cannot read mobj_t stored in player variable \'%s\'. Desyncs may occur.\n", field); continue; } @@ -1160,7 +1160,7 @@ static void UnArchiveTables(UINT8 **p, boolean network) ret = UnArchiveValue(p, TABLESINDEX, network); if (ret == 3) { - CONS_Alert(CONS_WARNING,"Couldn't read mobj_t\n"); + //CONS_Alert(CONS_WARNING,"Couldn't read mobj_t\n"); lua_pushnil(gL); } else if (ret == 1) // read key @@ -1175,7 +1175,7 @@ static void UnArchiveTables(UINT8 **p, boolean network) } else if (ret == 3) { - CONS_Alert(CONS_WARNING,"Couldn't read mobj_t\n"); + //CONS_Alert(CONS_WARNING,"Couldn't read mobj_t\n"); lua_pushnil(gL); } else if (ret == 2) // read value -- 2.54.0 From 7b776f01bd9179d4a18e22af5021b82dc1f6e302 Mon Sep 17 00:00:00 2001 From: Alug Date: Fri, 8 Aug 2025 22:43:23 +0200 Subject: [PATCH 28/66] change flow of K_drawKartStats a bit nothing notable, just the non splitscreen path will return early now --- src/k_hud.c | 91 +++++++++++++++++++++++++++++------------------------ 1 file changed, 50 insertions(+), 41 deletions(-) diff --git a/src/k_hud.c b/src/k_hud.c index deae2c028..05bce653c 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -1340,40 +1340,76 @@ static void K_drawKartStats(void) spdxoffset = 0; spdoffset = 0; - flags = V_SNAPTOBOTTOM|V_SNAPTOLEFT; - if (!LUA_HudEnabled(hud_statdisplay)) return; + flags = V_SNAPTOBOTTOM|V_SNAPTOLEFT; + //Internal offset for speedometer const UINT8 speedostyle = K_GetSpeedometerStyle(); if (cv_kartspeedometer.value && (!splitscreen)) { - if ((speedostyle == SPEEDO_EXTRA) || (speedostyle == SPEEDO_ACHII) || (speedostyle == SPEEDO_EXTRA3)) - spdoffset = -10; - else if (speedostyle == SPEEDO_DIAL) + switch (speedostyle) { - spdxoffset = 11; - spdoffset = 14; + case SPEEDO_EXTRA: + case SPEEDO_ACHII: + case SPEEDO_EXTRA3: + spdoffset = -10; + break; + case SPEEDO_DIAL: + spdxoffset = 11; + spdoffset = 14; + break; + default: + spdoffset = -14; + break; } - else - spdoffset = -14; } else spdoffset = 0; - if ((speedostyle != SPEEDO_DIAL) || (splitscreen)) - spdoffset += (G_BattleGametype() ? (stplyr->kartstuff[k_bumper] ? -5 : -8) : 0); + if (G_BattleGametype() && ((speedostyle != SPEEDO_DIAL) || splitscreen)) + spdoffset += ((stplyr->kartstuff[k_bumper] ? -5 : -8)); // Customizations c: if (!splitscreen) { + skin_t *fakeskin; + INT32 flags2; + x += 18 + cv_stat_xoffset.value + spdxoffset; y += cv_stat_yoffset.value + spdoffset; + + flags |= V_HUDTRANS; + flags2 = flags|V_ALLOWLOWERCASE|V_SkinColorToHighlightcolor(stplyr->skincolor); + + fakeskin = K_GetPlayerSkin(stplyr); + + // Skin name + if (K_IsHighResolution()) // V_DrawSmallString becomes a mess at low resolutions lel + { + V_DrawSmallString(x+20, y+12, flags2, fakeskin->realname); + } + else + { + V_DrawThinString(x+20, y+7, flags2, fakeskin->realname); + } + + // Icon and stats + if (K_UseHighResPortraits()) + V_DrawSmallMappedPatch(x, y, flags, R_GetSkinFaceWant(stplyr), R_GetLocalTranslationColormap(fakeskin, fakeskin, stplyr->skincolor, GTC_CACHE, stplyr->skinlocal)); + else + V_DrawMappedPatch(x, y, flags, R_GetSkinFaceRank(stplyr), R_GetLocalTranslationColormap(fakeskin, fakeskin, stplyr->skincolor, GTC_CACHE, stplyr->skinlocal)); + + V_DrawMappedPatch(x-3, y-2, flags, kp_facenum[min(9, max(1, stplyr->kartspeed))], R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_BLUEBERRY, GTC_CACHE)); + V_DrawMappedPatch(x+10, y+10, flags, kp_facenum[min(9, max(1, stplyr->kartweight))], R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_BURGUNDY, GTC_CACHE)); + + return; } - else if (splitscreen == 1) // I tried my best, but this is still mess :/ < :Blobcatpats: c: + + if (splitscreen == 1) // I tried my best, but this is still mess :/ < :Blobcatpats: c: { x -= 10; y -= 40; @@ -1411,35 +1447,8 @@ static void K_drawKartStats(void) flags |= V_HUDTRANS; - if (!splitscreen) - { - skin_t *fakeskin; - fakeskin = K_GetPlayerSkin(stplyr); - - // Skin name - if (K_IsHighResolution()) // V_DrawSmallString becomes a mess at low resolutions lel - { - V_DrawSmallString(x+20, y+12, flags|V_ALLOWLOWERCASE|V_SkinColorToHighlightcolor(stplyr->skincolor), fakeskin->realname); - } - else - { - V_DrawThinString(x+20, y+7, flags|V_ALLOWLOWERCASE|V_SkinColorToHighlightcolor(stplyr->skincolor), fakeskin->realname); - } - - // Icon and stats - if (K_UseHighResPortraits()) - V_DrawSmallMappedPatch(x, y, flags, R_GetSkinFaceWant(stplyr), R_GetLocalTranslationColormap(fakeskin, fakeskin, stplyr->skincolor, GTC_CACHE, stplyr->skinlocal)); - else - V_DrawMappedPatch(x, y, flags, R_GetSkinFaceRank(stplyr), R_GetLocalTranslationColormap(fakeskin, fakeskin, stplyr->skincolor, GTC_CACHE, stplyr->skinlocal)); - - V_DrawMappedPatch(x-3, y-2, flags, kp_facenum[min(9, max(1, stplyr->kartspeed))], R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_BLUEBERRY, GTC_CACHE)); - V_DrawMappedPatch(x+10, y+10, flags, kp_facenum[min(9, max(1, stplyr->kartweight))], R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_BURGUNDY, GTC_CACHE)); - } - else - { - // In splitscreen, just draw a string with stats - V_DrawString(x, y+10, flags, va("\x84%dS \x87%dW", stplyr->kartspeed, stplyr->kartweight)); - } + // In splitscreen, just draw a string with stats + V_DrawString(x, y+10, flags, va("\x84%dS \x87%dW", stplyr->kartspeed, stplyr->kartweight)); } static void K_drawKartItem(void) -- 2.54.0 From c36f64e97b8e1f9b25c6670f5501fe66e891af3b Mon Sep 17 00:00:00 2001 From: Alug Date: Sat, 9 Aug 2025 17:13:13 +0200 Subject: [PATCH 29/66] use memcmp for legacy sky check just gotta know if first three letters match it --- src/hardware/hw_cache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 00eba196b..d45d20887 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -328,7 +328,7 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *gltex, boolean noe gltex->mipmap.format = textureformat; // hack the Legacy skies.. - if (UNLIKELY(strncmp(texture->name, "SKY", 3) == 0 && + if (UNLIKELY(memcmp(texture->name, "SKY", 3) == 0 && (texture->name[4] == 0 || texture->name[5] == 0))) { skyspecial = true; -- 2.54.0 From ff6279a4063c69db4cfb069d99be23438c0a8de4 Mon Sep 17 00:00:00 2001 From: Alug Date: Sat, 9 Aug 2025 16:28:04 +0200 Subject: [PATCH 30/66] add P_GetLocalPlayerForNum just to get rid of ternaries lel --- src/g_game.c | 2 +- src/p_local.h | 1 + src/p_tick.c | 2 +- src/p_user.c | 13 ++++++++++++- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index d02c610fa..bba2a99ec 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -883,7 +883,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) return; const UINT8 forplayer = (ssplayer-1); - player_t *player = ((ssplayer == 1) ? &players[consoleplayer] : &players[displayplayers[forplayer]]); + player_t *player = P_GetLocalPlayerForNum(forplayer); camera_t *thiscam = &camera[forplayer]; const boolean freecam = camera[forplayer].freecam; diff --git a/src/p_local.h b/src/p_local.h index de62c86a1..fbb232bda 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -180,6 +180,7 @@ void P_CalcChasePostImg(player_t *player, camera_t *thiscam); boolean P_PlayerInPain(player_t *player); void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor); void P_ResetPlayer(player_t *player); +player_t *P_GetLocalPlayerForNum(UINT8 pnum); boolean P_IsLocalPlayer(const player_t *player); boolean P_IsDisplayPlayer(const player_t *player); diff --git a/src/p_tick.c b/src/p_tick.c index ce985a5e2..f383d1844 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -488,7 +488,7 @@ static void P_DeviceRumbleTick(void) UINT16 low = 0, high = 0; UINT16 lenght = 57; // in ms - const player_t *player = ((i == 0) ? &players[consoleplayer] : &players[displayplayers[i]]); + const player_t *player = P_GetLocalPlayerForNum(i); // allow lua to do some crap for spectators if (player->spectator || !player->mo) diff --git a/src/p_user.c b/src/p_user.c index 731135ebd..3c8843d28 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -972,6 +972,17 @@ fixed_t P_GetPlayerSpinHeight(player_t *player) return FixedMul(FixedMul(player->mo->info->height, player->mo->scale),2*FRACUNIT/3); } +// +// P_GetLocalPlayerForNum +// +// Returns the player +// on the local machine for given number. +// +player_t *P_GetLocalPlayerForNum(UINT8 pnum) +{ + return (pnum == 0 ? &players[consoleplayer] : &players[displayplayers[pnum]]); +} + // // P_IsLocalPlayer // @@ -3673,7 +3684,7 @@ static boolean P_CheckNoclipCameraPosition(player_t *player, camera_t *thiscam, static void P_MoveCameraToSpawn(UINT8 playernum) { camera_t *thiscam = &camera[playernum]; - player_t *player = playernum == 0 ? &players[consoleplayer] : &players[displayplayers[playernum]]; + player_t *player = P_GetLocalPlayerForNum(playernum); if (!thiscam || !player->mo) return; -- 2.54.0 From ca04e084a282c61263a6ff87788855a569bceda7 Mon Sep 17 00:00:00 2001 From: Alug Date: Sat, 9 Aug 2025 23:31:55 +0100 Subject: [PATCH 31/66] link stdc++. pthread and gcclib statically on windows fixes the game throwing super cryptic errors when you dont have the right dlls --- src/Makefile.d/win32.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Makefile.d/win32.mk b/src/Makefile.d/win32.mk index db2b99a84..8c5e75b8e 100644 --- a/src/Makefile.d/win32.mk +++ b/src/Makefile.d/win32.mk @@ -15,6 +15,7 @@ endif sources+=win32/Srb2win.rc opts+=-DSTDC_HEADERS +libs+=-Wl,-Bstatic -lstdc++ -lpthread -lgcc -Wl,-Bdynamic libs+=-ladvapi32 -lkernel32 -lmsvcrt -luser32 ifndef DEDICATED -- 2.54.0 From f57b8092fcdb8cb9a55198639eb6970e051c019e Mon Sep 17 00:00:00 2001 From: Alug Date: Tue, 12 Aug 2025 20:27:22 +0200 Subject: [PATCH 32/66] dont need to reinit those gl vars --- src/hardware/hw_main.cpp | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/src/hardware/hw_main.cpp b/src/hardware/hw_main.cpp index 62c6c97ed..1760dfc0c 100644 --- a/src/hardware/hw_main.cpp +++ b/src/hardware/hw_main.cpp @@ -548,9 +548,9 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool INT32 i; float height; // constant y for all points on the convex flat polygon - float flatxref, flatyref = 0.0f; - float fflatsize = 64.0f; - INT32 flatflag = 63; + static float flatxref = 0.0f, flatyref = 0.0f; + static float fflatsize = 64.0f; + static INT32 flatflag = 63; size_t len; float tempxsow, tempytow; @@ -1013,10 +1013,10 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, float diff; - fixed_t v1x = FloatToFixed(wallVerts[0].x); - fixed_t v1y = FloatToFixed(wallVerts[0].z); - fixed_t v2x = FloatToFixed(wallVerts[1].x); - fixed_t v2y = FloatToFixed(wallVerts[1].z); + const fixed_t v1x = FloatToFixed(wallVerts[0].x); + const fixed_t v1y = FloatToFixed(wallVerts[0].z); + const fixed_t v2x = FloatToFixed(wallVerts[1].x); + const fixed_t v2y = FloatToFixed(wallVerts[1].z); const UINT8 alpha = Surf->PolyColor.s.alpha; FUINT lightnum = HWR_CalcWallLight(sector->lightlevel, gl_curline, NULL); @@ -5304,19 +5304,14 @@ static void HWR_DrawSkyBackground(void) { FTransform dometransform; - if (drewsky) - return; - - if (HWR_IsWireframeMode()) + if (drewsky || HWR_IsWireframeMode()) return; GL_SetBlend(PF_Translucent|PF_NoDepthTest|PF_Modulated); memcpy(&dometransform, &atransform, sizeof(FTransform)); - dometransform.x = 0.0; - dometransform.y = 0.0; - dometransform.z = 0.0; + dometransform.x = dometransform.y = dometransform.z = 0.0; //04/01/2000: Hurdler: added for T&L // It should replace all other gl_viewxxx when finished @@ -5350,7 +5345,6 @@ static inline void HWR_ClearView(void) GL_ClearBuffer(false, true, true, NULL); } - // -----------------+ // HWR_SetViewSize : set projection and scaling values // -----------------+ @@ -5581,7 +5575,7 @@ void HWR_RenderViewpoint(gl_portal_t *rootportal, player_t *player, int stencil_ drewsky = false; HWR_DrawSkyBackground(); HWR_SetStencilState(HWR_STENCIL_NORMAL, 0); - GL_ClearBuffer(false, false, true, 0);// clear skywall markings from the stencil buffer + GL_ClearBuffer(false, false, true, NULL);// clear skywall markings from the stencil buffer HWR_SetTransform(fpov);// restore transform } } @@ -5700,13 +5694,7 @@ void HWR_RenderPlayerView(void) // Clear the color buffer, stops HOMs. Also seems to fix the skybox issue on Intel GPUs. if (viewssnum == 0) // Only do it if it's the first screen being rendered { - FRGBAFloat ClearColor; - - ClearColor.red = 0.0f; - ClearColor.green = 0.0f; - ClearColor.blue = 0.0f; - ClearColor.alpha = 1.0f; - + static FRGBAFloat ClearColor = {0.0f, 0.0f, 0.0f, 1.0f}; GL_ClearBuffer(true, false, false, &ClearColor); } -- 2.54.0 From 602bd1a0103a8aacd0917fc687fed1765ed72d24 Mon Sep 17 00:00:00 2001 From: Alug Date: Tue, 12 Aug 2025 20:25:57 +0200 Subject: [PATCH 33/66] fix directional light stuff --- src/hardware/hw_main.cpp | 23 ++++++++++++++++------- src/hardware/hw_shaders.c | 2 +- src/hardware/r_opengl/r_opengl.c | 2 +- src/p_setup.c | 1 - 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/hardware/hw_main.cpp b/src/hardware/hw_main.cpp index 1760dfc0c..0e89f4138 100644 --- a/src/hardware/hw_main.cpp +++ b/src/hardware/hw_main.cpp @@ -378,7 +378,7 @@ void HWR_ObjectLightLevelPost(gl_vissprite_t *spr, const sector_t *sector, INT32 fixed_t extralight = R_GetSpriteDirectionalLighting(R_PointToAngle(spr->mobj->x, spr->mobj->y)); // Less change in contrast in dark sectors - extralight = FixedMul(extralight, CLAMP(*lightlevel, 0, 255) * FRACUNIT / 255); + extralight = FixedMul(extralight, std::min(std::max(0, *lightlevel), 255) * FRACUNIT / 255); // simple OGL approximation fixed_t tr = R_QuickCamDist(spr->mobj->x, spr->mobj->y) << FRACBITS; @@ -459,6 +459,7 @@ void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *col V_CubeApply(&tint_color.s.red, &tint_color.s.green, &tint_color.s.blue); V_CubeApply(&fade_color.s.red, &fade_color.s.green, &fade_color.s.blue); } + Surface->PolyColor.rgba = poly_color.rgba; Surface->TintColor.rgba = tint_color.rgba; Surface->FadeColor.rgba = fade_color.rgba; @@ -1222,6 +1223,7 @@ static void HWR_DrawSkyWallList(void) HWR_SetCurrentTexture(NULL); GL_UnSetShader(); + for (i = 0; i < skyWallVertexArraySize; i++) { GL_DrawPolygon(&surf, skyWallVertexArray + i * 4, 4, PF_Occlude|PF_Invisible|PF_NoTexture|PF_Skydecal); @@ -5328,6 +5330,7 @@ static void HWR_DrawSkyBackground(void) if (HWR_UseShader()) GL_SetShader(HWR_GetShaderFromTarget(SHADER_SKY)); + GL_SetTransform(&dometransform); GL_RenderSkyDome(&gl_sky); } @@ -5703,13 +5706,19 @@ void HWR_RenderPlayerView(void) if (cv_ripplewater.value) GL_SetShaderInfo(HWD_SHADERINFO_LEVELTIME, (INT32)leveltime); // The water surface shader needs the leveltime. - const angle_t light_angle = maplighting.angle - viewangle + ANGLE_90; // I fucking hate OGL's coordinate system - GL_SetShaderInfo(HWD_SHADERINFO_LIGHT_X, FINECOSINE(light_angle >> ANGLETOFINESHIFT)); - GL_SetShaderInfo(HWD_SHADERINFO_LIGHT_Y, 0); - GL_SetShaderInfo(HWD_SHADERINFO_LIGHT_Z, -FINESINE(light_angle >> ANGLETOFINESHIFT)); + if (cv_glmdls.value) + { + if (maplighting.directional) + { + const angle_t light_angle = maplighting.angle - viewangle + ANGLE_90; // I fucking hate OGL's coordinate system + GL_SetShaderInfo(HWD_SHADERINFO_LIGHT_X, FINECOSINE(light_angle >> ANGLETOFINESHIFT)); + GL_SetShaderInfo(HWD_SHADERINFO_LIGHT_Y, 0); + GL_SetShaderInfo(HWD_SHADERINFO_LIGHT_Z, -FINESINE(light_angle >> ANGLETOFINESHIFT)); + } - GL_SetShaderInfo(HWD_SHADERINFO_LIGHT_CONTRAST, maplighting.contrast); - GL_SetShaderInfo(HWD_SHADERINFO_LIGHT_BACKLIGHT, maplighting.backlight); + GL_SetShaderInfo(HWD_SHADERINFO_LIGHT_CONTRAST, maplighting.contrast); + GL_SetShaderInfo(HWD_SHADERINFO_LIGHT_BACKLIGHT, maplighting.backlight); + } } if (viewssnum > 3) diff --git a/src/hardware/hw_shaders.c b/src/hardware/hw_shaders.c index b4041fcae..9724378fe 100644 --- a/src/hardware/hw_shaders.c +++ b/src/hardware/hw_shaders.c @@ -35,7 +35,7 @@ static struct { // Sprite shader {GLSL_DEFAULT_VERTEX_SHADER, GLSL_WALL_FRAGMENT_SHADER}, - // Model shader + // Model shader + diffuse lighting from above {GLSL_MODEL_LIGHTING_VERTEX_SHADER, GLSL_WALL_FRAGMENT_SHADER}, // Water shader diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index e21219083..4dcd1253b 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -2112,7 +2112,7 @@ static void GL_Shader_SetUniforms(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRG UNIFORM_1(shader->uniforms[gluniform_lighting], (GLfloat)Surface->LightInfo.light_level, pglUniform1f); UNIFORM_1(shader->uniforms[gluniform_fade_start], (GLfloat)Surface->LightInfo.fade_start, pglUniform1f); UNIFORM_1(shader->uniforms[gluniform_fade_end], (GLfloat)Surface->LightInfo.fade_end, pglUniform1f); - directional = Surface->LightInfo.directional; + directional = cv_glmdls.value && Surface->LightInfo.directional; } else { diff --git a/src/p_setup.c b/src/p_setup.c index 0958054cf..05af8bfcb 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -537,7 +537,6 @@ static void P_SetupDirectionalLight(void) oldmap = gamemap; oldencore = encoremode; - return; } maplighting.contrast = lighting->light_contrast; -- 2.54.0 From 7deeb4486fc6474360e4d458b1f2017f36959020 Mon Sep 17 00:00:00 2001 From: Alug Date: Wed, 13 Aug 2025 18:00:11 +0200 Subject: [PATCH 34/66] port RR camera slope pitch stuff + make it toggable "cam_pitch" this makes the camera pitch on upwards and downwards slopes a bit --- src/m_menudefs.c | 18 ++++---- src/p_local.h | 9 ++-- src/p_user.c | 115 ++++++++++++++++++++++++++++++++++++----------- src/r_main.cpp | 9 ++-- 4 files changed, 111 insertions(+), 40 deletions(-) diff --git a/src/m_menudefs.c b/src/m_menudefs.c index 28b8b94bf..a3be98ac2 100644 --- a/src/m_menudefs.c +++ b/src/m_menudefs.c @@ -1346,14 +1346,15 @@ static const char* OP_CamOptionsTooltips[] = }; #define OP_CAMMENU(pnum) \ -{IT_STRING | IT_CVAR, NULL, "Flipcam", &cv_flipcam[pnum], 30}, \ -{IT_STRING | IT_CVAR | IT_CV_BIGFLOAT, NULL, "Camera Distance", &cv_cam_dist[pnum], 50}, \ -{IT_STRING | IT_CVAR | IT_CV_BIGFLOAT, NULL, "Camera Height", &cv_cam_height[pnum], 60}, \ -{IT_STRING | IT_CVAR, NULL, "Camera Speed", &cv_cam_speed[pnum], 70}, \ -{IT_STRING | IT_CVAR, NULL, "Camera Lookback Momentum", &cv_lookbackmom[pnum], 90}, \ -{IT_STRING | IT_CVAR, NULL, "Camera Vertical Look", &cv_verticallook[pnum], 100}, \ -{IT_STRING | IT_CVAR, NULL, "Freecam Speed", &cv_freecam_speed[pnum], 120}, \ -{IT_STRING | IT_CVAR, NULL, "Third Person Camera", &cv_chasecam[pnum], 135}, \ + {IT_STRING | IT_CVAR, NULL, "Flipcam", &cv_flipcam[pnum], 30}, \ + {IT_STRING | IT_CVAR | IT_CV_BIGFLOAT, NULL, "Camera Distance", &cv_cam_dist[pnum], 50}, \ + {IT_STRING | IT_CVAR | IT_CV_BIGFLOAT, NULL, "Camera Height", &cv_cam_height[pnum], 60}, \ + {IT_STRING | IT_CVAR, NULL, "Camera Slope Pitch", &cv_cam_pitch[pnum], 70}, \ + {IT_STRING | IT_CVAR, NULL, "Camera Speed", &cv_cam_speed[pnum], 80}, \ + {IT_STRING | IT_CVAR, NULL, "Camera Lookback Momentum", &cv_cam_lookbackmom[pnum], 100}, \ + {IT_STRING | IT_CVAR, NULL, "Camera Vertical Look", &cv_verticallook[pnum], 110}, \ + {IT_STRING | IT_CVAR, NULL, "Freecam Speed", &cv_freecam_speed[pnum], 130}, \ + {IT_STRING | IT_CVAR, NULL, "Third Person Camera", &cv_chasecam[pnum], 145}, \ static menuitem_t OP_Player1CamOptionsMenu[] = { @@ -1385,6 +1386,7 @@ static const char* OP_PlayerCamOptionsTooltips[] = "Should the Camera flip on gravity flipped sections?.", "Camera distance relative to the Player.", "Height of the Camera", + "Pitch Camera on Upwards or Downhill Slopes", "Speed of the Camera", "Should looking back inherit the Players Momentum?\nEither inherit Player Momentum or double of it\nmay make looking back while boosting or going in high speed less jarring", "Allows looking up/down by holding\naim forward/backward while standing still.", diff --git a/src/p_local.h b/src/p_local.h index fbb232bda..23c6b3a71 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -128,6 +128,9 @@ typedef struct camera_s // SRB2Kart: camera pans while drifting fixed_t pan; + // SRB2Kart: camera pitches on slopes + angle_t pitch; + // postproccess effects UINT8 postimg; } camera_t; @@ -144,9 +147,11 @@ enum extern camera_t camera[MAXSPLITSCREENPLAYERS]; extern consvar_t cv_cam_dist[MAXSPLITSCREENPLAYERS]; -extern consvar_t cv_cam_still[MAXSPLITSCREENPLAYERS]; extern consvar_t cv_cam_height[MAXSPLITSCREENPLAYERS]; +extern consvar_t cv_cam_pitch[MAXSPLITSCREENPLAYERS]; extern consvar_t cv_cam_speed[MAXSPLITSCREENPLAYERS]; +extern consvar_t cv_cam_lookbackmom[MAXSPLITSCREENPLAYERS]; +extern consvar_t cv_cam_still[MAXSPLITSCREENPLAYERS]; extern consvar_t cv_cam_rotate[MAXSPLITSCREENPLAYERS]; extern consvar_t cv_cam_timeover[MAXSPLITSCREENPLAYERS]; @@ -160,8 +165,6 @@ extern consvar_t cv_actionmovie; extern consvar_t cv_screenquake; -extern consvar_t cv_lookbackmom[MAXSPLITSCREENPLAYERS]; - extern consvar_t cv_verticallook[MAXSPLITSCREENPLAYERS]; extern fixed_t t_cam_rotate[MAXSPLITSCREENPLAYERS]; diff --git a/src/p_user.c b/src/p_user.c index 3c8843d28..24fdb0b01 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -3003,21 +3003,28 @@ static void CV_PlayerCam4_OnChange(void) } consvar_t cv_cam_dist[MAXSPLITSCREENPLAYERS] = { - {"cam_dist", "160", CV_FLOAT|CV_SAVE|CV_CALL|CV_NOINIT, NULL, CV_PlayerCam1_OnChange, 0, NULL, NULL, 0, 0, NULL}, + {"cam_dist", "160", CV_FLOAT|CV_SAVE|CV_CALL|CV_NOINIT, NULL, CV_PlayerCam1_OnChange, 0, NULL, NULL, 0, 0, NULL}, {"cam2_dist", "160", CV_FLOAT|CV_SAVE|CV_CALL|CV_NOINIT, NULL, CV_PlayerCam2_OnChange, 0, NULL, NULL, 0, 0, NULL}, {"cam3_dist", "160", CV_FLOAT|CV_SAVE|CV_CALL|CV_NOINIT, NULL, CV_PlayerCam3_OnChange, 0, NULL, NULL, 0, 0, NULL}, {"cam4_dist", "160", CV_FLOAT|CV_SAVE|CV_CALL|CV_NOINIT, NULL, CV_PlayerCam4_OnChange, 0, NULL, NULL, 0, 0, NULL} }; consvar_t cv_cam_height[MAXSPLITSCREENPLAYERS] = { - {"cam_height", "50", CV_FLOAT|CV_SAVE|CV_CALL|CV_NOINIT, NULL, CV_PlayerCam1_OnChange, 0, NULL, NULL, 0, 0, NULL}, + {"cam_height", "50", CV_FLOAT|CV_SAVE|CV_CALL|CV_NOINIT, NULL, CV_PlayerCam1_OnChange, 0, NULL, NULL, 0, 0, NULL}, {"cam2_height", "50", CV_FLOAT|CV_SAVE|CV_CALL|CV_NOINIT, NULL, CV_PlayerCam2_OnChange, 0, NULL, NULL, 0, 0, NULL}, {"cam3_height", "50", CV_FLOAT|CV_SAVE|CV_CALL|CV_NOINIT, NULL, CV_PlayerCam3_OnChange, 0, NULL, NULL, 0, 0, NULL}, {"cam4_height", "50", CV_FLOAT|CV_SAVE|CV_CALL|CV_NOINIT, NULL, CV_PlayerCam4_OnChange, 0, NULL, NULL, 0, 0, NULL}, }; +consvar_t cv_cam_pitch[MAXSPLITSCREENPLAYERS] = { + {"cam_pitch", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}, + {"cam2_pitch", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}, + {"cam3_pitch", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}, + {"cam4_pitch", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL} +}; + consvar_t cv_cam_still[MAXSPLITSCREENPLAYERS] = { - {"cam_still", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}, + {"cam_still", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}, {"cam2_still", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}, {"cam3_still", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}, {"cam4_still", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL} @@ -3025,7 +3032,7 @@ consvar_t cv_cam_still[MAXSPLITSCREENPLAYERS] = { static CV_PossibleValue_t cam_speed_cons_t[] = {{0, "MIN"}, {1*FRACUNIT, "MAX"}, {0, NULL}}; consvar_t cv_cam_speed[MAXSPLITSCREENPLAYERS] = { - {"cam_speed", "0.4", CV_FLOAT|CV_SAVE, cam_speed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, + {"cam_speed", "0.4", CV_FLOAT|CV_SAVE, cam_speed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, {"cam2_speed", "0.4", CV_FLOAT|CV_SAVE, cam_speed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, {"cam3_speed", "0.4", CV_FLOAT|CV_SAVE, cam_speed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, {"cam4_speed", "0.4", CV_FLOAT|CV_SAVE, cam_speed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL} @@ -3034,14 +3041,14 @@ consvar_t cv_cam_speed[MAXSPLITSCREENPLAYERS] = { static CV_PossibleValue_t cam_rotate_cons_t[] = {{-720, "MIN"}, {720, "MAX"}, {0, NULL}}; consvar_t cv_cam_rotate[MAXSPLITSCREENPLAYERS] = { - {"cam_rotate", "0", CV_CALL|CV_NOINIT, cam_rotate_cons_t, CV_CamRotate_OnChange, 0, NULL, NULL, 0, 0, NULL}, + {"cam_rotate", "0", CV_CALL|CV_NOINIT, cam_rotate_cons_t, CV_CamRotate_OnChange, 0, NULL, NULL, 0, 0, NULL}, {"cam2_rotate", "0", CV_CALL|CV_NOINIT, cam_rotate_cons_t, CV_CamRotate2_OnChange, 0, NULL, NULL, 0, 0, NULL}, {"cam3_rotate", "0", CV_CALL|CV_NOINIT, cam_rotate_cons_t, CV_CamRotate3_OnChange, 0, NULL, NULL, 0, 0, NULL}, {"cam4_rotate", "0", CV_CALL|CV_NOINIT, cam_rotate_cons_t, CV_CamRotate4_OnChange, 0, NULL, NULL, 0, 0, NULL} }; consvar_t cv_cam_timeover[MAXSPLITSCREENPLAYERS] = { - {"cam_timeover", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}, + {"cam_timeover", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}, {"cam2_timeover", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}, {"cam3_timeover", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}, {"cam4_timeover", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL} @@ -3049,7 +3056,7 @@ consvar_t cv_cam_timeover[MAXSPLITSCREENPLAYERS] = { static CV_PossibleValue_t freecam_speed_cons_t[] = {{0, "MIN"}, {10, "MAX"}, {0, NULL}}; consvar_t cv_freecam_speed[MAXSPLITSCREENPLAYERS] = { - {"freecam_speed", "1", CV_SAVE, freecam_speed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, + {"freecam_speed", "1", CV_SAVE, freecam_speed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, {"freecam2_speed", "1", CV_SAVE, freecam_speed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, {"freecam3_speed", "1", CV_SAVE, freecam_speed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, {"freecam4_speed", "1", CV_SAVE, freecam_speed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL} @@ -3063,13 +3070,13 @@ consvar_t cv_actionmovie = {"actionmovie", "Off", CV_SAVE, CV_OnOff, NULL, 0, NU consvar_t cv_screenquake = {"quakescreenshake", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -static CV_PossibleValue_t lookbackmom_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Double"}, {0, NULL}}; +static CV_PossibleValue_t cam_lookbackmom_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Double"}, {0, NULL}}; -consvar_t cv_lookbackmom[MAXSPLITSCREENPLAYERS] = { - {"cameralookbackmom", "Off", CV_SAVE, lookbackmom_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, - {"cameralookbackmom2", "Off", CV_SAVE, lookbackmom_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, - {"cameralookbackmom3", "Off", CV_SAVE, lookbackmom_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, - {"cameralookbackmom4", "Off", CV_SAVE, lookbackmom_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL} +consvar_t cv_cam_lookbackmom[MAXSPLITSCREENPLAYERS] = { + {"cameralookbackmom", "Off", CV_SAVE, cam_lookbackmom_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, + {"cameralookbackmom2", "Off", CV_SAVE, cam_lookbackmom_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, + {"cameralookbackmom3", "Off", CV_SAVE, cam_lookbackmom_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, + {"cameralookbackmom4", "Off", CV_SAVE, cam_lookbackmom_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL} }; fixed_t t_cam_rotate[MAXSPLITSCREENPLAYERS] = {-42, -42, -42, -42}; @@ -3713,8 +3720,8 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall static boolean lookbackactive[MAXSPLITSCREENPLAYERS]; static UINT8 lookbackdelay[MAXSPLITSCREENPLAYERS]; UINT8 num = 0; - angle_t angle = 0, focusangle = 0, focusaiming = 0; - fixed_t x, y, z, dist, viewpointx, viewpointy, camspeed, camdist, camheight, pviewheight; + angle_t angle = 0, focusangle = 0, focusaiming = 0, pitch = 0; + fixed_t x, y, z, dist, distxy, distz, viewpointx, viewpointy, camspeed, camdist, camheight, pviewheight; fixed_t pan, xpan, ypan; INT32 camrotate; boolean camstill, lookback, lookbackdown; @@ -3758,8 +3765,6 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall mo = player->mo; - const boolean vflip = (mo->eflags & MFE_VERTICALFLIP); - if (cv_cam_timeover[num].value && (player->pflags & PF_TIMEOVER)) timeover = (player->kartstuff[k_timeovercam] > 2*TICRATE ? 2 : 1); // 1 for momentum keep, 2 for turnaround else @@ -3817,6 +3822,8 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall if (P_CameraThinker(player, thiscam, resetcalled)) return true; + const boolean vflip = (mo->eflags & MFE_VERTICALFLIP); + camspeed = cv_cam_speed[num].value; camstill = cv_cam_still[num].value; camrotate = cv_cam_rotate[num].value; @@ -3913,8 +3920,41 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall if (player->kartstuff[k_boostcam]) dist -= FixedMul(11*dist/16, player->kartstuff[k_boostcam]); - x = mo->x - FixedMul(FINECOSINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist); - y = mo->y - FixedMul(FINESINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist); + if (cv_cam_pitch[num].value) + { + if (mo->standingslope) + { + pitch = (angle_t)FixedMul(P_ReturnThrustX(mo, thiscam->angle - mo->standingslope->xydirection, FRACUNIT), (fixed_t)mo->standingslope->zangle); + + if (vflip) + { + if (pitch >= ANGLE_180) + pitch = 0; + } + else + { + if (pitch < ANGLE_180) + pitch = 0; + } + } + pitch = thiscam->pitch + (angle_t)FixedMul(pitch - thiscam->pitch, camspeed/4); + +#ifdef HWRENDER + if (rendermode == render_opengl) + distxy = FixedMul(dist, FINECOSINE((pitch>>ANGLETOFINESHIFT) & FINEMASK)); + else +#endif + distxy = dist; + distz = -FixedMul(dist, FINESINE((pitch>>ANGLETOFINESHIFT) & FINEMASK)); + } + else + { + distxy = dist; + distz = 0; + } + + x = mo->x - FixedMul(FINECOSINE((angle>>ANGLETOFINESHIFT) & FINEMASK), distxy); + y = mo->y - FixedMul(FINESINE((angle>>ANGLETOFINESHIFT) & FINEMASK), distxy); // SRB2Kart: set camera panning if (camstill || resetcalled || player->playerstate == PST_DEAD) @@ -3946,10 +3986,26 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall pviewheight = FixedMul(32<scale); - if (vflip) - z = mo->z + mo->height - pviewheight - camheight; + if (cv_cam_pitch[num].value) + { + if (vflip) + { + distz = min(-camheight, distz); + z = mo->z + mo->height - pviewheight + distz; + } + else + { + distz = max(camheight, distz); + z = mo->z + pviewheight + distz; + } + } else - z = mo->z + pviewheight + camheight; + { + if (vflip) + z = mo->z + mo->height - pviewheight - camheight; + else + z = mo->z + pviewheight + camheight; + } #ifndef NOCLIPCAM // Disable all z-clipping for noclip cam if (P_CheckNoclipCameraPosition(player, thiscam, x, y, z, resetcalled)) @@ -3991,16 +4047,17 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall // when looking back, camera's momentum // should inherit the momentum of the player // if value is 2, add extra - if (cv_lookbackmom[num].value && lookback && lookbackdelay[num]) + if (cv_cam_lookbackmom[num].value && lookback && lookbackdelay[num]) { - thiscam->momx += cv_lookbackmom[num].value*mo->momx; - thiscam->momy += cv_lookbackmom[num].value*mo->momy; + thiscam->momx += cv_cam_lookbackmom[num].value*mo->momx; + thiscam->momy += cv_cam_lookbackmom[num].value*mo->momy; } thiscam->momz = FixedMul(z - thiscam->z, camspeed/2); } thiscam->pan = pan; + thiscam->pitch = pitch; // compute aming to look the viewed point f1 = viewpointx-thiscam->x; @@ -4008,9 +4065,17 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall dist = FixedHypot(f1, f2); if (vflip) + { angle = R_PointToAngle2(0, thiscam->z + thiscam->height, dist, mo->z + mo->height - P_GetPlayerHeight(player)); + if (thiscam->pitch < ANGLE_180 && thiscam->pitch > angle) + angle += (thiscam->pitch - angle)/2; + } else + { angle = R_PointToAngle2(0, thiscam->z, dist, mo->z + P_GetPlayerHeight(player)); + if (thiscam->pitch >= ANGLE_180 && thiscam->pitch < angle) + angle -= (angle - thiscam->pitch)/2; + } if (player->playerstate != PST_DEAD && !((player->pflags & PF_NIGHTSMODE) && player->exiting)) angle += (focusaiming < ANGLE_180 ? focusaiming/2 : InvAngle(InvAngle(focusaiming)/2)); // overcomplicated version of '((signed)focusaiming)/2;' diff --git a/src/r_main.cpp b/src/r_main.cpp index 656bc78d8..4e0b59126 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -1569,14 +1569,15 @@ void R_RegisterEngineStuff(void) CV_RegisterVar(&cv_chasecam[i]); CV_RegisterVar(&cv_cam_dist[i]); - CV_RegisterVar(&cv_cam_still[i]); CV_RegisterVar(&cv_cam_height[i]); + CV_RegisterVar(&cv_cam_pitch[i]); CV_RegisterVar(&cv_cam_speed[i]); - CV_RegisterVar(&cv_cam_rotate[i]); CV_RegisterVar(&cv_cam_timeover[i]); - CV_RegisterVar(&cv_freecam_speed[i]); + CV_RegisterVar(&cv_cam_lookbackmom[i]); + CV_RegisterVar(&cv_cam_still[i]); + CV_RegisterVar(&cv_cam_rotate[i]); - CV_RegisterVar(&cv_lookbackmom[i]); + CV_RegisterVar(&cv_freecam_speed[i]); } CV_RegisterVar(&cv_tilting); -- 2.54.0 From b7ecffedcd46b7d9320c03769d37e9db86b6249e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Wed, 13 Aug 2025 17:51:08 +0200 Subject: [PATCH 35/66] Fix pixel shift caused by negative pixel positioning in software --- src/r_draw_column.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_draw_column.cpp b/src/r_draw_column.cpp index dcc1a5b90..4b3a4f95d 100644 --- a/src/r_draw_column.cpp +++ b/src/r_draw_column.cpp @@ -217,7 +217,7 @@ static void R_DrawColumnTemplate(drawcolumndata_t *dc) { if (frac < 0) // adjust in case we underread - frac += FRACUNIT; + frac += fracstep; // texture has no height, so just go while (--count >= 0) -- 2.54.0 From 9338b5b10f8e262f30530c493fe0af3f260e31c7 Mon Sep 17 00:00:00 2001 From: Alug Date: Thu, 14 Aug 2025 16:19:05 +0200 Subject: [PATCH 36/66] dont need to realloc this didnt see when i added realloc everywhere this doesent need to keep old data --- src/hardware/hw_batching.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hardware/hw_batching.c b/src/hardware/hw_batching.c index 3b5c5426e..28b568c54 100644 --- a/src/hardware/hw_batching.c +++ b/src/hardware/hw_batching.c @@ -99,7 +99,8 @@ void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPt polygonArrayAllocSize *= 2; polygonArray = realloc(polygonArray, polygonArrayAllocSize * sizeof(PolygonArrayEntry)); // also need to redo the index array, dont need to copy it though - polygonArraySorted = realloc(polygonArraySorted, polygonArrayAllocSize * sizeof(PolygonArrayEntry*)); + free(polygonArraySorted); + polygonArraySorted = malloc(polygonArrayAllocSize * sizeof(PolygonArrayEntry *)); } while (unsortedVertexArraySize + (int)iNumPts > unsortedVertexArrayAllocSize) -- 2.54.0 From 9dee0f0ea8cb33f07a44214bbf6301c59a2705ef Mon Sep 17 00:00:00 2001 From: Alug Date: Fri, 15 Aug 2025 07:58:26 +0200 Subject: [PATCH 37/66] fix restrict being in wrong place in declaration R_DrawColumnPixel --- src/r_draw_column.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_draw_column.cpp b/src/r_draw_column.cpp index 4b3a4f95d..bae220e6d 100644 --- a/src/r_draw_column.cpp +++ b/src/r_draw_column.cpp @@ -57,7 +57,7 @@ static constexpr UINT8 R_GetColumnTranslucent(drawcolumndata_t* dc, UINT8 * rest } template -static constexpr UINT8 R_DrawColumnPixel(drawcolumndata_t* dc, UINT8 * restrict dest, UINT32 bit, const restrict UINT8 *source, const restrict UINT8 *colormap) +static constexpr UINT8 R_DrawColumnPixel(drawcolumndata_t* dc, UINT8 * restrict dest, UINT32 bit, const UINT8 * restrict source, const UINT8 * restrict colormap) { UINT8 col = source[bit]; -- 2.54.0 From 7d06f59da57983b1e72754ca94a83a50163e0f92 Mon Sep 17 00:00:00 2001 From: Alug Date: Fri, 15 Aug 2025 07:57:31 +0200 Subject: [PATCH 38/66] append those to LDFLAGS instead of libs so they may be passed to other things --- src/Makefile | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Makefile b/src/Makefile index 9b8a92f55..8b7d17cec 100644 --- a/src/Makefile +++ b/src/Makefile @@ -236,7 +236,7 @@ endif # build with profiling information ifdef PROFILEMODE opts+=-pg -libs+=-pg +LDFLAGS+=-pg endif ifdef DEBUGMODE @@ -248,10 +248,10 @@ ifdef USELTO # compile with LTO ifdef MINGW opts+=-flto=auto -g -libs+=-flto=auto -g +LDFLAGS+=-flto=auto -g else opts+=-flto=auto -libs+=-flto=auto +LDFLAGS+=-flto=auto endif endif endif @@ -265,8 +265,8 @@ else opts+=-fsanitize=address libs+=-fsanitize=address endif -opts+=-fsanitize=address -libs+=-fsanitize=address +endif + endif # debug_opts also get passed to windres @@ -281,6 +281,7 @@ cxxopts:=$(opts) $(CXXFLAGS) opts+=$(CWFLAGS) # warning flags that shouldnt be passed to c++ compiler libs+=$(LDFLAGS) -lstdc++ -lpthread + asflags:=$(ASFLAGS) -x assembler-with-cpp cc=$(CC) -- 2.54.0 From 6c891f11462fc86ed41cdc87f841cd1da7e800cc Mon Sep 17 00:00:00 2001 From: Alug Date: Fri, 15 Aug 2025 07:53:13 +0200 Subject: [PATCH 39/66] supress align and unkown pragma warnings in clang --- src/Makefile.d/versions.mk | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Makefile.d/versions.mk b/src/Makefile.d/versions.mk index 8485b0b16..d34070bb9 100644 --- a/src/Makefile.d/versions.mk +++ b/src/Makefile.d/versions.mk @@ -144,6 +144,10 @@ ifdef GCC81 WFLAGS+=-Wno-error=multistatement-macros endif +ifeq ($(CC),clang) + WFLAGS+= -Wno-unknown-pragmas -Wno-cast-align +endif + ifdef NONX86 ifdef X86_64 # yeah that SEEMS contradictory opts+=-march=nocona -- 2.54.0 From b5dfe74cfe0a2359c77a79f57fa6f6ed2ecffd9d Mon Sep 17 00:00:00 2001 From: Alug Date: Fri, 15 Aug 2025 07:59:00 +0200 Subject: [PATCH 40/66] add USECLANG compile flag to force building with clang --- src/Makefile | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/Makefile b/src/Makefile index 8b7d17cec..752579fdb 100644 --- a/src/Makefile +++ b/src/Makefile @@ -131,9 +131,19 @@ endif include Makefile.d/util.mk ifdef PREFIX +ifdef USECLANG +CC:=$(PREFIX)-clang +CXX:=$(PREFIX)-clang++ +else CC:=$(PREFIX)-gcc CXX:=$(PREFIX)-g++ endif +endif + +ifdef USECLANG +CC=clang +CXX=clang++ +endif OBJDUMP_OPTS?=--wide --source --line-numbers @@ -267,6 +277,8 @@ libs+=-fsanitize=address endif endif +ifeq ($(CC),clang) + LDFLAGS+= -fuse-ld=lld endif # debug_opts also get passed to windres -- 2.54.0 From c2767360020624dccd07ad8ba7890cf11efb8815 Mon Sep 17 00:00:00 2001 From: Indev Date: Fri, 15 Aug 2025 21:51:58 +0300 Subject: [PATCH 41/66] Add option to center text in chat (chatcentertext) --- src/d_netcmd.c | 1 + src/g_game.c | 2 ++ src/g_game.h | 2 +- src/hu_stuff.c | 2 +- src/m_menudefs.c | 19 ++++++++++--------- 5 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index d60d87ba6..adeca66f9 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -937,6 +937,7 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_consolechat); CV_RegisterVar(&cv_chatnotifications); CV_RegisterVar(&cv_chatbacktint); + CV_RegisterVar(&cv_chatcentertext); CV_RegisterVar(&cv_songcredits); CV_RegisterVar(&cv_showfreeplay); CV_RegisterVar(&cv_skinselectspin); diff --git a/src/g_game.c b/src/g_game.c index bba2a99ec..79b5bbdfa 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -310,6 +310,8 @@ consvar_t cv_chatbacktint = {"chatbacktint", "On", CV_SAVE, CV_OnOff, NULL, 0, N static CV_PossibleValue_t consolechat_cons_t[] = {{0, "Window"}, {1, "Console"}, {2, "Window (Hidden)"}, {0, NULL}}; consvar_t cv_consolechat = {"chatmode", "Window", CV_SAVE, consolechat_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_chatcentertext = {"chatcentertext", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; + // Pause game upon window losing focus consvar_t cv_pauseifunfocused = {"pauseifunfocused", "Yes", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; diff --git a/src/g_game.h b/src/g_game.h index 9d8b74144..43d9d14b2 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -49,7 +49,7 @@ extern tic_t timeinmap; // Ticker for time spent in level (used for levelcard di extern INT16 rw_maximums[NUM_WEAPONS]; // used in game menu -extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, cv_consolechat, cv_chatbacktint, cv_chatspamprotection/*, cv_compactscoreboard*/; +extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, cv_consolechat, cv_chatbacktint, cv_chatspamprotection, cv_chatcentertext/*, cv_compactscoreboard*/; extern consvar_t cv_songcredits; extern consvar_t cv_showfreeplay; extern consvar_t cv_growmusic, cv_supermusic; diff --git a/src/hu_stuff.c b/src/hu_stuff.c index de9e26040..062abd0d2 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1658,7 +1658,7 @@ static void HU_drawMiniChat(void) if (cv_chatbacktint.value) // on request of wolfy V_DrawFillConsoleMap(x + dx + 2, y+dy, charwidth, charheight, 239|V_SNAPTOBOTTOM|V_SNAPTOLEFT); - V_DrawChatCharacter(x + dx + 2, y+dy, msg[j++] |V_SNAPTOBOTTOM|V_SNAPTOLEFT|transflag, !cv_allcaps.value, colormap); + V_DrawChatCharacter(x + dx + 2, y+dy+cv_chatcentertext.value, msg[j++] |V_SNAPTOBOTTOM|V_SNAPTOLEFT|transflag, !cv_allcaps.value, colormap); } dx += charwidth; diff --git a/src/m_menudefs.c b/src/m_menudefs.c index a3be98ac2..0179d267a 100644 --- a/src/m_menudefs.c +++ b/src/m_menudefs.c @@ -1404,18 +1404,19 @@ static menuitem_t OP_ChatOptionsMenu[] = NULL, "Chat Box Width", &cv_chatwidth, 20}, {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Chat Box Height", &cv_chatheight, 30}, + {IT_STRING | IT_CVAR, NULL, "Center Text in Chat", &cv_chatcentertext, 40}, - {IT_STRING | IT_CVAR, NULL, "Chat Background Tint", &cv_chatbacktint, 45}, - {IT_STRING | IT_CVAR, NULL, "Message Fadeout Time", &cv_chattime, 55}, - {IT_STRING | IT_CVAR, NULL, "Spam Protection", &cv_chatspamprotection, 65}, - {IT_STRING | IT_CVAR, NULL, "Max Chat Messages", &cv_chatlogsize, 75}, + {IT_STRING | IT_CVAR, NULL, "Chat Background Tint", &cv_chatbacktint, 55}, + {IT_STRING | IT_CVAR, NULL, "Message Fadeout Time", &cv_chattime, 65}, + {IT_STRING | IT_CVAR, NULL, "Spam Protection", &cv_chatspamprotection, 75}, + {IT_STRING | IT_CVAR, NULL, "Max Chat Messages", &cv_chatlogsize, 85}, - {IT_STRING | IT_CVAR, NULL, "Local ping display", &cv_showping, 95}, // shows ping above the framerate if we want to. - {IT_STRING | IT_CVAR, NULL, "Ping display style", &cv_pingstyle, 105}, - {IT_STRING | IT_CVAR, NULL, "Ping measurement", &cv_pingmeasurement, 115}, - {IT_STRING | IT_CVAR, NULL, "Ping icon", &cv_pingicon, 125}, + {IT_STRING | IT_CVAR, NULL, "Local ping display", &cv_showping, 105}, // shows ping above the framerate if we want to. + {IT_STRING | IT_CVAR, NULL, "Ping display style", &cv_pingstyle, 115}, + {IT_STRING | IT_CVAR, NULL, "Ping measurement", &cv_pingmeasurement, 125}, + {IT_STRING | IT_CVAR, NULL, "Ping icon", &cv_pingicon, 135}, - {IT_STRING | IT_CVAR, NULL, "Show IP address in playerlist", &cv_shownodeip, 135}, + {IT_STRING | IT_CVAR, NULL, "Show IP address in playerlist", &cv_shownodeip, 145}, }; static const char* OP_ChatOptionsTooltips[] = -- 2.54.0 From 9549a204a5b59721e0b5fb0d432b1603f202a024 Mon Sep 17 00:00:00 2001 From: Indev Date: Fri, 15 Aug 2025 22:57:09 +0300 Subject: [PATCH 42/66] Add tooltip for centered chat text --- src/m_menudefs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/m_menudefs.c b/src/m_menudefs.c index 0179d267a..9f20b5f91 100644 --- a/src/m_menudefs.c +++ b/src/m_menudefs.c @@ -1424,6 +1424,7 @@ static const char* OP_ChatOptionsTooltips[] = "Chat mode used for in-game chat.", "Width of chat box.", "Height of chat box.", + "Center text in the chat message pop ups.", "Chatbox background.", "Fadeout time for new chat message.", "Spam protection for in-game chat.", -- 2.54.0 From a9068ee16263a65e20dd61ce9d5d530e30e8126b Mon Sep 17 00:00:00 2001 From: Alug Date: Sat, 16 Aug 2025 16:23:55 +0200 Subject: [PATCH 43/66] mark this with "noreturn" clang kept yelling for some reason --- src/cxxutil.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cxxutil.hpp b/src/cxxutil.hpp index 545d38dfd..591d7aa4d 100644 --- a/src/cxxutil.hpp +++ b/src/cxxutil.hpp @@ -61,7 +61,7 @@ struct SourceLocation { class IErrorAssertHandler { public: - static void handle(const SourceLocation& source_location, const char* expression) { + [[ noreturn ]] static void handle(const SourceLocation& source_location, const char* expression) { I_Error("Assertion failed at %s:%u: %s != true", source_location.file_name, source_location.line_number, -- 2.54.0 From 4117eb5b409eb2efa0a8d78aa8101133b7bc2892 Mon Sep 17 00:00:00 2001 From: Alug Date: Sat, 16 Aug 2025 16:24:58 +0200 Subject: [PATCH 44/66] fix Paranoia compile --- src/p_tick.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/p_tick.c b/src/p_tick.c index f383d1844..09912de59 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -16,6 +16,7 @@ #endif #include "doomstat.h" +#include "dehacked.h" #include "g_game.h" #include "g_input.h" #include "p_local.h" -- 2.54.0 From 294ce055cd38064fd5c7d19a8024b70f2610810c Mon Sep 17 00:00:00 2001 From: Alug Date: Sat, 16 Aug 2025 16:25:16 +0200 Subject: [PATCH 45/66] mark this with restrict --- src/r_main.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/r_main.h b/src/r_main.h index db3142548..3f815d083 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -108,7 +108,7 @@ FUNCINLINE static ATTRINLINE PUREFUNC INT32 R_PointOnSide(fixed_t x, fixed_t y, // This is not as accurate // SHOULD NOT BE USED FOR ANYTHING GAMEPLAY RELATED!! -FUNCINLINE static ATTRINLINE PUREFUNC INT32 R_PointOnSideFast(fixed_t x, fixed_t y, const node_t *node) +FUNCINLINE static ATTRINLINE PUREFUNC INT32 R_PointOnSideFast(fixed_t x, fixed_t y, const node_t* restrict node) { // use cross product to determine side quickly INT64 v = ((INT64)y - node->y) * node->dx - ((INT64)x - node->x) * node->dy; @@ -201,7 +201,7 @@ extern consvar_t cv_secbright; extern consvar_t cv_randomdirlight; -static inline INT32 R_GetSoftLightlevel(INT32 llevel) +FUNCINLINE static ATTRINLINE INT32 R_GetSoftLightlevel(INT32 llevel) { return CLAMP(llevel, cv_secbright.value, 255) >> LIGHTSEGSHIFT; } -- 2.54.0 From aca48d69cdc7d305ede3237a62e7d6ba44cfda39 Mon Sep 17 00:00:00 2001 From: Alug Date: Sat, 16 Aug 2025 16:26:39 +0200 Subject: [PATCH 46/66] style fixes --- src/d_main.c | 2 +- src/g_game.c | 4 ++-- src/m_random.c | 2 +- src/p_setup.c | 50 +++++++++++++++++++++++++------------------------- src/p_tick.c | 5 +++-- 5 files changed, 32 insertions(+), 31 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index add5b6f5a..f191a546c 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -933,7 +933,6 @@ void D_SRB2Loop(void) Discord_RunCallbacks(); } #endif - // Fully completed frame made. finishprecise = I_GetPreciseTime(); @@ -971,6 +970,7 @@ void D_SRB2Loop(void) I_SleepDuration(capbudget - elapsed); } } + // Capture the time once more to get the real delta time. finishprecise = I_GetPreciseTime(); deltasecs = (double)((INT64)(finishprecise - enterprecise)) / I_GetPrecisePrecision(); diff --git a/src/g_game.c b/src/g_game.c index 79b5bbdfa..21749d374 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1795,11 +1795,11 @@ void G_Ticker(boolean run) { for (i = 0; i < MAXPLAYERS; i++) // read/write demo and check turbo cheat { - cmd = &players[i].cmd; - if (!playeringame[i]) continue; + cmd = &players[i].cmd; + //@TODO all this throwdir stuff shouldn't be here! But it stays for now to maintain 1.0.4 compat... // Remove for 1.1! diff --git a/src/m_random.c b/src/m_random.c index cb8367b43..7b588bb6f 100644 --- a/src/m_random.c +++ b/src/m_random.c @@ -96,7 +96,7 @@ ATTRINLINE static fixed_t FUNCINLINE __internal_prng__(void) randomseed ^= randomseed >> 13; randomseed ^= randomseed >> 11; randomseed ^= randomseed << 21; - return ( (randomseed*36548569) >> 4) & (FRACUNIT-1); + return ((randomseed*36548569) >> 4) & (FRACUNIT-1); } /** Provides a random fixed point number. Distribution is uniform. diff --git a/src/p_setup.c b/src/p_setup.c index 05af8bfcb..51eb3a61b 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1747,33 +1747,33 @@ static void P_CreateBlockMap(void) // Now we simply iterate block-by-block until we reach the end block. for (curblockx = bxstart; curblockx <= bxend; curblockx++) - for (curblocky = bystart; curblocky <= byend; curblocky++) - { - size_t b = curblocky * bmapwidth + curblockx; - - if (b >= tot) - continue; - - if (!straight && !(LineInBlock((fixed_t)x, (fixed_t)y, (fixed_t)v2x, (fixed_t)v2y, (fixed_t)(curblockx << MAPBTOFRAC), (fixed_t)(curblocky << MAPBTOFRAC)))) - continue; - - // Increase size of allocated list if necessary - if (bmap[b].n >= bmap[b].nalloc) + for (curblocky = bystart; curblocky <= byend; curblocky++) { - // Graue 02-29-2004: make code more readable, don't realloc a null pointer - // (because it crashes for me, and because the comp.lang.c FAQ says so) - if (bmap[b].nalloc == 0) - bmap[b].nalloc = 8; - else - bmap[b].nalloc *= 2; - bmap[b].list = Z_Realloc(bmap[b].list, bmap[b].nalloc * sizeof (*bmap->list), PU_CACHE, &bmap[b].list); - if (!bmap[b].list) - I_Error("Out of Memory in P_CreateBlockMap"); - } + size_t b = curblocky * bmapwidth + curblockx; - // Add linedef to end of list - bmap[b].list[bmap[b].n++] = (INT32)i; - } + if (b >= tot) + continue; + + if (!straight && !(LineInBlock((fixed_t)x, (fixed_t)y, (fixed_t)v2x, (fixed_t)v2y, (fixed_t)(curblockx << MAPBTOFRAC), (fixed_t)(curblocky << MAPBTOFRAC)))) + continue; + + // Increase size of allocated list if necessary + if (bmap[b].n >= bmap[b].nalloc) + { + // Graue 02-29-2004: make code more readable, don't realloc a null pointer + // (because it crashes for me, and because the comp.lang.c FAQ says so) + if (bmap[b].nalloc == 0) + bmap[b].nalloc = 8; + else + bmap[b].nalloc *= 2; + bmap[b].list = Z_Realloc(bmap[b].list, bmap[b].nalloc * sizeof (*bmap->list), PU_CACHE, &bmap[b].list); + if (!bmap[b].list) + I_Error("Out of Memory in P_CreateBlockMap"); + } + + // Add linedef to end of list + bmap[b].list[bmap[b].n++] = (INT32)i; + } } // Compute the total size of the blockmap. diff --git a/src/p_tick.c b/src/p_tick.c index 09912de59..76379f5a0 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -635,7 +635,8 @@ static inline void P_ResetSpriteStuff(void) mo = (mobj_t *)th; - if (!mo || (mo->sprite == SPR_NULL) || (mo->flags2 & MF2_DONTDRAW) || (mo->type == MT_SHADOW)) + if (!mo || (mo->sprite == SPR_NULL) + || (mo->flags2 & MF2_DONTDRAW) || (mo->type == MT_SHADOW)) continue; mo->spritexscale = mo->realxscale; @@ -712,9 +713,9 @@ void P_Ticker(boolean run) if (playeringame[i]) G_WriteDemoTiccmd(&players[i].cmd, i); } + if (demo.playback) { - #ifdef DEMO_COMPAT_100 if (demo.version == 0x0001) { -- 2.54.0 From 44fe1567518bb52f4ab37ecd7017895aed7ae763 Mon Sep 17 00:00:00 2001 From: Alug Date: Sat, 16 Aug 2025 19:32:49 +0200 Subject: [PATCH 47/66] update comment for lightcontrast --- 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 51eb3a61b..f36ab9b44 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -442,7 +442,7 @@ void P_UpdateSegLightOffset(seg_t *li) extralight = -contrastFixed + FixedMul(light, contrastFixed * 2); - // Between -2 and 2 for software, -8 and 8 for hardware + // Between -1 and 1 for software, -8 and 8 for hardware li->lightOffset = FixedFloor((extralight / 8) + (FRACUNIT / 2)) / FRACUNIT; #ifdef HWRENDER li->hwLightOffset = FixedFloor(extralight + (FRACUNIT / 2)) / FRACUNIT; -- 2.54.0 From 02ffceb300e421499c28399efc90e58c96785c18 Mon Sep 17 00:00:00 2001 From: Alug Date: Sat, 16 Aug 2025 20:21:16 +0200 Subject: [PATCH 48/66] fix rotating polyobject interpolation --- src/r_fps.c | 20 ++++++++++++++++++++ src/r_fps.h | 1 + 2 files changed, 21 insertions(+) diff --git a/src/r_fps.c b/src/r_fps.c index f5d02dda1..710210939 100644 --- a/src/r_fps.c +++ b/src/r_fps.c @@ -492,6 +492,7 @@ void R_CreateInterpolator_Polyobj(thinker_t *thinker, polyobj_t *polyobj) interp->polyobj.oldcx = interp->polyobj.bakcx = polyobj->centerPt.x; interp->polyobj.oldcy = interp->polyobj.bakcy = polyobj->centerPt.y; + interp->polyobj.oldangle = interp->polyobj.bakangle = polyobj->angle; } /*void R_CreateInterpolator_DynSlope(thinker_t *thinker, pslope_t *slope) @@ -515,6 +516,15 @@ void R_InitializeLevelInterpolators(void) levelinterpolators = NULL; } +static void RecalculatePolyobjectSegAngles(polyobj_t *polyobj) +{ + for (size_t i = 0; i < polyobj->segCount; i++) + { + seg_t *seg = polyobj->segs[i]; + seg->angle = R_PointToAngle2(seg->v1->x, seg->v1->y, seg->v2->x, seg->v2->y); + } +} + static void UpdateLevelInterpolatorState(levelinterpolator_t *interp) { size_t i; @@ -545,10 +555,14 @@ static void UpdateLevelInterpolatorState(levelinterpolator_t *interp) interp->polyobj.bakvertices[i * 2 ] = interp->polyobj.polyobj->vertices[i]->x; interp->polyobj.bakvertices[i * 2 + 1] = interp->polyobj.polyobj->vertices[i]->y; } + + RecalculatePolyobjectSegAngles(interp->polyobj.polyobj); interp->polyobj.oldcx = interp->polyobj.bakcx; interp->polyobj.oldcy = interp->polyobj.bakcy; + interp->polyobj.oldangle = interp->polyobj.bakangle; interp->polyobj.bakcx = interp->polyobj.polyobj->centerPt.x; interp->polyobj.bakcy = interp->polyobj.polyobj->centerPt.y; + interp->polyobj.bakangle = interp->polyobj.polyobj->angle; break; /*case LVLINTERP_DynSlope: FV3_Copy(&interp->dynslope.oldo, &interp->dynslope.bako); @@ -630,8 +644,11 @@ void R_ApplyLevelInterpolators(fixed_t frac) interp->polyobj.polyobj->vertices[ii]->x = R_LerpFixed(interp->polyobj.oldvertices[ii * 2 ], interp->polyobj.bakvertices[ii * 2 ], frac); interp->polyobj.polyobj->vertices[ii]->y = R_LerpFixed(interp->polyobj.oldvertices[ii * 2 + 1], interp->polyobj.bakvertices[ii * 2 + 1], frac); } + + RecalculatePolyobjectSegAngles(interp->polyobj.polyobj); interp->polyobj.polyobj->centerPt.x = R_LerpFixed(interp->polyobj.oldcx, interp->polyobj.bakcx, frac); interp->polyobj.polyobj->centerPt.y = R_LerpFixed(interp->polyobj.oldcy, interp->polyobj.bakcy, frac); + interp->polyobj.polyobj->angle = R_LerpAngle(interp->polyobj.oldangle, interp->polyobj.bakangle, frac); break; /*case LVLINTERP_DynSlope: R_LerpVector3(&interp->dynslope.oldo, &interp->dynslope.bako, frac, &interp->dynslope.slope->o); @@ -685,8 +702,11 @@ void R_RestoreLevelInterpolators(void) interp->polyobj.polyobj->vertices[ii]->x = interp->polyobj.bakvertices[ii * 2 ]; interp->polyobj.polyobj->vertices[ii]->y = interp->polyobj.bakvertices[ii * 2 + 1]; } + + RecalculatePolyobjectSegAngles(interp->polyobj.polyobj); interp->polyobj.polyobj->centerPt.x = interp->polyobj.bakcx; interp->polyobj.polyobj->centerPt.y = interp->polyobj.bakcy; + interp->polyobj.polyobj->angle = interp->polyobj.bakangle; break; /*case LVLINTERP_DynSlope: FV3_Copy(&interp->dynslope.slope->o, &interp->dynslope.bako); diff --git a/src/r_fps.h b/src/r_fps.h index 870fa70f1..cbcde0db8 100644 --- a/src/r_fps.h +++ b/src/r_fps.h @@ -119,6 +119,7 @@ typedef struct levelinterpolator_s { fixed_t *bakvertices; size_t vertices_size; fixed_t oldcx, oldcy, bakcx, bakcy; + angle_t oldangle, bakangle; } polyobj; struct { pslope_t *slope; -- 2.54.0 From 8d1ef1721f4886aca83350fceb40a25499189cdd Mon Sep 17 00:00:00 2001 From: Alug Date: Sat, 16 Aug 2025 22:00:58 +0200 Subject: [PATCH 49/66] =?UTF-8?q?port=20srb2classic=C2=B4s=20sdl=20blittin?= =?UTF-8?q?g=20stuff=20for=20software?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit all credits to hanicef mostly from https://codeberg.org/srb2classic/srb2classic/commit/a1fa0b89dbf75ef8be17c9ca5c728cc9c1848582 and https://codeberg.org/srb2classic/srb2classic/commit/a1cf54e66ad1cb66af99056bc940fc68dce24224 boosts my fps around 20-25 fps --- src/sdl/i_video.c | 95 +++++++++++------------------------------------ src/v_video.c | 38 ++++++++++++++++--- src/v_video.h | 12 ++++++ 3 files changed, 67 insertions(+), 78 deletions(-) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 798be9593..d95d0afe2 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -164,13 +164,8 @@ static INT32 mousemovex = 0, mousemovey = 0; // SDL vars static SDL_Surface *vidSurface = NULL; -static SDL_Surface *bufSurface = NULL; static SDL_Surface *icoSurface = NULL; -static SDL_Color localPalette[256]; -#if 0 -static SDL_Rect **modeList = NULL; -static Uint8 BitsPerPixel = 16; -#endif +static UINT32 localPalette[256]; Uint16 realwidth = BASEVIDWIDTH; Uint16 realheight = BASEVIDHEIGHT; static SDL_bool mousegrabok = SDL_TRUE; @@ -219,7 +214,6 @@ static INT32 windowedModes[MAXWINMODES][2] = static INT32 custom_width = 0; static INT32 custom_height = 0; -static void Impl_VideoSetupSDLBuffer(void); static void Impl_VideoSetupBuffer(void); static SDL_bool Impl_CreateWindow(SDL_bool fullscreen); static void Impl_SetWindowIcon(void); @@ -514,7 +508,6 @@ static void VID_Command_Info_f (void) if (!M_CheckParm("-noblit")) videoblitok = SDL_TRUE; - SurfaceInfo(bufSurface, M_GetText("Current Engine Mode")); SurfaceInfo(vidSurface, M_GetText("Current Video Mode")); } @@ -1341,7 +1334,7 @@ static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen) { static SDL_bool wasfullscreen = SDL_FALSE; Uint32 rmask, gmask, bmask, amask; - int bpp = 16; + int bpp; int sw_texture_format = SDL_PIXELFORMAT_ABGR8888; realwidth = vid.width; @@ -1410,16 +1403,6 @@ static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen) SDL_DestroyTexture(texture); } - if (!usesdl2soft) - { - sw_texture_format = SDL_PIXELFORMAT_RGB565; - } - else - { - bpp = 32; - sw_texture_format = SDL_PIXELFORMAT_RGBA8888; - } - texture = SDL_CreateTexture(renderer, sw_texture_format, SDL_TEXTUREACCESS_STREAMING, width, height); // Set up SW surface @@ -1494,19 +1477,18 @@ void I_FinishUpdate(void) if (rendermode == render_soft && vid.screens[0]) { - if (!bufSurface) //Double-Check - { - Impl_VideoSetupSDLBuffer(); - } - if (bufSurface) - { - SDL_BlitSurface(bufSurface, &src_rect, vidSurface, &src_rect); - // Fury -- there's no way around UpdateTexture, the GL backend uses it anyway - SDL_LockSurface(vidSurface); - SDL_UpdateTexture(texture, &src_rect, vidSurface->pixels, vidSurface->pitch); - SDL_UnlockSurface(vidSurface); - } + SDL_LockSurface(vidSurface); + // copy pixels ourselves to the video surface (prevents a crash in libsdl) + UINT32 *dst = vidSurface->pixels; + UINT8 *src = vid.screens[0]; + for (int32_t i = 0; i < vid.width * vid.height; i++) + *dst++ = localPalette[*src++]; + SDL_UnlockSurface(vidSurface); + // Fury -- there's no way around UpdateTexture, the GL backend uses it anyway + SDL_LockSurface(vidSurface); + SDL_UpdateTexture(texture, &src_rect, vidSurface->pixels, vidSurface->pitch); + SDL_UnlockSurface(vidSurface); SDL_RenderClear(renderer); SDL_RenderCopy(renderer, texture, &src_rect, NULL); @@ -1553,14 +1535,11 @@ void I_SetPalette(RGBA_t *palette) for (i = 0; i < 256; i++) { - localPalette[i].r = palette[i].s.red; - localPalette[i].g = palette[i].s.green; - localPalette[i].b = palette[i].s.blue; + localPalette[i] = 0xff000000; + localPalette[i] |= palette[i].s.red << 0; + localPalette[i] |= palette[i].s.green << 8; + localPalette[i] |= palette[i].s.blue << 16; } - - //if (vidSurface) SDL_SetPaletteColors(vidSurface->format->palette, localPalette, 0, 256); - // Fury -- SDL2 vidSurface is a 32-bit surface buffer copied to the texture. It's not palletized, like bufSurface. - if (bufSurface) SDL_SetPaletteColors(bufSurface->format->palette, localPalette, 0, 256); } // return number of fullscreen + X11 modes @@ -1682,15 +1661,6 @@ INT32 VID_SetMode(INT32 modeNum) SDLSetMode(vid.width, vid.height, USE_FULLSCREEN); Impl_VideoSetupBuffer(); - if (rendermode == render_soft) - { - if (bufSurface) - { - SDL_FreeSurface(bufSurface); - bufSurface = NULL; - } - } - src_rect.w = vid.width; src_rect.h = vid.height; @@ -1818,36 +1788,19 @@ static void Impl_SetWindowIcon(void) SDL_SetWindowIcon(window, icoSurface); } -static void Impl_VideoSetupSDLBuffer(void) -{ - if (bufSurface != NULL) - { - SDL_FreeSurface(bufSurface); - bufSurface = NULL; - } - // Set up the SDL palletized buffer (copied to vidbuffer before being rendered to texture) - bufSurface = SDL_CreateRGBSurfaceFrom(vid.screens[0], vid.width, vid.height, 8, - (int)vid.rowbytes, 0x00000000, 0x00000000, 0x00000000, 0x00000000); // 256 mode - - if (bufSurface) - { - SDL_SetPaletteColors(bufSurface->format->palette, localPalette, 0, 256); - } - else - { - I_Error("%s", M_GetText("No system memory for SDL buffer surface\n")); - } -} - static void Impl_VideoSetupBuffer(void) { // Set up game's software render buffer + size_t size; + vid.rowbytes = vid.width; if (vid.buffer) free(vid.buffer); - vid.buffer = calloc(vid.rowbytes*vid.height, NUMSCREENS); + size = vid.rowbytes*vid.height * NUMSCREENS; + + vid.buffer = calloc(size, NUMSCREENS); if (!vid.buffer) { @@ -2108,10 +2061,6 @@ void I_ShutdownGraphics(void) if (vid.buffer) free(vid.buffer); vid.buffer = NULL; - - if (bufSurface) - SDL_FreeSurface(bufSurface); - bufSurface = NULL; } I_OutputMsg("I_ShutdownGraphics(): "); diff --git a/src/v_video.c b/src/v_video.c index 247272dcb..e9404d391 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -615,8 +615,21 @@ static void CV_constextsize_OnChange(void) void VID_BlitLinearScreen(const UINT8 *srcptr, UINT8 *destptr, INT32 width, INT32 height, size_t srcrowbytes, size_t destrowbytes) { - if ((srcrowbytes == destrowbytes) && (srcrowbytes == (size_t)width)) - M_Memcpy(destptr, srcptr, srcrowbytes * height); + if (srcrowbytes == destrowbytes) + { + size_t i = srcrowbytes * height; +#if defined(__SSE__) + while (i >= 16) + { + // TODO: find where the buffer is misaligned at times and align it + _mm_storeu_ps((float *)destptr, _mm_loadu_ps((const float *)srcptr)); + srcptr += 16; + destptr += 16; + i -= 16; + } +#endif + M_Memcpy(destptr, srcptr, i); + } else { while (height--) @@ -3775,17 +3788,32 @@ UINT8 GetColorLUTDirect(colorlookup_t *lut, UINT8 r, UINT8 g, UINT8 b) void V_Init(void) { INT32 i; - UINT8 *base = vid.buffer; const INT32 screensize = vid.rowbytes * vid.height; for (i = 0; i < NUMSCREENS; i++) + { +#if defined(__SSE__) + aligned_free(vid.screens[i]); +#else + free(vid.screens[i]); +#endif vid.screens[i] = NULL; + } // start address of NUMSCREENS * width*height vidbuffers - if (base) + if (screensize > 0) { for (i = 0; i < NUMSCREENS; i++) - vid.screens[i] = base + i*screensize; + { + // we need to allocate these relative to their cpu restrictions to not trigger segfaults + // TODO: add support for sve and neon +#if defined(__SSE__) + vid.screens[i] = aligned_alloc(128, screensize); +#else + vid.screens[i] = malloc(screensize); +#endif + memset(vid.screens[i], 0, screensize); + } } #ifdef DEBUG diff --git a/src/v_video.h b/src/v_video.h index d5a4adf5e..1032082be 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -23,6 +23,18 @@ extern "C" { #include "r_defs.h" #include "r_main.h" +#if defined(__SSE__) +#ifdef _WIN32 +#include +#define aligned_alloc(align, size) _aligned_malloc(size, align) +#define aligned_free(ptr) _aligned_free(ptr) +#else +#define aligned_free(ptr) free(ptr) +#endif + +#include +#endif + // // VIDEO // -- 2.54.0 From 4fcb41f6596c08084cb482ab4ad7d42910b2f57e Mon Sep 17 00:00:00 2001 From: Alug Date: Sun, 17 Aug 2025 18:18:53 +0200 Subject: [PATCH 50/66] mark stuff for blitting loop as const and with register gives another 5-7fps or so for me --- src/sdl/i_video.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index d95d0afe2..ad92d1c27 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1477,12 +1477,12 @@ void I_FinishUpdate(void) if (rendermode == render_soft && vid.screens[0]) { - SDL_LockSurface(vidSurface); // copy pixels ourselves to the video surface (prevents a crash in libsdl) - UINT32 *dst = vidSurface->pixels; - UINT8 *src = vid.screens[0]; - for (int32_t i = 0; i < vid.width * vid.height; i++) + UINT32 *restrict dst = vidSurface->pixels; + const UINT8 *restrict src = vid.screens[0]; + const INT32 count = vid.width * vid.height; + for (INT32 i = 0; i < count; i++) *dst++ = localPalette[*src++]; SDL_UnlockSurface(vidSurface); // Fury -- there's no way around UpdateTexture, the GL backend uses it anyway -- 2.54.0 From 684a43a95c863e09b94830b8ae587b314197d6ae Mon Sep 17 00:00:00 2001 From: Alug Date: Mon, 18 Aug 2025 16:35:28 +0200 Subject: [PATCH 51/66] fix software extra 3d floors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit lmao was a copy paste oopsie from ages ago shoutout to phoenix´s new map making me find this --- src/r_plane.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/r_plane.cpp b/src/r_plane.cpp index dd4813794..94fbcae4b 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -1072,15 +1072,15 @@ void R_DrawSinglePlane(drawspandata_t* ds, visplane_t *pl, boolean allow_paralle { if ((pl->ffloor->flags & FF_CUTEXTRA) && (rover->flags & FF_EXTRA)) { - if (!(rover->flags & FF_EXTRA)) - continue; - - // The plane is from an extra 3D floor... Check the flags so - // there are no undesired cuts. - if (((pl->ffloor->flags & (FF_FOG|FF_SWIMMABLE)) == (rover->flags & (FF_FOG|FF_SWIMMABLE))) - && pl->height < *rover->topheight - && pl->height > *rover->bottomheight) - return; + if (pl->ffloor->flags & FF_EXTRA) + { + // The plane is from an extra 3D floor... Check the flags so + // there are no undesired cuts. + if (((pl->ffloor->flags & (FF_FOG|FF_SWIMMABLE)) == (rover->flags & (FF_FOG|FF_SWIMMABLE))) + && pl->height < *rover->topheight + && pl->height > *rover->bottomheight) + return; + } } } -- 2.54.0 From 145eecf8a40e9b573dd9a9aa60c3b41886556106 Mon Sep 17 00:00:00 2001 From: Alug Date: Tue, 19 Aug 2025 11:30:28 +0200 Subject: [PATCH 52/66] move sprite reset stuff into R_ResetMobjInterpolationState this also gets called at the start of the tic and sets a bunch of rendering crap eitherways so we can save another thinker loop and a bunch of checks with this bit of perf gain, 3-4fps on that awful hadal trench timedemo --- src/p_mobj.c | 6 ++++-- src/p_tick.c | 34 ---------------------------------- src/r_fps.c | 13 +++++++++++++ 3 files changed, 17 insertions(+), 36 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index ff0a35949..ada4dbcdb 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9854,7 +9854,6 @@ mobj_t *P_SpawnShadowMobj(mobj_t * caster) mobj->radius = info->radius; mobj->height = info->height; mobj->flags = info->flags; - mobj->blendmode = AST_TRANSLUCENT; mobj->health = info->spawnhealth; @@ -9890,7 +9889,10 @@ mobj_t *P_SpawnShadowMobj(mobj_t * caster) } // Sprite rendering - mobj->spritexscale = mobj->spriteyscale = mobj->scale; + mobj->blendmode = AST_TRANSLUCENT; + mobj->realxscale = mobj->realyscale = mobj->scale; + mobj->spritexscale = mobj->realxscale; + mobj->spriteyscale = mobj->realyscale; // set subsector and/or block links P_SetThingPosition(mobj); diff --git a/src/p_tick.c b/src/p_tick.c index 76379f5a0..752e60794 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -614,38 +614,6 @@ static void P_RunQuakes(void) --quake.time; } -// Reset our Sprite scales and offsets -// at the start of our tic -// this is just to make things simpler -// as we dont have to reset it ourselves after use -// done at the start so lua can still overwrite everything -static inline void P_ResetSpriteStuff(void) -{ - thinker_t *th; - - if (rendermode == render_none) - return; - - for (th = thinkercap.next; th != &thinkercap; th = th->next) - { - mobj_t *mo; - - if (th->function != (actionf_p1)P_MobjThinker) // not a mobj - continue; - - mo = (mobj_t *)th; - - if (!mo || (mo->sprite == SPR_NULL) - || (mo->flags2 & MF2_DONTDRAW) || (mo->type == MT_SHADOW)) - continue; - - mo->spritexscale = mo->realxscale; - mo->spriteyscale = mo->realyscale; - mo->spritexoffset = mo->realxoffset; - mo->spriteyoffset = mo->realyoffset; - } -} - // // P_Ticker // @@ -747,8 +715,6 @@ void P_Ticker(boolean run) ps_lua_mobjhooks.value.i = 0; ps_checkposition_calls.value.i = 0; - P_ResetSpriteStuff(); - PS_START_TIMING(ps_lua_prethinkframe_time); LUA_HookPreThinkFrame(); PS_STOP_TIMING(ps_lua_prethinkframe_time); diff --git a/src/r_fps.c b/src/r_fps.c index 710210939..6bd385066 100644 --- a/src/r_fps.c +++ b/src/r_fps.c @@ -860,6 +860,19 @@ void R_ResetMobjInterpolationState(mobj_t *mobj) mobj->player->old_frameangle = mobj->player->frameangle; } + // Reset our Sprite scales and offsets + // at the start of the tic + // this is just to make things simpler + // as we dont have to reset it ourselves after use + // done at the start so lua can still overwrite everything + + // technically not interpolation related + // but this saves us another thinkerloop and multiple checks lel + mobj->spritexscale = mobj->realxscale; + mobj->spriteyscale = mobj->realyscale; + mobj->spritexoffset = mobj->realxoffset; + mobj->spriteyoffset = mobj->realyoffset; + mobj->resetinterp = false; } -- 2.54.0 From 3af0009453787e78d755d69fde3385bf5a571e48 Mon Sep 17 00:00:00 2001 From: Indev Date: Wed, 20 Aug 2025 16:18:28 +0300 Subject: [PATCH 53/66] Fix off-by-one in M_FindFirstMap --- src/m_menu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index 02a1bee87..959f0b82a 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -7046,7 +7046,7 @@ static INT32 M_FindFirstMap(INT32 gtype) { INT32 i; - if (mapheaderinfo[gamemap] && (mapheaderinfo[gamemap]->typeoflevel & gtype)) + if (mapheaderinfo[gamemap-1] && (mapheaderinfo[gamemap-1]->typeoflevel & gtype)) return gamemap; for (i = 0; i < NUMMAPS; i++) -- 2.54.0 From 601754366685f8d02f00143fa76ad9379b0f5f7d Mon Sep 17 00:00:00 2001 From: Alug Date: Fri, 22 Aug 2025 17:41:30 +0200 Subject: [PATCH 54/66] dont try to make glpatch from nothing --- 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 5c774aa60..ec3b1f3aa 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1819,7 +1819,7 @@ void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag) #ifdef HWRENDER // Software-only compile cache the data without conversion - if (rendermode == render_opengl) + if (patch != NULL && rendermode == render_opengl) Patch_CreateGL(patch); #endif -- 2.54.0 From 7e5acd72c129f4de0b18d17a04ded44127abdbf7 Mon Sep 17 00:00:00 2001 From: Indev Date: Thu, 28 Aug 2025 15:37:03 +0300 Subject: [PATCH 55/66] Make replay search textbox fit on all resolutions --- src/m_menu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 959f0b82a..ca9f6e175 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3752,7 +3752,7 @@ I_mutex replayquerymutex; #endif/*HAVE_THREADS*/ -#define MAXREPLAYQUERY 40 +#define MAXREPLAYQUERY 37 static char replayqueryinput_buffer[MAXREPLAYQUERY+1]; // The input typed static textinput_t replayqueryinput; @@ -4454,7 +4454,7 @@ static void M_DrawReplayHut(void) DrawReplayHutReplayInfo(); } - x -= 40; + x = 4; // Draw search query M_DrawTextBoxFlags(x, 200 - 22, MAXREPLAYQUERY, 1, V_SNAPTOBOTTOM); -- 2.54.0 From 94d01d1ee9864f52d525a0c51b7ca538a8473ab3 Mon Sep 17 00:00:00 2001 From: Alug Date: Sat, 30 Aug 2025 14:38:55 +0200 Subject: [PATCH 56/66] check clientcfg packet length to skip potential garbage data dont think this ever broke, but better safe than sorry --- src/d_clisrv.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 7aa2c77a0..f8bf137f9 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1535,12 +1535,12 @@ static boolean CL_SendJoin(void) netbuffer->u.clientcfg.version = VERSION; netbuffer->u.clientcfg.subversion = SUBVERSION; strncpy(netbuffer->u.clientcfg.application, SRB2APPLICATION, - sizeof netbuffer->u.clientcfg.application); + sizeof(netbuffer->u.clientcfg.application)); #ifdef SATURNJOIN netbuffer->u.clientcfg.issaturn = ISSATURN; #endif - return HSendPacket(servernode, false, 0, sizeof (clientconfig_pak)); + return HSendPacket(servernode, false, 0, sizeof(clientconfig_pak)); } static void SV_SendServerInfo(INT32 node, tic_t servertime) @@ -4706,6 +4706,10 @@ static void HandleConnect(SINT8 node) if (playernode[i] != UINT8_MAX) // We use this to count players because it is affected by SV_AddWaitingPlayers when more than one client joins on the same tic, unlike playeringame and D_NumPlayers. UINT8_MAX denotes no node for that player connectedplayers++; +#ifdef SATURNJOIN + const boolean issaturn = (((doomcom->datalength-BASEPACKETSIZE) == sizeof(clientconfig_pak)) && netbuffer->u.clientcfg.issaturn == ISSATURN); // Check the packet lenght to skip potential garbo data! +#endif + if (bannednode && bannednode[node].banid != SIZE_MAX) { const char *reason = NULL; @@ -4759,7 +4763,7 @@ static void HandleConnect(SINT8 node) SV_SendRefuse(node, va(M_GetText("Different SRB2Kart versions cannot\nplay a netgame!\n(server version %d.%d)"), VERSION, SUBVERSION)); } #ifdef SATURNJOIN - else if ((!cv_allownewplayer.value && node && netbuffer->u.clientcfg.issaturn != ISSATURN) || (!cv_allownewsaturnplayer.value && node && netbuffer->u.clientcfg.issaturn == ISSATURN)) + else if (((!cv_allownewplayer.value && !issaturn) || (!cv_allownewsaturnplayer.value && issaturn)) && node) #else else if (!cv_allownewplayer.value && node) #endif @@ -4787,16 +4791,15 @@ static void HandleConnect(SINT8 node) #ifndef NONET boolean newnode = false; #endif - // client authorised to join nodewaiting[node] = (UINT8)(netbuffer->u.clientcfg.localplayers - playerpernode[node]); + if (!nodeingame[node]) { gamestate_t backupstate = gamestate; #ifndef NONET newnode = true; #endif - SV_AddNode(node); /// \note Wait what??? @@ -4818,12 +4821,14 @@ static void HandleConnect(SINT8 node) /// \todo fix this !!! return; // restart the while } + SV_SendServerInfo(node, 0); // Dunno if 0 time is good idea //if (gamestate != GS_LEVEL) // GS_INTERMISSION, etc? // SV_SendPlayerConfigs(node); // send bare minimum player info G_SetGamestate(backupstate); DEBFILE("new node joined\n"); } + #ifdef JOININGAME if (nodewaiting[node]) { @@ -4832,6 +4837,7 @@ static void HandleConnect(SINT8 node) SV_SendSaveGame(node, false); // send a complete game state DEBFILE("send savegame\n"); } + SV_AddWaitingPlayers(); } #else @@ -5566,7 +5572,6 @@ static void PT_TextCmd(INT32 netconsole, SINT8 node) static void PT_ClientQuit(INT32 netconsole, SINT8 node) { - if (client) return; @@ -6982,6 +6987,7 @@ void NetUpdate(void) #endif CON_Ticker(); } + SV_FileSendTicker(); } -- 2.54.0 From 015d9208e38c70f42e72766c7d0f933b03525ae8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Mon, 1 Sep 2025 17:38:48 +0200 Subject: [PATCH 57/66] Refactor software blitting logic --- assets/LICENSE-3RD-PARTY.txt | 18 +++++++++ src/sdl/i_video.c | 78 +++++++----------------------------- 2 files changed, 33 insertions(+), 63 deletions(-) diff --git a/assets/LICENSE-3RD-PARTY.txt b/assets/LICENSE-3RD-PARTY.txt index 42ea20e96..1897c4e08 100644 --- a/assets/LICENSE-3RD-PARTY.txt +++ b/assets/LICENSE-3RD-PARTY.txt @@ -30,6 +30,24 @@ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-------------------------------------------------------------------------------- + 0-Clause BSD License + applies to: + - qs22k + Copyright (c) 2022, Raymond Gardner +-------------------------------------------------------------------------------- + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + -------------------------------------------------------------------------------- curl License applies to: diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index ad92d1c27..8e19b33ac 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -163,7 +163,6 @@ static INT32 firstEntry = 0; static INT32 mousemovex = 0, mousemovey = 0; // SDL vars -static SDL_Surface *vidSurface = NULL; static SDL_Surface *icoSurface = NULL; static UINT32 localPalette[256]; Uint16 realwidth = BASEVIDWIDTH; @@ -171,7 +170,6 @@ Uint16 realheight = BASEVIDHEIGHT; static SDL_bool mousegrabok = SDL_TRUE; static SDL_bool wrapmouseok = SDL_FALSE; #define HalfWarpMouse(x,y) if (wrapmouseok) SDL_WarpMouseInWindow(window, (Uint16)(x/2),(Uint16)(y/2)) -static SDL_bool videoblitok = SDL_FALSE; static SDL_bool exposevideo = SDL_FALSE; static SDL_bool usesdl2soft = SDL_FALSE; static SDL_bool borderlesswindow = SDL_FALSE; @@ -479,38 +477,6 @@ static void VID_Command_NumModes_f (void) CONS_Printf(M_GetText("%d video mode(s) available(s)\n"), VID_NumModes()); } -// SDL2 doesn't have SDL_GetVideoSurface or a lot of the SDL_Surface flags that SDL 1.2 had -static void SurfaceInfo(const SDL_Surface *infoSurface, const char *SurfaceText) -{ - INT32 vfBPP; - - if (!infoSurface) - return; - - if (!SurfaceText) - SurfaceText = M_GetText("Unknown Surface"); - - vfBPP = infoSurface->format?infoSurface->format->BitsPerPixel:0; - - CONS_Printf("\x82" "%s\n", SurfaceText); - CONS_Printf(M_GetText(" %ix%i at %i bit color\n"), infoSurface->w, infoSurface->h, vfBPP); - - if (infoSurface->flags&SDL_PREALLOC) - CONS_Printf("%s", M_GetText(" Uses preallocated memory\n")); - else - CONS_Printf("%s", M_GetText(" Stored in system memory\n")); - if (infoSurface->flags&SDL_RLEACCEL) - CONS_Printf("%s", M_GetText(" Colorkey RLE acceleration blit\n")); -} - -static void VID_Command_Info_f (void) -{ - if (!M_CheckParm("-noblit")) - videoblitok = SDL_TRUE; - - SurfaceInfo(vidSurface, M_GetText("Current Video Mode")); -} - static void VID_Command_ModeList_f(void) { // List windowed modes @@ -1333,8 +1299,6 @@ void I_OsPolling(void) static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen) { static SDL_bool wasfullscreen = SDL_FALSE; - Uint32 rmask, gmask, bmask, amask; - int bpp; int sw_texture_format = SDL_PIXELFORMAT_ABGR8888; realwidth = vid.width; @@ -1405,20 +1369,11 @@ static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen) texture = SDL_CreateTexture(renderer, sw_texture_format, SDL_TEXTUREACCESS_STREAMING, width, height); - // Set up SW surface - if (vidSurface != NULL) - { - SDL_FreeSurface(vidSurface); - } - if (vid.buffer) { free(vid.buffer); vid.buffer = NULL; } - - SDL_PixelFormatEnumToMasks(sw_texture_format, &bpp, &rmask, &gmask, &bmask, &amask); - vidSurface = SDL_CreateRGBSurface(0, width, height, bpp, rmask, gmask, bmask, amask); } } @@ -1477,18 +1432,21 @@ void I_FinishUpdate(void) if (rendermode == render_soft && vid.screens[0]) { - SDL_LockSurface(vidSurface); - // copy pixels ourselves to the video surface (prevents a crash in libsdl) - UINT32 *restrict dst = vidSurface->pixels; - const UINT8 *restrict src = vid.screens[0]; - const INT32 count = vid.width * vid.height; - for (INT32 i = 0; i < count; i++) - *dst++ = localPalette[*src++]; - SDL_UnlockSurface(vidSurface); - // Fury -- there's no way around UpdateTexture, the GL backend uses it anyway - SDL_LockSurface(vidSurface); - SDL_UpdateTexture(texture, &src_rect, vidSurface->pixels, vidSurface->pitch); - SDL_UnlockSurface(vidSurface); + void *pixels; + int pitch; + SDL_LockTexture(texture, NULL, &pixels, &pitch); + int step = pitch / 4 - vid.width; + UINT32 *restrict dst = pixels; + UINT8 *restrict src = vid.screens[0]; + UINT32 *restrict palette = localPalette; + for (INT32 y = 0; y < vid.height; y++) + { + UINT8 *restrict end = src + vid.width; + do *dst++ = palette[*src++]; + while (src < end); + dst += step; + } + SDL_UnlockTexture(texture); SDL_RenderClear(renderer); SDL_RenderCopy(renderer, texture, &src_rect, NULL); @@ -1827,7 +1785,6 @@ void I_StartupGraphics(void) return; COM_AddCommand ("vid_nummodes", VID_Command_NumModes_f); - COM_AddCommand ("vid_info", VID_Command_Info_f); COM_AddCommand ("vid_modelist", VID_Command_ModeList_f); COM_AddCommand ("vid_mode", VID_Command_Mode_f); CV_RegisterVar (&cv_vidwait); @@ -2029,7 +1986,6 @@ void I_StartupGraphics(void) realwidth = (Uint16)vid.width; realheight = (Uint16)vid.height; - VID_Command_Info_f(); SDLdoUngrabMouse(); SDL_RaiseWindow(window); @@ -2054,10 +2010,6 @@ void I_ShutdownGraphics(void) if (oldrendermode == render_soft) { - if (vidSurface) - SDL_FreeSurface(vidSurface); - vidSurface = NULL; - if (vid.buffer) free(vid.buffer); vid.buffer = NULL; -- 2.54.0 From 6af09bd21509a3223c4cf3a47b053f9d2b7f0730 Mon Sep 17 00:00:00 2001 From: Indev Date: Mon, 1 Sep 2025 19:56:42 +0300 Subject: [PATCH 58/66] Add offset for small nametags in opengl without shearing enabled --- src/k_hud.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/k_hud.c b/src/k_hud.c index 05bce653c..9a78a23a9 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -3074,6 +3074,10 @@ static void K_drawNameTags(void) else flipped = players[i].mo->eflags & MFE_VERTICALFLIP; + // Needs extra offset. Not perfect but this will do for now + if (rendermode == render_opengl && !cv_glshearing.value && cv_smallnametags.value) + namey -= dup*6; + if (cv_smallnametags.value || !nametaggfx) { if (flipped) -- 2.54.0 From 6adf39b460e59574c23311575c9e8660905b409e Mon Sep 17 00:00:00 2001 From: Indev Date: Tue, 2 Sep 2025 23:01:07 +0300 Subject: [PATCH 59/66] Don't check for opengl in NOHW/DEDICATED builds --- src/k_hud.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/k_hud.c b/src/k_hud.c index 9a78a23a9..56843ca25 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -3074,9 +3074,11 @@ static void K_drawNameTags(void) else flipped = players[i].mo->eflags & MFE_VERTICALFLIP; +#ifdef HWRENDER // Needs extra offset. Not perfect but this will do for now if (rendermode == render_opengl && !cv_glshearing.value && cv_smallnametags.value) namey -= dup*6; +#endif if (cv_smallnametags.value || !nametaggfx) { -- 2.54.0 From 85cac497ea2e1ef1a7ca793ae4abfb8d31710b7d Mon Sep 17 00:00:00 2001 From: Alug Date: Wed, 3 Sep 2025 12:25:41 +0200 Subject: [PATCH 60/66] fixup building map title string for serverinfo fixes numerous issues, like zonetitle not appearing on bots and serverinfo screen and generally making this more sane by appending stuff if needed also fixes "Zone" not displaying in serverinfo screen --- src/d_clisrv.c | 69 +++++++++++++++++++------------------------------- 1 file changed, 26 insertions(+), 43 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index f8bf137f9..67799fd62 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1341,7 +1341,11 @@ static inline void CL_DrawConnectionStatus(void) patch_t *current_map = W_LumpExists(map) ? W_CachePatchName(map, PU_CACHE) : W_CachePatchName("BLANKLVL", PU_CACHE); V_DrawSmallScaledPatch(10, 18, 0, current_map); - V_DrawThinString(12 + 80, 38, V_ALLOWLOWERCASE, va("%s", serverlist[joinnode].info.maptitle)); + if (serverlist[joinnode].info.iszone) + V_DrawThinString(12 + 80, 38, V_ALLOWLOWERCASE, va("%s Zone", serverlist[joinnode].info.maptitle)); + else + V_DrawThinString(12 + 80, 38, V_ALLOWLOWERCASE, va("%s", serverlist[joinnode].info.maptitle)); + V_DrawThinString(12 + 80, 48, V_ALLOWLOWERCASE, va("%s", Gametype_Names[serverlist[joinnode].info.gametype])); if (fileneedednum > 0) @@ -1581,59 +1585,38 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime) CopyCaretColors(netbuffer->u.serverinfo.servername, cv_servername.string, MAXSERVERNAME); - strncpy(netbuffer->u.serverinfo.mapname, G_BuildMapName(gamemap), 7); + strncpy(netbuffer->u.serverinfo.mapname, G_BuildMapName(gamemap), sizeof(netbuffer->u.serverinfo.mapname)-1); - M_Memcpy(netbuffer->u.serverinfo.mapmd5, mapmd5, 16); + M_Memcpy(netbuffer->u.serverinfo.mapmd5, mapmd5, sizeof(netbuffer->u.serverinfo.mapmd5)); - if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE) && !(mapheaderinfo[prevmap]->zonttl[0])) - netbuffer->u.serverinfo.iszone = 1; - else - netbuffer->u.serverinfo.iszone = 0; + netbuffer->u.serverinfo.iszone = 0; - memset(netbuffer->u.serverinfo.maptitle, 0, 33); + memset(netbuffer->u.serverinfo.maptitle, 0, sizeof(netbuffer->u.serverinfo.maptitle)); memset(netbuffer->u.serverinfo.httpsource, 0, MAX_MIRROR_LENGTH); if (!(mapheaderinfo[gamemap-1]->menuflags & LF2_HIDEINMENU) && mapheaderinfo[gamemap-1]->lvlttl[0]) { - //strncpy(netbuffer->u.serverinfo.maptitle, (char *)mapheaderinfo[gamemap-1]->lvlttl, 33); - // set up the levelstring - if (netbuffer->u.serverinfo.iszone || (mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE)) + strncpy(netbuffer->u.serverinfo.maptitle, mapheaderinfo[gamemap-1]->lvlttl, sizeof(netbuffer->u.serverinfo.maptitle)-1); + + if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE)) { - if (mapheaderinfo[gamemap-1]->actnum[0]) - snprintf(netbuffer->u.serverinfo.maptitle, - 33, - "%s %s", - mapheaderinfo[gamemap-1]->lvlttl, mapheaderinfo[gamemap-1]->actnum); + if (mapheaderinfo[gamemap-1]->zonttl[0]) + { + strncat(netbuffer->u.serverinfo.maptitle, " ", sizeof(netbuffer->u.serverinfo.maptitle)-1); + strncat(netbuffer->u.serverinfo.maptitle, mapheaderinfo[gamemap-1]->zonttl, + sizeof(netbuffer->u.serverinfo.maptitle)-1); + } else - snprintf(netbuffer->u.serverinfo.maptitle, - 33, - "%s", - mapheaderinfo[gamemap-1]->lvlttl); + { + netbuffer->u.serverinfo.iszone = 1; // ms and clients will append this themselves + } } - else + + if (mapheaderinfo[gamemap-1]->actnum[0]) { - if (mapheaderinfo[gamemap-1]->actnum[0]) - { - if (snprintf(netbuffer->u.serverinfo.maptitle, - 33, - "%s %s %s", - mapheaderinfo[gamemap-1]->lvlttl, mapheaderinfo[gamemap-1]->zonttl, mapheaderinfo[gamemap-1]->actnum) < 0) - { - // If there's an encoding error, send UNKNOWN, we accept that the above may be truncated - strncpy(netbuffer->u.serverinfo.maptitle, "Unknown", 33); - } - } - else - { - if (snprintf(netbuffer->u.serverinfo.maptitle, - 33, - "%s %s", - mapheaderinfo[gamemap-1]->lvlttl, mapheaderinfo[gamemap-1]->zonttl) < 0) - { - // If there's an encoding error, send UNKNOWN, we accept that the above may be truncated - strncpy(netbuffer->u.serverinfo.maptitle, "Unknown", 33); - } - } + strncat(netbuffer->u.serverinfo.maptitle, " ", sizeof(netbuffer->u.serverinfo.maptitle)-1); + strncat(netbuffer->u.serverinfo.maptitle, mapheaderinfo[gamemap-1]->actnum, + sizeof(netbuffer->u.serverinfo.maptitle)-1); } } else -- 2.54.0 From cd7ce5698ca89162ea937962530b94e552cad047 Mon Sep 17 00:00:00 2001 From: Indev Date: Fri, 5 Sep 2025 17:34:09 +0300 Subject: [PATCH 61/66] Update vote background if hud.setVoteBackground was called on vote screen --- src/lua_hudlib.c | 4 ++++ src/y_inter.c | 2 +- src/y_inter.h | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 98120cebf..c33b2fca1 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -1278,6 +1278,10 @@ static int lib_hudsetvotebackground(lua_State *L) strncpy(VoteScreen.luaPrefix, prefix, 4); strupr(VoteScreen.luaPrefix); + // Update background if we're already on vote screen + if (gamestate == GS_VOTING) + Y_VoteScreenCheck(); + return 0; } diff --git a/src/y_inter.c b/src/y_inter.c index 0c096127a..bbd9f11fe 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -820,7 +820,7 @@ static void Y_FollowIntermission(void) // // Y_VoteScreenCheck // -static void Y_VoteScreenCheck(void) +void Y_VoteScreenCheck(void) { strcpy(VoteScreen.Prefix, "INTS"); diff --git a/src/y_inter.h b/src/y_inter.h index be8592357..31dc96694 100644 --- a/src/y_inter.h +++ b/src/y_inter.h @@ -21,6 +21,7 @@ void Y_VoteTicker(void); void Y_StartVote(void); void Y_EndVote(void); void Y_SetupVoteFinish(SINT8 pick, SINT8 level); +void Y_VoteScreenCheck(void); typedef struct { -- 2.54.0 From 437f900c257578930644994a5881849ae0747e6a Mon Sep 17 00:00:00 2001 From: Indev Date: Fri, 5 Sep 2025 18:21:01 +0300 Subject: [PATCH 62/66] Clear dangling pointers in VoteScreen struct after mapload --- src/p_setup.c | 2 ++ src/y_inter.c | 16 ++++++++++++++++ src/y_inter.h | 1 + 3 files changed, 19 insertions(+) diff --git a/src/p_setup.c b/src/p_setup.c index f36ab9b44..3d5bf3f7f 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2942,6 +2942,8 @@ boolean P_SetupLevel(boolean fromnetsave, boolean reloadinggamestate) //Patch_FreeTag(PU_PATCH_ROTATED); // we keep those ty! Z_FreeTags(PU_LEVEL, PU_PURGELEVEL - 1); + Y_VoteClear(); + #if defined (WALLSPLATS) || defined (FLOORSPLATS) // clear the splats from previous level R_ClearLevelSplats(); diff --git a/src/y_inter.c b/src/y_inter.c index bbd9f11fe..892187d85 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -1574,6 +1574,22 @@ void Y_EndVote(void) voteendtic = -1; } +// +// Y_VoteClear +// Resets patches to prevent dangling pointers +// +void Y_VoteClear(void) +{ + VoteScreen.bgpatch = NULL; + VoteScreen.widebgpatch = NULL; + + for (size_t i = 0; i < sizeof(VoteScreen.cursor)/sizeof(VoteScreen.cursor[0]); ++i) + VoteScreen.cursor[i] = NULL; + + VoteScreen.randomlvl = NULL; + VoteScreen.rubyicon = NULL; +} + // // Y_SetupVoteFinish // diff --git a/src/y_inter.h b/src/y_inter.h index 31dc96694..401461db7 100644 --- a/src/y_inter.h +++ b/src/y_inter.h @@ -22,6 +22,7 @@ void Y_StartVote(void); void Y_EndVote(void); void Y_SetupVoteFinish(SINT8 pick, SINT8 level); void Y_VoteScreenCheck(void); +void Y_VoteClear(void); typedef struct { -- 2.54.0 From 77a00b08a5d628c9c373dcf4a7e79046f7000c2a Mon Sep 17 00:00:00 2001 From: Alug Date: Mon, 8 Sep 2025 19:29:01 +0200 Subject: [PATCH 63/66] optimize gl vhseffect slightly we dont need to remake our screen texture 3 times also avoid combining float with interger maths esp in the loop --- src/hardware/r_opengl/r_opengl.c | 55 +++++++++++++++++++------------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 4dcd1253b..32aa784d1 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -3348,7 +3348,6 @@ void GL_DoScreenWipe(int wipeStart, int wipeEnd) void GL_RenderVhsEffect(fixed_t upbary, fixed_t downbary, UINT8 updistort, UINT8 downdistort, UINT8 barsize) { - int tex = HWD_SCREENTEXTURE_VHS; float xfix, yfix; float fix[8]; GLubyte color[4] = {255, 255, 255, 255}; @@ -3368,14 +3367,19 @@ void GL_RenderVhsEffect(fixed_t upbary, fixed_t downbary, UINT8 updistort, UINT8 xfix = 1/((float)(screen_texsizew)/((float)((screen_width)))); yfix = 1/((float)(screen_texsizeh)/((float)((screen_height)))); - // Slight fuzziness - GL_MakeScreenTexture(tex); - GL_SetBlend(PF_Modulated|PF_Translucent|PF_NoDepthTest); - pglBindTexture(GL_TEXTURE_2D, screenTextures[tex]); + const GLfloat scrwf = (float)screen_width; + const GLfloat scrwh = (float)screen_height; - for (i = 0; i < 1; i += 2.f/vid.height) + // Slight fuzziness + GL_MakeScreenTexture(HWD_SCREENTEXTURE_VHS); + GL_SetBlend(PF_Modulated|PF_Translucent|PF_NoDepthTest); + pglBindTexture(GL_TEXTURE_2D, screenTextures[HWD_SCREENTEXTURE_VHS]); + + const float stride = 2.f/scrwh; + + for (i = 0; i < 1; i += stride) { - fix[2] = (float)(rand() % 128) / -22000 * xfix; + fix[2] = (float)(rand() % 128) / -22000.f * xfix; fix[0] = fix[2]; fix[6] = fix[0] + xfix; fix[4] = fix[2] + xfix; @@ -3393,8 +3397,8 @@ void GL_RenderVhsEffect(fixed_t upbary, fixed_t downbary, UINT8 updistort, UINT8 } // Upward bar - GL_MakeScreenTexture(tex); - pglBindTexture(GL_TEXTURE_2D, screenTextures[tex]); + //GL_MakeScreenTexture(HWD_SCREENTEXTURE_VHS); + //pglBindTexture(GL_TEXTURE_2D, screenTextures[HWD_SCREENTEXTURE_VHS]); color[0] = color[1] = color[2] = 190; color[3] = 250; @@ -3402,14 +3406,14 @@ void GL_RenderVhsEffect(fixed_t upbary, fixed_t downbary, UINT8 updistort, UINT8 fix[0] = 0.0f; fix[6] = xfix; - fix[2] = (float)updistort / screen_width * xfix; + fix[2] = (float)updistort / scrwf * xfix; fix[4] = fix[2] + fix[6]; - screenVerts[1] = screenVerts[10] = 2.0f*upbary/screen_height - 1.0f; - screenVerts[4] = screenVerts[7] = screenVerts[1] + (float)barsize/screen_height; + screenVerts[1] = screenVerts[10] = 2.0f*upbary/scrwh - 1.0f; + screenVerts[4] = screenVerts[7] = screenVerts[1] + (float)barsize/scrwh; - fix[1] = fix[7] = (float)upbary/screen_height * yfix; - fix[3] = fix[5] = fix[1] + (float)barsize/2/screen_height * yfix; + fix[1] = fix[7] = (float)upbary/scrwh * yfix; + fix[3] = fix[5] = fix[1] + (float)barsize/2/scrwh * yfix; pglTexCoordPointer(2, GL_FLOAT, 0, fix); pglVertexPointer(3, GL_FLOAT, 0, screenVerts); @@ -3422,19 +3426,19 @@ void GL_RenderVhsEffect(fixed_t upbary, fixed_t downbary, UINT8 updistort, UINT8 pglDrawArrays(GL_TRIANGLE_FAN, 0, 4); // Downward bar - GL_MakeScreenTexture(tex); - pglBindTexture(GL_TEXTURE_2D, screenTextures[tex]); + //GL_MakeScreenTexture(HWD_SCREENTEXTURE_VHS); + //pglBindTexture(GL_TEXTURE_2D, screenTextures[HWD_SCREENTEXTURE_VHS]); fix[0] = 0.0f; fix[6] = xfix; - fix[2] = (float)downdistort / screen_width * -xfix; + fix[2] = (float)downdistort / scrwf * -xfix; fix[4] = fix[2] + fix[6]; - screenVerts[1] = screenVerts[10] = 2.0f*downbary/screen_height - 1.0f; - screenVerts[4] = screenVerts[7] = screenVerts[1] + (float)barsize/screen_height; + screenVerts[1] = screenVerts[10] = 2.0f*downbary/scrwh - 1.0f; + screenVerts[4] = screenVerts[7] = screenVerts[1] + (float)barsize/scrwh; - fix[1] = fix[7] = (float)downbary/screen_height * yfix; - fix[3] = fix[5] = fix[1] + (float)barsize/2/screen_height * yfix; + fix[1] = fix[7] = (float)downbary/scrwh * yfix; + fix[3] = fix[5] = fix[1] + (float)barsize/2/scrwh * yfix; pglTexCoordPointer(2, GL_FLOAT, 0, fix); pglVertexPointer(3, GL_FLOAT, 0, screenVerts); @@ -3450,11 +3454,13 @@ void GL_RenderVhsEffect(fixed_t upbary, fixed_t downbary, UINT8 updistort, UINT8 // Create a texture from the screen. void GL_MakeScreenTexture(int tex) { - boolean firstTime = (screenTextures[tex] == 0); + boolean firstTime; if (!gl_enable_screen_textures) return; + firstTime = (screenTextures[tex] == 0); + // Create screen texture if (firstTime) pglGenTextures(1, &screenTextures[tex]); @@ -3539,7 +3545,7 @@ void GL_DrawScreenFinalTexture(int tex, INT32 width, INT32 height, boolean usesh pglBindTexture(GL_TEXTURE_2D, screenTextures[tex]); if (useshader) - pglUseProgram(gl_shaders[SHADER_PALETTE_POSTPROCESS].program); // palette postprocess shader + pglUseProgram(gl_shaders[SHADER_PALETTE_POSTPROCESS].program); // Final postprocess step of palette rendering, after everything else has been drawn. pglColor4ubv(white); @@ -3557,6 +3563,7 @@ void GL_DrawScreenFinalTexture(int tex, INT32 width, INT32 height, boolean usesh void GL_SetPaletteLookup(UINT8 *lut) { GLenum internalFormat; + if (gl_version[0] == '1' || gl_version[0] == '2') { // if the OpenGL version is below 3.0, then the GL_R8 format may not be available. @@ -3584,6 +3591,7 @@ void GL_SetPaletteLookup(UINT8 *lut) UINT32 GL_CreateLightTable(RGBA_t *hw_lighttable) { LTListItem *item = malloc(sizeof(LTListItem)); + if (!LightTablesTail) { LightTablesHead = LightTablesTail = item; @@ -3593,6 +3601,7 @@ UINT32 GL_CreateLightTable(RGBA_t *hw_lighttable) LightTablesTail->next = item; LightTablesTail = item; } + item->next = NULL; pglGenTextures(1, &item->id); pglBindTexture(GL_TEXTURE_2D, item->id); -- 2.54.0 From ff5bb34204ab5e5ed0d3209212462a153f9d8752 Mon Sep 17 00:00:00 2001 From: Alug Date: Mon, 8 Sep 2025 19:33:46 +0200 Subject: [PATCH 64/66] parentheses hell --- src/hardware/r_opengl/r_opengl.c | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 32aa784d1..3a903a9af 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -3142,8 +3142,8 @@ void GL_PostImgRedraw(float points[SCREENVERTS][SCREENVERTS][2]) return; // X/Y stretch fix for all resolutions(!) - xfix = (float)(screen_texsizew)/((float)((screen_width)/(float)(SCREENVERTS-1))); - yfix = (float)(screen_texsizeh)/((float)((screen_height)/(float)(SCREENVERTS-1))); + xfix = (float)screen_texsizew/((float)(screen_width/(float)(SCREENVERTS-1))); + yfix = (float)screen_texsizeh/((float)(screen_height/(float)(SCREENVERTS-1))); pglDisable(GL_DEPTH_TEST); pglDisable(GL_BLEND); @@ -3230,12 +3230,9 @@ void GL_DrawScreenTexture(int tex, FSurfaceInfo *surf, FBITFIELD polyflags) if (gl_enable_screen_textures != 2) return; - xfix = 1/((float)(screen_texsizew)/((float)((screen_width)))); - yfix = 1/((float)(screen_texsizeh)/((float)((screen_height)))); + xfix = 1/((float)screen_texsizew/(float)screen_width); + yfix = 1/((float)screen_texsizeh/(float)screen_height); - // const float screenVerts[12] - - // float fix[8]; fix[0] = 0.0f; fix[1] = 0.0f; fix[2] = 0.0f; @@ -3289,12 +3286,9 @@ void GL_DoScreenWipe(int wipeStart, int wipeEnd) if (!gl_enable_screen_textures) return; - xfix = 1/((float)(screen_texsizew)/((float)((screen_width)))); - yfix = 1/((float)(screen_texsizeh)/((float)((screen_height)))); + xfix = 1/((float)screen_texsizew/(float)screen_width); + yfix = 1/((float)screen_texsizeh/(float)screen_height); - // const float screenVerts[12] - - // float fix[8]; fix[0] = 0.0f; fix[1] = 0.0f; fix[2] = 0.0f; @@ -3364,8 +3358,8 @@ void GL_RenderVhsEffect(fixed_t upbary, fixed_t downbary, UINT8 updistort, UINT8 if (gl_enable_screen_textures != 2) return; - xfix = 1/((float)(screen_texsizew)/((float)((screen_width)))); - yfix = 1/((float)(screen_texsizeh)/((float)((screen_height)))); + xfix = 1/((float)screen_texsizew/(float)screen_width); + yfix = 1/((float)screen_texsizeh/(float)screen_height); const GLfloat scrwf = (float)screen_width; const GLfloat scrwh = (float)screen_height; @@ -3494,8 +3488,8 @@ void GL_DrawScreenFinalTexture(int tex, INT32 width, INT32 height, boolean usesh if (gl_enable_screen_textures != 2) return; - xfix = 1/((float)(screen_texsizew)/((float)((screen_width)))); - yfix = 1/((float)(screen_texsizeh)/((float)((screen_height)))); + xfix = 1/((float)screen_texsizew/(float)screen_width); + yfix = 1/((float)screen_texsizeh/(float)screen_height); origaspect = (float)screen_width / screen_height; newaspect = (float)width / height; -- 2.54.0 From 29db810c54ebdfe8cfd04614a04e180ffb9d9498 Mon Sep 17 00:00:00 2001 From: Alug Date: Tue, 9 Sep 2025 18:16:52 +0200 Subject: [PATCH 65/66] delet remaining "highcolor" stuff --- src/android/i_video.c | 4 ---- src/dedicated/i_video.c | 4 +--- src/i_video.h | 5 ----- src/r_data.c | 44 ----------------------------------------- src/r_data.h | 3 --- src/screen.c | 4 ++-- src/screen.h | 2 +- src/sdl/i_video.c | 2 -- 8 files changed, 4 insertions(+), 64 deletions(-) diff --git a/src/android/i_video.c b/src/android/i_video.c index 4db66afe0..bbe1cf3a3 100644 --- a/src/android/i_video.c +++ b/src/android/i_video.c @@ -10,12 +10,8 @@ rendermode_t rendermode = render_soft; -boolean highcolor = false; - boolean allow_fullscreen = false; - - consvar_t cv_vidwait = {"vid_wait", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; void I_StartupGraphics(void){} diff --git a/src/dedicated/i_video.c b/src/dedicated/i_video.c index 8f8781e9e..e2a712995 100644 --- a/src/dedicated/i_video.c +++ b/src/dedicated/i_video.c @@ -29,8 +29,6 @@ rendermode_t rendermode = render_none; -boolean highcolor = false; - // synchronize page flipping with screen refresh consvar_t cv_vidwait = {"vid_wait", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -153,7 +151,7 @@ boolean I_UseNativeKeyboard(void) return false; } -void I_SetBorderlessWindow(void) +void I_SetBorderlessWindow(void) { } diff --git a/src/i_video.h b/src/i_video.h index 88d295ed9..d9bb9e1ce 100644 --- a/src/i_video.h +++ b/src/i_video.h @@ -40,11 +40,6 @@ typedef enum */ extern rendermode_t rendermode; - -/** \brief use highcolor modes if true -*/ -extern boolean highcolor; - /** \brief setup video mode */ void I_StartupGraphics(void); diff --git a/src/r_data.c b/src/r_data.c index 688b03972..0b4b153e4 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -121,10 +121,6 @@ UINT8 invertmap[256]; // for debugging/info purposes size_t flatmemory, spritememory, texturememory; // gotta play by 2.2 rules to get this to work -// highcolor stuff -INT16 color8to16[256]; // remap color index to highcolor rgb value -INT16 *hicolormaps; // test a 32k colormap remaps high -> high - // Blends two pixels together, using the equation // that matches the specified alpha style. UINT32 ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha) @@ -1661,40 +1657,6 @@ const char *R_ColormapNameForNum(INT32 num) } -// -// build a table for quick conversion from 8bpp to 15bpp -// - -// -// added "static inline" keywords, linking with the debug version -// of allegro, it have a makecol15 function of it's own, now -// with "static inline" keywords,it sloves this problem ;) -// -FUNCMATH static inline int makecol15(int r, int g, int b) -{ - return (((r >> 3) << 10) | ((g >> 3) << 5) | ((b >> 3))); -} - -static void R_Init8to16(void) -{ - UINT8 *palette; - int i; - - palette = W_CacheLumpName("PLAYPAL",PU_CACHE); - - for (i = 0; i < 256; i++) - { - // PLAYPAL uses 8 bit values - color8to16[i] = (INT16)makecol15(palette[0], palette[1], palette[2]); - palette += 3; - } - - // test a big colormap - hicolormaps = Z_Malloc(16384*sizeof(*hicolormaps), PU_STATIC, NULL); - for (i = 0; i < 16384; i++) - hicolormaps[i] = (INT16)(i<<1); -} - // // R_InitData // @@ -1703,12 +1665,6 @@ static void R_Init8to16(void) // void R_InitData(void) { - if (highcolor) - { - CONS_Printf("InitHighColor...\n"); - R_Init8to16(); - } - CONS_Printf("R_LoadTextures()...\n"); R_LoadTextures(); diff --git a/src/r_data.h b/src/r_data.h index 58afc34d0..2a74d591c 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -69,9 +69,6 @@ extern fixed_t *textureheight; // needed for texture pegging UINT32 ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha); UINT32 ASTBlendTexturePixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha); -extern INT16 color8to16[256]; // remap color index to highcolor -extern INT16 *hicolormaps; // remap high colors to high colors.. - extern CV_PossibleValue_t Color_cons_t[]; // Load TEXTURE1/TEXTURE2/PNAMES definitions, create lookup tables diff --git a/src/screen.c b/src/screen.c index a8a3ca78b..4d239e186 100644 --- a/src/screen.c +++ b/src/screen.c @@ -8,7 +8,7 @@ // See the 'LICENSE' file for more details. //----------------------------------------------------------------------------- /// \file screen.c -/// \brief Handles multiple resolutions, 8bpp/16bpp(highcolor) modes +/// \brief Handles multiple resolutions #include "doomdef.h" #include "doomstat.h" @@ -37,7 +37,7 @@ // global video state // ------------------ viddef_t vid; -INT32 setmodeneeded; //video mode change needed if > 0 (the mode number to set + 1) +INT32 setmodeneeded; // video mode change needed if > 0 (the mode number to set + 1) static CV_PossibleValue_t shittyscreen_cons_t[] = {{0, "Okay"}, {1, "Shitty"}, {2, "Extra Shitty"}, {0, NULL}}; diff --git a/src/screen.h b/src/screen.h index 38483b28d..42bc6c144 100644 --- a/src/screen.h +++ b/src/screen.h @@ -8,7 +8,7 @@ // See the 'LICENSE' file for more details. //----------------------------------------------------------------------------- /// \file screen.h -/// \brief Handles multiple resolutions, 8bpp/16bpp(highcolor) modes +/// \brief Handles multiple resolutions #ifndef __SCREEN_H__ #define __SCREEN_H__ diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 8e19b33ac..389e086e2 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -113,8 +113,6 @@ unsigned msaa = 0; boolean a2c = false; #endif -boolean highcolor = false; - static void KeyboardLayout_OnChange(void) { HU_Shiftform(); -- 2.54.0 From c98861be6eead0a719ba2b1a7a0ee181047632a3 Mon Sep 17 00:00:00 2001 From: Alug Date: Wed, 10 Sep 2025 13:07:15 +0200 Subject: [PATCH 66/66] fix tracker module playback going nuts when changing audio buffer size forgor CV_CALL :chaosleep: --- src/s_sound.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/s_sound.c b/src/s_sound.c index aead25f0c..1bac40a46 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -62,7 +62,7 @@ consvar_t cv_samplerate = {"samplerate", "44100", 0, CV_Unsigned, NULL, 22050, N #endif static CV_PossibleValue_t audbuffersize_cons_t[] = {{128, "128"}, {256, "256"}, {512, "512"}, {1024, "1024"}, {2048, "2048"}, {4096, "4096"}, {0, NULL}}; -consvar_t cv_audbuffersize = {"audiobuffersize", "2048", CV_SAVE, audbuffersize_cons_t, BufferSize_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_audbuffersize = {"audiobuffersize", "2048", CV_SAVE|CV_CALL, audbuffersize_cons_t, BufferSize_OnChange, 0, NULL, NULL, 0, 0, NULL}; // stereo reverse consvar_t stereoreverse = {"stereoreverse", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -- 2.54.0