diff --git a/configure.py b/configure.py index f764847d..f956d1e4 100644 --- a/configure.py +++ b/configure.py @@ -801,13 +801,14 @@ def MatchingFor(*versions): Object(Matching, "MarioUtil/GDUtil.cpp"), Object(Matching, "MarioUtil/TexUtil.cpp"), Object(Matching, "MarioUtil/MapUtil.cpp"), - Object(NonMatching, "MarioUtil/ToolData.cpp"), + Object(Matching, "MarioUtil/ToolData.cpp"), ], }, { "lib": "M3DUtil", "mw_version": "GC/1.2.5", "cflags": [*cflags_system, "-inline deferred"], + "progress_category": "game", "objects": [ Object(NonMatching, "M3DUtil/M3UJoint.cpp"), Object(NonMatching, "M3DUtil/M3UModel.cpp"), @@ -826,6 +827,7 @@ def MatchingFor(*versions): "lib": "System", "mw_version": "GC/1.2.5", "cflags": [*cflags_system, "-inline deferred"], + "progress_category": "game", "objects": [ Object(Matching, "System/BaseParam.cpp"), Object(NonMatching, "System/EmitterViewObj.cpp"), diff --git a/include/GC2D/MovieRumble.hpp b/include/GC2D/MovieRumble.hpp index a93c9d47..47b0e7cb 100644 --- a/include/GC2D/MovieRumble.hpp +++ b/include/GC2D/MovieRumble.hpp @@ -2,11 +2,8 @@ #define GC2D_MOVIE_RUMBLE_HPP #include - -class TTHPRender; -namespace Koga { -class ToolData; -} +#include +#include class TMovieRumble : public JDrama::TViewObj { public: diff --git a/include/MarioUtil/RumbleMgr.hpp b/include/MarioUtil/RumbleMgr.hpp index 0cc89750..edaab773 100644 --- a/include/MarioUtil/RumbleMgr.hpp +++ b/include/MarioUtil/RumbleMgr.hpp @@ -1,9 +1,9 @@ #ifndef MARIO_UTIL_RUMBLE_MGR_HPP #define MARIO_UTIL_RUMBLE_MGR_HPP -#include #include #include +#include #define RUMBLE_CHANNELS_PER_CONTROLLER 32 diff --git a/include/MarioUtil/ToolData.hpp b/include/MarioUtil/ToolData.hpp index b959fe62..fdc1c74b 100644 --- a/include/MarioUtil/ToolData.hpp +++ b/include/MarioUtil/ToolData.hpp @@ -1,58 +1,117 @@ #ifndef MARIO_UTIL_TOOL_DATA_HPP #define MARIO_UTIL_TOOL_DATA_HPP - -#include +#include namespace Koga { - +/** + * @brief ToolData is a class that reads BCSV data. Usage is as follows: + * Create a ToolData instance, fetch the BCSV data from disk and attach it. + * One can then call GetValue to retrieve data from the file. + * + * The structures and parsing logic are based off the Mario Galaxy decomp's + * handling of JMap files + */ class ToolData { public: ToolData(); + virtual ~ToolData(); // if not explicitly defined its not generated ok + BOOL Attach(const void* bcsvFileData); + // returns TRUE if the value was found, otherwise FALSE + BOOL GetValue(int entryIndex, const char* key, long& pValueOut) const; + // returns TRUE if the value was found, otherwise FALSE + BOOL GetValue(int entryIndex, const char* key, + const char*& pValueOut) const; - virtual ~ToolData(); + inline bool dataExists() const { return !!mData; } - bool Attach(const void*); - void Detach(); - static u32 Hash(const char*); + inline bool isIndexValid(s32 entryIndex) + { + return entryIndex < mData->mNumEntries; + } - bool GetValue(int, const char*, u32&) const; - bool GetValue(int, const char*, s32&) const; - bool GetValue(int, const char*, bool&) const; - bool GetValue(int, const char*, const char*&) const; - bool GetValue(int, const char*, f32&) const; +// JMAP value types, ignored in sunshine +#define JMAP_VALUE_TYPE_LONG 0 +#define JMAP_VALUE_TYPE_STRING 1 +#define JMAP_VALUE_TYPE_FLOAT 2 +#define JMAP_VALUE_TYPE_LONG_2 3 +#define JMAP_VALUE_TYPE_SHORT 4 +#define JMAP_VALUE_TYPE_BYTE 5 +#define JMAP_VALUE_TYPE_STRING_PTR 6 +#define JMAP_VALUE_TYPE_NULL 7 - int SearchItemInfo(const char*) const; + struct JMapItem { + u32 mHash; // 0x0 + u32 mMask; // 0x4 + u16 mOffsData; // 0x8 + u8 mShift; // 0xA + u8 mType; // 0xB + }; - void FindElement(int, u32, int) const; - void FindElement(int, s32, int) const; - void FindElement(int, bool, int) const; - void FindElement(int, const char*, int) const; - void FindElement(int, f32, int) const; + struct JMapData { + s32 mNumEntries; // 0x0 + s32 mNumFields; // 0x4 + s32 mDataOffset; // 0x8 + u32 mEntrySize; // 0xC + const JMapItem mItems[]; // 0x10 + }; - const void* GetData() const { return unk4; } - int GetGroupCount() const { return unk4->unk0; } +private: + inline u32 hashString(const char* key) const + { + u32 stringHash = 0; + char current_char; -public: - struct ItemInfo { - u16 getUnk8() const { return unk8; } - u32 getUnk0() const { return unk0; } + while ((current_char = *key) != 0) { + key++; + stringHash = (current_char + (stringHash << 8)) % 0x1FFFFD9; + } + return stringHash; + } - /* 0x0 */ u32 unk0; - /* 0x4 */ char unk4[0x4]; - /* 0x8 */ u16 unk8; - }; + inline s32 searchItemInfo(const char* pKey) const + { + s32 nFields = mData->mNumFields; + u32 hash = hashString(pKey); - struct Header { - /* 0x0 */ int unk0; - /* 0x4 */ int unk4; - /* 0x8 */ u32 unk8; - /* 0xC */ u32 unkC; - /* 0x10 */ ItemInfo unk10[]; - }; + for (int i = 0; i < nFields; ++i) { + if (hash == mData->mItems[i].mHash) { + return i; + } + } - /* 0x4 */ const Header* unk4; -}; + return -1; + } -} // namespace Koga + inline const char* getEntryAddress(const JMapData* pData, + const s32 dataOffset, + const int entryIndex) const + { + return reinterpret_cast(pData) + dataOffset + + entryIndex * pData->mEntrySize; + } + + inline BOOL getValue(const int entryIndex, const int itemIndex, + s32* pValueOut) const + { + const JMapItem* item = &mData->mItems[itemIndex]; + const char* valuePtr + = getEntryAddress(mData, mData->mDataOffset, entryIndex) + + item->mOffsData; + *pValueOut = *reinterpret_cast(valuePtr); + return TRUE; + } + + inline BOOL getValue(const int entryIndex, const int itemIndex, + const char** pValueOut) const + { + const JMapItem* item = &mData->mItems[itemIndex]; + *pValueOut = getEntryAddress(mData, mData->mDataOffset, entryIndex) + + item->mOffsData; + return TRUE; + } +public: + const JMapData* mData; +}; +} // namespace Koga #endif diff --git a/src/GC2D/MovieRumble.cpp b/src/GC2D/MovieRumble.cpp index d2aa9735..106643d6 100644 --- a/src/GC2D/MovieRumble.cpp +++ b/src/GC2D/MovieRumble.cpp @@ -1,10 +1,10 @@ #include -#include #include -#include +#include #include #include -#include +#include +#include // TODO: removeme static const char* dummyMactorStringValue1 = "\0\0\0\0\0\0\0\0\0\0\0"; @@ -23,7 +23,7 @@ void TMovieRumble::init(const char* param_1) unk14 = new Koga::ToolData; void* bcr = JKRGetResource(acStack_90); unk14->Attach(bcr); - if (!unk14->GetData()) + if (!unk14->dataExists()) unk18 = -1; else unk18 = 0; @@ -71,7 +71,7 @@ void TMovieRumble::readCurInfo() { int group = unk18; - if (isValid() && group < unk14->GetGroupCount()) { + if (isValid() && unk14->isIndexValid(group)) { Koga::ToolData* toolData = unk14; toolData->GetValue(group, "start_frame", unk1C); toolData->GetValue(group, "end_frame", unk20); diff --git a/src/MarioUtil/RumbleData.cpp b/src/MarioUtil/RumbleData.cpp index 6de4e6e8..8a9466db 100644 --- a/src/MarioUtil/RumbleData.cpp +++ b/src/MarioUtil/RumbleData.cpp @@ -1,5 +1,5 @@ -#include #include +#include static int rumblePoint_00 = 0x0000000B; diff --git a/src/MarioUtil/RumbleMgr.cpp b/src/MarioUtil/RumbleMgr.cpp index 8d80ba99..824368d5 100644 --- a/src/MarioUtil/RumbleMgr.cpp +++ b/src/MarioUtil/RumbleMgr.cpp @@ -1,7 +1,7 @@ -#include #include -#include +#include #include +#include int RumbleMgr::mMotorCountLimit = 900; u16 RumbleMgr::mMotorTimerPeriod = 80; diff --git a/src/MarioUtil/ToolData.cpp b/src/MarioUtil/ToolData.cpp index b8fb6ca4..8e3fd04c 100644 --- a/src/MarioUtil/ToolData.cpp +++ b/src/MarioUtil/ToolData.cpp @@ -1,80 +1,34 @@ #include -#include - -using namespace Koga; - -ToolData::ToolData() - : unk4(nullptr) -{ -} +#include +namespace Koga { +ToolData::ToolData() { mData = nullptr; } ToolData::~ToolData() { } -bool ToolData::Attach(const void* data) +BOOL ToolData::Attach(const void* jmapData) { - if (!data) - return false; - unk4 = (Header*)data; - return true; + if (!jmapData) + return FALSE; + this->mData = (JMapData*)jmapData; + return TRUE; } -void ToolData::Detach() { } - -u32 ToolData::Hash(const char* str) +BOOL ToolData::GetValue(int entryIndex, const char* key, long& pValueOut) const { - u32 hash = 0; - for (; *str; ++str) - hash = (hash + (*str << 8)) % 33554393; - return hash; + s32 itemIndex = searchItemInfo(key); + if (itemIndex < 0) { + return FALSE; + } + return getValue(entryIndex, itemIndex, &pValueOut); } -bool ToolData::GetValue(int, const char*, u32&) const { } - -bool ToolData::GetValue(int param_1, const char* param_2, s32& param_3) const +BOOL ToolData::GetValue(int entryIndex, const char* key, + const char*& pValueOut) const { - int idx = SearchItemInfo(param_2); - if (idx < 0) - return false; - u8* base = (u8*)unk4 + unk4->unk8 + param_1 * unk4->unkC; - u8* ptr = base + unk4->unk10[idx].getUnk8(); - param_3 = *(s32*)ptr; - return true; + s32 itemIndex = searchItemInfo(key); + if (itemIndex < 0) { + return FALSE; + } + return getValue(entryIndex, itemIndex, &pValueOut); } - -bool ToolData::GetValue(int, const char*, bool&) const { } - -bool ToolData::GetValue(int param_1, const char* param_2, - const char*& param_3) const -{ - int idx = SearchItemInfo(param_2); - if (idx < 0) - return false; - u8* base = (u8*)unk4 + unk4->unk8 + param_1 * unk4->unkC; - u8* ptr = base + unk4->unk10[idx].getUnk8(); - param_3 = (const char*)ptr; - return true; -} - -bool ToolData::GetValue(int, const char*, f32&) const { } - -int ToolData::SearchItemInfo(const char* name) const -{ - int count = unk4->unk4; - u32 hash = Hash(name); - - for (int i = 0; i < count; i++) - if (hash == unk4->unk10[i].unk0) - return i; - - return -1; -} - -void ToolData::FindElement(int, u32, int) const { } - -void ToolData::FindElement(int, s32, int) const { } - -void ToolData::FindElement(int, bool, int) const { } - -void ToolData::FindElement(int, const char*, int) const { } - -void ToolData::FindElement(int, f32, int) const { } +} // namespace Koga