Migrate sound to SDL (#70)
This commit is contained in:
parent
bbfd7785b5
commit
07d1f9fd81
|
@ -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"
|
||||
|
|
|
@ -0,0 +1,432 @@
|
|||
#include "audio_engine.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#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;
|
||||
std::recursive_mutex mutex;
|
||||
};
|
||||
|
||||
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]);
|
||||
std::lock_guard<std::recursive_mutex> lock(soundBuffer->mutex);
|
||||
|
||||
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]);
|
||||
std::lock_guard<std::recursive_mutex> lock(soundBuffer->mutex);
|
||||
|
||||
if (!soundBuffer->active) {
|
||||
soundBuffer->active = true;
|
||||
soundBuffer->size = size;
|
||||
soundBuffer->bitsPerSample = bitsPerSample;
|
||||
soundBuffer->channels = channels;
|
||||
soundBuffer->rate = rate;
|
||||
soundBuffer->volume = SDL_MIX_MAXVOLUME;
|
||||
soundBuffer->playing = false;
|
||||
soundBuffer->looping = false;
|
||||
soundBuffer->pos = 0;
|
||||
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]);
|
||||
std::lock_guard<std::recursive_mutex> lock(soundBuffer->mutex);
|
||||
|
||||
if (!soundBuffer->active) {
|
||||
return false;
|
||||
}
|
||||
|
||||
soundBuffer->active = false;
|
||||
|
||||
free(soundBuffer->data);
|
||||
soundBuffer->data = NULL;
|
||||
|
||||
SDL_FreeAudioStream(soundBuffer->stream);
|
||||
soundBuffer->stream = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool audioEngineSoundBufferSetVolume(int soundBufferIndex, int volume)
|
||||
{
|
||||
if (!soundBufferIsValid(soundBufferIndex)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
AudioEngineSoundBuffer* soundBuffer = &(gAudioEngineSoundBuffers[soundBufferIndex]);
|
||||
std::lock_guard<std::recursive_mutex> lock(soundBuffer->mutex);
|
||||
|
||||
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]);
|
||||
std::lock_guard<std::recursive_mutex> lock(soundBuffer->mutex);
|
||||
|
||||
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]);
|
||||
std::lock_guard<std::recursive_mutex> lock(soundBuffer->mutex);
|
||||
|
||||
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]);
|
||||
std::lock_guard<std::recursive_mutex> lock(soundBuffer->mutex);
|
||||
|
||||
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]);
|
||||
std::lock_guard<std::recursive_mutex> lock(soundBuffer->mutex);
|
||||
|
||||
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]);
|
||||
std::lock_guard<std::recursive_mutex> lock(soundBuffer->mutex);
|
||||
|
||||
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]);
|
||||
std::lock_guard<std::recursive_mutex> lock(soundBuffer->mutex);
|
||||
|
||||
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]);
|
||||
std::lock_guard<std::recursive_mutex> lock(soundBuffer->mutex);
|
||||
|
||||
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]);
|
||||
std::lock_guard<std::recursive_mutex> lock(soundBuffer->mutex);
|
||||
|
||||
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]);
|
||||
std::lock_guard<std::recursive_mutex> lock(soundBuffer->mutex);
|
||||
|
||||
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;
|
||||
}
|
|
@ -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 */
|
18
src/core.cc
18
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 <limits.h>
|
||||
#include <string.h>
|
||||
#include <SDL.h>
|
||||
#if _WIN32
|
||||
#include <SDL_syswm.h>
|
||||
#endif
|
||||
|
||||
// NOT USED.
|
||||
void (*_idle_func)() = NULL;
|
||||
|
@ -1276,9 +1274,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;
|
||||
|
@ -2055,18 +2055,6 @@ int _GNW95_init_window(int width, int height, bool fullscreen)
|
|||
if (gSdlTextureSurface == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
#if _WIN32
|
||||
SDL_SysWMinfo info;
|
||||
SDL_VERSION(&info.version);
|
||||
|
||||
if (!SDL_GetWindowWMInfo(gSdlWindow, &info)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
// Needed for DirectSound.
|
||||
gProgramWindow = info.info.win.window;
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -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 <windows.h>
|
||||
|
||||
#include <mmreg.h>
|
||||
|
||||
#define DIRECTSOUND_VERSION 0x0300
|
||||
#include <dsound.h>
|
||||
#endif
|
||||
|
||||
#endif /* DSOUND_COMPAT_H */
|
11
src/movie.cc
11
src/movie.cc
|
@ -163,9 +163,6 @@ static int _movieX;
|
|||
// 0x638EB4
|
||||
static int _movieY;
|
||||
|
||||
// 0x638EB8
|
||||
static bool gMovieDirectSoundInitialized;
|
||||
|
||||
// 0x638EBC
|
||||
static File* _alphaHandle;
|
||||
|
||||
|
@ -364,12 +361,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);
|
||||
|
@ -835,11 +826,9 @@ void movieSetBuildSubtitleFilePathProc(MovieBuildSubtitleFilePathProc* proc)
|
|||
// 0x487BD0
|
||||
void movieSetVolume(int volume)
|
||||
{
|
||||
if (gMovieDirectSoundInitialized) {
|
||||
int normalizedVolume = _soundVolumeHMItoDirectSound(volume);
|
||||
movieLibSetVolume(normalizedVolume);
|
||||
}
|
||||
}
|
||||
|
||||
// 0x487BEC
|
||||
void _movieUpdate()
|
||||
|
|
164
src/movie_lib.cc
164
src/movie_lib.cc
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include "movie_lib.h"
|
||||
|
||||
#include "audio_engine.h"
|
||||
#include "platform_compat.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
@ -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
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#ifndef MOVIE_LIB_H
|
||||
#define MOVIE_LIB_H
|
||||
|
||||
#include "dsound_compat.h"
|
||||
#include "memory_defs.h"
|
||||
|
||||
#include <SDL.h>
|
||||
|
@ -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);
|
||||
|
|
552
src/sound.cc
552
src/sound.cc
File diff suppressed because it is too large
Load Diff
18
src/sound.h
18
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);
|
||||
|
|
55
src/win32.cc
55
src/win32.cc
|
@ -8,77 +8,26 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
|
|
15
src/win32.h
15
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 <windows.h>
|
||||
|
||||
#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
|
||||
|
|
Loading…
Reference in New Issue