From 06856ed973717072aaec63119bb159639e068a8d Mon Sep 17 00:00:00 2001 From: Maxime Morel Date: Thu, 22 Oct 2026 18:27:58 +0200 Subject: [PATCH] Water decal improvement 3 --- src/game/explosion.c | 51 ++++++++++++++++++++++++++++++++++++++++---- src/game/explosion.h | 5 +++++ 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/src/game/explosion.c b/src/game/explosion.c index eeebd390..fe18dfef 100644 --- a/src/game/explosion.c +++ b/src/game/explosion.c @@ -1590,6 +1590,9 @@ void explosionInitFlyingParticles(coord3d *spawnpos, f32 spawn_rand_scale, f32 s rand3 = (2.0f * (((f32) randomGetNext()) * (1.0f / (f32)UINT_MAX))) - 1.0f; g_FlyingParticlesBuffer[g_NumParticleEntries].unk00 = 1; +#ifdef PORT + g_FlyingParticlesBuffer[g_NumParticleEntries].is_splash = FALSE; +#endif g_FlyingParticlesBuffer[g_NumParticleEntries].position.f[0] = spawnpos->f[0] + (spawn_rand_scale * rand1); g_FlyingParticlesBuffer[g_NumParticleEntries].position.f[1] = spawnpos->f[1] + (spawn_rand_scale * rand2); @@ -1739,6 +1742,15 @@ void explosionUpdateFlyingParticles(void) g_FlyingParticlesBuffer[i].unk00 = 0; } +#ifdef PORT + if (g_FlyingParticlesBuffer[i].is_splash + && g_FlyingParticlesBuffer[i].position_drift.f[1] < 0.0f + && g_FlyingParticlesBuffer[i].position.f[1] < g_FlyingParticlesBuffer[i].splash_y) + { + g_FlyingParticlesBuffer[i].unk00 = 0; + } +#endif + // position-related. deletes particles that are too low or too high. if ((g_FlyingParticlesBuffer[i].position.f[1] < -30000.0f) || (g_FlyingParticlesBuffer[i].position.f[1] > 30000.0f)) { @@ -1754,22 +1766,53 @@ void explosionUpdateFlyingParticles(void) /* Bullet hitting water (PC): the N64 only drew the yellow impact flash there. * Use the chr hit puffs instead (chrCreateHitPuffs: the small impact puff and - * the larger burst), tinted to the water colour. */ + * the larger burst), tinted to the water colour, plus droplets (the wall-hit + * dust particles, recoloured) thrown up and removed when they fall back + * through the surface. */ +#define WATER_SPLASH_R 0xA0 +#define WATER_SPLASH_G 0xC8 +#define WATER_SPLASH_B 0xF0 +#define WATER_SPLASH_DROPLETS 12 + static void explosionTintSpark(s_bullet_spark *spark) { if (spark != NULL) { - spark->unk28 = 0xA0; - spark->unk29 = 0xC8; - spark->unk2A = 0xF0; + spark->unk28 = WATER_SPLASH_R; + spark->unk29 = WATER_SPLASH_G; + spark->unk2A = WATER_SPLASH_B; spark->unk2B = 0xFF; } } void explosionCreateWaterSplash(coord3d *pos, s16 room) { + s32 i; + s32 j; + explosionTintSpark(bullet_spark_create(pos, 3, 43.0f, room)); explosionTintSpark(bullet_spark_create(pos, 1, 21.0f, room)); + + for (i = 0; i < WATER_SPLASH_DROPLETS; i++) + { + struct FlyingParticles *drop = &g_FlyingParticlesBuffer[g_NumParticleEntries]; + + explosionInitFlyingParticles(pos, 2.0f, 1.0f, 6.0f, 3.0f); + + drop->is_splash = TRUE; + drop->splash_y = pos->f[1]; + + for (j = 0; j < 4; j++) + { + /* vary the brightness per vertex, keep the water hue */ + s32 shade = 0xC0 + (randomGetNext() & 0x3F); + + drop->vertex_list[j].v.cn[0] = (WATER_SPLASH_R * shade) / 0xFF; + drop->vertex_list[j].v.cn[1] = (WATER_SPLASH_G * shade) / 0xFF; + drop->vertex_list[j].v.cn[2] = (WATER_SPLASH_B * shade) / 0xFF; + drop->vertex_list[j].v.cn[3] = 0xB0; + } + } } #endif diff --git a/src/game/explosion.h b/src/game/explosion.h index 58740f1a..83d55c39 100644 --- a/src/game/explosion.h +++ b/src/game/explosion.h @@ -148,6 +148,11 @@ struct FlyingParticles { s32 unk34; Vtx vertex_list[4]; +#ifdef PORT + /* water splash droplet: removed once it falls back below splash_y */ + s32 is_splash; + f32 splash_y; +#endif }; extern f32 g_SpExplosionDamageMult;