diff --git a/configure.py b/configure.py index a3a0773c..972f1d5d 100755 --- a/configure.py +++ b/configure.py @@ -386,7 +386,7 @@ LIBS = [ "MetroidPrime/CArtifactDoll", "MetroidPrime/CProjectedShadow", ["MetroidPrime/CPreFrontEnd", True], - "MetroidPrime/CGameCubeDoll", + ["MetroidPrime/CGameCubeDoll", False], ["MetroidPrime/ScriptObjects/CScriptProjectedShadow", False], "MetroidPrime/ScriptObjects/CEnergyBall", ["MetroidPrime/Enemies/CMetroidPrimeProjectile", False], diff --git a/include/Kyoto/Graphics/CGraphics.hpp b/include/Kyoto/Graphics/CGraphics.hpp index e8c6c34c..52d653b7 100644 --- a/include/Kyoto/Graphics/CGraphics.hpp +++ b/include/Kyoto/Graphics/CGraphics.hpp @@ -145,6 +145,7 @@ public: static const CViewport& GetViewport() { return mViewport; } static const CTransform4f& GetViewMatrix() { return mViewMatrix; } static const CTransform4f& GetModelMatrix() { return mModelMatrix; } + static void SetViewPointMatrix(const CTransform4f&); static void SetBrightness(float b) { mBrightness = b; } static float GetSecondsMod900(); diff --git a/include/Kyoto/Graphics/CModel.hpp b/include/Kyoto/Graphics/CModel.hpp new file mode 100644 index 00000000..bf9d4a7b --- /dev/null +++ b/include/Kyoto/Graphics/CModel.hpp @@ -0,0 +1,12 @@ +#ifndef _CMODEL +#define _CMODEL + +class CModelFlags; + +class CModel { +public: + void Touch(int) const; + void Draw(const CModelFlags&) const; +}; + +#endif // _CMODEL diff --git a/include/MetaRender/CCubeRenderer.hpp b/include/MetaRender/CCubeRenderer.hpp index f5f0fb17..eea07db5 100644 --- a/include/MetaRender/CCubeRenderer.hpp +++ b/include/MetaRender/CCubeRenderer.hpp @@ -22,39 +22,39 @@ class CModel; class CCubeRenderer : public IRenderer, public IWeaponRenderer { public: - virtual ~CCubeRenderer(); + ~CCubeRenderer() override; // 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 AddParticleGen(const CParticleGen& gen); - virtual void AddParticleGen2(); - virtual void AddPlaneObject(); - virtual void AddDrawable(const void* obj, const CVector3f& pos, const CAABox& bounds, int mode, - IRenderer::EDrawableSorting sorting); - virtual void SetDrawableCallback(); - virtual void SetWorldViewpoint(); - virtual void SetPerspective1(); - virtual void SetPerspective2(); - virtual rstl::pair< CVector2f, CVector2f > SetViewportOrtho(bool centered, float znear, - float 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(); + void AddStaticGeometry() override; + void EnablePVS() override; + void DisablePVS() override; + void RemoveStaticGeometry() override; + void DrawUnsortedGeometry() override; + void DrawSortedGeometry() override; + void DrawStaticGeometry() override; + void DrawAreaGeometry() override; + void PostRenderFogs() override; + void SetModelMatrix(const CTransform4f& xf) override; + void AddParticleGen(const CParticleGen& gen) override; + void AddParticleGen2() override; + void AddPlaneObject() override; + void AddDrawable(const void* obj, const CVector3f& pos, const CAABox& bounds, int mode, + IRenderer::EDrawableSorting sorting) override; + void SetDrawableCallback() override; + void SetWorldViewpoint() override; + void SetPerspective1(float, float, float, float, float) override; + void SetPerspective2() override; + rstl::pair< CVector2f, CVector2f > SetViewportOrtho(bool centered, float znear, + float zfar) override; + void SetClippingPlanes() override; + void SetViewport() override; + void SetDepthReadWrite(bool read, bool update) override; + void SetBlendMode_AdditiveAlpha() override; + void SetBlendMode_AlphaBlended() override; + void SetBlendMode_NoColorWrite() override; + void SetBlendMode_ColorMultiply() override; + void SetBlendMode_InvertDst() override; + void SetBlendMode_InvertSrc() override; + void SetBlendMode_AdditiveDestColor() override; virtual void SetDebugOption(); virtual void BeginScene(); virtual void EndScene(); @@ -80,7 +80,7 @@ public: virtual void SetWireframeFlags(); virtual void SetWorldFog(); virtual void RenderFogVolume(const CColor&, const CAABox&, const TLockedToken< CModel >*, - const CSkinnedModel*); + const CSkinnedModel*); virtual void SetThermal(); virtual void SetThermalColdScale(); virtual void DoThermalBlendCold(); diff --git a/include/MetaRender/IRenderer.hpp b/include/MetaRender/IRenderer.hpp index e48a61d7..36ab5e38 100644 --- a/include/MetaRender/IRenderer.hpp +++ b/include/MetaRender/IRenderer.hpp @@ -41,7 +41,7 @@ public: IRenderer::EDrawableSorting sorting); virtual void SetDrawableCallback(); virtual void SetWorldViewpoint(); - virtual void SetPerspective1(); + virtual void SetPerspective1(float, float, float, float, float); virtual void SetPerspective2(); virtual rstl::pair< CVector2f, CVector2f > SetViewportOrtho(bool centered, float znear, float zfar); diff --git a/include/MetroidPrime/CActorLights.hpp b/include/MetroidPrime/CActorLights.hpp index 682180e7..d20ddc46 100644 --- a/include/MetroidPrime/CActorLights.hpp +++ b/include/MetroidPrime/CActorLights.hpp @@ -26,6 +26,9 @@ public: void BuildConstantAmbientLighting(const CColor&); bool BuildAreaLightList(const CStateManager& mgr, const CGameArea& area, const CAABox& bounds); void BuildDynamicLightList(const CStateManager& mgr, const CAABox& bounds); + void BuildFakeLightList(const rstl::vector&, const CColor&); + + void ActivateLights() const; bool GetNeedsRelight() const { return x298_24_dirty == TRUE; } bool HasShadowLight() const { return x29c_shadowLightArrIdx != -1; } diff --git a/include/MetroidPrime/CGameCubeDoll.hpp b/include/MetroidPrime/CGameCubeDoll.hpp new file mode 100644 index 00000000..ef5ea9be --- /dev/null +++ b/include/MetroidPrime/CGameCubeDoll.hpp @@ -0,0 +1,34 @@ +#ifndef _CGAMECUBEDOLL +#define _CGAMECUBEDOLL + +#include "Kyoto/TToken.hpp" + +#include "rstl/single_ptr.hpp" +#include "rstl/vector.hpp" + +class CActorLights; +class CModel; +class CLight; + +class CGameCubeDoll { +public: + CGameCubeDoll(); + ~CGameCubeDoll(); + + void Update(float dt); + void Draw(float alpha); + void Touch(); + bool CheckLoadComplete(); + bool IsLoaded() const; + +private: + CToken x0_model; + rstl::vector< CLight > x8_lights; + rstl::single_ptr< CActorLights > x18_actorLights; + float x1c_fader; + bool x20_24_loaded : 1; + + void UpdateActorLights(); +}; + +#endif // _CGAMECUBEDOLL diff --git a/include/rstl/vector.hpp b/include/rstl/vector.hpp index 0e892c93..31db9826 100644 --- a/include/rstl/vector.hpp +++ b/include/rstl/vector.hpp @@ -47,6 +47,8 @@ public: x0_allocator.allocate(xc_items, x4_count); uninitialized_fill_n(xc_items, count, v); } + vector(int count, const T& v, const Alloc& alloc); + vector(const vector& other) : x4_count(other.x4_count), x8_capacity(other.x8_capacity) { if (other.x4_count == 0 && other.x8_capacity == 0) { xc_items = nullptr; diff --git a/src/MetroidPrime/CGameCubeDoll.cpp b/src/MetroidPrime/CGameCubeDoll.cpp new file mode 100644 index 00000000..d7a91951 --- /dev/null +++ b/src/MetroidPrime/CGameCubeDoll.cpp @@ -0,0 +1,81 @@ +#include "MetroidPrime/CGameCubeDoll.hpp" + +#include "MetroidPrime/CActorLights.hpp" + +#include "Kyoto/Graphics/CGraphics.hpp" +#include "Kyoto/Graphics/CLight.hpp" +#include "Kyoto/Graphics/CModel.hpp" +#include "Kyoto/Graphics/CModelFlags.hpp" +#include "Kyoto/Math/CMath.hpp" +#include "Kyoto/Math/CRelAngle.hpp" +#include "MetaRender/CCubeRenderer.hpp" + +#include "rstl/math.hpp" + +CGameCubeDoll::CGameCubeDoll() +: x0_model(gpSimplePool->GetObj("CMDL_GameCube")) +, x8_lights(1, CLight::BuildDirectional(CVector3f::Forward(), CColor(0xFFFFFFFF)), rstl::rmemory_allocator()) +, x18_actorLights(new CActorLights(8, CVector3f::Zero(), 4, 4, 0.1f, false, false, false)) +, x1c_fader(0.0f) +, x20_24_loaded(false) { + x0_model.Lock(); +} + +bool CGameCubeDoll::CheckLoadComplete() { + if (IsLoaded()) + return true; + + if (!x0_model.IsLoaded()) { + return false; + } + + x20_24_loaded = true; + return true; +} + +bool CGameCubeDoll::IsLoaded() const { return x20_24_loaded != false; } + +CGameCubeDoll::~CGameCubeDoll() {} + +void CGameCubeDoll::UpdateActorLights() { + (CVector3f::Forward() + CVector3f::Right() * 0.25f + CVector3f::Down() * 0.1f).AsNormalized(); + + x8_lights[0] = + CLight::BuildDirectional(CVector3f::Forward(), CColor(uchar(0xFF), uchar(0xFF), uchar(0xFF))); + x18_actorLights->BuildFakeLightList(x8_lights, CColor(0.25f, 0.25f, 0.25f, 1.f)); +} + +void CGameCubeDoll::Touch() { + if (!CheckLoadComplete()) + return; + TToken< CModel >(x0_model)->Touch(0); +} + +void CGameCubeDoll::Update(float dt) { + if (!CheckLoadComplete()) + return; + x1c_fader = rstl::min_val(1.f, 2.f * dt + x1c_fader); + UpdateActorLights(); +} + +void CGameCubeDoll::Draw(float alpha) { + if (!IsLoaded()) + return; + + float alphaFader = alpha * x1c_fader; + + gpRender->SetPerspective1(55.f, CGraphics::GetViewport().mWidth, CGraphics::GetViewport().mHeight, + 0.2f, 4096.f); + + CGraphics::SetViewPointMatrix(CTransform4f::Translate(0.f, -2.f, 0.f)); + x18_actorLights->ActivateLights(); + + float f = CGraphics::GetSecondsMod900() * 360.f; + CGraphics::SetModelMatrix(CTransform4f::RotateZ(CRelAngle::FromDegrees(-(f * 0.25f))) * + CTransform4f::Scale(0.2f)); + + TToken< CModel > model(x0_model); + CModelFlags flags(CModelFlags::kT_Blend, alphaFader); + model->Draw(flags); + CGraphics::DisableAllLights(); +}