diff --git a/data/uking_functions.csv b/data/uking_functions.csv index 04d88abe..fdf08d2e 100644 --- a/data/uking_functions.csv +++ b/data/uking_functions.csv @@ -61780,51 +61780,51 @@ 0x0000007100aab7f8,isCurrentMapTypeMainFieldOrGameTestField,264, 0x0000007100aab900,sub_7100AAB900,84, 0x0000007100aab954,sub_7100AAB954,32, -0x0000007100aab974,_ZN2al9ByamlIterC2Ev,8, -0x0000007100aab97c,_ZN2al9ByamlIterC2EPKh,76, -0x0000007100aab9c8,_ZN2al9ByamlIterC1EPKhS2_,20, -0x0000007100aab9dc,_ZN2al9ByamlIteraSERKS0_,28, -0x0000007100aab9f8,_ZN2al9ByamlIterC1EPKhS2__0,8, -0x0000007100aaba00,_ZNK2al9ByamlIter7isValidEv,16, -0x0000007100aaba10,_ZNK2al9ByamlIter11isTypeArrayEv,32, -0x0000007100aaba30,_ZNK2al9ByamlIter10isExistKeyEPKc,140, -0x0000007100aababc,_ZNK2al9ByamlIter11getKeyIndexEPKc,60, -0x0000007100aabaf8,_ZNK2al9ByamlIter7getSizeEv,56, -0x0000007100aabb30,_ZNK2al9ByamlIter19getByamlDataByIndexEPNS_9ByamlDataEi,212, -0x0000007100aabc04,_ZNK2al9ByamlIter12getIterByKeyEPKc,136, -0x0000007100aabc8c,_ZNK2al9ByamlIter17getByamlDataByKeyEPNS_9ByamlDataEPKc,252, -0x0000007100aabd88,_ZNK2al9ByamlIter10getKeyNameEPPKci,152, -0x0000007100aabe20,_ZNK2al9ByamlIter17tryGetIterByIndexEPS0_i,88, -0x0000007100aabe78,_ZNK2al9ByamlIter27tryGetIterAndKeyNameByIndexEPS0_PPKci,324, -0x0000007100aabfbc,_ZNK2al9ByamlIter15tryGetIterByKeyEPS0_PKc,164, -0x0000007100aac060,_ZNK2al9ByamlIter17tryGetStringByKeyEPPKcS2_,140, -0x0000007100aac0ec,_ZNK2al9ByamlIter16tryConvertStringEPPKcPKNS_9ByamlDataE,100, -0x0000007100aac150,_ZNK2al9ByamlIter14tryGetIntByKeyEPiPKc,104, -0x0000007100aac1b8,_ZNK2al9ByamlIter15tryGetUIntByKeyEPjPKc,136, -0x0000007100aac240,_ZNK2al9ByamlIter14tryConvertUIntEPjPKNS_9ByamlDataE,72, -0x0000007100aac288,_ZNK2al9ByamlIter16tryGetFloatByKeyEPfPKc,104, -0x0000007100aac2f0,_ZNK2al9ByamlIter15tryGetBoolByKeyEPbPKc,112, -0x0000007100aac360,_ZNK2al9ByamlIter19tryGetStringByIndexEPPKci,208, -0x0000007100aac430,_ZNK2al9ByamlIter16tryGetIntByIndexEPii,180, -0x0000007100aac4e4,_ZNK2al9ByamlIter17tryGetUIntByIndexEPji,212, -0x0000007100aac5b8,_ZNK2al9ByamlIter18tryGetFloatByIndexEPfi,180, -0x0000007100aac66c,_ZNK2al9ByamlIter17tryGetBoolByIndexEPbi,188, -0x0000007100aac728,_ZNK2al9ByamlIter11isEqualDataERKS0_,60, -0x0000007100aac764,_ZN2al9ByamlDataC2Ev,12, -0x0000007100aac770,alByamlLocalUtil::getHashKeyTableOrStringTable,8, -0x0000007100aac778,_ZNK2al20ByamlStringTableIter9getStringEi,20, -0x0000007100aac78c,_ZNK2al20ByamlStringTableIter15findStringIndexEPKc,152, -0x0000007100aac824,_ZN2al14ByamlArrayIterC2EPKhb,8, -0x0000007100aac82c,_ZNK2al14ByamlArrayIter12getDataTableEv,32, -0x0000007100aac84c,_ZNK2al14ByamlArrayIter14getDataByIndexEPNS_9ByamlDataEi,96, +0x0000007100aab974,_ZN2al9ByamlIterC2Ev,8,_ZN2al9ByamlIterC1Ev +0x0000007100aab97c,_ZN2al9ByamlIterC2EPKh,76,_ZN2al9ByamlIterC1EPKh +0x0000007100aab9c8,_ZN2al9ByamlIterC1EPKhS2_,20,_ZN2al9ByamlIterC1ERKS0_ +0x0000007100aab9dc,_ZN2al9ByamlIteraSERKS0_,28,_ZN2al9ByamlIter3SetERKS0_ +0x0000007100aab9f8,_ZN2al9ByamlIterC1EPKhS2__0,8,_ZN2al9ByamlIterC1EPKhS2_ +0x0000007100aaba00,_ZNK2al9ByamlIter7isValidEv,16,_ZNK2al9ByamlIter7isValidEv +0x0000007100aaba10,_ZNK2al9ByamlIter11isTypeArrayEv,32,_ZNK2al9ByamlIter11isTypeArrayEv +0x0000007100aaba30,_ZNK2al9ByamlIter10isExistKeyEPKc,140,_ZNK2al9ByamlIter10isExistKeyEPKc +0x0000007100aababc,_ZNK2al9ByamlIter11getKeyIndexEPKc,60,_ZNK2al9ByamlIter11getKeyIndexEPKc +0x0000007100aabaf8,_ZNK2al9ByamlIter7getSizeEv,56,_ZNK2al9ByamlIter7getSizeEv +0x0000007100aabb30,_ZNK2al9ByamlIter19getByamlDataByIndexEPNS_9ByamlDataEi,212,_ZNK2al9ByamlIter14getIterByIndexEi +0x0000007100aabc04,_ZNK2al9ByamlIter12getIterByKeyEPKc,136,_ZNK2al9ByamlIter12getIterByKeyEPKc +0x0000007100aabc8c,_ZNK2al9ByamlIter17getByamlDataByKeyEPNS_9ByamlDataEPKc,252,_ZNK2al9ByamlIter17getByamlDataByKeyEPNS_9ByamlDataEPKc +0x0000007100aabd88,_ZNK2al9ByamlIter10getKeyNameEPPKci,152,_ZNK2al9ByamlIter10getKeyNameEPPKci +0x0000007100aabe20,_ZNK2al9ByamlIter17tryGetIterByIndexEPS0_i,88,_ZNK2al9ByamlIter17tryGetIterByIndexEPS0_i +0x0000007100aabe78,_ZNK2al9ByamlIter27tryGetIterAndKeyNameByIndexEPS0_PPKci,324,_ZNK2al9ByamlIter27tryGetIterAndKeyNameByIndexEPS0_PPKci! +0x0000007100aabfbc,_ZNK2al9ByamlIter15tryGetIterByKeyEPS0_PKc,164,_ZNK2al9ByamlIter15tryGetIterByKeyEPS0_PKc +0x0000007100aac060,_ZNK2al9ByamlIter17tryGetStringByKeyEPPKcS2_,140,_ZNK2al9ByamlIter17tryGetStringByKeyEPPKcS2_ +0x0000007100aac0ec,_ZNK2al9ByamlIter16tryConvertStringEPPKcPKNS_9ByamlDataE,100,_ZNK2al9ByamlIter16tryConvertStringEPPKcPKNS_9ByamlDataE +0x0000007100aac150,_ZNK2al9ByamlIter14tryGetIntByKeyEPiPKc,104,_ZNK2al9ByamlIter14tryGetIntByKeyEPiPKc +0x0000007100aac1b8,_ZNK2al9ByamlIter15tryGetUIntByKeyEPjPKc,136,_ZNK2al9ByamlIter15tryGetUIntByKeyEPjPKc! +0x0000007100aac240,_ZNK2al9ByamlIter14tryConvertUIntEPjPKNS_9ByamlDataE,72,_ZNK2al9ByamlIter14tryConvertUIntEPjPKNS_9ByamlDataE +0x0000007100aac288,_ZNK2al9ByamlIter16tryGetFloatByKeyEPfPKc,104,_ZNK2al9ByamlIter16tryGetFloatByKeyEPfPKc +0x0000007100aac2f0,_ZNK2al9ByamlIter15tryGetBoolByKeyEPbPKc,112,_ZNK2al9ByamlIter15tryGetBoolByKeyEPbPKc +0x0000007100aac360,_ZNK2al9ByamlIter19tryGetStringByIndexEPPKci,208,_ZNK2al9ByamlIter19tryGetStringByIndexEPPKci +0x0000007100aac430,_ZNK2al9ByamlIter16tryGetIntByIndexEPii,180,_ZNK2al9ByamlIter16tryGetIntByIndexEPii +0x0000007100aac4e4,_ZNK2al9ByamlIter17tryGetUIntByIndexEPji,212,_ZNK2al9ByamlIter17tryGetUIntByIndexEPji! +0x0000007100aac5b8,_ZNK2al9ByamlIter18tryGetFloatByIndexEPfi,180,_ZNK2al9ByamlIter18tryGetFloatByIndexEPfi +0x0000007100aac66c,_ZNK2al9ByamlIter17tryGetBoolByIndexEPbi,188,_ZNK2al9ByamlIter17tryGetBoolByIndexEPbi +0x0000007100aac728,_ZNK2al9ByamlIter11isEqualDataERKS0_,60,_ZNK2al9ByamlIter11isEqualDataERKS0_ +0x0000007100aac764,_ZN2al9ByamlDataC2Ev,12,_ZN2al9ByamlDataC1Ev +0x0000007100aac770,alByamlLocalUtil::getHashKeyTableOrStringTable,8,_ZN2al20ByamlStringTableIterC1EPKh +0x0000007100aac778,_ZNK2al20ByamlStringTableIter9getStringEi,20,_ZNK2al20ByamlStringTableIter9getStringEi +0x0000007100aac78c,_ZNK2al20ByamlStringTableIter15findStringIndexEPKc,152,_ZNK2al20ByamlStringTableIter15findStringIndexEPKc +0x0000007100aac824,_ZN2al14ByamlArrayIterC2EPKhb,8,_ZN2al14ByamlArrayIterC1EPKh +0x0000007100aac82c,_ZNK2al14ByamlArrayIter12getDataTableEv,32,_ZNK2al14ByamlArrayIter12getDataTableEv +0x0000007100aac84c,_ZNK2al14ByamlArrayIter14getDataByIndexEPNS_9ByamlDataEi,96,_ZN2al14ByamlArrayIter14getDataByIndexEPNS_9ByamlDataEi 0x0000007100aac8ac,_ZN16alByamlLocalUtil11verifiByamlEPKh,640, -0x0000007100aacb2c,_ZN2al13ByamlHashIterC2EPKhb,8, -0x0000007100aacb34,_ZNK2al13ByamlHashIter7getSizeEv,28, -0x0000007100aacb50,_ZNK2al13ByamlHashIter12getPairTableEv,20, -0x0000007100aacb64,_ZNK2al13ByamlHashIter14getDataByIndexEPNS_9ByamlDataEi,88, -0x0000007100aacbbc,_ZNK2al13ByamlHashIter12getDataByKeyEPNS_9ByamlDataEi,168, -0x0000007100aacc64,_ZNK2al13ByamlHashIter8findPairEi,92, -0x0000007100aaccc0,_ZNK2al13ByamlHashIter14getPairByIndexEi,80, +0x0000007100aacb2c,_ZN2al13ByamlHashIterC2EPKhb,8,_ZN2al13ByamlHashIterC1EPKh +0x0000007100aacb34,_ZNK2al13ByamlHashIter7getSizeEv,28,_ZNK2al13ByamlHashIter7getSizeEv +0x0000007100aacb50,_ZNK2al13ByamlHashIter12getPairTableEv,20,_ZNK2al13ByamlHashIter12getPairTableEv +0x0000007100aacb64,_ZNK2al13ByamlHashIter14getDataByIndexEPNS_9ByamlDataEi,88,_ZNK2al13ByamlHashIter14getDataByIndexEPNS_9ByamlDataEi +0x0000007100aacbbc,_ZNK2al13ByamlHashIter12getDataByKeyEPNS_9ByamlDataEi,168,_ZNK2al13ByamlHashIter12getDataByKeyEPNS_9ByamlDataEi +0x0000007100aacc64,_ZNK2al13ByamlHashIter8findPairEi,92,_ZNK2al13ByamlHashIter8findPairEi +0x0000007100aaccc0,_ZNK2al13ByamlHashIter14getPairByIndexEi,80,_ZNK2al13ByamlHashIter14getPairByIndexEi 0x0000007100aacd10,_ZN2al14tryGetByamlS32EPiRKNS_9ByamlIterEPKc,16,_ZN2al14tryGetByamlS32EPiRKNS_9ByamlIterEPKc 0x0000007100aacd20,_ZN2al14tryGetByamlU32EPjRKNS_9ByamlIterEPKc,64,_ZN2al14tryGetByamlU32EPjRKNS_9ByamlIterEPKc 0x0000007100aacd60,_ZN2al14tryGetByamlF32EPfRKNS_9ByamlIterEPKc,72,_ZN2al14tryGetByamlF32EPfRKNS_9ByamlIterEPKc diff --git a/src/KingSystem/ActorSystem/actActorParam.cpp b/src/KingSystem/ActorSystem/actActorParam.cpp index b358375a..639f6b3f 100644 --- a/src/KingSystem/ActorSystem/actActorParam.cpp +++ b/src/KingSystem/ActorSystem/actActorParam.cpp @@ -3,7 +3,7 @@ #include #include "KingSystem/ActorSystem/actActorParamMgr.h" #include "KingSystem/ActorSystem/actActorTemplate.h" -#include "KingSystem/Utils/Byaml.h" +#include "KingSystem/Utils/Byaml/Byaml.h" namespace ksys::act { diff --git a/src/KingSystem/ActorSystem/actActorTemplate.cpp b/src/KingSystem/ActorSystem/actActorTemplate.cpp index 0daf5dae..f4b16526 100644 --- a/src/KingSystem/ActorSystem/actActorTemplate.cpp +++ b/src/KingSystem/ActorSystem/actActorTemplate.cpp @@ -1,6 +1,6 @@ #include "KingSystem/ActorSystem/actActorTemplate.h" #include "KingSystem/ActorSystem/actActorParamMgr.h" -#include "KingSystem/Utils/Byaml.h" +#include "KingSystem/Utils/Byaml/Byaml.h" #include "KingSystem/Utils/SafeDelete.h" namespace ksys::act { diff --git a/src/KingSystem/Ecosystem/ecoLevelSensor.cpp b/src/KingSystem/Ecosystem/ecoLevelSensor.cpp index 42676953..f7db37fd 100644 --- a/src/KingSystem/Ecosystem/ecoLevelSensor.cpp +++ b/src/KingSystem/Ecosystem/ecoLevelSensor.cpp @@ -1,5 +1,5 @@ #include "KingSystem/Ecosystem/ecoLevelSensor.h" -#include "KingSystem/Utils/Byaml.h" +#include "KingSystem/Utils/Byaml/Byaml.h" namespace ksys::eco { diff --git a/src/KingSystem/GameData/gdtManager.h b/src/KingSystem/GameData/gdtManager.h index 8208414b..7dca62ce 100644 --- a/src/KingSystem/GameData/gdtManager.h +++ b/src/KingSystem/GameData/gdtManager.h @@ -12,7 +12,7 @@ #include "KingSystem/GameData/gdtTriggerParam.h" #include "KingSystem/Resource/resHandle.h" #include "KingSystem/System/KingEditor.h" -#include "KingSystem/Utils/Byaml.h" +#include "KingSystem/Utils/Byaml/Byaml.h" #include "KingSystem/Utils/Types.h" namespace sead { diff --git a/src/KingSystem/Map/mapMubinIter.h b/src/KingSystem/Map/mapMubinIter.h index cf9f7243..fc7c8606 100644 --- a/src/KingSystem/Map/mapMubinIter.h +++ b/src/KingSystem/Map/mapMubinIter.h @@ -2,7 +2,7 @@ #include #include "KingSystem/Map/mapTypes.h" -#include "KingSystem/Utils/Byaml.h" +#include "KingSystem/Utils/Byaml/Byaml.h" namespace ksys::map { diff --git a/src/KingSystem/Resource/resResourceGameData.cpp b/src/KingSystem/Resource/resResourceGameData.cpp index 7020a57d..cc315128 100644 --- a/src/KingSystem/Resource/resResourceGameData.cpp +++ b/src/KingSystem/Resource/resResourceGameData.cpp @@ -1,7 +1,7 @@ #include "KingSystem/Resource/resResourceGameData.h" #include #include "KingSystem/GameData/gdtManager.h" -#include "KingSystem/Utils/Byaml.h" +#include "KingSystem/Utils/Byaml/Byaml.h" #include "KingSystem/Utils/HeapUtil.h" namespace ksys::res { diff --git a/src/KingSystem/Resource/resResourceGameSaveData.cpp b/src/KingSystem/Resource/resResourceGameSaveData.cpp index 108239f2..b832fb27 100644 --- a/src/KingSystem/Resource/resResourceGameSaveData.cpp +++ b/src/KingSystem/Resource/resResourceGameSaveData.cpp @@ -3,7 +3,7 @@ #include #include #include "KingSystem/GameData/gdtManager.h" -#include "KingSystem/Utils/Byaml.h" +#include "KingSystem/Utils/Byaml/Byaml.h" namespace ksys::res { diff --git a/src/KingSystem/Utils/Byaml.cpp b/src/KingSystem/Utils/Byaml.cpp deleted file mode 100644 index 23d82bb9..00000000 --- a/src/KingSystem/Utils/Byaml.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "KingSystem/Utils/Byaml.h" diff --git a/src/KingSystem/Utils/Byaml/Byaml.cpp b/src/KingSystem/Utils/Byaml/Byaml.cpp new file mode 100644 index 00000000..bb1df102 --- /dev/null +++ b/src/KingSystem/Utils/Byaml/Byaml.cpp @@ -0,0 +1,396 @@ +#include "KingSystem/Utils/Byaml/Byaml.h" +#include "KingSystem/Utils/Byaml/ByamlArrayIter.h" +#include "KingSystem/Utils/Byaml/ByamlData.h" +#include "KingSystem/Utils/Byaml/ByamlHashIter.h" +#include "KingSystem/Utils/Byaml/ByamlLocal.h" +#include "KingSystem/Utils/Byaml/ByamlStringTableIter.h" +#include "math/seadMathCalcCommon.h" + +namespace al { + +ByamlIter::ByamlIter() : mData(nullptr), mRootNode(nullptr) {} + +ByamlIter::ByamlIter(const u8* data) { + mData = data; + mRootNode = nullptr; + if (mData) { + if (ByamlLocalUtil::verifiByaml(mData)) { + const ByamlHeader* header = reinterpret_cast(mData); + u32 data_root_offset = header->getDataOffset(); + if (data_root_offset) { + mRootNode = &mData[data_root_offset]; + } + } else { + mData = nullptr; + mRootNode = nullptr; + } + } +} + +ByamlIter::ByamlIter(const u8* data, const u8* root_node) : mData(data), mRootNode(root_node) {} + +ByamlIter::ByamlIter(const ByamlIter& other) : mData(other.mData), mRootNode(other.mRootNode) {} + +void ByamlIter::Set(const ByamlIter& other) { + if (this != &other) { + *this = other; + } +} + +bool ByamlIter::isValid() const { + return mData != nullptr; +} + +bool ByamlIter::isTypeHash() const { + const ByamlContainerHeader* node = reinterpret_cast(mRootNode); + return node && node->getType() == ByamlType::Hash; +} + +bool ByamlIter::isTypeArray() const { + const ByamlContainerHeader* node = reinterpret_cast(mRootNode); + return node && node->getType() == ByamlType::Array; +} + +bool ByamlIter::isTypeContainer() const { + return isTypeArray() || isTypeHash(); +} + +bool ByamlIter::isExistKey(const char* key) const { + if (!mRootNode) { + return false; + } + + if (!isTypeHash()) { + return false; + } + + const s32 index = getKeyIndex(key); + if (index < 0) { + return 0; + } + + ByamlHashIter node_hash(mRootNode); + return node_hash.findPair(index); +} + +s32 ByamlIter::getKeyIndex(const char* key) const { + const ByamlStringTableIter table = ByamlLocalUtil::getHashKeyTableIter(mData); + return table.findStringIndex(key); +} + +s32 ByamlIter::getSize() const { + if (!mRootNode) { + return 0; + } + + if (isTypeContainer()) { + return ByamlLocalUtil::getContainerSize(mRootNode); + } + + return 0; +} + +ByamlIter ByamlIter::getIterByIndex(s32 index) const { + ByamlData data; + if (!getByamlDataByIndex(&data, index)) { + return ByamlIter(); + } + + return getIterFromData(data); +} + +ByamlIter ByamlIter::getIterByKey(const char* key) const { + ByamlData data; + if (!getByamlDataByKey(&data, key)) { + return ByamlIter(); + } + + return getIterFromData(data); +} + +ByamlIter ByamlIter::getIterFromData(const ByamlData& data) const { + if (data.getType() == ByamlType::Hash || data.getType() == ByamlType::Array) { + return ByamlIter(mData, &mData[data.getValue()]); + } + + if (data.getType() == ByamlType::Null) { + return ByamlIter(mData, nullptr); + } + + return ByamlIter(); +} + +bool ByamlIter::getByamlDataByIndex(ByamlData* data, s32 index) const { + if (isTypeArray()) { + ByamlArrayIter array_node(mRootNode); + return array_node.getDataByIndex(data, index); + } else if (isTypeHash()) { + ByamlHashIter hash_node(mRootNode); + return hash_node.getDataByIndex(data, index); + } + + return false; +} + +bool ByamlIter::getByamlDataByKey(ByamlData* data, const char* key) const { + if (!isTypeHash()) { + return false; + } + + auto* header = reinterpret_cast(mData); + const s32 offset = header->getHashKeyTableOffset(); + if (!offset) { + return false; + } + const ByamlStringTableIter table = ByamlStringTableIter(&mData[offset]); + + ByamlHashIter hash_node(mRootNode); + const s32 size = hash_node.getSize(); + if (size < 1) { + return false; + } + + // Binary Search + const ByamlHashPair* pair; + s32 start = 0; + s32 end = size; + s32 index; + while (true) { + if (start >= end) { + return false; + } + + index = (start + end) / 2; + pair = hash_node.getPairByIndex(index); + const char* str = table.getString(pair->getKey()); + s32 result = std::strcmp(key, str); + if (result == 0) + break; + if (result > 0) + start = index + 1; + else if (result < 0) + end = index; + } + + data->set(pair); + + return true; +} + +bool ByamlIter::getByamlDataAndKeyNameByIndex(ByamlData* data, const char** key, s32 index) const { + if (!isTypeHash()) { + return false; + } + + const ByamlHashIter hash_iter(mRootNode); + const ByamlHashPair* pair = hash_iter.getPairByIndex(index); + if (!pair) { + return false; + } + + if (data) { + data->set(pair); + } + + ByamlStringTableIter table_iter = ByamlLocalUtil::getHashKeyTableIter(mData); + *key = table_iter.getString(pair->getKey()); + return true; +} + +bool ByamlIter::getKeyName(const char** key, s32 index) const { + if (!mRootNode) { + return false; + } + + if (!isTypeHash()) { + return false; + } + + ByamlHashIter hash_node(mRootNode); + const ByamlHashPair* pair = hash_node.getPairByIndex(index); + if (!pair) { + return false; + } + + const ByamlStringTableIter hash_table = ByamlLocalUtil::getHashKeyTableIter(mData); + *key = hash_table.getString(pair->getKey()); + + return true; +} + +bool ByamlIter::tryGetIterByIndex(ByamlIter* iter, s32 index) const { + iter->Set(getIterByIndex(index)); + return iter->isValid(); +} + +bool ByamlIter::tryGetIterByKey(ByamlIter* iter, const char* key) const { + iter->Set(getIterByKey(key)); + return iter->isValid(); +} + +bool ByamlIter::tryGetIterAndKeyNameByIndex(ByamlIter* iter, const char** key, s32 index) const { + ByamlData data; + if (!getByamlDataAndKeyNameByIndex(&data, key, index)) { + *key = nullptr; + return tryGetIterByIndex(iter, index); + } + + iter->Set(getIterFromData(data)); + return true; +} + +bool ByamlIter::tryGetStringByIndex(const char** value, s32 index) const { + ByamlData data; + if (!getByamlDataByIndex(&data, index)) { + return false; + } + + return tryConvertString(value, &data); +} + +bool ByamlIter::tryGetStringByKey(const char** value, const char* key) const { + ByamlData data; + if (!getByamlDataByKey(&data, key)) { + return false; + } + + return tryConvertString(value, &data); +} + +bool ByamlIter::tryConvertString(const char** value, const ByamlData* data) const { + if (data->getType() != ByamlType::String) { + return false; + } + + const auto string_table = ByamlLocalUtil::getStringTableIter(mData); + *value = string_table.getString(data->getValue()); + + return true; +} + +bool ByamlIter::tryGetIntByIndex(s32* value, s32 index) const { + ByamlData data; + if (!getByamlDataByIndex(&data, index)) { + return false; + } + + return tryConvertInt(value, &data); +} + +bool ByamlIter::tryGetIntByKey(s32* value, const char* key) const { + ByamlData data; + if (!getByamlDataByKey(&data, key)) { + return false; + } + + return tryConvertInt(value, &data); +} + +bool ByamlIter::tryConvertInt(s32* value, const ByamlData* data) const { + if (data->getType() != ByamlType::Int) { + return false; + } + + *value = data->getValue(); + return true; +} + +bool ByamlIter::tryGetUIntByIndex(u32* value, s32 index) const { + ByamlData data; + if (!getByamlDataByIndex(&data, index)) { + return false; + } + + return tryConvertUInt(value, &data); +} + +bool ByamlIter::tryGetUIntByKey(u32* value, const char* key) const { + ByamlData data; + if (!getByamlDataByKey(&data, key)) { + return false; + } + + return tryConvertUInt(value, &data); +} + +bool ByamlIter::tryConvertUInt(u32* value, const ByamlData* data) const { + if (data->getType() == ByamlType::Int) { + s32 signed_value = data->getValue(); + if (signed_value < 0) { + *value = 0; + return false; + } else { + *value = signed_value; + return true; + } + } else if (data->getType() == ByamlType::UInt) { + *value = data->getValue(); + return true; + } + + return false; +} + +bool ByamlIter::tryGetFloatByIndex(f32* value, s32 index) const { + ByamlData data; + if (!getByamlDataByIndex(&data, index)) { + return false; + } + + return tryConvertFloat(value, &data); +} + +bool ByamlIter::tryGetFloatByKey(f32* value, const char* key) const { + ByamlData data; + if (!getByamlDataByKey(&data, key)) { + return false; + } + + return tryConvertFloat(value, &data); +} + +bool ByamlIter::tryConvertFloat(f32* value, const ByamlData* data) const { + if (data->getType() != ByamlType::Float) { + return false; + } + + *value = data->getValue(); + return true; +} + +bool ByamlIter::tryGetBoolByIndex(bool* value, s32 index) const { + ByamlData data; + if (!getByamlDataByIndex(&data, index)) { + return false; + } + + return tryConvertBool(value, &data); +} + +bool ByamlIter::tryGetBoolByKey(bool* value, const char* key) const { + ByamlData data; + if (!getByamlDataByKey(&data, key)) { + return false; + } + + return tryConvertBool(value, &data); +} + +bool ByamlIter::tryConvertBool(bool* value, const ByamlData* data) const { + if (data->getType() != ByamlType::Bool) { + return false; + } + + *value = data->getValue() != 0; + return true; +} + +bool ByamlIter::isEqualData(const ByamlIter& other) const { + if (!mData || !other.mData) { + return false; + } + + return mData == other.mData && mRootNode == other.mRootNode; +} + +} // namespace al \ No newline at end of file diff --git a/src/KingSystem/Utils/Byaml.h b/src/KingSystem/Utils/Byaml/Byaml.h similarity index 63% rename from src/KingSystem/Utils/Byaml.h rename to src/KingSystem/Utils/Byaml/Byaml.h index 5c600627..4a3bf037 100644 --- a/src/KingSystem/Utils/Byaml.h +++ b/src/KingSystem/Utils/Byaml/Byaml.h @@ -4,12 +4,14 @@ #include #include +#include #include #include "KingSystem/Utils/Types.h" namespace al { struct ByamlData; +struct ByamlHashPair; enum class ByamlType { Invalid = 0, @@ -39,7 +41,8 @@ public: ByamlIter(const u8* data, const u8* root_node); ByamlIter(const ByamlIter& other); - ByamlIter& operator=(const ByamlIter& rhs); + ByamlIter& operator=(const ByamlIter& rhs) = default; + void Set(const ByamlIter& other); bool isValid() const; bool isTypeHash() const; @@ -51,11 +54,13 @@ public: s32 getSize() const; - void getByamlDataByIndex(ByamlData* data, s32 index) const; - bool getByamlDataByKey(ByamlData* data, const char* key) const; - bool getByamlDataByKeyIndex(ByamlData* data, s32 index) const; ByamlIter getIterByIndex(s32 index) const; ByamlIter getIterByKey(const char* key) const; + ByamlIter getIterFromData(const ByamlData& data) const; + bool getByamlDataByIndex(ByamlData* data, s32 index) const; + bool getByamlDataByKey(ByamlData* data, const char* key) const; + bool getByamlDataAndKeyNameByIndex(ByamlData* data, const char** key, s32 index) const; + bool getKeyName(const char** key, s32 index) const; bool tryGetIterByIndex(ByamlIter* iter, s32 index) const; @@ -68,6 +73,7 @@ public: bool tryGetIntByIndex(s32* value, s32 index) const; bool tryGetIntByKey(s32* value, const char* key) const; + bool tryConvertInt(s32* value, const ByamlData* data) const; bool tryGetUIntByIndex(u32* value, s32 index) const; bool tryGetUIntByKey(u32* value, const char* key) const; @@ -75,9 +81,11 @@ public: bool tryGetFloatByIndex(f32* value, s32 index) const; bool tryGetFloatByKey(f32* value, const char* key) const; + bool tryConvertFloat(f32* value, const ByamlData* data) const; bool tryGetBoolByIndex(bool* value, s32 index) const; bool tryGetBoolByKey(bool* value, const char* key) const; + bool tryConvertBool(bool* value, const ByamlData* data) const; bool isEqualData(const ByamlIter& other) const; @@ -86,50 +94,13 @@ private: const u8* mRootNode = nullptr; }; -class ByamlStringTableIter { -public: - explicit ByamlStringTableIter(const u8* data) : mData(data) {} - - const char* getString(s32 index) const; - s32 findStringIndex(const char* string) const; - -private: - const u8* mData; -}; - -class ByamlArrayIter { -public: - explicit ByamlArrayIter(const u8* data); - - const u8* getDataTable() const; - bool getDataByIndex(ByamlData* data, s32 index); - -private: - const u8* mData; -}; - -class ByamlHashIter { -public: - explicit ByamlHashIter(const u8* data); - - s32 getSize() const; - const u8* getPairTable() const; - bool getDataByIndex(ByamlData* data, s32 index) const; - bool getDataByKey(ByamlData* data, s32 key_index) const; - const u8* findPair(s32 key_index) const; - const u8* getPairByIndex(s32 index) const; - -private: - const u8* mData; -}; - struct ByamlHeader { u16 getTag() const; bool isInvertHeader() const; - u16 getVersion() const; - u16 getHashKeyTableOffset() const; - u16 getStringTableOffset() const; - u16 getDataOffset() const; + u16 getVersion() const { return version; }; + u32 getHashKeyTableOffset() const { return hash_key_table_offset; }; + u32 getStringTableOffset() const { return string_table_offset; }; + u32 getDataOffset() const { return data_offset; }; u16 magic; u16 version; @@ -140,32 +111,15 @@ struct ByamlHeader { KSYS_CHECK_SIZE_NX150(ByamlHeader, 0x10); struct ByamlContainerHeader { - ByamlType getType() const; - u32 getCount(bool byteswap) const; + ByamlType getType() const { + // Type is only the first byte + return ByamlType(*reinterpret_cast(&type_and_size)); + } + u32 getCount() const { return type_and_size >> 8; }; u32 type_and_size; }; -struct ByamlHashPair { - u32 getKey(bool byteswap) const; - ByamlType getType() const; - u32 getValue(bool byteswap) const; - - u32 name_and_type; - u32 value; -}; - -struct ByamlData { - u32 getValue() const { return value; } - ByamlType getType() const { return type; } - - void set(const ByamlHashPair* pair, bool byteswap); - void set(u8, u32, bool byteswap); - - u32 value = 0; - sead::SizedEnum type = ByamlType::Invalid; -}; - bool tryGetByamlS32(s32* value, const ByamlIter& iter, const char* key); bool tryGetByamlU32(u32* value, const ByamlIter& iter, const char* key); bool tryGetByamlF32(f32* value, const ByamlIter& iter, const char* key); diff --git a/src/KingSystem/Utils/Byaml/ByamlArrayIter.cpp b/src/KingSystem/Utils/Byaml/ByamlArrayIter.cpp new file mode 100644 index 00000000..fe5db205 --- /dev/null +++ b/src/KingSystem/Utils/Byaml/ByamlArrayIter.cpp @@ -0,0 +1,29 @@ +#include "KingSystem/Utils/Byaml/ByamlArrayIter.h" +#include "KingSystem/Utils/Byaml/Byaml.h" +#include "KingSystem/Utils/Byaml/ByamlData.h" +#include "KingSystem/Utils/Byaml/ByamlLocal.h" + +namespace al { +ByamlArrayIter::ByamlArrayIter(const u8* data) { + mData = data; +} + +const u32* ByamlArrayIter::getDataTable() const { + return reinterpret_cast(&mData[TypeTableOffset + getDataOffset()]); +} + +bool ByamlArrayIter::getDataByIndex(ByamlData* data, s32 index) { + if (index < 0) { + return false; + } + + if (index >= ByamlLocalUtil::getContainerSize(mData)) { + return false; + } + + data->setType(ByamlType(mData[TypeTableOffset + index])); + data->setValue(getDataTable()[index]); + + return true; +} +} // namespace al \ No newline at end of file diff --git a/src/KingSystem/Utils/Byaml/ByamlArrayIter.h b/src/KingSystem/Utils/Byaml/ByamlArrayIter.h new file mode 100644 index 00000000..a29cefc1 --- /dev/null +++ b/src/KingSystem/Utils/Byaml/ByamlArrayIter.h @@ -0,0 +1,28 @@ +#pragma once + +#include +#include +#include "KingSystem/Utils/Byaml/Byaml.h" +#include "KingSystem/Utils/Byaml/ByamlLocal.h" + +namespace al { + +class ByamlArrayIter { +public: + explicit ByamlArrayIter(const u8* data); + + const u32* getDataTable() const; + bool getDataByIndex(ByamlData* data, s32 index); + +private: + s32 getDataOffset() const { + const s32 size = ByamlLocalUtil::getContainerSize(mData); + return sead::Mathu::roundUp(size, 4); + } + + static constexpr s32 TypeTableOffset = 4; + + const u8* mData; +}; + +} // namespace al diff --git a/src/KingSystem/Utils/Byaml/ByamlData.cpp b/src/KingSystem/Utils/Byaml/ByamlData.cpp new file mode 100644 index 00000000..2aff5f96 --- /dev/null +++ b/src/KingSystem/Utils/Byaml/ByamlData.cpp @@ -0,0 +1,7 @@ +#include "KingSystem/Utils/Byaml/ByamlData.h" +#include "KingSystem/Utils/Byaml/Byaml.h" + +namespace al { +ByamlData::ByamlData() = default; + +} // namespace al \ No newline at end of file diff --git a/src/KingSystem/Utils/Byaml/ByamlData.h b/src/KingSystem/Utils/Byaml/ByamlData.h new file mode 100644 index 00000000..ed41dc82 --- /dev/null +++ b/src/KingSystem/Utils/Byaml/ByamlData.h @@ -0,0 +1,45 @@ +#pragma once + +#include +#include "KingSystem/Utils/Byaml/Byaml.h" +#include "KingSystem/Utils/Byaml/ByamlHashIter.h" + +namespace al { + +struct ByamlData { + ByamlData(); + + template + T getValue() const { + return *reinterpret_cast(&mValue); + } + ByamlType getType() const { return mType; } + + void set(const ByamlHashPair* pair) { + mType = pair->getType(); + mValue = pair->getValue(); + } + template + void set(const ByamlType& type, const T& value) { + mType = type; + mValue = *reinterpret_cast(&value); + } + + void setType(const ByamlType& type) { mType = type; } + + template + void setValue(const T& value) { + mValue = *reinterpret_cast(&value); + } + + void clear() { + mValue = 0; + mType = ByamlType::Invalid; + } + +private: + u32 mValue = 0; + sead::SizedEnum mType = ByamlType::Invalid; +}; + +} // namespace al diff --git a/src/KingSystem/Utils/Byaml/ByamlHashIter.cpp b/src/KingSystem/Utils/Byaml/ByamlHashIter.cpp new file mode 100644 index 00000000..edce10ee --- /dev/null +++ b/src/KingSystem/Utils/Byaml/ByamlHashIter.cpp @@ -0,0 +1,110 @@ +#include "KingSystem/Utils/Byaml/ByamlHashIter.h" +#include "KingSystem/Utils/Byaml/Byaml.h" +#include "KingSystem/Utils/Byaml/ByamlData.h" +#include "KingSystem/Utils/Byaml/ByamlLocal.h" + +namespace al { + +ByamlHashIter::ByamlHashIter(const u8* data) { + mData = data; +} + +s32 ByamlHashIter::getSize() const { + if (!mData) { + return 0; + } + + return ByamlLocalUtil::getContainerSize(mData); +} + +const ByamlHashPair* ByamlHashIter::getPairTable() const { + if (!mData) { + return nullptr; + } + + return reinterpret_cast(&mData[mTableOffset]); +} + +bool ByamlHashIter::getDataByIndex(ByamlData* data, s32 index) const { + if (!mData) { + return false; + } + + if (ByamlLocalUtil::getContainerSize(mData) == 0) { + return false; + } + + const ByamlHashPair* pair_table = getPairTable(); + const ByamlHashPair* pair = &pair_table[index]; + if (!pair) // This seems wrong, this can never be null? + { + return false; + } + + data->set(pair); + + return true; +} + +bool ByamlHashIter::getDataByKey(ByamlData* data, s32 key_index) const { + if (getSize() == 0) { + return false; + } + + const ByamlHashPair* pair = findPair(key_index); + if (!pair) { + return false; + } + + data->set(pair); + return true; +} + +const ByamlHashPair* ByamlHashIter::findPair(s32 key_index) const { + const ByamlHashPair* pair_table = getPairTable(); + if (!pair_table) { + return nullptr; + } + + if (ByamlLocalUtil::getContainerSize(mData) == 0) { + return nullptr; + } + + // Binary Search + s32 start = 0; + s32 end = getSize(); + s32 index; + const ByamlHashPair* pair; + while (true) { + if (start >= end) { + return nullptr; + } + + index = (start + end) / 2; + pair = &pair_table[index]; + s32 result = key_index - pair->getKey(); + if (result == 0) + break; + if (result > 0) + start = index + 1; + else if (result < 0) + end = index; + } + + return pair; +} + +const ByamlHashPair* ByamlHashIter::getPairByIndex(s32 index) const { + if (index < 0) { + return nullptr; + } + + if (getSize() <= index) { + return nullptr; + } + + const ByamlHashPair* pair_table = getPairTable(); + return pair_table + index; +} + +} // namespace al diff --git a/src/KingSystem/Utils/Byaml/ByamlHashIter.h b/src/KingSystem/Utils/Byaml/ByamlHashIter.h new file mode 100644 index 00000000..2ad55877 --- /dev/null +++ b/src/KingSystem/Utils/Byaml/ByamlHashIter.h @@ -0,0 +1,38 @@ +#pragma once + +#include +#include "KingSystem/Utils/Byaml/Byaml.h" +#include "prim/seadEndian.h" + +namespace al { + +struct ByamlData; +struct ByamlHashPair; + +class ByamlHashIter { +public: + explicit ByamlHashIter(const u8* data); + + s32 getSize() const; + const ByamlHashPair* getPairTable() const; + bool getDataByIndex(ByamlData* data, s32 index) const; + bool getDataByKey(ByamlData* data, s32 key_index) const; + const ByamlHashPair* findPair(s32 key_index) const; + const ByamlHashPair* getPairByIndex(s32 index) const; + +private: + const u8* mData; + + static constexpr s32 mTableOffset = 4; +}; + +struct ByamlHashPair { + u32 getKey() const { return mKeyAndType & 0xFFFFFF; } + ByamlType getType() const { return ByamlType(mKeyAndType >> 24); } + u32 getValue() const { return mValue; } + + u32 mKeyAndType; + u32 mValue; +}; + +} // namespace al diff --git a/src/KingSystem/Utils/Byaml/ByamlLocal.cpp b/src/KingSystem/Utils/Byaml/ByamlLocal.cpp new file mode 100644 index 00000000..321fc879 --- /dev/null +++ b/src/KingSystem/Utils/Byaml/ByamlLocal.cpp @@ -0,0 +1,3 @@ +#include "KingSystem/Utils/Byaml/ByamlLocal.h" + +namespace al::ByamlLocalUtil {} // namespace al::ByamlLocalUtil \ No newline at end of file diff --git a/src/KingSystem/Utils/Byaml/ByamlLocal.h b/src/KingSystem/Utils/Byaml/ByamlLocal.h new file mode 100644 index 00000000..faf51cac --- /dev/null +++ b/src/KingSystem/Utils/Byaml/ByamlLocal.h @@ -0,0 +1,38 @@ +#pragma once + +#include "KingSystem/Utils/Byaml/Byaml.h" +#include "KingSystem/Utils/Byaml/ByamlStringTableIter.h" + +#include + +namespace al::ByamlLocalUtil { + +inline ByamlStringTableIter getHashKeyTableIter(const u8* data) { + auto* header = reinterpret_cast(data); + const u8* ptr = &data[header->getHashKeyTableOffset()]; + return ByamlStringTableIter(ptr); +} + +inline ByamlStringTableIter getStringTableIter(const u8* data) { + auto* header = reinterpret_cast(data); + const u8* ptr = &data[header->getStringTableOffset()]; + return ByamlStringTableIter(ptr); +} + +inline s32 getContainerSize(const u8* data) { + auto* node = reinterpret_cast(data); + return node->getCount(); +} + +inline al::ByamlType getType(const u8* data) { + auto* node = reinterpret_cast(data); + return node->getType(); +} + +const char* getDataTypeString(s32 type); + +bool verifiByaml(const u8* data); +bool verifiByamlHeader(const u8* data); +bool verifiByamlStringTable(const u8* data); + +} // namespace al::ByamlLocalUtil diff --git a/src/KingSystem/Utils/Byaml/ByamlStringTableIter.cpp b/src/KingSystem/Utils/Byaml/ByamlStringTableIter.cpp new file mode 100644 index 00000000..f55e69c8 --- /dev/null +++ b/src/KingSystem/Utils/Byaml/ByamlStringTableIter.cpp @@ -0,0 +1,50 @@ +#include "KingSystem/Utils/Byaml/ByamlStringTableIter.h" +#include "KingSystem/Utils/Byaml/Byaml.h" +#include "KingSystem/Utils/Byaml/ByamlLocal.h" + +namespace al { + +ByamlStringTableIter::ByamlStringTableIter(const u8* data) { + mData = data; +} + +ByamlStringTableIter::ByamlStringTableIter(const ByamlStringTableIter& other) { + mData = other.mData; +} + +const char* ByamlStringTableIter::getString(s32 index) const { + const u32* string_offset_array = getStringOffsetArray(); + return reinterpret_cast(&mData[string_offset_array[index]]); +} + +s32 ByamlStringTableIter::findStringIndex(const char* string) const { + const u32* string_offset_array = getStringOffsetArray(); + u32 table_size = ByamlLocalUtil::getContainerSize(mData); + if (table_size == 0) { + return -1; + } + + // Binary Search + s32 start = 0; + s32 end = table_size; + s32 index; + while (true) { + if (start >= end) { + return -1; + } + + index = (start + end) / 2; + const char* str = reinterpret_cast(&mData[string_offset_array[index]]); + s32 result = std::strcmp(string, str); + if (result == 0) + break; + if (result > 0) + start = index + 1; + else if (result < 0) + end = index; + } + + return index; +} + +} // namespace al diff --git a/src/KingSystem/Utils/Byaml/ByamlStringTableIter.h b/src/KingSystem/Utils/Byaml/ByamlStringTableIter.h new file mode 100644 index 00000000..5e397ab4 --- /dev/null +++ b/src/KingSystem/Utils/Byaml/ByamlStringTableIter.h @@ -0,0 +1,27 @@ +#pragma once + +#include + +namespace al { + +class ByamlStringTableIter { +public: + explicit ByamlStringTableIter(const u8* data); + ByamlStringTableIter(const ByamlStringTableIter& other); + + const char* getString(s32 index) const; + s32 findStringIndex(const char* string) const; + + bool isValid() const { return mData != nullptr; } + + const u32* getStringOffsetArray() const { + return reinterpret_cast(&mData[TableOffset]); + } + +private: + const u8* mData; + + static constexpr u32 TableOffset = 4u; +}; + +} // namespace al \ No newline at end of file diff --git a/src/KingSystem/Utils/ByamlUtil.cpp b/src/KingSystem/Utils/Byaml/ByamlUtil.cpp similarity index 95% rename from src/KingSystem/Utils/ByamlUtil.cpp rename to src/KingSystem/Utils/Byaml/ByamlUtil.cpp index 6c46fff5..ef0df072 100644 --- a/src/KingSystem/Utils/ByamlUtil.cpp +++ b/src/KingSystem/Utils/Byaml/ByamlUtil.cpp @@ -1,4 +1,4 @@ -#include "KingSystem/Utils/Byaml.h" +#include "KingSystem/Utils/Byaml/Byaml.h" namespace al { diff --git a/src/KingSystem/Utils/ByamlLocal.cpp b/src/KingSystem/Utils/ByamlLocal.cpp deleted file mode 100644 index e981e804..00000000 --- a/src/KingSystem/Utils/ByamlLocal.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "KingSystem/Utils/ByamlLocal.h" diff --git a/src/KingSystem/Utils/ByamlLocal.h b/src/KingSystem/Utils/ByamlLocal.h deleted file mode 100644 index f10c68b8..00000000 --- a/src/KingSystem/Utils/ByamlLocal.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include - -namespace alByamlLocalUtil { - -const char* getDataTypeString(s32 type); - -const u8* getHashKeyTable(const u8* data); -const u8* getStringTable(const u8* data); - -bool verifiByaml(const u8* data); -bool verifiByamlHeader(const u8* data); -bool verifiByamlStringTable(const u8* data); - -} // namespace alByamlLocalUtil diff --git a/src/KingSystem/Utils/CMakeLists.txt b/src/KingSystem/Utils/CMakeLists.txt index 1fa59cff..45b8ecdd 100644 --- a/src/KingSystem/Utils/CMakeLists.txt +++ b/src/KingSystem/Utils/CMakeLists.txt @@ -21,11 +21,20 @@ target_sources(uking PRIVATE Thread/TaskThread.cpp Thread/TaskThread.h - Byaml.cpp - Byaml.h - ByamlLocal.cpp - ByamlLocal.h - ByamlUtil.cpp + Byaml/Byaml.cpp + Byaml/Byaml.h + Byaml/ByamlArrayIter.cpp + Byaml/ByamlArrayIter.h + Byaml/ByamlData.cpp + Byaml/ByamlData.h + Byaml/ByamlStringTableIter.cpp + Byaml/ByamlStringTableIter.h + Byaml/ByamlHashIter.cpp + Byaml/ByamlHashIter.h + Byaml/ByamlLocal.cpp + Byaml/ByamlLocal.h + Byaml/ByamlUtil.cpp + Debug.h FixedString.h HashUtil.h