diff --git a/projects/openrct2.vcxproj b/projects/openrct2.vcxproj
index 9c079203b5..3077811de3 100644
--- a/projects/openrct2.vcxproj
+++ b/projects/openrct2.vcxproj
@@ -201,7 +201,7 @@
true
- winmm.lib;sdl2.lib;%(AdditionalDependencies)
+ winmm.lib;sdl2.lib;Dsound.lib;%(AdditionalDependencies)
@@ -224,7 +224,7 @@
true
true
true
- winmm.lib;sdl2.lib;%(AdditionalDependencies)
+ winmm.lib;sdl2.lib;Dsound.lib;%(AdditionalDependencies)
xcopy /Y "$(ProjectDir)\..\Data\Language\*.*" "$(TargetDir)\Data\Language\"
diff --git a/src/addresses.h b/src/addresses.h
index 700ad084be..d6b95d7426 100644
--- a/src/addresses.h
+++ b/src/addresses.h
@@ -165,6 +165,7 @@
#define RCT2_ADDRESS_SOUNDLIST_BEGIN 0x009E2B98
#define RCT2_ADDRESS_SOUNDLIST_END 0x009E2B9C
#define RCT2_ADDRESS_DIRECTSOUND 0x009E2BA0
+#define RCT2_ADDRESS_DSOUND_DEVICES_COUNTER 0x009E2BAC
#define RCT2_ADDRESS_CMDLINE 0x009E2D98
@@ -316,6 +317,8 @@
#define RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER 0x0141ED68
+#define RCT2_ADDRESS_AUDIO_INFO 0x01425B40
+
#define RCT2_ADDRESS_SOUND_CHANNEL_LIST 0x014262E0
#define RCT2_ADDRESS_WATER_RAISE_COST 0x0141F738
diff --git a/src/audio.c b/src/audio.c
index 4bfbf81863..ecc2ddb50d 100644
--- a/src/audio.c
+++ b/src/audio.c
@@ -66,16 +66,79 @@ void audio_get_devices()
}
}
+/**
+*
+* rct2: 0x00404BD2
+*/
+int sound_release()
+{
+ sound_stop_all();
+ if (RCT2_GLOBAL(0x009E2BA4, LPDIRECTSOUND3DBUFFER)) {
+ RCT2_GLOBAL(0x009E2BA4, LPDIRECTSOUND3DBUFFER)->lpVtbl->Release(RCT2_GLOBAL(0x009E2BA4, LPDIRECTSOUND3DBUFFER));
+ RCT2_GLOBAL(0x009E2BA4, LPDIRECTSOUND3DBUFFER) = 0;
+ }
+ if (RCT2_GLOBAL(0x009E2BA8, LPDIRECTSOUNDBUFFER)) {
+ RCT2_GLOBAL(0x009E2BA8, LPDIRECTSOUNDBUFFER)->lpVtbl->Release(RCT2_GLOBAL(0x009E2BA8, LPDIRECTSOUNDBUFFER));
+ RCT2_GLOBAL(0x009E2BA8, LPDIRECTSOUNDBUFFER) = 0;
+ }
+ int result = 0;
+ if (RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND)) {
+ result = RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND)->lpVtbl->Release(RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND));
+ RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND) = 0;
+ }
+ return result;
+}
+
+/**
+*
+* rct2: 0x00404C45
+*/
+int sound_unmap_info()
+{
+ if (RCT2_GLOBAL(RCT2_ADDRESS_SOUND_INFO_LIST_OFFSET, int)) {
+ sound_stop_all();
+ sound_unmap_file(RCT2_GLOBAL(RCT2_ADDRESS_SOUND_INFO_LIST_OFFSET, LPCVOID));
+ RCT2_GLOBAL(RCT2_ADDRESS_SOUND_INFO_LIST_OFFSET, int) = 0;
+ return 1;
+ }
+ return 0;
+}
+
+/**
+*
+* rct2: 0x00404DF5
+*/
+int sound_stop_all()
+{
+ int result = 0;
+ while (RCT2_GLOBAL(RCT2_ADDRESS_SOUNDLIST_BEGIN, rct_sound*)) {
+ result = sound_stop(RCT2_GLOBAL(RCT2_ADDRESS_SOUNDLIST_BEGIN, rct_sound*));
+ }
+ return result;
+}
+
+/**
+*
+* rct2: 0x004068A0
+*/
+int sound_unmap_file(LPCVOID base)
+{
+ if (base) {
+ return UnmapViewOfFile(base);
+ }
+ return 0;
+}
+
/**
*
* rct2: 0x006BAB21
*/
-void sub_6BAB21(void)
+void sub_6BAB21()
{
if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SOUND_DEVICE, uint32) != -1) {
stop_other_sounds();
stop_peep_sounds();
- RCT2_CALLPROC_EBPSAFE(0x006BD0BD);
+ stop_title_music();
if (RCT2_GLOBAL(0x009AF284, uint32) & (1 << 0)) {
stop_ride_music();
RCT2_GLOBAL(0x014241BC, uint32) = 1;
@@ -83,13 +146,125 @@ void sub_6BAB21(void)
RCT2_GLOBAL(0x014241BC, uint32) = 0;
}
RCT2_GLOBAL(0x014241BC, uint32) = 1;
- RCT2_CALLPROC(0x00404C45);
- RCT2_CALLPROC(0x00404BD2);
+ sound_unmap_info();
+ sound_release();
RCT2_GLOBAL(0x014241BC, uint32) = 0;
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SOUND_DEVICE, uint32) = -1;
}
}
+/**
+*
+* rct2: 0x000404F28
+*/
+int sound_load3dparameters()
+{
+ if (SUCCEEDED(RCT2_GLOBAL(0x009E2BA4, LPDIRECTSOUND3DBUFFER)->lpVtbl->GetAllParameters(RCT2_GLOBAL(0x009E2BA4, LPDIRECTSOUND3DBUFFER), &RCT2_GLOBAL(0x009A6084, DS3DBUFFER)))) {
+ return 1;
+ }
+ return 0;
+}
+
+/**
+*
+* rct2: 0x00404932
+*/
+int dsound_create_primary_buffer(int a, int device, int channels, int samples, int bits)
+{
+ rct_dsdevice* dsdevice = 0;
+ if (device) {
+ if (device > RCT2_GLOBAL(RCT2_ADDRESS_NUM_DSOUND_DEVICES, int)) {
+ return 0;
+ }
+ dsdevice = &RCT2_GLOBAL(RCT2_ADDRESS_DSOUND_DEVICES, rct_dsdevice*)[device];
+ }
+ memset(&RCT2_GLOBAL(RCT2_ADDRESS_AUDIO_INFO, rct_audio_info), 0, sizeof(rct_audio_info));
+ RCT2_GLOBAL(RCT2_ADDRESS_AUDIO_INFO, rct_audio_info).var_0 = 1;
+ RCT2_GLOBAL(RCT2_ADDRESS_AUDIO_INFO, rct_audio_info).channels = channels;
+ RCT2_GLOBAL(RCT2_ADDRESS_AUDIO_INFO, rct_audio_info).samples = samples;
+ RCT2_GLOBAL(RCT2_ADDRESS_AUDIO_INFO, rct_audio_info).var_8 = samples * RCT2_GLOBAL(0x01425B4C, uint16);
+ RCT2_GLOBAL(RCT2_ADDRESS_AUDIO_INFO, rct_audio_info).bytes = bits * channels / 8;
+ RCT2_GLOBAL(RCT2_ADDRESS_AUDIO_INFO, rct_audio_info).bits = bits;
+ RCT2_GLOBAL(RCT2_ADDRESS_AUDIO_INFO, rct_audio_info).var_E = 0;
+ DSBUFFERDESC bufferdesc;
+ memset(&bufferdesc, 0, sizeof(bufferdesc));
+ bufferdesc.dwSize = sizeof(bufferdesc);
+ if (a) {
+ if (a != 1) {
+ return 0;
+ }
+ bufferdesc.dwFlags = DSBCAPS_CTRL3D | DSBCAPS_PRIMARYBUFFER;
+ if (RCT2_GLOBAL(0x009E2B90, uint32)) {
+ bufferdesc.dwFlags = DSBCAPS_STICKYFOCUS | DSBCAPS_CTRL3D | DSBCAPS_PRIMARYBUFFER;
+ }
+ if (FAILED(DirectSoundCreate(&dsdevice->guid, &RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND), 0))) {
+ return 0;
+ }
+ if (FAILED(RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND)->lpVtbl->SetCooperativeLevel(RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND), RCT2_GLOBAL(0x009E2D70, HWND), DSSCL_NORMAL)) ||
+ FAILED(RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND)->lpVtbl->CreateSoundBuffer(RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND), &bufferdesc, &RCT2_GLOBAL(0x009E2BA8, LPDIRECTSOUNDBUFFER), 0))) {
+ RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND)->lpVtbl->Release(RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND));
+ RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND) = 0;
+ return 0;
+ }
+ if (SUCCEEDED(RCT2_GLOBAL(0x009E2BA8, LPDIRECTSOUNDBUFFER)->lpVtbl->QueryInterface(RCT2_GLOBAL(0x009E2BA8, LPDIRECTSOUNDBUFFER), &RCT2_GLOBAL(0x009A4444, IID) /* IID_IDirectSound3DBuffer */, &RCT2_GLOBAL(0x009E2BA4, LPDIRECTSOUND3DBUFFER)))) {
+ // doesn't seem to ever make it here, below doesn't make sense and is probably remnants of unused 3d sound tests
+ memset(&RCT2_GLOBAL(0x009A6084, DS3DBUFFER), 0, sizeof(RCT2_GLOBAL(0x009A6084, DS3DBUFFER)));
+ RCT2_GLOBAL(0x009A6084, DS3DBUFFER).dwSize = sizeof(RCT2_GLOBAL(0x009A6084, DS3DBUFFER));
+
+ if (sound_load3dparameters()) {
+ RCT2_GLOBAL(0x009A6084, DS3DBUFFER).vPosition.x = 0.0f;
+ }
+ RCT2_GLOBAL(0x009A6084, DS3DBUFFER).vPosition.y = 0.0f;
+ RCT2_GLOBAL(0x009A6084, DS3DBUFFER).vPosition.x = -1.0f;
+ RCT2_GLOBAL(0x009A6084, DS3DBUFFER).flMaxDistance = 9.8999996f;
+ RCT2_GLOBAL(0x009A6084, DS3DBUFFER).flMinDistance = 0.25f;
+ if (RCT2_CALLFUNC(0x00404F3F, int)) {
+ if (SUCCEEDED(RCT2_GLOBAL(0x009E2BA4, LPDIRECTSOUND3DBUFFER)->lpVtbl->SetMinDistance(RCT2_GLOBAL(0x009E2BA4, LPDIRECTSOUND3DBUFFER), RCT2_GLOBAL(0x009A6084, DS3DBUFFER).flMinDistance, 1))) {
+ if (sound_load3dparameters()) {
+ return 1;
+ }
+ }
+ }
+ RCT2_GLOBAL(0x009E2BA4, LPDIRECTSOUND3DBUFFER)->lpVtbl->Release(RCT2_GLOBAL(0x009E2BA4, LPDIRECTSOUND3DBUFFER));
+ RCT2_GLOBAL(0x009E2BA4, LPDIRECTSOUND3DBUFFER) = 0;
+ RCT2_GLOBAL(0x009E2BA8, LPDIRECTSOUNDBUFFER)->lpVtbl->Release(RCT2_GLOBAL(0x009E2BA8, LPDIRECTSOUNDBUFFER));
+ RCT2_GLOBAL(0x009E2BA8, LPDIRECTSOUNDBUFFER) = 0;
+ RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND)->lpVtbl->Release(RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND));
+ RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND) = 0;
+ } else {
+ RCT2_GLOBAL(0x009E2BA8, LPDIRECTSOUNDBUFFER)->lpVtbl->Release(RCT2_GLOBAL(0x009E2BA8, LPDIRECTSOUNDBUFFER));
+ RCT2_GLOBAL(0x009E2BA8, LPDIRECTSOUNDBUFFER) = 0;
+ RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND)->lpVtbl->Release(RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND));
+ RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND) = 0;
+ }
+ }
+ bufferdesc.dwFlags = DSBCAPS_PRIMARYBUFFER;
+ if (RCT2_GLOBAL(0x009E2B90, uint32)) {
+ bufferdesc.dwFlags = DSBCAPS_STICKYFOCUS | DSBCAPS_PRIMARYBUFFER;
+ }
+ if (FAILED(DirectSoundCreate(&dsdevice->guid, &RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND), 0))) {
+ return 0;
+ }
+ if (FAILED(RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND)->lpVtbl->SetCooperativeLevel(RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND), RCT2_GLOBAL(0x009E2D70, HWND), DSSCL_PRIORITY))) {
+ RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND)->lpVtbl->Release(RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND));
+ RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND) = 0;
+ return 0;
+ }
+ RCT2_GLOBAL(0x01425B60, DSCAPS).dwSize = sizeof(DSCAPS);
+ RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND)->lpVtbl->GetCaps(RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND), &RCT2_GLOBAL(0x01425B60, DSCAPS));
+ if (FAILED(RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND)->lpVtbl->CreateSoundBuffer(RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND), &bufferdesc, &RCT2_GLOBAL(0x009E2BA8, LPDIRECTSOUNDBUFFER), 0))) {
+ RCT2_GLOBAL(0x009E2BA8, LPDIRECTSOUNDBUFFER)->lpVtbl->Release(RCT2_GLOBAL(0x009E2BA8, LPDIRECTSOUNDBUFFER));
+ RCT2_GLOBAL(0x009E2BA8, LPDIRECTSOUNDBUFFER) = 0;
+ RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND)->lpVtbl->Release(RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND));
+ RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND) = 0;
+ }
+ WAVEFORMATEX waveformat1, waveformat2;
+ RCT2_GLOBAL(0x009E2BA8, LPDIRECTSOUNDBUFFER)->lpVtbl->GetFormat(RCT2_GLOBAL(0x009E2BA8, LPDIRECTSOUNDBUFFER), &waveformat1, sizeof(WAVEFORMATEX), 0);
+ RCT2_GLOBAL(0x009E2BA8, LPDIRECTSOUNDBUFFER)->lpVtbl->SetFormat(RCT2_GLOBAL(0x009E2BA8, LPDIRECTSOUNDBUFFER), &RCT2_GLOBAL(0x01425B40, WAVEFORMATEX));
+ RCT2_GLOBAL(0x009E2BA8, LPDIRECTSOUNDBUFFER)->lpVtbl->GetFormat(RCT2_GLOBAL(0x009E2BA8, LPDIRECTSOUNDBUFFER), &waveformat2, sizeof(WAVEFORMATEX), 0);
+ return 1;
+}
+
/**
*
* rct2: 0x006BA9B5
@@ -106,7 +281,8 @@ void audio_init2(int device)
other_sound->id = 0xFFFF;
}
RCT2_GLOBAL(0x014241BC, uint32) = 1;
- int v5 = RCT2_CALLFUNC_5(0x00404932, int, int, int, int, int, int, 0, device, 2, 22050, 16);
+ int v5 = dsound_create_primary_buffer(0, device, 2, 22050, 16);
+ //int v5 = RCT2_CALLFUNC_5(0x00404932, int, int, int, int, int, int, 0, device, 2, 22050, 16);
RCT2_GLOBAL(0x014241BC, uint32) = 0;
if (!v5) {
return;
@@ -117,16 +293,16 @@ void audio_init2(int device)
RCT2_GLOBAL(0x014241BC, uint32) = 0;
if (!v8) {
RCT2_GLOBAL(0x014241BC, uint32) = 1;
- RCT2_CALLPROC(0x00404BD2);
+ sound_release();
RCT2_GLOBAL(0x014241BC, uint32) = 0;
return;
}
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SOUND_DEVICE, uint32) = device;
- int* data = RCT2_ADDRESS(RCT2_ADDRESS_DSOUND_DEVICES + (0x210 * device), int);
- RCT2_GLOBAL(0x009AAC5D, uint32) = data[0];
- RCT2_GLOBAL(0x009AAC61, uint32) = data[1];
- RCT2_GLOBAL(0x009AAC65, uint32) = data[2];
- RCT2_GLOBAL(0x009AAC69, uint32) = data[3];
+ rct_dsdevice dsdevice = RCT2_GLOBAL(RCT2_ADDRESS_DSOUND_DEVICES, rct_dsdevice*)[device];
+ RCT2_GLOBAL(0x009AAC5D, uint32) = dsdevice.guid.Data1;
+ RCT2_GLOBAL(0x009AAC61, uint32) = dsdevice.guid.Data2;
+ RCT2_GLOBAL(0x009AAC65, uint32) = dsdevice.guid.Data3;
+ RCT2_GLOBAL(0x009AAC69, uint32) = (uint32)dsdevice.guid.Data4;
RCT2_GLOBAL(0x009AAC5C, uint8) = 1;
config_save();
RCT2_GLOBAL(0x014241BC, uint32) = 1;
@@ -146,13 +322,60 @@ void audio_init2(int device)
}
}
+/**
+*
+* rct2: 0x00404F85
+*/
+BOOL CALLBACK dsound_enum_callback_count(LPGUID lpGuid, LPCSTR lpcstrDescription, LPCSTR lpcstrModule, LPVOID lpContext)
+{
+ RCT2_GLOBAL(RCT2_ADDRESS_DSOUND_DEVICES_COUNTER, int)++;
+ return 1;
+}
+
+/**
+*
+* rct2: 0x00404F91
+*/
+int dsound_count_devices()
+{
+ RCT2_GLOBAL(RCT2_ADDRESS_DSOUND_DEVICES_COUNTER, int) = 0;
+ if (SUCCEEDED(DirectSoundEnumerate(dsound_enum_callback_count, 0))) {
+ return RCT2_GLOBAL(RCT2_ADDRESS_DSOUND_DEVICES_COUNTER, int);
+ }
+ return 0;
+}
+
+/**
+*
+* rct2: 0x00404FB1
+*/
+BOOL CALLBACK dsound_enum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription, LPCSTR lpcstrModule, LPVOID lpContext)
+{
+ if (lpGuid) {
+ memcpy(&RCT2_GLOBAL(RCT2_ADDRESS_DSOUND_DEVICES, rct_dsdevice*)[RCT2_GLOBAL(0x01425B54, int)].guid, lpGuid, sizeof(GUID));
+ } else {
+ memset(&RCT2_GLOBAL(RCT2_ADDRESS_DSOUND_DEVICES, rct_dsdevice*)[RCT2_GLOBAL(0x01425B54, int)].guid, 0, sizeof(GUID));
+ }
+ strcpy(RCT2_GLOBAL(RCT2_ADDRESS_DSOUND_DEVICES, rct_dsdevice*)[RCT2_GLOBAL(0x01425B54, int)].desc, lpcstrDescription);
+ strcpy(RCT2_GLOBAL(RCT2_ADDRESS_DSOUND_DEVICES, rct_dsdevice*)[RCT2_GLOBAL(0x01425B54, int)].drvname, lpcstrModule);
+ RCT2_GLOBAL(0x01425B54, int)++;
+ return 1;
+}
+
/**
*
* rct2: 0x0040502E
*/
-void get_dsound_devices()
+int get_dsound_devices()
{
- RCT2_CALLPROC(0x0040502E);
+ RCT2_GLOBAL(RCT2_ADDRESS_NUM_DSOUND_DEVICES, uint32) = dsound_count_devices();
+ RCT2_GLOBAL(RCT2_ADDRESS_DSOUND_DEVICES, rct_dsdevice*) = malloc(RCT2_GLOBAL(RCT2_ADDRESS_NUM_DSOUND_DEVICES, uint32) * sizeof(rct_dsdevice));
+ if (RCT2_GLOBAL(RCT2_ADDRESS_DSOUND_DEVICES, rct_dsdevice*)) {
+ RCT2_GLOBAL(0x01425B54, int) = 0;
+ DirectSoundEnumerate(dsound_enum_callback, 0);
+ return RCT2_GLOBAL(0x01425B54, int);
+ }
+ return 0;
}
/**
@@ -200,7 +423,7 @@ rct_sound* sound_next(rct_sound* sound)
*/
rct_sound_info* sound_get_info(uint16 sound_id)
{
- if (RCT2_GLOBAL(RCT2_ADDRESS_SOUND_INFO_LIST_OFFSET, int) && sound_id < RCT2_GLOBAL(RCT2_ADDRESS_SOUND_INFO_LIST_OFFSET, int)) {
+ if (RCT2_GLOBAL(RCT2_ADDRESS_SOUND_INFO_LIST_OFFSET, int) && sound_id < RCT2_GLOBAL(RCT2_ADDRESS_SOUND_INFO_LIST_OFFSET, int*)[0]) {
return (rct_sound_info*)(RCT2_GLOBAL(RCT2_ADDRESS_SOUND_INFO_LIST_OFFSET, int) + RCT2_GLOBAL(RCT2_ADDRESS_SOUND_INFO_LIST_OFFSET, int*)[sound_id + 1]);
}
return 0;
@@ -419,7 +642,7 @@ int sound_channel_set_volume(int channel, int volume)
*/
int sound_play(rct_sound* sound, int looping, int volume, int pan, int frequency)
{
- if (sound) {
+ if (sound->dsbuffer) {
sound_set_frequency(sound, frequency);
sound_set_pan(sound, pan);
sound_set_volume(sound, volume);
@@ -444,7 +667,7 @@ int sound_play(rct_sound* sound, int looping, int volume, int pan, int frequency
* rct2: 0x00404E53
*/
int sound_is_playing(rct_sound* sound){
- if (sound) {
+ if (sound->dsbuffer) {
DWORD status;
if (SUCCEEDED(sound->dsbuffer->lpVtbl->GetStatus(sound->dsbuffer, &status))) {
if (status & DSBSTATUS_PLAYING || status & DSBSTATUS_LOOPING)
@@ -461,7 +684,7 @@ int sound_is_playing(rct_sound* sound){
*/
int sound_set_frequency(rct_sound* sound, int frequency)
{
- if (sound) {
+ if (sound->dsbuffer) {
if (SUCCEEDED(sound->dsbuffer->lpVtbl->SetFrequency(sound->dsbuffer, frequency)))
return 1;
@@ -475,7 +698,7 @@ int sound_set_frequency(rct_sound* sound, int frequency)
*/
int sound_set_pan(rct_sound* sound, int pan)
{
- if (sound) {
+ if (sound->dsbuffer) {
if (SUCCEEDED(sound->dsbuffer->lpVtbl->SetPan(sound->dsbuffer, pan)))
return 1;
@@ -489,7 +712,7 @@ int sound_set_pan(rct_sound* sound, int pan)
*/
int sound_set_volume(rct_sound* sound, int volume)
{
- if (sound) {
+ if (sound->dsbuffer) {
if (SUCCEEDED(sound->dsbuffer->lpVtbl->SetVolume(sound->dsbuffer, volume)))
return 1;
@@ -501,14 +724,14 @@ int sound_set_volume(rct_sound* sound, int volume)
*
* rct2: 0x00404DD8
*/
-rct_sound* sound_stop(rct_sound* sound)
+int sound_stop(rct_sound* sound)
{
if (sound->dsbuffer) {
sound->dsbuffer->lpVtbl->Release(sound->dsbuffer);
sound->dsbuffer = 0;
- return sound_remove(sound);
+ return sound_remove(sound) ? 1 : 0;
}
- return sound;
+ return 0;
}
/**
@@ -678,6 +901,21 @@ void stop_peep_sounds()
}
}
+/**
+*
+* rct2: 0x006BD0BD
+*/
+void stop_title_music()
+{
+ if (RCT2_GLOBAL(0x009AF284, uint32) & (1 << 0)) {
+ if (RCT2_GLOBAL(0x009AF600, uint8) != 0) {
+ RCT2_GLOBAL(0x014241BC, uint32) = 1;
+ sound_channel_stop(3);
+ RCT2_GLOBAL(0x014241BC, uint32) = 0;
+ }
+ }
+}
+
/**
*
* rct2: 0x00401A05
diff --git a/src/audio.h b/src/audio.h
index 6009cd40cf..1ce9960cb4 100644
--- a/src/audio.h
+++ b/src/audio.h
@@ -57,6 +57,16 @@ typedef struct rct_sound {
struct rct_sound* next;
} rct_sound;
+typedef struct {
+ uint16 var_0;
+ uint16 channels;
+ uint32 samples;
+ uint32 var_8;
+ uint16 bytes;
+ uint16 bits;
+ uint16 var_E;
+} rct_audio_info;
+
typedef struct {
uint32 var_0;
uint8 pad_4[0x118];
@@ -90,7 +100,7 @@ typedef struct {
rct_sound sound;
} rct_other_sound;
-void get_dsound_devices();
+int get_dsound_devices();
int sound_prepare(int sound_id, rct_sound *sound, int channels, int software);
int sound_play_panned(int sound_id, int x);
int sound_play(rct_sound* sound, int looping, int volume, int pan, int frequency);
@@ -102,7 +112,9 @@ int sound_channel_play(int channel, int a2, int volume, int pan, int frequency);
int sound_channel_set_frequency(int channel, int frequency);
int sound_channel_set_pan(int channel, int pan);
int sound_channel_set_volume(int channel, int volume);
-rct_sound* sound_stop(rct_sound *sound);
+int sound_stop(rct_sound *sound);
+int sound_stop_all();
+int sound_unmap_file(LPCVOID base);
int sound_channel_stop(int channel);
rct_sound* sound_add(rct_sound* sound);
rct_sound* sound_remove(rct_sound* sound);
@@ -113,6 +125,7 @@ void stop_other_sounds();
void stop_vehicle_sounds();
void stop_ride_music();
void stop_peep_sounds();
+void stop_title_music();
void unpause_sounds();
// 0x009AF59C probably does the same job
diff --git a/src/rct2.c b/src/rct2.c
index b413820fd9..29572477a3 100644
--- a/src/rct2.c
+++ b/src/rct2.c
@@ -84,7 +84,7 @@ __declspec(dllexport) int StartOpenRCT(HINSTANCE hInstance, HINSTANCE hPrevInsta
audio_init();
audio_get_devices();
- RCT2_CALLPROC(0x0040502E); // get_dsound_devices()
+ get_dsound_devices();
config_init();
language_open(gGeneral_config.language);
rct2_init();
diff --git a/src/title.c b/src/title.c
index 79a6aae429..adfb25e080 100644
--- a/src/title.c
+++ b/src/title.c
@@ -22,6 +22,7 @@
#include
#include
#include "addresses.h"
+#include "audio.h"
#include "config.h"
#include "climate.h"
#include "date.h"
@@ -309,7 +310,7 @@ static void title_play_music()
if (!(RCT2_GLOBAL(0x009AF284, uint32) & 1) || !(RCT2_GLOBAL(0x009AF59D, uint8) & 1)) {
if (RCT2_GLOBAL(0x009AF600, uint8) != 0)
- RCT2_CALLPROC_EBPSAFE(0x006BD0BD); // stop music
+ stop_title_music();
return;
}