summaryrefslogtreecommitdiff
path: root/src/KingSystem/Resource
diff options
context:
space:
mode:
authorLéo Lam <leo@leolam.fr>2021-04-13 19:11:23 +0200
committerLéo Lam <leo@leolam.fr>2021-04-14 00:45:59 +0200
commit6e08ff502968caed588e3f33fa90f81896e353c2 (patch)
tree07dab41c71bb5d42cbafa03464cb214131fb7310 /src/KingSystem/Resource
parent49a96d9e62114f44e7f44e7a0a52b444ca1fda42 (diff)
ksys/res: Implement AS
Diffstat (limited to 'src/KingSystem/Resource')
-rw-r--r--src/KingSystem/Resource/resResourceAS.cpp169
-rw-r--r--src/KingSystem/Resource/resResourceAS.h8
-rw-r--r--src/KingSystem/Resource/resResourceASResource.cpp6
-rw-r--r--src/KingSystem/Resource/resResourceASResource.h18
4 files changed, 186 insertions, 15 deletions
diff --git a/src/KingSystem/Resource/resResourceAS.cpp b/src/KingSystem/Resource/resResourceAS.cpp
index e4d0dbdc..53aaf594 100644
--- a/src/KingSystem/Resource/resResourceAS.cpp
+++ b/src/KingSystem/Resource/resResourceAS.cpp
@@ -1 +1,170 @@
#include "KingSystem/Resource/resResourceAS.h"
+#include <memory>
+#include <random/seadGlobalRandom.h>
+#include "KingSystem/Resource/resResourceASResource.h"
+#include "KingSystem/Utils/HeapUtil.h"
+#include "KingSystem/Utils/SafeDelete.h"
+
+namespace ksys::res {
+
+namespace {
+sead::SafeString str_Elements = "Elements";
+sead::SafeString str_CommonParams = "CommonParams";
+} // namespace
+
+AS::AS() : ParamIO("as", 0) {}
+
+AS::~AS() = default;
+
+void AS::doCreate_(u8*, u32, sead::Heap*) {}
+
+// NON_MATCHING: SafeString vtable load is reordered
+bool AS::parse_(u8* data, size_t size, sead::Heap* parent_heap) {
+ mHeap = util::tryCreateDualHeap(parent_heap);
+ if (!mHeap)
+ return false;
+
+ mHeap->enableWarning(false);
+ auto* heap = mHeap;
+
+ agl::utl::ResParameterArchive archive{data};
+ const auto root = archive.getRootList();
+
+ const auto Elements = agl::utl::getResParameterList(root, str_Elements);
+ if (!Elements) {
+ mHeap->adjust();
+ return true;
+ }
+
+ const int num_elements = Elements.getResParameterListNum();
+ if (num_elements == 0) {
+ mHeap->adjust();
+ return true;
+ }
+
+ if (!mElementResources.tryAllocBuffer(num_elements, heap)) {
+ mHeap->adjust();
+ return false;
+ }
+
+ for (int i = 0, n = mElementResources.size(); i < n; ++i)
+ mElementResources(i) = nullptr;
+
+ ASResource::ParseArgs args;
+ args.list = {};
+ args.heap = heap;
+ args.as = this;
+ args.index = 0;
+
+ auto res_it = Elements.listBegin();
+ const auto res_end = Elements.listEnd();
+
+ sead::FixedSafeString<16> name{"Element"};
+ const auto name_prefix_len = name.calcLength();
+
+ for (auto it = mElementResources.begin(), end = mElementResources.end();
+ it != end && res_it != res_end; ++it, ++res_it) {
+ args.list = res_it.getList();
+ *it = ASResource::make(args);
+ if (*it == nullptr) {
+ mHeap->adjust();
+ return false;
+ }
+
+ name.trim(name_prefix_len);
+ name.appendWithFormat("%d", args.index);
+ mElementsList.addList(&(*it)->getList(), name);
+ ++args.index;
+ }
+
+ addList(&mElementsList, str_Elements);
+
+ mRandomRateMin.init(1.0, "RandomRateMin", "ランダム再生率小", "Min=0.f,Max=10.f",
+ &mCommonParams);
+ mRandomRateMax.init(1.0, "RandomRateMax", "ランダム再生率大", "Min=0.f,Max=10.f",
+ &mCommonParams);
+ mForbidPartialDemoAS.init(false, "ForbidPartialDemoAS", "一括再生する", "", &mCommonParams);
+ mUseIK.init(true, "UseIK", "IKする", "", &mCommonParams);
+
+ addObj(&mCommonParams, str_CommonParams);
+
+ _3bb = 0;
+
+ res_it = Elements.listBegin();
+ args.index = 0;
+ for (auto it = mElementResources.begin(), end = mElementResources.end();
+ it != end && res_it != res_end; ++it, ++res_it) {
+ args.list = res_it.getList();
+ if (!(*it)->parse(args)) {
+ mHeap->adjust();
+ return false;
+ }
+
+ _3ba |= (*it)->m7() & 1;
+
+ switch ((*it)->getTypeIndex()) {
+ case 62:
+ _3bb |= 1 << 0;
+ break;
+ case 63:
+ _3bb |= 1 << 1;
+ break;
+ case 64:
+ _3bb |= 1 << 2;
+ break;
+ case 83:
+ _3bb |= 1 << 3;
+ break;
+ case 6:
+ _3bb |= 1 << 4;
+ break;
+ case 39:
+ _3bb |= 1 << 5;
+ break;
+ }
+ ++args.index;
+ }
+
+ applyResParameterArchive(archive);
+
+ if (auto* first = getFirstResource()) {
+ u32 x = first->m4();
+ x = x >= 0xff ? 0xff : x;
+ u32 y = first->m5();
+ y = y >= 0xff ? 0xff : y;
+
+ _3b8 = x;
+ _3b9 = y;
+ } else {
+ _3b8 = 0;
+ _3b9 = 0;
+ }
+
+ mHeap->adjust();
+ return true;
+}
+
+ASResource* AS::getFirstResource() const {
+ if (mElementResources.size() == 0)
+ return nullptr;
+ return mElementResources[0];
+}
+
+void AS::finalize_() {
+ for (auto* ptr : mElementResources) {
+ if (ptr)
+ std::destroy_at(ptr);
+ }
+
+ util::safeDeleteHeap(mHeap);
+}
+
+float AS::getRandomRate() const {
+ const auto max = getRandomRateMax();
+ const auto min = getRandomRateMin();
+ if (max - min > 0.0)
+ return sead::GlobalRandom::instance()->getF32Range(min, max);
+ return min;
+}
+
+} // namespace ksys::res
diff --git a/src/KingSystem/Resource/resResourceAS.h b/src/KingSystem/Resource/resResourceAS.h
index 91853282..14a6b1e4 100644
--- a/src/KingSystem/Resource/resResourceAS.h
+++ b/src/KingSystem/Resource/resResourceAS.h
@@ -16,8 +16,11 @@ class AS : public ParamIO, public Resource {
SEAD_RTTI_OVERRIDE(AS, Resource)
public:
AS();
+ ~AS() override;
+ AS(const AS&) = delete;
+ auto operator=(const AS&) = delete;
- void doCreate_(u8*, u32, sead::Heap*) override {}
+ void doCreate_(u8*, u32, sead::Heap*) override;
bool needsParse() const override { return true; }
bool parse_(u8* data, size_t size, sead::Heap* heap) override;
void finalize_() override;
@@ -28,6 +31,9 @@ public:
const auto& getForbidPartialDemoAs() const { return *mForbidPartialDemoAS; }
const auto& getUseIk() const { return *mUseIK; }
+ ASResource* getFirstResource() const;
+ float getRandomRate() const;
+
private:
friend class ASList;
diff --git a/src/KingSystem/Resource/resResourceASResource.cpp b/src/KingSystem/Resource/resResourceASResource.cpp
index 92db7010..e7b348db 100644
--- a/src/KingSystem/Resource/resResourceASResource.cpp
+++ b/src/KingSystem/Resource/resResourceASResource.cpp
@@ -13,7 +13,7 @@ namespace {
struct ASElementFactory {
const char* name;
- ASResource* (*make_res)(int type_index, const ASResource::MakeResourceArgs& args);
+ ASResource* (*make_res)(int type_index, const ASResource::ParseArgs& args);
// FIXME: signature
as::Element* (*make)();
/// Arbitrary value that is passed to the Element class
@@ -23,7 +23,7 @@ struct ASElementFactory {
sead::SafeString sStr_default = "default";
template <typename T>
-ASResource* resFactoryImpl_(int type_index, const ASResource::MakeResourceArgs& arg) {
+ASResource* resFactoryImpl_(int type_index, const ASResource::ParseArgs& arg) {
return new (arg.heap) T(type_index, arg.index);
}
@@ -358,7 +358,7 @@ bool ASSkeltalAssetResource::doParse(const ASResource::ParseArgs& args) {
return true;
}
-ASResource* ASResource::make(const ASResource::MakeResourceArgs& args) {
+ASResource* ASResource::make(const ASResource::ParseArgs& args) {
const auto Parameters = agl::utl::getResParameterObj(args.list, "Parameters");
const auto TypeIndex = agl::utl::getResParameter(Parameters, "TypeIndex");
diff --git a/src/KingSystem/Resource/resResourceASResource.h b/src/KingSystem/Resource/resResourceASResource.h
index d3b37f44..167fbe01 100644
--- a/src/KingSystem/Resource/resResourceASResource.h
+++ b/src/KingSystem/Resource/resResourceASResource.h
@@ -17,12 +17,6 @@ public:
agl::utl::ResParameterList list;
sead::Heap* heap;
AS* as;
- };
-
- struct MakeResourceArgs {
- agl::utl::ResParameterList list;
- sead::Heap* heap;
- void* x;
int index;
};
@@ -37,18 +31,20 @@ public:
virtual int m7() { return 0; }
static const sead::SafeString& getDefaultStr();
- static ASResource* make(const MakeResourceArgs& args);
+ static ASResource* make(const ParseArgs& args);
- s16 getTypeIndex() const { return mTypeIndex; }
- s16 getIndex() const { return mIndex; }
+ u16 getTypeIndex() const { return mTypeIndex; }
+ u16 getIndex() const { return mIndex; }
int findStringIndex(const sead::SafeString& value) const;
int findIntIndex(int value) const;
+ agl::utl::ParameterList& getList() { return mList; }
+
protected:
virtual bool doParse(const ParseArgs& args) { return true; }
- s16 mTypeIndex{};
- s16 mIndex{};
+ u16 mTypeIndex{};
+ u16 mIndex{};
agl::utl::ParameterList mList;
ASExtensions mExtensions;
};