ksys/res: Implement remaining AS param parser classes

This commit is contained in:
Léo Lam
2021-04-10 22:14:51 +02:00
parent 1a5d9aba68
commit 9846d6fef9
4 changed files with 511 additions and 53 deletions
@@ -1 +1,240 @@
#include "KingSystem/Resource/resResourceASResource.h"
#include <prim/seadSafeString.h>
namespace ksys::res {
bool ASFrameCtrlParser::parse(const ASParamParser::ParseArgs& args) {
mRate.init(1.0, "Rate", "再生速度", "Min=0.f,Max=10.f", &mObj);
mStartFrame.init(0.0, "StartFrame", "開始フレーム", "Min=0.f,Max=100.f", &mObj);
mEndFrame.init(-1.0, "EndFrame", "終了フレーム", "Min=-1.f,Max=100.f", &mObj);
mLoopStopCount.init(-1.0, "LoopStopCount", "ループ停止回数", "Min=-1.f,Max=10.f", &mObj);
mLoopStopCountRandom.init(0.0, "LoopStopCountRandom", "ランダムループ追加回数",
"Min=0.f,Max=10.f", &mObj);
mReversePlay.init(false, "ReversePlay", "逆再生", "", &mObj);
mUseGlobalFrame.init(false, "UseGlobalFrame", "グローバルフレーム使う", "", &mObj);
mFootType.init(0, "FootType", "足解決", "", &mObj);
mConnect.init(false, "Connect", "接続", "", &mObj);
mAnmLoop.init(0, "AnmLoop", "ループ設定", "", &mObj);
mList.addObj(&mObj, "FrameCtrl0");
return true;
}
bool ASTriggerEventsParser::parse(const ASParamParser::ParseArgs& args) {
const int num_objs = args.res_list.getResParameterObjNum();
if (num_objs == 0)
return true;
if (!mEvents.tryAllocBuffer(num_objs, args.heap))
return false;
auto it = mEvents.begin();
const auto end = mEvents.end();
sead::FixedSafeString<32> obj_name{"Event"};
const auto obj_name_prefix_len = obj_name.calcLength();
auto res_it = args.res_list.objBegin();
const auto res_end = args.res_list.objEnd();
while (res_it != res_end && it != end) {
u32 type_index = -1;
const auto TypeIndex = agl::utl::getResParameter(res_it.getObj(), "TypeIndex");
if (TypeIndex.ptr())
type_index = *TypeIndex.getData<int>();
// TODO: add a TypeIndex enum
it->type_index = type_index > 33 ? 88 : int(type_index) + 54;
it->frame.init(0.0, "Frame", "フレーム", "Min=0.f,Max=100.f", &it->obj);
it->value.init("", "Value", "", "", &it->obj);
obj_name.trim(obj_name_prefix_len);
obj_name.appendWithFormat("%d", it.getIndex());
mList.addObj(&it->obj, obj_name);
++res_it;
++it;
}
return true;
}
bool ASHoldEventsParser::parse(const ASParamParser::ParseArgs& args) {
const int num_objs = args.res_list.getResParameterObjNum();
if (num_objs == 0)
return true;
if (!mEvents.tryAllocBuffer(num_objs, args.heap))
return false;
auto it = mEvents.begin();
const auto end = mEvents.end();
sead::FixedSafeString<32> obj_name{"Event"};
const auto obj_name_prefix_len = obj_name.calcLength();
auto res_it = args.res_list.objBegin();
const auto res_end = args.res_list.objEnd();
while (res_it != res_end && it != end) {
u32 type_index = -1;
const auto TypeIndex = agl::utl::getResParameter(res_it.getObj(), "TypeIndex");
if (TypeIndex.ptr())
type_index = *TypeIndex.getData<int>();
// TODO: add a TypeIndex enum
it->type_index = type_index > 53 ? 88 : int(type_index);
it->start_frame.init(0.0, "StartFrame", "開始フレーム", "Min=0.f,Max=100.f", &it->obj);
it->end_frame.init(0.0, "EndFrame", "終了フレーム", "Min=0.f,Max=100.f", &it->obj);
it->value.init("", "Value", "", "", &it->obj);
obj_name.trim(obj_name_prefix_len);
obj_name.appendWithFormat("%d", it.getIndex());
mList.addObj(&it->obj, obj_name);
++res_it;
++it;
}
return true;
}
bool ASStringArrayParser::parse(const ASParamParser::ParseArgs& args) {
const int size = args.res_list.getResParameterObj(0).getNum();
if (size != 0) {
if (!mValues.tryAllocBuffer(size, args.heap))
return false;
sead::FixedSafeString<32> param_name{"Value"};
const auto param_name_prefix_len = param_name.calcLength();
for (int i = 0; i < size; ++i) {
param_name.trim(param_name_prefix_len);
param_name.appendWithFormat("%d", i);
mValues[i].value.init("", param_name, "", "", &mObj);
}
}
mList.addObj(&mObj, "StringArray0");
return true;
}
bool ASRangesParser::parse(const ASParamParser::ParseArgs& args) {
const int num_objs = args.res_list.getResParameterObjNum();
if (num_objs == 0)
return true;
if (!mRanges.tryAllocBuffer(num_objs, args.heap))
return false;
auto it = mRanges.begin();
const auto end = mRanges.end();
sead::FixedSafeString<32> obj_name{"Range"};
const auto obj_name_prefix_len = obj_name.calcLength();
auto res_it = args.res_list.objBegin();
const auto res_end = args.res_list.objEnd();
while (res_it != res_end && it != end) {
obj_name.trim(obj_name_prefix_len);
obj_name.appendWithFormat("%d", it.getIndex());
it->start.init(0.0, "Start", "開始", "Min=0.f,Max=1.f", &it->obj);
it->end.init(0.0, "End", "終了", "Min=0.f,Max=1.f", &it->obj);
mList.addObj(&it->obj, obj_name);
++res_it;
++it;
}
return true;
}
bool ASFloatArrayParser::parse(const ASParamParser::ParseArgs& args) {
const int size = args.res_list.getResParameterObj(0).getNum();
if (size != 0) {
if (!mValues.tryAllocBuffer(size, args.heap))
return false;
sead::FixedSafeString<32> param_name{"Value"};
const auto param_name_prefix_len = param_name.calcLength();
for (int i = 0; i < size; ++i) {
param_name.trim(param_name_prefix_len);
param_name.appendWithFormat("%d", i);
mValues[i].value.init(1.0, param_name, "", "", &mObj);
}
}
mList.addObj(&mObj, "FloatArray0");
return true;
}
bool ASIntArrayParser::parse(const ASParamParser::ParseArgs& args) {
const int size = args.res_list.getResParameterObj(0).getNum();
if (size != 0) {
if (!mValues.tryAllocBuffer(size, args.heap))
return false;
sead::FixedSafeString<32> param_name{"Value"};
const auto param_name_prefix_len = param_name.calcLength();
for (int i = 0; i < size; ++i) {
param_name.trim(param_name_prefix_len);
param_name.appendWithFormat("%d", i);
mValues[i].value.init(1, param_name, "", "", &mObj);
}
}
mList.addObj(&mObj, "IntArray0");
return true;
}
bool ASBitIndexParser::parse(const ASParamParser::ParseArgs& args) {
const auto obj = args.res_list.getResParameterObj(0);
if (obj.getNum() < 1)
return true;
const auto TypeIndex = agl::utl::getResParameter(obj, "TypeIndex");
if (!TypeIndex.ptr())
return true;
mTypeIndex = *TypeIndex.getData<int>();
return true;
}
template <typename T>
static ASParamParser* factoryImpl_(sead::Heap* heap) {
return new (heap) T;
}
static ASParamParser* dummyASParserFactoryImpl_(sead::Heap*) {
return nullptr;
}
std::array<ASExtensions::Factory, ASParamParser::NumTypes> ASExtensions::sFactories{{
{"FrameCtrl", factoryImpl_<ASFrameCtrlParser>},
{"TriggerEvents", factoryImpl_<ASTriggerEventsParser>},
{"HoldEvents", factoryImpl_<ASHoldEventsParser>},
{"StringArray", factoryImpl_<ASStringArrayParser>},
{"Ranges", factoryImpl_<ASRangesParser>},
{"FloatArray", factoryImpl_<ASFloatArrayParser>},
{"IntArray", factoryImpl_<ASIntArrayParser>},
{"BitIndex", factoryImpl_<ASBitIndexParser>},
{"BlenderBone", dummyASParserFactoryImpl_},
}};
ASExtensions::~ASExtensions() {
for (auto*& parser : mParsers) {
if (parser && parser->getType() != ASParamParser::Type::BlenderBone)
delete parser;
parser = nullptr;
}
mParsers.freeBuffer();
}
} // namespace ksys::res
+219 -1
View File
@@ -1,8 +1,12 @@
#pragma once
#include <agl/Utils/aglParameter.h>
#include <agl/Utils/aglParameterList.h>
#include <agl/Utils/aglParameterObj.h>
#include <agl/Utils/aglResParameter.h>
#include <array>
#include <basis/seadTypes.h>
#include <container/seadBuffer.h>
#include <prim/seadRuntimeTypeInfo.h>
#include "KingSystem/Utils/Types.h"
@@ -15,22 +19,236 @@ namespace ksys::res {
class ASParamParser {
SEAD_RTTI_BASE(ASParamParser)
public:
enum class Type {
FrameCtrl = 0,
TriggerEvents = 1,
HoldEvents = 2,
StringArray = 3,
Ranges = 4,
FloatArray = 5,
IntArray = 6,
BitIndex = 7,
BlenderBone = 8,
};
static constexpr int NumTypes = 9;
struct ParseArgs {
void* user_data;
agl::utl::ResParameterList res_list;
sead::Heap* heap;
};
explicit ASParamParser(Type type) : mType(type) {}
virtual ~ASParamParser() = default;
virtual bool parse(const ParseArgs& args) { return true; }
Type getType() const { return mType; }
agl::utl::ParameterList& getList() { return mList; }
const agl::utl::ParameterList& getList() const { return mList; }
protected:
u32 _8 = 8;
Type mType;
agl::utl::ParameterList mList;
};
KSYS_CHECK_SIZE_NX150(ASParamParser, 0x58);
class ASExtensions {
public:
ASExtensions() = default;
~ASExtensions();
ASExtensions(const ASExtensions&) = delete;
auto operator=(const ASExtensions&) = delete;
const sead::Buffer<ASParamParser*>& getParsers() const { return mParsers; }
private:
struct Factory {
const char* name;
ASParamParser* (*make)(sead::Heap* heap);
};
static std::array<Factory, ASParamParser::NumTypes> sFactories;
agl::utl::ParameterList mList;
sead::Buffer<ASParamParser*> mParsers;
};
class ASFrameCtrlParser : public ASParamParser {
SEAD_RTTI_OVERRIDE(ASFrameCtrlParser, ASParamParser)
public:
ASFrameCtrlParser() : ASParamParser(Type::FrameCtrl) {}
const auto& getRate() const { return *mRate; }
const auto& getStartFrame() const { return *mStartFrame; }
const auto& getEndFrame() const { return *mEndFrame; }
const auto& getLoopStopCount() const { return *mLoopStopCount; }
const auto& getLoopStopCountRandom() const { return *mLoopStopCountRandom; }
const auto& getReversePlay() const { return *mReversePlay; }
const auto& getUseGlobalFrame() const { return *mUseGlobalFrame; }
const auto& getConnect() const { return *mConnect; }
const auto& getFootType() const { return *mFootType; }
const auto& getAnmLoop() const { return *mAnmLoop; }
bool parse(const ParseArgs& args) override;
private:
agl::utl::ParameterObj mObj;
agl::utl::Parameter<float> mRate;
agl::utl::Parameter<float> mStartFrame;
agl::utl::Parameter<float> mEndFrame;
agl::utl::Parameter<float> mLoopStopCount;
agl::utl::Parameter<float> mLoopStopCountRandom;
agl::utl::Parameter<bool> mReversePlay;
agl::utl::Parameter<bool> mUseGlobalFrame;
agl::utl::Parameter<int> mConnect;
agl::utl::Parameter<int> mFootType;
agl::utl::Parameter<int> mAnmLoop;
};
class ASTriggerEventsParser : public ASParamParser {
SEAD_RTTI_OVERRIDE(ASTriggerEventsParser, ASParamParser)
public:
struct Event {
agl::utl::ParameterObj obj;
int type_index;
agl::utl::Parameter<float> frame;
agl::utl::Parameter<sead::SafeString> value;
};
ASTriggerEventsParser() : ASParamParser(Type::TriggerEvents) {}
~ASTriggerEventsParser() override { mEvents.freeBuffer(); }
ASTriggerEventsParser(const ASTriggerEventsParser&) = delete;
auto operator=(const ASTriggerEventsParser&) = delete;
const sead::Buffer<Event>& getEvents() const { return mEvents; }
bool parse(const ParseArgs& args) override;
private:
sead::Buffer<Event> mEvents;
};
class ASHoldEventsParser : public ASParamParser {
SEAD_RTTI_OVERRIDE(ASHoldEventsParser, ASParamParser)
public:
struct Event {
agl::utl::ParameterObj obj;
int type_index;
agl::utl::Parameter<float> start_frame;
agl::utl::Parameter<float> end_frame;
agl::utl::Parameter<sead::SafeString> value;
};
ASHoldEventsParser() : ASParamParser(Type::HoldEvents) {}
~ASHoldEventsParser() override { mEvents.freeBuffer(); }
ASHoldEventsParser(const ASHoldEventsParser&) = delete;
auto operator=(const ASHoldEventsParser&) = delete;
const sead::Buffer<Event>& getEvents() const { return mEvents; }
bool parse(const ParseArgs& args) override;
private:
sead::Buffer<Event> mEvents;
};
class ASStringArrayParser : public ASParamParser {
SEAD_RTTI_OVERRIDE(ASStringArrayParser, ASParamParser)
public:
struct Value {
agl::utl::Parameter<sead::SafeString> value;
};
ASStringArrayParser() : ASParamParser(Type::StringArray) {}
~ASStringArrayParser() override { mValues.freeBuffer(); }
ASStringArrayParser(const ASStringArrayParser&) = delete;
auto operator=(const ASStringArrayParser&) = delete;
const sead::Buffer<Value>& getValues() const { return mValues; }
bool parse(const ParseArgs& args) override;
private:
agl::utl::ParameterObj mObj;
sead::Buffer<Value> mValues;
};
class ASRangesParser : public ASParamParser {
SEAD_RTTI_OVERRIDE(ASRangesParser, ASParamParser)
public:
struct Range {
agl::utl::ParameterObj obj;
agl::utl::Parameter<float> start;
agl::utl::Parameter<float> end;
};
ASRangesParser() : ASParamParser(Type::Ranges) {}
~ASRangesParser() override { mRanges.freeBuffer(); }
ASRangesParser(const ASRangesParser&) = delete;
auto operator=(const ASRangesParser&) = delete;
const sead::Buffer<Range>& getRanges() const { return mRanges; }
bool parse(const ParseArgs& args) override;
private:
sead::Buffer<Range> mRanges;
};
class ASFloatArrayParser : public ASParamParser {
SEAD_RTTI_OVERRIDE(ASFloatArrayParser, ASParamParser)
public:
struct Value {
agl::utl::Parameter<float> value;
};
ASFloatArrayParser() : ASParamParser(Type::FloatArray) {}
~ASFloatArrayParser() override { mValues.freeBuffer(); }
ASFloatArrayParser(const ASFloatArrayParser&) = delete;
auto operator=(const ASFloatArrayParser&) = delete;
const sead::Buffer<Value>& getValues() const { return mValues; }
bool parse(const ParseArgs& args) override;
private:
agl::utl::ParameterObj mObj;
sead::Buffer<Value> mValues;
};
class ASIntArrayParser : public ASParamParser {
SEAD_RTTI_OVERRIDE(ASIntArrayParser, ASParamParser)
public:
struct Value {
agl::utl::Parameter<int> value;
};
ASIntArrayParser() : ASParamParser(Type::IntArray) {}
~ASIntArrayParser() override { mValues.freeBuffer(); }
ASIntArrayParser(const ASIntArrayParser&) = delete;
auto operator=(const ASIntArrayParser&) = delete;
const sead::Buffer<Value>& getValues() const { return mValues; }
bool parse(const ParseArgs& args) override;
private:
agl::utl::ParameterObj mObj;
sead::Buffer<Value> mValues;
};
class ASBitIndexParser : public ASParamParser {
SEAD_RTTI_OVERRIDE(ASBitIndexParser, ASParamParser)
public:
ASBitIndexParser() : ASParamParser(Type::BitIndex) {}
int getBitIndex() const { return mTypeIndex; }
bool parse(const ParseArgs& args) override;
private:
int mTypeIndex = -1;
};
} // namespace ksys::res
@@ -28,6 +28,7 @@ public:
class BoneParams : public ASParamParser {
SEAD_RTTI_OVERRIDE(BoneParams, ASParamParser)
public:
BoneParams() : ASParamParser(Type::BlenderBone) {}
~BoneParams() override;
bool parse(const ParseArgs& args) override;
f32 getBoneWeight(const sead::SafeString& name) const;