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
|
target_sources(${EXECUTABLE_NAME} PUBLIC
|
||||||
"src/dsound_compat.h"
|
"src/audio_engine.cc"
|
||||||
|
"src/audio_engine.h"
|
||||||
"src/fps_limiter.cc"
|
"src/fps_limiter.cc"
|
||||||
"src/fps_limiter.h"
|
"src/fps_limiter.h"
|
||||||
"src/platform_compat.cc"
|
"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 "core.h"
|
||||||
|
|
||||||
|
#include "audio_engine.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "color.h"
|
#include "color.h"
|
||||||
#include "dinput.h"
|
#include "dinput.h"
|
||||||
|
@ -15,9 +16,6 @@
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
#if _WIN32
|
|
||||||
#include <SDL_syswm.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// NOT USED.
|
// NOT USED.
|
||||||
void (*_idle_func)() = NULL;
|
void (*_idle_func)() = NULL;
|
||||||
|
@ -1276,9 +1274,11 @@ void _GNW95_process_message()
|
||||||
case SDL_WINDOWEVENT_FOCUS_GAINED:
|
case SDL_WINDOWEVENT_FOCUS_GAINED:
|
||||||
gProgramIsActive = true;
|
gProgramIsActive = true;
|
||||||
windowRefreshAll(&_scr_size);
|
windowRefreshAll(&_scr_size);
|
||||||
|
audioEngineResume();
|
||||||
break;
|
break;
|
||||||
case SDL_WINDOWEVENT_FOCUS_LOST:
|
case SDL_WINDOWEVENT_FOCUS_LOST:
|
||||||
gProgramIsActive = false;
|
gProgramIsActive = false;
|
||||||
|
audioEnginePause();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -2055,18 +2055,6 @@ int _GNW95_init_window(int width, int height, bool fullscreen)
|
||||||
if (gSdlTextureSurface == NULL) {
|
if (gSdlTextureSurface == NULL) {
|
||||||
goto err;
|
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;
|
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
|
// 0x638EB4
|
||||||
static int _movieY;
|
static int _movieY;
|
||||||
|
|
||||||
// 0x638EB8
|
|
||||||
static bool gMovieDirectSoundInitialized;
|
|
||||||
|
|
||||||
// 0x638EBC
|
// 0x638EBC
|
||||||
static File* _alphaHandle;
|
static File* _alphaHandle;
|
||||||
|
|
||||||
|
@ -364,12 +361,6 @@ static int _noop()
|
||||||
void movieInit()
|
void movieInit()
|
||||||
{
|
{
|
||||||
movieLibSetMemoryProcs(movieMallocImpl, movieFreeImpl);
|
movieLibSetMemoryProcs(movieMallocImpl, movieFreeImpl);
|
||||||
#ifdef HAVE_DSOUND
|
|
||||||
movieLibSetDirectSound(gDirectSound);
|
|
||||||
gMovieDirectSoundInitialized = (gDirectSound != NULL);
|
|
||||||
#else
|
|
||||||
gMovieDirectSoundInitialized = false;
|
|
||||||
#endif
|
|
||||||
movieLibSetPaletteEntriesProc(movieSetPaletteEntriesImpl);
|
movieLibSetPaletteEntriesProc(movieSetPaletteEntriesImpl);
|
||||||
_MVE_sfSVGA(640, 480, 480, 0, 0, 0, 0, 0, 0);
|
_MVE_sfSVGA(640, 480, 480, 0, 0, 0, 0, 0, 0);
|
||||||
movieLibSetReadProc(movieReadImpl);
|
movieLibSetReadProc(movieReadImpl);
|
||||||
|
@ -835,10 +826,8 @@ void movieSetBuildSubtitleFilePathProc(MovieBuildSubtitleFilePathProc* proc)
|
||||||
// 0x487BD0
|
// 0x487BD0
|
||||||
void movieSetVolume(int volume)
|
void movieSetVolume(int volume)
|
||||||
{
|
{
|
||||||
if (gMovieDirectSoundInitialized) {
|
|
||||||
int normalizedVolume = _soundVolumeHMItoDirectSound(volume);
|
int normalizedVolume = _soundVolumeHMItoDirectSound(volume);
|
||||||
movieLibSetVolume(normalizedVolume);
|
movieLibSetVolume(normalizedVolume);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x487BEC
|
// 0x487BEC
|
||||||
|
|
164
src/movie_lib.cc
164
src/movie_lib.cc
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include "movie_lib.h"
|
#include "movie_lib.h"
|
||||||
|
|
||||||
|
#include "audio_engine.h"
|
||||||
#include "platform_compat.h"
|
#include "platform_compat.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
@ -146,16 +147,6 @@ static int _sync_late = 0;
|
||||||
// 0x51EDEC
|
// 0x51EDEC
|
||||||
static int _sync_FrameDropped = 0;
|
static int _sync_FrameDropped = 0;
|
||||||
|
|
||||||
#ifdef HAVE_DSOUND
|
|
||||||
// 0x51EDF0
|
|
||||||
static LPDIRECTSOUND gMovieLibDirectSound = NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_DSOUND
|
|
||||||
// 0x51EDF4
|
|
||||||
static LPDIRECTSOUNDBUFFER gMovieLibDirectSoundBuffer = NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// 0x51EDF8
|
// 0x51EDF8
|
||||||
static int gMovieLibVolume = 0;
|
static int gMovieLibVolume = 0;
|
||||||
|
|
||||||
|
@ -348,11 +339,6 @@ static unsigned int _$$R0063[256] = {
|
||||||
// 0x6B3660
|
// 0x6B3660
|
||||||
static int dword_6B3660;
|
static int dword_6B3660;
|
||||||
|
|
||||||
#ifdef HAVE_DSOUND
|
|
||||||
// 0x6B3668
|
|
||||||
static DSBCAPS stru_6B3668;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// 0x6B367C
|
// 0x6B367C
|
||||||
static int _sf_ScreenWidth;
|
static int _sf_ScreenWidth;
|
||||||
|
|
||||||
|
@ -520,6 +506,8 @@ static int dword_6B403F;
|
||||||
|
|
||||||
static SDL_Surface* gMovieSdlSurface1;
|
static SDL_Surface* gMovieSdlSurface1;
|
||||||
static SDL_Surface* gMovieSdlSurface2;
|
static SDL_Surface* gMovieSdlSurface2;
|
||||||
|
static int gMveSoundBuffer = -1;
|
||||||
|
static unsigned int gMveBufferBytes;
|
||||||
|
|
||||||
// 0x4F4800
|
// 0x4F4800
|
||||||
void movieLibSetMemoryProcs(MallocProc* mallocProc, FreeProc* freeProc)
|
void movieLibSetMemoryProcs(MallocProc* mallocProc, FreeProc* freeProc)
|
||||||
|
@ -558,24 +546,14 @@ static void _MVE_MemFree(STRUCT_6B3690* a1)
|
||||||
a1->field_4 = 0;
|
a1->field_4 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_DSOUND
|
|
||||||
// 0x4F48F0
|
|
||||||
void movieLibSetDirectSound(LPDIRECTSOUND ds)
|
|
||||||
{
|
|
||||||
gMovieLibDirectSound = ds;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// 0x4F4900
|
// 0x4F4900
|
||||||
void movieLibSetVolume(int volume)
|
void movieLibSetVolume(int volume)
|
||||||
{
|
{
|
||||||
gMovieLibVolume = volume;
|
gMovieLibVolume = volume;
|
||||||
|
|
||||||
#ifdef HAVE_DSOUND
|
if (gMveSoundBuffer != -1) {
|
||||||
if (gMovieLibDirectSoundBuffer != NULL) {
|
audioEngineSoundBufferSetVolume(gMveSoundBuffer, volume);
|
||||||
IDirectSoundBuffer_SetVolume(gMovieLibDirectSoundBuffer, volume);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x4F4920
|
// 0x4F4920
|
||||||
|
@ -583,11 +561,9 @@ void movieLibSetPan(int pan)
|
||||||
{
|
{
|
||||||
gMovieLibPan = pan;
|
gMovieLibPan = pan;
|
||||||
|
|
||||||
#ifdef HAVE_DSOUND
|
if (gMveSoundBuffer != -1) {
|
||||||
if (gMovieLibDirectSoundBuffer != NULL) {
|
audioEngineSoundBufferSetPan(gMveSoundBuffer, pan);
|
||||||
IDirectSoundBuffer_SetPan(gMovieLibDirectSoundBuffer, pan);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x4F4940
|
// 0x4F4940
|
||||||
|
@ -832,11 +808,9 @@ static int _syncWait()
|
||||||
// 0x4F4EA0
|
// 0x4F4EA0
|
||||||
static void _MVE_sndPause()
|
static void _MVE_sndPause()
|
||||||
{
|
{
|
||||||
#ifdef HAVE_DSOUND
|
if (gMveSoundBuffer != -1) {
|
||||||
if (gMovieLibDirectSoundBuffer != NULL) {
|
audioEngineSoundBufferStop(gMveSoundBuffer);
|
||||||
IDirectSoundBuffer_Stop(gMovieLibDirectSoundBuffer);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x4F4EC0
|
// 0x4F4EC0
|
||||||
|
@ -1151,55 +1125,28 @@ static void _syncReset(int a1)
|
||||||
// 0x4F5570
|
// 0x4F5570
|
||||||
static int _MVE_sndConfigure(int a1, int a2, int a3, int a4, int a5, int a6)
|
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();
|
_MVE_sndReset();
|
||||||
|
|
||||||
_snd_comp = a3;
|
_snd_comp = a3;
|
||||||
dword_6B36A0 = a5;
|
dword_6B36A0 = a5;
|
||||||
_snd_buf = a6;
|
_snd_buf = a6;
|
||||||
|
|
||||||
dsbd.dwSize = sizeof(DSBUFFERDESC);
|
gMveBufferBytes = (a2 + (a2 >> 1)) & 0xFFFFFFFC;
|
||||||
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;
|
|
||||||
|
|
||||||
dword_6B3AE4 = 0;
|
dword_6B3AE4 = 0;
|
||||||
dword_6B3660 = 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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
IDirectSoundBuffer_SetVolume(gMovieLibDirectSoundBuffer, gMovieLibVolume);
|
audioEngineSoundBufferSetVolume(gMveSoundBuffer, gMovieLibVolume);
|
||||||
IDirectSoundBuffer_SetPan(gMovieLibDirectSoundBuffer, gMovieLibPan);
|
audioEngineSoundBufferSetPan(gMveSoundBuffer, gMovieLibPan);
|
||||||
|
|
||||||
dword_6B36A4 = 0;
|
dword_6B36A4 = 0;
|
||||||
|
|
||||||
stru_6B3668.dwSize = sizeof(DSBCAPS);
|
|
||||||
if (IDirectSoundBuffer_GetCaps(gMovieLibDirectSoundBuffer, &stru_6B3668) != DS_OK) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
#else
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x4F56C0
|
// 0x4F56C0
|
||||||
|
@ -1214,23 +1161,20 @@ static void _MVE_syncSync()
|
||||||
// 0x4F56F0
|
// 0x4F56F0
|
||||||
static void _MVE_sndReset()
|
static void _MVE_sndReset()
|
||||||
{
|
{
|
||||||
#ifdef HAVE_DSOUND
|
if (gMveSoundBuffer != -1) {
|
||||||
if (gMovieLibDirectSoundBuffer != NULL) {
|
audioEngineSoundBufferStop(gMveSoundBuffer);
|
||||||
IDirectSoundBuffer_Stop(gMovieLibDirectSoundBuffer);
|
audioEngineSoundBufferRelease(gMveSoundBuffer);
|
||||||
IDirectSoundBuffer_Release(gMovieLibDirectSoundBuffer);
|
gMveSoundBuffer = -1;
|
||||||
gMovieLibDirectSoundBuffer = NULL;
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x4F5720
|
// 0x4F5720
|
||||||
static void _MVE_sndSync()
|
static void _MVE_sndSync()
|
||||||
{
|
{
|
||||||
#ifdef HAVE_DSOUND
|
unsigned int dwCurrentPlayCursor;
|
||||||
DWORD dwCurrentPlayCursor;
|
unsigned int dwCurrentWriteCursor;
|
||||||
DWORD dwCurrentWriteCursor;
|
|
||||||
bool v10;
|
bool v10;
|
||||||
DWORD dwStatus;
|
unsigned int dwStatus;
|
||||||
unsigned int v1;
|
unsigned int v1;
|
||||||
bool v2;
|
bool v2;
|
||||||
int v3;
|
int v3;
|
||||||
|
@ -1247,27 +1191,23 @@ static void _MVE_sndSync()
|
||||||
_sync_late = _syncWaitLevel(_sync_wait_quanta >> 2) > -_sync_wait_quanta >> 1 && !_sync_FrameDropped;
|
_sync_late = _syncWaitLevel(_sync_wait_quanta >> 2) > -_sync_wait_quanta >> 1 && !_sync_FrameDropped;
|
||||||
_sync_FrameDropped = 0;
|
_sync_FrameDropped = 0;
|
||||||
|
|
||||||
if (gMovieLibDirectSound == NULL) {
|
if (gMveSoundBuffer == -1) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gMovieLibDirectSoundBuffer == NULL) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (IDirectSoundBuffer_GetStatus(gMovieLibDirectSoundBuffer, &dwStatus) != DS_OK) {
|
if (!audioEngineSoundBufferGetStatus(gMveSoundBuffer, &dwStatus)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IDirectSoundBuffer_GetCurrentPosition(gMovieLibDirectSoundBuffer, &dwCurrentPlayCursor, &dwCurrentWriteCursor) != DS_OK) {
|
if (!audioEngineSoundBufferGetCurrentPosition(gMveSoundBuffer, &dwCurrentPlayCursor, &dwCurrentWriteCursor)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dwCurrentWriteCursor = dword_6B36A4;
|
dwCurrentWriteCursor = dword_6B36A4;
|
||||||
|
|
||||||
v1 = (stru_6B3668.dwBufferBytes + dword_6B39E0[dword_6B3660] - _gSoundTimeBase)
|
v1 = (gMveBufferBytes + dword_6B39E0[dword_6B3660] - _gSoundTimeBase)
|
||||||
% stru_6B3668.dwBufferBytes;
|
% gMveBufferBytes;
|
||||||
|
|
||||||
if (dwCurrentPlayCursor <= dword_6B36A4) {
|
if (dwCurrentPlayCursor <= dword_6B36A4) {
|
||||||
if (v1 < dwCurrentPlayCursor || v1 >= 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) {
|
if (v0) {
|
||||||
_syncReset(_sync_wait_quanta + (_sync_wait_quanta >> 2));
|
_syncReset(_sync_wait_quanta + (_sync_wait_quanta >> 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
v3 = dword_6B39E0[dword_6B3660];
|
v3 = dword_6B39E0[dword_6B3660];
|
||||||
|
|
||||||
if (!(dwStatus & DSBSTATUS_PLAYING)) {
|
if (!(dwStatus & AUDIO_ENGINE_SOUND_BUFFER_STATUS_PLAYING)) {
|
||||||
v4 = (stru_6B3668.dwBufferBytes + v3) % stru_6B3668.dwBufferBytes;
|
v4 = (gMveBufferBytes + v3) % gMveBufferBytes;
|
||||||
|
|
||||||
if (dwCurrentWriteCursor >= dwCurrentPlayCursor) {
|
if (dwCurrentWriteCursor >= dwCurrentPlayCursor) {
|
||||||
if (v4 >= dwCurrentPlayCursor && v4 < dwCurrentWriteCursor) {
|
if (v4 >= dwCurrentPlayCursor && v4 < dwCurrentWriteCursor) {
|
||||||
|
@ -1306,11 +1246,11 @@ static void _MVE_sndSync()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v5) {
|
if (v5) {
|
||||||
if (IDirectSoundBuffer_SetCurrentPosition(gMovieLibDirectSoundBuffer, v4) != DS_OK) {
|
if (!audioEngineSoundBufferSetCurrentPosition(gMveSoundBuffer, v4)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IDirectSoundBuffer_Play(gMovieLibDirectSoundBuffer, 0, 0, 1) != DS_OK) {
|
if (!audioEngineSoundBufferPlay(gMveSoundBuffer, 1)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1318,20 +1258,20 @@ static void _MVE_sndSync()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
v6 = (stru_6B3668.dwBufferBytes + _gSoundTimeBase + v3) % stru_6B3668.dwBufferBytes;
|
v6 = (gMveBufferBytes + _gSoundTimeBase + v3) % gMveBufferBytes;
|
||||||
v7 = dwCurrentWriteCursor - dwCurrentPlayCursor;
|
v7 = dwCurrentWriteCursor - dwCurrentPlayCursor;
|
||||||
|
|
||||||
if (((dwCurrentWriteCursor - dwCurrentPlayCursor) & 0x80000000) != 0) {
|
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.
|
// NOTE: Original code uses signed comparison.
|
||||||
if ((int)stru_6B3668.dwBufferBytes / 2 < v8) {
|
if ((int)gMveBufferBytes / 2 < v8) {
|
||||||
v8 = stru_6B3668.dwBufferBytes >> 1;
|
v8 = gMveBufferBytes >> 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
v9 = (stru_6B3668.dwBufferBytes + dwCurrentPlayCursor - v8) % stru_6B3668.dwBufferBytes;
|
v9 = (gMveBufferBytes + dwCurrentPlayCursor - v8) % gMveBufferBytes;
|
||||||
|
|
||||||
dwCurrentPlayCursor = v9;
|
dwCurrentPlayCursor = v9;
|
||||||
|
|
||||||
|
@ -1350,7 +1290,7 @@ static void _MVE_sndSync()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!v10) {
|
if (!v10) {
|
||||||
IDirectSoundBuffer_Stop(gMovieLibDirectSoundBuffer);
|
audioEngineSoundBufferStop(gMveSoundBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -1365,10 +1305,6 @@ static void _MVE_sndSync()
|
||||||
++dword_6B3660;
|
++dword_6B3660;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
_sync_late = _syncWaitLevel(_sync_wait_quanta >> 2) > -_sync_wait_quanta >> 1 && !_sync_FrameDropped;
|
|
||||||
_sync_FrameDropped = 0;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x4F59B0
|
// 0x4F59B0
|
||||||
|
@ -1394,20 +1330,19 @@ static int _syncWaitLevel(int a1)
|
||||||
// 0x4F5A00
|
// 0x4F5A00
|
||||||
static void _CallsSndBuff_Loc(unsigned char* a1, int a2)
|
static void _CallsSndBuff_Loc(unsigned char* a1, int a2)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_DSOUND
|
|
||||||
int v2;
|
int v2;
|
||||||
int v3;
|
int v3;
|
||||||
int v5;
|
int v5;
|
||||||
DWORD dwCurrentPlayCursor;
|
unsigned int dwCurrentPlayCursor;
|
||||||
DWORD dwCurrentWriteCursor;
|
unsigned int dwCurrentWriteCursor;
|
||||||
LPVOID lpvAudioPtr1;
|
void* lpvAudioPtr1;
|
||||||
DWORD dwAudioBytes1;
|
unsigned int dwAudioBytes1;
|
||||||
LPVOID lpvAudioPtr2;
|
void* lpvAudioPtr2;
|
||||||
DWORD dwAudioBytes2;
|
unsigned int dwAudioBytes2;
|
||||||
|
|
||||||
_gSoundTimeBase = a2;
|
_gSoundTimeBase = a2;
|
||||||
|
|
||||||
if (gMovieLibDirectSoundBuffer == NULL) {
|
if (gMveSoundBuffer == -1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1420,13 +1355,13 @@ static void _CallsSndBuff_Loc(unsigned char* a1, int a2)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IDirectSoundBuffer_GetCurrentPosition(gMovieLibDirectSoundBuffer, &dwCurrentPlayCursor, &dwCurrentWriteCursor) != DS_OK) {
|
if (!audioEngineSoundBufferGetCurrentPosition(gMveSoundBuffer, &dwCurrentPlayCursor, &dwCurrentWriteCursor)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dwCurrentWriteCursor = dword_6B36A4;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1443,11 +1378,11 @@ static void _CallsSndBuff_Loc(unsigned char* a1, int a2)
|
||||||
dword_6B36A4 = dwAudioBytes2;
|
dword_6B36A4 = dwAudioBytes2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dword_6B36A4 == stru_6B3668.dwBufferBytes) {
|
if (dword_6B36A4 == gMveBufferBytes) {
|
||||||
dword_6B36A4 = 0;
|
dword_6B36A4 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
IDirectSoundBuffer_Unlock(gMovieLibDirectSoundBuffer, lpvAudioPtr1, dwAudioBytes1, lpvAudioPtr2, dwAudioBytes2);
|
audioEngineSoundBufferUnlock(gMveSoundBuffer, lpvAudioPtr1, dwAudioBytes1, lpvAudioPtr2, dwAudioBytes2);
|
||||||
|
|
||||||
dword_6B39E0[dword_6B3AE4] = dwCurrentWriteCursor;
|
dword_6B39E0[dword_6B3AE4] = dwCurrentWriteCursor;
|
||||||
|
|
||||||
|
@ -1456,7 +1391,6 @@ static void _CallsSndBuff_Loc(unsigned char* a1, int a2)
|
||||||
} else {
|
} else {
|
||||||
++dword_6B3AE4;
|
++dword_6B3AE4;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x4F5B70
|
// 0x4F5B70
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#ifndef MOVIE_LIB_H
|
#ifndef MOVIE_LIB_H
|
||||||
#define MOVIE_LIB_H
|
#define MOVIE_LIB_H
|
||||||
|
|
||||||
#include "dsound_compat.h"
|
|
||||||
#include "memory_defs.h"
|
#include "memory_defs.h"
|
||||||
|
|
||||||
#include <SDL.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 movieLibSetMemoryProcs(MallocProc* mallocProc, FreeProc* freeProc);
|
||||||
void movieLibSetReadProc(MovieReadProc* readProc);
|
void movieLibSetReadProc(MovieReadProc* readProc);
|
||||||
#ifdef HAVE_DSOUND
|
|
||||||
void movieLibSetDirectSound(LPDIRECTSOUND ds);
|
|
||||||
#endif
|
|
||||||
void movieLibSetVolume(int volume);
|
void movieLibSetVolume(int volume);
|
||||||
void movieLibSetPan(int pan);
|
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);
|
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_INVALID_HANDLE = 30,
|
||||||
SOUND_NO_MEMORY_AVAILABLE = 31,
|
SOUND_NO_MEMORY_AVAILABLE = 31,
|
||||||
SOUND_UNKNOWN_ERROR = 32,
|
SOUND_UNKNOWN_ERROR = 32,
|
||||||
// TODO: Remove once DirectX -> SDL transition is completed.
|
|
||||||
SOUND_NOT_IMPLEMENTED = 33,
|
|
||||||
SOUND_ERR_COUNT,
|
SOUND_ERR_COUNT,
|
||||||
} SoundError;
|
} SoundError;
|
||||||
|
|
||||||
|
@ -70,10 +68,10 @@ typedef void SoundCallback(void* userData, int a2);
|
||||||
typedef struct Sound {
|
typedef struct Sound {
|
||||||
SoundFileIO io;
|
SoundFileIO io;
|
||||||
unsigned char* field_20;
|
unsigned char* field_20;
|
||||||
#ifdef HAVE_DSOUND
|
int soundBuffer;
|
||||||
LPDIRECTSOUNDBUFFER directSoundBuffer;
|
int bitsPerSample;
|
||||||
DSBUFFERDESC directSoundBufferDescription;
|
int channels;
|
||||||
#endif
|
int rate;
|
||||||
int field_3C;
|
int field_3C;
|
||||||
// flags
|
// flags
|
||||||
int field_40;
|
int field_40;
|
||||||
|
@ -91,9 +89,7 @@ typedef struct Sound {
|
||||||
int field_68;
|
int field_68;
|
||||||
int readLimit;
|
int readLimit;
|
||||||
int field_70;
|
int field_70;
|
||||||
#ifdef HAVE_DSOUND
|
unsigned int field_74;
|
||||||
DWORD field_74;
|
|
||||||
#endif
|
|
||||||
int field_78;
|
int field_78;
|
||||||
int field_7C;
|
int field_7C;
|
||||||
int field_80;
|
int field_80;
|
||||||
|
@ -106,10 +102,6 @@ typedef struct Sound {
|
||||||
struct Sound* prev;
|
struct Sound* prev;
|
||||||
} Sound;
|
} Sound;
|
||||||
|
|
||||||
#ifdef HAVE_DSOUND
|
|
||||||
extern LPDIRECTSOUND gDirectSound;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void soundSetMemoryProcs(MallocProc* mallocProc, ReallocProc* reallocProc, FreeProc* freeProc);
|
void soundSetMemoryProcs(MallocProc* mallocProc, ReallocProc* reallocProc, FreeProc* freeProc);
|
||||||
const char* soundGetErrorDescription(int err);
|
const char* soundGetErrorDescription(int err);
|
||||||
int soundInit(int a1, int a2, int a3, int a4, int rate);
|
int soundInit(int a1, int a2, int a3, int a4, int rate);
|
||||||
|
|
55
src/win32.cc
55
src/win32.cc
|
@ -8,77 +8,26 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#ifdef HAVE_DSOUND
|
|
||||||
// 0x51E430
|
|
||||||
DirectSoundCreateProc* gDirectSoundCreateProc = NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// 0x51E434
|
|
||||||
HWND gProgramWindow = NULL;
|
|
||||||
|
|
||||||
// 0x51E444
|
// 0x51E444
|
||||||
bool gProgramIsActive = false;
|
bool gProgramIsActive = false;
|
||||||
|
|
||||||
// GNW95MUTEX
|
// GNW95MUTEX
|
||||||
HANDLE _GNW95_mutex = NULL;
|
HANDLE _GNW95_mutex = NULL;
|
||||||
|
|
||||||
#ifdef HAVE_DSOUND
|
|
||||||
// 0x51E454
|
|
||||||
HMODULE gDSoundDLL = NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// 0x4DE700
|
// 0x4DE700
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
_GNW95_mutex = CreateMutexA(0, TRUE, "GNW95MUTEX");
|
_GNW95_mutex = CreateMutexA(0, TRUE, "GNW95MUTEX");
|
||||||
if (GetLastError() == ERROR_SUCCESS) {
|
if (GetLastError() == ERROR_SUCCESS) {
|
||||||
SDL_ShowCursor(SDL_DISABLE);
|
SDL_ShowCursor(SDL_DISABLE);
|
||||||
if (_LoadDirectX()) {
|
|
||||||
gProgramIsActive = true;
|
gProgramIsActive = true;
|
||||||
falloutMain(argc, argv);
|
falloutMain(argc, argv);
|
||||||
}
|
|
||||||
CloseHandle(_GNW95_mutex);
|
CloseHandle(_GNW95_mutex);
|
||||||
}
|
}
|
||||||
return 0;
|
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
|
#else
|
||||||
bool gProgramIsActive = false;
|
bool gProgramIsActive = false;
|
||||||
|
|
||||||
|
|
15
src/win32.h
15
src/win32.h
|
@ -1,28 +1,13 @@
|
||||||
#ifndef WIN32_H
|
#ifndef WIN32_H
|
||||||
#define WIN32_H
|
#define WIN32_H
|
||||||
|
|
||||||
#include "dsound_compat.h"
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#define NOMINMAX
|
#define NOMINMAX
|
||||||
#include <windows.h>
|
#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 bool gProgramIsActive;
|
||||||
extern HANDLE _GNW95_mutex;
|
extern HANDLE _GNW95_mutex;
|
||||||
#ifdef HAVE_DSOUND
|
|
||||||
extern HMODULE gDSoundDLL;
|
|
||||||
#endif
|
|
||||||
bool _LoadDirectX();
|
|
||||||
void _UnloadDirectX(void);
|
|
||||||
#else
|
#else
|
||||||
extern bool gProgramIsActive;
|
extern bool gProgramIsActive;
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue