From 20daddde3215b95067d699b66b2fe7bcbd9eed6e Mon Sep 17 00:00:00 2001 From: Misha <106913236+MishaProductions@users.noreply.github.com> Date: Sun, 17 Dec 2023 12:24:39 -0500 Subject: [PATCH] implement MxDSBuffer object creation (#340) * push changes * Update mxstreamcontroller.cpp * fix build * MxStreamChunk * fix format * Match functions * Add a comment --------- Co-authored-by: Christian Semmler --- CMakeLists.txt | 1 + LEGO1/legoomni.cpp | 8 +- LEGO1/legoutil.h | 8 +- LEGO1/mxdiskstreamcontroller.cpp | 7 ++ LEGO1/mxdiskstreamcontroller.h | 1 + LEGO1/mxdsaction.cpp | 4 +- LEGO1/mxdsaction.h | 2 +- LEGO1/mxdsbuffer.cpp | 133 ++++++++++++++++++++++++++++++- LEGO1/mxdsbuffer.h | 42 +++++++--- LEGO1/mxdschunk.cpp | 2 +- LEGO1/mxdschunk.h | 15 ++-- LEGO1/mxdsmediaaction.cpp | 2 +- LEGO1/mxdsmediaaction.h | 2 +- LEGO1/mxdsmultiaction.cpp | 2 +- LEGO1/mxdsmultiaction.h | 2 +- LEGO1/mxdsobject.cpp | 4 +- LEGO1/mxdsobject.h | 4 +- LEGO1/mxdsselectaction.cpp | 14 ++-- LEGO1/mxdsselectaction.h | 2 +- LEGO1/mxdssound.cpp | 2 +- LEGO1/mxdssound.h | 2 +- LEGO1/mxdsstreamingaction.h | 1 + LEGO1/mxpresenter.h | 1 + LEGO1/mxstreamchunk.cpp | 55 +++++++++++++ LEGO1/mxstreamchunk.h | 16 +++- LEGO1/mxstreamcontroller.cpp | 15 ++++ LEGO1/mxstreamcontroller.h | 1 + 27 files changed, 297 insertions(+), 51 deletions(-) create mode 100644 LEGO1/mxstreamchunk.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 2537059c..b549047b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -172,6 +172,7 @@ add_library(lego1 SHARED LEGO1/mxsoundmanager.cpp LEGO1/mxsoundpresenter.cpp LEGO1/mxstillpresenter.cpp + LEGO1/mxstreamchunk.cpp LEGO1/mxstreamchunklist.cpp LEGO1/mxstreamcontroller.cpp LEGO1/mxstreamer.cpp diff --git a/LEGO1/legoomni.cpp b/LEGO1/legoomni.cpp index 1dd1bde8..5ecbb286 100644 --- a/LEGO1/legoomni.cpp +++ b/LEGO1/legoomni.cpp @@ -731,7 +731,7 @@ void SetOmniUserMessage(void (*p_userMsg)(const char*, int)) // FUNCTION: LEGO1 0x100c0280 MxDSObject* CreateStreamObject(MxDSFile* p_file, MxS16 p_ofs) { - char* buf; + MxU8* buf; _MMCKINFO tmpChunk; if (p_file->Seek(((MxLong*) p_file->GetBuffer())[p_ofs], 0)) { @@ -741,18 +741,18 @@ MxDSObject* CreateStreamObject(MxDSFile* p_file, MxS16 p_ofs) if (p_file->Read((MxU8*) &tmpChunk.ckid, 8) == 0 && tmpChunk.ckid == FOURCC('M', 'x', 'S', 't')) { if (p_file->Read((MxU8*) &tmpChunk.ckid, 8) == 0 && tmpChunk.ckid == FOURCC('M', 'x', 'O', 'b')) { - buf = new char[tmpChunk.cksize]; + buf = new MxU8[tmpChunk.cksize]; if (!buf) { return NULL; } - if (p_file->Read((MxU8*) buf, tmpChunk.cksize) != 0) { + if (p_file->Read(buf, tmpChunk.cksize) != 0) { return NULL; } // Save a copy so we can clean up properly, because // this function will alter the pointer value. - char* copy = buf; + MxU8* copy = buf; MxDSObject* obj = DeserializeDSObjectDispatch(&buf, -1); delete[] copy; return obj; diff --git a/LEGO1/legoutil.h b/LEGO1/legoutil.h index afc0a0d4..a6351395 100644 --- a/LEGO1/legoutil.h +++ b/LEGO1/legoutil.h @@ -27,7 +27,7 @@ inline T Max(T p_t1, T p_t2) } template -inline void GetScalar(char** p_source, T& p_dest) +inline void GetScalar(MxU8** p_source, T& p_dest) { p_dest = *(T*) *p_source; *p_source += sizeof(T); @@ -42,16 +42,16 @@ inline T GetScalar(T** p_source) } template -inline void GetDouble(char** p_source, T& p_dest) +inline void GetDouble(MxU8** p_source, T& p_dest) { p_dest = *(double*) *p_source; *p_source += sizeof(double); } template -inline void GetString(char** p_source, const char* p_dest, T* p_obj, void (T::*p_setter)(const char*)) +inline void GetString(MxU8** p_source, const char* p_dest, T* p_obj, void (T::*p_setter)(const char*)) { - (p_obj->*p_setter)(*p_source); + (p_obj->*p_setter)((char*) *p_source); *p_source += strlen(p_dest) + 1; } diff --git a/LEGO1/mxdiskstreamcontroller.cpp b/LEGO1/mxdiskstreamcontroller.cpp index 285b94e7..489d1b74 100644 --- a/LEGO1/mxdiskstreamcontroller.cpp +++ b/LEGO1/mxdiskstreamcontroller.cpp @@ -115,6 +115,13 @@ MxResult MxDiskStreamController::VTable0x24(MxDSAction* p_action) return FAILURE; } +// FUNCTION: LEGO1 0x100c84a0 +void MxDiskStreamController::InsertToList74(MxDSBuffer* p_buffer) +{ + MxAutoLocker lock(&this->m_criticalSection); + m_list0x74.push_back(p_buffer); +} + // STUB: LEGO1 0x100c8640 MxResult MxDiskStreamController::Tickle() { diff --git a/LEGO1/mxdiskstreamcontroller.h b/LEGO1/mxdiskstreamcontroller.h index e77c75db..373e29a1 100644 --- a/LEGO1/mxdiskstreamcontroller.h +++ b/LEGO1/mxdiskstreamcontroller.h @@ -51,6 +51,7 @@ class MxDiskStreamController : public MxStreamController { undefined m_unk0xc4; // 0xc4 void FUN_100c7f40(MxDSStreamingAction* p_streamingaction); + void InsertToList74(MxDSBuffer* p_buffer); }; // TEMPLATE: LEGO1 0x100c7330 diff --git a/LEGO1/mxdsaction.cpp b/LEGO1/mxdsaction.cpp index 3b71011d..36533a1a 100644 --- a/LEGO1/mxdsaction.cpp +++ b/LEGO1/mxdsaction.cpp @@ -205,7 +205,7 @@ void MxDSAction::AppendData(MxU16 p_extraLength, const char* p_extraData) } // FUNCTION: LEGO1 0x100adf70 -void MxDSAction::Deserialize(char** p_source, MxS16 p_unk0x24) +void MxDSAction::Deserialize(MxU8** p_source, MxS16 p_unk0x24) { MxDSObject::Deserialize(p_source, p_unk0x24); @@ -225,7 +225,7 @@ void MxDSAction::Deserialize(char** p_source, MxS16 p_unk0x24) MxU16 extraLength = GetScalar((MxU16**) p_source); if (extraLength) { - AppendData(extraLength, *p_source); + AppendData(extraLength, (char*) *p_source); *p_source += extraLength; } } diff --git a/LEGO1/mxdsaction.h b/LEGO1/mxdsaction.h index 041322e7..eb70b18f 100644 --- a/LEGO1/mxdsaction.h +++ b/LEGO1/mxdsaction.h @@ -44,7 +44,7 @@ class MxDSAction : public MxDSObject { } virtual MxU32 GetSizeOnDisk() override; // vtable+18; - virtual void Deserialize(char** p_source, MxS16 p_unk0x24) override; // vtable+1c; + virtual void Deserialize(MxU8** p_source, MxS16 p_unk0x24) override; // vtable+1c; virtual MxLong GetDuration(); // vtable+24; virtual void SetDuration(MxLong p_duration); // vtable+28; virtual MxDSAction* Clone(); // vtable+2c; diff --git a/LEGO1/mxdsbuffer.cpp b/LEGO1/mxdsbuffer.cpp index 5b308fd2..501cefd6 100644 --- a/LEGO1/mxdsbuffer.cpp +++ b/LEGO1/mxdsbuffer.cpp @@ -1,6 +1,9 @@ #include "mxdsbuffer.h" +#include "mxdschunk.h" +#include "mxdsstreamingaction.h" #include "mxomni.h" +#include "mxstreamchunk.h" #include "mxstreamcontroller.h" #include "mxstreamer.h" @@ -9,7 +12,7 @@ DECOMP_SIZE_ASSERT(MxDSBuffer, 0x34); // FUNCTION: LEGO1 0x100c6470 MxDSBuffer::MxDSBuffer() { - m_unk0x20 = 0; + m_refcount = 0; m_pBuffer = NULL; m_pIntoBuffer = NULL; m_pIntoBuffer2 = NULL; @@ -49,7 +52,7 @@ MxResult MxDSBuffer::AllocateBuffer(MxU32 p_bufferSize, MxDSBufferType p_mode) else if (p_mode == MxDSBufferType_Chunk) { MxStreamer* streamer = Streamer(); // I have no clue as to what this does, or even if its correct. Maybe it's related to storing chunks in - // MxRamStreamController? + // MxDiskStreamController? if (p_bufferSize >> 10 == 0x40) { i = 0; while (i < 22) { @@ -126,6 +129,132 @@ MxResult MxDSBuffer::FUN_100c67b0(MxStreamController* p_controller, MxDSAction* return FAILURE; } +// FUNCTION: LEGO1 0x100c68a0 +MxResult MxDSBuffer::CreateObject( + MxStreamController* p_controller, + MxU32* p_data, + MxDSAction* p_action, + undefined4 p_undefined +) +{ + if (p_data == NULL) { + return FAILURE; + } + + MxCore* header = ReadChunk(this, p_data, p_action->GetUnknown24()); + + if (header == NULL) { + return FAILURE; + } + + if (*p_data == FOURCC('M', 'x', 'O', 'b')) + return StartPresenterFromAction(p_controller, p_action, (MxDSAction*) header); + else if (*p_data == FOURCC('M', 'x', 'C', 'h')) { + MxStreamChunk* chunk = (MxStreamChunk*) header; + if (!m_unk0x30->HasId((chunk)->GetObjectId())) { + delete header; + return SUCCESS; + } + + return ParseChunk(p_controller, p_data, p_action, p_undefined, chunk); + } + + delete header; + return FAILURE; +} + +// FUNCTION: LEGO1 0x100c6960 +MxResult MxDSBuffer::StartPresenterFromAction( + MxStreamController* p_controller, + MxDSAction* p_action1, + MxDSAction* p_objectheader +) +{ + if (!m_unk0x30->GetInternalAction()) { + p_objectheader->SetAtomId(p_action1->GetAtomId()); + p_objectheader->SetUnknown28(p_action1->GetUnknown28()); + p_objectheader->SetUnknown84(p_action1->GetUnknown84()); + p_objectheader->SetOrigin(p_action1->GetOrigin()); + p_objectheader->SetUnknown90(p_action1->GetUnknown90()); + p_objectheader->MergeFrom(*p_action1); + + m_unk0x30->SetInternalAction(p_objectheader->Clone()); + + p_controller->InsertActionToList54(p_objectheader); + + if (MxOmni::GetInstance()->CreatePresenter(p_controller, *p_objectheader) != SUCCESS) { + return FAILURE; + } + + m_unk0x30->SetLoopCount(p_objectheader->GetLoopCount()); + m_unk0x30->SetFlags(p_objectheader->GetFlags()); + m_unk0x30->SetDuration(p_objectheader->GetDuration()); + + if (m_unk0x30->GetInternalAction() == NULL) { + return FAILURE; + } + } + else if (p_objectheader) { + delete p_objectheader; + } + + return SUCCESS; +} + +// STUB: LEGO1 0x100c6a50 +MxResult MxDSBuffer::ParseChunk( + MxStreamController* p_controller, + MxU32* p_data, + MxDSAction* p_action, + undefined4, + MxStreamChunk* p_header +) +{ + // TODO + return FAILURE; +} + +// FUNCTION: LEGO1 0x100c6d00 +MxCore* MxDSBuffer::ReadChunk(MxDSBuffer* p_buffer, MxU32* p_chunkData, MxU16 p_flags) +{ + // This function reads a chunk. If it is an object, this function returns an MxDSObject. If it is a chunk, returns a + // MxDSChunk. + MxCore* result = NULL; + MxU8* dataStart = (MxU8*) p_chunkData + 8; + + switch (*p_chunkData) { + case FOURCC('M', 'x', 'O', 'b'): + result = DeserializeDSObjectDispatch(&dataStart, p_flags); + break; + case FOURCC('M', 'x', 'C', 'h'): + result = new MxStreamChunk(); + if (result != NULL && ((MxStreamChunk*) result)->ReadChunk(p_buffer, (MxU8*) p_chunkData) != SUCCESS) { + delete result; + result = NULL; + } + return result; + } + + return result; +} + +// FUNCTION: LEGO1 0x100c6ec0 +MxU8 MxDSBuffer::ReleaseRef(MxDSChunk*) +{ + if (m_refcount != 0) { + m_refcount--; + } + return 0; +} + +// FUNCTION: LEGO1 0x100c6ee0 +void MxDSBuffer::AddRef(MxDSChunk* p_chunk) +{ + if (p_chunk) { + m_refcount++; + } +} + // FUNCTION: LEGO1 0x100c6f80 void MxDSBuffer::FUN_100c6f80(MxU32 p_writeOffset) { diff --git a/LEGO1/mxdsbuffer.h b/LEGO1/mxdsbuffer.h index aaecd4c0..1a37ba2a 100644 --- a/LEGO1/mxdsbuffer.h +++ b/LEGO1/mxdsbuffer.h @@ -6,6 +6,9 @@ class MxStreamController; class MxDSAction; +class MxDSStreamingAction; +class MxStreamChunk; +class MxDSChunk; enum MxDSBufferType { MxDSBufferType_Chunk = 0, @@ -31,23 +34,40 @@ class MxDSBuffer : public MxCore { 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 CreateObject( + MxStreamController* p_controller, + MxU32* p_data, + MxDSAction* p_action, + undefined4 p_undefined + ); + MxResult StartPresenterFromAction(MxStreamController* p_controller, MxDSAction* p_action1, MxDSAction* p_action2); + MxResult ParseChunk( + MxStreamController* p_controller, + MxU32* p_data, + MxDSAction* p_action, + undefined4, + MxStreamChunk* p_header + ); + static MxCore* ReadChunk(MxDSBuffer* p_buffer, MxU32* p_chunkData, MxU16 p_flags); + MxU8 ReleaseRef(MxDSChunk*); + void AddRef(MxDSChunk* p_chunk); void FUN_100c6f80(MxU32 p_writeOffset); inline MxU8* GetBuffer() { return m_pBuffer; } inline MxU32 GetWriteOffset() { return m_writeOffset; } private: - MxU8* m_pBuffer; - MxU8* m_pIntoBuffer; - MxU8* m_pIntoBuffer2; - undefined4 m_unk0x14; - undefined4 m_unk0x18; - undefined4 m_unk0x1c; - undefined2 m_unk0x20; - MxDSBufferType m_mode; - MxU32 m_writeOffset; - MxU32 m_bytesRemaining; - MxDSAction* m_unk0x30; + MxU8* m_pBuffer; // 0x08 + MxU8* m_pIntoBuffer; // 0x0c + MxU8* m_pIntoBuffer2; // 0x10 + undefined4 m_unk0x14; // 0x14 + undefined4 m_unk0x18; // 0x18 + undefined4 m_unk0x1c; // 0x1c + MxU16 m_refcount; // 0x20 + MxDSBufferType m_mode; // 0x24 + MxU32 m_writeOffset; // 0x28 + MxU32 m_bytesRemaining; // 0x2c + MxDSStreamingAction* m_unk0x30; // 0x30 }; #endif // MXDSBUFFER_H diff --git a/LEGO1/mxdschunk.cpp b/LEGO1/mxdschunk.cpp index 8b64bc0c..b44bc475 100644 --- a/LEGO1/mxdschunk.cpp +++ b/LEGO1/mxdschunk.cpp @@ -7,7 +7,7 @@ MxDSChunk::MxDSChunk() { m_flags = 0; m_data = NULL; - m_unk0x0c = -1; + m_objectId = -1; m_time = 0; m_length = 0; } diff --git a/LEGO1/mxdschunk.h b/LEGO1/mxdschunk.h index 2c43b83e..ad57fcc4 100644 --- a/LEGO1/mxdschunk.h +++ b/LEGO1/mxdschunk.h @@ -34,6 +34,7 @@ class MxDSChunk : public MxCore { } inline void SetFlags(MxU16 p_flags) { m_flags = p_flags; } + inline void SetObjectId(undefined4 p_objectid) { m_objectId = p_objectid; } inline void SetTime(MxLong p_time) { m_time = p_time; } inline void SetLength(MxU32 p_length) { m_length = p_length; } inline void SetData(MxU8* p_data) { m_data = p_data; } @@ -43,18 +44,20 @@ class MxDSChunk : public MxCore { inline MxU32 GetLength() { return m_length; } inline MxU8* GetData() { return m_data; } + inline undefined4 GetObjectId() { return m_objectId; } + inline void Release() { if (m_data) delete[] m_data; } -private: - MxU16 m_flags; // 0x8 - undefined4 m_unk0x0c; // 0xc - MxLong m_time; // 0x10 - MxU32 m_length; // 0x14 - MxU8* m_data; // 0x18 +protected: + MxU16 m_flags; // 0x8 + undefined4 m_objectId; // 0xc + MxLong m_time; // 0x10 + MxU32 m_length; // 0x14 + MxU8* m_data; // 0x18 }; #endif // MXDSCHUNK_H diff --git a/LEGO1/mxdsmediaaction.cpp b/LEGO1/mxdsmediaaction.cpp index d5d7446a..9e07f2d3 100644 --- a/LEGO1/mxdsmediaaction.cpp +++ b/LEGO1/mxdsmediaaction.cpp @@ -80,7 +80,7 @@ MxU32 MxDSMediaAction::GetSizeOnDisk() } // FUNCTION: LEGO1 0x100c8f60 -void MxDSMediaAction::Deserialize(char** p_source, MxS16 p_unk0x24) +void MxDSMediaAction::Deserialize(MxU8** p_source, MxS16 p_unk0x24) { MxDSAction::Deserialize(p_source, p_unk0x24); diff --git a/LEGO1/mxdsmediaaction.h b/LEGO1/mxdsmediaaction.h index 27965be9..6cddd8c1 100644 --- a/LEGO1/mxdsmediaaction.h +++ b/LEGO1/mxdsmediaaction.h @@ -29,7 +29,7 @@ class MxDSMediaAction : public MxDSAction { } virtual MxU32 GetSizeOnDisk() override; // vtable+18; - virtual void Deserialize(char** p_source, MxS16 p_unk0x24) override; // vtable+1c; + virtual void Deserialize(MxU8** p_source, MxS16 p_unk0x24) override; // vtable+1c; void CopyMediaSrcPath(const char* p_mediaSrcPath); diff --git a/LEGO1/mxdsmultiaction.cpp b/LEGO1/mxdsmultiaction.cpp index 2b3c3801..9108837d 100644 --- a/LEGO1/mxdsmultiaction.cpp +++ b/LEGO1/mxdsmultiaction.cpp @@ -117,7 +117,7 @@ MxU32 MxDSMultiAction::GetSizeOnDisk() } // FUNCTION: LEGO1 0x100ca7b0 -void MxDSMultiAction::Deserialize(char** p_source, MxS16 p_unk0x24) +void MxDSMultiAction::Deserialize(MxU8** p_source, MxS16 p_unk0x24) { MxDSAction::Deserialize(p_source, p_unk0x24); diff --git a/LEGO1/mxdsmultiaction.h b/LEGO1/mxdsmultiaction.h index 1f9b693b..5003a378 100644 --- a/LEGO1/mxdsmultiaction.h +++ b/LEGO1/mxdsmultiaction.h @@ -29,7 +29,7 @@ class MxDSMultiAction : public MxDSAction { virtual undefined4 VTable0x14() override; // vtable+14; virtual MxU32 GetSizeOnDisk() override; // vtable+18; - virtual void Deserialize(char** p_source, MxS16 p_unk0x24) override; // vtable+1c; + virtual void Deserialize(MxU8** p_source, MxS16 p_unk0x24) override; // vtable+1c; virtual void SetAtomId(MxAtomId p_atomId) override; // vtable+20; virtual MxDSAction* Clone() override; // vtable+2c; virtual void MergeFrom(MxDSAction& p_dsAction) override; // vtable+30; diff --git a/LEGO1/mxdsobject.cpp b/LEGO1/mxdsobject.cpp index 8b31e8c9..fa0b944c 100644 --- a/LEGO1/mxdsobject.cpp +++ b/LEGO1/mxdsobject.cpp @@ -127,7 +127,7 @@ MxU32 MxDSObject::GetSizeOnDisk() } // FUNCTION: LEGO1 0x100bfa20 -void MxDSObject::Deserialize(char** p_source, MxS16 p_unk0x24) +void MxDSObject::Deserialize(MxU8** p_source, MxS16 p_unk0x24) { GetString(p_source, this->m_sourceName, this, &MxDSObject::SetSourceName); GetScalar(p_source, this->m_unk0x14); @@ -138,7 +138,7 @@ void MxDSObject::Deserialize(char** p_source, MxS16 p_unk0x24) } // FUNCTION: LEGO1 0x100bfb30 -MxDSObject* DeserializeDSObjectDispatch(char** p_source, MxS16 p_flags) +MxDSObject* DeserializeDSObjectDispatch(MxU8** p_source, MxS16 p_flags) { MxU16 type = *(MxU16*) *p_source; *p_source += 2; diff --git a/LEGO1/mxdsobject.h b/LEGO1/mxdsobject.h index e3fe75e9..a05d319b 100644 --- a/LEGO1/mxdsobject.h +++ b/LEGO1/mxdsobject.h @@ -32,7 +32,7 @@ class MxDSObject : public MxCore { virtual undefined4 VTable0x14(); // vtable+14; virtual MxU32 GetSizeOnDisk(); // vtable+18; - virtual void Deserialize(char** p_source, MxS16 p_unk0x24); // vtable+1c; + virtual void Deserialize(MxU8** p_source, MxS16 p_unk0x24); // vtable+1c; inline virtual void SetAtomId(MxAtomId p_atomId) { this->m_atomId = p_atomId; } // vtable+20; inline MxDSType GetType() const { return (MxDSType) this->m_type; } @@ -61,7 +61,7 @@ class MxDSObject : public MxCore { MxPresenter* m_unk0x28; // 0x28 }; -MxDSObject* DeserializeDSObjectDispatch(char**, MxS16); +MxDSObject* DeserializeDSObjectDispatch(MxU8**, MxS16); // FUNCTION: ISLE 0x401c40 // MxDSObject::SetAtomId diff --git a/LEGO1/mxdsselectaction.cpp b/LEGO1/mxdsselectaction.cpp index 10825c54..d064b0f3 100644 --- a/LEGO1/mxdsselectaction.cpp +++ b/LEGO1/mxdsselectaction.cpp @@ -74,7 +74,7 @@ MxU32 MxDSSelectAction::GetSizeOnDisk() } // FUNCTION: LEGO1 0x100cbf60 -void MxDSSelectAction::Deserialize(char** p_source, MxS16 p_unk0x24) +void MxDSSelectAction::Deserialize(MxU8** p_source, MxS16 p_unk0x24) { MxString string; MxDSAction::Deserialize(p_source, p_unk0x24); @@ -82,7 +82,7 @@ void MxDSSelectAction::Deserialize(char** p_source, MxS16 p_unk0x24) MxU32 extraFlag = *(MxU32*) (*p_source + 4) & 1; *p_source += 12; - this->m_unk0x9c = *p_source; + this->m_unk0x9c = (char*) *p_source; if (!strnicmp(this->m_unk0x9c.GetData(), "RANDOM_", strlen("RANDOM_"))) { char buffer[10]; @@ -93,9 +93,9 @@ void MxDSSelectAction::Deserialize(char** p_source, MxS16 p_unk0x24) string = itoa((MxS16) random, buffer, 10); } else - string = VariableTable()->GetVariable(*p_source); + string = VariableTable()->GetVariable((char*) *p_source); - *p_source += strlen(*p_source) + 1; + *p_source += strlen((char*) *p_source) + 1; MxU32 count = *(MxU32*) *p_source; *p_source += sizeof(MxU32); @@ -106,11 +106,11 @@ void MxDSSelectAction::Deserialize(char** p_source, MxS16 p_unk0x24) MxU32 i; for (i = 0; i < count; i++) { - if (!strcmp(string.GetData(), *p_source)) + if (!strcmp(string.GetData(), (char*) *p_source)) index = i; - this->m_unk0xac->Append(*p_source); - *p_source += strlen(*p_source) + 1; + this->m_unk0xac->Append((char*) *p_source); + *p_source += strlen((char*) *p_source) + 1; } for (i = 0; i < count; i++) { diff --git a/LEGO1/mxdsselectaction.h b/LEGO1/mxdsselectaction.h index 4f41f7d2..e4f09433 100644 --- a/LEGO1/mxdsselectaction.h +++ b/LEGO1/mxdsselectaction.h @@ -29,7 +29,7 @@ class MxDSSelectAction : public MxDSParallelAction { } virtual MxU32 GetSizeOnDisk() override; // vtable+18; - virtual void Deserialize(char** p_source, MxS16 p_unk0x24) override; // vtable+1c; + virtual void Deserialize(MxU8** p_source, MxS16 p_unk0x24) override; // vtable+1c; virtual MxDSAction* Clone() override; // vtable+2c; private: diff --git a/LEGO1/mxdssound.cpp b/LEGO1/mxdssound.cpp index 1ff2a4d1..359ff906 100644 --- a/LEGO1/mxdssound.cpp +++ b/LEGO1/mxdssound.cpp @@ -46,7 +46,7 @@ MxDSAction* MxDSSound::Clone() } // FUNCTION: LEGO1 0x100c95a0 -void MxDSSound::Deserialize(char** p_source, MxS16 p_unk0x24) +void MxDSSound::Deserialize(MxU8** p_source, MxS16 p_unk0x24) { MxDSMediaAction::Deserialize(p_source, p_unk0x24); diff --git a/LEGO1/mxdssound.h b/LEGO1/mxdssound.h index 0eaa5fce..45f93942 100644 --- a/LEGO1/mxdssound.h +++ b/LEGO1/mxdssound.h @@ -27,7 +27,7 @@ class MxDSSound : public MxDSMediaAction { } virtual MxU32 GetSizeOnDisk() override; // vtable+18; - virtual void Deserialize(char** p_source, MxS16 p_unk0x24) override; // vtable+1c; + virtual void Deserialize(MxU8** p_source, MxS16 p_unk0x24) override; // vtable+1c; virtual MxDSAction* Clone() override; // vtable+2c; inline MxS32 GetVolume() const { return m_volume; } diff --git a/LEGO1/mxdsstreamingaction.h b/LEGO1/mxdsstreamingaction.h index 4e5f0979..49c2d74f 100644 --- a/LEGO1/mxdsstreamingaction.h +++ b/LEGO1/mxdsstreamingaction.h @@ -34,6 +34,7 @@ class MxDSStreamingAction : public MxDSAction { inline MxU32 GetUnknown94() { return m_unk0x94; } inline MxDSBuffer* GetUnknowna0() { return m_unk0xa0; } inline MxDSBuffer* GetUnknowna4() { return m_unk0xa4; } + inline MxDSAction* GetInternalAction() { return m_internalAction; } inline void SetUnknowna0(MxDSBuffer* p_unk0xa0) { m_unk0xa0 = p_unk0xa0; } private: diff --git a/LEGO1/mxpresenter.h b/LEGO1/mxpresenter.h index fae7021a..41b255dc 100644 --- a/LEGO1/mxpresenter.h +++ b/LEGO1/mxpresenter.h @@ -10,6 +10,7 @@ class MxCompositePresenter; class MxStreamController; +class MxPresenter; // VTABLE: LEGO1 0x100d4d38 // SIZE 0x40 diff --git a/LEGO1/mxstreamchunk.cpp b/LEGO1/mxstreamchunk.cpp new file mode 100644 index 00000000..93e76a6c --- /dev/null +++ b/LEGO1/mxstreamchunk.cpp @@ -0,0 +1,55 @@ +#include "mxstreamchunk.h" + +#include "legoutil.h" +#include "mxdsbuffer.h" + +// FUNCTION: LEGO1 0x100c2fe0 +MxStreamChunk::~MxStreamChunk() +{ + if (m_buffer) { + m_buffer->ReleaseRef(this); + } +} + +// FUNCTION: LEGO1 0x100c3050 +MxResult MxStreamChunk::ReadChunk(MxDSBuffer* p_buffer, MxU8* p_chunkData) +{ + MxResult result = FAILURE; + + if (p_chunkData != NULL && *(MxU32*) p_chunkData == FOURCC('M', 'x', 'C', 'h')) { + if (ReadChunkHeader(p_chunkData + 8)) { + if (p_buffer) { + SetBuffer(p_buffer); + p_buffer->AddRef(this); + } + result = SUCCESS; + } + } + + return result; +} + +// FUNCTION: LEGO1 0x100c30a0 +MxU32 MxStreamChunk::ReadChunkHeader(MxU8* p_chunkData) +{ + MxU32 headersize = 0; + if (p_chunkData) { + MxU8* chunkData = p_chunkData; + // Note: the alpha debug version uses memcpy calls here, + // but the code generation is the same. + GetScalar(&p_chunkData, m_flags); + GetScalar(&p_chunkData, m_objectId); + GetScalar(&p_chunkData, m_time); + GetScalar(&p_chunkData, m_length); + m_data = p_chunkData; + headersize = p_chunkData - chunkData; + } + + return headersize; +} + +// FUNCTION: LEGO1 0x100c3170 +void MxStreamChunk::SetBuffer(MxDSBuffer* p_buffer) +{ + m_buffer = p_buffer; +} diff --git a/LEGO1/mxstreamchunk.h b/LEGO1/mxstreamchunk.h index 817d699f..53cbfc68 100644 --- a/LEGO1/mxstreamchunk.h +++ b/LEGO1/mxstreamchunk.h @@ -3,11 +3,14 @@ #include "mxdschunk.h" +class MxDSBuffer; + // VTABLE: LEGO1 0x100dc2a8 // SIZE 0x20 class MxStreamChunk : public MxDSChunk { public: - inline MxStreamChunk() : m_unk0x1c(NULL) {} + inline MxStreamChunk() : m_buffer(NULL) {} + virtual ~MxStreamChunk() override; // FUNCTION: LEGO1 0x100b1fe0 inline virtual const char* ClassName() const override // vtable+0xc @@ -22,8 +25,17 @@ class MxStreamChunk : public MxDSChunk { return !strcmp(p_name, MxStreamChunk::ClassName()) || MxDSChunk::IsA(p_name); } + inline MxDSBuffer* GetBuffer() { return m_buffer; } + + MxResult ReadChunk(MxDSBuffer* p_buffer, MxU8* p_chunkData); + MxU32 ReadChunkHeader(MxU8* p_chunkData); + void SetBuffer(MxDSBuffer* p_buffer); + private: - void* m_unk0x1c; // 0x1c + MxDSBuffer* m_buffer; // 0x1c }; +// SYNTHETIC: LEGO1 0x100b20a0 +// MxStreamChunk::`scalar deleting destructor' + #endif // MXSTREAMCHUNK_H diff --git a/LEGO1/mxstreamcontroller.cpp b/LEGO1/mxstreamcontroller.cpp index d18f4bcc..e882898b 100644 --- a/LEGO1/mxstreamcontroller.cpp +++ b/LEGO1/mxstreamcontroller.cpp @@ -133,6 +133,21 @@ MxResult MxStreamController::VTable0x30(MxDSAction* p_action) return result; } +// FUNCTION: LEGO1 0x100c1da0 +MxResult MxStreamController::InsertActionToList54(MxDSAction* p_action) +{ + MxAutoLocker locker(&m_criticalSection); + MxDSAction* action = p_action->Clone(); + + if (action == NULL) { + return FAILURE; + } + else { + m_unk0x54.push_back(action); + return SUCCESS; + } +} + // FUNCTION: LEGO1 0x100c1e70 MxPresenter* MxStreamController::FUN_100c1e70(MxDSAction& p_action) { diff --git a/LEGO1/mxstreamcontroller.h b/LEGO1/mxstreamcontroller.h index 803e12b9..50259226 100644 --- a/LEGO1/mxstreamcontroller.h +++ b/LEGO1/mxstreamcontroller.h @@ -45,6 +45,7 @@ class MxStreamController : public MxCore { MxBool FUN_100c20d0(MxDSObject& p_obj); MxResult FUN_100c1a00(MxDSAction* p_action, MxU32 p_bufferval); MxPresenter* FUN_100c1e70(MxDSAction& p_action); + MxResult InsertActionToList54(MxDSAction* p_action); MxResult FUN_100c1f00(MxDSAction* p_action); inline MxAtomId& GetAtom() { return m_atom; };