From 63bae718b52e9d6a12c4488f48fe9ef1ec229a8c Mon Sep 17 00:00:00 2001 From: Steven Casper Date: Sun, 23 Jun 2024 11:06:32 -0400 Subject: [PATCH] xClimate.cpp 100% Equivalent (maybe) (#271) --- src/SB/Core/x/xClimate.cpp | 166 ++++++++++++++++++++++++++++++----- src/SB/Core/x/xClimate.h | 5 +- src/SB/Core/x/xParEmitter.h | 5 +- src/SB/Game/zCutsceneMgr.cpp | 1 + src/SB/Game/zParPTank.h | 7 +- 5 files changed, 157 insertions(+), 27 deletions(-) diff --git a/src/SB/Core/x/xClimate.cpp b/src/SB/Core/x/xClimate.cpp index 466052cbb..354877050 100644 --- a/src/SB/Core/x/xClimate.cpp +++ b/src/SB/Core/x/xClimate.cpp @@ -1,27 +1,35 @@ -#include -#include "xVec3.h" -#include "xGlobals.h" #include "xClimate.h" + +#include +#include +#include "xMath.h" #include "xMath3.h" #include "xString.h" +#include "xVec3.h" +#include "zGlobals.h" #include "zParEmitter.h" +#include "zParPTank.h" -// TODO: figure out where to put this -extern "C" { -void memcpy(void* a, const void* b, int32 size); -} +_tagClimate* sClimate; -extern xGlobals xglobals; -extern float32 xClimate_f_0; -extern float32 xClimate_f_10_0; -extern _tagClimate* sClimate; +float snow_life = 3.0f; +const xVec3 snow_vel = {0.0f, -2.0f, 0.0f}; +const xVec3 snow_dvel = {0.1f, 0.1f, 0.1f}; +void xClimateVecFromAngle(float32 angleDegrees, xVec3* vec) +{ + xMat3x3 Mat; + xMat3x3Identity(&Mat); + xMat3x3Euler(&Mat, (PI * angleDegrees) / ONEEIGHTY, 0.0f, 0.0f); + xVec3Init(vec, 0.0f, 0.0f, 1.0f); + xMat3x3LMulVec(vec, &Mat, vec); +} void xClimateInit(_tagClimate* climate) { - climate->rain.strength = xClimate_f_0; + climate->rain.strength = 0.0f; climate->rain.rain_emitter = zParEmitterFind(xStrHash("PAREMIT_RAIN")); climate->rain.rain_emitter->emit_flags &= 0xfe; @@ -30,8 +38,35 @@ void xClimateInit(_tagClimate* climate) climate->rain.snow_emitter->emit_flags &= 0xfe; } - - +#ifdef NON_MATCHING +// Equivalent +// float ops are being optimized more aggressively +void xClimateInitAsset(_tagClimate* climate, xEnvAsset* asset) +{ + sClimate = climate; + climate->wind.strength = 0.0f; + xClimateVecFromAngle(climate->wind.angle, &climate->wind.dir); + + if(asset->climateFlags == 0) + { + climate->wind.strength = 0.0f; + climate->rain.strength = 0.0f; + return; + } + if(asset->climateFlags & 1) + { + climate->rain.rain = 1.0f; + climate->rain.strength = 0.5f * (asset->climateStrengthMax - asset->climateStrengthMin); + climate->rain.strength += asset->climateStrengthMin; + } + else if(asset->climateFlags & 2) + { + climate->rain.rain = 0.0f; + climate->rain.strength = 0.5f * (asset->climateStrengthMax - asset->climateStrengthMin); + climate->rain.strength += asset->climateStrengthMin; + } +} +#endif void xClimateSetSnow(float32 stre) { @@ -45,18 +80,104 @@ void xClimateSetRain(float32 stre) sClimate->rain.strength = stre; } - -#if 0 +#ifdef NON_MATCHING +// Equivalent +// Float literal is being loaded three separate times in the original code. void GetPosBigDogWhattupFool(xVec3* vec) { - vec->x = xClimate_f_10_0 * xglobals.camera.mat.at.x + xglobals.camera.mat.pos.x; - vec->y = xClimate_f_10_0 * xglobals.camera.mat.at.y + xglobals.camera.mat.pos.y; - vec->z = xClimate_f_10_0 * xglobals.camera.mat.at.z + xglobals.camera.mat.pos.z; + xCamera* camera = &xglobals->camera; + vec->x = 10.0f * camera->mat.at.x + camera->mat.pos.x; + vec->y = 10.0f * camera->mat.at.y + camera->mat.pos.y; + vec->z = 10.0f * camera->mat.at.z + camera->mat.pos.z; } #endif - - +#ifdef NON_MATCHING +// NOTE (Square): I think it's equivalent but it's very hard to tell. Our compiler is optimizing the float ops +// much more aggresively and it's throwing the regalloc off. +void UpdateRain(_tagClimate* climate, float seconds) +{ + _tagRain* r = &climate->rain; + xParEmitterCustomSettings info; + memset(&info, 0, sizeof(xParEmitterCustomSettings)); + info.custom_flags = 0x100; + + if(r->rain != 0) + { + int32 total_rain_drops = 25.0f * r->strength; + for(int32 i = 0; i < total_rain_drops; i++) + { + GetPosBigDogWhattupFool(&info.pos); + info.pos.x += 25.0f * xurand() - 12.5f; + info.pos.y += 8.0f; + info.pos.z += 25.0f * xurand() - 12.5f; + xParEmitterEmitCustom(r->rain_emitter, seconds, &info); + } + return; + } + + xVec3 fool; + int32 total_snow_flakes = 25.0f * r->strength; + info.custom_flags |= 0x202; + GetPosBigDogWhattupFool(&fool); + if(gPTankDisable) + { + for(int32 i = 0; i < total_snow_flakes; i++) + { + info.pos = fool; + info.pos.x += 45.0f * xurand() - 22.5f; + info.pos.z += 25.0f * xurand() - 22.5f; + + float32 xx = info.pos.x - fool.x; + float32 zz = info.pos.z - fool.z; + float32 perc = 1.0f - xx * zz / 506.25f; + info.pos.y += 4.0f * perc + 4.0f; + + info.vel.x = snow_dvel.x * xurand() + snow_vel.x; + info.vel.y = snow_dvel.y * xurand() + snow_vel.y; + info.vel.z = snow_dvel.z * xurand() + snow_vel.z; + + + info.life.val[0] = snow_life * perc + snow_life; + xParEmitterEmitCustom(r->snow_emitter, seconds, &info); + } + return; + } + + int32 num = (float32)total_snow_flakes * 0.1f; + if(num > 0) + { + xVec3* pos = (xVec3*)xMemPushTemp(num * 2 * sizeof(xVec3)); + xVec3* vel = pos+num; + if(pos != NULL) + { + + for(int32 i = 0; i < num; i++) + { + *pos = fool; + pos->x += 45.0f * xurand() - 22.5f; + pos->z += 45.0f * xurand() - 22.5f; + + float32 zz = pos->z - fool.z; + float32 xx = pos->x - fool.x; + float perc = (1.0f - (xx * xx + zz * zz) / 506.25f); + + pos->y += 4.0f * perc + 4.0f; + + vel->x = snow_dvel.x * xurand() + snow_vel.x; + vel->y = snow_dvel.y * xurand() + snow_vel.y; + vel->z = snow_dvel.z * xurand() + snow_vel.z; + + pos++; + vel++; + } + + zParPTankSpawnSnow(pos, vel, num); + xMemPopTemp(pos); + } + } +} +#endif void UpdateWind(_tagClimate* climate, float32 seconds) { @@ -78,8 +199,7 @@ void xVec3Init(xVec3* vec, float32 x, float32 y, float32 z) void xMat3x3Identity(xMat3x3* matrix) { - // TODO: figure out what/where this global variable is - xMat3x3Copy(matrix, (xMat3x3*)0x8038C2E0); + xMat3x3Copy(matrix, &g_I3); } void xMat3x3Copy(xMat3x3* m1, const xMat3x3* m2) diff --git a/src/SB/Core/x/xClimate.h b/src/SB/Core/x/xClimate.h index a4fca81f5..83487701b 100644 --- a/src/SB/Core/x/xClimate.h +++ b/src/SB/Core/x/xClimate.h @@ -3,8 +3,9 @@ #include #include "xVec3.h" -#include "xEnv.h" -#include "zParEmitter.h" + +struct xEnvAsset; +struct zParEmitter; struct _tagRain { diff --git a/src/SB/Core/x/xParEmitter.h b/src/SB/Core/x/xParEmitter.h index a09fb5f8c..d92d64404 100644 --- a/src/SB/Core/x/xParEmitter.h +++ b/src/SB/Core/x/xParEmitter.h @@ -15,6 +15,7 @@ struct xParInterp float32 oofreq; }; +// Size 0x138 struct xParEmitterPropsAsset : xBaseAsset { uint32 parSysID; @@ -35,6 +36,7 @@ struct xParEmitterPropsAsset : xBaseAsset float32 emit_limit_reset_time; }; +// Size 0x16c struct xParEmitterCustomSettings : xParEmitterPropsAsset { uint32 custom_flags; @@ -103,5 +105,6 @@ void xParEmitterInit(void* b, void* tasset); void xParEmitterSetup(xParEmitter* t); void xParEmitterDestroy(); void xParEmitterUpdate(xBase* to, xScene*, float32 dt); +xPar* xParEmitterEmitCustom(xParEmitter* p, float dt, xParEmitterCustomSettings* info); -#endif \ No newline at end of file +#endif diff --git a/src/SB/Game/zCutsceneMgr.cpp b/src/SB/Game/zCutsceneMgr.cpp index 973b4fd21..232cda58a 100644 --- a/src/SB/Game/zCutsceneMgr.cpp +++ b/src/SB/Game/zCutsceneMgr.cpp @@ -7,6 +7,7 @@ #include "zEntPlayer.h" #include "zMusic.h" #include "zNPCFXCinematic.h" +#include "zParEmitter.h" #include "xEvent.h" #include "xCutscene.h" #include "xserializer.h" diff --git a/src/SB/Game/zParPTank.h b/src/SB/Game/zParPTank.h index df8ff8e41..c2f424c95 100644 --- a/src/SB/Game/zParPTank.h +++ b/src/SB/Game/zParPTank.h @@ -3,11 +3,16 @@ #include +struct xVec3; + void zParPTankInit(); void zParPTankSceneEnter(); void zParPTankSceneExit(); +void zParPTankSpawnSnow(xVec3* pos, xVec3* vel, uint32 count); void zParPTankExit(); void zParPTankRender(); void zParPTankUpdate(float32 dt); -#endif \ No newline at end of file +extern uint32 gPTankDisable; + +#endif