diff --git a/src/audio/audio.c b/src/audio/audio.c index ea9d9fa39f..8137a37f8f 100644 --- a/src/audio/audio.c +++ b/src/audio/audio.c @@ -34,7 +34,11 @@ audio_device *gAudioDevices = NULL; rct_vehicle_sound gVehicleSoundList[AUDIO_MAX_VEHICLE_SOUNDS]; rct_vehicle_sound_params gVehicleSoundParamsList[AUDIO_MAX_VEHICLE_SOUNDS]; rct_vehicle_sound_params *gVehicleSoundParamsListEnd; -void* gMusicChannels[4]; +rct_ride_music gRideMusicList[AUDIO_MAX_RIDE_MUSIC]; +rct_ride_music_params gRideMusicParamsList[AUDIO_MAX_RIDE_MUSIC]; +rct_ride_music_params *gRideMusicParamsListEnd; +void *gCrowdSoundChannel = 0; +void *gTitleMusicChannel = 0; void audio_init(int i) { @@ -1543,7 +1547,7 @@ void start_title_music() if ((RCT2_GLOBAL(0x009AF284, uint32) & (1 << 0)) && RCT2_GLOBAL(0x009AF59D, uint8) & 1 && RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 1) { if (!RCT2_GLOBAL(0x009AF600, uint8)) { #ifdef USE_MIXER - gMusicChannels[3] = Mixer_Play_Music(PATH_ID_CSS17); + gTitleMusicChannel = Mixer_Play_Music(PATH_ID_CSS17); #else RCT2_GLOBAL(0x014241BC, uint32) = 1; int result = sound_channel_load_file2(3, (char*)get_file_path(PATH_ID_CSS17), 0); @@ -1598,13 +1602,17 @@ void stop_other_sounds() void stop_ride_music() { if ((RCT2_GLOBAL(0x009AF284, uint32) & (1 << 0))) { - for (int i = 0; i < 2; i++) { - rct_music_info2* music_info2 = &RCT2_ADDRESS(0x009AF46C, rct_music_info2)[i]; - if (music_info2->id != (uint8)-1) { + for (int i = 0; i < AUDIO_MAX_RIDE_MUSIC; i++) { + rct_ride_music* ride_music = &gRideMusicList[i];//&RCT2_ADDRESS(0x009AF46C, rct_ride_music)[i]; + if (ride_music->rideid != (uint8)-1) { +#ifdef USE_MIXER + Mixer_Stop_Channel(ride_music->sound_channel); +#else RCT2_GLOBAL(0x014241BC, uint32) = 1; sound_channel_stop(i); RCT2_GLOBAL(0x014241BC, uint32) = 0; - music_info2->id = -1; +#endif + ride_music->rideid = -1; } } } @@ -1619,9 +1627,9 @@ void stop_crowd_sound() if ((RCT2_GLOBAL(0x009AF284, uint32) & (1 << 0))) { if (RCT2_GLOBAL(0x009AF5FC, uint32) != 1) { #ifdef USE_MIXER - if (gMusicChannels[2]) { - Mixer_Stop_Channel(gMusicChannels[2]); - gMusicChannels[2] = 0; + if (gCrowdSoundChannel) { + Mixer_Stop_Channel(gCrowdSoundChannel); + gCrowdSoundChannel = 0; } #else RCT2_GLOBAL(0x014241BC, uint32) = 1; @@ -1642,9 +1650,9 @@ void stop_title_music() if (RCT2_GLOBAL(0x009AF284, uint32) & (1 << 0)) { if (RCT2_GLOBAL(0x009AF600, uint8) != 0) { #ifdef USE_MIXER - if (gMusicChannels[3]) { - Mixer_Stop_Channel(gMusicChannels[3]); - gMusicChannels[3] = 0; + if (gTitleMusicChannel) { + Mixer_Stop_Channel(gTitleMusicChannel); + gTitleMusicChannel = 0; } #else RCT2_GLOBAL(0x014241BC, uint32) = 1; @@ -1680,8 +1688,8 @@ void audio_init1() audio_init2(devicenum); int m = 0; do { - rct_music_info3* music_info3 = &RCT2_GLOBAL(0x009AF1C8, rct_music_info3*)[m]; - const char* path = get_file_path(music_info3->pathid); + rct_ride_music_info* ride_music_info = &RCT2_GLOBAL(0x009AF1C8, rct_ride_music_info*)[m]; + const char* path = get_file_path(ride_music_info->pathid); RCT2_GLOBAL(0x014241BC, uint32) = 3; HANDLE hfile = osinterface_file_open(path); RCT2_GLOBAL(0x014241BC, uint32) = 0; @@ -1691,7 +1699,7 @@ void audio_init1() osinterface_file_close(hfile); RCT2_GLOBAL(0x014241BC, uint32) = 0; if (RCT2_GLOBAL(0x009AF47E, uint32) == 0x78787878) { - music_info3->var_0 = 0; + ride_music_info->var_0 = 0; } } m++; @@ -1705,7 +1713,7 @@ void audio_init1() void audio_init2(int device) { audio_close(); - for (int i = 0; i < countof(gVehicleSoundList)/*7*/; i++) { + for (int i = 0; i < AUDIO_MAX_VEHICLE_SOUNDS/*7*/; i++) { rct_vehicle_sound* vehicle_sound = &gVehicleSoundList[i]; //rct_vehicle_sound* vehicle_sound = &RCT2_ADDRESS(RCT2_ADDRESS_VEHICLE_SOUND_LIST, rct_vehicle_sound)[i]; vehicle_sound->id = 0xFFFF; @@ -1740,9 +1748,9 @@ void audio_init2(int device) RCT2_GLOBAL(0x014241BC, uint32) = 0; if (successtimer) { RCT2_GLOBAL(0x009AF284, uint32) |= (1 << 0); - for (int i = 0; i < 2; i++) { - rct_music_info2* music_info2 = &RCT2_ADDRESS(0x009AF46C, rct_music_info2)[i]; - music_info2->id = -1; + for (int i = 0; i < AUDIO_MAX_RIDE_MUSIC; i++) { + rct_ride_music* ride_music = &gRideMusicList[i];//&RCT2_ADDRESS(0x009AF46C, rct_ride_music)[i]; + ride_music->rideid = -1; } } if (!(RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) & 1 << 4)) { @@ -1834,353 +1842,4 @@ void stop_vehicle_sounds() vehicle_sound->id = 0xFFFF; } } -} - -/** - * - * rct2: 0x006BC3AC - * Update ride music - * cant properly hook this function, because the EBP register is used as a return value, - * so it isn't fully tested. need to decompile 6ABE4C (ride_update_all) first - * @param x (ax) - * @param y (cx) - * @param z (dx) - * @param sampleRate (di) - * @param rideIndex (bl) - * @param position (ebp) - * @param tuneId (bh) - * @returns new position (ebp) - */ -int sub_6BC3AC(sint16 x, sint16 y, sint16 z, uint8 rideIndex, uint16 sampleRate, uint32 position, uint8 *tuneId) -{ - { - int a_eax, a_ebx, a_ecx, a_edx, a_esi, a_edi, a_ebp; - - a_eax = x; - a_ebx = (*tuneId << 8) | rideIndex; - a_ecx = y; - a_edx = z; - a_edi = sampleRate; - a_ebp = position; - RCT2_CALLFUNC_X(0x006BC3AC, &a_eax, &a_ebx, &a_ecx, &a_edx, &a_esi, &a_edi, &a_ebp); - - *tuneId = (a_ebx >> 8) & 0xFF; - return a_ebp; - } - - // TODO fix / bh needs returning too! - if(!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_SCENARIO_EDITOR) && !RCT2_GLOBAL(0x009AF59C, uint8) && RCT2_GLOBAL(0x00F438A4, rct_viewport*) != (rct_viewport*)-1) { - RCT2_GLOBAL(0x009AF47C, uint16) = sampleRate; - sint16 v11; - sint16 v12; - switch (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32)) { - case 0: - v11 = y - x; - v12 = ((y + x) / 2) - z; - break; - case 1: - v11 = -x - y; - v12 = ((y - x) / 2) - z; - break; - case 2: - v11 = x - y; - v12 = ((-y - x) / 2) - z; - break; - case 3: - v11 = y + x; - v12 = ((x - y) / 2) - z; - break; - } - RCT2_GLOBAL(0x009AF5A0, sint16) = v11; - RCT2_GLOBAL(0x009AF5A2, sint16) = v12; - rct_viewport* viewport = RCT2_GLOBAL(0x00F438A4, rct_viewport*); - sint16 view_width = RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_width; - sint16 view_width2 = view_width * 2; - sint16 view_x = RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_x - view_width2; - sint16 view_y = RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_y - view_width; - sint16 v16 = view_width2 + view_width2 + RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_width + view_x; - sint16 v17 = view_width + view_width + RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_height + view_y; - if (view_x >= RCT2_GLOBAL(0x009AF5A0, sint16) || - view_y >= RCT2_GLOBAL(0x009AF5A2, sint16) || - v16 < RCT2_GLOBAL(0x009AF5A0, sint16) || - v17 < RCT2_GLOBAL(0x009AF5A2, sint16)) { - goto label58; - } - int x2 = RCT2_GLOBAL(0x00F438A4, rct_viewport*)->x + ((RCT2_GLOBAL(0x009AF5A0, sint16) - RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_x) >> RCT2_GLOBAL(0x00F438A4, rct_viewport*)->zoom); - x2 <<= 16; - uint16 screenwidth = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, uint16); - if (screenwidth < 64) { - screenwidth = 64; - } - int panx = ((x2 / screenwidth) - 0x8000) >> 4; - - int y2 = RCT2_GLOBAL(0x00F438A4, rct_viewport*)->y + ((RCT2_GLOBAL(0x009AF5A2, sint16) - RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_y) >> RCT2_GLOBAL(0x00F438A4, rct_viewport*)->zoom); - y2 <<= 16; - uint16 screenheight = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, uint16); - if (screenheight < 64) { - screenheight = 64; - } - int pany = ((y2 / screenheight) - 0x8000) >> 4; - - uint8 v24l = -1; - uint8 v24h = -1; - if (pany < 0) { - pany = -pany; - } - if (pany > 6143) { - pany = 6143; - } - if (pany > 2048) { - uint16 v27 = -(((pany - 2048) >> 2) - 1024) >> 2; - v24l = (uint8)v27; - if (v27 & 0xFF00) { - v24l = -1; - } - } - - if (panx < 0) { - panx = -panx; - } - if (panx > 6143) { - panx = 6143; - } - if (panx > 2048) { - uint16 v27 = -(((panx - 2048) >> 2) - 1024) >> 2; - v24h = (uint8)v27; - if (v27 & 0xFF00) { - v24h = -1; - } - } - - if (v24l >= v24h) { - v24l = v24h; - } - - sint8 v31 = v24l - (3 * RCT2_GLOBAL(RCT2_ADDRESS_VOLUME_ADJUST_ZOOM, uint8)); - if (v24l < (3 * RCT2_GLOBAL(RCT2_ADDRESS_VOLUME_ADJUST_ZOOM, uint8))) { - v31 = 0; - } - int v32 = -(((-v31 - 1) * (-v31 - 1)) >> 4) - 700; - if (v31 && v32 >= -4000) { - if (panx > 10000) { - panx = 10000; - } - if (panx < -10000) { - panx = -10000; - } - if (!RCT2_GLOBAL(0x009AAC6D, uint8)) { - panx = 0; - } - rct_music_info2* music_info2 = &RCT2_GLOBAL(0x009AF46C, rct_music_info2); - int channel = 0; - uint32 a1; - while (music_info2->id != rideIndex && music_info2->var_1 != *tuneId) { - music_info2++; - channel++; - if (channel >= 2) { - rct_music_info3* music_info3 = &RCT2_GLOBAL(0x009AF1C8, rct_music_info3*)[*tuneId]; - a1 = position + music_info3->var_4; - goto label51; - } - } - RCT2_GLOBAL(0x014241BC, uint32) = 1; - int playing = sound_channel_is_playing(channel); - RCT2_GLOBAL(0x014241BC, uint32) = 0; - if (!playing) { - return 0; - } - RCT2_GLOBAL(0x014241BC, uint32) = 1; - a1 = sub_401B46(channel); - RCT2_GLOBAL(0x014241BC, uint32) = 0; - label51: - if (a1 < RCT2_GLOBAL(0x009AF1C8, rct_music_info3*)[*tuneId].var_0) { - rct_music_info* music_info = RCT2_GLOBAL(0x009AF42C, rct_music_info*); - if (music_info < (rct_music_info*)0x009AF46C/*music_info list end*/) { - music_info->id = rideIndex; - music_info->var_1 = *tuneId; - music_info->offset = a1; - music_info->volume = v32; - music_info->pan = panx; - music_info->freq = RCT2_GLOBAL(0x009AF47C, uint16); - RCT2_GLOBAL(0x009AF42C, rct_music_info*)++; - } - } - } else { - uint32 eax; - label58: - eax = position; - position = *tuneId; - rct_music_info3* music_info3 = &RCT2_GLOBAL(0x009AF1C8, rct_music_info3*)[*tuneId]; - eax += music_info3->var_4; - if (eax < music_info3->var_0) { - position = eax; - } - } - } - return position; -} - -/** -* Play/update ride music based on structs updated in 0x006BC3AC -* rct2: 0x006BC6D8 -*/ -void sub_6BC6D8() -{ - rct_music_info* edi; - int ebx; - if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 2)) { - if ((RCT2_GLOBAL(0x009AF284, uint32) & (1 << 0))) { - if (!RCT2_GLOBAL(0x009AF59C, uint8) && RCT2_GLOBAL(0x009AF59D, uint8) & 1 && RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_MUSIC, uint8) && !(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 1)) { - // set to stop music if volume <= 1 ? - while (1) { - int v8 = 0; - int v9 = 1; - rct_music_info* music_info = &RCT2_GLOBAL(0x009AF430, rct_music_info); - while (music_info < RCT2_GLOBAL(0x009AF42C, rct_music_info*)) { - if (music_info->id != (uint8)-1) { - rct_music_info3* music_info3 = &RCT2_GLOBAL(0x009AF1C8, rct_music_info3*)[music_info->var_1]; - if (RCT2_ADDRESS(0x009AA0B1, uint8*)[music_info3->pathid]) { // file_on_cdrom[] - v8++; - if (v9 >= music_info->volume) { - v9 = music_info->volume; - edi = music_info; - } - } - } - music_info++; - } - if (v8 <= 1) { - break; - } - edi->id = -1; - } - while (1) { - int v8 = 0; - int v9 = 1; - rct_music_info* music_info = &RCT2_GLOBAL(0x009AF430, rct_music_info); - while (music_info < RCT2_GLOBAL(0x009AF42C, rct_music_info*)) { - if (music_info->id != (uint8)-1) { - v8++; - if (v9 >= music_info->volume) { - v9 = music_info->volume; - edi = music_info; - } - } - music_info++; - } - if (v8 <= 2) { - break; - } - edi->id = -1; - } - - // stop currently playing music that is not in music_info list or not playing? - rct_music_info2* music_info2 = &RCT2_GLOBAL(0x009AF46C, rct_music_info2); - int channel = 0; - do { - if (music_info2->id != (uint8)-1) { - rct_music_info* music_info = &RCT2_GLOBAL(0x009AF430, rct_music_info); - while (music_info < RCT2_GLOBAL(0x009AF42C, rct_music_info*)) { - if (music_info->id == music_info2->id && music_info->var_1 == music_info2->var_1) { - RCT2_GLOBAL(0x014241BC, uint32) = 1; - int v16 = sound_channel_is_playing(channel); - RCT2_GLOBAL(0x014241BC, uint32) = 0; - if (v16) { - goto label32; - } - break; - } - music_info++; - } - RCT2_GLOBAL(0x014241BC, uint32) = 1; - sound_channel_stop(channel); - RCT2_GLOBAL(0x014241BC, uint32) = 0; - music_info2->id = -1; - } - label32: - music_info2++; - channel++; - } while(channel < 2); - - for (rct_music_info* music_info = &RCT2_GLOBAL(0x009AF430, rct_music_info); music_info < RCT2_GLOBAL(0x009AF42C, rct_music_info*); music_info++) { - if (music_info->id != (uint8)-1) { - rct_music_info2* music_info2 = &RCT2_GLOBAL(0x009AF46C, rct_music_info2); - int channel = 0; - while (music_info->id != music_info2->id || music_info->var_1 != music_info2->var_1) { - if (music_info2->id == (uint8)-1) { - ebx = channel; - } - music_info2++; - channel++; - if (channel >= 2) { - rct_music_info3* music_info3 = &RCT2_GLOBAL(0x009AF1C8, rct_music_info3*)[music_info->var_1]; - const char* filename = get_file_path(music_info3->pathid); - RCT2_GLOBAL(0x014241BC, uint32) = 3; - HANDLE hfile = osinterface_file_open(filename); - RCT2_GLOBAL(0x014241BC, uint32) = 0; - if (hfile != INVALID_HANDLE_VALUE) { - RCT2_GLOBAL(0x014241BC, uint32) = 3; - osinterface_file_read(hfile, &RCT2_GLOBAL(0x009AF47E, uint32), 4); - RCT2_GLOBAL(0x014241BC, uint32) = 3; - osinterface_file_close(hfile); - RCT2_GLOBAL(0x014241BC, uint32) = 0; - } - if (hfile == INVALID_HANDLE_VALUE || RCT2_GLOBAL(0x009AF47E, uint32) != 0x78787878) { - int offset = music_info->offset - 10000; - if (offset < 0) { - offset = 0; - } - RCT2_GLOBAL(0x014241BC, uint32) = 1; - int musicloaded = sound_channel_load_file2(ebx, filename, offset & 0xFFFFFFF0); - RCT2_GLOBAL(0x014241BC, uint32) = 0; - if (musicloaded) { - RCT2_GLOBAL(0x014241BC, uint32) = 1; - int musicplayed = sound_channel_play(ebx, 0, music_info->volume, music_info->pan, music_info->freq); - RCT2_GLOBAL(0x014241BC, uint32) = 0; - if (musicplayed) { - rct_music_info3* music_info3 = &RCT2_GLOBAL(0x009AF1C8, rct_music_info3*)[music_info->var_1]; - if (music_info3->var_9) { - RCT2_GLOBAL(0x014241BC, uint32) = 1; - sub_401AF3(ebx, get_file_path(music_info3->pathid), 1, 0); - RCT2_GLOBAL(0x014241BC, uint32) = 0; - } - rct_music_info2* music_info2 = &RCT2_ADDRESS(0x009AF46C, rct_music_info2)[ebx]; - music_info2->volume = music_info->volume; - music_info2->pan = music_info->pan; - music_info2->freq = music_info->freq; - music_info2->id = music_info->id; - music_info2->var_1 = music_info->var_1; - } - } else { - RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_MUSIC, uint8) = 0; - } - } - return; - } - } - - if (music_info->volume != music_info2->volume) { - music_info2->volume = music_info->volume; - RCT2_GLOBAL(0x014241BC, uint32) = 1; - sound_channel_set_volume(channel, music_info->volume); - RCT2_GLOBAL(0x014241BC, uint32) = 0; - } - if (music_info->pan != music_info2->pan) { - music_info2->pan = music_info->pan; - RCT2_GLOBAL(0x014241BC, uint32) = 1; - sound_channel_set_pan(channel, music_info->pan); - RCT2_GLOBAL(0x014241BC, uint32) = 0; - } - if (music_info->freq != music_info2->freq) { - music_info2->freq = music_info->freq; - RCT2_GLOBAL(0x014241BC, uint32) = 1; - sound_channel_set_frequency(channel, music_info->freq); - RCT2_GLOBAL(0x014241BC, uint32) = 0; - } - - } - } - } - } - } -} +} \ No newline at end of file diff --git a/src/audio/audio.h b/src/audio/audio.h index cc91205edc..3c2621afa9 100644 --- a/src/audio/audio.h +++ b/src/audio/audio.h @@ -32,6 +32,7 @@ extern int gAudioDeviceCount; extern audio_device *gAudioDevices; #define AUDIO_MAX_VEHICLE_SOUNDS 14 +#define AUDIO_MAX_RIDE_MUSIC 2 void audio_init(); void audio_quit(); @@ -121,33 +122,39 @@ typedef struct { } rct_other_sound; typedef struct { - uint8 id; - uint8 var_1; + uint8 rideid; + uint8 tuneid; sint32 offset; //0x2 sint16 volume; //0x6 sint16 pan; //0x8 uint16 freq; //0xA -} rct_music_info; +} rct_ride_music_params; typedef struct { - uint8 id; - uint8 var_1; - uint16 volume; //0x2 - uint16 pan; //0x4 + uint8 rideid; + uint8 tuneid; + sint16 volume; //0x2 + sint16 pan; //0x4 uint16 freq; //0x6 -} rct_music_info2; + // added to openrct2: + void* sound_channel; +} rct_ride_music; typedef struct { uint32 var_0; uint32 var_4; uint8 pathid; //0x8 uint8 var_9; -} rct_music_info3; +} rct_ride_music_info; extern rct_vehicle_sound gVehicleSoundList[AUDIO_MAX_VEHICLE_SOUNDS]; extern rct_vehicle_sound_params gVehicleSoundParamsList[AUDIO_MAX_VEHICLE_SOUNDS]; extern rct_vehicle_sound_params *gVehicleSoundParamsListEnd; -extern void* gMusicChannels[4]; +extern rct_ride_music gRideMusicList[AUDIO_MAX_RIDE_MUSIC]; +extern rct_ride_music_params gRideMusicParamsList[AUDIO_MAX_RIDE_MUSIC]; +extern rct_ride_music_params *gRideMusicParamsListEnd; +extern void *gCrowdSoundChannel; +extern void *gTitleMusicChannel; void audio_timefunc(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2, int channel); int CALLBACK audio_timer_callback(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2); @@ -213,8 +220,6 @@ void audio_close(); void pause_sounds(); void unpause_sounds(); void stop_vehicle_sounds(); -void sub_6BC6D8(); -int sub_6BC3AC(sint16 x, sint16 y, sint16 z, uint8 rideIndex, uint16 sampleRate, uint32 position, uint8 *tuneId); // 0x009AF59C probably does the same job // once it's confirmed and calls in pause_sounds() are reversed, it can be used instead of this diff --git a/src/audio/mixer.cpp b/src/audio/mixer.cpp index 428431f787..042f349a78 100644 --- a/src/audio/mixer.cpp +++ b/src/audio/mixer.cpp @@ -205,6 +205,7 @@ Channel::Channel() SetPan(0.5f); done = true; stopping = false; + stream = 0; } Channel::~Channel() @@ -260,6 +261,21 @@ bool Channel::IsPlaying() return !done; } +unsigned long Channel::GetOffset() +{ + return offset; +} + +bool Channel::SetOffset(unsigned long offset) +{ + if (stream && offset < stream->Length()) { + int samplesize = stream->Format()->channels * stream->Format()->BytesPerSample(); + Channel::offset = (offset / samplesize) * samplesize; + return true; + } + return false; +} + void Mixer::Init(const char* device) { Close(); @@ -281,7 +297,7 @@ void Mixer::Init(const char* device) css1samples[i].Convert(format); // convert to audio output format, saves some cpu usage but requires a bit more memory, optional css1streams[i].SetSource_Sample(css1samples[i]); } - effectbuffer = new uint8[(have.samples * format.BytesPerSample() * format.channels) + 200]; + effectbuffer = new uint8[(have.samples * format.BytesPerSample() * format.channels)]; SDL_PauseAudioDevice(deviceid, 0); } @@ -361,7 +377,7 @@ void SDLCALL Mixer::Callback(void* arg, uint8* stream, int length) void Mixer::MixChannel(Channel& channel, uint8* data, int length) { if (channel.stream && !channel.done) { - AudioFormat channelformat = *channel.stream->Format(); + AudioFormat streamformat = *channel.stream->Format(); int loaded = 0; SDL_AudioCVT cvt; cvt.len_ratio = 1; @@ -373,19 +389,20 @@ void Mixer::MixChannel(Channel& channel, uint8* data, int length) if (format.format == AUDIO_S16SYS) { rate = channel.rate; } - int samplestoread = (int)ceil((samples - samplesloaded) * rate); + int samplestoread = (int)((samples - samplesloaded) * rate); int lengthloaded = 0; if (channel.offset < channel.stream->Length()) { bool mustconvert = false; if (MustConvert(*channel.stream)) { - if (SDL_BuildAudioCVT(&cvt, channelformat.format, channelformat.channels, channelformat.freq, Mixer::format.format, Mixer::format.channels, Mixer::format.freq) == -1) { + if (SDL_BuildAudioCVT(&cvt, streamformat.format, streamformat.channels, streamformat.freq, Mixer::format.format, Mixer::format.channels, Mixer::format.freq) == -1) { break; } mustconvert = true; } const uint8* datastream = 0; - int readfromstream = (channel.stream->GetSome(channel.offset, &datastream, (int)(((samplestoread) * samplesize) / cvt.len_ratio)) / channelformat.BytesPerSample()) * channelformat.BytesPerSample(); + int toread = (int)(samplestoread / cvt.len_ratio) * samplesize; + int readfromstream = (channel.stream->GetSome(channel.offset, &datastream, toread)); if (readfromstream == 0) { break; } @@ -395,9 +412,10 @@ void Mixer::MixChannel(Channel& channel, uint8* data, int length) const uint8* tomix = 0; if (mustconvert) { + // tofix: there seems to be an issue with converting audio using SDL_ConvertAudio in the callback vs preconverted, can cause pops and static depending on sample rate and channels if (Convert(cvt, datastream, readfromstream, &dataconverted)) { tomix = dataconverted; - lengthloaded = (cvt.len_cvt / samplesize) * samplesize; + lengthloaded = cvt.len_cvt; } else { break; } @@ -408,12 +426,18 @@ void Mixer::MixChannel(Channel& channel, uint8* data, int length) bool effectbufferloaded = false; if (rate != 1 && format.format == AUDIO_S16SYS) { - int in_len = (int)(ceil((double)lengthloaded / samplesize)); - int out_len = samples + 20; // needs some extra, otherwise resampler sometimes doesn't process all the input samples + int in_len = (int)((double)lengthloaded / samplesize); + int out_len = samples; if (!channel.resampler) { channel.resampler = speex_resampler_init(format.channels, format.freq, format.freq, 0, 0); } - speex_resampler_set_rate(channel.resampler, format.freq, (int)(format.freq * (1 / rate))); + if (readfromstream == toread) { + // use buffer lengths for conversion ratio so that it fits exactly + speex_resampler_set_rate(channel.resampler, in_len, samples - samplesloaded); + } else { + // reached end of stream so we cant use buffer length as resampling ratio + speex_resampler_set_rate(channel.resampler, format.freq, (int)(format.freq * (1 / rate))); + } speex_resampler_process_interleaved_int(channel.resampler, (const spx_int16_t*)tomix, (spx_uint32_t*)&in_len, (spx_int16_t*)effectbuffer, (spx_uint32_t*)&out_len); effectbufferloaded = true; tomix = effectbuffer; @@ -612,6 +636,16 @@ int Mixer_Channel_IsPlaying(void* channel) return ((Channel*)channel)->IsPlaying(); } +unsigned long Mixer_Channel_GetOffset(void* channel) +{ + return ((Channel*)channel)->GetOffset(); +} + +int Mixer_Channel_SetOffset(void* channel, unsigned long offset) +{ + return ((Channel*)channel)->SetOffset(offset); +} + void* Mixer_Play_Music(int pathid) { if (gMixer.LoadMusic(pathid)) { diff --git a/src/audio/mixer.h b/src/audio/mixer.h index 1775c58b5c..6920986e92 100644 --- a/src/audio/mixer.h +++ b/src/audio/mixer.h @@ -94,6 +94,8 @@ public: void SetVolume(int volume); void SetPan(float pan); bool IsPlaying(); + unsigned long GetOffset(); + bool SetOffset(unsigned long offset); friend class Mixer; @@ -154,6 +156,8 @@ void Mixer_Channel_Volume(void* channel, int volume); void Mixer_Channel_Pan(void* channel, float pan); void Mixer_Channel_Rate(void* channel, double rate); int Mixer_Channel_IsPlaying(void* channel); +unsigned long Mixer_Channel_GetOffset(void* channel); +int Mixer_Channel_SetOffset(void* channel, unsigned long offset); void* Mixer_Play_Music(int pathid); static int DStoMixerVolume(int volume) { return (int)(SDL_MIX_MAXVOLUME * (SDL_pow(10, (float)volume / 2000))); }; diff --git a/src/interface/window.c b/src/interface/window.c index 6200194443..82dfc4e358 100644 --- a/src/interface/window.c +++ b/src/interface/window.c @@ -1822,7 +1822,7 @@ void window_update_viewport_ride_music() rct_viewport *viewport; rct_window *w; - RCT2_GLOBAL(0x009AF42C, rct_music_info*) = (rct_music_info*)0x009AF430; + gRideMusicParamsListEnd = &gRideMusicParamsList[0];//RCT2_GLOBAL(0x009AF42C, rct_ride_music_params*) = (rct_ride_music_params*)0x009AF430; RCT2_GLOBAL(0x00F438A4, rct_viewport*) = (rct_viewport*)-1; for (w = RCT2_LAST_WINDOW; w >= g_window_list; w--) { diff --git a/src/peep/peep.c b/src/peep/peep.c index 8bb9b1847a..a6b115788a 100644 --- a/src/peep/peep.c +++ b/src/peep/peep.c @@ -974,8 +974,8 @@ void peep_update_crowd_noise() // Mute crowd noise if (RCT2_GLOBAL(0x009AF5FC, uint32) != 1) { #ifdef USE_MIXER - Mixer_Stop_Channel(gMusicChannels[2]); - gMusicChannels[2] = 0; + Mixer_Stop_Channel(gCrowdSoundChannel); + gCrowdSoundChannel = 0; #else sound_channel_stop(2); //RCT2_CALLPROC_1(0x00401A05, int, 2); #endif @@ -994,9 +994,11 @@ void peep_update_crowd_noise() if (RCT2_GLOBAL(0x009AF5FC, uint32) == 1) { // Load and play crowd noise #ifdef USE_MIXER - gMusicChannels[2] = Mixer_Play_Music(PATH_ID_CSS2); - if (gMusicChannels[2]) { - Mixer_Channel_Volume(gMusicChannels[2], DStoMixerVolume(volume)); + if (!gCrowdSoundChannel) { + gCrowdSoundChannel = Mixer_Play_Music(PATH_ID_CSS2); + } + if (gCrowdSoundChannel) { + Mixer_Channel_Volume(gCrowdSoundChannel, DStoMixerVolume(volume)); RCT2_GLOBAL(0x009AF5FC, uint32) = volume; } #else @@ -1009,7 +1011,7 @@ void peep_update_crowd_noise() // Alter crowd noise volume if (RCT2_GLOBAL(0x009AF5FC, uint32) != volume) { #ifdef USE_MIXER - Mixer_Channel_Volume(gMusicChannels[2], DStoMixerVolume(volume)); + Mixer_Channel_Volume(gCrowdSoundChannel, DStoMixerVolume(volume)); #else sound_channel_set_volume(2, volume);//RCT2_CALLPROC_2(0x00401AD3, int, int, 2, volume); #endif diff --git a/src/ride/ride.c b/src/ride/ride.c index d51abeeb2c..f383bd5d32 100644 --- a/src/ride/ride.c +++ b/src/ride/ride.c @@ -21,6 +21,7 @@ #include #include "../addresses.h" #include "../audio/audio.h" +#include "../audio/mixer.h" #include "../game.h" #include "../input.h" #include "../interface/window.h" @@ -29,6 +30,7 @@ #include "../management/news_item.h" #include "../peep/peep.h" #include "../peep/staff.h" +#include "../platform/osinterface.h" #include "../scenario.h" #include "../util/util.h" #include "../windows/error.h" @@ -1022,7 +1024,7 @@ void ride_update_all() FOR_ALL_RIDES(i, ride) ride_update(i); - sub_6BC6D8(); + ride_music_update_final(); } /** @@ -1742,7 +1744,7 @@ static void ride_music_update(int rideIndex) sampleRate += 22050; } - ride->music_position = sub_6BC3AC(x, y, z, rideIndex, sampleRate, ride->music_position, &ride->music_tune_id); + ride->music_position = ride_music_params_update(x, y, z, rideIndex, sampleRate, ride->music_position, &ride->music_tune_id); } #pragma endregion @@ -2251,4 +2253,406 @@ void ride_set_map_tooltip(rct_map_element *mapElement) } } +/** + * + * rct2: 0x006BC3AC + * Update ride music parameters + * @param x (ax) + * @param y (cx) + * @param z (dx) + * @param sampleRate (di) + * @param rideIndex (bl) + * @param position (ebp) + * @param tuneId (bh) + * @returns new position (ebp) + */ +int ride_music_params_update(sint16 x, sint16 y, sint16 z, uint8 rideIndex, uint16 sampleRate, uint32 position, uint8 *tuneId) +{ + /*{ + int a_eax, a_ebx, a_ecx, a_edx, a_esi, a_edi, a_ebp; + + a_eax = x; + a_ebx = (*tuneId << 8) | rideIndex; + a_ecx = y; + a_edx = z; + a_edi = sampleRate; + a_ebp = position; + RCT2_CALLFUNC_X(0x006BC3AC, &a_eax, &a_ebx, &a_ecx, &a_edx, &a_esi, &a_edi, &a_ebp); + + *tuneId = (a_ebx >> 8) & 0xFF; + return a_ebp; + }*/ + if(!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_SCENARIO_EDITOR) && !RCT2_GLOBAL(0x009AF59C, uint8) && RCT2_GLOBAL(0x00F438A4, rct_viewport*) != (rct_viewport*)-1) { + RCT2_GLOBAL(0x009AF47C, uint16) = sampleRate; + sint16 v11; + sint16 v12; + switch (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32)) { + case 0: + v11 = y - x; + v12 = ((y + x) / 2) - z; + break; + case 1: + v11 = -x - y; + v12 = ((y - x) / 2) - z; + break; + case 2: + v11 = x - y; + v12 = ((-y - x) / 2) - z; + break; + case 3: + v11 = y + x; + v12 = ((x - y) / 2) - z; + break; + } + RCT2_GLOBAL(0x009AF5A0, sint16) = v11; + RCT2_GLOBAL(0x009AF5A2, sint16) = v12; + rct_viewport* viewport = RCT2_GLOBAL(0x00F438A4, rct_viewport*); + sint16 view_width = RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_width; + sint16 view_width2 = view_width * 2; + sint16 view_x = RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_x - view_width2; + sint16 view_y = RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_y - view_width; + sint16 v16 = view_width2 + view_width2 + RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_width + view_x; + sint16 v17 = view_width + view_width + RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_height + view_y; + if (view_x >= RCT2_GLOBAL(0x009AF5A0, sint16) || + view_y >= RCT2_GLOBAL(0x009AF5A2, sint16) || + v16 < RCT2_GLOBAL(0x009AF5A0, sint16) || + v17 < RCT2_GLOBAL(0x009AF5A2, sint16)) { + goto label58; + } + int x2 = RCT2_GLOBAL(0x00F438A4, rct_viewport*)->x + ((RCT2_GLOBAL(0x009AF5A0, sint16) - RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_x) >> RCT2_GLOBAL(0x00F438A4, rct_viewport*)->zoom); + x2 <<= 16; + uint16 screenwidth = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, uint16); + if (screenwidth < 64) { + screenwidth = 64; + } + int panx = ((x2 / screenwidth) - 0x8000) >> 4; + + int y2 = RCT2_GLOBAL(0x00F438A4, rct_viewport*)->y + ((RCT2_GLOBAL(0x009AF5A2, sint16) - RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_y) >> RCT2_GLOBAL(0x00F438A4, rct_viewport*)->zoom); + y2 <<= 16; + uint16 screenheight = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, uint16); + if (screenheight < 64) { + screenheight = 64; + } + int pany = ((y2 / screenheight) - 0x8000) >> 4; + + uint8 vol1 = -1; + uint8 vol2 = -1; + if (pany < 0) { + pany = -pany; + } + if (pany > 6143) { + pany = 6143; + } + pany -= 2048; + if (pany > 0) { + pany = -((pany / 4) - 1024) / 4; + vol1 = (uint8)pany; + if (pany >= 256) { + vol1 = -1; + } + } + + if (panx < 0) { + panx = -panx; + } + if (panx > 6143) { + panx = 6143; + } + panx -= 2048; + if (panx > 0) { + panx = -((panx / 4) - 1024) / 4; + vol2 = (uint8)panx; + if (panx >= 256) { + vol2 = -1; + } + } + if (vol1 >= vol2) { + vol1 = vol2; + } + if (vol1 < RCT2_GLOBAL(RCT2_ADDRESS_VOLUME_ADJUST_ZOOM, uint8) * 3) { + vol1 = 0; + } else { + vol1 = vol1 - (RCT2_GLOBAL(RCT2_ADDRESS_VOLUME_ADJUST_ZOOM, uint8) * 3); + } + int v32 = -(((uint8)(-vol1 - 1) * (uint8)(-vol1 - 1)) / 16) - 700; + if (vol1 && v32 >= -4000) { + if (panx > 10000) { + panx = 10000; + } + if (panx < -10000) { + panx = -10000; + } + if (!RCT2_GLOBAL(0x009AAC6D, uint8)) { + panx = 0; + } + rct_ride_music* ride_music = &gRideMusicList[0];//&RCT2_GLOBAL(0x009AF46C, rct_ride_music); + int channel = 0; + uint32 a1; + while (ride_music->rideid != rideIndex || ride_music->tuneid != *tuneId) { + ride_music++; + channel++; + if (channel >= AUDIO_MAX_RIDE_MUSIC) { + rct_ride_music_info* ride_music_info = &RCT2_GLOBAL(0x009AF1C8, rct_ride_music_info*)[*tuneId]; + a1 = position + ride_music_info->var_4; + goto label51; + } + } +#ifdef USE_MIXER + int playing = Mixer_Channel_IsPlaying(gRideMusicList[channel].sound_channel); +#else + RCT2_GLOBAL(0x014241BC, uint32) = 1; + int playing = sound_channel_is_playing(channel); + RCT2_GLOBAL(0x014241BC, uint32) = 0; +#endif + if (!playing) { + *tuneId = 0xFF; + return 0; + } +#ifdef USE_MIXER + a1 = Mixer_Channel_GetOffset(gRideMusicList[channel].sound_channel); +#else + RCT2_GLOBAL(0x014241BC, uint32) = 1; + a1 = sub_401B46(channel); + RCT2_GLOBAL(0x014241BC, uint32) = 0; +#endif + label51: + if (a1 < RCT2_GLOBAL(0x009AF1C8, rct_ride_music_info*)[*tuneId].var_0) { + position = a1; + rct_ride_music_params* ride_music_params = gRideMusicParamsListEnd;//RCT2_GLOBAL(0x009AF42C, rct_ride_music_params*); + if (ride_music_params < &gRideMusicParamsList[AUDIO_MAX_RIDE_MUSIC]/*(rct_ride_music_params*)0x009AF46C*/) { + ride_music_params->rideid = rideIndex; + ride_music_params->tuneid = *tuneId; + ride_music_params->offset = a1; + ride_music_params->volume = v32; + ride_music_params->pan = panx; + ride_music_params->freq = RCT2_GLOBAL(0x009AF47C, uint16); + gRideMusicParamsListEnd++;//RCT2_GLOBAL(0x009AF42C, rct_ride_music_params*)++; + } + } else { + *tuneId = 0xFF; + return 0; + } + } else { + label58: + ; + rct_ride_music_info* ride_music_info = &RCT2_GLOBAL(0x009AF1C8, rct_ride_music_info*)[*tuneId]; + position += ride_music_info->var_4; + if (position < ride_music_info->var_0) { + return position; + } else { + *tuneId = 0xFF; + return 0; + } + } + } + return position; +} + +/** +* Play/update ride music based on structs updated in 0x006BC3AC +* rct2: 0x006BC6D8 +*/ +void ride_music_update_final() +{ + rct_ride_music_params* edi; + int ebx; + if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 2)) { + if ((RCT2_GLOBAL(0x009AF284, uint32) & (1 << 0))) { + if (!RCT2_GLOBAL(0x009AF59C, uint8) && RCT2_GLOBAL(0x009AF59D, uint8) & 1 && RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_MUSIC, uint8) && !(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 1)) { + // set to stop music if volume <= 1 ? + while (1) { + int v8 = 0; + int v9 = 1; + rct_ride_music_params* ride_music_params = &gRideMusicParamsList[0];//&RCT2_GLOBAL(0x009AF430, rct_ride_music_params); + while (ride_music_params < gRideMusicParamsListEnd/*RCT2_GLOBAL(0x009AF42C, rct_ride_music_params*)*/) { + if (ride_music_params->rideid != (uint8)-1) { + rct_ride_music_info* ride_music_info = &RCT2_GLOBAL(0x009AF1C8, rct_ride_music_info*)[ride_music_params->tuneid]; + if (RCT2_ADDRESS(0x009AA0B1, uint8*)[ride_music_info->pathid]) { // file_on_cdrom[] + v8++; + if (v9 >= ride_music_params->volume) { + v9 = ride_music_params->volume; + edi = ride_music_params; + } + } + } + ride_music_params++; + } + if (v8 <= 1) { + break; + } + edi->rideid = -1; + } + while (1) { + int v8 = 0; + int v9 = 1; + rct_ride_music_params* ride_music_params = &gRideMusicParamsList[0];//&RCT2_GLOBAL(0x009AF430, rct_ride_music_params); + while (ride_music_params < gRideMusicParamsListEnd/*RCT2_GLOBAL(0x009AF42C, rct_ride_music_params*)*/) { + if (ride_music_params->rideid != (uint8)-1) { + v8++; + if (v9 >= ride_music_params->volume) { + v9 = ride_music_params->volume; + edi = ride_music_params; + } + } + ride_music_params++; + } + if (v8 <= 2) { + break; + } + edi->rideid = -1; + } + + // stop currently playing music that is not in music params list or not playing? + rct_ride_music* ride_music = &gRideMusicList[0];//&RCT2_GLOBAL(0x009AF46C, rct_ride_music); + int channel = 0; + do { + if (ride_music->rideid != (uint8)-1) { + rct_ride_music_params* ride_music_params = &gRideMusicParamsList[0];//&RCT2_GLOBAL(0x009AF430, rct_ride_music_params); + while (ride_music_params < gRideMusicParamsListEnd/*RCT2_GLOBAL(0x009AF42C, rct_ride_music_params*)*/) { + if (ride_music_params->rideid == ride_music->rideid && ride_music_params->tuneid == ride_music->tuneid) { +#ifdef USE_MIXER + int isplaying = Mixer_Channel_IsPlaying(gRideMusicList[channel].sound_channel); +#else + RCT2_GLOBAL(0x014241BC, uint32) = 1; + int isplaying = sound_channel_is_playing(channel); + RCT2_GLOBAL(0x014241BC, uint32) = 0; +#endif + if (isplaying) { + goto label32; + } + break; + } + ride_music_params++; + } +#ifdef USE_MIXER + Mixer_Stop_Channel(gRideMusicList[channel].sound_channel); +#else + RCT2_GLOBAL(0x014241BC, uint32) = 1; + sound_channel_stop(channel); + RCT2_GLOBAL(0x014241BC, uint32) = 0; +#endif + ride_music->rideid = -1; + } + label32: + ride_music++; + channel++; + } while(channel < AUDIO_MAX_RIDE_MUSIC); + + for (rct_ride_music_params* ride_music_params = &gRideMusicParamsList[0]/*&RCT2_GLOBAL(0x009AF430, rct_ride_music_params)*/; ride_music_params < gRideMusicParamsListEnd/*RCT2_GLOBAL(0x009AF42C, rct_ride_music_params*)*/; ride_music_params++) { + if (ride_music_params->rideid != (uint8)-1) { + rct_ride_music* ride_music = &gRideMusicList[0];//&RCT2_GLOBAL(0x009AF46C, rct_ride_music); + int channel = 0; + while (ride_music_params->rideid != ride_music->rideid || ride_music_params->tuneid != ride_music->tuneid) { + if (ride_music->rideid == (uint8)-1) { + ebx = channel; + } + ride_music++; + channel++; + if (channel >= AUDIO_MAX_RIDE_MUSIC) { + rct_ride_music_info* ride_music_info = &RCT2_GLOBAL(0x009AF1C8, rct_ride_music_info*)[ride_music_params->tuneid]; +#ifdef USE_MIXER + rct_ride_music* ride_music = &gRideMusicList[ebx]; + ride_music->sound_channel = Mixer_Play_Music(ride_music_info->pathid); + if (ride_music->sound_channel) { + ride_music->volume = ride_music_params->volume; + ride_music->pan = ride_music_params->pan; + ride_music->freq = ride_music_params->freq; + ride_music->rideid = ride_music_params->rideid; + ride_music->tuneid = ride_music_params->tuneid; + Mixer_Channel_Volume(ride_music->sound_channel, DStoMixerVolume(ride_music->volume)); + Mixer_Channel_Pan(ride_music->sound_channel, DStoMixerPan(ride_music->pan)); + Mixer_Channel_Rate(ride_music->sound_channel, DStoMixerRate(ride_music->freq)); + int offset = ride_music_params->offset - 10000; + if (offset < 0) { + offset = 0; + } + Mixer_Channel_SetOffset(ride_music->sound_channel, offset); + } else { + RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_MUSIC, uint8) = 0; + } +#else + const char* filename = get_file_path(ride_music_info->pathid); + RCT2_GLOBAL(0x014241BC, uint32) = 3; + HANDLE hfile = osinterface_file_open(filename); + RCT2_GLOBAL(0x014241BC, uint32) = 0; + if (hfile != INVALID_HANDLE_VALUE) { + RCT2_GLOBAL(0x014241BC, uint32) = 3; + osinterface_file_read(hfile, &RCT2_GLOBAL(0x009AF47E, uint32), 4); + RCT2_GLOBAL(0x014241BC, uint32) = 3; + osinterface_file_close(hfile); + RCT2_GLOBAL(0x014241BC, uint32) = 0; + } + if (hfile == INVALID_HANDLE_VALUE || RCT2_GLOBAL(0x009AF47E, uint32) != 0x78787878) { + int offset = ride_music_params->offset - 10000; + if (offset < 0) { + offset = 0; + } + RCT2_GLOBAL(0x014241BC, uint32) = 1; + int musicloaded = sound_channel_load_file2(ebx, filename, offset & 0xFFFFFFF0); + RCT2_GLOBAL(0x014241BC, uint32) = 0; + if (musicloaded) { + RCT2_GLOBAL(0x014241BC, uint32) = 1; + int musicplayed = sound_channel_play(ebx, 0, ride_music_params->volume, ride_music_params->pan, ride_music_params->freq); + RCT2_GLOBAL(0x014241BC, uint32) = 0; + if (musicplayed) { + rct_ride_music_info* ride_music_info = &RCT2_GLOBAL(0x009AF1C8, rct_ride_music_info*)[ride_music_params->tuneid]; + if (ride_music_info->var_9) { + RCT2_GLOBAL(0x014241BC, uint32) = 1; + sub_401AF3(ebx, get_file_path(ride_music_info->pathid), 1, 0); + RCT2_GLOBAL(0x014241BC, uint32) = 0; + } + rct_ride_music* ride_music = &gRideMusicList[ebx];//&RCT2_ADDRESS(0x009AF46C, rct_ride_music)[ebx]; + ride_music->volume = ride_music_params->volume; + ride_music->pan = ride_music_params->pan; + ride_music->freq = ride_music_params->freq; + ride_music->rideid = ride_music_params->rideid; + ride_music->tuneid = ride_music_params->tuneid; + } + } else { + RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_MUSIC, uint8) = 0; + } + } +#endif + return; + } + } + + if (ride_music_params->volume != ride_music->volume) { + ride_music->volume = ride_music_params->volume; +#ifdef USE_MIXER + Mixer_Channel_Volume(ride_music->sound_channel, DStoMixerVolume(ride_music->volume)); +#else + RCT2_GLOBAL(0x014241BC, uint32) = 1; + sound_channel_set_volume(channel, ride_music_params->volume); + RCT2_GLOBAL(0x014241BC, uint32) = 0; +#endif + } + if (ride_music_params->pan != ride_music->pan) { + ride_music->pan = ride_music_params->pan; +#ifdef USE_MIXER + Mixer_Channel_Pan(ride_music->sound_channel, DStoMixerPan(ride_music->pan)); +#else + RCT2_GLOBAL(0x014241BC, uint32) = 1; + sound_channel_set_pan(channel, ride_music_params->pan); + RCT2_GLOBAL(0x014241BC, uint32) = 0; +#endif + } + if (ride_music_params->freq != ride_music->freq) { + ride_music->freq = ride_music_params->freq; +#ifdef USE_MIXER + Mixer_Channel_Rate(ride_music->sound_channel, DStoMixerRate(ride_music->freq)); +#else + RCT2_GLOBAL(0x014241BC, uint32) = 1; + sound_channel_set_frequency(channel, ride_music_params->freq); + RCT2_GLOBAL(0x014241BC, uint32) = 0; +#endif + } + + } + } + } + } + } +} + #pragma endregion \ No newline at end of file diff --git a/src/ride/ride.h b/src/ride/ride.h index 4d3e884ce1..8bfe4dcea9 100644 --- a/src/ride/ride.h +++ b/src/ride/ride.h @@ -628,5 +628,7 @@ void ride_breakdown_add_news_item(int rideIndex); rct_peep *ride_find_closest_mechanic(rct_ride *ride, int forInspection); int sub_6CC3FB(int rideIndex); void ride_set_map_tooltip(rct_map_element *mapElement); +int ride_music_params_update(sint16 x, sint16 y, sint16 z, uint8 rideIndex, uint16 sampleRate, uint32 position, uint8 *tuneId); +void ride_music_update_final(); #endif diff --git a/src/ride/vehicle.c b/src/ride/vehicle.c index a66327253f..0f905e4598 100644 --- a/src/ride/vehicle.c +++ b/src/ride/vehicle.c @@ -169,9 +169,13 @@ void vehicle_sounds_update() { if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SOUND_DEVICE, uint32) != -1 && !RCT2_GLOBAL(0x009AF59C, uint8) && RCT2_GLOBAL(0x009AF59D, uint8) & 1) { RCT2_GLOBAL(0x00F438A4, rct_viewport*) = (rct_viewport*)-1; - rct_window* window = RCT2_GLOBAL(RCT2_ADDRESS_NEW_WINDOW_PTR, rct_window*); rct_viewport* viewport = (rct_viewport*)-1; - for (window = RCT2_GLOBAL(RCT2_ADDRESS_NEW_WINDOW_PTR, rct_window*); window >= RCT2_ADDRESS(RCT2_ADDRESS_WINDOW_LIST, rct_window); window--) { + rct_window* window = RCT2_GLOBAL(RCT2_ADDRESS_NEW_WINDOW_PTR, rct_window*); + while (1) { + window--; + if (window < RCT2_ADDRESS(RCT2_ADDRESS_WINDOW_LIST, rct_window)) { + break; + } viewport = window->viewport; if (viewport && viewport->flags & VIEWPORT_FLAG_SOUND_ON) { break; diff --git a/src/world/climate.c b/src/world/climate.c index a47016445d..acae9b61d2 100644 --- a/src/world/climate.c +++ b/src/world/climate.c @@ -53,7 +53,7 @@ static const rct_weather_transition* climate_transitions[4]; // Sound data static int _rainVolume = 1; static rct_sound _rainSoundInstance; -static void* _rainSoundChannel; +static void* _rainSoundChannel = 0; static unsigned int _lightningTimer, _thunderTimer; static rct_sound _thunderSoundInstance[MAX_THUNDER_INSTANCES]; static void* _thunderSoundChannels[MAX_THUNDER_INSTANCES]; @@ -218,7 +218,9 @@ static void climate_update_rain_sound() if (_rainVolume == 1) { // Start playing the rain sound #ifdef USE_MIXER - _rainSoundChannel = Mixer_Play_Effect(SOUND_RAIN_1, MIXER_LOOP_INFINITE, DStoMixerVolume(-4000), 0.5f, 1, 0); + if (!_rainSoundChannel) { + _rainSoundChannel = Mixer_Play_Effect(SOUND_RAIN_1, MIXER_LOOP_INFINITE, DStoMixerVolume(-4000), 0.5f, 1, 0); + } #else if (sound_prepare(SOUND_RAIN_1, &_rainSoundInstance, 1, RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_SOUND_SW_BUFFER, uint32))) sound_play(&_rainSoundInstance, 1, -4000, 0, 0); @@ -250,6 +252,7 @@ static void climate_update_rain_sound() #ifdef USE_MIXER if (_rainSoundChannel) { Mixer_Stop_Channel(_rainSoundChannel); + _rainSoundChannel = 0; } #else sound_stop(&_rainSoundInstance);