From 4f201eaa485c46ac44b09e25261d5599771ebea3 Mon Sep 17 00:00:00 2001 From: Joshua Peisach Date: Fri, 20 Oct 2023 14:41:23 -0400 Subject: [PATCH 01/11] MxEventPresenter destructor (#223) * MxEventPresenter destructor * Fix and implement Destroy * Fix scope of Destroy decl --------- Co-authored-by: Christian Semmler --- LEGO1/mxeventpresenter.cpp | 25 ++++++++++++++++++++++--- LEGO1/mxeventpresenter.h | 4 +++- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/LEGO1/mxeventpresenter.cpp b/LEGO1/mxeventpresenter.cpp index 88c20ce3..3a4ff7f4 100644 --- a/LEGO1/mxeventpresenter.cpp +++ b/LEGO1/mxeventpresenter.cpp @@ -1,4 +1,6 @@ #include "mxeventpresenter.h" +#include "mxeventmanager.h" +#include "mxomni.h" #include "decomp.h" @@ -10,14 +12,31 @@ MxEventPresenter::MxEventPresenter() Init(); } -// OFFSET: LEGO1 0x100c2d40 STUB +// OFFSET: LEGO1 0x100c2d40 MxEventPresenter::~MxEventPresenter() { - // TODO + Destroy(); } // OFFSET: LEGO1 0x100c2da0 void MxEventPresenter::Init() { - m_unk50 = 0; + m_unk50 = NULL; +} + +// OFFSET: LEGO1 0x100c2de0 +void MxEventPresenter::Destroy() +{ + MxEventManager *eventManager = EventManager(); + if (eventManager) + EventManager()->RemovePresenter(*this); + + m_criticalSection.Enter(); + + if (m_unk50) + delete m_unk50; + + Init(); + + m_criticalSection.Leave(); } diff --git a/LEGO1/mxeventpresenter.h b/LEGO1/mxeventpresenter.h index 256d0c7f..358a54af 100644 --- a/LEGO1/mxeventpresenter.h +++ b/LEGO1/mxeventpresenter.h @@ -26,10 +26,12 @@ class MxEventPresenter : public MxMediaPresenter return !strcmp(name, MxEventPresenter::ClassName()) || MxMediaPresenter::IsA(name); } + virtual void Destroy() override; // vtable+0x38 + private: void Init(); - undefined4 m_unk50; + undefined4 *m_unk50; }; #endif // MXEVENTPRESENTER_H From 6931a817a639334156f36dc38dfd27363b1bec16 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Sat, 21 Oct 2023 17:02:55 -0400 Subject: [PATCH 02/11] Implement NotifyCurrentEntity (#224) --- LEGO1/legoomni.cpp | 7 +++++-- LEGO1/legoomni.h | 2 +- LEGO1/mxomni.cpp | 2 +- LEGO1/mxomni.h | 3 ++- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/LEGO1/legoomni.cpp b/LEGO1/legoomni.cpp index d4ab47ea..f3ba3a81 100644 --- a/LEGO1/legoomni.cpp +++ b/LEGO1/legoomni.cpp @@ -6,6 +6,7 @@ #include "legoutil.h" #include "legoobjectfactory.h" #include "legoinputmanager.h" +#include "legoworld.h" // 0x100f4588 MxAtomId *g_nocdSourceName = NULL; @@ -329,9 +330,11 @@ int LegoOmni::vtable0x30(char*, int, MxCore*) return 0; } -void LegoOmni::NotifyCurrentEntity() +// OFFSET: LEGO1 0x1005b3a0 +void LegoOmni::NotifyCurrentEntity(MxNotificationParam *p_param) { - // FIXME: Stub + if (m_currentWorld) + NotificationManager()->Send(m_currentWorld, p_param); } // OFFSET: LEGO1 0x1005b640 diff --git a/LEGO1/legoomni.h b/LEGO1/legoomni.h index 37d3ef4b..7404e8fa 100644 --- a/LEGO1/legoomni.h +++ b/LEGO1/legoomni.h @@ -61,7 +61,7 @@ class LegoOmni : public MxOmni virtual MxBool DoesEntityExist(MxDSAction &ds) override; virtual void vtable0x2c() override; virtual int vtable0x30(char*, int, MxCore*) override; - virtual void NotifyCurrentEntity() override; + virtual void NotifyCurrentEntity(MxNotificationParam *p_param) override; virtual void StartTimer() override; virtual void StopTimer() override; diff --git a/LEGO1/mxomni.cpp b/LEGO1/mxomni.cpp index 88e4bf02..1b9e557e 100644 --- a/LEGO1/mxomni.cpp +++ b/LEGO1/mxomni.cpp @@ -94,7 +94,7 @@ int MxOmni::vtable0x30(char*, int, MxCore*) } // OFFSET: LEGO1 0x100aefc0 -void MxOmni::NotifyCurrentEntity(MxParam *p_param) +void MxOmni::NotifyCurrentEntity(MxNotificationParam *p_param) { } diff --git a/LEGO1/mxomni.h b/LEGO1/mxomni.h index ab07d2bd..ff7df048 100644 --- a/LEGO1/mxomni.h +++ b/LEGO1/mxomni.h @@ -10,6 +10,7 @@ class MxDSAction; class MxEventManager; class MxMusicManager; class MxNotificationManager; +class MxNotificationParam; class MxObjectFactory; class MxOmniCreateParam; class MxSoundManager; @@ -45,7 +46,7 @@ class MxOmni : public MxCore virtual MxBool DoesEntityExist(MxDSAction &ds); // vtable+28 virtual void vtable0x2c(); // vtable+2c virtual int vtable0x30(char*, int, MxCore*); // vtable+30 - virtual void NotifyCurrentEntity(MxParam *p_param); // vtable+34 + virtual void NotifyCurrentEntity(MxNotificationParam *p_param); // vtable+34 virtual void StartTimer(); // vtable+38 virtual void StopTimer(); // vtable+3c virtual MxBool IsTimerRunning(); //vtable+40 From 5dfb132025205e865a4e8cff6469f2eb62587718 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Sat, 21 Oct 2023 17:23:55 -0400 Subject: [PATCH 03/11] Implement MxOmni::DoesEntityExist and related (#225) * Implement MxOmni::DoesEntityExist and related * Rename function for consistency --- LEGO1/mxnotificationmanager.h | 2 ++ LEGO1/mxomni.cpp | 15 ++++++++++----- LEGO1/mxomni.h | 4 ++-- LEGO1/mxstreamer.cpp | 11 ++++++++++- LEGO1/mxstreamer.h | 6 +++--- 5 files changed, 27 insertions(+), 11 deletions(-) diff --git a/LEGO1/mxnotificationmanager.h b/LEGO1/mxnotificationmanager.h index adcd6876..5bc7b3a4 100644 --- a/LEGO1/mxnotificationmanager.h +++ b/LEGO1/mxnotificationmanager.h @@ -50,6 +50,8 @@ class MxNotificationManager : public MxCore void Unregister(MxCore *p_listener); MxResult Send(MxCore *p_listener, MxNotificationParam *p_param); + inline MxNotificationPtrList *GetQueue() { return m_queue; } + private: void FlushPending(MxCore *p_listener); }; diff --git a/LEGO1/mxomni.cpp b/LEGO1/mxomni.cpp index 1b9e557e..fab1c99b 100644 --- a/LEGO1/mxomni.cpp +++ b/LEGO1/mxomni.cpp @@ -61,22 +61,27 @@ MxResult MxOmni::Start(MxDSAction* p_dsAction) MxResult result = FAILURE; if(p_dsAction->GetAtomId().GetInternal() != NULL && p_dsAction->GetObjectId() != -1 && m_streamer != NULL) { - result = m_streamer->Unknown100b99b0(p_dsAction); + result = m_streamer->FUN_100b99b0(p_dsAction); } return result; } // OFFSET: LEGO1 0x100b00c0 STUB -void MxOmni::DeleteObject(MxDSAction &ds) +void MxOmni::DeleteObject(MxDSAction &p_dsAction) { // TODO } -// OFFSET: LEGO1 0x100b09a0 STUB -MxBool MxOmni::DoesEntityExist(MxDSAction &ds) +// OFFSET: LEGO1 0x100b09a0 +MxBool MxOmni::DoesEntityExist(MxDSAction &p_dsAction) { - // TODO + if (m_streamer->FUN_100b9b30(p_dsAction)) { + MxNotificationPtrList *queue = m_notificationManager->GetQueue(); + + if (!queue || queue->size() == 0) + return TRUE; + } return FALSE; } diff --git a/LEGO1/mxomni.h b/LEGO1/mxomni.h index ff7df048..630d2214 100644 --- a/LEGO1/mxomni.h +++ b/LEGO1/mxomni.h @@ -42,8 +42,8 @@ class MxOmni : public MxCore virtual MxResult Create(COMPAT_CONST MxOmniCreateParam &p); // vtable+18 virtual void Destroy(); // vtable+1c virtual MxResult Start(MxDSAction* p_dsAction); // vtable+20 - virtual void DeleteObject(MxDSAction &ds); // vtable+24 - virtual MxBool DoesEntityExist(MxDSAction &ds); // vtable+28 + virtual void DeleteObject(MxDSAction &p_dsAction); // vtable+24 + virtual MxBool DoesEntityExist(MxDSAction &p_dsAction); // vtable+28 virtual void vtable0x2c(); // vtable+2c virtual int vtable0x30(char*, int, MxCore*); // vtable+30 virtual void NotifyCurrentEntity(MxNotificationParam *p_param); // vtable+34 diff --git a/LEGO1/mxstreamer.cpp b/LEGO1/mxstreamer.cpp index 84d1b7b9..3bb13b73 100644 --- a/LEGO1/mxstreamer.cpp +++ b/LEGO1/mxstreamer.cpp @@ -132,7 +132,7 @@ MxResult MxStreamer::AddStreamControllerToOpenList(MxStreamController *stream) } // OFFSET: LEGO1 0x100b99b0 -MxResult MxStreamer::Unknown100b99b0(MxDSAction* p_action) +MxResult MxStreamer::FUN_100b99b0(MxDSAction* p_action) { MxStreamController* controller; if (p_action != NULL && p_action->GetAtomId().GetInternal() != NULL && p_action->GetObjectId() != -1) @@ -147,6 +147,15 @@ MxResult MxStreamer::Unknown100b99b0(MxDSAction* p_action) return FAILURE; } +// OFFSET: LEGO1 0x100b9b30 +MxBool MxStreamer::FUN_100b9b30(MxDSObject &p_dsObject) +{ + MxStreamController *controller = GetOpenStream(p_dsObject.GetAtomId().GetInternal()); + if (controller) + return controller->FUN_100c20d0(p_dsObject); + return TRUE; +} + // OFFSET: LEGO1 0x100b9b60 MxLong MxStreamer::Notify(MxParam &p) { diff --git a/LEGO1/mxstreamer.h b/LEGO1/mxstreamer.h index b5d86e4d..3931b1fb 100644 --- a/LEGO1/mxstreamer.h +++ b/LEGO1/mxstreamer.h @@ -7,6 +7,7 @@ #include "mxcore.h" #include "mxnotificationparam.h" #include "mxstreamcontroller.h" +#include "mxdsobject.h" #include "mxtypes.h" // NOTE: This feels like some kind of templated class, maybe something from the @@ -92,11 +93,10 @@ class MxStreamer : public MxCore virtual MxResult Create(); // vtable+0x14 + MxBool FUN_100b9b30(MxDSObject &p_dsObject); MxStreamController *GetOpenStream(const char *p_name); - MxResult AddStreamControllerToOpenList(MxStreamController *p_stream); - - MxResult MxStreamer::Unknown100b99b0(MxDSAction* p_action); + MxResult FUN_100b99b0(MxDSAction* p_action); private: list m_openStreams; // 0x8 From 85d94baa503b9987c0c2a3abd9c891eccafa3e19 Mon Sep 17 00:00:00 2001 From: MS Date: Sat, 21 Oct 2023 18:40:31 -0400 Subject: [PATCH 04/11] MxVideoPresenter AlphaMask (formerly UnkStruct) (#226) --- LEGO1/mxbitmap.cpp | 2 +- LEGO1/mxbitmap.h | 11 ++++ LEGO1/mxvideopresenter.cpp | 102 ++++++++++++++++++++++++++++++++++--- LEGO1/mxvideopresenter.h | 14 ++--- 4 files changed, 115 insertions(+), 14 deletions(-) diff --git a/LEGO1/mxbitmap.cpp b/LEGO1/mxbitmap.cpp index 8f33fc22..1128fded 100644 --- a/LEGO1/mxbitmap.cpp +++ b/LEGO1/mxbitmap.cpp @@ -369,7 +369,7 @@ MxResult MxBitmap::SetBitDepth(MxBool p_isHighColor) MxResult MxBitmap::StretchBits(HDC p_hdc, MxS32 p_xSrc, MxS32 p_ySrc, MxS32 p_xDest, MxS32 p_yDest, MxS32 p_destWidth, MxS32 p_destHeight) { // Compression fix? - if ((this->m_bmiHeader->biCompression != 16) && (0 < this->m_bmiHeader->biHeight)) { + if ((this->m_bmiHeader->biCompression != BI_RGB_TOPDOWN) && (0 < this->m_bmiHeader->biHeight)) { p_ySrc = (this->m_bmiHeader->biHeight - p_destHeight) - p_ySrc; } diff --git a/LEGO1/mxbitmap.h b/LEGO1/mxbitmap.h index 53b01e16..6bb1c5fd 100644 --- a/LEGO1/mxbitmap.h +++ b/LEGO1/mxbitmap.h @@ -21,6 +21,13 @@ struct MxBITMAPINFO { RGBQUAD bmiColors[256]; }; +// Non-standard value for biCompression in the BITMAPINFOHEADER struct. +// By default, uncompressed bitmaps (BI_RGB) are stored in bottom-up order. +// You can specify that the bitmap has top-down order instead by providing +// a negative number for biHeight. It could be that Mindscape decided on a +// belt & suspenders approach here. +#define BI_RGB_TOPDOWN 0x10 + // SIZE 0x20 // VTABLE 0x100dc7b0 class MxBitmap : public MxCore @@ -43,6 +50,10 @@ class MxBitmap : public MxCore virtual MxResult StretchBits(HDC p_hdc, MxS32 p_xSrc, MxS32 p_ySrc, MxS32 p_xDest, MxS32 p_yDest, MxS32 p_destWidth, MxS32 p_destHeight); // vtable+40 inline BITMAPINFOHEADER *GetBmiHeader() const { return m_bmiHeader; } + inline MxLong GetBmiWidth() const { return m_bmiHeader->biWidth; } + inline MxLong GetBmiHeight() const { return m_bmiHeader->biHeight; } + inline MxLong GetBmiHeightAbs() const { return m_bmiHeader->biHeight > 0 ? m_bmiHeader->biHeight : -m_bmiHeader->biHeight; } + inline MxU8 *GetBitmapData() const { return m_data; } private: MxResult ImportColorsToPalette(RGBQUAD*, MxPalette*); diff --git a/LEGO1/mxvideopresenter.cpp b/LEGO1/mxvideopresenter.cpp index a22adcd4..5abef00d 100644 --- a/LEGO1/mxvideopresenter.cpp +++ b/LEGO1/mxvideopresenter.cpp @@ -2,7 +2,7 @@ #include "MxVideoManager.h" DECOMP_SIZE_ASSERT(MxVideoPresenter, 0x64); -DECOMP_SIZE_ASSERT(MxVideoPresenter::UnkStruct, 0xc); +DECOMP_SIZE_ASSERT(MxVideoPresenter::AlphaMask, 0xc); // OFFSET: LEGO1 0x1000c700 void MxVideoPresenter::VTable0x5c(undefined4 p_unknown1) @@ -49,28 +49,116 @@ LPDIRECTDRAWSURFACE MxVideoPresenter::VTable0x78() // OFFSET: LEGO1 0x1000c7c0 MxBool MxVideoPresenter::VTable0x7c() { - return (m_bitmap != NULL) || (m_unk54 != NULL); + return (m_bitmap != NULL) || (m_alpha != NULL); } // OFFSET: LEGO1 0x1000c7e0 MxS32 MxVideoPresenter::GetWidth() { - return m_unk54 ? m_unk54->width + return m_alpha ? m_alpha->m_width : m_bitmap->GetBmiHeader()->biWidth; } // OFFSET: LEGO1 0x1000c800 MxS32 MxVideoPresenter::GetHeight() { - return m_unk54 ? m_unk54->height + return m_alpha ? m_alpha->m_height : m_bitmap->GetBmiHeader()->biHeight; } +// OFFSET: LEGO1 0x100b24f0 +MxVideoPresenter::AlphaMask::AlphaMask(MxBitmap &p_bitmap) +{ + m_width = p_bitmap.GetBmiWidth(); + // DECOMP: ECX becomes word-sized if these are not two separate actions. + MxLong _height = p_bitmap.GetBmiHeightAbs(); + m_height = _height; + + MxS32 size = ((m_width * m_height) / 8) + 1; + m_bitmask = new MxU8[size]; + memset(m_bitmask, 0, size); + + MxU32 biCompression = p_bitmap.GetBmiHeader()->biCompression; + MxU32 rows_before_top; + MxU8 *bitmap_src_ptr; + + // The goal here is to enable us to walk through the bitmap's rows + // in order, regardless of the orientation. We want to end up at the + // start of the first row, which is either at position 0, or at + // (image_stride * biHeight) - 1. + + // Reminder: Negative biHeight means this is a top-down DIB. + // Otherwise it is bottom-up. + + if (biCompression == BI_RGB) { + // DECOMP: I think this must be an OR. If not, the check for + // biCompression == 16 gets optimized away. + if (biCompression == BI_RGB_TOPDOWN || p_bitmap.GetBmiHeight() < 0) { + rows_before_top = 0; + } else { + rows_before_top = p_bitmap.GetBmiHeightAbs(); + rows_before_top--; + } + + goto seek_to_last_row; + } else if (biCompression == BI_RGB_TOPDOWN) { + // DECOMP: This is the only condition where we skip the + // calculation below. + bitmap_src_ptr = p_bitmap.GetBitmapData(); + } else { + if (p_bitmap.GetBmiHeight() < 0) { + rows_before_top = 0; + } else { + rows_before_top = p_bitmap.GetBmiHeightAbs(); + rows_before_top--; + } + +// TODO: would prefer not to use goto if we can figure this structure out +seek_to_last_row: + bitmap_src_ptr = ((p_bitmap.GetBmiWidth()+3)&-4) * rows_before_top + p_bitmap.GetBitmapData(); + } + + // How many bytes are there for each row of the bitmap? + // (i.e. the image stride) + // If this is a bottom-up DIB, we will walk it in reverse. + // TODO: Same rounding trick as in MxBitmap + MxS32 row_seek = ((m_height+3)&-4); + if (p_bitmap.GetBmiHeight() < 0) + row_seek = -row_seek; + + // The actual offset into the m_bitmask array. The two for-loops + // are just for counting the pixels. + MxS32 offset = 0; + + MxU8 *t_ptr = bitmap_src_ptr; + for (MxS32 j = 0; j < m_height; j++) { + for (MxS32 i = 0; i < m_width; i++) { + if (*t_ptr) { + // TODO: Second CDQ instruction for abs() should not be there. + MxU32 shift = abs(offset) & 7; + m_bitmask[offset / 8] |= (1 << abs(shift)); + } + t_ptr++; + offset++; + } + // Seek to the start of the next row + bitmap_src_ptr += row_seek; + t_ptr = bitmap_src_ptr; + } +} + +// OFFSET: LEGO1 0x100b26d0 +MxVideoPresenter::AlphaMask::~AlphaMask() +{ + if (m_bitmask) + delete[] m_bitmask; +} + // OFFSET: LEGO1 0x100b2760 void MxVideoPresenter::Init() { m_bitmap = NULL; - m_unk54 = NULL; + m_alpha = NULL; m_unk5c = 1; m_unk58 = NULL; m_unk60 = -1; @@ -99,7 +187,7 @@ void MxVideoPresenter::Destroy(MxBool p_fromDestructor) m_flags = m_flags & 0xfb; } - if (MVideoManager() && (m_unk54 || m_bitmap)) { + if (MVideoManager() && (m_alpha || m_bitmap)) { MxS32 height = GetHeight(); MxS32 width = GetWidth(); @@ -112,7 +200,7 @@ void MxVideoPresenter::Destroy(MxBool p_fromDestructor) } delete m_bitmap; - delete m_unk54; + delete m_alpha; Init(); diff --git a/LEGO1/mxvideopresenter.h b/LEGO1/mxvideopresenter.h index 30a6ada7..4f66075c 100644 --- a/LEGO1/mxvideopresenter.h +++ b/LEGO1/mxvideopresenter.h @@ -49,16 +49,18 @@ class MxVideoPresenter : public MxMediaPresenter // TODO: Not sure what this is. Seems to have size of 12 bytes // based on 0x100b9e9a. Values are copied from the bitmap header. - struct UnkStruct { - undefined unk0[4]; - MxU16 width; - MxU16 height; + // SIZE 0xc + struct AlphaMask { + MxU8 *m_bitmask; + MxU16 m_width; + MxU16 m_height; - virtual ~UnkStruct() {} + AlphaMask(MxBitmap &); + virtual ~AlphaMask(); }; MxBitmap *m_bitmap; - UnkStruct *m_unk54; + AlphaMask *m_alpha; LPDIRECTDRAWSURFACE m_unk58; undefined2 m_unk5c; unsigned char m_flags; // 0x5e From af0e38176cc65fcb8af69f1e05ee6357b5e7bfc9 Mon Sep 17 00:00:00 2001 From: Joshua Peisach Date: Sat, 21 Oct 2023 18:41:05 -0400 Subject: [PATCH 05/11] MxSoundPresenter (#227) * MxSoundPresenter Destructor, destroy, function adding itself to the sound manager and vtable38. * Fix virtual function declarations --------- Co-authored-by: Christian Semmler --- LEGO1/mxmediapresenter.h | 3 +-- LEGO1/mxsoundpresenter.cpp | 44 ++++++++++++++++++++++++++++++++++++++ LEGO1/mxsoundpresenter.h | 8 +++++++ 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/LEGO1/mxmediapresenter.h b/LEGO1/mxmediapresenter.h index d0a5efe4..7ef31a98 100644 --- a/LEGO1/mxmediapresenter.h +++ b/LEGO1/mxmediapresenter.h @@ -43,9 +43,8 @@ class MxMediaPresenter : public MxPresenter undefined4 m_unk44; undefined4 m_unk48; undefined4 m_unk4c; -private: - void Init(); protected: + void Init(); void Destroy(MxBool p_fromDestructor); }; diff --git a/LEGO1/mxsoundpresenter.cpp b/LEGO1/mxsoundpresenter.cpp index 50e04ce4..8204c01c 100644 --- a/LEGO1/mxsoundpresenter.cpp +++ b/LEGO1/mxsoundpresenter.cpp @@ -1 +1,45 @@ #include "mxsoundpresenter.h" + +#include "decomp.h" +#include "mxsoundmanager.h" + +DECOMP_SIZE_ASSERT(MxSoundPresenter, 0x54) + +// OFFSET: LEGO1 0x1000d430 +MxSoundPresenter::~MxSoundPresenter() +{ + Destroy(TRUE); +} + +// OFFSET: LEGO1 0x100b1a50 +void MxSoundPresenter::Destroy(MxBool p_fromDestructor) +{ + if (MSoundManager()) + MSoundManager()->RemovePresenter(*this); + + this->m_criticalSection.Enter(); + MxMediaPresenter::Init(); + this->m_criticalSection.Leave(); + + if (!p_fromDestructor) + MxMediaPresenter::Destroy(FALSE); +} + +// OFFSET: LEGO1 0x100b1aa0 +MxResult MxSoundPresenter::AddToManager() +{ + MxResult ret = FAILURE; + + if (MSoundManager()) { + ret = SUCCESS; + MSoundManager()->AddPresenter(*this); + } + + return ret; +} + +// OFFSET: LEGO1 0x1000d490 +void MxSoundPresenter::Destroy() +{ + Destroy(FALSE); +} diff --git a/LEGO1/mxsoundpresenter.h b/LEGO1/mxsoundpresenter.h index 53d7000d..a63083af 100644 --- a/LEGO1/mxsoundpresenter.h +++ b/LEGO1/mxsoundpresenter.h @@ -2,11 +2,14 @@ #define MXSOUNDPRESENTER_H #include "mxaudiopresenter.h" +#include "mxomni.h" // VTABLE 0x100d4b08 class MxSoundPresenter : public MxAudioPresenter { public: + virtual ~MxSoundPresenter() override; + // OFFSET: LEGO1 0x1000d4a0 inline virtual const char *ClassName() const // vtable+0x0c { @@ -20,6 +23,11 @@ class MxSoundPresenter : public MxAudioPresenter return !strcmp(name, MxSoundPresenter::ClassName()) || MxAudioPresenter::IsA(name); }; + virtual MxResult AddToManager() override; // vtable+0x34 + virtual void Destroy() override; // vtable+0x38 + +private: + void Destroy(MxBool); }; #endif // MXSOUNDPRESENTER_H From ae908a74cc58c35d2fa2fa191edda4ee089f7db6 Mon Sep 17 00:00:00 2001 From: MS Date: Sat, 21 Oct 2023 19:47:48 -0400 Subject: [PATCH 06/11] Copy constructor for MxVideoPresenter::AlphaMask (#229) --- LEGO1/mxvideopresenter.cpp | 14 +++++++++++++- LEGO1/mxvideopresenter.h | 3 ++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/LEGO1/mxvideopresenter.cpp b/LEGO1/mxvideopresenter.cpp index 5abef00d..f48a0f8b 100644 --- a/LEGO1/mxvideopresenter.cpp +++ b/LEGO1/mxvideopresenter.cpp @@ -67,7 +67,7 @@ MxS32 MxVideoPresenter::GetHeight() } // OFFSET: LEGO1 0x100b24f0 -MxVideoPresenter::AlphaMask::AlphaMask(MxBitmap &p_bitmap) +MxVideoPresenter::AlphaMask::AlphaMask(const MxBitmap &p_bitmap) { m_width = p_bitmap.GetBmiWidth(); // DECOMP: ECX becomes word-sized if these are not two separate actions. @@ -147,6 +147,18 @@ MxVideoPresenter::AlphaMask::AlphaMask(MxBitmap &p_bitmap) } } +// OFFSET: LEGO1 0x100b2670 +MxVideoPresenter::AlphaMask::AlphaMask(const MxVideoPresenter::AlphaMask &p_alpha) +{ + m_width = p_alpha.m_width; + m_height = p_alpha.m_height; + + MxS32 size = ((m_width * m_height) / 8) + 1; + m_bitmask = new MxU8[size]; + memcpy(m_bitmask, p_alpha.m_bitmask, size); +} + + // OFFSET: LEGO1 0x100b26d0 MxVideoPresenter::AlphaMask::~AlphaMask() { diff --git a/LEGO1/mxvideopresenter.h b/LEGO1/mxvideopresenter.h index 4f66075c..61a1027c 100644 --- a/LEGO1/mxvideopresenter.h +++ b/LEGO1/mxvideopresenter.h @@ -55,7 +55,8 @@ class MxVideoPresenter : public MxMediaPresenter MxU16 m_width; MxU16 m_height; - AlphaMask(MxBitmap &); + AlphaMask(const MxBitmap &); + AlphaMask(const AlphaMask &); virtual ~AlphaMask(); }; From 50fe5f9c833d3e3b535e98fece72c9101f849eb4 Mon Sep 17 00:00:00 2001 From: Misha <106913236+MishaProductions@users.noreply.github.com> Date: Sun, 22 Oct 2023 09:48:20 -0400 Subject: [PATCH 07/11] implement LegoSoundManager vtable (#231) * LegoSoundManager * Fix virtual function declarations/locations --------- Co-authored-by: Christian Semmler --- LEGO1/legosoundmanager.cpp | 40 ++++++++++++++++++++++++++++++++------ LEGO1/legosoundmanager.h | 6 ++++++ LEGO1/mxsoundmanager.cpp | 16 +++++++++++++-- LEGO1/mxsoundmanager.h | 2 ++ 4 files changed, 56 insertions(+), 8 deletions(-) diff --git a/LEGO1/legosoundmanager.cpp b/LEGO1/legosoundmanager.cpp index 01f8fee5..cec30564 100644 --- a/LEGO1/legosoundmanager.cpp +++ b/LEGO1/legosoundmanager.cpp @@ -1,20 +1,48 @@ #include "legosoundmanager.h" +#include "mxautolocker.h" -// OFFSET: LEGO1 0x100298a0 STUB +// OFFSET: LEGO1 0x100298a0 LegoSoundManager::LegoSoundManager() { - // TODO + Init(); } -// OFFSET: LEGO1 0x10029940 STUB +// OFFSET: LEGO1 0x10029940 LegoSoundManager::~LegoSoundManager() { - // TODO + Destroy(TRUE); +} + +// OFFSET: LEGO1 0x1002a390 +void LegoSoundManager::Destroy() +{ + Destroy(FALSE); +} + +// OFFSET: LEGO1 0x100299b0 STUB +void LegoSoundManager::Destroy(MxBool p_fromDestructor) +{ + +} + +// OFFSET: LEGO1 0x100299f0 STUB +MxResult LegoSoundManager::Create(MxU32 p_frequencyMS, MxBool p_createThread) +{ + return FAILURE; +} + +// OFFSET: LEGO1 0x100299a0 +void LegoSoundManager::Init() +{ + unk0x40 = 0; + unk0x3c = 0; } // OFFSET: LEGO1 0x1002a3a0 STUB MxResult LegoSoundManager::Tickle() { - // TODO - return 0; + MxMediaManager::Tickle(); + MxAutoLocker lock(&this->m_criticalSection); + + return 0; // TODO: call something in unk0x40 } diff --git a/LEGO1/legosoundmanager.h b/LEGO1/legosoundmanager.h index 90e23fba..1f16f497 100644 --- a/LEGO1/legosoundmanager.h +++ b/LEGO1/legosoundmanager.h @@ -10,11 +10,17 @@ class LegoSoundManager : public MxSoundManager public: LegoSoundManager(); virtual ~LegoSoundManager() override; + virtual MxResult Tickle() override; // vtable+08 + virtual void Destroy() override; // vtable+18 + virtual MxResult Create(MxU32 p_frequencyMS, MxBool p_createThread) override; //vtable+0x30 private: void Init(); + void Destroy(MxBool p_fromDestructor); + undefined4 unk0x3c; + undefined4 unk0x40; }; #endif // LEGOSOUNDMANAGER_H diff --git a/LEGO1/mxsoundmanager.cpp b/LEGO1/mxsoundmanager.cpp index 51336843..ca04580f 100644 --- a/LEGO1/mxsoundmanager.cpp +++ b/LEGO1/mxsoundmanager.cpp @@ -58,11 +58,23 @@ MxResult MxSoundManager::Create(MxU32 p_frequencyMS, MxBool p_createThread) // OFFSET: LEGO1 0x100aed10 STUB void MxSoundManager::vtable0x34() { - // TODO STUB + // TODO } // OFFSET: LEGO1 0x100aee10 STUB void MxSoundManager::vtable0x38() { - // TODO STUB + // TODO +} + +// OFFSET: LEGO1 0x100aeab0 +void MxSoundManager::Destroy() +{ + Destroy(FALSE); +} + +// OFFSET: LEGO1 0x100aeac0 STUB +void MxSoundManager::SetVolume(MxS32 p_volume) +{ + // TODO } diff --git a/LEGO1/mxsoundmanager.h b/LEGO1/mxsoundmanager.h index 3bd41085..9e0656f8 100644 --- a/LEGO1/mxsoundmanager.h +++ b/LEGO1/mxsoundmanager.h @@ -14,6 +14,8 @@ class MxSoundManager : public MxAudioManager MxSoundManager(); virtual ~MxSoundManager() override; // vtable+0x0 + virtual void Destroy() override; // vtable+18 + virtual void SetVolume(MxS32 p_volume) override; // vtable+2c virtual MxResult Create(MxU32 p_frequencyMS, MxBool p_createThread); //vtable+0x30 virtual void vtable0x34(); // vtable+0x34 virtual void vtable0x38(); // vtable+0x38 From 681ab9c0262e443b6827f70bbd052f222411d7df Mon Sep 17 00:00:00 2001 From: Misha <106913236+MishaProductions@users.noreply.github.com> Date: Sun, 22 Oct 2023 10:11:46 -0400 Subject: [PATCH 08/11] implement most of MxBackgroundAudioManager (#232) * implement most of MxBackgroundAudioManager * Match OpenMusic to 100%, style fixes --------- Co-authored-by: Christian Semmler --- LEGO1/legoomni.cpp | 11 ++++-- LEGO1/legoomni.h | 2 +- LEGO1/mxbackgroundaudiomanager.cpp | 63 +++++++++++++++++++++++++++++- LEGO1/mxbackgroundaudiomanager.h | 5 ++- LEGO1/mxomni.cpp | 11 +++++- LEGO1/mxomni.h | 3 +- 6 files changed, 85 insertions(+), 10 deletions(-) diff --git a/LEGO1/legoomni.cpp b/LEGO1/legoomni.cpp index f3ba3a81..8786145e 100644 --- a/LEGO1/legoomni.cpp +++ b/LEGO1/legoomni.cpp @@ -11,6 +11,9 @@ // 0x100f4588 MxAtomId *g_nocdSourceName = NULL; +// 0x100f456c +MxAtomId *g_jukeboxScript = NULL; + // 0x101020e8 void (*g_omniUserMessage)(const char *,int); @@ -26,10 +29,11 @@ LegoOmni::~LegoOmni() Destroy(); } -// OFFSET: LEGO1 0x1005b560 STUB +// OFFSET: LEGO1 0x1005b560 void LegoOmni::CreateBackgroundAudio() { - // TODO + if (m_bkgAudioManager) + m_bkgAudioManager->Create(*g_jukeboxScript, 100); } // OFFSET: LEGO1 0x1005af10 STUB @@ -308,9 +312,10 @@ MxResult LegoOmni::Start(MxDSAction* action) return result; } -void LegoOmni::DeleteObject(MxDSAction &ds) +MxResult LegoOmni::DeleteObject(MxDSAction &ds) { // FIXME: Stub + return FAILURE; } MxBool LegoOmni::DoesEntityExist(MxDSAction &ds) diff --git a/LEGO1/legoomni.h b/LEGO1/legoomni.h index 7404e8fa..8a61c2df 100644 --- a/LEGO1/legoomni.h +++ b/LEGO1/legoomni.h @@ -57,7 +57,7 @@ class LegoOmni : public MxOmni virtual MxResult Create(COMPAT_CONST MxOmniCreateParam &p) override; // vtable+18 virtual void Destroy() override; // vtable+1c virtual MxResult Start(MxDSAction* action) override; - virtual void DeleteObject(MxDSAction &ds) override; + virtual MxResult DeleteObject(MxDSAction &ds) override; virtual MxBool DoesEntityExist(MxDSAction &ds) override; virtual void vtable0x2c() override; virtual int vtable0x30(char*, int, MxCore*) override; diff --git a/LEGO1/mxbackgroundaudiomanager.cpp b/LEGO1/mxbackgroundaudiomanager.cpp index 40891bef..cbf480fc 100644 --- a/LEGO1/mxbackgroundaudiomanager.cpp +++ b/LEGO1/mxbackgroundaudiomanager.cpp @@ -1,6 +1,8 @@ #include "mxbackgroundaudiomanager.h" #include "mxomni.h" +#include "mxstreamer.h" +#include "mxticklemanager.h" DECOMP_SIZE_ASSERT(MxBackgroundAudioManager, 0x150) @@ -20,14 +22,29 @@ MxBackgroundAudioManager::MxBackgroundAudioManager() // OFFSET: LEGO1 0x1007ec20 MxBackgroundAudioManager::~MxBackgroundAudioManager() { - // TODO + TickleManager()->UnregisterClient(this); NotificationManager()->Unregister(this); + DestroyMusic(); } // OFFSET: LEGO1 0x1007f470 void MxBackgroundAudioManager::Stop() { - // TODO + if (m_action2.GetObjectId() != -1) + DeleteObject(m_action2); + + m_unk138 = 0; + m_action2.SetAtomId(MxAtomId()); + m_action2.SetObjectId(-1); + + if (m_action1.GetObjectId() != -1) + DeleteObject(m_action1); + + m_unka0 = 0; + m_action1.SetAtomId(MxAtomId()); + m_unk148 = 0; + m_action1.SetObjectId(-1); + m_unk13c = 0; } // OFFSET: LEGO1 0x1007f5f0 @@ -47,3 +64,45 @@ void MxBackgroundAudioManager::Init() this->m_unka0 = 0; this->m_unk13c = 0; } + +// OFFSET: LEGO1 0x1007ece0 +MxResult MxBackgroundAudioManager::Create(MxAtomId &p_script, MxU32 p_frequencyMS) +{ + MxResult result = OpenMusic(p_script); + + if (result == SUCCESS) { + TickleManager()->RegisterClient(this, p_frequencyMS); + m_musicEnabled = TRUE; + } + + return result; +} + +// OFFSET: LEGO1 0x1007ed20 +MxResult MxBackgroundAudioManager::OpenMusic(MxAtomId &p_script) +{ + if (m_script.GetInternal()) + DestroyMusic(); + + MxResult result = FAILURE; + + if (Streamer()->Open(p_script.GetInternal(), 0)) { + m_script = p_script; + result = SUCCESS; + } + + return result; +} + +// OFFSET: LEGO1 0x1007ed70 +void MxBackgroundAudioManager::DestroyMusic() +{ + if (m_script.GetInternal()) { + MxDSAction ds; + ds.SetAtomId(m_script); + ds.SetUnknown24(-2); + DeleteObject(ds); + Streamer()->Close(m_script.GetInternal()); + m_musicEnabled = FALSE; + } +} \ No newline at end of file diff --git a/LEGO1/mxbackgroundaudiomanager.h b/LEGO1/mxbackgroundaudiomanager.h index a2c4cae3..f81fe854 100644 --- a/LEGO1/mxbackgroundaudiomanager.h +++ b/LEGO1/mxbackgroundaudiomanager.h @@ -28,10 +28,13 @@ class MxBackgroundAudioManager : public MxCore } __declspec(dllexport) void Enable(unsigned char p); + virtual MxResult Create(MxAtomId &p_script, MxU32 p_frequencyMS); void Stop(); private: void Init(); + MxResult OpenMusic(MxAtomId &p_script); + void DestroyMusic(); MxBool m_musicEnabled; // 0x8 MxDSAction m_action1; // 0xc @@ -42,7 +45,7 @@ class MxBackgroundAudioManager : public MxCore MxS32 m_unk140; MxS32 m_unk144; MxS16 m_unk148; - MxAtomId m_unk14c; + MxAtomId m_script; }; #endif // MXBACKGROUNDAUDIOMANAGER_H diff --git a/LEGO1/mxomni.cpp b/LEGO1/mxomni.cpp index fab1c99b..0265cc74 100644 --- a/LEGO1/mxomni.cpp +++ b/LEGO1/mxomni.cpp @@ -68,9 +68,10 @@ MxResult MxOmni::Start(MxDSAction* p_dsAction) } // OFFSET: LEGO1 0x100b00c0 STUB -void MxOmni::DeleteObject(MxDSAction &p_dsAction) +MxResult MxOmni::DeleteObject(MxDSAction &p_dsAction) { // TODO + return FAILURE; } // OFFSET: LEGO1 0x100b09a0 @@ -231,7 +232,7 @@ MxResult MxOmni::Create(MxOmniCreateParam &p) } if (p.CreateFlags().CreateStreamer()) { - if (!(m_streamer = new MxStreamer()) || m_streamer->Create() != SUCCESS) + if (!(m_streamer = new MxStreamer()) || m_streamer->Create() != SUCCESS) goto done; } @@ -402,3 +403,9 @@ MxEventManager* EventManager() { return MxOmni::GetInstance()->GetEventManager(); } + +// OFFSET: LEGO1 0x100acf70 +MxResult DeleteObject(MxDSAction &p_dsAction) +{ + return MxOmni::GetInstance()->DeleteObject(p_dsAction); +} \ No newline at end of file diff --git a/LEGO1/mxomni.h b/LEGO1/mxomni.h index 630d2214..430c0fe6 100644 --- a/LEGO1/mxomni.h +++ b/LEGO1/mxomni.h @@ -42,7 +42,7 @@ class MxOmni : public MxCore virtual MxResult Create(COMPAT_CONST MxOmniCreateParam &p); // vtable+18 virtual void Destroy(); // vtable+1c virtual MxResult Start(MxDSAction* p_dsAction); // vtable+20 - virtual void DeleteObject(MxDSAction &p_dsAction); // vtable+24 + virtual MxResult DeleteObject(MxDSAction &p_dsAction); // vtable+24 virtual MxBool DoesEntityExist(MxDSAction &p_dsAction); // vtable+28 virtual void vtable0x2c(); // vtable+2c virtual int vtable0x30(char*, int, MxCore*); // vtable+30 @@ -95,6 +95,7 @@ __declspec(dllexport) MxMusicManager * MusicManager(); __declspec(dllexport) MxEventManager * EventManager(); __declspec(dllexport) MxNotificationManager * NotificationManager(); +MxResult DeleteObject(MxDSAction &p_dsAction); MxVideoManager *MVideoManager(); MxAtomIdCounterSet *AtomIdCounterSet(); MxObjectFactory *ObjectFactory(); From 7e907cfe3f8ce56362392655975319186116151d Mon Sep 17 00:00:00 2001 From: Ramen2X <64166386+Ramen2X@users.noreply.github.com> Date: Sun, 22 Oct 2023 11:33:29 -0400 Subject: [PATCH 09/11] implement/match JukeBoxState (#233) --- LEGO1/jukeboxstate.cpp | 5 +++++ LEGO1/jukeboxstate.h | 2 ++ 2 files changed, 7 insertions(+) diff --git a/LEGO1/jukeboxstate.cpp b/LEGO1/jukeboxstate.cpp index 25b6dc90..d4a2511f 100644 --- a/LEGO1/jukeboxstate.cpp +++ b/LEGO1/jukeboxstate.cpp @@ -1 +1,6 @@ #include "jukeboxstate.h" + +// OFFSET: LEGO1 0x1000f300 +MxBool JukeBoxState::VTable0x14() { + return FALSE; +} diff --git a/LEGO1/jukeboxstate.h b/LEGO1/jukeboxstate.h index 75640fe3..d2b37e38 100644 --- a/LEGO1/jukeboxstate.h +++ b/LEGO1/jukeboxstate.h @@ -21,6 +21,8 @@ class JukeBoxState : public LegoState return !strcmp(name, JukeBoxState::ClassName()) || LegoState::IsA(name); } + virtual MxBool VTable0x14() override; // vtable+0x14 + }; #endif // JUKEBOXSTATE_H From 5ab993bfda54c4186602311335354abf77435ae1 Mon Sep 17 00:00:00 2001 From: Ramen2X <64166386+Ramen2X@users.noreply.github.com> Date: Sun, 22 Oct 2023 13:38:25 -0400 Subject: [PATCH 10/11] cleanup: fix all improper uses of MxResult (#234) * cleanup: fix all improper uses of MxResult --- LEGO1/act2brick.cpp | 2 +- LEGO1/legoanimationmanager.cpp | 2 +- LEGO1/legopathcontroller.cpp | 2 +- LEGO1/mxdiskstreamcontroller.cpp | 2 +- LEGO1/mxmediapresenter.cpp | 2 +- LEGO1/mxpalette.cpp | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/LEGO1/act2brick.cpp b/LEGO1/act2brick.cpp index dde79d0b..1ec4f139 100644 --- a/LEGO1/act2brick.cpp +++ b/LEGO1/act2brick.cpp @@ -25,5 +25,5 @@ MxResult Act2Brick::Tickle() { // TODO - return 0; + return SUCCESS; } diff --git a/LEGO1/legoanimationmanager.cpp b/LEGO1/legoanimationmanager.cpp index 20e0a0e3..bf182ef5 100644 --- a/LEGO1/legoanimationmanager.cpp +++ b/LEGO1/legoanimationmanager.cpp @@ -27,7 +27,7 @@ MxResult LegoAnimationManager::Tickle() { // TODO - return 0; + return SUCCESS; } // OFFSET: LEGO1 0x1005f130 STUB diff --git a/LEGO1/legopathcontroller.cpp b/LEGO1/legopathcontroller.cpp index f8b64109..94a6aa1d 100644 --- a/LEGO1/legopathcontroller.cpp +++ b/LEGO1/legopathcontroller.cpp @@ -16,5 +16,5 @@ LegoPathController::~LegoPathController() MxResult LegoPathController::Tickle() { // TODO - return 0; + return SUCCESS; } diff --git a/LEGO1/mxdiskstreamcontroller.cpp b/LEGO1/mxdiskstreamcontroller.cpp index 0c74c3a7..0c1afedf 100644 --- a/LEGO1/mxdiskstreamcontroller.cpp +++ b/LEGO1/mxdiskstreamcontroller.cpp @@ -16,7 +16,7 @@ MxDiskStreamController::~MxDiskStreamController() MxResult MxDiskStreamController::Tickle() { // TODO - return 0; + return SUCCESS; } // OFFSET: LEGO1 0x100c7790 STUB diff --git a/LEGO1/mxmediapresenter.cpp b/LEGO1/mxmediapresenter.cpp index 2fb6b57c..3f31bf96 100644 --- a/LEGO1/mxmediapresenter.cpp +++ b/LEGO1/mxmediapresenter.cpp @@ -12,7 +12,7 @@ MxMediaPresenter::~MxMediaPresenter() MxResult MxMediaPresenter::Tickle() { // TODO - return 0; + return SUCCESS; } // OFFSET: LEGO1 0x100b54e0 diff --git a/LEGO1/mxpalette.cpp b/LEGO1/mxpalette.cpp index cdd1597f..b11a1209 100644 --- a/LEGO1/mxpalette.cpp +++ b/LEGO1/mxpalette.cpp @@ -379,7 +379,7 @@ void MxPalette::Detach() MxResult MxPalette::SetEntries(LPPALETTEENTRY p_entries) { MxS32 i; - MxResult status = 0; + MxResult status = SUCCESS; if ( this->m_palette ) { @@ -423,7 +423,7 @@ MxResult MxPalette::SetEntries(LPPALETTEENTRY p_entries) this->m_entries[i].peFlags = 0x80; if ( this->m_palette->SetEntries(0, 0, 256, this->m_entries) ) - status = -1; + status = FAILURE; } return status; From 724c9539473214e975f228cf133e5ef458398b9d Mon Sep 17 00:00:00 2001 From: Misha <106913236+MishaProductions@users.noreply.github.com> Date: Sun, 22 Oct 2023 15:58:05 -0400 Subject: [PATCH 11/11] Implement MxDSBuffer constructor, match MxDSSource::FUN_100bffd0 (#235) * Implement MxDSBuffer constructor, match FUN_100bffd0 * Match to 100%, minor style fixes --------- Co-authored-by: Christian Semmler --- LEGO1/mxdsbuffer.cpp | 26 +++++++++++++++++++++++++- LEGO1/mxdsbuffer.h | 25 +++++++++++++++++++++++-- LEGO1/mxdssource.cpp | 8 ++++---- LEGO1/mxdssource.h | 6 ++++-- 4 files changed, 56 insertions(+), 9 deletions(-) diff --git a/LEGO1/mxdsbuffer.cpp b/LEGO1/mxdsbuffer.cpp index 686627a4..b01be21a 100644 --- a/LEGO1/mxdsbuffer.cpp +++ b/LEGO1/mxdsbuffer.cpp @@ -1,9 +1,21 @@ #include "mxdsbuffer.h" +DECOMP_SIZE_ASSERT(MxDSBuffer, 0x34); + // OFFSET: LEGO1 0x100c6470 MxDSBuffer::MxDSBuffer() { - // TODO + m_unk20 = 0; + m_pBuffer = NULL; + m_pIntoBuffer = NULL; + m_pIntoBuffer2 = NULL; + m_unk14 = 0; + m_unk18 = 0; + m_unk1c = 0; + m_writeOffset = 0; + m_bytesRemaining = 0; + m_mode = 2; + m_unk30 = 0; } // OFFSET: LEGO1 0x100c6530 @@ -11,3 +23,15 @@ MxDSBuffer::~MxDSBuffer() { // TODO } + +// OFFSET: LEGO1 0x100c6780 +MxResult MxDSBuffer::FUN_100c6780(void* p_buffer, MxU32 p_size) +{ + m_pBuffer = p_buffer; + m_pIntoBuffer = p_buffer; + m_pIntoBuffer2 = p_buffer; + m_bytesRemaining = p_size; + m_writeOffset = p_size; + m_mode = 2; + return SUCCESS; +} diff --git a/LEGO1/mxdsbuffer.h b/LEGO1/mxdsbuffer.h index cb962cea..a48c4727 100644 --- a/LEGO1/mxdsbuffer.h +++ b/LEGO1/mxdsbuffer.h @@ -12,9 +12,30 @@ class MxDSBuffer : public MxCore MxDSBuffer(); virtual ~MxDSBuffer() override; -private: - undefined m_unk08[0x2C]; + // OFFSET: LEGO1 0x100c6500 + inline virtual const char *ClassName() const override // vtable+0x0c + { + // 0x100f0568 + return "MxDSBuffer"; + } + MxResult FUN_100c6780(void* p_buffer, MxU32 p_size); + + inline void* GetBuffer() { return m_pBuffer;} + inline MxU32 GetWriteOffset() { return m_writeOffset;} + +private: + void* m_pBuffer; + void* m_pIntoBuffer; + void* m_pIntoBuffer2; + undefined4 m_unk14; + undefined4 m_unk18; + undefined4 m_unk1c; + undefined2 m_unk20; + undefined4 m_mode; + MxU32 m_writeOffset; + MxU32 m_bytesRemaining; + undefined4 m_unk30; }; #endif // MXDSBUFFER_H diff --git a/LEGO1/mxdssource.cpp b/LEGO1/mxdssource.cpp index 0ede6402..3c725a81 100644 --- a/LEGO1/mxdssource.cpp +++ b/LEGO1/mxdssource.cpp @@ -1,10 +1,10 @@ #include "mxdssource.h" +#include "mxdsbuffer.h" // OFFSET: LEGO1 0x100bffd0 -void MxDSSource::FUN_100bffd0(void* p_unk) +void MxDSSource::ReadToBuffer(MxDSBuffer* p_buffer) { - // TODO: Calls read, reading into a buffer somewhere in p_unk. - Read(NULL, 0); + Read((unsigned char*)p_buffer->GetBuffer(), p_buffer->GetWriteOffset()); } // OFFSET: LEGO1 0x100bfff0 @@ -17,4 +17,4 @@ MxLong MxDSSource::GetLengthInDWords() MxU32 *MxDSSource::GetBuffer() { return m_pBuffer; -} \ No newline at end of file +} diff --git a/LEGO1/mxdssource.h b/LEGO1/mxdssource.h index 2891f426..9c404ad0 100644 --- a/LEGO1/mxdssource.h +++ b/LEGO1/mxdssource.h @@ -3,13 +3,15 @@ #include "mxcore.h" +class MxDSBuffer; + // VTABLE 0x100dc8c8 class MxDSSource : public MxCore { public: MxDSSource() : m_lengthInDWords(0) - , m_pBuffer(0) + , m_pBuffer(NULL) , m_position(-1) {} @@ -28,7 +30,7 @@ class MxDSSource : public MxCore virtual MxLong Open(MxULong) = 0; virtual MxLong Close() = 0; - virtual void FUN_100bffd0(void* p_unk); + virtual void ReadToBuffer(MxDSBuffer* p_buffer); virtual MxResult Read(unsigned char *, MxULong) = 0; virtual MxLong Seek(MxLong, int) = 0; virtual MxULong GetBufferSize() = 0;