From b8dea116ee2ad048204456fc33c667eb3b34cec0 Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Sun, 25 Dec 2022 21:56:23 +0300 Subject: [PATCH] Improve Sound readability --- src/game_sound.cc | 16 +- src/interpreter_lib.cc | 29 ++- src/lips.cc | 2 +- src/sound.cc | 453 +++++++++++++++++++++-------------------- src/sound.h | 66 +++--- 5 files changed, 292 insertions(+), 274 deletions(-) diff --git a/src/game_sound.cc b/src/game_sound.cc index 0044fa0..88d6a04 100644 --- a/src/game_sound.cc +++ b/src/game_sound.cc @@ -1681,21 +1681,21 @@ void soundEffectCallback(void* userData, int a2) // 0x451ADC int _gsound_background_allocate(Sound** soundPtr, int a2, int a3) { - int v5 = 10; - int v6 = 0; + int soundFlags = SOUND_FLAG_0x02 | SOUND_16BIT; + int type = 0; if (a2 == 13) { - v6 |= 0x01; + type |= SOUND_TYPE_MEMORY; } else if (a2 == 14) { - v6 |= 0x02; + type |= SOUND_TYPE_STREAMING; } if (a3 == 15) { - v6 |= 0x04; + type |= SOUND_TYPE_FIRE_AND_FORGET; } else if (a3 == 16) { - v5 = 42; + soundFlags |= SOUND_LOOPING; } - Sound* sound = soundAllocate(v6, v5); + Sound* sound = soundAllocate(type, soundFlags); if (sound == NULL) { return -1; } @@ -2006,7 +2006,7 @@ Sound* _gsound_get_sound_ready_for_effect() { int rc; - Sound* sound = soundAllocate(5, 10); + Sound* sound = soundAllocate(SOUND_TYPE_MEMORY | SOUND_TYPE_FIRE_AND_FORGET, SOUND_FLAG_0x02 | SOUND_16BIT); if (sound == NULL) { if (gGameSoundDebugEnabled) { debugPrint(" Can't allocate sound for effect. "); diff --git a/src/interpreter_lib.cc b/src/interpreter_lib.cc index 0d6008f..67201f1 100644 --- a/src/interpreter_lib.cc +++ b/src/interpreter_lib.cc @@ -1872,32 +1872,29 @@ static int intLibSoundDelete(int value) // 0x466110 static int intLibSoundPlay(char* fileName, int mode) { - int v3 = 1; - int v5 = 0; + int type = SOUND_TYPE_MEMORY; + int soundFlags = 0; if (mode & 0x01) { - // looping - v5 |= 0x20; + soundFlags |= SOUND_LOOPING; } else { - v3 = 5; + type |= SOUND_TYPE_FIRE_AND_FORGET; } if (mode & 0x02) { - v5 |= 0x08; + soundFlags |= SOUND_16BIT; } else { - v5 |= 0x10; + soundFlags |= SOUND_8BIT; } if (mode & 0x0100) { - // memory - v3 &= ~0x03; - v3 |= 0x01; + type &= ~(SOUND_TYPE_MEMORY | SOUND_TYPE_STREAMING); + type |= SOUND_TYPE_MEMORY; } if (mode & 0x0200) { - // streamed - v3 &= ~0x03; - v3 |= 0x02; + type &= ~(SOUND_TYPE_MEMORY | SOUND_TYPE_STREAMING); + type |= SOUND_TYPE_STREAMING; } int index; @@ -1911,7 +1908,7 @@ static int intLibSoundPlay(char* fileName, int mode) return -1; } - Sound* sound = gIntLibSounds[index] = soundAllocate(v3, v5); + Sound* sound = gIntLibSounds[index] = soundAllocate(type, soundFlags); if (sound == NULL) { return -1; } @@ -2009,7 +2006,7 @@ static int intLibSoundPause(int value) } int rc; - if (_soundType(sound, 0x01)) { + if (_soundType(sound, SOUND_TYPE_MEMORY)) { rc = soundStop(sound); } else { rc = soundPause(sound); @@ -2061,7 +2058,7 @@ static int intLibSoundResume(int value) } int rc; - if (_soundType(sound, 0x01)) { + if (_soundType(sound, SOUND_TYPE_MEMORY)) { rc = soundPlay(sound); } else { rc = soundResume(sound); diff --git a/src/lips.cc b/src/lips.cc index 38576f1..07c53dc 100644 --- a/src/lips.cc +++ b/src/lips.cc @@ -413,7 +413,7 @@ static int _lips_make_speech() gLipsData.sound = NULL; } - gLipsData.sound = soundAllocate(1, 8); + gLipsData.sound = soundAllocate(SOUND_TYPE_MEMORY, SOUND_16BIT); if (gLipsData.sound == NULL) { debugPrint("\nsoundAllocate falied in lips_make_speech!"); return -1; diff --git a/src/sound.cc b/src/sound.cc index 0c7d47e..3881a68 100644 --- a/src/sound.cc +++ b/src/sound.cc @@ -22,10 +22,12 @@ namespace fallout { -#define SOUND_FLAG_SOUND_IS_DONE (0x01) -#define SOUND_FLAG_SOUND_IS_PLAYING (0x02) -#define SOUND_FLAG_SOUND_IS_FADING (0x04) -#define SOUND_FLAG_SOUND_IS_PAUSED (0x08) +typedef enum SoundStatusFlags { + SOUND_STATUS_DONE = 0x01, + SOUND_STATUS_IS_PLAYING = 0x02, + SOUND_STATUS_IS_FADING = 0x04, + SOUND_STATUS_IS_PAUSED = 0x08, +} SoundStatusFlags; typedef char*(SoundFileNameMangler)(char*); @@ -35,7 +37,7 @@ typedef struct FadeSound { int targetVolume; int initialVolume; int currentVolume; - int field_14; + int pause; struct FadeSound* prev; struct FadeSound* next; } FadeSound; @@ -56,7 +58,7 @@ static Uint32 _doTimerEvent(Uint32 interval, void* param); static void _removeTimedEvent(SDL_TimerID* timerId); static void _removeFadeSound(FadeSound* fadeSound); static void _fadeSounds(); -static int _internalSoundFade(Sound* sound, int duration, int targetVolume, int a4); +static int _internalSoundFade(Sound* sound, int duration, int targetVolume, bool pause); // 0x51D478 static FadeSound* _fadeHead = NULL; @@ -205,7 +207,7 @@ const char* soundGetErrorDescription(int err) // 0x4AC7B0 void _refreshSoundBuffers(Sound* sound) { - if (sound->field_3C & 0x80) { + if ((sound->soundFlags & SOUND_FLAG_0x80) != 0) { return; } @@ -216,50 +218,50 @@ void _refreshSoundBuffers(Sound* sound) return; } - if (readPos < sound->field_74) { - sound->field_64 += readPos + sound->field_78 * sound->field_7C - sound->field_74; + if (readPos < sound->lastPosition) { + sound->numBytesRead += readPos + sound->numBuffers * sound->dataSize - sound->lastPosition; } else { - sound->field_64 += readPos - sound->field_74; + sound->numBytesRead += readPos - sound->lastPosition; } - if (sound->field_3C & 0x0100) { - if (sound->field_44 & 0x20) { - if (sound->field_3C & 0x0200) { - sound->field_3C |= 0x80; + if ((sound->soundFlags & SOUND_FLAG_0x100) != 0) { + if ((sound->type & SOUND_TYPE_0x20) != 0) { + if ((sound->soundFlags & SOUND_FLAG_0x200) != 0) { + sound->soundFlags |= SOUND_FLAG_0x80; } } else { - if (sound->field_60 <= sound->field_64) { - sound->field_3C |= 0x0280; + if (sound->fileSize <= sound->numBytesRead) { + sound->soundFlags |= SOUND_FLAG_0x200 | SOUND_FLAG_0x80; } } } - sound->field_74 = readPos; + sound->lastPosition = readPos; - if (sound->field_60 < sound->field_64) { + if (sound->fileSize < sound->numBytesRead) { int v3; do { - v3 = sound->field_64 - sound->field_60; - sound->field_64 = v3; - } while (v3 > sound->field_60); + v3 = sound->numBytesRead - sound->fileSize; + sound->numBytesRead = v3; + } while (v3 > sound->fileSize); } - int v6 = readPos / sound->field_7C; - if (sound->field_70 == v6) { + int v6 = readPos / sound->dataSize; + if (sound->lastUpdate == v6) { return; } int v53; - if (sound->field_70 > v6) { - v53 = v6 + sound->field_78 - sound->field_70; + if (sound->lastUpdate > v6) { + v53 = v6 + sound->numBuffers - sound->lastUpdate; } else { - v53 = v6 - sound->field_70; + v53 = v6 - sound->lastUpdate; } - if (sound->field_7C * v53 >= sound->readLimit) { - v53 = (sound->readLimit + sound->field_7C - 1) / sound->field_7C; + if (sound->dataSize * v53 >= sound->readLimit) { + v53 = (sound->readLimit + sound->dataSize - 1) / sound->dataSize; } - if (v53 < sound->field_5C) { + if (v53 < sound->minReadBuffer) { return; } @@ -267,17 +269,17 @@ void _refreshSoundBuffers(Sound* sound) void* audioPtr2; unsigned int audioBytes1; unsigned int audioBytes2; - hr = audioEngineSoundBufferLock(sound->soundBuffer, sound->field_7C * sound->field_70, sound->field_7C * v53, &audioPtr1, &audioBytes1, &audioPtr2, &audioBytes2, 0); + hr = audioEngineSoundBufferLock(sound->soundBuffer, sound->dataSize * sound->lastUpdate, sound->dataSize * v53, &audioPtr1, &audioBytes1, &audioPtr2, &audioBytes2, 0); if (!hr) { return; } - if (audioBytes1 + audioBytes2 != sound->field_7C * v53) { - debugPrint("locked memory region not big enough, wanted %d (%d * %d), got %d (%d + %d)\n", sound->field_7C * v53, v53, sound->field_7C, audioBytes1 + audioBytes2, audioBytes1, audioBytes2); - debugPrint("Resetting readBuffers from %d to %d\n", v53, (audioBytes1 + audioBytes2) / sound->field_7C); + if (audioBytes1 + audioBytes2 != sound->dataSize * v53) { + debugPrint("locked memory region not big enough, wanted %d (%d * %d), got %d (%d + %d)\n", sound->dataSize * v53, v53, sound->dataSize, audioBytes1 + audioBytes2, audioBytes1, audioBytes2); + debugPrint("Resetting readBuffers from %d to %d\n", v53, (audioBytes1 + audioBytes2) / sound->dataSize); - v53 = (audioBytes1 + audioBytes2) / sound->field_7C; - if (v53 < sound->field_5C) { + v53 = (audioBytes1 + audioBytes2) / sound->dataSize; + if (v53 < sound->minReadBuffer) { debugPrint("No longer above read buffer size, returning\n"); return; } @@ -286,11 +288,11 @@ void _refreshSoundBuffers(Sound* sound) int audioBytes = audioBytes1; while (--v53 != -1) { int bytesRead; - if (sound->field_3C & 0x0200) { - bytesRead = sound->field_7C; - memset(sound->field_20, 0, bytesRead); + if ((sound->soundFlags & SOUND_FLAG_0x200) != 0) { + bytesRead = sound->dataSize; + memset(sound->data, 0, bytesRead); } else { - int bytesToRead = sound->field_7C; + int bytesToRead = sound->dataSize; if (sound->field_58 != -1) { int pos = sound->io.tell(sound->io.fd); if (bytesToRead + pos > sound->field_58) { @@ -298,30 +300,30 @@ void _refreshSoundBuffers(Sound* sound) } } - bytesRead = sound->io.read(sound->io.fd, sound->field_20, bytesToRead); - if (bytesRead < sound->field_7C) { - if (!(sound->field_3C & 0x20) || (sound->field_3C & 0x0100)) { - memset(sound->field_20 + bytesRead, 0, sound->field_7C - bytesRead); - sound->field_3C |= 0x0200; - bytesRead = sound->field_7C; + bytesRead = sound->io.read(sound->io.fd, sound->data, bytesToRead); + if (bytesRead < sound->dataSize) { + if ((sound->soundFlags & SOUND_LOOPING) == 0 || (sound->soundFlags & SOUND_FLAG_0x100) != 0) { + memset(sound->data + bytesRead, 0, sound->dataSize - bytesRead); + sound->soundFlags |= SOUND_FLAG_0x200; + bytesRead = sound->dataSize; } else { - while (bytesRead < sound->field_7C) { - if (sound->field_50 == -1) { + while (bytesRead < sound->dataSize) { + if (sound->loops == -1) { sound->io.seek(sound->io.fd, sound->field_54, SEEK_SET); if (sound->callback != NULL) { sound->callback(sound->callbackUserData, 0x0400); } } else { - if (sound->field_50 <= 0) { + if (sound->loops <= 0) { sound->field_58 = -1; sound->field_54 = 0; - sound->field_50 = 0; - sound->field_3C &= ~0x20; - bytesRead += sound->io.read(sound->io.fd, sound->field_20 + bytesRead, sound->field_7C - bytesRead); + sound->loops = 0; + sound->soundFlags &= ~SOUND_LOOPING; + bytesRead += sound->io.read(sound->io.fd, sound->data + bytesRead, sound->dataSize - bytesRead); break; } - sound->field_50--; + sound->loops--; sound->io.seek(sound->io.fd, sound->field_54, SEEK_SET); if (sound->callback != NULL) { @@ -330,17 +332,17 @@ void _refreshSoundBuffers(Sound* sound) } if (sound->field_58 == -1) { - bytesToRead = sound->field_7C - bytesRead; + bytesToRead = sound->dataSize - bytesRead; } else { int pos = sound->io.tell(sound->io.fd); - if (sound->field_7C + bytesRead + pos <= sound->field_58) { - bytesToRead = sound->field_7C - bytesRead; + if (sound->dataSize + bytesRead + pos <= sound->field_58) { + bytesToRead = sound->dataSize - bytesRead; } else { bytesToRead = sound->field_58 - bytesRead - pos; } } - int v20 = sound->io.read(sound->io.fd, sound->field_20 + bytesRead, bytesToRead); + int v20 = sound->io.read(sound->io.fd, sound->data + bytesRead, bytesToRead); bytesRead += v20; if (v20 < bytesToRead) { break; @@ -352,18 +354,18 @@ void _refreshSoundBuffers(Sound* sound) if (bytesRead > audioBytes) { if (audioBytes != 0) { - memcpy(audioPtr, sound->field_20, audioBytes); + memcpy(audioPtr, sound->data, audioBytes); } if (audioPtr2 != NULL) { - memcpy(audioPtr2, sound->field_20 + audioBytes, bytesRead - audioBytes); + memcpy(audioPtr2, sound->data + audioBytes, bytesRead - audioBytes); audioPtr = (unsigned char*)audioPtr2 + bytesRead - audioBytes; audioBytes = audioBytes2 - bytesRead; } else { debugPrint("Hm, no second write pointer, but buffer not big enough, this shouldn't happen\n"); } } else { - memcpy(audioPtr, sound->field_20, bytesRead); + memcpy(audioPtr, sound->data, bytesRead); audioPtr += bytesRead; audioBytes -= bytesRead; } @@ -371,11 +373,11 @@ void _refreshSoundBuffers(Sound* sound) audioEngineSoundBufferUnlock(sound->soundBuffer, audioPtr1, audioBytes1, audioPtr2, audioBytes2); - sound->field_70 = v6; + sound->lastUpdate = v6; } // 0x4ACC58 -int soundInit(int a1, int a2, int a3, int a4, int rate) +int soundInit(int a1, int numBuffers, int a3, int dataSize, int rate) { if (!audioEngineInit()) { debugPrint("soundInit: Unable to init audio engine\n"); @@ -385,8 +387,8 @@ int soundInit(int a1, int a2, int a3, int a4, int rate) } _sampleRate = rate; - _dataSize = a4; - _numBuffers = a2; + _dataSize = dataSize; + _numBuffers = numBuffers; gSoundInitialized = true; _deviceInit = 1; @@ -422,7 +424,7 @@ void soundExit() } // 0x4AD0FC -Sound* soundAllocate(int a1, int a2) +Sound* soundAllocate(int type, int soundFlags) { if (!gSoundInitialized) { gSoundLastError = SOUND_NOT_INITIALIZED; @@ -434,30 +436,30 @@ Sound* soundAllocate(int a1, int a2) memcpy(&(sound->io), &gSoundDefaultFileIO, sizeof(gSoundDefaultFileIO)); - if (!(a2 & 0x02)) { - a2 |= 0x02; + if ((soundFlags & SOUND_FLAG_0x02) == 0) { + soundFlags |= SOUND_FLAG_0x02; } - sound->bitsPerSample = (a2 & 0x08) != 0 ? 16 : 8; + sound->bitsPerSample = (soundFlags & SOUND_16BIT) != 0 ? 16 : 8; sound->channels = 1; sound->rate = _sampleRate; - sound->field_3C = a2; - sound->field_44 = a1; - sound->field_7C = _dataSize; - sound->field_64 = 0; + sound->soundFlags = soundFlags; + sound->type = type; + sound->dataSize = _dataSize; + sound->numBytesRead = 0; sound->soundBuffer = -1; - sound->field_40 = 0; - sound->field_78 = _numBuffers; - sound->readLimit = sound->field_7C * _numBuffers; + sound->statusFlags = 0; + sound->numBuffers = _numBuffers; + sound->readLimit = sound->dataSize * _numBuffers; - if (a1 & 0x10) { - sound->field_50 = -1; - sound->field_3C |= 0x20; + if ((type & SOUND_TYPE_INFINITE) != 0) { + sound->loops = -1; + sound->soundFlags |= SOUND_LOOPING; } sound->field_58 = -1; - sound->field_5C = 1; + sound->minReadBuffer = 1; sound->volume = VOLUME_MAX; sound->prev = NULL; sound->field_54 = 0; @@ -483,29 +485,29 @@ int _preloadBuffers(Sound* sound) int size; size = sound->io.filelength(sound->io.fd); - sound->field_60 = size; + sound->fileSize = size; - if (sound->field_44 & 0x02) { - if (!(sound->field_3C & 0x20)) { - sound->field_3C |= 0x0120; + if ((sound->type & SOUND_TYPE_STREAMING) != 0) { + if ((sound->soundFlags & SOUND_LOOPING) == 0) { + sound->soundFlags |= SOUND_FLAG_0x100 | SOUND_LOOPING; } - if (sound->field_78 * sound->field_7C >= size) { - if (size / sound->field_7C * sound->field_7C != size) { - size = (size / sound->field_7C + 1) * sound->field_7C; + if (sound->numBuffers * sound->dataSize >= size) { + if (size / sound->dataSize * sound->dataSize != size) { + size = (size / sound->dataSize + 1) * sound->dataSize; } } else { - size = sound->field_78 * sound->field_7C; + size = sound->numBuffers * sound->dataSize; } } else { - sound->field_44 &= ~(0x03); - sound->field_44 |= 0x01; + sound->type &= ~(SOUND_TYPE_MEMORY | SOUND_TYPE_STREAMING); + sound->type |= SOUND_TYPE_MEMORY; } buf = (unsigned char*)gSoundMallocProc(size); bytes_read = sound->io.read(sound->io.fd, buf, size); if (bytes_read != size) { - if (!(sound->field_3C & 0x20) || (sound->field_3C & (0x01 << 8))) { + if ((sound->soundFlags & SOUND_LOOPING) == 0 || (sound->soundFlags & SOUND_FLAG_0x100) != 0) { memset(buf + bytes_read, 0, size - bytes_read); } else { v14 = buf + bytes_read; @@ -525,12 +527,12 @@ int _preloadBuffers(Sound* sound) result = _soundSetData(sound, buf, size); gSoundFreeProc(buf); - if (sound->field_44 & 0x01) { + if ((sound->type & SOUND_TYPE_MEMORY) != 0) { sound->io.close(sound->io.fd); sound->io.fd = -1; } else { - if (sound->field_20 == NULL) { - sound->field_20 = (unsigned char*)gSoundMallocProc(sound->field_7C); + if (sound->data == NULL) { + sound->data = (unsigned char*)gSoundMallocProc(sound->dataSize); } } @@ -574,12 +576,12 @@ int _soundRewind(Sound* sound) return gSoundLastError; } - if (sound->field_44 & 0x02) { + if ((sound->type & SOUND_TYPE_STREAMING) != 0) { sound->io.seek(sound->io.fd, 0, SEEK_SET); - sound->field_70 = 0; - sound->field_74 = 0; - sound->field_64 = 0; - sound->field_3C &= 0xFD7F; + sound->lastUpdate = 0; + sound->lastPosition = 0; + sound->numBytesRead = 0; + sound->soundFlags &= ~(SOUND_FLAG_0x200 | SOUND_FLAG_0x80); hr = audioEngineSoundBufferSetCurrentPosition(sound->soundBuffer, 0); _preloadBuffers(sound); } else { @@ -591,7 +593,7 @@ int _soundRewind(Sound* sound) return gSoundLastError; } - sound->field_40 &= ~SOUND_FLAG_SOUND_IS_DONE; + sound->statusFlags &= ~SOUND_STATUS_DONE; gSoundLastError = SOUND_NO_ERROR; return gSoundLastError; @@ -669,24 +671,23 @@ int soundPlay(Sound* sound) return gSoundLastError; } - // TODO: Check. - if (sound->field_40 & SOUND_FLAG_SOUND_IS_DONE) { + if ((sound->statusFlags & SOUND_STATUS_DONE) != 0) { _soundRewind(sound); } soundSetVolume(sound, sound->volume); - hr = audioEngineSoundBufferPlay(sound->soundBuffer, sound->field_3C & 0x20 ? AUDIO_ENGINE_SOUND_BUFFER_PLAY_LOOPING : 0); + hr = audioEngineSoundBufferPlay(sound->soundBuffer, sound->soundFlags & SOUND_LOOPING ? AUDIO_ENGINE_SOUND_BUFFER_PLAY_LOOPING : 0); audioEngineSoundBufferGetCurrentPosition(sound->soundBuffer, &readPos, &writePos); - sound->field_70 = readPos / sound->field_7C; + sound->lastUpdate = readPos / sound->dataSize; if (!hr) { gSoundLastError = SOUND_UNKNOWN_ERROR; return gSoundLastError; } - sound->field_40 |= SOUND_FLAG_SOUND_IS_PLAYING; + sound->statusFlags |= SOUND_STATUS_IS_PLAYING; ++_numSounds; @@ -709,7 +710,7 @@ int soundStop(Sound* sound) return gSoundLastError; } - if (!(sound->field_40 & SOUND_FLAG_SOUND_IS_PLAYING)) { + if ((sound->statusFlags & SOUND_STATUS_IS_PLAYING) == 0) { gSoundLastError = SOUND_NOT_PLAYING; return gSoundLastError; } @@ -720,7 +721,7 @@ int soundStop(Sound* sound) return gSoundLastError; } - sound->field_40 &= ~SOUND_FLAG_SOUND_IS_PLAYING; + sound->statusFlags &= ~SOUND_STATUS_IS_PLAYING; _numSounds--; gSoundLastError = SOUND_NO_ERROR; @@ -772,12 +773,17 @@ int soundContinue(Sound* sound) return gSoundLastError; } - if (!(sound->field_40 & SOUND_FLAG_SOUND_IS_PLAYING) || (sound->field_40 & SOUND_FLAG_SOUND_IS_PAUSED)) { + if ((sound->statusFlags & SOUND_STATUS_IS_PLAYING) == 0) { gSoundLastError = SOUND_NOT_PLAYING; return gSoundLastError; } - if (sound->field_40 & SOUND_FLAG_SOUND_IS_DONE) { + if ((sound->statusFlags & SOUND_STATUS_IS_PAUSED) != 0) { + gSoundLastError = SOUND_NOT_PLAYING; + return gSoundLastError; + } + + if ((sound->statusFlags & SOUND_STATUS_DONE) != 0) { gSoundLastError = SOUND_UNKNOWN_ERROR; return gSoundLastError; } @@ -790,29 +796,29 @@ int soundContinue(Sound* sound) return gSoundLastError; } - if (!(sound->field_3C & 0x80) && (status & (AUDIO_ENGINE_SOUND_BUFFER_STATUS_PLAYING | AUDIO_ENGINE_SOUND_BUFFER_STATUS_LOOPING))) { - if (!(sound->field_40 & SOUND_FLAG_SOUND_IS_PAUSED) && (sound->field_44 & 0x02)) { + if ((sound->soundFlags & SOUND_FLAG_0x80) == 0 && (status & (AUDIO_ENGINE_SOUND_BUFFER_STATUS_PLAYING | AUDIO_ENGINE_SOUND_BUFFER_STATUS_LOOPING)) != 0) { + if ((sound->statusFlags & SOUND_STATUS_IS_PAUSED) == 0 && (sound->type & SOUND_TYPE_STREAMING) != 0) { _refreshSoundBuffers(sound); } - } else if (!(sound->field_40 & SOUND_FLAG_SOUND_IS_PAUSED)) { + } else if ((sound->statusFlags & SOUND_STATUS_IS_PAUSED) == 0) { if (sound->callback != NULL) { sound->callback(sound->callbackUserData, 1); sound->callback = NULL; } - if (sound->field_44 & 0x04) { + if ((sound->type & SOUND_TYPE_FIRE_AND_FORGET) != 0) { sound->callback = NULL; soundDelete(sound); } else { - sound->field_40 |= SOUND_FLAG_SOUND_IS_DONE; + sound->statusFlags |= SOUND_STATUS_DONE; - if (sound->field_40 & SOUND_FLAG_SOUND_IS_PLAYING) { + if ((sound->statusFlags & SOUND_STATUS_IS_PLAYING) != 0) { --_numSounds; } soundStop(sound); - sound->field_40 &= ~(SOUND_FLAG_SOUND_IS_DONE | SOUND_FLAG_SOUND_IS_PLAYING); + sound->statusFlags &= ~(SOUND_STATUS_DONE | SOUND_STATUS_IS_PLAYING); } } @@ -833,7 +839,7 @@ bool soundIsPlaying(Sound* sound) return false; } - return (sound->field_40 & SOUND_FLAG_SOUND_IS_PLAYING) != 0; + return (sound->statusFlags & SOUND_STATUS_IS_PLAYING) != 0; } // 0x4ADAC4 @@ -849,7 +855,7 @@ bool _soundDone(Sound* sound) return false; } - return sound->field_40 & 1; + return (sound->statusFlags & SOUND_STATUS_DONE) != 0; } // 0x4ADB44 @@ -865,11 +871,11 @@ bool soundIsPaused(Sound* sound) return false; } - return (sound->field_40 & SOUND_FLAG_SOUND_IS_PAUSED) != 0; + return (sound->statusFlags & SOUND_STATUS_IS_PAUSED) != 0; } // 0x4ADBC4 -int _soundType(Sound* sound, int a2) +int _soundType(Sound* sound, int type) { if (!gSoundInitialized) { gSoundLastError = SOUND_NOT_INITIALIZED; @@ -881,7 +887,7 @@ int _soundType(Sound* sound, int a2) return 0; } - return sound->field_44 & a2; + return sound->type & type; } // 0x4ADC04 @@ -898,7 +904,7 @@ int soundGetDuration(Sound* sound) } int bytesPerSec = sound->bitsPerSample / 8 * sound->rate; - int v3 = sound->field_60; + int v3 = sound->fileSize; int v4 = v3 % bytesPerSec; int result = v3 / bytesPerSec; if (v4 != 0) { @@ -909,7 +915,7 @@ int soundGetDuration(Sound* sound) } // 0x4ADD00 -int soundSetLooping(Sound* sound, int a2) +int soundSetLooping(Sound* sound, int loops) { if (!gSoundInitialized) { gSoundLastError = SOUND_NOT_INITIALIZED; @@ -921,14 +927,14 @@ int soundSetLooping(Sound* sound, int a2) return gSoundLastError; } - if (a2) { - sound->field_3C |= 0x20; - sound->field_50 = a2; + if (loops != 0) { + sound->soundFlags |= SOUND_LOOPING; + sound->loops = loops; } else { - sound->field_50 = 0; + sound->loops = 0; sound->field_58 = -1; sound->field_54 = 0; - sound->field_3C &= ~(0x20); + sound->soundFlags &= ~SOUND_LOOPING; } gSoundLastError = SOUND_NO_ERROR; @@ -1085,12 +1091,12 @@ int soundPause(Sound* sound) return gSoundLastError; } - if (!(sound->field_40 & SOUND_FLAG_SOUND_IS_PLAYING)) { + if ((sound->statusFlags & SOUND_STATUS_IS_PLAYING) == 0) { gSoundLastError = SOUND_NOT_PLAYING; return gSoundLastError; } - if (sound->field_40 & SOUND_FLAG_SOUND_IS_PAUSED) { + if ((sound->statusFlags & SOUND_STATUS_IS_PAUSED) != 0) { gSoundLastError = SOUND_ALREADY_PAUSED; return gSoundLastError; } @@ -1101,8 +1107,8 @@ int soundPause(Sound* sound) return gSoundLastError; } - sound->field_48 = readPos; - sound->field_40 |= SOUND_FLAG_SOUND_IS_PAUSED; + sound->pausePos = readPos; + sound->statusFlags |= SOUND_STATUS_IS_PAUSED; return soundStop(sound); } @@ -1124,24 +1130,24 @@ int soundResume(Sound* sound) return gSoundLastError; } - if ((sound->field_40 & SOUND_FLAG_SOUND_IS_PLAYING) != 0) { + if ((sound->statusFlags & SOUND_STATUS_IS_PLAYING) != 0) { gSoundLastError = SOUND_NOT_PAUSED; return gSoundLastError; } - if (!(sound->field_40 & SOUND_FLAG_SOUND_IS_PAUSED)) { + if ((sound->statusFlags & SOUND_STATUS_IS_PAUSED) == 0) { gSoundLastError = SOUND_NOT_PAUSED; return gSoundLastError; } - hr = audioEngineSoundBufferSetCurrentPosition(sound->soundBuffer, sound->field_48); + hr = audioEngineSoundBufferSetCurrentPosition(sound->soundBuffer, sound->pausePos); if (!hr) { gSoundLastError = SOUND_UNKNOWN_ERROR; return gSoundLastError; } - sound->field_40 &= ~SOUND_FLAG_SOUND_IS_PAUSED; - sound->field_48 = 0; + sound->statusFlags &= ~SOUND_STATUS_IS_PAUSED; + sound->pausePos = 0; return soundPlay(sound); } @@ -1194,22 +1200,21 @@ int soundSetFileIO(Sound* sound, SoundOpenProc* openProc, SoundCloseProc* closeP // 0x4AE378 void soundDeleteInternal(Sound* sound) { - FadeSound* curr; - Sound* v10; - Sound* v11; + Sound* next; + Sound* prev; - if (sound->field_40 & SOUND_FLAG_SOUND_IS_FADING) { - curr = _fadeHead; + if ((sound->statusFlags & SOUND_STATUS_IS_FADING) != 0) { + FadeSound* fadeSound = _fadeHead; - while (curr != NULL) { - if (sound == curr->sound) { + while (fadeSound != NULL) { + if (sound == fadeSound->sound) { break; } - curr = curr->next; + fadeSound = fadeSound->next; } - _removeFadeSound(curr); + _removeFadeSound(fadeSound); } if (sound->soundBuffer != -1) { @@ -1226,23 +1231,23 @@ void soundDeleteInternal(Sound* sound) sound->soundBuffer = -1; } - if (sound->field_90 != NULL) { - sound->field_90(sound->field_8C); + if (sound->deleteCallback != NULL) { + sound->deleteCallback(sound->deleteUserData); } - if (sound->field_20 != NULL) { - gSoundFreeProc(sound->field_20); - sound->field_20 = NULL; + if (sound->data != NULL) { + gSoundFreeProc(sound->data); + sound->data = NULL; } - v10 = sound->next; - if (v10 != NULL) { - v10->prev = sound->prev; + next = sound->next; + if (next != NULL) { + next->prev = sound->prev; } - v11 = sound->prev; - if (v11 != NULL) { - v11->next = sound->next; + prev = sound->prev; + if (prev != NULL) { + prev->next = sound->next; } else { gSoundListHead = sound->next; } @@ -1305,23 +1310,23 @@ int _soundGetPosition(Sound* sound) return gSoundLastError; } - unsigned int playPos; + unsigned int readPos; unsigned int writePos; - audioEngineSoundBufferGetCurrentPosition(sound->soundBuffer, &playPos, &writePos); + audioEngineSoundBufferGetCurrentPosition(sound->soundBuffer, &readPos, &writePos); - if ((sound->field_44 & 0x02) != 0) { - if (playPos < sound->field_74) { - playPos += sound->field_64 + sound->field_78 * sound->field_7C - sound->field_74; + if ((sound->type & SOUND_TYPE_STREAMING) != 0) { + if (readPos < sound->lastPosition) { + readPos += sound->numBytesRead + sound->numBuffers * sound->dataSize - sound->lastPosition; } else { - playPos -= sound->field_74 + sound->field_64; + readPos -= sound->lastPosition + sound->numBytesRead; } } - return playPos; + return readPos; } // 0x4AE6CC -int _soundSetPosition(Sound* sound, int a2) +int _soundSetPosition(Sound* sound, int pos) { if (!gSoundInitialized) { gSoundLastError = SOUND_NOT_INITIALIZED; @@ -1338,34 +1343,34 @@ int _soundSetPosition(Sound* sound, int a2) return gSoundLastError; } - if (sound->field_44 & 0x02) { - int v6 = a2 / sound->field_7C % sound->field_78; + if ((sound->type & SOUND_TYPE_STREAMING) != 0) { + int section = pos / sound->dataSize % sound->numBuffers; - audioEngineSoundBufferSetCurrentPosition(sound->soundBuffer, v6 * sound->field_7C + a2 % sound->field_7C); + audioEngineSoundBufferSetCurrentPosition(sound->soundBuffer, section * sound->dataSize + pos % sound->dataSize); - sound->io.seek(sound->io.fd, v6 * sound->field_7C, SEEK_SET); - int bytes_read = sound->io.read(sound->io.fd, sound->field_20, sound->field_7C); - if (bytes_read < sound->field_7C) { - if (sound->field_44 & 0x02) { + sound->io.seek(sound->io.fd, section * sound->dataSize, SEEK_SET); + int bytesRead = sound->io.read(sound->io.fd, sound->data, sound->dataSize); + if (bytesRead < sound->dataSize) { + if ((sound->type & SOUND_TYPE_STREAMING) != 0) { sound->io.seek(sound->io.fd, 0, SEEK_SET); - sound->io.read(sound->io.fd, sound->field_20 + bytes_read, sound->field_7C - bytes_read); + sound->io.read(sound->io.fd, sound->data + bytesRead, sound->dataSize - bytesRead); } else { - memset(sound->field_20 + bytes_read, 0, sound->field_7C - bytes_read); + memset(sound->data + bytesRead, 0, sound->dataSize - bytesRead); } } - int v17 = v6 + 1; - sound->field_64 = a2; + int nextSection = section + 1; + sound->numBytesRead = pos; - if (v17 < sound->field_78) { - sound->field_70 = v17; + if (nextSection < sound->numBuffers) { + sound->lastUpdate = nextSection; } else { - sound->field_70 = 0; + sound->lastUpdate = 0; } soundContinue(sound); } else { - audioEngineSoundBufferSetCurrentPosition(sound->soundBuffer, a2); + audioEngineSoundBufferSetCurrentPosition(sound->soundBuffer, pos); } gSoundLastError = SOUND_NO_ERROR; @@ -1387,7 +1392,7 @@ void _removeFadeSound(FadeSound* fadeSound) return; } - if (!(fadeSound->sound->field_40 & SOUND_FLAG_SOUND_IS_FADING)) { + if ((fadeSound->sound->statusFlags & SOUND_STATUS_IS_FADING) == 0) { return; } @@ -1403,7 +1408,7 @@ void _removeFadeSound(FadeSound* fadeSound) next->prev = fadeSound->prev; } - fadeSound->sound->field_40 &= ~SOUND_FLAG_SOUND_IS_FADING; + fadeSound->sound->statusFlags &= ~SOUND_STATUS_IS_FADING; fadeSound->sound = NULL; tmp = _fadeFreeList; @@ -1414,34 +1419,34 @@ void _removeFadeSound(FadeSound* fadeSound) // 0x4AE8B0 void _fadeSounds() { - FadeSound* ptr; + FadeSound* fadeSound; - ptr = _fadeHead; - while (ptr != NULL) { - if ((ptr->currentVolume > ptr->targetVolume || ptr->currentVolume + ptr->deltaVolume < ptr->targetVolume) && (ptr->currentVolume < ptr->targetVolume || ptr->currentVolume + ptr->deltaVolume > ptr->targetVolume)) { - ptr->currentVolume += ptr->deltaVolume; - soundSetVolume(ptr->sound, ptr->currentVolume); + fadeSound = _fadeHead; + while (fadeSound != NULL) { + if ((fadeSound->currentVolume > fadeSound->targetVolume || fadeSound->currentVolume + fadeSound->deltaVolume < fadeSound->targetVolume) && (fadeSound->currentVolume < fadeSound->targetVolume || fadeSound->currentVolume + fadeSound->deltaVolume > fadeSound->targetVolume)) { + fadeSound->currentVolume += fadeSound->deltaVolume; + soundSetVolume(fadeSound->sound, fadeSound->currentVolume); } else { - if (ptr->targetVolume == 0) { - if (ptr->field_14) { - soundPause(ptr->sound); - soundSetVolume(ptr->sound, ptr->initialVolume); + if (fadeSound->targetVolume == 0) { + if (fadeSound->pause) { + soundPause(fadeSound->sound); + soundSetVolume(fadeSound->sound, fadeSound->initialVolume); } else { - if (ptr->sound->field_44 & 0x04) { - soundDelete(ptr->sound); + if ((fadeSound->sound->type & SOUND_TYPE_FIRE_AND_FORGET) != 0) { + soundDelete(fadeSound->sound); } else { - soundStop(ptr->sound); + soundStop(fadeSound->sound); - ptr->initialVolume = ptr->targetVolume; - ptr->currentVolume = ptr->targetVolume; - ptr->deltaVolume = 0; + fadeSound->initialVolume = fadeSound->targetVolume; + fadeSound->currentVolume = fadeSound->targetVolume; + fadeSound->deltaVolume = 0; - soundSetVolume(ptr->sound, ptr->targetVolume); + soundSetVolume(fadeSound->sound, fadeSound->targetVolume); } } } - _removeFadeSound(ptr); + _removeFadeSound(fadeSound); } } @@ -1452,9 +1457,9 @@ void _fadeSounds() } // 0x4AE988 -int _internalSoundFade(Sound* sound, int duration, int targetVolume, int a4) +int _internalSoundFade(Sound* sound, int duration, int targetVolume, bool pause) { - FadeSound* ptr; + FadeSound* fadeSound; if (!_deviceInit) { gSoundLastError = SOUND_NOT_INITIALIZED; @@ -1466,56 +1471,56 @@ int _internalSoundFade(Sound* sound, int duration, int targetVolume, int a4) return gSoundLastError; } - ptr = NULL; - if (sound->field_40 & SOUND_FLAG_SOUND_IS_FADING) { - ptr = _fadeHead; - while (ptr != NULL) { - if (ptr->sound == sound) { + fadeSound = NULL; + if ((sound->statusFlags & SOUND_STATUS_IS_FADING) != 0) { + fadeSound = _fadeHead; + while (fadeSound != NULL) { + if (fadeSound->sound == sound) { break; } - ptr = ptr->next; + fadeSound = fadeSound->next; } } - if (ptr == NULL) { + if (fadeSound == NULL) { if (_fadeFreeList != NULL) { - ptr = _fadeFreeList; + fadeSound = _fadeFreeList; _fadeFreeList = _fadeFreeList->next; } else { - ptr = (FadeSound*)gSoundMallocProc(sizeof(FadeSound)); + fadeSound = (FadeSound*)gSoundMallocProc(sizeof(FadeSound)); } - if (ptr != NULL) { + if (fadeSound != NULL) { if (_fadeHead != NULL) { - _fadeHead->prev = ptr; + _fadeHead->prev = fadeSound; } - ptr->sound = sound; - ptr->prev = NULL; - ptr->next = _fadeHead; - _fadeHead = ptr; + fadeSound->sound = sound; + fadeSound->prev = NULL; + fadeSound->next = _fadeHead; + _fadeHead = fadeSound; } } - if (ptr == NULL) { + if (fadeSound == NULL) { gSoundLastError = SOUND_NO_MEMORY_AVAILABLE; return gSoundLastError; } - ptr->targetVolume = targetVolume; - ptr->initialVolume = _soundGetVolume(sound); - ptr->currentVolume = ptr->initialVolume; - ptr->field_14 = a4; + fadeSound->targetVolume = targetVolume; + fadeSound->initialVolume = _soundGetVolume(sound); + fadeSound->currentVolume = fadeSound->initialVolume; + fadeSound->pause = pause; // TODO: Check. - ptr->deltaVolume = 8 * (125 * (targetVolume - ptr->initialVolume)) / (40 * duration); + fadeSound->deltaVolume = 8 * (125 * (targetVolume - fadeSound->initialVolume)) / (40 * duration); - sound->field_40 |= SOUND_FLAG_SOUND_IS_FADING; + sound->statusFlags |= SOUND_STATUS_IS_FADING; bool shouldPlay; if (gSoundInitialized) { if (sound->soundBuffer != -1) { - shouldPlay = (sound->field_40 & SOUND_FLAG_SOUND_IS_PLAYING) == 0; + shouldPlay = (sound->statusFlags & SOUND_STATUS_IS_PLAYING) == 0; } else { gSoundLastError = SOUND_NO_SOUND; shouldPlay = true; @@ -1547,7 +1552,7 @@ int _internalSoundFade(Sound* sound, int duration, int targetVolume, int a4) // 0x4AEB0C int _soundFade(Sound* sound, int duration, int targetVolume) { - return _internalSoundFade(sound, duration, targetVolume, 0); + return _internalSoundFade(sound, duration, targetVolume, false); } // 0x4AEB54 diff --git a/src/sound.h b/src/sound.h index 34a5712..57d371c 100644 --- a/src/sound.h +++ b/src/sound.h @@ -65,50 +65,66 @@ typedef struct SoundFileIO { int fd; } SoundFileIO; +typedef enum SoundType { + SOUND_TYPE_MEMORY = 0x01, + SOUND_TYPE_STREAMING = 0x02, + SOUND_TYPE_FIRE_AND_FORGET = 0x04, + SOUND_TYPE_INFINITE = 0x10, + SOUND_TYPE_0x20 = 0x20, +} SoundType; + +typedef enum SoundFlags { + SOUND_FLAG_0x02 = 0x02, + SOUND_FLAG_0x04 = 0x04, + SOUND_16BIT = 0x08, + SOUND_8BIT = 0x10, + SOUND_LOOPING = 0x20, + SOUND_FLAG_0x80 = 0x80, + SOUND_FLAG_0x100 = 0x100, + SOUND_FLAG_0x200 = 0x200, +} SoundFlags; + typedef void SoundCallback(void* userData, int a2); +typedef void SoundDeleteCallback(void* userData); typedef struct Sound { SoundFileIO io; - unsigned char* field_20; + unsigned char* data; int soundBuffer; int bitsPerSample; int channels; int rate; - int field_3C; - // flags - int field_40; - int field_44; - // pause pos - int field_48; + int soundFlags; + int statusFlags; + int type; + int pausePos; int volume; - int field_50; + int loops; int field_54; int field_58; - int field_5C; - // file size - int field_60; - int field_64; + int minReadBuffer; + int fileSize; + int numBytesRead; int field_68; int readLimit; - int field_70; - unsigned int field_74; - int field_78; - int field_7C; - int field_80; - // callback data + int lastUpdate; + unsigned int lastPosition; + int numBuffers; + int dataSize; + void* userData; void* callbackUserData; SoundCallback* callback; - int field_8C; - void (*field_90)(int); + void* deleteUserData; + SoundDeleteCallback* deleteCallback; struct Sound* next; struct Sound* prev; } Sound; void soundSetMemoryProcs(MallocProc* mallocProc, ReallocProc* reallocProc, FreeProc* freeProc); const char* soundGetErrorDescription(int err); -int soundInit(int a1, int a2, int a3, int a4, int rate); +int soundInit(int a1, int numBuffers, int a3, int dataSize, int rate); void soundExit(); -Sound* soundAllocate(int a1, int a2); +Sound* soundAllocate(int type, int soundFlags); int soundLoad(Sound* sound, char* filePath); int soundPlay(Sound* sound); int soundStop(Sound* sound); @@ -116,9 +132,9 @@ int soundDelete(Sound* sound); bool soundIsPlaying(Sound* sound); bool _soundDone(Sound* sound); bool soundIsPaused(Sound* sound); -int _soundType(Sound* sound, int a2); +int _soundType(Sound* sound, int type); int soundGetDuration(Sound* sound); -int soundSetLooping(Sound* sound, int a2); +int soundSetLooping(Sound* sound, int loops); int _soundVolumeHMItoDirectSound(int a1); int soundSetVolume(Sound* sound, int volume); int soundSetCallback(Sound* sound, SoundCallback* callback, void* userData); @@ -129,7 +145,7 @@ int soundResume(Sound* sound); int soundSetFileIO(Sound* sound, SoundOpenProc* openProc, SoundCloseProc* closeProc, SoundReadProc* readProc, SoundWriteProc* writeProc, SoundSeekProc* seekProc, SoundTellProc* tellProc, SoundFileLengthProc* fileLengthProc); int _soundSetMasterVolume(int value); int _soundGetPosition(Sound* sound); -int _soundSetPosition(Sound* sound, int a2); +int _soundSetPosition(Sound* sound, int pos); int _soundFade(Sound* sound, int duration, int targetVolume); void soundDeleteAll(); void soundContinueAll();