From 799797876a712cae699bdeaeb7bdecd9d9b59e9a Mon Sep 17 00:00:00 2001 From: zsilencer Date: Sun, 24 Aug 2014 22:18:01 -0600 Subject: [PATCH] Audio fixes #361 #355 --- src/audio.c | 136 +++++++++++++++++++++++++++++++++++++++++-- src/audio.h | 10 +++- src/game.c | 2 + src/window_options.c | 6 +- 4 files changed, 145 insertions(+), 9 deletions(-) diff --git a/src/audio.c b/src/audio.c index be4683a9c0..7f123efcd9 100644 --- a/src/audio.c +++ b/src/audio.c @@ -21,6 +21,7 @@ #include #include "audio.h" #include "addresses.h" +#include "config.h" #include "rct2.h" int gAudioDeviceCount; @@ -65,6 +66,86 @@ void audio_get_devices() } } +/** +* +* rct2: 0x006BAB21 +*/ +void audio_6BAB21(void) +{ + if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SOUND_DEVICE, uint32) != -1) { + stop_other_sounds(); + stop_peep_sounds(); + RCT2_CALLPROC_EBPSAFE(0x006BD0BD); + if (RCT2_GLOBAL(0x009AF284, uint32) & (1 << 0)) { + stop_ride_music(); + RCT2_GLOBAL(0x014241BC, uint32) = 1; + RCT2_CALLPROC(0x004018F0); // remove multimedia timer + RCT2_GLOBAL(0x014241BC, uint32) = 0; + } + RCT2_GLOBAL(0x014241BC, uint32) = 1; + RCT2_CALLPROC(0x00404C45); + RCT2_CALLPROC(0x00404BD2); + RCT2_GLOBAL(0x014241BC, uint32) = 0; + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SOUND_DEVICE, uint32) = -1; + } +} + +/** +* +* rct2: 0x006BA9B5 +*/ +void audio_init2(int device) +{ + audio_6BAB21(); + for (int i = 0; i < 7; i++) { + rct_vehicle_sound* vehicle_sound = &RCT2_ADDRESS(RCT2_ADDRESS_VEHICLE_SOUND_LIST, rct_vehicle_sound)[i]; + vehicle_sound->id = 0xFFFF; + } + for (int i = 0; i < 7; i++) { + rct_other_sound* other_sound = &RCT2_ADDRESS(0x009AF484, rct_other_sound)[i]; + 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); + RCT2_GLOBAL(0x014241BC, uint32) = 0; + if (!v5) { + return; + } + const char * filepath = get_file_path(2); + RCT2_GLOBAL(0x014241BC, uint32) = 1; + int v8 = RCT2_CALLFUNC_1(0x00404C1A, int, const char *, filepath); + RCT2_GLOBAL(0x014241BC, uint32) = 0; + if (!v8) { + RCT2_GLOBAL(0x014241BC, uint32) = 1; + RCT2_CALLPROC(0x00404BD2); + 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]; + RCT2_GLOBAL(0x009AAC5C, uint8) = 1; + config_save(); + RCT2_GLOBAL(0x014241BC, uint32) = 1; + int result = RCT2_CALLFUNC(0x004018A6, int); // create multimedia timer + RCT2_GLOBAL(0x014241BC, uint32) = 0; + if (result) { + if ((RCT2_GLOBAL(0x009AF284, uint32) & (1 << 0))) { + for (int i = 0; i < 2; i++) { + RCT2_GLOBAL(0x009AF46C + (i * 8), uint8) = -1; + } + } + } + if (!RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) & 1 << 4) { + RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_SOUND_SW_BUFFER, uint32) = RCT2_GLOBAL(0x001425B74, uint32) != RCT2_GLOBAL(0x001425B78, uint32) || RCT2_GLOBAL(0x001425B74, uint32) != RCT2_GLOBAL(0x001425B7C, uint32); + RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) |= 1 << 4; + config_save(); + } +} + /** * * rct2: 0x0040502E @@ -74,14 +155,58 @@ void get_dsound_devices() RCT2_CALLPROC(0x0040502E); } +/** +* +* rct2: 0x00404C6D +*/ int sound_prepare(int sound_id, rct_sound *sound, int var_8, int var_c) { return RCT2_CALLFUNC_4(0x00404C6D, int, int, rct_sound*, int, int, sound_id, sound, var_8, var_c); } -void sound_play_panned(int sound_id, int x) +/** +* +* rct2: 0x006BB76E +*/ +int sound_play_panned(int sound_id, int x) { - RCT2_CALLPROC_X(0x006BB76E, sound_id, x, 0, 0, 0, 0, 0); + //RCT2_CALLPROC_X(0x006BB76E, sound_id, x, 0, 0, 0, 0, 0); + // this function is not complete, need to add in volume and pan adjust + int result = 0; + if (RCT2_GLOBAL(0x009AF59D, uint8) & 1) { + RCT2_GLOBAL(0x00F438AD, uint8) = 0; + int volume = 0; + if (x == 0x8001) { + // stuff to adjust volume + } + int i = 0; + rct_other_sound* other_sound = &RCT2_ADDRESS(0x009AF484, rct_other_sound)[i]; + while (other_sound->id != 0xFFFF) { + i++; + other_sound = &RCT2_ADDRESS(0x009AF484, rct_other_sound)[i]; + if (i > RCT2_GLOBAL(0x009AAC76, uint8)) { // too many sounds playing + return sound_id; + } + } + other_sound->id = sound_id; + int pan; + if (x == 0x8000) { + pan = 0; + } else { + // stuff to adjust pan + } + if (!RCT2_GLOBAL(0x009AAC6D, uint8)) { + pan = 0; + } + + RCT2_GLOBAL(0x014241BC, uint32) = 1; + sound_prepare(sound_id, &other_sound->sound, 1, RCT2_GLOBAL(0x009AAC6E, uint32)); + RCT2_GLOBAL(0x014241BC, uint32) = 0; + RCT2_GLOBAL(0x014241BC, uint32) = 1; + result = sound_play(&other_sound->sound, 0, volume, pan, 0); + RCT2_GLOBAL(0x014241BC, uint32) = 0; + } + return result; } /** @@ -294,7 +419,7 @@ void pause_sounds() */ void stop_other_sounds() { - if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SOUND_DEVICE, uint32) != 0xFFFFFFFF) { + if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SOUND_DEVICE, uint32) != -1) { if (RCT2_GLOBAL(0x009AF5A8, uint32) != 1) { RCT2_GLOBAL(0x014241BC, uint32) = 1; sound_stop(RCT2_GLOBAL(0x009AF5AC, rct_sound*)); @@ -325,7 +450,7 @@ void stop_vehicle_sounds() if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SOUND_DEVICE, sint32) != -1) { for (int i = 0; i < 7; i++) { rct_vehicle_sound* vehicle_sound = &RCT2_ADDRESS(RCT2_ADDRESS_VEHICLE_SOUND_LIST, rct_vehicle_sound)[i]; - if (vehicle_sound->var_0 != 0xFFFF) { + if (vehicle_sound->id != 0xFFFF) { if (vehicle_sound->var_18 != 0xFFFF) { RCT2_GLOBAL(0x014241BC, uint32) = 1; sound_stop(&vehicle_sound->sound1); @@ -337,7 +462,7 @@ void stop_vehicle_sounds() RCT2_GLOBAL(0x014241BC, uint32) = 0; } } - vehicle_sound->var_0 = 0xFFFF; + vehicle_sound->id = 0xFFFF; } } } @@ -396,6 +521,7 @@ int sound_channel_stop(int channel) if (dsbuffer) { dsbuffer->lpVtbl->Stop(dsbuffer); dsbuffer->lpVtbl->Release(dsbuffer); + RCT2_ADDRESS(RCT2_ADDRESS_DSOUND_BUFFERS, LPDIRECTSOUNDBUFFER)[channel] = 0; } InterlockedExchange(&RCT2_GLOBAL(0x009E1AAC, int), 0); return 1; diff --git a/src/audio.h b/src/audio.h index ddc9f46d72..e7430cec61 100644 --- a/src/audio.h +++ b/src/audio.h @@ -33,6 +33,7 @@ extern audio_device *gAudioDevices; void audio_init(); void audio_quit(); void audio_get_devices(); +void audio_init2(int device); #include @@ -69,7 +70,7 @@ typedef struct { } rct_sound_channel; typedef struct { - uint16 var_0; + uint16 id; uint16 var_2; rct_sound sound1; // 0x04 uint16 var_18; @@ -79,9 +80,14 @@ typedef struct { uint8 pad_36[0x06]; } rct_vehicle_sound; +typedef struct { + uint16 id; + rct_sound sound; +} rct_other_sound; + void get_dsound_devices(); int sound_prepare(int sound_id, rct_sound *sound, int var_8, int var_c); -void sound_play_panned(int sound_id, int x); +int sound_play_panned(int sound_id, int x); int sound_play(rct_sound* sound, int looping, int volume, int pan, int frequency); int sound_is_playing(rct_sound* sound); int sound_set_frequency(rct_sound* sound, int frequency); diff --git a/src/game.c b/src/game.c index 2ea9e63a97..4b8a8a8cb1 100644 --- a/src/game.c +++ b/src/game.c @@ -388,6 +388,8 @@ void game_logic_update() news_item_update_current(); RCT2_CALLPROC_EBPSAFE(0x0067009A); // scenario editor opening of windows for a phase + RCT2_CALLPROC_EBPSAFE(0x006BB991); // removes other sounds that are no longer playing, this is normally called somewhere in rct2_init + // Update windows window_dispatch_update_all(); diff --git a/src/window_options.c b/src/window_options.c index 952e294d86..8190d761ed 100644 --- a/src/window_options.c +++ b/src/window_options.c @@ -500,13 +500,15 @@ static void window_options_dropdown() switch (widgetIndex) { case WIDX_SOUND_DROPDOWN: - #ifdef _MSC_VER + audio_init2(dropdownIndex); + /*#ifdef _MSC_VER __asm movzx ax, dropdownIndex #else __asm__ ( "movzx ax, %[dropdownIndex] " : : [dropdownIndex] "g" ((char)dropdownIndex) ); #endif // the switch replaces ax value - RCT2_CALLPROC_EBPSAFE(0x006BA9B5); // part of init audio + RCT2_CALLPROC_EBPSAFE(0x006BA9B5); // part of init audio*/ + window_invalidate(w); break; case WIDX_HEIGHT_LABELS_DROPDOWN: