diff --git a/config/GM8E01_00/symbols.txt b/config/GM8E01_00/symbols.txt index b805f73c..3891029a 100644 --- a/config/GM8E01_00/symbols.txt +++ b/config/GM8E01_00/symbols.txt @@ -11950,7 +11950,7 @@ SetupCGraphicsStates__13CCubeRendererFv = .text:0x802BD79C; // type:function siz SetupRendererStates__13CCubeRendererFb = .text:0x802BD830; // type:function size:0x7C scope:global AddDrawable__13CCubeRendererFPCvRC9CVector3fRC6CAABoxiQ29IRenderer16EDrawableSorting = .text:0x802BD8AC; // type:function size:0x64 scope:global AddPlaneObject__13CCubeRendererFPCvRC6CAABoxRC6CPlanei = .text:0x802BD910; // type:function size:0x1F4 scope:global -fn_802BDB04 = .text:0x802BDB04; // type:function size:0x40 +AddParticleGen__13CCubeRendererFRC12CParticleGenRC9CVector3fRC6CAABox = .text:0x802BDB04; // type:function size:0x40 AddParticleGen__13CCubeRendererFRC12CParticleGen = .text:0x802BDB44; // type:function size:0xF0 scope:global EndScene__13CCubeRendererFv = .text:0x802BDC34; // type:function size:0x6C scope:global BeginScene__13CCubeRendererFv = .text:0x802BDCA0; // type:function size:0x164 scope:global diff --git a/config/GM8E01_01/symbols.txt b/config/GM8E01_01/symbols.txt index 8984fc5e..5366990f 100644 --- a/config/GM8E01_01/symbols.txt +++ b/config/GM8E01_01/symbols.txt @@ -11950,7 +11950,7 @@ SetupCGraphicsStates__13CCubeRendererFv = .text:0x802BD848; // type:function siz SetupRendererStates__13CCubeRendererFb = .text:0x802BD8DC; // type:function size:0x7C scope:global AddDrawable__13CCubeRendererFPCvRC9CVector3fRC6CAABoxiQ29IRenderer16EDrawableSorting = .text:0x802BD958; // type:function size:0x64 scope:global AddPlaneObject__13CCubeRendererFPCvRC6CAABoxRC6CPlanei = .text:0x802BD9BC; // type:function size:0x1F4 scope:global -fn_802BDB04 = .text:0x802BDBB0; // type:function size:0x40 scope:global +AddParticleGen__13CCubeRendererFRC12CParticleGenRC9CVector3fRC6CAABox = .text:0x802BDBB0; // type:function size:0x40 scope:global AddParticleGen__13CCubeRendererFRC12CParticleGen = .text:0x802BDBF0; // type:function size:0xF0 scope:global EndScene__13CCubeRendererFv = .text:0x802BDCE0; // type:function size:0x6C scope:global BeginScene__13CCubeRendererFv = .text:0x802BDD4C; // type:function size:0x164 scope:global diff --git a/include/Kyoto/Graphics/CCubeMaterial.hpp b/include/Kyoto/Graphics/CCubeMaterial.hpp index 406e5263..719ed4b7 100644 --- a/include/Kyoto/Graphics/CCubeMaterial.hpp +++ b/include/Kyoto/Graphics/CCubeMaterial.hpp @@ -10,6 +10,9 @@ extern CVector3f sPlayerPosition; class CCubeMaterial { public: + static void ResetCachedMaterials(); + static void EnsureTevsDirect(); + private: static void SetupBlendMode(uint blendFactors, const CModelFlags& flags, bool alphaTest); diff --git a/include/Kyoto/Graphics/CDrawable.hpp b/include/Kyoto/Graphics/CDrawable.hpp index c597d8c4..9a1d24e3 100644 --- a/include/Kyoto/Graphics/CDrawable.hpp +++ b/include/Kyoto/Graphics/CDrawable.hpp @@ -7,12 +7,12 @@ // TODO enum EDrawableType { - WorldSurface, - Particle, - Actor, - SimpleShadow, - Decal, - Invalid = 0xFFFF, + kDT_WorldSurface, + kDT_Particle, + kDT_Actor, + kDT_SimpleShadow, + kDT_Decal, + kDT_Invalid = 0xFFFF, }; class CDrawable { diff --git a/include/Kyoto/Graphics/CGraphics.hpp b/include/Kyoto/Graphics/CGraphics.hpp index 465aadff..34c1d5d1 100644 --- a/include/Kyoto/Graphics/CGraphics.hpp +++ b/include/Kyoto/Graphics/CGraphics.hpp @@ -353,7 +353,7 @@ public: static void SetModelMatrix(const CTransform4f& xf); static void SetAlphaCompare(ERglAlphaFunc comp0, uchar ref0, ERglAlphaOp op, ERglAlphaFunc comp1, uchar ref1); - static void SetDepthWriteMode(bool test, ERglEnum comp, bool write); + static void SetDepthWriteMode(const bool test, ERglEnum comp, const bool write); static void SetBlendMode(ERglBlendMode mode, ERglBlendFactor src, ERglBlendFactor dst, ERglLogicOp op); static void SetCullMode(ERglCullMode cullMode); diff --git a/include/Kyoto/Graphics/CGraphicsPalette.hpp b/include/Kyoto/Graphics/CGraphicsPalette.hpp index 1ed22de3..c1ebe7d1 100644 --- a/include/Kyoto/Graphics/CGraphicsPalette.hpp +++ b/include/Kyoto/Graphics/CGraphicsPalette.hpp @@ -27,6 +27,10 @@ public: ushort* GetPaletteData() { return xc_entries.get(); } const ushort* GetPaletteData() const { return xc_entries.get(); } void Load() const; + void* Lock() { + x1c_locked = true; + return xc_entries.get(); + } void UnLock(); private: diff --git a/include/Kyoto/Graphics/CTexture.hpp b/include/Kyoto/Graphics/CTexture.hpp index dc810b57..c54e488e 100644 --- a/include/Kyoto/Graphics/CTexture.hpp +++ b/include/Kyoto/Graphics/CTexture.hpp @@ -71,7 +71,7 @@ public: void Load(GXTexMapID texMapId, EClampMode clampMode) const; bool HasPalette() const { return IsCITextureFormat(mTexelFormat); } const void* GetConstBitMapData(const int mip) const; - void* GetBitMapData(int); + void* GetBitMapData(int); ETexelFormat GetTexelFormat() const { return mTexelFormat; } const short GetWidth() const { return mWidth; } const short GetHeight() const { return mHeight; } @@ -96,6 +96,8 @@ public: void InitBitmapBuffers(const ETexelFormat fmt, const short w, const short h, const int mips); void InitTextureObjects(); void UnLock(); + CGraphicsPalette* GetPalette() { return mGraphicsPalette.get(); } + const CGraphicsPalette* GetPalette() const { return mGraphicsPalette.get(); } static void InvalidateTexmap(GXTexMapID id); static bool IsCITextureFormat(ETexelFormat fmt) { diff --git a/include/Kyoto/TOneStatic.hpp b/include/Kyoto/TOneStatic.hpp index d413a46a..58ffdea8 100644 --- a/include/Kyoto/TOneStatic.hpp +++ b/include/Kyoto/TOneStatic.hpp @@ -7,6 +7,10 @@ template < typename T > class TOneStatic { public: +#ifndef __MWERKS__ + // For clangd + void* operator new(size_t sz); +#endif void* operator new(size_t sz, const char*, const char*); void operator delete(void* ptr); diff --git a/include/MetaRender/CCubeRenderer.hpp b/include/MetaRender/CCubeRenderer.hpp index 35f286af..6cc73387 100644 --- a/include/MetaRender/CCubeRenderer.hpp +++ b/include/MetaRender/CCubeRenderer.hpp @@ -85,7 +85,7 @@ public: void SetModelMatrix(const CTransform4f& xf) override; void AddParticleGen(const CParticleGen& gen) override; void AddParticleGen(const CParticleGen& gen, const CVector3f&, const CAABox&) override; - void AddPlaneObject() override; + void AddPlaneObject(const void* obj, const CAABox& aabb, const CPlane& plane, int type) override; void AddDrawable(const void* obj, const CVector3f& pos, const CAABox& bounds, int mode, IRenderer::EDrawableSorting sorting) override; void SetDrawableCallback(TDrawableCallback cb, const void* ctx) override; @@ -142,6 +142,8 @@ public: void PrepareDynamicLights(const rstl::vector< CLight >& lights) override; void AllocatePhazonSuitMaskTexture(); + void SetupRendererStates(bool depthWrite); + void SetupCGraphicsStates(); void SetRequestRGBA6(bool req) { x318_26_requestRGBA6 = req; } CTexture* GetRealReflection(); diff --git a/include/MetaRender/IRenderer.hpp b/include/MetaRender/IRenderer.hpp index ebe80b64..8c39b3a9 100644 --- a/include/MetaRender/IRenderer.hpp +++ b/include/MetaRender/IRenderer.hpp @@ -20,6 +20,7 @@ class CMetroidModelInstance; class CModel; class COsContext; class CParticleGen; +class CPlane; class CPVSVisSet; class CResFactory; class CSkinnedModel; @@ -70,7 +71,7 @@ public: virtual void SetModelMatrix(const CTransform4f& xf); virtual void AddParticleGen(const CParticleGen& gen); virtual void AddParticleGen(const CParticleGen& gen, const CVector3f&, const CAABox&); - virtual void AddPlaneObject(); + virtual void AddPlaneObject(const void* obj, const CAABox& aabb, const CPlane& plane, int type); virtual void AddDrawable(const void* obj, const CVector3f& pos, const CAABox& bounds, int mode, IRenderer::EDrawableSorting sorting); virtual void SetDrawableCallback(TDrawableCallback cb, const void* ctx); diff --git a/src/Kyoto/Graphics/DolphinCGraphics.cpp b/src/Kyoto/Graphics/DolphinCGraphics.cpp index 94567a0d..ab074b51 100644 --- a/src/Kyoto/Graphics/DolphinCGraphics.cpp +++ b/src/Kyoto/Graphics/DolphinCGraphics.cpp @@ -776,10 +776,9 @@ void CGraphics::EndScene() { CFrameDelayedKiller::fn_8036CB90(); } -void CGraphics::SetDepthWriteMode(bool test, ERglEnum comp, bool write) { +void CGraphics::SetDepthWriteMode(const bool test, ERglEnum comp, const bool write) { mDepthFunc = comp; - CGX::SetZMode(static_cast< uchar >(test), static_cast< GXCompare >(comp), - static_cast< uchar >(write)); + CGX::SetZMode(test, static_cast< GXCompare >(comp), write); } void CGraphics::SetCullMode(ERglCullMode cullMode) { diff --git a/src/MetaRender/CCubeRenderer.cpp b/src/MetaRender/CCubeRenderer.cpp index efe90f7a..58e165a8 100644 --- a/src/MetaRender/CCubeRenderer.cpp +++ b/src/MetaRender/CCubeRenderer.cpp @@ -2,6 +2,7 @@ #include "Kyoto/Animation/CSkinnedModel.hpp" #include "Kyoto/Graphics/CColor.hpp" +#include "Kyoto/Graphics/CCubeMaterial.hpp" #include "Kyoto/Graphics/CCubeModel.hpp" #include "Kyoto/Graphics/CCubeSurface.hpp" #include "Kyoto/Graphics/CDrawable.hpp" @@ -13,21 +14,27 @@ #include "Kyoto/Graphics/CModelFlags.hpp" #include "Kyoto/Graphics/CTexture.hpp" #include "Kyoto/IObjectStore.hpp" +#include "Kyoto/Math/CAABox.hpp" #include "Kyoto/Math/CFrustumPlanes.hpp" #include "Kyoto/Math/CPlane.hpp" #include "Kyoto/Math/CTransform4f.hpp" #include "Kyoto/Math/CUnitVector3f.hpp" #include "Kyoto/Math/CVector2f.hpp" #include "Kyoto/Math/CVector3f.hpp" +#include "Kyoto/Particles/CParticleGen.hpp" +#include "Kyoto/TToken.hpp" #include "MetaRender/IRenderer.hpp" #include "Weapons/IWeaponRenderer.hpp" #include "WorldFormat/CMetroidModelInstance.hpp" #include "dolphin/gx/GXEnum.h" #include "dolphin/gx/GXGeometry.h" +#include "dolphin/gx/GXStruct.h" #include "dolphin/gx/GXVert.h" #include "dolphin/types.h" #include "rstl/auto_ptr.hpp" +#include "rstl/construct.hpp" #include "rstl/math.hpp" +#include "rstl/optional_object.hpp" #include "rstl/pair.hpp" #include "rstl/reserved_vector.hpp" #include "rstl/vector.hpp" @@ -72,7 +79,7 @@ void Shutdown() { } // TODO non-matching -void Insert(const CVector3f& pos, const CAABox& aabb, ushort dtype, const void* data, +void Insert(const CVector3f& pos, const CAABox& aabb, EDrawableType dtype, const void* data, const CPlane& plane, ushort extraSort) { if (sData->size() == sData->capacity()) { return; @@ -190,11 +197,43 @@ void CCubeRenderer::GenerateFogVolumeRampTex() { } void CCubeRenderer::GenerateSphereRampTex() { - // TODO + const int height = 32; + const int width = 32; + const float halfRes = (height - 1) / 2.f; + + uchar* data = static_cast< uchar* >(x220_sphereRamp.Lock()); + for (int y = 0; y < height; ++y) { + int start = y * width; + for (int x = 0; x < width; ++x) { + // I8 block is 8x4 (WxH) + // Convert swizzled coords to linear + float fx = static_cast< float >(((y % 4) << 3) + (x & 7)); + float fy = static_cast< float >(((y / 4) << 2) + (x >> 3)); + fx = (fx / halfRes) - 1.f; + fy = (fy / halfRes) - 1.f; + float mag = CMath::SqrtF(fx * fx + fy * fy); + float value = CMath::Clamp(0.f, 1.f - (mag * mag), 1.f); + data[start + x] = static_cast< uchar >(value * 255.f); + } + } + x220_sphereRamp.UnLock(); } void CCubeRenderer::LoadThermoPalette() { - // TODO + x288_thermalPalette.Lock(); + TLockedToken< CTexture > token = xc_objStore.GetObj("TXTR_ThermoPalette"); + int i = 0; + if (const CGraphicsPalette* pal = token->GetPalette()) { + while (i < 16) { + x288_thermalPalette.GetPaletteData()[i] = pal->GetPaletteData()[i]; + ++i; + } + } else { + while (i < 16) { + x288_thermalPalette.GetPaletteData()[i++] = 0; + } + } + x288_thermalPalette.UnLock(); } CCubeRenderer::~CCubeRenderer() { @@ -305,7 +344,84 @@ void CCubeRenderer::EndScene() { } void CCubeRenderer::AddParticleGen(const CParticleGen& gen) { - // TODO + AUTO(bounds, gen.GetBounds()); + if (bounds) { + CVector3f closestPoint = bounds->ClosestPointAlongVector(xb0_viewPlane.GetNormal()); + Buckets::Insert(closestPoint, *bounds, kDT_Particle, static_cast< const void* >(&gen), + xb0_viewPlane, 0); + } +} + +void CCubeRenderer::AddParticleGen(const CParticleGen& gen, const CVector3f& pos, + const CAABox& bounds) { + Buckets::Insert(pos, bounds, kDT_Particle, static_cast< const void* >(&gen), xb0_viewPlane, 0); +} + +void CCubeRenderer::AddPlaneObject(const void* obj, const CAABox& aabb, const CPlane& plane, + int type) { + static const CVector3f sOptimalPlane(0.f, 0.f, 1.f); + + CVector3f closestPoint = aabb.ClosestPointAlongVector(xb0_viewPlane.GetNormal()); + float closestDist = xb0_viewPlane.GetHeight(closestPoint); + CVector3f furthestPoint = aabb.FurthestPointAlongVector(xb0_viewPlane.GetNormal()); + float furthestDist = xb0_viewPlane.GetHeight(furthestPoint); + if (closestDist < 0.f && furthestDist < 0.f) { + return; + } + + bool zOnly; + if (plane.GetNormal() == sOptimalPlane) { + zOnly = true; + } else { + zOnly = false; + } + + bool invertTest; + if (zOnly) { + if (CGraphics::GetViewMatrix().GetTranslation().GetZ() >= plane.GetConstant()) { + invertTest = true; + } else { + invertTest = false; + } + } else if (plane.GetHeight(CGraphics::GetViewMatrix().GetTranslation()) >= 0.f) { + invertTest = true; + } else { + invertTest = false; + } + + Buckets::InsertPlaneObject(closestDist, furthestDist, aabb, invertTest, plane, zOnly, + EDrawableType(type + 2), obj); +} + +void CCubeRenderer::AddDrawable(const void* obj, const CVector3f& pos, const CAABox& aabb, int mode, + IRenderer::EDrawableSorting sorting) { + if (sorting == IRenderer::kDS_UnsortedCallback) { + xa8_drawableCallback(obj, xac_drawableCallbackUserData, mode); + } else { + Buckets::Insert(pos, aabb, EDrawableType(mode + 2), obj, xb0_viewPlane, 0); + } +} + +void CCubeRenderer::SetupRendererStates(bool depthWrite) { + CGraphics::DisableAllLights(); + CGraphics::SetModelMatrix(CTransform4f::Identity()); + CGraphics::SetAmbientColor(CColor(0)); + CGraphics::SetDepthWriteMode(true, kE_LEqual, depthWrite); + CCubeMaterial::ResetCachedMaterials(); + GXSetTevColor(GX_TEVREG1, x2fc_tevReg1Color.GetGXColor()); +} + +void CCubeRenderer::SetupCGraphicsStates() { + const GXColor sWhite = {255, 255, 255, 255}; + CGraphics::DisableAllLights(); + CGraphics::SetModelMatrix(CTransform4f::Identity()); + CTevCombiners::ResetStates(); + CGraphics::SetAmbientColor(CColor(0.4f, 0.4f, 0.4f, 1.f)); + CGX::SetChanMatColor(CGX::Channel0, sWhite); + CGraphics::SetDepthWriteMode(true, kE_LEqual, true); + CGX::SetChanCtrl(CGX::Channel1, false, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_NONE, + GX_AF_NONE); + CCubeMaterial::EnsureTevsDirect(); } namespace Renderer {