diff options
| author | Léo Lam <leo@leolam.fr> | 2021-04-13 19:11:23 +0200 |
|---|---|---|
| committer | Léo Lam <leo@leolam.fr> | 2021-04-14 00:45:59 +0200 |
| commit | 6e08ff502968caed588e3f33fa90f81896e353c2 (patch) | |
| tree | 07dab41c71bb5d42cbafa03464cb214131fb7310 /src/KingSystem/Resource | |
| parent | 49a96d9e62114f44e7f44e7a0a52b444ca1fda42 (diff) | |
ksys/res: Implement AS
Diffstat (limited to 'src/KingSystem/Resource')
| -rw-r--r-- | src/KingSystem/Resource/resResourceAS.cpp | 169 | ||||
| -rw-r--r-- | src/KingSystem/Resource/resResourceAS.h | 8 | ||||
| -rw-r--r-- | src/KingSystem/Resource/resResourceASResource.cpp | 6 | ||||
| -rw-r--r-- | src/KingSystem/Resource/resResourceASResource.h | 18 |
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; }; |
