diff --git a/LEGO1/legoloadcachesoundpresenter.cpp b/LEGO1/legoloadcachesoundpresenter.cpp index 4bc2cbd6..41445182 100644 --- a/LEGO1/legoloadcachesoundpresenter.cpp +++ b/LEGO1/legoloadcachesoundpresenter.cpp @@ -1,19 +1,30 @@ #include "legoloadcachesoundpresenter.h" +DECOMP_SIZE_ASSERT(LegoLoadCacheSoundPresenter, 0x90) + // FUNCTION: LEGO1 0x10018340 LegoLoadCacheSoundPresenter::LegoLoadCacheSoundPresenter() { Init(); } -// STUB: LEGO1 0x10018480 +// FUNCTION: LEGO1 0x10018480 LegoLoadCacheSoundPresenter::~LegoLoadCacheSoundPresenter() { - // TODO + Destroy(TRUE); } -// STUB: LEGO1 0x100184e0 +// FUNCTION: LEGO1 0x100184e0 void LegoLoadCacheSoundPresenter::Init() { - // TODO + this->m_unk0x70 = NULL; + this->m_unk0x78 = 0; + this->m_unk0x7c = 0; +} + +// FUNCTION: LEGO1 0x100184f0 +void LegoLoadCacheSoundPresenter::Destroy(MxBool p_fromDestructor) +{ + delete this->m_unk0x70; + MxWavePresenter::Destroy(p_fromDestructor); } diff --git a/LEGO1/legoloadcachesoundpresenter.h b/LEGO1/legoloadcachesoundpresenter.h index 6f9f473b..c9255b01 100644 --- a/LEGO1/legoloadcachesoundpresenter.h +++ b/LEGO1/legoloadcachesoundpresenter.h @@ -1,6 +1,7 @@ #ifndef LEGOLOADCACHESOUNDPRESENTER_H #define LEGOLOADCACHESOUNDPRESENTER_H +#include "decomp.h" #include "mxwavepresenter.h" // VTABLE: LEGO1 0x100d5fa8 @@ -19,6 +20,17 @@ class LegoLoadCacheSoundPresenter : public MxWavePresenter { private: void Init(); + void Destroy(MxBool p_fromDestructor); + + undefined4* m_unk0x6c; // 0x6c + undefined4* m_unk0x70; // 0x70 + undefined4 m_unk0x74; // 0x74 + undefined4 m_unk0x78; // 0x78 + undefined m_unk0x7c; // 0x7c + undefined4 m_unk0x80[4]; // 0x80 }; +// SYNTHETIC: LEGO1 0x10018460 +// LegoLoadCacheSoundPresenter::`scalar deleting destructor' + #endif // LEGOLOADCACHESOUNDPRESENTER_H diff --git a/LEGO1/legosoundmanager.cpp b/LEGO1/legosoundmanager.cpp index a74ca419..d31e5d1c 100644 --- a/LEGO1/legosoundmanager.cpp +++ b/LEGO1/legosoundmanager.cpp @@ -29,7 +29,7 @@ void LegoSoundManager::Destroy(MxBool p_fromDestructor) // STUB: LEGO1 0x100299f0 MxResult LegoSoundManager::Create(MxU32 p_frequencyMS, MxBool p_createThread) { - return FAILURE; + return MxSoundManager::Create(p_frequencyMS, p_createThread); } // FUNCTION: LEGO1 0x1002a390 diff --git a/LEGO1/legoutil.h b/LEGO1/legoutil.h index a6351395..bd7adae6 100644 --- a/LEGO1/legoutil.h +++ b/LEGO1/legoutil.h @@ -49,10 +49,10 @@ inline void GetDouble(MxU8** p_source, T& p_dest) } template -inline void GetString(MxU8** p_source, const char* p_dest, T* p_obj, void (T::*p_setter)(const char*)) +inline void GetString(MxU8** p_source, char** p_dest, T* p_obj, void (T::*p_setter)(const char*)) { (p_obj->*p_setter)((char*) *p_source); - *p_source += strlen(p_dest) + 1; + *p_source += strlen(*p_dest) + 1; } ExtraActionType MatchActionString(const char*); diff --git a/LEGO1/mxbitmap.cpp b/LEGO1/mxbitmap.cpp index 0aec1a6e..4f2393cf 100644 --- a/LEGO1/mxbitmap.cpp +++ b/LEGO1/mxbitmap.cpp @@ -10,22 +10,6 @@ DECOMP_SIZE_ASSERT(MxBITMAPINFO, 0x428); // (1998) GLOBAL: LEGO1 0x10102184 MxU16 g_bitmapSignature = TWOCC('B', 'M'); -// 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 AbsFlipped(MxLong p_value) -{ - return p_value > 0 ? p_value : -p_value; -} - // FUNCTION: LEGO1 0x1004e0d0 int MxBitmap::VTable0x28(int) { @@ -140,16 +124,14 @@ MxResult MxBitmap::ImportBitmap(MxBitmap* p_bitmap) this->m_info = new MxBITMAPINFO; if (this->m_info) { - MxLong height = AbsFlipped(p_bitmap->m_bmiHeader->biHeight); - this->m_data = new MxU8[AlignToFourByte(p_bitmap->m_bmiHeader->biWidth) * height]; + this->m_data = new MxU8[p_bitmap->GetDataSize()]; if (this->m_data) { - memcpy(this->m_info, p_bitmap->m_info, sizeof(*this->m_info)); - height = AbsFlipped(p_bitmap->m_bmiHeader->biHeight); - memcpy(this->m_data, p_bitmap->m_data, AlignToFourByte(p_bitmap->m_bmiHeader->biWidth) * height); + memcpy(this->m_info, p_bitmap->GetBitmapInfo(), MxBITMAPINFO::Size()); + memcpy(this->m_data, p_bitmap->GetBitmapData(), p_bitmap->GetDataSize()); - result = SUCCESS; this->m_bmiHeader = &this->m_info->m_bmiHeader; this->m_paletteData = this->m_info->m_bmiColors; + result = SUCCESS; } } @@ -250,17 +232,25 @@ MxPalette* MxBitmap::CreatePalette() switch (this->m_isHighColor) { case FALSE: palette = new MxPalette(this->m_paletteData); - if (palette) - success = TRUE; - break; + if (!palette) + goto done; + + break; case TRUE: palette = this->m_palette->Clone(); - if (palette) - success = TRUE; + + if (!palette) + goto done; + break; + default: + goto done; } + success = TRUE; + +done: if (!success && palette) { delete palette; palette = NULL; @@ -296,36 +286,41 @@ MxResult MxBitmap::SetBitDepth(MxBool p_isHighColor) if (m_isHighColor == p_isHighColor) { // no change: do nothing. ret = SUCCESS; + goto done; } - else { - switch (p_isHighColor) { - case FALSE: - ImportColorsToPalette(m_paletteData, m_palette); - if (m_palette) - delete m_palette; - m_palette = NULL; - break; + switch (p_isHighColor) { + case FALSE: + ImportColorsToPalette(m_paletteData, m_palette); + if (m_palette) + delete m_palette; - case TRUE: - pal = NULL; - pal = new MxPalette(m_paletteData); - if (pal) { - m_palette = pal; + m_palette = NULL; + break; + case TRUE: { + pal = NULL; + pal = new MxPalette(m_paletteData); - // TODO: what is this? zeroing out top half of palette? - MxU16* buf = (MxU16*) m_paletteData; - for (MxU16 i = 0; i < 256; i++) { - buf[i] = i; - } + if (!pal) + goto done; - m_isHighColor = p_isHighColor; - ret = SUCCESS; - } - break; + m_palette = pal; + + // TODO: what is this? zeroing out top half of palette? + MxU16* buf = (MxU16*) m_paletteData; + for (MxU16 i = 0; i < 256; i++) { + buf[i] = i; } + break; + } + default: + goto done; } + m_isHighColor = p_isHighColor; + ret = SUCCESS; + +done: // If we were unsuccessful overall but did manage to alloc // the MxPalette, free it. if (ret && pal) diff --git a/LEGO1/mxbitmap.h b/LEGO1/mxbitmap.h index b87bcdcf..ed944138 100644 --- a/LEGO1/mxbitmap.h +++ b/LEGO1/mxbitmap.h @@ -19,6 +19,8 @@ struct MxBITMAPINFO { BITMAPINFOHEADER m_bmiHeader; RGBQUAD m_bmiColors[256]; + + static MxU32 Size() { return sizeof(MxBITMAPINFO); } }; // Non-standard value for biCompression in the BITMAPINFOHEADER struct. @@ -56,16 +58,29 @@ class MxBitmap : public MxCore { MxS32 p_destHeight ); // vtable+40 + // 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) const { 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 AbsFlipped(MxLong p_value) const { return p_value > 0 ? p_value : -p_value; } + inline BITMAPINFOHEADER* GetBmiHeader() const { return m_bmiHeader; } inline MxLong GetBmiWidth() const { return m_bmiHeader->biWidth; } inline MxLong GetBmiStride() const { return ((m_bmiHeader->biWidth + 3) & -4); } inline MxLong GetBmiHeight() const { return m_bmiHeader->biHeight; } - inline MxLong GetBmiHeightAbs() const - { - return m_bmiHeader->biHeight > 0 ? m_bmiHeader->biHeight : -m_bmiHeader->biHeight; - } + inline MxLong GetBmiHeightAbs() const { return AbsFlipped(m_bmiHeader->biHeight); } inline MxU8* GetBitmapData() const { return m_data; } inline MxBITMAPINFO* GetBitmapInfo() const { return m_info; } + inline MxLong GetDataSize() const + { + MxLong absHeight = GetBmiHeightAbs(); + MxLong alignedWidth = AlignToFourByte(m_bmiHeader->biWidth); + return alignedWidth * absHeight; + } private: MxResult ImportColorsToPalette(RGBQUAD*, MxPalette*); diff --git a/LEGO1/mxcriticalsection.h b/LEGO1/mxcriticalsection.h index 8756853c..8c5f77d6 100644 --- a/LEGO1/mxcriticalsection.h +++ b/LEGO1/mxcriticalsection.h @@ -13,8 +13,8 @@ class MxCriticalSection { void Leave(); private: - CRITICAL_SECTION m_criticalSection; - HANDLE m_mutex; + CRITICAL_SECTION m_criticalSection; // 0x00 + HANDLE m_mutex; // 0x18 }; #endif // MXCRITICALSECTION_H diff --git a/LEGO1/mxdiskstreamcontroller.cpp b/LEGO1/mxdiskstreamcontroller.cpp index 71ebc827..1520ba3b 100644 --- a/LEGO1/mxdiskstreamcontroller.cpp +++ b/LEGO1/mxdiskstreamcontroller.cpp @@ -1,5 +1,6 @@ #include "mxdiskstreamcontroller.h" +#include "mxactionnotificationparam.h" #include "mxautolocker.h" #include "mxdiskstreamprovider.h" #include "mxdsstreamingaction.h" @@ -52,12 +53,31 @@ MxResult MxDiskStreamController::VTable0x18(undefined4, undefined4) return SUCCESS; } +// FUNCTION: LEGO1 0x100c7890 +MxResult MxDiskStreamController::FUN_100c7890(MxDSStreamingAction* p_action) +{ + MxAutoLocker lock(&this->m_criticalSection); + if (p_action == NULL) { + return FAILURE; + } + + m_list0x80.push_back(p_action); + FUN_100c7970(); + return SUCCESS; +} + // FUNCTION: LEGO1 0x100c7960 MxResult MxDiskStreamController::VTable0x34(undefined4) { return FAILURE; } +// FUNCTION: LEGO1 0x100c7970 +void MxDiskStreamController::FUN_100c7970() +{ + // Empty +} + // FUNCTION: LEGO1 0x100c7980 void MxDiskStreamController::FUN_100c7980() { @@ -181,10 +201,29 @@ MxResult MxDiskStreamController::FUN_100c7d10() return SUCCESS; } -// STUB: LEGO1 0x100c7db0 +// FUNCTION: LEGO1 0x100c7db0 MxDSStreamingAction* MxDiskStreamController::FUN_100c7db0() { - // TODO + MxAutoLocker lock(&this->m_criticalSection); + + for (MxStreamListMxNextActionDataStart::iterator it = m_nextActionList.begin(); it != m_nextActionList.end(); + it++) { + MxNextActionDataStart* data = *it; + for (MxStreamListMxDSAction::iterator it2 = m_list0x64.begin(); it2 != m_list0x64.end(); it2++) { + MxDSStreamingAction* streamingAction = (MxDSStreamingAction*) *it2; + if (streamingAction->GetObjectId() == data->GetObjectId() && + streamingAction->GetUnknown24() == data->GetUnknown24() && + streamingAction->GetBufferOffset() == data->GetData()) { + m_nextActionList.erase(it); + + data->SetData(m_provider->GetFileSize() + data->GetData()); + m_nextActionList.push_back(data); + + m_list0x64.erase(it2); + return streamingAction; + } + } + } return NULL; } @@ -203,7 +242,6 @@ MxResult MxDiskStreamController::VTable0x20(MxDSAction* p_action) MxAutoLocker lock(&this->m_criticalSection); MxDSStreamingAction* entry = (MxDSStreamingAction*) m_list0x80.Find(p_action, FALSE); // TODO: is this a seperate class? - if (entry) { MxDSStreamingAction* action = new MxDSStreamingAction(*p_action, 0); action->SetUnknown28(entry->GetUnknown28()); @@ -224,11 +262,39 @@ MxResult MxDiskStreamController::VTable0x20(MxDSAction* p_action) return SUCCESS; } -// STUB: LEGO1 0x100c8160 +// FUNCTION: LEGO1 0x100c8160 MxResult MxDiskStreamController::VTable0x24(MxDSAction* p_action) { - // TODO - return FAILURE; + MxAutoLocker lock(&this->m_criticalSection); + if (m_unk0x54.Find(p_action, FALSE) == NULL) { + if (VTable0x30(p_action) == SUCCESS) { + MxOmni::GetInstance()->NotifyCurrentEntity( + &MxEndActionNotificationParam(c_notificationEndAction, NULL, p_action, TRUE) + ); + } + } + + MxDSAction action; + if (m_provider) { + m_provider->VTable0x20(p_action); + } + + do { + if (m_action0x60 != NULL) { + delete m_action0x60; + m_action0x60 = NULL; + } + + action = *p_action; + MxStreamController::VTable0x24(&action); + } while (m_action0x60 != NULL); + + if (m_unk0x3c.size() == 0) { + m_unk0x70 = 0; + m_unk0xc4 = 0; + } + + return SUCCESS; } // FUNCTION: LEGO1 0x100c8360 @@ -269,10 +335,28 @@ void MxDiskStreamController::InsertToList74(MxDSBuffer* p_buffer) m_list0x74.push_back(p_buffer); } -// STUB: LEGO1 0x100c8540 +// FUNCTION: LEGO1 0x100c8540 void MxDiskStreamController::FUN_100c8540() { - // TODO + MxAutoLocker lock(&this->m_criticalSection); + for (list::iterator it = m_list0x74.begin(); it != m_list0x74.end();) { + MxDSBuffer* buf = *it; + // TODO: Match + if (buf->GetRefCount() == 0) { + m_list0x74.erase(it++); + FUN_100c7ce0(buf); + } + else + it++; + } + + if (m_nextActionList.empty()) { + while (!m_list0x64.empty()) { + MxDSStreamingAction* action = (MxDSStreamingAction*) m_list0x64.front(); + m_list0x64.pop_front(); + FUN_100c7cb0(action); + } + } } // FUNCTION: LEGO1 0x100c8640 @@ -292,6 +376,13 @@ MxResult MxDiskStreamController::Tickle() return SUCCESS; } +// FUNCTION: LEGO1 0x100c8670 +void MxDiskStreamController::FUN_100c8670(MxDSStreamingAction* p_streamingAction) +{ + MxAutoLocker lock(&this->m_critical9c); + m_list0xb8.push_back(p_streamingAction); +} + // FUNCTION: LEGO1 0x100c8720 void MxDiskStreamController::FUN_100c8720() { diff --git a/LEGO1/mxdiskstreamcontroller.h b/LEGO1/mxdiskstreamcontroller.h index 1d1cf7d5..703b3bf2 100644 --- a/LEGO1/mxdiskstreamcontroller.h +++ b/LEGO1/mxdiskstreamcontroller.h @@ -39,6 +39,13 @@ class MxDiskStreamController : public MxStreamController { return !strcmp(p_name, MxDiskStreamController::ClassName()) || MxStreamController::IsA(p_name); } + inline MxBool GetUnk0xc4() const { return m_unk0xc4; } + + void FUN_100c7f40(MxDSStreamingAction* p_streamingaction); + void FUN_100c8670(MxDSStreamingAction* p_streamingAction); + void InsertToList74(MxDSBuffer* p_buffer); + void FUN_100c7cb0(MxDSStreamingAction* p_action); + private: MxStreamListMxDSAction m_list0x64; // 0x64 undefined m_unk0x70; // 0x70 @@ -48,16 +55,15 @@ class MxDiskStreamController : public MxStreamController { MxStreamListMxDSAction m_list0x90; // 0x90 MxCriticalSection m_critical9c; // 0x9c MxStreamListMxDSAction m_list0xb8; // 0xb8 - undefined m_unk0xc4; // 0xc4 + MxBool m_unk0xc4; // 0xc4 - void FUN_100c7cb0(MxDSStreamingAction* p_action); + MxResult FUN_100c7890(MxDSStreamingAction* p_action); + void FUN_100c7970(); void FUN_100c7ce0(MxDSBuffer* p_buffer); MxResult FUN_100c7d10(); void FUN_100c7980(); MxDSStreamingAction* FUN_100c7db0(); - void FUN_100c7f40(MxDSStreamingAction* p_streamingaction); MxResult FUN_100c8360(MxDSStreamingAction* p_action); - void InsertToList74(MxDSBuffer* p_buffer); void FUN_100c8540(); void FUN_100c8720(); }; diff --git a/LEGO1/mxdiskstreamprovider.cpp b/LEGO1/mxdiskstreamprovider.cpp index a8d15984..c7e311eb 100644 --- a/LEGO1/mxdiskstreamprovider.cpp +++ b/LEGO1/mxdiskstreamprovider.cpp @@ -1,13 +1,20 @@ #include "mxdiskstreamprovider.h" +#include "mxautolocker.h" +#include "mxdiskstreamcontroller.h" #include "mxdsbuffer.h" +#include "mxdsstreamingaction.h" #include "mxomni.h" #include "mxstreamcontroller.h" #include "mxstring.h" #include "mxthread.h" +DECOMP_SIZE_ASSERT(MxDiskStreamProviderThread, 0x1c) DECOMP_SIZE_ASSERT(MxDiskStreamProvider, 0x60); +// GLOBAL: LEGO1 0x10102878 +MxU32 g_unk0x10102878 = 0; + // FUNCTION: LEGO1 0x100d0f30 MxResult MxDiskStreamProviderThread::Run() { @@ -29,8 +36,8 @@ MxResult MxDiskStreamProviderThread::StartWithTarget(MxDiskStreamProvider* p_tar MxDiskStreamProvider::MxDiskStreamProvider() { this->m_pFile = NULL; - this->m_remainingWork = 0; - this->m_unk0x35 = 0; + this->m_remainingWork = FALSE; + this->m_unk0x35 = FALSE; } // STUB: LEGO1 0x100d1240 @@ -58,7 +65,7 @@ MxResult MxDiskStreamProvider::SetResourceToGet(MxStreamController* p_resource) goto done; } - m_remainingWork = 1; + m_remainingWork = TRUE; m_busySemaphore.Init(0, 100); if (m_thread.StartWithTarget(this) == SUCCESS && p_resource != NULL) { @@ -79,25 +86,125 @@ void MxDiskStreamProvider::VTable0x20(MxDSAction* p_action) // FUNCTION: LEGO1 0x100d1750 MxResult MxDiskStreamProvider::WaitForWorkToComplete() { - while (m_remainingWork != 0) { + while (m_remainingWork) { m_busySemaphore.Wait(INFINITE); - if (m_unk0x35 != 0) + if (m_unk0x35) PerformWork(); } + return SUCCESS; } -// STUB: LEGO1 0x100d1780 +// FUNCTION: LEGO1 0x100d1780 MxResult MxDiskStreamProvider::FUN_100d1780(MxDSStreamingAction* p_action) { - // TODO - return FAILURE; + if (!m_remainingWork) + return FAILURE; + + if (p_action->GetUnknown9c() > 0 && !p_action->GetUnknowna0()) { + MxDSBuffer* buffer = new MxDSBuffer(); + + if (!buffer) + return FAILURE; + + if (buffer->AllocateBuffer(GetFileSize(), MxDSBufferType_Allocate) != SUCCESS) { + delete buffer; + return FAILURE; + } + + p_action->SetUnknowna0(buffer); + } + + if (p_action->GetUnknowna0()->GetWriteOffset() < 0x20000) { + g_unk0x10102878++; + } + + { + MxAutoLocker lock(&m_criticalSection); + m_list.push_back(p_action); + } + + m_unk0x35 = TRUE; + m_busySemaphore.Release(1); + return SUCCESS; } -// STUB: LEGO1 0x100d18f0 +// FUNCTION: LEGO1 0x100d18f0 void MxDiskStreamProvider::PerformWork() { - // TODO + MxDiskStreamController* controller = (MxDiskStreamController*) m_pLookup; + MxDSStreamingAction* streamingAction = NULL; + + { + MxAutoLocker lock(&m_criticalSection); + if (!m_list.empty()) { + streamingAction = (MxDSStreamingAction*) m_list.front(); + + if (streamingAction && !FUN_100d1af0(streamingAction)) { + m_thread.Sleep(500); + m_busySemaphore.Release(1); + return; + } + } + } + + { + MxAutoLocker lock(&m_criticalSection); + + if (!m_list.PopFrontStreamingAction(streamingAction)) + return; + } + + if (streamingAction->GetUnknowna0()->GetWriteOffset() < 0x20000) { + g_unk0x10102878--; + } + + MxDSBuffer* buffer = streamingAction->GetUnknowna0(); + + if (m_pFile->GetPosition() == streamingAction->GetBufferOffset() || + m_pFile->Seek(streamingAction->GetBufferOffset(), 0) == 0) { + buffer->SetUnknown14(m_pFile->GetPosition()); + + if (m_pFile->ReadToBuffer(buffer) == SUCCESS) { + buffer->SetUnknown1c(m_pFile->GetPosition()); + + if (streamingAction->GetUnknown9c() > 0) { + FUN_100d1b20(streamingAction); + } + else { + if (m_pLookup == NULL || !((MxDiskStreamController*) m_pLookup)->GetUnk0xc4()) { + controller->FUN_100c8670(streamingAction); + } + else { + controller->FUN_100c7f40(streamingAction); + } + } + + streamingAction = NULL; + } + } + + if (streamingAction) { + controller->FUN_100c8670(streamingAction); + } + + m_thread.Sleep(0); +} + +// FUNCTION: LEGO1 0x100d1af0 +MxBool MxDiskStreamProvider::FUN_100d1af0(MxDSStreamingAction* p_action) +{ + if (p_action->GetUnknowna0()->GetWriteOffset() == 0x20000) { + return g_unk0x10102878 == 0; + } + + return TRUE; +} + +// STUB: LEGO1 0x100d1b20 +MxResult MxDiskStreamProvider::FUN_100d1b20(MxDSStreamingAction* p_action) +{ + return FAILURE; } // FUNCTION: LEGO1 0x100d1e90 diff --git a/LEGO1/mxdiskstreamprovider.h b/LEGO1/mxdiskstreamprovider.h index 55d4f0f2..bc73c0e4 100644 --- a/LEGO1/mxdiskstreamprovider.h +++ b/LEGO1/mxdiskstreamprovider.h @@ -13,21 +13,20 @@ class MxDiskStreamProvider; class MxDSStreamingAction; // VTABLE: LEGO1 0x100dd130 +// SIZE 0x1c class MxDiskStreamProviderThread : public MxThread { public: - // Only inlined, no offset inline MxDiskStreamProviderThread() : MxThread() { m_target = NULL; } MxResult Run() override; - MxResult StartWithTarget(MxDiskStreamProvider* p_target); }; // VTABLE: LEGO1 0x100dd138 +// SIZE 0x60 class MxDiskStreamProvider : public MxStreamProvider { public: MxDiskStreamProvider(); - virtual ~MxDiskStreamProvider() override; // FUNCTION: LEGO1 0x100d1160 @@ -46,6 +45,8 @@ class MxDiskStreamProvider : public MxStreamProvider { MxResult WaitForWorkToComplete(); MxResult FUN_100d1780(MxDSStreamingAction* p_action); void PerformWork(); + static MxBool FUN_100d1af0(MxDSStreamingAction* p_action); + MxResult FUN_100d1b20(MxDSStreamingAction* p_action); virtual MxResult SetResourceToGet(MxStreamController* p_resource) override; // vtable+0x14 virtual MxU32 GetFileSize() override; // vtable+0x18 @@ -57,8 +58,8 @@ class MxDiskStreamProvider : public MxStreamProvider { private: MxDiskStreamProviderThread m_thread; // 0x10 MxSemaphore m_busySemaphore; // 0x2c - undefined m_remainingWork; // 0x34 - undefined m_unk0x35; // 0x35 + MxBool m_remainingWork; // 0x34 + MxBool m_unk0x35; // 0x35 MxCriticalSection m_criticalSection; // 0x38 MxStreamListMxDSAction m_list; // 0x54 }; diff --git a/LEGO1/mxdsbuffer.cpp b/LEGO1/mxdsbuffer.cpp index 634afc6e..261f00d3 100644 --- a/LEGO1/mxdsbuffer.cpp +++ b/LEGO1/mxdsbuffer.cpp @@ -1,5 +1,6 @@ #include "mxdsbuffer.h" +#include "mxdiskstreamcontroller.h" #include "mxdschunk.h" #include "mxdsstreamingaction.h" #include "mxomni.h" @@ -45,68 +46,65 @@ MxDSBuffer::~MxDSBuffer() MxResult MxDSBuffer::AllocateBuffer(MxU32 p_bufferSize, MxDSBufferType p_mode) { MxResult result = FAILURE; - MxU32 i = 0; - if (p_mode == MxDSBufferType_Allocate) { - m_pBuffer = new MxU8[p_bufferSize]; - } - else if (p_mode == MxDSBufferType_Chunk) { - MxStreamer* streamer = Streamer(); - // I have no clue as to what this does, or even if its correct. Maybe it's related to storing chunks in - // MxDiskStreamController? - if (p_bufferSize >> 10 == 0x40) { - i = 0; - while (i < 22) { - if ((*(MxU32*) ((streamer->GetSubclass1().GetUnk08() + ((i & 0xffffffe7) >> 3)) & 1 << ((MxU8) i & 0x1f) - )) == 0) { - MxU32* ptr = (MxU32*) ((streamer->GetSubclass1().GetUnk08() + ((i & 0xffffffe7) >> 3)) & - 1 << ((MxU8) i & 0x1f)); - // mark it as used? + switch (p_mode) { + case MxDSBufferType_Allocate: + m_pBuffer = new MxU8[p_bufferSize]; + break; + + case MxDSBufferType_Chunk: { + MxStreamer* streamer = Streamer(); + + switch (p_bufferSize / 1024) { + case 0x40: { + for (MxU32 i = 0; i < 22; i++) { + if (((1 << (i & 0x1f)) & (*(MxU32*) &streamer->GetSubclass1().GetUnk08Ref()[(i & ~0x18u) >> 3])) == 0) { + MxU32* ptr = (MxU32*) &streamer->GetSubclass1().GetUnk08Ref()[(i & 0xffffffe7) >> 3]; + *ptr = *ptr ^ 1 << (i & 0x1f); m_pBuffer = (MxU8*) (streamer->GetSubclass1().GetSize() * i * 0x400 + streamer->GetSubclass1().GetBuffer()); - break; + goto done; } - i++; } m_pBuffer = NULL; + break; } - else if (p_bufferSize >> 10 == 0x80) { - i = 0; - // Same thing as above but it uses subclass2 - while (i < 22) { - if ((*(MxU32*) ((streamer->GetSubclass2().GetUnk08() + ((i & 0xffffffe7) >> 3)) & 1 << ((MxU8) i & 0x1f) - )) == 0) { - MxU32* ptr = (MxU32*) ((streamer->GetSubclass2().GetUnk08() + ((i & 0xffffffe7) >> 3)) & - 1 << ((MxU8) i & 0x1f)); + case 0x80: { + for (MxU32 i = 0; i < 2; i++) { + if (((1 << (i & 0x1f)) & (*(MxU32*) &streamer->GetSubclass2().GetUnk08Ref()[(i & ~0x18u) >> 3])) == 0) { + MxU32* ptr = (MxU32*) &streamer->GetSubclass2().GetUnk08Ref()[(i & 0xffffffe7) >> 3]; - // mark it as used? *ptr = *ptr ^ 1 << (i & 0x1f); m_pBuffer = (MxU8*) (streamer->GetSubclass2().GetSize() * i * 0x400 + streamer->GetSubclass2().GetBuffer()); - break; + goto done; } - i++; } m_pBuffer = NULL; + break; } - else { - m_pIntoBuffer = NULL; + default: + m_pBuffer = NULL; } } + } +done: m_pIntoBuffer = m_pBuffer; m_pIntoBuffer2 = m_pBuffer; + if (m_pBuffer != NULL) { m_mode = p_mode; m_bytesRemaining = p_bufferSize; m_writeOffset = p_bufferSize; result = SUCCESS; } + return result; } @@ -122,15 +120,58 @@ MxResult MxDSBuffer::SetBufferPointer(MxU32* p_buffer, MxU32 p_size) return SUCCESS; } -// STUB: LEGO1 0x100c67b0 +// FUNCTION: LEGO1 0x100c67b0 MxResult MxDSBuffer::FUN_100c67b0( MxStreamController* p_controller, MxDSAction* p_action, MxDSStreamingAction** p_streamingAction ) { - // TODO STUB - return FAILURE; + MxResult result = FAILURE; + + m_unk0x30 = (MxDSStreamingAction*) p_controller->GetUnk0x3c().Find(p_action, FALSE); + if (m_unk0x30 == NULL) + return FAILURE; + + MxU8* data; + while (data = (MxU8*) SkipToData()) { + if (*p_streamingAction == NULL) { + result = CreateObject(p_controller, (MxU32*) data, p_action, p_streamingAction); + + if (result == FAILURE) + return result; + // TODO: Not a MxResult value? + if (result == 1) + break; + } + else { + MxDSBuffer* buffer = (*p_streamingAction)->GetUnknowna0(); + + if (buffer->CalcBytesRemaining(data) != SUCCESS) { + return result; + } + + if (buffer->GetBytesRemaining() == 0) { + buffer->SetUnk30(m_unk0x30); + + result = buffer->CreateObject(p_controller, (MxU32*) buffer->GetBuffer(), p_action, p_streamingAction); + if (result != SUCCESS) { + return result; + } + + if (buffer->GetRefCount() != 0) { + // Note: *p_streamingAction is always null in MxRamStreamProvider + ((MxDiskStreamController*) p_controller)->InsertToList74(buffer); + (*p_streamingAction)->SetUnknowna0(NULL); + } + + ((MxDiskStreamController*) p_controller)->FUN_100c7cb0(*p_streamingAction); + *p_streamingAction = NULL; + } + } + } + + return SUCCESS; } // FUNCTION: LEGO1 0x100c68a0 @@ -138,7 +179,7 @@ MxResult MxDSBuffer::CreateObject( MxStreamController* p_controller, MxU32* p_data, MxDSAction* p_action, - undefined4 p_undefined + MxDSStreamingAction** p_streamingAction ) { if (p_data == NULL) { @@ -160,7 +201,7 @@ MxResult MxDSBuffer::CreateObject( return SUCCESS; } - return ParseChunk(p_controller, p_data, p_action, p_undefined, chunk); + return ParseChunk(p_controller, p_data, p_action, p_streamingAction, chunk); } delete header; @@ -210,7 +251,7 @@ MxResult MxDSBuffer::ParseChunk( MxStreamController* p_controller, MxU32* p_data, MxDSAction* p_action, - undefined4, + MxDSStreamingAction** p_streamingAction, MxStreamChunk* p_header ) { @@ -221,8 +262,8 @@ MxResult MxDSBuffer::ParseChunk( // FUNCTION: LEGO1 0x100c6d00 MxCore* MxDSBuffer::ReadChunk(MxDSBuffer* p_buffer, MxU32* p_chunkData, MxU16 p_flags) { - // This function reads a chunk. If it is an object, this function returns an MxDSObject. If it is a chunk, returns a - // MxDSChunk. + // This function reads a chunk. If it is an object, this function returns an MxDSObject. If it is a chunk, + // returns a MxDSChunk. MxCore* result = NULL; MxU8* dataStart = (MxU8*) p_chunkData + 8; @@ -242,6 +283,49 @@ MxCore* MxDSBuffer::ReadChunk(MxDSBuffer* p_buffer, MxU32* p_chunkData, MxU16 p_ return result; } +// FUNCTION: LEGO1 0x100c6df0 +MxU8* MxDSBuffer::SkipToData() +{ + MxU8* result = NULL; + + if (m_pIntoBuffer != NULL) { + do { + MxU32* ptr = (MxU32*) m_pIntoBuffer; + switch (*ptr) { + case FOURCC('L', 'I', 'S', 'T'): + case FOURCC('R', 'I', 'F', 'F'): + m_pIntoBuffer = (MxU8*) (ptr + 3); + break; + case FOURCC('M', 'x', 'O', 'b'): + case FOURCC('M', 'x', 'C', 'h'): + result = m_pIntoBuffer; + m_pIntoBuffer = (MxU8*) ((ptr[1] & 1) + ptr[1] + (MxU32) ptr); + m_pIntoBuffer = (MxU8*) ((MxU32*) m_pIntoBuffer + 2); + if (m_pBuffer + (m_writeOffset - 8) < m_pIntoBuffer) { + m_pIntoBuffer2 = result; + m_pIntoBuffer = NULL; + return result; + } + goto done; + case FOURCC('M', 'x', 'D', 'a'): + case FOURCC('M', 'x', 'S', 't'): + m_pIntoBuffer = (MxU8*) (ptr + 2); + break; + case FOURCC('M', 'x', 'H', 'd'): + m_pIntoBuffer = (MxU8*) ((MxU32) ptr + ptr[1] + 8); + break; + default: + m_pIntoBuffer = NULL; + m_pIntoBuffer2 = NULL; + return NULL; + } + } while (m_pIntoBuffer <= m_pBuffer + (m_writeOffset - 8)); + } +done: + m_pIntoBuffer2 = result; + return result; +} + // FUNCTION: LEGO1 0x100c6ec0 MxU8 MxDSBuffer::ReleaseRef(MxDSChunk*) { @@ -259,6 +343,13 @@ void MxDSBuffer::AddRef(MxDSChunk* p_chunk) } } +// STUB: LEGO1 0x100c6ef0 +MxResult MxDSBuffer::CalcBytesRemaining(MxU8* p_data) +{ + // TODO + return FAILURE; +} + // FUNCTION: LEGO1 0x100c6f80 void MxDSBuffer::FUN_100c6f80(MxU32 p_writeOffset) { diff --git a/LEGO1/mxdsbuffer.h b/LEGO1/mxdsbuffer.h index d8532a55..e9fe2675 100644 --- a/LEGO1/mxdsbuffer.h +++ b/LEGO1/mxdsbuffer.h @@ -42,25 +42,31 @@ class MxDSBuffer : public MxCore { MxStreamController* p_controller, MxU32* p_data, MxDSAction* p_action, - undefined4 p_undefined + MxDSStreamingAction** p_streamingAction ); MxResult StartPresenterFromAction(MxStreamController* p_controller, MxDSAction* p_action1, MxDSAction* p_action2); MxResult ParseChunk( MxStreamController* p_controller, MxU32* p_data, MxDSAction* p_action, - undefined4, + MxDSStreamingAction** p_streamingAction, MxStreamChunk* p_header ); static MxCore* ReadChunk(MxDSBuffer* p_buffer, MxU32* p_chunkData, MxU16 p_flags); + MxU8* SkipToData(); MxU8 ReleaseRef(MxDSChunk*); void AddRef(MxDSChunk* p_chunk); + MxResult CalcBytesRemaining(MxU8* p_data); void FUN_100c6f80(MxU32 p_writeOffset); inline MxU8* GetBuffer() { return m_pBuffer; } inline MxU32 GetWriteOffset() { return m_writeOffset; } + inline MxU32 GetBytesRemaining() { return m_bytesRemaining; } inline MxU16 GetRefCount() { return m_refcount; } inline MxDSBufferType GetMode() { return m_mode; } + inline void SetUnknown14(undefined4 p_unk0x14) { m_unk0x14 = p_unk0x14; } + inline void SetUnknown1c(undefined4 p_unk0x1c) { m_unk0x1c = p_unk0x1c; } + inline void SetUnk30(MxDSStreamingAction* p_unk0x30) { m_unk0x30 = p_unk0x30; } private: MxU8* m_pBuffer; // 0x08 diff --git a/LEGO1/mxdsmediaaction.cpp b/LEGO1/mxdsmediaaction.cpp index 9e07f2d3..fb9425d2 100644 --- a/LEGO1/mxdsmediaaction.cpp +++ b/LEGO1/mxdsmediaaction.cpp @@ -84,7 +84,7 @@ void MxDSMediaAction::Deserialize(MxU8** p_source, MxS16 p_unk0x24) { MxDSAction::Deserialize(p_source, p_unk0x24); - GetString(p_source, this->m_mediaSrcPath, this, &MxDSMediaAction::CopyMediaSrcPath); + GetString(p_source, &this->m_mediaSrcPath, this, &MxDSMediaAction::CopyMediaSrcPath); GetScalar(p_source, this->m_unk0x9c.m_unk0x00); GetScalar(p_source, this->m_unk0x9c.m_unk0x04); GetScalar(p_source, this->m_framesPerSecond); diff --git a/LEGO1/mxdsobject.cpp b/LEGO1/mxdsobject.cpp index fa0b944c..9a5801d1 100644 --- a/LEGO1/mxdsobject.cpp +++ b/LEGO1/mxdsobject.cpp @@ -129,9 +129,9 @@ MxU32 MxDSObject::GetSizeOnDisk() // FUNCTION: LEGO1 0x100bfa20 void MxDSObject::Deserialize(MxU8** p_source, MxS16 p_unk0x24) { - GetString(p_source, this->m_sourceName, this, &MxDSObject::SetSourceName); + GetString(p_source, &this->m_sourceName, this, &MxDSObject::SetSourceName); GetScalar(p_source, this->m_unk0x14); - GetString(p_source, this->m_objectName, this, &MxDSObject::SetObjectName); + GetString(p_source, &this->m_objectName, this, &MxDSObject::SetObjectName); GetScalar(p_source, this->m_objectId); this->m_unk0x24 = p_unk0x24; diff --git a/LEGO1/mxdssource.cpp b/LEGO1/mxdssource.cpp index c38799d3..c2d86abb 100644 --- a/LEGO1/mxdssource.cpp +++ b/LEGO1/mxdssource.cpp @@ -2,10 +2,12 @@ #include "mxdsbuffer.h" +DECOMP_SIZE_ASSERT(MxDSSource, 0x14) + // FUNCTION: LEGO1 0x100bffd0 -void MxDSSource::ReadToBuffer(MxDSBuffer* p_buffer) +MxResult MxDSSource::ReadToBuffer(MxDSBuffer* p_buffer) { - Read(p_buffer->GetBuffer(), p_buffer->GetWriteOffset()); + return Read(p_buffer->GetBuffer(), p_buffer->GetWriteOffset()); } // FUNCTION: LEGO1 0x100bfff0 diff --git a/LEGO1/mxdssource.h b/LEGO1/mxdssource.h index 724efca5..711ba110 100644 --- a/LEGO1/mxdssource.h +++ b/LEGO1/mxdssource.h @@ -6,6 +6,7 @@ class MxDSBuffer; // VTABLE: LEGO1 0x100dc8c8 +// SIZE 0x14 class MxDSSource : public MxCore { public: MxDSSource() : m_lengthInDWords(0), m_pBuffer(NULL), m_position(-1) {} @@ -23,20 +24,21 @@ class MxDSSource : public MxCore { return !strcmp(p_name, MxDSSource::ClassName()) || MxCore::IsA(p_name); } - virtual MxLong Open(MxULong) = 0; - virtual MxLong Close() = 0; - virtual void ReadToBuffer(MxDSBuffer* p_buffer); - 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 MxU32* GetBuffer(); // 0x34 + virtual MxLong Open(MxULong) = 0; // vtable+0x14 + virtual MxLong Close() = 0; // vtable+0x18 + virtual MxResult ReadToBuffer(MxDSBuffer* p_buffer); // vtable+0x1c + virtual MxResult Read(unsigned char*, MxULong) = 0; // vtable+0x20 + virtual MxLong Seek(MxLong, int) = 0; // vtable+0x24 + virtual MxULong GetBufferSize() = 0; // vtable+0x28 + virtual MxULong GetStreamBuffersNum() = 0; // vtable+0x2c + virtual MxLong GetLengthInDWords(); // vtable+0x30 + virtual MxU32* GetBuffer(); // vtable+0x34 + inline MxLong GetPosition() const { return m_position; } protected: - MxULong m_lengthInDWords; - MxU32* m_pBuffer; - MxLong m_position; + MxULong m_lengthInDWords; // 0x08 + MxU32* m_pBuffer; // 0x0c + MxLong m_position; // 0x10 }; #endif // MXDSSOURCE_H diff --git a/LEGO1/mxdsstreamingaction.h b/LEGO1/mxdsstreamingaction.h index 1766bd76..7581b217 100644 --- a/LEGO1/mxdsstreamingaction.h +++ b/LEGO1/mxdsstreamingaction.h @@ -32,11 +32,13 @@ class MxDSStreamingAction : public MxDSAction { void FUN_100cd2d0(); inline MxU32 GetUnknown94() { return m_unk0x94; } + inline MxS32 GetUnknown9c() { return m_unk0x9c; } inline MxDSBuffer* GetUnknowna0() { return m_unk0xa0; } inline MxDSBuffer* GetUnknowna4() { return m_unk0xa4; } inline MxDSAction* GetInternalAction() { return m_internalAction; } inline MxU32 GetBufferOffset() { return m_bufferOffset; } inline void SetUnknown94(MxU32 p_unk0x94) { m_unk0x94 = p_unk0x94; } + inline void SetUnknown9c(MxS32 p_unk0x9c) { m_unk0x9c = p_unk0x9c; } inline void SetUnknowna0(MxDSBuffer* p_unk0xa0) { m_unk0xa0 = p_unk0xa0; } inline void SetBufferOffset(MxU32 p_bufferOffset) { m_bufferOffset = p_bufferOffset; } diff --git a/LEGO1/mxnextactiondatastart.h b/LEGO1/mxnextactiondatastart.h index 10d2a2f2..c9534899 100644 --- a/LEGO1/mxnextactiondatastart.h +++ b/LEGO1/mxnextactiondatastart.h @@ -30,11 +30,13 @@ class MxNextActionDataStart : public MxCore { inline MxU32 GetObjectId() const { return m_objectId; } inline MxS16 GetUnknown24() const { return m_unk0x24; } + inline MxU32 GetData() const { return m_data; } + inline void SetData(MxU32 p_data) { m_data = p_data; } private: - MxU32 m_objectId; - MxS16 m_unk0x24; - MxU32 m_data; + MxU32 m_objectId; // 0x08 + MxS16 m_unk0x24; // 0x0c + MxU32 m_data; // 0x10 }; #endif // MXNEXTACTIONDATASTART_H diff --git a/LEGO1/mxrectlist.h b/LEGO1/mxrectlist.h index c0527f01..e19c4994 100644 --- a/LEGO1/mxrectlist.h +++ b/LEGO1/mxrectlist.h @@ -69,13 +69,13 @@ class MxRectListCursor : public MxPtrListCursor { // MxRectListCursor::`scalar deleting destructor' // TEMPLATE: LEGO1 0x100b4090 -// MxPtrListCursor::~MxPtrListCursor +// MxPtrListCursor::~MxPtrListCursor // SYNTHETIC: LEGO1 0x100b40e0 // MxListCursor::`scalar deleting destructor' // SYNTHETIC: LEGO1 0x100b4150 -// MxPtrListCursor::`scalar deleting destructor' +// MxPtrListCursor::`scalar deleting destructor' // TEMPLATE: LEGO1 0x100b41c0 // MxListCursor::~MxListCursor diff --git a/LEGO1/mxsemaphore.cpp b/LEGO1/mxsemaphore.cpp index 18637185..5692a888 100644 --- a/LEGO1/mxsemaphore.cpp +++ b/LEGO1/mxsemaphore.cpp @@ -1,6 +1,10 @@ #include "mxsemaphore.h" +#include "decomp.h" + +DECOMP_SIZE_ASSERT(MxSemaphore, 0x08) + // FUNCTION: LEGO1 0x100c87d0 MxSemaphore::MxSemaphore() { diff --git a/LEGO1/mxsemaphore.h b/LEGO1/mxsemaphore.h index 3bc6d66b..ecb6509c 100644 --- a/LEGO1/mxsemaphore.h +++ b/LEGO1/mxsemaphore.h @@ -5,6 +5,7 @@ #include +// SIZE 0x08 class MxSemaphore { public: MxSemaphore(); @@ -18,7 +19,7 @@ class MxSemaphore { void Release(MxU32 p_releaseCount); private: - HANDLE m_hSemaphore; + HANDLE m_hSemaphore; // 0x04 }; #endif // MX_SEMAPHORE_H diff --git a/LEGO1/mxstreamcontroller.cpp b/LEGO1/mxstreamcontroller.cpp index 92dcfb26..c7d30cc4 100644 --- a/LEGO1/mxstreamcontroller.cpp +++ b/LEGO1/mxstreamcontroller.cpp @@ -5,6 +5,7 @@ #include "mxautolocker.h" #include "mxdsstreamingaction.h" #include "mxnextactiondatastart.h" +#include "mxstl/stlcompat.h" #include "mxstreamchunk.h" #include "mxtimer.h" diff --git a/LEGO1/mxstreamcontroller.h b/LEGO1/mxstreamcontroller.h index ca3b09b3..b8a5bfbd 100644 --- a/LEGO1/mxstreamcontroller.h +++ b/LEGO1/mxstreamcontroller.h @@ -53,6 +53,7 @@ class MxStreamController : public MxCore { MxResult InsertActionToList54(MxDSAction* p_action); inline MxAtomId& GetAtom() { return m_atom; }; + inline MxStreamListMxDSAction& GetUnk0x3c() { return m_unk0x3c; }; inline MxStreamListMxDSAction& GetUnk0x54() { return m_unk0x54; }; protected: diff --git a/LEGO1/mxstreamer.h b/LEGO1/mxstreamer.h index 3b58b260..8017e898 100644 --- a/LEGO1/mxstreamer.h +++ b/LEGO1/mxstreamer.h @@ -22,7 +22,7 @@ class MxStreamerSubClass1 { void SetBuffer(undefined* p_buf) { m_buffer = p_buf; } inline undefined* GetBuffer() const { return m_buffer; } - inline undefined4 GetUnk08() const { return m_unk0x08; } + inline undefined* GetUnk08Ref() const { return (undefined*) &m_unk0x08; } private: undefined* m_buffer; diff --git a/LEGO1/mxstreamlist.h b/LEGO1/mxstreamlist.h index 9b65c53d..6aa63de0 100644 --- a/LEGO1/mxstreamlist.h +++ b/LEGO1/mxstreamlist.h @@ -1,7 +1,7 @@ #ifndef MXSTREAMLIST_H #define MXSTREAMLIST_H -#include "mxdsaction.h" +#include "mxdsstreamingaction.h" #include "mxdssubscriber.h" #include "mxnextactiondatastart.h" #include "mxstl/stlcompat.h" @@ -24,6 +24,18 @@ class MxStreamList : public list { class MxStreamListMxDSAction : public MxStreamList { public: MxDSAction* Find(MxDSAction* p_action, MxBool p_delete); + + // There chance this list actually holds MxDSStreamingListAction + // instead of MxDSAction. Until then, we use this helper. + MxBool PopFrontStreamingAction(MxDSStreamingAction*& p_obj) + { + if (empty()) + return FALSE; + + p_obj = (MxDSStreamingAction*) front(); + pop_front(); + return TRUE; + } }; // SIZE 0xc diff --git a/LEGO1/mxstreamprovider.h b/LEGO1/mxstreamprovider.h index ecbe9ab4..73804684 100644 --- a/LEGO1/mxstreamprovider.h +++ b/LEGO1/mxstreamprovider.h @@ -34,8 +34,8 @@ class MxStreamProvider : public MxCore { virtual MxU32* GetBufferForDWords() = 0; // vtable+0x28 protected: - MxStreamController* m_pLookup; - MxDSFile* m_pFile; + MxStreamController* m_pLookup; // 0x08 + MxDSFile* m_pFile; // 0x0c }; #endif // MXSTREAMPROVIDER_H diff --git a/LEGO1/mxthread.cpp b/LEGO1/mxthread.cpp index 899e959e..401860a1 100644 --- a/LEGO1/mxthread.cpp +++ b/LEGO1/mxthread.cpp @@ -1,11 +1,15 @@ #include "mxthread.h" +#include "decomp.h" #include "mxomni.h" #include "mxtimer.h" #include +DECOMP_SIZE_ASSERT(MxThread, 0x1c) +DECOMP_SIZE_ASSERT(MxTickleThread, 0x20) + // FUNCTION: LEGO1 0x100b8bb0 MxTickleThread::MxTickleThread(MxCore* p_target, MxS32 p_frequencyMS) { diff --git a/LEGO1/mxthread.h b/LEGO1/mxthread.h index 3c7faab0..e3af186d 100644 --- a/LEGO1/mxthread.h +++ b/LEGO1/mxthread.h @@ -8,6 +8,7 @@ class MxCore; // VTABLE: LEGO1 0x100dc860 +// SIZE 0x1c class MxThread { public: // Note: Comes before virtual destructor @@ -16,10 +17,8 @@ class MxThread { MxResult Start(MxS32 p_stack, MxS32 p_flag); void Terminate(); - void Sleep(MxS32 p_milliseconds); - // Inferred, not in DLL inline MxBool IsRunning() { return m_running; } protected: @@ -31,27 +30,26 @@ class MxThread { private: static unsigned ThreadProc(void* p_thread); - MxULong m_hThread; - MxU32 m_threadId; - MxBool m_running; - MxSemaphore m_semaphore; + MxULong m_hThread; // 0x04 + MxU32 m_threadId; // 0x08 + MxBool m_running; // 0x0c + MxSemaphore m_semaphore; // 0x10 protected: - MxCore* m_target; + MxCore* m_target; // 0x18 }; // VTABLE: LEGO1 0x100dc6d8 +// SIZE 0x20 class MxTickleThread : public MxThread { public: MxTickleThread(MxCore* p_target, MxS32 p_frequencyMS); - - // Only inlined, no offset virtual ~MxTickleThread() {} MxResult Run() override; private: - MxS32 m_frequencyMS; + MxS32 m_frequencyMS; // 0x1c }; #endif // MXTHREAD_H diff --git a/LEGO1/mxwavepresenter.h b/LEGO1/mxwavepresenter.h index ddb2b480..4210a44e 100644 --- a/LEGO1/mxwavepresenter.h +++ b/LEGO1/mxwavepresenter.h @@ -50,9 +50,11 @@ class MxWavePresenter : public MxSoundPresenter { MxU32 m_flags; }; +protected: + void Destroy(MxBool p_fromDestructor); + private: void Init(); - void Destroy(MxBool p_fromDestructor); MxS8 GetPlayedChunks(); MxBool FUN_100b1ba0(); void WriteToSoundBuffer(void* p_audioPtr, MxU32 p_length);