diff --git a/LEGO1/mxdiskstreamcontroller.h b/LEGO1/mxdiskstreamcontroller.h index 28966d9d..703b3bf2 100644 --- a/LEGO1/mxdiskstreamcontroller.h +++ b/LEGO1/mxdiskstreamcontroller.h @@ -43,6 +43,8 @@ public: void FUN_100c7f40(MxDSStreamingAction* p_streamingaction); void FUN_100c8670(MxDSStreamingAction* p_streamingAction); + void InsertToList74(MxDSBuffer* p_buffer); + void FUN_100c7cb0(MxDSStreamingAction* p_action); private: MxStreamListMxDSAction m_list0x64; // 0x64 @@ -57,13 +59,11 @@ private: 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(); MxResult FUN_100c8360(MxDSStreamingAction* p_action); - void InsertToList74(MxDSBuffer* p_buffer); void FUN_100c8540(); void FUN_100c8720(); }; diff --git a/LEGO1/mxdsbuffer.cpp b/LEGO1/mxdsbuffer.cpp index b9908558..f4b30215 100644 --- a/LEGO1/mxdsbuffer.cpp +++ b/LEGO1/mxdsbuffer.cpp @@ -1,5 +1,6 @@ #include "mxdsbuffer.h" +#include "mxdiskstreamcontroller.h" #include "mxdschunk.h" #include "mxdsstreamingaction.h" #include "mxomni.h" @@ -119,15 +120,58 @@ MxResult MxDSBuffer::SetBufferPointer(MxU32* p_buffer, MxU32 p_size) return SUCCESS; } -// STUB: LEGO1 0x100c67b0 +// FUNCTION: LEGO1 0x100c67b0 MxResult MxDSBuffer::FUN_100c67b0( MxStreamController* p_controller, MxDSAction* p_action, MxDSStreamingAction** p_streamingAction ) { - // TODO STUB - return FAILURE; + MxResult result = FAILURE; + + m_unk0x30 = (MxDSStreamingAction*) p_controller->GetUnk0x3c().Find(p_action, FALSE); + if (m_unk0x30 == NULL) + return FAILURE; + + MxU8* data; + while (data = (MxU8*) SkipToData()) { + if (*p_streamingAction == NULL) { + result = CreateObject(p_controller, (MxU32*) data, p_action, p_streamingAction); + + if (result == FAILURE) + return result; + // TODO: Not a MxResult value? + if (result == 1) + break; + } + else { + MxDSBuffer* buffer = (*p_streamingAction)->GetUnknowna0(); + + if (buffer->CalcBytesRemaining(data) != SUCCESS) { + return result; + } + + if (buffer->GetBytesRemaining() == 0) { + buffer->SetUnk30(m_unk0x30); + + result = buffer->CreateObject(p_controller, (MxU32*) buffer->GetBuffer(), p_action, p_streamingAction); + if (result != SUCCESS) { + return result; + } + + if (buffer->GetRefCount() != 0) { + // Note: *p_streamingAction is always null in MxRamStreamProvider + ((MxDiskStreamController*) p_controller)->InsertToList74(buffer); + (*p_streamingAction)->SetUnknowna0(NULL); + } + + ((MxDiskStreamController*) p_controller)->FUN_100c7cb0(*p_streamingAction); + *p_streamingAction = NULL; + } + } + } + + return SUCCESS; } // FUNCTION: LEGO1 0x100c68a0 @@ -212,6 +256,7 @@ MxResult MxDSBuffer::ParseChunk( ) { // TODO + OutputDebugString("ParseChunk() todo\n"); return FAILURE; } @@ -239,6 +284,49 @@ MxCore* MxDSBuffer::ReadChunk(MxDSBuffer* p_buffer, MxU32* p_chunkData, MxU16 p_ return result; } +// FUNCTION: LEGO1 0x100c6df0 +MxU8* MxDSBuffer::SkipToData() +{ + MxU8* result = NULL; + + if (m_pIntoBuffer != NULL) { + do { + MxU32* ptr = (MxU32*) m_pIntoBuffer; + switch (*ptr) { + case FOURCC('L', 'I', 'S', 'T'): + case FOURCC('R', 'I', 'F', 'F'): + m_pIntoBuffer = (MxU8*) (ptr + 3); + break; + case FOURCC('M', 'x', 'O', 'b'): + case FOURCC('M', 'x', 'C', 'h'): + result = m_pIntoBuffer; + m_pIntoBuffer = (MxU8*) ((ptr[1] & 1) + ptr[1] + (MxU32) ptr); + m_pIntoBuffer = (MxU8*) ((MxU32*) m_pIntoBuffer + 2); + if (m_pBuffer + (m_writeOffset - 8) < m_pIntoBuffer) { + m_pIntoBuffer2 = result; + m_pIntoBuffer = NULL; + return result; + } + goto done; + case FOURCC('M', 'x', 'D', 'a'): + case FOURCC('M', 'x', 'S', 't'): + m_pIntoBuffer = (MxU8*) (ptr + 2); + break; + case FOURCC('M', 'x', 'H', 'd'): + m_pIntoBuffer = (MxU8*) ((MxU32) ptr + ptr[1] + 8); + break; + default: + m_pIntoBuffer = NULL; + m_pIntoBuffer2 = NULL; + return NULL; + } + } while (m_pIntoBuffer <= m_pBuffer + (m_writeOffset - 8)); + } +done: + m_pIntoBuffer2 = result; + return result; +} + // FUNCTION: LEGO1 0x100c6ec0 MxU8 MxDSBuffer::ReleaseRef(MxDSChunk*) { @@ -256,6 +344,13 @@ void MxDSBuffer::AddRef(MxDSChunk* p_chunk) } } +// STUB: LEGO1 0x100c6ef0 +MxResult MxDSBuffer::CalcBytesRemaining(MxU8* p_data) +{ + // TODO + return FAILURE; +} + // FUNCTION: LEGO1 0x100c6f80 void MxDSBuffer::FUN_100c6f80(MxU32 p_writeOffset) { diff --git a/LEGO1/mxdsbuffer.h b/LEGO1/mxdsbuffer.h index ac003711..e9fe2675 100644 --- a/LEGO1/mxdsbuffer.h +++ b/LEGO1/mxdsbuffer.h @@ -53,17 +53,20 @@ public: MxStreamChunk* p_header ); static MxCore* ReadChunk(MxDSBuffer* p_buffer, MxU32* p_chunkData, MxU16 p_flags); - void SwapBuffers(); + MxU8* SkipToData(); MxU8 ReleaseRef(MxDSChunk*); void AddRef(MxDSChunk* p_chunk); + MxResult CalcBytesRemaining(MxU8* p_data); void FUN_100c6f80(MxU32 p_writeOffset); inline MxU8* GetBuffer() { return m_pBuffer; } inline MxU32 GetWriteOffset() { return m_writeOffset; } + inline MxU32 GetBytesRemaining() { return m_bytesRemaining; } 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; } + inline void SetUnk30(MxDSStreamingAction* p_unk0x30) { m_unk0x30 = p_unk0x30; } private: MxU8* m_pBuffer; // 0x08