diff options
| author | Léo Lam <leo@leolam.fr> | 2021-04-11 14:31:55 +0200 |
|---|---|---|
| committer | Léo Lam <leo@leolam.fr> | 2021-04-11 15:54:21 +0200 |
| commit | 73637128659db7df2f332ea3d3285d07abf25f4f (patch) | |
| tree | d86c4f4d9cfe325f04e466f6e1850ec7d81571fe /src | |
| parent | 225ee27b41ae3e74cf0242108c6fc4df291c1987 (diff) | |
ksys/res: Finish implementing ASExtensions
Diffstat (limited to 'src')
| -rw-r--r-- | src/KingSystem/ActorSystem/actASSetting.cpp | 4 | ||||
| -rw-r--r-- | src/KingSystem/ActorSystem/actASSetting.h | 2 | ||||
| -rw-r--r-- | src/KingSystem/Resource/resResourceASResource.cpp | 101 | ||||
| -rw-r--r-- | src/KingSystem/Resource/resResourceASResource.h | 17 | ||||
| -rw-r--r-- | src/KingSystem/Resource/resResourceASSetting.cpp | 2 | ||||
| -rw-r--r-- | src/KingSystem/Resource/resResourceASSetting.h | 1 |
6 files changed, 116 insertions, 11 deletions
diff --git a/src/KingSystem/ActorSystem/actASSetting.cpp b/src/KingSystem/ActorSystem/actASSetting.cpp index 0202a85c..7c3d82e2 100644 --- a/src/KingSystem/ActorSystem/actASSetting.cpp +++ b/src/KingSystem/ActorSystem/actASSetting.cpp @@ -16,12 +16,12 @@ void ASSetting::init(const sead::SafeString& config_path) { } // NON_MATCHING: sead::DirectResource to res::ASSetting cast nullptr check; branching for the return -const res::ASSetting::BoneParams* ASSetting::getBoneParams(const sead::SafeString& key) const { +res::ASParamParser* ASSetting::getBoneParams(const sead::SafeString& key) const { auto* res = sead::DynamicCast<res::ASSetting>(mHandle.getResource()); if (!res) return nullptr; - for (const auto& bones : res->getBlenderBones()) { + for (auto& bones : res->getBlenderBones()) { if (key == bones.mKeyName.ref()) return &bones.mBoneParams; } diff --git a/src/KingSystem/ActorSystem/actASSetting.h b/src/KingSystem/ActorSystem/actASSetting.h index 289d68dd..399ad201 100644 --- a/src/KingSystem/ActorSystem/actASSetting.h +++ b/src/KingSystem/ActorSystem/actASSetting.h @@ -16,7 +16,7 @@ class ASSetting { public: void init(const sead::SafeString& config_path); - const res::ASSetting::BoneParams* getBoneParams(const sead::SafeString& key) const; + res::ASParamParser* getBoneParams(const sead::SafeString& key) const; private: res::Handle mHandle; diff --git a/src/KingSystem/Resource/resResourceASResource.cpp b/src/KingSystem/Resource/resResourceASResource.cpp index 0025bfe1..0112f3af 100644 --- a/src/KingSystem/Resource/resResourceASResource.cpp +++ b/src/KingSystem/Resource/resResourceASResource.cpp @@ -1,5 +1,9 @@ #include "KingSystem/Resource/resResourceASResource.h" +#include <container/seadSafeArray.h> +#include <optional> #include <prim/seadSafeString.h> +#include "KingSystem/ActorSystem/actASSetting.h" +#include "KingSystem/Resource/resResourceASSetting.h" namespace ksys::res { @@ -216,7 +220,13 @@ static ASParamParser* dummyASParserFactoryImpl_(sead::Heap*) { return nullptr; } -std::array<ASExtensions::Factory, ASParamParser::NumTypes> ASExtensions::sFactories{{ +namespace { +struct Factory { + const char* name; + ASParamParser* (*make)(sead::Heap* heap); +}; + +sead::SafeArray<Factory, ASParamParser::NumTypes> sASFactories{{ {"FrameCtrl", factoryImpl_<ASFrameCtrlParser>}, {"TriggerEvents", factoryImpl_<ASTriggerEventsParser>}, {"HoldEvents", factoryImpl_<ASHoldEventsParser>}, @@ -227,6 +237,7 @@ std::array<ASExtensions::Factory, ASParamParser::NumTypes> ASExtensions::sFactor {"BitIndex", factoryImpl_<ASBitIndexParser>}, {"BlenderBone", dummyASParserFactoryImpl_}, }}; +} // namespace ASExtensions::~ASExtensions() { for (auto*& parser : mParsers) { @@ -237,4 +248,92 @@ ASExtensions::~ASExtensions() { mParsers.freeBuffer(); } +bool ASExtensions::parse(const ASExtensions::ParseArgs& args) { + const auto Extend = agl::utl::getResParameterList(args.res_list, "Extend"); + if (!Extend) + return true; + + const auto num_extensions = Extend.getResParameterListNum(); + if (num_extensions == 0) + return true; + + if (!mParsers.tryAllocBuffer(num_extensions, args.heap)) + return false; + for (int i = 0, n = mParsers.size(); i < n; ++i) + mParsers(i) = nullptr; + + auto it = mParsers.begin(); + const auto end = mParsers.end(); + + ASParamParser::ParseArgs parse_args{}; + parse_args.list = &mList; + parse_args.heap = args.heap; + + auto res_it = Extend.listBegin(); + const auto res_end = Extend.listEnd(); + + for (; it != end && res_it != res_end; ++it, ++res_it) { + parse_args.res_list = res_it.getList(); + *it = makeParser(parse_args); + + constexpr int bone = int(ASParamParser::Type::BlenderBone); + if (*it == nullptr && parse_args.res_list.getParameterListNameHash() != + agl::utl::ParameterBase::calcHash(sASFactories[bone].name)) { + return false; + } + } + + args.list->addList(&mList, "Extend"); + return true; +} + +ASParamParser* ASExtensions::makeParser(const ASParamParser::ParseArgs& args) const { + const auto is_factory = [&args](int i) { + return args.res_list.getParameterListNameHash() == + agl::utl::ParameterBase::calcHash(sASFactories[i].name); + }; + + std::optional<int> type; + for (int i = 0; i < ASParamParser::NumTypes - 1; ++i) { + if (!is_factory(i)) + continue; + type = i; + break; + } + + if (!type.has_value() && is_factory(int(ASParamParser::Type::BlenderBone))) { + const auto obj = args.res_list.getResParameterObj(0); + if (obj.getNum() > 0) { + const sead::SafeString name = obj.getResParameter(0).getData<const char>(); + return act::ASSetting::instance()->getBoneParams(name); + } + } + + if (!type.has_value()) + return nullptr; + + const auto& factory = sASFactories[*type]; + + auto* parser = factory.make(args.heap); + if (!parser) + return nullptr; + + if (!parser->parse(args)) { + delete parser; + return nullptr; + } + + args.list->addList(&parser->getList(), factory.name); + return parser; +} + +ASParamParser* ASExtensions::getParser(ASParamParser::Type type) const { + for (int i = 0, n = mParsers.size(); i < n; ++i) { + auto* parser = mParsers[i]; + if (parser && parser->getType() == type) + return parser; + } + return nullptr; +} + } // namespace ksys::res diff --git a/src/KingSystem/Resource/resResourceASResource.h b/src/KingSystem/Resource/resResourceASResource.h index 0a2ab6bb..fd244cc6 100644 --- a/src/KingSystem/Resource/resResourceASResource.h +++ b/src/KingSystem/Resource/resResourceASResource.h @@ -33,7 +33,7 @@ public: static constexpr int NumTypes = 9; struct ParseArgs { - void* user_data; + agl::utl::ParameterList* list; agl::utl::ResParameterList res_list; sead::Heap* heap; }; @@ -54,19 +54,24 @@ KSYS_CHECK_SIZE_NX150(ASParamParser, 0x58); class ASExtensions { public: + struct ParseArgs { + agl::utl::ResParameterList res_list; + agl::utl::ParameterList* list; + sead::Heap* heap; + }; + ASExtensions() = default; ~ASExtensions(); ASExtensions(const ASExtensions&) = delete; auto operator=(const ASExtensions&) = delete; const sead::Buffer<ASParamParser*>& getParsers() const { return mParsers; } + ASParamParser* getParser(ASParamParser::Type type) const; + + bool parse(const ParseArgs& args); private: - struct Factory { - const char* name; - ASParamParser* (*make)(sead::Heap* heap); - }; - static std::array<Factory, ASParamParser::NumTypes> sFactories; + ASParamParser* makeParser(const ASParamParser::ParseArgs& args) const; agl::utl::ParameterList mList; sead::Buffer<ASParamParser*> mParsers; diff --git a/src/KingSystem/Resource/resResourceASSetting.cpp b/src/KingSystem/Resource/resResourceASSetting.cpp index 2fe40a2a..be0a3865 100644 --- a/src/KingSystem/Resource/resResourceASSetting.cpp +++ b/src/KingSystem/Resource/resResourceASSetting.cpp @@ -59,7 +59,7 @@ bool ASSetting::parse_(u8* data, size_t size, sead::Heap* heap) { it->mList.addList(&it->mBoneParams.getList(), "BoneParam"); const auto list = *res_it; - args.user_data = std::addressof(*it); + args.list = &it->mList; args.res_list = agl::utl::getResParameterList(list, "BoneParam"); if (!it->mBoneParams.parse(args)) return false; diff --git a/src/KingSystem/Resource/resResourceASSetting.h b/src/KingSystem/Resource/resResourceASSetting.h index 069f98ff..9d052bcc 100644 --- a/src/KingSystem/Resource/resResourceASSetting.h +++ b/src/KingSystem/Resource/resResourceASSetting.h @@ -51,6 +51,7 @@ public: bool needsParse() const override { return true; } bool parse_(u8* data, size_t size, sead::Heap* heap) override; + sead::Buffer<BlenderBone>& getBlenderBones() { return mBlenderBones; } const sead::Buffer<BlenderBone>& getBlenderBones() const { return mBlenderBones; } private: |
