summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLéo Lam <leo@leolam.fr>2021-04-11 14:31:55 +0200
committerLéo Lam <leo@leolam.fr>2021-04-11 15:54:21 +0200
commit73637128659db7df2f332ea3d3285d07abf25f4f (patch)
treed86c4f4d9cfe325f04e466f6e1850ec7d81571fe /src
parent225ee27b41ae3e74cf0242108c6fc4df291c1987 (diff)
ksys/res: Finish implementing ASExtensions
Diffstat (limited to 'src')
-rw-r--r--src/KingSystem/ActorSystem/actASSetting.cpp4
-rw-r--r--src/KingSystem/ActorSystem/actASSetting.h2
-rw-r--r--src/KingSystem/Resource/resResourceASResource.cpp101
-rw-r--r--src/KingSystem/Resource/resResourceASResource.h17
-rw-r--r--src/KingSystem/Resource/resResourceASSetting.cpp2
-rw-r--r--src/KingSystem/Resource/resResourceASSetting.h1
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: