diff --git a/Makefile b/Makefile index 80cc7581..4e429ff2 100644 --- a/Makefile +++ b/Makefile @@ -99,7 +99,7 @@ PYTHON := python3 FRANK := tools/franklite.py # Options -INCLUDES := -i include/ +INCLUDES := -i include/ -i include/Kyoto_CWD/ -i include/rstl/ ASM_INCLUDES := -I include/ ASFLAGS := -mgekko $(ASM_INCLUDES) --defsym version=$(VERSION) diff --git a/include/Kyoto_CWD/CGameGlobalObjects.hpp b/include/Kyoto_CWD/CGameGlobalObjects.hpp index bbe7281f..b412648f 100644 --- a/include/Kyoto_CWD/CGameGlobalObjects.hpp +++ b/include/Kyoto_CWD/CGameGlobalObjects.hpp @@ -50,7 +50,6 @@ private: // TODO move to related headers extern unkptr gGuiSystem; -extern unkptr gpStringTable; extern unkptr gpController; extern unkptr gpDefaultFont; diff --git a/include/Kyoto_CWD/CGameState.hpp b/include/Kyoto_CWD/CGameState.hpp index 70e35594..65f15361 100644 --- a/include/Kyoto_CWD/CGameState.hpp +++ b/include/Kyoto_CWD/CGameState.hpp @@ -25,6 +25,8 @@ public: CGameState& operator=(const CGameState&); rstl::rc_ptr< CPlayerState >& PlayerState(); + CAssetId CurrentWorldAssetId(); + CSystemOptions& SystemOptions() { return xa8_systemOptions; } CGameOptions& GameOptions() { return x17c_gameOptions; } CHintOptions& HintOptions() { return x1f8_hintOptions; } @@ -32,11 +34,6 @@ public: u64& CardSerial() { return x210_cardSerial; } rstl::vector< u8 >& BackupBuf() { return x218_backupBuf; } - void SetGameOptions(CGameOptions options) { - x17c_gameOptions = options; - x17c_gameOptions.EnsureOptions(); - } - private: rstl::reserved_vector< bool, 128 > x0_; CAssetId x84_mlvlId; diff --git a/include/Kyoto_CWD/CMain.hpp b/include/Kyoto_CWD/CMain.hpp index 57064686..377aa60a 100644 --- a/include/Kyoto_CWD/CMain.hpp +++ b/include/Kyoto_CWD/CMain.hpp @@ -13,6 +13,7 @@ #include "CStopwatch.hpp" #include "CTweaks.hpp" #include "TReservedAverage.hpp" +#include "TGameTypes.hpp" class CMain { public: @@ -22,7 +23,6 @@ public: void StreamNewGameState(CInputStream& in, int saveIdx); void RefreshGameState(); void AddWorldPaks(); - void EnsureWorldPaksReady(); void AsyncIdle(u32 time); int RsMain(int argc, char** argv); void InitializeSubsystems(); @@ -34,6 +34,9 @@ public: bool CheckTerminate(); bool CheckReset(); + static void EnsureWorldPaksReady(); + static void EnsureWorldPakReady(CAssetId id); + private: COsContext x0_osContext; u8 x6c_unk; diff --git a/include/Kyoto_CWD/CPakFile.hpp b/include/Kyoto_CWD/CPakFile.hpp index ef9a82d8..1642c4b9 100644 --- a/include/Kyoto_CWD/CPakFile.hpp +++ b/include/Kyoto_CWD/CPakFile.hpp @@ -3,19 +3,36 @@ #include "types.h" +#include "rstl/auto_ptr.hpp" +#include "rstl/string.hpp" + #include "CDvdFile.hpp" +#include "CResLoader.hpp" +#include "TGameTypes.hpp" class CPakFile : CDvdFile { public: bool IsWorldPak() const { return x28_26_worldPak; } void EnsureWorldPakReady(); + void sub_8036742c(); + + rstl::vector< rstl::pair< rstl::string, SObjectTag > >& NameList() { return x54_nameList; } private: bool x28_24_buildDepList : 1; bool x28_25_aramFile : 1; bool x28_26_worldPak : 1; bool x28_27_stashedInARAM : 1; - // TODO + int x2c_asyncLoadPhase; // EAsyncPhase + rstl::auto_ptr< void > x30_dvdReq; // IDvdRequest + rstl::vector< u8 > x38_headerData; + u32 x48_resTableOffset; + u32 x4c_resTableCount; + s32 x50_aramBase; + rstl::vector< rstl::pair< rstl::string, SObjectTag > > x54_nameList; + rstl::vector< CAssetId > x64_depList; + rstl::vector< SResInfo > x74_resList; + mutable s32 x84_currentSeek; }; #endif diff --git a/include/Kyoto_CWD/CResLoader.hpp b/include/Kyoto_CWD/CResLoader.hpp index e5761b39..f464131a 100644 --- a/include/Kyoto_CWD/CResLoader.hpp +++ b/include/Kyoto_CWD/CResLoader.hpp @@ -6,9 +6,10 @@ #include "rstl/list.hpp" #include "rstl/string.hpp" -#include "CPakFile.hpp" #include "TGameTypes.hpp" +class CPakFile; + struct SResInfo { CAssetId x0_id; bool x4_compressed : 1; @@ -19,9 +20,9 @@ struct SResInfo { class CResLoader { public: - s32 GetPakCount(); - CPakFile& GetPakFile(s32 idx); - void AddPakFileAsync(rstl::string&, bool, bool); + s32 GetPakCount() const; + CPakFile& GetPakFile(int idx) const; + void AddPakFileAsync(const rstl::string&, bool, bool); void AsyncIdlePakLoading(); bool AreAllPaksLoaded() const; diff --git a/include/Kyoto_CWD/CStopwatch.hpp b/include/Kyoto_CWD/CStopwatch.hpp index 62867004..3a1c909f 100644 --- a/include/Kyoto_CWD/CStopwatch.hpp +++ b/include/Kyoto_CWD/CStopwatch.hpp @@ -15,6 +15,7 @@ public: s64 GetTimerFreq() const { return x0_timerFreq; } s64 GetTimerFreqO1M() const { return x8_timerFreqO1M; } f32 GetTimerPeriod() const { return x10_timerPeriod; } + s64 GetCPUCycles() const { return OSGetTime(); } private: s64 x0_timerFreq; @@ -22,17 +23,17 @@ public: f32 x10_timerPeriod; }; - CStopwatch() : x0_startTime(OSGetTime()) {} + CStopwatch() : x0_startTime(mData.GetCPUCycles()) {} // static inline void InitGlobalTimer() {} // static inline CStopwatch& GetGlobalTimerObj() { return mGlobalTimer; } inline void Reset() { if (mData.GetTimerFreq() == 0) { mData.Initialize(); } - x0_startTime = OSGetTime(); + x0_startTime = mData.GetCPUCycles(); } - inline float GetElapsedTime() const { return (OSGetTime() - x0_startTime) * mData.GetTimerPeriod(); } - inline s64 GetElapsedMicros() const { return (OSGetTime() - x0_startTime) / mData.GetTimerFreqO1M(); } + inline float GetElapsedTime() const { return (mData.GetCPUCycles() - x0_startTime) * mData.GetTimerPeriod(); } + inline s64 GetElapsedMicros() const { return (mData.GetCPUCycles() - x0_startTime) / mData.GetTimerFreqO1M(); } private: static CSWData mData; diff --git a/include/Kyoto_CWD/CStringTable.hpp b/include/Kyoto_CWD/CStringTable.hpp index cf625e2b..a290b4e8 100644 --- a/include/Kyoto_CWD/CStringTable.hpp +++ b/include/Kyoto_CWD/CStringTable.hpp @@ -15,4 +15,6 @@ public: CStringTable(CInputStream& in); }; +extern CStringTable* gpStringTable; + #endif diff --git a/include/Kyoto_CWD/TGameTypes.hpp b/include/Kyoto_CWD/TGameTypes.hpp index 8d5e73a4..947a96cc 100644 --- a/include/Kyoto_CWD/TGameTypes.hpp +++ b/include/Kyoto_CWD/TGameTypes.hpp @@ -11,16 +11,21 @@ extern TAreaId kInvalidAreaId; extern TEditorId kInvalidEditorId; extern TUniqueId kInvalidUniqueId; -class CAssetId { -public: - u32 id; -}; +typedef u32 CAssetId; +// class CAssetId { +// public: +// u32 id; -struct SObjectTag { - char type[4]; - u32 id; -}; +// bool operator==(const CAssetId& other) { return id == other.id; } +// }; #define FourCC unsigned long +struct SObjectTag { + FourCC type; + CAssetId id; + + SObjectTag(const SObjectTag& other) : type(other.type), id(other.id) {} +}; + #endif diff --git a/include/rstl/auto_ptr.hpp b/include/rstl/auto_ptr.hpp new file mode 100644 index 00000000..0aabfa00 --- /dev/null +++ b/include/rstl/auto_ptr.hpp @@ -0,0 +1,19 @@ +#ifndef _RSTL_AUTO_PTR_HPP +#define _RSTL_AUTO_PTR_HPP + +#include "types.h" + +namespace rstl { +template < typename T > +class auto_ptr { + bool x0_has; + T* x4_item; + +public: + auto_ptr() : x0_has(false), x4_item(nullptr) {} + T* get() { return x4_item; } + T* operator->() { return get(); } +}; +} // namespace rstl + +#endif diff --git a/include/rstl/construct.hpp b/include/rstl/construct.hpp index 09ee2201..27f372a0 100644 --- a/include/rstl/construct.hpp +++ b/include/rstl/construct.hpp @@ -6,7 +6,7 @@ namespace rstl { template < typename T > inline void construct(void* dest, const T& src) { - *static_cast< T* >(dest) = src; + new(dest) T(src); } template < typename T > @@ -32,14 +32,12 @@ inline void uninitialized_copy(Iter begin, Iter end, T* in) { } } -template < typename T > -inline void uninitialized_copy_n(T* dest, size_t count, T* src) { - for (size_t i = 0; i < count; ++i) { +template < typename S, typename D > +inline void uninitialized_copy_n(D* dest, S* src, size_t count) { + for (size_t i = 0; i < count; ++dest, ++i, ++src) { construct(dest, *src); - destroy(src); - ++dest; - ++src; } + // destroy(src, src + count); ?? } } // namespace rstl diff --git a/include/rstl/pair.hpp b/include/rstl/pair.hpp index f0b510d8..d4d13c82 100644 --- a/include/rstl/pair.hpp +++ b/include/rstl/pair.hpp @@ -7,11 +7,13 @@ namespace rstl { template < typename L, typename R > class pair { public: - L first; - R second; - inline pair() {} inline pair(const L& first, const R& second) : first(first), second(second) {} + inline pair(const pair& other) : first(other.first), second(other.second) {} + inline void operator=(const pair& other) { first = other.first; second = other.second; } + + L first; + R second; }; } // namespace rstl diff --git a/include/rstl/rmemory_allocator.hpp b/include/rstl/rmemory_allocator.hpp index fba66b96..36d127a3 100644 --- a/include/rstl/rmemory_allocator.hpp +++ b/include/rstl/rmemory_allocator.hpp @@ -8,8 +8,8 @@ namespace rstl { struct rmemory_allocator { template < typename T > - static void allocate(T*& out, size_t count) { - out = new T[count]; + static void allocate(T*& out, size_t sz) { + out = reinterpret_cast< T* >(new u8[sz]); } template < typename T > static void deallocate(T* ptr) { diff --git a/include/rstl/vector.hpp b/include/rstl/vector.hpp index 9622696a..0ef9e01b 100644 --- a/include/rstl/vector.hpp +++ b/include/rstl/vector.hpp @@ -30,26 +30,18 @@ public: if (x4_count == 0 && x8_capacity == 0) { xc_items = NULL; } else { - if (x8_capacity == 0) { + size_t sz = x8_capacity * sizeof(T); + if (sz == 0) { xc_items = NULL; } else { - Alloc::allocate(xc_items, x8_capacity); - } - // what's going on here? - iterator iter; - const_iterator otherIter; - otherIter = other.begin(); - iter = begin(); - for (size_t i = 0; i < x4_count; ++i) { - iter = *otherIter; - ++iter; - ++otherIter; + x0_allocator.allocate(xc_items, sz); } + rstl::uninitialized_copy_n(data(), other.data(), x4_count); } } ~vector() { rstl::destroy(begin(), end()); - Alloc::deallocate(xc_items); + x0_allocator.deallocate(xc_items); } void reserve(size_t size); /* { diff --git a/src/Kyoto_CWD/main.cpp b/src/Kyoto_CWD/main.cpp index 952339bf..91318fbf 100644 --- a/src/Kyoto_CWD/main.cpp +++ b/src/Kyoto_CWD/main.cpp @@ -16,11 +16,13 @@ #include "Kyoto_CWD/CInGameTweakManager.hpp" #include "Kyoto_CWD/CMemoryCardSys.hpp" #include "Kyoto_CWD/CMemoryInStream.hpp" +#include "Kyoto_CWD/CPakFile.hpp" #include "Kyoto_CWD/CPlayerState.hpp" #include "Kyoto_CWD/CResFactory.hpp" #include "Kyoto_CWD/CSfxManager.hpp" #include "Kyoto_CWD/CSimplePool.hpp" #include "Kyoto_CWD/CStreamAudioManager.hpp" +#include "Kyoto_CWD/CStringTable.hpp" #include "Kyoto_CWD/CSystemOptions.hpp" #include "Kyoto_CWD/CTweakGame.hpp" @@ -38,7 +40,7 @@ CSimplePool* gpSimplePool; CCubeRenderer* gpRender; CCharacterFactoryBuilder* gpCharacterFactoryBuilder; unkptr gGuiSystem; -unkptr gpStringTable; +CStringTable* gpStringTable; CMain* gpMain; unkptr gpController; CGameState* gpGameState; @@ -78,7 +80,8 @@ void CMain::ResetGameState() { x128_gameGlobalObjects->SetGameState(nullptr); x128_gameGlobalObjects->SetGameState(new CGameState()); gpGameState->SystemOptions() = persistentOptions; - gpGameState->SetGameOptions(gameOptions); + gpGameState->GameOptions() = gameOptions; + gpGameState->GameOptions().EnsureOptions(); gpGameState->PlayerState()->SetIsFusionEnabled( gpGameState->SystemOptions().GetHasFusion()); } @@ -109,7 +112,8 @@ void CMain::RefreshGameState() { } // gpGameState = x128_gameGlobalObjects->x134_gameState.get(); gpGameState->SystemOptions() = systemOptions; - gpGameState->SetGameOptions(gameOptions); + gpGameState->GameOptions() = gameOptions; + gpGameState->GameOptions().EnsureOptions(); gpGameState->CardSerial() = cardSerial; gpGameState->PlayerState()->SetIsFusionEnabled( gpGameState->SystemOptions().GetHasFusion()); @@ -209,7 +213,8 @@ int CMain::RsMain(int argc, char** argv) { if (lbl_805A8C54 != nullptr) { CMemoryInStream stream(lbl_805A8C54, 0x80); stream.ReadBits(1); - gpGameState->SetGameOptions(CGameOptions(stream)); + gpGameState->GameOptions() = CGameOptions(stream); + gpGameState->GameOptions().EnsureOptions(); lbl_805A6BC0 = stream.ReadBits(1); } @@ -300,3 +305,27 @@ int CMain::RsMain(int argc, char** argv) { CARAMManager::Shutdown(); return 0; } + +// 8036723C +void CMain::EnsureWorldPakReady(CAssetId id) { + CResLoader& resLoader = gpResourceFactory->GetResLoader(); + for (int i = 0; i < resLoader.GetPakCount(); ++i) { + bool notInNameList = true; + CPakFile& pakFile = resLoader.GetPakFile(i); + if (pakFile.IsWorldPak()) { + rstl::vector< rstl::pair< rstl::string, SObjectTag > > nameList = pakFile.NameList(); + rstl::vector< rstl::pair< rstl::string, SObjectTag > >::iterator cur = nameList.begin(); + while (cur != nameList.end()) { + if (cur->second.id == id) { + notInNameList = false; + } + ++cur; + } + if (notInNameList) { + pakFile.sub_8036742c(); + } else { + pakFile.EnsureWorldPakReady(); + } + } + } +}