From ab209448d19c27dff9433fbedf2bfbf6a6d07b12 Mon Sep 17 00:00:00 2001 From: Alug Date: Mon, 23 Mar 2026 20:38:21 +0100 Subject: [PATCH 01/21] Introduce GNU constructor and destructor attributes The constructor attribute causes the function to be called automatically before execution enters main (). Similarly, the destructor attribute causes the function to be called automatically after main () has completed or exit () has been called. Functions with these attributes are useful for initializing data that will be used implicitly during the execution of the program. added "used" attribute aswell so compiler does not omit non referenced functions (i hope) gotta test this a bit but seems cool for stuff like verstable maps --- src/doomdef.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/doomdef.h b/src/doomdef.h index 445b6951f..1543e68a9 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -573,6 +573,13 @@ INT32 I_GetKey(void); // NOTE: you WILL have nasal troubles if the variable is not initialized #define CLEANUP(f) __attribute__((__cleanup__(f))) +// the GNU constructor and destructor attributes +// The constructor attribute causes the function to be called automatically before execution enters main (). +// Similarly, the destructor attribute causes the function to be called automatically after main () has completed or exit () has been called. +// Functions with these attributes are useful for initializing data that will be used implicitly during the execution of the program. +#define CONSTRUCTOR __attribute__((constructor, used)) +#define DESTRUCTOR __attribute__((destructor, used)) + // An assert-type mechanism. #ifdef PARANOIA #define I_Assert(e) ((e) ? (void)0 : I_Error("assert failed: %s, file %s, line %d", #e, __FILE__, __LINE__)) -- 2.54.0 From f6a0430a408861d091d5cdfa26bbaa83560b1cc2 Mon Sep 17 00:00:00 2001 From: Alug Date: Mon, 23 Mar 2026 20:39:16 +0100 Subject: [PATCH 02/21] use constructor for W_Startup never liked having this inside i_system --- src/dedicated/i_system.c | 1 - src/sdl/i_system.cpp | 2 -- src/w_wad.c | 5 ++--- src/w_wad.h | 1 - 4 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/dedicated/i_system.c b/src/dedicated/i_system.c index ddc17d6a5..f6450134c 100644 --- a/src/dedicated/i_system.c +++ b/src/dedicated/i_system.c @@ -1384,7 +1384,6 @@ static void I_Fork(void) INT32 I_StartupSystem(void) { - W_Startup(); I_StartupConsole(); #ifdef NEWSIGNALHANDLER // This is useful when debugging. It lets GDB attach to diff --git a/src/sdl/i_system.cpp b/src/sdl/i_system.cpp index 407e5c3a0..c30e93d90 100644 --- a/src/sdl/i_system.cpp +++ b/src/sdl/i_system.cpp @@ -1887,8 +1887,6 @@ INT32 I_StartupSystem(void) SDL_VERSION(&SDLcompiled) SDL_GetVersion(&SDLlinked); - W_Startup(); - I_StartupConsole(); #ifdef NEWSIGNALHANDLER // This is useful when debugging. It lets GDB attach to diff --git a/src/w_wad.c b/src/w_wad.c index 2ac8ae68d..8c7494898 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -158,8 +158,7 @@ void W_Shutdown(void) } // the lumpnum cache needs to be initialized before use -// call this as early as possible! -void W_Startup(void) +CONSTRUCTOR static void W_Startup(void) { lumpnum_map_init(&lumpnumcache); lumpnum_map_reserve(&lumpnumcache, LUMPNUMCACHESIZE); @@ -367,7 +366,7 @@ static inline INT32 W_MakeFileMD5(const char *filename, void *resblock) { precise_t t = I_GetPreciseTime(); - CONS_Debug(DBG_SETUP, "Making MD5 for %s\n",filename); + CONS_Debug(DBG_SETUP, "Making MD5 for %s\n", filename); if (md5_stream(fhandle, resblock) == 1) { diff --git a/src/w_wad.h b/src/w_wad.h index ea4a98dd6..474f72c23 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -154,7 +154,6 @@ extern wadfile_t *wadfiles[MAX_WADFILES]; // ========================================================================= -void W_Startup(void); void W_Shutdown(void); // Opens a WAD file. Returns the FILE * handle for the file, or NULL if not found or could not be opened -- 2.54.0 From 7fb21c35ba822290ee5c7203491eeca1002f9e50 Mon Sep 17 00:00:00 2001 From: Alug Date: Mon, 23 Mar 2026 20:57:06 +0100 Subject: [PATCH 03/21] Experiment: speed up CV_FindVar and CV_FindNetVar oftentimes lua scripts call CV_FindVar a fuckton of times during runtime, with many cvars this can actually tank performance more than one might think ideally lua scripts should cache the result, but with so much stuff and servers we cant expect everyone to go through all scripts to do that using a hashtable for CV_FindNetVar might improve join times aswell, but needs further testing to confirm --- src/command.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/src/command.c b/src/command.c index c37b8f1d3..f19bb89c6 100644 --- a/src/command.c +++ b/src/command.c @@ -1165,6 +1165,39 @@ void VS_Print(vsbuf_t *buf, const char *data) // // ========================================================================= +#define NAME cvar_map_t +#define KEY_TY const char * +#define VAL_TY consvar_t * +#define HASH_FN vt_hash_string +#define CMPR_FN vt_cmpr_string +#include "verstable.h" + +#define NAME netvar_map_t +#define KEY_TY UINT16 +#define VAL_TY consvar_t * +#define HASH_FN vt_hash_integer +#define CMPR_FN vt_cmpr_integer +#include "verstable.h" + +static cvar_map_t cvar_map; +static netvar_map_t netvar_map; + +CONSTRUCTOR static void CV_InitMap(void) +{ + // ensure the map is initialized + cvar_map_t_init(&cvar_map); + cvar_map_t_reserve(&cvar_map, 512); + + netvar_map_t_init(&netvar_map); + netvar_map_t_reserve(&netvar_map, 256); +} + +DESTRUCTOR static void CV_DestroyMap(void) +{ + cvar_map_t_cleanup(&cvar_map); + netvar_map_t_cleanup(&netvar_map); +} + static const char *cv_null_string = ""; /** Searches if a variable has been registered. @@ -1175,11 +1208,17 @@ static const char *cv_null_string = ""; */ consvar_t *CV_FindVar(const char *name) { - consvar_t *cvar; + cvar_map_t_itr it = cvar_map_t_get(&cvar_map, name); + if (!cvar_map_t_is_end(it)) + return it.data->val; + // fallback linear search + /* + consvar_t *cvar; for (cvar = consvar_vars; cvar; cvar = cvar->next) if (fasticmp(name, cvar->name)) return cvar; + */ return NULL; } @@ -1213,11 +1252,17 @@ static inline UINT16 CV_ComputeNetid(const char *s) */ static consvar_t *CV_FindNetVar(UINT16 netid) { + netvar_map_t_itr it = netvar_map_t_get(&netvar_map, netid); + if (!netvar_map_t_is_end(it)) + return it.data->val; + + /* consvar_t *cvar; for (cvar = consvar_vars; cvar; cvar = cvar->next) if (cvar->netid == netid) return cvar; + */ if (netid == 44542) // ouch this hack return &cv_karteliminatelast; @@ -1283,6 +1328,11 @@ void CV_RegisterVar(consvar_t *variable) // the SetValue will set this bit variable->flags &= ~CV_MODIFIED; + + cvar_map_t_insert(&cvar_map, variable->name, variable); + + if (variable->flags & CV_NETVAR) + netvar_map_t_insert(&netvar_map, variable->netid, variable); } /** Finds the string value of a console variable. @@ -1588,9 +1638,21 @@ size_t CV_LoadNetVars(const UINT8 *bufstart) // prevent "invalid command received" serverloading = true; + // we can use our netvar map instead of going through all cvars each time + netvar_map_t_itr it; + for (it = netvar_map_t_first(&netvar_map); + !netvar_map_t_is_end(it); + it = netvar_map_t_next(it)) + { + cvar = it.data->val; + Setvalue(cvar, cvar->defaultvalue, true); + } + + /* for (cvar = consvar_vars; cvar; cvar = cvar->next) if (cvar->flags & CV_NETVAR) Setvalue(cvar, cvar->defaultvalue, true); + */ count = READUINT16(p); while (count--) -- 2.54.0 From 43465c0e3f56d7402af8a3cd3bbfa54f8c923fbe Mon Sep 17 00:00:00 2001 From: Alug Date: Thu, 26 Mar 2026 18:29:31 +0100 Subject: [PATCH 04/21] add debug print for fallback flashpals --- src/v_video.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/v_video.c b/src/v_video.c index 940dd190d..d4788cf94 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -432,14 +432,17 @@ static void ApplyPaletteDelta(const RGBA_t *pal_in, RGBA_t *pal_out, const INT16 static void GenerateFlashPalettes(void) { - size_t i, palsize; + size_t i; + static const size_t palsize = (2*256); // two flashpals RGBA_t *pFlashPalGammaCorrectedPalette = NULL; // generate flashpalettes if the current palette does not provide any subpalettes if (currentPaletteSize >= (14 * (256 * 3))) // 14 palettes are in playpal + { return; + } - palsize = (2*256); + CONS_Debug(DBG_RENDER, "Current palette does not provide enough subpalettes for flashpalettes to work!\nCreating fallback palettes...\n"); pFallbackFlashPal = Z_Malloc(sizeof(*pFallbackFlashPal)*palsize, PU_STATIC, NULL); pFlashPalGammaCorrectedPalette = Z_Malloc(sizeof (*pFlashPalGammaCorrectedPalette)*palsize, PU_STATIC, NULL); -- 2.54.0 From fded8cc5623f0cdf9b57498d364f13d0a2c9ba10 Mon Sep 17 00:00:00 2001 From: Indev Date: Fri, 27 Mar 2026 22:05:11 +0300 Subject: [PATCH 05/21] Crash fix for super tiny resolutions Not really sure if anyone would actually want to play on something that is lower than 320x200 but this prevents zero division in V_Recalc at least --- src/v_video.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/v_video.c b/src/v_video.c index d4788cf94..29857dd74 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -3845,12 +3845,12 @@ void V_Recalc(void) // Set dup based on width or height, whichever is less if (((vid.width*FRACUNIT) / BASEVIDWIDTH) < ((vid.height*FRACUNIT) / BASEVIDHEIGHT)) { - vid.dup = vid.width / BASEVIDWIDTH; + vid.dup = max(vid.width / BASEVIDWIDTH, 1); vid.fdup = (vid.width*FRACUNIT) / BASEVIDWIDTH; } else { - vid.dup = vid.height / BASEVIDHEIGHT; + vid.dup = max(vid.height / BASEVIDHEIGHT, 1); vid.fdup = (vid.height*FRACUNIT) / BASEVIDHEIGHT; } -- 2.54.0 From 6a1c907aa4a3f560256a088afdd4938281073a37 Mon Sep 17 00:00:00 2001 From: Alug Date: Sat, 28 Mar 2026 00:45:15 +0100 Subject: [PATCH 06/21] bunch of random fixes -handle more memory allocation failures -fix null pointer dereferences -prevent writing out of bounds while writing filenames for D_ParseFileneeded -prevent reading out of bounds while checking for new target in director -fix Update_MS checking against an unitialized value in some cases -fix assert for AddLumpToCache since strlen on non null terminated strings is UB -cleanup and rearrange R_DrawColumn -cleanup musicdef parser a little all in one commit cause idk would be ugly if those were seperate ig --- src/d_main.c | 6 +++- src/d_netcmd.c | 2 +- src/d_netfil.c | 2 +- src/dehacked.c | 11 +------- src/filesrch.c | 4 ++- src/g_demo.c | 4 ++- src/hu_stuff.c | 11 ++++++-- src/k_director.c | 6 ++++ src/mserv.c | 5 ++++ src/p_enemy.c | 5 ++++ src/p_mobj.c | 8 ++++-- src/r_data.c | 6 ++-- src/r_draw_column.cpp | 66 +++++++++++++++++++++---------------------- src/s_sound.c | 25 +++++++--------- src/w_wad.c | 2 +- 15 files changed, 91 insertions(+), 72 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index ccfa61f4e..a0b1f6fa4 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -2043,9 +2043,13 @@ void D_SRB2Main(void) if (M_CheckProtoParam("replay")) { const char *replayurl = M_GetProtoParam(); + + if (!replayurl) + I_Error("REPLAY: Invalid URL."); + gconst char *replayname = strrchr(replayurl, '/'); - if (!replayname || !replayurl) + if (!replayname) I_Error("REPLAY: Invalid URL."); #define REPLAYDIR "/DownloadedReplays/" diff --git a/src/d_netcmd.c b/src/d_netcmd.c index d16b54be9..aee7f20d4 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1631,7 +1631,7 @@ static void SendNameAndColor(UINT8 splitplayer) static void Got_NameAndColor(const UINT8 **cp, INT32 playernum) { player_t *player = &players[playernum]; - char name[MAXPLAYERNAME+1]; + char name[MAXPLAYERNAME+1] = {}; UINT8 color, skin; #ifdef PARANOIA diff --git a/src/d_netfil.c b/src/d_netfil.c index 67fd28a82..aca8f35ba 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -225,7 +225,7 @@ void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr, UINT16 fi fileneeded[i].willsend = (UINT8)(filestatus >> 4); fileneeded[i].totalsize = READUINT32(p); // The four next bytes are the file size fileneeded[i].file = NULL; // The file isn't open yet - READSTRINGN(p, fileneeded[i].filename, MAX_WADPATH); // The next bytes are the file name + READSTRINGL(p, fileneeded[i].filename, MAX_WADPATH); // The next bytes are the file name READMEM(p, fileneeded[i].md5sum, 16); // The last 16 bytes are the file checksum } } diff --git a/src/dehacked.c b/src/dehacked.c index 59e9d8276..38f713092 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -2812,12 +2812,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad) deh_num_warning = 0; // save values for cross reference - /* - for (i = 0; i < NUMSTATES; i++) - saveactions[i] = states[i].action; - for (i = 0; i < NUMSPRITES; i++) - savesprnames[i] = sprnames[i]; - */ for (i = 0; i < NUMSFX; i++) savesfxnames[i] = S_sfx[i].name; @@ -3124,11 +3118,8 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad) if (deh_num_warning) { CONS_Printf(M_GetText("%d warning%s in the SOC lump\n"), deh_num_warning, deh_num_warning == 1 ? "" : "s"); - if (devparm) { + if (devparm) I_Error("%s%s",va(M_GetText("%d warning%s in the SOC lump\n"), deh_num_warning, deh_num_warning == 1 ? "" : "s"), M_GetText("See log.txt for details.\n")); - //while (!I_GetKey()) - //I_OsPolling(); - } } deh_loaded = true; diff --git a/src/filesrch.c b/src/filesrch.c index 0ba117a1e..1647e1705 100644 --- a/src/filesrch.c +++ b/src/filesrch.c @@ -111,10 +111,12 @@ filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *want char *searchname; int depthleft = maxsearchdepth; char searchpath[MAXFILEPATH]; - size_t *searchpathindex; + size_t *searchpathindex = NULL; dirhandle = (DIR**)malloc(maxsearchdepth * sizeof(DIR*)); searchpathindex = (size_t *)malloc(maxsearchdepth * sizeof(size_t)); + if (!searchpathindex) + I_Error("out of memory while searching for file %s\n", filename); strcpy(searchpath, startpath); searchpathindex[--depthleft] = strlen(searchpath) + 1; diff --git a/src/g_demo.c b/src/g_demo.c index 0af73328d..4acbba9f5 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -1653,10 +1653,12 @@ void G_RecordDemo(const char *name) maxsize = cv_maxdemosize.value*1024*1024; demobuf.buffer = Z_Malloc(maxsize + 100*1024, PU_STATIC, NULL); - demoend = demobuf.buffer + maxsize; if (demobuf.buffer) + { + demoend = demobuf.buffer + maxsize; demo.recording = true; + } else CONS_Alert(CONS_ERROR, "Failed to allocate demo buffer\n"); } diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 91f9ca7d1..0f54d7bf8 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -543,6 +543,8 @@ void HU_AddChatText(const char *text, boolean playsound) HU_removeChatText_Log(); chat_log[chat_nummsg_log] = malloc(HU_MSGBUFSIZE); + if (!chat_log[chat_nummsg_log]) + I_Error("HU_AddChatText: out of memory for chat log\n"); strcpy(chat_log[chat_nummsg_log], text); ++chat_nummsg_log; @@ -625,7 +627,10 @@ static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags) // with that logic, characters 4 and 5 are our numbers: const char *newmsg; INT32 spc = 1; // used if nodenum[1] is a space. - CLEANUP(pfree) char *nodenum = (char*) malloc(3); + CLEANUP(pfree) char *nodenum = (char*)malloc(3); + if (!nodenum) + I_Error("DoSayCommand: out of memory for sending pm\n"); + memcpy(nodenum, msg+3, 2); nodenum[2] = '\0'; @@ -1230,7 +1235,9 @@ static void HU_SendChatMessage(void) { INT32 spc = 1; // used if nodenum[1] is a space. const char *newmsg; - CLEANUP(pfree) char *nodenum = (char*) malloc(3); + CLEANUP(pfree) char *nodenum = (char*)malloc(3); + if (!nodenum) + I_Error("HU_SendChatMessage: out of memory for sending pm\n"); // what we're gonna do now is check if the node exists // with that logic, characters 4 and 5 are our numbers: diff --git a/src/k_director.c b/src/k_director.c index 8fd5ab960..34bf367b6 100644 --- a/src/k_director.c +++ b/src/k_director.c @@ -446,6 +446,12 @@ void K_UpdateDirector(void) } } + // not sure if we should just stop here? + if (targetposition == MAXPLAYERS) + { + break; + } + target = directorinfo.sortedplayers[targetposition]; // stop here since we're already viewing this player diff --git a/src/mserv.c b/src/mserv.c index c91dacfcf..25ff733cb 100644 --- a/src/mserv.c +++ b/src/mserv.c @@ -599,9 +599,14 @@ Update_parameters (void) delayed = MSInProgress; if (delayed)/* do another update after the current one */ + { + registered = 0; MSUpdateAgain = true; + } else + { registered = MSRegistered; + } } Unlock_state(); diff --git a/src/p_enemy.c b/src/p_enemy.c index 3e83bec0c..d1c96d6f7 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -5344,6 +5344,11 @@ void A_MixUp(void *thing) } } + // idk if we ever really end up here + // but bad things would happen if we do without this + if (one == -1) + return; + //get this done first! tempthing = players[one].mo->tracer; P_SetTarget(&players[one].mo->tracer, players[two].mo->tracer); diff --git a/src/p_mobj.c b/src/p_mobj.c index daef6d1e9..28b85dea6 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -5620,13 +5620,15 @@ void P_SetScale(mobj_t *mobj, fixed_t newscale) void P_Attract(mobj_t *source, mobj_t *dest, boolean nightsgrab) // Home in on your target { fixed_t dist, ndist, speedmul; - fixed_t tx = dest->x; - fixed_t ty = dest->y; - fixed_t tz = dest->z + (dest->height/2); // Aim for center + fixed_t tx, ty, tz; if (!dest || dest->health <= 0 || !dest->player || !source->tracer) return; + tx = dest->x; + ty = dest->y; + tz = dest->z + (dest->height/2); // Aim for center + // change slope dist = P_AproxDistance(P_AproxDistance(tx - source->x, ty - source->y), tz - source->z); diff --git a/src/r_data.c b/src/r_data.c index f0a075217..43ff16cbb 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -1366,7 +1366,7 @@ void R_ReInitColormaps(UINT16 num, lumpnum_t newencoremap) colormap_p = colormap_p2 = colormaps; colormap_p += COLORMAP_REMAPOFFSET; - for (p = 0; p < 32; p++) + for (p = 0; p < LIGHTLEVELS; p++) { for (i = 0; i < 256; i++) { @@ -1588,7 +1588,7 @@ INT32 R_CreateColormap(char *p1, char *p2, char *p3) // Calculate the palette index for each palette index, for each light level // (as well as the two unused colormap lines we inherited from Doom) - for (p = 0; p < 32; p++) + for (p = 0; p < LIGHTLEVELS; p++) { for (i = 0; i < 256; i++) { @@ -1622,7 +1622,7 @@ INT32 R_CreateColormap(char *p1, char *p2, char *p3) { lighttable_t *colormap_p2 = extra_colormaps[mapnum].colormap; - for (p = 0; p < 32; p++) + for (p = 0; p < LIGHTLEVELS; p++) { for (i = 0; i < 256; i++) { diff --git a/src/r_draw_column.cpp b/src/r_draw_column.cpp index 67dbf94e3..526e136eb 100644 --- a/src/r_draw_column.cpp +++ b/src/r_draw_column.cpp @@ -204,7 +204,7 @@ static void R_DrawColumnTemplate(drawcolumndata_t *dc) intptr_t frac; // Looks familiar. const intptr_t fracstep = dc->iscale; - const intptr_t heightmask = dc->sourcelength-1; // CPhipps - specify type + intptr_t heightmask = dc->sourcelength-1; // CPhipps - specify type constexpr INT32 npow2min = -1; const INT32 npow2max = dc->sourcelength; @@ -237,10 +237,10 @@ static void R_DrawColumnTemplate(drawcolumndata_t *dc) // Determine scaling, which is the only mapping to be done. frac = (dc->texturemid + FixedMul((dc->yl << FRACBITS) - centeryfrac, fracstep)); - switch (heightmask) + switch (dc->sourcelength) { - case 255: - case 127: + case 256: + case 128: { while (count--) { @@ -251,7 +251,7 @@ static void R_DrawColumnTemplate(drawcolumndata_t *dc) } } break; - case npow2min: + case 0: { if (frac < 0) // adjust in case we underread @@ -269,42 +269,22 @@ static void R_DrawColumnTemplate(drawcolumndata_t *dc) break; default: { - if (!(dc->sourcelength & heightmask)) // power of 2 -- killough + if (dc->sourcelength & heightmask) // not a power of 2 -- killough { - while ((count -= 2) >= 0) // texture height is a power of 2 -- killough - { - *dest = R_DrawColumnPixel(dc, dest, (frac>>FRACBITS) & heightmask, source, colormap); - - dest += stride; - frac += fracstep; - - *dest = R_DrawColumnPixel(dc, dest, (frac>>FRACBITS) & heightmask, source, colormap); - - dest += stride; - frac += fracstep; - } - - if (count & 1) - { - *dest = R_DrawColumnPixel(dc, dest, (frac>>FRACBITS) & heightmask, source, colormap); - } - } - else - { - const intptr_t fixed_heightmask = dc->texheight << FRACBITS; + heightmask = dc->texheight << FRACBITS; if (frac < 0) { - while ((frac += fixed_heightmask) < 0) + while ((frac += heightmask) < 0) { ; } } else { - while (frac >= fixed_heightmask) + while (frac >= heightmask) { - frac -= fixed_heightmask; + frac -= heightmask; } } @@ -324,7 +304,7 @@ static void R_DrawColumnTemplate(drawcolumndata_t *dc) // Avoid overflow. if (fracstep > 0x7FFFFFFF - frac) { - frac += fracstep - fixed_heightmask; + frac += fracstep - heightmask; } else #endif @@ -332,13 +312,33 @@ static void R_DrawColumnTemplate(drawcolumndata_t *dc) frac += fracstep; } - while (frac >= fixed_heightmask) + while (frac >= heightmask) { - frac -= fixed_heightmask; + frac -= heightmask; } } while (--count); } + else + { + while ((count -= 2) >= 0) // texture height is a power of 2 -- killough + { + *dest = R_DrawColumnPixel(dc, dest, ((frac>>FRACBITS) & heightmask), source, colormap); + + dest += stride; + frac += fracstep; + + *dest = R_DrawColumnPixel(dc, dest, ((frac>>FRACBITS) & heightmask), source, colormap); + + dest += stride; + frac += fracstep; + } + + if (count & 1) + { + *dest = R_DrawColumnPixel(dc, dest, ((frac>>FRACBITS) & heightmask), source, colormap); + } + } } break; } diff --git a/src/s_sound.c b/src/s_sound.c index 2c0466c46..9ca078cec 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1286,7 +1286,8 @@ static boolean ReadMusicDefFields(UINT16 wadnum, int line, char *stoken, musicde CONS_Alert(CONS_WARNING, "MUSICDEF: Field '%s' is missing name. (file %s, line %d)\n", stoken, wadfiles[wadnum]->filename, line); - goto skip_lump; + (void)strtok(NULL, " "); + return true; } else { @@ -1304,14 +1305,10 @@ static boolean ReadMusicDefFields(UINT16 wadnum, int line, char *stoken, musicde (*defp) = def; } - -skip_lump: - stoken = strtok(NULL, " "); - line++; } else { - value = strtok(NULL, ""); + value = strtok(NULL, " "); if (value) { @@ -1324,7 +1321,8 @@ skip_lump: CONS_Alert(CONS_WARNING, "MUSICDEF: Field '%s' is missing value. (file %s, line %d)\n", stoken, wadfiles[wadnum]->filename, line); - goto skip_field; + (void)strtok(NULL, " "); + return true; } else { @@ -1376,10 +1374,6 @@ skip_lump: else CONS_Alert(CONS_WARNING, "MUSICDEF: Invalid field '%s'. (file %s, line %d)\n", stoken, wadfiles[wadnum]->filename, line); #undef ADDDEF - -skip_field: - stoken = strtok(NULL, "= "); - line++; } } @@ -1404,7 +1398,8 @@ void S_LoadMusicDefs(UINT16 wadnum) for (int k = 0; k < 2; k++) { - lumpnum = W_CheckNumForNamePwad((k == 1 ? "MUSCINFO" : "MUSICDEF") , wadnum, 0); //check for MUSCINFO lump on 2nd iteration + const char *lumpname = (k == 1 ? "MUSCINFO" : "MUSICDEF"); + lumpnum = W_CheckNumForNamePwad(lumpname, wadnum, 0); //check for MUSCINFO lump on 2nd iteration if (lumpnum == INT16_MAX) continue; @@ -1430,7 +1425,7 @@ void S_LoadMusicDefs(UINT16 wadnum) nlf = 1; else nlf = 0; - *lf++ = '\0';/* now we can delimit to here */ + *lf++ = '\0'; /* now we can delimit to here */ } stoken = strtok(stoken, " "); @@ -1452,10 +1447,10 @@ void S_LoadMusicDefs(UINT16 wadnum) } while (nlf || ncr) ; - stoken = lf;/* now the next nonempty line */ + stoken = lf; /* now the next nonempty line */ } else - break;/* EOF */ + break; /* EOF */ } free(musdeftext); diff --git a/src/w_wad.c b/src/w_wad.c index 2ac8ae68d..3b4a5824f 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1269,7 +1269,7 @@ FUNCINLINE static ATTRINLINE lumpnum_t CheckLumpInCache(const char *name) FUNCINLINE static ATTRINLINE void AddLumpToCache(lumpnum_t lumpnum, const char *name) { - I_Assert(strlen(name) <= 8); // we dont have longnames, so assume this is a non terminated string + I_Assert(strnlen(name, 9) <= 8); // we dont have longnames, so assume this is a non terminated string lumpnum_map_insert(&lumpnumcache, strdup(name), lumpnum); } -- 2.54.0 From b44e003ab97f6f6508ba04fe1d119b0573d03721 Mon Sep 17 00:00:00 2001 From: Indev Date: Sun, 29 Mar 2026 00:29:38 +0300 Subject: [PATCH 07/21] This is intended to be empty string, this way it reads the rest of the string including '=' :p --- src/s_sound.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/s_sound.c b/src/s_sound.c index 9ca078cec..59f80ac5d 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1308,7 +1308,7 @@ static boolean ReadMusicDefFields(UINT16 wadnum, int line, char *stoken, musicde } else { - value = strtok(NULL, " "); + value = strtok(NULL, ""); if (value) { @@ -1346,6 +1346,7 @@ static boolean ReadMusicDefFields(UINT16 wadnum, int line, char *stoken, musicde // turn _ into spaces. #define ADDDEF(field)\ + CONS_Printf("%s = %s\n",#field, textline); \ STRBUFCPY(def->field, textline);\ for (textline = def->field; *textline; textline++)\ if (*textline == '_') *textline = ' '; -- 2.54.0 From 6760546bcd5facc000327e8be0c56d21022193d7 Mon Sep 17 00:00:00 2001 From: Indev Date: Sun, 29 Mar 2026 00:34:11 +0300 Subject: [PATCH 08/21] I thought i reverted debug print aaaaaaaa --- src/s_sound.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/s_sound.c b/src/s_sound.c index 59f80ac5d..5b959e063 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1346,7 +1346,6 @@ static boolean ReadMusicDefFields(UINT16 wadnum, int line, char *stoken, musicde // turn _ into spaces. #define ADDDEF(field)\ - CONS_Printf("%s = %s\n",#field, textline); \ STRBUFCPY(def->field, textline);\ for (textline = def->field; *textline; textline++)\ if (*textline == '_') *textline = ' '; -- 2.54.0 From 06a9ab785e09c7b16d306d9572113ce135d1638b Mon Sep 17 00:00:00 2001 From: Alug Date: Sat, 28 Mar 2026 22:59:30 +0100 Subject: [PATCH 09/21] add misssing break K_SpawnBattlePoints oopsie, somehow this seems to never caused any issues? --- src/k_kart.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/k_kart.c b/src/k_kart.c index 3ba8ce8a2..8dc651ecc 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2372,6 +2372,7 @@ void K_SpawnBattlePoints(player_t *source, player_t *victim, UINT8 amount) break; case 3: st = S_BATTLEPOINT3A; + break; default: return; // NO STATE! } -- 2.54.0 From cd766603146018b4aee18a12e7f55219f16dc19f Mon Sep 17 00:00:00 2001 From: Alug Date: Sat, 28 Mar 2026 23:38:45 +0100 Subject: [PATCH 10/21] restore intended behavior for cvar menu categories for onchange functions --- src/lua_consolelib.c | 55 +++++++++++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 13 deletions(-) diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index f9d36e2cf..0f6b74f88 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -358,7 +358,8 @@ static int lib_cvRegisterVar(lua_State *L) #define TYPEERROR(f, t) FIELDERROR(f, va("%s expected, got %s", lua_typename(L, t), luaL_typename(L, -1))) lua_pushnil(L); - while (lua_next(L, 1)) { + while (lua_next(L, 1)) + { // stack: cvar table, cvar userdata, key/index, value // 1 2 3 4 i = 0; @@ -368,26 +369,40 @@ static int lib_cvRegisterVar(lua_State *L) else if (lua_isstring(L, 3)) k = lua_tostring(L, 3); - if (i == 1 || (k && fasticmp(k, "name"))) { + if (i == 1 || (k && fasticmp(k, "name"))) + { if (!lua_isstring(L, 4)) TYPEERROR("name", LUA_TSTRING) + cvar->name = Z_StrDup(lua_tostring(L, 4)); - } else if (i == 2 || (k && fasticmp(k, "defaultvalue"))) { + } + else if (i == 2 || (k && fasticmp(k, "defaultvalue"))) + { if (!lua_isstring(L, 4)) TYPEERROR("defaultvalue", LUA_TSTRING) + cvar->defaultvalue = Z_StrDup(lua_tostring(L, 4)); - } else if (i == 3 || (k && fasticmp(k, "flags"))) { + } + else if (i == 3 || (k && fasticmp(k, "flags"))) + { if (!lua_isnumber(L, 4)) TYPEERROR("flags", LUA_TNUMBER) + cvar->flags = (INT32)lua_tointeger(L, 4); - } else if (i == 4 || (k && fasticmp(k, "PossibleValue"))) { - if (lua_islightuserdata(L, 4)) { + } + else if (i == 4 || (k && fasticmp(k, "PossibleValue"))) + { + if (lua_islightuserdata(L, 4)) + { CV_PossibleValue_t *pv = lua_touserdata(L, 4); + if (pv == CV_OnOff || pv == CV_YesNo || pv == CV_Unsigned || pv == CV_Natural) cvar->PossibleValue = pv; else FIELDERROR("PossibleValue", "CV_PossibleValue_t expected, got unrecognised pointer") - } else if (lua_istable(L, 4)) { + } + else if (lua_istable(L, 4)) + { // Accepts tables in the form of {MIN=0, MAX=9999} or {Red=0, Green=1, Blue=2} // and converts them to CV_PossibleValue_t {{0,"MIN"},{9999,"MAX"}} or {{0,"Red"},{1,"Green"},{2,"Blue"}} // @@ -398,7 +413,9 @@ static int lib_cvRegisterVar(lua_State *L) CV_PossibleValue_t *cvpv; lua_pushnil(L); - while (lua_next(L, 4)) { + + while (lua_next(L, 4)) + { count++; lua_pop(L, 1); } @@ -412,7 +429,9 @@ static int lib_cvRegisterVar(lua_State *L) i = 0; lua_pushnil(L); - while (lua_next(L, 4)) { + + while (lua_next(L, 4)) + { // stack: [...] PossibleValue table, index, value // 4 5 6 if (lua_type(L, 5) != LUA_TSTRING @@ -423,14 +442,19 @@ static int lib_cvRegisterVar(lua_State *L) i++; lua_pop(L, 1); } + cvpv[i].value = 0; cvpv[i].strvalue = NULL; cvar->PossibleValue = cvpv; - } else + } + else FIELDERROR("PossibleValue", va("%s or CV_PossibleValue_t expected, got %s", lua_typename(L, LUA_TTABLE), luaL_typename(L, -1))) - } else if (i == 5 || (k && fasticmp(k, "func"))) { + } + else if (i == 5 || (k && fasticmp(k, "func"))) + { if (!lua_isfunction(L, 4)) TYPEERROR("func", LUA_TFUNCTION) + lua_getfield(L, LUA_REGISTRYINDEX, "CV_OnChange"); I_Assert(lua_istable(L, 5)); lua_pushlightuserdata(L, cvar); @@ -438,9 +462,13 @@ static int lib_cvRegisterVar(lua_State *L) lua_rawset(L, 5); lua_pop(L, 1); cvar->func = Lua_OnChange; + + if (i == 5 && !(cvar->flags & CV_CALL)) + { + category = lua_isnoneornil(L, 4) ? NULL : lua_tostring(L, 4); + } } - else if (((i == 5 && !(cvar->flags & CV_CALL)) - || (cvar->flags & CV_CALL && i == 6)) + else if ((cvar->flags & CV_CALL && i == 6) || (k && fasticmp(k, "category"))) { category = lua_isnoneornil(L, 4) ? NULL : lua_tostring(L, 4); @@ -451,6 +479,7 @@ static int lib_cvRegisterVar(lua_State *L) { menu_name = lua_isnoneornil(L, 4) ? NULL : lua_tostring(L, 4); } + lua_pop(L, 1); } #undef FIELDERROR -- 2.54.0 From 17d72e02fe6cf0f9f18ed5b3cf973a0cc497b499 Mon Sep 17 00:00:00 2001 From: Alug Date: Sat, 28 Mar 2026 23:39:17 +0100 Subject: [PATCH 11/21] cleanup some redundant/dead code --- src/command.c | 2 +- src/console.c | 2 +- src/d_clisrv.c | 18 ++++------ src/g_demo.c | 72 +++++++++++++++++---------------------- src/g_game.c | 1 - src/hardware/hw_draw.c | 4 +-- src/k_hud.c | 4 +-- src/k_kart.c | 11 ++---- src/lua_hudlib_drawlist.c | 57 +++++++++++++++---------------- src/m_menu.c | 2 +- src/m_textinput.c | 10 +++--- src/p_enemy.c | 8 ++--- src/p_inter.c | 22 +----------- src/p_local.h | 1 - src/p_user.c | 38 +++------------------ src/r_bsp.cpp | 1 - src/r_data.c | 44 +----------------------- src/r_data.h | 3 -- src/r_plane.cpp | 5 +-- src/r_things.h | 2 +- src/st_stuff.c | 2 +- src/y_inter.c | 10 ------ 22 files changed, 94 insertions(+), 225 deletions(-) diff --git a/src/command.c b/src/command.c index c37b8f1d3..be46e2505 100644 --- a/src/command.c +++ b/src/command.c @@ -1194,7 +1194,7 @@ consvar_t *CV_FindVar(const char *name) static inline UINT16 CV_ComputeNetid(const char *s) { UINT16 ret = 0, i = 0; - static UINT16 premiers[16] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53}; + static const UINT16 premiers[16] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53}; while (*s) { diff --git a/src/console.c b/src/console.c index df7fc299d..50d10d020 100644 --- a/src/console.c +++ b/src/console.c @@ -852,7 +852,7 @@ boolean CON_Responder(event_t *ev) return true; // ctrl modifier -- changes behavior, adds shortcuts - if (ctrldown && (cv_keyboardlayout.value != 3 || (cv_keyboardlayout.value == 3 && !altdown))) + if (ctrldown && (cv_keyboardlayout.value != 3 || !altdown)) { // show all cvars/commands that match what we have inputted if (key == KEY_TAB) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 02febde12..f5e32b2e0 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2509,7 +2509,7 @@ static boolean CL_FinishedFileList(void) * \sa CL_ConnectToServer * */ -static boolean CL_ServerConnectionSearchTicker(tic_t *asksent) +static void CL_ServerConnectionSearchTicker(tic_t *asksent) { INT32 i; @@ -2527,7 +2527,7 @@ static boolean CL_ServerConnectionSearchTicker(tic_t *asksent) { i = SL_SearchServer(servernode); if (i < 0) - return true; + return; } joinnode = i; @@ -2555,7 +2555,7 @@ static boolean CL_ServerConnectionSearchTicker(tic_t *asksent) { cl_mode = CL_ASKFULLFILELIST; cl_lastcheckedfilecount = 0; - return true; + return; } cl_mode = cv_serverinfoscreen.value ? CL_VIEWSERVER : CL_CHECKFILES; @@ -2566,7 +2566,7 @@ static boolean CL_ServerConnectionSearchTicker(tic_t *asksent) *asksent = 0; } - return true; + return; } // Ask the info to the server (askinfo packet) @@ -2576,7 +2576,6 @@ static boolean CL_ServerConnectionSearchTicker(tic_t *asksent) *asksent = I_GetTime() + NEWTICRATE; } - return true; } static void FreeMapIcon(void) @@ -2608,8 +2607,7 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic switch (cl_mode) { case CL_SEARCHING: - if (!CL_ServerConnectionSearchTicker(asksent)) - return false; + CL_ServerConnectionSearchTicker(asksent); break; case CL_ASKFULLFILELIST: @@ -5905,13 +5903,11 @@ static void PT_ServerTics(SINT8 node) realend = gametic + CLIENTBACKUPTICS; cl_packetmissed = realstart > neededtic; - UINT8 *pak = (UINT8 *)&packet->cmds; - UINT8 *txtpak = (UINT8 *)&packet->cmds[packet->numslots * packet->numtics]; - if (realstart <= neededtic && realend > neededtic) { tic_t i, j; - pak = (UINT8 *)&packet->cmds; + UINT8 *pak = (UINT8 *)&packet->cmds; + UINT8 *txtpak = (UINT8 *)&packet->cmds[packet->numslots * packet->numtics]; for (i = realstart; i < realend; i++) { diff --git a/src/g_demo.c b/src/g_demo.c index 4acbba9f5..c36b3273b 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -1996,7 +1996,6 @@ static UINT8 G_CheckDemoExtraFiles(UINT8 **pp, boolean quick) UINT8 totalfiles, filesloaded, nmusfilecount; char filename[MAX_WADPATH]; UINT8 md5sum[16]; - boolean toomany = false; boolean alreadyloaded; UINT8 i, j; UINT8 error = 0; @@ -2006,53 +2005,44 @@ static UINT8 G_CheckDemoExtraFiles(UINT8 **pp, boolean quick) for (i = 0; i < totalfiles; ++i) { - if (toomany) - SKIPSTRING((*pp)); - else - { - strlcpy(filename, (char *)(*pp), sizeof filename); - SKIPSTRING((*pp)); - } + strlcpy(filename, (char *)(*pp), sizeof filename); + SKIPSTRING((*pp)); READMEM((*pp), md5sum, 16); // hue hue peepee - if (!toomany) + alreadyloaded = false; + nmusfilecount = 0; + + for (j = 0; j < numwadfiles; ++j) { - alreadyloaded = false; - nmusfilecount = 0; - - for (j = 0; j < numwadfiles; ++j) - { - if (wadfiles[j]->important && j > mainwads) - nmusfilecount++; - else - continue; - - if (memcmp(md5sum, wadfiles[j]->md5sum, 16) == 0) - { - alreadyloaded = true; - - if (i != nmusfilecount-1 && error < DFILE_ERROR_OUTOFORDER) - error |= DFILE_ERROR_OUTOFORDER; - - break; - } - } - - if (alreadyloaded) - { - filesloaded++; + if (wadfiles[j]->important && j > mainwads) + nmusfilecount++; + else continue; - } - if (numwadfiles >= MAX_WADFILES) - error = DFILE_ERROR_CANNOTLOAD; - else if (!quick && findfile(filename, md5sum, false) != FS_FOUND) - error = DFILE_ERROR_CANNOTLOAD; - else if (error < DFILE_ERROR_INCOMPLETEOUTOFORDER) - error |= DFILE_ERROR_NOTLOADED; - } else + if (memcmp(md5sum, wadfiles[j]->md5sum, 16) == 0) + { + alreadyloaded = true; + + if (i != nmusfilecount-1 && error < DFILE_ERROR_OUTOFORDER) + error |= DFILE_ERROR_OUTOFORDER; + + break; + } + } + + if (alreadyloaded) + { + filesloaded++; + continue; + } + + if (numwadfiles >= MAX_WADFILES) error = DFILE_ERROR_CANNOTLOAD; + else if (!quick && findfile(filename, md5sum, false) != FS_FOUND) + error = DFILE_ERROR_CANNOTLOAD; + else if (error < DFILE_ERROR_INCOMPLETEOUTOFORDER) + error |= DFILE_ERROR_NOTLOADED; } // Get final file count diff --git a/src/g_game.c b/src/g_game.c index 6b01b2bdc..f41e7ad79 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -4047,7 +4047,6 @@ void G_InitNew(UINT8 pencoremode, const char *mapname, boolean resetplayer, bool if (W_CheckNumForName(mapname) == LUMPERROR) { I_Error("Internal game map '%s' not found\n", mapname); - Command_ExitGame_f(); return; } diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index 3602cef1b..7bccbe198 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -150,7 +150,7 @@ void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t p if (!column->topdelta) { const UINT8 *source = (const UINT8 *)(column) + 3; - HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0])); + HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, source[0]); } } @@ -302,7 +302,7 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, if (!column->topdelta) { const UINT8 *source = (const UINT8 *)(column) + 3; - HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0])); + HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, source[0]); } } diff --git a/src/k_hud.c b/src/k_hud.c index 3fc83c10b..3ec17ddd0 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -2094,7 +2094,7 @@ static void K_DrawKartPositionNum(INT32 num) fy = POSI_Y; fflags = V_SNAPTOLEFT|((stplyrnum == 2) ? V_SPLITSCREEN|V_SNAPTOBOTTOM : 0); // flip P3 to the bottom. flipdraw = true; - if (num && num >= 10) + if (num >= 10) fx += W; // this seems dumb, but we need to do this in order for positions above 10 going off screen. } else // else, that means we're P2 or P4. @@ -4076,7 +4076,7 @@ static void K_drawBattleFullscreen(void) { if (i == displayplayers[0]) continue; - if (playeringame[i] && !stplyr->spectator) + if (playeringame[i]) return; } diff --git a/src/k_kart.c b/src/k_kart.c index 8dc651ecc..ec312cc3b 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1955,11 +1955,9 @@ static void K_PlayGenericCombatSound(mobj_t *source, mobj_t *other, sfxenum_t sf if (!skin) return; - boolean alwaysHear = false; - if (cv_kartvoices.value && !P_MobjWasRemoved(other) && other->player != NULL) { - alwaysHear = P_IsDisplayPlayer(other->player); + boolean alwaysHear = P_IsDisplayPlayer(other->player); S_StartSound(alwaysHear ? NULL : source, skin->soundsid[S_sfx[sfx_id].skinsound]); } @@ -3678,10 +3676,8 @@ mobj_t *K_SpawnWipeoutTrail(mobj_t *mo, boolean translucent) dust->momx = mo->momx/2; dust->momy = mo->momy/2; dust->momz = mo->momz/2; - } - - if (translucent) dust->flags2 |= MF2_SHADOW; + } return dust; } @@ -4658,8 +4654,7 @@ void K_RepairOrbitChain(mobj_t *orbit) prev->movedir = num; } - if (player->kartstuff[k_itemamount] != num) - player->kartstuff[k_itemamount] = num; + player->kartstuff[k_itemamount] = num; } } diff --git a/src/lua_hudlib_drawlist.c b/src/lua_hudlib_drawlist.c index 6d3542c48..d2b2eeeb4 100644 --- a/src/lua_hudlib_drawlist.c +++ b/src/lua_hudlib_drawlist.c @@ -650,34 +650,34 @@ void LUA_HUD_DrawList(huddrawlist_h list) case DI_DrawString: switch(item->align) { - // hu_font - case align_left: - V_DrawString(LERPS(x), LERPS(y), item->flags, itemstr); - break; - case align_center: - V_DrawCenteredString(LERPS(x), LERPS(y), item->flags, itemstr); - break; - case align_right: - V_DrawRightAlignedString(LERPS(x), LERPS(y), item->flags, itemstr); - break; - case align_fixed: - V_DrawStringAtFixed(LERPS(x), LERPS(y), item->flags, itemstr); - break; - // hu_font, 0.5x scale - case align_small: - V_DrawSmallString(LERPS(x), LERPS(y), item->flags, itemstr); - break; - case align_smallright: - V_DrawRightAlignedSmallString(LERPS(x), LERPS(y), item->flags, itemstr); - break; - // tny_font - case align_thin: - V_DrawThinString(LERPS(x), LERPS(y), item->flags, itemstr); - break; - case align_thinright: - V_DrawRightAlignedThinString(LERPS(x), LERPS(y), item->flags, itemstr); - break; - } + // hu_font + case align_left: + V_DrawString(LERPS(x), LERPS(y), item->flags, itemstr); + break; + case align_center: + V_DrawCenteredString(LERPS(x), LERPS(y), item->flags, itemstr); + break; + case align_right: + V_DrawRightAlignedString(LERPS(x), LERPS(y), item->flags, itemstr); + break; + case align_fixed: + V_DrawStringAtFixed(LERPS(x), LERPS(y), item->flags, itemstr); + break; + // hu_font, 0.5x scale + case align_small: + V_DrawSmallString(LERPS(x), LERPS(y), item->flags, itemstr); + break; + case align_smallright: + V_DrawRightAlignedSmallString(LERPS(x), LERPS(y), item->flags, itemstr); + break; + // tny_font + case align_thin: + V_DrawThinString(LERPS(x), LERPS(y), item->flags, itemstr); + break; + case align_thinright: + V_DrawRightAlignedThinString(LERPS(x), LERPS(y), item->flags, itemstr); + break; + } break; case DI_DrawKartString: V_DrawKartString(LERPS(x), LERPS(y), item->flags, itemstr); @@ -690,7 +690,6 @@ void LUA_HUD_DrawList(huddrawlist_h list) break; default: I_Error("can't draw draw list item: invalid draw list item type"); - continue; } } } diff --git a/src/m_menu.c b/src/m_menu.c index cfc854d36..01b106d95 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -5418,7 +5418,7 @@ void M_SlotCvarIntoModMenu(consvar_t* cvar, const char* category, const char* na } if (cvar->flags & CV_NETVAR) - OP_CustomCvarMenu[ccvarposition] = (menuitem_t){ IT_STRING | IT_CVAR , NULL, Z_StrDup(va("\x85 %s", name)), cvar, ccvaralphakey }; + OP_CustomCvarMenu[ccvarposition] = (menuitem_t){ IT_STRING | IT_CVAR, NULL, Z_StrDup(va("\x85 %s", name)), cvar, ccvaralphakey }; else OP_CustomCvarMenu[ccvarposition] = (menuitem_t){ IT_STRING | IT_CVAR, NULL, Z_StrDup(name), cvar, ccvaralphakey }; diff --git a/src/m_textinput.c b/src/m_textinput.c index c49294094..a7c048e66 100644 --- a/src/m_textinput.c +++ b/src/m_textinput.c @@ -256,7 +256,7 @@ static boolean M_TextInputHandleBase(textinput_t *input, INT32 key, boolean emot return true; } - if (ctrldown && (cv_keyboardlayout.value != 3 || (cv_keyboardlayout.value == 3 && !altdown))) + if (ctrldown && (cv_keyboardlayout.value!=3 || !altdown)) { if (key == 'x' || key == 'X') { @@ -381,10 +381,10 @@ static boolean M_TextInputHandleBase(textinput_t *input, INT32 key, boolean emot // allow people to use keypad in console (good for typing IP addresses) - Calum if (key >= KEY_KEYPAD7 && key <= KEY_KPADDEL) { - char keypad_translation[] = {'7','8','9','-', - '4','5','6','+', - '1','2','3', - '0','.'}; + const char keypad_translation[] = {'7','8','9','-', + '4','5','6','+', + '1','2','3', + '0', '.'}; key = keypad_translation[key - KEY_KEYPAD7]; } diff --git a/src/p_enemy.c b/src/p_enemy.c index d1c96d6f7..cb9b16f2d 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3650,7 +3650,7 @@ static inline boolean PIT_GrenadeRing(mobj_t *thing) return true; if (thing->player && (thing->player->kartstuff[k_hyudorotimer] - || (G_BattleGametype() && thing->player && thing->player->kartstuff[k_bumper] <= 0 && thing->player->kartstuff[k_comebacktimer]))) + || (G_BattleGametype() && thing->player->kartstuff[k_bumper] <= 0 && thing->player->kartstuff[k_comebacktimer]))) return true; if ((gametype == GT_CTF || gametype == GT_TEAMMATCH) @@ -5301,7 +5301,7 @@ void A_MixUp(void *thing) if (playeringame[i] && players[i].mo && players[i].mo->health > 0 && players[i].playerstate == PST_LIVE && !players[i].exiting && !players[i].powers[pw_super]) { - if ((netgame || multiplayer) && players[i].spectator) // Ignore spectators + if (netgame && players[i].spectator) // Ignore spectators continue; numplayers++; @@ -7923,7 +7923,7 @@ void A_ItemPop(void *thing) if (!(actor->target && actor->target->player)) { - if (cv_debug && !(actor->target && actor->target->player)) + if (cv_debug) CONS_Printf("ERROR: Powerup has no target!\n"); return; } @@ -8785,7 +8785,7 @@ void A_ReaperThinker(void *thing) actor->angle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y); // The player we should target if it's near us: - for (i = 0; ipowers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL) - return; - if (UNLIKELY(maptol & TOL_NIGHTS)) - return; - if (UNLIKELY(mariomode)) - return; - else if (toucher->eflags & MFE_VERTICALFLIP) - { - if (special->z+special->height < toucher->z + toucher->height / 3 - || special->z+special->height > toucher->z + (toucher->height*2/3)) - return; // Only go in the mouth - } - else if (special->z < toucher->z + toucher->height / 3 - || special->z > toucher->z + (toucher->height*2/3)) - return; // Only go in the mouth - - toucher->momx = toucher->momy = toucher->momz = 0; - break; case MT_WATERDROP: if (special->state == &states[special->info->spawnstate]) @@ -1877,11 +1859,9 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source) P_SetThingPosition(target); P_InstaThrust(target,target->angle,FixedMul(2*FRACUNIT, target->scale)); target->momz = FixedMul(7*FRACUNIT, target->scale); - if (flip) - target->momz = -target->momz; - if (flip) { + target->momz = -target->momz; target = P_SpawnMobj(x,y,z-FixedMul(12*FRACUNIT, target->scale),MT_SPIKE); target->eflags |= MFE_VERTICALFLIP; } diff --git a/src/p_local.h b/src/p_local.h index 518bc12cb..95020c022 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -212,7 +212,6 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj); void P_GivePlayerRings(player_t *player, INT32 num_rings); void P_GivePlayerLives(player_t *player, INT32 numlives); UINT8 P_GetNextEmerald(void); -void P_GiveEmerald(boolean spawnObj); void P_ResetScore(player_t *player); boolean P_AutoPause(void); diff --git a/src/p_user.c b/src/p_user.c index 7c4756bfa..f57739c92 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -220,32 +220,6 @@ UINT8 P_GetNextEmerald(void) return (UINT8)(gamemap - sstage_start); } -// -// P_GiveEmerald -// -// Award an emerald upon completion -// of a special stage. -// -void P_GiveEmerald(boolean spawnObj) -{ - INT32 i; - UINT8 em; - - S_StartSound(NULL, sfx_cgot); // Got the emerald! - em = P_GetNextEmerald(); - emeralds |= (1 << em); - - if (spawnObj) - { - for (i = 0; i < MAXPLAYERS; i++) - { - if (playeringame[i]) - P_SetMobjState(P_SpawnMobj(players[i].mo->x, players[i].mo->y, players[i].mo->z + players[i].mo->info->height, MT_GOTEMERALD), - mobjinfo[MT_GOTEMERALD].spawnstate + em); - } - } -} - // // P_ResetScore // @@ -1226,7 +1200,6 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj) ghost->pitch = mobj->pitch; ghost->roll = mobj->roll; - ghost->sloperoll = mobj->sloperoll; ghost->rollangle = mobj->rollangle; ghost->sloperoll = mobj->sloperoll; ghost->slopepitch = mobj->slopepitch; @@ -3130,19 +3103,16 @@ void P_ToggleDemoCamera(UINT8 viewnum) return; } - if (!cam->freecam) // toggle on + if (!cam->freecam) // toggle on { cam->freecam = true; cam->button_a_held = 2; cam->reset_aiming = true; // get rid of some hud elements - if (displayplayers[0] != consoleplayer) - { - displayplayers[0] = consoleplayer; - } + displayplayers[0] = consoleplayer; } - else // toggle off + else // toggle off { cam->freecam = false; G_FixCamera(viewnum+1); @@ -4056,7 +4026,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall if (timeover) thiscam->angle = angle; - else if (!camstill && !resetcalled && !paused && timeover != 1) + else if (!camstill && !resetcalled && !paused) thiscam->angle = R_PointToAngle2(thiscam->x, thiscam->y, viewpointx, viewpointy); if (timeover == 1) diff --git a/src/r_bsp.cpp b/src/r_bsp.cpp index 55a475c9d..60d84c57f 100644 --- a/src/r_bsp.cpp +++ b/src/r_bsp.cpp @@ -991,7 +991,6 @@ static void R_Subsector(size_t num) visffloor[numffloors].height = polysec->floorheight; visffloor[numffloors].polyobj = po; visffloor[numffloors].slope = NULL; -// visffloor[numffloors].ffloor = rover; po->visplane = visffloor[numffloors].plane; numffloors++; } diff --git a/src/r_data.c b/src/r_data.c index 43ff16cbb..507696925 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -37,44 +37,6 @@ // Not sure if this is necessary, but it was in w_wad.c, so I'm putting it here too -Shadow Hog #include -// -// Texture definition. -// Each texture is composed of one or more patches, -// with patches being lumps stored in the WAD. -// The lumps are referenced by number, and patched -// into the rectangular texture space using origin -// and possibly other attributes. -// -typedef struct -{ - INT16 originx, originy; - INT16 patch, stepdir, colormap; -} ATTRPACK mappatch_t; - -// -// Texture definition. -// An SRB2 wall texture is a list of patches -// which are to be combined in a predefined order. -// -typedef struct -{ - char name[8]; - INT32 masked; - INT16 width; - INT16 height; - INT32 columndirectory; // FIXTHIS: OBSOLETE - INT16 patchcount; - mappatch_t patches[1]; -} ATTRPACK maptexture_t; - -// Store lists of lumps for F_START/F_END etc. -typedef struct -{ - UINT16 wadfile; - UINT16 firstlump; - size_t numlumps; -} lumplist_t; - // // Graphics. // SRB2 graphics for walls and sprites @@ -836,11 +798,7 @@ static texpatch_t *R_ParsePatch(boolean actuallyLoadPatch) } else { - if (patchName != NULL) - { - Z_Free(patchName); - } - + Z_Free(patchName); patchName = (char *)Z_Malloc((texturesTokenLength+1)*sizeof(char),PU_STATIC,NULL); memcpy(patchName,texturesToken,texturesTokenLength*sizeof(char)); patchName[texturesTokenLength] = '\0'; diff --git a/src/r_data.h b/src/r_data.h index 090c363ed..168f72bf0 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -45,9 +45,6 @@ enum TEXTURETYPE_COMPOSITE, }; -// A maptexturedef_t describes a rectangular texture, -// which is composed of one or more mappatch_t structures -// that arrange graphic patches. typedef struct { // Keep name for switch changing, etc. diff --git a/src/r_plane.cpp b/src/r_plane.cpp index 05c4d943a..a6a52fe83 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -1282,10 +1282,7 @@ void R_DrawSinglePlane(drawspandata_t* ds, visplane_t *pl, boolean allow_paralle else { // Don't mess with angle on slopes! We'll handle this ourselves later - if (viewangle != pl->viewangle + pl->plangle) - { - viewangle = pl->viewangle + pl->plangle; - } + viewangle = pl->viewangle + pl->plangle; ds->planeheight = abs(pl->height - pl->viewz); ds->planezlight = zlight[light]; diff --git a/src/r_things.h b/src/r_things.h index c8195891a..e8e30ca6b 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -50,7 +50,7 @@ extern fixed_t windowtop; extern fixed_t windowbottom; extern INT32 lengthcol; -FUNCINLINE static ATTRINLINE INT32 R_ThingLightLevel(mobj_t* thing) +FUNCINLINE static ATTRINLINE INT32 R_ThingLightLevel(const mobj_t* thing) { return (INT32)thing->lightlevel; } diff --git a/src/st_stuff.c b/src/st_stuff.c index 64bc4dc00..57a7c6e29 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -185,7 +185,7 @@ static void ST_doPaletteStuff(void) #endif if (stplyr && stplyr->flashcount) - palette = CLAMP(stplyr->flashpal, 0, 13); + palette = min(stplyr->flashpal, 13); if (palette != st_palette) { diff --git a/src/y_inter.c b/src/y_inter.c index 27e794ffc..684797999 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -51,13 +51,6 @@ #include "hardware/hw_main.h" #endif -typedef struct -{ - char patch[9]; - INT32 points; - UINT8 display; -} y_bonus_t; - static y_data_t data; // graphics @@ -1609,9 +1602,6 @@ void Y_SetupVoteFinish(SINT8 pick, SINT8 level) if (votes[i] == -1 || endtype > 1) // Don't need to go on continue; - if (endtype == 2) - continue; - if (votecompare == -1) { votecompare = votes[i]; -- 2.54.0 From 621df7e29695900de025c7bde5a8f95ac9fd60fa Mon Sep 17 00:00:00 2001 From: Alug Date: Sat, 28 Mar 2026 23:36:10 +0100 Subject: [PATCH 12/21] v_video: make stringwidth loops safer --- src/v_video.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/v_video.c b/src/v_video.c index 29857dd74..078e65b3c 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -3235,7 +3235,7 @@ INT32 V_SubStringWidth(const char *string, INT32 length, INT32 option) break; } - for (i = 0; string[i] && i < length; i++) + for (i = 0; i < length && string[i]; i++) { c = string[i]; if ((UINT8)c >= 0x80 && (UINT8)c <= 0x8F) //color parsing! -Inuyasha 2.16.09 @@ -3280,7 +3280,7 @@ INT32 V_SmallSubStringWidth(const char *string, INT32 length, INT32 option) break; } - for (i = 0; string[i] && i < length; i++) + for (i = 0; i < length && string[i]; i++) { c = string[i]; if ((UINT8)c >= 0x80 && (UINT8)c <= 0x8F) //color parsing! -Inuyasha 2.16.09 @@ -3329,7 +3329,7 @@ INT32 V_ThinSubStringWidth(const char *string, INT32 length, INT32 option) break; } - for (i = 0; string[i] && i < length; i++) + for (i = 0; i < length && string[i]; i++) { c = string[i]; if ((UINT8)c >= 0x80 && (UINT8)c <= 0x8F) //color parsing! -Inuyasha 2.16.09 -- 2.54.0 From 0fadfe0f72cfd1739db137248489ccb2bd7c89d5 Mon Sep 17 00:00:00 2001 From: Alug Date: Sun, 29 Mar 2026 10:58:29 +0200 Subject: [PATCH 13/21] dehacked: fixup lua_enumlib_sprintf_upper apparently reusing a va list like that is ub, so we should just copy it if we want to reuse it also fix the resize check, since vsnprintf return does not include 0 terminator which we need to account for also make this part of dehacked.c a bit more readable lol --- src/dehacked.c | 134 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 106 insertions(+), 28 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 38f713092..a4082c6f2 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8208,84 +8208,109 @@ struct { {NULL,0} }; +// Returns the vlaue of MT_ enumerations static mobjtype_t get_mobjtype(const char *word) -{ // Returns the vlaue of MT_ enumerations +{ mobjtype_t i; + if (*word >= '0' && *word <= '9') return atoi(word); + if (fastncmp("MT_",word,3)) word += 3; // take off the MT_ - for (i = 0; i < NUMMOBJFREESLOTS; i++) { + + for (i = 0; i < NUMMOBJFREESLOTS; i++) + { if (!FREE_MOBJS[i]) break; if (fastcmp(word, FREE_MOBJS[i])) return MT_FIRSTFREESLOT+i; } + for (i = 0; i < MT_FIRSTFREESLOT; i++) if (fastcmp(word, MOBJTYPE_LIST[i]+3)) return i; + deh_warning("Couldn't find mobjtype named 'MT_%s'",word); return MT_BLUECRAWLA; } +// Returns the value of S_ enumerations static statenum_t get_state(const char *word) -{ // Returns the value of S_ enumerations +{ statenum_t i; if (*word >= '0' && *word <= '9') return atoi(word); + if (fastncmp("S_",word,2)) word += 2; // take off the S_ - for (i = 0; i < NUMSTATEFREESLOTS; i++) { + + for (i = 0; i < NUMSTATEFREESLOTS; i++) + { if (!FREE_STATES[i]) break; + if (fastcmp(word, FREE_STATES[i])) return S_FIRSTFREESLOT+i; } + for (i = 0; i < S_FIRSTFREESLOT; i++) if (fastcmp(word, STATE_LIST[i]+2)) return i; + deh_warning("Couldn't find state named 'S_%s'",word); return S_NULL; } +// Returns the value of SPR_ enumerations static spritenum_t get_sprite(const char *word) -{ // Returns the value of SPR_ enumerations +{ spritenum_t i; if (*word >= '0' && *word <= '9') return atoi(word); + if (fastncmp("SPR_",word,4)) word += 4; // take off the SPR_ + for (i = 0; i < NUMSPRITES; i++) - if (!sprnames[i][4] && memcmp(word,sprnames[i],4)==0) + if (!sprnames[i][4] && memcmp(word,sprnames[i],4) == 0) return i; + deh_warning("Couldn't find sprite named 'SPR_%s'",word); return SPR_NULL; } +// Returns the value of SFX_ enumerations static sfxenum_t get_sfx(const char *word) -{ // Returns the value of SFX_ enumerations +{ sfxenum_t i; + if (*word >= '0' && *word <= '9') return atoi(word); + if (fastncmp("SFX_",word,4)) word += 4; // take off the SFX_ else if (fastncmp("DS",word,2)) word += 2; // take off the DS + for (i = 0; i < NUMSFX; i++) if (S_sfx[i].name && fasticmp(word, S_sfx[i].name)) return i; + deh_warning("Couldn't find sfx named 'SFX_%s'",word); return sfx_None; } #ifdef MUSICSLOT_COMPATIBILITY +// Returns the value of MUS_ enumerations static UINT16 get_mus(const char *word, UINT8 dehacked_mode) -{ // Returns the value of MUS_ enumerations +{ UINT16 i; char lumptmp[4]; if (*word >= '0' && *word <= '9') return atoi(word); + if (!word[2] && toupper(word[0]) >= 'A' && toupper(word[0]) <= 'Z') return (UINT16)M_MapNumber(word[0], word[1]); @@ -8309,25 +8334,33 @@ static UINT16 get_mus(const char *word, UINT8 dehacked_mode) deh_warning("Couldn't find music named 'MUS_%s'",word); return 0; } + for (i = 0; compat_special_music_slots[i][0]; ++i) if (fasticmp(word, compat_special_music_slots[i])) return i + 1036; + if (dehacked_mode) deh_warning("Couldn't find music named 'MUS_%s'",word); + return 0; } #endif +// Returns the value of HUD_ enumerations static hudnum_t get_huditem(const char *word) -{ // Returns the value of HUD_ enumerations +{ hudnum_t i; + if (*word >= '0' && *word <= '9') return atoi(word); + if (fastncmp("HUD_",word,4)) word += 4; // take off the HUD_ + for (i = 0; i < NUMHUDITEMS; i++) if (fastcmp(word, HUDITEMS_LIST[i])) return i; + deh_warning("Couldn't find huditem named 'HUD_%s'",word); return HUD_LIVESNAME; } @@ -8374,15 +8407,16 @@ static inline int lib_freeslot(lua_State *L) { int n = lua_gettop(L); int r = 0; // args returned - char *s, *type,*word; + char *s, *type, *word; - while (n-- > 0) - { + while (n-- > 0) + { s = Z_StrDup(luaL_checkstring(L,1)); type = strtok(s, "_"); if (type) strupr(type); - else { + else + { Z_Free(s); return luaL_error(L, "Unknown enum type in '%s'\n", luaL_checkstring(L, 1)); } @@ -8390,19 +8424,25 @@ static inline int lib_freeslot(lua_State *L) word = strtok(NULL, "\n"); if (word) strupr(word); - else { + else + { Z_Free(s); return luaL_error(L, "Missing enum name in '%s'\n", luaL_checkstring(L, 1)); } - if (fastcmp(type, "SFX")) { + + if (fastcmp(type, "SFX")) + { sfxenum_t sfx; strlwr(word); CONS_Printf("Sound sfx_%s allocated.\n",word); sfx = S_AddSoundFx(word, false, 0, false); - if (sfx != sfx_None) { + + if (sfx != sfx_None) + { lua_pushinteger(L, sfx); r++; - } else + } + else I_Error("Out of Sfx Freeslots while allocating \"%s\"\nLoad less addons to fix this.", word); //Should never get here since S_AddSoundFx was changed to throw I_Error when it can't allocate } else if (fastcmp(type, "SPR")) @@ -8416,7 +8456,7 @@ static inline int lib_freeslot(lua_State *L) { if (used_spr[(j-SPR_FIRSTFREESLOT)/8] & (1<<(j%8))) { - if (!sprnames[j][4] && memcmp(sprnames[j],word,4)==0) + if (!sprnames[j][4] && memcmp(sprnames[j], word, 4) == 0) sprnames[j][4] = wad; continue; // Already allocated, next. } @@ -8434,6 +8474,7 @@ static inline int lib_freeslot(lua_State *L) r++; break; } + if (j > SPR_LASTFREESLOT) I_Error("Out of Sprite Freeslots while allocating \"%s\"\nLoad less addons to fix this.", word); } @@ -8441,7 +8482,9 @@ static inline int lib_freeslot(lua_State *L) { statenum_t i; for (i = 0; i < NUMSTATEFREESLOTS; i++) - if (!FREE_STATES[i]) { + { + if (!FREE_STATES[i]) + { CONS_Printf("State S_%s allocated.\n",word); lua_pushcfunction(L, lua_glib_invalidate_cache); @@ -8455,6 +8498,8 @@ static inline int lib_freeslot(lua_State *L) r++; break; } + } + if (i == NUMSTATEFREESLOTS) I_Error("Out of State Freeslots while allocating \"%s\"\nLoad less addons to fix this.", word); } @@ -8462,7 +8507,9 @@ static inline int lib_freeslot(lua_State *L) { mobjtype_t i; for (i = 0; i < NUMMOBJFREESLOTS; i++) - if (!FREE_MOBJS[i]) { + { + if (!FREE_MOBJS[i]) + { CONS_Printf("MobjType MT_%s allocated.\n",word); lua_pushcfunction(L, lua_glib_invalidate_cache); @@ -8476,13 +8523,17 @@ static inline int lib_freeslot(lua_State *L) r++; break; } + } + if (i == NUMMOBJFREESLOTS) I_Error("Out of Mobj Freeslots while allocating \"%s\"\nLoad less addons to fix this.", word); } + Z_Free(s); lua_remove(L, 1); continue; } + return r; } @@ -8495,8 +8546,10 @@ static inline int lib_action(lua_State *L) mobj_t *actor = *((mobj_t **)luaL_checkudata(L,1,META_MOBJ)); var1 = (INT32)luaL_optinteger(L,2,0); var2 = (INT32)luaL_optinteger(L,3,0); + if (!actor) return LUA_ErrInvalid(L, "mobj_t"); + (*action)(actor); return 0; } @@ -8518,23 +8571,29 @@ FUNCINLINE static ATTRINLINE int lib_getenum(lua_State *L) const char *word; boolean mathlib = lua_toboolean(L, UV_MATHLIB); + if (lua_type(L,2) != LUA_TSTRING) return 0; + word = lua_tostring(L,2); /* First check actions, as they can be overridden. */ - if (!mathlib && fastncmp("A_",word,2)) { + if (!mathlib && fastncmp("A_",word,2)) + { char *caps; // Try to get a Lua action first. /// \todo Push a closure that sets superactions[] and superstack. lua_getfield(L, LUA_REGISTRYINDEX, LREG_ACTIONS); + // actions are stored in all uppercase. caps = Z_StrDup(word); strupr(caps); lua_getfield(L, -1, caps); Z_Free(caps); + if (!lua_isnil(L, -1)) return 1; // Success! :D That was easy. + // Welp, that failed. lua_pop(L, 2); // pop nil and LREG_ACTIONS // Hardcoded actions are handled by the proxy. @@ -8543,12 +8602,14 @@ FUNCINLINE static ATTRINLINE int lib_getenum(lua_State *L) /* Then check the globals proxy table. */ lua_pushvalue(L, 2); lua_gettable(L, GLIB_PROXY); + if (!lua_isnil(L, -1)) { return 1; } - if (mathlib) return luaL_error(L, "constant '%s' could not be parsed.\n", word); + if (mathlib) + return luaL_error(L, "constant '%s' could not be parsed.\n", word); return 0; } @@ -8606,6 +8667,7 @@ static int lua_enumlib_server_get(lua_State *L) { if ((!multiplayer || !(netgame || demo.playback)) && !playeringame[serverplayer]) return 0; + LUA_PushUserdata(L, &players[serverplayer], META_PLAYER); return 1; } @@ -8614,6 +8676,7 @@ static int lua_enumlib_consoleplayer_get(lua_State *L) { if (consoleplayer < 0 || !playeringame[consoleplayer]) return 0; + LUA_PushUserdata(L, &players[consoleplayer], META_PLAYER); return 1; } @@ -8806,12 +8869,15 @@ static int lua_enumlib_action_get(lua_State *L) const char *action = lua_tostring(L, 1); for (int i = 0; actionpointers[i].name; i++) - if (fasticmp(action, actionpointers[i].name)) { + { + if (fasticmp(action, actionpointers[i].name)) + { // push lib_action as a C closure with the actionf_t* as an upvalue. lua_pushlightuserdata(L, &actionpointers[i].action); lua_pushcclosure(L, lib_action, 1); return 1; } + } return 0; } @@ -8829,8 +8895,13 @@ static char *lua_enumlib_sprintf_upper(char **buf, int* size, const char *format va_list va; va_start(va, format); - int length = vsnprintf(*buf, *size, format, va); - if (length > *size) + va_list vacpy; + va_copy(vacpy, va); + + int length = vsnprintf(*buf, *size, format, vacpy); + va_end(vacpy); + + if (length >= *size) { void *ptr = realloc(*buf, length+1); if (!ptr) @@ -8838,12 +8909,13 @@ static char *lua_enumlib_sprintf_upper(char **buf, int* size, const char *format va_end(va); return NULL; } + *buf = ptr; *size = length+1; - va_start(va, format); - vsnprintf(*buf, *size, format, va); + length = vsnprintf(*buf, *size, format, va); } + va_end(va); for (int i = 0; i < length; i++) @@ -8868,11 +8940,14 @@ static int lua_enumlib_super_get(lua_State *L) } for (int i = 0; actionpointers[i].name; i++) - if (fasticmp(superactions[superstack-1], actionpointers[i].name)) { + { + if (fasticmp(superactions[superstack-1], actionpointers[i].name)) + { lua_pushlightuserdata(L, &actionpointers[i].action); lua_pushcclosure(L, lib_action, 1); return 1; } + } return 0; } @@ -9341,7 +9416,10 @@ enum actionnum LUA_GetActionNumByName(const char *actiontocompare) { size_t z; for (z = 0; actionpointers[z].name; z++) + { if (fasticmp(actiontocompare, actionpointers[z].name)) return z; + } + return z; } -- 2.54.0 From 4dd5957f1918e253531a6d0a29e28471fd4e8cb1 Mon Sep 17 00:00:00 2001 From: Alug Date: Sun, 29 Mar 2026 13:46:57 +0200 Subject: [PATCH 14/21] cache islocalplayer in P_SpectatorJoinGame --- src/p_user.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index f57739c92..24b646ee3 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4149,10 +4149,12 @@ void P_ResetLocalCamAiming(player_t *player) boolean P_SpectatorJoinGame(player_t *player) { + const boolean islocalplayer = P_IsLocalPlayer(player); + // Team changing isn't allowed. if (!cv_allowteamchange.value) { - if (P_IsLocalPlayer(player)) + if (islocalplayer) CONS_Printf(M_GetText("Server does not allow team change.\n")); } // Team changing in Team Match and CTF @@ -4200,7 +4202,7 @@ boolean P_SpectatorJoinGame(player_t *player) P_ResetLocalCamAiming(player); //Reset away view - if (P_IsLocalPlayer(player) && displayplayers[0] != consoleplayer) + if (islocalplayer && displayplayers[0] != consoleplayer) displayplayers[0] = consoleplayer; if (changeto == 1) @@ -4227,7 +4229,7 @@ boolean P_SpectatorJoinGame(player_t *player) P_ResetLocalCamAiming(player); //Reset away view - if (P_IsLocalPlayer(player) && displayplayers[0] != consoleplayer) + if (islocalplayer && displayplayers[0] != consoleplayer) displayplayers[0] = consoleplayer; HU_AddChatText(va(M_GetText("\x82*%s entered the game."), player_names[player-players]), false); -- 2.54.0 From 12169bfb388b18fdf112ad399099fd9da6ca1b68 Mon Sep 17 00:00:00 2001 From: Alug Date: Sun, 29 Mar 2026 13:49:59 +0200 Subject: [PATCH 15/21] controllers:check if controller supports addressable led and rumble --- src/dedicated/i_system.c | 12 ++++++++++++ src/g_input.c | 21 ++++++++++++++++++++ src/i_system.h | 3 +++ src/sdl/i_system.cpp | 41 ++++++++++++++++++++++++++++++++++++++++ src/sdl/sdlmain.h | 4 ++++ 5 files changed, 81 insertions(+) diff --git a/src/dedicated/i_system.c b/src/dedicated/i_system.c index ddc17d6a5..978190bec 100644 --- a/src/dedicated/i_system.c +++ b/src/dedicated/i_system.c @@ -735,6 +735,18 @@ const char *I_GetJoyName(INT32 joyindex) return NULL; } +boolean I_GamepadHasLED(INT32 playernum) +{ + (void)playernum; + return false; +} + +boolean I_GamepadHasRumble(INT32 playernum) +{ + (void)playernum; + return false; +} + void I_GamepadRumble(INT32 playernum, UINT16 low_strength, UINT16 high_strength, UINT32 duration) { (void)playernum; diff --git a/src/g_input.c b/src/g_input.c index d44edd6dc..091027ada 100644 --- a/src/g_input.c +++ b/src/g_input.c @@ -939,6 +939,11 @@ void G_SetPlayerGamepadIndicatorColor(INT32 playernum, UINT8 color) return; } + if (!I_GamepadHasLED(playernum)) + { + return; + } + // so we can override this skincolor = color ? color : G_GetSkinColorForGamepad(playernum); byte_color = V_GetColor(colortranslations[skincolor][8]).s; @@ -974,12 +979,22 @@ void G_DeviceLEDTick(void) for (i = 0; i <= splitscreen; i++) { if (!cv_usejoystick[i].value || !cv_gamepadled[i].value) + { continue; + } + + // does not have a configurable led! :c + if (!I_GamepadHasLED(i)) + { + continue; + } newcolor = G_GetSkinColorForGamepad(i); if (curcolor[i] == newcolor) // dont update if same colour + { continue; + } G_SetPlayerGamepadIndicatorColor(i, newcolor); curcolor[i] = newcolor; @@ -1055,6 +1070,12 @@ void G_DeviceRumbleTick(void) continue; } + // does not support rumble! :c + if (!I_GamepadHasRumble(i)) + { + continue; + } + if (camera[i].freecam) { continue; diff --git a/src/i_system.h b/src/i_system.h index 45767f1f7..88bb9c985 100644 --- a/src/i_system.h +++ b/src/i_system.h @@ -148,6 +148,9 @@ extern INT32 numcontrollers; */ const char *I_GetJoyName(INT32 joyindex); +boolean I_GamepadHasLED(INT32 playernum); +boolean I_GamepadHasRumble(INT32 playernum); + void I_GamepadRumble(INT32 playernum, UINT16 low_strength, UINT16 high_strength, UINT32 duration); void I_SetGamepadIndicatorColor(INT32 playernum, UINT8 red, UINT8 green, UINT8 blue); diff --git a/src/sdl/i_system.cpp b/src/sdl/i_system.cpp index 407e5c3a0..8ddea4249 100644 --- a/src/sdl/i_system.cpp +++ b/src/sdl/i_system.cpp @@ -729,6 +729,8 @@ static void JoyReset(SDLJoyInfo_t *JoySet) #if (SDL_VERSION_ATLEAST(2,32,4)) JoySet->id = -1; #endif + JoySet->hasled = false; + JoySet->hasrumble = false; } /** \brief SDL info about joystick @@ -949,6 +951,13 @@ static int joy_open(int playerIndex, int joyIndex) JoyInfo[playerIndex].id = I_GetJoystickDeviceIndex(JoyInfo[playerIndex].dev); #endif +#if (SDL_VERSION_ATLEAST(2,0,14)) + JoyInfo[playerIndex].hasled = SDL_GameControllerHasLED(JoyInfo[playerIndex].dev); +#endif +#if (SDL_VERSION_ATLEAST(2,0,18)) + JoyInfo[playerIndex].hasrumble = SDL_GameControllerHasRumble(JoyInfo[playerIndex].dev); +#endif + return SDL_CONTROLLER_AXIS_MAX; } @@ -996,6 +1005,8 @@ void I_InitJoystick(UINT8 index) #if (SDL_VERSION_ATLEAST(2,32,4)) JoyInfo[index].id = -1; #endif + JoyInfo[index].hasled = false; + JoyInfo[index].hasrumble = false; if (cv_usejoystick[index].value) newcontroller = SDL_GameControllerOpen(cv_usejoystick[index].value-1); @@ -1130,6 +1141,26 @@ const char *I_GetJoyName(INT32 joyindex) return joyname; } +boolean I_GamepadHasLED(INT32 playernum) +{ +#if !(SDL_VERSION_ATLEAST(2,0,14)) + (void)playernum; + return false; +#else + return (JoyInfo[playernum].dev != NULL && JoyInfo[playernum].hasled); +#endif +} + +boolean I_GamepadHasRumble(INT32 playernum) +{ +#if !(SDL_VERSION_ATLEAST(2,0,18)) + (void)playernum; + return false; +#else + return (JoyInfo[playernum].dev != NULL && JoyInfo[playernum].hasrumble); +#endif +} + void I_GamepadRumble(INT32 playernum, UINT16 low_strength, UINT16 high_strength, UINT32 duration) { #if !(SDL_VERSION_ATLEAST(2,0,14)) @@ -1145,6 +1176,11 @@ void I_GamepadRumble(INT32 playernum, UINT16 low_strength, UINT16 high_strength, return; } + if (!I_GamepadHasRumble(playernum)) + { + return; + } + SDL_GameControllerRumble(controller, low_strength, high_strength, duration); #endif } @@ -1164,6 +1200,11 @@ void I_SetGamepadIndicatorColor(INT32 playernum, UINT8 red, UINT8 green, UINT8 b return; } + if (!I_GamepadHasLED(playernum)) + { + return; + } + SDL_GameControllerSetLED(controller, red, green, blue); #endif } diff --git a/src/sdl/sdlmain.h b/src/sdl/sdlmain.h index 11287fe55..b904eefc6 100644 --- a/src/sdl/sdlmain.h +++ b/src/sdl/sdlmain.h @@ -57,6 +57,10 @@ typedef struct SDLJoyInfo_s //int hats; /// number of balls //int balls; + /// + boolean hasled; + /// + boolean hasrumble; } SDLJoyInfo_t; /** \brief SDL info about controller 1 -- 2.54.0 From 7b0e3269b32e278a66f4664c9026ac9340ad27a3 Mon Sep 17 00:00:00 2001 From: Indev Date: Sat, 4 Apr 2026 16:37:15 +0300 Subject: [PATCH 16/21] Add option to hide finished players from minimap --- src/d_netcmd.h | 1 + src/k_hud.c | 5 +++++ src/m_menudefs.c | 52 +++++++++++++++++++++++++----------------------- 3 files changed, 33 insertions(+), 25 deletions(-) diff --git a/src/d_netcmd.h b/src/d_netcmd.h index f22fe33a8..c28df3e7d 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -155,6 +155,7 @@ extern consvar_t cv_pingstyle; //extern consvar_t cv_smallpos; extern consvar_t cv_showminimapnames; +extern consvar_t cv_showminimapfinished; extern consvar_t cv_minihead; extern consvar_t cv_showminimapangle; diff --git a/src/k_hud.c b/src/k_hud.c index 3ec17ddd0..6ded3a2f1 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -92,6 +92,7 @@ consvar_t cv_showinput = {"showinput", "Off", CV_SAVE, inputdisplay_cons_t, NULL static CV_PossibleValue_t minihead_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Others"}, {0, NULL}}; consvar_t cv_minihead = {"smallminimapplayers", "Off", CV_SAVE, minihead_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_showminimapnames = {"showminimapnames", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_showminimapfinished = {"showminimapfinished", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; CV_PossibleValue_t minimapdot_cons_t[NUMMINIMAPDOTSTUFF]; consvar_t cv_showminimapangle = {"showminimapangle", "Off", CV_SAVE, minimapdot_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -221,6 +222,7 @@ void K_RegisterKartHudStuff(void) CV_RegisterVar(&cv_minihead); CV_RegisterVar(&cv_showminimapnames); + CV_RegisterVar(&cv_showminimapfinished); CV_RegisterVar(&cv_showminimapangle); CV_RegisterVar(&cv_showlapemblem); @@ -3772,6 +3774,9 @@ static void K_drawKartMinimap(void) if (!players[i].mo || players[i].spectator) continue; + if (!cv_showminimapfinished.value && players[i].exiting) + continue; + if (P_IsDisplayPlayer(&players[i])) { // Draw display players on top of everything else diff --git a/src/m_menudefs.c b/src/m_menudefs.c index e734021eb..3f1b969ee 100644 --- a/src/m_menudefs.c +++ b/src/m_menudefs.c @@ -1831,44 +1831,45 @@ static menuitem_t OP_SaturnHudMenu[] = {IT_STRING|IT_CVAR, NULL, "Speedometer Style", &cv_newspeedometer, 10}, {IT_STRING|IT_CVAR, NULL, "Battle Speedometer", &cv_battlespeedo, 15}, - {IT_STRING|IT_CVAR, NULL, "Colourized HUD", &cv_colorizedhud, 25}, - {IT_STRING|IT_CVAR, NULL, "Colourized Itembox", &cv_colorizeditembox, 30}, - {IT_STRING|IT_CVAR, NULL, "Colourized HUD Color", &cv_colorizedhudcolor, 35}, + {IT_STRING|IT_CVAR, NULL, "Colourized HUD", &cv_colorizedhud, 25}, + {IT_STRING|IT_CVAR, NULL, "Colourized Itembox", &cv_colorizeditembox, 30}, + {IT_STRING|IT_CVAR, NULL, "Colourized HUD Color", &cv_colorizedhudcolor, 35}, - {IT_STRING|IT_CVAR, NULL, "Input Display", &cv_showinput, 45}, + {IT_STRING|IT_CVAR, NULL, "Input Display", &cv_showinput, 45}, - {IT_STRING|IT_CVAR, NULL, "Stat Display", &cv_showstats, 55}, + {IT_STRING|IT_CVAR, NULL, "Stat Display", &cv_showstats, 55}, - {IT_STRING|IT_CVAR, NULL, "Higher Resolution Portraits", &cv_highresportrait, 65}, + {IT_STRING|IT_CVAR, NULL, "Higher Resolution Portraits", &cv_highresportrait, 65}, - {IT_STRING|IT_CVAR, NULL, "Small Positionnumber", &cv_smallposnum, 75}, - {IT_STRING|IT_CVAR, NULL, "Positionnumber Animation", &cv_posanim, 80}, + {IT_STRING|IT_CVAR, NULL, "Small Positionnumber", &cv_smallposnum, 75}, + {IT_STRING|IT_CVAR, NULL, "Positionnumber Animation", &cv_posanim, 80}, - {IT_STRING|IT_CVAR, NULL, "Flash Lap Times", &cv_showlaptimes, 90}, + {IT_STRING|IT_CVAR, NULL, "Flash Lap Times", &cv_showlaptimes, 90}, - {IT_STRING|IT_CVAR, NULL, "Multi-Item icons", &cv_multiitemicon, 100}, - {IT_STRING|IT_CVAR, NULL, "Item Amount Number", &cv_huditemamount, 105}, - {IT_STRING|IT_CVAR, NULL, "Animated Roulette", &cv_fancyroulette, 110}, + {IT_STRING|IT_CVAR, NULL, "Multi-Item icons", &cv_multiitemicon, 100}, + {IT_STRING|IT_CVAR, NULL, "Item Amount Number", &cv_huditemamount, 105}, + {IT_STRING|IT_CVAR, NULL, "Animated Roulette", &cv_fancyroulette, 110}, - {IT_STRING|IT_CVAR, NULL, "Show Lap Emblem", &cv_showlapemblem, 120}, - {IT_STRING|IT_CVAR, NULL, "Show Cecho Messages", &cv_cechotoggle, 125}, + {IT_STRING|IT_CVAR, NULL, "Show Lap Emblem", &cv_showlapemblem, 120}, + {IT_STRING|IT_CVAR, NULL, "Show Cecho Messages", &cv_cechotoggle, 125}, - {IT_STRING|IT_CVAR, NULL, "Show Names on Minimap", &cv_showminimapnames, 135}, - {IT_STRING|IT_CVAR, NULL, "Small Minimap Players", &cv_minihead, 140}, - {IT_STRING|IT_CVAR, NULL, "Spin Minimap Icons", &cv_spinoutroll, 145}, - {IT_STRING|IT_CVAR, NULL, "Player Angle Visual", &cv_showminimapangle, 150}, + {IT_STRING|IT_CVAR, NULL, "Show Names on Minimap", &cv_showminimapnames, 135}, + {IT_STRING|IT_CVAR, NULL, "Show Finished on Minimap", &cv_showminimapfinished, 140}, + {IT_STRING|IT_CVAR, NULL, "Small Minimap Players", &cv_minihead, 145}, + {IT_STRING|IT_CVAR, NULL, "Spin Minimap Icons", &cv_spinoutroll, 150}, + {IT_STRING|IT_CVAR, NULL, "Player Angle Visual", &cv_showminimapangle, 155}, - {IT_STRING|IT_CVAR, NULL, "Music Credits", &cv_songcredits, 160}, - {IT_STRING|IT_CVAR, NULL, "Music Credits on Pause", &cv_pausesongcredits, 165}, + {IT_STRING|IT_CVAR, NULL, "Music Credits", &cv_songcredits, 165}, + {IT_STRING|IT_CVAR, NULL, "Music Credits on Pause", &cv_pausesongcredits, 170}, - {IT_STRING|IT_CVAR, NULL, "Beta Intermissionscreen", &cv_betainterscreen, 175}, + {IT_STRING|IT_CVAR, NULL, "Beta Intermissionscreen", &cv_betainterscreen, 180}, - {IT_STRING|IT_CVAR, NULL, "Show Director Prompt", &cv_showdirectorhud, 185}, + {IT_STRING|IT_CVAR, NULL, "Show Director Prompt", &cv_showdirectorhud, 190}, - {IT_STRING|IT_SUBMENU, NULL, "Nametags...", &OP_NametagDef, 195}, - {IT_STRING|IT_SUBMENU, NULL, "Driftgauge...", &OP_DriftGaugeDef, 200}, + {IT_STRING|IT_SUBMENU, NULL, "Nametags...", &OP_NametagDef, 200}, + {IT_STRING|IT_SUBMENU, NULL, "Driftgauge...", &OP_DriftGaugeDef, 205}, - {IT_SUBMENU|IT_STRING, NULL, "Hud Offsets...", &OP_HudOffsetDef, 210}, + {IT_SUBMENU|IT_STRING, NULL, "Hud Offsets...", &OP_HudOffsetDef, 215}, }; static const char* OP_SaturnHudTooltips[] = @@ -1891,6 +1892,7 @@ static const char* OP_SaturnHudTooltips[] = "Show the big 'LAP' text on a lap change.", "Show the big Cecho Messages.", "Show player names on the minimap.", + "Show players that have finished already on the minimap.", "Minimize the player icons on the minimap.", "Erratically rotate player icons during spinouts.", "Visualize the player facing angle.", -- 2.54.0 From 9d75bb14056c00aa3311f6d73f0e0f4e7c11597c Mon Sep 17 00:00:00 2001 From: Alug Date: Sat, 4 Apr 2026 15:46:23 +0200 Subject: [PATCH 17/21] hw_main: reorder things, mark const, remove pointless check for polyobject planes like normal planes, polyobject planes will just reallocate their vertex buffer eitherways according to size, so that check does not make much sense, srb2 also did remove it a while ago --- src/hardware/hw_main.cpp | 39 +++++++++++++++------------------------ src/hardware/hw_shaders.c | 10 ++++++++-- src/r_main.cpp | 12 ++++++------ src/sdl/i_system.cpp | 4 +++- 4 files changed, 32 insertions(+), 33 deletions(-) diff --git a/src/hardware/hw_main.cpp b/src/hardware/hw_main.cpp index 0806d05c8..87192e2bd 100644 --- a/src/hardware/hw_main.cpp +++ b/src/hardware/hw_main.cpp @@ -388,11 +388,11 @@ void HWR_ObjectLightLevelPost(gl_vissprite_t *spr, const sector_t *sector, INT32 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); - fixed_t xscale = FixedDiv((vid.width / 2) << FRACBITS, tr); + const fixed_t tr = R_QuickCamDist(spr->mobj->x, spr->mobj->y); + const fixed_t xscale = FixedDiv((vid.width / 2) << FRACBITS, tr); // Less change in contrast at further distances, to counteract DOOM diminished light - fixed_t n = FixedDiv(FixedMul(xscale, LIGHTRESOLUTIONFIX), ((MAXLIGHTSCALE-1) << LIGHTSCALESHIFT)); + const fixed_t n = FixedDiv(FixedMul(xscale, LIGHTRESOLUTIONFIX), ((MAXLIGHTSCALE-1) << LIGHTSCALESHIFT)); extralight = FixedMul(extralight, std::min(n, FRACUNIT)); // Contrast is stronger for normal sprites, stronger than wall lighting is at the same distance @@ -515,7 +515,7 @@ static FUINT HWR_CalcWallLight(FUINT lightnum, seg_t *seg, extracolormap_t *colo if (seg != NULL && P_ApplyLightOffsetFine(lightnum, seg->frontsector)) { - INT16 offset = (cv_glfakecontrast.value == 2) ? seg->hwLightOffset : ((INT16)seg->lightOffset * 8); + const INT16 offset = (cv_glfakecontrast.value == 2) ? seg->hwLightOffset : ((INT16)seg->lightOffset * 8); finallight += offset; finallight = CLAMP(finallight, 0 , 255); @@ -533,7 +533,7 @@ static FUINT HWR_CalcSlopeLight(FUINT lightnum, pslope_t *slope, const sector_t if (slope != NULL && sector != NULL && P_ApplyLightOffsetFine(lightnum, sector)) { - INT16 offset = (cv_glfakecontrast.value == 2) ? slope->hwLightOffset : ((INT16)slope->lightOffset * 8); + const INT16 offset = (cv_glfakecontrast.value == 2) ? slope->hwLightOffset : ((INT16)slope->lightOffset * 8); finallight += (fof ? -offset : offset); finallight = CLAMP(finallight, 0 , 255); @@ -1420,6 +1420,11 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom { draw_sky_walls(0, 1, worldhigh, worldhighslope); } + + // hack to allow height changes in outdoor areas + // This is what gets rid of the upper textures if there should be sky + worldtop = worldhigh; + worldtopslope = worldhighslope; } else { @@ -1464,15 +1469,6 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom } } - // hack to allow height changes in outdoor areas - // This is what gets rid of the upper textures if there should be sky - if (gl_frontsector->ceilingpic == skyflatnum - && gl_backsector->ceilingpic == skyflatnum) - { - worldtop = worldhigh; - worldtopslope = worldhighslope; - } - gl_toptexture = R_GetTextureNum(gl_sidedef->toptexture); // check TOP TEXTURE @@ -2263,7 +2259,7 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom static inline boolean HWR_UsePortals(void) { - return supportstencil && cv_glportals.value && gl_maphasportals; + return supportstencil && gl_maphasportals && cv_glportals.value; } // From PrBoom: @@ -2407,7 +2403,8 @@ static inline void DoAddLine(seg_t* line, angle_t angle1, angle_t angle2) // SoM: Backsector needs to be run through R_FakeFlat static sector_t tempsec; - auto do_addline = [&](bool dontdraw) { + auto do_addline = [&](bool dontdraw) + { // Single sided line? if (!line->backsector) { @@ -2688,14 +2685,6 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, if (nrPlaneVerts < 3) // not even a triangle ? return; - if (nrPlaneVerts > INT16_MAX) // FIXME: exceeds plVerts size - { - CONS_Debug(DBG_RENDER, "polygon size of %s exceeds max value of %d vertices\n", sizeu1(nrPlaneVerts), UINT16_MAX); - return; - } - - const sector_t *sec = FOFsector ? FOFsector : gl_frontsector; - // Allocate plane-vertex buffer if we need to if (!planeVerts || nrPlaneVerts > numAllocedPlaneVerts) { @@ -2704,6 +2693,8 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, Z_Malloc(numAllocedPlaneVerts * sizeof(FOutVector), PU_LEVEL, &planeVerts); } + const sector_t *sec = FOFsector ? FOFsector : gl_frontsector; + height = FixedToFloat(fixedheight); len = W_LumpLength(lumpnum); diff --git a/src/hardware/hw_shaders.c b/src/hardware/hw_shaders.c index 90d019b2b..31723eab1 100644 --- a/src/hardware/hw_shaders.c +++ b/src/hardware/hw_shaders.c @@ -365,13 +365,17 @@ static void HWR_CompileShader(int index) if (vertex_source) { char *preprocessed = HWR_PreprocessShader(vertex_source); - if (!preprocessed) return; + if (!preprocessed) + return; + GL_LoadShader(index, preprocessed, HWD_SHADERSTAGE_VERTEX); } if (fragment_source) { char *preprocessed = HWR_PreprocessShader(fragment_source); - if (!preprocessed) return; + if (!preprocessed) + return; + GL_LoadShader(index, preprocessed, HWD_SHADERSTAGE_FRAGMENT); } @@ -387,8 +391,10 @@ void HWR_CompileShaders(void) { int custom_index = gl_shadertargets[i].custom_shader; HWR_CompileShader(i); + if (!gl_shaders[i].compiled) CONS_Alert(CONS_ERROR, "HWR_CompileShaders: Compilation failed for base %s shader!\n", shaderxlat[i].type); + if (custom_index != -1) { HWR_CompileShader(custom_index); diff --git a/src/r_main.cpp b/src/r_main.cpp index 2b318858a..cf7df9088 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -342,14 +342,14 @@ angle_t R_PointToAngle64(INT64 x, INT64 y) return (y -= viewy, (x -= viewx) || y) ? x >= 0 ? y >= 0 ? - (x > y) ? tantoangle[SlopeDivEx(y,x)] : // octant 0 - ANGLE_90-tantoangle[SlopeDivEx(x,y)] : // octant 1 - x > (y = -y) ? 0-tantoangle[SlopeDivEx(y,x)] : // octant 8 - ANGLE_270+tantoangle[SlopeDivEx(x,y)] : // octant 7 + (x > y) ? tantoangle[SlopeDivEx(y,x)] : // octant 0 + ANGLE_90-tantoangle[SlopeDivEx(x,y)] : // octant 1 + x > (y = -y) ? 0-tantoangle[SlopeDivEx(y,x)] : // octant 8 + ANGLE_270+tantoangle[SlopeDivEx(x,y)] : // octant 7 y >= 0 ? (x = -x) > y ? ANGLE_180-tantoangle[SlopeDivEx(y,x)] : // octant 3 - ANGLE_90 + tantoangle[SlopeDivEx(x,y)] : // octant 2 + ANGLE_90 + tantoangle[SlopeDivEx(x,y)] : // octant 2 (x = -x) > (y = -y) ? ANGLE_180+tantoangle[SlopeDivEx(y,x)] : // octant 4 - ANGLE_270-tantoangle[SlopeDivEx(x,y)] : // octant 5 + ANGLE_270-tantoangle[SlopeDivEx(x,y)] : // octant 5 0; } diff --git a/src/sdl/i_system.cpp b/src/sdl/i_system.cpp index 8ddea4249..2f2253fe8 100644 --- a/src/sdl/i_system.cpp +++ b/src/sdl/i_system.cpp @@ -304,7 +304,7 @@ static void I_StartupConsole(void) if (!consolevent) return; - if (isatty(STDIN_FILENO)!=1) + if (isatty(STDIN_FILENO) != 1) { I_OutputMsg("stdin is not a tty, tty console mode failed\n"); consolevent = false; @@ -1993,12 +1993,14 @@ FUNCNORETURN void ATTRNORETURN I_Quit(void) I_ShutdownInput(); I_ShutdownSystem(); SDL_Quit(); + /* if option -noendtxt is set, don't print the text */ if (!M_CheckParm("-noendtxt") && W_CheckNumForName("ENDOOM") != LUMPERROR) { printf("\r"); ShowEndTxt(); } + if (myargmalloc) free(myargv); // Deallocate allocated memory -- 2.54.0 From e543599598236f205c050b4f6cff248cb4b944fd Mon Sep 17 00:00:00 2001 From: Indev Date: Sat, 4 Apr 2026 16:53:01 +0300 Subject: [PATCH 18/21] Add option to hide skin name from stat display --- src/k_hud.c | 17 +++++++++++------ src/k_hud.h | 1 + src/m_menudefs.c | 48 +++++++++++++++++++++++++----------------------- 3 files changed, 37 insertions(+), 29 deletions(-) diff --git a/src/k_hud.c b/src/k_hud.c index 6ded3a2f1..1efdcbdcb 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -83,6 +83,7 @@ IMPL_HUD_OFFSET(stat); // Stats // extra hud things consvar_t cv_showstats = {"showstats", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_showstats_skinname = {"showstats_skinname", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_highresportrait = {"highresportrait", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; // make char potraits use their high-res version instead @@ -208,6 +209,7 @@ void K_RegisterKartHudStuff(void) CV_RegisterVar(&cv_kartspeedometer); CV_RegisterVar(&cv_showstats); + CV_RegisterVar(&cv_showstats_skinname); CV_RegisterVar(&cv_showinput); CV_RegisterVar(&cv_posanim); @@ -1436,13 +1438,16 @@ static void K_drawKartStats(void) fakeskin = K_GetPlayerSkin(stplyr); // Skin name - if (K_IsHighResolution()) // V_DrawSmallString becomes a mess at low resolutions lel + if (cv_showstats_skinname.value) { - V_DrawSmallString(x+20, y+12, flags2, fakeskin->realname); - } - else - { - V_DrawThinString(x+20, y+7, flags2, fakeskin->realname); + 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 diff --git a/src/k_hud.h b/src/k_hud.h index c42996a4e..ca38f43ea 100644 --- a/src/k_hud.h +++ b/src/k_hud.h @@ -35,6 +35,7 @@ extern consvar_t cv_darkitembox; extern consvar_t cv_biglaps; extern consvar_t cv_highresportrait; extern consvar_t cv_showstats; +extern consvar_t cv_showstats_skinname; extern consvar_t cv_fancyroulette; extern consvar_t cv_showlaptimes; extern consvar_t cv_battlespeedo; diff --git a/src/m_menudefs.c b/src/m_menudefs.c index 3f1b969ee..0b176fab3 100644 --- a/src/m_menudefs.c +++ b/src/m_menudefs.c @@ -1828,8 +1828,8 @@ static menuitem_t OP_SaturnHudMenu[] = { {IT_HEADER, NULL, "Saturn Hud Options", NULL, 0}, - {IT_STRING|IT_CVAR, NULL, "Speedometer Style", &cv_newspeedometer, 10}, - {IT_STRING|IT_CVAR, NULL, "Battle Speedometer", &cv_battlespeedo, 15}, + {IT_STRING|IT_CVAR, NULL, "Speedometer Style", &cv_newspeedometer, 10}, + {IT_STRING|IT_CVAR, NULL, "Battle Speedometer", &cv_battlespeedo, 15}, {IT_STRING|IT_CVAR, NULL, "Colourized HUD", &cv_colorizedhud, 25}, {IT_STRING|IT_CVAR, NULL, "Colourized Itembox", &cv_colorizeditembox, 30}, @@ -1838,38 +1838,39 @@ static menuitem_t OP_SaturnHudMenu[] = {IT_STRING|IT_CVAR, NULL, "Input Display", &cv_showinput, 45}, {IT_STRING|IT_CVAR, NULL, "Stat Display", &cv_showstats, 55}, + {IT_STRING|IT_CVAR, NULL, "Skin Name in Stat Display", &cv_showstats_skinname, 60}, - {IT_STRING|IT_CVAR, NULL, "Higher Resolution Portraits", &cv_highresportrait, 65}, + {IT_STRING|IT_CVAR, NULL, "Higher Resolution Portraits", &cv_highresportrait, 70}, - {IT_STRING|IT_CVAR, NULL, "Small Positionnumber", &cv_smallposnum, 75}, - {IT_STRING|IT_CVAR, NULL, "Positionnumber Animation", &cv_posanim, 80}, + {IT_STRING|IT_CVAR, NULL, "Small Positionnumber", &cv_smallposnum, 80}, + {IT_STRING|IT_CVAR, NULL, "Positionnumber Animation", &cv_posanim, 85}, - {IT_STRING|IT_CVAR, NULL, "Flash Lap Times", &cv_showlaptimes, 90}, + {IT_STRING|IT_CVAR, NULL, "Flash Lap Times", &cv_showlaptimes, 95}, - {IT_STRING|IT_CVAR, NULL, "Multi-Item icons", &cv_multiitemicon, 100}, - {IT_STRING|IT_CVAR, NULL, "Item Amount Number", &cv_huditemamount, 105}, - {IT_STRING|IT_CVAR, NULL, "Animated Roulette", &cv_fancyroulette, 110}, + {IT_STRING|IT_CVAR, NULL, "Multi-Item icons", &cv_multiitemicon, 105}, + {IT_STRING|IT_CVAR, NULL, "Item Amount Number", &cv_huditemamount, 110}, + {IT_STRING|IT_CVAR, NULL, "Animated Roulette", &cv_fancyroulette, 115}, - {IT_STRING|IT_CVAR, NULL, "Show Lap Emblem", &cv_showlapemblem, 120}, - {IT_STRING|IT_CVAR, NULL, "Show Cecho Messages", &cv_cechotoggle, 125}, + {IT_STRING|IT_CVAR, NULL, "Show Lap Emblem", &cv_showlapemblem, 125}, + {IT_STRING|IT_CVAR, NULL, "Show Cecho Messages", &cv_cechotoggle, 130}, - {IT_STRING|IT_CVAR, NULL, "Show Names on Minimap", &cv_showminimapnames, 135}, - {IT_STRING|IT_CVAR, NULL, "Show Finished on Minimap", &cv_showminimapfinished, 140}, - {IT_STRING|IT_CVAR, NULL, "Small Minimap Players", &cv_minihead, 145}, - {IT_STRING|IT_CVAR, NULL, "Spin Minimap Icons", &cv_spinoutroll, 150}, - {IT_STRING|IT_CVAR, NULL, "Player Angle Visual", &cv_showminimapangle, 155}, + {IT_STRING|IT_CVAR, NULL, "Show Names on Minimap", &cv_showminimapnames, 140}, + {IT_STRING|IT_CVAR, NULL, "Show Finished on Minimap", &cv_showminimapfinished, 145}, + {IT_STRING|IT_CVAR, NULL, "Small Minimap Players", &cv_minihead, 150}, + {IT_STRING|IT_CVAR, NULL, "Spin Minimap Icons", &cv_spinoutroll, 155}, + {IT_STRING|IT_CVAR, NULL, "Player Angle Visual", &cv_showminimapangle, 160}, - {IT_STRING|IT_CVAR, NULL, "Music Credits", &cv_songcredits, 165}, - {IT_STRING|IT_CVAR, NULL, "Music Credits on Pause", &cv_pausesongcredits, 170}, + {IT_STRING|IT_CVAR, NULL, "Music Credits", &cv_songcredits, 170}, + {IT_STRING|IT_CVAR, NULL, "Music Credits on Pause", &cv_pausesongcredits, 175}, - {IT_STRING|IT_CVAR, NULL, "Beta Intermissionscreen", &cv_betainterscreen, 180}, + {IT_STRING|IT_CVAR, NULL, "Beta Intermissionscreen", &cv_betainterscreen, 185}, - {IT_STRING|IT_CVAR, NULL, "Show Director Prompt", &cv_showdirectorhud, 190}, + {IT_STRING|IT_CVAR, NULL, "Show Director Prompt", &cv_showdirectorhud, 195}, - {IT_STRING|IT_SUBMENU, NULL, "Nametags...", &OP_NametagDef, 200}, - {IT_STRING|IT_SUBMENU, NULL, "Driftgauge...", &OP_DriftGaugeDef, 205}, + {IT_STRING|IT_SUBMENU, NULL, "Nametags...", &OP_NametagDef, 205}, + {IT_STRING|IT_SUBMENU, NULL, "Driftgauge...", &OP_DriftGaugeDef, 210}, - {IT_SUBMENU|IT_STRING, NULL, "Hud Offsets...", &OP_HudOffsetDef, 215}, + {IT_SUBMENU|IT_STRING, NULL, "Hud Offsets...", &OP_HudOffsetDef, 220}, }; static const char* OP_SaturnHudTooltips[] = @@ -1882,6 +1883,7 @@ static const char* OP_SaturnHudTooltips[] = "The color to use instead of the player color when\ncolourized hud is enabled.", "Displays the input display and lets you choose its style.", "Enable the stat display.", + "Show skin name in the stat display.", "Enable the use of the higher resolution want icons instead of rank\nfor some places.", "Make the Postionnumber half the size.", "Disable the animation of the Positionnumber\nwhen overtaking someone.", -- 2.54.0 From 873cff447483c8f396456fbeae7b007b87d30546 Mon Sep 17 00:00:00 2001 From: Indev Date: Tue, 10 Mar 2026 02:27:36 +0300 Subject: [PATCH 19/21] Display information about addon types loaded on server when joining (WIP) --- src/d_clisrv.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/d_netfil.c | 49 +++++++++++++++++++++++++++++++++++ src/d_netfil.h | 12 +++++++++ 3 files changed, 131 insertions(+) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index f5e32b2e0..fb665a943 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1154,6 +1154,64 @@ static void CV_LoadPlayerNames(UINT8 **p) } } +static void CL_DrawAddonTypes(void) +{ + INT32 y = 0; + + INT32 addontypes_downloaded[NUMADDONTYPES] = {0}; + + for (INT32 i = 0; i < fileneedednum; ++i) + { + switch (fileneeded[i].status) + { + case FS_FOUND: + case FS_OPEN: + addontypes_downloaded[fileneeded[i].type]++; + break; + + default: + break; + } + } + + for (addontype_t type = 0; type < NUMADDONTYPES; ++type) + { + if (addontypes[type] == 0) + continue; + + INT32 flags = V_SNAPTOTOP|V_SNAPTOLEFT|V_ALLOWLOWERCASE; + + if (addontypes[type] == addontypes_downloaded[type]) + flags |= V_GREENMAP; + else + flags |= V_YELLOWMAP; + + const char *typestr = "Misc"; + + switch (type) + { + case ADDON_SCRIPT: + typestr = "Script"; + break; + + case ADDON_MAP: + typestr = "Map"; + break; + + case ADDON_CHARACTER: + typestr = "Character"; + break; + + default: + break; + } + + V_DrawSmallString(4, 4 + y, flags, va("%s addons", typestr)); + V_DrawRightAlignedSmallString(100, 4 + y, flags, va("%d/%d", addontypes_downloaded[type], addontypes[type])); + y += 6; + } +} + // // CL_DrawConnectionStatus // @@ -1269,6 +1327,8 @@ static void CL_DrawConnectionStatus(void) V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, totalfileslength, 8, 160); V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24, V_20TRANS|V_MONOSPACE|MENUCAPS, va(" %2u/%2u Files", checkednum, fileneedednum)); + + CL_DrawAddonTypes(); } else if (cl_mode == CL_LOADFILES) { @@ -1292,6 +1352,8 @@ static void CL_DrawConnectionStatus(void) V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, totalfileslength, 8, 160); V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24, V_20TRANS|V_MONOSPACE|MENUCAPS, va(" %2u/%2u Files", loadcompletednum, fileneedednum)); + + CL_DrawAddonTypes(); } else if (cl_mode == CL_VIEWSERVER) { @@ -1495,6 +1557,8 @@ static void CL_DrawConnectionStatus(void) V_DrawRightAlignedString(BASEVIDWIDTH/2+128, BASEVIDHEIGHT-24, V_20TRANS|V_MONOSPACE|MENUCAPS, va("%2u/%2u Files ", filedownload.completednum, filedownload.totalnum)); + + CL_DrawAddonTypes(); } else { @@ -1511,6 +1575,8 @@ static void CL_DrawConnectionStatus(void) V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24-32, V_YELLOWMAP|MENUCAPS, M_GetText("Waiting to download files...")); + + CL_DrawAddonTypes(); } } } @@ -2559,6 +2625,7 @@ static void CL_ServerConnectionSearchTicker(tic_t *asksent) } cl_mode = cv_serverinfoscreen.value ? CL_VIEWSERVER : CL_CHECKFILES; + CL_CheckAddonTypes(); } else { @@ -2612,7 +2679,10 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic case CL_ASKFULLFILELIST: if (cl_lastcheckedfilecount == UINT16_MAX) // All files retrieved + { cl_mode = cv_serverinfoscreen.value ? CL_VIEWSERVER : CL_CHECKFILES; + CL_CheckAddonTypes(); + } else if (fileneedednum != cl_lastcheckedfilecount || I_GetTime() >= *asksent) { if (CL_AskFileList(fileneedednum)) diff --git a/src/d_netfil.c b/src/d_netfil.c index aca8f35ba..8865ab618 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -116,6 +116,8 @@ static I_mutex downloadmutex; #endif char downloaddir[512] = "DOWNLOAD"; +INT32 addontypes[NUMADDONTYPES] = {0}; + file_download_t filedownload = {}; #ifdef HAVE_CURL @@ -135,6 +137,8 @@ HTTP_login *curl_logins = NULL; static void CURLGetFile(void); #endif +static addontype_t GetAddonType(const char *name); + /** Fills a serverinfo packet with information about wad files loaded. * * \todo Give this function a better name since it is in global scope. @@ -227,6 +231,9 @@ void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr, UINT16 fi fileneeded[i].file = NULL; // The file isn't open yet READSTRINGL(p, fileneeded[i].filename, MAX_WADPATH); // The next bytes are the file name READMEM(p, fileneeded[i].md5sum, 16); // The last 16 bytes are the file checksum + + // Should be good place to calculate that? + fileneeded[i].type = GetAddonType(fileneeded[i].filename); } } @@ -575,6 +582,48 @@ INT32 CL_CheckFiles(void) return 1; //everything is FS_OPEN or FS_FOUND, proceed to loading } +static addontype_t GetAddonType(const char *name) +{ + const char *prefix = strchr(name, '_'); + + // Doesn't have prefix (no '_' character or it is too far and is probably not for prefix but for something like version) + // KRBCL_ is longest prefix i can think of so this should be enough + if (prefix == NULL || prefix - name > 5) + return ADDON_MISC; + + // Skip 'K' + if (*name == 'K') + ++name; + + switch (*name) + { + case 'L': + return ADDON_SCRIPT; + break; + + case 'R': + case 'B': + return ADDON_MAP; + break; + + case 'C': + return ADDON_CHARACTER; + break; + } + + return ADDON_MISC; +} + +void CL_CheckAddonTypes(void) +{ + memset(&addontypes, 0, sizeof(addontypes)); + + for (INT32 i = 0; i < fileneedednum; i++) + { + addontypes[fileneeded[i].type]++; + } +} + // Load it now boolean CL_LoadServerFiles(void) { diff --git a/src/d_netfil.h b/src/d_netfil.h index 268cd80be..4d4cdba74 100644 --- a/src/d_netfil.h +++ b/src/d_netfil.h @@ -40,6 +40,15 @@ typedef enum FS_FALLBACK, // HTTP failed } filestatus_t; +typedef enum addontype_e +{ + ADDON_SCRIPT, + ADDON_MAP, + ADDON_CHARACTER, + ADDON_MISC, + NUMADDONTYPES, +} addontype_t; + typedef struct { UINT8 willsend; // Is the server willing to send it? @@ -51,11 +60,13 @@ typedef struct UINT32 totalsize; filestatus_t status; // The value returned by recsearch boolean justdownloaded; // To prevent late fragments from causing an I_Error + addontype_t type; } fileneeded_t; extern INT32 fileneedednum; extern fileneeded_t fileneeded[MAX_WADFILES]; extern char downloaddir[512]; +extern INT32 addontypes[NUMADDONTYPES]; typedef struct { @@ -91,6 +102,7 @@ void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr, UINT16 fi void CL_PrepareDownloadSaveGame(const char *tmpsave); INT32 CL_CheckFiles(void); +void CL_CheckAddonTypes(void); boolean CL_LoadServerFiles(void); void SV_SendRam(INT32 node, void *data, size_t size, freemethod_t freemethod, UINT8 fileid); -- 2.54.0 From 42fa435a0ba12a55a080fa2a1b381636b030b952 Mon Sep 17 00:00:00 2001 From: Indev Date: Wed, 11 Mar 2026 17:26:12 +0300 Subject: [PATCH 20/21] Add toggle for server addon info --- src/d_clisrv.c | 5 +++++ src/d_clisrv.h | 2 ++ src/d_netcmd.c | 1 + 3 files changed, 8 insertions(+) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index fb665a943..d9419a15b 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1156,6 +1156,9 @@ static void CV_LoadPlayerNames(UINT8 **p) static void CL_DrawAddonTypes(void) { + if (!cv_serveraddoninfo.value) + return; + INT32 y = 0; INT32 addontypes_downloaded[NUMADDONTYPES] = {0}; @@ -4284,6 +4287,8 @@ consvar_t cv_connectawaittime = {"connectawaittime", "5", CV_SAVE, connectawaitt consvar_t cv_serverinfoscreen = {"serverinfoscreen", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_serveraddoninfo = {"serveraddoninfo", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; + static void Got_AddPlayer(const UINT8 **p, INT32 playernum); static void Got_RemovePlayer(const UINT8 **p, INT32 playernum); diff --git a/src/d_clisrv.h b/src/d_clisrv.h index e6741b949..8392f13a1 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -600,6 +600,8 @@ extern consvar_t cv_discordinvites; extern consvar_t cv_serverinfoscreen; +extern consvar_t cv_serveraddoninfo; + // Used in d_net, the only dependence //tic_t ExpandTics(INT32 low, tic_t basetic); void D_ClientServerInit(void); diff --git a/src/d_netcmd.c b/src/d_netcmd.c index aee7f20d4..828ad136a 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -900,6 +900,7 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_mindelay); CV_RegisterVar(&cv_gentlemens); CV_RegisterVar(&cv_serverinfoscreen); + CV_RegisterVar(&cv_serveraddoninfo); #ifdef NETGAME_DEVMODE CV_RegisterVar(&cv_fishcake); -- 2.54.0 From b84e6d89e20776174a50e9dfe949dd51668d25be Mon Sep 17 00:00:00 2001 From: Indev Date: Sat, 4 Apr 2026 17:24:58 +0300 Subject: [PATCH 21/21] Add toggle for server addons info hud into settings --- src/m_menudefs.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/m_menudefs.c b/src/m_menudefs.c index 0b176fab3..e2fd3305f 100644 --- a/src/m_menudefs.c +++ b/src/m_menudefs.c @@ -1694,29 +1694,30 @@ static menuitem_t OP_SaturnMenu[] = {IT_STRING | IT_CVAR, NULL, "Minimum Input Delay", &cv_mindelay, 20}, {IT_STRING | IT_CVAR, NULL, "Gentlemens Ping", &cv_gentlemens, 25}, {IT_STRING | IT_CVAR, NULL, "Server Info Screen", &cv_serverinfoscreen, 30}, + {IT_STRING | IT_CVAR, NULL, "Server Addons Info", &cv_serveraddoninfo, 35}, - {IT_STRING | IT_CVAR, NULL, "Skin Select Spinning Speed", &cv_skinselectspin, 40}, + {IT_STRING | IT_CVAR, NULL, "Skin Select Spinning Speed", &cv_skinselectspin, 45}, - {IT_STRING | IT_CVAR, NULL, "Colorized Speedlines", &cv_coloredspeedlines, 50}, - {IT_STRING | IT_CVAR, NULL, "Colorized Sneakertrails", &cv_coloredsneakertrail, 55}, + {IT_STRING | IT_CVAR, NULL, "Colorized Speedlines", &cv_coloredspeedlines, 55}, + {IT_STRING | IT_CVAR, NULL, "Colorized Sneakertrails", &cv_coloredsneakertrail, 60}, - {IT_STRING | IT_CVAR, NULL, "Player Blendeffects", &cv_playerblendeffects, 65}, + {IT_STRING | IT_CVAR, NULL, "Player Blendeffects", &cv_playerblendeffects, 70}, - {IT_STRING | IT_CVAR, NULL, "Bananadrag Jitter", &cv_bananajitter, 75}, + {IT_STRING | IT_CVAR, NULL, "Bananadrag Jitter", &cv_bananajitter, 80}, - {IT_STRING | IT_CVAR, NULL, "Midair Driftsparks", &cv_airsparks, 85}, + {IT_STRING | IT_CVAR, NULL, "Midair Driftsparks", &cv_airsparks, 90}, - {IT_STRING | IT_CVAR, NULL, "Show Localskin Menus", &cv_showlocalskinmenus, 95}, + {IT_STRING | IT_CVAR, NULL, "Show Localskin Menus", &cv_showlocalskinmenus, 100}, - {IT_STRING | IT_CVAR, NULL, "Uppercase Menu", &cv_menucaps, 105}, + {IT_STRING | IT_CVAR, NULL, "Uppercase Menu", &cv_menucaps, 110}, - {IT_STRING | IT_CVAR, NULL, "Keyboard Layout", &cv_keyboardlayout, 115}, + {IT_STRING | IT_CVAR, NULL, "Keyboard Layout", &cv_keyboardlayout, 120}, - {IT_STRING | IT_CVAR, NULL, "Less Midnight Channel Flicker", &cv_lessflicker, 125}, + {IT_STRING | IT_CVAR, NULL, "Less Midnight Channel Flicker", &cv_lessflicker, 130}, - {IT_SUBMENU|IT_STRING, NULL, "Saturn Hud...", &OP_SaturnHudDef, 135}, - {IT_SUBMENU|IT_STRING, NULL, "Sprite Distortion...", &OP_PlayerDistortDef, 140}, - {IT_SUBMENU|IT_STRING, NULL, "Saturn Credits", &OP_SaturnCreditsDef, 145}, // uwu + {IT_SUBMENU|IT_STRING, NULL, "Saturn Hud...", &OP_SaturnHudDef, 140}, + {IT_SUBMENU|IT_STRING, NULL, "Sprite Distortion...", &OP_PlayerDistortDef, 145}, + {IT_SUBMENU|IT_STRING, NULL, "Saturn Credits", &OP_SaturnCreditsDef, 150}, // uwu }; static const char* OP_SaturnTooltips[] = @@ -1726,6 +1727,7 @@ static const char* OP_SaturnTooltips[] = "Practice for online play! 0 = instant response.", "Simulate online input delay when hosting a server.\nValue choosen by Player with the lowest ping", "Show a screen before joining a server displaying important information about it", + "Show a amount and types of addons loaded by server when joining", "How much speen do you want?", "Colourize the speedlines in your skincolor if you go fast enough!", "Colourize the sneaker flame trails in your skincolor!", -- 2.54.0