diff --git a/LEGO1/mxdiskstreamcontroller.h b/LEGO1/mxdiskstreamcontroller.h index a69c28d8..28966d9d 100644 --- a/LEGO1/mxdiskstreamcontroller.h +++ b/LEGO1/mxdiskstreamcontroller.h @@ -39,6 +39,11 @@ class MxDiskStreamController : public MxStreamController { 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,7 +53,7 @@ class MxDiskStreamController : public MxStreamController { 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(); @@ -57,12 +62,10 @@ class MxDiskStreamController : public MxStreamController { 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(); - void FUN_100c8670(MxDSStreamingAction* p_streamingAction); }; // TEMPLATE: LEGO1 0x100c7330 diff --git a/LEGO1/mxdiskstreamprovider.cpp b/LEGO1/mxdiskstreamprovider.cpp index b9118db8..bba524a2 100644 --- a/LEGO1/mxdiskstreamprovider.cpp +++ b/LEGO1/mxdiskstreamprovider.cpp @@ -1,6 +1,7 @@ #include "mxdiskstreamprovider.h" #include "mxautolocker.h" +#include "mxdiskstreamcontroller.h" #include "mxdsbuffer.h" #include "mxdsstreamingaction.h" #include "mxomni.h" @@ -131,8 +132,56 @@ MxResult MxDiskStreamProvider::FUN_100d1780(MxDSStreamingAction* p_action) // FUNCTION: LEGO1 0x100d18f0 void MxDiskStreamProvider::PerformWork() { - // TODO - OutputDebugStringA("work is not being preformed.\n"); + MxDSStreamingAction* action; + { + MxAutoLocker lock(&m_criticalSection); + if (m_list.size() != 0 && !FUN_100d1af0((MxDSStreamingAction*)m_list.front())) { + MxThread::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 line function) + if (action->GetUnknowna0()->GetWriteOffset() < 0x20000) { + g_unk0x10102878--; + } + + 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; + } + } + } + } + + if (action) + { + ((MxDiskStreamController*) m_pLookup)->FUN_100c8670(action); + } + MxThread::Sleep(0); } // FUNCTION: LEGO1 0x100d1af0 @@ -145,6 +194,13 @@ MxBool MxDiskStreamProvider::FUN_100d1af0(MxDSStreamingAction* p_action) return TRUE; } +// STUB: LEGO1 0x100d1b20 +MxResult MxDiskStreamProvider::FUN_100d1b20(MxDSStreamingAction* p_action) +{ + OutputDebugString("MxDiskStreamProvider::FUN_100d1b20"); + return FAILURE; +} + // FUNCTION: LEGO1 0x100d1e90 MxU32 MxDiskStreamProvider::GetFileSize() { diff --git a/LEGO1/mxdiskstreamprovider.h b/LEGO1/mxdiskstreamprovider.h index 80719ab0..4f54a3ed 100644 --- a/LEGO1/mxdiskstreamprovider.h +++ b/LEGO1/mxdiskstreamprovider.h @@ -47,6 +47,7 @@ class MxDiskStreamProvider : public MxStreamProvider { 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 diff --git a/LEGO1/mxdsbuffer.h b/LEGO1/mxdsbuffer.h index f396a9e2..ac003711 100644 --- a/LEGO1/mxdsbuffer.h +++ b/LEGO1/mxdsbuffer.h @@ -62,6 +62,8 @@ class MxDSBuffer : public MxCore { 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..4e4cf65d 100644 --- a/LEGO1/mxdssource.cpp +++ b/LEGO1/mxdssource.cpp @@ -3,9 +3,9 @@ #include "mxdsbuffer.h" // 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..c38d1e50 100644 --- a/LEGO1/mxdssource.h +++ b/LEGO1/mxdssource.h @@ -23,15 +23,16 @@ class MxDSSource : public MxCore { 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; diff --git a/LEGO1/mxthread.h b/LEGO1/mxthread.h index 3c7faab0..3695b29f 100644 --- a/LEGO1/mxthread.h +++ b/LEGO1/mxthread.h @@ -17,7 +17,7 @@ class MxThread { void Terminate(); - void Sleep(MxS32 p_milliseconds); + static void Sleep(MxS32 p_milliseconds); // Inferred, not in DLL inline MxBool IsRunning() { return m_running; }