From dbaac9cb7834f7408287df9ef833175aa1d43bc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Thu, 15 Oct 2020 22:31:45 +0200 Subject: [PATCH] ksys/act: Add InstParamPack --- data/uking_functions.csv | 10 +- src/KingSystem/ActorSystem/CMakeLists.txt | 2 + .../ActorSystem/actInstParamPack.cpp | 79 +++++++++++++ src/KingSystem/ActorSystem/actInstParamPack.h | 110 ++++++++++++++++++ 4 files changed, 196 insertions(+), 5 deletions(-) create mode 100644 src/KingSystem/ActorSystem/actInstParamPack.cpp create mode 100644 src/KingSystem/ActorSystem/actInstParamPack.h diff --git a/data/uking_functions.csv b/data/uking_functions.csv index 4993e887..510a5228 100644 --- a/data/uking_functions.csv +++ b/data/uking_functions.csv @@ -74109,11 +74109,11 @@ 0x0000007100dca244,sub_7100DCA244,32, 0x0000007100dca264,sub_7100DCA264,32, 0x0000007100dca284,sub_7100DCA284,52, -0x0000007100dca2b8,_ZN15ActorInstParams3Buf5clearEv,28, -0x0000007100dca2d4,_ZN15ActorInstParams3Buf3addEPKvRKN4sead10SafeStringEiNS_9EntryTypeE,224, -0x0000007100dca3b4,ActorInstParams::Buf::addInvoker,196, -0x0000007100dca478,ActorInstParams::Buf::pop,604, -0x0000007100dca6d4,_ZN15ActorInstParams3BufaSERS0_,56, +0x0000007100dca2b8,_ZN15ActorInstParams3Buf5clearEv,28,_ZN4ksys3act13InstParamPack6Buffer5clearEv +0x0000007100dca2d4,_ZN15ActorInstParams3Buf3addEPKvRKN4sead10SafeStringEiNS_9EntryTypeE,224,_ZN4ksys3act13InstParamPack6Buffer3addEPKvRKN4sead14SafeStringBaseIcEEiNS1_9EntryTypeE? +0x0000007100dca3b4,ActorInstParams::Buf::addInvoker,196,_ZN4ksys3act13InstParamPack6Buffer3addEPN4sead10IDelegate1IPNS0_8BaseProcEEERKNS3_14SafeStringBaseIcEE? +0x0000007100dca478,ActorInstParams::Buf::pop,604,_ZN4ksys3act13InstParamPack6Buffer3popEPiPNS1_5EntryE! +0x0000007100dca6d4,_ZN15ActorInstParams3BufaSERS0_,56,_ZN4ksys3act13InstParamPack6BufferaSERKS2_ 0x0000007100dca70c,_ZN13ActorAccessorD2Ev,56,_ZN4ksys3act24ActorLinkConstDataAccessD1Ev 0x0000007100dca744,ActorAccessor::acquire,88,_ZN4ksys3act24ActorLinkConstDataAccess7acquireEPNS0_8BaseProcE 0x0000007100dca79c,act::acquireActorFromGameOrHavokThread,256,_ZN4ksys3act11acquireProcEPNS0_24ActorLinkConstDataAccessEPNS0_8BaseProcERKN4sead14SafeStringBaseIcEEi diff --git a/src/KingSystem/ActorSystem/CMakeLists.txt b/src/KingSystem/ActorSystem/CMakeLists.txt index a7a5b4f4..4e59d0cc 100644 --- a/src/KingSystem/ActorSystem/CMakeLists.txt +++ b/src/KingSystem/ActorSystem/CMakeLists.txt @@ -31,5 +31,7 @@ target_sources(uking PRIVATE actBaseProcMgr.h actBaseProcUnit.cpp actBaseProcUnit.h + actInstParamPack.cpp + actInstParamPack.h actTag.h ) diff --git a/src/KingSystem/ActorSystem/actInstParamPack.cpp b/src/KingSystem/ActorSystem/actInstParamPack.cpp new file mode 100644 index 00000000..566cb7be --- /dev/null +++ b/src/KingSystem/ActorSystem/actInstParamPack.cpp @@ -0,0 +1,79 @@ +#include "KingSystem/ActorSystem/actInstParamPack.h" +#include + +namespace ksys::act { + +void InstParamPack::Buffer::clear() { + mNumItems = 0; + mPosition = 0; + mData.fill(0); +} + +// NON_MATCHING: write() +void InstParamPack::Buffer::add(const void* data, const sead::SafeString& name, s32 byte_size, + InstParamPack::EntryType type) { + if (byte_size + mPosition + u32(sizeof(const char*)) + 1 > mData.getByteSize()) { + SEAD_ASSERT_MSG(false, "InstParamPack::Buffer::add: Buffer overflow"); + return; + } + + write(name.cstr()); + write(u8(type)); + writeBytes(data, byte_size); + ++mNumItems; +} + +// NON_MATCHING: write() +void InstParamPack::Buffer::add(ActorCallback* callback, const sead::SafeString& name) { + add(callback, name, sizeof(callback), EntryType::UInt64); +} + +// NON_MATCHING +bool InstParamPack::Buffer::pop(s32* position, InstParamPack::Entry* out_entry) { + if (!read(out_entry->key, position)) + return false; + + if (!read(out_entry->type.mValue, position)) + return false; + + switch (out_entry->type) { + case EntryType::Int: + return read(out_entry->data.i, position); + case EntryType::_1: + return read(out_entry->data.type1, position); + case EntryType::Float: + return read(out_entry->data.f, position); + case EntryType::Bool: + return read(out_entry->data.b, position); + case EntryType::Vec3: + return read(out_entry->data.vec3, position); + case EntryType::String: { + const s32 start_pos = *position; + char c; + do { + if (!read(c, position)) { + out_entry->data.str = nullptr; + return false; + } + } while (c != sead::SafeString::cNullChar); + out_entry->data.str = reinterpret_cast(&mData[start_pos]); + return true; + } + case EntryType::UInt64: + return read(out_entry->data.l, position); + case EntryType::Matrix34: + return read(out_entry->data.mtx34, position); + default: + return false; + } +} + +InstParamPack::Buffer& InstParamPack::Buffer::operator=(const InstParamPack::Buffer& other) { + size_t pos = other.mPosition; + mPosition = pos; + mNumItems = other.mNumItems; + sead::MemUtil::copy(mData.getBufferPtr(), other.mData.getBufferPtr(), pos); + return *this; +} + +} // namespace ksys::act diff --git a/src/KingSystem/ActorSystem/actInstParamPack.h b/src/KingSystem/ActorSystem/actInstParamPack.h new file mode 100644 index 00000000..dbb5d868 --- /dev/null +++ b/src/KingSystem/ActorSystem/actInstParamPack.h @@ -0,0 +1,110 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include "KingSystem/Utils/Types.h" + +namespace ksys::act { + +class BaseProc; + +class InstParamPack { +public: + enum class EntryType { + /// Signed(?) 32-bit integer. + Int = 0, + /// Unknown. + _1 = 1, + /// Single-precision float. + Float = 2, + /// Boolean. + Bool = 3, + /// Vector3f. + Vec3 = 4, + /// String (stored inline). + String = 5, + /// Unsigned 64-bit integer. Can be used to store pointers. + UInt64 = 6, + /// 3x4 matrix (sead::Matrix34). + Matrix34 = 7, + }; + + using ActorCallback = sead::IDelegate1; + + struct Entry { + union Data { + s32 i; + f32 f; + u32 type1; + u64 l; + bool b; + sead::Vector3f vec3; + sead::Matrix34f mtx34; + const char* str; + ActorCallback* cb; + }; + KSYS_CHECK_SIZE_NX150(Data, 0x30); + + const char* key; + sead::SizedEnum type; + Data data; + }; + KSYS_CHECK_SIZE_NX150(Entry, 0x40); + + class Buffer { + public: + Buffer() { clear(); } + Buffer& operator=(const Buffer& other); + + void clear(); + void add(const void* data, const sead::SafeString& name, s32 byte_size, EntryType type); + void add(ActorCallback* callback, const sead::SafeString& name); + + bool pop(s32* position, Entry* out_entry); + + private: + void writeBytes(const void* value, s32 size) { + sead::MemUtil::copy(&mData[mPosition], value, size); + mPosition += size; + } + + template + void write(const T& value) { + writeBytes(&value, sizeof(value)); + } + + template + bool read(T& value, s32* position) { + if (*position + s32(sizeof(T)) > mData.size()) + return false; + + sead::MemUtil::copy(&value, &mData[*position], sizeof(T)); + *position += s32(sizeof(T)); + return true; + } + + u16 mNumItems; + s16 mPosition; + sead::SafeArray mData; + }; + KSYS_CHECK_SIZE_NX150(Buffer, 0xc4); + + InstParamPack() = default; + virtual ~InstParamPack() = default; + + Buffer& getBuffer() { return mBuffer; } + const Buffer& getBuffer() const { return mBuffer; } + +private: + BaseProc* mProc = nullptr; + Buffer mBuffer; +}; +KSYS_CHECK_SIZE_NX150(InstParamPack, 0xd8); + +} // namespace ksys::act