From feddcf83c002ba9262bd6ff2fc67cb1d43d3b565 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Wed, 9 Apr 2025 22:39:18 -0600 Subject: [PATCH] CMappableObject, CMapArea equivalent --- .gitignore | 1 + config/GM8E01_00/symbols.txt | 4 +- config/GM8E01_01/symbols.txt | 4 +- configure.py | 4 +- include/Kyoto/Basics/CBasics.hpp | 10 +- include/Kyoto/Math/CMatrix3f.hpp | 4 +- include/MetroidPrime/CMapArea.hpp | 12 +- include/MetroidPrime/CMapWorld.hpp | 5 +- include/MetroidPrime/CMapWorldInfo.hpp | 3 + include/MetroidPrime/CMappableObject.hpp | 15 +- .../MetroidPrime/Tweaks/CTweakAutoMapper.hpp | 7 - .../MetroidPrime/Tweaks/CTweakPlayerRes.hpp | 18 +- src/Kyoto/Math/CMatrix3f.cpp | 24 +- src/MetroidPrime/CMapArea.cpp | 72 +++-- src/MetroidPrime/CMappableObject.cpp | 281 ++++++++++++------ tools/metaforce_renames.py | 1 + 16 files changed, 286 insertions(+), 179 deletions(-) diff --git a/.gitignore b/.gitignore index 83345ae1..f56ab36d 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,7 @@ ctx.* # Generated configs objdiff.json compile_commands.json +report*.json # Miscellaneous /*.txt diff --git a/config/GM8E01_00/symbols.txt b/config/GM8E01_00/symbols.txt index d1c38c42..548532f8 100644 --- a/config/GM8E01_00/symbols.txt +++ b/config/GM8E01_00/symbols.txt @@ -1912,8 +1912,8 @@ FMapAreaFactory__FRC10SObjectTagR12CInputStreamRC15CVParamTransfer = .text:0x800 __dt__35TObjOwnerDerivedFromIObj<8CMapArea>Fv = .text:0x800802A4; // type:function size:0x90 scope:global GetIObjObjectFor__17TToken<8CMapArea>FRCQ24rstl19auto_ptr<8CMapArea> = .text:0x80080334; // type:function size:0x2C scope:global GetNewDerivedObject__35TObjOwnerDerivedFromIObj<8CMapArea>FRCQ24rstl19auto_ptr<8CMapArea> = .text:0x80080360; // type:function size:0x9C scope:global -GetAreaPostTranslate__8CMapAreaFRC6IWorld7TAreaId = .text:0x800803FC; // type:function size:0x6C scope:global -GetAreaPostTransform__8CMapAreaFRC6CWorld7TAreaId = .text:0x80080468; // type:function size:0x108 scope:global +GetAreaPostTranslate__8CMapAreaFRC6IWorldi = .text:0x800803FC; // type:function size:0x6C scope:global +GetAreaPostTransform__8CMapAreaFRC6IWorldi = .text:0x80080468; // type:function size:0x108 scope:global SetupGXMaterial__Q28CMapArea15CMapAreaSurfaceFv = .text:0x80080570; // type:function size:0x104 scope:global Draw__Q28CMapArea15CMapAreaSurfaceCFPC9CVector3fRC6CColorRC6CColorf = .text:0x80080674; // type:function size:0x384 scope:global PostConstruct__Q28CMapArea15CMapAreaSurfaceFPCv = .text:0x800809F8; // type:function size:0x304 scope:global diff --git a/config/GM8E01_01/symbols.txt b/config/GM8E01_01/symbols.txt index 89f068be..d04263fb 100644 --- a/config/GM8E01_01/symbols.txt +++ b/config/GM8E01_01/symbols.txt @@ -1912,8 +1912,8 @@ FMapAreaFactory__FRC10SObjectTagR12CInputStreamRC15CVParamTransfer = .text:0x800 __dt__35TObjOwnerDerivedFromIObj<8CMapArea>Fv = .text:0x80080320; // type:function size:0x90 scope:global GetIObjObjectFor__17TToken<8CMapArea>FRCQ24rstl19auto_ptr<8CMapArea> = .text:0x800803B0; // type:function size:0x2C scope:global GetNewDerivedObject__35TObjOwnerDerivedFromIObj<8CMapArea>FRCQ24rstl19auto_ptr<8CMapArea> = .text:0x800803DC; // type:function size:0x9C scope:global -GetAreaPostTranslate__8CMapAreaFRC6IWorld7TAreaId = .text:0x80080478; // type:function size:0x6C scope:global -GetAreaPostTransform__8CMapAreaFRC6CWorld7TAreaId = .text:0x800804E4; // type:function size:0x108 scope:global +GetAreaPostTranslate__8CMapAreaFRC6IWorldi = .text:0x80080478; // type:function size:0x6C scope:global +GetAreaPostTransform__8CMapAreaFRC6IWorldi = .text:0x800804E4; // type:function size:0x108 scope:global SetupGXMaterial__Q28CMapArea15CMapAreaSurfaceFv = .text:0x800805EC; // type:function size:0x104 scope:global Draw__Q28CMapArea15CMapAreaSurfaceCFPC9CVector3fRC6CColorRC6CColorf = .text:0x800806F0; // type:function size:0x384 scope:global PostConstruct__Q28CMapArea15CMapAreaSurfaceFPCv = .text:0x80080A74; // type:function size:0x304 scope:global diff --git a/configure.py b/configure.py index 5c3349e3..44dba4fb 100755 --- a/configure.py +++ b/configure.py @@ -446,7 +446,7 @@ config.libs = [ Object(NonMatching, "MetroidPrime/Enemies/CPatterned.cpp"), Object(NonMatching, "MetroidPrime/ScriptObjects/CScriptDoor.cpp"), Object(NonMatching, "MetroidPrime/Enemies/CStateMachine.cpp"), - Object(NonMatching, "MetroidPrime/CMapArea.cpp"), + Object(Equivalent, "MetroidPrime/CMapArea.cpp"), Object(NonMatching, "MetroidPrime/Cameras/CBallCamera.cpp"), Object(NonMatching, "MetroidPrime/ScriptObjects/CScriptEffect.cpp"), Object(NonMatching, "MetroidPrime/Weapons/CBomb.cpp"), @@ -493,7 +493,7 @@ config.libs = [ Object(NonMatching, "MetroidPrime/Enemies/CBeetle.cpp"), Object(MatchingFor("GM8E01_00", "GM8E01_01"), "MetroidPrime/HUD/CHUDMemoParms.cpp"), Object(MatchingFor("GM8E01_00", "GM8E01_01"), "MetroidPrime/ScriptObjects/CScriptHUDMemo.cpp"), - Object(NonMatching, "MetroidPrime/CMappableObject.cpp"), + Object(Equivalent, "MetroidPrime/CMappableObject.cpp"), Object(NonMatching, "MetroidPrime/Player/CPlayerCameraBob.cpp"), Object( MatchingFor("GM8E01_00", "GM8E01_01"), "MetroidPrime/ScriptObjects/CScriptCameraFilterKeyframe.cpp" diff --git a/include/Kyoto/Basics/CBasics.hpp b/include/Kyoto/Basics/CBasics.hpp index 23ea9f90..47f0719b 100644 --- a/include/Kyoto/Basics/CBasics.hpp +++ b/include/Kyoto/Basics/CBasics.hpp @@ -6,13 +6,19 @@ namespace CBasics { bool Init(); char* Stringize(const char* fmt, ...); -inline uint SwapBytes(uint x) { +inline const int SwapBytes(int x) { #if 0 x = ((x << 24) | ((x << 8) & 0x00FF0000) | ((x >> 8) & 0x0000FF00) | (x >> 24)); #endif return x; } -inline float SwapBytes(float x) { +inline const uint SwapBytes(uint x) { +#if 0 + x = ((x << 24) | ((x << 8) & 0x00FF0000) | ((x >> 8) & 0x0000FF00) | (x >> 24)); +#endif + return x; +} +inline const float SwapBytes(float x) { union { float f; uint u; diff --git a/include/Kyoto/Math/CMatrix3f.hpp b/include/Kyoto/Math/CMatrix3f.hpp index 24fe3128..8b928ce4 100644 --- a/include/Kyoto/Math/CMatrix3f.hpp +++ b/include/Kyoto/Math/CMatrix3f.hpp @@ -32,8 +32,8 @@ public: , m1(xf.GetRow(kDY)) , m2(xf.GetRow(kDZ)) {}*/ - void RotateY(const CRelAngle& angle); - void RotateZ(const CRelAngle& angle); + static CMatrix3f RotateY(const CRelAngle& angle); + static CMatrix3f RotateZ(const CRelAngle& angle); const CMatrix3f& operator=(const CMatrix3f& other); const CVector3f operator*(const CVector3f&) const; const CMatrix3f operator*(const CMatrix3f&) const; diff --git a/include/MetroidPrime/CMapArea.hpp b/include/MetroidPrime/CMapArea.hpp index 0a7ae73f..c451687b 100644 --- a/include/MetroidPrime/CMapArea.hpp +++ b/include/MetroidPrime/CMapArea.hpp @@ -11,9 +11,7 @@ #include "rstl/single_ptr.hpp" #include "rstl/vector.hpp" - class IWorld; -class CWorld; class CMapArea { public: @@ -25,13 +23,11 @@ public: const int* x1c_outlineOffset; public: - explicit CMapAreaSurface(const void* surfBuf); - void PostConstruct(const void* buf); void Draw(const CVector3f* verts, const CColor& surfColor, const CColor& lineColor, float lineWidth) const; - void SetupGXMaterial(); + static void SetupGXMaterial(); const CVector3f& GetNormal() const { return x0_normal; } const CVector3f& GetCenterPosition() const { return xc_centroid; } @@ -44,8 +40,8 @@ public: void PostConstruct(); bool GetIsVisibleToAutoMapper(bool worldVis, bool areaVis) const; CVector3f GetAreaCenterPoint() const; - CTransform4f GetAreaPostTransform(const CWorld&, TAreaId); - const CVector3f& GetAreaPostTranslate(const IWorld&, TAreaId); + CTransform4f GetAreaPostTransform(const IWorld&, int); + static const CVector3f& GetAreaPostTranslate(const IWorld&, int); private: uint x0_magic; @@ -60,7 +56,7 @@ private: CMappableObject* x38_moStart; CVector3f* x3c_vertexStart; CMapAreaSurface* x40_surfaceStart; - rstl::single_ptr< u8 > x44_buf; + rstl::single_ptr< uchar > x44_buf; static int gUsedMemory; }; diff --git a/include/MetroidPrime/CMapWorld.hpp b/include/MetroidPrime/CMapWorld.hpp index 4ed898de..984e4d99 100644 --- a/include/MetroidPrime/CMapWorld.hpp +++ b/include/MetroidPrime/CMapWorld.hpp @@ -1,9 +1,12 @@ #ifndef _CMAPWORLD #define _CMAPWORLD -#include "Kyoto/Graphics/CColor.hpp" #include "MetroidPrime/CMapArea.hpp" +#include "Kyoto/Graphics/CColor.hpp" + +#include "rstl/reserved_vector.hpp" + class CStateManager; class CMapWorld { diff --git a/include/MetroidPrime/CMapWorldInfo.hpp b/include/MetroidPrime/CMapWorldInfo.hpp index ef4989f7..15df4550 100644 --- a/include/MetroidPrime/CMapWorldInfo.hpp +++ b/include/MetroidPrime/CMapWorldInfo.hpp @@ -1,8 +1,11 @@ #ifndef _CMAPWORLDINFO #define _CMAPWORLDINFO +#include "MetroidPrime/TGameTypes.hpp" + class CMapWorldInfo { public: + bool IsAreaVisible(TAreaId areaId) const; bool IsDoorVisited(TEditorId eid) const; }; diff --git a/include/MetroidPrime/CMappableObject.hpp b/include/MetroidPrime/CMappableObject.hpp index aa73473c..3721a99c 100644 --- a/include/MetroidPrime/CMappableObject.hpp +++ b/include/MetroidPrime/CMappableObject.hpp @@ -8,6 +8,8 @@ #include "rstl/pair.hpp" +#include "CMapWorldInfo.hpp" + class CTweakAutoMapper; class CMapWorldInfo; @@ -45,14 +47,23 @@ public: void PostConstruct(const void*); rstl::pair< CColor, CColor > GetDoorColors(int idx, const CMapWorldInfo&, float alpha) const; - void Draw(int, const CMapWorldInfo&, float, bool) const; + void Draw(int curAreaId, const CMapWorldInfo& mwInfo, float alpha, bool needsVtxLoad) const; + void DrawDoorSurface(int curAreaId, const CMapWorldInfo& mwInfo, float alpha, int surfaceIdx, + bool needsVtxLoad) const; + CVector3f BuildSurfaceCenterPoint(int surfaceIdx) const; + bool GetIsVisibleToAutoMapper(bool worldVis, const CMapWorldInfo& mwInfo) const; + CTransform4f AdjustTransformForType() const; + EMappableObjectType GetType() const { return x0_type; } + TEditorId GetObjId() const { return x8_objId; } + const CTransform4f& GetTransform() const { return x10_transform; } static bool IsDoorType(EMappableObjectType type) { return type >= kMOT_BlueDoor && type <= kMOT_PlasmaDoorFloor2; } static void ReadAutomapperTweaks(const CTweakAutoMapper&); + private: EMappableObjectType x0_type; EVisMode x4_visibilityMode; @@ -62,8 +73,6 @@ private: uchar x40_pad[0x10]; CTransform4f AdjustTransformForType(); - - static CVector3f skDoorVerts[8]; }; CHECK_SIZEOF(CMappableObject, 0x50) diff --git a/include/MetroidPrime/Tweaks/CTweakAutoMapper.hpp b/include/MetroidPrime/Tweaks/CTweakAutoMapper.hpp index 3342009f..a296c518 100644 --- a/include/MetroidPrime/Tweaks/CTweakAutoMapper.hpp +++ b/include/MetroidPrime/Tweaks/CTweakAutoMapper.hpp @@ -16,13 +16,6 @@ public: ~CTweakAutoMapper(); CTweakAutoMapper(CInputStream&); - const CColor& GetDoorColor(int idx) const { return x100_doorColors[idx]; } - const CColor& GetOpenDoorColor() const { return x11c_openDoorColor; } - const CVector3f& GetDoorCenter() const { - return CVector3f(xa4_doorCenterA, xa8_doorCenterB, xac_doorCenterC); - } - -private: bool x4_24_showOneMiniMapArea : 1; bool x4_25_ : 1; bool x4_26_scaleMoveSpeedWithCamDist : 1; diff --git a/include/MetroidPrime/Tweaks/CTweakPlayerRes.hpp b/include/MetroidPrime/Tweaks/CTweakPlayerRes.hpp index a6dc001c..17864607 100644 --- a/include/MetroidPrime/Tweaks/CTweakPlayerRes.hpp +++ b/include/MetroidPrime/Tweaks/CTweakPlayerRes.hpp @@ -5,21 +5,23 @@ #include "MetroidPrime/Tweaks/ITweakObject.hpp" #include "Kyoto/SObjectTag.hpp" +#include "Kyoto/TOneStatic.hpp" +#include "types.h" struct CTweakPlayerRes : public ITweakObject, public TOneStatic< CTweakPlayerRes > { public: - /* - CAssetId x4_saveStationIcon; - CAssetId x8_missileStationIcon; - CAssetId xc_elevatorIcon; - CAssetId x10_minesBreakFirstTopIcon; - CAssetId x14_minesBreakFirstBottomIcon; - */ - char cls[0xf0]; + CAssetId x4_saveStationIcon; + CAssetId x8_missileStationIcon; + CAssetId xc_elevatorIcon; + CAssetId x10_minesBreakFirstTopIcon; + CAssetId x14_minesBreakFirstBottomIcon; + char cls[0xdc]; + CTweakPlayerRes(CInputStream& in); CAssetId GetBallTransitionBeamResId(CPlayerState::EBeamId id) const; }; +CHECK_SIZEOF(CTweakPlayerRes, 0xf4); extern CTweakPlayerRes* gpTweakPlayerRes; diff --git a/src/Kyoto/Math/CMatrix3f.cpp b/src/Kyoto/Math/CMatrix3f.cpp index e7db293f..e9afbfa3 100644 --- a/src/Kyoto/Math/CMatrix3f.cpp +++ b/src/Kyoto/Math/CMatrix3f.cpp @@ -41,32 +41,16 @@ CMatrix3f::CMatrix3f(CInputStream& in) { m22 = in.ReadFloat(); } -void CMatrix3f::RotateY(const CRelAngle& angle) { +CMatrix3f CMatrix3f::RotateY(const CRelAngle& angle) { const float dVar1 = sin(angle.AsRadians()); const float dVar2 = cos(angle.AsRadians()); - m00 = dVar2; - m01 = 0.f; - m02 = dVar1; - m10 = 0.f; - m11 = 1.f; - m12 = 0.f; - m20 = -dVar1; - m21 = 0.f; - m22 = dVar2; + return CMatrix3f(dVar2, 0.f, dVar1, 0.f, 1.f, 0.f, -dVar1, 0.f, dVar2); } -void CMatrix3f::RotateZ(const CRelAngle& angle) { +CMatrix3f CMatrix3f::RotateZ(const CRelAngle& angle) { const float dVar1 = sin(angle.AsRadians()); const float dVar2 = cos(angle.AsRadians()); - m00 = dVar2; - m01 = -dVar1; - m02 = 0.f; - m10 = dVar1; - m11 = dVar2; - m12 = 0.f; - m20 = 0.f; - m21 = 0.f; - m22 = 1.f; + return CMatrix3f(dVar2, -dVar1, 0.f, dVar1, dVar2, 0.f, 0.f, 0.f, 1.f); } CMatrix3f CMatrix3f::Orthonormalized() const { diff --git a/src/MetroidPrime/CMapArea.cpp b/src/MetroidPrime/CMapArea.cpp index b60b800a..6d6e6039 100644 --- a/src/MetroidPrime/CMapArea.cpp +++ b/src/MetroidPrime/CMapArea.cpp @@ -1,5 +1,6 @@ #include "MetroidPrime/CMapArea.hpp" +#include "MetroidPrime/CMappableObject.hpp" #include "MetroidPrime/CWorld.hpp" #include "MetroidPrime/Tweaks/CTweakAutoMapper.hpp" @@ -8,12 +9,13 @@ #include "Kyoto/CResFactory.hpp" #include "Kyoto/Graphics/CGX.hpp" #include "Kyoto/Graphics/CGraphics.hpp" +#include "Kyoto/Math/CVector3f.hpp" #include "Kyoto/Streams/CInputStream.hpp" -#include "Kyoto/Streams/CMemoryInStream.hpp" -#include "dolphin/os.h" -#include "limits.h" -#include "stdint.h" +#include +#include + +#include static const CVector3f MinesPostTransforms[3] = { CVector3f(0.f, 0.f, 200.f), @@ -72,13 +74,13 @@ CMapArea::CMapArea(CInputStream& in, uint size) : x0_magic(in.ReadLong()) , x4_version(in.ReadLong()) , x8_(in.ReadLong()) -, xc_visibilityMode(EVisMode(in.ReadLong())) +, xc_visibilityMode(static_cast(in.ReadLong())) , x10_box(in) , x28_mappableObjCount(in.ReadLong()) , x2c_vertexCount(in.ReadLong()) -, x30_surfaceCount(in.ReadLong()) -, x34_size(size - 52) { - x44_buf = rs_new u8[x34_size]; +, x30_surfaceCount(in.ReadLong()) { + x34_size = size - 52; + x44_buf = rs_new uchar[x34_size]; in.Get(x44_buf.get(), x34_size); PostConstruct(); @@ -92,16 +94,17 @@ CMapArea::~CMapArea() { } void CMapArea::PostConstruct() { - x38_moStart = (CMappableObject*)(x44_buf.get()); - void* vertexStart = x38_moStart + x28_mappableObjCount; - x3c_vertexStart = (CVector3f*)(vertexStart); - x40_surfaceStart = (CMapAreaSurface*)((CVector3f*)(vertexStart) + x2c_vertexCount); + CMappableObject* moStart = x38_moStart = reinterpret_cast< CMappableObject* >(x44_buf.get()); + CVector3f* vertexStart = x3c_vertexStart = + reinterpret_cast< CVector3f* >(moStart + x28_mappableObjCount); + x40_surfaceStart = reinterpret_cast< CMapAreaSurface* >(vertexStart + x2c_vertexCount); for (int i = 0; i < x28_mappableObjCount; ++i) { x38_moStart[i].PostConstruct(x44_buf.get()); } + float* floatStart = reinterpret_cast< float* >(x3c_vertexStart); for (int i = 0; i < x2c_vertexCount * 3; ++i) { - // Somehow this empty loop generates a lot worse code than it should... + floatStart[i] = floatStart[i]; // no-op, stripped out, possible byteswapping? } for (int i = 0; i < x30_surfaceCount; ++i) { x40_surfaceStart[i].PostConstruct(x44_buf.get()); @@ -126,18 +129,24 @@ bool CMapArea::GetIsVisibleToAutoMapper(bool worldVis, bool areaVis) const { CVector3f CMapArea::GetAreaCenterPoint() const { return x10_box.GetCenterPoint(); } void CMapArea::CMapAreaSurface::PostConstruct(const void* buf) { - x18_surfOffset = (const int*)((const uchar*)buf + reinterpret_cast< uintptr_t >(x18_surfOffset)); - x1c_outlineOffset = - (const int*)((const uchar*)buf + reinterpret_cast< uintptr_t >(x1c_outlineOffset)); + x18_surfOffset = reinterpret_cast< const int* >(static_cast< const uchar* >(buf) + + reinterpret_cast< uintptr_t >(x18_surfOffset)); + x1c_outlineOffset = reinterpret_cast< const int* >( + static_cast< const uchar* >(buf) + reinterpret_cast< uintptr_t >(x1c_outlineOffset)); int numSurfaces = *x18_surfOffset; + const int* surfOffset = x18_surfOffset + 1; for (int i = 0; i < numSurfaces; ++i) { - // Nothing? + int numVertices = *++surfOffset; + surfOffset++; // skip primitive type + surfOffset += ((numVertices + 3) & ~3) / 4; } int numOutlines = *x1c_outlineOffset; + const int* outlineOffset = x1c_outlineOffset + 1; for (int i = 0; i < numOutlines; ++i) { - // Nothing? + int numVertices = *outlineOffset++; + outlineOffset += ((numVertices + 3) & ~3) / 4; } } @@ -159,10 +168,10 @@ void CMapArea::CMapAreaSurface::Draw(const CVector3f* verts, const CColor& surfC CGX::SetTevKColor(GX_KCOLOR0, surfColor.GetGXColor()); const int* surface = &x18_surfOffset[1]; for (int i = 0; i < numSurfaces; ++i) { - GXPrimitive primType = GXPrimitive(*surface++); + GXPrimitive primType = static_cast< GXPrimitive >(*surface++); int numVertices = *surface++; - const u8* data = reinterpret_cast< const u8* >(surface); - surface += (numVertices + 3) / 4; + const uchar* data = reinterpret_cast< const uchar* >(surface); + surface += ((numVertices + 3) & ~3) / 4; CGX::Begin(primType, GX_VTXFMT0, numVertices); for (int v = 0; v < numVertices; ++v) { @@ -172,20 +181,20 @@ void CMapArea::CMapAreaSurface::Draw(const CVector3f* verts, const CColor& surfC } } if (hasLineAlpha) { - bool thickLine = 1.0f < lineWidth; - for (int j = 0; j < 1 + !!thickLine; ++j) { + bool thickLine = lineWidth > 1.f; + for (int j = 0; j < (thickLine ? 1 : 0) + 1; ++j) { const int* outline = &x1c_outlineOffset[1]; if (thickLine) { - CGraphics::SetLineWidth(lineWidth - j, ERglTexOffset(5)); + CGraphics::SetLineWidth(lineWidth - j, kTO_One); } CGX::SetTevKColor(GX_KCOLOR0, lineColor.WithAlphaModulatedBy(thickLine ? 0.5f : 1.0f).GetGXColor()); for (int i = 0; i < numOutlines; ++i) { int numVertices = *outline++; - const u8* data = reinterpret_cast< const u8* >(outline); - outline += (numVertices + 3) / 4; + const uchar* data = reinterpret_cast< const uchar* >(outline); + outline += ((numVertices + 3) & ~3) / 4; CGX::Begin(GX_LINESTRIP, GX_VTXFMT0, numVertices); for (int v = 0; v < numVertices; ++v) { @@ -216,21 +225,20 @@ void CMapArea::CMapAreaSurface::SetupGXMaterial() { CGX::SetTevKAlphaSel(GX_TEVSTAGE0, GX_TEV_KASEL_K0_A); } -CTransform4f CMapArea::GetAreaPostTransform(const CWorld& world, TAreaId aid) { +CTransform4f CMapArea::GetAreaPostTransform(const IWorld& world, int aid) { if (world.IGetWorldAssetId() == 0xB1AC4D65) // Phazon Mines { - const CTransform4f& areaXf = world.IGetAreaAlways(aid)->IGetTM(); - const CVector3f& postVec = MinesPostTransforms[MinesPostTransformIndices[aid.value]]; - return CTransform4f::Translate(postVec) * areaXf; + return CTransform4f::Translate(MinesPostTransforms[MinesPostTransformIndices[aid]]) * + world.IGetAreaAlways(aid)->IGetTM(); } else { return world.IGetAreaAlways(aid)->IGetTM(); } } -const CVector3f& CMapArea::GetAreaPostTranslate(const IWorld& world, TAreaId aid) { +const CVector3f& CMapArea::GetAreaPostTranslate(const IWorld& world, int aid) { if (world.IGetWorldAssetId() == 0xB1AC4D65) // Phazon Mines { - return MinesPostTransforms[MinesPostTransformIndices[aid.Value()]]; + return MinesPostTransforms[MinesPostTransformIndices[aid]]; } else { return CVector3f::Zero(); } diff --git a/src/MetroidPrime/CMappableObject.cpp b/src/MetroidPrime/CMappableObject.cpp index 8e3d014c..e92c500c 100644 --- a/src/MetroidPrime/CMappableObject.cpp +++ b/src/MetroidPrime/CMappableObject.cpp @@ -1,74 +1,75 @@ #include "MetroidPrime/CMappableObject.hpp" +#include "Kyoto/Basics/CBasics.hpp" #include "MetroidPrime/CMapWorldInfo.hpp" #include "MetroidPrime/Tweaks/CTweakAutoMapper.hpp" #include "MetroidPrime/Tweaks/CTweakPlayerRes.hpp" #include "Kyoto/CSimplePool.hpp" +#include "Kyoto/Graphics/CColor.hpp" #include "Kyoto/Graphics/CGX.hpp" #include "Kyoto/Graphics/CGraphics.hpp" #include "Kyoto/Graphics/CTexture.hpp" +#include "Kyoto/Math/CMatrix3f.hpp" +#include "Kyoto/Math/CRelAngle.hpp" +#include "Kyoto/Math/CTransform4f.hpp" +#include "Kyoto/Math/CVector3f.hpp" #include "Kyoto/SObjectTag.hpp" #include "Kyoto/TToken.hpp" +#include "dolphin/gx/GXEnum.h" + #include "rstl/math.hpp" struct SDrawData { - float x0_; - float x4_; - float x8_; + float x0_x; + float x4_y; + float x8_z; uchar xc_idxA; uchar xd_idxB; uchar xe_idxC; uchar xf_idxD; }; -static const SDrawData sDoorData[6] = { - {0.f, 0.f, -1, 6, 4, 2, 0}, - {0.f, 0.f, 1.f, 3, 1, 7, 5}, - {0.f, -1.f, 1.f, 1, 0, 5, 4}, - {0.f, 1.f, 1.f, 7, 6, 3, 2}, - {-1.f, 0.f, 0.f, 3, 2, 1, 0}, - {1.f, 0.f, 0.f, 5, 4, 7, 6}, + +static const SDrawData sDrawData[6] = { + // clang-format off + { 0.f, 0.f, -1.f, 6, 4, 2, 0}, + { 0.f, 0.f, 1.f, 3, 1, 7, 5}, + { 0.f, -1.f, 1.f, 1, 0, 5, 4}, + { 0.f, 1.f, 1.f, 7, 6, 3, 2}, + {-1.f, 0.f, 0.f, 3, 2, 1, 0}, + { 1.f, 0.f, 0.f, 5, 4, 7, 6}, + // clang-format on }; -CVector3f CMappableObject::skDoorVerts[8] = { +static CVector3f skDoorVerts[8] = { CVector3f::Zero(), CVector3f::Zero(), CVector3f::Zero(), CVector3f::Zero(), CVector3f::Zero(), CVector3f::Zero(), CVector3f::Zero(), CVector3f::Zero(), }; void CMappableObject::ReadAutomapperTweaks(const CTweakAutoMapper& tweaks) { - const CVector3f& center = tweaks.GetDoorCenter(); - - // skDoorVerts[0] = CVector3f(-center.GetZ(), -center.GetY(), 0.f); - // skDoorVerts[1] = CVector3f(-center.GetZ(), skDoorVerts[0].GetY(), center.GetX() * 2.0f); - // skDoorVerts[2] = CVector3f(-center.GetZ(), center.GetY(), 0.f); - // skDoorVerts[3] = CVector3f(-center.GetZ(), skDoorVerts[2].GetY(), skDoorVerts[1].GetZ()); - - // skDoorVerts[4] = CVector3f(-center.GetZ() * 0.2f, skDoorVerts[0].GetY(), 0.f); - // skDoorVerts[5] = CVector3f(skDoorVerts[4].GetX(), skDoorVerts[0].GetY(), - // skDoorVerts[1].GetZ()); skDoorVerts[6] = CVector3f(skDoorVerts[4].GetX(), - // skDoorVerts[2].GetY(), 0.f); skDoorVerts[7] = CVector3f(skDoorVerts[4].GetX(), - // skDoorVerts[2].GetY(), skDoorVerts[1].GetZ()); - - skDoorVerts[0] = CVector3f(-center.GetZ(), -center.GetY(), 0.f); - skDoorVerts[1] = CVector3f(-center.GetZ(), -center.GetY(), 2.f * center.GetX()); - skDoorVerts[2] = CVector3f(-center.GetZ(), center.GetY(), 0.f); - skDoorVerts[3] = CVector3f(-center.GetZ(), center.GetY(), 2.f * center.GetX()); - skDoorVerts[4] = CVector3f(.2f * -center.GetZ(), -center.GetY(), 0.f); - skDoorVerts[5] = CVector3f(.2f * -center.GetZ(), -center.GetY(), 2.f * center.GetX()); - skDoorVerts[6] = CVector3f(.2f * -center.GetZ(), center.GetY(), 0.f); - skDoorVerts[7] = CVector3f(.2f * -center.GetZ(), center.GetY(), 2.f * center.GetX()); + const float x = tweaks.xac_doorCenterC; + const float y = tweaks.xa8_doorCenterB; + const float z = tweaks.xa4_doorCenterA; + skDoorVerts[0] = CVector3f(-x, -y, 0.f); + skDoorVerts[1] = CVector3f(-x, -y, z * 2.f); + skDoorVerts[2] = CVector3f(-x, y, 0.f); + skDoorVerts[3] = CVector3f(-x, y, z * 2.f); + skDoorVerts[4] = CVector3f(-x * .2f, -y, 0.f); + skDoorVerts[5] = CVector3f(-x * .2f, -y, z * 2.f); + skDoorVerts[6] = CVector3f(-x * .2f, y, 0.f); + skDoorVerts[7] = CVector3f(-x * .2f, y, z * 2.f); } rstl::pair< CColor, CColor > CMappableObject::GetDoorColors(int curAreaId, const CMapWorldInfo& mwInfo, float alpha) const { - CColor firstColor(0xff00ffff); + CColor firstColor((uchar)0xff, 0x00, 0xff, 0xff); bool areaNumMatches = x8_objId.AreaNum() == curAreaId; bool doorVisited = mwInfo.IsDoorVisited(x8_objId); if (areaNumMatches) { if (doorVisited && x0_type == kMOT_ShieldDoor) { - firstColor = gpTweakAutoMapper->GetDoorColor(0); + firstColor = gpTweakAutoMapper->x100_doorColors[0]; } else { int colorIdx = 0; switch (x0_type) { @@ -96,25 +97,28 @@ CMappableObject::GetDoorColors(int curAreaId, const CMapWorldInfo& mwInfo, float default: break; } - firstColor = gpTweakAutoMapper->GetDoorColor(colorIdx); + firstColor = gpTweakAutoMapper->x100_doorColors[colorIdx]; } - } else if (doorVisited) { - firstColor = gpTweakAutoMapper->GetOpenDoorColor(); + firstColor = gpTweakAutoMapper->x11c_openDoorColor; } else { firstColor = CColor(0); } firstColor = firstColor.WithAlphaModulatedBy(alpha); - - float r = rstl::min_val(1.0f, firstColor.GetRed() * 1.4f); - float g = rstl::min_val(1.0f, firstColor.GetGreen() * 1.4f); - float b = rstl::min_val(1.0f, firstColor.GetBlue() * 1.4f); - float a = rstl::min_val(1.0f, firstColor.GetAlpha() * 1.4f); - return rstl::pair< CColor, CColor >(firstColor, CColor(r, g, b, a)); + const CColor secondColor(rstl::min_val(1.0f, firstColor.GetRed() * 0.5f), + rstl::min_val(1.0f, firstColor.GetGreen() * 0.5f), + rstl::min_val(1.0f, firstColor.GetBlue() * 0.5f), + rstl::min_val(1.0f, firstColor.GetAlpha() * 0.5f)); + return rstl::pair< CColor, CColor >(firstColor, secondColor); } -void CMappableObject::PostConstruct(const void*) { x10_transform = AdjustTransformForType(); } +void CMappableObject::PostConstruct(const void*) { + for (int i = 0; i < offsetof(CMappableObject, x40_pad) / sizeof(int); ++i) { + reinterpret_cast< int* >(this)[i] = CBasics::SwapBytes(reinterpret_cast< int* >(this)[i]); + } + x10_transform = AdjustTransformForType(); +} void CMappableObject::Draw(int curArea, const CMapWorldInfo& mwInfo, float alpha, bool needsVtxLoad) const { @@ -122,23 +126,23 @@ void CMappableObject::Draw(int curArea, const CMapWorldInfo& mwInfo, float alpha rstl::pair< CColor, CColor > colors = GetDoorColors(curArea, mwInfo, alpha); for (int i = 0; i < 6; ++i) { if (needsVtxLoad) { - CGX::SetArray(GX_VA_POS, skDoorVerts, '\f'); + CGX::SetArray(GX_VA_POS, skDoorVerts, sizeof(skDoorVerts[0])); } CGX::SetTevKColor(GX_KCOLOR0, colors.first.GetGXColor()); CGX::Begin(GX_TRIANGLESTRIP, GX_VTXFMT0, 4); - GXPosition1x8(sDoorData[i].xc_idxA); - GXPosition1x8(sDoorData[i].xd_idxB); - GXPosition1x8(sDoorData[i].xe_idxC); - GXPosition1x8(sDoorData[i].xf_idxD); + GXPosition1x8(sDrawData[i].xc_idxA); + GXPosition1x8(sDrawData[i].xd_idxB); + GXPosition1x8(sDrawData[i].xe_idxC); + GXPosition1x8(sDrawData[i].xf_idxD); CGX::End(); CGX::SetTevKColor(GX_KCOLOR0, colors.second.GetGXColor()); CGX::Begin(GX_LINESTRIP, GX_VTXFMT0, 5); - GXPosition1x8(sDoorData[i].xc_idxA); - GXPosition1x8(sDoorData[i].xd_idxB); - GXPosition1x8(sDoorData[i].xf_idxD); - GXPosition1x8(sDoorData[i].xe_idxC); - GXPosition1x8(sDoorData[i].xc_idxA); + GXPosition1x8(sDrawData[i].xc_idxA); + GXPosition1x8(sDrawData[i].xd_idxB); + GXPosition1x8(sDrawData[i].xf_idxD); + GXPosition1x8(sDrawData[i].xe_idxC); + GXPosition1x8(sDrawData[i].xc_idxA); CGX::End(); } return; @@ -146,43 +150,42 @@ void CMappableObject::Draw(int curArea, const CMapWorldInfo& mwInfo, float alpha CAssetId iconRes = kInvalidAssetId; CColor iconColor = CColor(0xffffffff); + switch (x0_type) { + case kMOT_DownArrowYellow: + iconColor = CColor((uchar)0xff, 0xff, 0x96, 0xff); + iconRes = gpTweakPlayerRes->x10_minesBreakFirstTopIcon; + break; + case kMOT_UpArrowYellow: + iconColor = CColor((uchar)0xff, 0xff, 0x96, 0xff); + iconRes = gpTweakPlayerRes->x14_minesBreakFirstBottomIcon; + break; + case kMOT_DownArrowGreen: + iconColor = CColor((uchar)0x64, 0xff, 0x96, 0xff); + iconRes = gpTweakPlayerRes->x10_minesBreakFirstTopIcon; + break; + case kMOT_UpArrowGreen: + iconColor = CColor((uchar)0x64, 0xff, 0x96, 0xff); + iconRes = gpTweakPlayerRes->x14_minesBreakFirstBottomIcon; + break; + case kMOT_DownArrowRed: + iconColor = CColor((uchar)0xff, 0x64, 0x96, 0xff); + iconRes = gpTweakPlayerRes->x10_minesBreakFirstTopIcon; + break; + case kMOT_UpArrowRed: + iconColor = CColor((uchar)0xff, 0x64, 0x96, 0xff); + iconRes = gpTweakPlayerRes->x14_minesBreakFirstBottomIcon; + break; + case kMOT_SaveStation: + iconRes = gpTweakPlayerRes->x4_saveStationIcon; + break; + case kMOT_MissileStation: + iconRes = gpTweakPlayerRes->x8_missileStationIcon; + break; + default: + iconRes = gpTweakPlayerRes->xc_elevatorIcon; + break; + } - // TODO - // switch (x0_type) { - // case kMOT_DownArrowYellow: - // iconRes = gpTweakPlayerRes->x10_minesBreakFirstTopIcon; - // iconColor = CColor(0xffff96ff); - // break; - // case kMOT_UpArrowYellow: - // iconRes = gpTweakPlayerRes->x14_minesBreakFirstBottomIcon; - // iconColor = CColor(0xffff96ff); - // break; - // case kMOT_DownArrowGreen: - // iconRes = gpTweakPlayerRes->x10_minesBreakFirstTopIcon; - // iconColor = CColor(0x64ff96ff); - // break; - // case kMOT_UpArrowGreen: - // iconRes = gpTweakPlayerRes->x14_minesBreakFirstBottomIcon; - // iconColor = CColor(0x64ff96ff); - // break; - // case kMOT_DownArrowRed: - // iconRes = gpTweakPlayerRes->x10_minesBreakFirstTopIcon; - // iconColor = CColor(0xff6496ff); - // break; - // case kMOT_UpArrowRed: - // iconRes = gpTweakPlayerRes->x14_minesBreakFirstBottomIcon; - // iconColor = CColor(0xff6496ff); - // break; - // case kMOT_SaveStation: - // iconRes = gpTweakPlayerRes->x4_saveStationIcon; - // break; - // case kMOT_MissileStation: - // iconRes = gpTweakPlayerRes->x8_missileStationIcon; - // break; - // default: - // iconRes = gpTweakPlayerRes->xc_elevatorIcon; - // break; - // } TLockedToken< CTexture > tex = gpSimplePool->GetObj(SObjectTag('TXTR', iconRes)); tex->Load(GX_TEXMAP0, CTexture::kCM_Repeat); CGraphics::SetTevOp(kTS_Stage0, CGraphics::kEnvModulate); @@ -198,3 +201,101 @@ void CMappableObject::Draw(int curArea, const CMapWorldInfo& mwInfo, float alpha CGraphics::StreamVertex(2.6f, 0.0f, -2.6f); CGraphics::StreamEnd(); } + +void CMappableObject::DrawDoorSurface(int curAreaId, const CMapWorldInfo& mwInfo, float alpha, + int surfaceIdx, bool needsVtxLoad) const { + rstl::pair< CColor, CColor > colors = GetDoorColors(curAreaId, mwInfo, alpha); + const SDrawData& drawData = sDrawData[surfaceIdx]; + if (needsVtxLoad) { + CGX::SetArray(GX_VA_POS, skDoorVerts, 12); + } + + CGX::SetTevKColor(GX_KCOLOR0, colors.first.GetGXColor()); + CGX::Begin(GX_TRIANGLESTRIP, GX_VTXFMT0, 4); + GXPosition1x8(drawData.xc_idxA); + GXPosition1x8(drawData.xd_idxB); + GXPosition1x8(drawData.xe_idxC); + GXPosition1x8(drawData.xf_idxD); + CGX::End(); + + CGX::SetTevKColor(GX_KCOLOR0, colors.second.GetGXColor()); + CGX::Begin(GX_LINESTRIP, GX_VTXFMT0, 5); + GXPosition1x8(drawData.xc_idxA); + GXPosition1x8(drawData.xd_idxB); + GXPosition1x8(drawData.xf_idxD); + GXPosition1x8(drawData.xe_idxC); + GXPosition1x8(drawData.xc_idxA); + CGX::End(); +} + +CVector3f CMappableObject::BuildSurfaceCenterPoint(int surfaceIdx) const { + const float x = gpTweakAutoMapper->xac_doorCenterC; + const float y = gpTweakAutoMapper->xa8_doorCenterB; + const float z = gpTweakAutoMapper->xa4_doorCenterA; + switch (surfaceIdx) { + case 0: + return x10_transform * CVector3f::Zero(); + case 1: + return x10_transform * CVector3f(0.f, 0.f, 2.f * z); + case 2: + return x10_transform * CVector3f(0.f, -y, 0.f); + case 3: + return x10_transform * CVector3f(0.f, y, 0.f); + case 4: + return x10_transform * CVector3f(-x, 0.f, 0.f); + case 5: + return x10_transform * CVector3f(x, 0.f, 0.f); + default: + return CVector3f::Zero(); + } +} + +bool CMappableObject::GetIsVisibleToAutoMapper(bool worldVis, const CMapWorldInfo& mwInfo) const { + bool areaVis = mwInfo.IsAreaVisible(x8_objId.AreaNum()); + switch (x4_visibilityMode) { + case kVM_Always: + return true; + case kVM_MapStationOrVisit: + case kVM_MapStationOrVisit2: + return worldVis || areaVis; + case kVM_Visit: + if (IsDoorType(x0_type)) { + return mwInfo.IsDoorVisited(x8_objId); + } + return areaVis; + case kVM_Never: + return false; + default: + return true; + } +} + +CTransform4f CMappableObject::AdjustTransformForType() const { + const float doorCenterX = gpTweakAutoMapper->xa4_doorCenterA; + const float doorCenterZ = gpTweakAutoMapper->xac_doorCenterC; + if (x0_type == kMOT_BigDoor1) { + return (GetTransform() * CTransform4f(CMatrix3f::RotateZ(CRelAngle::FromDegrees(90.f)), + CVector3f(0.f, 0.f, doorCenterX * -1.4f))) * + CTransform4f::Scale(1.5f); + } else if (x0_type == kMOT_BigDoor2) { + return (GetTransform() * + CTransform4f(CMatrix3f::RotateZ(CRelAngle::FromDegrees(-90.f)), + CVector3f(0.f, doorCenterZ * -2.f, doorCenterX * -1.4f))) * + CTransform4f::Scale(1.5f); + } else if (x0_type == kMOT_IceDoorCeiling || x0_type == kMOT_WaveDoorCeiling || + x0_type == kMOT_PlasmaDoorCeiling) { + return GetTransform() * CTransform4f(CMatrix3f::RotateY(CRelAngle::FromDegrees(90.f)), + CVector3f(doorCenterX * -1.65f, 0.f, doorCenterZ * -1.f)); + } else if (x0_type == kMOT_IceDoorFloor || x0_type == kMOT_WaveDoorFloor || + x0_type == kMOT_PlasmaDoorFloor) { + return GetTransform() * CTransform4f(CMatrix3f::RotateY(CRelAngle::FromDegrees(90.f)), + CVector3f(doorCenterX * -1.65f, 0.f, doorCenterZ * -1.f)); + } else if ((u32(x0_type) - u32(kMOT_IceDoorFloor2)) <= u32(kMOT_ShieldDoor) || + x0_type == kMOT_PlasmaDoorFloor2) { + return GetTransform() * CTransform4f(CMatrix3f::RotateY(CRelAngle::FromDegrees(90.f)), + CVector3f(doorCenterX * -0.49f, 0.f, doorCenterZ * -1.f)); + } else if (IsDoorType(x0_type)) { + return GetTransform(); + } + return CTransform4f::Translate(GetTransform().GetTranslation()); +} diff --git a/tools/metaforce_renames.py b/tools/metaforce_renames.py index f9dd27c6..4ff44288 100644 --- a/tools/metaforce_renames.py +++ b/tools/metaforce_renames.py @@ -108,6 +108,7 @@ _LITERAL_REPLACEMENTS = [ ("ERglBlendMode::", "kBM_"), ("ERglBlendFactor::", "kBF_"), ("ERglLogicOp::", "kLO_"), + ("EVisMode", "kVM_"), # CActor ("x34_transform.origin", "GetTranslation()"),