diff --git a/CMakeLists.txt b/CMakeLists.txt index a8680eac..217aba43 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,6 +49,10 @@ add_executable(uking src/KingSystem/ActorSystem/actBaseProcUnit.h src/KingSystem/ActorSystem/actTag.h + src/KingSystem/Map/mapTypes.h + src/KingSystem/Map/mapMubinIter.cpp + src/KingSystem/Map/mapMubinIter.h + src/KingSystem/MessageSystem/mesTransceiver.h src/KingSystem/Resource/resCurrentResNameMgr.cpp diff --git a/data/uking_functions.csv b/data/uking_functions.csv index 1a999ca1..9ccd3e35 100644 --- a/data/uking_functions.csv +++ b/data/uking_functions.csv @@ -79915,24 +79915,24 @@ 0x0000007100f446e0,sub_7100F446E0,480, 0x0000007100f448c0,areAllActorsDeletedForReset,436, 0x0000007100f44a74,sinitResetActorStrings,100, -0x0000007100f44ad8,MubinBymlIter::ctor,4, -0x0000007100f44adc,MubinBymlIter::ctorWithData,4, -0x0000007100f44ae0,MubinBymlIter::getU8ByKey,252, -0x0000007100f44bdc,MubinBymlIter::getIntByKey,220, -0x0000007100f44cb8,MubinBymlIter::getUIntByKey,220, -0x0000007100f44d94,MubinBymlIter::getFloatByKey,232, -0x0000007100f44e7c,MubinBymlIter::getBoolByKey,220, -0x0000007100f44f58,MubinBymlIter::getStringByKey,276, -0x0000007100f4506c,MubinBymlIter::tryGetIterByIndex,4, -0x0000007100f45070,MubinBymlIter::getIterByKey,324, -0x0000007100f451b4,MubinBymlIter::getSize,4, -0x0000007100f451b8,MubinBymlIter::isValid,4, -0x0000007100f451bc,MubinBymlIter::getFloatArrayByKey,404, -0x0000007100f45350,MubinBymlIter::getControlPoints,272, -0x0000007100f45460,MubinBymlIter::getSRT,248, -0x0000007100f45558,MubinBymlIter::getScale,228, -0x0000007100f4563c,MubinBymlIter::getRotate,188, -0x0000007100f456f8,sinitMubinBymlIterCrc32Strings,448, +0x0000007100f44ad8,MubinBymlIter::ctor,4,_ZN4ksys3map9MubinIterC1Ev +0x0000007100f44adc,MubinBymlIter::ctorWithData,4,_ZN4ksys3map9MubinIterC1EPKh +0x0000007100f44ae0,MubinBymlIter::getU8ByKey,252,_ZNK4ksys3map9MubinIter21tryGetParamUInt8ByKeyEPhRKN4sead14SafeStringBaseIcEE +0x0000007100f44bdc,MubinBymlIter::getIntByKey,220,_ZNK4ksys3map9MubinIter19tryGetParamIntByKeyEPiRKN4sead14SafeStringBaseIcEE +0x0000007100f44cb8,MubinBymlIter::getUIntByKey,220,_ZNK4ksys3map9MubinIter20tryGetParamUIntByKeyEPjRKN4sead14SafeStringBaseIcEE +0x0000007100f44d94,MubinBymlIter::getFloatByKey,232,_ZNK4ksys3map9MubinIter21tryGetParamFloatByKeyEPfRKN4sead14SafeStringBaseIcEE +0x0000007100f44e7c,MubinBymlIter::getBoolByKey,220,_ZNK4ksys3map9MubinIter20tryGetParamBoolByKeyEPbRKN4sead14SafeStringBaseIcEE +0x0000007100f44f58,MubinBymlIter::getStringByKey,276,_ZNK4ksys3map9MubinIter22tryGetParamStringByKeyEPPKcRKN4sead14SafeStringBaseIcEE +0x0000007100f4506c,MubinBymlIter::tryGetIterByIndex,4,_ZNK4ksys3map9MubinIter17tryGetIterByIndexEPS1_i +0x0000007100f45070,MubinBymlIter::getIterByKey,324,_ZNK4ksys3map9MubinIter20tryGetParamIterByKeyEPS1_RKN4sead14SafeStringBaseIcEE +0x0000007100f451b4,MubinBymlIter::getSize,4,_ZNK4ksys3map9MubinIter7getSizeEv +0x0000007100f451b8,MubinBymlIter::isValid,4,_ZNK4ksys3map9MubinIter7isValidEv +0x0000007100f451bc,MubinBymlIter::getFloatArrayByKey,404,_ZNK4ksys3map9MubinIter21tryGetFloatArrayByKeyEPfRKN4sead14SafeStringBaseIcEE +0x0000007100f45350,MubinBymlIter::getControlPoints,272,_ZNK4ksys3map9MubinIter19tryGetControlPointsEPN4sead9SafeArrayINS2_7Vector3IfEELi2EEE +0x0000007100f45460,MubinBymlIter::getSRT,248,_ZNK4ksys3map9MubinIter6getSRTEPNS0_3SRTE +0x0000007100f45558,MubinBymlIter::getScale,228,_ZNK4ksys3map9MubinIter8getScaleEPN4sead7Vector3IfEE +0x0000007100f4563c,MubinBymlIter::getRotate,188,_ZNK4ksys3map9MubinIter9getRotateEPN4sead7Vector3IfEE +0x0000007100f456f8,sinitMubinBymlIterCrc32Strings,448,_GLOBAL__sub_I_mapMubinIter.cpp 0x0000007100f458b8,NFP::Disposer::dtor,100, 0x0000007100f4591c,NFP::Disposer::dtorDelete,108, 0x0000007100f45988,NFP::createInstance,152, diff --git a/src/KingSystem/Map/mapMubinIter.cpp b/src/KingSystem/Map/mapMubinIter.cpp new file mode 100644 index 00000000..3a9890ea --- /dev/null +++ b/src/KingSystem/Map/mapMubinIter.cpp @@ -0,0 +1,218 @@ +#include "KingSystem/Map/mapMubinIter.h" +#include + +namespace ksys::map { + +static const u32 sCrc32_SRTHash = sead::HashCRC32::calcStringHash("SRTHash"); +static const u32 sCrc32_Index = sead::HashCRC32::calcStringHash("Index"); +static const u32 sCrc32_HashId = sead::HashCRC32::calcStringHash("HashId"); +static const u32 sCrc32_DestUnitHashId = sead::HashCRC32::calcStringHash("DestUnitHashId"); +static const u32 sCrc32_LocationPosX = sead::HashCRC32::calcStringHash("LocationPosX"); +static const u32 sCrc32_LocationPosZ = sead::HashCRC32::calcStringHash("LocationPosZ"); +static const u32 sCrc32_NextDistance = sead::HashCRC32::calcStringHash("NextDistance"); +static const u32 sCrc32_PrevDistance = sead::HashCRC32::calcStringHash("PrevDistance"); +static const u32 sCrc32_IsClosed = sead::HashCRC32::calcStringHash("IsClosed"); +static const u32 sCrc32_OnlyOne = sead::HashCRC32::calcStringHash("OnlyOne"); +static const u32 sCrc32_RailType = sead::HashCRC32::calcStringHash("RailType"); +static const u32 sCrc32_UniqueName = sead::HashCRC32::calcStringHash("UniqueName"); +static const u32 sCrc32_UnitConfigName = sead::HashCRC32::calcStringHash("UnitConfigName"); +static const u32 sCrc32_CheckPointName = sead::HashCRC32::calcStringHash("CheckPointName"); +static const u32 sCrc32_EntryPointName = sead::HashCRC32::calcStringHash("EntryPointName"); +static const u32 sCrc32_DefinitionName = sead::HashCRC32::calcStringHash("DefinitionName"); +static const u32 sCrc32_Objs = sead::HashCRC32::calcStringHash("Objs"); +static const u32 sCrc32_Rails = sead::HashCRC32::calcStringHash("Rails"); +static const u32 sCrc32_LinksToObj = sead::HashCRC32::calcStringHash("LinksToObj"); +static const u32 sCrc32_LinksToRail = sead::HashCRC32::calcStringHash("LinksToRail"); +static const u32 sCrc32_Rotate = sead::HashCRC32::calcStringHash("Rotate"); +static const u32 sCrc32_Scale = sead::HashCRC32::calcStringHash("Scale"); +static const u32 sCrc32_Translate = sead::HashCRC32::calcStringHash("Translate"); +static const u32 sCrc32_RailPoints = sead::HashCRC32::calcStringHash("RailPoints"); +static const u32 sCrc32_ControlPoints = sead::HashCRC32::calcStringHash("ControlPoints"); +static const u32 sCrc32_Junctions = sead::HashCRC32::calcStringHash("Junctions"); + +MubinIter::MubinIter() : ByamlIter() {} + +MubinIter::MubinIter(const u8* data) : ByamlIter(data) {} + +bool MubinIter::tryGetParamUInt8ByKey(u8* value, const sead::SafeString& key) const { + const u32 hash = sead::HashCRC32::calcStringHash(key.cstr()); + + if (sCrc32_SRTHash == hash || sCrc32_Index == hash) { + s32 x = 0; + if (!tryGetIntByKey(&x, key.cstr())) + return false; + *value = x; + return true; + } + + al::ByamlIter iter; + if (!tryGetIterByIndex(&iter, 0)) + return false; + s32 x = 0; + if (!iter.tryGetIntByKey(&x, key.cstr())) + return false; + *value = x; + return true; +} + +bool MubinIter::tryGetParamIntByKey(s32* value, const sead::SafeString& key) const { + const u32 hash = sead::HashCRC32::calcStringHash(key.cstr()); + if (sCrc32_SRTHash == hash || sCrc32_Index == hash) + return tryGetIntByKey(value, key.cstr()); + + al::ByamlIter iter; + return tryGetIterByIndex(&iter, 0) && iter.tryGetIntByKey(value, key.cstr()); +} + +bool MubinIter::tryGetParamUIntByKey(u32* value, const sead::SafeString& key) const { + const u32 hash = sead::HashCRC32::calcStringHash(key.cstr()); + if (sCrc32_HashId == hash || sCrc32_DestUnitHashId == hash) + return tryGetUIntByKey(value, key.cstr()); + + al::ByamlIter iter; + return tryGetIterByIndex(&iter, 0) && iter.tryGetUIntByKey(value, key.cstr()); +} + +bool MubinIter::tryGetParamFloatByKey(f32* value, const sead::SafeString& key) const { + const u32 hash = sead::HashCRC32::calcStringHash(key.cstr()); + if (sCrc32_LocationPosX == hash || sCrc32_LocationPosZ == hash || sCrc32_NextDistance == hash || + sCrc32_PrevDistance == hash) { + return tryGetFloatByKey(value, key.cstr()); + } + + al::ByamlIter iter; + return tryGetIterByIndex(&iter, 0) && iter.tryGetFloatByKey(value, key.cstr()); +} + +bool MubinIter::tryGetParamBoolByKey(bool* value, const sead::SafeString& key) const { + const u32 hash = sead::HashCRC32::calcStringHash(key.cstr()); + if (sCrc32_IsClosed == hash || sCrc32_OnlyOne == hash) + return tryGetBoolByKey(value, key.cstr()); + + al::ByamlIter iter; + return tryGetIterByIndex(&iter, 0) && iter.tryGetBoolByKey(value, key.cstr()); +} + +bool MubinIter::tryGetParamStringByKey(const char** value, const sead::SafeString& key) const { + const u32 hash = sead::HashCRC32::calcStringHash(key.cstr()); + if (sCrc32_RailType == hash || sCrc32_UniqueName == hash || sCrc32_UnitConfigName == hash || + sCrc32_CheckPointName == hash || sCrc32_EntryPointName == hash || + sCrc32_DefinitionName == hash) { + return tryGetStringByKey(value, key.cstr()); + } + + al::ByamlIter iter; + return tryGetIterByIndex(&iter, 0) && iter.tryGetStringByKey(value, key.cstr()); +} + +bool MubinIter::tryGetIterByIndex(MubinIter* iter, s32 index) const { + return al::ByamlIter::tryGetIterByIndex(iter, index); +} + +bool MubinIter::tryGetParamIterByKey(MubinIter* value, const sead::SafeString& key) const { + const u32 hash = sead::HashCRC32::calcStringHash(key.cstr()); + if (sCrc32_Objs == hash || sCrc32_Rails == hash || sCrc32_LinksToObj == hash || + sCrc32_LinksToRail == hash || sCrc32_Rotate == hash || sCrc32_Scale == hash || + sCrc32_Translate == hash || sCrc32_RailPoints == hash || sCrc32_ControlPoints == hash || + sCrc32_Junctions == hash) { + return tryGetIterByKey(value, key.cstr()); + } + + al::ByamlIter iter; + return tryGetIterByIndex(&iter, 0) && iter.tryGetIterByKey(value, key.cstr()); +} + +s32 MubinIter::getSize() const { + return al::ByamlIter::getSize(); +} + +bool MubinIter::isValid() const { + return al::ByamlIter::isValid(); +} + +bool MubinIter::tryGetFloatArrayByKey(f32* value, const sead::SafeString& key) const { + al::ByamlIter iter; + const u32 hash = sead::HashCRC32::calcStringHash(key.cstr()); + if (sCrc32_Objs == hash || sCrc32_Rails == hash || sCrc32_LinksToObj == hash || + sCrc32_LinksToRail == hash || sCrc32_Rotate == hash || sCrc32_Scale == hash || + sCrc32_Translate == hash || sCrc32_RailPoints == hash || sCrc32_ControlPoints == hash || + sCrc32_Junctions == hash) { + if (!tryGetIterByKey(&iter, key.cstr())) + return false; + } else { + al::ByamlIter i; + if (!tryGetIterByIndex(&i, 0) || !i.tryGetIterByKey(&iter, key.cstr())) + return false; + } + + const s32 size = iter.getSize(); + bool ok = true; + for (s32 i = 0; i < size; ++i) { + ok &= iter.tryGetFloatByIndex(&value[i], i); + } + return ok; +} + +bool MubinIter::tryGetControlPoints(ControlPoints* points) const { + al::ByamlIter pts_iter; + if (!tryGetIterByKey(&pts_iter, "ControlPoints")) { + *points = {}; + return false; + } + + const s32 num_pts = pts_iter.getSize(); + + for (s32 pt_idx = 0; pt_idx < num_pts; ++pt_idx) { + al::ByamlIter iter; + if (!pts_iter.tryGetIterByIndex(&iter, pt_idx)) + return false; + + const s32 num_coords = iter.getSize(); + for (s32 i = 0; i < num_coords; ++i) { + if (!iter.tryGetFloatByIndex(&(*points)[pt_idx].e[i], i)) + return false; + } + } + + return true; +} + +void MubinIter::getSRT(SRT* srt) const { + getScale(&srt->scale); + getRotate(&srt->rotate); + getTranslate(&srt->translate); +} + +void MubinIter::getScale(sead::Vector3f* scale) const { + al::ByamlIter iter; + if (tryGetIterByKey(&iter, "Scale")) { + for (s32 i = 0, n = iter.getSize(); i < n; ++i) { + if (!iter.tryGetFloatByIndex(&scale->e[i], i)) + scale->e[i] = 1.0; + } + } else if (tryGetFloatByKey(&scale->e[0], "Scale")) { + scale->e[1] = scale->e[2] = scale->e[0]; + } else { + *scale = sead::Vector3f::ones; + } +} + +void MubinIter::getRotate(sead::Vector3f* rotate) const { + al::ByamlIter iter; + if (tryGetIterByKey(&iter, "Rotate")) { + for (s32 i = 0, n = iter.getSize(); i < n; ++i) { + if (!iter.tryGetFloatByIndex(&rotate->e[i], i)) + rotate->e[i] = 0.0; + } + } else { + rotate->x = rotate->z = 0.0; + if (!tryGetFloatByKey(&rotate->y, "Rotate")) + rotate->y = 0.0; + } +} + +void MubinIter::getTranslate(sead::Vector3f* translate) const { + tryGetFloatArrayByKey(translate->e.data(), "Translate"); +} + +} // namespace ksys::map diff --git a/src/KingSystem/Map/mapMubinIter.h b/src/KingSystem/Map/mapMubinIter.h new file mode 100644 index 00000000..cf9f7243 --- /dev/null +++ b/src/KingSystem/Map/mapMubinIter.h @@ -0,0 +1,49 @@ +#pragma once + +#include +#include "KingSystem/Map/mapTypes.h" +#include "KingSystem/Utils/Byaml.h" + +namespace ksys::map { + +struct SRT; + +class MubinIter : public al::ByamlIter { +public: + MubinIter(); + explicit MubinIter(const u8* data); + + bool tryGetParamUInt8ByKey(u8* value, const sead::SafeString& key) const; + bool tryGetParamIntByKey(s32* value, const sead::SafeString& key) const; + bool tryGetParamUIntByKey(u32* value, const sead::SafeString& key) const; + bool tryGetParamFloatByKey(f32* value, const sead::SafeString& key) const; + bool tryGetParamBoolByKey(bool* value, const sead::SafeString& key) const; + bool tryGetParamStringByKey(const char** value, const sead::SafeString& key) const; + bool tryGetIterByIndex(MubinIter* iter, s32 index) const; + using al::ByamlIter::tryGetIterByIndex; + bool tryGetParamIterByKey(MubinIter* value, const sead::SafeString& key) const; + using al::ByamlIter::tryGetIterByKey; + + s32 getSize() const; + bool isValid() const; + + /// @warning UNSAFE. Will happily write as many floats as there are items in the BYML data. + bool tryGetFloatArrayByKey(f32* array, const sead::SafeString& key) const; + + /// @warning UNSAFE. Will happily write as many floats as there are items in the BYML data. + bool tryGetControlPoints(ControlPoints* points) const; + + /// @warning UNSAFE. Will happily write as many floats as there are items in the BYML data. + void getSRT(SRT* srt) const; + + /// @warning UNSAFE. Will happily write as many floats as there are items in the BYML data. + void getScale(sead::Vector3f* scale) const; + + /// @warning UNSAFE. Will happily write as many floats as there are items in the BYML data. + void getRotate(sead::Vector3f* rotate) const; + + /// @warning UNSAFE. Will happily write as many floats as there are items in the BYML data. + void getTranslate(sead::Vector3f* translate) const; +}; + +} // namespace ksys::map diff --git a/src/KingSystem/Map/mapTypes.h b/src/KingSystem/Map/mapTypes.h new file mode 100644 index 00000000..a248bdcf --- /dev/null +++ b/src/KingSystem/Map/mapTypes.h @@ -0,0 +1,16 @@ +#pragma once + +#include +#include + +namespace ksys::map { + +using ControlPoints = sead::SafeArray; + +struct SRT { + sead::Vector3f scale; + sead::Vector3f rotate; + sead::Vector3f translate; +}; + +} // namespace ksys::map