diff --git a/data/uking_functions.csv b/data/uking_functions.csv index 2d4350f2..15cda80c 100644 --- a/data/uking_functions.csv +++ b/data/uking_functions.csv @@ -75585,20 +75585,20 @@ 0x0000007100db3ffc,evt::Event::doAssign,296, 0x0000007100db4124,evt::Event::assign,48, 0x0000007100db4154,sub_7100DB4154,1680, -0x0000007100db47e4,ksys::evt::OrderParam::ctor,36, -0x0000007100db4808,sub_7100DB4808,20, -0x0000007100db481c,sub_7100DB481C,284, -0x0000007100db4938,sub_7100DB4938,52, -0x0000007100db496c,ksys::evt::OrderParam::doAssign,1160, -0x0000007100db4df4,ksys::evt::OrderParam::assign,48, -0x0000007100db4e24,ksys::evt::OrderParam::initialize,332, -0x0000007100db4f70,ksys::evt::OrderParam::addParamInt,220, -0x0000007100db504c,ksys::evt::OrderParam::addParamStr,412, -0x0000007100db51e8,ksys::evt::OrderParam::tryAlloc_,944, -0x0000007100db5598,ksys::evt::OrderParam::addParamActor,240, -0x0000007100db5688,ksys::evt::OrderParam::addInt,176, -0x0000007100db5738,ksys::evt::OrderParam::getParameter,176, -0x0000007100db57e8,ksys::evt::OrderParam::x_1,208, +0x0000007100db47e4,ksys::evt::OrderParam::ctor,36,_ZN4ksys3evt10OrderParamC1EPN4sead4HeapE +0x0000007100db4808,ksys::evt::OrderParam::dtor,20,_ZN4ksys3evt10OrderParamD1Ev +0x0000007100db481c,ksys::evt::OrderParam::uninitialize,284,_ZN4ksys3evt10OrderParam12uninitializeEv +0x0000007100db4938,ksys::evt::OrderParam::dtorDelete,52,_ZN4ksys3evt10OrderParamD0Ev +0x0000007100db496c,ksys::evt::OrderParam::doAssign,1160,_ZN4ksys3evt10OrderParam8doAssignERKS1_ +0x0000007100db4df4,ksys::evt::OrderParam::assign,48,_ZN4ksys3evt10OrderParamaSERKS1_ +0x0000007100db4e24,ksys::evt::OrderParam::initialize,332,_ZN4ksys3evt10OrderParam10initializeEi +0x0000007100db4f70,ksys::evt::OrderParam::addParamInt,220,_ZN4ksys3evt10OrderParam11addParamIntEiRKN4sead14SafeStringBaseIcEE +0x0000007100db504c,ksys::evt::OrderParam::addParamString,412,_ZN4ksys3evt10OrderParam14addParamStringERKN4sead14SafeStringBaseIcEES6_ +0x0000007100db51e8,ksys::evt::OrderParam::tryAlloc_,944,_ZN4ksys3evt10OrderParam8tryAllocENS0_14OrderParamTypeEjRKN4sead14SafeStringBaseIcEE +0x0000007100db5598,ksys::evt::OrderParam::addParamActor,240,_ZN4ksys3evt10OrderParam13addParamActorEPNS_3act8BaseProcERN4sead14SafeStringBaseIcEE +0x0000007100db5688,ksys::evt::OrderParam::getIntByName,176,_ZNK4ksys3evt10OrderParam12getIntByNameERKN4sead14SafeStringBaseIcEEPPj +0x0000007100db5738,ksys::evt::OrderParam::getStringByName,176,_ZNK4ksys3evt10OrderParam15getStringByNameERKN4sead14SafeStringBaseIcEEPPS4_ +0x0000007100db57e8,ksys::evt::OrderParam::getArrayByName,208,_ZNK4ksys3evt10OrderParam14getArrayByNameERKN4sead14SafeStringBaseIcEEPPvPj 0x0000007100db58b8,evt::EventFlowBase::ctor,2140, 0x0000007100db6114,_ZN4sead9SafeArrayINS_15FixedSafeStringILi64EEELi8EEC2Ev,360, 0x0000007100db627c,evt::EventFlowBase::getBaseProcLink,12, diff --git a/src/KingSystem/Event/CMakeLists.txt b/src/KingSystem/Event/CMakeLists.txt index 0de91345..2ba90f45 100644 --- a/src/KingSystem/Event/CMakeLists.txt +++ b/src/KingSystem/Event/CMakeLists.txt @@ -5,4 +5,6 @@ target_sources(uking PRIVATE evtInfoData.h evtManager.cpp evtManager.h + evtOrderParam.cpp + evtOrderParam.h ) diff --git a/src/KingSystem/Event/evtEvent.cpp b/src/KingSystem/Event/evtEvent.cpp index 9577e6a3..8addcda3 100644 --- a/src/KingSystem/Event/evtEvent.cpp +++ b/src/KingSystem/Event/evtEvent.cpp @@ -1 +1,8 @@ #include "KingSystem/Event/evtEvent.h" +#include "KingSystem/Event/evtManager.h" +#include "KingSystem/Event/evtOrderParam.h" + +namespace ksys::evt { + +Event::Event() {} +} // namespace ksys::evt \ No newline at end of file diff --git a/src/KingSystem/Event/evtEvent.h b/src/KingSystem/Event/evtEvent.h index ac6a8a94..3d5c255b 100644 --- a/src/KingSystem/Event/evtEvent.h +++ b/src/KingSystem/Event/evtEvent.h @@ -1,10 +1,12 @@ #pragma once #include +#include #include namespace ksys::evt { +class OrderParam; // TODO class Event { public: diff --git a/src/KingSystem/Event/evtManager.h b/src/KingSystem/Event/evtManager.h index 0850d534..4d192721 100644 --- a/src/KingSystem/Event/evtManager.h +++ b/src/KingSystem/Event/evtManager.h @@ -16,6 +16,8 @@ public: void init(sead::Heap* heap); Event* getActiveEvent() const; + + sead::Heap* mEventHeap; // 0x1d180 }; } // namespace ksys::evt diff --git a/src/KingSystem/Event/evtOrderParam.cpp b/src/KingSystem/Event/evtOrderParam.cpp new file mode 100644 index 00000000..0504ed5e --- /dev/null +++ b/src/KingSystem/Event/evtOrderParam.cpp @@ -0,0 +1,294 @@ +#include "KingSystem/Event/evtOrderParam.h" +#include +#include +#include +#include +#include "KingSystem/ActorSystem/actBaseProcLink.h" + +namespace ksys::evt { + +OrderParam::OrderParam(sead::Heap* heap) { + mHeap = heap; +} + +OrderParam::~OrderParam() { + uninitialize(); +} + +bool OrderParam::initialize(s32 entry_count) { + sead::FixedSafeString<0x100> error_message; + + error_message.format("[%s] initialize(%d) is failed.", "ksys::evt::OrderParam", entry_count); + uninitialize(); + if (!entry_count) + return true; + if (!mHeap) + return false; + if (!mEntries.tryAllocBuffer(entry_count, mHeap)) + return false; + + for (u32 i = 0; i < u32(entry_count); i++) + mEntries[i].clear(); + + mEntryCount = 0; + mInitialized = true; + return true; +} + +void OrderParam::uninitialize() { + for (s32 i = 0; i < mEntries.size(); i++) { + auto& entry = mEntries[i]; + if (entry.name) + delete (entry.name); + auto* ptr = entry.data; + if (ptr) { + switch (entry.type) { + case OrderParamType::String: + delete static_cast(ptr); + break; + case OrderParamType::Int: + delete static_cast(ptr); + break; + case OrderParamType::Float: + delete static_cast(ptr); + break; + case OrderParamType::Bool: + delete static_cast(ptr); + break; + case OrderParamType::Actor: + delete static_cast(ptr); + break; + case OrderParamType::Array: + mHeap->free(ptr); + break; + default: + break; + } + } + entry.clear(); + } + mEntries.freeBuffer(); + mEntryCount = 0; + mInitialized = false; +} + +const OrderParamEntry* OrderParam::getParam(const s32 index) const { + sead::FixedSafeString<0x100> error_message; + + error_message.format("[%s] getParam(%d) is failed.", "ksys::evt::OrderParam", index); + if (u32(std::max(0, mEntries.size())) > u32(index)) { + return &mEntries[index]; + } else { + return nullptr; + } +} + +OrderParam& OrderParam::operator=(const OrderParam& other) { + if (this != &other) { + doAssign(other); + } + return *this; +} + +bool OrderParam::doAssign(const OrderParam& other) { + if (this == &other) + return true; + + if (!initialize(std::max(0, other.mEntries.size()))) + return false; + for (s32 i = 0; i < mEntries.size(); i++) { + auto* other_entry = other.getParam(i); + if (other_entry) { + auto* other_ptr = other_entry->data; + auto* other_name = other_entry->name; + ksys::act::BaseProcLink* link_ptr; + ksys::act::BaseProc* actor_ptr; + if (other_ptr && other_name) { + switch (other_entry->type) { + case OrderParamType::Int: + if (!addParamInt(*static_cast(other_ptr), *other_name)) + return false; + break; + case OrderParamType::Float: + if (!addParamFloat(*static_cast(other_ptr), *other_name)) + return false; + break; + case OrderParamType::String: + if (!addParamString(*static_cast(other_ptr), *other_name)) + return false; + break; + case OrderParamType::Bool: + if (!addParamBool(*static_cast(other_ptr), *other_name)) + return false; + break; + case OrderParamType::Actor: + link_ptr = static_cast(other_ptr); + actor_ptr = + sead::DynamicCast(link_ptr->getProc(nullptr, nullptr)); + if (!addParamActor(actor_ptr, *other_name)) + return false; + break; + case OrderParamType::Array: + if (!addParamArray(static_cast(other_ptr), other_entry->size, + *other_name)) + return false; + break; + default: + break; + } + } + } + } + return true; +} + +bool OrderParam::addParamInt(s32 val, const sead::SafeString& name) { + auto* entry_ptr = tryAllocParam(name, OrderParamType::Int); + if (!entry_ptr) + return false; + *entry_ptr = val; + ++mEntryCount; + return true; +} + +bool OrderParam::addParamFloat(f32 val, const sead::SafeString& name) { + auto* entry_ptr = tryAllocParam(name, OrderParamType::Float); + if (!entry_ptr) + return false; + *entry_ptr = val; + ++mEntryCount; + return true; +} + +bool OrderParam::addParamString(const sead::SafeString& val, const sead::SafeString& name) { + auto* entry_ptr = tryAllocParam(name, OrderParamType::String); + if (!entry_ptr) + return false; + entry_ptr->copy(val); + ++mEntryCount; + return true; +} + +bool OrderParam::addParamBool(bool val, const sead::SafeString& name) { + auto* entry_ptr = tryAllocParam(name, OrderParamType::Bool); + if (!entry_ptr) + return false; + *entry_ptr = val; + ++mEntryCount; + return true; +} + +bool OrderParam::addParamActor(ksys::act::BaseProc* actor, sead::SafeString& name) { + auto* entry_ptr = tryAllocParam(name, OrderParamType::Actor); + if (!entry_ptr) + return false; + if (!entry_ptr->acquire(actor, false)) + return false; + ++mEntryCount; + return true; +} + +bool OrderParam::addParamArray(char* array, u32 size, sead::SafeString& name) { + auto* entry_ptr = tryAllocParam(name, OrderParamType::Array, size); + if (!entry_ptr) + return false; + std::memcpy(entry_ptr, array, size); + ++mEntryCount; + return true; +} + +bool OrderParam::getIntByName(const sead::SafeString& name, u32** out_ptr) const { + return getPointerByName(name, out_ptr, OrderParamType::Int); +} + +bool OrderParam::getStringByName(const sead::SafeString& name, sead::SafeString** out_ptr) const { + return getPointerByName(name, out_ptr, OrderParamType::String); +} + +bool OrderParam::getArrayByName(const sead::SafeString& name, void** out_ptr, u32* out_size) const { + return getPointerByName(name, out_ptr, OrderParamType::Array, out_size); +} + +OrderParamEntry* OrderParam::getFreeEntry() { + for (s32 i = 0; i < mEntries.size(); i++) { + auto* entry = &mEntries[i]; + if (!entry->data) { + return entry; + } + } + return nullptr; +} + +OrderParamEntry* OrderParam::tryAlloc(OrderParamType type, u32 size, const sead::SafeString& name) { + sead::FixedSafeString<0x100> error_message; + + error_message.format("[%s] tryAlloc_(%d, %d, %s) is failed.", "ksys::evt::OrderParam", + static_cast(type), size, name.cstr()); + + OrderParamEntry* entry = getFreeEntry(); + + if (!entry) + return nullptr; + auto* heap = mHeap; + if (!heap) + return nullptr; + + entry->name = new (heap, std::nothrow_t()) sead::FixedSafeString<0x20>(name); + + switch (type) { + case OrderParamType::Int: + entry->data = new (heap, std::nothrow_t()) s32(); + entry->size = sizeof(s32); + break; + case OrderParamType::Float: + entry->data = new (heap, std::nothrow_t()) f32(); + entry->size = sizeof(f32); + break; + case OrderParamType::String: + entry->data = new (heap, std::nothrow_t()) sead::FixedSafeString<0x40>; + entry->size = sizeof(sead::FixedSafeString<0x40>); + break; + case OrderParamType::Bool: + entry->data = new (heap, std::nothrow_t()) bool(); + entry->size = sizeof(bool); + break; + case OrderParamType::Actor: + entry->data = new (heap, std::nothrow_t()) ksys::act::BaseProcLink; + entry->size = sizeof(act::BaseProcLink); + break; + case OrderParamType::Array: + entry->data = new (heap, std::nothrow_t()) char[size]; + entry->size = size; + break; + default: + break; + } + + auto* ptr = entry->data; + + if (ptr) { + entry->hash = sead::HashCRC32::calcStringHash(*entry->name); + entry->type = type; + return entry; + } + + if (entry->name) + delete entry->name; + entry->clear(); + return nullptr; +} + +void* OrderParam::getPointerByName(const sead::SafeString& name, OrderParamType type, + u32* out_size) const { + const u32 hash = sead::HashCRC32::calcStringHash(name); + for (s32 i = 0; i < mEntries.size(); i++) { + if (mEntries[i].hash == hash && mEntries[i].type == type) { + if (out_size) + *out_size = mEntries[i].size; + return mEntries[i].data; + } + } + return nullptr; +} + +} // namespace ksys::evt diff --git a/src/KingSystem/Event/evtOrderParam.h b/src/KingSystem/Event/evtOrderParam.h new file mode 100644 index 00000000..d53c02fa --- /dev/null +++ b/src/KingSystem/Event/evtOrderParam.h @@ -0,0 +1,93 @@ +#pragma once + +#include +#include +#include +#include +#include "KingSystem/ActorSystem/actBaseProc.h" + +namespace ksys::evt { + +enum class OrderParamType : u16 { + Invalid = 0, + Int = 1, + Float = 2, + String = 3, + Bool = 4, + Actor = 5, + Array = 6, +}; + +struct OrderParamEntry { + void clear() { + hash = 0; + size = 0; + type = OrderParamType::Invalid; + name = nullptr; + data = nullptr; + } + + u32 hash; + sead::SafeString* name; + void* data; + u32 size; + OrderParamType type; +}; + +class OrderParam { +public: + explicit OrderParam(sead::Heap* heap); + OrderParam(const OrderParam& other) { *this = other; } + virtual ~OrderParam(); + OrderParam& operator=(const OrderParam& other); + bool initialize(s32 entry_count); + void uninitialize(); + + const OrderParamEntry* getParam(s32 index) const; + bool addParamInt(s32 val, const sead::SafeString& name); + bool addParamFloat(f32 val, const sead::SafeString& name); + bool addParamString(const sead::SafeString& val, const sead::SafeString& name); + bool addParamBool(bool val, const sead::SafeString& name); + bool addParamActor(ksys::act::BaseProc* actor, sead::SafeString& name); + bool addParamArray(char* array, u32 size, sead::SafeString& name); + + OrderParamEntry* tryAlloc(OrderParamType type, u32 size, const sead::SafeString& name); + bool getIntByName(const sead::SafeString& name, u32** out_ptr) const; + bool getStringByName(const sead::SafeString& name, sead::SafeString** out_ptr) const; + bool getArrayByName(const sead::SafeString& name, void** out_ptr, u32* out_size) const; + +private: + bool doAssign(const OrderParam& other); + + OrderParamEntry* getFreeEntry(); + void* getPointerByName(const sead::SafeString& name, OrderParamType type, + u32* out_size = nullptr) const; + + template + bool getPointerByName(const sead::SafeString& name, T** out_ptr, OrderParamType type, + u32* out_size = nullptr) const { + auto* ptr = getPointerByName(name, type, out_size); + if (!ptr) + return false; + *out_ptr = static_cast(ptr); + return true; + } + + template + T* tryAllocParam(const sead::SafeString& name, OrderParamType type, u32 size = 0) { + auto* ptr = getPointerByName(name, type); + if (ptr) + return nullptr; + + auto* entry = tryAlloc(type, size, name); + if (!entry || !entry->data) + return nullptr; + return static_cast(entry->data); + } + + sead::Heap* mHeap; + sead::Buffer mEntries; + u32 mEntryCount = 0; + bool mInitialized = false; +}; +} // namespace ksys::evt diff --git a/workflow.sh b/workflow.sh index 4f89dae9..8e0cee7b 100755 --- a/workflow.sh +++ b/workflow.sh @@ -6,7 +6,7 @@ # Diff a function (in this example, OrderParam::doAssign, -v is equivalent to --source in diff.py) # ./workflow.sh diff -v _ZN4ksys3evt10OrderParam13addParamActorEPNS_3act8BaseProcERN4sead14SafeStringBaseIcEE # Search for mangle name and diff (-f turns off interaction) -# ./workflow.sh mad -v -f _ZN4ksys3evt10OrderParam13addParamActorEPNS_3act8BaseProcERN4sead14SafeStringBaseIcEE +# ./workflow.sh mad -v -f orderparam::doassign # Get ready to pr # ./workflow.sh check