Increase amount of rain and weather effects. (#24)

* Increase amount of rain and weather effects.

* Update weather and snow to be able to revert to vanilla behavior under demo playback.
This commit is contained in:
Darío
2025-12-28 16:13:48 -03:00
committed by GitHub
parent 8d91c1d411
commit 9ca2716376
4 changed files with 220 additions and 10 deletions
+17
View File
@@ -0,0 +1,17 @@
#include "patches.h"
extern s32 getGameMode(void);
// @recomp Check whether the game is currently on a mode that uses demo playback instead of the player's inputs.
bool recomp_in_demo_playback_game_mode() {
switch (getGameMode()) {
case GAME_MODE_6_FILE_PLAYBACK:
case GAME_MODE_7_ATTRACT_DEMO:
case GAME_MODE_8_BOTTLES_BONUS:
case GAME_MODE_A_SNS_PICTURE:
case GAME_MODE_9_BANJO_AND_KAZOOIE:
return TRUE;
default:
return FALSE;
}
}
+19 -9
View File
@@ -26,13 +26,16 @@ extern void func_802F8FFC(void);
extern void func_8033BD20(BKModelBin **arg0);
extern s32 globalTimer_getTime(void);
#define SNOW_PARTICLE_COUNT 256
#define SNOW_PARTICLE_COUNT_ORIGINAL 100
#define SNOW_PARTICLE_COUNT_EXPANDED 256
#define SNOW_SKIP_INTERPOLATION_MASK 0x8000
u16 snowIDArray[SNOW_PARTICLE_COUNT];
u16 snowIDQueue[SNOW_PARTICLE_COUNT];
u16 snowIDArray[SNOW_PARTICLE_COUNT_EXPANDED];
u16 snowIDQueue[SNOW_PARTICLE_COUNT_EXPANDED];
u16 snowIDQueueCount = 0;
struct4Ds snowData[SNOW_PARTICLE_COUNT];
struct4Ds snowData[SNOW_PARTICLE_COUNT_EXPANDED];
extern bool recomp_in_demo_playback_game_mode();
// @recomp Patched to initialize the ID queue for snow particles.
RECOMP_PATCH void func_802F9054(void) {
@@ -46,7 +49,7 @@ RECOMP_PATCH void func_802F9054(void) {
D_80369288 = assetcache_get(0x8a1); //2D_light
// @recomp Initialize the snow ID queue.
while (snowIDQueueCount < SNOW_PARTICLE_COUNT) {
while (snowIDQueueCount < SNOW_PARTICLE_COUNT_EXPANDED) {
snowIDQueue[snowIDQueueCount] = snowIDQueueCount;
snowIDQueueCount++;
}
@@ -132,8 +135,10 @@ RECOMP_PATCH void func_802F919C(void) {
}
if (D_80369280->unk18 == 1) {
// @recomp Patched to use the count from the macro instead and spawn multiple snow particles at once.
u32 particlesToSpawn = 2;
while (D_80369284 < SNOW_PARTICLE_COUNT && particlesToSpawn > 0) {
// This behavior must be ignored while in demo mode to not alter the RNG, as it'll affect the demo's result.
u32 snowParticleLimit = recomp_in_demo_playback_game_mode() ? SNOW_PARTICLE_COUNT_ORIGINAL : SNOW_PARTICLE_COUNT_EXPANDED;
u32 particlesToSpawn = recomp_in_demo_playback_game_mode() ? 1 : 2;
while (D_80369284 < snowParticleLimit && particlesToSpawn > 0) {
sp40 = D_80369280->unk1C + D_80369284;
// @recomp Assign a new ID to this particle. Also mark it to skip interpolation.
@@ -153,7 +158,10 @@ RECOMP_PATCH void func_802F919C(void) {
}
// @recomp Use the full 360 degrees instead.
var_f20 = 180.0f;
// This behavior must be ignored while in demo mode to not alter the RNG, as it'll affect the demo's result.
if (!recomp_in_demo_playback_game_mode()) {
var_f20 = 180.0f;
}
ml_vec3f_yaw_rotate_copy(sp4C, sp4C, viewport_getYaw() + randf2(-var_f20, var_f20));
sp4C[0] += D_80381040[0];
@@ -184,7 +192,9 @@ RECOMP_PATCH bool func_802F989C(Gfx **gfx, Mtx **mtx, f32 arg2[3]) {
&& (arg2[1] > -200.0f)
&& ((-17000.0f < D_80381070[2]) && (D_80381070[2] < 17000.0f))
// @recomp Remove frustum check.
//&& viewport_func_8024DB50(arg2, D_8038108C, aspect_ratio_scale)
// This behavior must be ignored while in demo mode to not alter the RNG, as it'll affect the demo's result.
//&& viewport_func_8024DB50(arg2, D_8038108C)
&& (!recomp_in_demo_playback_game_mode() || viewport_func_8024DB50(arg2, D_8038108C))
) {
func_80251B5C(D_80381070[0], D_80381070[1], D_80381070[2]);
mlMtxApply(*mtx);
+5
View File
@@ -102,6 +102,11 @@
#define WEATHER_PARTICLE_ID_COUNT 256
#define WEATHER_PARTICLE_ID_MAX 0x8000
// Rain Particles: 0x30800000 - 0x31000000
#define RAIN_PARTICLE_TRANSFORM_ID_START 0x30800000
#define RAIN_PARTICLE_ID_COUNT 256
#define RAIN_PARTICLE_ID_MAX 0x8000
// Markers: 0x10000000 - 0x1FFFFFFF
#define BANJO_TRANSFORM_ID_START 0x10000000
#define MARKER_TRANSFORM_ID_START (BANJO_TRANSFORM_ID_START + MARKER_TRANSFORM_ID_COUNT)
+179 -1
View File
@@ -5,8 +5,13 @@
extern s32 func_8033A170(void);
extern struct6s *D_80381030;
extern struct3s *D_80381034;
u32 weather_particle_spawn_count = 0;
extern bool recomp_in_demo_playback_game_mode();
u32 get_weather_particle_id(struct5s *p) {
u8 *padding = p->pad35;
u32 id = (padding[0] << 16) | (padding[1] << 8) | (padding[2] << 0);
@@ -48,6 +53,14 @@ RECOMP_PATCH void func_802F87B0(struct6s *this) {
else {
ml_vec3f_yaw_rotate_copy(sp4C, sp4C, camRot[1] + randf2(-70.0f, 70.0f));
}//L802F88F0
// @recomp Force particles to spawn 360 degrees around the player at all times.
// This behavior must be ignored while in demo mode to not alter the RNG, as it'll affect the
// demo's result.
if (!recomp_in_demo_playback_game_mode()) {
ml_vec3f_yaw_rotate_copy(sp4C, sp4C, randf2(0.0f, 360.0f));
}
sp4C[0] += plyrPos[0];
sp4C[1] += plyrPos[1];
sp4C[2] += plyrPos[2];
@@ -81,6 +94,28 @@ RECOMP_PATCH void func_802F87B0(struct6s *this) {
if (weather_particle_spawn_count >= WEATHER_PARTICLE_ID_MAX) {
weather_particle_spawn_count = 0;
}
// @recomp Increase the spawn rate of the particles by calling the function recursively again.
// Infinite recursion is prevented by keeping track of the current recursion depth. To control
// the frequency of the spawn rate, an additional counter is used to spawn an extra particle
// every N amount of frames.
// This behavior must be ignored while in demo mode to not alter the RNG, as it'll affect the
// demo's result.
if (!recomp_in_demo_playback_game_mode()) {
const u32 spawn_rate_frequency = 2;
static u32 recursion_depth = 0;
if (recursion_depth == 0) {
static u32 spawn_rate_counter = 0;
spawn_rate_counter++;
if (spawn_rate_counter == spawn_rate_frequency) {
recursion_depth++;
func_802F87B0(this);
recursion_depth--;
spawn_rate_counter = 0;
}
}
}
}
// @recomp Patched to tag the weather effect for interpolation.
@@ -101,4 +136,147 @@ RECOMP_PATCH void func_802F8A90(struct6s *this, Gfx **gdl, Mtx **mptr, Vtx **vpt
iPtr->unk34 = func_8033A170();
}
}
}
// @recomp Patched to increase capacity of the weather effect vector.
RECOMP_PATCH struct6s *func_802F7C38(void) {
if (D_80381030 == NULL) {
// @recomp Increase capacity of the weather effect vector to accomodate for more particles on screen.
// This behavior must be ignored while in demo mode to not alter the RNG, as it'll affect the
// demo's result.
//D_80381030 = func_802F8BE0(50); //new CCW weather
D_80381030 = func_802F8BE0(recomp_in_demo_playback_game_mode() ? 50 : 250);
}
return D_80381030;
}
u32 rain_particle_spawn_count = 0;
u32 get_rain_particle_id(struct4s *p) {
u8 *padding = p->pad19;
u32 id = (padding[0] << 16) | (padding[1] << 8) | (padding[2] << 0);
return id;
}
void set_rain_particle_id(struct4s *p, u32 id) {
u8 *padding = p->pad19;
padding[0] = (id >> 16) & 0xFF;
padding[1] = (id >> 8) & 0xFF;
padding[2] = (id >> 0) & 0xFF;
}
// @recomp Patched to assign an interpolation ID to the rain particle when it's created.
RECOMP_PATCH void func_802F7EB0(struct3s *this) {
f32 plyrPos[3]; //sp74
f32 camNorm[3]; //sp68
f32 camRot[3]; //sp5C
s32 i;
f32 tmpf;
struct4s *sp50;
f32 sp4C[3];
if (vector_size(this->unk20) >= this->unk24)
return;
player_getPosition(plyrPos);
viewport_getLookVector(camNorm);
viewport_getRotation_vec3f(camRot);
sp50 = vector_pushBackNew(&this->unk20);
tmpf = randf2(50.0f, 1100.0f);
sp4C[0] = 0.0f;
sp4C[1] = randf2(200.0f, 300.0f);
sp4C[2] = -tmpf;
if (gu_sqrtf(this->unk10[0] * this->unk10[0] + this->unk10[1] * this->unk10[1] + this->unk10[2] * this->unk10[2]) < 5.0f) {
ml_vec3f_yaw_rotate_copy(sp4C, sp4C, randf2(0.0f, 360.0f));
}
else {
ml_vec3f_yaw_rotate_copy(sp4C, sp4C, camRot[1] + randf2(-70.0f, 70.0f));
}
// @recomp Force particles to spawn 360 degrees around the player at all times.
// This behavior must be ignored while in demo mode to not alter the RNG, as it'll affect the
// demo's result.
if (!recomp_in_demo_playback_game_mode()) {
ml_vec3f_yaw_rotate_copy(sp4C, sp4C, randf2(0.0f, 360.0f));
}
sp4C[0] = plyrPos[0] + sp4C[0];
sp4C[1] = plyrPos[1] + sp4C[1];
sp4C[2] = plyrPos[2] + sp4C[2];
if (tmpf < 550.0)
for (i = 0; (i < 0xa) && viewport_isPointPlane_3f(sp4C[0], sp4C[1] - 10.0f, sp4C[2]); i++) {
sp4C[1] += 100.0f;
}
sp50->unk0[0] = sp4C[0];
sp50->unk0[1] = sp4C[1];
sp50->unk0[2] = sp4C[2];
sp50->unkC[0] = 0.0f;
sp50->unkC[1] = randf2(-1600.0f, -1500.0f);
sp50->unkC[2] = 0.0f;
// @recomp Set the rain particle's ID based on the particle spawn count and increment it.
set_rain_particle_id(sp50, rain_particle_spawn_count++);
if (rain_particle_spawn_count >= RAIN_PARTICLE_ID_MAX) {
rain_particle_spawn_count = 0;
}
// @recomp Increase the spawn rate of the particles by calling the function recursively again.
// Infinite recursion is prevented by keeping track of the current recursion depth. To control
// the frequency of the spawn rate, an additional counter is used to spawn an extra particle
// every N amount of frames.
// This behavior must be ignored while in demo mode to not alter the RNG, as it'll affect the
// demo's result.
if (!recomp_in_demo_playback_game_mode()) {
const u32 spawn_rate_frequency = 2;
static u32 recursion_depth = 0;
if (recursion_depth == 0) {
static u32 spawn_rate_counter = 0;
spawn_rate_counter++;
if (spawn_rate_counter == spawn_rate_frequency) {
recursion_depth++;
func_802F7EB0(this);
recursion_depth--;
spawn_rate_counter = 0;
}
}
}
}
// @recomp Patched to tag the rain particle for interpolation.
RECOMP_PATCH void func_802F8110(struct3s *this, Gfx **gdl, Mtx **mptr, u32 arg3) {
struct4s *startPtr; //sp4c
struct4s *endPtr;
struct4s *iPtr;
startPtr = vector_getBegin(this->unk20);
endPtr = vector_getEnd(this->unk20);
for (iPtr = startPtr; iPtr < endPtr; iPtr++) {
modelRender_setDepthMode(MODEL_RENDER_DEPTH_COMPARE);
// @recomp Set the model transform ID before drawing the rain particle.
cur_drawn_model_transform_id = RAIN_PARTICLE_TRANSFORM_ID_START + RAIN_PARTICLE_ID_COUNT * get_rain_particle_id(iPtr);
modelRender_draw(gdl, mptr, iPtr, 0, 1.0f, 0, this->unk2C);
// @recomp Clear the model transform ID after drawing the rain particle.
cur_drawn_model_transform_id = 0;
iPtr->unk18 = func_8033A170();
}
}
// @recomp Patched to increase the capacity of the rain particle vector.
RECOMP_PATCH struct3s *func_802F7C7C(void) {
if (D_80381034 == NULL) {
// @recomp Increase capacity of the rain particle vector to accomodate for more droplets on screen.
// This behavior must be ignored while in demo mode to not alter the RNG, as it'll affect the
// demo's result.
//D_80381034 = func_802F8264(30); //rain
D_80381034 = func_802F8264(recomp_in_demo_playback_game_mode() ? 30 : 300);
}
return D_80381034;
}