Implement/match LegoCacheSound::Play and Lego3DSound::FUN_10011a60

This commit is contained in:
Christian Semmler 2024-06-02 10:53:49 -04:00
parent 03ffb9c5de
commit fb8e7c6269
5 changed files with 168 additions and 26 deletions

View File

@ -20,6 +20,7 @@ class Lego3DSound {
MxResult Create(LPDIRECTSOUNDBUFFER p_directSoundBuffer, const char* p_name, MxS32 p_volume);
void Destroy();
MxU32 UpdatePosition(LPDIRECTSOUNDBUFFER p_directSoundBuffer);
void FUN_10011a60(LPDIRECTSOUNDBUFFER p_directSoundBuffer, const char* p_name);
void Reset();
MxS32 SetDistance(MxS32 p_min, MxS32 p_max);

View File

@ -39,8 +39,8 @@ class LegoCacheSound : public MxCore {
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);
LegoCacheSound* Clone();
MxResult Play(const char* p_name, MxBool p_looping);
void FUN_10006b80();
void FUN_10006be0();
void SetDistance(MxS32 p_min, MxS32 p_max);
@ -59,12 +59,12 @@ class LegoCacheSound : public MxCore {
MxU8* m_data; // 0x40
MxU32 m_dataSize; // 0x44
MxString m_unk0x48; // 0x48
undefined m_unk0x58; // 0x58
MxBool m_unk0x58; // 0x58
PCMWAVEFORMAT m_wfx; // 0x59
MxBool m_isLooping; // 0x69
MxBool m_looping; // 0x69
MxBool m_unk0x6a; // 0x6a
MxS32 m_volume; // 0x6c
undefined m_unk0x70; // 0x70
MxBool m_unk0x70; // 0x70
MxString m_unk0x74; // 0x74
undefined m_unk0x84; // 0x84
};

View File

@ -151,7 +151,6 @@ MxU32 Lego3DSound::UpdatePosition(LPDIRECTSOUNDBUFFER p_directSoundBuffer)
}
else {
MxS32 newVolume = m_volume;
if (distance < 100.0f) {
newVolume = m_volume;
}
@ -184,6 +183,101 @@ MxU32 Lego3DSound::UpdatePosition(LPDIRECTSOUNDBUFFER p_directSoundBuffer)
return updated;
}
// FUNCTION: LEGO1 0x10011a60
// FUNCTION: BETA10 0x10039d04
void Lego3DSound::FUN_10011a60(LPDIRECTSOUNDBUFFER p_directSoundBuffer, const char* p_name)
{
assert(p_directSoundBuffer);
if (p_name == NULL) {
if (m_ds3dBuffer != NULL) {
m_ds3dBuffer->SetMode(DS3DMODE_DISABLE, DS3D_IMMEDIATE);
}
}
else {
if (CharacterManager()->IsActor(p_name)) {
m_roi = CharacterManager()->GetActorROI(p_name, TRUE);
m_enabled = m_isActor = TRUE;
}
else {
m_roi = FindROI(p_name);
}
if (m_roi == NULL) {
m_roi = CharacterManager()->CreateAutoROI(NULL, p_name, TRUE);
if (m_roi != NULL) {
m_enabled = TRUE;
}
}
if (m_roi == NULL) {
return;
}
if (m_isActor) {
m_positionROI = m_roi->FindChildROI("head", m_roi);
}
else {
m_positionROI = m_roi;
}
if (m_ds3dBuffer != NULL) {
DWORD dwMode;
m_ds3dBuffer->GetMode(&dwMode);
if (dwMode & DS3DMODE_DISABLE) {
m_ds3dBuffer->SetMode(DS3DMODE_NORMAL, DS3D_IMMEDIATE);
}
const float* position = m_positionROI->GetWorldPosition();
m_ds3dBuffer->SetPosition(position[0], position[1], position[2], DS3D_IMMEDIATE);
}
else {
const float* position = m_positionROI->GetWorldPosition();
ViewROI* pov = VideoManager()->GetViewROI();
if (pov != NULL) {
const float* povPosition = pov->GetWorldPosition();
float distance = DISTSQRD3(povPosition, position);
MxS32 newVolume;
if (distance < 100.0f) {
newVolume = m_volume;
}
else if (distance < 400.0f) {
newVolume = m_volume * 0.4;
}
else if (distance < 3600.0f) {
newVolume = m_volume * 0.1;
}
else {
newVolume = 0;
}
newVolume = newVolume * SoundManager()->GetVolume() / 100;
newVolume = SoundManager()->GetAttenuation(newVolume);
p_directSoundBuffer->SetVolume(newVolume);
}
}
LegoEntity* entity = m_roi->GetEntity();
if (entity != NULL && entity->IsA("LegoActor") && ((LegoActor*) entity)->GetSoundFrequencyFactor() != 0.0f) {
m_actor = ((LegoActor*) entity);
}
p_directSoundBuffer->GetFrequency(&m_dwFrequency);
if (m_actor != NULL) {
m_frequencyFactor = m_actor->GetSoundFrequencyFactor();
if (m_frequencyFactor != 0.0) {
p_directSoundBuffer->SetFrequency(m_frequencyFactor * m_dwFrequency);
}
}
}
}
// FUNCTION: LEGO1 0x10011ca0
void Lego3DSound::Reset()
{

View File

@ -118,16 +118,16 @@ LegoCacheSound* LegoCacheSoundManager::FUN_1003db10(LegoCacheSound* p_one, const
}
if (p_one->GetUnknown0x58()) {
LegoCacheSound* result = p_one->FUN_10006960();
LegoCacheSound* result = p_one->Clone();
if (result) {
LegoCacheSound* t = ManageSoundEntry(result);
t->FUN_10006a30(p_two, p_three);
t->Play(p_two, p_three);
return t;
}
}
else {
p_one->FUN_10006a30(p_two, p_three);
p_one->Play(p_two, p_three);
return p_one;
}

View File

@ -23,11 +23,11 @@ void LegoCacheSound::Init()
{
m_dsBuffer = NULL;
m_data = NULL;
m_unk0x58 = 0;
m_unk0x58 = FALSE;
memset(&m_wfx, 0, sizeof(m_wfx));
m_unk0x6a = FALSE;
m_unk0x70 = 0;
m_isLooping = TRUE;
m_unk0x70 = FALSE;
m_looping = TRUE;
m_volume = 79;
m_unk0x84 = 0;
}
@ -114,22 +114,69 @@ void LegoCacheSound::Destroy()
Init();
}
// STUB: LEGO1 0x10006960
LegoCacheSound* LegoCacheSound::FUN_10006960()
// FUNCTION: LEGO1 0x10006960
// FUNCTION: BETA10 0x100668cf
LegoCacheSound* LegoCacheSound::Clone()
{
// TODO
LegoCacheSound* pnew = new LegoCacheSound();
if (pnew->Create(&m_wfx, m_unk0x48, m_volume, m_data, m_dataSize) == SUCCESS) {
return pnew;
}
delete pnew;
return NULL;
}
// STUB: LEGO1 0x10006a30
MxResult LegoCacheSound::FUN_10006a30(const char* p_str, MxBool)
// FUNCTION: LEGO1 0x10006a30
// FUNCTION: BETA10 0x10066a23
MxResult LegoCacheSound::Play(const char* p_name, MxBool p_looping)
{
// TODO
// gets param2 from FUN_1003db10
if (m_data == NULL && m_dataSize == 0) {
if (m_data == NULL || m_dataSize == 0) {
return FAILURE;
}
m_unk0x6a = FALSE;
m_sound.FUN_10011a60(m_dsBuffer, p_name);
if (p_name != NULL) {
m_unk0x74 = p_name;
}
DWORD dwStatus;
m_dsBuffer->GetStatus(&dwStatus);
if (dwStatus == DSBSTATUS_BUFFERLOST) {
m_dsBuffer->Restore();
m_dsBuffer->GetStatus(&dwStatus);
}
if (dwStatus != DSBSTATUS_BUFFERLOST) {
LPVOID pvAudioPtr1, pvAudioPtr2;
DWORD dwAudioBytes1, dwAudioBytes2;
if (m_dsBuffer->Lock(0, m_dataSize, &pvAudioPtr1, &dwAudioBytes1, &pvAudioPtr2, &dwAudioBytes2, 0) == DS_OK) {
memcpy(pvAudioPtr1, m_data, dwAudioBytes1);
if (dwAudioBytes2 != 0) {
memcpy(pvAudioPtr2, m_data + dwAudioBytes1, dwAudioBytes2);
}
m_dsBuffer->Unlock(pvAudioPtr1, dwAudioBytes1, pvAudioPtr2, dwAudioBytes2);
m_dsBuffer->SetCurrentPosition(0);
m_dsBuffer->Play(0, 0, p_looping);
}
}
if (p_looping == FALSE) {
m_looping = FALSE;
}
else {
m_looping = TRUE;
}
m_unk0x58 = TRUE;
m_unk0x70 = TRUE;
return SUCCESS;
}
@ -137,13 +184,13 @@ MxResult LegoCacheSound::FUN_10006a30(const char* p_str, MxBool)
void LegoCacheSound::FUN_10006b80()
{
DWORD dwStatus;
m_dsBuffer->GetStatus(&dwStatus);
if (dwStatus) {
m_dsBuffer->Stop();
}
m_unk0x58 = 0;
m_unk0x58 = FALSE;
m_unk0x6a = FALSE;
m_sound.Reset();
@ -155,7 +202,7 @@ void LegoCacheSound::FUN_10006b80()
// FUNCTION: LEGO1 0x10006be0
void LegoCacheSound::FUN_10006be0()
{
if (!m_isLooping) {
if (!m_looping) {
DWORD dwStatus;
m_dsBuffer->GetStatus(&dwStatus);
@ -164,7 +211,7 @@ void LegoCacheSound::FUN_10006be0()
return;
}
m_unk0x70 = 0;
m_unk0x70 = FALSE;
}
if (dwStatus == 0) {
@ -174,7 +221,7 @@ void LegoCacheSound::FUN_10006be0()
m_unk0x74 = "";
}
m_unk0x58 = 0;
m_unk0x58 = FALSE;
return;
}
}
@ -189,7 +236,7 @@ void LegoCacheSound::FUN_10006be0()
m_unk0x6a = TRUE;
}
else if (m_unk0x6a) {
m_dsBuffer->Play(0, 0, m_isLooping);
m_dsBuffer->Play(0, 0, m_looping);
m_unk0x6a = FALSE;
}
}