diff --git a/.gitignore b/.gitignore index 3e49300b..105d561e 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,5 @@ LEGO1.DLL build/ *.swp __pycache__/ +LEGO1PROGRESS.HTML +LEGO1PROGRESS.SVG diff --git a/LEGO1/legoactor.cpp b/LEGO1/legoactor.cpp index ace8a47c..31c6da6f 100644 --- a/LEGO1/legoactor.cpp +++ b/LEGO1/legoactor.cpp @@ -3,43 +3,49 @@ DECOMP_SIZE_ASSERT(LegoActor, 0x78) // Probably in header -// OFFSET: LEGO1 0x10002cc0 STUB -void LegoActor::VTable0x50() +// OFFSET: LEGO1 0x10002cc0 +MxFloat LegoActor::VTable0x50() { - // TODO + return m_unk68; } -// OFFSET: LEGO1 0x10002cd0 STUB -void LegoActor::VTable0x54() +// OFFSET: LEGO1 0x10002cd0 +void LegoActor::VTable0x54(MxFloat p_unk) { - // TODO + m_unk68 = p_unk; } -// OFFSET: LEGO1 0x10002ce0 STUB -void LegoActor::VTable0x58() +// OFFSET: LEGO1 0x10002ce0 +void LegoActor::VTable0x58(MxFloat p_unk) { - // TODO + m_unk70 = p_unk; } -// OFFSET: LEGO1 0x10002cf0 STUB -void LegoActor::VTable0x5c() +// OFFSET: LEGO1 0x10002cf0 +MxFloat LegoActor::VTable0x5c() { - // TODO + return m_unk70; } -// OFFSET: LEGO1 0x10002d00 STUB -void LegoActor::VTable0x60() +// OFFSET: LEGO1 0x10002d00 +undefined LegoActor::VTable0x60() { - // TODO + return m_unk74; } -// OFFSET: LEGO1 0x10002d10 STUB -void LegoActor::VTable0x64() +// OFFSET: LEGO1 0x10002d10 +void LegoActor::VTable0x64(undefined p_unk) { - // TODO + m_unk74 = p_unk; } // End header +// OFFSET: LEGO1 0x1002d110 LegoActor::LegoActor() { + m_unk68 = 0.0f; + m_unk6c = 0; + m_unk70 = 0.0f; + m_unk10 = 0; + m_unk74 = 0; } diff --git a/LEGO1/legoactor.h b/LEGO1/legoactor.h index 3c4ed06e..3ab451ce 100644 --- a/LEGO1/legoactor.h +++ b/LEGO1/legoactor.h @@ -23,15 +23,18 @@ class LegoActor : public LegoEntity { return !strcmp(name, LegoActor::ClassName()) || LegoEntity::IsA(name); } - virtual void VTable0x50(); // vtable+0x50 - virtual void VTable0x54(); // vtable+0x54 - virtual void VTable0x58(); // vtable+0x58 - virtual void VTable0x5c(); // vtable+0x5c - virtual void VTable0x60(); // vtable+0x60 - virtual void VTable0x64(); // vtable+0x64 + virtual MxFloat VTable0x50(); // vtable+0x50 + virtual void VTable0x54(MxFloat p_unk); // vtable+0x54 + virtual void VTable0x58(MxFloat p_unk); // vtable+0x58 + virtual MxFloat VTable0x5c(); // vtable+0x5c + virtual undefined VTable0x60(); // vtable+0x60 + virtual void VTable0x64(undefined p_unk); // vtable+0x64 private: - undefined unk68[0x10]; + MxFloat m_unk68; + undefined4 m_unk6c; + MxFloat m_unk70; + undefined m_unk74; }; #endif // LEGOACTOR_H diff --git a/LEGO1/legoentity.cpp b/LEGO1/legoentity.cpp index 19820154..2a9b4b76 100644 --- a/LEGO1/legoentity.cpp +++ b/LEGO1/legoentity.cpp @@ -3,6 +3,7 @@ #include "define.h" #include "legoomni.h" #include "legoutil.h" +#include "legoworld.h" DECOMP_SIZE_ASSERT(LegoEntity, 0x68) @@ -60,12 +61,12 @@ void LegoEntity::Destroy(MxBool p_fromDestructor) Init(); } -// OFFSET: LEGO1 0x10010880 STUB +// OFFSET: LEGO1 0x10010880 void LegoEntity::SetWorld() { LegoWorld* world = GetCurrentWorld(); if (world != NULL && world != (LegoWorld*) this) { - // TODO: world->AddEntity(this); + world->VTable0x58(this); } } diff --git a/LEGO1/legoentity.h b/LEGO1/legoentity.h index f9345d89..e22c1d73 100644 --- a/LEGO1/legoentity.h +++ b/LEGO1/legoentity.h @@ -13,10 +13,7 @@ class LegoEntity : public MxEntity { public: // Inlined at 0x100853f7 - inline LegoEntity() - { - // TODO - } + inline LegoEntity() { Init(); } __declspec(dllexport) virtual ~LegoEntity() override; // vtable+0x0 diff --git a/LEGO1/mxdiskstreamcontroller.cpp b/LEGO1/mxdiskstreamcontroller.cpp index 0bd3893e..95d6858c 100644 --- a/LEGO1/mxdiskstreamcontroller.cpp +++ b/LEGO1/mxdiskstreamcontroller.cpp @@ -1,5 +1,10 @@ #include "mxdiskstreamcontroller.h" +#include "mxautolocker.h" +#include "mxdiskstreamprovider.h" +#include "mxomni.h" +#include "mxticklemanager.h" + // OFFSET: LEGO1 0x100c7120 STUB MxDiskStreamController::MxDiskStreamController() { @@ -19,11 +24,30 @@ MxResult MxDiskStreamController::Tickle() return SUCCESS; } -// OFFSET: LEGO1 0x100c7790 STUB +// OFFSET: LEGO1 0x100c7790 MxResult MxDiskStreamController::Open(const char* p_filename) { - // TODO - return FAILURE; + MxAutoLocker lock(&this->m_criticalSection); + MxResult result = MxStreamController::Open(p_filename); + + if (result == SUCCESS) { + m_provider = new MxDiskStreamProvider(); + if (m_provider == NULL) { + result = FAILURE; + } + else { + result = m_provider->SetResourceToGet(this); + if (result != SUCCESS) { + delete m_provider; + m_provider = NULL; + } + else { + TickleManager()->RegisterClient(this, 10); + } + } + } + + return result; } // OFFSET: LEGO1 0x100c7880 diff --git a/LEGO1/mxdiskstreamprovider.cpp b/LEGO1/mxdiskstreamprovider.cpp index 5ea03197..b5dabe4a 100644 --- a/LEGO1/mxdiskstreamprovider.cpp +++ b/LEGO1/mxdiskstreamprovider.cpp @@ -1,5 +1,8 @@ #include "mxdiskstreamprovider.h" +#include "mxomni.h" +#include "mxstreamcontroller.h" +#include "mxstring.h" #include "mxthread.h" DECOMP_SIZE_ASSERT(MxDiskStreamProvider, 0x60); @@ -7,13 +10,20 @@ DECOMP_SIZE_ASSERT(MxDiskStreamProvider, 0x60); // OFFSET: LEGO1 0x100d0f30 MxResult MxDiskStreamProviderThread::Run() { - if (m_target != NULL) - m_target->WaitForWorkToComplete(); + if (m_target) + ((MxDiskStreamProvider*) m_target)->WaitForWorkToComplete(); MxThread::Run(); // They should probably have writen "return MxThread::Run()" but they didn't. return SUCCESS; } +// OFFSET: LEGO1 0x100d0f50 +MxResult MxDiskStreamProviderThread::StartWithTarget(MxDiskStreamProvider* p_target) +{ + m_target = p_target; + return Start(0x1000, 0); +} + // OFFSET: LEGO1 0x100d0f70 MxDiskStreamProvider::MxDiskStreamProvider() { @@ -22,13 +32,44 @@ MxDiskStreamProvider::MxDiskStreamProvider() this->m_unk35 = 0; } -// OFFSET: LEGO1 0x100d1240 +// OFFSET: LEGO1 0x100d1240 STUB MxDiskStreamProvider::~MxDiskStreamProvider() { // TODO } -// Matching but with esi / edi swapped +// OFFSET: LEGO1 0x100d13d0 +MxResult MxDiskStreamProvider::SetResourceToGet(MxStreamController* p_resource) +{ + MxResult result = FAILURE; + MxString path; + m_pLookup = p_resource; + + path = (MxString(MxOmni::GetHD()) + p_resource->GetAtom().GetInternal() + ".si"); + + m_pFile = new MxDSFile(path.GetData(), 0); + if (m_pFile != NULL) { + if (m_pFile->Open(0) != 0) { + path = MxString(MxOmni::GetCD()) + p_resource->GetAtom().GetInternal() + ".si"; + m_pFile->SetFileName(path.GetData()); + + if (m_pFile->Open(0) != 0) + goto done; + } + + m_remainingWork = 1; + MxResult success = m_busySemaphore.Init(0, 100); + m_thread.StartWithTarget(this); + + if (success == SUCCESS && p_resource != NULL) { + result = SUCCESS; + } + } + +done: + return result; +} + // OFFSET: LEGO1 0x100d1750 MxResult MxDiskStreamProvider::WaitForWorkToComplete() { @@ -46,13 +87,6 @@ void MxDiskStreamProvider::PerformWork() // TODO } -// OFFSET: LEGO1 0x100d13d0 STUB -MxResult MxDiskStreamProvider::SetResourceToGet(void* p_resource) -{ - // TODO - return FAILURE; -} - // OFFSET: LEGO1 0x100d1e90 MxU32 MxDiskStreamProvider::GetFileSize() { diff --git a/LEGO1/mxdiskstreamprovider.h b/LEGO1/mxdiskstreamprovider.h index e343fa93..a1e3417f 100644 --- a/LEGO1/mxdiskstreamprovider.h +++ b/LEGO1/mxdiskstreamprovider.h @@ -13,12 +13,11 @@ class MxDiskStreamProvider; class MxDiskStreamProviderThread : public MxThread { public: // Only inlined, no offset - inline MxDiskStreamProviderThread() : MxThread(), m_target(NULL) {} + inline MxDiskStreamProviderThread() : MxThread() { m_target = NULL; } MxResult Run() override; -private: - MxDiskStreamProvider* m_target; + MxResult StartWithTarget(MxDiskStreamProvider* p_target); }; // VTABLEADDR 0x100dd138 @@ -45,12 +44,12 @@ 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 + virtual MxResult SetResourceToGet(MxStreamController* 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 diff --git a/LEGO1/mxdsbuffer.cpp b/LEGO1/mxdsbuffer.cpp index 4163e39b..a09bb101 100644 --- a/LEGO1/mxdsbuffer.cpp +++ b/LEGO1/mxdsbuffer.cpp @@ -1,5 +1,8 @@ #include "mxdsbuffer.h" +#include "mxomni.h" +#include "mxstreamer.h" + DECOMP_SIZE_ASSERT(MxDSBuffer, 0x34); // OFFSET: LEGO1 0x100c6470 @@ -14,24 +17,112 @@ MxDSBuffer::MxDSBuffer() m_unk1c = 0; m_writeOffset = 0; m_bytesRemaining = 0; - m_mode = 2; + m_mode = MxDSBufferType_Preallocated; m_unk30 = 0; } // OFFSET: LEGO1 0x100c6530 MxDSBuffer::~MxDSBuffer() { - // TODO + if (m_pBuffer != NULL) { + if (m_mode == MxDSBufferType_Chunk) { + // TODO + } + else if (m_mode == MxDSBufferType_Allocate || m_mode == MxDSBufferType_Unknown) { + delete[] m_pBuffer; + } + } + + m_unk14 = 0; + m_unk1c = 0; +} + +// OFFSET: LEGO1 0x100c6640 +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 + // MxRamStreamController? + 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? + *ptr = *ptr ^ 1 << (i & 0x1f); + + m_pBuffer = + (MxU8*) (streamer->GetSubclass1().GetSize() * i * 0x400 + streamer->GetSubclass1().GetBuffer()); + break; + } + i++; + } + + m_pBuffer = NULL; + } + 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)); + + // mark it as used? + *ptr = *ptr ^ 1 << (i & 0x1f); + + m_pBuffer = + (MxU8*) (streamer->GetSubclass2().GetSize() * i * 0x400 + streamer->GetSubclass2().GetBuffer()); + break; + } + i++; + } + + m_pBuffer = NULL; + } + else { + m_pIntoBuffer = NULL; + } + } + + 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; } // OFFSET: LEGO1 0x100c6780 -MxResult MxDSBuffer::FUN_100c6780(void* p_buffer, MxU32 p_size) +MxResult MxDSBuffer::SetBufferPointer(MxU32* p_buffer, MxU32 p_size) { - m_pBuffer = p_buffer; - m_pIntoBuffer = p_buffer; - m_pIntoBuffer2 = p_buffer; + m_pBuffer = (MxU8*) p_buffer; + m_pIntoBuffer = (MxU8*) p_buffer; + m_pIntoBuffer2 = (MxU8*) p_buffer; m_bytesRemaining = p_size; m_writeOffset = p_size; - m_mode = 2; + m_mode = MxDSBufferType_Preallocated; return SUCCESS; } + +// OFFSET: LEGO1 0x100c6f80 +void MxDSBuffer::FUN_100c6f80(MxU32 p_unk) +{ + if (p_unk < m_writeOffset) { + m_pIntoBuffer2 = m_pBuffer + p_unk; + m_pIntoBuffer = m_pBuffer + p_unk; + } +} diff --git a/LEGO1/mxdsbuffer.h b/LEGO1/mxdsbuffer.h index ceb72c0c..f2657b3c 100644 --- a/LEGO1/mxdsbuffer.h +++ b/LEGO1/mxdsbuffer.h @@ -4,6 +4,13 @@ #include "decomp.h" #include "mxcore.h" +enum MxDSBufferType { + MxDSBufferType_Chunk = 0, + MxDSBufferType_Allocate = 1, + MxDSBufferType_Preallocated = 2, + MxDSBufferType_Unknown = 3, +}; + // VTABLEADDR 0x100dcca0 // SIZE 0x34 class MxDSBuffer : public MxCore { @@ -18,20 +25,22 @@ class MxDSBuffer : public MxCore { return "MxDSBuffer"; } - MxResult FUN_100c6780(void* p_buffer, MxU32 p_size); + MxResult AllocateBuffer(MxU32 p_bufferSize, MxDSBufferType p_mode); + MxResult SetBufferPointer(MxU32* p_buffer, MxU32 p_size); + void FUN_100c6f80(MxU32 p_unk); - inline void* GetBuffer() { return m_pBuffer; } + inline MxU8* GetBuffer() { return m_pBuffer; } inline MxU32 GetWriteOffset() { return m_writeOffset; } private: - void* m_pBuffer; - void* m_pIntoBuffer; - void* m_pIntoBuffer2; + MxU8* m_pBuffer; + MxU8* m_pIntoBuffer; + MxU8* m_pIntoBuffer2; undefined4 m_unk14; undefined4 m_unk18; undefined4 m_unk1c; undefined2 m_unk20; - undefined4 m_mode; + MxDSBufferType m_mode; MxU32 m_writeOffset; MxU32 m_bytesRemaining; undefined4 m_unk30; diff --git a/LEGO1/mxdsfile.h b/LEGO1/mxdsfile.h index d64c2fa7..ca07b1fd 100644 --- a/LEGO1/mxdsfile.h +++ b/LEGO1/mxdsfile.h @@ -31,6 +31,9 @@ class MxDSFile : public MxDSSource { __declspec(dllexport) virtual MxLong Seek(MxLong, int); // vtable+0x24 __declspec(dllexport) virtual MxULong GetBufferSize(); // vtable+0x28 __declspec(dllexport) virtual MxULong GetStreamBuffersNum(); // vtable+0x2c + + inline void SetFileName(const char* p_filename) { m_filename = p_filename; } + private: MxLong ReadChunks(); struct ChunkHeader { diff --git a/LEGO1/mxdssource.cpp b/LEGO1/mxdssource.cpp index f94318d1..7110c9ee 100644 --- a/LEGO1/mxdssource.cpp +++ b/LEGO1/mxdssource.cpp @@ -5,7 +5,7 @@ // OFFSET: LEGO1 0x100bffd0 void MxDSSource::ReadToBuffer(MxDSBuffer* p_buffer) { - Read((unsigned char*) p_buffer->GetBuffer(), p_buffer->GetWriteOffset()); + Read(p_buffer->GetBuffer(), p_buffer->GetWriteOffset()); } // OFFSET: LEGO1 0x100bfff0 diff --git a/LEGO1/mxramstreamcontroller.cpp b/LEGO1/mxramstreamcontroller.cpp index 1b75fd4f..2e8efc36 100644 --- a/LEGO1/mxramstreamcontroller.cpp +++ b/LEGO1/mxramstreamcontroller.cpp @@ -1,13 +1,41 @@ #include "mxramstreamcontroller.h" +#include "mxautolocker.h" #include "mxramstreamprovider.h" DECOMP_SIZE_ASSERT(MxRAMStreamController, 0x98); -// OFFSET: LEGO1 0x100c6110 STUB +// OFFSET: LEGO1 0x100d0d80 STUB +undefined* __cdecl FUN_100d0d80(MxU32* p_fileSizeBuffer, MxU32 p_fileSize) +{ + return NULL; +} + +// OFFSET: LEGO1 0x100c6110 MxResult MxRAMStreamController::Open(const char* p_filename) { - // TODO STUB + MxAutoLocker locker(&m_criticalSection); + if (MxStreamController::Open(p_filename) != SUCCESS) { + return FAILURE; + } + + m_provider = new MxRAMStreamProvider(); + if (((MxRAMStreamProvider*) m_provider) != NULL) { + if (m_provider->SetResourceToGet(this) != SUCCESS) { + return FAILURE; + } + + FUN_100d0d80( + ((MxRAMStreamProvider*) m_provider)->GetBufferOfFileSize(), + ((MxRAMStreamProvider*) m_provider)->GetFileSize() + ); + m_buffer.SetBufferPointer( + ((MxRAMStreamProvider*) m_provider)->GetBufferOfFileSize(), + ((MxRAMStreamProvider*) m_provider)->GetFileSize() + ); + return SUCCESS; + } + return FAILURE; } diff --git a/LEGO1/mxramstreamprovider.cpp b/LEGO1/mxramstreamprovider.cpp index 0cb5353d..795523c8 100644 --- a/LEGO1/mxramstreamprovider.cpp +++ b/LEGO1/mxramstreamprovider.cpp @@ -30,7 +30,7 @@ MxRAMStreamProvider::~MxRAMStreamProvider() } // OFFSET: LEGO1 0x100d0ae0 STUB -MxResult MxRAMStreamProvider::SetResourceToGet(void* p_resource) +MxResult MxRAMStreamProvider::SetResourceToGet(MxStreamController* p_resource) { return FAILURE; } diff --git a/LEGO1/mxramstreamprovider.h b/LEGO1/mxramstreamprovider.h index 1d389a15..e8b37e15 100644 --- a/LEGO1/mxramstreamprovider.h +++ b/LEGO1/mxramstreamprovider.h @@ -9,16 +9,18 @@ class MxRAMStreamProvider : public MxStreamProvider { MxRAMStreamProvider(); virtual ~MxRAMStreamProvider() override; - virtual MxResult SetResourceToGet(void* p_resource) override; // vtable+0x14 - virtual MxU32 GetFileSize() override; // vtable+0x18 - virtual MxU32 GetStreamBuffersNum() override; // vtable+0x1c - virtual MxU32 GetLengthInDWords() override; // vtable+0x24 - virtual MxU32* GetBufferForDWords() override; // vtable+0x28 + virtual MxResult SetResourceToGet(MxStreamController* p_resource) override; // vtable+0x14 + virtual MxU32 GetFileSize() override; // vtable+0x18 + virtual MxU32 GetStreamBuffersNum() override; // vtable+0x1c + virtual MxU32 GetLengthInDWords() override; // vtable+0x24 + virtual MxU32* GetBufferForDWords() override; // vtable+0x28 + + inline MxU32* GetBufferOfFileSize() { return m_pBufferOfFileSize; } protected: MxU32 m_bufferSize; MxU32 m_fileSize; - void* m_pBufferOfFileSize; + MxU32* m_pBufferOfFileSize; MxU32 m_lengthInDWords; MxU32* m_bufferForDWords; }; diff --git a/LEGO1/mxsmkpresenter.cpp b/LEGO1/mxsmkpresenter.cpp index 126c9a7a..c4c2224e 100644 --- a/LEGO1/mxsmkpresenter.cpp +++ b/LEGO1/mxsmkpresenter.cpp @@ -1,6 +1,7 @@ #include "mxsmkpresenter.h" #include "decomp.h" +#include "mxvideomanager.h" DECOMP_SIZE_ASSERT(MxSmkPresenter, 0x720); @@ -65,3 +66,48 @@ void MxSmkPresenter::FUN_100c5d40(MxSmack* p_mxSmack) if (p_mxSmack->m_unk0x6b4) delete p_mxSmack->m_unk0x6b4; } + +// OFFSET: LEGO1 0x100b4300 +void MxSmkPresenter::Destroy() +{ + Destroy(FALSE); +} + +// OFFSET: LEGO1 0x100b3940 STUB +void MxSmkPresenter::VTable0x5c(undefined4 p_unknown1) +{ +} + +// OFFSET: LEGO1 0x100b3a00 STUB +void MxSmkPresenter::VTable0x68(undefined4 p_unknown1) +{ +} + +// OFFSET: LEGO1 0x100b42c0 +void MxSmkPresenter::VTable0x70() +{ + MxPalette* palette = m_bitmap->CreatePalette(); + MVideoManager()->RealizePalette(palette); + delete palette; +} + +// OFFSET: LEGO1 0x100b4260 +MxU32 MxSmkPresenter::VTable0x88() +{ + MxU32 result = m_unk0x71c; + if ((m_mxSmack.m_smack.m_smkType & 1) != 0) { + result = m_unk0x71c / m_mxSmack.m_smack.m_frames; + if (1 < m_unk0x71c && (m_unk0x71c % m_mxSmack.m_smack.m_frames) == 1) { + m_unk0x71c = 1; + } + return result; + } + else { + if (m_mxSmack.m_smack.m_frames == result) { + m_unk0x71c = 0; + result = 0; + memset(m_mxSmack.m_smack.m_palette, 0, sizeof(m_mxSmack.m_smack.m_palette)); + } + return result; + } +} diff --git a/LEGO1/mxsmkpresenter.h b/LEGO1/mxsmkpresenter.h index 1f9958ee..bae35196 100644 --- a/LEGO1/mxsmkpresenter.h +++ b/LEGO1/mxsmkpresenter.h @@ -13,7 +13,12 @@ class MxSmkPresenter : public MxVideoPresenter { MxSmkPresenter(); virtual ~MxSmkPresenter() override; + virtual void Destroy() override; + virtual void VTable0x5c(undefined4 p_unknown1) override; virtual void VTable0x60() override; + virtual void VTable0x68(undefined4 p_unknown1) override; // vtable+0x68 + virtual void VTable0x70() override; + virtual MxU32 VTable0x88(); struct MxSmack { Smack m_smack; diff --git a/LEGO1/mxstreamer.h b/LEGO1/mxstreamer.h index fb6110c2..8570f347 100644 --- a/LEGO1/mxstreamer.h +++ b/LEGO1/mxstreamer.h @@ -18,9 +18,11 @@ class MxStreamerSubClass1 { ~MxStreamerSubClass1() { delete[] m_buffer; } - undefined4 GetSize() { return m_size; } + undefined4 GetSize() const { return m_size; } void SetBuffer(undefined* p_buf) { m_buffer = p_buf; } + inline undefined* GetBuffer() const { return m_buffer; } + inline undefined4 GetUnk08() const { return m_unk08; } private: undefined* m_buffer; @@ -93,6 +95,9 @@ class MxStreamer : public MxCore { MxResult AddStreamControllerToOpenList(MxStreamController* p_stream); MxResult FUN_100b99b0(MxDSAction* p_action); + inline const MxStreamerSubClass2& GetSubclass1() { return m_subclass1; } + inline const MxStreamerSubClass3& GetSubclass2() { return m_subclass2; } + private: list m_openStreams; // 0x8 MxStreamerSubClass2 m_subclass1; // 0x14 diff --git a/LEGO1/mxstreamprovider.cpp b/LEGO1/mxstreamprovider.cpp index b7233690..c1ba84cd 100644 --- a/LEGO1/mxstreamprovider.cpp +++ b/LEGO1/mxstreamprovider.cpp @@ -5,7 +5,7 @@ DECOMP_SIZE_ASSERT(MxStreamProvider, 0x10); // OFFSET: LEGO1 0x100d07c0 -MxResult MxStreamProvider::SetResourceToGet(void* p_resource) +MxResult MxStreamProvider::SetResourceToGet(MxStreamController* p_resource) { m_pLookup = p_resource; return SUCCESS; diff --git a/LEGO1/mxstreamprovider.h b/LEGO1/mxstreamprovider.h index e372d9ab..0b68e177 100644 --- a/LEGO1/mxstreamprovider.h +++ b/LEGO1/mxstreamprovider.h @@ -5,6 +5,8 @@ #include "mxcore.h" #include "mxdsfile.h" +class MxStreamController; + // VTABLEADDR 0x100dd100 // SIZE 0x10 class MxStreamProvider : public MxCore { @@ -23,15 +25,15 @@ class MxStreamProvider : public MxCore { return !strcmp(name, MxStreamProvider::ClassName()) || MxCore::IsA(name); } - virtual MxResult SetResourceToGet(void* p_resource); // vtable+0x14 - virtual MxU32 GetFileSize() = 0; // vtable+0x18 - virtual MxU32 GetStreamBuffersNum() = 0; // vtable+0x1c - virtual void vtable0x20(undefined4 p_unknown1); // vtable+0x20 - virtual MxU32 GetLengthInDWords() = 0; // vtable+0x24 - virtual MxU32* GetBufferForDWords() = 0; // vtable+0x28 + virtual MxResult SetResourceToGet(MxStreamController* p_resource); // vtable+0x14 + virtual MxU32 GetFileSize() = 0; // vtable+0x18 + virtual MxU32 GetStreamBuffersNum() = 0; // vtable+0x1c + virtual void vtable0x20(undefined4 p_unknown1); // vtable+0x20 + virtual MxU32 GetLengthInDWords() = 0; // vtable+0x24 + virtual MxU32* GetBufferForDWords() = 0; // vtable+0x28 protected: - void* m_pLookup; + MxStreamController* m_pLookup; MxDSFile* m_pFile; }; diff --git a/LEGO1/mxthread.cpp b/LEGO1/mxthread.cpp index fd252799..7e445f7d 100644 --- a/LEGO1/mxthread.cpp +++ b/LEGO1/mxthread.cpp @@ -68,13 +68,6 @@ MxTickleThread::MxTickleThread(MxCore* p_target, int p_frequencyMS) m_frequencyMS = p_frequencyMS; } -// OFFSET: LEGO1 0x100d0f50 -MxResult MxTickleThread::StartWithTarget(MxCore* p_target) -{ - m_target = p_target; - return Start(0x1000, 0); -} - // Match except for register allocation // OFFSET: LEGO1 0x100b8c90 MxResult MxTickleThread::Run() diff --git a/LEGO1/mxthread.h b/LEGO1/mxthread.h index 72a61d95..59b31554 100644 --- a/LEGO1/mxthread.h +++ b/LEGO1/mxthread.h @@ -7,6 +7,7 @@ class MxCore; +// VTABLE 0x100dc860 class MxThread { public: // Note: Comes before virtual destructor @@ -34,24 +35,22 @@ class MxThread { MxU32 m_threadId; MxBool m_running; MxSemaphore m_semaphore; + +protected: + MxCore* m_target; }; +// VTABLE 0x100dc6d8 class MxTickleThread : public MxThread { public: MxTickleThread(MxCore* p_target, int p_frequencyMS); - // Unclear at this time whether this function and the m_target field are - // actually a general "userdata" pointer in the base MxThread, but it seems - // like the only usage is with an MxTickleThread. - MxResult StartWithTarget(MxCore* p_target); - // Only inlined, no offset virtual ~MxTickleThread() {} MxResult Run() override; private: - MxCore* m_target; MxS32 m_frequencyMS; };