From cac0e328f748253cd33af8f589e27b06ed48af1e Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Fri, 3 Mar 2017 18:31:08 -1000 Subject: [PATCH 1/3] Tons of DrawWorld-related implementations --- DataSpec/DNACommon/Tweaks/ITweakGui.hpp | 6 + DataSpec/DNAMP1/Tweaks/CTweakGui.hpp | 32 ++-- Runtime/CStateManager.cpp | 242 +++++++++++++++++++++++- Runtime/CStateManager.hpp | 6 +- Runtime/Camera/CCameraManager.hpp | 2 +- Runtime/Graphics/CBooRenderer.cpp | 11 +- Runtime/Graphics/CBooRenderer.hpp | 4 +- Runtime/Graphics/CDrawable.hpp | 3 +- Runtime/Graphics/CSimpleShadow.cpp | 5 + Runtime/Graphics/CSimpleShadow.hpp | 3 + Runtime/Graphics/IRenderer.hpp | 5 +- Runtime/Particle/CDecal.cpp | 5 + Runtime/Particle/CDecal.hpp | 2 + Runtime/Particle/CDecalManager.cpp | 18 ++ Runtime/Particle/CDecalManager.hpp | 12 +- Runtime/World/CActor.cpp | 6 +- Runtime/World/CActor.hpp | 7 +- Runtime/World/CActorModelParticles.cpp | 154 +++++++++++++++ Runtime/World/CActorModelParticles.hpp | 79 ++++++++ Runtime/World/CEntity.hpp | 1 + Runtime/World/CGameArea.cpp | 18 ++ Runtime/World/CGameArea.hpp | 5 + Runtime/World/CMakeLists.txt | 1 + Runtime/World/CMorphBallTrail.cpp | 69 +++++++ Runtime/World/CMorphBallTrail.hpp | 36 ++++ Runtime/World/CPlayer.cpp | 2 +- Runtime/World/CPlayer.hpp | 2 +- Runtime/World/CScriptAreaAttributes.cpp | 7 - Runtime/World/CScriptAreaAttributes.hpp | 12 +- Runtime/World/CWorld.cpp | 43 ++++- Runtime/World/CWorld.hpp | 4 + Runtime/World/IGameArea.hpp | 2 +- 32 files changed, 743 insertions(+), 61 deletions(-) create mode 100644 Runtime/World/CMorphBallTrail.cpp create mode 100644 Runtime/World/CMorphBallTrail.hpp diff --git a/DataSpec/DNACommon/Tweaks/ITweakGui.hpp b/DataSpec/DNACommon/Tweaks/ITweakGui.hpp index 89d9768b6..5c921895c 100644 --- a/DataSpec/DNACommon/Tweaks/ITweakGui.hpp +++ b/DataSpec/DNACommon/Tweaks/ITweakGui.hpp @@ -36,6 +36,12 @@ struct ITweakGui : ITweak virtual float GetXrayBlurScaleLinear() const=0; virtual float GetXrayBlurScaleQuadratic() const=0; virtual float GetWorldTransManagerCharsPerSfx() const=0; + virtual atUint32 GetXRayFogMode() const=0; + virtual float GetXRayFogNearZ() const=0; + virtual float GetXRayFogFarZ() const=0; + virtual const zeus::CColor& GetXRayFogColor() const=0; + virtual float GetThermalVisorLevel() const=0; + virtual const zeus::CColor& GetThermalVisorColor() const=0; }; } diff --git a/DataSpec/DNAMP1/Tweaks/CTweakGui.hpp b/DataSpec/DNAMP1/Tweaks/CTweakGui.hpp index 7b76481b6..54e67a9f0 100644 --- a/DataSpec/DNAMP1/Tweaks/CTweakGui.hpp +++ b/DataSpec/DNAMP1/Tweaks/CTweakGui.hpp @@ -151,12 +151,12 @@ struct CTweakGui : ITweakGui Value x274_; bool x275_ = true; Value x278_wtMgrCharsPerSfx; - Value x27c_; - Value x280_; - Value x284_; - DNAColor x288_; - Value x28c_; - DNAColor x290_; + Value x27c_xrayFogMode; + Value x280_xrayFogNearZ; + Value x284_xrayFogFarZ; + DNAColor x288_xrayFogColor; + Value x28c_thermalVisorLevel; + DNAColor x290_thermalVisorColor; DNAColor x294_; DNAColor x298_; DNAColor x29c_; @@ -204,6 +204,12 @@ struct CTweakGui : ITweakGui float GetXrayBlurScaleLinear() const { return x204_xrayBlurScaleLinear; } float GetXrayBlurScaleQuadratic() const { return x208_xrayBlurScaleQuadratic; } float GetWorldTransManagerCharsPerSfx() const { return x278_wtMgrCharsPerSfx; } + atUint32 GetXRayFogMode() const { return x27c_xrayFogMode; } + float GetXRayFogNearZ() const { return x280_xrayFogNearZ; } + float GetXRayFogFarZ() const { return x284_xrayFogFarZ; } + const zeus::CColor& GetXRayFogColor() const { return x288_xrayFogColor; } + float GetThermalVisorLevel() const { return x28c_thermalVisorLevel; } + const zeus::CColor& GetThermalVisorColor() const { return x290_thermalVisorColor; } float GetScanSpeed(int idx) const { @@ -224,14 +230,14 @@ struct CTweakGui : ITweakGui x210_ = zeus::degToRad(x210_); x228_ = x220_ + x224_; - if (x27c_ == 1) - x27c_ = 2; - else if (x27c_ == 2) - x27c_ = 4; - else if (x27c_ == 3) - x27c_ = 5; + if (x27c_xrayFogMode == 1) + x27c_xrayFogMode = 2; + else if (x27c_xrayFogMode == 2) + x27c_xrayFogMode = 4; + else if (x27c_xrayFogMode == 3) + x27c_xrayFogMode = 5; else - x27c_ = 0; + x27c_xrayFogMode = 0; x84_ *= 2.0f; } diff --git a/Runtime/CStateManager.cpp b/Runtime/CStateManager.cpp index 754a43d66..3714915d9 100644 --- a/Runtime/CStateManager.cpp +++ b/Runtime/CStateManager.cpp @@ -30,6 +30,7 @@ #include "Camera/CBallCamera.hpp" #include "Collision/CMaterialFilter.hpp" #include "World/CScriptDock.hpp" +#include "Particle/CDecalManager.hpp" #include @@ -63,6 +64,8 @@ CStateManager::CStateManager(const std::weak_ptr& relayTracker, x884_actorModelParticles = &x86c_stateManagerContainer->xf168_actorModelParticles; x88c_rumbleManager = &x86c_stateManagerContainer->xf250_rumbleManager; + g_Renderer->SetDrawableCallback(&CStateManager::RendererDrawCallback, this); + x90c_loaderFuncs[int(EScriptObjectType::Actor)] = ScriptLoader::LoadActor; x90c_loaderFuncs[int(EScriptObjectType::Waypoint)] = ScriptLoader::LoadWaypoint; x90c_loaderFuncs[int(EScriptObjectType::Door)] = ScriptLoader::LoadDoor; @@ -255,22 +258,44 @@ void CStateManager::UpdateThermalVisor() } } +void CStateManager::RendererDrawCallback(const void* drawable, const void* ctx, int type) +{ + CStateManager& mgr = reinterpret_cast(ctx); + switch (type) + { + case 0: + { + CActor& actor = reinterpret_cast(drawable); + if (actor.xc8_drawnToken == mgr.x8dc_objectDrawToken) + break; + if (actor.xc6_nextDrawNode != kInvalidUniqueId) + mgr.RecursiveDrawTree(actor.xc6_nextDrawNode); + actor.Render(mgr); + actor.xc8_drawnToken = mgr.x8dc_objectDrawToken; + break; + } + case 1: + reinterpret_cast(drawable).Render(mgr.x8f0_shadowTex.GetObj()); + break; + case 2: + reinterpret_cast(drawable).Render(); + break; + default: break; + } +} + bool CStateManager::RenderLast(TUniqueId) { return false; } void CStateManager::AddDrawableActorPlane(const CActor& actor, const zeus::CPlane& plane, const zeus::CAABox& aabb) const { -#if 0 - actor.SetAddedToken(x8dc_ + 1); -#endif + const_cast(actor).SetAddedToken(x8dc_objectDrawToken + 1); g_Renderer->AddPlaneObject(static_cast(&actor), aabb, plane, 0); } void CStateManager::AddDrawableActor(const CActor& actor, const zeus::CVector3f& vec, const zeus::CAABox& aabb) const { -#if 0 - actor.SetAddedToken(x8dc_ + 1); -#endif + const_cast(actor).SetAddedToken(x8dc_objectDrawToken + 1); g_Renderer->AddDrawable(static_cast(&actor), vec, aabb, 0, IRenderer::EDrawableSorting::SortedCallback); } @@ -344,7 +369,10 @@ std::string CStateManager::HashInstanceName(CInputStream& in) void CStateManager::SetActorAreaId(CActor& actor, TAreaId) {} -void CStateManager::TouchSky() const {} +void CStateManager::TouchSky() const +{ + x850_world->TouchSky(); +} void CStateManager::TouchPlayerActor() { @@ -442,10 +470,191 @@ void CStateManager::DrawWorld() const CTimeProvider timeProvider(xf14_); zeus::CFrustum frustum = SetupViewForDraw(g_Viewport); - GetVisAreaId(); + /* Area camera is in (not necessarily player) */ + TAreaId visAreaId = GetVisAreaId(); + + x850_world->TouchSky(); + + int areaCount = 0; + CGameArea* areaArr[10]; + for (CGameArea* area = x850_world->x4c_chainHeads[3]; + area != CWorld::AliveAreasEnd() && areaCount != 10; + area = area->x130_next) + { + CGameArea::EOcclusionState occState = CGameArea::EOcclusionState::NotOccluded; + if (area->IsPostConstructed()) + occState = area->GetOcclusionState(); + if (occState == CGameArea::EOcclusionState::Occluded) + areaArr[areaCount++] = area; + } + + std::sort(std::begin(areaArr), std::begin(areaArr) + areaCount, + [visAreaId](CGameArea* a, CGameArea* b) -> bool + { + if (a->x4_selfIdx == b->x4_selfIdx) + return false; + if (visAreaId == a->x4_selfIdx) + return false; + if (visAreaId == b->x4_selfIdx) + return true; + return CGraphics::g_ViewPoint.dot(a->GetAABB().center()) > + CGraphics::g_ViewPoint.dot(b->GetAABB().center()); + }); + + int pvsCount = 0; + CPVSVisSet pvsArr[10]; + for (CGameArea** area = areaArr; + area != areaArr + areaCount; + ++area) + { + CGameArea* areaPtr = *area; + CPVSVisSet& pvsSet = pvsArr[pvsCount++]; + pvsSet.Reset(EPVSVisSetState::OutOfBounds); + GetVisSetForArea(areaPtr->x4_selfIdx, visAreaId, pvsSet); + } + + int mask; + int targetMask; + CPlayerState::EPlayerVisor visor = x8b8_playerState->GetActiveVisor(*this); + bool thermal = visor == CPlayerState::EPlayerVisor::Thermal; + if (thermal) + { + const_cast(*this).xf34_particleFlags = 1; + mask = 52; + targetMask = 0; + } + else + { + const_cast(*this).xf34_particleFlags = 2; + mask = 1 << (visor == CPlayerState::EPlayerVisor::XRay ? 3 : 1); + targetMask = 0; + } + + g_Renderer->SetThermal(thermal, g_tweakGui->GetThermalVisorLevel(), g_tweakGui->GetThermalVisorColor()); + g_Renderer->SetThermalColdScale(xf28_thermColdScale2 + xf24_thermColdScale1); + + for (int i=areaCount-1 ; i>=0 ; --i) + { + CGameArea& area = *areaArr[i]; + SetupFogForArea(area); + g_Renderer->EnablePVS(&pvsArr[i], area.x4_selfIdx); + g_Renderer->SetWorldLightFadeLevel(area.GetPostConstructed()->x1128_worldLightingLevel); + g_Renderer->DrawUnsortedGeometry(area.x4_selfIdx, mask, targetMask); + } + + if (!SetupFogForDraw()) + g_Renderer->SetWorldFog(ERglFogMode::None, 0.f, 1.f, zeus::CColor::skBlack); + + x850_world->DrawSky(zeus::CTransform::Translate(CGraphics::g_ViewPoint)); + + if (areaCount) + SetupFogForArea(*areaArr[areaCount-1]); + + for (TUniqueId id : x86c_stateManagerContainer->xf370_) + { + if (const CActor* ent = static_cast(GetObjectById(id))) + { + if (!thermal || ent->xe6_27_ & 0x2) + { + ent->Render(*this); + } + } + } + + bool morphingPlayerVisible = false; + int thermalActorCount = 0; + CActor* thermalActorArr[1024]; + for (int i=0 ; iSetWorldLightFadeLevel(area.GetPostConstructed()->x1128_worldLightingLevel); + for (CEntity* ent : *area.GetPostConstructed()->x10c0_areaObjs) + { + if (TCastToPtr actor = ent) + { + if (!actor->xe7_29_) + continue; + TUniqueId actorId = actor->GetUniqueId(); + if (!thermal && area.LookupPVSUniqueID(actorId) == actorId) + if (pvs.GetVisible(area.LookupPVSID(actorId)) == EPVSVisSetState::EndOfTree) + continue; + if (x84c_player.get() == actor.GetPtr()) + { + if (thermal) + continue; + switch (x84c_player->GetMorphballTransitionState()) + { + case CPlayer::EPlayerMorphBallState::Unmorphed: + case CPlayer::EPlayerMorphBallState::Morphed: + x84c_player->AddToRenderer(frustum, *this); + continue; + default: + morphingPlayerVisible = true; + continue; + } + } + if (!thermal || actor->xe6_27_ & 0x2) + actor->AddToRenderer(frustum, *this); + if (thermal && actor->xe6_27_ & 0x4) + thermalActorArr[thermalActorCount++] = actor.GetPtr(); + } + } + + if (isVisArea && !thermal) + { + CDecalManager::AddToRenderer(frustum, *this); + x884_actorModelParticles->AddStragglersToRenderer(*this); + } + + ++const_cast(*this).x8dc_objectDrawToken; + + // TODO: Finish + x84c_player->GetMorphBall(); + } } -void CStateManager::SetupFogForArea(const CGameArea& area) const {} +void CStateManager::SetupFogForArea(const CGameArea& area) const +{ + if (SetupFogForDraw()) + return; + + if (x8b8_playerState->GetActiveVisor(*this) == CPlayerState::EPlayerVisor::XRay) + { + float fogDist = area.GetXRayFogDistance(); + float farz = g_tweakGui->GetXRayFogNearZ() * (1.f - fogDist) + + g_tweakGui->GetXRayFogFarZ() * fogDist; + g_Renderer->SetWorldFog(ERglFogMode(g_tweakGui->GetXRayFogMode()), + g_tweakGui->GetXRayFogNearZ(), + farz, g_tweakGui->GetXRayFogColor()); + } + else + { + area.GetAreaFog()->SetCurrent(); + } +} + +bool CStateManager::SetupFogForDraw() const +{ + switch (x8b8_playerState->GetActiveVisor(*this)) + { + case CPlayerState::EPlayerVisor::Thermal: + g_Renderer->SetWorldFog(ERglFogMode::None, 0.f, 1.f, zeus::CColor::skBlack); + return true; + case CPlayerState::EPlayerVisor::XRay: + default: + return false; + case CPlayerState::EPlayerVisor::Combat: + case CPlayerState::EPlayerVisor::Scan: + auto& fog = x870_cameraManager->Fog(); + if (fog.IsFogDisabled()) + return false; + fog.SetCurrent(); + return true; + } +} void CStateManager::PreRender() { @@ -549,7 +758,20 @@ bool CStateManager::GetVisSetForArea(TAreaId a, TAreaId b, CPVSVisSet& setOut) c return false; } -void CStateManager::RecursiveDrawTree(TUniqueId) const {} +void CStateManager::RecursiveDrawTree(TUniqueId node) const +{ + if (TCastToConstPtr actor = GetObjectById(node)) + { + if (x8dc_objectDrawToken != actor->xc8_drawnToken) + { + if (actor->xc6_nextDrawNode != kInvalidUniqueId) + RecursiveDrawTree(actor->xc6_nextDrawNode); + if (x8dc_objectDrawToken == actor->xcc_addedToken) + actor->Render(*this); + const_cast(actor.GetPtr())->xc8_drawnToken = x8dc_objectDrawToken; + } + } +} void CStateManager::SendScriptMsg(CEntity* dest, TUniqueId src, EScriptObjectMessage msg) { diff --git a/Runtime/CStateManager.hpp b/Runtime/CStateManager.hpp index 53dcb4788..4c61d5420 100644 --- a/Runtime/CStateManager.hpp +++ b/Runtime/CStateManager.hpp @@ -133,6 +133,7 @@ class CStateManager //u32 x8d0_extFrameIdx = 0; //u32 x8d4_updateFrameIdx = 0; //u32 x8d8_drawFrameIdx = 0; + u32 x8dc_objectDrawToken = 0; std::vector x8e0_dynamicLights; @@ -192,7 +193,7 @@ class CStateManager float xf24_thermColdScale1 = 0.f; float xf28_thermColdScale2 = 0.f; zeus::CVector2f xf2c_viewportScale = {1.f, 1.f}; - u32 xf34_ = 2; + u32 xf34_particleFlags = 2; TUniqueId xf38_skipCineSpecialFunc = kInvalidUniqueId; std::list xf3c_; u32 xf50_ = 0; @@ -228,6 +229,7 @@ class CStateManager }; void UpdateThermalVisor(); + static void RendererDrawCallback(const void*, const void*, int); public: /* TODO: Public for CFirstPersonCamera */ @@ -268,6 +270,7 @@ public: zeus::CFrustum SetupViewForDraw(const SViewport& vp) const; void DrawWorld() const; void SetupFogForArea(const CGameArea& area) const; + bool SetupFogForDraw() const; void PreRender(); bool GetVisSetForArea(TAreaId, TAreaId, CPVSVisSet& setOut) const; void RecursiveDrawTree(TUniqueId) const; @@ -394,6 +397,7 @@ public: TUniqueId GetLastRelayId() const { return xf76_lastRelay; } bool GetIsGeneratingObject() const { return xf94_26_generatingObject; } void SetIsGeneratingObject(bool gen) { xf94_26_generatingObject = gen; } + u32 GetParticleFlags() const { return xf34_particleFlags; } }; } diff --git a/Runtime/Camera/CCameraManager.hpp b/Runtime/Camera/CCameraManager.hpp index f5b0ef09c..f1522198d 100644 --- a/Runtime/Camera/CCameraManager.hpp +++ b/Runtime/Camera/CCameraManager.hpp @@ -102,7 +102,7 @@ public: CFirstPersonCamera* GetFirstPersonCamera() { return x7c_fpCamera; } CBallCamera* GetBallCamera() { return x80_ballCamera; } CBallCamera* BallCamera(CStateManager&) const; - CGameArea::CAreaFog Fog() { return x3c_fog; } + CGameArea::CAreaFog& Fog() { return x3c_fog; } float sub80009148() const; diff --git a/Runtime/Graphics/CBooRenderer.cpp b/Runtime/Graphics/CBooRenderer.cpp index dd8330369..db5631089 100644 --- a/Runtime/Graphics/CBooRenderer.cpp +++ b/Runtime/Graphics/CBooRenderer.cpp @@ -231,7 +231,7 @@ void CBooRenderer::RenderBucketItems(CAreaListItem* item) if (xa8_drawableCallback) { xa8_drawableCallback(drawable->GetData(), xac_callbackContext, - int(drawable->GetType()) - 2); + int(drawable->GetType()) - 2); } break; } @@ -512,9 +512,9 @@ void CBooRenderer::AddDrawable(const void* obj, const zeus::CVector3f& pos, cons Buckets::Insert(pos, aabb, EDrawableType(mode + 2), obj, xb0_viewPlane, 0); } -void CBooRenderer::SetDrawableCallback(TDrawableCallback&& cb, const void* ctx) +void CBooRenderer::SetDrawableCallback(TDrawableCallback cb, const void* ctx) { - xa8_drawableCallback = std::move(cb); + xa8_drawableCallback = cb; xac_callbackContext = ctx; } @@ -727,4 +727,9 @@ void CBooRenderer::PrepareDynamicLights(const std::vector& lights) } } +void CBooRenderer::SetWorldLightFadeLevel(float level) +{ + x2fc_tevReg1Color = zeus::CColor(level, level, level, 1.f); +} + } diff --git a/Runtime/Graphics/CBooRenderer.hpp b/Runtime/Graphics/CBooRenderer.hpp index 22425798c..68c822b9f 100644 --- a/Runtime/Graphics/CBooRenderer.hpp +++ b/Runtime/Graphics/CBooRenderer.hpp @@ -111,6 +111,7 @@ class CBooRenderer : public IRenderer float x2f0_thermalVisorLevel; zeus::CColor x2f4_thermColor; float x2f8_thermColdScale = 0.f; + zeus::CColor x2fc_tevReg1Color = {1.f, 0.f, 1.f, 1.f}; CThermalColdFilter m_thermColdFilter; std::experimental::optional m_thermHotFilter; @@ -157,7 +158,7 @@ public: void AddParticleGen(const CParticleGen&); void AddPlaneObject(const void*, const zeus::CAABox&, const zeus::CPlane&, int); void AddDrawable(void const *, const zeus::CVector3f&, const zeus::CAABox&, int, EDrawableSorting); - void SetDrawableCallback(TDrawableCallback&&, const void*); + void SetDrawableCallback(TDrawableCallback, const void*); void SetWorldViewpoint(const zeus::CTransform&); void SetPerspective(float, float, float, float, float); void SetPerspective(float, float, float, float); @@ -203,6 +204,7 @@ public: void DoThermalBlendHot(); u32 GetStaticWorldDataSize(); void PrepareDynamicLights(const std::vector& lights); + void SetWorldLightFadeLevel(float level); boo::ITexture* GetThermoPalette() {return x288_thermoPalette;} diff --git a/Runtime/Graphics/CDrawable.hpp b/Runtime/Graphics/CDrawable.hpp index b24cb0c14..820856162 100644 --- a/Runtime/Graphics/CDrawable.hpp +++ b/Runtime/Graphics/CDrawable.hpp @@ -11,7 +11,8 @@ enum class EDrawableType : u16 WorldSurface, Particle, UnsortedCallback, - SortedCallback + SortedCallback, + Decal }; class CDrawable diff --git a/Runtime/Graphics/CSimpleShadow.cpp b/Runtime/Graphics/CSimpleShadow.cpp index a69ea36b9..458e48369 100644 --- a/Runtime/Graphics/CSimpleShadow.cpp +++ b/Runtime/Graphics/CSimpleShadow.cpp @@ -5,5 +5,10 @@ namespace urde CSimpleShadow::CSimpleShadow(float, float, float, float) { +} + +void CSimpleShadow::Render(const CTexture* tex) +{ + } } diff --git a/Runtime/Graphics/CSimpleShadow.hpp b/Runtime/Graphics/CSimpleShadow.hpp index 69122d37d..c1eff7374 100644 --- a/Runtime/Graphics/CSimpleShadow.hpp +++ b/Runtime/Graphics/CSimpleShadow.hpp @@ -3,11 +3,14 @@ namespace urde { +class CTexture; + class CSimpleShadow { public: CSimpleShadow() = default; CSimpleShadow(float, float, float, float); + void Render(const CTexture* tex); }; } diff --git a/Runtime/Graphics/IRenderer.hpp b/Runtime/Graphics/IRenderer.hpp index c9a69a3f7..77340ff02 100644 --- a/Runtime/Graphics/IRenderer.hpp +++ b/Runtime/Graphics/IRenderer.hpp @@ -25,7 +25,7 @@ struct CAreaRenderOctTree; class IRenderer { public: - using TDrawableCallback = std::function; + typedef void(*TDrawableCallback)(const void*, const void*, int); using TReflectionCallback = std::function; enum class EDrawableSorting @@ -54,7 +54,7 @@ public: virtual void AddParticleGen(const CParticleGen&)=0; virtual void AddPlaneObject(const void*, const zeus::CAABox&, const zeus::CPlane&, int)=0; virtual void AddDrawable(void const *, const zeus::CVector3f&, const zeus::CAABox&, int, EDrawableSorting)=0; - virtual void SetDrawableCallback(TDrawableCallback&&, const void*)=0; + virtual void SetDrawableCallback(TDrawableCallback, const void*)=0; virtual void SetWorldViewpoint(const zeus::CTransform&)=0; virtual void SetPerspective(float, float, float, float, float)=0; virtual void SetPerspective(float, float, float, float)=0; @@ -100,6 +100,7 @@ public: virtual void DoThermalBlendHot()=0; virtual u32 GetStaticWorldDataSize()=0; virtual void PrepareDynamicLights(const std::vector& lights)=0; + virtual void SetWorldLightFadeLevel(float level)=0; }; } diff --git a/Runtime/Particle/CDecal.cpp b/Runtime/Particle/CDecal.cpp index 5768944fd..d482380bb 100644 --- a/Runtime/Particle/CDecal.cpp +++ b/Runtime/Particle/CDecal.cpp @@ -72,4 +72,9 @@ void CDecal::SetMoveRedToAlphaBuffer(bool move) { sMoveRedToAphaBuffer = move; } + +void CDecal::Render() const +{ + +} } diff --git a/Runtime/Particle/CDecal.hpp b/Runtime/Particle/CDecal.hpp index c7b822553..f8117ec3b 100644 --- a/Runtime/Particle/CDecal.hpp +++ b/Runtime/Particle/CDecal.hpp @@ -11,6 +11,7 @@ namespace urde { class CDecal { + friend class CDecalManager; public: struct CQuadDecal { @@ -58,6 +59,7 @@ public: bool IsDone() const; void RenderQuad(CQuadDecal&, const CDecalDescription::SQuadDescr&) const; void RenderMdl() const; + void Render() const; void ProcessQuad(CQuadDecal&, const CDecalDescription::SQuadDescr&, s32) const; void Update(float); void CheckTime(s32, s32); diff --git a/Runtime/Particle/CDecalManager.cpp b/Runtime/Particle/CDecalManager.cpp index 3809036c6..de35bb00f 100644 --- a/Runtime/Particle/CDecalManager.cpp +++ b/Runtime/Particle/CDecalManager.cpp @@ -1,6 +1,9 @@ #include "CDecalManager.hpp" #include "CDecalDescription.hpp" #include "CDecal.hpp" +#include "CStateManager.hpp" +#include "Graphics/CBooRenderer.hpp" +#include "GameGlobalObjects.hpp" namespace urde { @@ -32,4 +35,19 @@ void CDecalManager::Shutdown() } +void CDecalManager::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) +{ + for (s32 idx : m_ActiveIndexList) + { + CDecalManager::SDecal& decal = m_DecalPool[idx]; + if (decal.x75_flags & 0x2 || mgr.GetParticleFlags()) + { + const zeus::CVector3f& point = decal.x0_decal->xc_transform.origin; + zeus::CAABox aabb(point, point); + g_Renderer->AddDrawable(&*decal.x0_decal, point, aabb, 2, + IRenderer::EDrawableSorting::SortedCallback); + } + } +} + } diff --git a/Runtime/Particle/CDecalManager.hpp b/Runtime/Particle/CDecalManager.hpp index 06d85fa31..819292d77 100644 --- a/Runtime/Particle/CDecalManager.hpp +++ b/Runtime/Particle/CDecalManager.hpp @@ -6,17 +6,20 @@ #include "optional.hpp" #include "CToken.hpp" #include "CDecal.hpp" +#include "zeus/CFrustum.hpp" namespace urde { +class CStateManager; + class CDecalManager { struct SDecal { - TAreaId m_areaId; - std::experimental::optional x60_decal; - SDecal() = default; - SDecal(std::experimental::optional&&, TAreaId); + std::experimental::optional x0_decal; + TAreaId x70_areaId; + u8 x74_index; + u8 x75_flags : 2; }; static bool m_PoolInitialized; @@ -29,6 +32,7 @@ class CDecalManager public: static void Initialize(); static void Shutdown(); + static void AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr); }; } diff --git a/Runtime/World/CActor.cpp b/Runtime/World/CActor.cpp index 14dca5139..49d26be07 100644 --- a/Runtime/World/CActor.cpp +++ b/Runtime/World/CActor.cpp @@ -24,7 +24,7 @@ CActor::CActor(TUniqueId uid, bool active, const std::string& name, const CEntit : CEntity(uid, info, active, name) , x68_material(MakeActorMaterialList(list, params)) , x70_materialFilter(CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {0ull})) -, xc6_(otherUid) +, xc6_nextDrawNode(otherUid) { if (mData.x10_animData || mData.x1c_normalModel) x64_modelData = std::make_unique(std::move(mData)); @@ -74,8 +74,8 @@ void CActor::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateMana continue; const CActor* act = TCastToConstPtr(mgr.GetObjectById(mgr.GetIdForScript(conn.x8_objId))); - if (act && xc6_ == kInvalidUniqueId) - xc6_ = act->GetUniqueId(); + if (act && xc6_nextDrawNode == kInvalidUniqueId) + xc6_nextDrawNode = act->GetUniqueId(); } } break; diff --git a/Runtime/World/CActor.hpp b/Runtime/World/CActor.hpp index dcb1222ec..6be7395c1 100644 --- a/Runtime/World/CActor.hpp +++ b/Runtime/World/CActor.hpp @@ -26,6 +26,7 @@ class CSimpleShadow; class CActor : public CEntity { + friend class CStateManager; protected: zeus::CTransform x34_transform; std::unique_ptr x64_modelData; @@ -44,9 +45,9 @@ protected: float xbc_time = 0.f; s32 xc0_ = 0; TUniqueId xc4_fluidId = kInvalidUniqueId; - TUniqueId xc6_ = kInvalidUniqueId; - s32 xc8_ = -1; - s32 xcc_addedToken = -1; + TUniqueId xc6_nextDrawNode = kInvalidUniqueId; + u32 xc8_drawnToken = -1; + u32 xcc_addedToken = -1; float xd0_; u8 xd4_ = 0x7F; u32 xd8_ = 2; diff --git a/Runtime/World/CActorModelParticles.cpp b/Runtime/World/CActorModelParticles.cpp index e69de29bb..70a144a80 100644 --- a/Runtime/World/CActorModelParticles.cpp +++ b/Runtime/World/CActorModelParticles.cpp @@ -0,0 +1,154 @@ +#include "CActorModelParticles.hpp" +#include "CStateManager.hpp" +#include "GameGlobalObjects.hpp" +#include "CSimplePool.hpp" +#include "CDependencyGroup.hpp" +#include "Particle/CElementGen.hpp" +#include "Particle/CParticleElectric.hpp" +#include "Particle/CParticleSwoosh.hpp" +#include "World/CWorld.hpp" +#include "Graphics/CBooRenderer.hpp" + +namespace urde +{ +CActorModelParticles::CItem::CItem(const CEntity& ent, CActorModelParticles& parent) +: x0_id(ent.GetUniqueId()), x4_areaId(ent.GetAreaIdAlways()), + xdc_ashy(parent.x48_ashy), x128_parent(parent) +{ + x8_.resize(8); +} + +static const char* ParticleDGRPs[] = +{ + "Effect_OnFire_DGRP", + "Effect_Ash_DGRP", + "Effect_IceBreak_DGRP", + "Effect_FirePop_DGRP", + "Effect_IcePop_DGRP", + "Effect_Electric_DGRP", +}; + +std::pair, bool> +CActorModelParticles::GetParticleDGRPTokens(const char* name) +{ + std::pair, bool> ret = {}; + TToken dgrp = g_SimplePool->GetObj(name); + const auto& vector = dgrp->GetObjectTagVector(); + ret.first.reserve(vector.size()); + for (const SObjectTag& tag : vector) + ret.first.push_back(g_SimplePool->GetObj(tag)); + return ret; +} + +void CActorModelParticles::LoadParticleDGRPs() +{ + for (int i=0 ; i<6 ; ++i) + x50_dgrps.push_back(GetParticleDGRPTokens(ParticleDGRPs[i])); +} + +std::unique_ptr CActorModelParticles::MakeOnFireGen() const +{ + return std::make_unique(x18_onFire, + CElementGen::EModelOrientationType::Normal, + CElementGen::EOptionalSystemFlags::One); +} + +std::unique_ptr CActorModelParticles::MakeAshGen() const +{ + return std::make_unique(x20_ash, + CElementGen::EModelOrientationType::Normal, + CElementGen::EOptionalSystemFlags::One); +} + +std::unique_ptr CActorModelParticles::MakeIceGen() const +{ + return std::make_unique(x28_iceBreak, + CElementGen::EModelOrientationType::Normal, + CElementGen::EOptionalSystemFlags::One); +} + +std::unique_ptr CActorModelParticles::MakeFirePopGen() const +{ + return std::make_unique(x30_firePop, + CElementGen::EModelOrientationType::Normal, + CElementGen::EOptionalSystemFlags::One); +} + +std::unique_ptr CActorModelParticles::MakeIcePopGen() const +{ + return std::make_unique(x38_icePop, + CElementGen::EModelOrientationType::Normal, + CElementGen::EOptionalSystemFlags::One); +} + +std::unique_ptr CActorModelParticles::MakeElectricGen() const +{ + return std::make_unique(x40_electric); +} + +CActorModelParticles::CActorModelParticles() +{ + x18_onFire = g_SimplePool->GetObj("Effect_OnFire"); + x20_ash = g_SimplePool->GetObj("Effect_Ash"); + x28_iceBreak = g_SimplePool->GetObj("Effect_IceBreak"); + x30_firePop = g_SimplePool->GetObj("Effect_FirePop"); + x38_icePop = g_SimplePool->GetObj("Effect_IcePop"); + x40_electric = g_SimplePool->GetObj("Effect_Electric"); + x48_ashy = g_SimplePool->GetObj("TXTR_Ashy"); + LoadParticleDGRPs(); +} + +void CActorModelParticles::AddStragglersToRenderer(const CStateManager& mgr) +{ + bool isNotOne = mgr.GetParticleFlags() != 1; + bool isNotZero = mgr.GetParticleFlags() != 0; + + for (CItem& item : x0_items) + { + if (item.x4_areaId != kInvalidAreaId) + { + const CGameArea* area = mgr.GetWorld()->GetAreaAlways(item.x4_areaId); + if (!area->IsPostConstructed()) + continue; + CGameArea::EOcclusionState occState = area->GetPostConstructed()->x10dc_occlusionState; + if (occState == CGameArea::EOcclusionState::NotOccluded) + continue; + } + if (mgr.GetObjectById(item.x0_id) && + ((isNotOne && item.x12c_24_) || (isNotZero && item.x12c_25_))) + { + item.x12c_24_ = false; + item.x12c_25_ = false; + continue; + } + if (isNotOne) + { + for (int i=0 ; i<8 ; ++i) + { + std::unique_ptr& gen = item.x8_[i].first; + if (gen) + g_Renderer->AddParticleGen(*gen); + } + if (mgr.GetParticleFlags() && item.x78_) + g_Renderer->AddParticleGen(*item.x78_); + if (item.xb8_) + g_Renderer->AddParticleGen(*item.xb8_); + if (item.xc0_) + g_Renderer->AddParticleGen(*item.xc0_); + } + if (isNotZero) + { + for (std::unique_ptr& gen : item.x8c_) + g_Renderer->AddParticleGen(*gen); + if (item.xe4_) + g_Renderer->AddParticleGen(*item.xe4_); + } + if (isNotOne) + { + item.x12c_24_ = false; + item.x12c_25_ = false; + } + } +} + +} diff --git a/Runtime/World/CActorModelParticles.hpp b/Runtime/World/CActorModelParticles.hpp index 629348e9c..c91f156df 100644 --- a/Runtime/World/CActorModelParticles.hpp +++ b/Runtime/World/CActorModelParticles.hpp @@ -1,11 +1,90 @@ #ifndef __URDE_CACTORMODELPARTICLES_HPP__ #define __URDE_CACTORMODELPARTICLES_HPP__ +#include +#include "Audio/CSfxManager.hpp" +#include "CToken.hpp" +#include "zeus/CTransform.hpp" + namespace urde { +class CStateManager; +class CEntity; +class CElementGen; +class CTexture; +class CElectricDescription; +class CGenDescription; +class CParticleElectric; class CActorModelParticles { + class CItem + { + friend class CActorModelParticles; + TUniqueId x0_id; + TAreaId x4_areaId; + rstl::reserved_vector, u32>, 8> x8_; + float x6c_ = 0.f; + CSfxHandle x74_sfx; + bool x70_ = false; + std::unique_ptr x78_; + u32 x80_ = 0; + u32 x84_ = -1; + u32 x88_ = 99; + rstl::reserved_vector, 4> x8c_; + u32 xb0_ = -1; + u32 xb4_ = 99; + std::unique_ptr xb8_; + std::unique_ptr xc0_; + u32 xc8_ = 0; + u32 xcc_ = 99; + zeus::CColor xd0_; + std::unique_ptr xd4_; + TToken xdc_ashy; + std::unique_ptr xe4_; + float xec_ = 1.f; + float xf0_ = 1.f; + float xf4_ = 1.f; + zeus::CTransform xf8_; + CActorModelParticles& x128_parent; + union + { + struct + { + bool x12c_24_ : 1; + bool x12c_25_ : 1; + }; + u16 _dummy = 0; + }; + float x130_ = 10.f; + u8 x134_bits = 0; + public: + CItem(const CEntity& ent, CActorModelParticles& parent); + }; + + std::list x0_items; + TToken x18_onFire; + TToken x20_ash; + TToken x28_iceBreak; + TToken x30_firePop; + TToken x38_icePop; + TToken x40_electric; + TToken x48_ashy; + rstl::reserved_vector, bool>, 6> x50_dgrps; + + std::pair, bool> GetParticleDGRPTokens(const char* name); + void LoadParticleDGRPs(); + + std::unique_ptr MakeOnFireGen() const; + std::unique_ptr MakeAshGen() const; + std::unique_ptr MakeIceGen() const; + std::unique_ptr MakeFirePopGen() const; + std::unique_ptr MakeIcePopGen() const; + std::unique_ptr MakeElectricGen() const; + +public: + CActorModelParticles(); + void AddStragglersToRenderer(const CStateManager& mgr); }; } diff --git a/Runtime/World/CEntity.hpp b/Runtime/World/CEntity.hpp index e76452ecb..75aff72df 100644 --- a/Runtime/World/CEntity.hpp +++ b/Runtime/World/CEntity.hpp @@ -61,6 +61,7 @@ public: return x4_areaId; return kInvalidAreaId; } + TAreaId GetAreaIdAlways() const { return x4_areaId; } TUniqueId GetUniqueId() const {return x8_uid;} TEditorId GetEditorId() const {return xc_editorId;} void SendScriptMsgs(EScriptObjectState state, CStateManager& stateMgr, EScriptObjectMessage msg); diff --git a/Runtime/World/CGameArea.cpp b/Runtime/World/CGameArea.cpp index 875190bbb..efeea4d06 100644 --- a/Runtime/World/CGameArea.cpp +++ b/Runtime/World/CGameArea.cpp @@ -474,6 +474,14 @@ void CGameArea::SetThermalSpeedAndTarget(float speed, float target) x12c_postConstructed->x1124_thermalTarget = target; } +float CGameArea::GetXRayFogDistance() const +{ + const CScriptAreaAttributes* attrs = x12c_postConstructed->x10d8_areaAttributes; + if (attrs) + return attrs->GetXRayFogDistance(); + return 1.f; +} + bool CGameArea::DoesAreaNeedEnvFx() const { return false; @@ -1030,6 +1038,16 @@ CGameArea::MREAHeader CGameArea::VerifyHeader() const return header; } +TUniqueId CGameArea::LookupPVSUniqueID(TUniqueId id) const +{ + return x12c_postConstructed->xa8_pvsEntityMap[id & 0x3ff].x4_uid; +} + +s16 CGameArea::LookupPVSID(TUniqueId id) const +{ + return x12c_postConstructed->xa8_pvsEntityMap[id & 0x3ff].x0_id; +} + void CGameArea::SetAreaAttributes(const CScriptAreaAttributes* areaAttributes) { x12c_postConstructed->x10d8_areaAttributes = areaAttributes; diff --git a/Runtime/World/CGameArea.hpp b/Runtime/World/CGameArea.hpp index 4ebed4d1b..885dfd254 100644 --- a/Runtime/World/CGameArea.hpp +++ b/Runtime/World/CGameArea.hpp @@ -280,6 +280,7 @@ public: ResId GetAreaAssetId() const { return x84_mrea; } const CAreaFog* GetAreaFog() const { return GetPostConstructed()->x10c4_areaFog.get(); } CAreaFog* AreaFog() { return const_cast(GetAreaFog()); } + float GetXRayFogDistance() const; bool DoesAreaNeedEnvFx() const; bool DoesAreaNeedSkyNow() const; bool OtherAreaOcclusionChanged(); @@ -312,6 +313,8 @@ public: void ClearTokenList(); u32 GetPreConstructedSize() const; MREAHeader VerifyHeader() const; + TUniqueId LookupPVSUniqueID(TUniqueId id) const; + s16 LookupPVSID(TUniqueId id) const; const zeus::CTransform& GetTransform() const {return xc_transform;} const zeus::CTransform& GetInverseTransform() const {return x3c_invTransform;} @@ -329,6 +332,8 @@ public: bool GetActive() const { return xf0_25_active; } void SetActive(bool active) { xf0_25_active = active; } CObjectList& GetAreaObjects() const { return *GetPostConstructed()->x10c0_areaObjs.get(); } + + CGameArea* GetNext() const { return x130_next; } }; } diff --git a/Runtime/World/CMakeLists.txt b/Runtime/World/CMakeLists.txt index c9ec6fec1..ae8ed43bb 100644 --- a/Runtime/World/CMakeLists.txt +++ b/Runtime/World/CMakeLists.txt @@ -8,6 +8,7 @@ set(WORLD_SOURCES CEnergyDrainSource.hpp CEnergyDrainSource.cpp CPlayerCameraBob.hpp CPlayerCameraBob.cpp CMorphBall.hpp CMorphBall.cpp + CMorphBallTrail.hpp CMorphBallTrail.cpp CActor.hpp CActor.cpp CAi.hpp CAi.cpp CAiFuncMap.hpp CAiFuncMap.cpp diff --git a/Runtime/World/CMorphBallTrail.cpp b/Runtime/World/CMorphBallTrail.cpp new file mode 100644 index 000000000..a5e2874c2 --- /dev/null +++ b/Runtime/World/CMorphBallTrail.cpp @@ -0,0 +1,69 @@ +#include "CMorphBallTrail.hpp" +#include "CStateManager.hpp" +#include "World/CWorld.hpp" + +namespace urde +{ + +static union +{ + struct + { + bool x_24_ : 1; + bool x_25_ : 1; + bool x_26_ : 1; + bool x_27_ : 1; + }; + u16 _dummy = 0; +} s_flags; + +CMorphBallTrail::CMorphBallTrail(int w, int h, const TToken& fadeTex) +: xb0_w(w), xb4_h(h), xa8_ballFade(fadeTex) +{ + m_gfxToken = CGraphics::CommitResources([this, w, h](boo::IGraphicsDataFactory::Context& ctx) + { + m_renderTex = ctx.newRenderTexture(w, h, true, false); + return true; + }); +} + +void CMorphBallTrail::GatherAreas(CStateManager& mgr) +{ + x18_areas.clear(); + for (CGameArea* area = mgr.WorldNC()->GetChainHead(EChain::Alive); + area != CWorld::GetAliveAreasEnd(); + area = area->GetNext()) + { + CGameArea::EOcclusionState occState = CGameArea::EOcclusionState::NotOccluded; + if (area->IsPostConstructed()) + occState = area->GetPostConstructed()->x10dc_occlusionState; + if (occState == CGameArea::EOcclusionState::Occluded) + x18_areas.push_back(area); + } +} + +void CMorphBallTrail::RenderToTex(const zeus::CAABox& aabb, CStateManager& mgr, CPlayer& player) +{ + xb8_ = aabb; + x0_.clear(); + x18_areas.clear(); + x30_.clear(); + s_flags.x_26_ = true; + + if (!s_flags.x_27_) + { + xd0_ = false; + return; + } + + GatherAreas(mgr); + + // TODO: finish +} + +void CMorphBallTrail::Render(CStateManager& mgr) +{ + +} + +} diff --git a/Runtime/World/CMorphBallTrail.hpp b/Runtime/World/CMorphBallTrail.hpp new file mode 100644 index 000000000..01608066e --- /dev/null +++ b/Runtime/World/CMorphBallTrail.hpp @@ -0,0 +1,36 @@ +#ifndef __URDE_CMORPHBALLTRAIL_HPP__ +#define __URDE_CMORPHBALLTRAIL_HPP__ + +#include "CToken.hpp" +#include "Graphics/CTexture.hpp" +#include "zeus/CAABox.hpp" + +namespace urde +{ +class CStateManager; +class CPlayer; +class CGameArea; + +class CMorphBallTrail +{ + std::list x0_; + std::list x18_areas; + std::vector x30_; + //CTexture x40_; + boo::GraphicsDataToken m_gfxToken; + boo::ITextureR* m_renderTex; + TToken xa8_ballFade; + int xb0_w; + int xb4_h; + zeus::CAABox xb8_; + bool xd0_ = false; + void GatherAreas(CStateManager& mgr); +public: + CMorphBallTrail(int w, int h, const TToken& fadeTex); + void RenderToTex(const zeus::CAABox& aabb, CStateManager& mgr, CPlayer& player); + void Render(CStateManager& mgr); +}; + +} + +#endif // __URDE_CMORPHBALLTRAIL_HPP__ diff --git a/Runtime/World/CPlayer.cpp b/Runtime/World/CPlayer.cpp index e049a9055..6cf88f4d3 100644 --- a/Runtime/World/CPlayer.cpp +++ b/Runtime/World/CPlayer.cpp @@ -109,7 +109,7 @@ void CPlayer::PreRender(CStateManager& mgr, const zeus::CFrustum&) {} void CPlayer::CalculateRenderBounds() {} -void CPlayer::AddToRenderer(const zeus::CFrustum&, CStateManager&) {} +void CPlayer::AddToRenderer(const zeus::CFrustum&, const CStateManager&) {} void CPlayer::ComputeFreeLook(const CFinalInput& input) {} diff --git a/Runtime/World/CPlayer.hpp b/Runtime/World/CPlayer.hpp index 34efb63c8..5a02a5d62 100644 --- a/Runtime/World/CPlayer.hpp +++ b/Runtime/World/CPlayer.hpp @@ -319,7 +319,7 @@ public: void RenderReflectedPlayer(CStateManager& mgr) const; void PreRender(CStateManager& mgr, const zeus::CFrustum&); void CalculateRenderBounds(); - void AddToRenderer(const zeus::CFrustum&, CStateManager&); + void AddToRenderer(const zeus::CFrustum&, const CStateManager&); void ComputeFreeLook(const CFinalInput& input); void UpdateFreeLook(float dt); float GetMaximumPlayerPositiveVerticalVelocity(CStateManager&) const; diff --git a/Runtime/World/CScriptAreaAttributes.cpp b/Runtime/World/CScriptAreaAttributes.cpp index 2fb650451..faf0f85f6 100644 --- a/Runtime/World/CScriptAreaAttributes.cpp +++ b/Runtime/World/CScriptAreaAttributes.cpp @@ -50,11 +50,4 @@ void CScriptAreaAttributes::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId } } -bool CScriptAreaAttributes::GetNeedsSky() const { return x34_24_showSkybox; } - -bool CScriptAreaAttributes::GetNeedsEnvFx() const { return x38_envFx != EEnvFxType::None; } - -float CScriptAreaAttributes::GetThermalHeat() const { return x40_thermalHeat; } - -float CScriptAreaAttributes::GetWorldLightingLevel() const { return x48_worldLightingLevel; } } diff --git a/Runtime/World/CScriptAreaAttributes.hpp b/Runtime/World/CScriptAreaAttributes.hpp index 98a03d45b..bd111a9a7 100644 --- a/Runtime/World/CScriptAreaAttributes.hpp +++ b/Runtime/World/CScriptAreaAttributes.hpp @@ -25,11 +25,13 @@ public: void Accept(IVisitor& visitor); void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CStateManager& stateMgr); - bool GetNeedsSky() const; - bool GetNeedsEnvFx() const; - float GetEnvFxDensity() const; - float GetThermalHeat() const; - float GetWorldLightingLevel() const; + + bool GetNeedsSky() const { return x34_24_showSkybox; } + bool GetNeedsEnvFx() const { return x38_envFx != EEnvFxType::None; } + float GetEnvFxDensity() const { return x3c_envFxDensity; } + float GetThermalHeat() const { return x40_thermalHeat; } + float GetXRayFogDistance() const { return x44_xrayFogDistance; } + float GetWorldLightingLevel() const { return x48_worldLightingLevel; } }; } diff --git a/Runtime/World/CWorld.cpp b/Runtime/World/CWorld.cpp index bba70daaf..b4005ccd3 100644 --- a/Runtime/World/CWorld.cpp +++ b/Runtime/World/CWorld.cpp @@ -7,6 +7,7 @@ #include "Audio/CAudioGroupSet.hpp" #include "Editor/ProjectResourceFactoryBase.hpp" #include "CGameState.hpp" +#include "Graphics/CBooRenderer.hpp" namespace urde { @@ -237,7 +238,7 @@ void CWorld::MoveToChain(CGameArea* area, EChain chain) void CWorld::MoveAreaToChain3(TAreaId aid) { - MoveToChain(x18_areas[aid].get(), EChain::Three); + MoveToChain(x18_areas[aid].get(), EChain::Alive); } void CWorld::LoadSoundGroup(int groupId, ResId agscId, CSoundGroupData& data) {} @@ -416,13 +417,13 @@ bool CWorld::ScheduleAreaToLoad(CGameArea* area, CStateManager& mgr) } else { - if (area->x138_curChain != EChain::Three) + if (area->x138_curChain != EChain::Alive) { if (area->x138_curChain != EChain::Four) { x70_24_ = true; } - MoveToChain(area, EChain::Three); + MoveToChain(area, EChain::Alive); } return false; } @@ -464,7 +465,7 @@ void CWorld::TravelToArea(TAreaId aid, CStateManager& mgr, bool skipLoadOther) if (area->x138_curChain != EChain::Four) x70_24_ = true; area->Validate(mgr); - MoveToChain(area, EChain::Three); + MoveToChain(area, EChain::Alive); area->SetOcclusionState(CGameArea::EOcclusionState::Occluded); CGameArea* otherLoadArea = nullptr; @@ -581,4 +582,38 @@ void CWorld::PreRender() head->PreRender(); } } + +void CWorld::TouchSky() +{ +#if 0 + if (xa4_skyboxB.IsLoaded()) + xa4_skyboxB->Touch(); + if (xb4_skyboxC.IsLoaded()) + xb4_skyboxC->Touch(); +#endif +} + +void CWorld::DrawSky(const zeus::CTransform& xf) const +{ + const CModel* model; + if (xa4_skyboxB) + model = xa4_skyboxB.GetObj(); + else if (xb4_skyboxC) + model = xb4_skyboxC.GetObj(); + else + return; + + if (!x70_27_) + return; + + CGraphics::DisableAllLights(); + CGraphics::SetModelMatrix(xf); + g_Renderer->SetAmbientColor(zeus::CColor::skWhite); + CGraphics::SetDepthRange(0.999f, 1.f); + + CModelFlags flags(0, 0, 1, zeus::CColor::skWhite); + model->Draw(flags); + + CGraphics::SetDepthRange(0.125f, 1.f); +} } diff --git a/Runtime/World/CWorld.hpp b/Runtime/World/CWorld.hpp index 202dba97a..21c983790 100644 --- a/Runtime/World/CWorld.hpp +++ b/Runtime/World/CWorld.hpp @@ -145,6 +145,7 @@ private: std::string x84_defAudioTrack; TLockedToken x94_skybox; TLockedToken xa4_skyboxB; + TLockedToken xb4_skyboxC; void LoadSoundGroup(int groupId, ResId agscId, CSoundGroupData& data); void LoadSoundGroups(); @@ -154,6 +155,7 @@ public: void MoveToChain(CGameArea* area, EChain chain); void MoveAreaToChain3(TAreaId aid); bool CheckWorldComplete(CStateManager* mgr, TAreaId id, ResId mreaId); + CGameArea* GetChainHead(EChain chain) { return x4c_chainHeads[int(chain)]; } bool ScheduleAreaToLoad(CGameArea* area, CStateManager& mgr); void TravelToArea(TAreaId aid, CStateManager& mgr, bool); void SetPauseState(bool paused); @@ -186,6 +188,8 @@ public: static CGameArea* AliveAreasEnd() { return skGlobalNonConstEnd; } void PreRender(); + void TouchSky(); + void DrawSky(const zeus::CTransform& xf) const; }; struct CWorldLayers diff --git a/Runtime/World/IGameArea.hpp b/Runtime/World/IGameArea.hpp index e7305c368..0e8374454 100644 --- a/Runtime/World/IGameArea.hpp +++ b/Runtime/World/IGameArea.hpp @@ -58,7 +58,7 @@ enum class EChain Zero, One, Two, - Three, + Alive, Four }; From 52fe7954074a2f43bc8c704f7cd91588f6f8af3e Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Fri, 3 Mar 2017 18:58:33 -1000 Subject: [PATCH 2/3] Fix Windows compile fail --- Runtime/CStateManager.cpp | 4 ++-- Runtime/Graphics/CGraphics.cpp | 5 +++-- Runtime/World/CActorModelParticles.cpp | 1 + Runtime/World/CScriptAreaAttributes.cpp | 2 +- Runtime/World/CWorld.cpp | 26 +++++++++---------------- 5 files changed, 16 insertions(+), 22 deletions(-) diff --git a/Runtime/CStateManager.cpp b/Runtime/CStateManager.cpp index 3714915d9..22e3e4f8d 100644 --- a/Runtime/CStateManager.cpp +++ b/Runtime/CStateManager.cpp @@ -477,7 +477,7 @@ void CStateManager::DrawWorld() const int areaCount = 0; CGameArea* areaArr[10]; - for (CGameArea* area = x850_world->x4c_chainHeads[3]; + for (CGameArea* area = x850_world->GetChainHead(EChain::Alive); area != CWorld::AliveAreasEnd() && areaCount != 10; area = area->x130_next) { @@ -671,7 +671,7 @@ void CStateManager::PreRender() proj.setPersp(zeus::SProjPersp{zeus::degToRad(cam->GetFov()), cam->GetAspectRatio(), cam->GetNearClipDistance(), cam->GetFarClipDistance()}); frustum.updatePlanes(x870_cameraManager->GetCurrentCameraTransform(*this), proj); - for (CGameArea* area = x850_world->x4c_chainHeads[3]; + for (CGameArea* area = x850_world->GetChainHead(EChain::Alive); area != CWorld::AliveAreasEnd(); area = area->x130_next) { diff --git a/Runtime/Graphics/CGraphics.cpp b/Runtime/Graphics/CGraphics.cpp index 0d11040e9..76930e192 100644 --- a/Runtime/Graphics/CGraphics.cpp +++ b/Runtime/Graphics/CGraphics.cpp @@ -378,8 +378,9 @@ void CGraphics::FlushProjection() zeus::CVector2i CGraphics::ProjectPoint(const zeus::CVector3f& point) { zeus::CVector3f projPt = GetPerspectiveProjectionMatrix(false).multiplyOneOverW(point); - return {int(projPt.x * g_Viewport.x10_halfWidth) + g_Viewport.x10_halfWidth, - g_Viewport.x14_halfHeight - (int(projPt.y * g_Viewport.x14_halfHeight) + g_Viewport.x14_halfHeight)}; + return {int(projPt.x * g_Viewport.x10_halfWidth) + int(g_Viewport.x10_halfWidth), + int(g_Viewport.x14_halfHeight) - (int(projPt.y * g_Viewport.x14_halfHeight) + + int(g_Viewport.x14_halfHeight))}; } SClipScreenRect CGraphics::ClipScreenRectFromMS(const zeus::CVector3f& p1, diff --git a/Runtime/World/CActorModelParticles.cpp b/Runtime/World/CActorModelParticles.cpp index 70a144a80..cbdda89d8 100644 --- a/Runtime/World/CActorModelParticles.cpp +++ b/Runtime/World/CActorModelParticles.cpp @@ -6,6 +6,7 @@ #include "Particle/CElementGen.hpp" #include "Particle/CParticleElectric.hpp" #include "Particle/CParticleSwoosh.hpp" +#include "Particle/CGenDescription.hpp" #include "World/CWorld.hpp" #include "Graphics/CBooRenderer.hpp" diff --git a/Runtime/World/CScriptAreaAttributes.cpp b/Runtime/World/CScriptAreaAttributes.cpp index faf0f85f6..08445aeab 100644 --- a/Runtime/World/CScriptAreaAttributes.cpp +++ b/Runtime/World/CScriptAreaAttributes.cpp @@ -29,7 +29,7 @@ void CScriptAreaAttributes::Accept(IVisitor& visitor) void CScriptAreaAttributes::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CStateManager& stateMgr) { - AcceptScriptMsg(msg, objId, stateMgr); + CEntity::AcceptScriptMsg(msg, objId, stateMgr); if (x4_areaId == kInvalidAreaId) return; diff --git a/Runtime/World/CWorld.cpp b/Runtime/World/CWorld.cpp index b4005ccd3..c7dce8fc9 100644 --- a/Runtime/World/CWorld.cpp +++ b/Runtime/World/CWorld.cpp @@ -541,34 +541,24 @@ void CWorld::PropogateAreaChain(CGameArea::EOcclusionState occlusionState, CGame if (occlusionState == CGameArea::EOcclusionState::Occluded) area->SetOcclusionState(CGameArea::EOcclusionState::Occluded); - CGameArea* areaItr = world->x4c_chainHeads[3]; - - while (areaItr != skGlobalNonConstEnd) + for (CGameArea* areaItr = world->GetChainHead(EChain::Alive); + areaItr != skGlobalNonConstEnd; + areaItr = areaItr->x130_next) { if (areaItr == area) - { - areaItr = areaItr->x130_next; continue; - } if (areaItr->IsPostConstructed() && areaItr->GetOcclusionState() == CGameArea::EOcclusionState::Occluded) areaItr->PrepTokens(); - areaItr = areaItr->x130_next; } - areaItr = world->x4c_chainHeads[3]; - - while (areaItr != skGlobalNonConstEnd) + for (CGameArea* areaItr = world->GetChainHead(EChain::Alive); + areaItr != skGlobalNonConstEnd; + areaItr = areaItr->x130_next) { if (areaItr == area) - { - areaItr = areaItr->x130_next; continue; - } - - if (area->IsPostConstructed() && areaItr->GetOcclusionState() == CGameArea::EOcclusionState::NotOccluded) areaItr->PrepTokens(); - areaItr = areaItr->x130_next; } if (occlusionState == CGameArea::EOcclusionState::NotOccluded) @@ -577,7 +567,9 @@ void CWorld::PropogateAreaChain(CGameArea::EOcclusionState occlusionState, CGame void CWorld::PreRender() { - for (CGameArea* head = x4c_chainHeads[3] ; head != skGlobalNonConstEnd ; head = head->x130_next) + for (CGameArea* head = x4c_chainHeads[3] ; + head != skGlobalNonConstEnd ; + head = head->x130_next) { head->PreRender(); } From 8ef9ed2c3bf634797f995f9b090299483efc0c2e Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Sat, 4 Mar 2017 21:57:12 -1000 Subject: [PATCH 3/3] Work on CMorphBallShadow --- Runtime/Graphics/CBooRenderer.cpp | 97 ++++++++++++ Runtime/Graphics/CBooRenderer.hpp | 23 +++ Runtime/Graphics/CGraphics.cpp | 10 +- Runtime/Graphics/CGraphics.hpp | 1 + Runtime/Graphics/CModel.hpp | 4 +- Runtime/Graphics/CModelBoo.cpp | 38 ++++- Runtime/Graphics/Shaders/CModelShaders.cpp | 7 + Runtime/Graphics/Shaders/CModelShaders.hpp | 12 ++ .../Graphics/Shaders/CModelShadersGLSL.cpp | 48 ++++++ .../Graphics/Shaders/CModelShadersHLSL.cpp | 40 +++++ .../Graphics/Shaders/CModelShadersMetal.cpp | 43 ++++++ Runtime/World/CActor.cpp | 11 ++ Runtime/World/CActor.hpp | 1 + Runtime/World/CGameArea.cpp | 10 -- Runtime/World/CGameArea.hpp | 5 +- Runtime/World/CMakeLists.txt | 2 +- Runtime/World/CMorphBallShadow.cpp | 143 ++++++++++++++++++ Runtime/World/CMorphBallShadow.hpp | 35 +++++ Runtime/World/CMorphBallTrail.cpp | 69 --------- Runtime/World/CMorphBallTrail.hpp | 36 ----- hecl | 2 +- specter | 2 +- visigen/VISIBuilder.hpp | 2 +- 23 files changed, 509 insertions(+), 132 deletions(-) create mode 100644 Runtime/World/CMorphBallShadow.cpp create mode 100644 Runtime/World/CMorphBallShadow.hpp delete mode 100644 Runtime/World/CMorphBallTrail.cpp delete mode 100644 Runtime/World/CMorphBallTrail.hpp diff --git a/Runtime/Graphics/CBooRenderer.cpp b/Runtime/Graphics/CBooRenderer.cpp index db5631089..6022d9ed6 100644 --- a/Runtime/Graphics/CBooRenderer.cpp +++ b/Runtime/Graphics/CBooRenderer.cpp @@ -295,6 +295,14 @@ void CBooRenderer::LoadThermoPalette() x288_thermoPalette = thermoTexObj->GetPaletteTexture(); } +void CBooRenderer::LoadBallFade() +{ + m_ballFadeTex = xc_store.GetObj("TXTR_BallFade"); + CTexture* ballFadeTexObj = m_ballFadeTex.GetObj(); + if (ballFadeTexObj) + m_ballFade = ballFadeTexObj->GetBooTexture(); +} + CBooRenderer::CBooRenderer(IObjectStore& store, IFactory& resFac) : x8_factory(resFac), xc_store(store), x2a8_thermalRand(20) { @@ -305,9 +313,11 @@ CBooRenderer::CBooRenderer(IObjectStore& store, IFactory& resFac) { GenerateFogVolumeRampTex(ctx); GenerateSphereRampTex(ctx); + m_ballShadowId = ctx.newRenderTexture(m_ballShadowIdW, m_ballShadowIdH, true, false); return true; }); LoadThermoPalette(); + LoadBallFade(); m_thermHotFilter.emplace(); Buckets::Init(); @@ -732,4 +742,91 @@ void CBooRenderer::SetWorldLightFadeLevel(float level) x2fc_tevReg1Color = zeus::CColor(level, level, level, 1.f); } +void CBooRenderer::FindOverlappingWorldModels(std::vector& modelBits, const zeus::CAABox& aabb) const +{ + u32 bitmapWords = 0; + for (const CAreaListItem& item : x1c_areaListItems) + if (item.x4_octTree) + bitmapWords += item.x4_octTree->x14_bitmapWordCount; + + if (!bitmapWords) + { + modelBits.clear(); + return; + } + + modelBits.clear(); + modelBits.resize(bitmapWords); + + u32 curWord = 0; + for (const CAreaListItem& item : x1c_areaListItems) + { + if (!item.x4_octTree) + continue; + + item.x4_octTree->FindOverlappingModels(modelBits.data() + curWord, aabb); + + u32 wordModel = 0; + for (int i=0 ; ix14_bitmapWordCount ; ++i, wordModel += 32) + { + u32& word = modelBits[i]; + if (!word) + continue; + for (int j=0 ; j<32 ; ++j) + { + if ((1 << j) & word) + { + const zeus::CAABox& modelAABB = item.x10_models[wordModel + j]->x20_aabb; + if (!modelAABB.intersects(aabb)) + word &= ~(1 << j); + } + } + } + + curWord += item.x4_octTree->x14_bitmapWordCount; + } +} + +int CBooRenderer::DrawOverlappingWorldModelIDs(int alphaVal, const std::vector& modelBits, + const zeus::CAABox& aabb) const +{ + CModelFlags flags(0, 0, 3, zeus::CColor{1.f, 1.f, 1.f, alphaVal / 255.f}); + flags.m_extendedShaderIdx = 5; // Do solid color draw + + u32 curWord = 0; + for (const CAreaListItem& item : x1c_areaListItems) + { + if (!item.x4_octTree) + continue; + + u32 wordModel = 0; + for (int i=0 ; ix14_bitmapWordCount ; ++i, wordModel += 32) + { + const u32& word = modelBits[i]; + if (!word) + continue; + for (int j=0 ; j<32 ; ++j) + { + if ((1 << j) & word) + { + if (alphaVal > 255) + return alphaVal; + + const CBooModel& model = *item.x10_models[wordModel + j]; + const_cast(model).VerifyCurrentShader(0); + for (const CBooSurface* surf = model.x38_firstUnsortedSurface; surf; surf = surf->m_next) + if (surf->GetBounds().intersects(aabb)) + model.DrawSurface(*surf, flags); + alphaVal += 4; + flags.color.a = alphaVal / 255.f; + } + } + } + + curWord += item.x4_octTree->x14_bitmapWordCount; + } + + return alphaVal; +} + } diff --git a/Runtime/Graphics/CBooRenderer.hpp b/Runtime/Graphics/CBooRenderer.hpp index 68c822b9f..e2730a6e3 100644 --- a/Runtime/Graphics/CBooRenderer.hpp +++ b/Runtime/Graphics/CBooRenderer.hpp @@ -99,6 +99,11 @@ class CBooRenderer : public IRenderer boo::ITextureS* x220_sphereRamp = nullptr; TLockedToken m_thermoPaletteTex; boo::ITexture* x288_thermoPalette = nullptr; + TLockedToken m_ballFadeTex; + boo::ITexture* m_ballFade = nullptr; + boo::ITextureR* m_ballShadowId = nullptr; + int m_ballShadowIdW = 64; + int m_ballShadowIdH = 64; CRandom16 x2a8_thermalRand; std::list x2b8_; @@ -136,6 +141,7 @@ class CBooRenderer : public IRenderer void GenerateFogVolumeRampTex(boo::IGraphicsDataFactory::Context& ctx); void GenerateSphereRampTex(boo::IGraphicsDataFactory::Context& ctx); void LoadThermoPalette(); + void LoadBallFade(); void ActivateLightsForModel(CAreaListItem* item, CBooModel& model); void RenderBucketItems(CAreaListItem* item); @@ -210,6 +216,23 @@ public: void BindMainDrawTarget() {CGraphics::g_BooMainCommandQueue->setRenderTarget(CGraphics::g_SpareTexture);} void BindReflectionDrawTarget() {CGraphics::g_BooMainCommandQueue->setRenderTarget(x14c_reflectionTex);} + void BindBallShadowIdTarget() + { + CGraphics::g_BooMainCommandQueue->setRenderTarget(m_ballShadowId); + SetViewport(0, 0, m_ballShadowIdW, m_ballShadowIdH); + } + void ResolveBallShadowIdTarget() + { + CGraphics::g_BooMainCommandQueue->resolveBindTexture(m_ballShadowId, + boo::SWindowRect(0, 0, + m_ballShadowIdW, + m_ballShadowIdH), + false, true, false); + } + + void FindOverlappingWorldModels(std::vector& modelBits, const zeus::CAABox& aabb) const; + int DrawOverlappingWorldModelIDs(int alphaVal, const std::vector& modelBits, + const zeus::CAABox& aabb) const; }; } diff --git a/Runtime/Graphics/CGraphics.cpp b/Runtime/Graphics/CGraphics.cpp index 76930e192..c6e92fdc3 100644 --- a/Runtime/Graphics/CGraphics.cpp +++ b/Runtime/Graphics/CGraphics.cpp @@ -463,7 +463,7 @@ void CGraphics::SetViewportResolution(const zeus::CVector2i& res) } static boo::SWindowRect CachedVP; -static float CachedDepthRange[2] = {0.f, 1.f}; +zeus::CVector2f CGraphics::g_CachedDepthRange = {0.f, 1.f}; void CGraphics::SetViewport(int leftOff, int bottomOff, int width, int height) { @@ -471,7 +471,7 @@ void CGraphics::SetViewport(int leftOff, int bottomOff, int width, int height) CachedVP.location[1] = bottomOff; CachedVP.size[0] = width; CachedVP.size[1] = height; - g_BooMainCommandQueue->setViewport(CachedVP, CachedDepthRange[0], CachedDepthRange[1]); + g_BooMainCommandQueue->setViewport(CachedVP, g_CachedDepthRange[0], g_CachedDepthRange[1]); } void CGraphics::SetScissor(int leftOff, int bottomOff, int width, int height) @@ -482,9 +482,9 @@ void CGraphics::SetScissor(int leftOff, int bottomOff, int width, int height) void CGraphics::SetDepthRange(float znear, float zfar) { - CachedDepthRange[0] = znear; - CachedDepthRange[1] = zfar; - g_BooMainCommandQueue->setViewport(CachedVP, CachedDepthRange[0], CachedDepthRange[1]); + g_CachedDepthRange[0] = znear; + g_CachedDepthRange[1] = zfar; + g_BooMainCommandQueue->setViewport(CachedVP, g_CachedDepthRange[0], g_CachedDepthRange[1]); } CTimeProvider* CGraphics::g_ExternalTimeProvider = nullptr; diff --git a/Runtime/Graphics/CGraphics.hpp b/Runtime/Graphics/CGraphics.hpp index b28703fdb..5cf50e48a 100644 --- a/Runtime/Graphics/CGraphics.hpp +++ b/Runtime/Graphics/CGraphics.hpp @@ -220,6 +220,7 @@ public: }; static CProjectionState g_Proj; + static zeus::CVector2f g_CachedDepthRange; static CFogState g_Fog; static float g_ProjAspect; static u32 g_NumLightsActive; diff --git a/Runtime/Graphics/CModel.hpp b/Runtime/Graphics/CModel.hpp index b74d8dec9..9c168613e 100644 --- a/Runtime/Graphics/CModel.hpp +++ b/Runtime/Graphics/CModel.hpp @@ -126,8 +126,6 @@ private: void DrawSurfaces(const CModelFlags& flags) const; void DrawSurface(const CBooSurface& surf, const CModelFlags& flags) const; - void VerifyCurrentShader(int shaderIdx); - static zeus::CVector3f g_PlayerPosition; static float g_ModSeconds; static float g_TransformedTime; @@ -152,6 +150,7 @@ public: bool TryLockTextures() const; void UnlockTextures() const; void Touch(int shaderIdx) const; + void VerifyCurrentShader(int shaderIdx); void UpdateUniformData(const CModelFlags& flags, const CSkinRules* cskr, const CPoseAsTransforms* pose) const; @@ -178,6 +177,7 @@ public: static void SetNewPlayerPositionAndTime(const zeus::CVector3f& pos); static void KillCachedViewDepState(); + }; class CModel diff --git a/Runtime/Graphics/CModelBoo.cpp b/Runtime/Graphics/CModelBoo.cpp index 5843fead9..7f33e2364 100644 --- a/Runtime/Graphics/CModelBoo.cpp +++ b/Runtime/Graphics/CModelBoo.cpp @@ -172,6 +172,10 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance() newInst.m_shaderDataBindings.reserve(x0_surfaces->size()); std::vector texs; + texs.resize(8); + boo::ITexture* mbShadowTexs[] = {g_Renderer->m_ballShadowId, + g_Renderer->x220_sphereRamp, + g_Renderer->m_ballFade}; size_t thisOffs[3]; size_t thisSizes[3]; @@ -185,13 +189,11 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance() const MaterialSet::Material& mat = x4_matSet->materials.at(surf.m_data.matIdx); texs.clear(); - texs.reserve(8); for (atUint32 idx : mat.textureIdxs) { TCachedToken& tex = x1c_textures[idx]; texs.push_back(tex.GetObj()->GetBooTexture()); } - texs.resize(8); texs[7] = g_Renderer->x220_sphereRamp; if (m_skinBankCount) @@ -220,11 +222,27 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance() int idx = 0; for (boo::IShaderPipeline* pipeline : pipelines->m_pipelines) { + size_t texCount; + boo::ITexture** ltexs; + if (idx == 2) + { + texCount = 8; + ltexs = texs.data(); + } + else if (idx == 6) + { + texCount = 3; + ltexs = mbShadowTexs; + } + else + { + texCount = mat.textureIdxs.size(); + ltexs = texs.data(); + } extendeds.push_back( ctx.newShaderDataBinding(pipeline, m_vtxFmt, x8_vbo, nullptr, xc_ibo, 3, bufs, stages, - thisOffs, thisSizes, (idx == 2) ? 8 : mat.textureIdxs.size(), - texs.data())); + thisOffs, thisSizes, texCount, ltexs)); ++idx; } } @@ -630,6 +648,18 @@ void CBooModel::UpdateUniformData(const CModelFlags& flags, thermalOut.mulColor = flags.color; thermalOut.addColor = flags.addColor; } + else if (flags.m_extendedShaderIdx == 5) /* Solid color render */ + { + CModelShaders::SolidUniform& solidOut = *reinterpret_cast(dataCur); + solidOut.solidColor = flags.color; + } + else if (flags.m_extendedShaderIdx == 6) /* MorphBall shadow render */ + { + CModelShaders::MBShadowUniform& shadowOut = *reinterpret_cast(dataCur); + shadowOut.shadowUp = CGraphics::g_GXModelView * zeus::CVector3f::skUp; + shadowOut.shadowUp.w = flags.color.a; + shadowOut.shadowId = flags.color.r; + } else { CModelShaders::LightingUniform& lightingOut = *reinterpret_cast(dataCur); diff --git a/Runtime/Graphics/Shaders/CModelShaders.cpp b/Runtime/Graphics/Shaders/CModelShaders.cpp index 62612045a..8a6867b23 100644 --- a/Runtime/Graphics/Shaders/CModelShaders.cpp +++ b/Runtime/Graphics/Shaders/CModelShaders.cpp @@ -32,6 +32,13 @@ const hecl::Backend::TextureInfo CModelShaders::ThermalTextures[] = {hecl::Backend::TexGenSrc::Normal, 7, 0, 7, true} }; +const hecl::Backend::TextureInfo CModelShaders::BallFadeTextures[] = +{ + {hecl::Backend::TexGenSrc::Position, 0, 0, 0, false}, // ID tex + {hecl::Backend::TexGenSrc::Position, 1, 0, 0, false}, // Sphere ramp + {hecl::Backend::TexGenSrc::Position, 2, 0, 1, false} // TXTR_BallFade +}; + CModelShaders::CModelShaders(const hecl::Runtime::FileStoreManager& storeMgr, boo::IGraphicsDataFactory* gfxFactory) : m_shaderCache(storeMgr, gfxFactory, GetShaderExtensions(gfxFactory->platform())) {} diff --git a/Runtime/Graphics/Shaders/CModelShaders.hpp b/Runtime/Graphics/Shaders/CModelShaders.hpp index 52cd1c263..13a561f33 100644 --- a/Runtime/Graphics/Shaders/CModelShaders.hpp +++ b/Runtime/Graphics/Shaders/CModelShaders.hpp @@ -22,6 +22,7 @@ class CModelShaders static hecl::Runtime::ShaderCacheExtensions GetShaderExtensionsHLSL(boo::IGraphicsDataFactory::Platform plat); static hecl::Runtime::ShaderCacheExtensions GetShaderExtensionsMetal(boo::IGraphicsDataFactory::Platform plat); static const hecl::Backend::TextureInfo ThermalTextures[]; + static const hecl::Backend::TextureInfo BallFadeTextures[]; public: struct Light { @@ -47,6 +48,17 @@ public: zeus::CColor addColor; }; + struct SolidUniform + { + zeus::CColor solidColor; + }; + + struct MBShadowUniform + { + zeus::CVector4f shadowUp; + float shadowId; + }; + static void Initialize(const hecl::Runtime::FileStoreManager& storeMgr, boo::IGraphicsDataFactory* gfxFactory); diff --git a/Runtime/Graphics/Shaders/CModelShadersGLSL.cpp b/Runtime/Graphics/Shaders/CModelShadersGLSL.cpp index 0c4b98f07..48c653dcf 100644 --- a/Runtime/Graphics/Shaders/CModelShadersGLSL.cpp +++ b/Runtime/Graphics/Shaders/CModelShadersGLSL.cpp @@ -72,6 +72,35 @@ static const char* ThermalPostGLSL = "}\n" "\n"; +static const char* SolidPostGLSL = +"UBINDING2 uniform SolidUniform\n" +"{\n" +" vec4 solidColor;\n" +"};\n" +"vec4 SolidPostFunc(vec4 colorIn)\n" +"{\n" +" return solidColor;\n" +"}\n" +"\n"; + +static const char* MBShadowPostGLSL = +"UBINDING2 uniform MBShadowUniform\n" +"{\n" +" vec4 shadowUp;\n" +" float shadowId;\n" +"};\n" +"vec4 MBShadowPostFunc(vec4 colorIn)\n" +"{\n" +" float idTexel = texture(tex0, vtf.extTcgs[0]).a;\n" +" float sphereTexel = texture(tex1, vtf.extTcgs[1]).a;\n" +" float fadeTexel = texture(tex2, vtf.extTcgs[2]).a;\n" +" float val = ((abs(idTexel - shadowId) < 0.001) ?\n" +" (dot(vtf.mvNorm.xyz, shadowUp.xyz) * shadowUp.w) : 0.0) *\n" +" sphereTexel * fadeTexel;\n" +" return vec4(0.0, 0.0, 0.0, val);\n" +"}\n" +"\n"; + static const char* BlockNames[] = {HECL_GLSL_VERT_UNIFORM_BLOCK_NAME, HECL_GLSL_TEXMTX_UNIFORM_BLOCK_NAME, "LightingUniform"}; @@ -80,6 +109,14 @@ static const char* ThermalBlockNames[] = {HECL_GLSL_VERT_UNIFORM_BLOCK_NAME, HECL_GLSL_TEXMTX_UNIFORM_BLOCK_NAME, "ThermalUniform"}; +static const char* SolidBlockNames[] = {HECL_GLSL_VERT_UNIFORM_BLOCK_NAME, + HECL_GLSL_TEXMTX_UNIFORM_BLOCK_NAME, + "SolidUniform"}; + +static const char* MBShadowBlockNames[] = {HECL_GLSL_VERT_UNIFORM_BLOCK_NAME, + HECL_GLSL_TEXMTX_UNIFORM_BLOCK_NAME, + "MBShadowUniform"}; + hecl::Runtime::ShaderCacheExtensions CModelShaders::GetShaderExtensionsGLSL(boo::IGraphicsDataFactory::Platform plat) { @@ -105,6 +142,17 @@ CModelShaders::GetShaderExtensionsGLSL(boo::IGraphicsDataFactory::Platform plat) 3, BlockNames, 0, nullptr, hecl::Backend::BlendFactor::One, hecl::Backend::BlendFactor::One); + /* Solid shading */ + ext.registerExtensionSlot({}, {SolidPostGLSL, "SolidPostFunc"}, + 3, SolidBlockNames, 0, nullptr, hecl::Backend::BlendFactor::One, + hecl::Backend::BlendFactor::Zero); + + /* MorphBall shadow shading */ + ext.registerExtensionSlot({}, {MBShadowPostGLSL, "MBShadowPostFunc"}, + 3, MBShadowBlockNames, 3, BallFadeTextures, + hecl::Backend::BlendFactor::SrcAlpha, + hecl::Backend::BlendFactor::InvSrcAlpha); + return ext; } diff --git a/Runtime/Graphics/Shaders/CModelShadersHLSL.cpp b/Runtime/Graphics/Shaders/CModelShadersHLSL.cpp index 3ac9d15e6..44307d919 100644 --- a/Runtime/Graphics/Shaders/CModelShadersHLSL.cpp +++ b/Runtime/Graphics/Shaders/CModelShadersHLSL.cpp @@ -71,6 +71,35 @@ static const char* ThermalPostHLSL = "}\n" "\n"; +static const char* SolidPostHLSL = +"cbuffer SolidUniform : register(b2)\n" +"{\n" +" float4 solidColor;\n" +"};\n" +"static float4 SolidPostFunc(float4 colorIn)\n" +"{\n" +" return solidColor;\n" +"}\n" +"\n"; + +static const char* MBShadowPostHLSL = +"cbuffer MBShadowUniform : register(b2)\n" +"{\n" +" float4 shadowUp;\n" +" float shadowId;\n" +"};\n" +"static float4 MBShadowPostFunc(float4 colorIn)\n" +"{\n" +" float idTexel = extTex0.Sample(samp, vtf.extTcgs[0]).a;\n" +" float sphereTexel = extTex1.Sample(samp, vtf.extTcgs[1]).a;\n" +" float fadeTexel = extTex2.Sample(samp, vtf.extTcgs[2]).a;\n" +" float val = ((abs(idTexel - shadowId) < 0.001) ?\n" +" (dot(vtf.mvNorm.xyz, shadowUp.xyz) * shadowUp.w) : 0.0) *\n" +" sphereTexel * fadeTexel;\n" +" return float4(0.0, 0.0, 0.0, val);\n" +"}\n" +"\n"; + hecl::Runtime::ShaderCacheExtensions CModelShaders::GetShaderExtensionsHLSL(boo::IGraphicsDataFactory::Platform plat) { @@ -96,6 +125,17 @@ CModelShaders::GetShaderExtensionsHLSL(boo::IGraphicsDataFactory::Platform plat) 0, nullptr, 0, nullptr, hecl::Backend::BlendFactor::One, hecl::Backend::BlendFactor::One); + /* Solid shading */ + ext.registerExtensionSlot({}, {SolidPostHLSL, "SolidPostFunc"}, + 0, nullptr, 0, nullptr, hecl::Backend::BlendFactor::One, + hecl::Backend::BlendFactor::Zero); + + /* Solid shading */ + ext.registerExtensionSlot({}, {MBShadowPostHLSL, "MBShadowPostFunc"}, + 0, nullptr, 3, BallFadeTextures, + hecl::Backend::BlendFactor::SrcAlpha, + hecl::Backend::BlendFactor::InvSrcAlpha); + return ext; } diff --git a/Runtime/Graphics/Shaders/CModelShadersMetal.cpp b/Runtime/Graphics/Shaders/CModelShadersMetal.cpp index c5e3c65dc..2086b607b 100644 --- a/Runtime/Graphics/Shaders/CModelShadersMetal.cpp +++ b/Runtime/Graphics/Shaders/CModelShadersMetal.cpp @@ -71,8 +71,40 @@ static const char* ThermalPostMetal = "}\n" "\n"; +static const char* SolidPostMetal = +"struct SolidUniform\n" +"{\n" +" float4 solidColor;\n" +"};\n" +"static float4 SolidPostFunc(thread VertToFrag& vtf, constant SolidUniform& lu, float4 colorIn)\n" +"{\n" +" return lu.solidColor;\n" +"}\n" +"\n"; + +static const char* MBShadowPostMetal = +"UBINDING2 uniform MBShadowUniform\n" +"{\n" +" vec4 shadowUp;\n" +" float shadowId;\n" +"};\n" +"static float4 MBShadowPostFunc(thread VertToFrag& vtf, constant MBShadowUniform& su,\n" +" texture2d tex0, texture2d tex1, texture2d tex2, float4 colorIn)\n" +"{\n" +" float idTexel = tex0.sample(samp, vtf.extTcgs0).a;\n" +" float sphereTexel = tex1.sample(samp, vtf.extTcgs1).a;\n" +" float fadeTexel = tex2.sample(samp, vtf.extTcgs2).a;\n" +" float val = ((fabs(idTexel - su.shadowId) < 0.001) ?\n" +" (dot(vtf.mvNorm.xyz, su.shadowUp.xyz) * su.shadowUp.w) : 0.0) *\n" +" sphereTexel * fadeTexel;\n" +" return float4(0.0, 0.0, 0.0, val);\n" +"}\n" +"\n"; + static const char* BlockNames[] = {"LightingUniform"}; static const char* ThermalBlockNames[] = {"ThermalUniform"}; +static const char* SolidBlockNames[] = {"SolidUniform"}; +static const char* MBShadowBlockNames[] = {"MBShadowUniform"}; hecl::Runtime::ShaderCacheExtensions CModelShaders::GetShaderExtensionsMetal(boo::IGraphicsDataFactory::Platform plat) @@ -99,6 +131,17 @@ CModelShaders::GetShaderExtensionsMetal(boo::IGraphicsDataFactory::Platform plat 1, BlockNames, 0, nullptr, hecl::Backend::BlendFactor::One, hecl::Backend::BlendFactor::One); + /* Solid shading */ + ext.registerExtensionSlot({}, {SolidPostMetal, "SolidPostFunc"}, + 1, SolidBlockNames, 0, nullptr, hecl::Backend::BlendFactor::One, + hecl::Backend::BlendFactor::Zero); + + /* MorphBall shadow shading */ + ext.registerExtensionSlot({}, {MBShadowPostMetal, "MBShadowPostFunc"}, + 1, MBShadowBlockNames, 3, BallFadeTextures, + hecl::Backend::BlendFactor::SrcAlpha, + hecl::Backend::BlendFactor::InvSrcAlpha); + return ext; } diff --git a/Runtime/World/CActor.cpp b/Runtime/World/CActor.cpp index 49d26be07..d2dca9021 100644 --- a/Runtime/World/CActor.cpp +++ b/Runtime/World/CActor.cpp @@ -312,4 +312,15 @@ void CActor::SetActorLights(std::unique_ptr lights) x90_actorLights = std::move(lights); xe4_31_lightsDirty = true; } + +bool CActor::CanDrawStatic() const +{ + if (!x30_24_active) + return false; + + if (x64_modelData && x64_modelData->HasNormalModel()) + return xb4_ <= 4; + + return false; +} } diff --git a/Runtime/World/CActor.hpp b/Runtime/World/CActor.hpp index 6be7395c1..eafd4ab0f 100644 --- a/Runtime/World/CActor.hpp +++ b/Runtime/World/CActor.hpp @@ -161,6 +161,7 @@ public: void EnsureRendered(const CStateManager&, const zeus::CVector3f&, const zeus::CVector3f&); SAdvancementDeltas UpdateAnimation(float, CStateManager&, bool); void SetActorLights(std::unique_ptr); + bool CanDrawStatic() const; bool GetE7_29() const { return xe7_29_; } }; } diff --git a/Runtime/World/CGameArea.cpp b/Runtime/World/CGameArea.cpp index efeea4d06..60ed98268 100644 --- a/Runtime/World/CGameArea.cpp +++ b/Runtime/World/CGameArea.cpp @@ -414,16 +414,6 @@ bool CGameArea::IGetScriptingMemoryAlways() const return false; } -TAreaId CGameArea::IGetAreaId() const -{ - return 0; -} - -ResId CGameArea::IGetAreaAssetId() const -{ - return 0; -} - bool CGameArea::IIsActive() const { return false; diff --git a/Runtime/World/CGameArea.hpp b/Runtime/World/CGameArea.hpp index 885dfd254..62da725c4 100644 --- a/Runtime/World/CGameArea.hpp +++ b/Runtime/World/CGameArea.hpp @@ -266,8 +266,9 @@ public: void SetPauseState(bool paused); bool IGetScriptingMemoryAlways() const; - TAreaId IGetAreaId() const; - ResId IGetAreaAssetId() const; + TAreaId GetAreaId() const { return x4_selfIdx; } + TAreaId IGetAreaId() const { return x4_selfIdx; } + ResId IGetAreaAssetId() const { return x84_mrea; } bool IIsActive() const; TAreaId IGetAttachedAreaId(int) const; u32 IGetNumAttachedAreas() const; diff --git a/Runtime/World/CMakeLists.txt b/Runtime/World/CMakeLists.txt index ae8ed43bb..7d2f3e9fd 100644 --- a/Runtime/World/CMakeLists.txt +++ b/Runtime/World/CMakeLists.txt @@ -8,7 +8,7 @@ set(WORLD_SOURCES CEnergyDrainSource.hpp CEnergyDrainSource.cpp CPlayerCameraBob.hpp CPlayerCameraBob.cpp CMorphBall.hpp CMorphBall.cpp - CMorphBallTrail.hpp CMorphBallTrail.cpp + CMorphBallShadow.hpp CMorphBallShadow.cpp CActor.hpp CActor.cpp CAi.hpp CAi.cpp CAiFuncMap.hpp CAiFuncMap.cpp diff --git a/Runtime/World/CMorphBallShadow.cpp b/Runtime/World/CMorphBallShadow.cpp new file mode 100644 index 000000000..3a61a46f5 --- /dev/null +++ b/Runtime/World/CMorphBallShadow.cpp @@ -0,0 +1,143 @@ +#include "CMorphBallShadow.hpp" +#include "CStateManager.hpp" +#include "World/CWorld.hpp" +#include "GameGlobalObjects.hpp" +#include "Graphics/CBooRenderer.hpp" +#include "World/CPlayer.hpp" + +namespace urde +{ + +static union +{ + struct + { + bool x_24_ : 1; + bool x_25_ : 1; + bool x_26_ : 1; + bool x_27_ : 1; + }; + u16 _dummy = 0; +} s_flags; + +void CMorphBallShadow::GatherAreas(CStateManager& mgr) +{ + x18_areas.clear(); + for (CGameArea* area = mgr.WorldNC()->GetChainHead(EChain::Alive); + area != CWorld::GetAliveAreasEnd(); + area = area->GetNext()) + { + CGameArea::EOcclusionState occState = CGameArea::EOcclusionState::NotOccluded; + if (area->IsPostConstructed()) + occState = area->GetPostConstructed()->x10dc_occlusionState; + if (occState == CGameArea::EOcclusionState::Occluded) + x18_areas.push_back(area->GetAreaId()); + } +} + +void CMorphBallShadow::RenderIdBuffer(const zeus::CAABox& aabb, CStateManager& mgr, CPlayer& player) +{ + xb8_ = aabb; + x0_actors.clear(); + x18_areas.clear(); + x30_worldModelBits.clear(); + s_flags.x_26_ = true; + + if (!s_flags.x_27_) + { + xd0_hasIds = false; + return; + } + + GatherAreas(mgr); + + g_Renderer->BindBallShadowIdTarget(); + CGraphics::g_BooMainCommandQueue->clearTarget(); + + zeus::CTransform backupViewMtx = CGraphics::g_ViewMatrix; + CGraphics::CProjectionState backupProjection = CGraphics::g_Proj; + zeus::CVector2f backupDepth = CGraphics::g_CachedDepthRange; + zeus::CTransform viewMtx(zeus::CVector3f::skRight, zeus::CVector3f::skDown, zeus::CVector3f::skForward, + zeus::CVector3f((aabb.min.x + aabb.max.x) * 0.5f, + (aabb.min.y + aabb.max.y) * 0.5f, + aabb.max.z)); + + CGraphics::SetDepthRange(0.f, 1.f); + float vpX = (aabb.max.x - aabb.min.x) * 0.5f; + float vpY = (aabb.max.y - aabb.min.y) * 0.5f; + float vpZ = (aabb.max.z - aabb.min.z) + FLT_EPSILON; + CGraphics::SetOrtho(-vpX, vpX, vpY, -vpY, 0.f, vpZ); + + rstl::reserved_vector nearItems; + mgr.BuildNearList(nearItems, aabb, CMaterialFilter::skPassEverything, &player); + + CGraphics::SetViewPointMatrix(viewMtx); + + int alphaVal = 4; + for (TUniqueId id : nearItems) + { + if (alphaVal > 255) + break; + + const CActor* actor = static_cast(mgr.GetObjectById(id)); + if (!actor || !actor->CanDrawStatic()) + continue; + + x0_actors.push_back(actor); + + const CModelData* modelData = actor->GetModelData(); + zeus::CTransform modelXf = actor->GetTransform() * zeus::CTransform::Scale(modelData->GetScale()); + CGraphics::SetModelMatrix(modelXf); + + CModelFlags flags(0, 0, 3, zeus::CColor{1.f, 1.f, 1.f, alphaVal / 255.f}); + flags.m_extendedShaderIdx = 5; // Do solid color draw + const CBooModel& model = *modelData->PickStaticModel(CModelData::EWhichModel::Normal); + const_cast(model).VerifyCurrentShader(flags.m_matSetIdx); + model.DrawNormal(flags, nullptr, nullptr); + alphaVal += 4; + } + + CGraphics::SetModelMatrix(zeus::CTransform::Identity()); + + g_Renderer->FindOverlappingWorldModels(x30_worldModelBits, aabb); + alphaVal = g_Renderer->DrawOverlappingWorldModelIDs(alphaVal, x30_worldModelBits, aabb); + + g_Renderer->ResolveBallShadowIdTarget(); + + g_Renderer->BindMainDrawTarget(); + CGraphics::SetViewPointMatrix(backupViewMtx); + CGraphics::SetProjectionState(backupProjection); + CGraphics::SetDepthRange(backupDepth[0], backupDepth[1]); + + xd0_hasIds = alphaVal != 4; +} + +bool CMorphBallShadow::AreasValid(CStateManager& mgr) const +{ + auto it = x18_areas.begin(); + for (CGameArea* area = mgr.WorldNC()->GetChainHead(EChain::Alive); + area != CWorld::GetAliveAreasEnd(); + area = area->GetNext()) + { + CGameArea::EOcclusionState occState = CGameArea::EOcclusionState::NotOccluded; + if (area->IsPostConstructed()) + occState = area->GetPostConstructed()->x10dc_occlusionState; + if (occState != CGameArea::EOcclusionState::Occluded) + continue; + if (it == x18_areas.end()) + return false; + if (*it != area->GetAreaId()) + return false; + ++it; + } + return true; +} + +void CMorphBallShadow::Render(CStateManager& mgr, float alpha) +{ + if (!xd0_hasIds || !AreasValid(mgr)) + return; + +} + +} diff --git a/Runtime/World/CMorphBallShadow.hpp b/Runtime/World/CMorphBallShadow.hpp new file mode 100644 index 000000000..45922efa4 --- /dev/null +++ b/Runtime/World/CMorphBallShadow.hpp @@ -0,0 +1,35 @@ +#ifndef __URDE_CMORPHBALLSHADOW_HPP__ +#define __URDE_CMORPHBALLSHADOW_HPP__ + +#include "CToken.hpp" +#include "Graphics/CTexture.hpp" +#include "zeus/CAABox.hpp" + +namespace urde +{ +class CStateManager; +class CPlayer; +class CGameArea; +class CActor; + +class CMorphBallShadow +{ + std::list x0_actors; + std::list x18_areas; + std::vector x30_worldModelBits; + //CTexture x40_; + //TToken xa8_ballFade; + //int xb0_idW; + //int xb4_idH; + zeus::CAABox xb8_; + bool xd0_hasIds = false; + void GatherAreas(CStateManager& mgr); + bool AreasValid(CStateManager& mgr) const; +public: + void RenderIdBuffer(const zeus::CAABox& aabb, CStateManager& mgr, CPlayer& player); + void Render(CStateManager& mgr, float alpha); +}; + +} + +#endif // __URDE_CMORPHBALLSHADOW_HPP__ diff --git a/Runtime/World/CMorphBallTrail.cpp b/Runtime/World/CMorphBallTrail.cpp deleted file mode 100644 index a5e2874c2..000000000 --- a/Runtime/World/CMorphBallTrail.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#include "CMorphBallTrail.hpp" -#include "CStateManager.hpp" -#include "World/CWorld.hpp" - -namespace urde -{ - -static union -{ - struct - { - bool x_24_ : 1; - bool x_25_ : 1; - bool x_26_ : 1; - bool x_27_ : 1; - }; - u16 _dummy = 0; -} s_flags; - -CMorphBallTrail::CMorphBallTrail(int w, int h, const TToken& fadeTex) -: xb0_w(w), xb4_h(h), xa8_ballFade(fadeTex) -{ - m_gfxToken = CGraphics::CommitResources([this, w, h](boo::IGraphicsDataFactory::Context& ctx) - { - m_renderTex = ctx.newRenderTexture(w, h, true, false); - return true; - }); -} - -void CMorphBallTrail::GatherAreas(CStateManager& mgr) -{ - x18_areas.clear(); - for (CGameArea* area = mgr.WorldNC()->GetChainHead(EChain::Alive); - area != CWorld::GetAliveAreasEnd(); - area = area->GetNext()) - { - CGameArea::EOcclusionState occState = CGameArea::EOcclusionState::NotOccluded; - if (area->IsPostConstructed()) - occState = area->GetPostConstructed()->x10dc_occlusionState; - if (occState == CGameArea::EOcclusionState::Occluded) - x18_areas.push_back(area); - } -} - -void CMorphBallTrail::RenderToTex(const zeus::CAABox& aabb, CStateManager& mgr, CPlayer& player) -{ - xb8_ = aabb; - x0_.clear(); - x18_areas.clear(); - x30_.clear(); - s_flags.x_26_ = true; - - if (!s_flags.x_27_) - { - xd0_ = false; - return; - } - - GatherAreas(mgr); - - // TODO: finish -} - -void CMorphBallTrail::Render(CStateManager& mgr) -{ - -} - -} diff --git a/Runtime/World/CMorphBallTrail.hpp b/Runtime/World/CMorphBallTrail.hpp deleted file mode 100644 index 01608066e..000000000 --- a/Runtime/World/CMorphBallTrail.hpp +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef __URDE_CMORPHBALLTRAIL_HPP__ -#define __URDE_CMORPHBALLTRAIL_HPP__ - -#include "CToken.hpp" -#include "Graphics/CTexture.hpp" -#include "zeus/CAABox.hpp" - -namespace urde -{ -class CStateManager; -class CPlayer; -class CGameArea; - -class CMorphBallTrail -{ - std::list x0_; - std::list x18_areas; - std::vector x30_; - //CTexture x40_; - boo::GraphicsDataToken m_gfxToken; - boo::ITextureR* m_renderTex; - TToken xa8_ballFade; - int xb0_w; - int xb4_h; - zeus::CAABox xb8_; - bool xd0_ = false; - void GatherAreas(CStateManager& mgr); -public: - CMorphBallTrail(int w, int h, const TToken& fadeTex); - void RenderToTex(const zeus::CAABox& aabb, CStateManager& mgr, CPlayer& player); - void Render(CStateManager& mgr); -}; - -} - -#endif // __URDE_CMORPHBALLTRAIL_HPP__ diff --git a/hecl b/hecl index c9948da59..b80547d01 160000 --- a/hecl +++ b/hecl @@ -1 +1 @@ -Subproject commit c9948da598998fe630883639e63b4059adcd9cb3 +Subproject commit b80547d01fb70f349eb6128bd9c44921763f2821 diff --git a/specter b/specter index ccceebc33..717a6bbb1 160000 --- a/specter +++ b/specter @@ -1 +1 @@ -Subproject commit ccceebc331453fd3f71440ab8f14511572e36918 +Subproject commit 717a6bbb1dd3a9dbe9ab85e58033c8ebca163a92 diff --git a/visigen/VISIBuilder.hpp b/visigen/VISIBuilder.hpp index 7a396c78a..0e0a50501 100644 --- a/visigen/VISIBuilder.hpp +++ b/visigen/VISIBuilder.hpp @@ -3,7 +3,7 @@ #include "VISIRenderer.hpp" #include "zeus/CAABox.hpp" -#include "hecl/extern/xxhash/xxhash.h" +#include "hecl/extern/boo/xxhash/xxhash.h" #include "athena/MemoryWriter.hpp" #include "hecl/hecl.hpp" #include