diff --git a/LEGO1/mxdiskstreamprovider.cpp b/LEGO1/mxdiskstreamprovider.cpp index 2aa25e02..624b3cfc 100644 --- a/LEGO1/mxdiskstreamprovider.cpp +++ b/LEGO1/mxdiskstreamprovider.cpp @@ -130,55 +130,63 @@ MxResult MxDiskStreamProvider::FUN_100d1780(MxDSStreamingAction* p_action) // FUNCTION: LEGO1 0x100d18f0 void MxDiskStreamProvider::PerformWork() { - MxDSStreamingAction* action; + MxDiskStreamController* controller = (MxDiskStreamController*) m_pLookup; + MxDSStreamingAction* streamingAction = NULL; + { MxAutoLocker lock(&m_criticalSection); - if (m_list.size() != 0 && !FUN_100d1af0((MxDSStreamingAction*) m_list.front())) { - MxThread::Sleep(500); - m_busySemaphore.Release(1); - return; + 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.size() != 0) { - action = (MxDSStreamingAction*) m_list.front(); - m_list.pop_front(); - // TODO delete lock here (could be an inline function for locking & popping list) - if (action->GetUnknowna0()->GetWriteOffset() < 0x20000) { - g_unk0x10102878--; + 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); } - - MxDSBuffer* buffer = action->GetUnknowna0(); - if (m_pFile->GetPosition() == action->GetUnknowna0()->GetWriteOffset() || - m_pFile->Seek(action->GetBufferOffset(), 0) == 0) { - buffer->SetUnknown14(m_pFile->GetPosition()); - if (m_pFile->ReadToBuffer(buffer) == SUCCESS) { - buffer->SetUnknown1c(m_pFile->GetPosition()); - if (action->GetUnknown9c() < 1) { - if (m_pLookup == NULL || !((MxDiskStreamController*) m_pLookup)->GetUnk0xc4()) { - ((MxDiskStreamController*) m_pLookup)->FUN_100c8670(action); - } - else { - ((MxDiskStreamController*) m_pLookup)->FUN_100c7f40(action); - } - } - else { - FUN_100d1b20(action); - } - - action = NULL; + else { + if (m_pLookup == NULL || !((MxDiskStreamController*) m_pLookup)->GetUnk0xc4()) { + controller->FUN_100c8670(streamingAction); + } + else { + controller->FUN_100c7f40(streamingAction); } } + + streamingAction = NULL; } } - if (action) { - ((MxDiskStreamController*) m_pLookup)->FUN_100c8670(action); + if (streamingAction) { + controller->FUN_100c8670(streamingAction); } - MxThread::Sleep(0); + + m_thread.Sleep(0); } // FUNCTION: LEGO1 0x100d1af0 diff --git a/LEGO1/mxdssource.cpp b/LEGO1/mxdssource.cpp index 4e4cf65d..c2d86abb 100644 --- a/LEGO1/mxdssource.cpp +++ b/LEGO1/mxdssource.cpp @@ -2,6 +2,8 @@ #include "mxdsbuffer.h" +DECOMP_SIZE_ASSERT(MxDSSource, 0x14) + // FUNCTION: LEGO1 0x100bffd0 MxResult MxDSSource::ReadToBuffer(MxDSBuffer* p_buffer) { diff --git a/LEGO1/mxdssource.h b/LEGO1/mxdssource.h index c8279446..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) {} @@ -35,9 +36,9 @@ class MxDSSource : public MxCore { 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/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 @@ class MxStreamList : public list { 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 @@ class MxStreamProvider : public MxCore { 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.h b/LEGO1/mxthread.h index 3695b29f..fa85b83d 100644 --- a/LEGO1/mxthread.h +++ b/LEGO1/mxthread.h @@ -16,8 +16,7 @@ class MxThread { MxResult Start(MxS32 p_stack, MxS32 p_flag); void Terminate(); - - static void Sleep(MxS32 p_milliseconds); + void Sleep(MxS32 p_milliseconds); // Inferred, not in DLL inline MxBool IsRunning() { return m_running; }