From 44d675d87dede70d42dee8baa34d4ef52bef7921 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Sat, 2 Jul 2022 01:30:04 -0400 Subject: [PATCH] Begin decompiling CCameraFilterPass::DrawWideScreen --- .gitignore | 1 + include/Kyoto/Math/CColor.hpp | 14 ++++ include/Kyoto/Math/CTransform4f.hpp | 20 +++++ include/Kyoto/Math/CVector2f.hpp | 17 ++-- include/Kyoto/Math/CVector3f.hpp | 20 ++--- include/Kyoto/Math/CloseEnough.hpp | 10 ++- include/Kyoto_CWD/CCameraFilterPass.hpp | 15 ++++ include/Kyoto_CWD/CCubeRenderer.hpp | 69 ++++++++++++++++ include/Kyoto_CWD/CGraphics.hpp | 38 +++++++++ include/Kyoto_CWD/CTevCombiners.hpp | 100 ++++++++++++++++++++++++ include/Kyoto_CWD/CTexture.hpp | 18 +++++ include/gx_enum.h | 38 +++++++++ include/types.h | 1 + src/MetroidPrime/CCameraFilterPass.cpp | 49 ++++++++++++ 14 files changed, 389 insertions(+), 21 deletions(-) create mode 100644 include/Kyoto/Math/CColor.hpp create mode 100644 include/Kyoto/Math/CTransform4f.hpp create mode 100644 include/Kyoto_CWD/CCameraFilterPass.hpp create mode 100644 include/Kyoto_CWD/CTevCombiners.hpp create mode 100644 include/Kyoto_CWD/CTexture.hpp create mode 100644 include/gx_enum.h create mode 100644 src/MetroidPrime/CCameraFilterPass.cpp diff --git a/.gitignore b/.gitignore index 348460f7..a1905ba1 100644 --- a/.gitignore +++ b/.gitignore @@ -34,5 +34,6 @@ errors.txt output.asm Debug/ .vs/ +__pycache__/ ctx.c diff --git a/include/Kyoto/Math/CColor.hpp b/include/Kyoto/Math/CColor.hpp new file mode 100644 index 00000000..5e472ff8 --- /dev/null +++ b/include/Kyoto/Math/CColor.hpp @@ -0,0 +1,14 @@ +#ifndef __CCOLOR_HPP__ +#define __CCOLOR_HPP__ + +#include "types.h" + +class CColor { +public: + u8 r; + u8 g; + u8 b; + u8 a; +}; + +#endif // __CCOLOR_HPP__ diff --git a/include/Kyoto/Math/CTransform4f.hpp b/include/Kyoto/Math/CTransform4f.hpp new file mode 100644 index 00000000..6c018534 --- /dev/null +++ b/include/Kyoto/Math/CTransform4f.hpp @@ -0,0 +1,20 @@ +#ifndef __CTRANSFORM4F_HPP__ +#define __CTRANSFORM4F_HPP__ + +#include "types.h" + +#include "CVector3f.hpp" + +class CTransform4f { +public: + CVector3f m0; + f32 posX; + CVector3f m1; + f32 posY; + CVector3f m2; + f32 posZ; +}; + +extern CTransform4f skIdentity4f; + +#endif // __CTRANSFORM4F_HPP__ diff --git a/include/Kyoto/Math/CVector2f.hpp b/include/Kyoto/Math/CVector2f.hpp index 014bffc7..b26e947a 100644 --- a/include/Kyoto/Math/CVector2f.hpp +++ b/include/Kyoto/Math/CVector2f.hpp @@ -1,17 +1,18 @@ #ifndef __CVECTOR2F_HPP__ #define __CVECTOR2F_HPP__ +#include "types.h" class CVector2f { public: - explicit CVector2f(float x, float y) : mX(x), mY(y) {} - - float GetX() const { return mX; } - float GetY() const { return mY; } - -private: - float mX; - float mY; + explicit CVector2f(f32 x, f32 y) : mX(x), mY(y) {} + + f32 GetX() const { return mX; } + f32 GetY() const { return mY; } + +// private: + f32 mX; + f32 mY; }; #endif // __CVECTOR3F_HPP__ diff --git a/include/Kyoto/Math/CVector3f.hpp b/include/Kyoto/Math/CVector3f.hpp index 2f661c18..8df20dbe 100644 --- a/include/Kyoto/Math/CVector3f.hpp +++ b/include/Kyoto/Math/CVector3f.hpp @@ -1,18 +1,20 @@ #ifndef __CVECTOR3F_HPP__ #define __CVECTOR3F_HPP__ +#include "types.h" class CVector3f { public: - - float GetX() const { return mX; } - float GetY() const { return mY; } - float GetZ() const { return mZ; } - -private: - float mX; - float mY; - float mZ; + explicit CVector3f(f32 x, f32 y, f32 z) : mX(x), mY(y), mZ(z) {} + + f32 GetX() const { return mX; } + f32 GetY() const { return mY; } + f32 GetZ() const { return mZ; } + +// private: + f32 mX; + f32 mY; + f32 mZ; }; #endif // __CVECTOR3F_HPP__ diff --git a/include/Kyoto/Math/CloseEnough.hpp b/include/Kyoto/Math/CloseEnough.hpp index ba38eabd..8a5b1160 100644 --- a/include/Kyoto/Math/CloseEnough.hpp +++ b/include/Kyoto/Math/CloseEnough.hpp @@ -1,10 +1,12 @@ #ifndef __CLOSEENOUGH_HPP__ #define __CLOSEENOUGH_HPP__ -#include "Kyoto/CVector2f.hpp" -#include "Kyoto/CVector3f.hpp" +#include "types.h" -static bool close_enough(const CVector2f& a, const CVector2f& b, float epsilon = 0.001f); -static bool close_enough(const CVector3f& a, const CVector3f& b, float epsilon = 0.001f); +#include "CVector2f.hpp" +#include "CVector3f.hpp" + +static bool close_enough(const CVector2f& a, const CVector2f& b, f32 epsilon = 0.001f); +static bool close_enough(const CVector3f& a, const CVector3f& b, f32 epsilon = 0.001f); #endif // __CLOSEENOUGH_HPP__ diff --git a/include/Kyoto_CWD/CCameraFilterPass.hpp b/include/Kyoto_CWD/CCameraFilterPass.hpp new file mode 100644 index 00000000..98509343 --- /dev/null +++ b/include/Kyoto_CWD/CCameraFilterPass.hpp @@ -0,0 +1,15 @@ +#ifndef _CCAMERAFILTERPASS_HPP +#define _CCAMERAFILTERPASS_HPP + +#include "types.h" + +#include "Kyoto/Math/CColor.hpp" + +#include "CTexture.hpp" + +class CCameraFilterPass { +public: + static void DrawWideScreen(const CColor& color, const CTexture* tex, f32 v); +}; + +#endif diff --git a/include/Kyoto_CWD/CCubeRenderer.hpp b/include/Kyoto_CWD/CCubeRenderer.hpp index 1e3d5bce..d4eb856d 100644 --- a/include/Kyoto_CWD/CCubeRenderer.hpp +++ b/include/Kyoto_CWD/CCubeRenderer.hpp @@ -1,12 +1,81 @@ #ifndef _CCUBERENDERER_HPP #define _CCUBERENDERER_HPP +#include "gx_enum.h" #include "types.h" +#include "Kyoto/Math/CColor.hpp" +#include "Kyoto/Math/CTransform4f.hpp" +#include "Kyoto/Math/CVector2f.hpp" +#include "rstl/pair.hpp" + class CCubeRenderer { public: + virtual ~CCubeRenderer(); + // TODO types + virtual void AddStaticGeometry(); + virtual void EnablePVS(); + virtual void DisablePVS(); + virtual void RemoveStaticGeometry(); + virtual void DrawUnsortedGeometry(); + virtual void DrawSortedGeometry(); + virtual void DrawStaticGeometry(); + virtual void DrawAreaGeometry(); + virtual void PostRenderFogs(); + virtual void SetModelMatrix(const CTransform4f& xf); + virtual void AddParticleGen1(); + virtual void AddParticleGen2(); + virtual void AddPlaneObject(); + virtual void AddDrawable(); + virtual void SetDrawableCallback(); + virtual void SetWorldViewpoint(); + virtual void SetPerspective1(); + virtual void SetPerspective2(); + virtual rstl::pair< CVector2f, CVector2f > SetViewportOrtho(bool centered, f32 znear, f32 zfar); + virtual void SetClippingPlanes(); + virtual void SetViewport(); + virtual void SetDepthReadWrite(bool read, bool update); + virtual void SetBlendMode_AdditiveAlpha(); + virtual void SetBlendMode_AlphaBlended(); + virtual void SetBlendMode_NoColorWrite(); + virtual void SetBlendMode_ColorMultiply(); + virtual void SetBlendMode_InvertDst(); + virtual void SetBlendMode_InvertSrc(); + virtual void SetBlendMode_AdditiveDestColor(); + virtual void SetDebugOption(); virtual void BeginScene(); virtual void EndScene(); + virtual void BeginPrimitive(GXPrimitive prim, int count); + virtual void BeginLines(int nverts); + virtual void BeginLineStrip(int nverts); + virtual void BeginTriangles(int nverts); + virtual void BeginTriangleStrip(int nverts); + virtual void BeginTriangleFan(int nverts); + virtual void PrimVertex(const CVector3f& vtx); + virtual void PrimNormal(const CVector3f& nrm); + virtual void PrimColor(f32 r, f32 g, f32 b, f32 a); + virtual void PrimColor(const CColor& color); + virtual void EndPrimitive(); + virtual void SetAmbientColor(const CColor& color); + virtual void DrawString(); + virtual void GetFPS(); + virtual void CacheReflection(); + virtual void DrawSpaceWarp(); + virtual void DrawThermalModel(); + virtual void DrawModelDisintegrate(); + virtual void DrawModelFlat(); + virtual void SetWireframeFlags(); + virtual void SetWorldFog(); + virtual void RenderFogVolume(); + virtual void SetThermal(); + virtual void SetThermalColdScale(); + virtual void DoThermalBlendCold(); + virtual void DoThermalBlendHot(); + virtual void GetStaticWorldDataSize(); + virtual void SetGXRegister1Color(); + virtual void SetWorldLightFadeLevel(); + virtual void Something(); + virtual void PrepareDynamicLights(); }; extern CCubeRenderer* gpRender; diff --git a/include/Kyoto_CWD/CGraphics.hpp b/include/Kyoto_CWD/CGraphics.hpp index 19402e24..efa4ae74 100644 --- a/include/Kyoto_CWD/CGraphics.hpp +++ b/include/Kyoto_CWD/CGraphics.hpp @@ -3,11 +3,49 @@ #include "types.h" +#include "CTevCombiners.hpp" + +enum ERglTevStage { + kTS_Stage0, + kTS_Stage1, + kTS_Stage2, + kTS_Stage3, + kTS_Stage4, + kTS_Stage5, + kTS_Stage6, + kTS_Stage7, + kTS_Stage8, + kTS_Stage9, + kTS_Stage10, + kTS_Stage11, + kTS_Stage12, + kTS_Stage13, + kTS_Stage14, + kTS_Stage15, + kTS_MaxStage, +}; + +enum ERglPrimitive { + kP_Quads = 0x80, + kP_Triangles = 0x90, + kP_TriangleStrip = 0x98, + kP_TriangleFan = 0xA0, + kP_Lines = 0xA8, + kP_LineStrip = 0xB0, + kP_Points = 0xB8, +}; + class CGraphics { public: static void SetIsBeginSceneClearFb(bool); static void BeginScene(); static void EndScene(); + static void SetTevOp(ERglTevStage stage, const CTevCombiners::CTevPass& pass); + static void StreamBegin(ERglPrimitive primitive); + static void StreamColor(const CColor& color); + static void StreamTexcoord(f32 u, f32 v); + static void StreamVertex(const CVector3f& vtx); + static void StreamEnd(); }; #endif diff --git a/include/Kyoto_CWD/CTevCombiners.hpp b/include/Kyoto_CWD/CTevCombiners.hpp new file mode 100644 index 00000000..8b218fc7 --- /dev/null +++ b/include/Kyoto_CWD/CTevCombiners.hpp @@ -0,0 +1,100 @@ +#ifndef _CTEVCOMBINERS_HPP +#define _CTEVCOMBINERS_HPP + +#include "gx_enum.h" +#include "types.h" + +class CTevCombiners { +public: + enum EColorSrc { + kCS_PreviousColor, + kCS_PreviousAlpha, + kCS_RegisterC0, + kCS_RegisterA0, + kCS_RegisterC1, + kCS_RegisterA1, + kCS_RegisterC2, + kCS_RegisterA2, + kCS_TextureColor, + kCS_TextureAlpha, + kCS_RasterColor, + kCS_RasterAlpha, + kCS_One, + kCS_Half, + kCS_Konst, + kCS_Zero, + }; + struct ColorVar { + EColorSrc x0_src; + }; + struct ColorPass { + ColorVar x0_a; + ColorVar x4_b; + ColorVar x8_c; + ColorVar xc_d; + }; + + enum EAlphaSrc { + kAS_PreviousAlpha, + kAS_RegisterA0, + kAS_RegisterA1, + kAS_RegisterA2, + kAS_TextureAlpha, + kAS_RasterAlpha, + kAS_One, + kAS_Zero, + kAS_Konst, + }; + struct AlphaVar { + EAlphaSrc x0_src; + }; + struct AlphaPass { + AlphaVar x0_a; + AlphaVar x4_b; + AlphaVar x8_c; + AlphaVar xc_d; + }; + + enum ETevOp { + kTO_Add, + kTO_Subtract, + }; + enum ETevBias { + kTB_Zero, + kTB_AddHalf, + kTB_SubHalf, + }; + enum ETevScale { + kTS_Scale1, + kTS_Scale2, + kTS_Scale4, + kTS_Divide2, + }; + enum ETevOutput { + kTO_Previous, + kTO_Register0, + kTO_Register1, + kTO_Register2, + }; + struct CTevOp { + bool x0_clamp; + ETevOp x4_op; + ETevBias x8_bias; + ETevScale xc_scale; + ETevOutput x10_output; + }; + + class CTevPass { + public: + u32 x0_id; + ColorPass x4_colorPass; + AlphaPass x14_alphaPass; + CTevOp x24_colorOp; + CTevOp x38_alphaOp; + }; +}; + +extern CTevCombiners::CTevPass CTevPass_805a5ebc; +extern CTevCombiners::CTevPass* PTR_skPassThru_805a8828; + +#endif \ No newline at end of file diff --git a/include/Kyoto_CWD/CTexture.hpp b/include/Kyoto_CWD/CTexture.hpp new file mode 100644 index 00000000..c6d5288c --- /dev/null +++ b/include/Kyoto_CWD/CTexture.hpp @@ -0,0 +1,18 @@ +#ifndef _CTOKEN_HPP +#define _CTOKEN_HPP + +#include "gx_enum.h" +#include "types.h" + +class CTexture { +public: + enum EClampMode { + Clamp, + Repeat, + Mirror, + }; + + void Load(GXTexMapID texMapId, EClampMode clampMode) const; +}; + +#endif \ No newline at end of file diff --git a/include/gx_enum.h b/include/gx_enum.h new file mode 100644 index 00000000..497a91eb --- /dev/null +++ b/include/gx_enum.h @@ -0,0 +1,38 @@ +#ifndef __GX_ENUM_H__ +#define __GX_ENUM_H__ + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum _GXTexMapID { + GX_TEXMAP0, + GX_TEXMAP1, + GX_TEXMAP2, + GX_TEXMAP3, + GX_TEXMAP4, + GX_TEXMAP5, + GX_TEXMAP6, + GX_TEXMAP7, + GX_MAX_TEXMAP, + GX_TEXMAP_NULL = 0xFF, + GX_TEX_DISABLE = 0x100, +} GXTexMapID; + +typedef enum _GXPrimitive { + GX_QUADS = 0x80, + GX_TRIANGLES = 0x90, + GX_TRIANGLESTRIP = 0x98, + GX_TRIANGLEFAN = 0xA0, + GX_LINES = 0xA8, + GX_LINESTRIP = 0xB0, + GX_POINTS = 0xB8, +} GXPrimitive; + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/include/types.h b/include/types.h index 39404c05..d24bf183 100644 --- a/include/types.h +++ b/include/types.h @@ -61,6 +61,7 @@ typedef void* unkptr; // where should these go? void srand(int); +int rand(); #ifdef __cplusplus } diff --git a/src/MetroidPrime/CCameraFilterPass.cpp b/src/MetroidPrime/CCameraFilterPass.cpp new file mode 100644 index 00000000..47a0f0d5 --- /dev/null +++ b/src/MetroidPrime/CCameraFilterPass.cpp @@ -0,0 +1,49 @@ +#include "Kyoto_CWD/CCameraFilterPass.hpp" +#include "Kyoto_CWD/CCubeRenderer.hpp" +#include "Kyoto_CWD/CGraphics.hpp" + +// FIXME non-matching https://decomp.me/scratch/8N81d +void CCameraFilterPass::DrawWideScreen(const CColor& color, const CTexture* tex, float lod) { + const rstl::pair< CVector2f, CVector2f > vp = gpRender->SetViewportOrtho(true, -4096.f, 4096.f); + f32 left = vp.first.mX; + f32 dVar5 = -((vp.second.mX - vp.first.mX) * 0.0625f * 9.f - (vp.second.mY - vp.first.mY)) * 0.5f; + f32 bottom = vp.first.mY; + f32 right = vp.second.mX; + f32 top = vp.second.mY; + gpRender->SetDepthReadWrite(false, false); + gpRender->SetModelMatrix(skIdentity4f); + if (tex != nullptr) { + tex->Load(GX_TEXMAP0, CTexture::Repeat); + } + CGraphics::SetTevOp(kTS_Stage0, CTevPass_805a5ebc); + CGraphics::SetTevOp(kTS_Stage1, *PTR_skPassThru_805a8828); + + { + CGraphics::StreamBegin(kP_TriangleStrip); + float v = (float)(rand() % 4000) / 16384.f; + CGraphics::StreamColor(color); + CGraphics::StreamTexcoord(v, 1.f); + CGraphics::StreamVertex(CVector3f(left - 10.f, 0.f, bottom + (dVar5 * lod))); + CGraphics::StreamTexcoord(v, 0.f); + CGraphics::StreamVertex(CVector3f(left - 10.f, 0.f, bottom)); + CGraphics::StreamTexcoord(v + 1.f, 1.f); + CGraphics::StreamVertex(CVector3f(right + 10.f, 0.f, bottom + (dVar5 * lod))); + CGraphics::StreamTexcoord(v + 1.f, 0.f); + CGraphics::StreamVertex(CVector3f(right + 10.f, 0.f, bottom)); + CGraphics::StreamEnd(); + } + { + CGraphics::StreamBegin(kP_TriangleStrip); + float v = (float)(rand() % 4000) / 16384.f; + CGraphics::StreamColor(color); + CGraphics::StreamTexcoord(v, 0.f); + CGraphics::StreamVertex(CVector3f(left - 10.f, 0.f, top)); + CGraphics::StreamTexcoord(v, 1.f); + CGraphics::StreamVertex(CVector3f(left - 10.f, 0.f, top - (dVar5 * lod))); + CGraphics::StreamTexcoord(v + 1.f, 0.f); + CGraphics::StreamVertex(CVector3f(right + 10.f, 0.f, top)); + CGraphics::StreamTexcoord(v + 1.f, 1.f); + CGraphics::StreamVertex(CVector3f(right + 10.f, 0.f, top - (dVar5 * lod))); + CGraphics::StreamEnd(); + } +}