diff --git a/LEGO1/mxsoundmanager.h b/LEGO1/mxsoundmanager.h index 5fc5dfb3..5cb1f607 100644 --- a/LEGO1/mxsoundmanager.h +++ b/LEGO1/mxsoundmanager.h @@ -23,6 +23,8 @@ public: virtual void vtable0x34(); // vtable+0x34 virtual void vtable0x38(); // vtable+0x38 + inline LPDIRECTSOUND GetDirectSound() { return m_directSound; } + private: void Init(); void Destroy(MxBool p_fromDestructor); diff --git a/LEGO1/mxsoundpresenter.h b/LEGO1/mxsoundpresenter.h index 408dbe88..70ca14ca 100644 --- a/LEGO1/mxsoundpresenter.h +++ b/LEGO1/mxsoundpresenter.h @@ -26,7 +26,7 @@ public: virtual MxResult AddToManager() override; // vtable+0x34 virtual void Destroy() override; // vtable+0x38 -private: +protected: void Destroy(MxBool p_fromDestructor); }; diff --git a/LEGO1/mxwavepresenter.cpp b/LEGO1/mxwavepresenter.cpp index 133d08eb..e1ae2782 100644 --- a/LEGO1/mxwavepresenter.cpp +++ b/LEGO1/mxwavepresenter.cpp @@ -1,22 +1,213 @@ #include "mxwavepresenter.h" #include "decomp.h" +#include "mxdssound.h" +#include "mxomni.h" +#include "mxsoundmanager.h" + +#include DECOMP_SIZE_ASSERT(MxWavePresenter, 0x6c); +DECOMP_SIZE_ASSERT(MxWavePresenter::WaveFormat, 0x1c); + +// OFFSET: LEGO1 0x1000d640 +MxWavePresenter::~MxWavePresenter() +{ + Destroy(TRUE); +} + +// OFFSET: LEGO1 0x1000d6a0 +void MxWavePresenter::Destroy() +{ + Destroy(FALSE); +} + +// OFFSET: LEGO1 0x1000d6b0 +undefined MxWavePresenter::VTable0x6c() +{ + return m_unk68; +} // OFFSET: LEGO1 0x100b1ad0 void MxWavePresenter::Init() { - m_unk54 = 0; - m_unk58 = 0; - m_unk5c = 0; + m_waveFormat = NULL; + m_dsBuffer = NULL; + m_length = 0; m_unk60 = 0; m_unk64 = 0; - m_unk65 = 0; - m_unk66 = 0; + m_unk65 = FALSE; + m_unk66 = FALSE; m_unk68 = 0; } +// OFFSET: LEGO1 0x100b1af0 +MxResult MxWavePresenter::AddToManager() +{ + MxResult result = MxSoundPresenter::AddToManager(); + Init(); + return result; +} + +// OFFSET: LEGO1 0x100b1b10 +void MxWavePresenter::Destroy(MxBool p_fromDestructor) +{ + if (m_dsBuffer) { + m_dsBuffer->Stop(); + m_dsBuffer->Release(); + } + + if (m_waveFormat) + delete[] ((MxU8*) m_waveFormat); + + Init(); + + if (!p_fromDestructor) + MxSoundPresenter::Destroy(FALSE); +} + +// OFFSET: LEGO1 0x100b1b60 +MxS8 MxWavePresenter::FUN_100b1b60() +{ + DWORD dwCurrentPlayCursor, dwCurrentWriteCursor; + MxS8 result = -1; + + if (m_dsBuffer->GetCurrentPosition(&dwCurrentPlayCursor, &dwCurrentWriteCursor) == DS_OK) + result = dwCurrentPlayCursor / m_length; + + return result; +} + +// OFFSET: LEGO1 0x100b1ba0 +MxBool MxWavePresenter::FUN_100b1ba0() +{ + return !m_unk65 || FUN_100b1b60() != m_unk64; +} + +// OFFSET: LEGO1 0x100b1bd0 STUB +void MxWavePresenter::FUN_100b1bd0(void* p_audioPtr, MxU32 p_length) +{ + // Lock/Unlock on m_dsBuffer + // TODO +} + +// OFFSET: LEGO1 0x100b1cf0 +void MxWavePresenter::ReadyTickle() +{ + MxStreamChunk* chunk = NextChunk(); + + if (chunk) { + m_waveFormat = (WaveFormat*) new MxU8[chunk->GetLength()]; + memcpy(m_waveFormat, chunk->GetData(), chunk->GetLength()); + m_subscriber->FUN_100b8390(chunk); + ParseExtra(); + m_previousTickleStates |= 1 << (unsigned char) m_currentTickleState; + m_currentTickleState = TickleState_Starting; + } +} + +// OFFSET: LEGO1 0x100b1d50 +void MxWavePresenter::StartingTickle() +{ + MxStreamChunk* chunk = NextChunk(); + + if (chunk && m_action->GetElapsedTime() >= chunk->GetTime()) { + MxU32 length = chunk->GetLength(); + WAVEFORMATEX waveFormatEx; + + m_length = length; + memset(&waveFormatEx, 0, sizeof(waveFormatEx)); + + waveFormatEx.wFormatTag = m_waveFormat->m_waveFormatEx.wFormatTag; + waveFormatEx.nChannels = m_waveFormat->m_waveFormatEx.nChannels; + waveFormatEx.nSamplesPerSec = m_waveFormat->m_waveFormatEx.nSamplesPerSec; + waveFormatEx.nAvgBytesPerSec = m_waveFormat->m_waveFormatEx.nAvgBytesPerSec; + waveFormatEx.nBlockAlign = m_waveFormat->m_waveFormatEx.nBlockAlign; + waveFormatEx.wBitsPerSample = m_waveFormat->m_waveFormatEx.wBitsPerSample; + + if (waveFormatEx.wBitsPerSample == 8) + m_unk67 = SCHAR_MAX; + + if (waveFormatEx.wBitsPerSample == 16) + m_unk67 = 0; + + DSBUFFERDESC desc; + memset(&desc, 0, sizeof(desc)); + desc.dwSize = sizeof(desc); + + if (m_unk66) + desc.dwFlags = DSBCAPS_CTRL3D | DSBCAPS_CTRLFREQUENCY | DSBCAPS_CTRLVOLUME; + else + desc.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME; + + if (m_action->GetFlags() & MxDSAction::Flag_Looping) + desc.dwBufferBytes = m_waveFormat->m_waveFormatEx.nAvgBytesPerSec * + (m_action->GetDuration() / m_action->GetLoopCount()) / 1000; + else + desc.dwBufferBytes = 2 * length; + + desc.lpwfxFormat = &waveFormatEx; + + if (MSoundManager()->GetDirectSound()->CreateSoundBuffer(&desc, &m_dsBuffer, NULL) != DS_OK) { + EndAction(); + } + else { + SetVolume(((MxDSSound*) m_action)->GetVolume()); + m_previousTickleStates |= 1 << (unsigned char) m_currentTickleState; + m_currentTickleState = TickleState_Streaming; + } + } +} + +// OFFSET: LEGO1 0x100b1ea0 STUB +void MxWavePresenter::StreamingTickle() +{ + // TODO +} + +// OFFSET: LEGO1 0x100b20c0 STUB +void MxWavePresenter::DoneTickle() +{ + // TODO +} + +// OFFSET: LEGO1 0x100b2130 STUB +void MxWavePresenter::AppendChunk(MxStreamChunk* p_chunk) +{ + // TODO +} + +// OFFSET: LEGO1 0x100b2160 STUB +undefined4 MxWavePresenter::PutData() +{ + // TODO + return 0; +} + +// OFFSET: LEGO1 0x100b2280 STUB +void MxWavePresenter::EndAction() +{ + // TODO +} + +// OFFSET: LEGO1 0x100b2300 STUB +void MxWavePresenter::SetVolume(MxU32 p_volume) +{ + // TODO +} + +// OFFSET: LEGO1 0x100b2360 STUB +void MxWavePresenter::Enable(MxBool p_enable) +{ + // TODO +} + +// OFFSET: LEGO1 0x100b23a0 STUB +void MxWavePresenter::ParseExtra() +{ + // TODO +} + // OFFSET: LEGO1 0x100b2440 STUB void MxWavePresenter::VTable0x64() { @@ -28,9 +219,3 @@ void MxWavePresenter::VTable0x68() { // TODO } - -// OFFSET: LEGO1 0x1000d6b0 -undefined MxWavePresenter::VTable0x6c() -{ - return m_unk68; -} diff --git a/LEGO1/mxwavepresenter.h b/LEGO1/mxwavepresenter.h index 06300b7f..57e6f007 100644 --- a/LEGO1/mxwavepresenter.h +++ b/LEGO1/mxwavepresenter.h @@ -4,14 +4,14 @@ #include "decomp.h" #include "mxsoundpresenter.h" +#include + // VTABLE 0x100d49a8 // SIZE 0x6c class MxWavePresenter : public MxSoundPresenter { -private: - void Init(); - public: MxWavePresenter() { Init(); } + virtual ~MxWavePresenter() override; // vtable+0x00 // OFFSET: LEGO1 0x1000d6c0 inline virtual const char* ClassName() const override // vtable+0x0c @@ -26,19 +26,45 @@ public: return !strcmp(name, MxWavePresenter::ClassName()) || MxSoundPresenter::IsA(name); } - virtual void VTable0x64(); // vtable+0x64 - virtual void VTable0x68(); // vtable+0x68 - virtual undefined VTable0x6c(); // vtable+0x6c + 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 ParseExtra() override; // vtable+0x30 + 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 Enable(MxBool p_enable) override; // vtable+0x54 + virtual void AppendChunk(MxStreamChunk* p_chunk) override; // vtable+0x58 + virtual void SetVolume(MxU32 p_volume) override; // vtable+0x60 + virtual void VTable0x64(); // vtable+0x64 + virtual void VTable0x68(); // vtable+0x68 + virtual undefined VTable0x6c(); // vtable+0x6c + + // Reference: https://github.com/itsmattkc/SIEdit/blob/master/lib/othertypes.h + // SIZE 0x1c + struct WaveFormat { + WAVEFORMATEX m_waveFormatEx; + MxU32 m_dataSize; + MxU32 m_flags; + }; private: - undefined4 m_unk54; - undefined4 m_unk58; - undefined4 m_unk5c; + void Init(); + void Destroy(MxBool p_fromDestructor); + MxS8 FUN_100b1b60(); + MxBool FUN_100b1ba0(); + void FUN_100b1bd0(void* p_audioPtr, MxU32 p_length); + + WaveFormat* m_waveFormat; + LPDIRECTSOUNDBUFFER m_dsBuffer; + MxU32 m_length; undefined4 m_unk60; - undefined m_unk64; - undefined m_unk65; - undefined m_unk66; - undefined m_unk67; + MxU8 m_unk64; + MxBool m_unk65; + MxBool m_unk66; + MxS8 m_unk67; undefined m_unk68; };