From 042030934b517e93d3a40a18a3aac697beb7fd54 Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Sat, 16 Apr 2016 11:49:47 -1000 Subject: [PATCH] Various CStateManager additions and camera stubs --- Runtime/CEntity.hpp | 3 + Runtime/CGameState.hpp | 2 +- Runtime/CMakeLists.txt | 5 +- Runtime/CObjectList.cpp | 66 +++++++++++++ Runtime/CObjectList.hpp | 64 ++---------- Runtime/CSortedLists.cpp | 18 ++++ Runtime/CSortedLists.hpp | 38 ++++++++ Runtime/CStateManager.cpp | 7 ++ Runtime/CStateManager.hpp | 20 ++++ Runtime/Camera/CBallCamera.cpp | 0 Runtime/Camera/CBallCamera.hpp | 17 ++++ Runtime/Camera/CCameraManager.cpp | 10 ++ Runtime/Camera/CCameraManager.hpp | 39 ++++++++ Runtime/Camera/CCinematicCamera.cpp | 0 Runtime/Camera/CCinematicCamera.hpp | 18 ++++ Runtime/Camera/CFirstPersonCamera.cpp | 0 Runtime/Camera/CFirstPersonCamera.hpp | 17 ++++ Runtime/Camera/CGameCamera.cpp | 0 Runtime/Camera/CGameCamera.hpp | 16 +++ Runtime/Camera/CMakeLists.txt | 7 ++ Runtime/Camera/CPathCamera.cpp | 0 Runtime/Camera/CPathCamera.hpp | 23 +++++ Runtime/Character/CAdditiveAnimPlayback.cpp | 91 ++++++++++++++++- Runtime/Character/CAdditiveAnimPlayback.hpp | 35 ++++--- Runtime/Character/CAnimData.cpp | 42 +++++++- Runtime/Character/CAnimData.hpp | 9 ++ Runtime/Character/CCharacterFactory.cpp | 1 + Runtime/Character/CCharacterInfo.hpp | 2 + Runtime/Character/CInt32POINode.cpp | 3 + Runtime/Character/CInt32POINode.hpp | 1 + Runtime/Character/CMakeLists.txt | 1 + Runtime/Character/CParticleData.hpp | 9 +- Runtime/Character/CParticleDatabase.cpp | 10 ++ Runtime/Character/CParticleDatabase.hpp | 8 ++ Runtime/Character/CParticleGenInfo.cpp | 103 ++++++++++++++++++++ Runtime/Character/CParticleGenInfo.hpp | 82 ++++++++++++++++ Runtime/Character/CParticlePOINode.cpp | 3 + Runtime/Character/CParticlePOINode.hpp | 1 + Runtime/Character/CSoundPOINode.cpp | 7 ++ Runtime/Character/CSoundPOINode.hpp | 1 + Runtime/GameObjectLists.cpp | 27 +++++ Runtime/GameObjectLists.hpp | 53 ++++++++++ Runtime/RetroTypes.hpp | 41 +------- specter | 2 +- 44 files changed, 778 insertions(+), 124 deletions(-) create mode 100644 Runtime/CObjectList.cpp create mode 100644 Runtime/CSortedLists.cpp create mode 100644 Runtime/CSortedLists.hpp create mode 100644 Runtime/Camera/CBallCamera.cpp create mode 100644 Runtime/Camera/CBallCamera.hpp create mode 100644 Runtime/Camera/CCameraManager.cpp create mode 100644 Runtime/Camera/CCameraManager.hpp create mode 100644 Runtime/Camera/CCinematicCamera.cpp create mode 100644 Runtime/Camera/CCinematicCamera.hpp create mode 100644 Runtime/Camera/CFirstPersonCamera.cpp create mode 100644 Runtime/Camera/CFirstPersonCamera.hpp create mode 100644 Runtime/Camera/CGameCamera.cpp create mode 100644 Runtime/Camera/CGameCamera.hpp create mode 100644 Runtime/Camera/CMakeLists.txt create mode 100644 Runtime/Camera/CPathCamera.cpp create mode 100644 Runtime/Camera/CPathCamera.hpp create mode 100644 Runtime/Character/CParticleGenInfo.cpp create mode 100644 Runtime/Character/CParticleGenInfo.hpp create mode 100644 Runtime/GameObjectLists.cpp create mode 100644 Runtime/GameObjectLists.hpp diff --git a/Runtime/CEntity.hpp b/Runtime/CEntity.hpp index 961573d84..19cb1c06a 100644 --- a/Runtime/CEntity.hpp +++ b/Runtime/CEntity.hpp @@ -7,6 +7,7 @@ namespace urde { class CStateManager; +class IVisitor; struct SConnection { @@ -34,12 +35,14 @@ protected: public: virtual ~CEntity() {} CEntity(TUniqueId uid, const CEntityInfo& info, bool active); + virtual void Accept(IVisitor&)=0; virtual void PreThink(float, CStateManager&) {} virtual void Think(float, CStateManager&) {} virtual void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CStateManager& stateMgr); virtual bool GetActive() const {return m_active;} virtual void SetActive(bool active) {m_active = active;} + TUniqueId GetUniqueId() const {return m_uid;} void SendScriptMsgs(EScriptObjectState state, CStateManager& stateMgr, EScriptObjectMessage msg); }; diff --git a/Runtime/CGameState.hpp b/Runtime/CGameState.hpp index 360a66e56..b742debc8 100644 --- a/Runtime/CGameState.hpp +++ b/Runtime/CGameState.hpp @@ -13,7 +13,7 @@ namespace urde class CGameState { int m_stateFlag = -1; - TOneStatic m_playerState; + CPlayerState m_playerState; CWorldTransManager m_transManager; float m_gameTime = 0.0; CGameOptions m_gameOpts; diff --git a/Runtime/CMakeLists.txt b/Runtime/CMakeLists.txt index 03a0dc049..dc8fc78b6 100644 --- a/Runtime/CMakeLists.txt +++ b/Runtime/CMakeLists.txt @@ -4,6 +4,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${BOO_INCLUDE_DIR} add_subdirectory(Audio) add_subdirectory(Character) add_subdirectory(Graphics) +add_subdirectory(Camera) add_subdirectory(GuiSys) add_subdirectory(Input) add_subdirectory(Particle) @@ -48,7 +49,9 @@ add_library(RuntimeCommon IFactory.hpp IObjFactory.hpp ScriptObjectSupport.hpp ScriptObjectSupport.cpp - CObjectList.hpp + CObjectList.hpp CObjectList.cpp + GameObjectLists.hpp GameObjectLists.cpp + CSortedLists.hpp CSortedLists.cpp CArchitectureMessage.hpp CArchitectureQueue.hpp CArchitectureQueue.cpp IObj.hpp diff --git a/Runtime/CObjectList.cpp b/Runtime/CObjectList.cpp new file mode 100644 index 000000000..ec0f49233 --- /dev/null +++ b/Runtime/CObjectList.cpp @@ -0,0 +1,66 @@ +#include "CObjectList.hpp" + +namespace urde +{ + +CObjectList::CObjectList(EGameObjectList listEnum) +: m_listEnum(listEnum) +{} + +void CObjectList::AddObject(CEntity& entity) +{ + if (IsQualified()) + { + if (m_lastId != -1) + m_list[m_lastId].next = entity.GetUniqueId() & 0x3ff; + TUniqueId prevLast = m_lastId; + m_lastId = entity.GetUniqueId() & 0x3ff; + SObjectListEntry& newEnt = m_list[m_lastId]; + newEnt.entity = &entity; + newEnt.prev = prevLast; + newEnt.next = -1; + ++m_count; + } +} + +void CObjectList::RemoveObject(TUniqueId uid) +{ + uid = uid & 0x3ff; + SObjectListEntry& ent = m_list[uid]; + if (!ent.entity || ent.entity->GetUniqueId() != uid) + return; + if (uid == m_lastId) + { + m_lastId = ent.prev; + if (ent.prev != -1) + m_list[ent.prev].next = -1; + } + else + { + if (ent.prev != -1) + m_list[ent.prev].next = -1; + m_list[ent.next].prev = -1; + } + ent.entity = nullptr; + ent.prev = -1; + ent.next = -1; + --m_count; +} + +const CEntity* CObjectList::GetObjectById(TUniqueId uid) const +{ + if (!uid) + return nullptr; + return m_list[uid & 0x3ff].entity; +} + +CEntity* CObjectList::GetObjectById(TUniqueId uid) +{ + if (!uid) + return nullptr; + return m_list[uid & 0x3ff].entity; +} + +bool CObjectList::IsQualified() {return true;} + +} diff --git a/Runtime/CObjectList.hpp b/Runtime/CObjectList.hpp index 1cd450973..e2282be2b 100644 --- a/Runtime/CObjectList.hpp +++ b/Runtime/CObjectList.hpp @@ -32,65 +32,13 @@ class CObjectList TUniqueId m_lastId = -1; u16 m_count = 0; public: - CObjectList(EGameObjectList listEnum) - : m_listEnum(listEnum) - {} + CObjectList(EGameObjectList listEnum); - void AddObject(CEntity& entity) - { - if (IsQualified()) - { - if (m_lastId != -1) - m_list[m_lastId].next = entity.m_uid & 0x3ff; - TUniqueId prevLast = m_lastId; - m_lastId = entity.m_uid & 0x3ff; - SObjectListEntry& newEnt = m_list[m_lastId]; - newEnt.entity = &entity; - newEnt.prev = prevLast; - newEnt.next = -1; - ++m_count; - } - } - - void RemoveObject(TUniqueId uid) - { - uid = uid & 0x3ff; - SObjectListEntry& ent = m_list[uid]; - if (!ent.entity || ent.entity->m_uid != uid) - return; - if (uid == m_lastId) - { - m_lastId = ent.prev; - if (ent.prev != -1) - m_list[ent.prev].next = -1; - } - else - { - if (ent.prev != -1) - m_list[ent.prev].next = -1; - m_list[ent.next].prev = -1; - } - ent.entity = nullptr; - ent.prev = -1; - ent.next = -1; - --m_count; - } - - const CEntity* GetObjectById(TUniqueId uid) const - { - if (!uid) - return nullptr; - return m_list[uid & 0x3ff].entity; - } - - CEntity* GetObjectById(TUniqueId uid) - { - if (!uid) - return nullptr; - return m_list[uid & 0x3ff].entity; - } - - virtual bool IsQualified() {return true;} + void AddObject(CEntity& entity); + void RemoveObject(TUniqueId uid); + const CEntity* GetObjectById(TUniqueId uid) const; + CEntity* GetObjectById(TUniqueId uid); + virtual bool IsQualified(); }; } diff --git a/Runtime/CSortedLists.cpp b/Runtime/CSortedLists.cpp new file mode 100644 index 000000000..23a76cf4c --- /dev/null +++ b/Runtime/CSortedLists.cpp @@ -0,0 +1,18 @@ +#include "CSortedLists.hpp" + +namespace urde +{ + +CSortedListManager::CSortedListManager() +{ + Reset(); +} + +void CSortedListManager::Reset() +{ + std::fill(std::begin(x0_nodes), std::end(x0_nodes), SNode()); + for (int i=0 ; i<6 ; ++i) + xb000_sortedLists[i].Reset(); +} + +} diff --git a/Runtime/CSortedLists.hpp b/Runtime/CSortedLists.hpp new file mode 100644 index 000000000..98d23c4bf --- /dev/null +++ b/Runtime/CSortedLists.hpp @@ -0,0 +1,38 @@ +#ifndef __URDE_CSORTEDLISTS_HPP__ +#define __URDE_CSORTEDLISTS_HPP__ + +#include "RetroTypes.hpp" +#include "zeus/CAABox.hpp" + +namespace urde +{ + +struct SSortedList +{ + TUniqueId x0_ids[1024]; + void Reset() {std::fill(std::begin(x0_ids), std::end(x0_ids), -1);} + SSortedList() {Reset();} +}; + +class CSortedListManager +{ + struct SNode + { + u32 x0_ = 0; + zeus::CAABox x4_box = zeus::CAABox::skNullBox; + u32 x1c_; + u32 x20_; + u32 x24_; + u32 x28_ = -1; + bool x2a_ = false; + }; + SNode x0_nodes[1024]; + SSortedList xb000_sortedLists[6]; +public: + CSortedListManager(); + void Reset(); +}; + +} + +#endif // __URDE_CSORTEDLISTS_HPP__ diff --git a/Runtime/CStateManager.cpp b/Runtime/CStateManager.cpp index a3f8d52b0..a1fa8651d 100644 --- a/Runtime/CStateManager.cpp +++ b/Runtime/CStateManager.cpp @@ -3,6 +3,13 @@ namespace urde { +CStateManager::CStateManager(const std::weak_ptr&, + const std::weak_ptr&, + const std::weak_ptr&, + const std::weak_ptr&) +{ +} + void CStateManager::SendScriptMsg(TUniqueId uid, TEditorId eid, EScriptObjectMessage msg, EScriptObjectState state) { } diff --git a/Runtime/CStateManager.hpp b/Runtime/CStateManager.hpp index e2093451d..f8472ec63 100644 --- a/Runtime/CStateManager.hpp +++ b/Runtime/CStateManager.hpp @@ -4,6 +4,8 @@ #include #include "CBasics.hpp" #include "ScriptObjectSupport.hpp" +#include "GameObjectLists.hpp" +#include "Camera/CCameraManager.hpp" namespace urde { @@ -11,10 +13,27 @@ class CScriptMailbox; class CMapWorldInfo; class CPlayerState; class CWorldTransManager; +class CObjectList; class CStateManager { + TUniqueId x8_idArr[1024] = {}; + std::unique_ptr x80c_allObjs; + std::unique_ptr x814_allObjs; + std::unique_ptr x81c_allObjs; + std::unique_ptr x824_allObjs; + std::unique_ptr x82c_allObjs; + std::unique_ptr x834_allObjs; + std::unique_ptr x83c_allObjs; + std::unique_ptr x844_allObjs; + std::list x858_; + + // x86c_stateManagerContainer; + + + std::shared_ptr x8b8_playerState; + public: CStateManager(const std::weak_ptr&, const std::weak_ptr&, @@ -31,6 +50,7 @@ public: } void SendScriptMsg(TUniqueId uid, TEditorId eid, EScriptObjectMessage msg, EScriptObjectState state); + TUniqueId AllocateUniqueId(); }; } diff --git a/Runtime/Camera/CBallCamera.cpp b/Runtime/Camera/CBallCamera.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/Runtime/Camera/CBallCamera.hpp b/Runtime/Camera/CBallCamera.hpp new file mode 100644 index 000000000..750d6536e --- /dev/null +++ b/Runtime/Camera/CBallCamera.hpp @@ -0,0 +1,17 @@ +#ifndef __URDE_CBALLCAMERA_HPP__ +#define __URDE_CBALLCAMERA_HPP__ + +#include "CGameCamera.hpp" + +namespace urde +{ + +class CBallCamera : public CGameCamera +{ +public: + CBallCamera(TUniqueId, TUniqueId, const zeus::CTransform& xf, float, float, float, float); +}; + +} + +#endif // __URDE_CBALLCAMERA_HPP__ diff --git a/Runtime/Camera/CCameraManager.cpp b/Runtime/Camera/CCameraManager.cpp new file mode 100644 index 000000000..125ad4f1a --- /dev/null +++ b/Runtime/Camera/CCameraManager.cpp @@ -0,0 +1,10 @@ +#include "CCameraManager.hpp" + +namespace urde +{ + +CCameraManager::CCameraManager(TUniqueId id) +{ +} + +} diff --git a/Runtime/Camera/CCameraManager.hpp b/Runtime/Camera/CCameraManager.hpp new file mode 100644 index 000000000..8810123bf --- /dev/null +++ b/Runtime/Camera/CCameraManager.hpp @@ -0,0 +1,39 @@ +#ifndef __URDE_CCAMERAMANAGER_HPP__ +#define __URDE_CCAMERAMANAGER_HPP__ + +#include "RetroTypes.hpp" +#include "zeus/CVector3f.hpp" + +namespace urde +{ +class CFirstPersonCamera; +class CBallCamera; +class CStateManager; + +class CCameraManager +{ + TUniqueId x0_id; + std::vector x4_cineCameras; + CFirstPersonCamera* x7c_fpCamera; + CBallCamera* x80_ballCamera; +public: + CCameraManager(TUniqueId id); + + void SetSpecialCameras(CFirstPersonCamera& fp, CBallCamera& ball) + { + x7c_fpCamera = &fp; + x80_ballCamera = &ball; + } + bool IsInCinematicCamera() const {return x4_cineCameras.size() != 0;} + zeus::CVector3f GetGlobalCameraTranslation(const CStateManager& stateMgr) const; + zeus::CTransform GetGlobalCameraTransform(const CStateManager& stateMgr) const; + void RemoveCameraShaker(int); + void AddCinemaCamera(TUniqueId, CStateManager& stateMgr); + void SetInsideFluid(bool, TUniqueId); + void Update(float dt, CStateManager& stateMgr); + +}; + +} + +#endif // __URDE_CCAMERAMANAGER_HPP__ diff --git a/Runtime/Camera/CCinematicCamera.cpp b/Runtime/Camera/CCinematicCamera.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/Runtime/Camera/CCinematicCamera.hpp b/Runtime/Camera/CCinematicCamera.hpp new file mode 100644 index 000000000..becdeb3c1 --- /dev/null +++ b/Runtime/Camera/CCinematicCamera.hpp @@ -0,0 +1,18 @@ +#ifndef __URDE_CCINEMATICCAMERA_HPP__ +#define __URDE_CCINEMATICCAMERA_HPP__ + +#include "CGameCamera.hpp" + +namespace urde +{ + +class CCinematicCamera : public CGameCamera +{ +public: + CCinematicCamera(TUniqueId, const std::string& name, const CEntityInfo& info, + const zeus::CTransform& xf, bool, float, float, float, float, float, u32); +}; + +} + +#endif // __URDE_CCINEMATICCAMERA_HPP__ diff --git a/Runtime/Camera/CFirstPersonCamera.cpp b/Runtime/Camera/CFirstPersonCamera.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/Runtime/Camera/CFirstPersonCamera.hpp b/Runtime/Camera/CFirstPersonCamera.hpp new file mode 100644 index 000000000..6d1802787 --- /dev/null +++ b/Runtime/Camera/CFirstPersonCamera.hpp @@ -0,0 +1,17 @@ +#ifndef __URDE_CFIRSTPERSONCAMERA_HPP__ +#define __URDE_CFIRSTPERSONCAMERA_HPP__ + +#include "CGameCamera.hpp" + +namespace urde +{ + +class CFirstPersonCamera : public CGameCamera +{ +public: + CFirstPersonCamera(TUniqueId, const zeus::CTransform& xf, TUniqueId, float, float, float, float, float); +}; + +} + +#endif // __URDE_CFIRSTPERSONCAMERA_HPP__ diff --git a/Runtime/Camera/CGameCamera.cpp b/Runtime/Camera/CGameCamera.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/Runtime/Camera/CGameCamera.hpp b/Runtime/Camera/CGameCamera.hpp new file mode 100644 index 000000000..3aa81cad6 --- /dev/null +++ b/Runtime/Camera/CGameCamera.hpp @@ -0,0 +1,16 @@ +#ifndef __URDE_CGAMECAMERA_HPP__ +#define __URDE_CGAMECAMERA_HPP__ + +#include "CActor.hpp" + +namespace urde +{ + +class CGameCamera : public CActor +{ +public: +}; + +} + +#endif // __URDE_CGAMECAMERA_HPP__ diff --git a/Runtime/Camera/CMakeLists.txt b/Runtime/Camera/CMakeLists.txt new file mode 100644 index 000000000..c6f7c020d --- /dev/null +++ b/Runtime/Camera/CMakeLists.txt @@ -0,0 +1,7 @@ +add_library(RuntimeCommonCamera + CCameraManager.hpp CCameraManager.cpp + CGameCamera.hpp CGameCamera.cpp + CFirstPersonCamera.hpp CFirstPersonCamera.cpp + CBallCamera.hpp CBallCamera.cpp + CPathCamera.hpp CPathCamera.cpp + CCinematicCamera.hpp CCinematicCamera.cpp) diff --git a/Runtime/Camera/CPathCamera.cpp b/Runtime/Camera/CPathCamera.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/Runtime/Camera/CPathCamera.hpp b/Runtime/Camera/CPathCamera.hpp new file mode 100644 index 000000000..31c2effbd --- /dev/null +++ b/Runtime/Camera/CPathCamera.hpp @@ -0,0 +1,23 @@ +#ifndef __URDE_CPATHCAMERA_HPP__ +#define __URDE_CPATHCAMERA_HPP__ + +#include "CGameCamera.hpp" + +namespace urde +{ + +class CPathCamera : public CGameCamera +{ +public: + enum class EInitialSplinePosition + { + }; + CPathCamera(TUniqueId, const std::string& name, const CEntityInfo& info, + const zeus::CTransform& xf, bool, bool, bool, bool, bool, + float, float, float, float, float, float, float, u32, + EInitialSplinePosition); +}; + +} + +#endif // __URDE_CPATHCAMERA_HPP__ diff --git a/Runtime/Character/CAdditiveAnimPlayback.cpp b/Runtime/Character/CAdditiveAnimPlayback.cpp index 182197a3c..52bbbd444 100644 --- a/Runtime/Character/CAdditiveAnimPlayback.cpp +++ b/Runtime/Character/CAdditiveAnimPlayback.cpp @@ -1,33 +1,114 @@ #include "CAdditiveAnimPlayback.hpp" #include "CSegStatementSet.hpp" +#include "CCharLayoutInfo.hpp" +#include "CAnimTreeNode.hpp" namespace urde { -CAdditiveAnimPlayback::CAdditiveAnimPlayback(const std::weak_ptr& anim, float weight, bool a, - const CAdditiveAnimationInfo& info, bool b) -: x0_info(info), x8_anim(anim), xc_weight(weight), x14_a(a) +CAdditiveAnimPlayback::CAdditiveAnimPlayback(const std::weak_ptr& anim, + float weight, bool a, const CAdditiveAnimationInfo& info, bool b) +: x0_info(info), x8_anim(anim.lock()), xc_targetWeight(weight), x14_a(a) { if (!a && b) x20_ = true; } void CAdditiveAnimPlayback::AddToSegStatementSet(const CSegIdList& list, - const CCharLayoutInfo&, - CSegStatementSet&) const + const CCharLayoutInfo& layout, + CSegStatementSet& setOut) const { + CSegStatementSet stackSet; + x8_anim->VGetSegStatementSet(list, stackSet); + for (const CSegId& id : list.GetList()) + { + CAnimPerSegmentData& data = stackSet.x4_segData[id]; + data.x10_offset = layout.GetFromParentUnrotated(id); + data.x1c_hasOffset = true; + } + setOut.Add(list, layout, stackSet, x10_curWeight); } void CAdditiveAnimPlayback::Update(float dt) { + switch (x1c_phase) + { + case EAdditivePlaybackPhase::FadingIn: + { + float a = x0_info.GetFadeInDuration(); + float b = x18_weightTimer + dt; + x18_weightTimer = std::min(b, a); + if (a > 0.f) + x10_curWeight = x18_weightTimer / a * xc_targetWeight; + else + x10_curWeight = xc_targetWeight; + + if (std::fabs(x10_curWeight - xc_targetWeight) < 0.00001f) + x1c_phase = EAdditivePlaybackPhase::FadedIn; + + break; + } + case EAdditivePlaybackPhase::FadingOut: + { + float a = x18_weightTimer - dt; + x18_weightTimer = std::max(a, 0.f); + if (x0_info.GetFadeOutDuration() > 0.f) + x10_curWeight = x18_weightTimer / x0_info.GetFadeOutDuration() * xc_targetWeight; + else + x10_curWeight = 0.f; + + if (std::fabs(x10_curWeight) < 0.00001f) + x1c_phase = EAdditivePlaybackPhase::FadedOut; + } + default: break; + } } void CAdditiveAnimPlayback::FadeOut() { + switch (x1c_phase) + { + case EAdditivePlaybackPhase::FadedOut: + case EAdditivePlaybackPhase::FadedIn: + x18_weightTimer = x0_info.GetFadeOutDuration(); + break; + case EAdditivePlaybackPhase::FadingIn: + x18_weightTimer = x18_weightTimer / x0_info.GetFadeInDuration() * x0_info.GetFadeOutDuration(); + default: break; + } + + if (x0_info.GetFadeOutDuration() > 0.f) + x1c_phase = EAdditivePlaybackPhase::FadingOut; + else + x1c_phase = EAdditivePlaybackPhase::FadedOut; + x10_curWeight = 0.f; } void CAdditiveAnimPlayback::SetWeight(float w) { + xc_targetWeight = w; + switch (x1c_phase) + { + case EAdditivePlaybackPhase::FadingIn: + { + if (x0_info.GetFadeInDuration() > 0.f) + x10_curWeight = x18_weightTimer / x0_info.GetFadeInDuration() * xc_targetWeight; + else + x10_curWeight = xc_targetWeight; + break; + } + case EAdditivePlaybackPhase::FadingOut: + { + if (x0_info.GetFadeOutDuration() > 0.f) + x10_curWeight = x18_weightTimer / x0_info.GetFadeOutDuration() * xc_targetWeight; + else + x10_curWeight = xc_targetWeight; + break; + } + default: + x10_curWeight = xc_targetWeight; + break; + } } } diff --git a/Runtime/Character/CAdditiveAnimPlayback.hpp b/Runtime/Character/CAdditiveAnimPlayback.hpp index 6cf825fe6..609aaca3a 100644 --- a/Runtime/Character/CAdditiveAnimPlayback.hpp +++ b/Runtime/Character/CAdditiveAnimPlayback.hpp @@ -13,37 +13,39 @@ class CSegStatementSet; class CAdditiveAnimationInfo { - float x0_a = 0.f; - float x4_b = 0.f; + float x0_fadeInDur = 0.f; + float x4_fadeOutDur = 0.f; public: void read(CInputStream& in) { - x0_a = in.readFloatBig(); - x4_b = in.readFloatBig(); + x0_fadeInDur = in.readFloatBig(); + x4_fadeOutDur = in.readFloatBig(); } CAdditiveAnimationInfo() = default; CAdditiveAnimationInfo(CInputStream& in) {read(in);} + float GetFadeInDuration() const {return x0_fadeInDur;} + float GetFadeOutDuration() const {return x4_fadeOutDur;} }; class CAdditiveAnimPlayback { public: - enum class EAdditivePlaybackState + enum class EAdditivePlaybackPhase { - Zero, - One, - Two, - Three, - Four + None, + FadingIn, + FadingOut, + FadedIn, + FadedOut }; private: CAdditiveAnimationInfo x0_info; - std::weak_ptr x8_anim; - float xc_weight; - float x10_ = 0.f; + std::shared_ptr x8_anim; + float xc_targetWeight; + float x10_curWeight = 0.f; bool x14_a; - float x18_ = 0.f; - EAdditivePlaybackState x1c_ = EAdditivePlaybackState::One; + float x18_weightTimer = 0.f; + EAdditivePlaybackPhase x1c_phase = EAdditivePlaybackPhase::FadingIn; bool x20_ = false; public: CAdditiveAnimPlayback(const std::weak_ptr& anim, float weight, bool a, @@ -53,6 +55,9 @@ public: void Update(float dt); void FadeOut(); void SetWeight(float w); + float GetTargetWeight() const {return xc_targetWeight;} + bool GetA() const {return x14_a;} + const std::shared_ptr& GetAnim() const {return x8_anim;} }; } diff --git a/Runtime/Character/CAnimData.cpp b/Runtime/Character/CAnimData.cpp index e3e08c727..ce02b3010 100644 --- a/Runtime/Character/CAnimData.cpp +++ b/Runtime/Character/CAnimData.cpp @@ -6,10 +6,20 @@ #include "CAnimationManager.hpp" #include "CTransitionManager.hpp" #include "CAdditiveAnimPlayback.hpp" +#include "CBoolPOINode.hpp" +#include "CInt32POINode.hpp" +#include "CParticlePOINode.hpp" +#include "CSoundPOINode.hpp" +#include "CParticleGenInfo.hpp" #include "IAnimReader.hpp" +#include "CAnimTreeNode.hpp" namespace urde { +rstl::reserved_vectorCAnimData::g_BoolPOINodes; +rstl::reserved_vector CAnimData::g_Int32POINodes; +rstl::reserved_vector CAnimData::g_ParticlePOINodes; +rstl::reserved_vector CAnimData::g_SoundPOINodes; void CAnimData::FreeCache() { @@ -45,6 +55,14 @@ CAnimData::CAnimData(ResId id, { if (iceModel) xe4_iceModelData = *iceModel; + + g_BoolPOINodes.resize(8); + g_Int32POINodes.resize(16); + g_ParticlePOINodes.resize(20); + g_SoundPOINodes.resize(20); + + x108_aabb = xd8_modelData->GetModel()->GetAABB(); + x120_particleDB.CacheParticleDesc(xc_charInfo.GetParticleResData()); } ResId CAnimData::GetEventResourceIdForAnimResourceId(ResId id) const @@ -54,12 +72,34 @@ ResId CAnimData::GetEventResourceIdForAnimResourceId(ResId id) const void CAnimData::AddAdditiveSegData(const CSegIdList& list, CSegStatementSet& stSet) { + for (std::pair& additive : x1044_additiveAnims) + if (additive.second.GetTargetWeight() > 0.00001f) + additive.second.AddToSegStatementSet(list, *xcc_layoutData.GetObj(), stSet); } -void CAnimData::AdvanceAdditiveAnims(float) +static void AdvanceAnimationTree(std::weak_ptr& anim, const CCharAnimTime& dt) { } +void CAnimData::AdvanceAdditiveAnims(float dt) +{ + CCharAnimTime time(dt); + + for (std::pair& additive : x1044_additiveAnims) + { + if (additive.second.GetA()) + { + while (time.GreaterThanZero() && std::fabs(time) >= 0.00001f) + { + //additive.second.GetAnim()->GetInt32POIList(time, ); + } + } + else + { + } + } +} + void CAnimData::UpdateAdditiveAnims(float) { } diff --git a/Runtime/Character/CAnimData.hpp b/Runtime/Character/CAnimData.hpp index 94e2fb539..d38bcc557 100644 --- a/Runtime/Character/CAnimData.hpp +++ b/Runtime/Character/CAnimData.hpp @@ -37,6 +37,10 @@ class CAnimTreeNode; class CSegIdList; class CSegStatementSet; class CAdditiveAnimPlayback; +class CBoolPOINode; +class CInt32POINode; +class CParticlePOINode; +class CSoundPOINode; struct SAdvancementDeltas; class CAnimData @@ -99,6 +103,11 @@ class CAnimData u32 x1040_ = 0; rstl::reserved_vector, 8> x1044_additiveAnims; + static rstl::reserved_vector g_BoolPOINodes; + static rstl::reserved_vector g_Int32POINodes; + static rstl::reserved_vector g_ParticlePOINodes; + static rstl::reserved_vector g_SoundPOINodes; + public: CAnimData(ResId, const CCharacterInfo& character, diff --git a/Runtime/Character/CCharacterFactory.cpp b/Runtime/Character/CCharacterFactory.cpp index 1204536d9..cf9f3babc 100644 --- a/Runtime/Character/CCharacterFactory.cpp +++ b/Runtime/Character/CCharacterFactory.cpp @@ -10,6 +10,7 @@ #include "CAnimData.hpp" #include "CAdditiveAnimPlayback.hpp" #include "GameGlobalObjects.hpp" +#include "CParticleGenInfo.hpp" #include "Graphics/CSkinnedModel.hpp" namespace urde diff --git a/Runtime/Character/CCharacterInfo.hpp b/Runtime/Character/CCharacterInfo.hpp index 76a87c54b..7a9295b86 100644 --- a/Runtime/Character/CCharacterInfo.hpp +++ b/Runtime/Character/CCharacterInfo.hpp @@ -47,6 +47,8 @@ public: ResId GetIceModelId() const {return xa8_cmdlOverlay;} ResId GetIceSkinRulesId() const {return xac_cskrOverlay;} + + const CParticleResData& GetParticleResData() const {return x44_partRes;} }; } diff --git a/Runtime/Character/CInt32POINode.cpp b/Runtime/Character/CInt32POINode.cpp index 0fbaf8a20..5981a9f36 100644 --- a/Runtime/Character/CInt32POINode.cpp +++ b/Runtime/Character/CInt32POINode.cpp @@ -4,6 +4,9 @@ namespace urde { +CInt32POINode::CInt32POINode() +: CPOINode("root", 2, CCharAnimTime(), -1, false, 1.f, -1, 0), x38_val(0), x3c_boneName("root") {} + CInt32POINode::CInt32POINode(CInputStream& in) : CPOINode(in), x38_val(in.readUint32Big()), x3c_boneName(in.readString()) {} diff --git a/Runtime/Character/CInt32POINode.hpp b/Runtime/Character/CInt32POINode.hpp index a2a08900a..285e81b00 100644 --- a/Runtime/Character/CInt32POINode.hpp +++ b/Runtime/Character/CInt32POINode.hpp @@ -12,6 +12,7 @@ class CInt32POINode : public CPOINode s32 x38_val; std::string x3c_boneName; public: + CInt32POINode(); CInt32POINode(CInputStream& in); s32 GetValue() const {return x38_val;} const std::string& GetBoneName() const {return x3c_boneName;} diff --git a/Runtime/Character/CMakeLists.txt b/Runtime/Character/CMakeLists.txt index 985ac2ce4..471eabad5 100644 --- a/Runtime/Character/CMakeLists.txt +++ b/Runtime/Character/CMakeLists.txt @@ -61,6 +61,7 @@ add_library(RuntimeCommonCharacter CTimeScaleFunctions.hpp CTimeScaleFunctions.cpp CParticleData.hpp CParticleData.cpp CParticleDatabase.hpp CParticleDatabase.cpp + CParticleGenInfo.hpp CParticleGenInfo.cpp CAnimPOIData.hpp CAnimPOIData.cpp CPOINode.hpp CPOINode.cpp CBoolPOINode.hpp CBoolPOINode.cpp diff --git a/Runtime/Character/CParticleData.hpp b/Runtime/Character/CParticleData.hpp index ab74caf06..9d41d367c 100644 --- a/Runtime/Character/CParticleData.hpp +++ b/Runtime/Character/CParticleData.hpp @@ -17,12 +17,13 @@ public: ContinuousSystem }; private: - u32 x0_duration; + u32 x0_duration = 0; SObjectTag x4_particle; - std::string xc_boneName; - float x1c_scale; - EParentedMode x20_parentMode; + std::string xc_boneName = "root"; + float x1c_scale = 1.f; + EParentedMode x20_parentMode = EParentedMode::Initial; public: + CParticleData() = default; CParticleData(CInputStream& in); EParentedMode GetParentedMode() const {return x20_parentMode;} }; diff --git a/Runtime/Character/CParticleDatabase.cpp b/Runtime/Character/CParticleDatabase.cpp index e69de29bb..e8eb00b94 100644 --- a/Runtime/Character/CParticleDatabase.cpp +++ b/Runtime/Character/CParticleDatabase.cpp @@ -0,0 +1,10 @@ +#include "CParticleDatabase.hpp" + +namespace urde +{ + +void CParticleDatabase::CacheParticleDesc(const CCharacterInfo::CParticleResData& desc) +{ +} + +} diff --git a/Runtime/Character/CParticleDatabase.hpp b/Runtime/Character/CParticleDatabase.hpp index a655317c7..d6498c1f4 100644 --- a/Runtime/Character/CParticleDatabase.hpp +++ b/Runtime/Character/CParticleDatabase.hpp @@ -1,11 +1,19 @@ #ifndef __URDE_CPARTICLEDATABASE_HPP__ #define __URDE_CPARTICLEDATABASE_HPP__ +#include "CCharacterInfo.hpp" +#include "CParticleGenInfo.hpp" +#include + namespace urde { class CParticleDatabase { + std::map> x3c_; +public: + void CacheParticleDesc(const CCharacterInfo::CParticleResData& desc); + void SetModulationColorAllActiveEffects(const zeus::CColor& color); }; } diff --git a/Runtime/Character/CParticleGenInfo.cpp b/Runtime/Character/CParticleGenInfo.cpp new file mode 100644 index 000000000..33be2723c --- /dev/null +++ b/Runtime/Character/CParticleGenInfo.cpp @@ -0,0 +1,103 @@ +#include "CParticleGenInfo.hpp" +#include "Particle/CParticleGen.hpp" + +namespace urde +{ + +CParticleGenInfo::CParticleGenInfo(const SObjectTag& part, int frameCount, const std::string& boneName, + const zeus::CVector3f& scale, CParticleData::EParentedMode parentMode, + int a) +: x4_part(part), xc_seconds(frameCount / 60.f), x10_boneName(boneName), x28_parentMode(parentMode), + x2c_a(a), x30_particleScale(scale) +{} + +static TUniqueId _initializeLight(const std::weak_ptr& system, + CStateManager& stateMgr, int lightId) +{ + std::shared_ptr systemRef = system.lock(); + if (systemRef->SystemHasLight()) + { + + } + return kInvalidUniqueId; +} + +CParticleGenInfoGeneric::CParticleGenInfoGeneric(const SObjectTag& part, + const std::weak_ptr& system, + int frameCount, const std::string& boneName, + const zeus::CVector3f& scale, + CParticleData::EParentedMode parentMode, + int a, CStateManager& stateMgr, int lightId) +: CParticleGenInfo(part, frameCount, boneName, scale, parentMode, a), x80_system(system) +{ + if (lightId == -1) + x84_lightId = kInvalidUniqueId; + else + x84_lightId = _initializeLight(system, stateMgr, lightId); +} + +void CParticleGenInfoGeneric::AddToRenderer() +{ +} + +void CParticleGenInfoGeneric::Render() +{ +} + +void CParticleGenInfoGeneric::Update(float dt, CStateManager& stateMgr) +{ +} + +void CParticleGenInfoGeneric::SetOrientation(const zeus::CTransform& xf, CStateManager& stateMgr) +{ +} + +void CParticleGenInfoGeneric::SetTranslation(const zeus::CVector3f& trans, CStateManager& stateMgr) +{ +} + +void CParticleGenInfoGeneric::SetGlobalOrientation(const zeus::CTransform& xf, CStateManager& stateMgr) +{ +} + +void CParticleGenInfoGeneric::SetGlobalTranslation(const zeus::CVector3f& trans, CStateManager& stateMgr) +{ +} + +void CParticleGenInfoGeneric::SetGlobalScale(const zeus::CVector3f& scale) +{ +} + +void CParticleGenInfoGeneric::SetParticleEmission(bool, CStateManager& stateMgr) +{ +} + +bool CParticleGenInfoGeneric::IsSystemDeletable() const +{ +} + +zeus::CAABox CParticleGenInfoGeneric::GetBounds() const +{ +} + +bool CParticleGenInfoGeneric::HasActiveParticles() const +{ +} + +void CParticleGenInfoGeneric::DestroyParticles() +{ +} + +bool CParticleGenInfoGeneric::HasLight() const +{ +} + +TUniqueId CParticleGenInfoGeneric::GetLightId() const +{ +} + +void CParticleGenInfoGeneric::SetModulationColor(const zeus::CColor& color) +{ +} + +} diff --git a/Runtime/Character/CParticleGenInfo.hpp b/Runtime/Character/CParticleGenInfo.hpp new file mode 100644 index 000000000..4616a7f1c --- /dev/null +++ b/Runtime/Character/CParticleGenInfo.hpp @@ -0,0 +1,82 @@ +#ifndef __URDE_CPARTICLEGENINFO_HPP__ +#define __URDE_CPARTICLEGENINFO_HPP__ + +#include "RetroTypes.hpp" +#include "CParticleData.hpp" +#include "zeus/CVector3f.hpp" +#include "zeus/CAABox.hpp" + +namespace urde +{ +struct SObjectTag; +class CParticleGen; +class CStateManager; + +class CParticleGenInfo +{ + SObjectTag x4_part; + float xc_seconds; + std::string x10_boneName; + float x20_ = 0.f; + bool x24_ = false; + CParticleData::EParentedMode x28_parentMode; + int x2c_a; + zeus::CVector3f x30_particleScale; + float x3c_ = 0.f; + bool x40_ = false; + zeus::CTransform x44_; + zeus::CVector3f x74_; +public: + CParticleGenInfo(const SObjectTag& part, int frameCount, const std::string& boneName, + const zeus::CVector3f&, CParticleData::EParentedMode parentMode, int a); + + virtual ~CParticleGenInfo() = default; + virtual void AddToRenderer()=0; + virtual void Render()=0; + virtual void Update(float dt, CStateManager& stateMgr)=0; + virtual void SetOrientation(const zeus::CTransform& xf, CStateManager& stateMgr)=0; + virtual void SetTranslation(const zeus::CVector3f& trans, CStateManager& stateMgr)=0; + virtual void SetGlobalOrientation(const zeus::CTransform& xf, CStateManager& stateMgr)=0; + virtual void SetGlobalTranslation(const zeus::CVector3f& trans, CStateManager& stateMgr)=0; + virtual void SetGlobalScale(const zeus::CVector3f& scale)=0; + virtual void SetParticleEmission(bool, CStateManager& stateMgr)=0; + virtual bool IsSystemDeletable() const=0; + virtual zeus::CAABox GetBounds() const=0; + virtual bool HasActiveParticles() const=0; + virtual void DestroyParticles()=0; + virtual bool HasLight() const=0; + virtual TUniqueId GetLightId() const=0; + virtual void SetModulationColor(const zeus::CColor& color)=0; +}; + +class CParticleGenInfoGeneric : public CParticleGenInfo +{ + std::shared_ptr x80_system; + TUniqueId x84_lightId; +public: + CParticleGenInfoGeneric(const SObjectTag& part, const std::weak_ptr& system, + int, const std::string& boneName, const zeus::CVector3f& scale, + CParticleData::EParentedMode parentMode, int a, CStateManager& stateMgr, + int lightId); + + void AddToRenderer(); + void Render(); + void Update(float dt, CStateManager& stateMgr); + void SetOrientation(const zeus::CTransform& xf, CStateManager& stateMgr); + void SetTranslation(const zeus::CVector3f& trans, CStateManager& stateMgr); + void SetGlobalOrientation(const zeus::CTransform& xf, CStateManager& stateMgr); + void SetGlobalTranslation(const zeus::CVector3f& trans, CStateManager& stateMgr); + void SetGlobalScale(const zeus::CVector3f& scale); + void SetParticleEmission(bool, CStateManager& stateMgr); + bool IsSystemDeletable() const; + zeus::CAABox GetBounds() const; + bool HasActiveParticles() const; + void DestroyParticles(); + bool HasLight() const; + TUniqueId GetLightId() const; + void SetModulationColor(const zeus::CColor& color); +}; + +} + +#endif // __URDE_CPARTICLEGENINFO_HPP__ diff --git a/Runtime/Character/CParticlePOINode.cpp b/Runtime/Character/CParticlePOINode.cpp index 762cd62d1..6da2c62bc 100644 --- a/Runtime/Character/CParticlePOINode.cpp +++ b/Runtime/Character/CParticlePOINode.cpp @@ -4,6 +4,9 @@ namespace urde { +CParticlePOINode::CParticlePOINode() +: CPOINode("root", 5, CCharAnimTime(), -1, false, 1.f, -1, 0) {} + CParticlePOINode::CParticlePOINode(CInputStream& in) : CPOINode(in), x38_data(in) {} diff --git a/Runtime/Character/CParticlePOINode.hpp b/Runtime/Character/CParticlePOINode.hpp index 7115b2cc6..74a580e34 100644 --- a/Runtime/Character/CParticlePOINode.hpp +++ b/Runtime/Character/CParticlePOINode.hpp @@ -12,6 +12,7 @@ class CParticlePOINode : public CPOINode { CParticleData x38_data; public: + CParticlePOINode(); CParticlePOINode(CInputStream& in); const CParticleData& GetData() const {return x38_data;} diff --git a/Runtime/Character/CSoundPOINode.cpp b/Runtime/Character/CSoundPOINode.cpp index c5ba20da9..c3e2b035e 100644 --- a/Runtime/Character/CSoundPOINode.cpp +++ b/Runtime/Character/CSoundPOINode.cpp @@ -4,6 +4,13 @@ namespace urde { +CSoundPOINode::CSoundPOINode() +: CPOINode("root", 8, CCharAnimTime(), -1, false, 1.f, -1, 0), + x38_sfxId(0), + x3c_falloff(0.f), + x40_maxDist(0.f) +{} + CSoundPOINode::CSoundPOINode(CInputStream& in) : CPOINode(in), x38_sfxId(in.readUint32Big()), diff --git a/Runtime/Character/CSoundPOINode.hpp b/Runtime/Character/CSoundPOINode.hpp index df3752015..4ad0e0c69 100644 --- a/Runtime/Character/CSoundPOINode.hpp +++ b/Runtime/Character/CSoundPOINode.hpp @@ -14,6 +14,7 @@ class CSoundPOINode : public CPOINode float x3c_falloff; float x40_maxDist; public: + CSoundPOINode(); CSoundPOINode(CInputStream& in); CSoundPOINode(const std::string& name, u16 a, const CCharAnimTime& time, u32 b, bool c, diff --git a/Runtime/GameObjectLists.cpp b/Runtime/GameObjectLists.cpp new file mode 100644 index 000000000..eeb31fb34 --- /dev/null +++ b/Runtime/GameObjectLists.cpp @@ -0,0 +1,27 @@ +#include "GameObjectLists.hpp" + +namespace urde +{ + +CActorList::CActorList() +: CObjectList(EGameObjectList::Actor) {} + +CPhysicsActorList::CPhysicsActorList() +: CObjectList(EGameObjectList::PhysicsActor) {} + +CGameCameraList::CGameCameraList() +: CObjectList(EGameObjectList::GameCamera) {} + +CListeningAiList::CListeningAiList() +: CObjectList(EGameObjectList::ListeningAi) {} + +CAiWaypointList::CAiWaypointList() +: CObjectList(EGameObjectList::AiWaypoint) {} + +CPlatformAndDoorList::CPlatformAndDoorList() +: CObjectList(EGameObjectList::PlatformAndDoor) {} + +CGameLightList::CGameLightList() +: CObjectList(EGameObjectList::GameLight) {} + +} diff --git a/Runtime/GameObjectLists.hpp b/Runtime/GameObjectLists.hpp new file mode 100644 index 000000000..f147d6d01 --- /dev/null +++ b/Runtime/GameObjectLists.hpp @@ -0,0 +1,53 @@ +#ifndef __URDE_GAMEOBJECTLISTS_HPP__ +#define __URDE_GAMEOBJECTLISTS_HPP__ + +#include "CObjectList.hpp" + +namespace urde +{ + +class CActorList : public CObjectList +{ +public: + CActorList(); +}; + +class CPhysicsActorList : public CObjectList +{ +public: + CPhysicsActorList(); +}; + +class CGameCameraList : public CObjectList +{ +public: + CGameCameraList(); +}; + +class CListeningAiList : public CObjectList +{ +public: + CListeningAiList(); +}; + +class CAiWaypointList : public CObjectList +{ +public: + CAiWaypointList(); +}; + +class CPlatformAndDoorList : public CObjectList +{ +public: + CPlatformAndDoorList(); +}; + +class CGameLightList : public CObjectList +{ +public: + CGameLightList(); +}; + +} + +#endif // __URDE_GAMEOBJECTLISTS_HPP__ diff --git a/Runtime/RetroTypes.hpp b/Runtime/RetroTypes.hpp index 2069d152b..d15fdeb3a 100644 --- a/Runtime/RetroTypes.hpp +++ b/Runtime/RetroTypes.hpp @@ -31,44 +31,9 @@ struct SObjectTag } }; -/** - * @brief singleton static-allocator - */ -template -class TOneStatic -{ - static u8 m_allocspace[sizeof(T)]; - static u32 m_refCount; -public: - static T* GetAllocSpace() {return (T*)m_allocspace;} - static u32& ReferenceCount() {return m_refCount;} - T* operator->() const {return (T*)m_allocspace;} - T& operator*() const {return *(T*)m_allocspace;} - - void* operator new(size_t) = delete; - void operator delete(void*) = delete; - - template - TOneStatic(typename std::enable_if::value>::type* = 0) - {++m_refCount;} - template - TOneStatic(typename std::enable_if::value>::type* = 0) - {++m_refCount; new (m_allocspace) T();} - - template TOneStatic(Args&&... args) - {++m_refCount; new (m_allocspace) T(std::forward(args)...);} - - ~TOneStatic() {--m_refCount;} - - template void reset(Args&&... args) - {new (m_allocspace) T(std::forward(args)...);} -}; -template u8 TOneStatic::m_allocspace[sizeof(T)]; -template u32 TOneStatic::m_refCount; - -using TUniqueId = u16; -using TEditorId = u32; -using TAreaId = u32; +using TUniqueId = s16; +using TEditorId = s32; +using TAreaId = s32; #define kInvalidEditorId TEditorId(-1) #define kInvalidUniqueId TUniqueId(-1) diff --git a/specter b/specter index 36cd3fbf9..4c668ed85 160000 --- a/specter +++ b/specter @@ -1 +1 @@ -Subproject commit 36cd3fbf9dafdd9c83268593dfcd905edea32a9a +Subproject commit 4c668ed85828e2ac11c160a2536dce60bc62657d