diff --git a/port/src/video.c b/port/src/video.c index 50c309db..8064ff46 100644 --- a/port/src/video.c +++ b/port/src/video.c @@ -86,6 +86,11 @@ f32 portScreenShakeScale = 1.0f; * 0 (default) = the legal screen + logo attract sequence plays as normal. */ s32 portSkipIntro = 0; +/* D232: Game.NoHitFlash — the community "no damage flash" toggle (route-(b) + * hook in src/game/bondview2.c currentPlayerSetFadeColour). 0 (default) = + * original damage flash. */ +s32 portNoHitFlash = 0; + /* D211: Video.FovScale as a multiplier on the render FOV. Applied game-side * at the guPerspectiveF chokepoint (src/fr.c) so it lands BEFORE the CPU * pre-multiplies projection x view into the combined world matrix — the @@ -97,6 +102,7 @@ PD_CONSTRUCTOR static void videoConfigInit(void) { configRegisterFloat("Game.ScreenShakeIntensity", &portScreenShakeScale, 0.0f, 10.0f); configRegisterInt("Game.SkipIntro", &portSkipIntro, 0, 1); + configRegisterInt("Game.NoHitFlash", &portNoHitFlash, 0, 1); configRegisterInt("Video.VSync", &cfgVSync, 0, 1); configRegisterInt("Video.FpsCap", &cfgFpsCap, 0, 1000); configRegisterInt("Video.MSAA", &cfgMSAA, 1, 8); diff --git a/src/game/bondview2.c b/src/game/bondview2.c index dc29d2ed..c02b3a5d 100644 --- a/src/game/bondview2.c +++ b/src/game/bondview2.c @@ -4234,6 +4234,30 @@ Gfx *currentPlayerDrawFade(Gfx *gdl) } void currentPlayerSetFadeColour(s32 r, s32 g, s32 b, f32 frac) { +#if defined(PORT) + /* D232: Game.NoHitFlash — the community "no damage flash" toggle. + * Every fade in the game routes through this function, and the ONLY + * non-black ones are the two damage paths (the per-frame g_DamageTypes + * envelope in bondviewPlayerTickDamageAndHealth above — white 0xFF + * with an alpha envelope scaled by remaining health — and the red + * 150,0,0 overlay once the death blood finishes) — every other caller + * passes (0,0,0). User playtest (M-105 cont.) caught that zeroing just + * the RGB isn't enough: `frac` is the overlay's alpha/opacity, so a + * zeroed-RGB-but-nonzero-frac call still draws a fully opaque BLACK + * flash at the same envelope as the original white one -- same visual + * intrusion, different colour. Zero frac too so the overlay doesn't + * draw at all. Leaves all blackouts, the colour screen and the death + * fade's *own* frac-driven timing untouched (their frac is unaffected + * since they only ever pass (0,0,0) here). Default 0 = original + * behaviour. */ + extern s32 portNoHitFlash; + if (portNoHitFlash && (r != 0 || g != 0 || b != 0)) { + r = 0; + g = 0; + b = 0; + frac = 0.0f; + } +#endif g_CurrentPlayer->colourscreenred = r; g_CurrentPlayer->colourscreengreen = g; g_CurrentPlayer->colourscreenblue = b;