From 7f987ab10ed1873bcbdc21332902adf51d8dd007 Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Sat, 24 Sep 2016 15:58:20 -1000 Subject: [PATCH] Further CGameState imps --- Editor/ProjectResourceFactoryBase.cpp | 36 +++++++ Editor/ProjectResourceFactoryBase.hpp | 5 +- Runtime/AutoMapper/CMapWorldInfo.cpp | 5 + Runtime/AutoMapper/CMapWorldInfo.hpp | 5 +- Runtime/CGameHintInfo.hpp | 1 + Runtime/CGameOptions.cpp | 123 ++++++++++++++++++++++++ Runtime/CGameOptions.hpp | 112 +++++++++++++++++++-- Runtime/CGameState.cpp | 30 +++++- Runtime/CGameState.hpp | 38 +++++++- Runtime/CMainFlowBase.hpp | 1 + Runtime/CMakeLists.txt | 2 +- Runtime/CMemoryCardSys.cpp | 36 +++++++ Runtime/CMemoryCardSys.hpp | 42 ++++++++ Runtime/CResFactory.hpp | 8 ++ Runtime/CSaveWorld.hpp | 1 + Runtime/Character/CAssetFactory.cpp | 10 ++ Runtime/Character/CAssetFactory.hpp | 3 + Runtime/Character/CCharacterFactory.cpp | 9 ++ Runtime/Character/CCharacterFactory.hpp | 3 + Runtime/IFactory.hpp | 3 + Runtime/MP1/CSlideShow.cpp | 109 ++++++++++++++++++++- Runtime/MP1/CSlideShow.hpp | 13 ++- hecl | 2 +- 23 files changed, 575 insertions(+), 22 deletions(-) create mode 100644 Runtime/CMemoryCardSys.cpp diff --git a/Editor/ProjectResourceFactoryBase.cpp b/Editor/ProjectResourceFactoryBase.cpp index d899c3922..fd2b07857 100644 --- a/Editor/ProjectResourceFactoryBase.cpp +++ b/Editor/ProjectResourceFactoryBase.cpp @@ -521,6 +521,7 @@ bool ProjectResourceFactoryBase::WaitForTagReady(const urde::SObjectTag& tag, co while (m_backgroundRunning) { lk.unlock(); + std::this_thread::sleep_for(std::chrono::milliseconds(2)); lk.lock(); search = m_tagToPath.find(tag); if (search != m_tagToPath.end()) @@ -756,6 +757,7 @@ const urde::SObjectTag* ProjectResourceFactoryBase::GetResourceIdByName(const ch while (m_backgroundRunning) { lk.unlock(); + std::this_thread::sleep_for(std::chrono::milliseconds(2)); lk.lock(); search = m_catalogNameToTag.find(lower); if (search != m_catalogNameToTag.end()) @@ -782,6 +784,7 @@ FourCC ProjectResourceFactoryBase::GetResourceTypeById(ResId id) const while (m_backgroundRunning) { lk.unlock(); + std::this_thread::sleep_for(std::chrono::milliseconds(2)); lk.lock(); search = m_tagToPath.find(searchTag); if (search != m_tagToPath.end()) @@ -797,6 +800,39 @@ FourCC ProjectResourceFactoryBase::GetResourceTypeById(ResId id) const return search->first.type; } +void ProjectResourceFactoryBase::EnumerateResources(const std::function& lambda) const +{ + std::unique_lock lk(const_cast(this)->m_backgroundIndexMutex); + while (m_backgroundRunning) + { + lk.unlock(); + std::this_thread::sleep_for(std::chrono::milliseconds(2)); + lk.lock(); + } + for (const auto& pair : m_tagToPath) + { + if (!lambda(pair.first)) + break; + } +} + +void ProjectResourceFactoryBase::EnumerateNamedResources( + const std::function& lambda) const +{ + std::unique_lock lk(const_cast(this)->m_backgroundIndexMutex); + while (m_backgroundRunning) + { + lk.unlock(); + std::this_thread::sleep_for(std::chrono::milliseconds(2)); + lk.lock(); + } + for (const auto& pair : m_catalogNameToTag) + { + if (!lambda(pair.first, pair.second)) + break; + } +} + void ProjectResourceFactoryBase::AsyncIdle() { /* Consume completed transactions, they will be processed this cycle at the latest */ diff --git a/Editor/ProjectResourceFactoryBase.hpp b/Editor/ProjectResourceFactoryBase.hpp index 0af7257c9..2db448887 100644 --- a/Editor/ProjectResourceFactoryBase.hpp +++ b/Editor/ProjectResourceFactoryBase.hpp @@ -14,7 +14,7 @@ namespace urde { -class ProjectResourceFactoryBase : public urde::IFactory +class ProjectResourceFactoryBase : public IFactory { friend class ProjectResourcePool; hecl::ClientProcess& m_clientProc; @@ -121,6 +121,9 @@ public: const urde::SObjectTag* GetResourceIdByName(const char*) const; FourCC GetResourceTypeById(ResId id) const; + void EnumerateResources(const std::function& lambda) const; + void EnumerateNamedResources(const std::function& lambda) const; + u32 ResourceSize(const SObjectTag& tag); std::shared_ptr LoadResourceAsync(const urde::SObjectTag& tag, std::unique_ptr& target); std::shared_ptr LoadResourcePartAsync(const urde::SObjectTag& tag, u32 size, u32 off, std::unique_ptr& target); diff --git a/Runtime/AutoMapper/CMapWorldInfo.cpp b/Runtime/AutoMapper/CMapWorldInfo.cpp index b45264406..e27212be2 100644 --- a/Runtime/AutoMapper/CMapWorldInfo.cpp +++ b/Runtime/AutoMapper/CMapWorldInfo.cpp @@ -3,6 +3,11 @@ namespace urde { +CMapWorldInfo::CMapWorldInfo(CBitStreamReader& reader, const CSaveWorld& saveWorld, ResId mlvlId) +{ + /* TODO: implement */ +} + void CMapWorldInfo::SetDoorVisited(TEditorId eid, bool visited) { x14_[eid] = visited; diff --git a/Runtime/AutoMapper/CMapWorldInfo.hpp b/Runtime/AutoMapper/CMapWorldInfo.hpp index 3ca0c0c9c..3442b5514 100644 --- a/Runtime/AutoMapper/CMapWorldInfo.hpp +++ b/Runtime/AutoMapper/CMapWorldInfo.hpp @@ -5,13 +5,16 @@ namespace urde { +class CSaveWorld; + class CMapWorldInfo { std::vector x4_visitedAreas; std::map x14_; + std::vector x18_visitedAreas; public: CMapWorldInfo()=default; - CMapWorldInfo(CInputStream&); + CMapWorldInfo(CBitStreamReader&, const CSaveWorld& saveWorld, ResId mlvlId); void PutTo(COutputStream&); bool IsMapped() const; void SetIsMapped(bool) const; diff --git a/Runtime/CGameHintInfo.hpp b/Runtime/CGameHintInfo.hpp index f58d10c3b..c0e3553b4 100644 --- a/Runtime/CGameHintInfo.hpp +++ b/Runtime/CGameHintInfo.hpp @@ -34,6 +34,7 @@ private: std::vector x0_hints; public: CGameHintInfo(CInputStream&, s32); + const std::vector& GetHints() const { return x0_hints; } }; CFactoryFnReturn FHintFactory(const SObjectTag&, CInputStream&, const CVParamTransfer, CObjectReference*); diff --git a/Runtime/CGameOptions.cpp b/Runtime/CGameOptions.cpp index 90d6627a6..88b1e2046 100644 --- a/Runtime/CGameOptions.cpp +++ b/Runtime/CGameOptions.cpp @@ -1,6 +1,129 @@ #include "CGameOptions.hpp" +#include "GameGlobalObjects.hpp" +#include "CMemoryCardSys.hpp" +#include "CSimplePool.hpp" +#include "CSaveWorld.hpp" +#include "CGameHintInfo.hpp" namespace urde { +CPersistentOptions::CPersistentOptions(CBitStreamReader& stream) +{ + for (int b=0 ; b<98 ; ++b) + x0_[b] = stream.ReadEncoded(1); + + for (int b=0 ; b<64 ; ++b) + x68_[b] = stream.ReadEncoded(1); + + xc0_ = stream.ReadEncoded(2); + xc4_ = stream.ReadEncoded(2); + xc8_ = stream.ReadEncoded(1); + xcc_ = stream.ReadEncoded(7); + xd0_24_ = stream.ReadEncoded(1); + xd0_25_ = stream.ReadEncoded(1); + xd0_26_ = stream.ReadEncoded(1); + xd0_27_ = stream.ReadEncoded(1); + xd0_28_ = stream.ReadEncoded(1); + xd0_29_ = stream.ReadEncoded(1); + xbc_ = stream.ReadEncoded(2); + + auto& memWorlds = g_MemoryCardSys->GetMemoryWorlds(); + size_t cinematicCount = 0; + for (const CSaveWorldMemory& world : memWorlds) + { + TLockedToken saveWorld = + g_SimplePool->GetObj(SObjectTag{FOURCC('SAVW'), world.GetSaveWorldAssetId()}); + cinematicCount += saveWorld->GetCinematicCount(); + } + + std::vector cinematicStates; + cinematicStates.reserve(cinematicCount); + for (size_t i=0 ; i saveWorld = + g_SimplePool->GetObj(SObjectTag{FOURCC('SAVW'), world.GetSaveWorldAssetId()}); + + auto stateIt = cinematicStates.cbegin(); + for (TEditorId cineId : saveWorld->GetCinematics()) + if (*stateIt++) + SetCinematicState(world.GetWorldAssetId(), cineId, true); + } +} + +void CPersistentOptions::SetCinematicState(ResId mlvlId, TEditorId cineId, bool state) +{ + auto existing = std::find_if(xac_cinematicStates.cbegin(), xac_cinematicStates.cend(), + [&](const std::pair& pair) -> bool + { + return pair.first == mlvlId && pair.second == cineId; + }); + + if (state && existing == xac_cinematicStates.cend()) + xac_cinematicStates.emplace_back(mlvlId, cineId); + else if (!state && existing != xac_cinematicStates.cend()) + xac_cinematicStates.erase(existing); +} + +CGameOptions::CGameOptions(CBitStreamReader& stream) +{ + for (int b=0 ; b<64 ; ++b) + x0_[b] = stream.ReadEncoded(1); + + x44_soundMode = ESoundMode(stream.ReadEncoded(2)); + x48_ = stream.ReadEncoded(4); + + x4c_ = stream.ReadEncoded(6); + x50_ = stream.ReadEncoded(6); + x54_ = stream.ReadEncoded(5); + x58_ = stream.ReadEncoded(7); + x5c_ = stream.ReadEncoded(7); + x60_ = stream.ReadEncoded(8); + x64_ = stream.ReadEncoded(8); + + x68_24_ = stream.ReadEncoded(1); + x68_28_ = stream.ReadEncoded(1); + x68_25_ = stream.ReadEncoded(1); + x68_26_ = stream.ReadEncoded(1); + x68_27_ = stream.ReadEncoded(1); +} + +CGameOptions::CGameOptions() +{ + x68_24_ = true; + x68_26_ = true; + x68_28_ = true; + InitSoundMode(); +} + +void CGameOptions::InitSoundMode() +{ + /* If system is mono, force x44 to mono, otherwise honor user preference */ +} + +CHintOptions::CHintOptions(CBitStreamReader& stream) +{ + const auto& hints = g_MemoryCardSys->GetHints(); + x0_hintStates.reserve(hints.size()); + + u32 hintIdx = 0; + for (const auto& hint : hints) + { + EHintState state = EHintState(stream.ReadEncoded(2)); + u32 timeBits = stream.ReadEncoded(32); + float time = reinterpret_cast(timeBits); + if (state == EHintState::Zero) + time = 0.f; + + x0_hintStates.emplace_back(state, time, false); + + if (x10_nextHintIdx == -1 && state == EHintState::Two) + x10_nextHintIdx = hintIdx; + ++hintIdx; + } +} + } diff --git a/Runtime/CGameOptions.hpp b/Runtime/CGameOptions.hpp index 21448f3d2..696f98f32 100644 --- a/Runtime/CGameOptions.hpp +++ b/Runtime/CGameOptions.hpp @@ -6,15 +6,113 @@ namespace urde { +/** Options tracked persistently between game sessions */ +class CPersistentOptions +{ + bool x0_[98] = {}; + bool x68_[64] = {}; + std::vector> xac_cinematicStates; /* (MLVL, Cinematic) */ + u32 xb0_ = 0; + u32 xb4_ = 0; + u32 xb8_ = 0; + u32 xbc_ = 0; + u32 xc0_ = 0; + u32 xc4_ = 0; + u32 xc8_ = 0; + u32 xcc_ = 0; + + union + { + struct + { + bool xd0_24_; + bool xd0_25_; + bool xd0_26_; + bool xd0_27_; + bool xd0_28_; + bool xd0_29_; + }; + u16 _dummy = 0; + }; + +public: + CPersistentOptions() = default; + CPersistentOptions(CBitStreamReader& stream); + + void SetCinematicState(ResId mlvlId, TEditorId cineId, bool state); +}; + +/** Options tracked per game session */ class CGameOptions { - u8 a = 0; - u8 b = 0; - u8 c = 128; - u8 d = 128; - u8 e = 255; - u8 f = 255; - bool g = true; +public: + enum class ESoundMode + { + Mono, + Stereo, + Surround + }; + +private: + bool x0_[64] = {}; + ESoundMode x44_soundMode = ESoundMode::Stereo; + u32 x48_ = 4; + u32 x4c_ = 0; + u32 x50_ = 0; + u32 x54_ = 0; + u32 x58_ = 0x7f; + u32 x5c_ = 0x7f; + u32 x60_ = 0xff; + u32 x64_ = 0xff; + + union + { + struct + { + bool x68_24_; + bool x68_25_; + bool x68_26_; + bool x68_27_; + bool x68_28_; + }; + u16 _dummy = 0; + }; + + u32 x70_ = 0; + u32 x74_ = 0; + u32 x78_ = 0; + +public: + CGameOptions(); + CGameOptions(CBitStreamReader& stream); + void InitSoundMode(); +}; + +class CHintOptions +{ +public: + enum class EHintState + { + Zero, + One, + Two + }; + struct SHintState + { + EHintState x0_state = EHintState::Zero; + float x4_time = 0.f; + bool x8_flag = false; + + SHintState() = default; + SHintState(EHintState state, float time, bool flag) + : x0_state(state), x4_time(time), x8_flag(flag) {} + }; +private: + std::vector x0_hintStates; + u32 x10_nextHintIdx = -1; +public: + CHintOptions() = default; + CHintOptions(CBitStreamReader& stream); }; } diff --git a/Runtime/CGameState.cpp b/Runtime/CGameState.cpp index 2743a5f88..50ba70557 100644 --- a/Runtime/CGameState.cpp +++ b/Runtime/CGameState.cpp @@ -1,10 +1,24 @@ #include "CGameState.hpp" #include "IOStreams.hpp" #include "zeus/Math.hpp" +#include "GameGlobalObjects.hpp" +#include "CMemoryCardSys.hpp" +#include "CSimplePool.hpp" +#include "CSaveWorld.hpp" namespace urde { +CWorldState::CWorldState(CBitStreamReader& reader, ResId mlvlId, const CSaveWorld& saveWorld) +: x0_mlvlId(mlvlId) +{ + x4_areaId = reader.ReadEncoded(32); + x10_ = reader.ReadEncoded(32); + x8_relayTracker = std::make_shared(reader, saveWorld); + xc_mapWorldInfo = std::make_shared(reader, saveWorld, mlvlId); + x14_ = std::make_shared(reader, saveWorld); +} + CGameState::CGameState() { x98_playerState.reset(new CPlayerState()); @@ -29,8 +43,20 @@ CGameState::CGameState(CBitStreamReader& stream) tmp = stream.ReadEncoded(32); double val5 = *(reinterpret_cast(&tmp)); - CPlayerState tmpPlayer(stream); - float currentHealth = tmpPlayer.GetHealthInfo().GetHP(); + x98_playerState = std::make_shared(stream); + float currentHealth = x98_playerState->GetHealthInfo().GetHP(); + + x17c_gameOptions = CGameOptions(stream); + x1f8_hintOptions = CHintOptions(stream); + + const std::vector& memWorlds = g_MemoryCardSys->GetMemoryWorlds(); + x88_worldStates.reserve(memWorlds.size()); + for (const CSaveWorldMemory& memWorld : memWorlds) + { + TLockedToken saveWorld = + g_SimplePool->GetObj(SObjectTag{FOURCC('SAVW'), memWorld.GetSaveWorldAssetId()}); + x88_worldStates.emplace_back(stream, memWorld.GetWorldAssetId(), *saveWorld); + } } void CGameState::SetCurrentWorldId(unsigned int id) diff --git a/Runtime/CGameState.hpp b/Runtime/CGameState.hpp index 9a5565ca1..cc0204839 100644 --- a/Runtime/CGameState.hpp +++ b/Runtime/CGameState.hpp @@ -10,16 +10,44 @@ #include "AutoMapper/CMapWorldInfo.hpp" namespace urde { +class CSaveWorldMemory; + +/* TODO: Figure out */ +class CWorldSomethingState +{ + std::vector x0_; + u32 x10_bitCount = 0; + std::vector x14_; +public: + CWorldSomethingState(CBitStreamReader& reader, const CSaveWorld& saveWorld) + { + u32 bitCount = reader.ReadEncoded(10); + u32 wordCount = (bitCount + 31) / 32; + x14_.resize(wordCount); + + for (u32 i=0 ; i x8_relayTracker; std::shared_ptr xc_mapWorldInfo; - /* std::shared_ptr<> x14_ */ + u32 x10_; + std::shared_ptr x14_; public: CWorldState(ResId id) : x0_mlvlId(id) {} + CWorldState(CBitStreamReader& reader, ResId mlvlId, const CSaveWorld& saveWorld); ResId GetWorldAssetId() const {return x0_mlvlId;} void SetAreaId(TAreaId aid) { x4_areaId = aid; } const TAreaId& GetCurrentAreaId() const { return x4_areaId; } @@ -37,8 +65,9 @@ class CGameState std::shared_ptr x98_playerState; std::shared_ptr x9c_transManager; double xa0_playTime; + CPersistentOptions xa8_systemOptions; CGameOptions x17c_gameOptions; - /* x1f8_ */ + CHintOptions x1f8_hintOptions; union { @@ -49,6 +78,7 @@ class CGameState }; u8 _dummy = 0; }; + public: CGameState(); CGameState(CBitStreamReader& stream); @@ -56,6 +86,8 @@ public: std::shared_ptr GetPlayerState() {return x98_playerState;} std::shared_ptr GetWorldTransitionManager() {return x9c_transManager;} void SetTotalPlayTime(float time); + CPersistentOptions& SystemOptions() { return xa8_systemOptions; } + CGameOptions& GameOptions() { return x17c_gameOptions; } CWorldState& StateForWorld(ResId mlvlId); CWorldState& CurrentWorldState() { return StateForWorld(x84_mlvlId); } ResId CurrentWorldAssetId() const { return x84_mlvlId; } diff --git a/Runtime/CMainFlowBase.hpp b/Runtime/CMainFlowBase.hpp index dce650679..c291f1033 100644 --- a/Runtime/CMainFlowBase.hpp +++ b/Runtime/CMainFlowBase.hpp @@ -10,6 +10,7 @@ enum class EClientFlowStates { Unspecified = -1, FrontEnd = 7, + StateLoad = 8, GameLoad = 13, MoviePlay = 14 }; diff --git a/Runtime/CMakeLists.txt b/Runtime/CMakeLists.txt index 2a093780f..107343cd8 100644 --- a/Runtime/CMakeLists.txt +++ b/Runtime/CMakeLists.txt @@ -48,7 +48,7 @@ add_library(RuntimeCommon #CMemory.hpp CMemory.cpp ITweak.hpp IMain.hpp - CMemoryCardSys.hpp + CMemoryCardSys.hpp CMemoryCardSys.cpp CScannableObjectInfo.hpp CScannableObjectInfo.cpp CSaveWorld.hpp CSaveWorld.cpp IAllocator.hpp IAllocator.cpp diff --git a/Runtime/CMemoryCardSys.cpp b/Runtime/CMemoryCardSys.cpp new file mode 100644 index 000000000..6ae2cb621 --- /dev/null +++ b/Runtime/CMemoryCardSys.cpp @@ -0,0 +1,36 @@ +#include "CMemoryCardSys.hpp" +#include "GameGlobalObjects.hpp" +#include "CSimplePool.hpp" + +namespace urde +{ + +CSaveWorldMemory::CSaveWorldMemory(ResId mlvl, ResId savw) +: x0_mlvlId(mlvl), x8_savwId(savw) +{ + if (savw == -1) + x2c_dummyWorld = std::make_unique(mlvl, false); + else + x3c_saveWorld = g_SimplePool->GetObj(SObjectTag{FOURCC('SAVW'), savw}); +} + +CMemoryCardSys::CMemoryCardSys() +{ + xc_memoryWorlds.reserve(16); + x1c_.reserve(16); + + g_ResFactory->EnumerateNamedResources([&](const std::string& name, const SObjectTag& tag) -> bool + { + if (tag.type == FOURCC('MLVL')) + { + auto existingSearch = + std::find_if(xc_memoryWorlds.cbegin(), xc_memoryWorlds.cend(), [&](const CSaveWorldMemory& wld) + { return wld.GetWorldAssetId() == tag.id; }); + if (existingSearch == xc_memoryWorlds.cend()) + xc_memoryWorlds.emplace_back(tag.id, -1); + } + return true; + }); +} + +} diff --git a/Runtime/CMemoryCardSys.hpp b/Runtime/CMemoryCardSys.hpp index 9fd6d142c..f6b646b4d 100644 --- a/Runtime/CMemoryCardSys.hpp +++ b/Runtime/CMemoryCardSys.hpp @@ -1,11 +1,53 @@ #ifndef __URDE_CMEMORYCARDSYS_HPP__ #define __URDE_CMEMORYCARDSYS_HPP__ +#include "CToken.hpp" +#include "World/CWorld.hpp" +#include "CGameHintInfo.hpp" +#include + namespace urde { +class CDummyWorld; +class CSaveWorld; + +class CSaveWorldMemory +{ + ResId x0_mlvlId = -1; + ResId x4_unk = -1; + ResId x8_savwId; + std::vector xc_; + std::vector x1c_; + std::unique_ptr x2c_dummyWorld; + TLockedToken x3c_saveWorld; /* Used to be auto_ptr */ + +public: + ResId GetWorldAssetId() const { return x0_mlvlId; } + ResId GetSaveWorldAssetId() const { return x8_savwId; } + CSaveWorldMemory(ResId mlvl, ResId savw); +}; + +/* TODO: figure out */ +class CMemorySomethingElse +{ + u32 x0_; + u32 x4_; + u32 x8_; + std::vector xc_; + std::vector x1c_; + std::unique_ptr x2c_; + std::unique_ptr x34_; +}; class CMemoryCardSys { + TLockedToken x0_hints; + std::vector xc_memoryWorlds; + std::vector x1c_; /* used to be auto_ptr of vector */ +public: + const std::vector& GetHints() const { return x0_hints->GetHints(); } + const std::vector& GetMemoryWorlds() const { return xc_memoryWorlds; } + CMemoryCardSys(); }; } diff --git a/Runtime/CResFactory.hpp b/Runtime/CResFactory.hpp index b17006397..fd8163285 100644 --- a/Runtime/CResFactory.hpp +++ b/Runtime/CResFactory.hpp @@ -56,6 +56,14 @@ public: std::vector> retval; return retval; } + + void EnumerateResources(std::function lambda) const + { + } + + void EnumerateNamedResources(std::function lambda) const + { + } }; } diff --git a/Runtime/CSaveWorld.hpp b/Runtime/CSaveWorld.hpp index 9777edfed..14e9e7465 100644 --- a/Runtime/CSaveWorld.hpp +++ b/Runtime/CSaveWorld.hpp @@ -35,6 +35,7 @@ public: u32 GetAreaCount() const; u32 GetCinematicCount() const; s32 GetCinematicIndex(const TEditorId& id) const; + const std::vector& GetCinematics() const { return x4_cinematics; } u32 GetRelayCount() const; s32 GetRelayIndex(const TEditorId& id) const; TEditorId GetRelayEditorId(u32 idx) const; diff --git a/Runtime/Character/CAssetFactory.cpp b/Runtime/Character/CAssetFactory.cpp index 8d75ab1a2..d541dad6a 100644 --- a/Runtime/Character/CAssetFactory.cpp +++ b/Runtime/Character/CAssetFactory.cpp @@ -45,6 +45,16 @@ FourCC CCharacterFactoryBuilder::CDummyFactory::GetResourceTypeById(ResId id) co return {}; } +void CCharacterFactoryBuilder::CDummyFactory::EnumerateResources( + const std::function& lambda) const +{ +} + +void CCharacterFactoryBuilder::CDummyFactory::EnumerateNamedResources( + const std::function& lambda) const +{ +} + u32 CCharacterFactoryBuilder::CDummyFactory::ResourceSize(const urde::SObjectTag& tag) { return 0; diff --git a/Runtime/Character/CAssetFactory.hpp b/Runtime/Character/CAssetFactory.hpp index 9bd16f204..5ea12e53f 100644 --- a/Runtime/Character/CAssetFactory.hpp +++ b/Runtime/Character/CAssetFactory.hpp @@ -24,6 +24,9 @@ public: const SObjectTag* GetResourceIdByName(const char*) const; FourCC GetResourceTypeById(ResId id) const; + void EnumerateResources(const std::function& lambda) const; + void EnumerateNamedResources(const std::function& lambda) const; + u32 ResourceSize(const urde::SObjectTag& tag); bool LoadResourceAsync(const urde::SObjectTag& tag, std::unique_ptr& target); bool LoadResourcePartAsync(const urde::SObjectTag& tag, u32 size, u32 off, std::unique_ptr& target); diff --git a/Runtime/Character/CCharacterFactory.cpp b/Runtime/Character/CCharacterFactory.cpp index d670f2eed..a0b8f11d7 100644 --- a/Runtime/Character/CCharacterFactory.cpp +++ b/Runtime/Character/CCharacterFactory.cpp @@ -75,6 +75,15 @@ FourCC CCharacterFactory::CDummyFactory::GetResourceTypeById(ResId id) const return {}; } +void CCharacterFactory::CDummyFactory::EnumerateResources( + const std::function& lambda) const +{ +} +void CCharacterFactory::CDummyFactory::EnumerateNamedResources( + const std::function& lambda) const +{ +} + u32 CCharacterFactory::CDummyFactory::ResourceSize(const urde::SObjectTag& tag) { return 0; diff --git a/Runtime/Character/CCharacterFactory.hpp b/Runtime/Character/CCharacterFactory.hpp index 495f6a7d1..64cb20389 100644 --- a/Runtime/Character/CCharacterFactory.hpp +++ b/Runtime/Character/CCharacterFactory.hpp @@ -33,6 +33,9 @@ public: const SObjectTag* GetResourceIdByName(const char*) const; FourCC GetResourceTypeById(ResId id) const; + void EnumerateResources(const std::function& lambda) const; + void EnumerateNamedResources(const std::function& lambda) const; + u32 ResourceSize(const urde::SObjectTag& tag); bool LoadResourceAsync(const urde::SObjectTag& tag, std::unique_ptr& target); bool LoadResourcePartAsync(const urde::SObjectTag& tag, u32 size, u32 off, std::unique_ptr& target); diff --git a/Runtime/IFactory.hpp b/Runtime/IFactory.hpp index c56b109a0..81ad20edd 100644 --- a/Runtime/IFactory.hpp +++ b/Runtime/IFactory.hpp @@ -2,6 +2,7 @@ #define __URDE_IFACTORY_HPP__ #include +#include #include "RetroTypes.hpp" namespace urde @@ -30,6 +31,8 @@ public: virtual bool CanBuild(const SObjectTag&)=0; virtual const SObjectTag* GetResourceIdByName(const char*) const=0; virtual FourCC GetResourceTypeById(ResId id) const=0; + virtual void EnumerateResources(const std::function& lambda) const=0; + virtual void EnumerateNamedResources(const std::function& lambda) const=0; /* Non-factory versions, replaces CResLoader */ virtual u32 ResourceSize(const urde::SObjectTag& tag)=0; diff --git a/Runtime/MP1/CSlideShow.cpp b/Runtime/MP1/CSlideShow.cpp index 20b6a9079..2836c93ae 100644 --- a/Runtime/MP1/CSlideShow.cpp +++ b/Runtime/MP1/CSlideShow.cpp @@ -29,11 +29,118 @@ CSlideShow::CSlideShow() zeus::CColor::skWhite, 640, 480, g_SimplePool); } - xf8_.reserve(18); + xf8_stickTextures.reserve(18); + x108_buttonTextures.reserve(8); + SObjectTag txtrTag(FOURCC('TXTR'), 0); + for (int i=0 ; i<9 ; ++i) + { + txtrTag.id = g_tweakPlayerRes->x24_lStick[i]; + xf8_stickTextures.push_back(g_SimplePool->GetObj(txtrTag)); + } + for (int i=0 ; i<9 ; ++i) + { + txtrTag.id = g_tweakPlayerRes->x4c_cStick[i]; + xf8_stickTextures.push_back(g_SimplePool->GetObj(txtrTag)); + } + for (int i=0 ; i<2 ; ++i) + { + txtrTag.id = g_tweakPlayerRes->x74_lTrigger[i]; + xf8_stickTextures.push_back(g_SimplePool->GetObj(txtrTag)); + } + for (int i=0 ; i<2 ; ++i) + { + txtrTag.id = g_tweakPlayerRes->x80_rTrigger[i]; + xf8_stickTextures.push_back(g_SimplePool->GetObj(txtrTag)); + } + for (int i=0 ; i<2 ; ++i) + { + txtrTag.id = g_tweakPlayerRes->xa4_bButton[i]; + xf8_stickTextures.push_back(g_SimplePool->GetObj(txtrTag)); + } + for (int i=0 ; i<2 ; ++i) + { + txtrTag.id = g_tweakPlayerRes->xbc_yButton[i]; + xf8_stickTextures.push_back(g_SimplePool->GetObj(txtrTag)); + } +} + +bool CSlideShow::LoadTXTRDep(const std::string& name) +{ + const SObjectTag* dgrpTag = g_ResFactory->GetResourceIdByName(name.c_str()); + if (dgrpTag && dgrpTag->type == FOURCC('DGRP')) + { + x18_galleryTXTRDeps.push_back(g_SimplePool->GetObj(*dgrpTag)); + return true; + } + return false; +} + +bool CSlideShow::AreAllDepsLoaded(const std::vector>& deps) +{ + for (const TLockedToken& token : deps) + { + if (!token.IsLoaded()) + return false; + } + return true; } CIOWin::EMessageReturn CSlideShow::OnMessage(const CArchitectureMessage& msg, CArchitectureQueue& queue) { + switch (msg.GetType()) + { + case EArchMsgType::TimerTick: + { + if (x134_29_) + return EMessageReturn::RemoveIOWinAndExit; + + float dt = MakeMsg::GetParmTimerTick(msg).x4_parm; + + switch (x14_phase) + { + case Phase::Zero: + { + //if (!g_resLoader->AreAllPaksLoaded()) + //{ + // g_resLoader->AsyncIdlePakLoading(); + // return EMessageReturn::Exit; + //} + x14_phase = Phase::One; + } + case Phase::One: + { + if (x18_galleryTXTRDeps.empty()) + { + x18_galleryTXTRDeps.reserve(5); + for (int i=1 ; true ; ++i) + { + std::string depResName = hecl::Format("Gallery%02d_DGRP", i); + if (!LoadTXTRDep(depResName)) + break; + } + LoadTXTRDep("GalleryAssets_DGRP"); + } + if (!AreAllDepsLoaded(x18_galleryTXTRDeps)) + return EMessageReturn::Exit; + + x14_phase = Phase::Three; + } + case Phase::Two: + case Phase::Three: + { + + } + case Phase::Four: + case Phase::Five: + default: break; + } + + break; + } + case EArchMsgType::UserInput: + default: break; + } + return EMessageReturn::Exit; } diff --git a/Runtime/MP1/CSlideShow.hpp b/Runtime/MP1/CSlideShow.hpp index 4056a6f71..6ec5a89b2 100644 --- a/Runtime/MP1/CSlideShow.hpp +++ b/Runtime/MP1/CSlideShow.hpp @@ -12,6 +12,7 @@ namespace urde { class CTexture; class CSfxHandle; +class CDependencyGroup; class CSlideShow : public CIOWin { @@ -55,9 +56,7 @@ public: private: Phase x14_phase = Phase::Zero; - u32 x1c_ = 0; - u32 x20_ = 0; - u32 x24_ = 0; + std::vector> x18_galleryTXTRDeps; u32 x2c_ = 0; u32 x30_ = 0; u32 x34_ = 0; @@ -86,8 +85,8 @@ private: u32 xec_ = 0; u32 xf0_ = 0; u32 xf4_ = 0; - std::vector xf8_; - std::vector x108_; + std::vector> xf8_stickTextures; /* (9 LStick, 9 CStick) */ + std::vector x108_buttonTextures; /* (2L, 2R, 2B, 2Y) */ u32 x11c_ = 0; u32 x120_ = 0; u32 x124_ = 0; @@ -111,6 +110,10 @@ private: }; u32 dummy = 0; }; + + bool LoadTXTRDep(const std::string& name); + static bool AreAllDepsLoaded(const std::vector>& deps); + public: CSlideShow(); EMessageReturn OnMessage(const CArchitectureMessage&, CArchitectureQueue&); diff --git a/hecl b/hecl index 1326eacf9..536a8e4f7 160000 --- a/hecl +++ b/hecl @@ -1 +1 @@ -Subproject commit 1326eacf98fdc94d7fd692d248d54de9a09a2fb8 +Subproject commit 536a8e4f7dfff11695585d910018211718ff7225