Improve Sound readability

This commit is contained in:
Alexander Batalov 2022-12-25 21:56:23 +03:00
parent e11f1af9ae
commit b8dea116ee
5 changed files with 292 additions and 274 deletions

View File

@ -1681,21 +1681,21 @@ void soundEffectCallback(void* userData, int a2)
// 0x451ADC // 0x451ADC
int _gsound_background_allocate(Sound** soundPtr, int a2, int a3) int _gsound_background_allocate(Sound** soundPtr, int a2, int a3)
{ {
int v5 = 10; int soundFlags = SOUND_FLAG_0x02 | SOUND_16BIT;
int v6 = 0; int type = 0;
if (a2 == 13) { if (a2 == 13) {
v6 |= 0x01; type |= SOUND_TYPE_MEMORY;
} else if (a2 == 14) { } else if (a2 == 14) {
v6 |= 0x02; type |= SOUND_TYPE_STREAMING;
} }
if (a3 == 15) { if (a3 == 15) {
v6 |= 0x04; type |= SOUND_TYPE_FIRE_AND_FORGET;
} else if (a3 == 16) { } else if (a3 == 16) {
v5 = 42; soundFlags |= SOUND_LOOPING;
} }
Sound* sound = soundAllocate(v6, v5); Sound* sound = soundAllocate(type, soundFlags);
if (sound == NULL) { if (sound == NULL) {
return -1; return -1;
} }
@ -2006,7 +2006,7 @@ Sound* _gsound_get_sound_ready_for_effect()
{ {
int rc; 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 (sound == NULL) {
if (gGameSoundDebugEnabled) { if (gGameSoundDebugEnabled) {
debugPrint(" Can't allocate sound for effect. "); debugPrint(" Can't allocate sound for effect. ");

View File

@ -1872,32 +1872,29 @@ static int intLibSoundDelete(int value)
// 0x466110 // 0x466110
static int intLibSoundPlay(char* fileName, int mode) static int intLibSoundPlay(char* fileName, int mode)
{ {
int v3 = 1; int type = SOUND_TYPE_MEMORY;
int v5 = 0; int soundFlags = 0;
if (mode & 0x01) { if (mode & 0x01) {
// looping soundFlags |= SOUND_LOOPING;
v5 |= 0x20;
} else { } else {
v3 = 5; type |= SOUND_TYPE_FIRE_AND_FORGET;
} }
if (mode & 0x02) { if (mode & 0x02) {
v5 |= 0x08; soundFlags |= SOUND_16BIT;
} else { } else {
v5 |= 0x10; soundFlags |= SOUND_8BIT;
} }
if (mode & 0x0100) { if (mode & 0x0100) {
// memory type &= ~(SOUND_TYPE_MEMORY | SOUND_TYPE_STREAMING);
v3 &= ~0x03; type |= SOUND_TYPE_MEMORY;
v3 |= 0x01;
} }
if (mode & 0x0200) { if (mode & 0x0200) {
// streamed type &= ~(SOUND_TYPE_MEMORY | SOUND_TYPE_STREAMING);
v3 &= ~0x03; type |= SOUND_TYPE_STREAMING;
v3 |= 0x02;
} }
int index; int index;
@ -1911,7 +1908,7 @@ static int intLibSoundPlay(char* fileName, int mode)
return -1; return -1;
} }
Sound* sound = gIntLibSounds[index] = soundAllocate(v3, v5); Sound* sound = gIntLibSounds[index] = soundAllocate(type, soundFlags);
if (sound == NULL) { if (sound == NULL) {
return -1; return -1;
} }
@ -2009,7 +2006,7 @@ static int intLibSoundPause(int value)
} }
int rc; int rc;
if (_soundType(sound, 0x01)) { if (_soundType(sound, SOUND_TYPE_MEMORY)) {
rc = soundStop(sound); rc = soundStop(sound);
} else { } else {
rc = soundPause(sound); rc = soundPause(sound);
@ -2061,7 +2058,7 @@ static int intLibSoundResume(int value)
} }
int rc; int rc;
if (_soundType(sound, 0x01)) { if (_soundType(sound, SOUND_TYPE_MEMORY)) {
rc = soundPlay(sound); rc = soundPlay(sound);
} else { } else {
rc = soundResume(sound); rc = soundResume(sound);

View File

@ -413,7 +413,7 @@ static int _lips_make_speech()
gLipsData.sound = NULL; gLipsData.sound = NULL;
} }
gLipsData.sound = soundAllocate(1, 8); gLipsData.sound = soundAllocate(SOUND_TYPE_MEMORY, SOUND_16BIT);
if (gLipsData.sound == NULL) { if (gLipsData.sound == NULL) {
debugPrint("\nsoundAllocate falied in lips_make_speech!"); debugPrint("\nsoundAllocate falied in lips_make_speech!");
return -1; return -1;

View File

@ -22,10 +22,12 @@
namespace fallout { namespace fallout {
#define SOUND_FLAG_SOUND_IS_DONE (0x01) typedef enum SoundStatusFlags {
#define SOUND_FLAG_SOUND_IS_PLAYING (0x02) SOUND_STATUS_DONE = 0x01,
#define SOUND_FLAG_SOUND_IS_FADING (0x04) SOUND_STATUS_IS_PLAYING = 0x02,
#define SOUND_FLAG_SOUND_IS_PAUSED (0x08) SOUND_STATUS_IS_FADING = 0x04,
SOUND_STATUS_IS_PAUSED = 0x08,
} SoundStatusFlags;
typedef char*(SoundFileNameMangler)(char*); typedef char*(SoundFileNameMangler)(char*);
@ -35,7 +37,7 @@ typedef struct FadeSound {
int targetVolume; int targetVolume;
int initialVolume; int initialVolume;
int currentVolume; int currentVolume;
int field_14; int pause;
struct FadeSound* prev; struct FadeSound* prev;
struct FadeSound* next; struct FadeSound* next;
} FadeSound; } FadeSound;
@ -56,7 +58,7 @@ static Uint32 _doTimerEvent(Uint32 interval, void* param);
static void _removeTimedEvent(SDL_TimerID* timerId); static void _removeTimedEvent(SDL_TimerID* timerId);
static void _removeFadeSound(FadeSound* fadeSound); static void _removeFadeSound(FadeSound* fadeSound);
static void _fadeSounds(); 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 // 0x51D478
static FadeSound* _fadeHead = NULL; static FadeSound* _fadeHead = NULL;
@ -205,7 +207,7 @@ const char* soundGetErrorDescription(int err)
// 0x4AC7B0 // 0x4AC7B0
void _refreshSoundBuffers(Sound* sound) void _refreshSoundBuffers(Sound* sound)
{ {
if (sound->field_3C & 0x80) { if ((sound->soundFlags & SOUND_FLAG_0x80) != 0) {
return; return;
} }
@ -216,50 +218,50 @@ void _refreshSoundBuffers(Sound* sound)
return; return;
} }
if (readPos < sound->field_74) { if (readPos < sound->lastPosition) {
sound->field_64 += readPos + sound->field_78 * sound->field_7C - sound->field_74; sound->numBytesRead += readPos + sound->numBuffers * sound->dataSize - sound->lastPosition;
} else { } else {
sound->field_64 += readPos - sound->field_74; sound->numBytesRead += readPos - sound->lastPosition;
} }
if (sound->field_3C & 0x0100) { if ((sound->soundFlags & SOUND_FLAG_0x100) != 0) {
if (sound->field_44 & 0x20) { if ((sound->type & SOUND_TYPE_0x20) != 0) {
if (sound->field_3C & 0x0200) { if ((sound->soundFlags & SOUND_FLAG_0x200) != 0) {
sound->field_3C |= 0x80; sound->soundFlags |= SOUND_FLAG_0x80;
} }
} else { } else {
if (sound->field_60 <= sound->field_64) { if (sound->fileSize <= sound->numBytesRead) {
sound->field_3C |= 0x0280; 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; int v3;
do { do {
v3 = sound->field_64 - sound->field_60; v3 = sound->numBytesRead - sound->fileSize;
sound->field_64 = v3; sound->numBytesRead = v3;
} while (v3 > sound->field_60); } while (v3 > sound->fileSize);
} }
int v6 = readPos / sound->field_7C; int v6 = readPos / sound->dataSize;
if (sound->field_70 == v6) { if (sound->lastUpdate == v6) {
return; return;
} }
int v53; int v53;
if (sound->field_70 > v6) { if (sound->lastUpdate > v6) {
v53 = v6 + sound->field_78 - sound->field_70; v53 = v6 + sound->numBuffers - sound->lastUpdate;
} else { } else {
v53 = v6 - sound->field_70; v53 = v6 - sound->lastUpdate;
} }
if (sound->field_7C * v53 >= sound->readLimit) { if (sound->dataSize * v53 >= sound->readLimit) {
v53 = (sound->readLimit + sound->field_7C - 1) / sound->field_7C; v53 = (sound->readLimit + sound->dataSize - 1) / sound->dataSize;
} }
if (v53 < sound->field_5C) { if (v53 < sound->minReadBuffer) {
return; return;
} }
@ -267,17 +269,17 @@ void _refreshSoundBuffers(Sound* sound)
void* audioPtr2; void* audioPtr2;
unsigned int audioBytes1; unsigned int audioBytes1;
unsigned int audioBytes2; 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) { if (!hr) {
return; return;
} }
if (audioBytes1 + audioBytes2 != sound->field_7C * v53) { if (audioBytes1 + audioBytes2 != sound->dataSize * 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("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->field_7C); debugPrint("Resetting readBuffers from %d to %d\n", v53, (audioBytes1 + audioBytes2) / sound->dataSize);
v53 = (audioBytes1 + audioBytes2) / sound->field_7C; v53 = (audioBytes1 + audioBytes2) / sound->dataSize;
if (v53 < sound->field_5C) { if (v53 < sound->minReadBuffer) {
debugPrint("No longer above read buffer size, returning\n"); debugPrint("No longer above read buffer size, returning\n");
return; return;
} }
@ -286,11 +288,11 @@ void _refreshSoundBuffers(Sound* sound)
int audioBytes = audioBytes1; int audioBytes = audioBytes1;
while (--v53 != -1) { while (--v53 != -1) {
int bytesRead; int bytesRead;
if (sound->field_3C & 0x0200) { if ((sound->soundFlags & SOUND_FLAG_0x200) != 0) {
bytesRead = sound->field_7C; bytesRead = sound->dataSize;
memset(sound->field_20, 0, bytesRead); memset(sound->data, 0, bytesRead);
} else { } else {
int bytesToRead = sound->field_7C; int bytesToRead = sound->dataSize;
if (sound->field_58 != -1) { if (sound->field_58 != -1) {
int pos = sound->io.tell(sound->io.fd); int pos = sound->io.tell(sound->io.fd);
if (bytesToRead + pos > sound->field_58) { 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); bytesRead = sound->io.read(sound->io.fd, sound->data, bytesToRead);
if (bytesRead < sound->field_7C) { if (bytesRead < sound->dataSize) {
if (!(sound->field_3C & 0x20) || (sound->field_3C & 0x0100)) { if ((sound->soundFlags & SOUND_LOOPING) == 0 || (sound->soundFlags & SOUND_FLAG_0x100) != 0) {
memset(sound->field_20 + bytesRead, 0, sound->field_7C - bytesRead); memset(sound->data + bytesRead, 0, sound->dataSize - bytesRead);
sound->field_3C |= 0x0200; sound->soundFlags |= SOUND_FLAG_0x200;
bytesRead = sound->field_7C; bytesRead = sound->dataSize;
} else { } else {
while (bytesRead < sound->field_7C) { while (bytesRead < sound->dataSize) {
if (sound->field_50 == -1) { if (sound->loops == -1) {
sound->io.seek(sound->io.fd, sound->field_54, SEEK_SET); sound->io.seek(sound->io.fd, sound->field_54, SEEK_SET);
if (sound->callback != NULL) { if (sound->callback != NULL) {
sound->callback(sound->callbackUserData, 0x0400); sound->callback(sound->callbackUserData, 0x0400);
} }
} else { } else {
if (sound->field_50 <= 0) { if (sound->loops <= 0) {
sound->field_58 = -1; sound->field_58 = -1;
sound->field_54 = 0; sound->field_54 = 0;
sound->field_50 = 0; sound->loops = 0;
sound->field_3C &= ~0x20; sound->soundFlags &= ~SOUND_LOOPING;
bytesRead += sound->io.read(sound->io.fd, sound->field_20 + bytesRead, sound->field_7C - bytesRead); bytesRead += sound->io.read(sound->io.fd, sound->data + bytesRead, sound->dataSize - bytesRead);
break; break;
} }
sound->field_50--; sound->loops--;
sound->io.seek(sound->io.fd, sound->field_54, SEEK_SET); sound->io.seek(sound->io.fd, sound->field_54, SEEK_SET);
if (sound->callback != NULL) { if (sound->callback != NULL) {
@ -330,17 +332,17 @@ void _refreshSoundBuffers(Sound* sound)
} }
if (sound->field_58 == -1) { if (sound->field_58 == -1) {
bytesToRead = sound->field_7C - bytesRead; bytesToRead = sound->dataSize - bytesRead;
} else { } else {
int pos = sound->io.tell(sound->io.fd); int pos = sound->io.tell(sound->io.fd);
if (sound->field_7C + bytesRead + pos <= sound->field_58) { if (sound->dataSize + bytesRead + pos <= sound->field_58) {
bytesToRead = sound->field_7C - bytesRead; bytesToRead = sound->dataSize - bytesRead;
} else { } else {
bytesToRead = sound->field_58 - bytesRead - pos; 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; bytesRead += v20;
if (v20 < bytesToRead) { if (v20 < bytesToRead) {
break; break;
@ -352,18 +354,18 @@ void _refreshSoundBuffers(Sound* sound)
if (bytesRead > audioBytes) { if (bytesRead > audioBytes) {
if (audioBytes != 0) { if (audioBytes != 0) {
memcpy(audioPtr, sound->field_20, audioBytes); memcpy(audioPtr, sound->data, audioBytes);
} }
if (audioPtr2 != NULL) { if (audioPtr2 != NULL) {
memcpy(audioPtr2, sound->field_20 + audioBytes, bytesRead - audioBytes); memcpy(audioPtr2, sound->data + audioBytes, bytesRead - audioBytes);
audioPtr = (unsigned char*)audioPtr2 + bytesRead - audioBytes; audioPtr = (unsigned char*)audioPtr2 + bytesRead - audioBytes;
audioBytes = audioBytes2 - bytesRead; audioBytes = audioBytes2 - bytesRead;
} else { } else {
debugPrint("Hm, no second write pointer, but buffer not big enough, this shouldn't happen\n"); debugPrint("Hm, no second write pointer, but buffer not big enough, this shouldn't happen\n");
} }
} else { } else {
memcpy(audioPtr, sound->field_20, bytesRead); memcpy(audioPtr, sound->data, bytesRead);
audioPtr += bytesRead; audioPtr += bytesRead;
audioBytes -= bytesRead; audioBytes -= bytesRead;
} }
@ -371,11 +373,11 @@ void _refreshSoundBuffers(Sound* sound)
audioEngineSoundBufferUnlock(sound->soundBuffer, audioPtr1, audioBytes1, audioPtr2, audioBytes2); audioEngineSoundBufferUnlock(sound->soundBuffer, audioPtr1, audioBytes1, audioPtr2, audioBytes2);
sound->field_70 = v6; sound->lastUpdate = v6;
} }
// 0x4ACC58 // 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()) { if (!audioEngineInit()) {
debugPrint("soundInit: Unable to init audio engine\n"); 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; _sampleRate = rate;
_dataSize = a4; _dataSize = dataSize;
_numBuffers = a2; _numBuffers = numBuffers;
gSoundInitialized = true; gSoundInitialized = true;
_deviceInit = 1; _deviceInit = 1;
@ -422,7 +424,7 @@ void soundExit()
} }
// 0x4AD0FC // 0x4AD0FC
Sound* soundAllocate(int a1, int a2) Sound* soundAllocate(int type, int soundFlags)
{ {
if (!gSoundInitialized) { if (!gSoundInitialized) {
gSoundLastError = SOUND_NOT_INITIALIZED; gSoundLastError = SOUND_NOT_INITIALIZED;
@ -434,30 +436,30 @@ Sound* soundAllocate(int a1, int a2)
memcpy(&(sound->io), &gSoundDefaultFileIO, sizeof(gSoundDefaultFileIO)); memcpy(&(sound->io), &gSoundDefaultFileIO, sizeof(gSoundDefaultFileIO));
if (!(a2 & 0x02)) { if ((soundFlags & SOUND_FLAG_0x02) == 0) {
a2 |= 0x02; soundFlags |= SOUND_FLAG_0x02;
} }
sound->bitsPerSample = (a2 & 0x08) != 0 ? 16 : 8; sound->bitsPerSample = (soundFlags & SOUND_16BIT) != 0 ? 16 : 8;
sound->channels = 1; sound->channels = 1;
sound->rate = _sampleRate; sound->rate = _sampleRate;
sound->field_3C = a2; sound->soundFlags = soundFlags;
sound->field_44 = a1; sound->type = type;
sound->field_7C = _dataSize; sound->dataSize = _dataSize;
sound->field_64 = 0; sound->numBytesRead = 0;
sound->soundBuffer = -1; sound->soundBuffer = -1;
sound->field_40 = 0; sound->statusFlags = 0;
sound->field_78 = _numBuffers; sound->numBuffers = _numBuffers;
sound->readLimit = sound->field_7C * _numBuffers; sound->readLimit = sound->dataSize * _numBuffers;
if (a1 & 0x10) { if ((type & SOUND_TYPE_INFINITE) != 0) {
sound->field_50 = -1; sound->loops = -1;
sound->field_3C |= 0x20; sound->soundFlags |= SOUND_LOOPING;
} }
sound->field_58 = -1; sound->field_58 = -1;
sound->field_5C = 1; sound->minReadBuffer = 1;
sound->volume = VOLUME_MAX; sound->volume = VOLUME_MAX;
sound->prev = NULL; sound->prev = NULL;
sound->field_54 = 0; sound->field_54 = 0;
@ -483,29 +485,29 @@ int _preloadBuffers(Sound* sound)
int size; int size;
size = sound->io.filelength(sound->io.fd); size = sound->io.filelength(sound->io.fd);
sound->field_60 = size; sound->fileSize = size;
if (sound->field_44 & 0x02) { if ((sound->type & SOUND_TYPE_STREAMING) != 0) {
if (!(sound->field_3C & 0x20)) { if ((sound->soundFlags & SOUND_LOOPING) == 0) {
sound->field_3C |= 0x0120; sound->soundFlags |= SOUND_FLAG_0x100 | SOUND_LOOPING;
} }
if (sound->field_78 * sound->field_7C >= size) { if (sound->numBuffers * sound->dataSize >= size) {
if (size / sound->field_7C * sound->field_7C != size) { if (size / sound->dataSize * sound->dataSize != size) {
size = (size / sound->field_7C + 1) * sound->field_7C; size = (size / sound->dataSize + 1) * sound->dataSize;
} }
} else { } else {
size = sound->field_78 * sound->field_7C; size = sound->numBuffers * sound->dataSize;
} }
} else { } else {
sound->field_44 &= ~(0x03); sound->type &= ~(SOUND_TYPE_MEMORY | SOUND_TYPE_STREAMING);
sound->field_44 |= 0x01; sound->type |= SOUND_TYPE_MEMORY;
} }
buf = (unsigned char*)gSoundMallocProc(size); buf = (unsigned char*)gSoundMallocProc(size);
bytes_read = sound->io.read(sound->io.fd, buf, size); bytes_read = sound->io.read(sound->io.fd, buf, size);
if (bytes_read != 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); memset(buf + bytes_read, 0, size - bytes_read);
} else { } else {
v14 = buf + bytes_read; v14 = buf + bytes_read;
@ -525,12 +527,12 @@ int _preloadBuffers(Sound* sound)
result = _soundSetData(sound, buf, size); result = _soundSetData(sound, buf, size);
gSoundFreeProc(buf); gSoundFreeProc(buf);
if (sound->field_44 & 0x01) { if ((sound->type & SOUND_TYPE_MEMORY) != 0) {
sound->io.close(sound->io.fd); sound->io.close(sound->io.fd);
sound->io.fd = -1; sound->io.fd = -1;
} else { } else {
if (sound->field_20 == NULL) { if (sound->data == NULL) {
sound->field_20 = (unsigned char*)gSoundMallocProc(sound->field_7C); sound->data = (unsigned char*)gSoundMallocProc(sound->dataSize);
} }
} }
@ -574,12 +576,12 @@ int _soundRewind(Sound* sound)
return gSoundLastError; return gSoundLastError;
} }
if (sound->field_44 & 0x02) { if ((sound->type & SOUND_TYPE_STREAMING) != 0) {
sound->io.seek(sound->io.fd, 0, SEEK_SET); sound->io.seek(sound->io.fd, 0, SEEK_SET);
sound->field_70 = 0; sound->lastUpdate = 0;
sound->field_74 = 0; sound->lastPosition = 0;
sound->field_64 = 0; sound->numBytesRead = 0;
sound->field_3C &= 0xFD7F; sound->soundFlags &= ~(SOUND_FLAG_0x200 | SOUND_FLAG_0x80);
hr = audioEngineSoundBufferSetCurrentPosition(sound->soundBuffer, 0); hr = audioEngineSoundBufferSetCurrentPosition(sound->soundBuffer, 0);
_preloadBuffers(sound); _preloadBuffers(sound);
} else { } else {
@ -591,7 +593,7 @@ int _soundRewind(Sound* sound)
return gSoundLastError; return gSoundLastError;
} }
sound->field_40 &= ~SOUND_FLAG_SOUND_IS_DONE; sound->statusFlags &= ~SOUND_STATUS_DONE;
gSoundLastError = SOUND_NO_ERROR; gSoundLastError = SOUND_NO_ERROR;
return gSoundLastError; return gSoundLastError;
@ -669,24 +671,23 @@ int soundPlay(Sound* sound)
return gSoundLastError; return gSoundLastError;
} }
// TODO: Check. if ((sound->statusFlags & SOUND_STATUS_DONE) != 0) {
if (sound->field_40 & SOUND_FLAG_SOUND_IS_DONE) {
_soundRewind(sound); _soundRewind(sound);
} }
soundSetVolume(sound, sound->volume); 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); audioEngineSoundBufferGetCurrentPosition(sound->soundBuffer, &readPos, &writePos);
sound->field_70 = readPos / sound->field_7C; sound->lastUpdate = readPos / sound->dataSize;
if (!hr) { if (!hr) {
gSoundLastError = SOUND_UNKNOWN_ERROR; gSoundLastError = SOUND_UNKNOWN_ERROR;
return gSoundLastError; return gSoundLastError;
} }
sound->field_40 |= SOUND_FLAG_SOUND_IS_PLAYING; sound->statusFlags |= SOUND_STATUS_IS_PLAYING;
++_numSounds; ++_numSounds;
@ -709,7 +710,7 @@ int soundStop(Sound* sound)
return gSoundLastError; return gSoundLastError;
} }
if (!(sound->field_40 & SOUND_FLAG_SOUND_IS_PLAYING)) { if ((sound->statusFlags & SOUND_STATUS_IS_PLAYING) == 0) {
gSoundLastError = SOUND_NOT_PLAYING; gSoundLastError = SOUND_NOT_PLAYING;
return gSoundLastError; return gSoundLastError;
} }
@ -720,7 +721,7 @@ int soundStop(Sound* sound)
return gSoundLastError; return gSoundLastError;
} }
sound->field_40 &= ~SOUND_FLAG_SOUND_IS_PLAYING; sound->statusFlags &= ~SOUND_STATUS_IS_PLAYING;
_numSounds--; _numSounds--;
gSoundLastError = SOUND_NO_ERROR; gSoundLastError = SOUND_NO_ERROR;
@ -772,12 +773,17 @@ int soundContinue(Sound* sound)
return gSoundLastError; 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; gSoundLastError = SOUND_NOT_PLAYING;
return gSoundLastError; 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; gSoundLastError = SOUND_UNKNOWN_ERROR;
return gSoundLastError; return gSoundLastError;
} }
@ -790,29 +796,29 @@ int soundContinue(Sound* sound)
return gSoundLastError; return gSoundLastError;
} }
if (!(sound->field_3C & 0x80) && (status & (AUDIO_ENGINE_SOUND_BUFFER_STATUS_PLAYING | AUDIO_ENGINE_SOUND_BUFFER_STATUS_LOOPING))) { if ((sound->soundFlags & SOUND_FLAG_0x80) == 0 && (status & (AUDIO_ENGINE_SOUND_BUFFER_STATUS_PLAYING | AUDIO_ENGINE_SOUND_BUFFER_STATUS_LOOPING)) != 0) {
if (!(sound->field_40 & SOUND_FLAG_SOUND_IS_PAUSED) && (sound->field_44 & 0x02)) { if ((sound->statusFlags & SOUND_STATUS_IS_PAUSED) == 0 && (sound->type & SOUND_TYPE_STREAMING) != 0) {
_refreshSoundBuffers(sound); _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) { if (sound->callback != NULL) {
sound->callback(sound->callbackUserData, 1); sound->callback(sound->callbackUserData, 1);
sound->callback = NULL; sound->callback = NULL;
} }
if (sound->field_44 & 0x04) { if ((sound->type & SOUND_TYPE_FIRE_AND_FORGET) != 0) {
sound->callback = NULL; sound->callback = NULL;
soundDelete(sound); soundDelete(sound);
} else { } 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; --_numSounds;
} }
soundStop(sound); 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 false;
} }
return (sound->field_40 & SOUND_FLAG_SOUND_IS_PLAYING) != 0; return (sound->statusFlags & SOUND_STATUS_IS_PLAYING) != 0;
} }
// 0x4ADAC4 // 0x4ADAC4
@ -849,7 +855,7 @@ bool _soundDone(Sound* sound)
return false; return false;
} }
return sound->field_40 & 1; return (sound->statusFlags & SOUND_STATUS_DONE) != 0;
} }
// 0x4ADB44 // 0x4ADB44
@ -865,11 +871,11 @@ bool soundIsPaused(Sound* sound)
return false; return false;
} }
return (sound->field_40 & SOUND_FLAG_SOUND_IS_PAUSED) != 0; return (sound->statusFlags & SOUND_STATUS_IS_PAUSED) != 0;
} }
// 0x4ADBC4 // 0x4ADBC4
int _soundType(Sound* sound, int a2) int _soundType(Sound* sound, int type)
{ {
if (!gSoundInitialized) { if (!gSoundInitialized) {
gSoundLastError = SOUND_NOT_INITIALIZED; gSoundLastError = SOUND_NOT_INITIALIZED;
@ -881,7 +887,7 @@ int _soundType(Sound* sound, int a2)
return 0; return 0;
} }
return sound->field_44 & a2; return sound->type & type;
} }
// 0x4ADC04 // 0x4ADC04
@ -898,7 +904,7 @@ int soundGetDuration(Sound* sound)
} }
int bytesPerSec = sound->bitsPerSample / 8 * sound->rate; int bytesPerSec = sound->bitsPerSample / 8 * sound->rate;
int v3 = sound->field_60; int v3 = sound->fileSize;
int v4 = v3 % bytesPerSec; int v4 = v3 % bytesPerSec;
int result = v3 / bytesPerSec; int result = v3 / bytesPerSec;
if (v4 != 0) { if (v4 != 0) {
@ -909,7 +915,7 @@ int soundGetDuration(Sound* sound)
} }
// 0x4ADD00 // 0x4ADD00
int soundSetLooping(Sound* sound, int a2) int soundSetLooping(Sound* sound, int loops)
{ {
if (!gSoundInitialized) { if (!gSoundInitialized) {
gSoundLastError = SOUND_NOT_INITIALIZED; gSoundLastError = SOUND_NOT_INITIALIZED;
@ -921,14 +927,14 @@ int soundSetLooping(Sound* sound, int a2)
return gSoundLastError; return gSoundLastError;
} }
if (a2) { if (loops != 0) {
sound->field_3C |= 0x20; sound->soundFlags |= SOUND_LOOPING;
sound->field_50 = a2; sound->loops = loops;
} else { } else {
sound->field_50 = 0; sound->loops = 0;
sound->field_58 = -1; sound->field_58 = -1;
sound->field_54 = 0; sound->field_54 = 0;
sound->field_3C &= ~(0x20); sound->soundFlags &= ~SOUND_LOOPING;
} }
gSoundLastError = SOUND_NO_ERROR; gSoundLastError = SOUND_NO_ERROR;
@ -1085,12 +1091,12 @@ int soundPause(Sound* sound)
return gSoundLastError; return gSoundLastError;
} }
if (!(sound->field_40 & SOUND_FLAG_SOUND_IS_PLAYING)) { if ((sound->statusFlags & SOUND_STATUS_IS_PLAYING) == 0) {
gSoundLastError = SOUND_NOT_PLAYING; gSoundLastError = SOUND_NOT_PLAYING;
return gSoundLastError; return gSoundLastError;
} }
if (sound->field_40 & SOUND_FLAG_SOUND_IS_PAUSED) { if ((sound->statusFlags & SOUND_STATUS_IS_PAUSED) != 0) {
gSoundLastError = SOUND_ALREADY_PAUSED; gSoundLastError = SOUND_ALREADY_PAUSED;
return gSoundLastError; return gSoundLastError;
} }
@ -1101,8 +1107,8 @@ int soundPause(Sound* sound)
return gSoundLastError; return gSoundLastError;
} }
sound->field_48 = readPos; sound->pausePos = readPos;
sound->field_40 |= SOUND_FLAG_SOUND_IS_PAUSED; sound->statusFlags |= SOUND_STATUS_IS_PAUSED;
return soundStop(sound); return soundStop(sound);
} }
@ -1124,24 +1130,24 @@ int soundResume(Sound* sound)
return gSoundLastError; return gSoundLastError;
} }
if ((sound->field_40 & SOUND_FLAG_SOUND_IS_PLAYING) != 0) { if ((sound->statusFlags & SOUND_STATUS_IS_PLAYING) != 0) {
gSoundLastError = SOUND_NOT_PAUSED; gSoundLastError = SOUND_NOT_PAUSED;
return gSoundLastError; return gSoundLastError;
} }
if (!(sound->field_40 & SOUND_FLAG_SOUND_IS_PAUSED)) { if ((sound->statusFlags & SOUND_STATUS_IS_PAUSED) == 0) {
gSoundLastError = SOUND_NOT_PAUSED; gSoundLastError = SOUND_NOT_PAUSED;
return gSoundLastError; return gSoundLastError;
} }
hr = audioEngineSoundBufferSetCurrentPosition(sound->soundBuffer, sound->field_48); hr = audioEngineSoundBufferSetCurrentPosition(sound->soundBuffer, sound->pausePos);
if (!hr) { if (!hr) {
gSoundLastError = SOUND_UNKNOWN_ERROR; gSoundLastError = SOUND_UNKNOWN_ERROR;
return gSoundLastError; return gSoundLastError;
} }
sound->field_40 &= ~SOUND_FLAG_SOUND_IS_PAUSED; sound->statusFlags &= ~SOUND_STATUS_IS_PAUSED;
sound->field_48 = 0; sound->pausePos = 0;
return soundPlay(sound); return soundPlay(sound);
} }
@ -1194,22 +1200,21 @@ int soundSetFileIO(Sound* sound, SoundOpenProc* openProc, SoundCloseProc* closeP
// 0x4AE378 // 0x4AE378
void soundDeleteInternal(Sound* sound) void soundDeleteInternal(Sound* sound)
{ {
FadeSound* curr; Sound* next;
Sound* v10; Sound* prev;
Sound* v11;
if (sound->field_40 & SOUND_FLAG_SOUND_IS_FADING) { if ((sound->statusFlags & SOUND_STATUS_IS_FADING) != 0) {
curr = _fadeHead; FadeSound* fadeSound = _fadeHead;
while (curr != NULL) { while (fadeSound != NULL) {
if (sound == curr->sound) { if (sound == fadeSound->sound) {
break; break;
} }
curr = curr->next; fadeSound = fadeSound->next;
} }
_removeFadeSound(curr); _removeFadeSound(fadeSound);
} }
if (sound->soundBuffer != -1) { if (sound->soundBuffer != -1) {
@ -1226,23 +1231,23 @@ void soundDeleteInternal(Sound* sound)
sound->soundBuffer = -1; sound->soundBuffer = -1;
} }
if (sound->field_90 != NULL) { if (sound->deleteCallback != NULL) {
sound->field_90(sound->field_8C); sound->deleteCallback(sound->deleteUserData);
} }
if (sound->field_20 != NULL) { if (sound->data != NULL) {
gSoundFreeProc(sound->field_20); gSoundFreeProc(sound->data);
sound->field_20 = NULL; sound->data = NULL;
} }
v10 = sound->next; next = sound->next;
if (v10 != NULL) { if (next != NULL) {
v10->prev = sound->prev; next->prev = sound->prev;
} }
v11 = sound->prev; prev = sound->prev;
if (v11 != NULL) { if (prev != NULL) {
v11->next = sound->next; prev->next = sound->next;
} else { } else {
gSoundListHead = sound->next; gSoundListHead = sound->next;
} }
@ -1305,23 +1310,23 @@ int _soundGetPosition(Sound* sound)
return gSoundLastError; return gSoundLastError;
} }
unsigned int playPos; unsigned int readPos;
unsigned int writePos; unsigned int writePos;
audioEngineSoundBufferGetCurrentPosition(sound->soundBuffer, &playPos, &writePos); audioEngineSoundBufferGetCurrentPosition(sound->soundBuffer, &readPos, &writePos);
if ((sound->field_44 & 0x02) != 0) { if ((sound->type & SOUND_TYPE_STREAMING) != 0) {
if (playPos < sound->field_74) { if (readPos < sound->lastPosition) {
playPos += sound->field_64 + sound->field_78 * sound->field_7C - sound->field_74; readPos += sound->numBytesRead + sound->numBuffers * sound->dataSize - sound->lastPosition;
} else { } else {
playPos -= sound->field_74 + sound->field_64; readPos -= sound->lastPosition + sound->numBytesRead;
} }
} }
return playPos; return readPos;
} }
// 0x4AE6CC // 0x4AE6CC
int _soundSetPosition(Sound* sound, int a2) int _soundSetPosition(Sound* sound, int pos)
{ {
if (!gSoundInitialized) { if (!gSoundInitialized) {
gSoundLastError = SOUND_NOT_INITIALIZED; gSoundLastError = SOUND_NOT_INITIALIZED;
@ -1338,34 +1343,34 @@ int _soundSetPosition(Sound* sound, int a2)
return gSoundLastError; return gSoundLastError;
} }
if (sound->field_44 & 0x02) { if ((sound->type & SOUND_TYPE_STREAMING) != 0) {
int v6 = a2 / sound->field_7C % sound->field_78; 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); sound->io.seek(sound->io.fd, section * sound->dataSize, SEEK_SET);
int bytes_read = sound->io.read(sound->io.fd, sound->field_20, sound->field_7C); int bytesRead = sound->io.read(sound->io.fd, sound->data, sound->dataSize);
if (bytes_read < sound->field_7C) { if (bytesRead < sound->dataSize) {
if (sound->field_44 & 0x02) { if ((sound->type & SOUND_TYPE_STREAMING) != 0) {
sound->io.seek(sound->io.fd, 0, SEEK_SET); 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 { } 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; int nextSection = section + 1;
sound->field_64 = a2; sound->numBytesRead = pos;
if (v17 < sound->field_78) { if (nextSection < sound->numBuffers) {
sound->field_70 = v17; sound->lastUpdate = nextSection;
} else { } else {
sound->field_70 = 0; sound->lastUpdate = 0;
} }
soundContinue(sound); soundContinue(sound);
} else { } else {
audioEngineSoundBufferSetCurrentPosition(sound->soundBuffer, a2); audioEngineSoundBufferSetCurrentPosition(sound->soundBuffer, pos);
} }
gSoundLastError = SOUND_NO_ERROR; gSoundLastError = SOUND_NO_ERROR;
@ -1387,7 +1392,7 @@ void _removeFadeSound(FadeSound* fadeSound)
return; return;
} }
if (!(fadeSound->sound->field_40 & SOUND_FLAG_SOUND_IS_FADING)) { if ((fadeSound->sound->statusFlags & SOUND_STATUS_IS_FADING) == 0) {
return; return;
} }
@ -1403,7 +1408,7 @@ void _removeFadeSound(FadeSound* fadeSound)
next->prev = fadeSound->prev; next->prev = fadeSound->prev;
} }
fadeSound->sound->field_40 &= ~SOUND_FLAG_SOUND_IS_FADING; fadeSound->sound->statusFlags &= ~SOUND_STATUS_IS_FADING;
fadeSound->sound = NULL; fadeSound->sound = NULL;
tmp = _fadeFreeList; tmp = _fadeFreeList;
@ -1414,34 +1419,34 @@ void _removeFadeSound(FadeSound* fadeSound)
// 0x4AE8B0 // 0x4AE8B0
void _fadeSounds() void _fadeSounds()
{ {
FadeSound* ptr; FadeSound* fadeSound;
ptr = _fadeHead; fadeSound = _fadeHead;
while (ptr != NULL) { while (fadeSound != NULL) {
if ((ptr->currentVolume > ptr->targetVolume || ptr->currentVolume + ptr->deltaVolume < ptr->targetVolume) && (ptr->currentVolume < ptr->targetVolume || ptr->currentVolume + ptr->deltaVolume > ptr->targetVolume)) { if ((fadeSound->currentVolume > fadeSound->targetVolume || fadeSound->currentVolume + fadeSound->deltaVolume < fadeSound->targetVolume) && (fadeSound->currentVolume < fadeSound->targetVolume || fadeSound->currentVolume + fadeSound->deltaVolume > fadeSound->targetVolume)) {
ptr->currentVolume += ptr->deltaVolume; fadeSound->currentVolume += fadeSound->deltaVolume;
soundSetVolume(ptr->sound, ptr->currentVolume); soundSetVolume(fadeSound->sound, fadeSound->currentVolume);
} else { } else {
if (ptr->targetVolume == 0) { if (fadeSound->targetVolume == 0) {
if (ptr->field_14) { if (fadeSound->pause) {
soundPause(ptr->sound); soundPause(fadeSound->sound);
soundSetVolume(ptr->sound, ptr->initialVolume); soundSetVolume(fadeSound->sound, fadeSound->initialVolume);
} else { } else {
if (ptr->sound->field_44 & 0x04) { if ((fadeSound->sound->type & SOUND_TYPE_FIRE_AND_FORGET) != 0) {
soundDelete(ptr->sound); soundDelete(fadeSound->sound);
} else { } else {
soundStop(ptr->sound); soundStop(fadeSound->sound);
ptr->initialVolume = ptr->targetVolume; fadeSound->initialVolume = fadeSound->targetVolume;
ptr->currentVolume = ptr->targetVolume; fadeSound->currentVolume = fadeSound->targetVolume;
ptr->deltaVolume = 0; fadeSound->deltaVolume = 0;
soundSetVolume(ptr->sound, ptr->targetVolume); soundSetVolume(fadeSound->sound, fadeSound->targetVolume);
} }
} }
} }
_removeFadeSound(ptr); _removeFadeSound(fadeSound);
} }
} }
@ -1452,9 +1457,9 @@ void _fadeSounds()
} }
// 0x4AE988 // 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) { if (!_deviceInit) {
gSoundLastError = SOUND_NOT_INITIALIZED; gSoundLastError = SOUND_NOT_INITIALIZED;
@ -1466,56 +1471,56 @@ int _internalSoundFade(Sound* sound, int duration, int targetVolume, int a4)
return gSoundLastError; return gSoundLastError;
} }
ptr = NULL; fadeSound = NULL;
if (sound->field_40 & SOUND_FLAG_SOUND_IS_FADING) { if ((sound->statusFlags & SOUND_STATUS_IS_FADING) != 0) {
ptr = _fadeHead; fadeSound = _fadeHead;
while (ptr != NULL) { while (fadeSound != NULL) {
if (ptr->sound == sound) { if (fadeSound->sound == sound) {
break; break;
} }
ptr = ptr->next; fadeSound = fadeSound->next;
} }
} }
if (ptr == NULL) { if (fadeSound == NULL) {
if (_fadeFreeList != NULL) { if (_fadeFreeList != NULL) {
ptr = _fadeFreeList; fadeSound = _fadeFreeList;
_fadeFreeList = _fadeFreeList->next; _fadeFreeList = _fadeFreeList->next;
} else { } else {
ptr = (FadeSound*)gSoundMallocProc(sizeof(FadeSound)); fadeSound = (FadeSound*)gSoundMallocProc(sizeof(FadeSound));
} }
if (ptr != NULL) { if (fadeSound != NULL) {
if (_fadeHead != NULL) { if (_fadeHead != NULL) {
_fadeHead->prev = ptr; _fadeHead->prev = fadeSound;
} }
ptr->sound = sound; fadeSound->sound = sound;
ptr->prev = NULL; fadeSound->prev = NULL;
ptr->next = _fadeHead; fadeSound->next = _fadeHead;
_fadeHead = ptr; _fadeHead = fadeSound;
} }
} }
if (ptr == NULL) { if (fadeSound == NULL) {
gSoundLastError = SOUND_NO_MEMORY_AVAILABLE; gSoundLastError = SOUND_NO_MEMORY_AVAILABLE;
return gSoundLastError; return gSoundLastError;
} }
ptr->targetVolume = targetVolume; fadeSound->targetVolume = targetVolume;
ptr->initialVolume = _soundGetVolume(sound); fadeSound->initialVolume = _soundGetVolume(sound);
ptr->currentVolume = ptr->initialVolume; fadeSound->currentVolume = fadeSound->initialVolume;
ptr->field_14 = a4; fadeSound->pause = pause;
// TODO: Check. // 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; bool shouldPlay;
if (gSoundInitialized) { if (gSoundInitialized) {
if (sound->soundBuffer != -1) { if (sound->soundBuffer != -1) {
shouldPlay = (sound->field_40 & SOUND_FLAG_SOUND_IS_PLAYING) == 0; shouldPlay = (sound->statusFlags & SOUND_STATUS_IS_PLAYING) == 0;
} else { } else {
gSoundLastError = SOUND_NO_SOUND; gSoundLastError = SOUND_NO_SOUND;
shouldPlay = true; shouldPlay = true;
@ -1547,7 +1552,7 @@ int _internalSoundFade(Sound* sound, int duration, int targetVolume, int a4)
// 0x4AEB0C // 0x4AEB0C
int _soundFade(Sound* sound, int duration, int targetVolume) int _soundFade(Sound* sound, int duration, int targetVolume)
{ {
return _internalSoundFade(sound, duration, targetVolume, 0); return _internalSoundFade(sound, duration, targetVolume, false);
} }
// 0x4AEB54 // 0x4AEB54

View File

@ -65,50 +65,66 @@ typedef struct SoundFileIO {
int fd; int fd;
} SoundFileIO; } 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 SoundCallback(void* userData, int a2);
typedef void SoundDeleteCallback(void* userData);
typedef struct Sound { typedef struct Sound {
SoundFileIO io; SoundFileIO io;
unsigned char* field_20; unsigned char* data;
int soundBuffer; int soundBuffer;
int bitsPerSample; int bitsPerSample;
int channels; int channels;
int rate; int rate;
int field_3C; int soundFlags;
// flags int statusFlags;
int field_40; int type;
int field_44; int pausePos;
// pause pos
int field_48;
int volume; int volume;
int field_50; int loops;
int field_54; int field_54;
int field_58; int field_58;
int field_5C; int minReadBuffer;
// file size int fileSize;
int field_60; int numBytesRead;
int field_64;
int field_68; int field_68;
int readLimit; int readLimit;
int field_70; int lastUpdate;
unsigned int field_74; unsigned int lastPosition;
int field_78; int numBuffers;
int field_7C; int dataSize;
int field_80; void* userData;
// callback data
void* callbackUserData; void* callbackUserData;
SoundCallback* callback; SoundCallback* callback;
int field_8C; void* deleteUserData;
void (*field_90)(int); SoundDeleteCallback* deleteCallback;
struct Sound* next; struct Sound* next;
struct Sound* prev; struct Sound* prev;
} Sound; } Sound;
void soundSetMemoryProcs(MallocProc* mallocProc, ReallocProc* reallocProc, FreeProc* freeProc); void soundSetMemoryProcs(MallocProc* mallocProc, ReallocProc* reallocProc, FreeProc* freeProc);
const char* soundGetErrorDescription(int err); 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(); void soundExit();
Sound* soundAllocate(int a1, int a2); Sound* soundAllocate(int type, int soundFlags);
int soundLoad(Sound* sound, char* filePath); int soundLoad(Sound* sound, char* filePath);
int soundPlay(Sound* sound); int soundPlay(Sound* sound);
int soundStop(Sound* sound); int soundStop(Sound* sound);
@ -116,9 +132,9 @@ int soundDelete(Sound* sound);
bool soundIsPlaying(Sound* sound); bool soundIsPlaying(Sound* sound);
bool _soundDone(Sound* sound); bool _soundDone(Sound* sound);
bool soundIsPaused(Sound* sound); bool soundIsPaused(Sound* sound);
int _soundType(Sound* sound, int a2); int _soundType(Sound* sound, int type);
int soundGetDuration(Sound* sound); int soundGetDuration(Sound* sound);
int soundSetLooping(Sound* sound, int a2); int soundSetLooping(Sound* sound, int loops);
int _soundVolumeHMItoDirectSound(int a1); int _soundVolumeHMItoDirectSound(int a1);
int soundSetVolume(Sound* sound, int volume); int soundSetVolume(Sound* sound, int volume);
int soundSetCallback(Sound* sound, SoundCallback* callback, void* userData); 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 soundSetFileIO(Sound* sound, SoundOpenProc* openProc, SoundCloseProc* closeProc, SoundReadProc* readProc, SoundWriteProc* writeProc, SoundSeekProc* seekProc, SoundTellProc* tellProc, SoundFileLengthProc* fileLengthProc);
int _soundSetMasterVolume(int value); int _soundSetMasterVolume(int value);
int _soundGetPosition(Sound* sound); int _soundGetPosition(Sound* sound);
int _soundSetPosition(Sound* sound, int a2); int _soundSetPosition(Sound* sound, int pos);
int _soundFade(Sound* sound, int duration, int targetVolume); int _soundFade(Sound* sound, int duration, int targetVolume);
void soundDeleteAll(); void soundDeleteAll();
void soundContinueAll(); void soundContinueAll();