From 7db2b2e6b7e7e08754874dc6b4020328405d60a0 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Fri, 24 Nov 2023 12:21:26 -0500 Subject: [PATCH] Implement/match MxMidiPresenter (#301) --- LEGO1/mxmidipresenter.cpp | 90 ++++++++++++++++++++++++++++---------- LEGO1/mxmidipresenter.h | 19 ++++---- LEGO1/mxmusicmanager.cpp | 16 +++++++ LEGO1/mxmusicmanager.h | 5 ++- LEGO1/mxmusicpresenter.cpp | 4 ++ 5 files changed, 102 insertions(+), 32 deletions(-) diff --git a/LEGO1/mxmidipresenter.cpp b/LEGO1/mxmidipresenter.cpp index 37b6ea9c..6d283aad 100644 --- a/LEGO1/mxmidipresenter.cpp +++ b/LEGO1/mxmidipresenter.cpp @@ -2,17 +2,12 @@ #include "decomp.h" #include "legoomni.h" +#include "mxautolocker.h" +#include "mxdssound.h" #include "mxmusicmanager.h" DECOMP_SIZE_ASSERT(MxMIDIPresenter, 0x58); -// OFFSET: LEGO1 0x100c25a0 STUB -MxResult MxMIDIPresenter::AddToManager() -{ - // TODO - return SUCCESS; -} - // OFFSET: LEGO1 0x100c25e0 MxMIDIPresenter::MxMIDIPresenter() { @@ -28,31 +23,61 @@ MxMIDIPresenter::~MxMIDIPresenter() // OFFSET: LEGO1 0x100c2820 void MxMIDIPresenter::Init() { - m_unk54 = 0; + m_chunk = NULL; } -// OFFSET: LEGO1 0x100c2830 STUB +// OFFSET: LEGO1 0x100c2830 void MxMIDIPresenter::Destroy(MxBool p_fromDestructor) { - // TODO + if (MusicManager()) { + MusicManager()->DeinitializeMIDI(); + } + + m_criticalSection.Enter(); + + if (m_subscriber && m_chunk) + m_subscriber->FUN_100b8390(m_chunk); + Init(); + + m_criticalSection.Leave(); + + if (!p_fromDestructor) + MxMusicPresenter::Destroy(); } -// OFFSET: LEGO1 0x100c2890 STUB +// OFFSET: LEGO1 0x100c2890 void MxMIDIPresenter::ReadyTickle() { - // TODO + MxStreamChunk* chunk = NextChunk(); + + if (chunk) { + m_subscriber->FUN_100b8390(chunk); + ParseExtra(); + m_previousTickleStates |= 1 << (unsigned char) m_currentTickleState; + m_currentTickleState = TickleState_Starting; + } } -// OFFSET: LEGO1 0x100c28d0 STUB +// OFFSET: LEGO1 0x100c28d0 void MxMIDIPresenter::StartingTickle() { - // TODO + MxStreamChunk* chunk = FUN_100b5650(); + + if (chunk && m_action->GetElapsedTime() >= chunk->GetTime()) { + m_previousTickleStates |= 1 << (unsigned char) m_currentTickleState; + m_currentTickleState = TickleState_Streaming; + } } -// OFFSET: LEGO1 0x100c2910 STUB +// OFFSET: LEGO1 0x100c2910 void MxMIDIPresenter::StreamingTickle() { - // TODO + if (m_chunk) { + m_previousTickleStates |= 1 << (unsigned char) m_currentTickleState; + m_currentTickleState = TickleState_Done; + } + else + m_chunk = NextChunk(); } // OFFSET: LEGO1 0x100c2940 @@ -62,21 +87,42 @@ void MxMIDIPresenter::DoneTickle() EndAction(); } -// OFFSET: LEGO1 0x100c2960 STUB +// OFFSET: LEGO1 0x100c2960 void MxMIDIPresenter::Destroy() { - // TODO + Destroy(FALSE); } -// OFFSET: LEGO1 0x100c2970 STUB +// OFFSET: LEGO1 0x100c2970 undefined4 MxMIDIPresenter::PutData() { - // TODO + m_criticalSection.Enter(); + + if (m_currentTickleState == TickleState_Streaming && m_chunk && !MusicManager()->GetMIDIInitialized()) { + SetVolume(((MxDSSound*) m_action)->GetVolume()); + + if (MusicManager()->FUN_100c09c0(m_chunk->GetData(), 1)) + EndAction(); + } + + m_criticalSection.Leave(); return 0; } -// OFFSET: LEGO1 0x100c29e0 STUB +// OFFSET: LEGO1 0x100c29e0 void MxMIDIPresenter::EndAction() { - // TODO + if (m_action) { + MxAutoLocker lock(&m_criticalSection); + + MxMediaPresenter::EndAction(); + MusicManager()->DeinitializeMIDI(); + } +} + +// OFFSET: LEGO1 0x100c2a60 +void MxMIDIPresenter::SetVolume(MxS32 p_volume) +{ + m_volume = p_volume; + MusicManager()->SetMultiplier(p_volume); } diff --git a/LEGO1/mxmidipresenter.h b/LEGO1/mxmidipresenter.h index 245adb34..0d2afc2d 100644 --- a/LEGO1/mxmidipresenter.h +++ b/LEGO1/mxmidipresenter.h @@ -2,6 +2,7 @@ #define MXMIDIPRESENTER_H #include "mxmusicpresenter.h" +#include "mxstreamchunk.h" // VTABLE 0x100dca20 // SIZE 0x58 @@ -23,20 +24,20 @@ public: return !strcmp(name, MxMIDIPresenter::ClassName()) || MxMusicPresenter::IsA(name); } - virtual void ReadyTickle() override; // vtable+0x18 - virtual void StartingTickle() override; // vtable+0x1c - virtual void StreamingTickle() override; // vtable+0x20 - virtual void DoneTickle() override; // vtable+0x2c - virtual MxResult AddToManager() override; // vtable+0x34 - virtual void Destroy() override; // vtable+0x38 - virtual void EndAction() override; // vtable+0x40 - virtual undefined4 PutData() override; // vtable+0x4c + virtual void ReadyTickle() override; // vtable+0x18 + virtual void StartingTickle() override; // vtable+0x1c + virtual void StreamingTickle() override; // vtable+0x20 + virtual void DoneTickle() override; // vtable+0x2c + virtual void Destroy() override; // vtable+0x38 + virtual void EndAction() override; // vtable+0x40 + virtual undefined4 PutData() override; // vtable+0x4c + virtual void SetVolume(MxS32 p_volume) override; // vtable+0x60 private: void Init(); void Destroy(MxBool p_fromDestructor); - undefined4 m_unk54; + MxStreamChunk* m_chunk; }; #endif // MXMIDIPRESENTER_H diff --git a/LEGO1/mxmusicmanager.cpp b/LEGO1/mxmusicmanager.cpp index e380bcf7..1e971f4d 100644 --- a/LEGO1/mxmusicmanager.cpp +++ b/LEGO1/mxmusicmanager.cpp @@ -120,6 +120,15 @@ void MxMusicManager::SetVolume(MxS32 p_volume) m_criticalSection.Leave(); } +// OFFSET: LEGO1 0x100c0970 +void MxMusicManager::SetMultiplier(MxS32 p_multiplier) +{ + m_criticalSection.Enter(); + m_multiplier = p_multiplier; + SetMIDIVolume(); + m_criticalSection.Leave(); +} + // OFFSET: LEGO1 0x100c09a0 MxS32 MxMusicManager::CalculateVolume(MxS32 p_volume) { @@ -127,6 +136,13 @@ MxS32 MxMusicManager::CalculateVolume(MxS32 p_volume) return (result << 0x10) | result; } +// OFFSET: LEGO1 0x100c09c0 STUB +undefined4 MxMusicManager::FUN_100c09c0(MxU8* p_data, undefined4) +{ + // TODO + return 0; +} + // OFFSET: LEGO1 0x100c0b20 void MxMusicManager::DeinitializeMIDI() { diff --git a/LEGO1/mxmusicmanager.h b/LEGO1/mxmusicmanager.h index f128b1b6..b4a3a1c4 100644 --- a/LEGO1/mxmusicmanager.h +++ b/LEGO1/mxmusicmanager.h @@ -17,9 +17,12 @@ public: inline MxBool GetMIDIInitialized() { return m_MIDIInitialized; } + void DeinitializeMIDI(); + undefined4 FUN_100c09c0(MxU8* p_data, undefined4); + void SetMultiplier(MxS32 p_multiplier); + private: void Destroy(MxBool p_fromDestructor); - void DeinitializeMIDI(); MxS32 CalculateVolume(MxS32 p_volume); void SetMIDIVolume(); diff --git a/LEGO1/mxmusicpresenter.cpp b/LEGO1/mxmusicpresenter.cpp index bd28eae5..e963a8e1 100644 --- a/LEGO1/mxmusicpresenter.cpp +++ b/LEGO1/mxmusicpresenter.cpp @@ -29,9 +29,11 @@ void MxMusicPresenter::Destroy(MxBool p_fromDestructor) if (MusicManager()) { MusicManager()->RemovePresenter(*this); } + m_criticalSection.Enter(); Init(); m_criticalSection.Leave(); + if (!p_fromDestructor) { MxMediaPresenter::Destroy(FALSE); } @@ -41,10 +43,12 @@ void MxMusicPresenter::Destroy(MxBool p_fromDestructor) MxResult MxMusicPresenter::AddToManager() { MxResult result = FAILURE; + if (MusicManager()) { result = SUCCESS; MusicManager()->AddPresenter(*this); } + return result; }