From 85430d323270b83aff1e91837cd716733adce002 Mon Sep 17 00:00:00 2001 From: iTNTPiston Date: Thu, 4 Feb 2021 03:59:38 -0500 Subject: [PATCH] ksys/evt: Start adding OrderParam --- data/uking_functions.csv | 18 +-- src/KingSystem/Event/CMakeLists.txt | 2 + src/KingSystem/Event/evtEvent.cpp | 7 + src/KingSystem/Event/evtEvent.h | 2 + src/KingSystem/Event/evtManager.h | 2 + src/KingSystem/Event/evtOrderParam.cpp | 173 +++++++++++++++++++++++++ src/KingSystem/Event/evtOrderParam.h | 92 +++++++++++++ 7 files changed, 287 insertions(+), 9 deletions(-) create mode 100644 src/KingSystem/Event/evtOrderParam.cpp create mode 100644 src/KingSystem/Event/evtOrderParam.h diff --git a/data/uking_functions.csv b/data/uking_functions.csv index 2d4350f2..cd616398 100644 --- a/data/uking_functions.csv +++ b/data/uking_functions.csv @@ -75586,19 +75586,19 @@ 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, +0x0000007100db4808,ksys::evt::OrderParam::dtor,20, +0x0000007100db481c,ksys::evt::OrderParam::uninitialize,284,_ZN4ksys3evt10OrderParam12uninitializeEv +0x0000007100db4938,ksys::evt::OrderParam::dtorDelete,52, 0x0000007100db496c,ksys::evt::OrderParam::doAssign,1160, 0x0000007100db4df4,ksys::evt::OrderParam::assign,48, -0x0000007100db4e24,ksys::evt::OrderParam::initialize,332, +0x0000007100db4e24,ksys::evt::OrderParam::initialize,332,_ZN4ksys3evt10OrderParam10initializeEi? 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, +0x0000007100db51e8,ksys::evt::OrderParam::tryAlloc_,944,_ZN4ksys3evt10OrderParam8tryAllocENS0_14OrderParamTypeEjRN4sead14SafeStringBaseIcEE? +0x0000007100db5598,ksys::evt::OrderParam::addParamActor,240,_ZN4ksys3evt10OrderParam13addParamActorERNS_3act8BaseProcERN4sead14SafeStringBaseIcEE? +0x0000007100db5688,ksys::evt::OrderParam::getIntByName,176,_ZN4ksys3evt10OrderParam12getIntByNameERKN4sead14SafeStringBaseIcEEPPj? +0x0000007100db5738,ksys::evt::OrderParam::getStringByName,176,_ZN4ksys3evt10OrderParam15getStringByNameERKN4sead14SafeStringBaseIcEEPPS4_? +0x0000007100db57e8,ksys::evt::OrderParam::getArrayByName,208,_ZN4ksys3evt10OrderParam14getArrayByNameERKN4sead14SafeStringBaseIcEEPPvPj? 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..cbf71639 --- /dev/null +++ b/src/KingSystem/Event/evtOrderParam.cpp @@ -0,0 +1,173 @@ +#include "KingSystem/Event/evtOrderParam.h" +#include +#include +#include +#include +#include +#include "KingSystem/ActorSystem/actBaseProcLink.h" + +namespace ksys::evt { + +OrderParam::OrderParam(sead::ExpHeap* heap) { + mHeap = heap; +} + +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 == 0) + return true; + if (!mHeap) + return false; + if (entry_count < 1) + return false; + if (!mEntries.tryAllocBuffer(entry_count, mHeap)) + return false; + + // I think compiler is unrolling this loop + for (s32 i = 0; i != mEntries.size(); ++i) { + clearEntry(&mEntries[i]); + } + mEntryCount = 0; + mInitialized = true; + return true; +} + +void OrderParam::uninitialize() { + for (s32 i = 0; i < mEntries.size(); i++) { + auto* e = &mEntries[i]; + auto* name_ptr = e->mName; + if (name_ptr) + delete (sead::FixedSafeString<0x20>*)name_ptr; + auto* ptr = e->mPointer; + if (ptr) { + switch (e->mType) { + case OrderParamType::STRING: + delete (sead::FixedSafeString<0x40>*)ptr; + break; + case OrderParamType::INT: + case OrderParamType::INT_2: + delete (u32*)ptr; + break; + case OrderParamType::BYTE: + delete (char*)ptr; + break; + case OrderParamType::ACTOR: + delete (ksys::act::BaseProcLink*)ptr; + break; + case OrderParamType::ARRAY: + mHeap->free(ptr); + break; + default: + break; + } + } + clearEntry(e); + } + mEntries.freeBuffer(); + mEntryCount = 0; + mInitialized = false; +} + +// half done +void OrderParam::addParamActor(ksys::act::BaseProc& actor, sead::SafeString& name) { + u32 hash = sead::HashCRC32::calcStringHash(name.cstr()); + s32 i; + for (i = 0; i < mEntries.size(); i++) { + if (mEntries[i].mHash == hash && mEntries[i].mType == OrderParamType::ACTOR) { + if (!mEntries[i].mPointer) { + break; + } + } + } + + auto* entry = tryAlloc(OrderParamType::ACTOR, 0, name); + if (entry) { + auto* actor_ptr = (ksys::act::BaseProcLink*)entry->mPointer; + if (actor_ptr->acquire(&actor, false)) { + ++this->mEntryCount; + } + } +} +// The three below have 1 pair of instructions swapped + +bool OrderParam::getIntByName(const sead::SafeString& name, u32** out_ptr) { + return tryGetPointerByName(name, (void**)out_ptr, nullptr, OrderParamType::INT); +} + +bool OrderParam::getStringByName(const sead::SafeString& name, sead::SafeString** out_ptr) { + return tryGetPointerByName(name, (void**)out_ptr, nullptr, OrderParamType::STRING); +} + +bool OrderParam::getArrayByName(const sead::SafeString& name, void** out_ptr, u32* out_size) { + return tryGetPointerByName(name, out_ptr, out_size, OrderParamType::ARRAY); +} + +// This one also does not match +OrderParamEntry* OrderParam::tryAlloc(OrderParamType type, u32 size, sead::SafeString& name) { + sead::FixedSafeString<0x100> error_message; + + error_message.format("[%s] tryAlloc_(%d, %d, %s) is failed.", "ksys::evt::OrderParam", type, + size, name.cstr()); + + for (s32 i = 0; i < mEntries.size(); i++) { + auto* e = &mEntries[i]; + + if (!e->mPointer) { + void** in_ptr = &(e->mPointer); + std::nothrow_t nothrow_t; + auto* heap = mHeap; + if (!heap) + return nullptr; + + e->mName = new (heap, nothrow_t) sead::FixedSafeString<0x20>(name); + switch (type) { + case OrderParamType::STRING: + *in_ptr = new (heap, nothrow_t) sead::FixedSafeString<0x40>; + size = sizeof(sead::FixedSafeString<0x40>); + break; + case OrderParamType::INT: + case OrderParamType::INT_2: + *in_ptr = new (heap, nothrow_t) u32(0); + size = sizeof(u32); + break; + + case OrderParamType::BYTE: + *in_ptr = new (heap, nothrow_t) char(0); + size = sizeof(char); + break; + case OrderParamType::ACTOR: + *in_ptr = new (heap, nothrow_t) ksys::act::BaseProcLink; + size = sizeof(ksys::act::BaseProcLink); + break; + case OrderParamType::ARRAY: + *in_ptr = new (heap, nothrow_t) char[size]; + default: + break; + } + e->mSize = size; + if (e->mPointer) { + e->mHash = sead::HashCRC32::calcStringHash(e->mName->cstr()); + e->mType = type; + return e; + } + if (e->mName) + delete e->mName; + // clearEntry(e); + *e = {}; + return nullptr; + // auto* entry = mAllocArray+i; + // if (*in_ptr) { + + //} else { + + //} + } + } + + return nullptr; +} + +} // namespace ksys::evt \ No newline at end of file diff --git a/src/KingSystem/Event/evtOrderParam.h b/src/KingSystem/Event/evtOrderParam.h new file mode 100644 index 00000000..0fc07e74 --- /dev/null +++ b/src/KingSystem/Event/evtOrderParam.h @@ -0,0 +1,92 @@ +#pragma once + +#include +#include +#include +#include +#include "KingSystem/ActorSystem/actBaseProc.h" + +namespace ksys::evt { + +enum class OrderParamType : u16 { + INVALID = 0, + INT = 1, + INT_2 = 2, + STRING = 3, + BYTE = 4, + ACTOR = 5, + ARRAY = 6 + +}; + +struct OrderParamEntry { + u32 mHash = 0; + // u32 _4; alignment gap + sead::SafeString* mName = nullptr; + void* mPointer = nullptr; //_10 + u32 mSize = 0; //_18 + OrderParamType mType = OrderParamType::INVALID; + // u16 _1e; alignment gap +}; + +class OrderParam { + OrderParam(sead::ExpHeap* mHeap); + virtual ~OrderParam(); + +public: + bool initialize(s32 entry_count); + void uninitialize(); + + bool addParamInt(s32 val, const sead::SafeString& key); + void addParamActor(ksys::act::BaseProc& actor, sead::SafeString& name); + OrderParamEntry* tryAlloc(OrderParamType type, u32 size, sead::SafeString& name); + bool getIntByName(const sead::SafeString& name, u32** out_ptr); + bool getStringByName(const sead::SafeString& name, sead::SafeString** out_ptr); + bool getArrayByName(const sead::SafeString& name, void** out_ptr, u32* out_size); + +private: + inline void* getPointerByName(const sead::SafeString& name, OrderParamType type) { + u32 hash = sead::HashCRC32::calcStringHash(name.cstr()); + s32 i; + for (i = 0; i < mEntries.size(); i++) { + if (mEntries[i].mHash == hash && mEntries[i].mType == type) { + return mEntries[i].mPointer; + } + } + return nullptr; + } + inline bool tryGetPointerByName(const sead::SafeString& name, void** out_ptr, u32* out_size, + OrderParamType type) { + u32 hash = sead::HashCRC32::calcStringHash(name.cstr()); + s32 i; + for (i = 0; i < mEntries.size(); i++) { + if (mEntries[i].mHash == hash && mEntries[i].mType == type) { + if (out_size) { + *out_size = mEntries[i].mSize; + } + return tryGetPointer(i, out_ptr); + } + } + return false; + } + inline bool tryGetPointer(s32 i, void** out_ptr) { + auto* ptr = mEntries[i].mPointer; + if (ptr) { + *out_ptr = ptr; // minor diff with scheduling + return true; + } + return false; + } + inline void clearEntry(OrderParamEntry* e) { + e->mHash = 0; + e->mSize = 0; + e->mType = OrderParamType::INVALID; + e->mName = nullptr; + e->mPointer = nullptr; + } + sead::ExpHeap* mHeap; + sead::Buffer mEntries; + u32 mEntryCount = 0; + bool mInitialized = false; +}; +} // namespace ksys::evt \ No newline at end of file