From d00b818b5034bd68686ff045774afe912f6b44fb Mon Sep 17 00:00:00 2001 From: Alexander Batalov Date: Mon, 11 Jul 2022 17:48:46 +0300 Subject: [PATCH] Migrate sound to SDL --- CMakeLists.txt | 3 +- src/audio_engine.cc | 395 +++++++++++++++++++++++++++++++ src/audio_engine.h | 29 +++ src/core.cc | 22 +- src/dsound_compat.h | 17 -- src/movie.cc | 15 +- src/movie_lib.cc | 164 ++++--------- src/movie_lib.h | 4 - src/sound.cc | 552 +++++++++----------------------------------- src/sound.h | 18 +- src/win32.cc | 59 +---- src/win32.h | 15 -- 12 files changed, 603 insertions(+), 690 deletions(-) create mode 100644 src/audio_engine.cc create mode 100644 src/audio_engine.h delete mode 100644 src/dsound_compat.h diff --git a/CMakeLists.txt b/CMakeLists.txt index a268ea5..127322e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -233,7 +233,8 @@ add_executable(${EXECUTABLE_NAME} WIN32 MACOSX_BUNDLE ) target_sources(${EXECUTABLE_NAME} PUBLIC - "src/dsound_compat.h" + "src/audio_engine.cc" + "src/audio_engine.h" "src/fps_limiter.cc" "src/fps_limiter.h" "src/platform_compat.cc" diff --git a/src/audio_engine.cc b/src/audio_engine.cc new file mode 100644 index 0000000..de75072 --- /dev/null +++ b/src/audio_engine.cc @@ -0,0 +1,395 @@ +#include "audio_engine.h" + +#include + +#include + +#define AUDIO_ENGINE_SOUND_BUFFERS 8 + +struct AudioEngineSoundBuffer { + bool active; + unsigned int size; + int bitsPerSample; + int channels; + int rate; + void* data; + int volume; + bool playing; + bool looping; + unsigned int pos; + SDL_AudioStream* stream; +}; + +extern bool gProgramIsActive; + +static bool soundBufferIsValid(int soundBufferIndex); +static void audioEngineMixin(void* userData, Uint8* stream, int length); + +static SDL_AudioSpec gAudioEngineSpec; +static SDL_AudioDeviceID gAudioEngineDeviceId = -1; +static AudioEngineSoundBuffer gAudioEngineSoundBuffers[AUDIO_ENGINE_SOUND_BUFFERS]; + +static bool soundBufferIsValid(int soundBufferIndex) +{ + return soundBufferIndex >= 0 && soundBufferIndex < AUDIO_ENGINE_SOUND_BUFFERS; +} + +static void audioEngineMixin(void* userData, Uint8* stream, int length) +{ + memset(stream, gAudioEngineSpec.silence, length); + + if (!gProgramIsActive) { + return; + } + + for (int index = 0; index < AUDIO_ENGINE_SOUND_BUFFERS; index++) { + AudioEngineSoundBuffer* soundBuffer = &(gAudioEngineSoundBuffers[index]); + if (soundBuffer->active && soundBuffer->playing) { + int srcFrameSize = soundBuffer->bitsPerSample / 8 * soundBuffer->channels; + + unsigned char buffer[1024]; + int pos = 0; + while (pos < length) { + int remaining = length - pos; + if (remaining > sizeof(buffer)) { + remaining = sizeof(buffer); + } + + // TODO: Make something better than frame-by-frame convertion. + SDL_AudioStreamPut(soundBuffer->stream, (unsigned char*)soundBuffer->data + soundBuffer->pos, srcFrameSize); + soundBuffer->pos += srcFrameSize; + + int bytesRead = SDL_AudioStreamGet(soundBuffer->stream, buffer, remaining); + if (bytesRead == -1) { + break; + } + + SDL_MixAudioFormat(stream + pos, buffer, gAudioEngineSpec.format, bytesRead, soundBuffer->volume); + + if (soundBuffer->pos >= soundBuffer->size) { + if (soundBuffer->looping) { + soundBuffer->pos %= soundBuffer->size; + } else { + soundBuffer->playing = false; + break; + } + } + + pos += bytesRead; + } + } + } +} + +bool audioEngineInit() +{ + if (SDL_InitSubSystem(SDL_INIT_AUDIO) == -1) { + return false; + } + + SDL_AudioSpec desiredSpec; + desiredSpec.freq = 22050; + desiredSpec.format = AUDIO_S16; + desiredSpec.channels = 2; + desiredSpec.samples = 1024; + desiredSpec.callback = audioEngineMixin; + + gAudioEngineDeviceId = SDL_OpenAudioDevice(NULL, 0, &desiredSpec, &gAudioEngineSpec, SDL_AUDIO_ALLOW_ANY_CHANGE); + if (gAudioEngineDeviceId == -1) { + return false; + } + + SDL_PauseAudioDevice(gAudioEngineDeviceId, 0); + + return true; +} + +void audioEngineExit() +{ + if (gAudioEngineDeviceId != -1) { + SDL_CloseAudioDevice(gAudioEngineDeviceId); + gAudioEngineDeviceId = -1; + } + + SDL_QuitSubSystem(SDL_INIT_AUDIO); +} + +void audioEnginePause() +{ + if (gAudioEngineDeviceId != -1) { + SDL_PauseAudioDevice(gAudioEngineDeviceId, 1); + } +} + +void audioEngineResume() +{ + if (gAudioEngineDeviceId != -1) { + SDL_PauseAudioDevice(gAudioEngineDeviceId, 0); + } +} + +int audioEngineCreateSoundBuffer(unsigned int size, int bitsPerSample, int channels, int rate) +{ + for (int index = 0; index < AUDIO_ENGINE_SOUND_BUFFERS; index++) { + AudioEngineSoundBuffer* soundBuffer = &(gAudioEngineSoundBuffers[index]); + if (!soundBuffer->active) { + soundBuffer->active = true; + soundBuffer->size = size; + soundBuffer->bitsPerSample = bitsPerSample; + soundBuffer->channels = channels; + soundBuffer->rate = rate; + soundBuffer->data = malloc(size); + soundBuffer->stream = SDL_NewAudioStream(bitsPerSample == 16 ? AUDIO_S16 : AUDIO_S8, channels, rate, gAudioEngineSpec.format, gAudioEngineSpec.channels, gAudioEngineSpec.freq); + return index; + } + } + + return -1; +} + +bool audioEngineSoundBufferRelease(int soundBufferIndex) +{ + if (!soundBufferIsValid(soundBufferIndex)) { + return false; + } + + AudioEngineSoundBuffer* soundBuffer = &(gAudioEngineSoundBuffers[soundBufferIndex]); + if (!soundBuffer->active) { + return false; + } + + free(soundBuffer->data); + SDL_FreeAudioStream(soundBuffer->stream); + memset(soundBuffer, 0, sizeof(*soundBuffer)); + + return true; +} + +bool audioEngineSoundBufferSetVolume(int soundBufferIndex, int volume) +{ + if (!soundBufferIsValid(soundBufferIndex)) { + return false; + } + + AudioEngineSoundBuffer* soundBuffer = &(gAudioEngineSoundBuffers[soundBufferIndex]); + if (!soundBuffer->active) { + return false; + } + + soundBuffer->volume = volume; + + return true; +} + +bool audioEngineSoundBufferGetVolume(int soundBufferIndex, int* volumePtr) +{ + if (!soundBufferIsValid(soundBufferIndex)) { + return false; + } + + AudioEngineSoundBuffer* soundBuffer = &(gAudioEngineSoundBuffers[soundBufferIndex]); + if (!soundBuffer->active) { + return false; + } + + *volumePtr = soundBuffer->volume; + + return true; +} + +bool audioEngineSoundBufferSetPan(int soundBufferIndex, int pan) +{ + if (!soundBufferIsValid(soundBufferIndex)) { + return false; + } + + AudioEngineSoundBuffer* soundBuffer = &(gAudioEngineSoundBuffers[soundBufferIndex]); + if (!soundBuffer->active) { + return false; + } + + // NOTE: Audio engine does not support sound panning. I'm not sure it's + // even needed. For now this value is silently ignored. + + return true; +} + +bool audioEngineSoundBufferPlay(int soundBufferIndex, unsigned int flags) +{ + if (!soundBufferIsValid(soundBufferIndex)) { + return false; + } + + AudioEngineSoundBuffer* soundBuffer = &(gAudioEngineSoundBuffers[soundBufferIndex]); + if (!soundBuffer->active) { + return false; + } + + soundBuffer->playing = true; + + if ((flags & AUDIO_ENGINE_SOUND_BUFFER_PLAY_LOOPING) != 0) { + soundBuffer->looping = true; + } + + return true; +} + +bool audioEngineSoundBufferStop(int soundBufferIndex) +{ + if (!soundBufferIsValid(soundBufferIndex)) { + return false; + } + + AudioEngineSoundBuffer* soundBuffer = &(gAudioEngineSoundBuffers[soundBufferIndex]); + if (!soundBuffer->active) { + return false; + } + + soundBuffer->playing = false; + + return true; +} + +bool audioEngineSoundBufferGetCurrentPosition(int soundBufferIndex, unsigned int* readPosPtr, unsigned int* writePosPtr) +{ + if (!soundBufferIsValid(soundBufferIndex)) { + return false; + } + + AudioEngineSoundBuffer* soundBuffer = &(gAudioEngineSoundBuffers[soundBufferIndex]); + if (!soundBuffer->active) { + return false; + } + + if (readPosPtr != NULL) { + *readPosPtr = soundBuffer->pos; + } + + if (writePosPtr != NULL) { + *writePosPtr = soundBuffer->pos; + + if (soundBuffer->playing) { + // 15 ms lead + // See: https://docs.microsoft.com/en-us/previous-versions/windows/desktop/mt708925(v=vs.85)#remarks + *writePosPtr += soundBuffer->rate / 150; + *writePosPtr %= soundBuffer->size; + } + } + + return true; +} + +bool audioEngineSoundBufferSetCurrentPosition(int soundBufferIndex, unsigned int pos) +{ + if (!soundBufferIsValid(soundBufferIndex)) { + return false; + } + + AudioEngineSoundBuffer* soundBuffer = &(gAudioEngineSoundBuffers[soundBufferIndex]); + if (!soundBuffer->active) { + return false; + } + + soundBuffer->pos = pos % soundBuffer->size; + + return true; +} + +bool audioEngineSoundBufferLock(int soundBufferIndex, unsigned int writePos, unsigned int writeBytes, void** audioPtr1, unsigned int* audioBytes1, void** audioPtr2, unsigned int* audioBytes2, unsigned int flags) +{ + if (!soundBufferIsValid(soundBufferIndex)) { + return false; + } + + AudioEngineSoundBuffer* soundBuffer = &(gAudioEngineSoundBuffers[soundBufferIndex]); + if (!soundBuffer->active) { + return false; + } + + if (audioBytes1 == NULL) { + return false; + } + + if ((flags & AUDIO_ENGINE_SOUND_BUFFER_LOCK_FROM_WRITE_POS) != 0) { + if (!audioEngineSoundBufferGetCurrentPosition(soundBufferIndex, NULL, &writePos)) { + return false; + } + } + + if ((flags & AUDIO_ENGINE_SOUND_BUFFER_LOCK_ENTIRE_BUFFER) != 0) { + writeBytes = soundBuffer->size; + } + + if (writePos + writeBytes <= soundBuffer->size) { + *(unsigned char**)audioPtr1 = (unsigned char*)soundBuffer->data + writePos; + *audioBytes1 = writeBytes; + + if (audioPtr2 != NULL) { + *audioPtr2 = NULL; + } + + if (audioBytes2 != NULL) { + *audioBytes2 = 0; + } + } else { + unsigned int remainder = writePos + writeBytes - soundBuffer->size; + *(unsigned char**)audioPtr1 = (unsigned char*)soundBuffer->data + writePos; + *audioBytes1 = soundBuffer->size - writePos; + + if (audioPtr2 != NULL) { + *(unsigned char**)audioPtr2 = (unsigned char*)soundBuffer->data; + } + + if (audioBytes2 != NULL) { + *audioBytes2 = writeBytes - (soundBuffer->size - writePos); + } + } + + // TODO: Mark range as locked. + + return true; +} + +bool audioEngineSoundBufferUnlock(int soundBufferIndex, void* audioPtr1, unsigned int audioBytes1, void* audioPtr2, unsigned int audioBytes2) +{ + if (!soundBufferIsValid(soundBufferIndex)) { + return false; + } + + AudioEngineSoundBuffer* soundBuffer = &(gAudioEngineSoundBuffers[soundBufferIndex]); + if (!soundBuffer->active) { + return false; + } + + // TODO: Mark range as unlocked. + + return true; +} + +bool audioEngineSoundBufferGetStatus(int soundBufferIndex, unsigned int* statusPtr) +{ + if (!soundBufferIsValid(soundBufferIndex)) { + return false; + } + + AudioEngineSoundBuffer* soundBuffer = &(gAudioEngineSoundBuffers[soundBufferIndex]); + if (!soundBuffer->active) { + return false; + } + + if (statusPtr == NULL) { + return false; + } + + *statusPtr = 0; + + if (soundBuffer->playing) { + *statusPtr |= AUDIO_ENGINE_SOUND_BUFFER_STATUS_PLAYING; + + if (soundBuffer->looping) { + *statusPtr |= AUDIO_ENGINE_SOUND_BUFFER_STATUS_LOOPING; + } + } + + return true; +} diff --git a/src/audio_engine.h b/src/audio_engine.h new file mode 100644 index 0000000..b8eb69e --- /dev/null +++ b/src/audio_engine.h @@ -0,0 +1,29 @@ +#ifndef AUDIO_ENGINE_H +#define AUDIO_ENGINE_H + +#define AUDIO_ENGINE_SOUND_BUFFER_LOCK_FROM_WRITE_POS 0x00000001 +#define AUDIO_ENGINE_SOUND_BUFFER_LOCK_ENTIRE_BUFFER 0x00000002 + +#define AUDIO_ENGINE_SOUND_BUFFER_PLAY_LOOPING 0x00000001 + +#define AUDIO_ENGINE_SOUND_BUFFER_STATUS_PLAYING 0x00000001 +#define AUDIO_ENGINE_SOUND_BUFFER_STATUS_LOOPING 0x00000004 + +bool audioEngineInit(); +void audioEngineExit(); +void audioEnginePause(); +void audioEngineResume(); +int audioEngineCreateSoundBuffer(unsigned int size, int bitsPerSample, int channels, int rate); +bool audioEngineSoundBufferRelease(int soundBufferIndex); +bool audioEngineSoundBufferSetVolume(int soundBufferIndex, int volume); +bool audioEngineSoundBufferGetVolume(int soundBufferIndex, int* volumePtr); +bool audioEngineSoundBufferSetPan(int soundBufferIndex, int pan); +bool audioEngineSoundBufferPlay(int soundBufferIndex, unsigned int flags); +bool audioEngineSoundBufferStop(int soundBufferIndex); +bool audioEngineSoundBufferGetCurrentPosition(int soundBufferIndex, unsigned int* readPosPtr, unsigned int* writePosPtr); +bool audioEngineSoundBufferSetCurrentPosition(int soundBufferIndex, unsigned int pos); +bool audioEngineSoundBufferLock(int soundBufferIndex, unsigned int writePos, unsigned int writeBytes, void** audioPtr1, unsigned int* audioBytes1, void** audioPtr2, unsigned int* audioBytes2, unsigned int flags); +bool audioEngineSoundBufferUnlock(int soundBufferIndex, void* audioPtr1, unsigned int audioBytes1, void* audioPtr2, unsigned int audioBytes2); +bool audioEngineSoundBufferGetStatus(int soundBufferIndex, unsigned int* status); + +#endif /* AUDIO_ENGINE_H */ diff --git a/src/core.cc b/src/core.cc index d90b12c..1ddaba4 100644 --- a/src/core.cc +++ b/src/core.cc @@ -1,5 +1,6 @@ #include "core.h" +#include "audio_engine.h" #include "config.h" #include "color.h" #include "dinput.h" @@ -15,9 +16,6 @@ #include #include #include -#if _WIN32 -#include -#endif // NOT USED. void (*_idle_func)() = NULL; @@ -1275,9 +1273,11 @@ void _GNW95_process_message() case SDL_WINDOWEVENT_FOCUS_GAINED: gProgramIsActive = true; windowRefreshAll(&_scr_size); + audioEngineResume(); break; case SDL_WINDOWEVENT_FOCUS_LOST: gProgramIsActive = false; + audioEnginePause(); break; } break; @@ -1974,7 +1974,7 @@ int _GNW95_init_mode_ex(int width, int height, int bpp) configFree(&resolutionConfig); } - if (_GNW95_init_window(width, height, fullscreen) == -1) { + if (_GNW95_init_window(width, height, false) == -1) { return -1; } @@ -2029,20 +2029,6 @@ int _GNW95_init_window(int width, int height, bool fullscreen) gSdlWindow = NULL; return -1; } - -#if _WIN32 - SDL_SysWMinfo info; - SDL_VERSION(&info.version); - - if (!SDL_GetWindowWMInfo(gSdlWindow, &info)) { - SDL_DestroyWindow(gSdlWindow); - gSdlWindow = NULL; - return -1; - } - - // Needed for DirectSound. - gProgramWindow = info.info.win.window; -#endif } return 0; diff --git a/src/dsound_compat.h b/src/dsound_compat.h deleted file mode 100644 index e484d60..0000000 --- a/src/dsound_compat.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef DSOUND_COMPAT_H -#define DSOUND_COMPAT_H - -#ifdef _WIN32 -#define HAVE_DSOUND 1 - -#define WIN32_LEAN_AND_MEAN -#define NOMINMAX -#include - -#include - -#define DIRECTSOUND_VERSION 0x0300 -#include -#endif - -#endif /* DSOUND_COMPAT_H */ diff --git a/src/movie.cc b/src/movie.cc index 5d67768..0ebec83 100644 --- a/src/movie.cc +++ b/src/movie.cc @@ -163,9 +163,6 @@ static int _movieX; // 0x638EB4 static int _movieY; -// 0x638EB8 -static bool gMovieDirectSoundInitialized; - // 0x638EBC static File* _alphaHandle; @@ -361,12 +358,6 @@ static int _noop() void movieInit() { movieLibSetMemoryProcs(movieMallocImpl, movieFreeImpl); -#ifdef HAVE_DSOUND - movieLibSetDirectSound(gDirectSound); - gMovieDirectSoundInitialized = (gDirectSound != NULL); -#else - gMovieDirectSoundInitialized = false; -#endif movieLibSetPaletteEntriesProc(movieSetPaletteEntriesImpl); _MVE_sfSVGA(640, 480, 480, 0, 0, 0, 0, 0, 0); movieLibSetReadProc(movieReadImpl); @@ -832,10 +823,8 @@ void movieSetBuildSubtitleFilePathProc(MovieBuildSubtitleFilePathProc* proc) // 0x487BD0 void movieSetVolume(int volume) { - if (gMovieDirectSoundInitialized) { - int normalizedVolume = _soundVolumeHMItoDirectSound(volume); - movieLibSetVolume(normalizedVolume); - } + int normalizedVolume = _soundVolumeHMItoDirectSound(volume); + movieLibSetVolume(normalizedVolume); } // 0x487BEC diff --git a/src/movie_lib.cc b/src/movie_lib.cc index df59d34..8aaffbc 100644 --- a/src/movie_lib.cc +++ b/src/movie_lib.cc @@ -4,6 +4,7 @@ #include "movie_lib.h" +#include "audio_engine.h" #include "platform_compat.h" #include @@ -146,16 +147,6 @@ static int _sync_late = 0; // 0x51EDEC static int _sync_FrameDropped = 0; -#ifdef HAVE_DSOUND -// 0x51EDF0 -static LPDIRECTSOUND gMovieLibDirectSound = NULL; -#endif - -#ifdef HAVE_DSOUND -// 0x51EDF4 -static LPDIRECTSOUNDBUFFER gMovieLibDirectSoundBuffer = NULL; -#endif - // 0x51EDF8 static int gMovieLibVolume = 0; @@ -348,11 +339,6 @@ static unsigned int _$$R0063[256] = { // 0x6B3660 static int dword_6B3660; -#ifdef HAVE_DSOUND -// 0x6B3668 -static DSBCAPS stru_6B3668; -#endif - // 0x6B367C static int _sf_ScreenWidth; @@ -520,6 +506,8 @@ static int dword_6B403F; static SDL_Surface* gMovieSdlSurface1; static SDL_Surface* gMovieSdlSurface2; +static int gMveSoundBuffer = -1; +static unsigned int gMveBufferBytes; // 0x4F4800 void movieLibSetMemoryProcs(MallocProc* mallocProc, FreeProc* freeProc) @@ -558,24 +546,14 @@ static void _MVE_MemFree(STRUCT_6B3690* a1) a1->field_4 = 0; } -#ifdef HAVE_DSOUND -// 0x4F48F0 -void movieLibSetDirectSound(LPDIRECTSOUND ds) -{ - gMovieLibDirectSound = ds; -} -#endif - // 0x4F4900 void movieLibSetVolume(int volume) { gMovieLibVolume = volume; -#ifdef HAVE_DSOUND - if (gMovieLibDirectSoundBuffer != NULL) { - IDirectSoundBuffer_SetVolume(gMovieLibDirectSoundBuffer, volume); + if (gMveSoundBuffer != -1) { + audioEngineSoundBufferSetVolume(gMveSoundBuffer, volume); } -#endif } // 0x4F4920 @@ -583,11 +561,9 @@ void movieLibSetPan(int pan) { gMovieLibPan = pan; -#ifdef HAVE_DSOUND - if (gMovieLibDirectSoundBuffer != NULL) { - IDirectSoundBuffer_SetPan(gMovieLibDirectSoundBuffer, pan); + if (gMveSoundBuffer != -1) { + audioEngineSoundBufferSetPan(gMveSoundBuffer, pan); } -#endif } // 0x4F4940 @@ -832,11 +808,9 @@ static int _syncWait() // 0x4F4EA0 static void _MVE_sndPause() { -#ifdef HAVE_DSOUND - if (gMovieLibDirectSoundBuffer != NULL) { - IDirectSoundBuffer_Stop(gMovieLibDirectSoundBuffer); + if (gMveSoundBuffer != -1) { + audioEngineSoundBufferStop(gMveSoundBuffer); } -#endif } // 0x4F4EC0 @@ -1151,55 +1125,28 @@ static void _syncReset(int a1) // 0x4F5570 static int _MVE_sndConfigure(int a1, int a2, int a3, int a4, int a5, int a6) { -#ifdef HAVE_DSOUND - DSBUFFERDESC dsbd; - WAVEFORMATEX wfxFormat; - - if (gMovieLibDirectSound == NULL) { - return 1; - } - _MVE_sndReset(); _snd_comp = a3; dword_6B36A0 = a5; _snd_buf = a6; - dsbd.dwSize = sizeof(DSBUFFERDESC); - dsbd.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME; - dsbd.dwBufferBytes = (a2 + (a2 >> 1)) & 0xFFFFFFFC; - dsbd.dwReserved = 0; - dsbd.lpwfxFormat = &wfxFormat; - - wfxFormat.wFormatTag = 1; - wfxFormat.nSamplesPerSec = a4; - wfxFormat.nChannels = 2 - (a3 < 1); - wfxFormat.nBlockAlign = wfxFormat.nChannels * (2 - (a5 < 1)); - wfxFormat.cbSize = 0; - wfxFormat.nAvgBytesPerSec = wfxFormat.nSamplesPerSec * wfxFormat.nBlockAlign; - wfxFormat.wBitsPerSample = a5 < 1 ? 8 : 16; + gMveBufferBytes = (a2 + (a2 >> 1)) & 0xFFFFFFFC; dword_6B3AE4 = 0; dword_6B3660 = 0; - if (IDirectSound_CreateSoundBuffer(gMovieLibDirectSound, &dsbd, &gMovieLibDirectSoundBuffer, NULL) != DS_OK) { + gMveSoundBuffer = audioEngineCreateSoundBuffer(gMveBufferBytes, a5 < 1 ? 8 : 16, 2 - (a3 < 1), a4); + if (gMveSoundBuffer == -1) { return 0; } - IDirectSoundBuffer_SetVolume(gMovieLibDirectSoundBuffer, gMovieLibVolume); - IDirectSoundBuffer_SetPan(gMovieLibDirectSoundBuffer, gMovieLibPan); + audioEngineSoundBufferSetVolume(gMveSoundBuffer, gMovieLibVolume); + audioEngineSoundBufferSetPan(gMveSoundBuffer, gMovieLibPan); dword_6B36A4 = 0; - stru_6B3668.dwSize = sizeof(DSBCAPS); - if (IDirectSoundBuffer_GetCaps(gMovieLibDirectSoundBuffer, &stru_6B3668) != DS_OK) { - return 0; - } - return 1; -#else - return 0; -#endif } // 0x4F56C0 @@ -1214,23 +1161,20 @@ static void _MVE_syncSync() // 0x4F56F0 static void _MVE_sndReset() { -#ifdef HAVE_DSOUND - if (gMovieLibDirectSoundBuffer != NULL) { - IDirectSoundBuffer_Stop(gMovieLibDirectSoundBuffer); - IDirectSoundBuffer_Release(gMovieLibDirectSoundBuffer); - gMovieLibDirectSoundBuffer = NULL; + if (gMveSoundBuffer != -1) { + audioEngineSoundBufferStop(gMveSoundBuffer); + audioEngineSoundBufferRelease(gMveSoundBuffer); + gMveSoundBuffer = -1; } -#endif } // 0x4F5720 static void _MVE_sndSync() { -#ifdef HAVE_DSOUND - DWORD dwCurrentPlayCursor; - DWORD dwCurrentWriteCursor; + unsigned int dwCurrentPlayCursor; + unsigned int dwCurrentWriteCursor; bool v10; - DWORD dwStatus; + unsigned int dwStatus; unsigned int v1; bool v2; int v3; @@ -1247,27 +1191,23 @@ static void _MVE_sndSync() _sync_late = _syncWaitLevel(_sync_wait_quanta >> 2) > -_sync_wait_quanta >> 1 && !_sync_FrameDropped; _sync_FrameDropped = 0; - if (gMovieLibDirectSound == NULL) { - return; - } - - if (gMovieLibDirectSoundBuffer == NULL) { + if (gMveSoundBuffer == -1) { return; } while (1) { - if (IDirectSoundBuffer_GetStatus(gMovieLibDirectSoundBuffer, &dwStatus) != DS_OK) { + if (!audioEngineSoundBufferGetStatus(gMveSoundBuffer, &dwStatus)) { return; } - if (IDirectSoundBuffer_GetCurrentPosition(gMovieLibDirectSoundBuffer, &dwCurrentPlayCursor, &dwCurrentWriteCursor) != DS_OK) { + if (!audioEngineSoundBufferGetCurrentPosition(gMveSoundBuffer, &dwCurrentPlayCursor, &dwCurrentWriteCursor)) { return; } dwCurrentWriteCursor = dword_6B36A4; - v1 = (stru_6B3668.dwBufferBytes + dword_6B39E0[dword_6B3660] - _gSoundTimeBase) - % stru_6B3668.dwBufferBytes; + v1 = (gMveBufferBytes + dword_6B39E0[dword_6B3660] - _gSoundTimeBase) + % gMveBufferBytes; if (dwCurrentPlayCursor <= dword_6B36A4) { if (v1 < dwCurrentPlayCursor || v1 >= dword_6B36A4) { @@ -1283,15 +1223,15 @@ static void _MVE_sndSync() } } - if (!v2 || !(dwStatus & DSBSTATUS_PLAYING)) { + if (!v2 || !(dwStatus & AUDIO_ENGINE_SOUND_BUFFER_STATUS_PLAYING)) { if (v0) { _syncReset(_sync_wait_quanta + (_sync_wait_quanta >> 2)); } v3 = dword_6B39E0[dword_6B3660]; - if (!(dwStatus & DSBSTATUS_PLAYING)) { - v4 = (stru_6B3668.dwBufferBytes + v3) % stru_6B3668.dwBufferBytes; + if (!(dwStatus & AUDIO_ENGINE_SOUND_BUFFER_STATUS_PLAYING)) { + v4 = (gMveBufferBytes + v3) % gMveBufferBytes; if (dwCurrentWriteCursor >= dwCurrentPlayCursor) { if (v4 >= dwCurrentPlayCursor && v4 < dwCurrentWriteCursor) { @@ -1306,11 +1246,11 @@ static void _MVE_sndSync() } if (v5) { - if (IDirectSoundBuffer_SetCurrentPosition(gMovieLibDirectSoundBuffer, v4) != DS_OK) { + if (!audioEngineSoundBufferSetCurrentPosition(gMveSoundBuffer, v4)) { return; } - if (IDirectSoundBuffer_Play(gMovieLibDirectSoundBuffer, 0, 0, 1) != DS_OK) { + if (!audioEngineSoundBufferPlay(gMveSoundBuffer, 1)) { return; } } @@ -1318,20 +1258,20 @@ static void _MVE_sndSync() break; } - v6 = (stru_6B3668.dwBufferBytes + _gSoundTimeBase + v3) % stru_6B3668.dwBufferBytes; + v6 = (gMveBufferBytes + _gSoundTimeBase + v3) % gMveBufferBytes; v7 = dwCurrentWriteCursor - dwCurrentPlayCursor; if (((dwCurrentWriteCursor - dwCurrentPlayCursor) & 0x80000000) != 0) { - v7 += stru_6B3668.dwBufferBytes; + v7 += gMveBufferBytes; } - v8 = stru_6B3668.dwBufferBytes - v7 - 1; + v8 = gMveBufferBytes - v7 - 1; // NOTE: Original code uses signed comparison. - if ((int)stru_6B3668.dwBufferBytes / 2 < v8) { - v8 = stru_6B3668.dwBufferBytes >> 1; + if ((int)gMveBufferBytes / 2 < v8) { + v8 = gMveBufferBytes >> 1; } - v9 = (stru_6B3668.dwBufferBytes + dwCurrentPlayCursor - v8) % stru_6B3668.dwBufferBytes; + v9 = (gMveBufferBytes + dwCurrentPlayCursor - v8) % gMveBufferBytes; dwCurrentPlayCursor = v9; @@ -1350,7 +1290,7 @@ static void _MVE_sndSync() } if (!v10) { - IDirectSoundBuffer_Stop(gMovieLibDirectSoundBuffer); + audioEngineSoundBufferStop(gMveSoundBuffer); } break; @@ -1365,10 +1305,6 @@ static void _MVE_sndSync() ++dword_6B3660; } } -#else - _sync_late = _syncWaitLevel(_sync_wait_quanta >> 2) > -_sync_wait_quanta >> 1 && !_sync_FrameDropped; - _sync_FrameDropped = 0; -#endif } // 0x4F59B0 @@ -1394,20 +1330,19 @@ static int _syncWaitLevel(int a1) // 0x4F5A00 static void _CallsSndBuff_Loc(unsigned char* a1, int a2) { -#ifdef HAVE_DSOUND int v2; int v3; int v5; - DWORD dwCurrentPlayCursor; - DWORD dwCurrentWriteCursor; - LPVOID lpvAudioPtr1; - DWORD dwAudioBytes1; - LPVOID lpvAudioPtr2; - DWORD dwAudioBytes2; + unsigned int dwCurrentPlayCursor; + unsigned int dwCurrentWriteCursor; + void* lpvAudioPtr1; + unsigned int dwAudioBytes1; + void* lpvAudioPtr2; + unsigned int dwAudioBytes2; _gSoundTimeBase = a2; - if (gMovieLibDirectSoundBuffer == NULL) { + if (gMveSoundBuffer == -1) { return; } @@ -1420,13 +1355,13 @@ static void _CallsSndBuff_Loc(unsigned char* a1, int a2) return; } - if (IDirectSoundBuffer_GetCurrentPosition(gMovieLibDirectSoundBuffer, &dwCurrentPlayCursor, &dwCurrentWriteCursor) != DS_OK) { + if (!audioEngineSoundBufferGetCurrentPosition(gMveSoundBuffer, &dwCurrentPlayCursor, &dwCurrentWriteCursor)) { return; } dwCurrentWriteCursor = dword_6B36A4; - if (IDirectSoundBuffer_Lock(gMovieLibDirectSoundBuffer, dword_6B36A4, a2, &lpvAudioPtr1, &dwAudioBytes1, &lpvAudioPtr2, &dwAudioBytes2, 0) != DS_OK) { + if (!audioEngineSoundBufferLock(gMveSoundBuffer, dword_6B36A4, a2, &lpvAudioPtr1, &dwAudioBytes1, &lpvAudioPtr2, &dwAudioBytes2, 0)) { return; } @@ -1443,11 +1378,11 @@ static void _CallsSndBuff_Loc(unsigned char* a1, int a2) dword_6B36A4 = dwAudioBytes2; } - if (dword_6B36A4 == stru_6B3668.dwBufferBytes) { + if (dword_6B36A4 == gMveBufferBytes) { dword_6B36A4 = 0; } - IDirectSoundBuffer_Unlock(gMovieLibDirectSoundBuffer, lpvAudioPtr1, dwAudioBytes1, lpvAudioPtr2, dwAudioBytes2); + audioEngineSoundBufferUnlock(gMveSoundBuffer, lpvAudioPtr1, dwAudioBytes1, lpvAudioPtr2, dwAudioBytes2); dword_6B39E0[dword_6B3AE4] = dwCurrentWriteCursor; @@ -1456,7 +1391,6 @@ static void _CallsSndBuff_Loc(unsigned char* a1, int a2) } else { ++dword_6B3AE4; } -#endif } // 0x4F5B70 diff --git a/src/movie_lib.h b/src/movie_lib.h index c701557..9fe8b64 100644 --- a/src/movie_lib.h +++ b/src/movie_lib.h @@ -1,7 +1,6 @@ #ifndef MOVIE_LIB_H #define MOVIE_LIB_H -#include "dsound_compat.h" #include "memory_defs.h" #include @@ -11,9 +10,6 @@ typedef void(MovieShowFrameProc)(SDL_Surface*, int, int, int, int, int, int, int void movieLibSetMemoryProcs(MallocProc* mallocProc, FreeProc* freeProc); void movieLibSetReadProc(MovieReadProc* readProc); -#ifdef HAVE_DSOUND -void movieLibSetDirectSound(LPDIRECTSOUND ds); -#endif void movieLibSetVolume(int volume); void movieLibSetPan(int pan); void _MVE_sfSVGA(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9); diff --git a/src/sound.cc b/src/sound.cc index 07fc52b..5a8bc59 100644 --- a/src/sound.cc +++ b/src/sound.cc @@ -1,5 +1,6 @@ #include "sound.h" +#include "audio_engine.h" #include "debug.h" #include "platform_compat.h" @@ -11,14 +12,13 @@ #endif #include #include -#ifdef HAVE_DSOUND -#include -#endif #include #include #include +#include + #define SOUND_FLAG_SOUND_IS_PLAYING (0x02) #define SOUND_FLAG_SOUND_IS_PAUSED (0x08) @@ -47,10 +47,8 @@ static int _soundSetData(Sound* sound, unsigned char* buf, int size); static int soundContinue(Sound* sound); static int _soundGetVolume(Sound* sound); static void soundDeleteInternal(Sound* sound); -#ifdef HAVE_DSOUND -static void CALLBACK _doTimerEvent(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2); -static void _removeTimedEvent(unsigned int* timerId); -#endif +static Uint32 _doTimerEvent(Uint32 interval, void* param); +static void _removeTimedEvent(SDL_TimerID* timerId); static void _removeFadeSound(STRUCT_51D478* a1); static void _fadeSounds(); static int _internalSoundFade(Sound* sound, int a2, int a3, int a4); @@ -61,9 +59,6 @@ static STRUCT_51D478* _fadeHead = NULL; // 0x51D47C static STRUCT_51D478* _fadeFreeList = NULL; -// 0x51D480 -static unsigned int _fadeEventHandle = UINT_MAX; - // 0x51D488 static MallocProc* gSoundMallocProc = soundMallocProcDefaultImpl; @@ -123,7 +118,6 @@ static const char* gSoundErrorDescriptions[SOUND_ERR_COUNT] = { "sound.c: invalid handle", "sound.c: no memory available", "sound.c: unknown error", - "sound.c: not implemented", }; // 0x668150 @@ -132,11 +126,6 @@ static int gSoundLastError; // 0x668154 static int _masterVol; -#ifdef HAVE_DSOUND -// 0x668158 -static LPDIRECTSOUNDBUFFER gDirectSoundPrimaryBuffer; -#endif - // 0x66815C static int _sampleRate; @@ -160,10 +149,7 @@ static bool gSoundInitialized; // 0x668174 static Sound* gSoundListHead; -#ifdef HAVE_DSOUND -// 0x668178 -LPDIRECTSOUND gDirectSound; -#endif +static SDL_TimerID gFadeSoundsTimerId = 0; // 0x4AC6F0 void* soundMallocProcDefaultImpl(size_t size) @@ -214,15 +200,14 @@ const char* soundGetErrorDescription(int err) // 0x4AC7B0 void _refreshSoundBuffers(Sound* sound) { -#ifdef HAVE_DSOUND if (sound->field_3C & 0x80) { return; } - DWORD readPos; - DWORD writePos; - HRESULT hr = IDirectSoundBuffer_GetCurrentPosition(sound->directSoundBuffer, &readPos, &writePos); - if (hr != DS_OK) { + unsigned int readPos; + unsigned int writePos; + bool hr = audioEngineSoundBufferGetCurrentPosition(sound->soundBuffer, &readPos, &writePos); + if (!hr) { return; } @@ -273,17 +258,12 @@ void _refreshSoundBuffers(Sound* sound) return; } - VOID* audioPtr1; - VOID* audioPtr2; - DWORD audioBytes1; - DWORD audioBytes2; - hr = IDirectSoundBuffer_Lock(sound->directSoundBuffer, sound->field_7C * sound->field_70, sound->field_7C * v53, &audioPtr1, &audioBytes1, &audioPtr2, &audioBytes2, 0); - if (hr == DSERR_BUFFERLOST) { - IDirectSoundBuffer_Restore(sound->directSoundBuffer); - hr = IDirectSoundBuffer_Lock(sound->directSoundBuffer, sound->field_7C * sound->field_70, sound->field_7C * v53, &audioPtr1, &audioBytes1, &audioPtr2, &audioBytes2, 0); - } - - if (hr != DS_OK) { + void* audioPtr1; + 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); + if (!hr) { return; } @@ -384,166 +364,44 @@ void _refreshSoundBuffers(Sound* sound) } } - IDirectSoundBuffer_Unlock(sound->directSoundBuffer, audioPtr1, audioBytes1, audioPtr2, audioBytes2); + audioEngineSoundBufferUnlock(sound->soundBuffer, audioPtr1, audioBytes1, audioPtr2, audioBytes2); sound->field_70 = v6; - - return; -#endif } // 0x4ACC58 int soundInit(int a1, int a2, int a3, int a4, int rate) { -#ifdef HAVE_DSOUND - HRESULT hr; - DWORD v24; + if (!audioEngineInit()) { + debugPrint("soundInit: Unable to init audio engine\n"); - if (gDirectSoundCreateProc(0, &gDirectSound, 0) != DS_OK) { - gDirectSound = NULL; gSoundLastError = SOUND_SOS_DETECTION_FAILURE; return gSoundLastError; } - if (IDirectSound_SetCooperativeLevel(gDirectSound, gProgramWindow, DSSCL_EXCLUSIVE) != DS_OK) { - gSoundLastError = SOUND_UNKNOWN_ERROR; - return gSoundLastError; - } - _sampleRate = rate; _dataSize = a4; _numBuffers = a2; gSoundInitialized = true; _deviceInit = 1; - DSBUFFERDESC dsbdesc; - memset(&dsbdesc, 0, sizeof(dsbdesc)); - dsbdesc.dwSize = sizeof(dsbdesc); - dsbdesc.dwFlags = DSCAPS_PRIMARYMONO; - dsbdesc.dwBufferBytes = 0; - - hr = IDirectSound_CreateSoundBuffer(gDirectSound, &dsbdesc, &gDirectSoundPrimaryBuffer, NULL); - if (hr != DS_OK) { - switch (hr) { - case DSERR_ALLOCATED: - debugPrint("%s:%s\n", "CreateSoundBuffer", "DSERR_ALLOCATED"); - break; - case DSERR_BADFORMAT: - debugPrint("%s:%s\n", "CreateSoundBuffer", "DSERR_BADFORMAT"); - break; - case DSERR_INVALIDPARAM: - debugPrint("%s:%s\n", "CreateSoundBuffer", "DSERR_INVALIDPARAM"); - break; - case DSERR_NOAGGREGATION: - debugPrint("%s:%s\n", "CreateSoundBuffer", "DSERR_NOAGGREGATION"); - break; - case DSERR_OUTOFMEMORY: - debugPrint("%s:%s\n", "CreateSoundBuffer", "DSERR_OUTOFMEMORY"); - break; - case DSERR_UNINITIALIZED: - debugPrint("%s:%s\n", "CreateSoundBuffer", "DSERR_UNINITIALIZED"); - break; - case DSERR_UNSUPPORTED: - debugPrint("%s:%s\n", "CreateSoundBuffer", "DSERR_UNSUPPORTED"); - break; - } - - exit(1); - } - - WAVEFORMATEX pcmwf; - memset(&pcmwf, 0, sizeof(pcmwf)); - - DSCAPS dscaps; - memset(&dscaps, 0, sizeof(dscaps)); - dscaps.dwSize = sizeof(dscaps); - - hr = IDirectSound_GetCaps(gDirectSound, &dscaps); - if (hr != DS_OK) { - debugPrint("soundInit: Error getting primary buffer parameters\n"); - goto out; - } - - pcmwf.nSamplesPerSec = rate; - pcmwf.wFormatTag = WAVE_FORMAT_PCM; - - if (dscaps.dwFlags & DSCAPS_PRIMARY16BIT) { - pcmwf.wBitsPerSample = 16; - } else { - pcmwf.wBitsPerSample = 8; - } - - pcmwf.nChannels = (dscaps.dwFlags & DSCAPS_PRIMARYSTEREO) ? 2 : 1; - pcmwf.nBlockAlign = pcmwf.wBitsPerSample * pcmwf.nChannels / 8; - pcmwf.nSamplesPerSec = rate; - pcmwf.cbSize = 0; - pcmwf.nAvgBytesPerSec = pcmwf.nBlockAlign * rate; - - debugPrint("soundInit: Setting primary buffer to: %d bit, %d channels, %d rate\n", pcmwf.wBitsPerSample, pcmwf.nChannels, rate); - hr = IDirectSoundBuffer_SetFormat(gDirectSoundPrimaryBuffer, &pcmwf); - if (hr != DS_OK) { - debugPrint("soundInit: Couldn't change rate to %d\n", rate); - - switch (hr) { - case DSERR_BADFORMAT: - debugPrint("%s:%s\n", "SetFormat", "DSERR_BADFORMAT"); - break; - case DSERR_INVALIDCALL: - debugPrint("%s:%s\n", "SetFormat", "DSERR_INVALIDCALL"); - break; - case DSERR_INVALIDPARAM: - debugPrint("%s:%s\n", "SetFormat", "DSERR_INVALIDPARAM"); - break; - case DSERR_OUTOFMEMORY: - debugPrint("%s:%s\n", "SetFormat", "DSERR_OUTOFMEMORY"); - break; - case DSERR_PRIOLEVELNEEDED: - debugPrint("%s:%s\n", "SetFormat", "DSERR_PRIOLEVELNEEDED"); - break; - case DSERR_UNSUPPORTED: - debugPrint("%s:%s\n", "SetFormat", "DSERR_UNSUPPORTED"); - break; - } - - goto out; - } - - hr = IDirectSoundBuffer_GetFormat(gDirectSoundPrimaryBuffer, &pcmwf, sizeof(WAVEFORMATEX), &v24); - if (hr != DS_OK) { - debugPrint("soundInit: Couldn't read new settings\n"); - goto out; - } - - debugPrint("soundInit: Primary buffer settings set to: %d bit, %d channels, %d rate\n", pcmwf.wBitsPerSample, pcmwf.nChannels, pcmwf.nSamplesPerSec); - - if (dscaps.dwFlags & DSCAPS_EMULDRIVER) { - debugPrint("soundInit: using DirectSound emulated drivers\n"); - } - -out: - _soundSetMasterVolume(VOLUME_MAX); - gSoundLastError = SOUND_NO_ERROR; - return 0; -#else - gSoundLastError = SOUND_NOT_IMPLEMENTED; + gSoundLastError = SOUND_NO_ERROR; return gSoundLastError; -#endif } // 0x4AD04C void soundExit() { -#ifdef HAVE_DSOUND while (gSoundListHead != NULL) { Sound* next = gSoundListHead->next; soundDelete(gSoundListHead); gSoundListHead = next; } - if (_fadeEventHandle != -1) { - _removeTimedEvent(&_fadeEventHandle); + if (gFadeSoundsTimerId != 0) { + _removeTimedEvent(&gFadeSoundsTimerId); } while (_fadeFreeList != NULL) { @@ -552,25 +410,15 @@ void soundExit() _fadeFreeList = next; } - if (gDirectSoundPrimaryBuffer != NULL) { - IDirectSoundBuffer_Release(gDirectSoundPrimaryBuffer); - gDirectSoundPrimaryBuffer = NULL; - } - - if (gDirectSound != NULL) { - IDirectSound_Release(gDirectSound); - gDirectSound = NULL; - } + audioEngineExit(); gSoundLastError = SOUND_NO_ERROR; gSoundInitialized = false; -#endif } // 0x4AD0FC Sound* soundAllocate(int a1, int a2) { -#ifdef HAVE_DSOUND if (!gSoundInitialized) { gSoundLastError = SOUND_NOT_INITIALIZED; return NULL; @@ -581,51 +429,23 @@ Sound* soundAllocate(int a1, int a2) memcpy(&(sound->io), &gSoundDefaultFileIO, sizeof(gSoundDefaultFileIO)); - WAVEFORMATEX* wfxFormat = (WAVEFORMATEX*)gSoundMallocProc(sizeof(*wfxFormat)); - memset(wfxFormat, 0, sizeof(*wfxFormat)); - - wfxFormat->wFormatTag = 1; - wfxFormat->nChannels = 1; - - if (a2 & 0x08) { - wfxFormat->wBitsPerSample = 16; - } else { - wfxFormat->wBitsPerSample = 8; - } - if (!(a2 & 0x02)) { a2 |= 0x02; } - wfxFormat->nSamplesPerSec = _sampleRate; - wfxFormat->nBlockAlign = wfxFormat->nChannels * (wfxFormat->wBitsPerSample / 8); - wfxFormat->cbSize = 0; - wfxFormat->nAvgBytesPerSec = wfxFormat->nBlockAlign * wfxFormat->nSamplesPerSec; + sound->bitsPerSample = (a2 & 0x08) != 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->directSoundBuffer = 0; + sound->soundBuffer = -1; sound->field_40 = 0; - sound->directSoundBufferDescription.dwSize = sizeof(DSBUFFERDESC); - sound->directSoundBufferDescription.dwFlags = DSBCAPS_GETCURRENTPOSITION2; sound->field_78 = _numBuffers; sound->readLimit = sound->field_7C * _numBuffers; - if (a2 & 0x2) { - sound->directSoundBufferDescription.dwFlags |= DSBCAPS_CTRLVOLUME; - } - - if (a2 & 0x4) { - sound->directSoundBufferDescription.dwFlags |= DSBCAPS_CTRLPAN; - } - - if (a2 & 0x40) { - sound->directSoundBufferDescription.dwFlags |= DSBCAPS_CTRLFREQUENCY; - } - - sound->directSoundBufferDescription.lpwfxFormat = wfxFormat; if (a1 & 0x10) { sound->field_50 = -1; @@ -646,10 +466,6 @@ Sound* soundAllocate(int a1, int a2) gSoundListHead = sound; return sound; -#else - gSoundLastError = SOUND_NOT_IMPLEMENTED; - return NULL; -#endif } // 0x4AD308 @@ -742,15 +558,14 @@ int soundLoad(Sound* sound, char* filePath) // 0x4AD504 int _soundRewind(Sound* sound) { -#ifdef HAVE_DSOUND - HRESULT hr; + bool hr; if (!gSoundInitialized) { gSoundLastError = SOUND_NOT_INITIALIZED; return gSoundLastError; } - if (sound == NULL || sound->directSoundBuffer == NULL) { + if (sound == NULL || sound->soundBuffer == -1) { gSoundLastError = SOUND_NO_SOUND; return gSoundLastError; } @@ -761,13 +576,13 @@ int _soundRewind(Sound* sound) sound->field_74 = 0; sound->field_64 = 0; sound->field_3C &= 0xFD7F; - hr = IDirectSoundBuffer_SetCurrentPosition(sound->directSoundBuffer, 0); + hr = audioEngineSoundBufferSetCurrentPosition(sound->soundBuffer, 0); _preloadBuffers(sound); } else { - hr = IDirectSoundBuffer_SetCurrentPosition(sound->directSoundBuffer, 0); + hr = audioEngineSoundBufferSetCurrentPosition(sound->soundBuffer, 0); } - if (hr != DS_OK) { + if (!hr) { gSoundLastError = SOUND_UNKNOWN_ERROR; return gSoundLastError; } @@ -776,57 +591,42 @@ int _soundRewind(Sound* sound) gSoundLastError = SOUND_NO_ERROR; return gSoundLastError; -#else - gSoundLastError = SOUND_NOT_IMPLEMENTED; - return gSoundLastError; -#endif } // 0x4AD5C8 int _addSoundData(Sound* sound, unsigned char* buf, int size) { -#ifdef HAVE_DSOUND - HRESULT hr; - void* audio_ptr_1; - DWORD audio_bytes_1; - void* audio_ptr_2; - DWORD audio_bytes_2; + bool hr; + void* audioPtr1; + unsigned int audioBytes1; + void* audioPtr2; + unsigned int audioBytes2; - hr = IDirectSoundBuffer_Lock(sound->directSoundBuffer, 0, size, &audio_ptr_1, &audio_bytes_1, &audio_ptr_2, &audio_bytes_2, DSBLOCK_FROMWRITECURSOR); - if (hr == DSERR_BUFFERLOST) { - IDirectSoundBuffer_Restore(sound->directSoundBuffer); - hr = IDirectSoundBuffer_Lock(sound->directSoundBuffer, 0, size, &audio_ptr_1, &audio_bytes_1, &audio_ptr_2, &audio_bytes_2, DSBLOCK_FROMWRITECURSOR); - } - - if (hr != DS_OK) { + hr = audioEngineSoundBufferLock(sound->soundBuffer, 0, size, &audioPtr1, &audioBytes1, &audioPtr2, &audioBytes2, AUDIO_ENGINE_SOUND_BUFFER_LOCK_FROM_WRITE_POS); + if (!hr) { gSoundLastError = SOUND_UNKNOWN_ERROR; return gSoundLastError; } - memcpy(audio_ptr_1, buf, audio_bytes_1); + memcpy(audioPtr1, buf, audioBytes1); - if (audio_ptr_2 != NULL) { - memcpy(audio_ptr_2, buf + audio_bytes_1, audio_bytes_2); + if (audioPtr2 != NULL) { + memcpy(audioPtr2, buf + audioBytes1, audioBytes2); } - hr = IDirectSoundBuffer_Unlock(sound->directSoundBuffer, audio_ptr_1, audio_bytes_1, audio_ptr_2, audio_bytes_2); - if (hr != DS_OK) { + hr = audioEngineSoundBufferUnlock(sound->soundBuffer, audioPtr1, audioBytes1, audioPtr2, audioBytes2); + if (!hr) { gSoundLastError = SOUND_UNKNOWN_ERROR; return gSoundLastError; } gSoundLastError = SOUND_NO_ERROR; return gSoundLastError; -#else - gSoundLastError = SOUND_NOT_IMPLEMENTED; - return gSoundLastError; -#endif } // 0x4AD6C0 int _soundSetData(Sound* sound, unsigned char* buf, int size) { -#ifdef HAVE_DSOUND if (!gSoundInitialized) { gSoundLastError = SOUND_NOT_INITIALIZED; return gSoundLastError; @@ -837,36 +637,30 @@ int _soundSetData(Sound* sound, unsigned char* buf, int size) return gSoundLastError; } - if (sound->directSoundBuffer == NULL) { - sound->directSoundBufferDescription.dwBufferBytes = size; - - if (IDirectSound_CreateSoundBuffer(gDirectSound, &(sound->directSoundBufferDescription), &(sound->directSoundBuffer), NULL) != DS_OK) { + if (sound->soundBuffer == -1) { + sound->soundBuffer = audioEngineCreateSoundBuffer(size, sound->bitsPerSample, sound->channels, sound->rate); + if (sound->soundBuffer == -1) { gSoundLastError = SOUND_UNKNOWN_ERROR; return gSoundLastError; } } return _addSoundData(sound, buf, size); -#else - gSoundLastError = SOUND_NOT_IMPLEMENTED; - return gSoundLastError; -#endif } // 0x4AD73C int soundPlay(Sound* sound) { -#ifdef HAVE_DSOUND - HRESULT hr; - DWORD readPos; - DWORD writePos; + bool hr; + unsigned int readPos; + unsigned int writePos; if (!gSoundInitialized) { gSoundLastError = SOUND_NOT_INITIALIZED; return gSoundLastError; } - if (sound == NULL || sound->directSoundBuffer == NULL) { + if (sound == NULL || sound->soundBuffer == -1) { gSoundLastError = SOUND_NO_SOUND; return gSoundLastError; } @@ -878,12 +672,12 @@ int soundPlay(Sound* sound) soundSetVolume(sound, sound->volume); - hr = IDirectSoundBuffer_Play(sound->directSoundBuffer, 0, 0, sound->field_3C & 0x20 ? DSBPLAY_LOOPING : 0); + hr = audioEngineSoundBufferPlay(sound->soundBuffer, sound->field_3C & 0x20 ? AUDIO_ENGINE_SOUND_BUFFER_PLAY_LOOPING : 0); - IDirectSoundBuffer_GetCurrentPosition(sound->directSoundBuffer, &readPos, &writePos); + audioEngineSoundBufferGetCurrentPosition(sound->soundBuffer, &readPos, &writePos); sound->field_70 = readPos / sound->field_7C; - if (hr != DS_OK) { + if (!hr) { gSoundLastError = SOUND_UNKNOWN_ERROR; return gSoundLastError; } @@ -894,24 +688,19 @@ int soundPlay(Sound* sound) gSoundLastError = SOUND_NO_ERROR; return gSoundLastError; -#else - gSoundLastError = SOUND_NOT_IMPLEMENTED; - return gSoundLastError; -#endif } // 0x4AD828 int soundStop(Sound* sound) { -#ifdef HAVE_DSOUND - HRESULT hr; + bool hr; if (!gSoundInitialized) { gSoundLastError = SOUND_NOT_INITIALIZED; return gSoundLastError; } - if (sound == NULL || sound->directSoundBuffer == NULL) { + if (sound == NULL || sound->soundBuffer == -1) { gSoundLastError = SOUND_NO_SOUND; return gSoundLastError; } @@ -921,8 +710,8 @@ int soundStop(Sound* sound) return gSoundLastError; } - hr = IDirectSoundBuffer_Stop(sound->directSoundBuffer); - if (hr != DS_OK) { + hr = audioEngineSoundBufferStop(sound->soundBuffer); + if (!hr) { gSoundLastError = SOUND_UNKNOWN_ERROR; return gSoundLastError; } @@ -932,10 +721,6 @@ int soundStop(Sound* sound) gSoundLastError = SOUND_NO_ERROR; return gSoundLastError; -#else - gSoundLastError = SOUND_NOT_IMPLEMENTED; - return gSoundLastError; -#endif } // 0x4AD8DC @@ -965,9 +750,8 @@ int soundDelete(Sound* sample) // 0x4AD948 int soundContinue(Sound* sound) { -#ifdef HAVE_DSOUND - HRESULT hr; - DWORD status; + bool hr; + unsigned int status; if (!gSoundInitialized) { gSoundLastError = SOUND_NOT_INITIALIZED; @@ -979,7 +763,7 @@ int soundContinue(Sound* sound) return gSoundLastError; } - if (sound->directSoundBuffer == NULL) { + if (sound->soundBuffer == -1) { gSoundLastError = SOUND_NO_SOUND; return gSoundLastError; } @@ -994,15 +778,15 @@ int soundContinue(Sound* sound) return gSoundLastError; } - hr = IDirectSoundBuffer_GetStatus(sound->directSoundBuffer, &status); - if (hr != DS_OK) { + hr = audioEngineSoundBufferGetStatus(sound->soundBuffer, &status); + if (!hr) { debugPrint("Error in soundContinue, %x\n", hr); gSoundLastError = SOUND_UNKNOWN_ERROR; return gSoundLastError; } - if (!(sound->field_3C & 0x80) && (status & (DSBSTATUS_PLAYING | DSBSTATUS_LOOPING))) { + 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)) { _refreshSoundBuffers(sound); } @@ -1030,111 +814,86 @@ int soundContinue(Sound* sound) gSoundLastError = SOUND_NO_ERROR; return gSoundLastError; -#else - gSoundLastError = SOUND_NOT_IMPLEMENTED; - return gSoundLastError; -#endif } // 0x4ADA84 bool soundIsPlaying(Sound* sound) { -#ifdef HAVE_DSOUND if (!gSoundInitialized) { gSoundLastError = SOUND_NOT_INITIALIZED; return false; } - if (sound == NULL || sound->directSoundBuffer == 0) { + if (sound == NULL || sound->soundBuffer == -1) { gSoundLastError = SOUND_NO_SOUND; return false; } return (sound->field_40 & SOUND_FLAG_SOUND_IS_PLAYING) != 0; -#else - gSoundLastError = SOUND_NOT_IMPLEMENTED; - return false; -#endif } // 0x4ADAC4 bool _soundDone(Sound* sound) { -#ifdef HAVE_DSOUND if (!gSoundInitialized) { gSoundLastError = SOUND_NOT_INITIALIZED; return false; } - if (sound == NULL || sound->directSoundBuffer == 0) { + if (sound == NULL || sound->soundBuffer == -1) { gSoundLastError = SOUND_NO_SOUND; return false; } return sound->field_40 & 1; -#else - gSoundLastError = SOUND_NOT_IMPLEMENTED; - return false; -#endif } // 0x4ADB44 bool soundIsPaused(Sound* sound) { -#ifdef HAVE_DSOUND if (!gSoundInitialized) { gSoundLastError = SOUND_NOT_INITIALIZED; return false; } - if (sound == NULL || sound->directSoundBuffer == NULL) { + if (sound == NULL || sound->soundBuffer == -1) { gSoundLastError = SOUND_NO_SOUND; return false; } return (sound->field_40 & SOUND_FLAG_SOUND_IS_PAUSED) != 0; -#else - gSoundLastError = SOUND_NOT_IMPLEMENTED; - return false; -#endif } // 0x4ADBC4 int _soundType(Sound* sound, int a2) { -#ifdef HAVE_DSOUND if (!gSoundInitialized) { gSoundLastError = SOUND_NOT_INITIALIZED; return 0; } - if (sound == NULL || sound->directSoundBuffer == NULL) { + if (sound == NULL || sound->soundBuffer == -1) { gSoundLastError = SOUND_NO_SOUND; return 0; } return sound->field_44 & a2; -#else - gSoundLastError = SOUND_NOT_IMPLEMENTED; - return 0; -#endif } // 0x4ADC04 int soundGetDuration(Sound* sound) { -#ifdef HAVE_DSOUND if (!gSoundInitialized) { gSoundLastError = SOUND_NOT_INITIALIZED; return gSoundLastError; } - if (sound == NULL || sound->directSoundBuffer == NULL) { + if (sound == NULL || sound->soundBuffer == -1) { gSoundLastError = SOUND_NO_SOUND; return gSoundLastError; } - int bytesPerSec = sound->directSoundBufferDescription.lpwfxFormat->nAvgBytesPerSec; + int bytesPerSec = sound->bitsPerSample / 8 * sound->rate; int v3 = sound->field_60; int v4 = v3 % bytesPerSec; int result = v3 / bytesPerSec; @@ -1143,10 +902,6 @@ int soundGetDuration(Sound* sound) } return result; -#else - gSoundLastError = SOUND_NOT_IMPLEMENTED; - return gSoundLastError; -#endif } // 0x4ADD00 @@ -1176,8 +931,6 @@ int soundSetLooping(Sound* sound, int a2) return gSoundLastError; } -// Normalize volume? -// // 0x4ADD68 int _soundVolumeHMItoDirectSound(int volume) { @@ -1187,12 +940,8 @@ int _soundVolumeHMItoDirectSound(int volume) volume = VOLUME_MAX; } - if (volume != 0) { - normalizedVolume = -1000.0 * log2(32767.0 / volume); - normalizedVolume = std::clamp(normalizedVolume, -10000.0, 0.0); - } else { - normalizedVolume = -10000.0; - } + // Normalize volume to SDL (0-128). + normalizedVolume = (double)(volume - VOLUME_MIN) / (double)(VOLUME_MAX - VOLUME_MIN) * 128; return (int)normalizedVolume; } @@ -1200,9 +949,8 @@ int _soundVolumeHMItoDirectSound(int volume) // 0x4ADE0C int soundSetVolume(Sound* sound, int volume) { -#ifdef HAVE_DSOUND int normalizedVolume; - HRESULT hr; + bool hr; if (!gSoundInitialized) { gSoundLastError = SOUND_NOT_INITIALIZED; @@ -1216,67 +964,37 @@ int soundSetVolume(Sound* sound, int volume) sound->volume = volume; - if (sound->directSoundBuffer == NULL) { + if (sound->soundBuffer == -1) { gSoundLastError = SOUND_NO_ERROR; return gSoundLastError; } normalizedVolume = _soundVolumeHMItoDirectSound(_masterVol * volume / VOLUME_MAX); - hr = IDirectSoundBuffer_SetVolume(sound->directSoundBuffer, normalizedVolume); - if (hr != DS_OK) { + hr = audioEngineSoundBufferSetVolume(sound->soundBuffer, normalizedVolume); + if (!hr) { gSoundLastError = SOUND_UNKNOWN_ERROR; return gSoundLastError; } gSoundLastError = SOUND_NO_ERROR; return gSoundLastError; -#else - gSoundLastError = SOUND_NOT_IMPLEMENTED; - return gSoundLastError; -#endif } // 0x4ADE80 int _soundGetVolume(Sound* sound) { -#ifdef HAVE_DSOUND - long volume; - int v13; - int v8; - int diff; - if (!_deviceInit) { gSoundLastError = SOUND_NOT_INITIALIZED; return gSoundLastError; } - if (sound == NULL || sound->directSoundBuffer == NULL) { + if (sound == NULL || sound->soundBuffer == -1) { gSoundLastError = SOUND_NO_SOUND; return gSoundLastError; } - IDirectSoundBuffer_GetVolume(sound->directSoundBuffer, &volume); - - if (volume == -10000) { - v13 = 0; - } else { - // TODO: Check. - volume = -volume; - v13 = (int)(32767.0 / pow(2.0, (volume * 0.001))); - } - - v8 = VOLUME_MAX * v13 / _masterVol; - diff = abs(v8 - sound->volume); - if (diff > 20) { - debugPrint("Actual sound volume differs significantly from noted volume actual %x stored %x, diff %d.", v8, sound->volume, diff); - } - return sound->volume; -#else - gSoundLastError = SOUND_NOT_IMPLEMENTED; - return gSoundLastError; -#endif } // 0x4ADFF0 @@ -1302,9 +1020,6 @@ int soundSetCallback(Sound* sound, SoundCallback* callback, void* userData) // 0x4AE02C int soundSetChannels(Sound* sound, int channels) { -#ifdef HAVE_DSOUND - LPWAVEFORMATEX format; - if (!gSoundInitialized) { gSoundLastError = SOUND_NOT_INITIALIZED; return gSoundLastError; @@ -1316,19 +1031,11 @@ int soundSetChannels(Sound* sound, int channels) } if (channels == 3) { - format = sound->directSoundBufferDescription.lpwfxFormat; - - format->nBlockAlign = (2 * format->wBitsPerSample) / 8; - format->nChannels = 2; - format->nAvgBytesPerSec = format->nBlockAlign * _sampleRate; + sound->channels = 2; } gSoundLastError = SOUND_NO_ERROR; return gSoundLastError; -#else - gSoundLastError = SOUND_NOT_IMPLEMENTED; - return gSoundLastError; -#endif } // 0x4AE0B0 @@ -1355,10 +1062,9 @@ int soundSetReadLimit(Sound* sound, int readLimit) // 0x4AE0E4 int soundPause(Sound* sound) { -#ifdef HAVE_DSOUND - HRESULT hr; - DWORD readPos; - DWORD writePos; + bool hr; + unsigned int readPos; + unsigned int writePos; if (!gSoundInitialized) { gSoundLastError = SOUND_NOT_INITIALIZED; @@ -1370,7 +1076,7 @@ int soundPause(Sound* sound) return gSoundLastError; } - if (sound->directSoundBuffer == NULL) { + if (sound->soundBuffer == -1) { gSoundLastError = SOUND_NO_SOUND; return gSoundLastError; } @@ -1385,8 +1091,8 @@ int soundPause(Sound* sound) return gSoundLastError; } - hr = IDirectSoundBuffer_GetCurrentPosition(sound->directSoundBuffer, &readPos, &writePos); - if (hr != DS_OK) { + hr = audioEngineSoundBufferGetCurrentPosition(sound->soundBuffer, &readPos, &writePos); + if (!hr) { gSoundLastError = SOUND_UNKNOWN_ERROR; return gSoundLastError; } @@ -1395,10 +1101,6 @@ int soundPause(Sound* sound) sound->field_40 |= SOUND_FLAG_SOUND_IS_PAUSED; return soundStop(sound); -#else - gSoundLastError = SOUND_NOT_IMPLEMENTED; - return gSoundLastError; -#endif } // TODO: Check, looks like it uses couple of inlined functions. @@ -1406,15 +1108,14 @@ int soundPause(Sound* sound) // 0x4AE1F0 int soundResume(Sound* sound) { -#ifdef HAVE_DSOUND - HRESULT hr; + bool hr; if (!gSoundInitialized) { gSoundLastError = SOUND_NOT_INITIALIZED; return gSoundLastError; } - if (sound == NULL || sound->directSoundBuffer == NULL) { + if (sound == NULL || sound->soundBuffer == -1) { gSoundLastError = SOUND_NO_SOUND; return gSoundLastError; } @@ -1429,8 +1130,8 @@ int soundResume(Sound* sound) return gSoundLastError; } - hr = IDirectSoundBuffer_SetCurrentPosition(sound->directSoundBuffer, sound->field_48); - if (hr != DS_OK) { + hr = audioEngineSoundBufferSetCurrentPosition(sound->soundBuffer, sound->field_48); + if (!hr) { gSoundLastError = SOUND_UNKNOWN_ERROR; return gSoundLastError; } @@ -1439,10 +1140,6 @@ int soundResume(Sound* sound) sound->field_48 = 0; return soundPlay(sound); -#else - gSoundLastError = SOUND_NOT_IMPLEMENTED; - return gSoundLastError; -#endif } // 0x4AE2FC @@ -1493,7 +1190,6 @@ int soundSetFileIO(Sound* sound, SoundOpenProc* openProc, SoundCloseProc* closeP // 0x4AE378 void soundDeleteInternal(Sound* sound) { -#ifdef HAVE_DSOUND STRUCT_51D478* curr; Sound* v10; Sound* v11; @@ -1512,7 +1208,7 @@ void soundDeleteInternal(Sound* sound) _removeFadeSound(curr); } - if (sound->directSoundBuffer != NULL) { + if (sound->soundBuffer != -1) { // NOTE: Uninline. if (!soundIsPlaying(sound)) { soundStop(sound); @@ -1522,8 +1218,8 @@ void soundDeleteInternal(Sound* sound) sound->callback(sound->callbackUserData, 1); } - IDirectSoundBuffer_Release(sound->directSoundBuffer); - sound->directSoundBuffer = NULL; + audioEngineSoundBufferRelease(sound->soundBuffer); + sound->soundBuffer = -1; } if (sound->field_90 != NULL) { @@ -1535,10 +1231,6 @@ void soundDeleteInternal(Sound* sound) sound->field_20 = NULL; } - if (sound->directSoundBufferDescription.lpwfxFormat != NULL) { - gSoundFreeProc(sound->directSoundBufferDescription.lpwfxFormat); - } - v10 = sound->next; if (v10 != NULL) { v10->prev = sound->prev; @@ -1552,7 +1244,6 @@ void soundDeleteInternal(Sound* sound) } gSoundFreeProc(sound); -#endif } // 0x4AE578 @@ -1575,32 +1266,31 @@ int _soundSetMasterVolume(int volume) return gSoundLastError; } -#ifdef HAVE_DSOUND // 0x4AE5C8 -void CALLBACK _doTimerEvent(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2) +Uint32 _doTimerEvent(Uint32 interval, void* param) { void (*fn)(); - if (dwUser != 0) { - fn = (void (*)())dwUser; + if (param != NULL) { + fn = (void (*)())param; fn(); } + + return 40; } // 0x4AE614 -void _removeTimedEvent(unsigned int* timerId) +void _removeTimedEvent(SDL_TimerID* timerId) { - if (*timerId != -1) { - timeKillEvent(*timerId); - *timerId = -1; + if (*timerId != 0) { + SDL_RemoveTimer(*timerId); + *timerId = 0; } } -#endif // 0x4AE634 int _soundGetPosition(Sound* sound) { -#ifdef HAVE_DSOUND if (!gSoundInitialized) { gSoundLastError = SOUND_NOT_INITIALIZED; return gSoundLastError; @@ -1611,9 +1301,9 @@ int _soundGetPosition(Sound* sound) return gSoundLastError; } - DWORD playPos; - DWORD writePos; - IDirectSoundBuffer_GetCurrentPosition(sound->directSoundBuffer, &playPos, &writePos); + unsigned int playPos; + unsigned int writePos; + audioEngineSoundBufferGetCurrentPosition(sound->soundBuffer, &playPos, &writePos); if ((sound->field_44 & 0x02) != 0) { if (playPos < sound->field_74) { @@ -1624,16 +1314,11 @@ int _soundGetPosition(Sound* sound) } return playPos; -#else - gSoundLastError = SOUND_NOT_IMPLEMENTED; - return gSoundLastError; -#endif } // 0x4AE6CC int _soundSetPosition(Sound* sound, int a2) { -#ifdef HAVE_DSOUND if (!gSoundInitialized) { gSoundLastError = SOUND_NOT_INITIALIZED; return gSoundLastError; @@ -1644,7 +1329,7 @@ int _soundSetPosition(Sound* sound, int a2) return gSoundLastError; } - if (sound->directSoundBuffer == NULL) { + if (sound->soundBuffer == -1) { gSoundLastError = SOUND_NO_SOUND; return gSoundLastError; } @@ -1652,7 +1337,7 @@ int _soundSetPosition(Sound* sound, int a2) if (sound->field_44 & 0x02) { int v6 = a2 / sound->field_7C % sound->field_78; - IDirectSoundBuffer_SetCurrentPosition(sound->directSoundBuffer, v6 * sound->field_7C + a2 % sound->field_7C); + audioEngineSoundBufferSetCurrentPosition(sound->soundBuffer, v6 * sound->field_7C + a2 % sound->field_7C); 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); @@ -1676,15 +1361,11 @@ int _soundSetPosition(Sound* sound, int a2) soundContinue(sound); } else { - IDirectSoundBuffer_SetCurrentPosition(sound->directSoundBuffer, a2); + audioEngineSoundBufferSetCurrentPosition(sound->soundBuffer, a2); } gSoundLastError = SOUND_NO_ERROR; return gSoundLastError; -#else - gSoundLastError = SOUND_NOT_IMPLEMENTED; - return gSoundLastError; -#endif } // 0x4AE830 @@ -1760,18 +1441,15 @@ void _fadeSounds() } } -#ifdef HAVE_DSOUND - if (_fadeHead == NULL && _fadeEventHandle != -1) { - timeKillEvent(_fadeEventHandle); - _fadeEventHandle = -1; + if (_fadeHead == NULL) { + // NOTE: Uninline. + _removeTimedEvent(&gFadeSoundsTimerId); } -#endif } // 0x4AE988 int _internalSoundFade(Sound* sound, int a2, int a3, int a4) { -#ifdef HAVE_DSOUND STRUCT_51D478* ptr; if (!_deviceInit) { @@ -1832,7 +1510,7 @@ int _internalSoundFade(Sound* sound, int a2, int a3, int a4) bool v14; if (gSoundInitialized) { - if (sound->directSoundBuffer != NULL) { + if (sound->soundBuffer != -1) { v14 = (sound->field_40 & 0x02) == 0; } else { gSoundLastError = SOUND_NO_SOUND; @@ -1847,23 +1525,19 @@ int _internalSoundFade(Sound* sound, int a2, int a3, int a4) soundPlay(sound); } - if (_fadeEventHandle != -1) { + if (gFadeSoundsTimerId != 0) { gSoundLastError = SOUND_NO_ERROR; return gSoundLastError; } - _fadeEventHandle = timeSetEvent(40, 10, _doTimerEvent, (DWORD_PTR)_fadeSounds, 1); - if (_fadeEventHandle == 0) { + gFadeSoundsTimerId = SDL_AddTimer(40, _doTimerEvent, (void*)_fadeSounds); + if (gFadeSoundsTimerId == 0) { gSoundLastError = SOUND_UNKNOWN_ERROR; return gSoundLastError; } gSoundLastError = SOUND_NO_ERROR; return gSoundLastError; -#else - gSoundLastError = SOUND_NOT_IMPLEMENTED; - return gSoundLastError; -#endif } // 0x4AEB0C diff --git a/src/sound.h b/src/sound.h index 3672e7e..6917cc0 100644 --- a/src/sound.h +++ b/src/sound.h @@ -41,8 +41,6 @@ typedef enum SoundError { SOUND_INVALID_HANDLE = 30, SOUND_NO_MEMORY_AVAILABLE = 31, SOUND_UNKNOWN_ERROR = 32, - // TODO: Remove once DirectX -> SDL transition is completed. - SOUND_NOT_IMPLEMENTED = 33, SOUND_ERR_COUNT, } SoundError; @@ -70,10 +68,10 @@ typedef void SoundCallback(void* userData, int a2); typedef struct Sound { SoundFileIO io; unsigned char* field_20; -#ifdef HAVE_DSOUND - LPDIRECTSOUNDBUFFER directSoundBuffer; - DSBUFFERDESC directSoundBufferDescription; -#endif + int soundBuffer; + int bitsPerSample; + int channels; + int rate; int field_3C; // flags int field_40; @@ -91,9 +89,7 @@ typedef struct Sound { int field_68; int readLimit; int field_70; -#ifdef HAVE_DSOUND - DWORD field_74; -#endif + unsigned int field_74; int field_78; int field_7C; int field_80; @@ -106,10 +102,6 @@ typedef struct Sound { struct Sound* prev; } Sound; -#ifdef HAVE_DSOUND -extern LPDIRECTSOUND gDirectSound; -#endif - 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); diff --git a/src/win32.cc b/src/win32.cc index 298d88a..95d79ff 100644 --- a/src/win32.cc +++ b/src/win32.cc @@ -8,77 +8,26 @@ #include #ifdef _WIN32 -#ifdef HAVE_DSOUND -// 0x51E430 -DirectSoundCreateProc* gDirectSoundCreateProc = NULL; -#endif - -// 0x51E434 -HWND gProgramWindow = NULL; - // 0x51E444 bool gProgramIsActive = false; // GNW95MUTEX HANDLE _GNW95_mutex = NULL; -#ifdef HAVE_DSOUND -// 0x51E454 -HMODULE gDSoundDLL = NULL; -#endif - // 0x4DE700 int main(int argc, char* argv[]) { _GNW95_mutex = CreateMutexA(0, TRUE, "GNW95MUTEX"); if (GetLastError() == ERROR_SUCCESS) { SDL_ShowCursor(SDL_DISABLE); - if (_LoadDirectX()) { - gProgramIsActive = true; - falloutMain(argc, argv); - } + + gProgramIsActive = true; + falloutMain(argc, argv); + CloseHandle(_GNW95_mutex); } return 0; } - -// 0x4DE8D0 -bool _LoadDirectX() -{ -#ifdef HAVE_DSOUND - gDSoundDLL = LoadLibraryA("DSOUND.DLL"); - if (gDSoundDLL == NULL) { - goto err; - } - - gDirectSoundCreateProc = (DirectSoundCreateProc*)GetProcAddress(gDSoundDLL, "DirectSoundCreate"); - if (gDirectSoundCreateProc == NULL) { - goto err; - } -#endif - - atexit(_UnloadDirectX); - - return true; - -err: - _UnloadDirectX(); - - SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Could not load DirectX", "This program requires DirectX 3.0a or later.", NULL); - - return false; -} - -// 0x4DE988 -void _UnloadDirectX(void) -{ -#ifdef HAVE_DSOUND - if (gDSoundDLL != NULL) { - FreeLibrary(gDSoundDLL); - gDSoundDLL = NULL; - } -#endif -} #else bool gProgramIsActive = false; diff --git a/src/win32.h b/src/win32.h index 3d0bf6d..f152cf2 100644 --- a/src/win32.h +++ b/src/win32.h @@ -1,28 +1,13 @@ #ifndef WIN32_H #define WIN32_H -#include "dsound_compat.h" - #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN #define NOMINMAX #include -#ifdef HAVE_DSOUND -typedef HRESULT(__stdcall DirectSoundCreateProc)(GUID*, LPDIRECTSOUND*, IUnknown*); -#endif - -#ifdef HAVE_DSOUND -extern DirectSoundCreateProc* gDirectSoundCreateProc; -#endif -extern HWND gProgramWindow; extern bool gProgramIsActive; extern HANDLE _GNW95_mutex; -#ifdef HAVE_DSOUND -extern HMODULE gDSoundDLL; -#endif -bool _LoadDirectX(); -void _UnloadDirectX(void); #else extern bool gProgramIsActive; #endif