From 472f7d060c39079a0651c1b6228570bfb3ff5136 Mon Sep 17 00:00:00 2001 From: "James R." Date: Fri, 22 Sep 2023 01:59:55 -0700 Subject: [PATCH 01/21] Kill HW3SOUND related code (in files that are actually used) --- src/d_main.cpp | 12 -------- src/doomdef.h | 40 ------------------------ src/p_enemy.c | 4 --- src/p_spec.c | 4 --- src/p_user.c | 4 --- src/s_sound.c | 83 +------------------------------------------------- src/s_sound.h | 2 -- 7 files changed, 1 insertion(+), 148 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index 98fe6de7d..7235614f2 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -92,10 +92,6 @@ #include "hardware/hw_main.h" // 3D View Rendering #endif -#ifdef HW3SOUND -#include "hardware/hw3sound.h" -#endif - #include "lua_script.h" /* Manually defined asset hashes @@ -838,10 +834,6 @@ void D_SRB2Loop(void) interp = R_UsingFrameInterpolation() && !dedicated; doDisplay = false; -#ifdef HW3SOUND - HW3S_BeginFrameUpdate(); -#endif - if (realtics > 0 || singletics) { // don't skip more than 10 frames at a time @@ -932,10 +924,6 @@ void D_SRB2Loop(void) S_TickSoundTest(); } -#ifdef HW3SOUND - HW3S_EndFrameUpdate(); -#endif - LUA_Step(); #ifdef HAVE_DISCORDRPC diff --git a/src/doomdef.h b/src/doomdef.h index 00b4ce048..2747d0eac 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -15,46 +15,6 @@ #ifndef __DOOMDEF__ #define __DOOMDEF__ -// Sound system select -// This should actually be in the makefile, -// but I can't stand that gibberish. D: -#define SOUND_DUMMY 0 -#define SOUND_SDL 1 -#define SOUND_MIXER 2 -#define SOUND_FMOD 3 - -#ifndef SOUND -#ifdef HAVE_SDL - -// Use Mixer interface? -#ifdef HAVE_MIXER - #define SOUND SOUND_MIXER - #ifdef HW3SOUND - #undef HW3SOUND - #endif -#endif - -// Use generic SDL interface. -#ifndef SOUND -#define SOUND SOUND_SDL -#endif - -#else // No SDL. - -// Use FMOD? -#ifdef HAVE_FMOD - #define SOUND SOUND_FMOD - #ifdef HW3SOUND - #undef HW3SOUND - #endif -#else - // No more interfaces. :( - #define SOUND SOUND_DUMMY -#endif - -#endif -#endif - #ifdef _WIN32 #define ASMCALL __cdecl #else diff --git a/src/p_enemy.c b/src/p_enemy.c index b8bedfc5e..56ce9e217 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -36,10 +36,6 @@ #include "k_objects.h" #include "k_roulette.h" -#ifdef HW3SOUND -#include "hardware/hw3sound.h" -#endif - boolean LUA_CallAction(enum actionnum actionnum, mobj_t *actor); player_t *stplyr; diff --git a/src/p_spec.c b/src/p_spec.c index a9dc3760f..0951d8c56 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -48,10 +48,6 @@ #include "k_terrain.h" #include "acs/interface.h" -#ifdef HW3SOUND -#include "hardware/hw3sound.h" -#endif - // Not sure if this is necessary, but it was in w_wad.c, so I'm putting it here too -Shadow Hog #include diff --git a/src/p_user.c b/src/p_user.c index 8f4dc5090..15b96298a 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -67,10 +67,6 @@ #include "music.h" #include "k_tally.h" -#ifdef HW3SOUND -#include "hardware/hw3sound.h" -#endif - #ifdef HWRENDER #include "hardware/hw_light.h" #include "hardware/hw_main.h" diff --git a/src/s_sound.c b/src/s_sound.c index 9d5be54d4..6aa0a5b7e 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -37,12 +37,7 @@ #include "v_video.h" // V_ThinStringWidth #include "music.h" -#ifdef HW3SOUND -// 3D Sound Interface -#include "hardware/hw3sound.h" -#else static boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *vol, INT32 *sep, INT32 *pitch, sfxinfo_t *sfxinfo); -#endif static void Command_Tunes_f(void); static void Command_RestartAudio_f(void); @@ -213,13 +208,6 @@ void SetChannelsNum(void) if (cv_numChannels.value == 999999999) //Alam_GBC: OH MY ROD!(ROD rimmiced with GOD!) CV_StealthSet(&cv_numChannels,cv_numChannels.defaultvalue); -#ifdef HW3SOUND - if (hws_mode != HWS_DEFAULT_MODE) - { - HW3S_SetSourcesNum(); - return; - } -#endif if (cv_numChannels.value) channels = (channel_t *)Z_Calloc(cv_numChannels.value * sizeof (channel_t), PU_STATIC, NULL); numofchannels = (channels ? cv_numChannels.value : 0); @@ -267,14 +255,6 @@ void S_StopSounds(void) { INT32 cnum; -#ifdef HW3SOUND - if (hws_mode != HWS_DEFAULT_MODE) - { - HW3S_StopSounds(); - return; - } -#endif - // kill all playing sounds at start of level for (cnum = 0; cnum < numofchannels; cnum++) if (channels[cnum].sfxinfo) @@ -294,13 +274,6 @@ void S_StopSoundByID(void *origin, sfxenum_t sfx_id) #if 0 if (!origin) return; -#endif -#ifdef HW3SOUND - if (hws_mode != HWS_DEFAULT_MODE) - { - HW3S_StopSoundByID(origin, sfx_id); - return; - } #endif for (cnum = 0; cnum < numofchannels; cnum++) { @@ -315,13 +288,6 @@ void S_StopSoundByNum(sfxenum_t sfxnum) { INT32 cnum; -#ifdef HW3SOUND - if (hws_mode != HWS_DEFAULT_MODE) - { - HW3S_StopSoundByNum(sfxnum); - return; - } -#endif for (cnum = 0; cnum < numofchannels; cnum++) { if (channels[cnum].sfxinfo == &S_sfx[sfxnum]) @@ -484,14 +450,6 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume) } } -#ifdef HW3SOUND - if (hws_mode != HWS_DEFAULT_MODE) - { - HW3S_StartSound(origin, sfx_id); - return; - }; -#endif - for (i = 0; i <= r_splitscreen; i++) { player_t *player = &players[displayplayers[i]]; @@ -649,12 +607,7 @@ void S_StartSound(const void *origin, sfxenum_t sfx_id) return; // the volume is handled 8 bits -#ifdef HW3SOUND - if (hws_mode != HWS_DEFAULT_MODE) - HW3S_StartSound(origin, sfx_id); - else -#endif - S_StartSoundAtVolume(origin, sfx_id, 255); + S_StartSoundAtVolume(origin, sfx_id, 255); } void S_ReducedVFXSoundAtVolume(const void *origin, sfxenum_t sfx_id, INT32 volume, player_t *owner) @@ -687,13 +640,6 @@ void S_StopSound(void *origin) if (!origin) return; -#ifdef HW3SOUND - if (hws_mode != HWS_DEFAULT_MODE) - { - HW3S_StopSound(origin); - return; - } -#endif for (cnum = 0; cnum < numofchannels; cnum++) { if (channels[cnum].sfxinfo && channels[cnum].origin == origin) @@ -765,14 +711,6 @@ void S_UpdateSounds(void) I_UpdateMumble(players[consoleplayer].mo, listener[0]); #endif -#ifdef HW3SOUND - if (hws_mode != HWS_DEFAULT_MODE) - { - HW3S_UpdateSources(); - goto notinlevel; - } -#endif - for (i = 0; i <= r_splitscreen; i++) { player_t *player = &players[displayplayers[i]]; @@ -919,12 +857,8 @@ void S_SetSfxVolume(INT32 volume) //CV_SetValue(&cv_soundvolume, volume); actualsfxvolume = volume; -#ifdef HW3SOUND - hws_mode == HWS_DEFAULT_MODE ? I_SetSfxVolume(volume&0x1F) : HW3S_SetSfxVolume(volume&0x1F); -#else // now hardware volume I_SetSfxVolume(volume); -#endif } void S_ClearSfx(void) @@ -1128,11 +1062,6 @@ INT32 S_OriginPlaying(void *origin) if (!origin) return false; -#ifdef HW3SOUND - if (hws_mode != HWS_DEFAULT_MODE) - return HW3S_OriginPlaying(origin); -#endif - for (cnum = 0; cnum < numofchannels; cnum++) if (channels[cnum].origin == origin) return 1; @@ -1145,11 +1074,6 @@ INT32 S_IdPlaying(sfxenum_t id) { INT32 cnum; -#ifdef HW3SOUND - if (hws_mode != HWS_DEFAULT_MODE) - return HW3S_IdPlaying(id); -#endif - for (cnum = 0; cnum < numofchannels; cnum++) if ((size_t)(channels[cnum].sfxinfo - S_sfx) == (size_t)id) return 1; @@ -1164,11 +1088,6 @@ INT32 S_SoundPlaying(void *origin, sfxenum_t id) if (!origin) return 0; -#ifdef HW3SOUND - if (hws_mode != HWS_DEFAULT_MODE) - return HW3S_SoundPlaying(origin, id); -#endif - for (cnum = 0; cnum < numofchannels; cnum++) { if (channels[cnum].origin == origin diff --git a/src/s_sound.h b/src/s_sound.h index bd1955187..141818bd8 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -251,10 +251,8 @@ void S_StartSoundName(void *mo, const char *soundname); void S_StopSoundByID(void *origin, sfxenum_t sfx_id); void S_StopSoundByNum(sfxenum_t sfxnum); -#ifndef HW3SOUND #define S_StartAttackSound S_StartSound #define S_StartScreamSound S_StartSound -#endif #ifdef __cplusplus } // extern "C" From acbe0b270cb25b6cb51f9afcdf5400b8044bdea3 Mon Sep 17 00:00:00 2001 From: "James R." Date: Fri, 22 Sep 2023 01:50:31 -0700 Subject: [PATCH 02/21] s_sound.c: consolidate music volume related functions, always use cvars internally --- src/d_main.cpp | 4 ++-- src/s_sound.c | 33 ++++++++++++++------------------- src/s_sound.h | 8 +++----- src/sdl/i_video.cpp | 2 +- 4 files changed, 20 insertions(+), 27 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index 7235614f2..0ff725651 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1659,8 +1659,8 @@ void D_SRB2Main(void) CONS_Printf("S_InitSfxChannels(): Setting up sound channels.\n"); I_StartupSound(); I_InitMusic(); - S_InitSfxChannels(cv_soundvolume.value); - S_InitMusicVolume(); + S_InitSfxChannels(); + S_SetMusicVolume(); } Music_Init(); diff --git a/src/s_sound.c b/src/s_sound.c index 6aa0a5b7e..134b08874 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -667,9 +667,9 @@ void S_UpdateSounds(void) // Update sound/music volumes, if changed manually at console if (actualsfxvolume != cv_soundvolume.value) - S_SetSfxVolume (cv_soundvolume.value); + S_SetSfxVolume(); if (actualdigmusicvolume != cv_digmusicvolume.value) - S_SetDigMusicVolume (cv_digmusicvolume.value); + S_SetMusicVolume(); // We're done now, if we're not in a level. if (gamestate != GS_LEVEL) @@ -852,13 +852,12 @@ void S_UpdateClosedCaptions(void) } } -void S_SetSfxVolume(INT32 volume) +void S_SetSfxVolume(void) { - //CV_SetValue(&cv_soundvolume, volume); - actualsfxvolume = volume; + actualsfxvolume = cv_soundvolume.value; // now hardware volume - I_SetSfxVolume(volume); + I_SetSfxVolume(actualsfxvolume); } void S_ClearSfx(void) @@ -1149,7 +1148,7 @@ void S_StartSoundName(void *mo, const char *soundname) // Sets channels, SFX volume, // allocates channel buffer, sets S_sfx lookup. // -void S_InitSfxChannels(INT32 sfxVolume) +void S_InitSfxChannels(void) { extern consvar_t precachesound; @@ -1158,7 +1157,7 @@ void S_InitSfxChannels(INT32 sfxVolume) if (dedicated) return; - S_SetSfxVolume(sfxVolume); + S_SetSfxVolume(); SetChannelsNum(); @@ -2010,14 +2009,10 @@ void S_ResumeAudio(void) Music_UnPauseAll(); } -void S_SetMusicVolume(INT32 digvolume) +void S_SetMusicVolume(void) { - if (digvolume < 0) - digvolume = cv_digmusicvolume.value; - - //CV_SetValue(&cv_digmusicvolume, digvolume); - actualdigmusicvolume = digvolume; - I_SetMusicVolume(digvolume); + actualdigmusicvolume = cv_digmusicvolume.value; + I_SetMusicVolume(actualdigmusicvolume); } /// ------------------------ @@ -2138,8 +2133,8 @@ static void Command_RestartAudio_f(void) // These must be called or no sound and music until manually set. - I_SetSfxVolume(cv_soundvolume.value); - S_SetMusicVolume(cv_digmusicvolume.value); + S_SetSfxVolume(); + S_SetMusicVolume(); S_StartSound(NULL, sfx_strpst); @@ -2311,7 +2306,7 @@ void GameSounds_OnChange(void) { sound_disabled = false; I_StartupSound(); // will return early if initialised - S_InitSfxChannels(cv_soundvolume.value); + S_InitSfxChannels(); S_StartSound(NULL, sfx_strpst); } else @@ -2350,7 +2345,7 @@ void PlayMusicIfUnfocused_OnChange(void) if (cv_playmusicifunfocused.value) I_SetMusicVolume(0); else - S_InitMusicVolume(); + S_SetMusicVolume(); } } diff --git a/src/s_sound.h b/src/s_sound.h index 141818bd8..5da78c10b 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -98,7 +98,7 @@ void S_RegisterSoundStuff(void); // Initializes sound stuff, including volume // Sets channels, SFX, allocates channel buffer, sets S_sfx lookup. // -void S_InitSfxChannels(INT32 sfxVolume); +void S_InitSfxChannels(void); // // Per level startup code. @@ -237,10 +237,8 @@ FUNCMATH fixed_t S_CalculateSoundDistance(fixed_t px1, fixed_t py1, fixed_t pz1, INT32 S_GetSoundVolume(sfxinfo_t *sfx, INT32 volume); -void S_SetSfxVolume(INT32 volume); -void S_SetMusicVolume(INT32 digvolume); -#define S_SetDigMusicVolume S_SetMusicVolume -#define S_InitMusicVolume() S_SetMusicVolume(-1) +void S_SetSfxVolume(void); +void S_SetMusicVolume(void); INT32 S_OriginPlaying(void *origin); INT32 S_IdPlaying(sfxenum_t id); diff --git a/src/sdl/i_video.cpp b/src/sdl/i_video.cpp index cd5ba1848..84af0eed8 100644 --- a/src/sdl/i_video.cpp +++ b/src/sdl/i_video.cpp @@ -513,7 +513,7 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt) // Tell game we got focus back, resume music if necessary window_notinfocus = false; - S_InitMusicVolume(); + S_SetMusicVolume(); if (!firsttimeonmouse) { From 2230c855aeb201df0754ad4c3d16e85dfbcba680 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Mon, 21 Aug 2023 02:14:25 -0400 Subject: [PATCH 03/21] Some quake improvements - Use easing functions for quake intensity - Camera distance takes Z height into account --- src/p_spec.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index a9dc3760f..3d7fda055 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -47,6 +47,7 @@ #include "k_respawn.h" #include "k_terrain.h" #include "acs/interface.h" +#include "m_easing.h" #ifdef HW3SOUND #include "hardware/hw3sound.h" @@ -9411,17 +9412,20 @@ void P_DoQuakeOffset(UINT8 view, mappoint_t *viewPos, mappoint_t *offset) ir = quake->intensity; // Modulate with time remaining. - ir = FixedMul(ir, 2 * FRACUNIT * (quake->time + 1) / quake->startTime); + ir = Easing_InOutSine(FRACUNIT * (quake->time + 1) / quake->startTime, ir, 0); // Modulate with distance from epicenter, if it exists. if (quake->radius > 0 && quake->epicenter != NULL) { fixed_t epidist = P_AproxDistance( - viewPos->x - quake->epicenter->x, - viewPos->y - quake->epicenter->y + P_AproxDistance( + viewPos->x - quake->epicenter->x, + viewPos->y - quake->epicenter->y + ), + viewPos->z - quake->epicenter->z ); - ir = FixedMul(ir, FixedDiv(max(0, quake->radius - epidist), quake->radius)); + ir = Easing_InOutSine(min(FRACUNIT, FixedDiv(epidist, quake->radius)), ir, 0); } addZ += ir; From e6a19362fc7e19ffb9a38c8b4f98a60b5fa32fcd Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Wed, 20 Sep 2023 23:43:59 -0400 Subject: [PATCH 04/21] Center mobj quake on the z axis --- src/p_spec.c | 2 +- src/p_tick.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index 3d7fda055..d658a7648 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -9390,7 +9390,7 @@ void P_StartQuakeFromMobj(tic_t time, fixed_t intensity, fixed_t radius, mobj_t quake->epicenter = (mappoint_t *)Z_Malloc(sizeof(mappoint_t), PU_LEVEL, NULL); quake->epicenter->x = mobj->x; quake->epicenter->y = mobj->y; - quake->epicenter->z = mobj->z; + quake->epicenter->z = mobj->z + (mobj->height / 2); } void P_DoQuakeOffset(UINT8 view, mappoint_t *viewPos, mappoint_t *offset) diff --git a/src/p_tick.c b/src/p_tick.c index 737ff9ba2..f411aa382 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -1026,7 +1026,7 @@ void P_Ticker(boolean run) { quake->epicenter->x = quake->mobj->x; quake->epicenter->y = quake->mobj->y; - quake->epicenter->z = quake->mobj->z; + quake->epicenter->z = quake->mobj->z + (quake->mobj->height / 2); } quake = quake->next; From ca0b5902ba1ee80db48fbaab1e2ebc033033e748 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 23 Sep 2023 06:11:40 -0400 Subject: [PATCH 05/21] Fix use of easing functions, add distance buffer --- src/p_spec.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index d658a7648..dd73fcd7d 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -9412,20 +9412,24 @@ void P_DoQuakeOffset(UINT8 view, mappoint_t *viewPos, mappoint_t *offset) ir = quake->intensity; // Modulate with time remaining. - ir = Easing_InOutSine(FRACUNIT * (quake->time + 1) / quake->startTime, ir, 0); + const fixed_t timeEase = (FRACUNIT * ((quake->startTime - quake->time) - 1)) / quake->startTime; + ir = Easing_InCubic(timeEase, ir, 0); // Modulate with distance from epicenter, if it exists. if (quake->radius > 0 && quake->epicenter != NULL) { - fixed_t epidist = P_AproxDistance( + const fixed_t distBuffer = 256 * mapobjectscale; // add a small buffer zone before it starts to drop off + const fixed_t epidist = P_AproxDistance( P_AproxDistance( viewPos->x - quake->epicenter->x, viewPos->y - quake->epicenter->y ), viewPos->z - quake->epicenter->z - ); + ) - distBuffer; - ir = Easing_InOutSine(min(FRACUNIT, FixedDiv(epidist, quake->radius)), ir, 0); + + const fixed_t distEase = min(FixedDiv(max(epidist, 0), quake->radius), FRACUNIT); + ir = Easing_InCubic(distEase, ir, 0); } addZ += ir; From 91955b1383227886eed5404f885225a28b41667a Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 23 Sep 2023 06:22:47 -0400 Subject: [PATCH 06/21] Broly screen shake is done on the source object Screen shake was being done from the Broly vfx, which does scaling shenanigans so it caused Proximity Mine explosions to make the camera go apeshit. I'm also pretty sure the hitlag calcs Proximity Mine did for the broly effect was wrong, not sure though? I'm trying something else and I think it's better. --- src/k_collide.cpp | 14 ++++++-------- src/k_kart.c | 7 +++++++ src/objects/broly.c | 2 ++ src/p_enemy.c | 3 +-- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/k_collide.cpp b/src/k_collide.cpp index b897873a8..0d1d46348 100644 --- a/src/k_collide.cpp +++ b/src/k_collide.cpp @@ -305,7 +305,7 @@ static inline BlockItReturn_t PIT_SSMineExplode(mobj_t *thing) lagadded = (thing->hitlag - oldhitlag); - if (lagadded > 0) + if (lagadded > minehitlag) { minehitlag = lagadded; } @@ -337,19 +337,17 @@ tic_t K_MineExplodeAttack(mobj_t *actor, fixed_t size, boolean spin) // Set this flag to ensure that the inital action won't be triggered twice. actor->flags2 |= MF2_DEBRIS; + if (minehitlag == 0) + { + minehitlag = actor->hitlag; + } + // Set this flag to ensure the hitbox timer doesn't get extended with every player hit actor->flags |= MF_NOHITLAGFORME; actor->hitlag = 0; // same deal if (!spin) { - if (minehitlag == 0) - { - minehitlag = actor->hitlag; - } - - Obj_SpawnBrolyKi(actor, minehitlag); - return minehitlag; } diff --git a/src/k_kart.c b/src/k_kart.c index c4c48c630..4afe202ff 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4499,6 +4499,11 @@ void K_MineFlashScreen(mobj_t *source) INT32 pnum; player_t *p; + if (P_MobjWasRemoved(source)) + { + return; + } + S_StartSound(source, sfx_s3k4e); P_StartQuakeFromMobj(12, 55 * source->scale, MINEQUAKEDIST * source->scale, source); @@ -4608,6 +4613,8 @@ void K_SpawnMineExplosion(mobj_t *source, UINT8 color, tic_t delay) truc->hitlag += delay; truc->renderflags |= RF_DONTDRAW; } + + Obj_SpawnBrolyKi(source, delay); } #undef MINEQUAKEDIST diff --git a/src/objects/broly.c b/src/objects/broly.c index d8e2c8ffd..f67847ad1 100644 --- a/src/objects/broly.c +++ b/src/objects/broly.c @@ -37,6 +37,8 @@ Obj_SpawnBrolyKi x = P_SpawnMobjFromMobj( source, 0, 0, 0, MT_BROLY); + P_SetTarget(&x->target, source); + // Shrink into center of source object. x->z = (source->z + source->height / 2); diff --git a/src/p_enemy.c b/src/p_enemy.c index b8bedfc5e..31f43f371 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -13063,12 +13063,11 @@ void A_SSMineExplode(mobj_t *actor) void A_SSMineFlash(mobj_t *actor) { - K_MineFlashScreen(actor); + K_MineFlashScreen(actor->target); } void A_LandMineExplode(mobj_t *actor) { - mobj_t *expl; INT32 colour = SKINCOLOR_KETCHUP; // we spell words properly here INT32 i; From 8e6211759690dc63e7012dd8cb4bd8ee77f31aa0 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 23 Sep 2023 09:57:16 -0400 Subject: [PATCH 07/21] Damage hitlag sounds --- src/k_hitlag.c | 29 ++++++++++++++++++++++++++++- src/k_hitlag.h | 1 + src/p_inter.c | 2 +- src/sounds.c | 10 ++++++++++ src/sounds.h | 10 ++++++++++ 5 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/k_hitlag.c b/src/k_hitlag.c index fd682c4c1..4bb0d37f3 100644 --- a/src/k_hitlag.c +++ b/src/k_hitlag.c @@ -18,6 +18,7 @@ #include "m_random.h" #include "p_local.h" #include "r_main.h" +#include "s_sound.h" /*-------------------------------------------------- void K_AddHitLag(mobj_t *mo, INT32 tics, boolean fromDamage) @@ -129,13 +130,38 @@ static void K_SpawnSingleHitLagSpark( } } +/*-------------------------------------------------- + static void K_PlayHitLagSFX(mobj_t *victim, UINT8 tics) + + Plays a damage sound for a player. + + Input Arguments:- + victim - Object getting damaged. + tics - How long the hitlag was. + + Return:- + N/A +--------------------------------------------------*/ +static void K_PlayHitLagSFX(mobj_t *victim, UINT8 tics) +{ + sfxenum_t soundID = sfx_dmga1; + + if (P_Random(PR_DECORATION) & 1) // might want to use this set for some other scenario, instead of randomized? + { + soundID = sfx_dmgb1; + } + + soundID += ((tics * (NUM_HITLAG_SOUNDS - 1)) + (MAXHITLAGTICS >> 1)) / MAXHITLAGTICS; + S_StartSound(victim, soundID); +} + /*-------------------------------------------------- static void K_SpawnHitLagEFX(mobj_t *victim, mobj_t *inflictor, mobj_t *source, UINT8 tics) Spawns several hitlag sparks for damage. Input Arguments:- - victim - Object getting touched. + victim - Object getting damaged. inflictor - Object touching the victim. May be NULL. source - Object that inflictor came from. May be NULL or same as inflictor. tics - How long the hitlag was. @@ -152,6 +178,7 @@ static void K_SpawnHitLagEFX(mobj_t *victim, mobj_t *inflictor, mobj_t *source, I_Assert(P_MobjWasRemoved(victim) == false); + K_PlayHitLagSFX(victim, tics); P_StartQuakeFromMobj(tics, tics * 2 * mapobjectscale, 512 * mapobjectscale, victim); if (P_MobjWasRemoved(inflictor) == false) diff --git a/src/k_hitlag.h b/src/k_hitlag.h index cace7a964..fed3b75cc 100644 --- a/src/k_hitlag.h +++ b/src/k_hitlag.h @@ -23,6 +23,7 @@ extern "C" { #define MAXHITLAGTICS (30) #define HITLAGJITTERS (FRACUNIT / 20) #define NUM_HITLAG_STATES (9) +#define NUM_HITLAG_SOUNDS (4) /*-------------------------------------------------- void K_AddHitLag(mobj_t *mo, INT32 tics, boolean fromDamage); diff --git a/src/p_inter.c b/src/p_inter.c index 6176201ec..2c29b0c19 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2752,7 +2752,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da if (type != DMG_STING) player->flashing = K_GetKartFlashing(player); - P_PlayRinglossSound(target); + //P_PlayRinglossSound(target); P_PlayerRingBurst(player, ringburst); K_PopPlayerShield(player); diff --git a/src/sounds.c b/src/sounds.c index 18bfa26d9..747331ff7 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -1210,6 +1210,16 @@ sfxinfo_t S_sfx[NUMSFX] = {"rank", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Rank slam + // Damage sounds + {"dmga1", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"}, + {"dmga2", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"}, + {"dmga3", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"}, + {"dmga4", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"}, + {"dmgb1", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"}, + {"dmgb2", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"}, + {"dmgb3", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"}, + {"dmgb4", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"}, + // SRB2Kart - Engine sounds // Engine class A {"krta00", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR, ""}, diff --git a/src/sounds.h b/src/sounds.h index b9b0616e0..7c55906c0 100644 --- a/src/sounds.h +++ b/src/sounds.h @@ -1279,6 +1279,16 @@ typedef enum sfx_rank, + // Damage sounds + sfx_dmga1, + sfx_dmga2, + sfx_dmga3, + sfx_dmga4, + sfx_dmgb1, + sfx_dmgb2, + sfx_dmgb3, + sfx_dmgb4, + // Next up: UNIQUE ENGINE SOUNDS! Hoooooo boy... // Engine class A - Low Speed, Low Weight sfx_krta00, From c6897688d011ee573f382d0247d39fc644f7f517 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 23 Sep 2023 10:42:00 -0400 Subject: [PATCH 08/21] Delay ring burst after damage --- src/d_player.h | 1 + src/lua_playerlib.c | 4 ++++ src/p_inter.c | 3 +-- src/p_mobj.c | 8 ++++++++ src/p_saveg.c | 2 ++ src/sounds.c | 16 ++++++++-------- 6 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index b325137ea..b70a315ed 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -668,6 +668,7 @@ struct player_t UINT16 superring; // You were awarded rings, and have this many of them left to spawn on yourself. UINT8 nextringaward; // When should we spawn our next superring ring? UINT16 ringvolume; // When consuming lots of rings, lower the sound a little. + UINT16 ringburst; // Queued number of rings to lose after hitlag ends UINT8 curshield; // see kartshields_t UINT8 bubblecool; // Bubble Shield use cooldown diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index dca270903..c30d0d54d 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -361,6 +361,8 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->nextringaward); else if (fastcmp(field,"ringvolume")) lua_pushinteger(L, plr->ringvolume); + else if (fastcmp(field,"ringburst")) + lua_pushinteger(L, plr->ringburst); else if (fastcmp(field,"curshield")) lua_pushinteger(L, plr->curshield); else if (fastcmp(field,"bubblecool")) @@ -775,6 +777,8 @@ static int player_set(lua_State *L) plr->nextringaward = luaL_checkinteger(L, 3); else if (fastcmp(field,"ringvolume")) plr->ringvolume = luaL_checkinteger(L, 3); + else if (fastcmp(field,"ringburst")) + plr->ringburst = luaL_checkinteger(L, 3); else if (fastcmp(field,"curshield")) plr->curshield = luaL_checkinteger(L, 3); else if (fastcmp(field,"bubblecool")) diff --git a/src/p_inter.c b/src/p_inter.c index 2c29b0c19..fcf301f3c 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2752,8 +2752,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da if (type != DMG_STING) player->flashing = K_GetKartFlashing(player); - //P_PlayRinglossSound(target); - P_PlayerRingBurst(player, ringburst); + player->ringburst += ringburst; K_PopPlayerShield(player); player->instashield = 15; diff --git a/src/p_mobj.c b/src/p_mobj.c index 599dd37e8..dc3dd037a 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10031,6 +10031,14 @@ void P_MobjThinker(mobj_t *mobj) if (mobj->player != NULL && mobj->hitlag == 0 && (mobj->eflags & MFE_DAMAGEHITLAG)) { + if (mobj->player->ringburst > 0) + { + // Delayed ring loss + P_PlayRinglossSound(mobj); + P_PlayerRingBurst(mobj->player, mobj->player->ringburst); + mobj->player->ringburst = 0; + } + K_HandleDirectionalInfluence(mobj->player); } diff --git a/src/p_saveg.c b/src/p_saveg.c index 21414f22c..6c61e7f6a 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -468,6 +468,7 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEUINT16(save->p, players[i].superring); WRITEUINT8(save->p, players[i].nextringaward); WRITEUINT8(save->p, players[i].ringvolume); + WRITEUINT16(save->p, players[i].ringburst); WRITEUINT8(save->p, players[i].curshield); WRITEUINT8(save->p, players[i].bubblecool); @@ -946,6 +947,7 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].superring = READUINT16(save->p); players[i].nextringaward = READUINT8(save->p); players[i].ringvolume = READUINT8(save->p); + players[i].ringburst = READUINT16(save->p); players[i].curshield = READUINT8(save->p); players[i].bubblecool = READUINT8(save->p); diff --git a/src/sounds.c b/src/sounds.c index 747331ff7..e802d0664 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -1211,14 +1211,14 @@ sfxinfo_t S_sfx[NUMSFX] = {"rank", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Rank slam // Damage sounds - {"dmga1", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"}, - {"dmga2", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"}, - {"dmga3", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"}, - {"dmga4", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"}, - {"dmgb1", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"}, - {"dmgb2", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"}, - {"dmgb3", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"}, - {"dmgb4", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"}, + {"dmga1", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"}, + {"dmga2", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"}, + {"dmga3", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"}, + {"dmga4", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"}, + {"dmgb1", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"}, + {"dmgb2", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"}, + {"dmgb3", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"}, + {"dmgb4", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Damaged"}, // SRB2Kart - Engine sounds // Engine class A From 6c9a253ebf20b49864b9962028bb58142b89e21e Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 23 Sep 2023 14:49:28 -0400 Subject: [PATCH 09/21] Polish ring spill More circular by using pitch, takes gravity into account, actually has a code path for ring loss that's more than 5 rings --- src/p_inter.c | 47 +++++++++++++++++++---------------------------- 1 file changed, 19 insertions(+), 28 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index fcf301f3c..badd6d3a3 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2828,6 +2828,9 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da return true; } +#define RING_LAYER_SIDE_SIZE (3) +#define RING_LAYER_SIZE (RING_LAYER_SIDE_SIZE * 2) + static void P_FlingBurst ( player_t *player, angle_t fa, @@ -2836,16 +2839,11 @@ static void P_FlingBurst fixed_t objScale, INT32 i) { - mobj_t *mo; - fixed_t ns; - fixed_t momxy = 5<> 1; - - mo = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, objType); + mobj_t *mo = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, objType); + P_SetTarget(&mo->target, player->mo); mo->threshold = 10; // not useful for spikes mo->fuse = objFuse; - P_SetTarget(&mo->target, player->mo); // We want everything from P_SpawnMobjFromMobj except scale. objScale = FixedMul(objScale, FixedDiv(mapobjectscale, player->mo->scale)); @@ -2856,27 +2854,20 @@ static void P_FlingBurst mo->destscale = mo->scale; } - /* - 0: 0 - 1: 1 = (1+1)/2 = 1 - 2: 1 = (2+1)/2 = 1 - 3: 2 = (3+1)/2 = 2 - 4: 2 = (4+1)/2 = 2 - 5: 3 = (4+1)/2 = 2 - */ - // Angle / height offset changes every other ring - momxy -= mx * FRACUNIT; - momz += mx * (2<mo->scale); - mo->momx = (mo->target->momx/2) + FixedMul(FINECOSINE(fa>>ANGLETOFINESHIFT), ns); - mo->momy = (mo->target->momy/2) + FixedMul(FINESINE(fa>>ANGLETOFINESHIFT), ns); + // Pitch offset changes every other ring + angle_t offset = ANGLE_90 / (RING_LAYER_SIDE_SIZE + 2); + angle_t fp = offset + (((i / 2) % RING_LAYER_SIDE_SIZE) * (offset * 3 >> 1)); - ns = FixedMul(momz, player->mo->scale); - mo->momz = (mo->target->momz/2) + ((ns) * P_MobjFlip(mo)); + const UINT8 layer = i / RING_LAYER_SIZE; + const fixed_t thrust = (13 * mo->scale) + (7 * mo->scale * layer); + mo->momx = (player->mo->momx / 2) + FixedMul(FixedMul(thrust, FINECOSINE(fp >> ANGLETOFINESHIFT)), FINECOSINE(fa >> ANGLETOFINESHIFT)); + mo->momy = (player->mo->momy / 2) + FixedMul(FixedMul(thrust, FINECOSINE(fp >> ANGLETOFINESHIFT)), FINESINE(fa >> ANGLETOFINESHIFT)); + mo->momz = (player->mo->momz / 2) + (FixedMul(thrust, FINESINE(fp >> ANGLETOFINESHIFT)) * P_MobjFlip(mo)); } /** Spills an injured player's rings. @@ -2888,7 +2879,7 @@ static void P_FlingBurst */ void P_PlayerRingBurst(player_t *player, INT32 num_rings) { - INT32 num_fling_rings; + INT32 spill_total, num_fling_rings; INT32 i; angle_t fa; @@ -2910,8 +2901,8 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings) else if (num_rings <= 0) return; - num_rings = -P_GivePlayerRings(player, -num_rings); - num_fling_rings = num_rings+min(0, player->rings); + spill_total = -P_GivePlayerRings(player, -num_rings); + num_fling_rings = spill_total + min(0, player->rings); // determine first angle fa = player->mo->angle + ((P_RandomByte(PR_ITEM_RINGS) & 1) ? -ANGLE_90 : ANGLE_90); @@ -2921,7 +2912,7 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings) P_FlingBurst(player, fa, MT_FLINGRING, 60*TICRATE, FRACUNIT, i); } - while (i < num_rings) + while (i < spill_total) { P_FlingBurst(player, fa, MT_DEBTSPIKE, 0, 3 * FRACUNIT / 2, i++); } From 36f8a64d656207745d8b2fd57b6f01b2a65c82c5 Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 22 Sep 2023 00:38:48 +0100 Subject: [PATCH 10/21] Stereo Mode: Add "shf" (Shuffle) option This basically came to me in a dream, who am I to look the horse in its mouth - Press to start a shuffled sequence, losing your current position in the autosequence. - Press again to disable, but keep your current track. - Adjust horizontal offset of Stereo buttons slightly. - More judiciously comment Sound Test functionality, to assist future maintainers. --- src/k_menu.h | 1 + src/k_menudraw.c | 7 +- src/menus/transient/sound-test.c | 30 ++++- src/s_sound.c | 182 +++++++++++++++++++++++++++++-- src/s_sound.h | 4 + 5 files changed, 209 insertions(+), 15 deletions(-) diff --git a/src/k_menu.h b/src/k_menu.h index ea894fd3e..858749463 100644 --- a/src/k_menu.h +++ b/src/k_menu.h @@ -1309,6 +1309,7 @@ typedef enum stereospecial_pause, stereospecial_play, stereospecial_seq, + stereospecial_shf, stereospecial_vol, stereospecial_track, } stereospecial_e; diff --git a/src/k_menudraw.c b/src/k_menudraw.c index 84a216f34..0083ae643 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -7089,6 +7089,11 @@ void M_DrawSoundTest(void) if (soundtest.autosequence == true) y = currentMenu->y + 6; } + else if (currentMenu->menuitems[i].mvar2 == stereospecial_shf) // shf + { + if (soundtest.shuffle == true) + y = currentMenu->y + 6; + } // Button is being pressed if (i == itemOn && !soundtest.justopened && M_MenuConfirmHeld(pid)) @@ -7199,7 +7204,7 @@ void M_DrawSoundTest(void) V_DrawCenteredThinString(x + 13, y + 1, 0, currentMenu->menuitems[i].text); } - x += 27; + x += 25; } V_DrawCharacter(cursorx - 4, currentMenu->y - 8 - (skullAnimCounter/5), diff --git a/src/menus/transient/sound-test.c b/src/menus/transient/sound-test.c index 8fc18ef01..a32a912ca 100644 --- a/src/menus/transient/sound-test.c +++ b/src/menus/transient/sound-test.c @@ -82,6 +82,26 @@ static void M_SoundTestSeq(INT32 choice) soundtest.autosequence ^= true; } +static void M_SoundTestShf(INT32 choice) +{ + (void)choice; + + if (soundtest.shuffle) + { + soundtest.shuffle = false; + soundtest.sequence.shuffleinfo = 0; + } + else + { + S_SoundTestStop(); + + soundtest.playing = true; + soundtest.autosequence = true; + soundtest.shuffle = true; + S_UpdateSoundTestDef(false, false, false); + } +} + consvar_t *M_GetSoundTestVolumeCvar(void) { if (soundtest.current == NULL) @@ -160,18 +180,20 @@ static void M_SoundTestTick(void) menuitem_t MISC_SoundTest[] = { {IT_STRING | IT_CALL, "Back", "STER_IC0", NULL, {.routine = M_GoBack}, 0, stereospecial_back}, - {IT_SPACE, NULL, NULL, NULL, {NULL}, 11, 0}, + {IT_SPACE, NULL, NULL, NULL, {NULL}, 6, 0}, {IT_STRING | IT_CALL, "Stop", "STER_IC1", NULL, {.routine = M_SoundTestMainControl}, 0, 0}, - {IT_SPACE, NULL, NULL, NULL, {NULL}, 8, 0}, + {IT_SPACE, NULL, NULL, NULL, {NULL}, 6, 0}, {IT_STRING | IT_CALL, "Pause", "STER_IC2", NULL, {.routine = M_SoundTestMainControl}, 2, stereospecial_pause}, {IT_STRING | IT_CALL, "Play", "STER_IC3", NULL, {.routine = M_SoundTestMainControl}, 1, stereospecial_play}, - {IT_SPACE, NULL, NULL, NULL, {NULL}, 8, 0}, + {IT_SPACE, NULL, NULL, NULL, {NULL}, 6, 0}, {IT_STRING | IT_CALL, "Prev", "STER_IC4", NULL, {.routine = M_SoundTestNextPrev}, -1, 0}, {IT_STRING | IT_CALL, "Next", "STER_IC5", NULL, {.routine = M_SoundTestNextPrev}, 1, 0}, - {IT_SPACE, NULL, NULL, NULL, {NULL}, 8, 0}, + {IT_SPACE, NULL, NULL, NULL, {NULL}, 6, 0}, {IT_STRING | IT_ARROWS, "Seq", "STER_IC6", NULL, {.routine = M_SoundTestSeq}, 0, stereospecial_seq}, + {IT_STRING | IT_ARROWS, "Shf", "STER_IC7", NULL, {.routine = M_SoundTestShf}, 0, stereospecial_shf}, {IT_SPACE, NULL, NULL, NULL, {NULL}, 0, 244}, {IT_STRING | IT_ARROWS, "Vol", NULL, NULL, {.routine = M_SoundTestVol}, 0, stereospecial_vol}, + {IT_SPACE, NULL, NULL, NULL, {NULL}, 2, 0}, {IT_STRING | IT_ARROWS, "Track", NULL, NULL, {.routine = M_SoundTestTrack}, 0, stereospecial_track}, }; diff --git a/src/s_sound.c b/src/s_sound.c index 9d5be54d4..7c3415f4e 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -32,7 +32,7 @@ #include "lua_hook.h" // MusicChange hook #include "byteptr.h" #include "k_menu.h" // M_PlayMenuJam -#include "m_random.h" // P_RandomKey +#include "m_random.h" // M_RandomKey #include "i_time.h" #include "v_video.h" // V_ThinStringWidth #include "music.h" @@ -1366,6 +1366,10 @@ void S_PopulateSoundTestSequence(void) if (soundtest.sequence.id == 0) soundtest.sequence.id = 1; + // Prepare shuffle material. + soundtest.sequence.shuffleinfo = 0; + soundtest.sequence.shufflenext = NULL; + soundtest.sequence.next = NULL; tail = &soundtest.sequence.next; @@ -1437,6 +1441,11 @@ void S_PopulateSoundTestSequence(void) for (def = musicdefstart; def; def = def->next) { + // This is the simplest set of checks, + // so let's wipe the shuffle data here. + def->sequence.shuffleinfo = 0; + def->sequence.shufflenext = NULL; + if (def->sequence.id == soundtest.sequence.id) continue; @@ -1467,12 +1476,11 @@ static boolean S_SoundTestDefLocked(musicdef_t *def) void S_UpdateSoundTestDef(boolean reverse, boolean dotracks, boolean skipnull) { - musicdef_t *newdef; - - newdef = NULL; + musicdef_t *newdef = NULL; if (reverse == false) { + // Track update if (dotracks == true && soundtest.current != NULL && soundtest.currenttrack < soundtest.current->numtracks-1) { @@ -1480,22 +1488,146 @@ void S_UpdateSoundTestDef(boolean reverse, boolean dotracks, boolean skipnull) goto updatetrackonly; } - newdef = (soundtest.current != NULL) - ? soundtest.current->sequence.next - : soundtest.sequence.next; - while (newdef != NULL && S_SoundTestDefLocked(newdef)) - newdef = newdef->sequence.next; - if (newdef == NULL && skipnull == true) + if (soundtest.shuffle == true && soundtest.sequence.shuffleinfo == 0) { + // The shuffle data isn't initialised. + // Count the valid set of musicdefs we can randomly select from! + // This will later liberally be passed to M_RandomKey. + newdef = soundtest.sequence.next; + while (newdef != NULL) + { + if (S_SoundTestDefLocked(newdef) == false) + { + newdef->sequence.shuffleinfo = 0; + soundtest.sequence.shuffleinfo++; + } + else + { + // Don't permit if it gets unlocked before shuffle count gets reset + newdef->sequence.shuffleinfo = (size_t)-1; + } + newdef->sequence.shufflenext = NULL; + + newdef = newdef->sequence.next; + } + soundtest.sequence.shufflenext = NULL; + } + + if (soundtest.shuffle == true) + { + // Do we have it cached..? + newdef = soundtest.current != NULL + ? soundtest.current->sequence.shufflenext + : soundtest.sequence.shufflenext; + + if (newdef != NULL) + ; + else if (soundtest.sequence.shuffleinfo != 0) + { + // Nope, not cached. Grab a random entry and hunt for it. + size_t shuffleseek = M_RandomKey(soundtest.sequence.shuffleinfo); + size_t shuffleseekcopy = shuffleseek; + + // Since these are sequential, we can sometimes + // get a small benefit by starting partway down the list. + if ( + soundtest.current != NULL + && soundtest.current->sequence.shuffleinfo != 0 + && soundtest.current->sequence.shuffleinfo <= shuffleseek + ) + { + newdef = soundtest.current; + shuffleseek -= (soundtest.current->sequence.shuffleinfo - 1); + } + else + { + newdef = soundtest.sequence.next; + } + + // ...yeah, though, this is basically O(n). I could provide a + // great many excuses, but the basic impetus is that I saw + // a thread on an open-source software development forum where, + // since 2014, a parade of users have been asking for the same + // basic QoL feature and been consecutively berated by one developer + // extremely against the idea of implmenting something imperfect. + // I have enough self-awareness as a programmer to recognise that + // that is a chronic case of "PROGRAMMER BRAIN". Sometimes you + // just need to do a feature "badly" because it's more important + // for it to exist at all than to channel mathematical elegance. + // ~toast 220923 + + for (; newdef != NULL; newdef = newdef->sequence.next) + { + if (newdef->sequence.shuffleinfo != 0) + continue; + + if (S_SoundTestDefLocked(newdef) == true) + continue; + + if (shuffleseek != 0) + { + shuffleseek--; + continue; + } + break; + } + + if (newdef == NULL) + { + // Fell short!? Try again later + soundtest.sequence.shuffleinfo = 0; + } + else + { + // Don't select the same entry twice + if (soundtest.sequence.shuffleinfo) + soundtest.sequence.shuffleinfo--; + + // One-indexed so the first shuffled entry has a valid shuffleinfo + newdef->sequence.shuffleinfo = shuffleseekcopy+1; + + // Link it to the end of the chain + if (soundtest.current && soundtest.current->sequence.shuffleinfo != 0) + { + soundtest.current->sequence.shufflenext = newdef; + } + else + { + soundtest.sequence.shufflenext = newdef; + } + } + } + } + else + { + // Just blaze through the musicdefs + newdef = (soundtest.current != NULL) + ? soundtest.current->sequence.next + : soundtest.sequence.next; while (newdef != NULL && S_SoundTestDefLocked(newdef)) newdef = newdef->sequence.next; + + if (newdef == NULL && skipnull == true) + { + newdef = soundtest.sequence.next; + while (newdef != NULL && S_SoundTestDefLocked(newdef)) + newdef = newdef->sequence.next; + } } } else { + // Everything in this case is doing a full-on O(n) search + // for the previous entry in one of two singly linked lists. + // I know there are better solutions. It basically boils + // down to the fact that this code only runs on direct user + // input on a menu, never in the background, and therefore + // is straight up less important than the forwards direction. + musicdef_t *def, *lastdef = NULL; + // Track update if (dotracks == true && soundtest.current != NULL && soundtest.currenttrack > 0) { @@ -1503,6 +1635,34 @@ void S_UpdateSoundTestDef(boolean reverse, boolean dotracks, boolean skipnull) goto updatetrackonly; } + if (soundtest.shuffle && soundtest.current != NULL) + { + // Basically identical structure to the sequence.next case... templates might be cool one day + + if (soundtest.sequence.shufflenext == soundtest.current) + ; + else for (def = soundtest.sequence.shufflenext; def; def = def->sequence.shufflenext) + { + if (!S_SoundTestDefLocked(def)) + { + lastdef = def; + } + + if (def->sequence.shufflenext != soundtest.current) + { + continue; + } + + newdef = lastdef; + break; + } + + goto updatecurrent; + } + + soundtest.shuffle = false; + soundtest.sequence.shuffleinfo = 0; + if (soundtest.current == soundtest.sequence.next && skipnull == false) { @@ -1617,6 +1777,8 @@ void S_SoundTestStop(void) soundtest.playing = false; soundtest.autosequence = false; + soundtest.shuffle = false; + soundtest.sequence.shuffleinfo = 0; Music_Stop("stereo"); Music_Stop("stereo_fade"); diff --git a/src/s_sound.h b/src/s_sound.h index bd1955187..272822a0e 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -150,6 +150,9 @@ struct soundtestsequence_t UINT8 id; UINT16 map; musicdef_t *next; + + size_t shuffleinfo; + musicdef_t *shufflenext; }; // Music credits @@ -195,6 +198,7 @@ extern struct soundtest soundtestsequence_t sequence; // Sequence head boolean autosequence; // In auto sequence mode? + boolean shuffle; // In shuffle mode; } soundtest; void S_PopulateSoundTestSequence(void); From 1ffc7d7c829330ea99338a9302899b240eedc95f Mon Sep 17 00:00:00 2001 From: Eidolon Date: Sun, 24 Sep 2023 14:30:41 -0500 Subject: [PATCH 11/21] r_things.c -> r_things.cpp --- src/CMakeLists.txt | 2 +- src/{r_things.c => r_things.cpp} | 86 ++++++++++++++++---------------- 2 files changed, 45 insertions(+), 43 deletions(-) rename src/{r_things.c => r_things.cpp} (97%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 684b8c6b9..917020a75 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -78,7 +78,7 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32 r_sky.c r_splats.c r_spritefx.cpp - r_things.c + r_things.cpp r_bbox.c r_textures.c r_textures_dups.cpp diff --git a/src/r_things.c b/src/r_things.cpp similarity index 97% rename from src/r_things.c rename to src/r_things.cpp index d94ed27af..fea738fe9 100644 --- a/src/r_things.c +++ b/src/r_things.cpp @@ -8,9 +8,11 @@ // terms of the GNU General Public License, version 2. // See the 'LICENSE' file for more details. //----------------------------------------------------------------------------- -/// \file r_things.c +/// \file r_things.cpp /// \brief Refresh of things, i.e. objects represented by sprites +#include + #include "doomdef.h" #include "console.h" #include "g_game.h" @@ -325,7 +327,7 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16 if (Picture_IsLumpPNG((UINT8*)&patch, len)) { - UINT8 *png = W_CacheLumpNumPwad(wadnum, l, PU_STATIC); + UINT8 *png = static_cast(W_CacheLumpNumPwad(wadnum, l, PU_STATIC)); Picture_PNGDimensions((UINT8 *)png, &width, &height, &topoffset, &leftoffset, len); isPNG = true; Z_Free(png); @@ -451,7 +453,7 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16 // allocate this sprite's frames if (!spritedef->spriteframes) spritedef->spriteframes = - Z_Malloc(maxframe * sizeof (*spritedef->spriteframes), PU_STATIC, NULL); + static_cast(Z_Malloc(maxframe * sizeof (*spritedef->spriteframes), PU_STATIC, NULL)); spritedef->numframes = maxframe; M_Memcpy(spritedef->spriteframes, sprtemp, maxframe*sizeof (spriteframe_t)); @@ -574,7 +576,7 @@ void R_InitSprites(void) if (!numsprites) I_Error("R_AddSpriteDefs: no sprites in namelist\n"); - sprites = Z_Calloc(numsprites * sizeof (*sprites), PU_STATIC, NULL); + sprites = static_cast(Z_Calloc(numsprites * sizeof (*sprites), PU_STATIC, NULL)); // find sprites in each -file added pwad for (i = 0; i < numwadfiles; i++) @@ -765,13 +767,13 @@ void R_DrawFlippedMaskedColumn(column_t *column, column_t *brightmap, INT32 base if (dc_yl <= dc_yh && dc_yh > 0) { - dc_source = ZZ_Alloc(column->length); + dc_source = static_cast(ZZ_Alloc(column->length)); for (s = (UINT8 *)column+2+column->length, d = dc_source; d < dc_source+column->length; --s) *d++ = *s; if (brightmap != NULL) { - dc_brightmap = ZZ_Alloc(brightmap->length); + dc_brightmap = static_cast(ZZ_Alloc(brightmap->length)); for (s = (UINT8 *)brightmap+2+brightmap->length, d = dc_brightmap; d < dc_brightmap+brightmap->length; --s) *d++ = *s; } @@ -825,7 +827,7 @@ UINT8 *R_GetSpriteTranslation(vissprite_t *vis) if (!(vis->cut & SC_PRECIP) && R_ThingIsFlashing(vis->mobj)) { - return R_GetTranslationColormap(TC_HITLAG, 0, GTC_CACHE); + return R_GetTranslationColormap(TC_HITLAG, static_cast(0), GTC_CACHE); } /* else if (R_SpriteIsFlashing(vis)) // Bosses "flash" @@ -842,14 +844,14 @@ UINT8 *R_GetSpriteTranslation(vissprite_t *vis) { // New colormap stuff for skins Tails 06-07-2002 if (!(vis->cut & SC_PRECIP) && vis->mobj->colorized) - return R_GetTranslationColormap(TC_RAINBOW, vis->mobj->color, GTC_CACHE); + return R_GetTranslationColormap(TC_RAINBOW, static_cast(vis->mobj->color), GTC_CACHE); else if (!(vis->cut & SC_PRECIP) && vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // This thing is a player! { size_t skinnum = (skin_t*)vis->mobj->skin-skins; - return R_GetTranslationColormap((INT32)skinnum, vis->mobj->color, GTC_CACHE); + return R_GetTranslationColormap((INT32)skinnum, static_cast(vis->mobj->color), GTC_CACHE); } else // Use the defaults - return R_GetTranslationColormap(TC_DEFAULT, vis->mobj->color, GTC_CACHE); + return R_GetTranslationColormap(TC_DEFAULT, static_cast(vis->mobj->color), GTC_CACHE); } else if (vis->mobj->sprite == SPR_PLAY) // Looks like a player, but doesn't have a color? Get rid of green sonic syndrome. return R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_BLUE, GTC_CACHE); @@ -987,7 +989,7 @@ static void R_DrawVisSprite(vissprite_t *vis) vis->scale = FixedMul(vis->scale, this_scale); vis->scalestep = FixedMul(vis->scalestep, this_scale); vis->xiscale = FixedDiv(vis->xiscale,this_scale); - vis->cut |= SC_ISSCALED; + vis->cut = static_cast(vis->cut | SC_ISSCALED); } dc_texturemid = FixedDiv(dc_texturemid,this_scale); } @@ -1232,11 +1234,11 @@ static void R_SplitSprite(vissprite_t *sprite) // Found a split! Make a new sprite, copy the old sprite to it, and // adjust the heights. - newsprite = M_Memcpy(R_NewVisSprite(), sprite, sizeof (vissprite_t)); + newsprite = static_cast(M_Memcpy(R_NewVisSprite(), sprite, sizeof (vissprite_t))); - newsprite->cut |= (sprite->cut & SC_FLAGMASK); + newsprite->cut = static_cast(newsprite->cut | (sprite->cut & SC_FLAGMASK)); - sprite->cut |= SC_BOTTOM; + sprite->cut = static_cast(sprite->cut | SC_BOTTOM); sprite->gz = testheight; newsprite->gzt = sprite->gz; @@ -1246,7 +1248,7 @@ static void R_SplitSprite(vissprite_t *sprite) newsprite->szt -= 8; - newsprite->cut |= SC_TOP; + newsprite->cut = static_cast(newsprite->cut | SC_TOP); if (!(sector->lightlist[i].caster->fofflags & FOF_NOSHADE)) { lightnum = (*sector->lightlist[i].lightlevel >> LIGHTSEGSHIFT); @@ -1294,7 +1296,7 @@ static patch_t *R_CacheSpriteBrightMap(const spriteinfo_t *sprinfo, UINT8 frame) return NULL; } - return W_CachePatchNum(num, PU_SPRITE); + return static_cast(W_CachePatchNum(num, PU_SPRITE)); } // @@ -1451,12 +1453,12 @@ static void R_ProjectDropShadow( R_InterpolateMobjState(thing, FRACUNIT, &interp); } - patch = W_CachePatchName("DSHADOW", PU_SPRITE); + patch = static_cast(W_CachePatchName("DSHADOW", PU_SPRITE)); xscale = FixedDiv(projection[viewssnum], tz); yscale = FixedDiv(projectiony[viewssnum], tz); shadowxscale = FixedMul(thing->radius*2, scale); shadowyscale = FixedMul(FixedMul(thing->radius*2, scale), FixedDiv(abs(groundz - viewz), tz)); - shadowyscale = min(shadowyscale, shadowxscale) / patch->height; + shadowyscale = std::min(shadowyscale, shadowxscale) / patch->height; shadowxscale /= patch->width; shadowskew = 0; @@ -1511,7 +1513,7 @@ static void R_ProjectDropShadow( shadow->sector = vis->sector; shadow->szt = (INT16)((centeryfrac - FixedMul(shadow->gzt - viewz, yscale))>>FRACBITS); shadow->sz = (INT16)((centeryfrac - FixedMul(shadow->gz - viewz, yscale))>>FRACBITS); - shadow->cut = SC_ISSCALED|SC_SHADOW; //check this + shadow->cut = static_cast(SC_ISSCALED|SC_SHADOW); //check this shadow->startfrac = 0; //shadow->xiscale = 0x7ffffff0 / (shadow->xscale/2); @@ -1636,7 +1638,7 @@ static void R_ProjectBoundingBox(mobj_t *thing, vissprite_t *vis) box->sortscale = vis->sortscale; // link sorting to sprite box->dispoffset = vis->dispoffset + 5; - box->cut |= SC_LINKDRAW; + box->cut = static_cast(box->cut | SC_LINKDRAW); } else { @@ -1661,7 +1663,7 @@ static void R_ProjectBoundingBox(mobj_t *thing, vissprite_t *vis) static fixed_t R_GetSpriteDirectionalLighting(angle_t angle) { // Copied from P_UpdateSegLightOffset - const UINT8 contrast = min(max(0, maplighting.contrast - maplighting.backlight), UINT8_MAX); + const UINT8 contrast = std::min(std::max(0, maplighting.contrast - maplighting.backlight), UINT8_MAX); const fixed_t contrastFixed = ((fixed_t)contrast) * FRACUNIT; fixed_t light = FRACUNIT; @@ -1919,7 +1921,7 @@ static void R_ProjectSprite(mobj_t *thing) //Fab: lumppat is the lump number of the patch to use, this is different // than lumpid for sprites-in-pwad : the graphics are patched - patch = W_CachePatchNum(sprframe->lumppat[rot], PU_SPRITE); + patch = static_cast(W_CachePatchNum(sprframe->lumppat[rot], PU_SPRITE)); #ifdef ROTSPRITE spriterotangle = R_SpriteRotationAngle(thing, NULL); @@ -1940,7 +1942,7 @@ static void R_ProjectSprite(mobj_t *thing) if (rotsprite != NULL) { patch = rotsprite; - cut |= SC_ISROTATED; + cut = static_cast(cut | SC_ISROTATED); spr_width = rotsprite->width << FRACBITS; spr_height = rotsprite->height << FRACBITS; @@ -2022,7 +2024,7 @@ static void R_ProjectSprite(mobj_t *thing) tx2 = FixedMul(tr_x, viewsin) - FixedMul(tr_y, viewcos); - if (max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-papersprite clipping is handled earlier + if (std::max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-papersprite clipping is handled earlier return; // Needs partially clipped @@ -2172,7 +2174,7 @@ static void R_ProjectSprite(mobj_t *thing) dispoffset *= -1; // if it's physically behind, make sure it's ordered behind (if dispoffset > 0) sortscale = linkscale; // now make sure it's linked - cut |= SC_LINKDRAW; + cut = static_cast(cut | SC_LINKDRAW); } else if (splat) { @@ -2245,7 +2247,7 @@ static void R_ProjectSprite(mobj_t *thing) spritexscale = FixedMul(thing->radius * 2, FixedMul(shadowscale, spritexscale)); spriteyscale = FixedMul(thing->radius * 2, FixedMul(shadowscale, spriteyscale)); spriteyscale = FixedMul(spriteyscale, FixedDiv(abs(groundz - viewz), tz)); - spriteyscale = min(spriteyscale, spritexscale) / patch->height; + spriteyscale = std::min(spriteyscale, spritexscale) / patch->height; spritexscale /= patch->width; } else @@ -2261,7 +2263,7 @@ static void R_ProjectSprite(mobj_t *thing) gzt = (isflipped ? (interp.z + thing->height) : interp.z) + patch->height * spriteyscale / 2; gz = gzt - patch->height * spriteyscale; - cut |= SC_SHEAR; + cut = static_cast(cut | SC_SHEAR); } } @@ -2330,7 +2332,7 @@ static void R_ProjectSprite(mobj_t *thing) : R_PointToAngle(interp.x, interp.y)); // Less change in contrast in dark sectors - extralight = FixedMul(extralight, min(max(0, lightnum), LIGHTLEVELS - 1) * FRACUNIT / (LIGHTLEVELS - 1)); + extralight = FixedMul(extralight, std::min(std::max(0, lightnum), LIGHTLEVELS - 1) * FRACUNIT / (LIGHTLEVELS - 1)); if (papersprite) { @@ -2342,7 +2344,7 @@ static void R_ProjectSprite(mobj_t *thing) fixed_t n = FixedDiv(FixedMul(xscale, LIGHTRESOLUTIONFIX), ((MAXLIGHTSCALE-1) << LIGHTSCALESHIFT)); // Less change in contrast at further distances, to counteract DOOM diminished light - extralight = FixedMul(extralight, min(n, FRACUNIT)); + extralight = FixedMul(extralight, std::min(n, FRACUNIT)); // Contrast is stronger for normal sprites, stronger than wall lighting is at the same distance lightnum += FixedFloor((extralight / 4) + (FRACUNIT / 2)) / FRACUNIT; @@ -2484,11 +2486,11 @@ static void R_ProjectSprite(mobj_t *thing) vis->transmap = R_GetBlendTable(blendmode, trans); if (R_ThingIsSemiBright(oldthing)) - vis->cut |= SC_SEMIBRIGHT; + vis->cut = static_cast(vis->cut | SC_SEMIBRIGHT); else if (R_ThingIsFullBright(oldthing)) - vis->cut |= SC_FULLBRIGHT; + vis->cut = static_cast(vis->cut | SC_FULLBRIGHT); else if (R_ThingIsFullDark(oldthing)) - vis->cut |= SC_FULLDARK; + vis->cut = static_cast(vis->cut | SC_FULLDARK); // // determine the colormap (lightlevel & special effects) @@ -2517,9 +2519,9 @@ static void R_ProjectSprite(mobj_t *thing) } if (vflip) - vis->cut |= SC_VFLIP; + vis->cut = static_cast(vis->cut | SC_VFLIP); if (splat) - vis->cut |= SC_SPLAT; // I like ya cut g + vis->cut = static_cast(vis->cut | SC_SPLAT); // I like ya cut g vis->patch = patch; vis->bright = R_CacheSpriteBrightMap(sprinfo, frame); @@ -2714,7 +2716,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) //Fab: lumppat is the lump number of the patch to use, this is different // than lumpid for sprites-in-pwad : the graphics are patched - vis->patch = W_CachePatchNum(sprframe->lumppat[0], PU_SPRITE); + vis->patch = static_cast(W_CachePatchNum(sprframe->lumppat[0], PU_SPRITE)); vis->bright = R_CacheSpriteBrightMap(&spriteinfo[thing->sprite], thing->frame & FF_FRAMEMASK); @@ -3300,7 +3302,7 @@ static drawnode_t *R_CreateDrawNode(drawnode_t *link) if (node == &nodebankhead) { - node = malloc(sizeof (*node)); + node = static_cast(malloc(sizeof (*node))); if (!node) I_Error("No more free memory to CreateDrawNode"); } @@ -3591,12 +3593,12 @@ void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, portal_t* portal) if (xclip == x) { - spr->cut |= SC_CULL; // completely skip this sprite going forward + spr->cut = static_cast(spr->cut | SC_CULL); // completely skip this sprite going forward } else if (portal) { - INT32 start_index = max(portal->start, x1); - INT32 end_index = min(portal->start + portal->end - portal->start, x2); + INT32 start_index = std::max(portal->start, x1); + INT32 end_index = std::min(portal->start + portal->end - portal->start, x2); for (x = x1; x < start_index; x++) { spr->clipbot[x] = -1; @@ -3644,11 +3646,11 @@ void R_ClipSprites(drawseg_t* dsstart, portal_t* portal) for (i = 0; i < DS_RANGES_COUNT; i++) { - drawsegs_xranges[i].items = Z_Realloc( + drawsegs_xranges[i].items = static_cast(Z_Realloc( drawsegs_xranges[i].items, drawsegs_xrange_size * sizeof(drawsegs_xranges[i].items[0]), PU_STATIC, NULL - ); + )); } } @@ -3884,7 +3886,7 @@ void R_DrawMasked(maskcount_t* masks, INT32 nummasks) drawnode_t *heads; /**< Drawnode lists; as many as number of views/portals. */ INT32 i; - heads = calloc(nummasks, sizeof(drawnode_t)); + heads = static_cast(calloc(nummasks, sizeof(drawnode_t))); for (i = 0; i < nummasks; i++) { From 0f3ede7fed16d79997fec11102eb05559b93ccfc Mon Sep 17 00:00:00 2001 From: Eidolon Date: Sun, 24 Sep 2023 14:39:12 -0500 Subject: [PATCH 12/21] Always clamp texturecolumn in sprite draw --- src/r_things.cpp | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/src/r_things.cpp b/src/r_things.cpp index fea738fe9..67e7de57f 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -1068,12 +1068,8 @@ static void R_DrawVisSprite(vissprite_t *vis) // Vertically sheared sprite for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale, dc_texturemid -= vis->shear.tan) { - texturecolumn = frac>>FRACBITS; + texturecolumn = std::clamp(frac >> FRACBITS, 0, patch->width - 1); -#ifdef RANGECHECK - if (texturecolumn < 0 || texturecolumn >= pwidth) - I_Error("R_DrawSpriteRange: bad texturecolumn at %d from end, dc_x=%d, x2=%d, texturecolumn=%d (%d), pwidth=%d, xiscale=%d, startfrac=%d", vis->x2 - dc_x, dc_x, vis->x2, texturecolumn, frac, pwidth, vis->xiscale, vis->startfrac); -#endif column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[texturecolumn])); if (bmpatch) bmcol = (column_t *)((UINT8 *)bmpatch->columns + (bmpatch->columnofs[texturecolumn])); @@ -1084,10 +1080,8 @@ static void R_DrawVisSprite(vissprite_t *vis) } else { -#ifdef RANGECHECK - pwidth = patch->width; -#endif +#ifdef RANGECHECK if (vis->x1test && vis->x2test) { INT32 x1test = vis->x1test; @@ -1101,21 +1095,18 @@ static void R_DrawVisSprite(vissprite_t *vis) const INT32 t = (vis->startfrac + (vis->xiscale * (x2test - x1test))) >> FRACBITS; - if (x1test <= x2test && (t < 0 || t >= pwidth)) + if (x1test <= x2test && (t < 0 || t >= patch->width)) { CONS_Printf("THE GAME WOULD HAVE CRASHED, %d (old) vs %d (new)\n", (x2test - x1test), (vis->x2 - vis->x1)); } } +#endif // RANGECHECK // Non-paper drawing loop for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale, sprtopscreen += vis->shear.tan) { - texturecolumn = frac>>FRACBITS; + texturecolumn = std::clamp(frac >> FRACBITS, 0, patch->width - 1); -#ifdef RANGECHECK - if (texturecolumn < 0 || texturecolumn >= pwidth) - I_Error("R_DrawSpriteRange: bad texturecolumn at %d from end, dc_x=%d, x2=%d, texturecolumn=%d (%d), pwidth=%d, xiscale=%d, startfrac=%d", vis->x2 - dc_x, dc_x, vis->x2, texturecolumn, frac, pwidth, vis->xiscale, vis->startfrac); -#endif column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[texturecolumn])); if (bmpatch) From 2fa73d45d78ea24286f0cdc3b17ae03d61ad8d43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= Date: Wed, 19 Jul 2023 23:17:21 +0200 Subject: [PATCH 13/21] Clean up and simplify zone memory allocation --- src/lua_hudlib_drawlist.c | 6 +- src/r_fps.c | 19 ++-- src/z_zone.c | 195 +++++++------------------------------- src/z_zone.h | 8 +- 4 files changed, 48 insertions(+), 180 deletions(-) diff --git a/src/lua_hudlib_drawlist.c b/src/lua_hudlib_drawlist.c index 8418f1b5a..814632e66 100644 --- a/src/lua_hudlib_drawlist.c +++ b/src/lua_hudlib_drawlist.c @@ -91,7 +91,7 @@ huddrawlist_h LUA_HUD_CreateDrawList(void) { huddrawlist_h drawlist; - drawlist = (huddrawlist_h) Z_CallocAlign(sizeof(struct huddrawlist_s), PU_STATIC, NULL, 64); + drawlist = (huddrawlist_h) Z_Calloc(sizeof(struct huddrawlist_s), PU_STATIC, NULL); drawlist->items = NULL; drawlist->items_capacity = 0; drawlist->items_len = 0; @@ -152,7 +152,7 @@ static size_t AllocateDrawItem(huddrawlist_h list) { if (list->items_capacity == 0) list->items_capacity = 128; else list->items_capacity *= 2; - list->items = (drawitem_t *) Z_ReallocAlign(list->items, sizeof(struct drawitem_s) * list->items_capacity, PU_STATIC, NULL, 64); + list->items = (drawitem_t *) Z_Realloc(list->items, sizeof(struct drawitem_s) * list->items_capacity, PU_STATIC, NULL); } return list->items_len++; @@ -171,7 +171,7 @@ static size_t CopyString(huddrawlist_h list, const char* str) { if (list->strbuf_capacity == 0) list->strbuf_capacity = 256; else list->strbuf_capacity *= 2; - list->strbuf = (char*) Z_ReallocAlign(list->strbuf, sizeof(char) * list->strbuf_capacity, PU_STATIC, NULL, 8); + list->strbuf = (char*) Z_Realloc(list->strbuf, sizeof(char) * list->strbuf_capacity, PU_STATIC, NULL); } { diff --git a/src/r_fps.c b/src/r_fps.c index 2e9b8a7ce..c15a4b632 100644 --- a/src/r_fps.c +++ b/src/r_fps.c @@ -327,13 +327,12 @@ static void AddInterpolator(levelinterpolator_t* interpolator) { levelinterpolators_size *= 2; } - - levelinterpolators = Z_ReallocAlign( + + levelinterpolators = Z_Realloc( (void*) levelinterpolators, sizeof(levelinterpolator_t*) * levelinterpolators_size, PU_LEVEL, - NULL, - sizeof(levelinterpolator_t*) * 8 + NULL ); } @@ -343,11 +342,8 @@ static void AddInterpolator(levelinterpolator_t* interpolator) static levelinterpolator_t *CreateInterpolator(levelinterpolator_type_e type, thinker_t *thinker) { - levelinterpolator_t *ret = (levelinterpolator_t*) Z_CallocAlign( - sizeof(levelinterpolator_t), - PU_LEVEL, - NULL, - sizeof(levelinterpolator_t) * 8 + levelinterpolator_t *ret = (levelinterpolator_t*) Z_Calloc( + sizeof(levelinterpolator_t), PU_LEVEL, NULL ); ret->type = type; @@ -662,12 +658,11 @@ void R_AddMobjInterpolator(mobj_t *mobj) interpolated_mobjs_capacity *= 2; } - interpolated_mobjs = Z_ReallocAlign( + interpolated_mobjs = Z_Realloc( interpolated_mobjs, sizeof(mobj_t *) * interpolated_mobjs_capacity, PU_LEVEL, - NULL, - 64 + NULL ); } diff --git a/src/z_zone.c b/src/z_zone.c index 95a2097e7..4cbd2341f 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -49,27 +49,11 @@ static boolean Z_calloc = false; #define ZONEID 0xa441d13d -struct memblock_s; - -typedef struct -{ - struct memblock_s *block; // Describing this memory - UINT32 id; // Should be ZONEID -} ATTRPACK memhdr_t; - -// Some code might want aligned memory. Assume it wants memory n bytes -// aligned -- then we allocate n-1 extra bytes and return a pointer to -// the first byte aligned as requested. -// Thus, "real" is the pointer we get from malloc() and will free() -// later, but "hdr" is where the memhdr_t starts. -// For non-aligned allocations they will be the same. typedef struct memblock_s { - void *real; - memhdr_t *hdr; - void **user; INT32 tag; // purgelevel + UINT32 id; // Should be ZONEID size_t size; // including the header and blocks size_t realsize; // size of real data only @@ -78,7 +62,10 @@ typedef struct memblock_s INT32 ownerline; struct memblock_s *next, *prev; -} ATTRPACK memblock_t; +} memblock_t; + +#define MEMORY(x) (void *)((uintptr_t)(x) + sizeof(memblock_t)) +#define MEMBLOCK(x) (memblock_t *)((uintptr_t)(x) - sizeof(memblock_t)) // both the head and tail of the zone memory block list static memblock_t head; @@ -119,52 +106,6 @@ void Z_Init(void) // Zone memory allocation // ---------------------- -/** Returns the corresponding memblock_t for a given memory block. - * - * \param ptr A pointer to allocated memory, - * assumed to have been allocated with Z_Malloc/Z_Calloc. - * \param func A string containing the name of the function that called this, - * to be printed if the function I_Errors - * \return A pointer to the memblock_t for the given memory. - * \sa Z_Free, Z_ReallocAlign - */ -#define Ptr2Memblock(s, f) Ptr2Memblock2(s, f, __FILE__, __LINE__) -static memblock_t *Ptr2Memblock2(void *ptr, const char* func, const char *file, INT32 line) -{ - memhdr_t *hdr; - memblock_t *block; - - if (ptr == NULL) - return NULL; - -#ifdef ZDEBUG - CONS_Debug(DBG_MEMORY, "%s %s:%d\n", func, file, line); -#endif - - hdr = (memhdr_t *)((UINT8 *)ptr - sizeof *hdr); - -#ifdef VALGRIND_MAKE_MEM_DEFINED - VALGRIND_MAKE_MEM_DEFINED(hdr, sizeof *hdr); -#endif - -#ifdef VALGRIND_MEMPOOL_EXISTS - if (!VALGRIND_MEMPOOL_EXISTS(hdr->block)) - { - I_Error("%s: bad memblock from %s:%d", func, file, line); - } -#endif - if (hdr->id != ZONEID) - { - I_Error("%s: wrong id from %s:%d", func, file, line); - } - block = hdr->block; -#ifdef VALGRIND_MAKE_MEM_NOACCESS - VALGRIND_MAKE_MEM_NOACCESS(hdr, sizeof *hdr); -#endif - return block; - -} - /** Frees allocated memory. * * \param ptr A pointer to allocated memory, @@ -185,7 +126,11 @@ void Z_Free2(void *ptr, const char *file, INT32 line) #endif */ - block = Ptr2Memblock2(ptr, "Z_Free", file, line); + block = MEMBLOCK(ptr); +#ifdef PARANOIA + if (block->id != ZONEID) + I_Error("Z_Free at %s:%d: wrong id", file, line); +#endif // Write every Z_Free call to a debug file. CONS_Debug(DBG_MEMORY, "Z_Free at %s:%d\n", file, line); @@ -201,9 +146,6 @@ void Z_Free2(void *ptr, const char *file, INT32 line) if (block->user != NULL) *block->user = NULL; - // Free the memory and get rid of the block. - TracyCFree(block->real); - free(block->real); #ifdef VALGRIND_DESTROY_MEMPOOL VALGRIND_DESTROY_MEMPOOL(block); #endif @@ -256,35 +198,18 @@ static void *xm(size_t size) void *Z_Malloc2(size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) { - size_t extrabytes = (1<next->prev = block; - block->real = ptr; - block->hdr = hdr; block->tag = tag; block->user = NULL; block->ownerline = line; block->ownerfile = file; - block->size = blocksize; + block->size = sizeof (memblock_t) + size; block->realsize = size; #ifdef VALGRIND_CREATE_MEMPOOL - VALGRIND_CREATE_MEMPOOL(block, padsize, Z_calloc); + VALGRIND_CREATE_MEMPOOL(block, size, Z_calloc); #endif -//#ifdef VALGRIND_MEMPOOL_ALLOC -// VALGRIND_MEMPOOL_ALLOC(block, hdr, size + sizeof *hdr); -//#endif - hdr->id = ZONEID; - hdr->block = block; - -#ifdef VALGRIND_MAKE_MEM_NOACCESS - VALGRIND_MAKE_MEM_NOACCESS(hdr, sizeof *hdr); -#endif + block->id = ZONEID; if (user != NULL) { block->user = user; - *(void **)user = given; + *(void **)user = ptr; } else if (tag >= PU_PURGELEVEL) I_Error("Z_Malloc: attempted to allocate purgable block " "(size %s) with no user", sizeu1(size)); - return given; + return ptr; } /** The Z_CallocAlign function. @@ -388,7 +303,11 @@ void *Z_Realloc2(void *ptr, size_t size, INT32 tag, void *user, INT32 alignbits, return Z_Calloc2(size, tag, user, alignbits, file , line); } - block = Ptr2Memblock2(ptr, "Z_Realloc", file, line); + block = MEMBLOCK(ptr); +#ifdef PARANOIA + if (block->id != ZONEID) + I_Error("Z_ReallocAlign at %s:%d: wrong id", file, line); +#endif if (block == NULL) return NULL; @@ -430,9 +349,8 @@ void Z_FreeTags(INT32 lowtag, INT32 hightag) for (block = head.next; block != &head; block = next) { next = block->next; // get link before freeing - if (block->tag >= lowtag && block->tag <= hightag) - Z_Free((UINT8 *)block->hdr + sizeof *block->hdr); + Z_Free(MEMORY(block)); } } @@ -455,7 +373,7 @@ void Z_IterateTags(INT32 lowtag, INT32 hightag, boolean (*iterfunc)(void *)) if (block->tag >= lowtag && block->tag <= hightag) { - void *mem = (UINT8 *)block->hdr + sizeof *block->hdr; + void *mem = MEMORY(block); boolean free = iterfunc(mem); if (free) Z_Free(mem); @@ -500,15 +418,13 @@ void Z_CheckMemCleanup(void) void Z_CheckHeap(INT32 i) { memblock_t *block; - memhdr_t *hdr; UINT32 blocknumon = 0; void *given; for (block = head.next; block != &head; block = block->next) { blocknumon++; - hdr = block->hdr; - given = (UINT8 *)hdr + sizeof *hdr; + given = MEMORY(block); #ifdef ZDEBUG CONS_Debug(DBG_MEMORY, "block %u owned by %s:%d\n", blocknumon, block->ownerfile, block->ownerline); @@ -519,6 +435,7 @@ void Z_CheckHeap(INT32 i) I_Error("Z_CheckHeap %d: block %u" "(owned by %s:%d)" " should not exist", i, blocknumon, + " should not exist", i, blocknumon, block->ownerfile, block->ownerline ); } @@ -550,16 +467,7 @@ void Z_CheckHeap(INT32 i) #ifdef VALGRIND_MAKE_MEM_DEFINED VALGRIND_MAKE_MEM_DEFINED(hdr, sizeof *hdr); #endif - if (hdr->block != block) - { - I_Error("Z_CheckHeap %d: block %u" - "(owned by %s:%d)" - " doesn't have linkback from allocated memory", - i, blocknumon, - block->ownerfile, block->ownerline - ); - } - if (hdr->id != ZONEID) + if (block->id != ZONEID) { I_Error("Z_CheckHeap %d: block %u" "(owned by %s:%d)" @@ -567,9 +475,6 @@ void Z_CheckHeap(INT32 i) block->ownerfile, block->ownerline ); } -#ifdef VALGRIND_MAKE_MEM_NOACCESS - VALGRIND_MAKE_MEM_NOACCESS(hdr, sizeof *hdr); -#endif } } @@ -591,35 +496,14 @@ void Z_ChangeTag(void *ptr, INT32 tag) #endif { memblock_t *block; - memhdr_t *hdr; if (ptr == NULL) return; - hdr = (memhdr_t *)((UINT8 *)ptr - sizeof *hdr); + block = MEMBLOCK(ptr); -#ifdef VALGRIND_MAKE_MEM_DEFINED - VALGRIND_MAKE_MEM_DEFINED(hdr, sizeof *hdr); -#endif - -#ifdef VALGRIND_MEMPOOL_EXISTS - if (!VALGRIND_MEMPOOL_EXISTS(hdr->block)) - { #ifdef PARANOIA - I_Error("Z_CT at %s:%d: bad memblock", file, line); -#else - I_Error("Z_CT: bad memblock"); -#endif - } -#endif -#ifdef PARANOIA - if (hdr->id != ZONEID) I_Error("Z_CT at %s:%d: wrong id", file, line); -#endif - - block = hdr->block; - -#ifdef VALGRIND_MAKE_MEM_NOACCESS - VALGRIND_MAKE_MEM_NOACCESS(hdr, sizeof *hdr); + if (block->id != ZONEID) I_Error("Z_ChangeTag at %s:%d: wrong id", file, line); #endif if (tag >= PU_PURGELEVEL && block->user == NULL) @@ -643,25 +527,14 @@ void Z_SetUser(void *ptr, void **newuser) #endif { memblock_t *block; - memhdr_t *hdr; if (ptr == NULL) return; - hdr = (memhdr_t *)((UINT8 *)ptr - sizeof *hdr); - -#ifdef VALGRIND_MAKE_MEM_DEFINED - VALGRIND_MAKE_MEM_DEFINED(hdr, sizeof *hdr); -#endif + block = MEMBLOCK(ptr); #ifdef PARANOIA - if (hdr->id != ZONEID) I_Error("Z_CT at %s:%d: wrong id", file, line); -#endif - - block = hdr->block; - -#ifdef VALGRIND_MAKE_MEM_NOACCESS - VALGRIND_MAKE_MEM_NOACCESS(hdr, sizeof *hdr); + if (block->id != ZONEID) I_Error("Z_SetUser at %s:%d: wrong id", file, line); #endif if (block->tag >= PU_PURGELEVEL && newuser == NULL) diff --git a/src/z_zone.h b/src/z_zone.h index 5132c0d55..779c9aa70 100644 --- a/src/z_zone.h +++ b/src/z_zone.h @@ -95,10 +95,10 @@ void *Z_Malloc2(size_t size, INT32 tag, void *user, INT32 alignbits, const char void *Z_Calloc2(size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) FUNCALLOC(1); void *Z_Realloc2(void *ptr, size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) FUNCALLOC(2); -// Alloc with no alignment -#define Z_Malloc(s,t,u) Z_MallocAlign(s, t, u, 0) -#define Z_Calloc(s,t,u) Z_CallocAlign(s, t, u, 0) -#define Z_Realloc(p,s,t,u) Z_ReallocAlign(p, s, t, u, 0) +// Alloc with standard alignment +#define Z_Malloc(s,t,u) Z_MallocAlign(s, t, u, sizeof(void *)) +#define Z_Calloc(s,t,u) Z_CallocAlign(s, t, u, sizeof(void *)) +#define Z_Realloc(p,s,t,u) Z_ReallocAlign(p, s, t, u, sizeof(void *)) // Free all memory by tag // these don't give line numbers currently though From c743af4d7747a28966f851384d2a20f5eabd2aaa Mon Sep 17 00:00:00 2001 From: "James R." Date: Sun, 24 Sep 2023 15:36:46 -0700 Subject: [PATCH 14/21] P_SpawnMapThing, P_RaiseTaggedThingsToFakeFloor: save raised Z position for respawning later P_RespawnSpecials just calls P_SpawnMapThing again, so this works. --- src/doomdata.h | 1 + src/p_mobj.c | 11 ++++++++++- src/p_setup.c | 3 +++ src/p_spec.c | 2 ++ 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/doomdata.h b/src/doomdata.h index 32cc1e9db..5d78d9f17 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -278,6 +278,7 @@ struct mapthing_t char *script_stringargs[NUM_SCRIPT_STRINGARGS]; UINT8 layer; // FOF layer to spawn on, see P_GetMobjSpawnHeight mapUserProperties_t user; // UDMF user-defined custom properties. + fixed_t adjusted_z; // Z adjusted on map load, used for respawning mobj_t *mobj; }; diff --git a/src/p_mobj.c b/src/p_mobj.c index 599dd37e8..6d427777d 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -13910,7 +13910,16 @@ mobj_t *P_SpawnMapThing(mapthing_t *mthing) x = mthing->x << FRACBITS; y = mthing->y << FRACBITS; - z = P_GetMapThingSpawnHeight(i, mthing, x, y); + + if (mthing->adjusted_z != INT32_MAX) + { + z = mthing->adjusted_z; + } + else + { + z = P_GetMapThingSpawnHeight(i, mthing, x, y); + } + return P_SpawnMobjFromMapThing(mthing, x, y, z, i); } diff --git a/src/p_setup.c b/src/p_setup.c index da3f780b7..0dc168034 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1356,6 +1356,8 @@ static void P_LoadThings(UINT8 *data) else mt->z = mt->options >> ZSHIFT; + mt->adjusted_z = INT32_MAX; + mt->mobj = NULL; } } @@ -3239,6 +3241,7 @@ static void P_LoadTextmap(void) memset(mt->script_args, 0, NUM_SCRIPT_ARGS*sizeof(*mt->script_args)); memset(mt->script_stringargs, 0x00, NUM_SCRIPT_STRINGARGS*sizeof(*mt->script_stringargs)); mt->layer = 0; + mt->adjusted_z = INT32_MAX; mt->mobj = NULL; K_UserPropertiesClear(&mt->user); diff --git a/src/p_spec.c b/src/p_spec.c index 0951d8c56..e7b336af0 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -6256,6 +6256,8 @@ P_RaiseTaggedThingsToFakeFloor ( offset = mo->z - mo->floorz; mo->z = P_GetZAt(control->c_slope, mo->x, mo->y, control->ceilingheight) + offset; } + + mthing->adjusted_z = mo->z; } } } From bd9cadbe8d6c8cf8dff4debe47dd7caad6e143b7 Mon Sep 17 00:00:00 2001 From: "James R." Date: Sun, 24 Sep 2023 15:52:00 -0700 Subject: [PATCH 15/21] K_CalculateTrackComplexity: format using fmt::format, to account for differences in size_t platform type --- src/k_waypoint.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/k_waypoint.cpp b/src/k_waypoint.cpp index 4bb3089b3..e590aa875 100644 --- a/src/k_waypoint.cpp +++ b/src/k_waypoint.cpp @@ -26,6 +26,8 @@ #include #include +#include + // The number of sparkles per waypoint connection in the waypoint visualisation static const UINT32 SPARKLES_PER_CONNECTION = 16U; @@ -2574,8 +2576,8 @@ static INT32 K_CalculateTrackComplexity(void) delta = FixedMul(delta, FixedMul(FixedMul(dist_factor, radius_factor), wall_factor)); - CONS_Printf( - "TURN [%d]: r: %.2f, d: %.2f, w: %.2f, r*d*w: %.2f, DELTA: %d\n", + std::string msg = fmt::format( + "TURN [{}]: r: {:.2f}, d: {:.2f}, w: {:.2f}, r*d*w: {:.2f}, DELTA: {}\n", i, FixedToFloat(radius_factor), FixedToFloat(dist_factor), @@ -2583,6 +2585,7 @@ static INT32 K_CalculateTrackComplexity(void) FixedToFloat(FixedMul(FixedMul(dist_factor, radius_factor), wall_factor)), (delta / FRACUNIT) ); + CONS_Printf("%s", msg.c_str()); trackcomplexity += (delta / FRACUNIT); } @@ -2663,7 +2666,7 @@ static INT32 K_CalculateTrackComplexity(void) } } - CONS_Printf("Num sneaker panel sets: %d\n", sneaker_panels.size()); + CONS_Printf("%s", fmt::format("Num sneaker panel sets: {}\n", sneaker_panels.size()).c_str()); trackcomplexity -= sneaker_panels.size() * 1250; CONS_Printf(" ** COMPLEXITY: %d\n", trackcomplexity); From b7715d9186b7c31f0c69c441c61a183d24243a7a Mon Sep 17 00:00:00 2001 From: Eidolon Date: Sun, 24 Sep 2023 18:08:28 -0500 Subject: [PATCH 16/21] Ensure Z_Malloc provides same alignment as libc --- src/z_zone.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/z_zone.c b/src/z_zone.c index 4cbd2341f..8701848c6 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -25,6 +25,9 @@ /// allocator was fragmenting badly. Finally, this version is a bit /// simpler (about half the lines of code). +#include +#include + #include #include "doomdef.h" @@ -49,6 +52,7 @@ static boolean Z_calloc = false; #define ZONEID 0xa441d13d + typedef struct memblock_s { void **user; @@ -64,8 +68,9 @@ typedef struct memblock_s struct memblock_s *next, *prev; } memblock_t; -#define MEMORY(x) (void *)((uintptr_t)(x) + sizeof(memblock_t)) -#define MEMBLOCK(x) (memblock_t *)((uintptr_t)(x) - sizeof(memblock_t)) +#define ALIGNPAD (((sizeof (memblock_t) + (alignof (max_align_t) - 1)) & ~(alignof (max_align_t) - 1)) - sizeof (memblock_t)) +#define MEMORY(x) (void *)((uintptr_t)(x) + sizeof(memblock_t) + ALIGNPAD) +#define MEMBLOCK(x) (memblock_t *)((uintptr_t)(x) - ALIGNPAD - sizeof(memblock_t)) // both the head and tail of the zone memory block list static memblock_t head; @@ -200,16 +205,17 @@ void *Z_Malloc2(size_t size, INT32 tag, void *user, INT32 alignbits, { memblock_t *block; void *ptr; - (void)(alignbits); // no longer used, so silence warnings. + + (void)(alignbits); // no longer used, so silence warnings. TODO we should figure out a solution for this #ifdef ZDEBUG CONS_Debug(DBG_MEMORY, "Z_Malloc %s:%d\n", file, line); #endif - block = xm(sizeof (memblock_t) + size); - TracyCAlloc(block, sizeof (memblock_t) + size); + block = xm(sizeof (memblock_t) + ALIGNPAD + size); + TracyCAlloc(block, sizeof (memblock_t) + ALIGNPAD + size); ptr = MEMORY(block); - I_Assert((intptr_t)ptr % sizeof (void *) == 0); + I_Assert((intptr_t)ptr % alignof (max_align_t) == 0); #ifdef HAVE_VALGRIND Z_calloc = false; From 2bad8126ac36b4ec92a20ac3dc2f259d0e352607 Mon Sep 17 00:00:00 2001 From: Eidolon Date: Sun, 24 Sep 2023 18:32:22 -0500 Subject: [PATCH 17/21] Delete outdated memcpy optimization The libc memcpy is faster --- src/android/i_system.c | 5 - src/doomdef.h | 2 +- src/dummy/i_system.c | 5 - src/i_system.h | 34 ---- src/m_memcpy.c | 425 +---------------------------------------- src/m_misc.h | 2 - src/screen.c | 44 ----- src/sdl/i_system.c | 64 ------- src/typedef.h | 1 - 9 files changed, 4 insertions(+), 578 deletions(-) diff --git a/src/android/i_system.c b/src/android/i_system.c index 4ce2cf260..fe7fa863d 100644 --- a/src/android/i_system.c +++ b/src/android/i_system.c @@ -233,11 +233,6 @@ INT32 I_mkdir(const char *dirname, INT32 unixright) return -1; } -const CPUInfoFlags *I_CPUInfo(void) -{ - return NULL; -} - const char *I_LocateWad(void) { return "/sdcard/srb2"; diff --git a/src/doomdef.h b/src/doomdef.h index 2747d0eac..4cfdf29c4 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -493,7 +493,7 @@ extern char gpbackup[256]; #define M_GetText(x) (x) #endif void M_StartupLocale(void); -extern void *(*M_Memcpy)(void* dest, const void* src, size_t n) FUNCNONNULL; +void *M_Memcpy(void* dest, const void* src, size_t n); char *va(const char *format, ...) FUNCPRINTF; char *M_GetToken(const char *inputString); diff --git a/src/dummy/i_system.c b/src/dummy/i_system.c index 997115ad0..3af36c983 100644 --- a/src/dummy/i_system.c +++ b/src/dummy/i_system.c @@ -138,11 +138,6 @@ INT32 I_mkdir(const char *dirname, INT32 unixright) return -1; } -const CPUInfoFlags *I_CPUInfo(void) -{ - return NULL; -} - const char *I_LocateWad(void) { return NULL; diff --git a/src/i_system.h b/src/i_system.h index 9b1fd6c15..f9161ece0 100644 --- a/src/i_system.h +++ b/src/i_system.h @@ -280,40 +280,6 @@ char *I_GetUserName(void); */ INT32 I_mkdir(const char *dirname, INT32 unixright); -struct CPUInfoFlags { - int FPU : 1; ///< FPU availabile - int CPUID : 1; ///< CPUID instruction - int RDTSC : 1; ///< RDTSC instruction - int MMX : 1; ///< MMX features - int MMXExt : 1; ///< MMX Ext. features - int CMOV : 1; ///< Pentium Pro's "cmov" - int AMD3DNow : 1; ///< 3DNow features - int AMD3DNowExt: 1; ///< 3DNow! Ext. features - int SSE : 1; ///< SSE features - int SSE2 : 1; ///< SSE2 features - int SSE3 : 1; ///< SSE3 features - int IA64 : 1; ///< Running on IA64 - int AMD64 : 1; ///< Running on AMD64 - int AltiVec : 1; ///< AltiVec features - int FPPE : 1; ///< floating-point precision error - int PFC : 1; ///< TBD? - int cmpxchg : 1; ///< ? - int cmpxchg16b : 1; ///< ? - int cmp8xchg16 : 1; ///< ? - int FPE : 1; ///< FPU Emu - int DEP : 1; ///< Data excution prevent - int PPCMM64 : 1; ///< PowerPC Movemem 64bit ok? - int ALPHAbyte : 1; ///< ? - int PAE : 1; ///< Physical Address Extension - int CPUs : 8; -}; - - -/** \brief Info about CPU - \return CPUInfo in bits -*/ -const CPUInfoFlags *I_CPUInfo(void); - /** \brief Find main WAD \return path to main WAD */ diff --git a/src/m_memcpy.c b/src/m_memcpy.c index d24f00f94..ab362f589 100644 --- a/src/m_memcpy.c +++ b/src/m_memcpy.c @@ -9,432 +9,13 @@ // See the 'LICENSE' file for more details. //----------------------------------------------------------------------------- /// \file m_memcpy.c -/// \brief X86 optimized implementations of M_Memcpy +/// \brief (formerly) X86 optimized implementations of M_Memcpy #include "doomdef.h" #include "m_misc.h" -#if defined (__GNUC__) && defined (__i386__) // from libkwave, under GPL -// Alam: note libkwave memcpy code comes from mplayer's libvo/aclib_template.c, r699 - -/* for small memory blocks (<256 bytes) this version is faster */ -#define small_memcpy(dest,src,n)\ -{\ -register unsigned long int dummy;\ -__asm__ __volatile__(\ - "cld\n\t"\ - "rep; movsb"\ - :"=&D"(dest), "=&S"(src), "=&c"(dummy)\ - :"0" (dest), "1" (src),"2" (n)\ - : "memory", "cc");\ -} - -/* linux kernel __memcpy (from: /include/asm/string.h) */ -ATTRINLINE static FUNCINLINE void *__memcpy (void *dest, const void * src, size_t n) +void *M_Memcpy(void* dest, const void* src, size_t n) { - int d0, d1, d2; - - if ( n < 4 ) - { - small_memcpy(dest, src, n); - } - else - { - __asm__ __volatile__ ( - "rep ; movsl;" - "testb $2,%b4;" - "je 1f;" - "movsw;" - "1:\ttestb $1,%b4;" - "je 2f;" - "movsb;" - "2:" - : "=&c" (d0), "=&D" (d1), "=&S" (d2) - :"0" (n/4), "q" (n),"1" ((long) dest),"2" ((long) src) - : "memory"); - } - + memcpy(dest, src, n); return dest; } - -#define SSE_MMREG_SIZE 16 -#define MMX_MMREG_SIZE 8 - -#define MMX1_MIN_LEN 0x800 /* 2K blocks */ -#define MIN_LEN 0x40 /* 64-byte blocks */ - -/* SSE note: i tried to move 128 bytes a time instead of 64 but it -didn't make any measureable difference. i'm using 64 for the sake of -simplicity. [MF] */ -static /*FUNCTARGET("sse2")*/ void *sse_cpy(void * dest, const void * src, size_t n) -{ - void *retval = dest; - size_t i; - - /* PREFETCH has effect even for MOVSB instruction ;) */ - __asm__ __volatile__ ( - "prefetchnta (%0);" - "prefetchnta 32(%0);" - "prefetchnta 64(%0);" - "prefetchnta 96(%0);" - "prefetchnta 128(%0);" - "prefetchnta 160(%0);" - "prefetchnta 192(%0);" - "prefetchnta 224(%0);" - "prefetchnta 256(%0);" - "prefetchnta 288(%0);" - : : "r" (src) ); - - if (n >= MIN_LEN) - { - register unsigned long int delta; - /* Align destinition to MMREG_SIZE -boundary */ - delta = ((unsigned long int)dest)&(SSE_MMREG_SIZE-1); - if (delta) - { - delta=SSE_MMREG_SIZE-delta; - n -= delta; - small_memcpy(dest, src, delta); - } - i = n >> 6; /* n/64 */ - n&=63; - if (((unsigned long)src) & 15) - /* if SRC is misaligned */ - for (; i>0; i--) - { - __asm__ __volatile__ ( - "prefetchnta 320(%0);" - "prefetchnta 352(%0);" - "movups (%0), %%xmm0;" - "movups 16(%0), %%xmm1;" - "movups 32(%0), %%xmm2;" - "movups 48(%0), %%xmm3;" - "movntps %%xmm0, (%1);" - "movntps %%xmm1, 16(%1);" - "movntps %%xmm2, 32(%1);" - "movntps %%xmm3, 48(%1);" - :: "r" (src), "r" (dest) : "memory"); - src = (const unsigned char *)src + 64; - dest = (unsigned char *)dest + 64; - } - else - /* - Only if SRC is aligned on 16-byte boundary. - It allows to use movaps instead of movups, which required data - to be aligned or a general-protection exception (#GP) is generated. - */ - for (; i>0; i--) - { - __asm__ __volatile__ ( - "prefetchnta 320(%0);" - "prefetchnta 352(%0);" - "movaps (%0), %%xmm0;" - "movaps 16(%0), %%xmm1;" - "movaps 32(%0), %%xmm2;" - "movaps 48(%0), %%xmm3;" - "movntps %%xmm0, (%1);" - "movntps %%xmm1, 16(%1);" - "movntps %%xmm2, 32(%1);" - "movntps %%xmm3, 48(%1);" - :: "r" (src), "r" (dest) : "memory"); - src = ((const unsigned char *)src) + 64; - dest = ((unsigned char *)dest) + 64; - } - /* since movntq is weakly-ordered, a "sfence" - * is needed to become ordered again. */ - __asm__ __volatile__ ("sfence":::"memory"); - /* enables to use FPU */ - __asm__ __volatile__ ("emms":::"memory"); - } - /* - * Now do the tail of the block - */ - if (n) __memcpy(dest, src, n); - return retval; -} - -static FUNCTARGET("mmx") void *mmx2_cpy(void *dest, const void *src, size_t n) -{ - void *retval = dest; - size_t i; - - /* PREFETCH has effect even for MOVSB instruction ;) */ - __asm__ __volatile__ ( - "prefetchnta (%0);" - "prefetchnta 32(%0);" - "prefetchnta 64(%0);" - "prefetchnta 96(%0);" - "prefetchnta 128(%0);" - "prefetchnta 160(%0);" - "prefetchnta 192(%0);" - "prefetchnta 224(%0);" - "prefetchnta 256(%0);" - "prefetchnta 288(%0);" - : : "r" (src)); - - if (n >= MIN_LEN) - { - register unsigned long int delta; - /* Align destinition to MMREG_SIZE -boundary */ - delta = ((unsigned long int)dest)&(MMX_MMREG_SIZE-1); - if (delta) - { - delta=MMX_MMREG_SIZE-delta; - n -= delta; - small_memcpy(dest, src, delta); - } - i = n >> 6; /* n/64 */ - n&=63; - for (; i>0; i--) - { - __asm__ __volatile__ ( - "prefetchnta 320(%0);" - "prefetchnta 352(%0);" - "movq (%0), %%mm0;" - "movq 8(%0), %%mm1;" - "movq 16(%0), %%mm2;" - "movq 24(%0), %%mm3;" - "movq 32(%0), %%mm4;" - "movq 40(%0), %%mm5;" - "movq 48(%0), %%mm6;" - "movq 56(%0), %%mm7;" - "movntq %%mm0, (%1);" - "movntq %%mm1, 8(%1);" - "movntq %%mm2, 16(%1);" - "movntq %%mm3, 24(%1);" - "movntq %%mm4, 32(%1);" - "movntq %%mm5, 40(%1);" - "movntq %%mm6, 48(%1);" - "movntq %%mm7, 56(%1);" - :: "r" (src), "r" (dest) : "memory"); - src = ((const unsigned char *)src) + 64; - dest = ((unsigned char *)dest) + 64; - } - /* since movntq is weakly-ordered, a "sfence" - * is needed to become ordered again. */ - __asm__ __volatile__ ("sfence":::"memory"); - __asm__ __volatile__ ("emms":::"memory"); - } - /* - * Now do the tail of the block - */ - if (n) __memcpy(dest, src, n); - return retval; -} - -static FUNCTARGET("mmx") void *mmx1_cpy(void *dest, const void *src, size_t n) //3DNOW -{ - void *retval = dest; - size_t i; - - /* PREFETCH has effect even for MOVSB instruction ;) */ - __asm__ __volatile__ ( - "prefetch (%0);" - "prefetch 32(%0);" - "prefetch 64(%0);" - "prefetch 96(%0);" - "prefetch 128(%0);" - "prefetch 160(%0);" - "prefetch 192(%0);" - "prefetch 224(%0);" - "prefetch 256(%0);" - "prefetch 288(%0);" - : : "r" (src)); - - if (n >= MMX1_MIN_LEN) - { - register unsigned long int delta; - /* Align destinition to MMREG_SIZE -boundary */ - delta = ((unsigned long int)dest)&(MMX_MMREG_SIZE-1); - if (delta) - { - delta=MMX_MMREG_SIZE-delta; - n -= delta; - small_memcpy(dest, src, delta); - } - i = n >> 6; /* n/64 */ - n&=63; - for (; i>0; i--) - { - __asm__ __volatile__ ( - "prefetch 320(%0);" - "prefetch 352(%0);" - "movq (%0), %%mm0;" - "movq 8(%0), %%mm1;" - "movq 16(%0), %%mm2;" - "movq 24(%0), %%mm3;" - "movq 32(%0), %%mm4;" - "movq 40(%0), %%mm5;" - "movq 48(%0), %%mm6;" - "movq 56(%0), %%mm7;" - "movq %%mm0, (%1);" - "movq %%mm1, 8(%1);" - "movq %%mm2, 16(%1);" - "movq %%mm3, 24(%1);" - "movq %%mm4, 32(%1);" - "movq %%mm5, 40(%1);" - "movq %%mm6, 48(%1);" - "movq %%mm7, 56(%1);" - :: "r" (src), "r" (dest) : "memory"); - src = ((const unsigned char *)src) + 64; - dest = ((unsigned char *)dest) + 64; - } - __asm__ __volatile__ ("femms":::"memory"); // same as mmx_cpy() but with a femms - } - /* - * Now do the tail of the block - */ - if (n) __memcpy(dest, src, n); - return retval; -} -#endif - -// Alam: why? memcpy may be __cdecl/_System and our code may be not the same type -static void *cpu_cpy(void *dest, const void *src, size_t n) -{ - if (src == NULL) - { - CONS_Debug(DBG_MEMORY, "Memcpy from 0x0?!: %p %p %s\n", dest, src, sizeu1(n)); - return dest; - } - - if(dest == NULL) - { - CONS_Debug(DBG_MEMORY, "Memcpy to 0x0?!: %p %p %s\n", dest, src, sizeu1(n)); - return dest; - } - - return memcpy(dest, src, n); -} - -static /*FUNCTARGET("mmx")*/ void *mmx_cpy(void *dest, const void *src, size_t n) -{ -#if defined (_MSC_VER) && defined (_X86_) - _asm - { - mov ecx, [n] - mov esi, [src] - mov edi, [dest] - shr ecx, 6 // mit mmx: 64bytes per iteration - jz lower_64 // if lower than 64 bytes - loop_64: // MMX transfers multiples of 64bytes - movq mm0, 0[ESI] // read sources - movq mm1, 8[ESI] - movq mm2, 16[ESI] - movq mm3, 24[ESI] - movq mm4, 32[ESI] - movq mm5, 40[ESI] - movq mm6, 48[ESI] - movq mm7, 56[ESI] - - movq 0[EDI], mm0 // write destination - movq 8[EDI], mm1 - movq 16[EDI], mm2 - movq 24[EDI], mm3 - movq 32[EDI], mm4 - movq 40[EDI], mm5 - movq 48[EDI], mm6 - movq 56[EDI], mm7 - - add esi, 64 - add edi, 64 - dec ecx - jnz loop_64 - emms // close mmx operation - lower_64:// transfer rest of buffer - mov ebx,esi - sub ebx,src - mov ecx,[n] - sub ecx,ebx - shr ecx, 3 // multiples of 8 bytes - jz lower_8 - loop_8: - movq mm0, [esi] // read source - movq [edi], mm0 // write destination - add esi, 8 - add edi, 8 - dec ecx - jnz loop_8 - emms // close mmx operation - lower_8: - mov ebx,esi - sub ebx,src - mov ecx,[n] - sub ecx,ebx - rep movsb - mov eax, [dest] // return dest - } -#elif defined (__GNUC__) && defined (__i386__) - void *retval = dest; - size_t i; - - if (n >= MMX1_MIN_LEN) - { - register unsigned long int delta; - /* Align destinition to MMREG_SIZE -boundary */ - delta = ((unsigned long int)dest)&(MMX_MMREG_SIZE-1); - if (delta) - { - delta=MMX_MMREG_SIZE-delta; - n -= delta; - small_memcpy(dest, src, delta); - } - i = n >> 6; /* n/64 */ - n&=63; - for (; i>0; i--) - { - __asm__ __volatile__ ( - "movq (%0), %%mm0;" - "movq 8(%0), %%mm1;" - "movq 16(%0), %%mm2;" - "movq 24(%0), %%mm3;" - "movq 32(%0), %%mm4;" - "movq 40(%0), %%mm5;" - "movq 48(%0), %%mm6;" - "movq 56(%0), %%mm7;" - "movq %%mm0, (%1);" - "movq %%mm1, 8(%1);" - "movq %%mm2, 16(%1);" - "movq %%mm3, 24(%1);" - "movq %%mm4, 32(%1);" - "movq %%mm5, 40(%1);" - "movq %%mm6, 48(%1);" - "movq %%mm7, 56(%1);" - :: "r" (src), "r" (dest) : "memory"); - src = ((const unsigned char *)src) + 64; - dest = ((unsigned char *)dest) + 64; - } - __asm__ __volatile__ ("emms":::"memory"); - } - /* - * Now do the tail of the block - */ - if (n) __memcpy(dest, src, n); - return retval; -#else - return cpu_cpy(dest, src, n); -#endif -} - -void *(*M_Memcpy)(void* dest, const void* src, size_t n) = cpu_cpy; - -/** Memcpy that uses MMX, 3DNow, MMXExt or even SSE - * Do not use on overlapped memory, use memmove for that - */ -void M_SetupMemcpy(void) -{ -#if defined (__GNUC__) && defined (__i386__) - if (R_SSE2) - M_Memcpy = sse_cpy; - else if (R_MMXExt) - M_Memcpy = mmx2_cpy; - else if (R_3DNow) - M_Memcpy = mmx1_cpy; - else -#endif - if (R_MMX) - M_Memcpy = mmx_cpy; -#if 0 - M_Memcpy = cpu_cpy; -#endif -} diff --git a/src/m_misc.h b/src/m_misc.h index b56f307a3..a95d83a76 100644 --- a/src/m_misc.h +++ b/src/m_misc.h @@ -128,8 +128,6 @@ TMatrix *RotateZMatrix(angle_t rad); // s1 = s2+s3+s1 (1024 lenghtmax) void strcatbf(char *s1, const char *s2, const char *s3); -void M_SetupMemcpy(void); - const char *M_FileError(FILE *handle); int M_PathParts (const char *path); diff --git a/src/screen.c b/src/screen.c index 9652d1c08..3cfb86f3f 100644 --- a/src/screen.c +++ b/src/screen.c @@ -319,50 +319,6 @@ void SCR_SetMode(void) // void SCR_Startup(void) { - const CPUInfoFlags *RCpuInfo = I_CPUInfo(); - if (!M_CheckParm("-NOCPUID") && RCpuInfo) - { -#if defined (__i386__) || defined (_M_IX86) || defined (__WATCOMC__) - R_486 = true; -#endif - if (RCpuInfo->RDTSC) - R_586 = true; - if (RCpuInfo->MMX) - R_MMX = true; - if (RCpuInfo->AMD3DNow) - R_3DNow = true; - if (RCpuInfo->MMXExt) - R_MMXExt = true; - if (RCpuInfo->SSE) - R_SSE = true; - if (RCpuInfo->SSE2) - R_SSE2 = true; - CONS_Printf("CPU Info: 486: %i, 586: %i, MMX: %i, 3DNow: %i, MMXExt: %i, SSE2: %i\n", R_486, R_586, R_MMX, R_3DNow, R_MMXExt, R_SSE2); - } - - if (M_CheckParm("-noASM")) - R_ASM = false; - if (M_CheckParm("-486")) - R_486 = true; - if (M_CheckParm("-586")) - R_586 = true; - if (M_CheckParm("-MMX")) - R_MMX = true; - if (M_CheckParm("-3DNow")) - R_3DNow = true; - if (M_CheckParm("-MMXExt")) - R_MMXExt = true; - - if (M_CheckParm("-SSE")) - R_SSE = true; - if (M_CheckParm("-noSSE")) - R_SSE = false; - - if (M_CheckParm("-SSE2")) - R_SSE2 = true; - - M_SetupMemcpy(); - if (dedicated) { V_Init(); diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index d634aa368..5bd806cae 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -2423,70 +2423,6 @@ UINT32 I_GetFreeMem(UINT32 *total) #endif } -const CPUInfoFlags *I_CPUInfo(void) -{ -#if defined (_WIN32) - static CPUInfoFlags WIN_CPUInfo; - SYSTEM_INFO SI; - p_IsProcessorFeaturePresent pfnCPUID; - *(void**)&pfnCPUID = FUNCPTRCAST(GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsProcessorFeaturePresent")); - - ZeroMemory(&WIN_CPUInfo,sizeof (WIN_CPUInfo)); - if (pfnCPUID) - { - WIN_CPUInfo.FPPE = pfnCPUID( 0); //PF_FLOATING_POINT_PRECISION_ERRATA - WIN_CPUInfo.FPE = pfnCPUID( 1); //PF_FLOATING_POINT_EMULATED - WIN_CPUInfo.cmpxchg = pfnCPUID( 2); //PF_COMPARE_EXCHANGE_DOUBLE - WIN_CPUInfo.MMX = pfnCPUID( 3); //PF_MMX_INSTRUCTIONS_AVAILABLE - WIN_CPUInfo.PPCMM64 = pfnCPUID( 4); //PF_PPC_MOVEMEM_64BIT_OK - WIN_CPUInfo.ALPHAbyte = pfnCPUID( 5); //PF_ALPHA_BYTE_INSTRUCTIONS - WIN_CPUInfo.SSE = pfnCPUID( 6); //PF_XMMI_INSTRUCTIONS_AVAILABLE - WIN_CPUInfo.AMD3DNow = pfnCPUID( 7); //PF_3DNOW_INSTRUCTIONS_AVAILABLE - WIN_CPUInfo.RDTSC = pfnCPUID( 8); //PF_RDTSC_INSTRUCTION_AVAILABLE - WIN_CPUInfo.PAE = pfnCPUID( 9); //PF_PAE_ENABLED - WIN_CPUInfo.SSE2 = pfnCPUID(10); //PF_XMMI64_INSTRUCTIONS_AVAILABLE - //WIN_CPUInfo.blank = pfnCPUID(11); //PF_SSE_DAZ_MODE_AVAILABLE - WIN_CPUInfo.DEP = pfnCPUID(12); //PF_NX_ENABLED - WIN_CPUInfo.SSE3 = pfnCPUID(13); //PF_SSE3_INSTRUCTIONS_AVAILABLE - WIN_CPUInfo.cmpxchg16b = pfnCPUID(14); //PF_COMPARE_EXCHANGE128 - WIN_CPUInfo.cmp8xchg16 = pfnCPUID(15); //PF_COMPARE64_EXCHANGE128 - WIN_CPUInfo.PFC = pfnCPUID(16); //PF_CHANNELS_ENABLED - } -#ifdef HAVE_SDLCPUINFO - else - { - WIN_CPUInfo.RDTSC = SDL_HasRDTSC(); - WIN_CPUInfo.MMX = SDL_HasMMX(); - WIN_CPUInfo.AMD3DNow = SDL_Has3DNow(); - WIN_CPUInfo.SSE = SDL_HasSSE(); - WIN_CPUInfo.SSE2 = SDL_HasSSE2(); - WIN_CPUInfo.AltiVec = SDL_HasAltiVec(); - } - WIN_CPUInfo.MMXExt = SDL_FALSE; //SDL_HasMMXExt(); No longer in SDL2 - WIN_CPUInfo.AMD3DNowExt = SDL_FALSE; //SDL_Has3DNowExt(); No longer in SDL2 -#endif - GetSystemInfo(&SI); - WIN_CPUInfo.CPUs = SI.dwNumberOfProcessors; - WIN_CPUInfo.IA64 = (SI.dwProcessorType == 2200); // PROCESSOR_INTEL_IA64 - WIN_CPUInfo.AMD64 = (SI.dwProcessorType == 8664); // PROCESSOR_AMD_X8664 - return &WIN_CPUInfo; -#elif defined (HAVE_SDLCPUINFO) - static CPUInfoFlags SDL_CPUInfo; - memset(&SDL_CPUInfo,0,sizeof (CPUInfoFlags)); - SDL_CPUInfo.RDTSC = SDL_HasRDTSC(); - SDL_CPUInfo.MMX = SDL_HasMMX(); - SDL_CPUInfo.MMXExt = SDL_FALSE; //SDL_HasMMXExt(); No longer in SDL2 - SDL_CPUInfo.AMD3DNow = SDL_Has3DNow(); - SDL_CPUInfo.AMD3DNowExt = SDL_FALSE; //SDL_Has3DNowExt(); No longer in SDL2 - SDL_CPUInfo.SSE = SDL_HasSSE(); - SDL_CPUInfo.SSE2 = SDL_HasSSE2(); - SDL_CPUInfo.AltiVec = SDL_HasAltiVec(); - return &SDL_CPUInfo; -#else - return NULL; /// \todo CPUID asm -#endif -} - // note CPUAFFINITY code used to reside here void I_RegisterSysCommands(void) {} diff --git a/src/typedef.h b/src/typedef.h index 9a9074bbd..12160450d 100644 --- a/src/typedef.h +++ b/src/typedef.h @@ -159,7 +159,6 @@ TYPEDEF (bannednode_t); // i_system.h TYPEDEF (JoyFF_t); -TYPEDEF (CPUInfoFlags); // i_time.h TYPEDEF (timestate_t); From fa86512a4b277c5108a8799b78eaf8a95efc5f95 Mon Sep 17 00:00:00 2001 From: "James R." Date: Mon, 25 Sep 2023 02:02:10 -0700 Subject: [PATCH 18/21] ACS music functions: add optional bool to only affect player activator --- src/acs/call-funcs.cpp | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/acs/call-funcs.cpp b/src/acs/call-funcs.cpp index 72f95bfba..12fdd56c5 100644 --- a/src/acs/call-funcs.cpp +++ b/src/acs/call-funcs.cpp @@ -339,8 +339,6 @@ static bool ACS_CountThing(mobj_t *mobj, mobjtype_t type) return false; } -// Unused, but it's here if you need it. -#if 0 /*-------------------------------------------------- static bool ACS_ActivatorIsLocal(ACSVM::Thread *thread) @@ -368,7 +366,6 @@ static bool ACS_ActivatorIsLocal(ACSVM::Thread *thread) return false; } -#endif /*-------------------------------------------------- static UINT32 ACS_SectorThingCounter(sector_t *sec, mtag_t thingTag, bool (*filter)(mobj_t *)) @@ -2184,6 +2181,14 @@ bool CallFunc_MusicPlay(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::W { ACSVM::MapScope *map = thread->scopeMap; + // 0: str tune - id for the tune to play + // 1: [bool foractivator] - only do this if the activator is a player and is being viewed + + if (argC > 1 && argV[1] && !ACS_ActivatorIsLocal(thread)) + { + return false; + } + Music_Play(map->getString(argV[0])->str); return false; @@ -2196,6 +2201,13 @@ bool CallFunc_MusicPlay(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::W --------------------------------------------------*/ bool CallFunc_MusicStopAll(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC) { + // 0: [bool foractivator] - only do this if the activator is a player and is being viewed + + if (argC > 0 && argV[0] && !ACS_ActivatorIsLocal(thread)) + { + return false; + } + Music_StopAll(); return false; @@ -2210,6 +2222,15 @@ bool CallFunc_MusicRemap(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM:: { ACSVM::MapScope *map = thread->scopeMap; + // 0: str tune - id for the tune to play + // 1: str song - lump name for the song to map to + // 2: [bool foractivator] - only do this if the activator is a player and is being viewed + + if (argC > 2 && argV[2] && !ACS_ActivatorIsLocal(thread)) + { + return false; + } + Music_Remap(map->getString(argV[0])->str, map->getString(argV[1])->str); return false; From 7ea0e2081e6ad02ca77165dfa5b5960d61bb5654 Mon Sep 17 00:00:00 2001 From: "James R." Date: Mon, 25 Sep 2023 03:06:56 -0700 Subject: [PATCH 19/21] Move HOM removal from R_RenderPlayerView to D_Display This lets duplicate displayplayers[0] render correctly, since repeating occurrences of displayplayers[0] won't clear the screen multiple times. --- src/d_main.cpp | 23 +++++++++++++++++++++++ src/r_main.c | 20 -------------------- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index 0ff725651..2343a837c 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -510,6 +510,29 @@ static void D_Display(void) ps_rendercalltime = I_GetPreciseTime(); + if (rendermode == render_soft) + { + if (cv_homremoval.value) + { + if (cv_homremoval.value == 1) + { + // Clear the software screen buffer to remove HOM + memset(screens[0], 31, vid.width * vid.height * vid.bpp); + } + else + { + //'development' HOM removal -- makes it blindingly obvious if HOM is spotted. + memset(screens[0], 32+(timeinmap&15), vid.width * vid.height * vid.bpp); + } + } + + if (r_splitscreen == 2) + { + // Draw over the fourth screen so you don't have to stare at a HOM :V + V_DrawFill(viewwidth, viewheight, viewwidth, viewheight, 31|V_NOSCALESTART); + } + } + for (i = 0; i <= r_splitscreen; i++) { if (players[displayplayers[i]].mo || players[displayplayers[i]].playerstate == PST_DEAD) diff --git a/src/r_main.c b/src/r_main.c index c852b08d4..929175e1c 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1475,26 +1475,6 @@ void R_RenderPlayerView(void) INT32 nummasks = 1; maskcount_t* masks = malloc(sizeof(maskcount_t)); - // if this is display player 1 - if (cv_homremoval.value && player == &players[displayplayers[0]]) - { - if (cv_homremoval.value == 1) - { - // Clear the software screen buffer to remove HOM - memset(screens[0], 31, vid.width * vid.height * vid.bpp); - } - else - { - //'development' HOM removal -- makes it blindingly obvious if HOM is spotted. - memset(screens[0], 32+(timeinmap&15), vid.width * vid.height * vid.bpp); - } - } - else if (r_splitscreen == 2 && player == &players[displayplayers[2]]) - { - // Draw over the fourth screen so you don't have to stare at a HOM :V - V_DrawFill(viewwidth, viewheight, viewwidth, viewheight, 31|V_NOSCALESTART); - } - R_SetupFrame(viewssnum); framecount++; validcount++; From 15a87a8a7737149efd3ca6488090eb913af28750 Mon Sep 17 00:00:00 2001 From: toaster Date: Tue, 26 Sep 2023 21:34:08 +0100 Subject: [PATCH 20/21] P_DoQuakeOffset: Prevent two calls to FixedDiv --- src/p_spec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/p_spec.c b/src/p_spec.c index dd73fcd7d..336342889 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -9428,7 +9428,8 @@ void P_DoQuakeOffset(UINT8 view, mappoint_t *viewPos, mappoint_t *offset) ) - distBuffer; - const fixed_t distEase = min(FixedDiv(max(epidist, 0), quake->radius), FRACUNIT); + fixed_t distEase = FixedDiv(max(epidist, 0), quake->radius); + distEase = min(distEase, FRACUNIT); ir = Easing_InCubic(distEase, ir, 0); } From f522cae573df7e2c2d9909cbedaa196ddb167ce7 Mon Sep 17 00:00:00 2001 From: toaster Date: Tue, 26 Sep 2023 23:16:19 +0100 Subject: [PATCH 21/21] SV_GenContext: Guard #ifndef TESTERS Fixes compiling TESTERS builds --- src/d_clisrv.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 0c053c6b8..0a2cbf53d 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -3803,6 +3803,7 @@ void SV_ResetServer(void) DEBFILE("\n-=-=-=-=-=-=-= Server Reset =-=-=-=-=-=-=-\n\n"); } +#ifndef TESTERS static void SV_GenContext(void) { UINT8 i; @@ -3821,6 +3822,7 @@ static void SV_GenContext(void) strncpy(connectedservername, cv_servername.string, MAXSERVERNAME); strncpy(connectedservercontact, cv_server_contact.string, MAXSERVERCONTACT); } +#endif // TESTERS // // D_QuitNetGame