ksys/res: Finish implementing ASExtensions

This commit is contained in:
Léo Lam 2021-04-11 14:31:55 +02:00
parent 225ee27b41
commit 7363712865
No known key found for this signature in database
GPG Key ID: 0DF30F9081000741
8 changed files with 120 additions and 15 deletions

View File

@ -96595,10 +96595,10 @@
0x00000071012f1ef8,sub_71012F1EF8,896,_ZN4ksys3res9ASSetting10BoneParams5parseERKNS0_13ASParamParser9ParseArgsE 0x00000071012f1ef8,sub_71012F1EF8,896,_ZN4ksys3res9ASSetting10BoneParams5parseERKNS0_13ASParamParser9ParseArgsE
0x00000071012f2278,sub_71012F2278,300,_ZNK4ksys3res9ASSetting10BoneParams13getBoneWeightERKN4sead14SafeStringBaseIcEE 0x00000071012f2278,sub_71012F2278,300,_ZNK4ksys3res9ASSetting10BoneParams13getBoneWeightERKN4sead14SafeStringBaseIcEE
0x00000071012f23a4,sub_71012F23A4,132,_ZN4ksys3res12ASExtensionsD1Ev 0x00000071012f23a4,sub_71012F23A4,132,_ZN4ksys3res12ASExtensionsD1Ev
0x00000071012f2428,sub_71012F2428,508, 0x00000071012f2428,sub_71012F2428,508,_ZN4ksys3res12ASExtensions5parseERKNS1_9ParseArgsE
0x00000071012f2624,sub_71012F2624,636, 0x00000071012f2624,sub_71012F2624,636,_ZNK4ksys3res12ASExtensions10makeParserERKNS0_13ASParamParser9ParseArgsE
0x00000071012f28a0,sub_71012F28A0,428,_ZNK4ksys3act9ASSetting13getBoneParamsERKN4sead14SafeStringBaseIcEE? 0x00000071012f28a0,sub_71012F28A0,428,_ZNK4ksys3act9ASSetting13getBoneParamsERKN4sead14SafeStringBaseIcEE?
0x00000071012f2a4c,sub_71012F2A4C,80, 0x00000071012f2a4c,sub_71012F2A4C,80,_ZNK4ksys3res12ASExtensions9getParserENS0_13ASParamParser4TypeE
0x00000071012f2a9c,sub_71012F2A9C,252,_ZN4ksys3res9ASSettingC1Ev 0x00000071012f2a9c,sub_71012F2A9C,252,_ZN4ksys3res9ASSettingC1Ev
0x00000071012f2b98,sub_71012F2B98,360,_ZN4ksys3res9ASSettingD1Ev 0x00000071012f2b98,sub_71012F2B98,360,_ZN4ksys3res9ASSettingD1Ev
0x00000071012f2d00,sub_71012F2D00,8,_ZThn464_N4ksys3res9ASSettingD1Ev 0x00000071012f2d00,sub_71012F2D00,8,_ZThn464_N4ksys3res9ASSettingD1Ev

Can't render this file because it is too large.

@ -1 +1 @@
Subproject commit 078f7ddbca63a4e20410558f48edd726f7c5ddbc Subproject commit e19bb5df959a18aac742395ec993a27d0a571688

View File

@ -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 // 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()); auto* res = sead::DynamicCast<res::ASSetting>(mHandle.getResource());
if (!res) if (!res)
return nullptr; return nullptr;
for (const auto& bones : res->getBlenderBones()) { for (auto& bones : res->getBlenderBones()) {
if (key == bones.mKeyName.ref()) if (key == bones.mKeyName.ref())
return &bones.mBoneParams; return &bones.mBoneParams;
} }

View File

@ -16,7 +16,7 @@ class ASSetting {
public: public:
void init(const sead::SafeString& config_path); 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: private:
res::Handle mHandle; res::Handle mHandle;

View File

@ -1,5 +1,9 @@
#include "KingSystem/Resource/resResourceASResource.h" #include "KingSystem/Resource/resResourceASResource.h"
#include <container/seadSafeArray.h>
#include <optional>
#include <prim/seadSafeString.h> #include <prim/seadSafeString.h>
#include "KingSystem/ActorSystem/actASSetting.h"
#include "KingSystem/Resource/resResourceASSetting.h"
namespace ksys::res { namespace ksys::res {
@ -216,7 +220,13 @@ static ASParamParser* dummyASParserFactoryImpl_(sead::Heap*) {
return nullptr; 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>}, {"FrameCtrl", factoryImpl_<ASFrameCtrlParser>},
{"TriggerEvents", factoryImpl_<ASTriggerEventsParser>}, {"TriggerEvents", factoryImpl_<ASTriggerEventsParser>},
{"HoldEvents", factoryImpl_<ASHoldEventsParser>}, {"HoldEvents", factoryImpl_<ASHoldEventsParser>},
@ -227,6 +237,7 @@ std::array<ASExtensions::Factory, ASParamParser::NumTypes> ASExtensions::sFactor
{"BitIndex", factoryImpl_<ASBitIndexParser>}, {"BitIndex", factoryImpl_<ASBitIndexParser>},
{"BlenderBone", dummyASParserFactoryImpl_}, {"BlenderBone", dummyASParserFactoryImpl_},
}}; }};
} // namespace
ASExtensions::~ASExtensions() { ASExtensions::~ASExtensions() {
for (auto*& parser : mParsers) { for (auto*& parser : mParsers) {
@ -237,4 +248,92 @@ ASExtensions::~ASExtensions() {
mParsers.freeBuffer(); 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 } // namespace ksys::res

View File

@ -33,7 +33,7 @@ public:
static constexpr int NumTypes = 9; static constexpr int NumTypes = 9;
struct ParseArgs { struct ParseArgs {
void* user_data; agl::utl::ParameterList* list;
agl::utl::ResParameterList res_list; agl::utl::ResParameterList res_list;
sead::Heap* heap; sead::Heap* heap;
}; };
@ -54,19 +54,24 @@ KSYS_CHECK_SIZE_NX150(ASParamParser, 0x58);
class ASExtensions { class ASExtensions {
public: public:
struct ParseArgs {
agl::utl::ResParameterList res_list;
agl::utl::ParameterList* list;
sead::Heap* heap;
};
ASExtensions() = default; ASExtensions() = default;
~ASExtensions(); ~ASExtensions();
ASExtensions(const ASExtensions&) = delete; ASExtensions(const ASExtensions&) = delete;
auto operator=(const ASExtensions&) = delete; auto operator=(const ASExtensions&) = delete;
const sead::Buffer<ASParamParser*>& getParsers() const { return mParsers; } const sead::Buffer<ASParamParser*>& getParsers() const { return mParsers; }
ASParamParser* getParser(ASParamParser::Type type) const;
bool parse(const ParseArgs& args);
private: private:
struct Factory { ASParamParser* makeParser(const ASParamParser::ParseArgs& args) const;
const char* name;
ASParamParser* (*make)(sead::Heap* heap);
};
static std::array<Factory, ASParamParser::NumTypes> sFactories;
agl::utl::ParameterList mList; agl::utl::ParameterList mList;
sead::Buffer<ASParamParser*> mParsers; sead::Buffer<ASParamParser*> mParsers;

View File

@ -59,7 +59,7 @@ bool ASSetting::parse_(u8* data, size_t size, sead::Heap* heap) {
it->mList.addList(&it->mBoneParams.getList(), "BoneParam"); it->mList.addList(&it->mBoneParams.getList(), "BoneParam");
const auto list = *res_it; const auto list = *res_it;
args.user_data = std::addressof(*it); args.list = &it->mList;
args.res_list = agl::utl::getResParameterList(list, "BoneParam"); args.res_list = agl::utl::getResParameterList(list, "BoneParam");
if (!it->mBoneParams.parse(args)) if (!it->mBoneParams.parse(args))
return false; return false;

View File

@ -51,6 +51,7 @@ public:
bool needsParse() const override { return true; } bool needsParse() const override { return true; }
bool parse_(u8* data, size_t size, sead::Heap* heap) override; 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; } const sead::Buffer<BlenderBone>& getBlenderBones() const { return mBlenderBones; }
private: private: