From 03ffb9c5de0aefda46634d57bb8f6be5ed345917 Mon Sep 17 00:00:00 2001 From: Christian Semmler <mail@csemmler.com> Date: Sat, 1 Jun 2024 17:29:37 -0400 Subject: [PATCH] Implement/match LegoCacheSound::Create and LegoLoadCacheSoundPresenter::StreamingTickle (#986) * Implement/match LegoCacheSound::Create * Naming * Fix naming * Fix parens --- .../legoomni/include/legocachesoundmanager.h | 2 +- LEGO1/lego/legoomni/include/legocachsound.h | 28 +++-- .../include/legoloadcachesoundpresenter.h | 8 +- .../src/audio/legocachesoundmanager.cpp | 8 +- .../lego/legoomni/src/audio/legocachsound.cpp | 112 +++++++++++++++--- .../src/audio/legoloadcachesoundpresenter.cpp | 50 +++++--- LEGO1/omni/include/mxdsmediaaction.h | 3 + LEGO1/omni/include/mxdssound.h | 4 +- LEGO1/omni/src/audio/mxwavepresenter.cpp | 4 +- 9 files changed, 165 insertions(+), 54 deletions(-) diff --git a/LEGO1/lego/legoomni/include/legocachesoundmanager.h b/LEGO1/lego/legoomni/include/legocachesoundmanager.h index e8dbc204..8297b416 100644 --- a/LEGO1/lego/legoomni/include/legocachesoundmanager.h +++ b/LEGO1/lego/legoomni/include/legocachesoundmanager.h @@ -12,7 +12,7 @@ struct LegoCacheSoundEntry { LegoCacheSoundEntry() : m_sound(NULL), m_name(NULL) {} LegoCacheSoundEntry(LegoCacheSound* p_sound, const char* p_name) : m_sound(p_sound), m_name(p_name) {} - LegoCacheSoundEntry(LegoCacheSound* p_sound) : m_sound(p_sound), m_name(p_sound->GetString0x48().GetData()) {} + LegoCacheSoundEntry(LegoCacheSound* p_sound) : m_sound(p_sound), m_name(p_sound->GetUnknown0x48().GetData()) {} // FUNCTION: LEGO1 0x1003d030 ~LegoCacheSoundEntry() diff --git a/LEGO1/lego/legoomni/include/legocachsound.h b/LEGO1/lego/legoomni/include/legocachsound.h index 86255152..10d0108b 100644 --- a/LEGO1/lego/legoomni/include/legocachsound.h +++ b/LEGO1/lego/legoomni/include/legocachsound.h @@ -26,12 +26,18 @@ public: return !strcmp(p_name, LegoCacheSound::ClassName()) || MxCore::IsA(p_name); } - virtual MxResult FUN_10006710(); // vtable+0x14 + virtual MxResult Create( + LPPCMWAVEFORMAT p_pwfx, + MxString p_mediaSrcPath, + MxS32 p_volume, + MxU8* p_data, + MxU32 p_dataSize + ); // vtable+0x14 virtual void Destroy(); // vtable+0x18 virtual void FUN_10006cd0(undefined4, undefined4); // vtable+0x1c - inline const MxString& GetString0x48() const { return m_string0x48; } - inline const undefined GetUnk0x58() const { return m_unk0x58; } + inline const MxString& GetUnknown0x48() const { return m_unk0x48; } + inline const undefined GetUnknown0x58() const { return m_unk0x58; } LegoCacheSound* FUN_10006960(); MxResult FUN_10006a30(const char* p_str, MxBool); @@ -44,20 +50,22 @@ public: private: void Init(); + void CopyData(MxU8* p_data, MxU32 p_dataSize); + MxString FUN_10006d80(const MxString& p_str); LPDIRECTSOUNDBUFFER m_dsBuffer; // 0x08 - undefined m_unk0xc[4]; // 0x0c + undefined m_unk0x0c[4]; // 0x0c Lego3DSound m_sound; // 0x10 - undefined* m_unk0x40; // 0x40 - undefined4 m_unk0x44; // 0x44 - MxString m_string0x48; // 0x48 + MxU8* m_data; // 0x40 + MxU32 m_dataSize; // 0x44 + MxString m_unk0x48; // 0x48 undefined m_unk0x58; // 0x58 - PCMWAVEFORMAT m_unk0x59; // 0x59 + PCMWAVEFORMAT m_wfx; // 0x59 MxBool m_isLooping; // 0x69 MxBool m_unk0x6a; // 0x6a - undefined4 m_unk0x6c; // 0x6c + MxS32 m_volume; // 0x6c undefined m_unk0x70; // 0x70 - MxString m_string0x74; // 0x74 + MxString m_unk0x74; // 0x74 undefined m_unk0x84; // 0x84 }; diff --git a/LEGO1/lego/legoomni/include/legoloadcachesoundpresenter.h b/LEGO1/lego/legoomni/include/legoloadcachesoundpresenter.h index 883f4b01..6def0dee 100644 --- a/LEGO1/lego/legoomni/include/legoloadcachesoundpresenter.h +++ b/LEGO1/lego/legoomni/include/legoloadcachesoundpresenter.h @@ -37,10 +37,10 @@ private: void Destroy(MxBool p_fromDestructor); LegoCacheSound* m_cacheSound; // 0x6c - undefined* m_unk0x70; // 0x70 - undefined* m_unk0x74; // 0x74 - undefined4 m_unk0x78; // 0x78 - undefined m_unk0x7c; // 0x7c + MxU8* m_data; // 0x70 + MxU8* m_pData; // 0x74 + MxU32 m_dataSize; // 0x78 + MxBool m_unk0x7c; // 0x7c PCMWAVEFORMAT m_pcmWaveFormat; // 0x7d }; diff --git a/LEGO1/lego/legoomni/src/audio/legocachesoundmanager.cpp b/LEGO1/lego/legoomni/src/audio/legocachesoundmanager.cpp index 8d645dfd..6628246b 100644 --- a/LEGO1/lego/legoomni/src/audio/legocachesoundmanager.cpp +++ b/LEGO1/lego/legoomni/src/audio/legocachesoundmanager.cpp @@ -37,7 +37,7 @@ MxResult LegoCacheSoundManager::Tickle() for (Set100d6b4c::iterator setIter = m_set.begin(); setIter != m_set.end(); setIter++) { #endif LegoCacheSound* sound = (*setIter).GetSound(); - if (sound->GetUnk0x58()) { + if (sound->GetUnknown0x58()) { sound->FUN_10006be0(); } } @@ -46,7 +46,7 @@ MxResult LegoCacheSoundManager::Tickle() while (listIter != m_list.end()) { LegoCacheSound* sound = (*listIter).GetSound(); - if (sound->GetUnk0x58()) { + if (sound->GetUnknown0x58()) { sound->FUN_10006be0(); listIter++; } @@ -84,7 +84,7 @@ LegoCacheSound* LegoCacheSoundManager::ManageSoundEntry(LegoCacheSound* p_sound) if (it != m_set.end()) { LegoCacheSound* sound = (*it).GetSound(); - if (sound->GetUnk0x58()) { + if (sound->GetUnknown0x58()) { m_list.push_back(LegoCacheSoundEntry(p_sound)); return p_sound; } @@ -117,7 +117,7 @@ LegoCacheSound* LegoCacheSoundManager::FUN_1003db10(LegoCacheSound* p_one, const return NULL; } - if (p_one->GetUnk0x58()) { + if (p_one->GetUnknown0x58()) { LegoCacheSound* result = p_one->FUN_10006960(); if (result) { diff --git a/LEGO1/lego/legoomni/src/audio/legocachsound.cpp b/LEGO1/lego/legoomni/src/audio/legocachsound.cpp index b426da5a..19ba06f3 100644 --- a/LEGO1/lego/legoomni/src/audio/legocachsound.cpp +++ b/LEGO1/lego/legoomni/src/audio/legocachsound.cpp @@ -12,10 +12,9 @@ LegoCacheSound::LegoCacheSound() Init(); } -// STUB: LEGO1 0x10006630 +// FUNCTION: LEGO1 0x10006630 LegoCacheSound::~LegoCacheSound() { - // TODO Destroy(); } @@ -23,39 +22,85 @@ LegoCacheSound::~LegoCacheSound() void LegoCacheSound::Init() { m_dsBuffer = NULL; - m_unk0x40 = NULL; + m_data = NULL; m_unk0x58 = 0; - memset(&m_unk0x59, 0, sizeof(m_unk0x59)); + memset(&m_wfx, 0, sizeof(m_wfx)); m_unk0x6a = FALSE; m_unk0x70 = 0; m_isLooping = TRUE; - m_unk0x6c = 79; + m_volume = 79; m_unk0x84 = 0; } -// STUB: LEGO1 0x10006710 +// FUNCTION: LEGO1 0x10006710 // FUNCTION: BETA10 0x10066505 -MxResult LegoCacheSound::FUN_10006710() +MxResult LegoCacheSound::Create( + LPPCMWAVEFORMAT p_pwfx, + MxString p_mediaSrcPath, + MxS32 p_volume, + MxU8* p_data, + MxU32 p_dataSize +) { - // TODO + WAVEFORMATEX wfx; + wfx.wFormatTag = p_pwfx->wf.wFormatTag; + wfx.nChannels = p_pwfx->wf.nChannels; + wfx.nSamplesPerSec = p_pwfx->wf.nSamplesPerSec; + wfx.nAvgBytesPerSec = p_pwfx->wf.nAvgBytesPerSec; + wfx.nBlockAlign = p_pwfx->wf.nBlockAlign; + wfx.wBitsPerSample = p_pwfx->wBitsPerSample; + wfx.cbSize = 0; + DSBUFFERDESC desc; memset(&desc, 0, sizeof(desc)); desc.dwSize = sizeof(desc); if (MxOmni::IsSound3D()) { - desc.dwFlags = DSBCAPS_PRIMARYBUFFER | DSBCAPS_CTRL3D; + desc.dwFlags = + DSBCAPS_STATIC | DSBCAPS_LOCSOFTWARE | DSBCAPS_CTRL3D | DSBCAPS_CTRLFREQUENCY | DSBCAPS_CTRLVOLUME; } else { - desc.dwFlags = DSBCAPS_PRIMARYBUFFER | DSBCAPS_CTRLVOLUME; + desc.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME; } + desc.dwBufferBytes = p_dataSize; + desc.lpwfxFormat = &wfx; + if (SoundManager()->GetDirectSound()->CreateSoundBuffer(&desc, &m_dsBuffer, NULL) != DS_OK) { return FAILURE; } + m_volume = p_volume; + + MxS32 volume = m_volume * SoundManager()->GetVolume() / 100; + MxS32 attenuation = SoundManager()->GetAttenuation(volume); + m_dsBuffer->SetVolume(attenuation); + + if (m_sound.Create(m_dsBuffer, NULL, m_volume) != SUCCESS) { + m_dsBuffer->Release(); + m_dsBuffer = NULL; + return FAILURE; + } + + if (p_data != NULL && p_dataSize != 0) { + CopyData(p_data, p_dataSize); + } + + m_unk0x48 = FUN_10006d80(p_mediaSrcPath); + m_wfx = *p_pwfx; return SUCCESS; } +// FUNCTION: LEGO1 0x100068e0 +// FUNCTION: BETA10 0x100667a0 +void LegoCacheSound::CopyData(MxU8* p_data, MxU32 p_dataSize) +{ + delete[] m_data; + m_dataSize = p_dataSize; + m_data = new MxU8[m_dataSize]; + memcpy(m_data, p_data, m_dataSize); +} + // FUNCTION: LEGO1 0x10006920 void LegoCacheSound::Destroy() { @@ -65,7 +110,7 @@ void LegoCacheSound::Destroy() m_dsBuffer = NULL; } - delete m_unk0x40; + delete[] m_data; Init(); } @@ -81,7 +126,7 @@ MxResult LegoCacheSound::FUN_10006a30(const char* p_str, MxBool) { // TODO // gets param2 from FUN_1003db10 - if (!m_unk0x40 && !m_unk0x44) { + if (m_data == NULL && m_dataSize == 0) { return FAILURE; } @@ -102,8 +147,8 @@ void LegoCacheSound::FUN_10006b80() m_unk0x6a = FALSE; m_sound.Reset(); - if (m_string0x74.GetLength() != 0) { - m_string0x74 = ""; + if (m_unk0x74.GetLength() != 0) { + m_unk0x74 = ""; } } @@ -125,8 +170,8 @@ void LegoCacheSound::FUN_10006be0() if (dwStatus == 0) { m_dsBuffer->Stop(); m_sound.Reset(); - if (m_string0x74.GetLength() != 0) { - m_string0x74 = ""; + if (m_unk0x74.GetLength() != 0) { + m_unk0x74 = ""; } m_unk0x58 = 0; @@ -134,7 +179,7 @@ void LegoCacheSound::FUN_10006be0() } } - if (m_string0x74.GetLength() != 0 && !m_unk0x84) { + if (m_unk0x74.GetLength() != 0 && !m_unk0x84) { if (!m_sound.UpdatePosition(m_dsBuffer)) { if (m_unk0x6a) { return; @@ -160,3 +205,36 @@ void LegoCacheSound::SetDistance(MxS32 p_min, MxS32 p_max) void LegoCacheSound::FUN_10006cd0(undefined4, undefined4) { } + +// FUNCTION: LEGO1 0x10006d80 +// FUNCTION: BETA10 0x100670e7 +MxString LegoCacheSound::FUN_10006d80(const MxString& p_str) +{ + // TODO: Clean up code + char* str = p_str.GetData(); + MxU32 length = strlen(str); + + char* local28 = str + length; + char* local14 = local28; + char* pVar1 = local28; + + do { + local14 = pVar1; + pVar1 = local14 + -1; + + if (str == local14) { + break; + } + + if (*pVar1 == '.') { + local28 = pVar1; + } + } while (*pVar1 != '\\'); + + local14 = pVar1; + + MxString local24; + local14++; + *local28 = '\0'; + return local24 = local14; +} diff --git a/LEGO1/lego/legoomni/src/audio/legoloadcachesoundpresenter.cpp b/LEGO1/lego/legoomni/src/audio/legoloadcachesoundpresenter.cpp index 7bf31340..a0a66e89 100644 --- a/LEGO1/lego/legoomni/src/audio/legoloadcachesoundpresenter.cpp +++ b/LEGO1/lego/legoomni/src/audio/legoloadcachesoundpresenter.cpp @@ -4,6 +4,7 @@ #include "legocachsound.h" #include "legosoundmanager.h" #include "misc.h" +#include "mxdssound.h" #include "mxdssubscriber.h" #include "mxstreamchunk.h" #include "mxwavepresenter.h" @@ -25,50 +26,71 @@ LegoLoadCacheSoundPresenter::~LegoLoadCacheSoundPresenter() // FUNCTION: LEGO1 0x100184e0 void LegoLoadCacheSoundPresenter::Init() { - this->m_unk0x70 = NULL; - this->m_unk0x78 = 0; - this->m_unk0x7c = 0; + m_data = NULL; + m_dataSize = 0; + m_unk0x7c = FALSE; } // FUNCTION: LEGO1 0x100184f0 void LegoLoadCacheSoundPresenter::Destroy(MxBool p_fromDestructor) { - delete[] this->m_unk0x70; + delete[] m_data; MxWavePresenter::Destroy(p_fromDestructor); } // FUNCTION: LEGO1 0x10018510 +// FUNCTION: BETA10 0x1008c305 void LegoLoadCacheSoundPresenter::ReadyTickle() { MxStreamChunk* chunk = NextChunk(); if (chunk) { WaveFormat* header = (WaveFormat*) chunk->GetData(); - m_unk0x78 = 0; + m_dataSize = 0; MxU8* data = new MxU8[header->m_dataSize]; - m_unk0x70 = data; - m_unk0x74 = data; + m_data = data; + m_pData = data; - m_cacheSound = new LegoCacheSound; - memcpy(&m_pcmWaveFormat, &header->m_pcmWaveFormat, sizeof(m_pcmWaveFormat)); + m_cacheSound = new LegoCacheSound(); + m_pcmWaveFormat = header->m_pcmWaveFormat; m_subscriber->FreeDataChunk(chunk); ProgressTickleState(e_streaming); } } -// STUB: LEGO1 0x100185f0 +// FUNCTION: LEGO1 0x100185f0 +// FUNCTION: BETA10 0x1008c48f void LegoLoadCacheSoundPresenter::StreamingTickle() { - // TODO - EndAction(); + MxStreamChunk* chunk = NextChunk(); + + if (chunk) { + if (chunk->GetChunkFlags() & DS_CHUNK_END_OF_STREAM) { + m_cacheSound->Create( + &m_pcmWaveFormat, + ((MxDSSound*) m_action)->GetMediaSrcPath(), + ((MxDSSound*) m_action)->GetVolume(), + m_data + 2, + m_dataSize - 2 + ); + ProgressTickleState(e_done); + } + else { + memcpy(m_pData, chunk->GetData(), chunk->GetLength()); + m_dataSize += chunk->GetLength(); + m_pData += chunk->GetLength(); + } + + m_subscriber->FreeDataChunk(chunk); + } } // FUNCTION: LEGO1 0x100186f0 void LegoLoadCacheSoundPresenter::DoneTickle() { - if (m_unk0x7c != 0) { + if (m_unk0x7c) { EndAction(); } } @@ -80,7 +102,7 @@ MxResult LegoLoadCacheSoundPresenter::PutData() if (m_currentTickleState == e_done) { m_cacheSound = SoundManager()->GetCacheSoundManager()->ManageSoundEntry(m_cacheSound); - m_unk0x7c = 1; + m_unk0x7c = TRUE; } m_criticalSection.Leave(); diff --git a/LEGO1/omni/include/mxdsmediaaction.h b/LEGO1/omni/include/mxdsmediaaction.h index 9b5f8604..ec393c05 100644 --- a/LEGO1/omni/include/mxdsmediaaction.h +++ b/LEGO1/omni/include/mxdsmediaaction.h @@ -42,6 +42,9 @@ public: void CopyMediaSrcPath(const char* p_mediaSrcPath); + // FUNCTION: LEGO1 0x100186e0 + inline const char* GetMediaSrcPath() { return m_mediaSrcPath; } + // FUNCTION: BETA10 0x1013c2e0 inline MxS32 GetFramesPerSecond() const { return m_framesPerSecond; } diff --git a/LEGO1/omni/include/mxdssound.h b/LEGO1/omni/include/mxdssound.h index c406ba92..bd4f7c6b 100644 --- a/LEGO1/omni/include/mxdssound.h +++ b/LEGO1/omni/include/mxdssound.h @@ -36,8 +36,8 @@ public: // MxDSSound::`scalar deleting destructor' private: - MxU32 m_sizeOnDisk; - MxS32 m_volume; // 0xbc + MxU32 m_sizeOnDisk; // 0xb8 + MxS32 m_volume; // 0xbc }; #endif // MXDSSOUND_H diff --git a/LEGO1/omni/src/audio/mxwavepresenter.cpp b/LEGO1/omni/src/audio/mxwavepresenter.cpp index 80e52dd1..caac77cc 100644 --- a/LEGO1/omni/src/audio/mxwavepresenter.cpp +++ b/LEGO1/omni/src/audio/mxwavepresenter.cpp @@ -299,8 +299,8 @@ void MxWavePresenter::SetVolume(MxS32 p_volume) m_volume = p_volume; if (m_dsBuffer != NULL) { MxS32 volume = p_volume * MxOmni::GetInstance()->GetSoundManager()->GetVolume() / 100; - MxS32 otherVolume = MxOmni::GetInstance()->GetSoundManager()->GetAttenuation(volume); - m_dsBuffer->SetVolume(otherVolume); + MxS32 attenuation = MxOmni::GetInstance()->GetSoundManager()->GetAttenuation(volume); + m_dsBuffer->SetVolume(attenuation); } m_criticalSection.Leave();