1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-16 11:33:03 +01:00

Merge pull request #364 from zsilencer/master

Additional sound decompilation and fixes
This commit is contained in:
Ted John
2014-08-25 19:14:45 +01:00
7 changed files with 325 additions and 23 deletions

View File

@@ -106,6 +106,10 @@
#define RCT2_ADDRESS_INSTALLED_OBJECT_LIST 0x009ADAE8
#define RCT2_ADDRESS_CURRENT_SOUND_DEVICE 0x009AF280
#define RCT2_ADDRESS_VEHICLE_SOUND_LIST 0x009AF288
#define RCT2_ADDRESS_CURENT_CURSOR 0x009DE51C
#define RCT2_ADDRESS_INPUT_STATE 0x009DE51D
#define RCT2_ADDRESS_CURSOR_DOWN_WINDOWCLASS 0x009DE51F
@@ -310,7 +314,7 @@
#define RCT2_ADDRESS_COMMON_STRING_FORMAT_BUFFER 0x0141ED68
#define RCT2_ADDRESS_SOUND_CHANNEL_LIST 0x014262E0
#define RCT2_ADDRESS_WATER_RAISE_COST 0x0141F738
#define RCT2_ADDRESS_WATER_LOWER_COST 0x0141F73C

View File

@@ -21,6 +21,7 @@
#include <SDL.h>
#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;
}
/**
@@ -90,14 +215,15 @@ void sound_play_panned(int sound_id, int x)
*/
int sound_channel_play(int channel, int a2, int volume, int pan, int frequency)
{
RCT2_GLOBAL(0x1426444 + (91 * channel * 4), uint32) = a2;
rct_sound_channel* sound_channel = &RCT2_ADDRESS(RCT2_ADDRESS_SOUND_CHANNEL_LIST, rct_sound_channel)[channel];
sound_channel->var_164 = a2;
sound_channel_set_frequency(channel, frequency);
sound_channel_set_pan(channel, pan);
sound_channel_set_volume(channel, volume);
LPDIRECTSOUNDBUFFER dsbuffer = RCT2_ADDRESS(RCT2_ADDRESS_DSOUND_BUFFERS, LPDIRECTSOUNDBUFFER)[channel];
dsbuffer->lpVtbl->SetCurrentPosition(dsbuffer, 0);
dsbuffer->lpVtbl->Play(dsbuffer, 0, 0, DSBPLAY_LOOPING);
RCT2_GLOBAL(0x14262E0 + (91 * channel * 4), uint32) = 1;
sound_channel->var_0 = 1;
return 1;
}
@@ -172,6 +298,22 @@ int sound_play(rct_sound* sound, int looping, int volume, int pan, int frequency
return 0;
}
/**
*
* rct2: 0x00404E53
*/
int sound_is_playing(rct_sound* sound){
if (sound) {
DWORD status;
if (SUCCEEDED(sound->dsbuffer->lpVtbl->GetStatus(sound->dsbuffer, &status))) {
if (status & DSBSTATUS_PLAYING || status & DSBSTATUS_LOOPING)
return 1;
}
}
return 0;
}
/**
*
* rct2: 0x00404ED7
@@ -260,21 +402,137 @@ rct_sound* sound_remove(rct_sound* sound)
*
* rct2: 0x006BABB4
*/
void pause_sounds() {
void pause_sounds()
{
if (++RCT2_GLOBAL(0x009AF59C, uint8) == 1) {
RCT2_CALLPROC_EBPSAFE(0x006BCAE5);
RCT2_CALLPROC_EBPSAFE(0x006BABDF);
RCT2_CALLPROC_EBPSAFE(0x006BCA9F);
RCT2_CALLPROC_EBPSAFE(0x006BD07F);
stop_other_sounds();
stop_vehicle_sounds();
stop_ride_music();
stop_peep_sounds();
}
g_sounds_disabled = 1;
}
/**
*
* rct2: 0x006BCAE5
*/
void stop_other_sounds()
{
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*));
RCT2_GLOBAL(0x014241BC, uint32) = 0;
RCT2_GLOBAL(0x009AF5A8, uint32) = 1;
}
if (RCT2_GLOBAL(0x009AF5C0, uint32) != 8) {
RCT2_GLOBAL(0x014241BC, uint32) = 1;
sound_stop(RCT2_GLOBAL(0x009AF5C4, rct_sound*));
RCT2_GLOBAL(0x014241BC, uint32) = 0;
RCT2_GLOBAL(0x009AF5C0, uint32) = 8;
}
if (RCT2_GLOBAL(0x009AF5D8, uint32) != 8) {
RCT2_GLOBAL(0x014241BC, uint32) = 1;
sound_stop(RCT2_GLOBAL(0x009AF5DC, rct_sound*));
RCT2_GLOBAL(0x014241BC, uint32) = 0;
RCT2_GLOBAL(0x009AF5D8, uint32) = 8;
}
}
}
/**
*
* rct2: 0x006BABDF
*/
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->id != 0xFFFF) {
if (vehicle_sound->var_18 != 0xFFFF) {
RCT2_GLOBAL(0x014241BC, uint32) = 1;
sound_stop(&vehicle_sound->sound1);
RCT2_GLOBAL(0x014241BC, uint32) = 0;
}
if (vehicle_sound->var_34 != 0xFFFF) {
RCT2_GLOBAL(0x014241BC, uint32) = 1;
sound_stop(&vehicle_sound->sound2);
RCT2_GLOBAL(0x014241BC, uint32) = 0;
}
}
vehicle_sound->id = 0xFFFF;
}
}
}
/**
*
* rct2: 0x006BCA9F
*/
void stop_ride_music()
{
if ((RCT2_GLOBAL(0x009AF284, uint32) & (1 << 0))) {
for (int i = 0; i < 2; i++) {
uint8 * data = RCT2_ADDRESS(0x009AF46C + (i * 8), uint8);
if (data[0] != 0xFF) {
RCT2_GLOBAL(0x014241BC, uint32) = 1;
sound_channel_stop(i);
RCT2_GLOBAL(0x014241BC, uint32) = 0;
data[0] = 0xFF;
}
}
}
}
/**
*
* rct2: 0x006BD07F
*/
void stop_peep_sounds()
{
if ((RCT2_GLOBAL(0x009AF284, uint32) & (1 << 0))) {
if (RCT2_GLOBAL(0x009AF5FC, uint32) != 1) {
RCT2_GLOBAL(0x014241BC, uint32) = 1;
sound_channel_stop(2);
RCT2_GLOBAL(0x014241BC, uint32) = 0;
RCT2_GLOBAL(0x009AF5FC, uint32) = 1;
}
}
}
/**
*
* rct2: 0x00401A05
*/
int sound_channel_stop(int channel)
{
rct_sound_channel* sound_channel = &RCT2_ADDRESS(RCT2_ADDRESS_SOUND_CHANNEL_LIST, rct_sound_channel)[channel];
sound_channel->var_0 = 0;
sound_channel->var_160 = 1;
while (_InterlockedExchange(&RCT2_GLOBAL(0x009E1AAC, LONG), 1) != 1) {
Sleep(10);
}
if (sound_channel->var_120)
RCT2_CALLPROC_2(0x00405436, uint32, uint32, sound_channel->var_11C, sound_channel->var_120); // free_sound?
LPDIRECTSOUNDBUFFER dsbuffer = RCT2_ADDRESS(RCT2_ADDRESS_DSOUND_BUFFERS, LPDIRECTSOUNDBUFFER)[channel];
if (dsbuffer) {
dsbuffer->lpVtbl->Stop(dsbuffer);
dsbuffer->lpVtbl->Release(dsbuffer);
RCT2_ADDRESS(RCT2_ADDRESS_DSOUND_BUFFERS, LPDIRECTSOUNDBUFFER)[channel] = 0;
}
_InterlockedExchange(&RCT2_GLOBAL(0x009E1AAC, LONG), 0);
return 1;
}
/**
*
* rct2: 0x006BABD8
*/
void unpause_sounds() {
void unpause_sounds()
{
RCT2_GLOBAL(0x009AF59C, uint8)--;
g_sounds_disabled = 0;
}

View File

@@ -21,6 +21,8 @@
#ifndef _AUDIO_H_
#define _AUDIO_H_
#include "rct2.h"
typedef struct {
char name[256];
} audio_device;
@@ -31,6 +33,7 @@ extern audio_device *gAudioDevices;
void audio_init();
void audio_quit();
void audio_get_devices();
void audio_init2(int device);
#include <dsound.h>
@@ -55,10 +58,38 @@ typedef struct rct_sound {
struct rct_sound* next;
} rct_sound;
typedef struct {
uint32 var_0;
uint8 pad_4[0x118];
uint32 var_11C;
uint32 var_120;
uint8 pad_124[0x3C];
uint32 var_160;
uint32 var_164;
uint32 var_168;
} rct_sound_channel;
typedef struct {
uint16 id;
uint16 var_2;
rct_sound sound1; // 0x04
uint16 var_18;
uint8 pad_1A[0x06];
rct_sound sound2; // 0x20
uint16 var_34;
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);
int sound_set_pan(rct_sound* sound, int pan);
int sound_set_volume(rct_sound* sound, int volume);
@@ -67,8 +98,13 @@ 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);
void sound_stop(rct_sound *sound);
int sound_channel_stop(int channel);
rct_sound* sound_remove(rct_sound* sound);
void pause_sounds();
void stop_other_sounds();
void stop_vehicle_sounds();
void stop_ride_music();
void stop_peep_sounds();
void unpause_sounds();
// 0x009AF59C probably does the same job

View File

@@ -186,7 +186,7 @@ static void climate_determine_future_weather()
*/
void climate_update_sound()
{
if (RCT2_GLOBAL(0x009AF280, uint32) == 0xFFFFFFFF)
if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SOUND_DEVICE, uint32) == 0xFFFFFFFF)
return;
if (RCT2_GLOBAL(0x009AF59C, uint8) != 0)
return;
@@ -210,13 +210,13 @@ static void climate_update_rain_sound()
} else {
// Increase rain sound
_rainVolume = min(-1400, _rainVolume + 80);
RCT2_CALLPROC_2(0x00404F0D, rct_sound*, int, &_rainSoundInstance, _rainVolume);
sound_set_volume(&_rainSoundInstance, _rainVolume);
}
} else if (_rainVolume != 1) {
// Decrease rain sound
_rainVolume -= 80;
if (_rainVolume > -4000) {
RCT2_CALLPROC_2(0x00404F0D, rct_sound*, int, &_rainSoundInstance, _rainVolume);
sound_set_volume(&_rainSoundInstance, _rainVolume);
} else {
sound_stop(&_rainSoundInstance);
_rainVolume = 1;
@@ -248,7 +248,7 @@ static void climate_update_thunder_sound()
if (_thunderStatus[i] == THUNDER_STATUS_NULL)
continue;
if (!RCT2_CALLFUNC_1(0x00404E53, int, rct_sound*, &_thunderSoundInstance[i])) {
if (!sound_is_playing(&_thunderSoundInstance[i])) {
sound_stop(&_thunderSoundInstance[i]);
_thunderStatus[i] = THUNDER_STATUS_NULL;
}

View File

@@ -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();

View File

@@ -80,7 +80,7 @@ void intro_update()
// Chain lift sound
_sound_playing_flag = 0;
if (RCT2_GLOBAL(0x009AF280, sint32) != -1) {
if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SOUND_DEVICE, sint32) != -1) {
// Prepare and play the sound
if (sound_prepare(SOUND_LIFT_7, &_prepared_sound, 0, 1))
if (sound_play(&_prepared_sound, 1, 0, 0, 0))
@@ -157,7 +157,7 @@ void intro_update()
}
// Play the track friction sound
if (RCT2_GLOBAL(0x009AF280, sint32) != -1) {
if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SOUND_DEVICE, sint32) != -1) {
// Prepare and play the sound
if (sound_prepare(SOUND_TRACK_FRICTION_3, &_prepared_sound, 1, 1))
if (sound_play(&_prepared_sound, 1, -800, 0, 0x3A98))
@@ -188,7 +188,7 @@ void intro_update()
}
// Play long peep scream sound
if (RCT2_GLOBAL(0x009AF280, sint32) != -1)
if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SOUND_DEVICE, sint32) != -1)
if (sound_prepare(SOUND_SCREAM_1, &_prepared_sound, 0, 1))
if (sound_play(&_prepared_sound, 0, 0, 0, 0))
_sound_playing_flag = 1;

View File

@@ -379,7 +379,7 @@ static void window_options_mousedown(int widgetIndex, rct_window*w, rct_widget*
window_options_show_dropdown(w, widget, gAudioDeviceCount);
gDropdownItemsChecked |= (1 << RCT2_GLOBAL(0x9AF280, uint32));
gDropdownItemsChecked |= (1 << RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SOUND_DEVICE, uint32));
break;
case WIDX_HEIGHT_LABELS_DROPDOWN:
gDropdownItemsFormat[0] = 1142;
@@ -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:
@@ -670,7 +672,7 @@ static void window_options_invalidate()
window_options_widgets[WIDX_HEIGHT_LABELS_DROPDOWN].type = WWT_DROPDOWN_BUTTON;
break;
case WINDOW_OPTIONS_PAGE_AUDIO:
currentSoundDevice = RCT2_GLOBAL(0x009AF280, sint32);
currentSoundDevice = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SOUND_DEVICE, sint32);
// sound devices
if (currentSoundDevice == -1 || gAudioDeviceCount == 0) {