From a5aaebd02050be600cd0eb4d23a89a755a9039c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Thu, 8 Apr 2021 14:44:37 +0200 Subject: [PATCH] ksys/res: Finish implementing ASList --- data/uking_functions.csv | 14 +-- src/KingSystem/Resource/resResourceAS.h | 2 + src/KingSystem/Resource/resResourceASList.cpp | 106 ++++++++++++++++++ src/KingSystem/Resource/resResourceASList.h | 10 ++ 4 files changed, 125 insertions(+), 7 deletions(-) diff --git a/data/uking_functions.csv b/data/uking_functions.csv index ee86fa85..2ea402ea 100644 --- a/data/uking_functions.csv +++ b/data/uking_functions.csv @@ -91516,13 +91516,13 @@ 0x00000071011ad7e4,sub_71011AD7E4,8,_ZThn632_N4ksys3res6ASList6parse_EPhmPN4sead4HeapE 0x00000071011ad7ec,sub_71011AD7EC,8,_ZN4ksys3res6ASList14finishParsing_Ev 0x00000071011ad7f4,sub_71011AD7F4,8,_ZThn632_N4ksys3res6ASList14finishParsing_Ev -0x00000071011ad7fc,sub_71011AD7FC,108, -0x00000071011ad868,sub_71011AD868,108, -0x00000071011ad8d4,sub_71011AD8D4,356, -0x00000071011ada38,sub_71011ADA38,92, -0x00000071011ada94,sub_71011ADA94,424, -0x00000071011adc3c,sub_71011ADC3C,424, -0x00000071011adde4,sub_71011ADDE4,1032, +0x00000071011ad7fc,sub_71011AD7FC,108,_ZN4ksys3res6ASList3m7_Ev +0x00000071011ad868,sub_71011AD868,108,_ZThn632_N4ksys3res6ASList3m7_Ev +0x00000071011ad8d4,sub_71011AD8D4,356,_ZN4ksys3res6ASList6addAS_EiPNS0_2ASE +0x00000071011ada38,sub_71011ADA38,92,_ZNK4ksys3res6ASList13getASFileNameERKN4sead14SafeStringBaseIcEE +0x00000071011ada94,sub_71011ADA94,424,_ZNK4ksys3res6ASList12findASDefineERKN4sead14SafeStringBaseIcEE +0x00000071011adc3c,sub_71011ADC3C,424,_ZNK4ksys3res6ASList12findCFDefineERKN4sead14SafeStringBaseIcEE +0x00000071011adde4,sub_71011ADDE4,1032,_ZNK4ksys3res6ASList15getCFDefineInfoEPfS2_RKN4sead14SafeStringBaseIcEES7_Pb 0x00000071011ae1ec,sub_71011AE1EC,8,_ZNK4ksys3res6ASList27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE 0x00000071011ae1f4,sub_71011AE1F4,92,_ZNK4ksys3res6ASList18getRuntimeTypeInfoEv 0x00000071011ae250,sub_71011AE250,8,_ZNK4ksys3res6ASList10needsParseEv diff --git a/src/KingSystem/Resource/resResourceAS.h b/src/KingSystem/Resource/resResourceAS.h index 76f2af2d..af7e1706 100644 --- a/src/KingSystem/Resource/resResourceAS.h +++ b/src/KingSystem/Resource/resResourceAS.h @@ -23,6 +23,8 @@ public: void finalize_() override; private: + friend class ASList; + sead::Buffer mElements; agl::utl::ParameterList mElementsList; diff --git a/src/KingSystem/Resource/resResourceASList.cpp b/src/KingSystem/Resource/resResourceASList.cpp index 45c77d41..bddac110 100644 --- a/src/KingSystem/Resource/resResourceASList.cpp +++ b/src/KingSystem/Resource/resResourceASList.cpp @@ -1,4 +1,5 @@ #include "KingSystem/Resource/resResourceASList.h" +#include "KingSystem/Resource/resResourceAS.h" namespace ksys::res { @@ -138,4 +139,109 @@ bool ASList::finishParsing_() { return true; } +bool ASList::m7_() { + for (auto& as : mASDefines) + as.as = nullptr; + + _2b0 = 0; + _2b1 = 0; + _2b2 = 0; + _2b3 = 0; + return true; +} + +void ASList::addAS_(s32 index, AS* as) { + mASDefines[index].as = as; + + _2b0 = _2b0 > as->_3b8 ? _2b0 : as->_3b8; + + const auto as_counter = as->_3b9; + if (_2b1 == 0) { + _2b1 = as_counter; + _2b3 = as->_3bb; + } else { + u8* flags1; + u8* flags2; + if (as_counter > _2b1) { + _2b1 = as_counter; + flags1 = &as->_3bb; + flags2 = &_2b3; + } else { + flags1 = &_2b3; + flags2 = &as->_3bb; + } + + for (int i = 0; i < 6; ++i) { + const auto mask = 1u << i; + if ((*flags1 & mask) == 0 && (*flags2 & mask) != 0) { + _2b3 |= mask; + _2b1++; + } + } + } + + _2b2 |= as->_3ba; +} + +const char* ASList::getASFileName(const sead::SafeString& name) const { + const int idx = findASDefine(name); + if (idx == -1) + return nullptr; + return mASDefines[idx].getFileName(); +} + +int ASList::findASDefine(const sead::SafeString& name) const { + return mASDefines.binarySearch( + name, +[](const ASDefine& define, const sead::SafeString& key) { + return define.name->compare(key); + }); +} + +int ASList::findCFDefine(const sead::SafeString& name) const { + return mCFDefines.binarySearch( + name, +[](const CFDefine& define, const sead::SafeString& key) { + return define.name->compare(key); + }); +} + +int ASList::CFExcept::compare(const ASList::CFExcept& o, const sead::SafeString& n) { + return o.name->compare(n); +} + +int ASList::CFPost::compare(const ASList::CFPost& o, const sead::SafeString& n) { + return o.name->compare(n); +} + +bool ASList::getCFDefineInfo(float* frame, float* start_frame_value, const sead::SafeString& name, + const sead::SafeString& post_name, bool* is_default) const { + const int idx = findCFDefine(name); + *is_default = false; + if (idx == -1) + return false; + + const auto& cfdefine = mCFDefines[idx]; + + const int except_idx = cfdefine.excepts.binarySearch(post_name, CFExcept::compare); + if (except_idx >= 0) + return false; + + const CFPost* post = nullptr; + const int post_idx = cfdefine.posts.binarySearch(post_name, CFPost::compare); + if (post_idx != -1) { + post = std::addressof(cfdefine.posts[post_idx]); + } else { + post = std::addressof(cfdefine.posts[0]); + if (!post->name->isEmpty()) + return false; + *is_default = true; + } + + if (!post) + return false; + + *frame = *post->frame; + *start_frame_value = *post->start_frame_rate; + return true; +} + } // namespace ksys::res diff --git a/src/KingSystem/Resource/resResourceASList.h b/src/KingSystem/Resource/resResourceASList.h index 49c07fdb..d8836523 100644 --- a/src/KingSystem/Resource/resResourceASList.h +++ b/src/KingSystem/Resource/resResourceASList.h @@ -26,6 +26,8 @@ public: KSYS_CHECK_SIZE_NX150(ASDefine, 0x88); struct CFPost { + static int compare(const CFPost& o, const sead::SafeString& n); + agl::utl::Parameter name; agl::utl::Parameter frame; agl::utl::Parameter start_frame_rate; @@ -34,6 +36,8 @@ public: KSYS_CHECK_SIZE_NX150(CFPost, 0x98); struct CFExcept { + static int compare(const CFExcept& o, const sead::SafeString& n); + agl::utl::Parameter name; }; KSYS_CHECK_SIZE_NX150(CFExcept, 0x28); @@ -77,6 +81,12 @@ public: void addAS_(s32 index, AS* as); + const char* getASFileName(const sead::SafeString& name) const; + int findASDefine(const sead::SafeString& name) const; + int findCFDefine(const sead::SafeString& name) const; + bool getCFDefineInfo(float* frame, float* key, const sead::SafeString& name, + const sead::SafeString& post_name, bool* is_default) const; + protected: bool finishParsing_() override; bool m7_() override;