From b743f99d2080792468c35f8854e294269cc9b050 Mon Sep 17 00:00:00 2001 From: MS Date: Wed, 20 Sep 2023 16:22:57 -0400 Subject: [PATCH] LegoOmni::CreateStreamObject and related (#129) * LegoOmni::CreateStreamObject and related * Revert change to MxDSSource/MxDSFile Read export --- LEGO1/legoomni.cpp | 36 +++++++++++++++++-- LEGO1/mxdsfile.cpp | 16 ++++----- LEGO1/mxdsfile.h | 3 +- LEGO1/mxdsmultiaction.cpp | 2 ++ LEGO1/mxdsmultiaction.h | 4 +++ LEGO1/mxdsobject.cpp | 70 ++++++++++++++++++++++++++++++++++++ LEGO1/mxdsobject.h | 2 ++ LEGO1/mxdsparallelaction.cpp | 2 ++ LEGO1/mxdsselectaction.cpp | 2 ++ LEGO1/mxdsselectaction.h | 7 ++++ LEGO1/mxdsserialaction.cpp | 2 ++ LEGO1/mxdsserialaction.h | 5 +++ LEGO1/mxdssource.cpp | 6 ++++ LEGO1/mxdssource.h | 3 +- 14 files changed, 147 insertions(+), 13 deletions(-) diff --git a/LEGO1/legoomni.cpp b/LEGO1/legoomni.cpp index e5574058..cda6d9ff 100644 --- a/LEGO1/legoomni.cpp +++ b/LEGO1/legoomni.cpp @@ -1,5 +1,7 @@ #include "legoomni.h" +#include "mxdsobject.h" + // 0x100f4588 char *g_nocdSourceName = NULL; @@ -147,10 +149,38 @@ MxBackgroundAudioManager *BackgroundAudioManager() return LegoOmni::GetInstance()->GetBackgroundAudioManager(); } -// OFFSET: LEGO1 0x100c0280 STUB -MxDSObject *CreateStreamObject(MxDSFile *,MxS16) +// OFFSET: LEGO1 0x100c0280 +MxDSObject *CreateStreamObject(MxDSFile *p_file, MxS16 p_ofs) { - // TODO + char *buf; + _MMCKINFO tmp_chunk; + + if (p_file->Seek(((MxLong*)p_file->GetBuffer())[p_ofs], 0)) { + return NULL; + } + + if (p_file->Read((MxU8*)&tmp_chunk.ckid, 8) == 0 && tmp_chunk.ckid == FOURCC('M', 'x', 'S', 't')) { + if (p_file->Read((MxU8*)&tmp_chunk.ckid, 8) == 0 && tmp_chunk.ckid == FOURCC('M', 'x', 'O', 'b')) { + + buf = new char[tmp_chunk.cksize]; + if (!buf) { + return NULL; + } + + if (p_file->Read((MxU8*)buf, tmp_chunk.cksize) != 0) { + return NULL; + } + + // Save a copy so we can clean up properly, because + // this function will alter the pointer value. + char *copy = buf; + MxDSObject *obj = DeserializeDSObjectDispatch(&buf, -1); + delete[] copy; + return obj; + } + return NULL; + } + return NULL; } diff --git a/LEGO1/mxdsfile.cpp b/LEGO1/mxdsfile.cpp index 8bccf914..ca6e96fb 100644 --- a/LEGO1/mxdsfile.cpp +++ b/LEGO1/mxdsfile.cpp @@ -47,13 +47,13 @@ MxLong MxDSFile::Open(MxULong uStyle) } // OFFSET: LEGO1 0x100cc780 -MxLong MxDSFile::Read(unsigned char *pch, MxULong cch) +MxResult MxDSFile::Read(unsigned char *p_buf, MxULong p_nbytes) { - if (m_io.Read((char*)pch, cch) != cch) - return -1; + if (m_io.Read(p_buf, p_nbytes) != p_nbytes) + return FAILURE; - m_position += cch; - return 0; + m_position += p_nbytes; + return SUCCESS; } // OFFSET: LEGO1 0x100cc620 @@ -72,7 +72,7 @@ MxLong MxDSFile::ReadChunks() return -1; } - m_io.Read((char*)&m_header, 0xc); + m_io.Read(&m_header, 0xc); if ((m_header.majorVersion == SI_MAJOR_VERSION) && (m_header.minorVersion == SI_MINOR_VERSION)) { childChunk.ckid = FOURCC('M', 'x', 'O', 'f'); @@ -80,9 +80,9 @@ MxLong MxDSFile::ReadChunks() return -1; } MxULong* pLengthInDWords = &m_lengthInDWords; - m_io.Read((char *)pLengthInDWords, 4); + m_io.Read(pLengthInDWords, 4); m_pBuffer = malloc(*pLengthInDWords * 4); - m_io.Read((char*)m_pBuffer, *pLengthInDWords * 4); + m_io.Read(m_pBuffer, *pLengthInDWords * 4); return 0; } else diff --git a/LEGO1/mxdsfile.h b/LEGO1/mxdsfile.h index ac812df7..d46a6153 100644 --- a/LEGO1/mxdsfile.h +++ b/LEGO1/mxdsfile.h @@ -4,6 +4,7 @@ #include "mxdssource.h" #include "mxioinfo.h" #include "mxstring.h" +#include "mxtypes.h" // VTABLE 0x100dc890 class MxDSFile : public MxDSSource @@ -27,7 +28,7 @@ class MxDSFile : public MxDSSource __declspec(dllexport) virtual MxLong Open(MxULong); // vtable+0x14 __declspec(dllexport) virtual MxLong Close(); // vtable+0x18 - __declspec(dllexport) virtual MxLong Read(unsigned char *,MxULong); // vtable+0x20 + __declspec(dllexport) virtual MxResult Read(unsigned char *,MxULong); // vtable+0x20 __declspec(dllexport) virtual MxLong Seek(MxLong,int); // vtable+0x24 __declspec(dllexport) virtual MxULong GetBufferSize(); // vtable+0x28 __declspec(dllexport) virtual MxULong GetStreamBuffersNum(); // vtable+0x2c diff --git a/LEGO1/mxdsmultiaction.cpp b/LEGO1/mxdsmultiaction.cpp index 4188fb66..0328a5fd 100644 --- a/LEGO1/mxdsmultiaction.cpp +++ b/LEGO1/mxdsmultiaction.cpp @@ -1,5 +1,7 @@ #include "mxdsmultiaction.h" +DECOMP_SIZE_ASSERT(MxDSMultiAction, 0x9c) + // OFFSET: LEGO1 0x100c9b90 MxDSMultiAction::MxDSMultiAction() { diff --git a/LEGO1/mxdsmultiaction.h b/LEGO1/mxdsmultiaction.h index af3d69df..6e049965 100644 --- a/LEGO1/mxdsmultiaction.h +++ b/LEGO1/mxdsmultiaction.h @@ -2,6 +2,7 @@ #define MXDSMULTIACTION_H #include "mxdsaction.h" +#include "decomp.h" // VTABLE 0x100dcef0 // SIZE 0x9c @@ -23,6 +24,9 @@ class MxDSMultiAction : public MxDSAction { return !strcmp(name, MxDSMultiAction::ClassName()) || MxDSAction::IsA(name); } + + undefined4 m_unk0x94; + undefined4 m_unk0x98; }; #endif // MXDSMULTIACTION_H diff --git a/LEGO1/mxdsobject.cpp b/LEGO1/mxdsobject.cpp index 57663cee..2b7d8437 100644 --- a/LEGO1/mxdsobject.cpp +++ b/LEGO1/mxdsobject.cpp @@ -3,6 +3,19 @@ #include #include +#include "mxdstypes.h" +#include "mxdsaction.h" +#include "mxdsmediaaction.h" +#include "mxdsanim.h" +#include "mxdssound.h" +#include "mxdsmultiaction.h" +#include "mxdsserialaction.h" +#include "mxdsparallelaction.h" +#include "mxdsevent.h" +#include "mxdsselectaction.h" +#include "mxdsstill.h" +#include "mxdsobjectaction.h" + DECOMP_SIZE_ASSERT(MxDSObject, 0x2c); // OFFSET: LEGO1 0x100bf6a0 @@ -127,3 +140,60 @@ void MxDSObject::Deserialize(char **p_source, MxS16 p_unk24) this->m_unk24 = p_unk24; } + + +// OFFSET: LEGO1 0x100bfb30 +MxDSObject *DeserializeDSObjectDispatch(char **p_source, MxS16 p_flags) +{ + MxU16 type = *(MxU16*) *p_source; + *p_source += 2; + + MxDSObject *obj = NULL; + + switch (type) { + default: + return NULL; + case MxDSType_Object: + obj = new MxDSObject(); + break; + case MxDSType_Action: + obj = new MxDSAction(); + break; + case MxDSType_MediaAction: + obj = new MxDSMediaAction(); + break; + case MxDSType_Anim: + obj = new MxDSAnim(); + break; + case MxDSType_Sound: + obj = new MxDSSound(); + break; + case MxDSType_MultiAction: + obj = new MxDSMultiAction(); + break; + case MxDSType_SerialAction: + obj = new MxDSSerialAction(); + break; + case MxDSType_ParallelAction: + obj = new MxDSParallelAction(); + break; + case MxDSType_Event: + obj = new MxDSEvent(); + break; + case MxDSType_SelectAction: + obj = new MxDSSelectAction(); + break; + case MxDSType_Still: + obj = new MxDSStill(); + break; + case MxDSType_ObjectAction: + obj = new MxDSObjectAction(); + break; + } + + if (obj) { + obj->Deserialize(p_source, p_flags); + } + + return obj; +} \ No newline at end of file diff --git a/LEGO1/mxdsobject.h b/LEGO1/mxdsobject.h index c46ee609..0b247a6a 100644 --- a/LEGO1/mxdsobject.h +++ b/LEGO1/mxdsobject.h @@ -56,4 +56,6 @@ class MxDSObject : public MxCore undefined4 m_unk28; }; +MxDSObject *DeserializeDSObjectDispatch(char **, MxS16); + #endif // MXDSOBJECT_H diff --git a/LEGO1/mxdsparallelaction.cpp b/LEGO1/mxdsparallelaction.cpp index 97a8a9d3..2e0d66da 100644 --- a/LEGO1/mxdsparallelaction.cpp +++ b/LEGO1/mxdsparallelaction.cpp @@ -1,5 +1,7 @@ #include "mxdsparallelaction.h" +DECOMP_SIZE_ASSERT(MxDSParallelAction, 0x9c) + // OFFSET: LEGO1 0x100cae80 MxDSParallelAction::MxDSParallelAction() { diff --git a/LEGO1/mxdsselectaction.cpp b/LEGO1/mxdsselectaction.cpp index 5cae82fb..1c21b466 100644 --- a/LEGO1/mxdsselectaction.cpp +++ b/LEGO1/mxdsselectaction.cpp @@ -1,5 +1,7 @@ #include "mxdsselectaction.h" +DECOMP_SIZE_ASSERT(MxDSSelectAction, 0xb0) + // OFFSET: LEGO1 0x100cb2b0 MxDSSelectAction::MxDSSelectAction() { diff --git a/LEGO1/mxdsselectaction.h b/LEGO1/mxdsselectaction.h index cb5374e1..df956fbc 100644 --- a/LEGO1/mxdsselectaction.h +++ b/LEGO1/mxdsselectaction.h @@ -2,6 +2,7 @@ #define MXDSSELECTACTION_H #include "mxdsparallelaction.h" +#include "decomp.h" // VTABLE 0x100dcfc8 // SIZE 0xb0 @@ -24,6 +25,12 @@ class MxDSSelectAction : public MxDSParallelAction return !strcmp(name, MxDSSelectAction::ClassName()) || MxDSParallelAction::IsA(name); } + undefined4 m_unk0x9c; + undefined4 m_unk0xa0; + undefined4 m_unk0xa4; + undefined4 m_unk0xa8; + undefined4 m_unk0xac; + }; #endif // MXDSSELECTACTION_H diff --git a/LEGO1/mxdsserialaction.cpp b/LEGO1/mxdsserialaction.cpp index 46964208..c6aa541f 100644 --- a/LEGO1/mxdsserialaction.cpp +++ b/LEGO1/mxdsserialaction.cpp @@ -1,5 +1,7 @@ #include "mxdsserialaction.h" +DECOMP_SIZE_ASSERT(MxDSSerialAction, 0xa8) + // OFFSET: LEGO1 0x100ca9d0 MxDSSerialAction::MxDSSerialAction() { diff --git a/LEGO1/mxdsserialaction.h b/LEGO1/mxdsserialaction.h index 2b260556..6bf30c0f 100644 --- a/LEGO1/mxdsserialaction.h +++ b/LEGO1/mxdsserialaction.h @@ -2,6 +2,7 @@ #define MXDSSERIALACTION_H #include "mxdsmultiaction.h" +#include "decomp.h" // VTABLE 0x100dcf38 // SIZE 0xa8 @@ -23,6 +24,10 @@ class MxDSSerialAction : public MxDSMultiAction { return !strcmp(name, MxDSSerialAction::ClassName()) || MxDSMultiAction::IsA(name); } + + undefined4 m_unk0x9c; + undefined4 m_unk0xa0; + undefined4 m_unk0xa4; }; #endif // MXDSSERIALACTION_H diff --git a/LEGO1/mxdssource.cpp b/LEGO1/mxdssource.cpp index 9a94f110..4dfb5386 100644 --- a/LEGO1/mxdssource.cpp +++ b/LEGO1/mxdssource.cpp @@ -11,4 +11,10 @@ void MxDSSource::SomethingWhichCallsRead(void* pUnknownObject) MxLong MxDSSource::GetLengthInDWords() { return m_lengthInDWords; +} + +// OFFSET: LEGO1 0x100c0000 +void *MxDSSource::GetBuffer() +{ + return m_pBuffer; } \ No newline at end of file diff --git a/LEGO1/mxdssource.h b/LEGO1/mxdssource.h index 5ff4c33c..67cbc6c7 100644 --- a/LEGO1/mxdssource.h +++ b/LEGO1/mxdssource.h @@ -29,11 +29,12 @@ class MxDSSource : public MxCore virtual MxLong Open(MxULong) = 0; virtual MxLong Close() = 0; virtual void SomethingWhichCallsRead(void* pUnknownObject); - virtual MxLong Read(unsigned char *, MxULong) = 0; + 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 void* GetBuffer(); // 0x34 protected: MxULong m_lengthInDWords;