diff --git a/CMakeLists.txt b/CMakeLists.txt index 2e0fed5a..2cedd429 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -93,6 +93,7 @@ add_library(lego1 SHARED LEGO1/legoworld.cpp LEGO1/legoworldpresenter.cpp LEGO1/motorcycle.cpp + LEGO1/mxactionnotificationparam.cpp LEGO1/mxatomid.cpp LEGO1/mxatomidcounter.cpp LEGO1/mxaudiomanager.cpp @@ -144,11 +145,11 @@ add_library(lego1 SHARED LEGO1/mxmusicmanager.cpp LEGO1/mxmusicpresenter.cpp LEGO1/mxnotificationmanager.cpp + LEGO1/mxnotificationparam.cpp LEGO1/mxobjectfactory.cpp LEGO1/mxomni.cpp LEGO1/mxomnicreateflags.cpp LEGO1/mxomnicreateparam.cpp - LEGO1/mxomnicreateparambase.cpp LEGO1/mxpalette.cpp LEGO1/mxparam.cpp LEGO1/mxpresenter.cpp diff --git a/ISLE/isleapp.cpp b/ISLE/isleapp.cpp index 803ef45e..a4a73035 100644 --- a/ISLE/isleapp.cpp +++ b/ISLE/isleapp.cpp @@ -708,7 +708,7 @@ inline void IsleApp::Tick(BOOL sleepIfNotNextFrame) } if (this->m_frameDelta + g_lastFrameTime < currentTime) { - if (!Lego()->vtable40()) { + if (!Lego()->IsTimerRunning()) { TickleManager()->Tickle(); } g_lastFrameTime = currentTime; diff --git a/LEGO1/legoomni.cpp b/LEGO1/legoomni.cpp index f4480bb8..33f88a58 100644 --- a/LEGO1/legoomni.cpp +++ b/LEGO1/legoomni.cpp @@ -6,7 +6,7 @@ #include "legoutil.h" // 0x100f4588 -char *g_nocdSourceName = NULL; +MxAtomId *g_nocdSourceName = NULL; // 0x101020e8 void (*g_omniUserMessage)(const char *,int); @@ -225,7 +225,7 @@ MxTransitionManager *TransitionManager() // OFFSET: LEGO1 0x10053430 const char *GetNoCD_SourceName() { - return g_nocdSourceName; + return g_nocdSourceName->GetInternal(); } // OFFSET: LEGO1 0x1005b5f0 @@ -252,7 +252,23 @@ LegoEntity *PickEntity(MxLong,MxLong) // OFFSET: LEGO1 0x10058bd0 void LegoOmni::Init() { - // FIXME: Stub + MxOmni::Init(); + m_unk68 = 0; + m_inputMgr = NULL; + m_unk6c = 0; + m_unk74 = 0; + m_unk78 = 0; + m_currentWorld = NULL; + m_unk80 = FALSE; + m_isle = NULL; + m_unk8c = 0; + m_plantManager = NULL; + m_gameState = NULL; + m_animationManager = NULL; + m_buildingManager = NULL; + m_bkgAudioManager = NULL; + m_unk13c = TRUE; + m_transitionManager = NULL; } // OFFSET: LEGO1 0x10058e70 @@ -266,6 +282,7 @@ MxResult LegoOmni::Create(COMPAT_CONST MxOmniCreateParam &p) return SUCCESS; } +// OFFSET: LEGO1 0x10058c30 STUB void LegoOmni::Destroy() { // FIXME: Stub @@ -322,12 +339,6 @@ void LegoOmni::StopTimer() SetAppCursor(0); } -MxBool LegoOmni::vtable40() -{ - // FIXME: Stub - return 0; -} - // OFFSET: LEGO1 0x100157a0 LegoWorld *GetCurrentWorld() { diff --git a/LEGO1/legoomni.h b/LEGO1/legoomni.h index 4de0d1b5..e4074463 100644 --- a/LEGO1/legoomni.h +++ b/LEGO1/legoomni.h @@ -6,6 +6,7 @@ #include "mxdsaction.h" class Isle; +class LegoAnimationManager; class LegoBuildingManager; class LegoEntity; class LegoGameState; @@ -62,7 +63,6 @@ class LegoOmni : public MxOmni virtual void NotifyCurrentEntity() override; virtual void StartTimer() override; virtual void StopTimer() override; - virtual MxBool vtable40(); LegoVideoManager *GetVideoManager() { return (LegoVideoManager *) m_videoManager; } LegoSoundManager *GetSoundManager() { return (LegoSoundManager *)m_soundManager;} @@ -83,19 +83,18 @@ class LegoOmni : public MxOmni undefined4 m_unk74; undefined4 m_unk78; LegoWorld *m_currentWorld; - undefined4 m_unk80; + MxBool m_unk80; LegoNavController *m_navController; // 0x84 Isle* m_isle; // 0x88 - char m_unk8c[0x4]; + undefined4 m_unk8c; LegoPlantManager* m_plantManager; // 0x90 - char m_unk94[0x4]; + LegoAnimationManager* m_animationManager; LegoBuildingManager* m_buildingManager; // 0x98 LegoGameState *m_gameState; // 0x9c MxDSAction m_action; MxBackgroundAudioManager *m_bkgAudioManager; // 0x134 MxTransitionManager *m_transitionManager; // 0x138 - int m_unk13c; - + MxBool m_unk13c; }; __declspec(dllexport) MxBackgroundAudioManager * BackgroundAudioManager(); diff --git a/LEGO1/mxactionnotificationparam.cpp b/LEGO1/mxactionnotificationparam.cpp new file mode 100644 index 00000000..33395c4d --- /dev/null +++ b/LEGO1/mxactionnotificationparam.cpp @@ -0,0 +1,16 @@ +#include "mxactionnotificationparam.h" + +DECOMP_SIZE_ASSERT(MxActionNotificationParam, 0x14) +DECOMP_SIZE_ASSERT(MxEndActionNotificationParam, 0x14) + +// OFFSET: LEGO1 0x100510c0 +MxNotificationParam *MxActionNotificationParam::Clone() +{ + return new MxActionNotificationParam(this->m_type, this->m_sender, this->m_action, this->m_realloc); +} + +// OFFSET: LEGO1 0x10051270 +MxNotificationParam *MxEndActionNotificationParam::Clone() +{ + return new MxEndActionNotificationParam(MXSTREAMER_UNKNOWN, this->m_sender, this->m_action, this->m_realloc); +} diff --git a/LEGO1/mxactionnotificationparam.h b/LEGO1/mxactionnotificationparam.h new file mode 100644 index 00000000..4229e252 --- /dev/null +++ b/LEGO1/mxactionnotificationparam.h @@ -0,0 +1,59 @@ +#ifndef MXACTIONNOTIFICATIONPARAM_H +#define MXACTIONNOTIFICATIONPARAM_H + +#include "mxnotificationparam.h" +#include "mxdsaction.h" + +// VTABLE 0x100d8350 +// SIZE 0x14 +class MxActionNotificationParam : public MxNotificationParam +{ +public: + inline MxActionNotificationParam(MxParamType p_type, MxCore *p_sender, MxDSAction *p_action, MxBool p_reallocAction) : MxNotificationParam(p_type, p_sender) + { + MxDSAction *oldAction = p_action; + this->m_realloc = p_reallocAction; + + if (p_reallocAction) + this->m_action = new MxDSAction(); + else { + this->m_action = oldAction; + return; + } + + this->m_action->SetAtomId(oldAction->GetAtomId()); + this->m_action->SetObjectId(oldAction->GetObjectId()); + this->m_action->SetUnknown24(oldAction->GetUnknown24()); + } + + // OFFSET: LEGO1 0x10051050 + inline virtual MxActionNotificationParam::~MxActionNotificationParam() override + { + if (!this->m_realloc) + return; + + if (this->m_action) + delete this->m_action; + } + + virtual MxNotificationParam *Clone() override; // vtable+0x4 + +protected: + MxDSAction *m_action; // 0xc + MxBool m_realloc; // 0x10 +}; + +// VTABLE 0x100d8358 +// SIZE 0x14 +class MxEndActionNotificationParam : public MxActionNotificationParam +{ +public: + inline MxEndActionNotificationParam(MxParamType p_type, MxCore *p_sender, MxDSAction *p_action, MxBool p_reallocAction) + : MxActionNotificationParam(p_type, p_sender, p_action, p_reallocAction) {} + + inline virtual ~MxEndActionNotificationParam() override {}; // 0x100513a0 + + virtual MxNotificationParam *Clone() override; // vtable+0x4 +}; + +#endif \ No newline at end of file diff --git a/LEGO1/mxbitmap.cpp b/LEGO1/mxbitmap.cpp index 5987f31f..8f33fc22 100644 --- a/LEGO1/mxbitmap.cpp +++ b/LEGO1/mxbitmap.cpp @@ -1,12 +1,13 @@ #include "mxbitmap.h" #include "decomp.h" -DECOMP_SIZE_ASSERT(MxBITMAPINFO, 1064); +DECOMP_SIZE_ASSERT(MxBitmap, 0x20); +DECOMP_SIZE_ASSERT(MxBITMAPINFO, 0x428); -// The way that the BITMAPFILEHEADER structure ensures the file type is by ensuring it is "BM", which is literally just 0x424d. +// Bitmap header magic string "BM" (42 4d) // Sources: https://learn.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-bitmapfileheader, DirectX Complete (1998) // GLOBAL: LEGO1 0x10102184 -undefined2 g_bitmapSignature = 0x424d; +MxU16 g_bitmapSignature = TWOCC('B', 'M'); // OFFSET: LEGO1 0x100bc980 MxBitmap::MxBitmap() @@ -15,7 +16,7 @@ MxBitmap::MxBitmap() this->m_bmiHeader = NULL; this->m_paletteData = NULL; this->m_data = NULL; - this->m_bitDepth = LOWCOLOR; + this->m_isHighColor = FALSE; this->m_palette = NULL; } @@ -30,43 +31,54 @@ MxBitmap::~MxBitmap() delete m_palette; } +// Bit mask trick to round up to the nearest multiple of four. +// Pixel data may be stored with padding. +// https://learn.microsoft.com/en-us/windows/win32/medfound/image-stride +inline MxLong AlignToFourByte(MxLong p_value) +{ + return (p_value + 3) & -4; +} + +// Same as the one from legoutil.h, but flipped the other way +// TODO: While it's not outside the realm of possibility that they +// reimplemented Abs for only this file, that seems odd, right? +inline MxLong _Abs(MxLong p_value) +{ + return p_value > 0 ? p_value : -p_value; +} + // OFFSET: LEGO1 0x100bcc40 MxResult MxBitmap::ImportBitmap(MxBitmap *p_bitmap) { - MxLong height; MxResult result = FAILURE; this->m_info = new MxBITMAPINFO; if(this->m_info) { - height = p_bitmap->m_bmiHeader->biHeight; - if (height <= 0L) { - height = -height; - } - this->m_data = (LPVOID*) new MxU8[(p_bitmap->m_bmiHeader->biWidth + 3U & -4) * height]; + MxLong height = _Abs(p_bitmap->m_bmiHeader->biHeight); + this->m_data = new MxU8[AlignToFourByte(p_bitmap->m_bmiHeader->biWidth) * height]; if(this->m_data) { - memcpy(this->m_info, p_bitmap->m_info, sizeof(MxBITMAPINFO)); - - height = p_bitmap->m_bmiHeader->biHeight; - if (height <= 0L) { - height = -height; - } - memcpy(this->m_data, p_bitmap->m_data, (p_bitmap->m_bmiHeader->biWidth + 3U & -4) * height); + memcpy(this->m_info, p_bitmap->m_info, sizeof(*this->m_info)); + height = _Abs(p_bitmap->m_bmiHeader->biHeight); + memcpy(this->m_data, p_bitmap->m_data, AlignToFourByte(p_bitmap->m_bmiHeader->biWidth) * height); result = SUCCESS; this->m_bmiHeader = &this->m_info->bmiHeader; this->m_paletteData = this->m_info->bmiColors; } } + if (result != SUCCESS) { if (this->m_info) { delete this->m_info; this->m_info = NULL; } + if (this->m_data) { delete this->m_data; this->m_data = NULL; } } + return result; } @@ -76,29 +88,31 @@ MxResult MxBitmap::ImportBitmapInfo(MxBITMAPINFO *p_info) MxResult result = FAILURE; MxLong width = p_info->bmiHeader.biWidth; MxLong height = p_info->bmiHeader.biHeight; - // ((width + 3) & -4) clamps width to nearest 4-byte boundary - MxLong size = ((width + 3) & -4) * height; + MxLong size = AlignToFourByte(width) * height; this->m_info = new MxBITMAPINFO; if (this->m_info) { - this->m_data = (LPVOID*) new MxU8[size]; + this->m_data = new MxU8[size]; if(this->m_data) { - memcpy(this->m_info, p_info, sizeof(MxBITMAPINFO)); + memcpy(this->m_info, p_info, sizeof(*this->m_info)); this->m_bmiHeader = &this->m_info->bmiHeader; this->m_paletteData = this->m_info->bmiColors; result = SUCCESS; } } + if (result != SUCCESS) { if (this->m_info) { delete this->m_info; this->m_info = NULL; } + if (this->m_data) { delete this->m_data; this->m_data = NULL; } } + return result; } @@ -118,7 +132,7 @@ MxResult MxBitmap::ImportColorsToPalette(RGBQUAD* p_rgbquad, MxPalette* p_palett return ret; } - for (int i = 0; i < 256; i++) { + for (MxS32 i = 0; i < 256; i++) { p_rgbquad[i].rgbRed = entries[i].peRed; p_rgbquad[i].rgbGreen = entries[i].peGreen; p_rgbquad[i].rgbBlue = entries[i].peBlue; @@ -130,14 +144,14 @@ MxResult MxBitmap::ImportColorsToPalette(RGBQUAD* p_rgbquad, MxPalette* p_palett } // OFFSET: LEGO1 0x100bcaa0 -MxResult MxBitmap::SetSize(int p_width, int p_height, MxPalette *p_palette, int p_bitDepth) +MxResult MxBitmap::SetSize(MxS32 p_width, MxS32 p_height, MxPalette *p_palette, MxBool p_isHighColor) { MxResult ret = FAILURE; - MxLong size = ((p_width + 3) & -4) * p_height; + MxLong size = AlignToFourByte(p_width) * p_height; m_info = new MxBITMAPINFO; if (m_info) { - m_data = (LPVOID*) new MxU8[size]; + m_data = new MxU8[size]; if (m_data) { m_bmiHeader = &m_info->bmiHeader; m_paletteData = m_info->bmiColors; @@ -152,7 +166,7 @@ MxResult MxBitmap::SetSize(int p_width, int p_height, MxPalette *p_palette, int m_bmiHeader->biSizeImage = size; if (!ImportColorsToPalette(m_paletteData, p_palette)) { - if (!SetBitDepth(p_bitDepth)) { + if (!SetBitDepth(p_isHighColor)) { ret = SUCCESS; } } @@ -177,34 +191,26 @@ MxResult MxBitmap::SetSize(int p_width, int p_height, MxPalette *p_palette, int // OFFSET: LEGO1 0x100bcd60 MxResult MxBitmap::LoadFile(HANDLE p_handle) { - BOOL ret; - LPVOID* lpBuffer; - MxLong height; MxResult result = FAILURE; DWORD bytesRead; BITMAPFILEHEADER hdr; - MxLong size; - ret = ReadFile(p_handle, &hdr, sizeof(hdr), &bytesRead, NULL); + BOOL ret = ReadFile(p_handle, &hdr, sizeof(hdr), &bytesRead, NULL); if (ret && (hdr.bfType == g_bitmapSignature)) { this->m_info = new MxBITMAPINFO; - if(this->m_info) { - ret = ReadFile(p_handle, this->m_info, sizeof(MxBITMAPINFO), &bytesRead, NULL); - if (ret && ((this->m_info->bmiHeader).biBitCount == 8)) { - size = hdr.bfSize - (sizeof(MxBITMAPINFO) + sizeof(BITMAPFILEHEADER)); - lpBuffer = (LPVOID*) new MxU8[size]; - this->m_data = lpBuffer; - if (lpBuffer) { - ret = ReadFile(p_handle, lpBuffer, size, &bytesRead, NULL); - if(ret) { + if (this->m_info) { + ret = ReadFile(p_handle, this->m_info, sizeof(*this->m_info), &bytesRead, NULL); + if (ret && (this->m_info->bmiHeader.biBitCount == 8)) { + MxLong size = hdr.bfSize - (sizeof(MxBITMAPINFO) + sizeof(BITMAPFILEHEADER)); + this->m_data = new MxU8[size]; + if (this->m_data) { + ret = ReadFile(p_handle, this->m_data, size, &bytesRead, NULL); + if (ret) { this->m_bmiHeader = &this->m_info->bmiHeader; this->m_paletteData = this->m_info->bmiColors; - if((this->m_info->bmiHeader).biSizeImage == 0) { - height = (this->m_info->bmiHeader).biHeight; - if (height <= 0L) { - height = -height; - } - (this->m_info->bmiHeader).biSizeImage = ((this->m_info->bmiHeader).biWidth + 3U & -4) * height; + if (this->m_info->bmiHeader.biSizeImage == 0) { + MxLong height = _Abs(this->m_info->bmiHeader.biHeight); + this->m_info->bmiHeader.biSizeImage = AlignToFourByte(this->m_info->bmiHeader.biWidth) * height; } result = SUCCESS; } @@ -212,16 +218,19 @@ MxResult MxBitmap::LoadFile(HANDLE p_handle) } } } + if (result != SUCCESS) { if (this->m_info) { delete this->m_info; this->m_info = NULL; } + if (this->m_data) { delete this->m_data; this->m_data = NULL; } } + return result; } @@ -270,14 +279,14 @@ MxPalette *MxBitmap::CreatePalette() MxBool success = FALSE; MxPalette *palette = NULL; - switch (this->m_bitDepth) { - case LOWCOLOR: + switch (this->m_isHighColor) { + case FALSE: palette = new MxPalette(this->m_paletteData); if (palette) success = TRUE; break; - case HIGHCOLOR: + case TRUE: palette = this->m_palette->Clone(); if (palette) success = TRUE; @@ -295,14 +304,13 @@ MxPalette *MxBitmap::CreatePalette() // OFFSET: LEGO1 0x100bd280 void MxBitmap::ImportPalette(MxPalette* p_palette) { - // This is weird but it matches. Maybe m_bmiColorsProvided had more - // potential values than just true/false at some point? - switch (this->m_bitDepth) { - case LOWCOLOR: + // Odd to use a switch on a boolean, but it matches. + switch (this->m_isHighColor) { + case FALSE: ImportColorsToPalette(this->m_paletteData, p_palette); break; - case HIGHCOLOR: + case TRUE: if (this->m_palette) { delete this->m_palette; } @@ -312,18 +320,17 @@ void MxBitmap::ImportPalette(MxPalette* p_palette) } // OFFSET: LEGO1 0x100bd2d0 -MxResult MxBitmap::SetBitDepth(MxBool p_bitDepth) +MxResult MxBitmap::SetBitDepth(MxBool p_isHighColor) { MxResult ret = FAILURE; MxPalette *pal = NULL; - if (m_bitDepth == p_bitDepth) { + if (m_isHighColor == p_isHighColor) { // no change: do nothing. ret = SUCCESS; } else { - // TODO: Another switch used for this boolean value? Is it not a bool? - switch (p_bitDepth) { - case 0: + switch (p_isHighColor) { + case FALSE: ImportColorsToPalette(m_paletteData, m_palette); if (m_palette) delete m_palette; @@ -331,7 +338,7 @@ MxResult MxBitmap::SetBitDepth(MxBool p_bitDepth) m_palette = NULL; break; - case 1: + case TRUE: pal = NULL; pal = new MxPalette(m_paletteData); if (pal) { @@ -343,7 +350,7 @@ MxResult MxBitmap::SetBitDepth(MxBool p_bitDepth) buf[i] = i; } - m_bitDepth = p_bitDepth; + m_isHighColor = p_isHighColor; ret = SUCCESS; } break; @@ -359,12 +366,12 @@ MxResult MxBitmap::SetBitDepth(MxBool p_bitDepth) } // OFFSET: LEGO1 0x100bd3e0 -MxResult MxBitmap::StretchBits(HDC p_hdc, int p_xSrc, int p_ySrc, int p_xDest, int p_yDest, int p_destWidth, int p_destHeight) +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)) { p_ySrc = (this->m_bmiHeader->biHeight - p_destHeight) - p_ySrc; } - return StretchDIBits(p_hdc, p_xDest, p_yDest, p_destWidth, p_destHeight, p_xSrc, p_ySrc, p_destWidth, p_destHeight, this->m_data, (BITMAPINFO*)this->m_info, this->m_bitDepth, SRCCOPY); -} \ No newline at end of file + return StretchDIBits(p_hdc, p_xDest, p_yDest, p_destWidth, p_destHeight, p_xSrc, p_ySrc, p_destWidth, p_destHeight, this->m_data, (BITMAPINFO*)this->m_info, this->m_isHighColor, SRCCOPY); +} diff --git a/LEGO1/mxbitmap.h b/LEGO1/mxbitmap.h index 791581c6..53b01e16 100644 --- a/LEGO1/mxbitmap.h +++ b/LEGO1/mxbitmap.h @@ -21,10 +21,6 @@ struct MxBITMAPINFO { RGBQUAD bmiColors[256]; }; -// These values are the bit depth, set in the registry -#define LOWCOLOR 0 // 256 color -#define HIGHCOLOR 1 // High Color (16-bit) - // SIZE 0x20 // VTABLE 0x100dc7b0 class MxBitmap : public MxCore @@ -35,7 +31,7 @@ class MxBitmap : public MxCore virtual MxResult ImportBitmap(MxBitmap *p_bitmap); // vtable+14 virtual MxResult ImportBitmapInfo(MxBITMAPINFO *p_info); // vtable+18 - virtual MxResult SetSize(int p_width, int p_height, MxPalette *p_palette, int); // vtable+1c + virtual MxResult SetSize(MxS32 p_width, MxS32 p_height, MxPalette *p_palette, MxBool); // vtable+1c virtual MxResult LoadFile(HANDLE p_handle); // vtable+20 __declspec(dllexport) virtual MxLong Read(const char *p_filename); // vtable+24 virtual int vtable28(int); @@ -44,7 +40,7 @@ class MxBitmap : public MxCore __declspec(dllexport) virtual MxPalette *CreatePalette(); // vtable+34 virtual void ImportPalette(MxPalette* p_palette); // vtable+38 virtual MxResult SetBitDepth(MxBool); // vtable+3c - virtual MxResult StretchBits(HDC p_hdc, int p_xSrc, int p_ySrc, int p_xDest, int p_yDest, int p_destWidth, int p_destHeight); // vtable+40 + 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; } @@ -54,8 +50,8 @@ class MxBitmap : public MxCore MxBITMAPINFO *m_info; // 0x8 BITMAPINFOHEADER *m_bmiHeader; // 0xc RGBQUAD *m_paletteData; // 0x10 - LPVOID *m_data; // 0x14 - MxBool m_bitDepth; // 0x18 + MxU8 *m_data; // 0x14 + MxBool m_isHighColor; // 0x18 MxPalette *m_palette; // 0x1c }; diff --git a/LEGO1/mxdiskstreamcontroller.cpp b/LEGO1/mxdiskstreamcontroller.cpp index 9e37edc4..0c74c3a7 100644 --- a/LEGO1/mxdiskstreamcontroller.cpp +++ b/LEGO1/mxdiskstreamcontroller.cpp @@ -16,6 +16,52 @@ MxDiskStreamController::~MxDiskStreamController() MxResult MxDiskStreamController::Tickle() { // TODO - return 0; } + +// OFFSET: LEGO1 0x100c7790 STUB +MxResult MxDiskStreamController::Open(const char *p_filename) +{ + // TODO + return FAILURE; +} + +// OFFSET: LEGO1 0x100c7880 +MxResult MxDiskStreamController::vtable0x18(undefined4 p_unknown, undefined4 p_unknown2) +{ + return SUCCESS; +} + +// OFFSET: LEGO1 0x100c7ff0 STUB +MxResult MxDiskStreamController::vtable0x20(MxDSAction* p_action) +{ + // TODO + return FAILURE; +} + +// OFFSET: LEGO1 0x100c8160 STUB +MxResult MxDiskStreamController::vtable0x24(undefined4 p_unknown) +{ + // TODO + return FAILURE; +} + +// OFFSET: LEGO1 0x100c7ac0 STUB +MxResult MxDiskStreamController::vtable0x28() +{ + // TODO + return FAILURE; +} + +// OFFSET: LEGO1 0x100c7c00 STUB +MxResult MxDiskStreamController::vtable0x30(undefined4 p_unknown) +{ + // TODO + return FAILURE; +} + +// OFFSET: LEGO1 0x100c7960 +MxResult MxDiskStreamController::vtable0x34(undefined4 p_unknown) +{ + return FAILURE; +} diff --git a/LEGO1/mxdiskstreamcontroller.h b/LEGO1/mxdiskstreamcontroller.h index 1f66984c..5457a9b5 100644 --- a/LEGO1/mxdiskstreamcontroller.h +++ b/LEGO1/mxdiskstreamcontroller.h @@ -15,6 +15,13 @@ class MxDiskStreamController : public MxStreamController virtual ~MxDiskStreamController() override; virtual MxResult Tickle() override; // vtable+0x8 + virtual MxResult Open(const char *p_filename) override; // vtable+0x14 + virtual MxResult vtable0x18(undefined4 p_unknown, undefined4 p_unknown2) override; //vtable+0x18 + virtual MxResult vtable0x20(MxDSAction* p_action) override; //vtable+0x20 + virtual MxResult vtable0x24(undefined4 p_unknown) override; //vtable+0x24 + virtual MxResult vtable0x28() override; //vtable+0x28 + virtual MxResult vtable0x30(undefined4 p_unknown) override; //vtable+0x30 + virtual MxResult vtable0x34(undefined4 p_unknown); //vtable+0x34 // OFFSET: LEGO1 0x100c7360 inline virtual const char *ClassName() const override // vtable+0x0c diff --git a/LEGO1/mxdiskstreamprovider.cpp b/LEGO1/mxdiskstreamprovider.cpp index 4dcb02cf..9555a8cf 100644 --- a/LEGO1/mxdiskstreamprovider.cpp +++ b/LEGO1/mxdiskstreamprovider.cpp @@ -45,4 +45,41 @@ MxResult MxDiskStreamProvider::WaitForWorkToComplete() void MxDiskStreamProvider::PerformWork() { // TODO -} \ No newline at end of file +} + +// OFFSET: LEGO1 0x100d13d0 STUB +MxResult MxDiskStreamProvider::SetResourceToGet(void* p_resource) +{ + // TODO + return FAILURE; +} + +// OFFSET: LEGO1 0x100d1e90 +MxU32 MxDiskStreamProvider::GetFileSize() +{ + return m_pFile->GetBufferSize(); +} + +// OFFSET: LEGO1 0x100d1ea0 +MxU32 MxDiskStreamProvider::GetStreamBuffersNum() +{ + return m_pFile->GetStreamBuffersNum(); +} + +// OFFSET: LEGO1 0x100d15e0 STUB +void MxDiskStreamProvider::vtable0x20(undefined4 p_unknown1) +{ + // TODO +} + +// OFFSET: LEGO1 0x100d1eb0 +MxU32 MxDiskStreamProvider::GetLengthInDWords() +{ + return m_pFile->GetLengthInDWords(); +} + +// OFFSET: LEGO1 0x100d1ec0 +MxU32* MxDiskStreamProvider::GetBufferForDWords() +{ + return m_pFile->GetBuffer(); +} diff --git a/LEGO1/mxdiskstreamprovider.h b/LEGO1/mxdiskstreamprovider.h index c797a0de..de807e3d 100644 --- a/LEGO1/mxdiskstreamprovider.h +++ b/LEGO1/mxdiskstreamprovider.h @@ -49,6 +49,13 @@ class MxDiskStreamProvider : public MxStreamProvider void PerformWork(); + virtual MxResult SetResourceToGet(void* p_resource) override; //vtable+0x14 + virtual MxU32 GetFileSize() override; //vtable+0x18 + virtual MxU32 GetStreamBuffersNum() override; //vtable+0x1c + virtual void vtable0x20(undefined4 p_unknown1) override; //vtable+0x20 + virtual MxU32 GetLengthInDWords() override; //vtable+0x24 + virtual MxU32* GetBufferForDWords() override; //vtable+0x28 + private: MxDiskStreamProviderThread m_thread; // 0x10 MxSemaphore m_busySemaphore; // 0x2c diff --git a/LEGO1/mxdsfile.cpp b/LEGO1/mxdsfile.cpp index ca6e96fb..d1c87032 100644 --- a/LEGO1/mxdsfile.cpp +++ b/LEGO1/mxdsfile.cpp @@ -81,7 +81,7 @@ MxLong MxDSFile::ReadChunks() } MxULong* pLengthInDWords = &m_lengthInDWords; m_io.Read(pLengthInDWords, 4); - m_pBuffer = malloc(*pLengthInDWords * 4); + m_pBuffer = new MxU32[*pLengthInDWords]; m_io.Read(m_pBuffer, *pLengthInDWords * 4); return 0; } @@ -120,7 +120,7 @@ MxLong MxDSFile::Close() if (m_lengthInDWords != 0) { m_lengthInDWords = 0; - free(m_pBuffer); + delete[] m_pBuffer; m_pBuffer = NULL; } return 0; diff --git a/LEGO1/mxdsmediaaction.cpp b/LEGO1/mxdsmediaaction.cpp index 19f3bde2..125156d7 100644 --- a/LEGO1/mxdsmediaaction.cpp +++ b/LEGO1/mxdsmediaaction.cpp @@ -8,8 +8,8 @@ DECOMP_SIZE_ASSERT(MxDSMediaAction, 0xb8) MxDSMediaAction::MxDSMediaAction() { this->m_mediaSrcPath = NULL; - this->m_unk9c = 0; - this->m_unka0 = 0; + this->m_unk9c.m_unk00 = 0; + this->m_unk9c.m_unk04 = 0; this->m_framesPerSecond = 0; this->m_mediaFormat = 0; this->m_paletteManagement = 1; @@ -29,10 +29,7 @@ void MxDSMediaAction::CopyFrom(MxDSMediaAction &p_dsMediaAction) { CopyMediaSrcPath(p_dsMediaAction.m_mediaSrcPath); - // TODO this->m_unk9c = p_dsMediaAction.m_unk9c; - this->m_unka0 = p_dsMediaAction.m_unka0; - this->m_framesPerSecond = p_dsMediaAction.m_framesPerSecond; this->m_mediaFormat = p_dsMediaAction.m_mediaFormat; this->m_paletteManagement = p_dsMediaAction.m_paletteManagement; @@ -71,8 +68,8 @@ void MxDSMediaAction::Deserialize(char **p_source, MxS16 p_unk24) MxDSAction::Deserialize(p_source, p_unk24); GetString(p_source, this->m_mediaSrcPath, this, &MxDSMediaAction::CopyMediaSrcPath); - GetScalar(p_source, this->m_unk9c); - GetScalar(p_source, this->m_unka0); + GetScalar(p_source, this->m_unk9c.m_unk00); + GetScalar(p_source, this->m_unk9c.m_unk04); GetScalar(p_source, this->m_framesPerSecond); GetScalar(p_source, this->m_mediaFormat); GetScalar(p_source, this->m_paletteManagement); diff --git a/LEGO1/mxdsmediaaction.h b/LEGO1/mxdsmediaaction.h index 34b6695e..a6303227 100644 --- a/LEGO1/mxdsmediaaction.h +++ b/LEGO1/mxdsmediaaction.h @@ -3,6 +3,7 @@ #include "decomp.h" #include "mxdsaction.h" +#include "mxpoint32.h" // VTABLE 0x100dcd40 // SIZE 0xb8 @@ -38,8 +39,10 @@ class MxDSMediaAction : public MxDSAction private: MxU32 m_sizeOnDisk; char *m_mediaSrcPath; - undefined4 m_unk9c; - undefined4 m_unka0; + struct { + undefined4 m_unk00; + undefined4 m_unk04; + } m_unk9c; MxS32 m_framesPerSecond; MxS32 m_mediaFormat; MxS32 m_paletteManagement; diff --git a/LEGO1/mxdsmultiaction.h b/LEGO1/mxdsmultiaction.h index 1689cc2d..4e516333 100644 --- a/LEGO1/mxdsmultiaction.h +++ b/LEGO1/mxdsmultiaction.h @@ -37,10 +37,8 @@ class MxDSMultiAction : public MxDSAction virtual MxBool HasId(MxU32 p_objectId) override; // vtable+34; virtual void SetSomeTimingField(MxLong p_someTimingField) override; // vtable+38; -private: - MxU32 m_sizeOnDisk; - protected: + MxU32 m_sizeOnDisk; MxDSActionList *m_actions; }; diff --git a/LEGO1/mxdsobject.h b/LEGO1/mxdsobject.h index e340789a..cfb5d6a1 100644 --- a/LEGO1/mxdsobject.h +++ b/LEGO1/mxdsobject.h @@ -47,15 +47,15 @@ class MxDSObject : public MxCore inline MxDSType GetType() const { return (MxDSType) this->m_type; } private: - MxU32 m_sizeOnDisk; - MxU16 m_type; - char* m_sourceName; - undefined4 m_unk14; - char *m_objectName; - MxU32 m_objectId; - MxAtomId m_atomId; - MxS16 m_unk24; - undefined4 m_unk28; + MxU32 m_sizeOnDisk; // 0x8 + MxU16 m_type; // 0xc + char* m_sourceName; // 0x10 + undefined4 m_unk14; // 0x14 + char *m_objectName; // 0x18 + MxU32 m_objectId; // 0x1c + MxAtomId m_atomId; // 0x20 + MxS16 m_unk24; // 0x24 + undefined4 m_unk28; // 0x28 }; MxDSObject *DeserializeDSObjectDispatch(char **, MxS16); diff --git a/LEGO1/mxdsselectaction.cpp b/LEGO1/mxdsselectaction.cpp index 58af9543..e49f587a 100644 --- a/LEGO1/mxdsselectaction.cpp +++ b/LEGO1/mxdsselectaction.cpp @@ -1,4 +1,7 @@ #include "mxdsselectaction.h" +#include "mxvariabletable.h" +#include "mxtimer.h" +#include "mxomni.h" DECOMP_SIZE_ASSERT(MxDSSelectAction, 0xb0) @@ -48,4 +51,81 @@ MxDSAction *MxDSSelectAction::Clone() *clone = *this; return clone; +} + +// OFFSET: LEGO1 0x100cbe10 +MxU32 MxDSSelectAction::GetSizeOnDisk() +{ + MxU32 totalSizeOnDisk = MxDSParallelAction::GetSizeOnDisk(); + + totalSizeOnDisk += strlen(this->m_unk0x9c.GetData()) + 1; + + MxStringListCursor cursor(this->m_unk0xac); + MxString string; + while (cursor.Next(string)) + totalSizeOnDisk += strlen(string.GetData()) + 1; + + // Note: unlike the other classes, MxDSSelectAction does not have its own + // sizeOnDisk member. Instead, it overrides the one from MxDSMultiAction. + this->m_sizeOnDisk = totalSizeOnDisk; + + return totalSizeOnDisk; +} + +// OFFSET: LEGO1 0x100cbf60 +void MxDSSelectAction::Deserialize(char **p_source, MxS16 p_unk24) +{ + MxString string; + MxDSAction::Deserialize(p_source, p_unk24); + + MxU32 extraFlag = *(MxU32*)(*p_source + 4) & 1; + *p_source += 12; + + this->m_unk0x9c = *p_source; + + if (!strnicmp(this->m_unk0x9c.GetData(), "RANDOM_", strlen("RANDOM_"))) { + char buffer[10]; + MxS16 value = atoi(&this->m_unk0x9c.GetData()[strlen("RANDOM_")]); + + srand(Timer()->GetTime()); + MxS32 random = rand() % value; + string = itoa((MxS16) random, buffer, 10); + } + else + string = VariableTable()->GetVariable(*p_source); + + *p_source += strlen(*p_source) + 1; + + MxU32 count = *(MxU32*) *p_source; + *p_source += sizeof(MxU32); + + if (count) { + MxS32 index = -1; + this->m_unk0xac->DeleteAll(); + + MxU32 i; + for (i = 0; i < count; i++) { + if (!strcmp(string.GetData(), *p_source)) + index = i; + + this->m_unk0xac->OtherAppend(*p_source); + *p_source += strlen(*p_source) + 1; + } + + for (i = 0; i < count; i++) { + MxU32 extraFlag = *(MxU32*)(*p_source + 4) & 1; + *p_source += 8; + + MxDSAction *action = (MxDSAction*) DeserializeDSObjectDispatch(p_source, p_unk24); + + if (index == i) + this->m_actions->Append(action); + else + delete action; + + *p_source += extraFlag; + } + } + + *p_source += extraFlag; } \ No newline at end of file diff --git a/LEGO1/mxdsselectaction.h b/LEGO1/mxdsselectaction.h index 746afc87..7b668a15 100644 --- a/LEGO1/mxdsselectaction.h +++ b/LEGO1/mxdsselectaction.h @@ -29,9 +29,8 @@ class MxDSSelectAction : public MxDSParallelAction return !strcmp(name, MxDSSelectAction::ClassName()) || MxDSParallelAction::IsA(name); } - //virtual MxU32 GetSizeOnDisk() override; // vtable+18; - //virtual void Deserialize(char **p_source, MxS16 p_unk24) override; // vtable+1c; - //virtual MxLong GetDuration() override; // vtable+24; + virtual MxU32 GetSizeOnDisk() override; // vtable+18; + virtual void Deserialize(char **p_source, MxS16 p_unk24) override; // vtable+1c; virtual MxDSAction *Clone() override; // vtable+2c; private: diff --git a/LEGO1/mxdssource.cpp b/LEGO1/mxdssource.cpp index 4dfb5386..86c4f9fb 100644 --- a/LEGO1/mxdssource.cpp +++ b/LEGO1/mxdssource.cpp @@ -14,7 +14,7 @@ MxLong MxDSSource::GetLengthInDWords() } // OFFSET: LEGO1 0x100c0000 -void *MxDSSource::GetBuffer() +MxU32 *MxDSSource::GetBuffer() { return m_pBuffer; } \ No newline at end of file diff --git a/LEGO1/mxdssource.h b/LEGO1/mxdssource.h index 67cbc6c7..626eaf37 100644 --- a/LEGO1/mxdssource.h +++ b/LEGO1/mxdssource.h @@ -34,11 +34,11 @@ class MxDSSource : public MxCore virtual MxULong GetBufferSize() = 0; virtual MxULong GetStreamBuffersNum() = 0; virtual MxLong GetLengthInDWords(); - virtual void* GetBuffer(); // 0x34 + virtual MxU32* GetBuffer(); // 0x34 protected: MxULong m_lengthInDWords; - void* m_pBuffer; + MxU32* m_pBuffer; MxLong m_position; }; diff --git a/LEGO1/mxmediapresenter.h b/LEGO1/mxmediapresenter.h index 167b10c1..6b8fd552 100644 --- a/LEGO1/mxmediapresenter.h +++ b/LEGO1/mxmediapresenter.h @@ -43,9 +43,10 @@ class MxMediaPresenter : public MxPresenter undefined4 m_unk44; undefined4 m_unk48; undefined4 m_unk4c; +protected: + void Destroy(MxBool); private: void Init(); - void Destroy(MxBool); }; diff --git a/LEGO1/mxmusicpresenter.cpp b/LEGO1/mxmusicpresenter.cpp index 45a56679..f376c64f 100644 --- a/LEGO1/mxmusicpresenter.cpp +++ b/LEGO1/mxmusicpresenter.cpp @@ -23,10 +23,18 @@ void MxMusicPresenter::Init() { } -// OFFSET: LEGO1 0x100c2550 STUB -void MxMusicPresenter::Destroy(MxBool) +// OFFSET: LEGO1 0x100c2550 +void MxMusicPresenter::Destroy(MxBool p_reinit) { - // TODO + if (MusicManager()) { + MusicManager()->RemovePresenter(*this); + } + m_criticalSection.Enter(); + Init(); + m_criticalSection.Leave(); + if (!p_reinit) { + MxMediaPresenter::Destroy(FALSE); + } } // OFFSET: LEGO1 0x100c25a0 diff --git a/LEGO1/mxmusicpresenter.h b/LEGO1/mxmusicpresenter.h index 2e55aa6c..ff765786 100644 --- a/LEGO1/mxmusicpresenter.h +++ b/LEGO1/mxmusicpresenter.h @@ -29,7 +29,7 @@ class MxMusicPresenter : public MxAudioPresenter private: void Init(); - void Destroy(MxBool); + void Destroy(MxBool p_reinit); }; #endif // MXMUSICPRESENTER_H diff --git a/LEGO1/mxnotificationmanager.cpp b/LEGO1/mxnotificationmanager.cpp index cb653ba4..017df73d 100644 --- a/LEGO1/mxnotificationmanager.cpp +++ b/LEGO1/mxnotificationmanager.cpp @@ -13,7 +13,7 @@ DECOMP_SIZE_ASSERT(MxNotification, 0x8); DECOMP_SIZE_ASSERT(MxNotificationManager, 0x40); // OFFSET: LEGO1 0x100ac220 -MxNotification::MxNotification(MxCore *p_target, MxParam *p_param) +MxNotification::MxNotification(MxCore *p_target, MxNotificationParam *p_param) { m_target = p_target; m_param = p_param->Clone(); @@ -161,7 +161,7 @@ void MxNotificationManager::FlushPending(MxCore *p_listener) } // OFFSET: LEGO1 0x100ac6c0 -MxResult MxNotificationManager::Send(MxCore *p_listener, MxParam *p_param) +MxResult MxNotificationManager::Send(MxCore *p_listener, MxNotificationParam *p_param) { MxAutoLocker lock(&m_lock); diff --git a/LEGO1/mxnotificationmanager.h b/LEGO1/mxnotificationmanager.h index 1c2aee7c..89908871 100644 --- a/LEGO1/mxnotificationmanager.h +++ b/LEGO1/mxnotificationmanager.h @@ -3,6 +3,7 @@ #include "mxcore.h" #include "mxcriticalsection.h" +#include "mxnotificationparam.h" #include "mxtypes.h" #include "compat.h" @@ -10,22 +11,15 @@ class MxNotification { public: - MxNotification(MxCore *p_target, MxParam *p_param); + MxNotification(MxCore *p_target, MxNotificationParam *p_param); ~MxNotification(); - inline MxCore *GetTarget() - { - return m_target; - } - - inline MxParam *GetParam() - { - return m_param; - } + inline MxCore *GetTarget() { return m_target; } + inline MxNotificationParam *GetParam() { return m_param; } private: MxCore *m_target; // 0x0 - MxParam *m_param; // 0x4 + MxNotificationParam *m_param; // 0x4 }; class MxIdList : public list @@ -54,7 +48,7 @@ class MxNotificationManager : public MxCore virtual MxResult Create(MxS32 p_unk1, MxS32 p_unk2); // vtable+0x14 void Register(MxCore *p_listener); void Unregister(MxCore *p_listener); - MxResult Send(MxCore *p_listener, MxParam *p_param); + MxResult Send(MxCore *p_listener, MxNotificationParam *p_param); private: void FlushPending(MxCore *p_listener); diff --git a/LEGO1/mxnotificationparam.cpp b/LEGO1/mxnotificationparam.cpp new file mode 100644 index 00000000..16a0b41f --- /dev/null +++ b/LEGO1/mxnotificationparam.cpp @@ -0,0 +1,11 @@ +#include "mxnotificationparam.h" + +#include "decomp.h" + +DECOMP_SIZE_ASSERT(MxNotificationParam, 0xc); + +// OFFSET: LEGO1 0x10010390 +MxNotificationParam* MxNotificationParam::Clone() +{ + return new MxNotificationParam(m_type, m_sender); +} diff --git a/LEGO1/mxnotificationparam.h b/LEGO1/mxnotificationparam.h new file mode 100644 index 00000000..a02f33d8 --- /dev/null +++ b/LEGO1/mxnotificationparam.h @@ -0,0 +1,35 @@ +#ifndef MXNOTIFICATIONPARAM_H +#define MXNOTIFICATIONPARAM_H + +#include "compat.h" +#include "mxparam.h" +#include "mxtypes.h" + +class MxCore; + +enum MxParamType +{ + MXSTREAMER_UNKNOWN = 2, + MXPRESENTER_NOTIFICATION = 5, + MXSTREAMER_DELETE_NOTIFY = 6, + MXTRANSITIONMANAGER_TRANSITIONENDED = 24 +}; + +// VTABLE 0x100d56e0 +class MxNotificationParam : public MxParam +{ +public: + inline MxNotificationParam(MxParamType p_type, MxCore *p_sender) : MxParam(), m_type(p_type), m_sender(p_sender){} + + virtual ~MxNotificationParam() override {} // vtable+0x0 (scalar deleting destructor) + virtual MxNotificationParam *Clone(); // vtable+0x4 + + inline MxParamType GetType() const { return m_type; } + inline MxCore *GetSender() const { return m_sender; } + +protected: + MxParamType m_type; // 0x4 + MxCore *m_sender; // 0x8 +}; + +#endif // MXNOTIFICATIONPARAM_H diff --git a/LEGO1/mxomni.cpp b/LEGO1/mxomni.cpp index fb3251da..43b9578a 100644 --- a/LEGO1/mxomni.cpp +++ b/LEGO1/mxomni.cpp @@ -93,10 +93,9 @@ int MxOmni::vtable0x30(char*, int, MxCore*) return 0; } -// OFFSET: LEGO1 0x100aefc0 STUB -void MxOmni::NotifyCurrentEntity() +// OFFSET: LEGO1 0x100aefc0 +void MxOmni::NotifyCurrentEntity(MxParam *p_param) { - // TODO } // OFFSET: LEGO1 0x100b09d0 @@ -121,6 +120,12 @@ void MxOmni::StopTimer() } } +// OFFSET: LEGO1 0x10058a90 +MxBool MxOmni::IsTimerRunning() +{ + return m_timerRunning; +} + // OFFSET: LEGO1 0x100b0690 void MxOmni::DestroyInstance() { @@ -346,7 +351,7 @@ MxLong MxOmni::Notify(MxParam &p) { MxAutoLocker lock(&this->m_criticalsection); - if (p.GetType() != MXSTREAMER_UNKNOWN) + if (((MxNotificationParam&) p).GetType() != MXSTREAMER_UNKNOWN) return 0; return HandleNotificationType2(p); diff --git a/LEGO1/mxomni.h b/LEGO1/mxomni.h index 5290c6ed..265db29b 100644 --- a/LEGO1/mxomni.h +++ b/LEGO1/mxomni.h @@ -45,9 +45,10 @@ 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(); // vtable+34 + virtual void NotifyCurrentEntity(MxParam *p_param); // vtable+34 virtual void StartTimer(); // vtable+38 virtual void StopTimer(); // vtable+3c + virtual MxBool IsTimerRunning(); //vtable+40 static void SetInstance(MxOmni* instance); HWND GetWindowHandle() const { return this->m_windowHandle; } MxObjectFactory* GetObjectFactory() const { return this->m_objectFactory; } diff --git a/LEGO1/mxomnicreateparam.h b/LEGO1/mxomnicreateparam.h index 3c1059dd..d4984b24 100644 --- a/LEGO1/mxomnicreateparam.h +++ b/LEGO1/mxomnicreateparam.h @@ -4,11 +4,11 @@ #include #include "mxomnicreateflags.h" -#include "mxomnicreateparambase.h" +#include "mxparam.h" #include "mxstring.h" #include "mxvideoparam.h" -class MxOmniCreateParam : public MxOmniCreateParamBase +class MxOmniCreateParam : public MxParam { public: __declspec(dllexport) MxOmniCreateParam(const char *mediaPath, struct HWND__ *windowHandle, MxVideoParam &vparam, MxOmniCreateFlags flags); diff --git a/LEGO1/mxomnicreateparambase.cpp b/LEGO1/mxomnicreateparambase.cpp deleted file mode 100644 index 0091785d..00000000 --- a/LEGO1/mxomnicreateparambase.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "mxomnicreateparam.h" diff --git a/LEGO1/mxomnicreateparambase.h b/LEGO1/mxomnicreateparambase.h deleted file mode 100644 index 605f4d30..00000000 --- a/LEGO1/mxomnicreateparambase.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef MXOMNICREATEPARAMBASE_H -#define MXOMNICREATEPARAMBASE_H - -// FIXME: Clearly not its real name -class MxOmniCreateParamBase -{ -public: - virtual ~MxOmniCreateParamBase(){} - -}; - -#endif // MXOMNICREATEPARAMBASE_H diff --git a/LEGO1/mxparam.cpp b/LEGO1/mxparam.cpp index d7bb36b2..4faa1625 100644 --- a/LEGO1/mxparam.cpp +++ b/LEGO1/mxparam.cpp @@ -1,11 +1 @@ #include "mxparam.h" - -#include "decomp.h" - -DECOMP_SIZE_ASSERT(MxParam, 0xc); - -// OFFSET: LEGO1 0x10010390 -MxParam* MxParam::Clone() -{ - return new MxParam(m_type, m_sender); -} diff --git a/LEGO1/mxparam.h b/LEGO1/mxparam.h index d76ecdb0..8f89e2d0 100644 --- a/LEGO1/mxparam.h +++ b/LEGO1/mxparam.h @@ -1,42 +1,10 @@ #ifndef MXPARAM_H #define MXPARAM_H -#include "compat.h" -#include "mxomnicreateparambase.h" -#include "mxtypes.h" - -class MxCore; - -enum MxParamType -{ - MXSTREAMER_UNKNOWN = 2, - MXPRESENTER_NOTIFICATION = 5, - MXSTREAMER_DELETE_NOTIFY = 6, - MXTRANSITIONMANAGER_TRANSITIONENDED = 24 -}; - -// VTABLE 0x100d56e0 -class MxParam : public MxOmniCreateParamBase +class MxParam { public: - inline MxParam(MxParamType p_type, MxCore *p_sender) : MxOmniCreateParamBase(), m_type(p_type), m_sender(p_sender){} - - virtual ~MxParam() override {} // vtable+0x0 (scalar deleting destructor) - virtual MxParam *Clone(); // vtable+0x4 - - inline MxParamType GetType() const - { - return m_type; - } - - inline MxCore *GetSender() const - { - return m_sender; - } - -protected: - MxParamType m_type; // 0x4 - MxCore *m_sender; // 0x8 + virtual ~MxParam() {} }; #endif // MXPARAM_H diff --git a/LEGO1/mxpresenter.cpp b/LEGO1/mxpresenter.cpp index f8f60386..86e4ae26 100644 --- a/LEGO1/mxpresenter.cpp +++ b/LEGO1/mxpresenter.cpp @@ -6,7 +6,8 @@ #include "mxdsanim.h" #include "mxdssound.h" #include "mxnotificationmanager.h" - +#include "mxactionnotificationparam.h" +#include "mxstreamer.h" #include "decomp.h" #include "define.h" @@ -65,7 +66,7 @@ void MxPresenter::SendTo_unkPresenter(MxOmni *p_omni) if (m_unkPresenter) { MxAutoLocker lock(&m_criticalSection); - NotificationManager()->Send(m_unkPresenter, &MxParam(MXPRESENTER_NOTIFICATION, this)); + NotificationManager()->Send(m_unkPresenter, &MxNotificationParam(MXPRESENTER_NOTIFICATION, this)); m_action->SetOmni(p_omni ? p_omni : MxOmni::GetInstance()); m_unkPresenter = NULL; @@ -135,10 +136,21 @@ MxLong MxPresenter::StartAction(MxStreamController *, MxDSAction *p_action) return SUCCESS; } -// OFFSET: LEGO1 0x100b4e40 STUB +// OFFSET: LEGO1 0x100b4e40 void MxPresenter::EndAction() { - // TODO + if (this->m_action == FALSE) + return; + MxAutoLocker lock(&this->m_criticalSection); + if (!this->m_unkPresenter) + { + MxOmni::GetInstance()->NotifyCurrentEntity(&MxEndActionNotificationParam(MXSTREAMER_UNKNOWN, NULL, this->m_action, TRUE)); + } + + this->m_action = FALSE; + MxS32 previousTickleState = 1 << m_currentTickleState; + this->m_previousTickleStates |= previousTickleState; + this->m_currentTickleState = TickleState_Idle; } // OFFSET: LEGO1 0x100b52d0 diff --git a/LEGO1/mxpresenter.h b/LEGO1/mxpresenter.h index 959533c5..bcdc5aac 100644 --- a/LEGO1/mxpresenter.h +++ b/LEGO1/mxpresenter.h @@ -79,11 +79,11 @@ class MxPresenter : public MxCore __declspec(dllexport) void Init(); void SendTo_unkPresenter(MxOmni *); TickleState m_currentTickleState; // 0x8 - MxU32 m_previousTickleStates; - MxPoint32 m_location; - MxS32 m_displayZ; - MxDSAction *m_action; // 0 - MxCriticalSection m_criticalSection; + MxU32 m_previousTickleStates; // 0x0c + MxPoint32 m_location; // 0x10 + MxS32 m_displayZ; // 0x18 + MxDSAction *m_action; // 0x1c + MxCriticalSection m_criticalSection; // 0x20 MxPresenter *m_unkPresenter; // 0x3c }; diff --git a/LEGO1/mxramstreamprovider.cpp b/LEGO1/mxramstreamprovider.cpp index 9b052699..1b44d84f 100644 --- a/LEGO1/mxramstreamprovider.cpp +++ b/LEGO1/mxramstreamprovider.cpp @@ -41,7 +41,7 @@ MxU32 MxRAMStreamProvider::GetFileSize() } // OFFSET: LEGO1 0x100d0940 -MxU32 MxRAMStreamProvider::vtable0x1C() +MxU32 MxRAMStreamProvider::GetStreamBuffersNum() { return 1; } @@ -53,7 +53,7 @@ MxU32 MxRAMStreamProvider::GetLengthInDWords() } // OFFSET: LEGO1 0x100d0960 -void* MxRAMStreamProvider::GetBufferForDWords() +MxU32* MxRAMStreamProvider::GetBufferForDWords() { return m_bufferForDWords; } diff --git a/LEGO1/mxramstreamprovider.h b/LEGO1/mxramstreamprovider.h index 4a22b013..48e0dcae 100644 --- a/LEGO1/mxramstreamprovider.h +++ b/LEGO1/mxramstreamprovider.h @@ -9,19 +9,19 @@ class MxRAMStreamProvider : public MxStreamProvider public: MxRAMStreamProvider(); virtual ~MxRAMStreamProvider() override; - + virtual MxResult SetResourceToGet(void* p_resource) override; //vtable+0x14 virtual MxU32 GetFileSize() override; //vtable+0x18 - virtual MxU32 vtable0x1C() override; //vtable+0x1c + virtual MxU32 GetStreamBuffersNum() override; //vtable+0x1c virtual MxU32 GetLengthInDWords() override; //vtable+0x24 - virtual void* GetBufferForDWords() override; //vtable+0x28 + virtual MxU32* GetBufferForDWords() override; //vtable+0x28 protected: MxU32 m_bufferSize; MxU32 m_fileSize; void* m_pBufferOfFileSize; MxU32 m_lengthInDWords; - void* m_bufferForDWords; + MxU32* m_bufferForDWords; }; #endif // MXRAMSTREAMPROVIDER_H diff --git a/LEGO1/mxsmkpresenter.cpp b/LEGO1/mxsmkpresenter.cpp index 99faae22..d8699862 100644 --- a/LEGO1/mxsmkpresenter.cpp +++ b/LEGO1/mxsmkpresenter.cpp @@ -24,5 +24,5 @@ void MxSmkPresenter::VTable0x60() } m_bitmap = new MxBitmap(); - m_bitmap->SetSize(m_smkWidth, m_smkHeight, NULL, NULL); + m_bitmap->SetSize(m_smkWidth, m_smkHeight, NULL, FALSE); } diff --git a/LEGO1/mxstreamcontroller.cpp b/LEGO1/mxstreamcontroller.cpp index 36b85ebc..89b2fa51 100644 --- a/LEGO1/mxstreamcontroller.cpp +++ b/LEGO1/mxstreamcontroller.cpp @@ -45,11 +45,26 @@ MxResult MxStreamController::vtable0x1C(undefined4 p_unknown, undefined4 p_unkno return FAILURE; } -// OFFSET: LEGO1 0x100c1690 STUB +// OFFSET: LEGO1 0x100c1690 MxResult MxStreamController::vtable0x20(MxDSAction* p_action) { - // TODO STUB - return FAILURE; + MxAutoLocker locker(&m_criticalSection); + + MxResult result; + MxU32 offset = 0; + + MxS32 objectId = p_action->GetObjectId(); + MxStreamProvider *provider = m_provider; + + if ((MxS32) provider->GetLengthInDWords() > objectId) + offset = provider->GetBufferForDWords()[objectId]; + + if (offset) + result = vtable0x2c(p_action, offset); + else + result = FAILURE; + + return result; } // OFFSET: LEGO1 0x100c1740 STUB @@ -66,7 +81,7 @@ MxResult MxStreamController::vtable0x28() } // OFFSET: LEGO1 0x100c1c10 STUB -MxResult MxStreamController::vtable0x2c(undefined4 p_unknown1, undefined4 p_unknow2) +MxResult MxStreamController::vtable0x2c(MxDSAction* p_action, MxU32 p_bufferval) { return FAILURE; } diff --git a/LEGO1/mxstreamcontroller.h b/LEGO1/mxstreamcontroller.h index 59490d2c..539af0bd 100644 --- a/LEGO1/mxstreamcontroller.h +++ b/LEGO1/mxstreamcontroller.h @@ -7,6 +7,7 @@ #include "mxcore.h" #include "mxdsobject.h" #include "mxdsaction.h" +#include "mxstreamprovider.h" // VTABLE 0x100dc968 // SIZE 0x64 @@ -36,7 +37,7 @@ class MxStreamController : public MxCore virtual MxResult vtable0x20(MxDSAction* p_action); //vtable+0x20 virtual MxResult vtable0x24(undefined4 p_unknown); //vtable+0x24 virtual MxResult vtable0x28(); //vtable+0x28 - virtual MxResult vtable0x2c(undefined4 p_unknown1, undefined4 p_unknow2); //vtable+0x2c + virtual MxResult vtable0x2c(MxDSAction* p_action, MxU32 p_bufferval); //vtable+0x2c virtual MxResult vtable0x30(undefined4 p_unknown); //vtable+0x30 MxBool FUN_100c20d0(MxDSObject &p_obj); @@ -45,7 +46,7 @@ class MxStreamController : public MxCore protected: MxCriticalSection m_criticalSection; MxAtomId atom; - undefined4 m_unk28; // MxStreamProvider* + MxStreamProvider* m_provider; // MxStreamProvider* undefined4 m_unk2c; undefined m_unk30[0x34]; }; diff --git a/LEGO1/mxstreamer.cpp b/LEGO1/mxstreamer.cpp index 8e7cc231..e95e4558 100644 --- a/LEGO1/mxstreamer.cpp +++ b/LEGO1/mxstreamer.cpp @@ -99,7 +99,7 @@ MxLong MxStreamer::Close(const char *p) } // OFFSET: LEGO1 0x100b9700 -MxParam *MxStreamerNotification::Clone() +MxNotificationParam *MxStreamerNotification::Clone() { return new MxStreamerNotification(m_type, m_sender, m_controller); } @@ -120,7 +120,6 @@ MxStreamController *MxStreamer::GetOpenStream(const char *p_name) return NULL; } - // OFFSET: LEGO1 0x100b9930 MxResult MxStreamer::AddStreamControllerToOpenList(MxStreamController *stream) { @@ -151,7 +150,7 @@ MxResult MxStreamer::Unknown100b99b0(MxDSAction* p_action) // OFFSET: LEGO1 0x100b9b60 MxLong MxStreamer::Notify(MxParam &p) { - if (p.GetType() == MXSTREAMER_DELETE_NOTIFY) { + if (((MxNotificationParam&) p).GetType() == MXSTREAMER_DELETE_NOTIFY) { MxDSAction ds; ds.SetUnknown24(-2); @@ -178,4 +177,4 @@ MxStreamerSubClass1::MxStreamerSubClass1(undefined4 size) for (int i = 0; i >= 0; i--) { ptr[i] = 0; } -} +} \ No newline at end of file diff --git a/LEGO1/mxstreamer.h b/LEGO1/mxstreamer.h index 515be51b..529a564a 100644 --- a/LEGO1/mxstreamer.h +++ b/LEGO1/mxstreamer.h @@ -5,7 +5,7 @@ #include "decomp.h" #include "mxcore.h" -#include "mxparam.h" +#include "mxnotificationparam.h" #include "mxstreamcontroller.h" #include "mxtypes.h" @@ -40,17 +40,17 @@ class MxStreamerSubClass3 : public MxStreamerSubClass1 inline MxStreamerSubClass3() : MxStreamerSubClass1(0x80) {} }; -class MxStreamerNotification : public MxParam +class MxStreamerNotification : public MxNotificationParam { public: - inline MxStreamerNotification(MxParamType p_type, MxCore *p_sender, MxStreamController *p_ctrlr) : MxParam(p_type, p_sender) + inline MxStreamerNotification(MxParamType p_type, MxCore *p_sender, MxStreamController *p_ctrlr) : MxNotificationParam(p_type, p_sender) { m_controller = p_ctrlr; } virtual ~MxStreamerNotification() override {} - virtual MxParam *Clone() override; + virtual MxNotificationParam *Clone() override; MxStreamController *GetController() { return m_controller; } @@ -102,7 +102,6 @@ class MxStreamer : public MxCore list m_openStreams; // 0x8 MxStreamerSubClass2 m_subclass1; // 0x14 MxStreamerSubClass3 m_subclass2; // 0x20 - }; #endif // MXSTREAMER_H diff --git a/LEGO1/mxstreamprovider.h b/LEGO1/mxstreamprovider.h index 3cb11144..fb210f80 100644 --- a/LEGO1/mxstreamprovider.h +++ b/LEGO1/mxstreamprovider.h @@ -26,10 +26,10 @@ class MxStreamProvider : public MxCore virtual MxResult SetResourceToGet(void* p_resource); //vtable+0x14 virtual MxU32 GetFileSize() = 0; //vtable+0x18 - virtual MxU32 vtable0x1C() = 0; //vtable+0x1c + virtual MxU32 GetStreamBuffersNum() = 0; //vtable+0x1c virtual void vtable0x20(undefined4 p_unknown1); //vtable+0x20 virtual MxU32 GetLengthInDWords() = 0; //vtable+0x24 - virtual void* GetBufferForDWords() = 0; //vtable+0x28 + virtual MxU32* GetBufferForDWords() = 0; //vtable+0x28 protected: void *m_pLookup; diff --git a/LEGO1/mxtransitionmanager.cpp b/LEGO1/mxtransitionmanager.cpp index 66c99532..12d989c8 100644 --- a/LEGO1/mxtransitionmanager.cpp +++ b/LEGO1/mxtransitionmanager.cpp @@ -85,7 +85,7 @@ void MxTransitionManager::EndTransition(MxBool p_notifyWorld) LegoWorld *world = GetCurrentWorld(); if (world) { - world->Notify(MxParam(MXTRANSITIONMANAGER_TRANSITIONENDED, this)); + world->Notify(MxNotificationParam(MXTRANSITIONMANAGER_TRANSITIONENDED, this)); } } } diff --git a/LEGO1/mxvector.cpp b/LEGO1/mxvector.cpp index a4053105..ad4060e0 100644 --- a/LEGO1/mxvector.cpp +++ b/LEGO1/mxvector.cpp @@ -371,7 +371,7 @@ float MxVector4::DotImpl(float *p_a, float *p_b) const { return p_a[0] * p_b[0] + p_a[2] * p_b[2] + - p_a[1] * p_b[1] + p_a[3] * p_b[3]; + (p_a[1] * p_b[1] + p_a[3] * p_b[3]); } // OFFSET: LEGO1 0x10002a20 @@ -410,13 +410,14 @@ void MxVector4::EqualsScalar(float *p_value) m_data[3] = *p_value; } -// OFFSET: LEGO1 0x10002ae0 STUB -void MxVector4::unk1(MxVector4 *p_a, float *p_b) +// OFFSET: LEGO1 0x10002ae0 +void MxVector4::SetMatrixProduct(MxVector4 *p_a, float *p_b) { + SetMatrixProductImpl(p_a->m_data, p_b); } // OFFSET: LEGO1 0x10002a40 -void MxVector4::SetMatrixProduct(float *p_vec, float *p_mat) +void MxVector4::SetMatrixProductImpl(float *p_vec, float *p_mat) { m_data[0] = p_vec[0] * p_mat[0] + p_vec[1] * p_mat[4] + @@ -453,8 +454,19 @@ MxResult MxVector4::NormalizeQuaternion() return FAILURE; } -// OFFSET: LEGO1 0x10002bf0 STUB +// OFFSET: LEGO1 0x10002bf0 void MxVector4::UnknownQuaternionOp(MxVector4 *p_a, MxVector4 *p_b) { + MxFloat *bDat = p_b->m_data; + MxFloat *aDat = p_a->m_data; -} \ No newline at end of file + this->m_data[3] = aDat[3] * bDat[3] - (bDat[0] * aDat[0] + aDat[2] *bDat[2] + aDat[1] * aDat[1]); + this->m_data[0] = bDat[2] * aDat[1] - bDat[1] * aDat[2]; + this->m_data[1] = aDat[2] * bDat[0] - bDat[2] * aDat[0]; + this->m_data[2] = bDat[1] * aDat[0] - aDat[1] * bDat[0]; + + + m_data[0] = p_b->m_data[3] * p_a->m_data[0] + p_a->m_data[3] * p_b->m_data[0] + m_data[0]; + m_data[1] = p_b->m_data[1] * p_a->m_data[3] + p_a->m_data[1] * p_b->m_data[3] + m_data[1]; + m_data[2] = p_b->m_data[2] * p_a->m_data[3] + p_a->m_data[2] * p_b->m_data[3] + m_data[2]; +} diff --git a/LEGO1/mxvector.h b/LEGO1/mxvector.h index eef1d927..b2d0bf54 100644 --- a/LEGO1/mxvector.h +++ b/LEGO1/mxvector.h @@ -125,8 +125,8 @@ class MxVector4 : public MxVector3 void EqualsScalar(float *p_value); // vtable + 0x84 - virtual void unk1(MxVector4 *p_a, float *p_b); - virtual void SetMatrixProduct(float *p_vec, float *p_mat); + virtual void SetMatrixProduct(MxVector4 *p_a, float *p_b); + virtual void SetMatrixProductImpl(float *p_vec, float *p_mat); virtual MxResult NormalizeQuaternion(); virtual void UnknownQuaternionOp(MxVector4 *p_a, MxVector4 *p_b); };