From e22ad6031caf955c9b494c4d0f3470531d38f197 Mon Sep 17 00:00:00 2001 From: Misha <106913236+MishaProductions@users.noreply.github.com> Date: Fri, 22 Dec 2023 14:03:55 -0500 Subject: [PATCH] More MxDiskStreamController functions (#350) * push code * remove accidently commited code * Update mxstreamcontroller.cpp * implement MxDiskStreamController::VTable0x30 * implement MxDiskStreamController::VTable0x28 * Update mxdiskstreamcontroller.cpp * FUN_100c7d10 & FUN_100c8360 * fix format * Match MxDiskStreamController::FUN_100c7980 * Improve match of MxDiskStreamController::VTable0x28 * Match MxDiskStreamController::FUN_100c7d10 * Minor style fix --------- Co-authored-by: Christian Semmler --- LEGO1/mxdiskstreamcontroller.cpp | 193 +++++++++++++++++++++++++++++-- LEGO1/mxdiskstreamcontroller.h | 10 +- LEGO1/mxdiskstreamprovider.cpp | 10 +- LEGO1/mxdiskstreamprovider.h | 5 +- LEGO1/mxdsbuffer.cpp | 6 +- LEGO1/mxdsbuffer.h | 8 +- LEGO1/mxdsstreamingaction.h | 3 + LEGO1/mxramstreamcontroller.cpp | 2 +- LEGO1/mxramstreamprovider.cpp | 2 +- LEGO1/mxramstreamprovider.h | 2 +- LEGO1/mxstreamcontroller.cpp | 5 +- LEGO1/mxstreamcontroller.h | 4 +- LEGO1/mxstreamlist.h | 12 ++ LEGO1/mxstreamprovider.h | 2 +- 14 files changed, 243 insertions(+), 21 deletions(-) diff --git a/LEGO1/mxdiskstreamcontroller.cpp b/LEGO1/mxdiskstreamcontroller.cpp index 489d1b74..9bb8fdf6 100644 --- a/LEGO1/mxdiskstreamcontroller.cpp +++ b/LEGO1/mxdiskstreamcontroller.cpp @@ -58,18 +58,134 @@ MxResult MxDiskStreamController::VTable0x34(undefined4) return FAILURE; } -// STUB: LEGO1 0x100c7ac0 -MxResult MxDiskStreamController::VTable0x28() +// FUNCTION: LEGO1 0x100c7980 +void MxDiskStreamController::FUN_100c7980() { - // TODO - return FAILURE; + MxDSBuffer* buffer; + MxDSStreamingAction* action = NULL; + + { + MxAutoLocker lock(&this->m_criticalSection); + + if (m_unk0x3c.size() && m_unk0x8c < m_provider->GetStreamBuffersNum()) { + buffer = new MxDSBuffer(); + + if (buffer->AllocateBuffer(m_provider->GetFileSize(), MxDSBufferType_Chunk) != SUCCESS) { + if (buffer) + delete buffer; + return; + } + + action = VTable0x28(); + if (!action) { + if (buffer) + delete buffer; + return; + } + + action->SetUnknowna0(buffer); + m_unk0x8c++; + } + } + + if (action) { + ((MxDiskStreamProvider*) m_provider)->FUN_100d1780(action); + } } -// STUB: LEGO1 0x100c7c00 +// FUNCTION: LEGO1 0x100c7ac0 +MxDSStreamingAction* MxDiskStreamController::VTable0x28() +{ + MxAutoLocker lock(&this->m_criticalSection); + MxDSAction* oldAction; + MxDSStreamingAction* result = NULL; + MxU32 filesize = m_provider->GetFileSize(); + + if (m_unk0x3c.PopFront(oldAction)) { + result = new MxDSStreamingAction((MxDSStreamingAction&) *oldAction); + if (result) { + MxU32 offset = result->GetBufferOffset() + filesize; + ((MxDSStreamingAction*) oldAction)->SetUnknown94(offset); + ((MxDSStreamingAction*) oldAction)->SetBufferOffset(offset); + m_unk0x3c.push_back(result); + } + } + + return result; +} + +// FUNCTION: LEGO1 0x100c7c00 MxResult MxDiskStreamController::VTable0x30(MxDSAction* p_action) +{ + MxAutoLocker lock(&this->m_criticalSection); + MxResult result = MxStreamController::VTable0x30(p_action); + + MxDSStreamingAction* item; + while (TRUE) { + item = (MxDSStreamingAction*) m_list0x90.Find(p_action, TRUE); + if (item == NULL) { + break; + } + FUN_100c7cb0(item); + } + + while (TRUE) { + item = (MxDSStreamingAction*) m_list0x64.Find(p_action, TRUE); + if (item == NULL) { + break; + } + FUN_100c7cb0(item); + } + + return result; +} + +// FUNCTION: LEGO1 0x100c7cb0 +void MxDiskStreamController::FUN_100c7cb0(MxDSStreamingAction* p_action) +{ + if (p_action->GetUnknowna0()) { + FUN_100c7ce0(p_action->GetUnknowna0()); + } + p_action->SetUnknowna0(NULL); + delete p_action; +} + +// FUNCTION: LEGO1 0x100c7ce0 +void MxDiskStreamController::FUN_100c7ce0(MxDSBuffer* p_buffer) +{ + switch (p_buffer->GetMode()) { + case MxDSBufferType_Chunk: + m_unk0x8c--; + case MxDSBufferType_Allocate: + case MxDSBufferType_Unknown: + delete p_buffer; + break; + } +} + +// FUNCTION: LEGO1 0x100c7d10 +MxResult MxDiskStreamController::FUN_100c7d10() +{ + MxAutoLocker lock(&this->m_criticalSection); + MxDSStreamingAction* action = FUN_100c7db0(); + + if (!action) + return FAILURE; + + if (FUN_100c8360(action) != SUCCESS) { + VTable0x24(action); + FUN_100c7cb0(action); + return FAILURE; + } + + return SUCCESS; +} + +// STUB: LEGO1 0x100c7db0 +MxDSStreamingAction* MxDiskStreamController::FUN_100c7db0() { // TODO - return FAILURE; + return NULL; } // FUNCTION: LEGO1 0x100c7f40 @@ -115,6 +231,37 @@ MxResult MxDiskStreamController::VTable0x24(MxDSAction* p_action) return FAILURE; } +// FUNCTION: LEGO1 0x100c8360 +MxResult MxDiskStreamController::FUN_100c8360(MxDSStreamingAction* p_action) +{ + MxAutoLocker lock(&this->m_criticalSection); + MxDSBuffer* buffer = p_action->GetUnknowna0(); + MxDSStreamingAction* action2 = (MxDSStreamingAction*) m_list0x90.Find(p_action, TRUE); + buffer->FUN_100c6f80(p_action->GetUnknown94() - p_action->GetBufferOffset()); + buffer->FUN_100c67b0(this, p_action, &action2); + + if (buffer->GetRefCount()) { + p_action->SetUnknowna0(NULL); + InsertToList74(buffer); + } + + if (action2) { + if (action2->GetUnknowna0() == NULL) { + FUN_100c7cb0(action2); + } + else { + if (action2->GetObjectId() == -1) { + action2->SetObjectId(p_action->GetObjectId()); + } + + m_list0x90.push_back(action2); + } + } + + FUN_100c7cb0(p_action); + return SUCCESS; +} + // FUNCTION: LEGO1 0x100c84a0 void MxDiskStreamController::InsertToList74(MxDSBuffer* p_buffer) { @@ -122,9 +269,39 @@ void MxDiskStreamController::InsertToList74(MxDSBuffer* p_buffer) m_list0x74.push_back(p_buffer); } -// STUB: LEGO1 0x100c8640 -MxResult MxDiskStreamController::Tickle() +// STUB: LEGO1 0x100c8540 +void MxDiskStreamController::FUN_100c8540() { // TODO +} + +// FUNCTION: LEGO1 0x100c8640 +MxResult MxDiskStreamController::Tickle() +{ + if (m_unk0xc4) { + FUN_100c7d10(); + } + + FUN_100c8540(); + FUN_100c8720(); + + if (m_unk0x70) { + FUN_100c7980(); + } + return SUCCESS; } + +// FUNCTION: LEGO1 0x100c8720 +void MxDiskStreamController::FUN_100c8720() +{ + MxAutoLocker lock(&this->m_critical9c); + + MxDSStreamingAction* action; + while (m_list0xb8.size() != 0) { + action = (MxDSStreamingAction*) m_list0xb8.front(); + m_list0xb8.pop_front(); + + FUN_100c7cb0(action); + } +} diff --git a/LEGO1/mxdiskstreamcontroller.h b/LEGO1/mxdiskstreamcontroller.h index 373e29a1..1d1cf7d5 100644 --- a/LEGO1/mxdiskstreamcontroller.h +++ b/LEGO1/mxdiskstreamcontroller.h @@ -22,7 +22,7 @@ public: virtual MxResult VTable0x18(undefined4, undefined4) override; // vtable+0x18 virtual MxResult VTable0x20(MxDSAction* p_action) override; // vtable+0x20 virtual MxResult VTable0x24(MxDSAction* p_action) override; // vtable+0x24 - virtual MxResult VTable0x28() override; // vtable+0x28 + virtual MxDSStreamingAction* VTable0x28() override; // vtable+0x28 virtual MxResult VTable0x30(MxDSAction* p_action) override; // vtable+0x30 virtual MxResult VTable0x34(undefined4); // vtable+0x34 @@ -50,8 +50,16 @@ private: MxStreamListMxDSAction m_list0xb8; // 0xb8 undefined m_unk0xc4; // 0xc4 + void FUN_100c7cb0(MxDSStreamingAction* p_action); + void FUN_100c7ce0(MxDSBuffer* p_buffer); + MxResult FUN_100c7d10(); + void FUN_100c7980(); + MxDSStreamingAction* FUN_100c7db0(); void FUN_100c7f40(MxDSStreamingAction* p_streamingaction); + MxResult FUN_100c8360(MxDSStreamingAction* p_action); void InsertToList74(MxDSBuffer* p_buffer); + void FUN_100c8540(); + void FUN_100c8720(); }; // TEMPLATE: LEGO1 0x100c7330 diff --git a/LEGO1/mxdiskstreamprovider.cpp b/LEGO1/mxdiskstreamprovider.cpp index e4f8c2a1..dfdf8158 100644 --- a/LEGO1/mxdiskstreamprovider.cpp +++ b/LEGO1/mxdiskstreamprovider.cpp @@ -1,5 +1,6 @@ #include "mxdiskstreamprovider.h" +#include "mxdsbuffer.h" #include "mxomni.h" #include "mxstreamcontroller.h" #include "mxstring.h" @@ -87,6 +88,13 @@ MxResult MxDiskStreamProvider::WaitForWorkToComplete() return SUCCESS; } +// STUB: LEGO1 0x100d1780 +MxResult MxDiskStreamProvider::FUN_100d1780(MxDSStreamingAction* p_action) +{ + // TODO + return FAILURE; +} + // STUB: LEGO1 0x100d18f0 void MxDiskStreamProvider::PerformWork() { @@ -100,7 +108,7 @@ MxU32 MxDiskStreamProvider::GetFileSize() } // FUNCTION: LEGO1 0x100d1ea0 -MxU32 MxDiskStreamProvider::GetStreamBuffersNum() +MxS32 MxDiskStreamProvider::GetStreamBuffersNum() { return m_pFile->GetStreamBuffersNum(); } diff --git a/LEGO1/mxdiskstreamprovider.h b/LEGO1/mxdiskstreamprovider.h index 20b78f81..b5a2e9ff 100644 --- a/LEGO1/mxdiskstreamprovider.h +++ b/LEGO1/mxdiskstreamprovider.h @@ -10,6 +10,7 @@ #include "mxthread.h" class MxDiskStreamProvider; +class MxDSStreamingAction; // VTABLE: LEGO1 0x100dd130 class MxDiskStreamProviderThread : public MxThread { @@ -43,12 +44,12 @@ public: } MxResult WaitForWorkToComplete(); - + MxResult FUN_100d1780(MxDSStreamingAction* p_action); void PerformWork(); virtual MxResult SetResourceToGet(MxStreamController* p_resource) override; // vtable+0x14 virtual MxU32 GetFileSize() override; // vtable+0x18 - virtual MxU32 GetStreamBuffersNum() override; // vtable+0x1c + virtual MxS32 GetStreamBuffersNum() override; // vtable+0x1c virtual void VTable0x20(undefined4) override; // vtable+0x20 virtual MxU32 GetLengthInDWords() override; // vtable+0x24 virtual MxU32* GetBufferForDWords() override; // vtable+0x28 diff --git a/LEGO1/mxdsbuffer.cpp b/LEGO1/mxdsbuffer.cpp index 501cefd6..634afc6e 100644 --- a/LEGO1/mxdsbuffer.cpp +++ b/LEGO1/mxdsbuffer.cpp @@ -123,7 +123,11 @@ MxResult MxDSBuffer::SetBufferPointer(MxU32* p_buffer, MxU32 p_size) } // STUB: LEGO1 0x100c67b0 -MxResult MxDSBuffer::FUN_100c67b0(MxStreamController* p_controller, MxDSAction* p_action, undefined4*) +MxResult MxDSBuffer::FUN_100c67b0( + MxStreamController* p_controller, + MxDSAction* p_action, + MxDSStreamingAction** p_streamingAction +) { // TODO STUB return FAILURE; diff --git a/LEGO1/mxdsbuffer.h b/LEGO1/mxdsbuffer.h index af9b466f..d8532a55 100644 --- a/LEGO1/mxdsbuffer.h +++ b/LEGO1/mxdsbuffer.h @@ -33,7 +33,11 @@ public: MxResult AllocateBuffer(MxU32 p_bufferSize, MxDSBufferType p_mode); MxResult SetBufferPointer(MxU32* p_buffer, MxU32 p_size); - MxResult FUN_100c67b0(MxStreamController* p_controller, MxDSAction* p_action, undefined4*); + MxResult FUN_100c67b0( + MxStreamController* p_controller, + MxDSAction* p_action, + MxDSStreamingAction** p_streamingAction + ); MxResult CreateObject( MxStreamController* p_controller, MxU32* p_data, @@ -55,6 +59,8 @@ public: inline MxU8* GetBuffer() { return m_pBuffer; } inline MxU32 GetWriteOffset() { return m_writeOffset; } + inline MxU16 GetRefCount() { return m_refcount; } + inline MxDSBufferType GetMode() { return m_mode; } private: MxU8* m_pBuffer; // 0x08 diff --git a/LEGO1/mxdsstreamingaction.h b/LEGO1/mxdsstreamingaction.h index 49c2d74f..5b764c8f 100644 --- a/LEGO1/mxdsstreamingaction.h +++ b/LEGO1/mxdsstreamingaction.h @@ -35,7 +35,10 @@ public: inline MxDSBuffer* GetUnknowna0() { return m_unk0xa0; } inline MxDSBuffer* GetUnknowna4() { return m_unk0xa4; } inline MxDSAction* GetInternalAction() { return m_internalAction; } + inline MxU32 GetBufferOffset() { return m_bufferOffset; } + inline void SetUnknown94(MxU32 p_unk0x94) { m_unk0x94 = p_unk0x94; } inline void SetUnknowna0(MxDSBuffer* p_unk0xa0) { m_unk0xa0 = p_unk0xa0; } + inline void SetBufferOffset(MxU32 p_bufferOffset) { m_bufferOffset = p_bufferOffset; } private: MxU32 m_unk0x94; diff --git a/LEGO1/mxramstreamcontroller.cpp b/LEGO1/mxramstreamcontroller.cpp index 24c5a79d..930ca4ce 100644 --- a/LEGO1/mxramstreamcontroller.cpp +++ b/LEGO1/mxramstreamcontroller.cpp @@ -84,7 +84,7 @@ MxResult MxRAMStreamController::DeserializeObject(MxDSStreamingAction& p_action) { MxAutoLocker locker(&m_criticalSection); MxResult result; - undefined4 value = 0; + MxDSStreamingAction* value = NULL; do { m_buffer.FUN_100c6f80(p_action.GetUnknown94()); result = m_buffer.FUN_100c67b0(this, &p_action, &value); diff --git a/LEGO1/mxramstreamprovider.cpp b/LEGO1/mxramstreamprovider.cpp index 016bcc8d..9c52c20e 100644 --- a/LEGO1/mxramstreamprovider.cpp +++ b/LEGO1/mxramstreamprovider.cpp @@ -23,7 +23,7 @@ MxU32 MxRAMStreamProvider::GetFileSize() } // FUNCTION: LEGO1 0x100d0940 -MxU32 MxRAMStreamProvider::GetStreamBuffersNum() +MxS32 MxRAMStreamProvider::GetStreamBuffersNum() { return 1; } diff --git a/LEGO1/mxramstreamprovider.h b/LEGO1/mxramstreamprovider.h index 70402a8f..112f6b71 100644 --- a/LEGO1/mxramstreamprovider.h +++ b/LEGO1/mxramstreamprovider.h @@ -24,7 +24,7 @@ public: virtual MxResult SetResourceToGet(MxStreamController* p_resource) override; // vtable+0x14 virtual MxU32 GetFileSize() override; // vtable+0x18 - virtual MxU32 GetStreamBuffersNum() override; // vtable+0x1c + virtual MxS32 GetStreamBuffersNum() override; // vtable+0x1c virtual MxU32 GetLengthInDWords() override; // vtable+0x24 virtual MxU32* GetBufferForDWords() override; // vtable+0x28 diff --git a/LEGO1/mxstreamcontroller.cpp b/LEGO1/mxstreamcontroller.cpp index e882898b..c6aa8996 100644 --- a/LEGO1/mxstreamcontroller.cpp +++ b/LEGO1/mxstreamcontroller.cpp @@ -2,6 +2,7 @@ #include "legoomni.h" #include "mxautolocker.h" +#include "mxdsstreamingaction.h" #include "mxnextactiondatastart.h" #include "mxstreamchunk.h" @@ -21,9 +22,9 @@ MxResult MxStreamController::VTable0x1c(undefined4, undefined4) } // FUNCTION: LEGO1 0x100b9420 -MxResult MxStreamController::VTable0x28() +MxDSStreamingAction* MxStreamController::VTable0x28() { - return SUCCESS; + return NULL; } // FUNCTION: LEGO1 0x100c0b90 diff --git a/LEGO1/mxstreamcontroller.h b/LEGO1/mxstreamcontroller.h index 50259226..468782b1 100644 --- a/LEGO1/mxstreamcontroller.h +++ b/LEGO1/mxstreamcontroller.h @@ -11,6 +11,8 @@ #include "mxstreamlist.h" #include "mxstreamprovider.h" +class MxDSStreamingAction; + // VTABLE: LEGO1 0x100dc968 // SIZE 0x64 class MxStreamController : public MxCore { @@ -37,7 +39,7 @@ public: virtual MxResult VTable0x1c(undefined4, undefined4); // vtable+0x1c virtual MxResult VTable0x20(MxDSAction* p_action); // vtable+0x20 virtual MxResult VTable0x24(MxDSAction* p_action); // vtable+0x24 - virtual MxResult VTable0x28(); // vtable+0x28 + virtual MxDSStreamingAction* VTable0x28(); // vtable+0x28 virtual MxResult VTable0x2c(MxDSAction* p_action, MxU32 p_bufferval); // vtable+0x2c virtual MxResult VTable0x30(MxDSAction* p_action); // vtable+0x30 diff --git a/LEGO1/mxstreamlist.h b/LEGO1/mxstreamlist.h index 2a9e7351..abe48779 100644 --- a/LEGO1/mxstreamlist.h +++ b/LEGO1/mxstreamlist.h @@ -13,6 +13,18 @@ class MxStreamList : public list {}; class MxStreamListMxDSAction : public MxStreamList { public: MxDSAction* Find(MxDSAction* p_action, MxBool p_delete); + + // Could move this to MxStreamList + MxBool PopFront(MxDSAction*& p_obj) + { + if (!empty()) { + p_obj = front(); + pop_front(); + return TRUE; + } + + return FALSE; + } }; // SIZE 0xc diff --git a/LEGO1/mxstreamprovider.h b/LEGO1/mxstreamprovider.h index d32d2ab4..66f75be2 100644 --- a/LEGO1/mxstreamprovider.h +++ b/LEGO1/mxstreamprovider.h @@ -27,7 +27,7 @@ public: virtual MxResult SetResourceToGet(MxStreamController* p_resource); // vtable+0x14 virtual MxU32 GetFileSize() = 0; // vtable+0x18 - virtual MxU32 GetStreamBuffersNum() = 0; // vtable+0x1c + virtual MxS32 GetStreamBuffersNum() = 0; // vtable+0x1c virtual void VTable0x20(undefined4); // vtable+0x20 virtual MxU32 GetLengthInDWords() = 0; // vtable+0x24 virtual MxU32* GetBufferForDWords() = 0; // vtable+0x28