diff options
| author | Léo Lam <leo@leolam.fr> | 2021-03-19 14:31:19 +0100 |
|---|---|---|
| committer | Léo Lam <leo@leolam.fr> | 2021-03-20 00:17:33 +0100 |
| commit | 8c8d9c0e7036d22d3eebe1c8dca54b44b601e8e5 (patch) | |
| tree | a4370ba6302a8e91b171e352d8540fc9f4f28586 /src | |
| parent | c119c0eefa8513978bfbb48ebd1a3e74e266a86b (diff) | |
ksys/res: Finish implementing ModelList
Diffstat (limited to 'src')
| -rw-r--r-- | src/KingSystem/ActorSystem/actInfoData.cpp | 15 | ||||
| -rw-r--r-- | src/KingSystem/Resource/resResourceModelList.cpp | 367 | ||||
| -rw-r--r-- | src/KingSystem/Resource/resResourceModelList.h | 114 | ||||
| -rw-r--r-- | src/KingSystem/Utils/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/KingSystem/Utils/ParamIO.cpp | 21 | ||||
| -rw-r--r-- | src/KingSystem/Utils/ParamIO.h | 6 |
6 files changed, 482 insertions, 42 deletions
diff --git a/src/KingSystem/ActorSystem/actInfoData.cpp b/src/KingSystem/ActorSystem/actInfoData.cpp index 028cb26e..a36aeb30 100644 --- a/src/KingSystem/ActorSystem/actInfoData.cpp +++ b/src/KingSystem/ActorSystem/actInfoData.cpp @@ -6,6 +6,7 @@ #include "KingSystem/ActorSystem/actDebug.h" #include "KingSystem/Event/evtEvent.h" #include "KingSystem/Event/evtManager.h" +#include "KingSystem/Resource/resResourceModelList.h" #include "KingSystem/Utils/Byaml/Byaml.h" #include "KingSystem/Utils/Byaml/ByamlArrayIter.h" #include "KingSystem/Utils/Byaml/ByamlData.h" @@ -215,17 +216,6 @@ const char* InfoData::getStringByKey(const al::ByamlIter& iter, const char* key, return iter.tryGetStringByKey(&value, key) ? value : default_.cstr(); } -[[gnu::noinline]] static InfoData::Locator::Type -getLocatorTypeFromStr(const sead::SafeString& type) { - static constexpr const char* types[] = {"Trunk", "Branch", "GlowStone", - "OnTree", "MagnePos", "StopTimerPos"}; - for (s32 i = 0; i < s32(std::size(types)); ++i) { - if (type == types[i]) - return InfoData::Locator::Type(i); - } - return InfoData::Locator::Type::Invalid; -} - void InfoData::getLocators(const char* actor, Locators& info) const { info.num = 0; @@ -255,7 +245,8 @@ void InfoData::getLocators(const char* actor, Locators& info) const { it.tryGetFloatByKey(&locator.rot.z, "rot_z"); it.tryGetStringByKey(&type_str, "type"); - locator.type = type_str ? getLocatorTypeFromStr(type_str) : Locator::Type::Invalid; + locator.type = + type_str ? res::ModelList::getLocatorTypeFromStr(type_str) : Locator::Type::Invalid; locator.rot *= 2 * sead::numbers::pi / 360.0; } diff --git a/src/KingSystem/Resource/resResourceModelList.cpp b/src/KingSystem/Resource/resResourceModelList.cpp index b5d6ed03..9450ee52 100644 --- a/src/KingSystem/Resource/resResourceModelList.cpp +++ b/src/KingSystem/Resource/resResourceModelList.cpp @@ -1,7 +1,374 @@ #include "KingSystem/Resource/resResourceModelList.h" +#include <container/seadSafeArray.h> +#include "KingSystem/Resource/resModelResourceDivide.h" namespace ksys::res { +namespace { +sead::SafeString str_ModelData{"ModelData"}; +sead::SafeString str_Unit{"Unit"}; +sead::SafeString str_AnmTarget{"AnmTarget"}; +sead::SafeString str_Partial{"Partial"}; + +sead::SafeArray<const char*, 6> sLocatorTypes{{ + "Trunk", + "Branch", + "GlowStone", + "OnTree", + "MagnePos", + "StopTimerPos", +}}; + +constexpr u32 NumUnitMax = 8; +} // namespace + ModelList::ModelList() : ParamIO("modellist", 0) {} +ModelList::~ModelList() { + for (auto& entry : mModelData) + entry.units.freeBuffer(); + mModelData.freeBuffer(); + + for (auto& entry : mAnmTargets) + entry.partials.freeBuffer(); + mAnmTargets.freeBuffer(); +} + +void ModelList::doCreate_(u8* buffer, u32 buffer_size, sead::Heap* heap) {} + +// NON_MATCHING: reorderings +bool ModelList::parse_(u8* data, size_t size, sead::Heap* heap) { + agl::utl::ResParameterArchive archive{data}; + const auto root = archive.getRootList(); + + const auto model_data_list = agl::utl::getResParameterList(root, str_ModelData); + if (model_data_list.ptr() && model_data_list.getResParameterListNum() > 0) { + if (!parseModelData(model_data_list, heap)) + return false; + } + addList(&mModelDataList, str_ModelData); + + const auto anm_target_list = agl::utl::getResParameterList(root, str_AnmTarget); + if (anm_target_list.ptr() && anm_target_list.getResParameterListNum() > 0) { + if (!parseAnmTarget(anm_target_list, heap)) + return false; + } + addList(&mAnmTargetList, str_AnmTarget); + + mControllerInfo->mAddColor.init({0.0, 0.0, 0.0, 0.0}, "AddColor", "", &mControllerInfo->mObj); + mControllerInfo->mMulColor.init({1.0, 1.0, 1.0, 1.0}, "MulColor", "", &mControllerInfo->mObj); + mControllerInfo->mBaseScale.init(sead::Vector3f::ones, "BaseScale", "", &mControllerInfo->mObj); + mControllerInfo->mVariationMatAnim.init("", "VariationMatAnim", "", &mControllerInfo->mObj); + mControllerInfo->mVariationMatAnimFrame.init(0, "VariationMatAnimFrame", "", + &mControllerInfo->mObj); + mControllerInfo->mVariationShaderAnim.init("", "VariationShaderAnim", "", + &mControllerInfo->mObj); + mControllerInfo->mVariationShaderAnimFrame.init(0, "VariationShaderAnimFrame", "", + &mControllerInfo->mObj); + mControllerInfo->mCalcAABBASKey.init("Wait", "CalcAABBASKey", "", &mControllerInfo->mObj); + addObj(&mControllerInfo->mObj, sead::FormatFixedSafeString<128>("ControllerInfo")); + + mAttention->mIsEnableAttention.init(false, "IsEnableAttention", "", &mAttention->mObj); + mAttention->mLookAtBone.init("", "LookAtBone", "", &mAttention->mObj); + mAttention->mLookAtOffset.init(sead::Vector3f::zero, "LookAtOffset", "", &mAttention->mObj); + mAttention->mCursorOffsetY.init(0.0, "CursorOffsetY", "", &mAttention->mObj); + mAttention->mAIInfoOffsetY.init(0.0, "AIInfoOffsetY", "", &mAttention->mObj); + mAttention->mCutTargetBone.init("", "CutTargetBone", "", &mAttention->mObj); + mAttention->mCutTargetOffset.init(sead::Vector3f::zero, "CutTargetOffset", "", + &mAttention->mObj); + mAttention->mGameCameraBone.init("", "GameCameraBone", "", &mAttention->mObj); + mAttention->mGameCameraOffset.init(sead::Vector3f::zero, "GameCameraOffset", "", + &mAttention->mObj); + mAttention->mBowCameraBone.init("", "BowCameraBone", "", &mAttention->mObj); + mAttention->mBowCameraOffset.init(sead::Vector3f::zero, "BowCameraOffset", "", + &mAttention->mObj); + mAttention->mAttackTargetBone.init("", "AttackTargetBone", "", &mAttention->mObj); + mAttention->mAttackTargetOffset.init(sead::Vector3f::zero, "AttackTargetOffset", "", + &mAttention->mObj); + mAttention->mAttackTargetOffsetBack.init(0.0, "AttackTargetOffsetBack", "", &mAttention->mObj); + mAttention->mAtObstacleChkUseLookAtPos.init(true, "AtObstacleChkUseLookAtPos", "", + &mAttention->mObj); + mAttention->mAtObstacleChkOffsetBone.init("", "AtObstacleChkOffsetBone", "", &mAttention->mObj); + mAttention->mAtObstacleChkOffset.init(sead::Vector3f::zero, "AtObstacleChkOffset", "", + &mAttention->mObj); + mAttention->mCursorAIInfoBaseBone.init("", "CursorAIInfoBaseBone", "", &mAttention->mObj); + mAttention->mCursorAIInfoBaseOffset.init(sead::Vector3f::zero, "CursorAIInfoBaseOffset", "", + &mAttention->mObj); + addObj(&mAttention->mObj, sead::FormatFixedSafeString<128>("Attention")); + + if (data) { + applyResParameterArchive(agl::utl::ResParameterArchive{data}); + mRawData = data; + } + + return true; +} + +bool allocModelDataBuffer(sead::Buffer<ModelList::ModelData>& buffer, int size, sead::Heap* heap, + int alignment = sizeof(void*)) { + return buffer.tryAllocBuffer(size, heap, alignment); +} + +bool ModelList::parseModelData(const agl::utl::ResParameterList& res, sead::Heap* heap) { + if (!allocModelDataBuffer(mModelData, res.getResParameterListNum() != 0, heap)) + return false; + + sead::FixedSafeString<32> list_name{str_ModelData}; + list_name.append("_"); + const auto list_name_base_len = list_name.calcLength(); + + for (auto it = mModelData.begin(), it_end = mModelData.end(); it != it_end; ++it) { + list_name.trim(list_name_base_len); + list_name.appendWithFormat("%d", it.getIndex()); + + it->folder.init("", "Folder", "", &it->base_obj); + it->list.addObj(&it->base_obj, "Base"); + + const auto unit_list = + agl::utl::getResParameterList(res.getResParameterList(it.getIndex()), str_Unit); + if (unit_list.ptr()) { + const u32 num_units = unit_list.getResParameterObjNum(); + if (num_units != 0) { + if (!it->units.tryAllocBuffer(std::min(num_units, NumUnitMax), heap)) + return false; + + sead::FixedSafeString<32> unit_name{str_Unit}; + unit_name.append("_"); + const auto unit_name_base_len = unit_name.calcLength(); + + for (auto unit = it->units.begin(), end = it->units.end(); unit != end; ++unit) { + unit_name.trim(unit_name_base_len); + unit_name.appendWithFormat("%d", unit.getIndex()); + + unit->unit_name.init("", "UnitName", "", &unit->obj); + unit->bind_bone.init("", "BindBone", "", &unit->obj); + it->unit_list.addObj(&unit->obj, unit_name); + } + } + } + + it->list.addList(&it->unit_list, str_Unit); + mModelDataList.addList(&it->list, list_name); + } + + return true; +} + +bool allocAnmTargetPartialBuffer(sead::Buffer<ModelList::Partial>& buffer, int size, + sead::Heap* heap, int alignment = sizeof(void*)) { + return buffer.tryAllocBuffer(size, heap, alignment); +} + +bool ModelList::parseAnmTarget(const agl::utl::ResParameterList& res, sead::Heap* heap) { + if (!mAnmTargets.tryAllocBuffer(std::min<u32>(res.getResParameterListNum(), NumUnitMax), heap)) + return false; + + sead::FixedSafeString<32> list_name{str_AnmTarget}; + list_name.append("_"); + const auto list_name_base_len = list_name.calcLength(); + + for (auto it = mAnmTargets.begin(), it_end = mAnmTargets.end(); it != it_end; ++it) { + list_name.trim(list_name_base_len); + list_name.appendWithFormat("%d", it.getIndex()); + + it->num_as_slot.init(0, "NumASSlot", "", &it->base_obj); + // "is particle enabled" (particle is misspelled as "partical" [sic]) + it->is_partical_enable.init(false, "IsParticalEnable", "", &it->base_obj); + it->target_type.init(0, "TargetType", "", &it->base_obj); + it->list.addObj(&it->base_obj, "Base"); + + const auto partials = + agl::utl::getResParameterList(res.getResParameterList(it.getIndex()), str_Partial); + if (partials.ptr() && partials.getResParameterObjNum() != 0) { + if (!allocAnmTargetPartialBuffer(it->partials, partials.getResParameterObjNum(), heap)) + return false; + + sead::FixedSafeString<32> partial_name{str_Partial}; + partial_name.append("_"); + const auto partial_name_base_len = partial_name.calcLength(); + + for (auto partial = it->partials.begin(), partial_end = it->partials.end(); + partial != partial_end; ++partial) { + partial_name.trim(partial_name_base_len); + partial_name.appendWithFormat("%d", partial.getIndex()); + + partial->bone.init("", "Bone", "", &partial->obj); + partial->bind_flag.init(0, "BindFlg", "", &partial->obj); + partial->recursible.init(true, "Recursible", "", &partial->obj); + it->partial_list.addObj(&partial->obj, partial_name); + } + } + + it->list.addList(&it->partial_list, str_Partial); + mAnmTargetList.addList(&it->list, list_name); + } + + return true; +} + +int ModelList::getNumAnmTargets() const { + return mAnmTargets.size(); +} + +void ModelList::getModelDataInfo(ModelList::ModelDataInfo* info) const { + *info = {}; + + if (mModelData.size() > 0) { + info->num_model_data = mModelData.size(); + for (auto it = mModelData.begin(), end = mModelData.end(); it != end; ++it) { + const s32 idx = it.getIndex(); + + info->folder_name[idx] = it->folder.ref().cstr(); + info->num_units[idx] = it->units.size(); + + for (auto unit = it->units.begin(), uend = it->units.end(); unit != uend; ++unit) { + const s32 unit_idx = unit.getIndex(); + info->unit_names[idx][unit_idx] = unit->unit_name.ref().cstr(); + info->unit_bind_bones[idx][unit_idx] = unit->bind_bone.ref().cstr(); + } + + if (info->unit_names[idx][0]) { + const char* name = ModelResourceDivide::instance()->getModelResource( + info->folder_name[idx], info->unit_names[idx][0]); + if (name) + info->folder_name[idx] = name; + } + } + } + + info->base_scale = mControllerInfo->mBaseScale.ref(); +} + +bool ModelList::getAttentionInfo(AttentionInfo* info) const { + if (!mAttention->mIsEnableAttention.ref()) { + info->look_at_bone = {}; + info->look_at_offset = sead::Vector3f::zero; + + info->cursor_offset_y = {}; + info->ai_info_offset_y = {}; + + info->cut_target_bone = {}; + info->cut_target_offset = sead::Vector3f::zero; + + info->game_camera_bone = {}; + info->game_camera_offset = sead::Vector3f::zero; + + info->bow_camera_bone = {}; + info->bow_camera_offset = sead::Vector3f::zero; + + info->attack_target_bone = {}; + info->attack_target_offset = sead::Vector3f::zero; + info->attack_target_offset_back = {}; + + info->cursor_ai_info_base_bone = {}; + info->cursor_ai_info_base_offset = sead::Vector3f::zero; + + return false; + } + + info->look_at_bone = mAttention->mLookAtBone.ref().cstr(); + info->look_at_offset = mAttention->mLookAtOffset.ref(); + + info->cursor_offset_y = mAttention->mCursorOffsetY.ref(); + info->ai_info_offset_y = mAttention->mAIInfoOffsetY.ref(); + + info->cut_target_bone = mAttention->mCutTargetBone.ref().cstr(); + info->cut_target_offset = mAttention->mCutTargetOffset.ref(); + + info->game_camera_bone = mAttention->mGameCameraBone.ref().cstr(); + info->game_camera_offset = mAttention->mGameCameraOffset.ref(); + + info->bow_camera_bone = mAttention->mBowCameraBone.ref().cstr(); + info->bow_camera_offset = mAttention->mBowCameraOffset.ref(); + + info->attack_target_bone = mAttention->mAttackTargetBone.ref().cstr(); + info->attack_target_offset = mAttention->mAttackTargetOffset.ref(); + info->attack_target_offset_back = mAttention->mAttackTargetOffsetBack.ref(); + + if (mAttention->mAtObstacleChkUseLookAtPos.ref()) { + info->at_obstacle_chk_bone = mAttention->mLookAtBone.ref().cstr(); + info->at_obstacle_chk_offset = mAttention->mLookAtOffset.ref(); + } else { + info->at_obstacle_chk_bone = mAttention->mAtObstacleChkOffsetBone.ref().cstr(); + info->at_obstacle_chk_offset = mAttention->mAtObstacleChkOffset.ref(); + } + + info->cursor_ai_info_base_bone = mAttention->mCursorAIInfoBaseBone.ref().cstr(); + info->cursor_ai_info_base_offset = mAttention->mCursorAIInfoBaseOffset.ref(); + + const auto clear_if_empty = [](const char** s) { + if (!(*s)[0]) + *s = nullptr; + }; + + clear_if_empty(&info->look_at_bone); + clear_if_empty(&info->cut_target_bone); + clear_if_empty(&info->game_camera_bone); + clear_if_empty(&info->bow_camera_bone); + clear_if_empty(&info->attack_target_bone); + clear_if_empty(&info->at_obstacle_chk_bone); + clear_if_empty(&info->cursor_ai_info_base_bone); + + return true; +} + +act::InfoData::Locator::Type ModelList::getLocatorTypeFromStr(const sead::SafeString& type) { + for (s32 i = 0; i < sLocatorTypes.size(); ++i) { + if (type == sLocatorTypes[i]) + return act::InfoData::Locator::Type(i); + } + return act::InfoData::Locator::Type::Invalid; +} + +// NON_MATCHING: weird unrolling and Vector3f store (str should be a stp) +bool ModelList::getLocatorInfo(act::InfoData::Locator* info, + act::InfoData::Locator::Type type) const { + agl::utl::ResParameterArchive archive{mRawData}; + const auto root = archive.getRootList(); + + for (int i = 0;; ++i) { + const auto obj = + agl::utl::getResParameterObj(root, sead::FormatFixedSafeString<32>("Locator_%d", i)); + if (!obj.ptr()) + return false; + + const char* expected_type_str = sLocatorTypes[u32(type)]; + + if (sead::SafeString(getString(obj, "Type", "")) != expected_type_str) + continue; + + info->pos = getVec3(obj, "Pos", sead::Vector3f::zero); + info->rot = getVec3(obj, "Rot", sead::Vector3f::zero); + info->type = type; + return true; + } + + return false; +} + +bool ModelList::isParticalEnable(int anm_target_idx) const { + return mAnmTargets[anm_target_idx].is_partical_enable.ref(); +} + +int ModelList::getNumASSlot(int anm_target_idx) const { + return mAnmTargets[anm_target_idx].num_as_slot.ref(); +} + +int ModelList::getNumPartials(int anm_target_idx) const { + return mAnmTargets[anm_target_idx].partials.size(); +} + +void ModelList::getPartialInfo(PartialInfo* info, int anm_target_idx, int partial_idx) const { + if (mAnmTargets.size() > 0) { + const auto& partial = mAnmTargets[anm_target_idx].partials[partial_idx]; + info->bone = partial.bone.ref(); + info->bind_flag = partial.bind_flag.ref(); + info->recursible = partial.recursible.ref(); + } else { + info->bone = ""; + info->bind_flag = 0; + info->recursible = true; + } +} + } // namespace ksys::res diff --git a/src/KingSystem/Resource/resResourceModelList.h b/src/KingSystem/Resource/resResourceModelList.h index 58038559..d614ade5 100644 --- a/src/KingSystem/Resource/resResourceModelList.h +++ b/src/KingSystem/Resource/resResourceModelList.h @@ -3,7 +3,9 @@ #include <agl/Utils/aglParameter.h> #include <agl/Utils/aglParameterObj.h> #include <container/seadBuffer.h> +#include <prim/seadSafeString.h> #include <prim/seadStorageFor.h> +#include "KingSystem/ActorSystem/actInfoData.h" #include "KingSystem/Resource/resResource.h" #include "KingSystem/Utils/ParamIO.h" @@ -14,39 +16,39 @@ class ModelList : public ParamIO, public Resource { SEAD_RTTI_OVERRIDE(ModelList, Resource) public: struct ControllerInfo { - agl::utl::Parameter<sead::Color4f> _2b0; - agl::utl::Parameter<sead::Color4f> _2d8; - agl::utl::ParameterObj mControllerInfo; + agl::utl::Parameter<sead::Color4f> mAddColor; + agl::utl::Parameter<sead::Color4f> mMulColor; + agl::utl::ParameterObj mObj; agl::utl::Parameter<sead::Vector3f> mBaseScale; - agl::utl::Parameter<sead::SafeString> _358; - agl::utl::Parameter<s32> _380; - agl::utl::Parameter<sead::SafeString> _3a0; - agl::utl::Parameter<s32> _3c8; - agl::utl::Parameter<sead::SafeString> _3e8; + agl::utl::Parameter<sead::SafeString> mVariationMatAnim; + agl::utl::Parameter<s32> mVariationMatAnimFrame; + agl::utl::Parameter<sead::SafeString> mVariationShaderAnim; + agl::utl::Parameter<s32> mVariationShaderAnimFrame; + agl::utl::Parameter<sead::SafeString> mCalcAABBASKey; }; KSYS_CHECK_SIZE_NX150(ControllerInfo, 0x160); struct Attention { - agl::utl::Parameter<bool> _0; - agl::utl::Parameter<sead::SafeString> _20; - agl::utl::Parameter<sead::Vector3f> _48; - agl::utl::Parameter<f32> _70; - agl::utl::Parameter<f32> _90; - agl::utl::Parameter<sead::SafeString> _b0; - agl::utl::Parameter<sead::Vector3f> _d8; - agl::utl::Parameter<sead::SafeString> _100; - agl::utl::Parameter<sead::Vector3f> _128; - agl::utl::Parameter<sead::SafeString> _150; - agl::utl::Parameter<sead::Vector3f> _178; - agl::utl::Parameter<sead::SafeString> _1a0; - agl::utl::Parameter<sead::Vector3f> _1c8; - agl::utl::Parameter<f32> _1f0; - agl::utl::Parameter<sead::SafeString> _210; - agl::utl::Parameter<sead::Vector3f> _238; - agl::utl::Parameter<bool> _260; - agl::utl::Parameter<sead::SafeString> _280; - agl::utl::Parameter<sead::Vector3f> _2a8; - agl::utl::ParameterObj _2d0; + agl::utl::Parameter<bool> mIsEnableAttention; + agl::utl::Parameter<sead::SafeString> mLookAtBone; + agl::utl::Parameter<sead::Vector3f> mLookAtOffset; + agl::utl::Parameter<f32> mCursorOffsetY; + agl::utl::Parameter<f32> mAIInfoOffsetY; + agl::utl::Parameter<sead::SafeString> mCutTargetBone; + agl::utl::Parameter<sead::Vector3f> mCutTargetOffset; + agl::utl::Parameter<sead::SafeString> mGameCameraBone; + agl::utl::Parameter<sead::Vector3f> mGameCameraOffset; + agl::utl::Parameter<sead::SafeString> mBowCameraBone; + agl::utl::Parameter<sead::Vector3f> mBowCameraOffset; + agl::utl::Parameter<sead::SafeString> mAttackTargetBone; + agl::utl::Parameter<sead::Vector3f> mAttackTargetOffset; + agl::utl::Parameter<f32> mAttackTargetOffsetBack; + agl::utl::Parameter<sead::SafeString> mAtObstacleChkOffsetBone; + agl::utl::Parameter<sead::Vector3f> mAtObstacleChkOffset; + agl::utl::Parameter<bool> mAtObstacleChkUseLookAtPos; + agl::utl::Parameter<sead::SafeString> mCursorAIInfoBaseBone; + agl::utl::Parameter<sead::Vector3f> mCursorAIInfoBaseOffset; + agl::utl::ParameterObj mObj; }; KSYS_CHECK_SIZE_NX150(Attention, 0x300); @@ -86,6 +88,44 @@ public: }; KSYS_CHECK_SIZE_NX150(AnmTarget, 0x130); + struct ModelDataInfo { + std::array<std::array<const char*, 8>, 1> unit_names; + std::array<std::array<const char*, 8>, 1> unit_bind_bones; + std::array<int, 1> num_units; + std::array<const char*, 1> folder_name; + int num_model_data; + sead::Vector3f base_scale; + }; + KSYS_CHECK_SIZE_NX150(ModelDataInfo, 0xa0); + + struct AttentionInfo { + const char* look_at_bone; + sead::Vector3f look_at_offset; + float cursor_offset_y; + float ai_info_offset_y; + const char* cut_target_bone; + sead::Vector3f cut_target_offset; + const char* game_camera_bone; + sead::Vector3f game_camera_offset; + const char* bow_camera_bone; + sead::Vector3f bow_camera_offset; + const char* attack_target_bone; + sead::Vector3f attack_target_offset; + float attack_target_offset_back; + const char* at_obstacle_chk_bone; + sead::Vector3f at_obstacle_chk_offset; + const char* cursor_ai_info_base_bone; + sead::Vector3f cursor_ai_info_base_offset; + }; + KSYS_CHECK_SIZE_NX150(AttentionInfo, 0xb0); + + struct PartialInfo { + sead::SafeString bone; + int bind_flag; + bool recursible; + }; + KSYS_CHECK_SIZE_NX150(PartialInfo, 0x18); + ModelList(); ~ModelList() override; @@ -99,9 +139,23 @@ public: const sead::Buffer<AnmTarget>& getAnmTargets() const { return mAnmTargets; } bool is7C8() const { return _7c8; } + int getNumAnmTargets() const; + void getModelDataInfo(ModelDataInfo* info) const; + bool getAttentionInfo(AttentionInfo* info) const; + bool getLocatorInfo(act::InfoData::Locator* info, act::InfoData::Locator::Type type) const; + bool isParticalEnable(int anm_target_idx) const; + int getNumASSlot(int anm_target_idx) const; + int getNumPartials(int anm_target_idx) const; + void getPartialInfo(PartialInfo* info, int anm_target_idx, int partial_idx) const; + + static act::InfoData::Locator::Type getLocatorTypeFromStr(const sead::SafeString& type); + private: - sead::StorageFor<ControllerInfo> mControllerInfo{sead::ZeroInitializeTag{}}; - sead::StorageFor<Attention> mAttention{sead::ZeroInitializeTag{}}; + bool parseModelData(const agl::utl::ResParameterList& res, sead::Heap* heap); + bool parseAnmTarget(const agl::utl::ResParameterList& res, sead::Heap* heap); + + sead::StorageFor<ControllerInfo, true> mControllerInfo{sead::ZeroInitializeTag{}}; + sead::StorageFor<Attention, true> mAttention{sead::ZeroInitializeTag{}}; u8* mRawData{}; sead::Buffer<ModelData> mModelData; agl::utl::ParameterList mModelDataList; diff --git a/src/KingSystem/Utils/CMakeLists.txt b/src/KingSystem/Utils/CMakeLists.txt index a7baab79..7efc89f2 100644 --- a/src/KingSystem/Utils/CMakeLists.txt +++ b/src/KingSystem/Utils/CMakeLists.txt @@ -70,6 +70,7 @@ target_sources(uking PRIVATE HeapUtil.cpp HeapUtil.h InitTimeInfo.h + ParamIO.cpp ParamIO.h SafeDelete.h StrTreeMap.h diff --git a/src/KingSystem/Utils/ParamIO.cpp b/src/KingSystem/Utils/ParamIO.cpp new file mode 100644 index 00000000..de9d0bc5 --- /dev/null +++ b/src/KingSystem/Utils/ParamIO.cpp @@ -0,0 +1,21 @@ +#include "KingSystem/Utils/ParamIO.h" +#include <agl/Utils/aglParameter.h> + +namespace ksys { + +const char* ParamIO::getString(const agl::utl::ResParameterObj& obj, const char* key, + const char* default_value, void*) const { + const auto param = agl::utl::getResParameter(obj, key); + if (!param.ptr()) + return default_value; + return param.getData<const char>(); +} + +// NON_MATCHING: how the default_value Vec3f is stored on the stack +sead::Vector3f ParamIO::getVec3(const agl::utl::ResParameterObj& obj, const char* key, + sead::Vector3f default_value, void*) const { + const auto param = agl::utl::getResParameter(obj, key); + return param.ptr() ? *param.getData<sead::Vector3f>() : default_value; +} + +} // namespace ksys diff --git a/src/KingSystem/Utils/ParamIO.h b/src/KingSystem/Utils/ParamIO.h index 820cdc76..b960f18f 100644 --- a/src/KingSystem/Utils/ParamIO.h +++ b/src/KingSystem/Utils/ParamIO.h @@ -2,6 +2,7 @@ #include <agl/Utils/aglParameterIO.h> #include <hostio/seadHostIONode.h> +#include <math/seadVector.h> #include <prim/seadSafeString.h> #include "KingSystem/Utils/Types.h" @@ -15,6 +16,11 @@ public: bool applyResourceUpdate(const char* data, const char* data1); + const char* getString(const agl::utl::ResParameterObj& obj, const char* key, + const char* default_value, void* = nullptr) const; + sead::Vector3f getVec3(const agl::utl::ResParameterObj& obj, const char* key, + sead::Vector3f default_value, void* = nullptr) const; + u32 getIdx() const { return mIdx; } sead::BufferedSafeString& getPath() { return mPath; } const sead::BufferedSafeString& getPath() const { return mPath; } |
