From d99637766d1f37aed0cc7f74b5f2c2f24bf4fd4c Mon Sep 17 00:00:00 2001 From: Henrique Gemignani Passos Lima Date: Fri, 21 Oct 2022 17:28:54 +0300 Subject: [PATCH] Add almost matching CScriptDistanceFog --- asm/MetroidPrime/CGameArea.s | 8 +-- asm/MetroidPrime/ScriptLoader.s | 6 +- .../ScriptObjects/CScriptDistanceFog.s | 20 +++--- configure.py | 2 +- include/MetroidPrime/CAreaFog.hpp | 24 ++++++- include/MetroidPrime/CGameArea.hpp | 17 ++++- .../ScriptObjects/CScriptDistanceFog.hpp | 31 +++++++++ .../ScriptObjects/CScriptDistanceFog.cpp | 68 +++++++++++++++++++ tools/metaforce_renames.sh | 2 + 9 files changed, 156 insertions(+), 22 deletions(-) create mode 100644 include/MetroidPrime/ScriptObjects/CScriptDistanceFog.hpp create mode 100644 src/MetroidPrime/ScriptObjects/CScriptDistanceFog.cpp diff --git a/asm/MetroidPrime/CGameArea.s b/asm/MetroidPrime/CGameArea.s index b961fba0..1b4a9618 100644 --- a/asm/MetroidPrime/CGameArea.s +++ b/asm/MetroidPrime/CGameArea.s @@ -520,16 +520,16 @@ SetWeaponWorldLighting__9CGameAreaFff: /* 8005E1E0 0005B140 D0 43 11 38 */ stfs f2, 0x1138(r3) /* 8005E1E4 0005B144 4E 80 00 20 */ blr -.global sub_8005e1e8 -sub_8005e1e8: +.global SetXRaySpeedAndTarget__9CGameAreaFff +SetXRaySpeedAndTarget__9CGameAreaFff: /* 8005E1E8 0005B148 80 83 01 2C */ lwz r4, 0x12c(r3) /* 8005E1EC 0005B14C D0 24 11 2C */ stfs f1, 0x112c(r4) /* 8005E1F0 0005B150 80 63 01 2C */ lwz r3, 0x12c(r3) /* 8005E1F4 0005B154 D0 43 11 30 */ stfs f2, 0x1130(r3) /* 8005E1F8 0005B158 4E 80 00 20 */ blr -.global sub_8005e1fc -sub_8005e1fc: +.global SetThermalSpeedAndTarget__9CGameAreaFff +SetThermalSpeedAndTarget__9CGameAreaFff: /* 8005E1FC 0005B15C 80 83 01 2C */ lwz r4, 0x12c(r3) /* 8005E200 0005B160 D0 24 11 20 */ stfs f1, 0x1120(r4) /* 8005E204 0005B164 80 63 01 2C */ lwz r3, 0x12c(r3) diff --git a/asm/MetroidPrime/ScriptLoader.s b/asm/MetroidPrime/ScriptLoader.s index 87049178..abf03294 100644 --- a/asm/MetroidPrime/ScriptLoader.s +++ b/asm/MetroidPrime/ScriptLoader.s @@ -1308,7 +1308,7 @@ lbl_800C62A4: /* 800C637C 000C32DC 38 A1 00 30 */ addi r5, r1, 0x30 /* 800C6380 000C32E0 39 41 00 28 */ addi r10, r1, 0x28 /* 800C6384 000C32E4 38 E0 00 00 */ li r7, 0 -/* 800C6388 000C32E8 48 08 6E D1 */ bl "__ct__18CScriptDistanceFogF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC11ERglFogModeRC6CColorRC9CVector2ff9CVector2fbbffff" +/* 800C6388 000C32E8 48 08 6E D1 */ bl "__ct__18CScriptDistanceFogF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfo11ERglFogModeRC6CColorRC9CVector2ffRC9CVector2fbbffff" /* 800C638C 000C32EC 7C 7D 1B 78 */ mr r29, r3 lbl_800C6390: /* 800C6390 000C32F0 38 61 00 30 */ addi r3, r1, 0x30 @@ -2482,7 +2482,7 @@ lbl_800C7300: /* 800C73D8 000C4338 38 A1 00 30 */ addi r5, r1, 0x30 /* 800C73DC 000C433C 39 41 00 28 */ addi r10, r1, 0x28 /* 800C73E0 000C4340 38 E0 00 00 */ li r7, 0 -/* 800C73E4 000C4344 48 08 5E 75 */ bl "__ct__18CScriptDistanceFogF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC11ERglFogModeRC6CColorRC9CVector2ff9CVector2fbbffff" +/* 800C73E4 000C4344 48 08 5E 75 */ bl "__ct__18CScriptDistanceFogF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfo11ERglFogModeRC6CColorRC9CVector2ffRC9CVector2fbbffff" /* 800C73E8 000C4348 7C 7D 1B 78 */ mr r29, r3 lbl_800C73EC: /* 800C73EC 000C434C 38 61 00 30 */ addi r3, r1, 0x30 @@ -13169,7 +13169,7 @@ lbl_800D1030: /* 800D10AC 000CE00C 39 01 00 18 */ addi r8, r1, 0x18 /* 800D10B0 000CE010 39 21 00 2C */ addi r9, r1, 0x2c /* 800D10B4 000CE014 39 41 00 1C */ addi r10, r1, 0x1c -/* 800D10B8 000CE018 48 07 C1 A1 */ bl "__ct__18CScriptDistanceFogF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC11ERglFogModeRC6CColorRC9CVector2ff9CVector2fbbffff" +/* 800D10B8 000CE018 48 07 C1 A1 */ bl "__ct__18CScriptDistanceFogF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfo11ERglFogModeRC6CColorRC9CVector2ffRC9CVector2fbbffff" /* 800D10BC 000CE01C 7C 7D 1B 78 */ mr r29, r3 lbl_800D10C0: /* 800D10C0 000CE020 38 61 00 34 */ addi r3, r1, 0x34 diff --git a/asm/MetroidPrime/ScriptObjects/CScriptDistanceFog.s b/asm/MetroidPrime/ScriptObjects/CScriptDistanceFog.s index b2b07dc3..30f1b030 100644 --- a/asm/MetroidPrime/ScriptObjects/CScriptDistanceFog.s +++ b/asm/MetroidPrime/ScriptObjects/CScriptDistanceFog.s @@ -3,8 +3,8 @@ .section .data .balign 8 -.global lbl_803E27B0 -lbl_803E27B0: +.global __vt__18CScriptDistanceFog +__vt__18CScriptDistanceFog: # ROM: 0x3DF7B0 .4byte 0 .4byte 0 @@ -112,7 +112,7 @@ lbl_8014D11C: /* 8014D150 0014A0B0 90 A1 00 10 */ stw r5, 0x10(r1) /* 8014D154 0014A0B4 7C 64 00 2E */ lwzx r3, r4, r0 /* 8014D158 0014A0B8 C0 5E 00 50 */ lfs f2, 0x50(r30) -/* 8014D15C 0014A0BC 4B F1 10 A1 */ bl sub_8005e1fc +/* 8014D15C 0014A0BC 4B F1 10 A1 */ bl SetThermalSpeedAndTarget__9CGameAreaFff lbl_8014D160: /* 8014D160 0014A0C0 C0 3E 00 5C */ lfs f1, 0x5c(r30) /* 8014D164 0014A0C4 C0 42 9D 20 */ lfs f2, lbl_805ABA40@sda21(r2) @@ -130,7 +130,7 @@ lbl_8014D160: /* 8014D194 0014A0F4 90 A1 00 0C */ stw r5, 0xc(r1) /* 8014D198 0014A0F8 7C 64 00 2E */ lwzx r3, r4, r0 /* 8014D19C 0014A0FC C0 5E 00 58 */ lfs f2, 0x58(r30) -/* 8014D1A0 0014A100 4B F1 10 49 */ bl sub_8005e1e8 +/* 8014D1A0 0014A100 4B F1 10 49 */ bl SetXRaySpeedAndTarget__9CGameAreaFff lbl_8014D1A4: /* 8014D1A4 0014A104 80 01 00 44 */ lwz r0, 0x44(r1) /* 8014D1A8 0014A108 83 E1 00 3C */ lwz r31, 0x3c(r1) @@ -167,9 +167,9 @@ __dt__18CScriptDistanceFogFv: /* 8014D20C 0014A16C 93 C1 00 08 */ stw r30, 8(r1) /* 8014D210 0014A170 7C 7E 1B 79 */ or. r30, r3, r3 /* 8014D214 0014A174 41 82 00 28 */ beq lbl_8014D23C -/* 8014D218 0014A178 3C A0 80 3E */ lis r5, lbl_803E27B0@ha +/* 8014D218 0014A178 3C A0 80 3E */ lis r5, __vt__18CScriptDistanceFog@ha /* 8014D21C 0014A17C 38 80 00 00 */ li r4, 0 -/* 8014D220 0014A180 38 05 27 B0 */ addi r0, r5, lbl_803E27B0@l +/* 8014D220 0014A180 38 05 27 B0 */ addi r0, r5, __vt__18CScriptDistanceFog@l /* 8014D224 0014A184 90 1E 00 00 */ stw r0, 0(r30) /* 8014D228 0014A188 4B F0 40 4D */ bl __dt__7CEntityFv /* 8014D22C 0014A18C 7F E0 07 35 */ extsh. r0, r31 @@ -185,8 +185,8 @@ lbl_8014D23C: /* 8014D250 0014A1B0 38 21 00 10 */ addi r1, r1, 0x10 /* 8014D254 0014A1B4 4E 80 00 20 */ blr -.global "__ct__18CScriptDistanceFogF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC11ERglFogModeRC6CColorRC9CVector2ff9CVector2fbbffff" -"__ct__18CScriptDistanceFogF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC11ERglFogModeRC6CColorRC9CVector2ff9CVector2fbbffff": +.global "__ct__18CScriptDistanceFogF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfo11ERglFogModeRC6CColorRC9CVector2ffRC9CVector2fbbffff" +"__ct__18CScriptDistanceFogF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfo11ERglFogModeRC6CColorRC9CVector2ffRC9CVector2fbbffff": /* 8014D258 0014A1B8 94 21 FF 70 */ stwu r1, -0x90(r1) /* 8014D25C 0014A1BC 7C 08 02 A6 */ mflr r0 /* 8014D260 0014A1C0 90 01 00 94 */ stw r0, 0x94(r1) @@ -221,9 +221,9 @@ lbl_8014D23C: /* 8014D2D4 0014A234 7D 67 5B 78 */ mr r7, r11 /* 8014D2D8 0014A238 38 81 00 08 */ addi r4, r1, 8 /* 8014D2DC 0014A23C 4B F0 40 49 */ bl "__ct__7CEntityF9TUniqueIdRC11CEntityInfobRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>" -/* 8014D2E0 0014A240 3C 60 80 3E */ lis r3, lbl_803E27B0@ha +/* 8014D2E0 0014A240 3C 60 80 3E */ lis r3, __vt__18CScriptDistanceFog@ha /* 8014D2E4 0014A244 C0 22 9D 20 */ lfs f1, lbl_805ABA40@sda21(r2) -/* 8014D2E8 0014A248 38 03 27 B0 */ addi r0, r3, lbl_803E27B0@l +/* 8014D2E8 0014A248 38 03 27 B0 */ addi r0, r3, __vt__18CScriptDistanceFog@l /* 8014D2EC 0014A24C 38 61 00 0C */ addi r3, r1, 0xc /* 8014D2F0 0014A250 90 19 00 00 */ stw r0, 0(r25) /* 8014D2F4 0014A254 FC 40 08 90 */ fmr f2, f1 diff --git a/configure.py b/configure.py index 5b343ecf..f3d091b5 100755 --- a/configure.py +++ b/configure.py @@ -212,7 +212,7 @@ LIBS = [ "MetroidPrime/ScriptObjects/CScriptSpiderBallAttractionSurface", "MetroidPrime/BodyState/CBSScripted", "MetroidPrime/Enemies/CPuddleToadGamma", - "MetroidPrime/ScriptObjects/CScriptDistanceFog", + ["MetroidPrime/ScriptObjects/CScriptDistanceFog", False], "MetroidPrime/BodyState/CBSProjectileAttack", "MetroidPrime/Weapons/CPowerBomb", "MetroidPrime/Enemies/CMetaree", diff --git a/include/MetroidPrime/CAreaFog.hpp b/include/MetroidPrime/CAreaFog.hpp index 6c1dbb23..4f138403 100644 --- a/include/MetroidPrime/CAreaFog.hpp +++ b/include/MetroidPrime/CAreaFog.hpp @@ -7,7 +7,19 @@ #include "Kyoto/Math/CVector2f.hpp" enum ERglFogMode { - // TODO + kRFM_None = GX_FOG_NONE, + + kRFM_PerspLin = GX_FOG_PERSP_LIN, + kRFM_PerspExp = GX_FOG_PERSP_EXP, + kRFM_PerspExp2 = GX_FOG_ORTHO_EXP2, + kRFM_PerspRevExp = GX_FOG_PERSP_REVEXP, + kRFM_PerspRevExp2 = GX_FOG_PERSP_REVEXP2, + + kRFM_OrthoLin = GX_FOG_ORTHO_LIN, + kRFM_OrthoExp = GX_FOG_ORTHO_EXP, + kRFM_OrthoExp2 = GX_FOG_ORTHO_EXP2, + kRFM_OrthoRevExp = GX_FOG_ORTHO_REVEXP, + kRFM_OrthoRevExp2 = GX_FOG_ORTHO_REVEXP2, }; class CAreaFog { @@ -23,6 +35,16 @@ private: unkptr x2c_; unkptr x30_; float x34_colorDelta; + +public: + void SetCurrent() const; + void Update(float dt); + void RollFogOut(float rangeDelta, float colorDelta, const CColor& color); + void FadeFog(ERglFogMode, const CColor& color, const CVector2f& vec1, float, + const CVector2f& vec2); + void SetFogExplicit(ERglFogMode mode, const CColor& color, const CVector2f& range); + bool IsFogDisabled() const; + void DisableFog(); }; CHECK_SIZEOF(CAreaFog, 0x38) diff --git a/include/MetroidPrime/CGameArea.hpp b/include/MetroidPrime/CGameArea.hpp index 888f8171..49c0bd4a 100644 --- a/include/MetroidPrime/CGameArea.hpp +++ b/include/MetroidPrime/CGameArea.hpp @@ -32,6 +32,7 @@ class Dock; class CToken; class IDvdRequest; class CScriptAreaAttributes; +class CAreaFog; class CGameArea : public IGameArea { public: @@ -48,6 +49,10 @@ public: bool IsLoaded() const { return xf0_24_postConstructed; } bool IsActive() const { return xf0_25_active; } + void SetXRaySpeedAndTarget(float speed, float target); + void SetThermalSpeedAndTarget(float speed, float target); + void SetWeaponWorldLighting(float speed, float target); + void SetAreaAttributes(const CScriptAreaAttributes* areaAttributes); bool TryTakingOutOfARAM(); @@ -85,17 +90,23 @@ public: enum EOcclusionState { kOS_Occluded, kOS_Visible }; struct CPostConstructed { - uchar x0_pad[0x10dc]; + uchar x0_pad[0x10c4]; + rstl::single_ptr x10c4_areaFog; + rstl::optional_object x10c8_sclyBuf; // was rstl::optional_object + u32 x10d0_sclySize; + const u8* x10d4_firstMatPtr; + const CScriptAreaAttributes* x10d8_areaAttributes; EOcclusionState x10dc_occlusionState; }; + const CAreaFog* GetAreaFog() const { return x12c_postConstructed->x10c4_areaFog.get(); } + CAreaFog* AreaFog() { return x12c_postConstructed->x10c4_areaFog.get(); } EOcclusionState GetOcclusionState() const { return x12c_postConstructed->x10dc_occlusionState; } + private: uchar x110_pad[0x1c]; rstl::single_ptr x12c_postConstructed; - - }; #endif // _CGAMEAREA diff --git a/include/MetroidPrime/ScriptObjects/CScriptDistanceFog.hpp b/include/MetroidPrime/ScriptObjects/CScriptDistanceFog.hpp new file mode 100644 index 00000000..b07618ee --- /dev/null +++ b/include/MetroidPrime/ScriptObjects/CScriptDistanceFog.hpp @@ -0,0 +1,31 @@ +#ifndef _CSCRIPTDISTANCEFOG +#define _CSCRIPTDISTANCEFOG + +#include "MetroidPrime/CEntity.hpp" + +#include "MetroidPrime/CAreaFog.hpp" + +class CScriptDistanceFog : public CEntity { + ERglFogMode x34_mode; + CColor x38_color; + CVector2f x3c_range; + float x44_colorDelta; + CVector2f x48_rangeDelta; + float x50_thermalTarget; + float x54_thermalSpeed; + float x58_xrayTarget; + float x5c_xraySpeed; + bool x60_explicit; + bool x61_nonZero; + +public: + CScriptDistanceFog(TUniqueId, const rstl::string&, const CEntityInfo&, ERglFogMode, const CColor&, + const CVector2f&, float, const CVector2f&, bool, bool, float, float, float, + float); + ~CScriptDistanceFog(); + + void Accept(IVisitor& visitor) override; + void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CStateManager& stateMgr) override; +}; + +#endif // _CSCRIPTDISTANCEFOG diff --git a/src/MetroidPrime/ScriptObjects/CScriptDistanceFog.cpp b/src/MetroidPrime/ScriptObjects/CScriptDistanceFog.cpp new file mode 100644 index 00000000..c2f8ec46 --- /dev/null +++ b/src/MetroidPrime/ScriptObjects/CScriptDistanceFog.cpp @@ -0,0 +1,68 @@ +#include "MetroidPrime/ScriptObjects/CScriptDistanceFog.hpp" + +#include "MetroidPrime/CAreaFog.hpp" +#include "MetroidPrime/CGameArea.hpp" +#include "MetroidPrime/CStateManager.hpp" +#include "MetroidPrime/CWorld.hpp" + +#include "Kyoto/Math/CloseEnough.hpp" + +CScriptDistanceFog::CScriptDistanceFog(TUniqueId uid, const rstl::string& name, + const CEntityInfo& info, ERglFogMode mode, + const CColor& color, const CVector2f& range, + float colorDelta, const CVector2f& rangeDelta, bool expl, + bool active, float thermalTarget, float thermalSpeed, + float xrayTarget, float xraySpeed) +: CEntity(uid, info, active, name) +, x34_mode(mode) +, x38_color(color) +, x3c_range(range) +, x44_colorDelta(colorDelta) +, x48_rangeDelta(rangeDelta) +, x50_thermalTarget(thermalTarget) +, x54_thermalSpeed(thermalSpeed) +, x58_xrayTarget(xrayTarget) +, x5c_xraySpeed(xraySpeed) +, x60_explicit(expl) +, x61_nonZero(!close_enough(rangeDelta, CVector2f(0.f, 0.f)) || !close_enough(colorDelta, 0.f)) {} + +CScriptDistanceFog::~CScriptDistanceFog() {} + +void CScriptDistanceFog::Accept(IVisitor& visitor) { visitor.Visit(*this); } + +void CScriptDistanceFog::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, + CStateManager& stateMgr) { + CEntity::AcceptScriptMsg(msg, objId, stateMgr); + + if (GetAreaIdAlways() != kInvalidAreaId && GetActive()) { + switch (msg) { + case kSM_InitializedInArea: + if (x60_explicit) { + CAreaFog* fog = stateMgr.World()->Area(GetAreaIdAlways())->AreaFog(); + if (x34_mode == kRFM_None) { + fog->DisableFog(); + } else { + fog->SetFogExplicit(x34_mode, x38_color, x3c_range); + } + } + break; + case kSM_Action: + if (x61_nonZero) { + CAreaFog* fog = stateMgr.World()->Area(GetAreaIdAlways())->AreaFog(); + if (x34_mode != kRFM_None) { + fog->FadeFog(x34_mode, x38_color, x3c_range, x44_colorDelta, x48_rangeDelta); + } else { + fog->RollFogOut(x48_rangeDelta.GetX(), x44_colorDelta, x38_color); + } + } + + if (!close_enough(x54_thermalSpeed, 0.f)) { + stateMgr.World()->Area(GetAreaIdAlways())->SetThermalSpeedAndTarget(x54_thermalSpeed, x50_thermalTarget); + } + if (!close_enough(x5c_xraySpeed, 0.f)) { + stateMgr.World()->Area(GetAreaIdAlways())->SetXRaySpeedAndTarget(x5c_xraySpeed, x58_xrayTarget); + } + break; + } + } +} diff --git a/tools/metaforce_renames.sh b/tools/metaforce_renames.sh index 5fd0254e..226162a4 100644 --- a/tools/metaforce_renames.sh +++ b/tools/metaforce_renames.sh @@ -5,6 +5,8 @@ path=$1 sed -i "s/std::string_view/const rstl::string\&/g" "$path" sed -i "s/zeus::CTransform/CTransform4f/g" "$path" +sed -i "s/zeus::skZero2f/CVector2f(0.f, 0.f)/g" "$path" +sed -i "s/zeus::skZero3f/CVector3f::Zero()/g" "$path" sed -i "s/zeus::skPurple/CColor::Purple()/g" "$path" sed -i "s/zeus::skWhite/CColor::White()/g" "$path" sed -i "s/zeus:://g" "$path"