ksys: move AS setting, RootAi and three others to match link order

Each file moves to where its code is linked, and namespaces follow the
new paths. ASSettingMgr is an unofficial name.

| Old | New |
|---|---|
| act::ASSetting (ActorSystem/actASSetting) | res::ASSettingMgr (Resource/Actor/resResourceASSettingMgr) |
| Resource/resResourceASSetting, Resource/Actor/resResourceASResourceExtension | Resource/Actor/resResourceASSetting |
| ksys::DebugFinder (System/DebugFinder) | ksys::act::DebugFinder (ActorSystem/actDebugFinder) |
| ActorSystem/LOD/actLodState | ActorSystem/actLodState |
| ActorSystem/actAiRoot | ActorSystem/aiRootAi |
| Map/mapStagePreActorCache | System/StagePreActorCache (ksys) |

(AI assisted using Claude Fable 5.1 and Claude Opus 5.5)
This commit is contained in:
Léo Lam
2026-09-28 03:39:31 +02:00
parent e400fe7025
commit ea13bac74a
34 changed files with 263 additions and 271 deletions
@@ -0,0 +1,472 @@
#include "KingSystem/Resource/Actor/resResourceASSetting.h"
#include <container/seadSafeArray.h>
#include <optional>
#include <prim/seadSafeString.h>
#include "KingSystem/Resource/Actor/resResourceASResourceExtension.h"
#include "KingSystem/Resource/Actor/resResourceASSettingMgr.h"
#include "KingSystem/Resource/resLoadRequest.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;
}
bool ASSetting::BoneParams::parse(const ASParamParser::ParseArgs& args) {
const auto num_objects = args.res_list.getResParameterObjNum();
if (num_objects == 0)
return true;
if (!mBuffer.tryAllocBuffer(num_objects, args.heap))
return false;
auto it = mBuffer.begin();
const auto end = mBuffer.end();
sead::FixedSafeString<32> obj_name{"BoneParam"};
const auto obj_name_base_len = obj_name.calcLength();
auto res_it = args.res_list.objBegin();
const auto res_end = args.res_list.objEnd();
for (; it != end && res_it != res_end; ++it, ++res_it) {
it->mBone.init("", "Bone", "ボーン名", "", &it->mObj);
it->mWeight.init(0.0, "Weight", "ウェイト値", "Min=0.f,Max=1.f", &it->mObj);
obj_name.trim(obj_name_base_len);
obj_name.appendWithFormat("%d", res_it.getIndex());
mList.addObj(&it->mObj, obj_name);
}
return true;
}
f32 ASSetting::BoneParams::getBoneWeight(const sead::SafeString& name) const {
for (const auto& param : mBuffer) {
if (name == *param.mBone)
return *param.mWeight;
}
return 1.0;
}
namespace {
struct Factory {
const char* name;
ASParamParser* (*make)(sead::Heap* heap);
};
extern sead::SafeArray<Factory, ASParamParser::NumTypes> sASFactories;
} // namespace
ASExtensions::~ASExtensions() {
for (auto*& parser : mParsers) {
if (parser && parser->getType() != ASParamParser::Type::BlenderBone)
delete parser;
parser = nullptr;
}
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;
mParsers.fill(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 ASSettingMgr::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;
}
// NON_MATCHING: sead::DirectResource to res::ASSetting cast nullptr check; branching for the return
ASParamParser* ASSettingMgr::getBoneParams(const sead::SafeString& key) const {
auto* res = sead::DynamicCast<ASSetting>(mHandle.getResource());
if (!res)
return nullptr;
for (auto& bones : res->getBlenderBones()) {
if (key == bones.mKeyName.ref())
return &bones.mBoneParams;
}
return nullptr;
}
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;
}
ASSetting::ASSetting() {
mType = "assetting";
mVersion = 0;
}
ASSetting::~ASSetting() {
mBlenderBones.freeBuffer();
}
void ASSetting::doCreate_(u8* buffer, u32 buffer_size, sead::Heap* heap) {}
bool allocBlenderBones(sead::Buffer<ASSetting::BlenderBone>& buffer, int size, sead::Heap* heap,
int align = sizeof(void*));
bool ASSetting::parse_(u8* data, size_t size, sead::Heap* heap) {
if (!data)
return true;
agl::utl::ResParameterArchive archive{data};
const auto root = archive.getRootList();
addList(&mBlenderBoneList, "BlenderBone");
const auto lists = agl::utl::getResParameterList(root, "BlenderBone");
if (!lists.ptr())
return true;
const auto num_blender_bones = lists.getResParameterListNum();
if (num_blender_bones == 0)
return true;
if (!allocBlenderBones(mBlenderBones, num_blender_bones, heap))
return false;
auto res_it = lists.listBegin();
const auto res_it_end = lists.listEnd();
sead::FixedSafeString<32> list_name{"BlenderBone"};
const auto list_name_base_len = list_name.calcLength();
ASParamParser::ParseArgs args;
args.res_list = {};
args.heap = heap;
auto it = mBlenderBones.begin();
const auto end = mBlenderBones.end();
for (; it != end && res_it != res_it_end; ++it, ++res_it) {
list_name.trim(list_name_base_len);
list_name.appendWithFormat("%d", it.getIndex());
mBlenderBoneList.addList(&it->mList, list_name);
it->mKeyName.init("", "KeyName", "キー名", "", &it->mNameParamObj);
it->mList.addObj(&it->mNameParamObj, "NameParam");
it->mList.addList(&it->mBoneParams.getList(), "BoneParam");
const auto list = *res_it;
args.list = &it->mList;
args.res_list = agl::utl::getResParameterList(list, "BoneParam");
if (!it->mBoneParams.parse(args))
return false;
}
applyResParameterArchive(archive);
return true;
}
bool allocBlenderBones(sead::Buffer<ASSetting::BlenderBone>& buffer, int size, sead::Heap* heap,
int align) {
return buffer.tryAllocBuffer(size, heap, align);
}
SEAD_SINGLETON_DISPOSER_IMPL(ASSettingMgr)
void ASSettingMgr::init(const sead::SafeString& config_path, sead::Heap* heap) {
LoadRequest req;
req.mRequester = "ASSetting";
req._22 = true;
mHandle.load(config_path, &req);
}
template <typename T>
static ASParamParser* factoryImpl_(sead::Heap* heap) {
return new (heap) T;
}
static ASParamParser* dummyASParserFactoryImpl_(sead::Heap*) {
return nullptr;
}
namespace {
sead::SafeArray<Factory, ASParamParser::NumTypes> sASFactories{{
{"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_},
}};
} // namespace
} // namespace ksys::res