From cb8c143ce50c147ff5bdcb67aa64a3e77a6560bf Mon Sep 17 00:00:00 2001 From: Misha <106913236+MishaProductions@users.noreply.github.com> Date: Mon, 25 Dec 2023 13:32:01 -0500 Subject: [PATCH] Finish MxDiskStreamController methods (#359) * more mxdiskstreamcontroller methods * further debugging and fixes * add more functions * Update mxdiskstreamprovider.cpp * fix build * implement MxDiskStreamProvider::PerformWork * Update mxdiskstreamprovider.cpp * Update mxdiskstreamprovider.cpp * Update mxdssource.h * remove debug prints * Update mxdiskstreamprovider.cpp * Mostly match MxDiskStreamController::FUN_100c8540 * Mostly match MxDiskStreamProvider::FUN_100d1780 * Mostly match MxDiskStreamProvider::PerformWork * Fixes * Retype some members * Various annotations --------- Co-authored-by: Christian Semmler --- LEGO1/legosoundmanager.cpp | 2 +- LEGO1/mxcriticalsection.h | 4 +- LEGO1/mxdiskstreamcontroller.cpp | 107 ++++++++++++++++++++++++-- LEGO1/mxdiskstreamcontroller.h | 10 ++- LEGO1/mxdiskstreamprovider.cpp | 127 ++++++++++++++++++++++++++++--- LEGO1/mxdiskstreamprovider.h | 11 +-- LEGO1/mxdsbuffer.cpp | 6 +- LEGO1/mxdsbuffer.h | 7 +- LEGO1/mxdssource.cpp | 6 +- LEGO1/mxdssource.h | 26 ++++--- LEGO1/mxdsstreamingaction.h | 2 + LEGO1/mxnextactiondatastart.h | 8 +- LEGO1/mxsemaphore.cpp | 4 + LEGO1/mxsemaphore.h | 3 +- LEGO1/mxstreamcontroller.cpp | 1 + LEGO1/mxstreamcontroller.h | 1 + LEGO1/mxstreamlist.h | 14 +++- LEGO1/mxstreamprovider.h | 4 +- LEGO1/mxthread.cpp | 4 + LEGO1/mxthread.h | 18 ++--- 20 files changed, 301 insertions(+), 64 deletions(-) diff --git a/LEGO1/legosoundmanager.cpp b/LEGO1/legosoundmanager.cpp index a74ca419..8b8376fa 100644 --- a/LEGO1/legosoundmanager.cpp +++ b/LEGO1/legosoundmanager.cpp @@ -29,7 +29,7 @@ void LegoSoundManager::Destroy(MxBool p_fromDestructor) // STUB: LEGO1 0x100299f0 MxResult LegoSoundManager::Create(MxU32 p_frequencyMS, MxBool p_createThread) { - return FAILURE; + return SUCCESS; } // FUNCTION: LEGO1 0x1002a390 diff --git a/LEGO1/mxcriticalsection.h b/LEGO1/mxcriticalsection.h index 8756853c..8c5f77d6 100644 --- a/LEGO1/mxcriticalsection.h +++ b/LEGO1/mxcriticalsection.h @@ -13,8 +13,8 @@ public: void Leave(); private: - CRITICAL_SECTION m_criticalSection; - HANDLE m_mutex; + CRITICAL_SECTION m_criticalSection; // 0x00 + HANDLE m_mutex; // 0x18 }; #endif // MXCRITICALSECTION_H diff --git a/LEGO1/mxdiskstreamcontroller.cpp b/LEGO1/mxdiskstreamcontroller.cpp index 71ebc827..1520ba3b 100644 --- a/LEGO1/mxdiskstreamcontroller.cpp +++ b/LEGO1/mxdiskstreamcontroller.cpp @@ -1,5 +1,6 @@ #include "mxdiskstreamcontroller.h" +#include "mxactionnotificationparam.h" #include "mxautolocker.h" #include "mxdiskstreamprovider.h" #include "mxdsstreamingaction.h" @@ -52,12 +53,31 @@ MxResult MxDiskStreamController::VTable0x18(undefined4, undefined4) return SUCCESS; } +// FUNCTION: LEGO1 0x100c7890 +MxResult MxDiskStreamController::FUN_100c7890(MxDSStreamingAction* p_action) +{ + MxAutoLocker lock(&this->m_criticalSection); + if (p_action == NULL) { + return FAILURE; + } + + m_list0x80.push_back(p_action); + FUN_100c7970(); + return SUCCESS; +} + // FUNCTION: LEGO1 0x100c7960 MxResult MxDiskStreamController::VTable0x34(undefined4) { return FAILURE; } +// FUNCTION: LEGO1 0x100c7970 +void MxDiskStreamController::FUN_100c7970() +{ + // Empty +} + // FUNCTION: LEGO1 0x100c7980 void MxDiskStreamController::FUN_100c7980() { @@ -181,10 +201,29 @@ MxResult MxDiskStreamController::FUN_100c7d10() return SUCCESS; } -// STUB: LEGO1 0x100c7db0 +// FUNCTION: LEGO1 0x100c7db0 MxDSStreamingAction* MxDiskStreamController::FUN_100c7db0() { - // TODO + MxAutoLocker lock(&this->m_criticalSection); + + for (MxStreamListMxNextActionDataStart::iterator it = m_nextActionList.begin(); it != m_nextActionList.end(); + it++) { + MxNextActionDataStart* data = *it; + for (MxStreamListMxDSAction::iterator it2 = m_list0x64.begin(); it2 != m_list0x64.end(); it2++) { + MxDSStreamingAction* streamingAction = (MxDSStreamingAction*) *it2; + if (streamingAction->GetObjectId() == data->GetObjectId() && + streamingAction->GetUnknown24() == data->GetUnknown24() && + streamingAction->GetBufferOffset() == data->GetData()) { + m_nextActionList.erase(it); + + data->SetData(m_provider->GetFileSize() + data->GetData()); + m_nextActionList.push_back(data); + + m_list0x64.erase(it2); + return streamingAction; + } + } + } return NULL; } @@ -203,7 +242,6 @@ MxResult MxDiskStreamController::VTable0x20(MxDSAction* p_action) MxAutoLocker lock(&this->m_criticalSection); MxDSStreamingAction* entry = (MxDSStreamingAction*) m_list0x80.Find(p_action, FALSE); // TODO: is this a seperate class? - if (entry) { MxDSStreamingAction* action = new MxDSStreamingAction(*p_action, 0); action->SetUnknown28(entry->GetUnknown28()); @@ -224,11 +262,39 @@ MxResult MxDiskStreamController::VTable0x20(MxDSAction* p_action) return SUCCESS; } -// STUB: LEGO1 0x100c8160 +// FUNCTION: LEGO1 0x100c8160 MxResult MxDiskStreamController::VTable0x24(MxDSAction* p_action) { - // TODO - return FAILURE; + MxAutoLocker lock(&this->m_criticalSection); + if (m_unk0x54.Find(p_action, FALSE) == NULL) { + if (VTable0x30(p_action) == SUCCESS) { + MxOmni::GetInstance()->NotifyCurrentEntity( + &MxEndActionNotificationParam(c_notificationEndAction, NULL, p_action, TRUE) + ); + } + } + + MxDSAction action; + if (m_provider) { + m_provider->VTable0x20(p_action); + } + + do { + if (m_action0x60 != NULL) { + delete m_action0x60; + m_action0x60 = NULL; + } + + action = *p_action; + MxStreamController::VTable0x24(&action); + } while (m_action0x60 != NULL); + + if (m_unk0x3c.size() == 0) { + m_unk0x70 = 0; + m_unk0xc4 = 0; + } + + return SUCCESS; } // FUNCTION: LEGO1 0x100c8360 @@ -269,10 +335,28 @@ void MxDiskStreamController::InsertToList74(MxDSBuffer* p_buffer) m_list0x74.push_back(p_buffer); } -// STUB: LEGO1 0x100c8540 +// FUNCTION: LEGO1 0x100c8540 void MxDiskStreamController::FUN_100c8540() { - // TODO + MxAutoLocker lock(&this->m_criticalSection); + for (list::iterator it = m_list0x74.begin(); it != m_list0x74.end();) { + MxDSBuffer* buf = *it; + // TODO: Match + if (buf->GetRefCount() == 0) { + m_list0x74.erase(it++); + FUN_100c7ce0(buf); + } + else + it++; + } + + if (m_nextActionList.empty()) { + while (!m_list0x64.empty()) { + MxDSStreamingAction* action = (MxDSStreamingAction*) m_list0x64.front(); + m_list0x64.pop_front(); + FUN_100c7cb0(action); + } + } } // FUNCTION: LEGO1 0x100c8640 @@ -292,6 +376,13 @@ MxResult MxDiskStreamController::Tickle() return SUCCESS; } +// FUNCTION: LEGO1 0x100c8670 +void MxDiskStreamController::FUN_100c8670(MxDSStreamingAction* p_streamingAction) +{ + MxAutoLocker lock(&this->m_critical9c); + m_list0xb8.push_back(p_streamingAction); +} + // FUNCTION: LEGO1 0x100c8720 void MxDiskStreamController::FUN_100c8720() { diff --git a/LEGO1/mxdiskstreamcontroller.h b/LEGO1/mxdiskstreamcontroller.h index 1d1cf7d5..28966d9d 100644 --- a/LEGO1/mxdiskstreamcontroller.h +++ b/LEGO1/mxdiskstreamcontroller.h @@ -39,6 +39,11 @@ public: return !strcmp(p_name, MxDiskStreamController::ClassName()) || MxStreamController::IsA(p_name); } + inline MxBool GetUnk0xc4() const { return m_unk0xc4; } + + void FUN_100c7f40(MxDSStreamingAction* p_streamingaction); + void FUN_100c8670(MxDSStreamingAction* p_streamingAction); + private: MxStreamListMxDSAction m_list0x64; // 0x64 undefined m_unk0x70; // 0x70 @@ -48,14 +53,15 @@ private: MxStreamListMxDSAction m_list0x90; // 0x90 MxCriticalSection m_critical9c; // 0x9c MxStreamListMxDSAction m_list0xb8; // 0xb8 - undefined m_unk0xc4; // 0xc4 + MxBool m_unk0xc4; // 0xc4 + MxResult FUN_100c7890(MxDSStreamingAction* p_action); + void FUN_100c7970(); 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(); diff --git a/LEGO1/mxdiskstreamprovider.cpp b/LEGO1/mxdiskstreamprovider.cpp index a8d15984..c7e311eb 100644 --- a/LEGO1/mxdiskstreamprovider.cpp +++ b/LEGO1/mxdiskstreamprovider.cpp @@ -1,13 +1,20 @@ #include "mxdiskstreamprovider.h" +#include "mxautolocker.h" +#include "mxdiskstreamcontroller.h" #include "mxdsbuffer.h" +#include "mxdsstreamingaction.h" #include "mxomni.h" #include "mxstreamcontroller.h" #include "mxstring.h" #include "mxthread.h" +DECOMP_SIZE_ASSERT(MxDiskStreamProviderThread, 0x1c) DECOMP_SIZE_ASSERT(MxDiskStreamProvider, 0x60); +// GLOBAL: LEGO1 0x10102878 +MxU32 g_unk0x10102878 = 0; + // FUNCTION: LEGO1 0x100d0f30 MxResult MxDiskStreamProviderThread::Run() { @@ -29,8 +36,8 @@ MxResult MxDiskStreamProviderThread::StartWithTarget(MxDiskStreamProvider* p_tar MxDiskStreamProvider::MxDiskStreamProvider() { this->m_pFile = NULL; - this->m_remainingWork = 0; - this->m_unk0x35 = 0; + this->m_remainingWork = FALSE; + this->m_unk0x35 = FALSE; } // STUB: LEGO1 0x100d1240 @@ -58,7 +65,7 @@ MxResult MxDiskStreamProvider::SetResourceToGet(MxStreamController* p_resource) goto done; } - m_remainingWork = 1; + m_remainingWork = TRUE; m_busySemaphore.Init(0, 100); if (m_thread.StartWithTarget(this) == SUCCESS && p_resource != NULL) { @@ -79,25 +86,125 @@ void MxDiskStreamProvider::VTable0x20(MxDSAction* p_action) // FUNCTION: LEGO1 0x100d1750 MxResult MxDiskStreamProvider::WaitForWorkToComplete() { - while (m_remainingWork != 0) { + while (m_remainingWork) { m_busySemaphore.Wait(INFINITE); - if (m_unk0x35 != 0) + if (m_unk0x35) PerformWork(); } + return SUCCESS; } -// STUB: LEGO1 0x100d1780 +// FUNCTION: LEGO1 0x100d1780 MxResult MxDiskStreamProvider::FUN_100d1780(MxDSStreamingAction* p_action) { - // TODO - return FAILURE; + if (!m_remainingWork) + return FAILURE; + + if (p_action->GetUnknown9c() > 0 && !p_action->GetUnknowna0()) { + MxDSBuffer* buffer = new MxDSBuffer(); + + if (!buffer) + return FAILURE; + + if (buffer->AllocateBuffer(GetFileSize(), MxDSBufferType_Allocate) != SUCCESS) { + delete buffer; + return FAILURE; + } + + p_action->SetUnknowna0(buffer); + } + + if (p_action->GetUnknowna0()->GetWriteOffset() < 0x20000) { + g_unk0x10102878++; + } + + { + MxAutoLocker lock(&m_criticalSection); + m_list.push_back(p_action); + } + + m_unk0x35 = TRUE; + m_busySemaphore.Release(1); + return SUCCESS; } -// STUB: LEGO1 0x100d18f0 +// FUNCTION: LEGO1 0x100d18f0 void MxDiskStreamProvider::PerformWork() { - // TODO + MxDiskStreamController* controller = (MxDiskStreamController*) m_pLookup; + MxDSStreamingAction* streamingAction = NULL; + + { + MxAutoLocker lock(&m_criticalSection); + if (!m_list.empty()) { + streamingAction = (MxDSStreamingAction*) m_list.front(); + + if (streamingAction && !FUN_100d1af0(streamingAction)) { + m_thread.Sleep(500); + m_busySemaphore.Release(1); + return; + } + } + } + + { + MxAutoLocker lock(&m_criticalSection); + + if (!m_list.PopFrontStreamingAction(streamingAction)) + return; + } + + if (streamingAction->GetUnknowna0()->GetWriteOffset() < 0x20000) { + g_unk0x10102878--; + } + + MxDSBuffer* buffer = streamingAction->GetUnknowna0(); + + if (m_pFile->GetPosition() == streamingAction->GetBufferOffset() || + m_pFile->Seek(streamingAction->GetBufferOffset(), 0) == 0) { + buffer->SetUnknown14(m_pFile->GetPosition()); + + if (m_pFile->ReadToBuffer(buffer) == SUCCESS) { + buffer->SetUnknown1c(m_pFile->GetPosition()); + + if (streamingAction->GetUnknown9c() > 0) { + FUN_100d1b20(streamingAction); + } + else { + if (m_pLookup == NULL || !((MxDiskStreamController*) m_pLookup)->GetUnk0xc4()) { + controller->FUN_100c8670(streamingAction); + } + else { + controller->FUN_100c7f40(streamingAction); + } + } + + streamingAction = NULL; + } + } + + if (streamingAction) { + controller->FUN_100c8670(streamingAction); + } + + m_thread.Sleep(0); +} + +// FUNCTION: LEGO1 0x100d1af0 +MxBool MxDiskStreamProvider::FUN_100d1af0(MxDSStreamingAction* p_action) +{ + if (p_action->GetUnknowna0()->GetWriteOffset() == 0x20000) { + return g_unk0x10102878 == 0; + } + + return TRUE; +} + +// STUB: LEGO1 0x100d1b20 +MxResult MxDiskStreamProvider::FUN_100d1b20(MxDSStreamingAction* p_action) +{ + return FAILURE; } // FUNCTION: LEGO1 0x100d1e90 diff --git a/LEGO1/mxdiskstreamprovider.h b/LEGO1/mxdiskstreamprovider.h index 55d4f0f2..bc73c0e4 100644 --- a/LEGO1/mxdiskstreamprovider.h +++ b/LEGO1/mxdiskstreamprovider.h @@ -13,21 +13,20 @@ class MxDiskStreamProvider; class MxDSStreamingAction; // VTABLE: LEGO1 0x100dd130 +// SIZE 0x1c class MxDiskStreamProviderThread : public MxThread { public: - // Only inlined, no offset inline MxDiskStreamProviderThread() : MxThread() { m_target = NULL; } MxResult Run() override; - MxResult StartWithTarget(MxDiskStreamProvider* p_target); }; // VTABLE: LEGO1 0x100dd138 +// SIZE 0x60 class MxDiskStreamProvider : public MxStreamProvider { public: MxDiskStreamProvider(); - virtual ~MxDiskStreamProvider() override; // FUNCTION: LEGO1 0x100d1160 @@ -46,6 +45,8 @@ public: MxResult WaitForWorkToComplete(); MxResult FUN_100d1780(MxDSStreamingAction* p_action); void PerformWork(); + static MxBool FUN_100d1af0(MxDSStreamingAction* p_action); + MxResult FUN_100d1b20(MxDSStreamingAction* p_action); virtual MxResult SetResourceToGet(MxStreamController* p_resource) override; // vtable+0x14 virtual MxU32 GetFileSize() override; // vtable+0x18 @@ -57,8 +58,8 @@ public: private: MxDiskStreamProviderThread m_thread; // 0x10 MxSemaphore m_busySemaphore; // 0x2c - undefined m_remainingWork; // 0x34 - undefined m_unk0x35; // 0x35 + MxBool m_remainingWork; // 0x34 + MxBool m_unk0x35; // 0x35 MxCriticalSection m_criticalSection; // 0x38 MxStreamListMxDSAction m_list; // 0x54 }; diff --git a/LEGO1/mxdsbuffer.cpp b/LEGO1/mxdsbuffer.cpp index 0060dbdc..b9908558 100644 --- a/LEGO1/mxdsbuffer.cpp +++ b/LEGO1/mxdsbuffer.cpp @@ -135,7 +135,7 @@ MxResult MxDSBuffer::CreateObject( MxStreamController* p_controller, MxU32* p_data, MxDSAction* p_action, - undefined4 p_undefined + MxDSStreamingAction** p_streamingAction ) { if (p_data == NULL) { @@ -157,7 +157,7 @@ MxResult MxDSBuffer::CreateObject( return SUCCESS; } - return ParseChunk(p_controller, p_data, p_action, p_undefined, chunk); + return ParseChunk(p_controller, p_data, p_action, p_streamingAction, chunk); } delete header; @@ -207,7 +207,7 @@ MxResult MxDSBuffer::ParseChunk( MxStreamController* p_controller, MxU32* p_data, MxDSAction* p_action, - undefined4, + MxDSStreamingAction** p_streamingAction, MxStreamChunk* p_header ) { diff --git a/LEGO1/mxdsbuffer.h b/LEGO1/mxdsbuffer.h index d8532a55..ac003711 100644 --- a/LEGO1/mxdsbuffer.h +++ b/LEGO1/mxdsbuffer.h @@ -42,17 +42,18 @@ public: MxStreamController* p_controller, MxU32* p_data, MxDSAction* p_action, - undefined4 p_undefined + MxDSStreamingAction** p_streamingAction ); MxResult StartPresenterFromAction(MxStreamController* p_controller, MxDSAction* p_action1, MxDSAction* p_action2); MxResult ParseChunk( MxStreamController* p_controller, MxU32* p_data, MxDSAction* p_action, - undefined4, + MxDSStreamingAction** p_streamingAction, MxStreamChunk* p_header ); static MxCore* ReadChunk(MxDSBuffer* p_buffer, MxU32* p_chunkData, MxU16 p_flags); + void SwapBuffers(); MxU8 ReleaseRef(MxDSChunk*); void AddRef(MxDSChunk* p_chunk); void FUN_100c6f80(MxU32 p_writeOffset); @@ -61,6 +62,8 @@ public: inline MxU32 GetWriteOffset() { return m_writeOffset; } inline MxU16 GetRefCount() { return m_refcount; } inline MxDSBufferType GetMode() { return m_mode; } + inline void SetUnknown14(undefined4 p_unk0x14) { m_unk0x14 = p_unk0x14; } + inline void SetUnknown1c(undefined4 p_unk0x1c) { m_unk0x1c = p_unk0x1c; } private: MxU8* m_pBuffer; // 0x08 diff --git a/LEGO1/mxdssource.cpp b/LEGO1/mxdssource.cpp index c38799d3..c2d86abb 100644 --- a/LEGO1/mxdssource.cpp +++ b/LEGO1/mxdssource.cpp @@ -2,10 +2,12 @@ #include "mxdsbuffer.h" +DECOMP_SIZE_ASSERT(MxDSSource, 0x14) + // FUNCTION: LEGO1 0x100bffd0 -void MxDSSource::ReadToBuffer(MxDSBuffer* p_buffer) +MxResult MxDSSource::ReadToBuffer(MxDSBuffer* p_buffer) { - Read(p_buffer->GetBuffer(), p_buffer->GetWriteOffset()); + return Read(p_buffer->GetBuffer(), p_buffer->GetWriteOffset()); } // FUNCTION: LEGO1 0x100bfff0 diff --git a/LEGO1/mxdssource.h b/LEGO1/mxdssource.h index 724efca5..711ba110 100644 --- a/LEGO1/mxdssource.h +++ b/LEGO1/mxdssource.h @@ -6,6 +6,7 @@ class MxDSBuffer; // VTABLE: LEGO1 0x100dc8c8 +// SIZE 0x14 class MxDSSource : public MxCore { public: MxDSSource() : m_lengthInDWords(0), m_pBuffer(NULL), m_position(-1) {} @@ -23,20 +24,21 @@ public: return !strcmp(p_name, MxDSSource::ClassName()) || MxCore::IsA(p_name); } - virtual MxLong Open(MxULong) = 0; - virtual MxLong Close() = 0; - virtual void ReadToBuffer(MxDSBuffer* p_buffer); - virtual MxResult Read(unsigned char*, MxULong) = 0; - virtual MxLong Seek(MxLong, int) = 0; - virtual MxULong GetBufferSize() = 0; - virtual MxULong GetStreamBuffersNum() = 0; - virtual MxLong GetLengthInDWords(); - virtual MxU32* GetBuffer(); // 0x34 + virtual MxLong Open(MxULong) = 0; // vtable+0x14 + virtual MxLong Close() = 0; // vtable+0x18 + virtual MxResult ReadToBuffer(MxDSBuffer* p_buffer); // vtable+0x1c + virtual MxResult Read(unsigned char*, MxULong) = 0; // vtable+0x20 + virtual MxLong Seek(MxLong, int) = 0; // vtable+0x24 + virtual MxULong GetBufferSize() = 0; // vtable+0x28 + virtual MxULong GetStreamBuffersNum() = 0; // vtable+0x2c + virtual MxLong GetLengthInDWords(); // vtable+0x30 + virtual MxU32* GetBuffer(); // vtable+0x34 + inline MxLong GetPosition() const { return m_position; } protected: - MxULong m_lengthInDWords; - MxU32* m_pBuffer; - MxLong m_position; + MxULong m_lengthInDWords; // 0x08 + MxU32* m_pBuffer; // 0x0c + MxLong m_position; // 0x10 }; #endif // MXDSSOURCE_H diff --git a/LEGO1/mxdsstreamingaction.h b/LEGO1/mxdsstreamingaction.h index 1766bd76..7581b217 100644 --- a/LEGO1/mxdsstreamingaction.h +++ b/LEGO1/mxdsstreamingaction.h @@ -32,11 +32,13 @@ public: void FUN_100cd2d0(); inline MxU32 GetUnknown94() { return m_unk0x94; } + inline MxS32 GetUnknown9c() { return m_unk0x9c; } 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 SetUnknown9c(MxS32 p_unk0x9c) { m_unk0x9c = p_unk0x9c; } inline void SetUnknowna0(MxDSBuffer* p_unk0xa0) { m_unk0xa0 = p_unk0xa0; } inline void SetBufferOffset(MxU32 p_bufferOffset) { m_bufferOffset = p_bufferOffset; } diff --git a/LEGO1/mxnextactiondatastart.h b/LEGO1/mxnextactiondatastart.h index 10d2a2f2..c9534899 100644 --- a/LEGO1/mxnextactiondatastart.h +++ b/LEGO1/mxnextactiondatastart.h @@ -30,11 +30,13 @@ public: inline MxU32 GetObjectId() const { return m_objectId; } inline MxS16 GetUnknown24() const { return m_unk0x24; } + inline MxU32 GetData() const { return m_data; } + inline void SetData(MxU32 p_data) { m_data = p_data; } private: - MxU32 m_objectId; - MxS16 m_unk0x24; - MxU32 m_data; + MxU32 m_objectId; // 0x08 + MxS16 m_unk0x24; // 0x0c + MxU32 m_data; // 0x10 }; #endif // MXNEXTACTIONDATASTART_H diff --git a/LEGO1/mxsemaphore.cpp b/LEGO1/mxsemaphore.cpp index 18637185..5692a888 100644 --- a/LEGO1/mxsemaphore.cpp +++ b/LEGO1/mxsemaphore.cpp @@ -1,6 +1,10 @@ #include "mxsemaphore.h" +#include "decomp.h" + +DECOMP_SIZE_ASSERT(MxSemaphore, 0x08) + // FUNCTION: LEGO1 0x100c87d0 MxSemaphore::MxSemaphore() { diff --git a/LEGO1/mxsemaphore.h b/LEGO1/mxsemaphore.h index 3bc6d66b..ecb6509c 100644 --- a/LEGO1/mxsemaphore.h +++ b/LEGO1/mxsemaphore.h @@ -5,6 +5,7 @@ #include +// SIZE 0x08 class MxSemaphore { public: MxSemaphore(); @@ -18,7 +19,7 @@ public: void Release(MxU32 p_releaseCount); private: - HANDLE m_hSemaphore; + HANDLE m_hSemaphore; // 0x04 }; #endif // MX_SEMAPHORE_H diff --git a/LEGO1/mxstreamcontroller.cpp b/LEGO1/mxstreamcontroller.cpp index 92dcfb26..c7d30cc4 100644 --- a/LEGO1/mxstreamcontroller.cpp +++ b/LEGO1/mxstreamcontroller.cpp @@ -5,6 +5,7 @@ #include "mxautolocker.h" #include "mxdsstreamingaction.h" #include "mxnextactiondatastart.h" +#include "mxstl/stlcompat.h" #include "mxstreamchunk.h" #include "mxtimer.h" diff --git a/LEGO1/mxstreamcontroller.h b/LEGO1/mxstreamcontroller.h index ca3b09b3..b8a5bfbd 100644 --- a/LEGO1/mxstreamcontroller.h +++ b/LEGO1/mxstreamcontroller.h @@ -53,6 +53,7 @@ public: MxResult InsertActionToList54(MxDSAction* p_action); inline MxAtomId& GetAtom() { return m_atom; }; + inline MxStreamListMxDSAction& GetUnk0x3c() { return m_unk0x3c; }; inline MxStreamListMxDSAction& GetUnk0x54() { return m_unk0x54; }; protected: diff --git a/LEGO1/mxstreamlist.h b/LEGO1/mxstreamlist.h index 9b65c53d..6aa63de0 100644 --- a/LEGO1/mxstreamlist.h +++ b/LEGO1/mxstreamlist.h @@ -1,7 +1,7 @@ #ifndef MXSTREAMLIST_H #define MXSTREAMLIST_H -#include "mxdsaction.h" +#include "mxdsstreamingaction.h" #include "mxdssubscriber.h" #include "mxnextactiondatastart.h" #include "mxstl/stlcompat.h" @@ -24,6 +24,18 @@ public: class MxStreamListMxDSAction : public MxStreamList { public: MxDSAction* Find(MxDSAction* p_action, MxBool p_delete); + + // There chance this list actually holds MxDSStreamingListAction + // instead of MxDSAction. Until then, we use this helper. + MxBool PopFrontStreamingAction(MxDSStreamingAction*& p_obj) + { + if (empty()) + return FALSE; + + p_obj = (MxDSStreamingAction*) front(); + pop_front(); + return TRUE; + } }; // SIZE 0xc diff --git a/LEGO1/mxstreamprovider.h b/LEGO1/mxstreamprovider.h index ecbe9ab4..73804684 100644 --- a/LEGO1/mxstreamprovider.h +++ b/LEGO1/mxstreamprovider.h @@ -34,8 +34,8 @@ public: virtual MxU32* GetBufferForDWords() = 0; // vtable+0x28 protected: - MxStreamController* m_pLookup; - MxDSFile* m_pFile; + MxStreamController* m_pLookup; // 0x08 + MxDSFile* m_pFile; // 0x0c }; #endif // MXSTREAMPROVIDER_H diff --git a/LEGO1/mxthread.cpp b/LEGO1/mxthread.cpp index 899e959e..401860a1 100644 --- a/LEGO1/mxthread.cpp +++ b/LEGO1/mxthread.cpp @@ -1,11 +1,15 @@ #include "mxthread.h" +#include "decomp.h" #include "mxomni.h" #include "mxtimer.h" #include +DECOMP_SIZE_ASSERT(MxThread, 0x1c) +DECOMP_SIZE_ASSERT(MxTickleThread, 0x20) + // FUNCTION: LEGO1 0x100b8bb0 MxTickleThread::MxTickleThread(MxCore* p_target, MxS32 p_frequencyMS) { diff --git a/LEGO1/mxthread.h b/LEGO1/mxthread.h index 3c7faab0..e3af186d 100644 --- a/LEGO1/mxthread.h +++ b/LEGO1/mxthread.h @@ -8,6 +8,7 @@ class MxCore; // VTABLE: LEGO1 0x100dc860 +// SIZE 0x1c class MxThread { public: // Note: Comes before virtual destructor @@ -16,10 +17,8 @@ public: MxResult Start(MxS32 p_stack, MxS32 p_flag); void Terminate(); - void Sleep(MxS32 p_milliseconds); - // Inferred, not in DLL inline MxBool IsRunning() { return m_running; } protected: @@ -31,27 +30,26 @@ public: private: static unsigned ThreadProc(void* p_thread); - MxULong m_hThread; - MxU32 m_threadId; - MxBool m_running; - MxSemaphore m_semaphore; + MxULong m_hThread; // 0x04 + MxU32 m_threadId; // 0x08 + MxBool m_running; // 0x0c + MxSemaphore m_semaphore; // 0x10 protected: - MxCore* m_target; + MxCore* m_target; // 0x18 }; // VTABLE: LEGO1 0x100dc6d8 +// SIZE 0x20 class MxTickleThread : public MxThread { public: MxTickleThread(MxCore* p_target, MxS32 p_frequencyMS); - - // Only inlined, no offset virtual ~MxTickleThread() {} MxResult Run() override; private: - MxS32 m_frequencyMS; + MxS32 m_frequencyMS; // 0x1c }; #endif // MXTHREAD_H