From a72a4b25c0d2894055e982216b27d3bd891c6549 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Sat, 5 Dec 2020 19:25:07 +0100 Subject: [PATCH] ksys/act: Add most remaining ParamPack functions --- data/uking_functions.csv | 4 +- src/KingSystem/ActorSystem/actActor.h | 6 +- src/KingSystem/ActorSystem/actAiParam.cpp | 188 ++++++++++++++++++ src/KingSystem/ActorSystem/actAiParam.h | 22 ++ src/KingSystem/MessageSystem/mesTransceiver.h | 10 +- 5 files changed, 222 insertions(+), 8 deletions(-) diff --git a/data/uking_functions.csv b/data/uking_functions.csv index 8fa78cba..b4d26c20 100644 --- a/data/uking_functions.csv +++ b/data/uking_functions.csv @@ -73058,7 +73058,7 @@ 0x0000007100d175dc,ai::ParamPack::dtor,152,_ZN4ksys3act2ai9ParamPackD1Ev 0x0000007100d17674,ai::ParamPack::x,184, 0x0000007100d1772c,ai::ParamPack::getAITreeVariablePointer,116,_ZNK4ksys3act2ai9ParamPack24getAITreeVariablePointerERKN4sead14SafeStringBaseIcEENS_14AIDefParamTypeEb -0x0000007100d177a0,ai::ParamPack::loadFromInlineParamPack,1132, +0x0000007100d177a0,ai::ParamPack::loadFromInlineParamPack,1132,_ZN4ksys3act2ai9ParamPack4copyEPNS1_15InlineParamPackEb 0x0000007100d17c0c,ai::InlineParamPack::addInt,116,_ZN4ksys3act2ai15InlineParamPack6addIntEiRKN4sead14SafeStringBaseIcEEi 0x0000007100d17c80,ai::InlineParamPack::addFloat,116,_ZN4ksys3act2ai15InlineParamPack8addFloatEfRKN4sead14SafeStringBaseIcEEi 0x0000007100d17cf4,ai::InlineParamPack::addFloatArray,144,_ZN4ksys3act2ai15InlineParamPack7addVec3ERKN4sead7Vector3IfEERKNS3_14SafeStringBaseIcEEi @@ -73071,7 +73071,7 @@ 0x0000007100d181d4,ai::ParamPack::getString_0,316,_ZNK4ksys3act2ai9ParamPack9setStringERKN4sead14SafeStringBaseIcEES7_ 0x0000007100d18310,ai::ParamPack::getBaseProcLink_0,120,_ZNK4ksys3act2ai9ParamPack8getActorEPNS0_8BaseProcERKN4sead14SafeStringBaseIcEE 0x0000007100d18388,ai::ParamPack::getBaseProcLink,116,_ZNK4ksys3act2ai9ParamPack8setActorERKNS0_12BaseProcLinkERKN4sead14SafeStringBaseIcEE -0x0000007100d183fc,ai::ParamPack::allocAndLoadParams,1312, +0x0000007100d183fc,ai::ParamPack::allocAndLoadParams,1312,_ZN4ksys3act2ai9ParamPack4loadERKNS0_5ActorERKNS_5AIDefEPN4sead4HeapENS_18AIDefInstParamKindE 0x0000007100d1891c,ai::InlineParamPack::addString,132,_ZN4ksys3act2ai15InlineParamPack10addPointerEPvRKN4sead14SafeStringBaseIcEENS_14AIDefParamTypeEi 0x0000007100d189a0,sub_7100D189A0,136,_ZN4ksys3act2ai15InlineParamPack12acquireActorEPNS0_8BaseProcERKN4sead14SafeStringBaseIcEEi 0x0000007100d18a28,ai::InlineParamPack::copyToParamPack,1204,_ZNK4ksys3act2ai15InlineParamPack15copyToParamPackERNS1_9ParamPackE diff --git a/src/KingSystem/ActorSystem/actActor.h b/src/KingSystem/ActorSystem/actActor.h index 71608780..2fa71ca5 100644 --- a/src/KingSystem/ActorSystem/actActor.h +++ b/src/KingSystem/ActorSystem/actActor.h @@ -2,6 +2,7 @@ #include #include "KingSystem/ActorSystem/actBaseProc.h" +#include "KingSystem/Map/mapMubinIter.h" namespace ksys { @@ -24,6 +25,7 @@ public: SEAD_RTTI_OVERRIDE(Actor, BaseProc) const ActorParam* getParam() const { return mActorParam; } + const map::MubinIter& getMapObjIter() const { return mMapObjIter; } virtual s32 getMaxLife(); @@ -39,7 +41,9 @@ public: protected: /* 0x008 */ u8 TEMP_0x008[0x3F4]; // FIXME /* 0x570 */ ActorParam* mActorParam; - /* 0x578 */ u8 TEMP_0x578[0x710 - 0x578]; + /* 0x578 */ u8 TEMP_0x578[0x648 - 0x578]; + /* 0x648 */ map::MubinIter mMapObjIter; + /* 0x658 */ u8 TEMP_0x650[0x710 - 0x658]; // The name could be incorrect. /* 0x710 */ sead::TypedBitFlag mStasisFlags; /* 0x714 */ u8 TEMP_0x714[0x838 - 0x714]; // FIXME diff --git a/src/KingSystem/ActorSystem/actAiParam.cpp b/src/KingSystem/ActorSystem/actAiParam.cpp index a5f1ba97..3be0d6e2 100644 --- a/src/KingSystem/ActorSystem/actAiParam.cpp +++ b/src/KingSystem/ActorSystem/actAiParam.cpp @@ -1,4 +1,5 @@ #include "KingSystem/ActorSystem/actAiParam.h" +#include "KingSystem/ActorSystem/actActor.h" namespace ksys::act::ai { @@ -58,6 +59,69 @@ void* ParamPack::getAITreeVariablePointer(const sead::SafeString& key, AIDefPara return getVariable(key, type, x); } +void ParamPack::copy(InlineParamPack* dest, bool x) { + for (auto* param = mParams; param; param = param->next) { + if (!param->data || !param->used) + continue; + + const s32 dest_idx = dest->findIndex(param->name, param->type); + + switch (param->type) { + case AIDefParamType::String: { + dest->addString(*static_cast(param->data), param->name, dest_idx); + break; + } + case AIDefParamType::Int: + dest->addInt(*static_cast(param->data), param->name, dest_idx); + break; + case AIDefParamType::Float: + dest->addFloat(*static_cast(param->data), param->name, dest_idx); + break; + case AIDefParamType::Vec3: + dest->addVec3(*static_cast(param->data), param->name, dest_idx); + break; + case AIDefParamType::Bool: + dest->addBool(*static_cast(param->data), param->name, dest_idx); + break; + case AIDefParamType::UInt: + dest->addUInt(*static_cast(param->data), param->name, dest_idx); + break; + case AIDefParamType::BaseProcLink: + dest->addActor(*static_cast(param->data), param->name, dest_idx); + break; + case AIDefParamType::MesTransceiverId: + if (!x) { + dest->addMesTransceiverId(*static_cast(param->data), + param->name, dest_idx); + break; + } + [[fallthrough]]; + case AIDefParamType::BaseProcHandle: + if (!x) { + dest->addPointer(*static_cast(param->data), param->name, + AIDefParamType::BaseProcHandle, dest_idx); + break; + } + [[fallthrough]]; + case AIDefParamType::Rail: + dest->addPointer(*static_cast(param->data), param->name, AIDefParamType::Rail, + dest_idx); + break; + case AIDefParamType::Tree: + case AIDefParamType::AITreeVariablePointer: + case AIDefParamType::Other: + break; + } + } +} + +void InlineParamPack::addString(const char* value, const sead::SafeString& key, s32 idx) { + auto& param = getParam(idx); + param.key = key.cstr(); + param.cstr = value; + param.type = AIDefParamType::String; +} + void InlineParamPack::addInt(s32 value, const sead::SafeString& key, s32 idx) { auto& param = getParam(idx); param.key = key.cstr(); @@ -86,6 +150,13 @@ void InlineParamPack::addBool(bool value, const sead::SafeString& key, s32 idx) param.type = AIDefParamType::Bool; } +void InlineParamPack::addUInt(u32 value, const sead::SafeString& key, s32 idx) { + auto& param = getParam(idx); + param.key = key.cstr(); + param.u = value; + param.type = AIDefParamType::UInt; +} + void InlineParamPack::addActor(const BaseProcLink& value, const sead::SafeString& key, s32 idx) { auto& param = getParam(idx); param.key = key.cstr(); @@ -133,6 +204,123 @@ bool ParamPack::setActor(const BaseProcLink& new_link, const sead::SafeString& k return true; } +bool ParamPack::load(const Actor& actor, const AIDef& def, sead::Heap* heap, + AIDefInstParamKind kind) { + bool load_map_unit_params = false; + bool used = false; + + if (kind == AIDefInstParamKind::AITree) { + load_map_unit_params = false; + used = true; + } else if (kind == AIDefInstParamKind::MapUnit) { + load_map_unit_params = def._24b == 0; + used = true; + } + + const auto& iter = actor.getMapObjIter(); + for (s32 i = 0; i < def.num_params; ++i) { + const auto hash = agl::utl::ParameterBase::calcHash(def.param_names[i]); + + bool found = false; + for (auto* entry = mParams; entry; entry = entry->next) { + if (entry->hash == hash) { + found = true; + break; + } + } + if (found) + continue; + + // Otherwise, allocate a new entry. + auto* entry = new (heap) Param; + if (!entry) + return false; + entry->data = nullptr; + entry->next = mParams; + mParams = entry; + switch (def.param_types[i]) { + case AIDefParamType::String: { + const char* value = def.param_values[i].str ? def.param_values[i].str : ""; + + if (load_map_unit_params) + iter.tryGetParamStringByKey(&value, def.param_names[i]); + + entry->data = new (heap) sead::FixedSafeString<80>(value); + break; + } + case AIDefParamType::Int: { + int value = def.param_values[i].i; + if (load_map_unit_params) + iter.tryGetParamIntByKey(&value, def.param_names[i]); + entry->data = new (heap) int(value); + break; + } + case AIDefParamType::Float: { + float value = def.param_values[i].f; + if (load_map_unit_params) + iter.tryGetParamFloatByKey(&value, def.param_names[i]); + entry->data = new (heap) float(value); + break; + } + case AIDefParamType::Vec3: { + const auto& src = def.param_values[i].vec3; + sead::Vector3f value{src.x, src.y, src.z}; + if (load_map_unit_params) + iter.tryGetFloatArrayByKey(value.e.data(), def.param_names[i]); + entry->data = new (heap) sead::Vector3f(value); + break; + } + case AIDefParamType::Bool: { + bool value = def.param_values[i].b; + if (load_map_unit_params) + iter.tryGetParamBoolByKey(&value, def.param_names[i]); + entry->data = new (heap) bool(value); + break; + } + case AIDefParamType::AITreeVariablePointer: + entry->data = new (heap) void*(); + break; + case AIDefParamType::UInt: { + u32 value = def.param_values[i].u; + if (load_map_unit_params) + iter.tryGetParamUIntByKey(&value, def.param_names[i]); + entry->data = new (heap) u32(value); + break; + } + case AIDefParamType::BaseProcLink: + if (kind == AIDefInstParamKind::Dynamic) + entry->data = new (heap) BaseProcLink(); + break; + case AIDefParamType::MesTransceiverId: + if (kind == AIDefInstParamKind::Dynamic) + entry->data = new (heap) mes::TransceiverId(); + break; + case AIDefParamType::BaseProcHandle: + if (kind == AIDefInstParamKind::Dynamic) + entry->data = new (heap) BaseProcHandle*(); + break; + case AIDefParamType::Rail: + if (kind == AIDefInstParamKind::Dynamic) + entry->data = new (heap) Rail*(); + break; + case AIDefParamType::Tree: + case AIDefParamType::Other: + break; + } + + if (!entry->data) + return false; + + entry->hash = hash; + entry->name = def.param_names[i]; + entry->used = used; + entry->_23 = def._24b; + entry->type = def.param_types[i]; + } + + return true; +} + void InlineParamPack::addPointer(void* value, const sead::SafeString& key, AIDefParamType type, s32 idx) { auto& param = getParam(idx); diff --git a/src/KingSystem/ActorSystem/actAiParam.h b/src/KingSystem/ActorSystem/actAiParam.h index 4882f4dd..b008b325 100644 --- a/src/KingSystem/ActorSystem/actAiParam.h +++ b/src/KingSystem/ActorSystem/actAiParam.h @@ -16,8 +16,14 @@ namespace ksys { class Rail; +namespace act { +class Actor; +} + namespace act::ai { +struct InlineParamPack; + struct Param { Param* next; u32 hash; @@ -58,6 +64,7 @@ public: } void* getAITreeVariablePointer(const sead::SafeString& key, AIDefParamType type, bool x) const; + void copy(InlineParamPack* dest, bool x); bool getString(sead::SafeString* value, const sead::SafeString& key) const; bool setString(const sead::SafeString& value, const sead::SafeString& key) const; @@ -65,6 +72,8 @@ public: bool getActor(BaseProc* proc, const sead::SafeString& key) const; bool setActor(const BaseProcLink& link, const sead::SafeString& key) const; + bool load(const Actor& actor, const AIDef& def, sead::Heap* heap, AIDefInstParamKind kind); + private: Param* mParams = nullptr; }; @@ -98,10 +107,23 @@ struct InlineParamPack { return params[idx]; } + s32 findIndex(const sead::SafeString& name, AIDefParamType type) const { + for (s32 i = 0; i < count; ++i) { + if (params[i].type == type && name == params[i].key) + return i; + } + return -1; + } + + void addString(const char* value, const sead::SafeString& key, s32 idx); + void addString(const sead::SafeString& value, const sead::SafeString& key, s32 idx) { + addString(value.cstr(), key, idx); + } void addInt(s32 value, const sead::SafeString& key, s32 idx); void addFloat(f32 value, const sead::SafeString& key, s32 idx); void addVec3(const sead::Vector3f& value, const sead::SafeString& key, s32 idx); void addBool(bool value, const sead::SafeString& key, s32 idx); + void addUInt(u32 value, const sead::SafeString& key, s32 idx); void addActor(const BaseProcLink& value, const sead::SafeString& key, s32 idx); void addMesTransceiverId(const mes::TransceiverId& value, const sead::SafeString& key, s32 idx); void addPointer(void* value, const sead::SafeString& key, AIDefParamType type, s32 idx); diff --git a/src/KingSystem/MessageSystem/mesTransceiver.h b/src/KingSystem/MessageSystem/mesTransceiver.h index ea9d3f79..c433b923 100644 --- a/src/KingSystem/MessageSystem/mesTransceiver.h +++ b/src/KingSystem/MessageSystem/mesTransceiver.h @@ -9,7 +9,7 @@ namespace ksys { namespace mes { struct TransceiverId { - TransceiverId(); + TransceiverId() = default; TransceiverId& operator=(const TransceiverId& other) { _0 = other._0; @@ -19,10 +19,10 @@ struct TransceiverId { return *this; } - u32 _0; - u32 _4; - void* _8; - void* _10; + s32 _0 = -1; + s32 _4 = -1; + void* _8{}; + void* _10{}; }; KSYS_CHECK_SIZE_NX150(TransceiverId, 0x18);