diff --git a/src/audio/audio.c b/src/audio/audio.c index c230a7bbaa..4a0f5fd2de 100644 --- a/src/audio/audio.c +++ b/src/audio/audio.c @@ -77,67 +77,367 @@ void audio_get_devices() /** * -* rct2: 0x00404BD2 +* rct2: 0x00401000 */ -int audio_release() +void audio_timefunc(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2, int channel) { - sound_stop_all(); - if (RCT2_GLOBAL(0x009E2BA4, LPDIRECTSOUND3DBUFFER)) { - RCT2_GLOBAL(0x009E2BA4, LPDIRECTSOUND3DBUFFER)->lpVtbl->Release(RCT2_GLOBAL(0x009E2BA4, LPDIRECTSOUND3DBUFFER)); - RCT2_GLOBAL(0x009E2BA4, LPDIRECTSOUND3DBUFFER) = 0; + rct_sound_channel* sound_channel = &RCT2_ADDRESS(0x014262E0, rct_sound_channel)[channel]; + DWORD status; + DWORD dwCurrentPlayCursor; + DWORD dwCurrentWriteCursor; + uint32 var1; + int var2; + int bufferlost = 0; + char* buf1; + int buf1size; + char* buf2; + int buf2size; + sound_channel->dsbuffer->lpVtbl->GetStatus(sound_channel->dsbuffer, &status); + if (status & DSBSTATUS_BUFFERLOST) { + if (FAILED(sound_channel->dsbuffer->lpVtbl->Restore(sound_channel->dsbuffer))) { + return; + } + sound_channel->playpos = 0; + bufferlost = 1; } - if (RCT2_GLOBAL(0x009E2BA8, LPDIRECTSOUNDBUFFER)) { - RCT2_GLOBAL(0x009E2BA8, LPDIRECTSOUNDBUFFER)->lpVtbl->Release(RCT2_GLOBAL(0x009E2BA8, LPDIRECTSOUNDBUFFER)); - RCT2_GLOBAL(0x009E2BA8, LPDIRECTSOUNDBUFFER) = 0; + sound_channel->dsbuffer->lpVtbl->GetCurrentPosition(sound_channel->dsbuffer, &dwCurrentPlayCursor, &dwCurrentWriteCursor); + if (dwCurrentPlayCursor != sound_channel->playpos || bufferlost) { + if (sound_channel->var_168 && !sound_channel->var_15C) { + if (!sound_channel->stopped) { + sound_channel->stopped = 1; + if (!sound_channel->var_4) { + LPDIRECTSOUNDBUFFER dsbuffer = RCT2_ADDRESS(RCT2_ADDRESS_DSOUND_BUFFERS, LPDIRECTSOUNDBUFFER)[channel]; + sound_channel->playing = 0; + if (dsbuffer) { + dsbuffer->lpVtbl->Stop(dsbuffer); + dsbuffer->lpVtbl->Release(dsbuffer); + RCT2_ADDRESS(RCT2_ADDRESS_DSOUND_BUFFERS, LPDIRECTSOUNDBUFFER)[channel] = 0; + } + if (sound_channel->hmmio) { + sound_channel_free(&sound_channel->hmmio, &sound_channel->hmem); + } + } + } + return; + } + if (dwCurrentPlayCursor >= sound_channel->playpos) { + var1 = dwCurrentPlayCursor - sound_channel->playpos; + } else { + var1 = dwCurrentPlayCursor + sound_channel->bufsize - sound_channel->playpos; + } + if (bufferlost) { + var2 = 2 * sound_channel->bufsize / 6; + } else { + var2 = var1; + } + sound_channel->var_158 += var1; + if (sound_channel->var_168) { + uint32 var3 = sound_channel->var_15C; + uint32* var4 = &sound_channel->var_15C; + if (var3) { + if (var1 <= var3) { + *var4 = var3 - var1; + } else { + *var4 = 0; + } + if (SUCCEEDED(sound_channel->dsbuffer->lpVtbl->Lock(sound_channel->dsbuffer, sound_channel->playpos, var2, (LPVOID*)&buf1, (LPDWORD)&buf1size, (LPVOID*)&buf2, (LPDWORD)&buf2size, 0))) { + uint16 var5 = -(sound_channel->mmckinfo1.cksize != 8); + var5 &= 0x80; + memset(buf1, var5 + 128, buf1size); + if (buf2 && buf2size) { + uint16 var5 = -(sound_channel->mmckinfo1.cksize != 8); + var5 &= 0x80; + memset(buf2, var5 + 128, buf2size); + } + sound_channel->dsbuffer->lpVtbl->Unlock(sound_channel->dsbuffer, buf1, buf1size, buf2, buf2size); + sound_channel->playpos += var2; + if (sound_channel->playpos >= sound_channel->bufsize) { + sound_channel->playpos = sound_channel->playpos - sound_channel->bufsize; + } + return; + } + // TimeFunc() could not lock DirectSoundBuffer + return; + } + } + if (FAILED(sound_channel->dsbuffer->lpVtbl->Lock(sound_channel->dsbuffer, sound_channel->playpos, var2, (LPVOID*)&buf1, (LPDWORD)&buf1size, (LPVOID*)&buf2, (LPDWORD)&buf2size, 0))) { + // TimeFunc() could not lock DirectSoundBuffer + return; + } + if (buf1size) { + if (sound_channel->stopped) { + uint16 var5 = -(sound_channel->mmckinfo1.cksize != 8); + var5 &= 0x80; + memset(buf1, var5 + 128, buf1size); + goto label49; + } + } + int var7; + mmio_read(sound_channel->hmmio, buf1size, buf1, &sound_channel->mmckinfo1, &var7); + if (var7 < buf1size) { + if (!sound_channel->var_164) { + int s = sound_channel->mmckinfo1.cksize; + int t = buf1size - var7; + int v; + if (s == 8) { + v = 128; + } else { + if (s != 16) { + goto label42; + } + v = 0; + } + memset(&buf1[var7], v, t); + label42: + sound_channel->var_168 = 1; + if (dwCurrentPlayCursor <= sound_channel->playpos) { + sound_channel->var_15C = sound_channel->playpos - dwCurrentPlayCursor; + } else { + sound_channel->var_15C = sound_channel->playpos + sound_channel->bufsize - dwCurrentPlayCursor; + } + goto label49; + } + char* v21 = buf1; + int v38 = buf1size; + do { + v38 -= var7; + v21 += var7; + sub_40153B(channel); + mmio_read(sound_channel->hmmio, v38, v21, &sound_channel->mmckinfo1, &var7); + } while(var7 < v38); + } + label49: + if (buf2size == 0 || sound_channel->stopped != 0) { + if(buf2 != 0 && buf2size != 0 && sound_channel->stopped != 0) { + int var5 = -(sound_channel->mmckinfo1.cksize != 8); + var5 &= 0x80; + memset(buf2, var5 + 128, buf2size); + } + goto label68; + } + mmio_read(sound_channel->hmmio, buf2size, buf2, &sound_channel->mmckinfo1, &var7); + if (var7 >= buf2size) { + label68: + sound_channel->dsbuffer->lpVtbl->Unlock(sound_channel->dsbuffer, buf1, buf1size, buf2, buf2size); + sound_channel->playpos += var2; + if (sound_channel->playpos >= sound_channel->bufsize) { + sound_channel->playpos -= sound_channel->bufsize; + } + if (bufferlost != 0) { + sound_channel->dsbuffer->lpVtbl->Play(sound_channel->dsbuffer, 0, 0, DSBPLAY_LOOPING); + } + return; + } + if (sound_channel->var_164 != 0) { + char* v26 = buf2; + int v27 = buf2size; + do { + v26 += var7; + v27 -= var7; + sub_40153B(channel); + mmio_read(sound_channel->hmmio, v27, v26, &sound_channel->mmckinfo1, &var7); + } while(var7 < v27); + goto label68; + } + int s = buf2size - var7; + int v; + if (sound_channel->hmem == (HGLOBAL)8) { + v = 128; + } else { + if (sound_channel->hmem != (HGLOBAL)16) { + goto label58; + } + v = 0; + } + memset(&buf2[var7], v, s); + label58: + sound_channel->var_168 = 1; + if (dwCurrentPlayCursor <= sound_channel->playpos) { + sound_channel->var_15C = sound_channel->playpos - dwCurrentPlayCursor; + } else { + sound_channel->var_15C = sound_channel->playpos + sound_channel->bufsize - dwCurrentPlayCursor; + } + goto label68; } - 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 +* rct2: 0x004014DF */ -int unmap_sound_effects() +int CALLBACK audio_timer_callback(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2) { - if (RCT2_GLOBAL(RCT2_ADDRESS_SOUND_EFFECTS_MAPPING, LPVOID)) { - sound_stop_all(); - unmap_file(RCT2_GLOBAL(RCT2_ADDRESS_SOUND_EFFECTS_MAPPING, LPVOID)); - RCT2_GLOBAL(RCT2_ADDRESS_SOUND_EFFECTS_MAPPING, LPVOID) = 0; - return 1; + if (_InterlockedExchange(&RCT2_GLOBAL(0x009E1AAC, LONG), 1) == 0) { + for (int i = 0; i < 4; i++) { + rct_sound_channel* sound_channel = &RCT2_ADDRESS(RCT2_ADDRESS_SOUND_CHANNEL_LIST, rct_sound_channel)[i]; + if(sound_channel->playing){ + audio_timefunc(uTimerID, uMsg, dwUser, dw1, dw2, i); + } + } + return _InterlockedExchange(&RCT2_GLOBAL(0x009E1AAC, LONG), 0); } return 0; } /** * -* rct2: 0x00404DF5 +* rct2: 0x0040153B */ -int sound_stop_all() +int sub_40153B(int channel) { - int result = 0; - while (RCT2_GLOBAL(RCT2_ADDRESS_SOUNDLIST_BEGIN, rct_sound*)) { - result = sound_stop(RCT2_GLOBAL(RCT2_ADDRESS_SOUNDLIST_BEGIN, rct_sound*)); + rct_sound_channel* sound_channel = &RCT2_ADDRESS(0x014262E0, rct_sound_channel)[channel]; + if (sound_channel->var_4) { + if (sound_channel->hmmio) { + sound_channel_free(&sound_channel->hmmio, &sound_channel->hmem); + } + if (mmio_open_channel(channel, sound_channel->filename, sound_channel->var_110)) { + return 0; + } + sound_channel->var_164 = sound_channel->var_114; + sound_channel->var_118 = sound_channel->var_110; + sound_channel->var_4 = 0; + } else { + int result = mmio_seek(&sound_channel->hmmio, &sound_channel->mmckinfo1, &sound_channel->mmckinfo2, sound_channel->var_118); + sound_channel->var_158 = sound_channel->var_118; + if (result) { + return 0; + } + } + return 1; +} + +/** +* +* rct2: 0x004015E7 +*/ +int sub_4015E7(int channel) +{ + char* buf1; + int buf1size; + char* buf2; + int buf2size; + int read; + int zero = 0; + rct_sound_channel* sound_channel = &RCT2_ADDRESS(0x014262E0, rct_sound_channel)[channel]; + LPDIRECTSOUNDBUFFER dsbuffer = RCT2_ADDRESS(RCT2_ADDRESS_DSOUND_BUFFERS, LPDIRECTSOUNDBUFFER)[channel]; + int result = dsbuffer->lpVtbl->Lock(dsbuffer, 0, sound_channel->bufsize, (LPVOID*)&buf1, (LPDWORD)&buf1size, (LPVOID*)&buf2, (LPDWORD)&buf2size, 0); + if (SUCCEEDED(result)) { + if (buf1size) { + mmio_read(sound_channel->hmmio, buf1size, buf1, &sound_channel->mmckinfo1, &read); + int r = read; + if (read < buf1size) { + if (sound_channel->var_164) { + char* b = buf1; + int d = buf1size; + do { + d -= r; + b += r; + sub_40153B(channel); + mmio_read(sound_channel->hmmio, d, b, &sound_channel->mmckinfo1, &read); + r = read; + } while(read < d); + } else { + sound_channel->var_168 = 1; + sound_channel->var_15C = read; + LPWAVEFORMATEX waveformat = sound_channel->hmem; + uint16 v = ((waveformat->nBlockAlign != 8) - 1) & 0x80; + memset(&buf1[read], v, buf1size - r); + } + } + } + result = dsbuffer->lpVtbl->Unlock(dsbuffer, buf1, buf1size, buf2, zero); + sound_channel->var_158 = 0; + sound_channel->playpos = 0; } return result; } /** * -* rct2: 0x004068A0 +* rct2: 0x004016FF */ -int unmap_file(LPCVOID base) +int sound_channel_load_file(int channel, const char* filename, int offset) { - if (base) { - return UnmapViewOfFile(base); + rct_sound_channel* sound_channel = &RCT2_ADDRESS(0x014262E0, rct_sound_channel)[channel]; + sound_channel->hmem; + sound_channel->hmmio; + if (mmio_open(filename, &sound_channel->hmmio, &sound_channel->hmem, &sound_channel->mmckinfo2)) { + return -100; } + if (*(uint16*)sound_channel->hmem != 1) { + sound_channel_free(&sound_channel->hmmio, &sound_channel->hmem); + return -101; + } + if (mmio_seek(&sound_channel->hmmio, &sound_channel->mmckinfo1, &sound_channel->mmckinfo2, offset)) { + sound_channel_free(&sound_channel->hmmio, &sound_channel->hmem); + return -103; + } + sound_channel->bufsize = 120 * *((uint32*)sound_channel->hmem + 2) / 100; + DSBUFFERDESC bufferdesc; + memset(&bufferdesc, 0, sizeof(bufferdesc)); + bufferdesc.dwFlags = RCT2_GLOBAL(0x009E1AA8, uint32) | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPAN | DSBCAPS_CTRLFREQUENCY; + bufferdesc.dwBufferBytes = sound_channel->bufsize; + bufferdesc.lpwfxFormat = sound_channel->hmem; + bufferdesc.dwSize = sizeof(bufferdesc); + int ret = RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND)->lpVtbl->CreateSoundBuffer(RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND), &bufferdesc, &RCT2_ADDRESS(RCT2_ADDRESS_DSOUND_BUFFERS, LPDIRECTSOUNDBUFFER)[channel], 0); + if (FAILED(ret)) { + return -102; + } + sound_channel->dsbuffer = RCT2_ADDRESS(RCT2_ADDRESS_DSOUND_BUFFERS, LPDIRECTSOUNDBUFFER)[channel]; + sound_channel->var_168 = 0; + sound_channel->var_15C = 0; + sound_channel->var_164 = 1; + sub_4015E7(channel); + sound_channel->var_158 = offset; + sound_channel->stopped = 0; return 0; } +/** +* +* rct2: 0x00401822 +*/ +int mmio_open_channel(int channel, char* filename, LONG offset) +{ + rct_sound_channel* sound_channel = &RCT2_ADDRESS(0x014262E0, rct_sound_channel)[channel]; + LPMMCKINFO v4 = &sound_channel->mmckinfo2; + HMMIO* v5 = &sound_channel->hmmio; + if (mmio_open(filename, &sound_channel->hmmio, &sound_channel->hmem, &sound_channel->mmckinfo2)) { + return -100; + } + if (*(uint16*)sound_channel->hmem != 1) { + sound_channel_free(&sound_channel->hmmio, &sound_channel->hmem); + return -101; + } + if (mmio_seek(&sound_channel->hmmio, &sound_channel->mmckinfo1, &sound_channel->mmckinfo2, offset)) { + sound_channel_free(&sound_channel->hmmio, &sound_channel->hmem); + return -103; + } + sound_channel->var_158 = offset; + return 0; +} + +/** +* +* rct2: 0x004018A6 +*/ +int audio_create_timer() +{ + if (RCT2_GLOBAL(0x009E1AA4, int)) { + return 0; + } + for (int i = 0; i < 4; i++) { + rct_sound_channel* sound_channel = &RCT2_ADDRESS(RCT2_ADDRESS_SOUND_CHANNEL_LIST, rct_sound_channel)[i]; + sound_channel->playing = 0; + } + RCT2_GLOBAL(0x009E1AA0, MMRESULT) = timeSetEvent(50, 10, (LPTIMECALLBACK)audio_timer_callback, 0, TIME_PERIODIC); + if (!RCT2_GLOBAL(0x009E1AA0, MMRESULT)) { + return 0; + } + RCT2_GLOBAL(0x009E1AA4, int) = 1; + return 1; +} + /** * * rct2: 0x004018F0 @@ -162,26 +462,410 @@ int audio_remove_timer() /** * -* rct2: 0x006BAB21 +* rct2: 0x0040194E */ -void audio_close() +int sound_channel_load_file2(int channel, const char* filename, int offset) { - if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SOUND_DEVICE, uint32) != -1) { - stop_other_sounds(); - stop_crowd_sound(); - stop_title_music(); - if (RCT2_GLOBAL(0x009AF284, uint32) & (1 << 0)) { - stop_ride_music(); - RCT2_GLOBAL(0x014241BC, uint32) = 1; - audio_remove_timer(); - RCT2_GLOBAL(0x014241BC, uint32) = 0; - } - RCT2_GLOBAL(0x014241BC, uint32) = 1; - unmap_sound_effects(); - audio_release(); - RCT2_GLOBAL(0x014241BC, uint32) = 0; - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SOUND_DEVICE, uint32) = -1; + if (!RCT2_GLOBAL(0x009E1AA4, int)) { + return 0; } + if (sound_channel_is_playing(channel)) { + sound_channel_stop(channel); + } + if (SUCCEEDED(sound_channel_load_file(channel, filename, offset))) { + RCT2_ADDRESS(RCT2_ADDRESS_SOUND_CHANNEL_LIST, rct_sound_channel)[channel].var_4 = 0; + return 1; + } + return 0; +} + +/** +* +* rct2: 0x00401999 +*/ +int sound_channel_play(int channel, int a2, int volume, int pan, int frequency) +{ + 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); + sound_channel->playing = 1; + return 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->playing = 0; + sound_channel->stopped = 1; + while (_InterlockedExchange(&RCT2_GLOBAL(0x009E1AAC, LONG), 1) != 1) { + Sleep(10); + } + if (sound_channel->hmmio) { + sound_channel_free(&sound_channel->hmmio, &sound_channel->hmem); + } + + 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: 0x00401A93 +*/ +int sound_channel_set_frequency(int channel, int frequency) +{ + LPDIRECTSOUNDBUFFER dsbuffer = RCT2_ADDRESS(RCT2_ADDRESS_DSOUND_BUFFERS, LPDIRECTSOUNDBUFFER)[channel]; + if (dsbuffer) { + if (SUCCEEDED(dsbuffer->lpVtbl->SetFrequency(dsbuffer, frequency))) + return 1; + + } + return 0; +} + +/** +* +* rct2: 0x00401AB3 +*/ +int sound_channel_set_pan(int channel, int pan) +{ + LPDIRECTSOUNDBUFFER dsbuffer = RCT2_ADDRESS(RCT2_ADDRESS_DSOUND_BUFFERS, LPDIRECTSOUNDBUFFER)[channel]; + if (dsbuffer) { + if (SUCCEEDED(dsbuffer->lpVtbl->SetPan(dsbuffer, pan))) + return 1; + + } + return 0; +} + +/** +* +* rct2: 0x00401AD3 +*/ +int sound_channel_set_volume(int channel, int volume) +{ + LPDIRECTSOUNDBUFFER dsbuffer = RCT2_ADDRESS(RCT2_ADDRESS_DSOUND_BUFFERS, LPDIRECTSOUNDBUFFER)[channel]; + if (dsbuffer) { + if (SUCCEEDED(dsbuffer->lpVtbl->SetVolume(dsbuffer, volume))) + return 1; + + } + return 0; +} + +/** +* +* rct2: 0x00401AF3 +*/ +void sub_401AF3(int channel, const char* filename, int a3, int a4) +{ + rct_sound_channel* sound_channel = &RCT2_ADDRESS(RCT2_ADDRESS_SOUND_CHANNEL_LIST, rct_sound_channel)[channel]; + sound_channel->var_4 = 1; + memcpy(sound_channel->filename, filename, sizeof(sound_channel->filename)); + sound_channel->var_10C = 0; + sound_channel->var_110 = a4; + sound_channel->var_114 = a3; + sound_channel->var_164 = 1; +} + +/** +* +* rct2: 0x00401B46 +*/ +int sub_401B46(int channel) +{ + rct_sound_channel* sound_channel = &RCT2_ADDRESS(RCT2_ADDRESS_SOUND_CHANNEL_LIST, rct_sound_channel)[channel]; + if (sound_channel->stopped) { + return 0; + } else { + return sound_channel->var_158; + } +} + +/** +* +* rct2: 0x00401B63 +*/ +int sound_channel_is_playing(int channel) +{ + if (RCT2_ADDRESS(RCT2_ADDRESS_SOUND_CHANNEL_LIST, rct_sound_channel)[channel].playing) { + return RCT2_ADDRESS(RCT2_ADDRESS_SOUND_CHANNEL_LIST, rct_sound_channel)[channel].stopped == 0; + } else { + return 0; + } +} + +/** +* +* rct2: 0x00404BD2 +*/ +int audio_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: 0x00404C1A +*/ +int map_sound_effects(const char* filename) +{ + if (RCT2_GLOBAL(RCT2_ADDRESS_SOUND_EFFECTS_MAPPING, LPVOID)) { + return 0; + } else { + RCT2_GLOBAL(RCT2_ADDRESS_SOUND_EFFECTS_MAPPING, LPVOID) = map_file(filename, 0, 0); + return RCT2_GLOBAL(RCT2_ADDRESS_SOUND_EFFECTS_MAPPING, LPVOID) != 0; + } +} + +/** +* +* rct2: 0x00404C45 +*/ +int unmap_sound_effects() +{ + if (RCT2_GLOBAL(RCT2_ADDRESS_SOUND_EFFECTS_MAPPING, LPVOID)) { + sound_stop_all(); + unmap_file(RCT2_GLOBAL(RCT2_ADDRESS_SOUND_EFFECTS_MAPPING, LPVOID)); + RCT2_GLOBAL(RCT2_ADDRESS_SOUND_EFFECTS_MAPPING, LPVOID) = 0; + return 1; + } + return 0; +} + +/** +* +* rct2: 0x00404C6D +*/ +int sound_prepare(int sound_id, rct_sound *sound, int channels, int software) +{ + DSBUFFERDESC bufferdesc; + char* buffer = 0; + memset(&bufferdesc, 0, sizeof(bufferdesc)); + bufferdesc.dwSize = sizeof(bufferdesc); + rct_sound* tempsound = sound_begin(); + if (tempsound) { + int wasduplicated = 0; + while (!tempsound->dsbuffer || tempsound->id != sound_id || !sound_duplicate(sound, tempsound)) { + tempsound = sound_next(tempsound); + if (!tempsound) { + wasduplicated = 1; + break; + } + } + if (!wasduplicated) { + return 1; + } + } + rct_sound_effect* sound_effect = sound_get_effect(sound_id); + if (sound_effect) { + if (sound_effect_loadvars(sound_effect, &bufferdesc.lpwfxFormat, &buffer, &bufferdesc.dwBufferBytes)) { + bufferdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_STATIC; + if (channels) { + if (channels == 2) { + bufferdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRL3D | DSBCAPS_STATIC; + } else { + bufferdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPAN | DSBCAPS_CTRLFREQUENCY | DSBCAPS_STATIC; + } + if (RCT2_GLOBAL(0x009E2B90, uint32)) { + bufferdesc.dwFlags |= DSBCAPS_CTRLPAN; + } + if (software) { + bufferdesc.dwFlags |= DSBCAPS_LOCSOFTWARE; + } + if (SUCCEEDED(RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND)->lpVtbl->CreateSoundBuffer(RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND), &bufferdesc, &sound->dsbuffer, 0))) { + if (sound_fill_buffer(sound->dsbuffer, buffer, bufferdesc.dwBufferBytes)) { + sound->id = sound_id; + DSBCAPS caps; + caps.dwSize = sizeof(caps); + sound->dsbuffer->lpVtbl->GetCaps(sound->dsbuffer, &caps); + sound->has_caps = caps.dwFlags; + sound_add(sound); + return 1; + } + sound->dsbuffer->lpVtbl->Release(sound->dsbuffer); + sound->dsbuffer = 0; + } + } + sound->dsbuffer = 0; + } + } + return 0; +} + +/** +* +* rct2: 0x00404D99 +*/ +int sound_duplicate(rct_sound* newsound, rct_sound* sound) +{ + if (FAILED(RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND)->lpVtbl->DuplicateSoundBuffer(RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND), sound->dsbuffer, &newsound->dsbuffer))) { + return 0; + } else { + newsound->id = sound->id; + newsound->has_caps = sound->has_caps; + newsound->var_0C = sound->var_0C; + sound_add(newsound); + return 1; + } +} + +/** +* +* rct2: 0x00404DD8 +*/ +int sound_stop(rct_sound* sound) +{ + if (sound->dsbuffer) { + sound->dsbuffer->lpVtbl->Release(sound->dsbuffer); + sound->dsbuffer = 0; + return sound_remove(sound) ? 1 : 0; + } + 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: 0x00404E0D +*/ +void sound_bufferlost_check() +{ + rct_sound* sound = RCT2_GLOBAL(RCT2_ADDRESS_SOUNDLIST_BEGIN, rct_sound*); + while (sound && sound != RCT2_GLOBAL(RCT2_ADDRESS_SOUNDLIST_END, rct_sound*)) { + DWORD status; + if (SUCCEEDED(sound->dsbuffer->lpVtbl->GetStatus(sound->dsbuffer, &status))) { + if (status & DSBSTATUS_BUFFERLOST) { + sound_bufferlost_restore(sound); + } + } + sound = sound->next; + } +} + +/** +* +* rct2: 0x00404E53 +*/ +int sound_is_playing(rct_sound* sound){ + if (sound->dsbuffer) { + DWORD status; + if (SUCCEEDED(sound->dsbuffer->lpVtbl->GetStatus(sound->dsbuffer, &status))) { + if (status & DSBSTATUS_PLAYING || status & DSBSTATUS_LOOPING) + return 1; + + } + } + return 0; +} + +/** +* +* rct2: 0x00404E7F +*/ +int sound_play(rct_sound* sound, int looping, int volume, int pan, int frequency) +{ + if (sound->dsbuffer) { + sound_set_frequency(sound, frequency); + sound_set_pan(sound, pan); + sound_set_volume(sound, volume); + DWORD playflags; + if (looping) { + if (looping != 1) + return 1; + + playflags = DSBPLAY_LOOPING; + } else { + playflags = 0; + } + if (SUCCEEDED(sound->dsbuffer->lpVtbl->Play(sound->dsbuffer, 0, 0, playflags))) + return 1; + + } + return 0; +} + +/** +* +* rct2: 0x00404ED7 +*/ +int sound_set_frequency(rct_sound* sound, int frequency) +{ + if (sound->dsbuffer) { + if (SUCCEEDED(sound->dsbuffer->lpVtbl->SetFrequency(sound->dsbuffer, frequency))) + return 1; + + } + return 0; +} + +/** +* +* rct2: 0x00404EF2 +*/ +int sound_set_pan(rct_sound* sound, int pan) +{ + if (sound->dsbuffer) { + if (SUCCEEDED(sound->dsbuffer->lpVtbl->SetPan(sound->dsbuffer, pan))) + return 1; + + } + return 0; +} + +/** +* +* rct2: 0x00404F0D +*/ +int sound_set_volume(rct_sound* sound, int volume) +{ + if (sound->dsbuffer) { + if (SUCCEEDED(sound->dsbuffer->lpVtbl->SetVolume(sound->dsbuffer, volume))) + return 1; + + } + return 0; } /** @@ -208,6 +892,404 @@ int sound_load3dposition() return 0; } +/** +* +* 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: 0x00405054 +*/ +int sound_effect_loadvars(rct_sound_effect* sound_effect, LPWAVEFORMATEX* waveformat, char** data, DWORD* buffersize) +{ + *buffersize = sound_effect->size; + *waveformat = &sound_effect->format; + *data = (char*)&sound_effect->data; + return 1; +} + +/** +* +* rct2: 0x00405076 +*/ +int sound_fill_buffer(LPDIRECTSOUNDBUFFER dsbuffer, char* src, DWORD size) +{ + LPVOID buf; + LPVOID buf2; + DWORD buf2size; + if (SUCCEEDED(dsbuffer->lpVtbl->Lock(dsbuffer, 0, size, &buf, &size, &buf2, &buf2size, 0))) { + memset(buf, 0, size); + memcpy(buf, src, size); + if (buf2size) { + memcpy(buf2, &src[size], buf2size); + } + dsbuffer->lpVtbl->Unlock(dsbuffer, buf, size, buf2, buf2size); + return 1; + } + return 0; +} + +/** +* +* rct2: 0x00405103 +*/ +rct_sound* sound_begin() +{ + return RCT2_GLOBAL(RCT2_ADDRESS_SOUNDLIST_BEGIN, rct_sound*); +} + +/** +* +* rct2: 0x00405109 +*/ +rct_sound* sound_next(rct_sound* sound) +{ + if (RCT2_GLOBAL(RCT2_ADDRESS_SOUNDLIST_END, rct_sound*) == sound) { + return 0; + } else { + return sound->next; + } +} + +/** +* +* rct2: 0x0040511C +*/ +rct_sound* sound_add(rct_sound* sound) +{ + if (RCT2_GLOBAL(RCT2_ADDRESS_SOUNDLIST_BEGIN, rct_sound*)) { + RCT2_GLOBAL(RCT2_ADDRESS_SOUNDLIST_END, rct_sound*)->next = sound; + } else { + RCT2_GLOBAL(RCT2_ADDRESS_SOUNDLIST_BEGIN, rct_sound*) = sound; + } + RCT2_GLOBAL(RCT2_ADDRESS_SOUNDLIST_END, rct_sound*) = sound; + sound->next = 0; + return sound; +} + +/** +* +* rct2: 0x00405143 +*/ +rct_sound* sound_remove(rct_sound* sound) +{ + rct_sound* result = RCT2_GLOBAL(RCT2_ADDRESS_SOUNDLIST_BEGIN, rct_sound*); + if (sound == result) { + if (sound == RCT2_GLOBAL(RCT2_ADDRESS_SOUNDLIST_END, rct_sound*)) { + RCT2_GLOBAL(RCT2_ADDRESS_SOUNDLIST_END, rct_sound*) = 0; + RCT2_GLOBAL(RCT2_ADDRESS_SOUNDLIST_BEGIN, rct_sound*) = 0; + } + result = sound->next; + RCT2_GLOBAL(RCT2_ADDRESS_SOUNDLIST_BEGIN, rct_sound*) = result; + } else { + while (result->next != sound) + result = result->next; + + if (sound == RCT2_GLOBAL(RCT2_ADDRESS_SOUNDLIST_END, rct_sound*)) { + RCT2_GLOBAL(RCT2_ADDRESS_SOUNDLIST_END, rct_sound*) = result; + result->next = 0; + } else + result->next = sound->next; + + } + sound->next = 0; + return result; +} + +/** +* +* rct2: 0x00405199 +*/ +int sound_bufferlost_restore(rct_sound* sound) +{ + DWORD buffersize = 0; + LPWAVEFORMATEX waveformat = 0; + char* data = 0; + if (sound) { + if (SUCCEEDED(sound->dsbuffer->lpVtbl->Restore(sound->dsbuffer))) { + rct_sound_effect* sound_effect = sound_get_effect(sound->id); + if (sound_effect != 0) { + return sound_effect_loadvars(sound_effect, &waveformat, &data, &buffersize) && sound_fill_buffer(sound->dsbuffer, data, buffersize); + } + } + } + return 0; +} + +/** +* +* rct2: 0x00405206 +*/ +rct_sound_effect* sound_get_effect(uint16 sound_id) +{ + if (RCT2_GLOBAL(RCT2_ADDRESS_SOUND_EFFECTS_MAPPING, LPVOID) && sound_id < RCT2_GLOBAL(RCT2_ADDRESS_SOUND_EFFECTS_MAPPING, uint32*)[0]) { + return (rct_sound_effect*)(RCT2_GLOBAL(RCT2_ADDRESS_SOUND_EFFECTS_MAPPING, int) + RCT2_GLOBAL(RCT2_ADDRESS_SOUND_EFFECTS_MAPPING, uint32*)[sound_id + 1]); + } + return 0; +} + +/** +* +* rct2: 0x00405222 +*/ +MMRESULT mmio_open(const char* filename, HMMIO* hmmio, HGLOBAL* hmem, LPMMCKINFO mmckinfo) +{ + HGLOBAL* hmemold; + HGLOBAL hmemold2; + HMMIO hmmio1; + MMRESULT result; + MMCKINFO mmckinfo1; + WAVEFORMATEX waveformat; + + hmemold = hmem; + *hmem = 0; + hmmio1 = mmioOpenA((char*)filename, 0, MMIO_ALLOCBUF); + if (hmmio1) { + result = mmioDescend(hmmio1, mmckinfo, 0, 0); + if (result != MMSYSERR_NOERROR) { + goto label20; + } + if (mmckinfo->ckid != 1179011410/*RIFF*/ || mmckinfo->fccType != 1163280727/*WAVE*/) { + result = 57601; + goto label20; + } + mmckinfo1.ckid = 544501094/*fmt*/; + result = mmioDescend(hmmio1, &mmckinfo1, mmckinfo, MMIO_FINDCHUNK); + if (result != MMSYSERR_NOERROR) { + goto label20; + } + if (mmckinfo1.cksize < 16) { + label19: + result = 57601; + goto label20; + } + if (mmioRead(hmmio1, (HPSTR)&waveformat, 16) == 16) { + if (waveformat.wFormatTag == 1) { + //strcpy(audio_info.var_0, "\x01"); + hmem = 0; + label11: + hmemold2 = GlobalAlloc(0, (SIZE_T)(hmem + 18)); + *hmemold = hmemold2; + if (!hmemold2) { + result = 57344; + goto label20; + } + memcpy(hmemold2, &waveformat, 16); + *((uint16*)*hmemold + 8) = (uint16)hmem; + if (!hmem || mmioRead(hmmio1, (char*)*hmemold + 18, (LONG)hmem) == (LONG)hmem) { + result = mmioAscend(hmmio1, &mmckinfo1, 0); + if (!result) { + goto label24; + } + goto label20; + } + goto label19; + } + if (mmioRead(hmmio1, (HPSTR)&hmem, 2) == 2) { + goto label11; + } + } + result = 57602; + goto label20; + } + result = 57600; + label20: + if (*hmemold) { + GlobalFree(*hmemold); + *hmemold = 0; + } + if (hmmio1) { + mmioClose(hmmio1, 0); + hmmio1 = 0; + } + label24: + *hmmio = hmmio1; + return result; +} + +/** +* +* rct2: 0x00405383 +*/ +MMRESULT mmio_read(HMMIO hmmio, uint32 size, char* buffer, LPMMCKINFO mmckinfo, int* read) +{ + MMIOINFO mmioinfo; + MMRESULT result; + result = mmioGetInfo(hmmio, &mmioinfo, 0); + if (result != 0) { + *read = 0; + return 1; + } + int size2 = size; + if (size > mmckinfo->cksize) { + size2 = mmckinfo->cksize; + } + int v8 = 0; + mmckinfo->cksize -= size2; + if (size2) { + while (1) { + HPSTR p = mmioinfo.pchEndRead; + if (mmioinfo.pchNext == mmioinfo.pchEndRead) { + result = mmioAdvance(hmmio, &mmioinfo, 0); + if (result != 0) { + *read = 0; + return result; + } + p = mmioinfo.pchEndRead; + if (mmioinfo.pchNext == mmioinfo.pchEndRead) { + break; + } + } + int q = p - mmioinfo.pchNext; + if (size2 - v8 < p - mmioinfo.pchNext) { + q = size2 - v8; + } + memcpy(&buffer[v8], mmioinfo.pchNext, q); + mmioinfo.pchNext += q; + v8 += q; + if (v8 >= size2) { + result = mmioSetInfo(hmmio, &mmioinfo, 0); + if (result != 0) { + *read = 0; + return result; + } else { + *read = size2; + return result; + } + } + } + *read = 0; + return 57603; + } + result = mmioSetInfo(hmmio, &mmioinfo, 0); + if (result != 0) { + *read = 0; + return result; + } else { + *read = size2; + return result; + } +} + +/** +* +* rct2: 0x00405436 +*/ +void sound_channel_free(HMMIO* hmmio, HGLOBAL* hmem) +{ + if(*hmem) + { + GlobalFree(*hmem); + *hmem = 0; + } + if(*hmmio) + { + mmioClose(*hmmio, 0); + *hmmio = 0; + } +} + +/** +* +* rct2: 0x00405465 +*/ +MMRESULT mmio_seek(HMMIO* hmmio, LPMMCKINFO mmckinfo1, LPMMCKINFO mmckinfo2, int offset) +{ + mmioSeek(*hmmio, mmckinfo2->dwDataOffset + 4, SEEK_SET); + mmckinfo1->ckid = 1635017060/*DATA*/; + MMRESULT result = mmioDescend(*hmmio, mmckinfo1, mmckinfo2, MMIO_FINDCHUNK); + if (!result) { + mmioSeek(*hmmio, offset, SEEK_CUR); + return 0; + } + return result; +} + +/** +* +* rct2: 0x004067F9 +*/ +LPVOID map_file(LPCSTR lpFileName, DWORD dwCreationDisposition, DWORD dwNumberOfBytesToMap) +{ + DWORD dwDesiredAccess; + DWORD dwDesiredAccessmap; + DWORD flProtect; + HANDLE filehandle; + HANDLE filemaphandle; + LPVOID address = 0; + if (dwCreationDisposition) { + if (dwCreationDisposition == CREATE_NEW) { + dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; + dwDesiredAccessmap = FILE_MAP_WRITE; + flProtect = PAGE_READWRITE; + dwCreationDisposition = OPEN_ALWAYS; + } + } else { + dwDesiredAccess = GENERIC_READ; + flProtect = PAGE_READONLY; + dwDesiredAccessmap = FILE_MAP_READ; + dwCreationDisposition = OPEN_EXISTING; + } + filehandle = CreateFileA(lpFileName, dwDesiredAccess, 0, 0, dwCreationDisposition, FILE_ATTRIBUTE_NORMAL, 0); + if (filehandle != INVALID_HANDLE_VALUE) { + filemaphandle = CreateFileMappingA(filehandle, 0, flProtect, 0, dwNumberOfBytesToMap, 0); + CloseHandle(filehandle); + if (filemaphandle) { + address = MapViewOfFile(filemaphandle, dwDesiredAccessmap, 0, 0, dwNumberOfBytesToMap); + CloseHandle(filemaphandle); + } + } + return address; +} + +/** +* +* rct2: 0x004068A0 +*/ +int unmap_file(LPCVOID base) +{ + if (base) { + return UnmapViewOfFile(base); + } + return 0; +} + /** * * rct2: 0x00404932 @@ -308,729 +1390,6 @@ int dsound_create_primary_buffer(int a, int device, int channels, int samples, i return 1; } -/** -* -* rct2: 0x004067F9 -*/ -LPVOID map_file(LPCSTR lpFileName, DWORD dwCreationDisposition, DWORD dwNumberOfBytesToMap) -{ - DWORD dwDesiredAccess; - DWORD dwDesiredAccessmap; - DWORD flProtect; - HANDLE filehandle; - HANDLE filemaphandle; - LPVOID address = 0; - if (dwCreationDisposition) { - if (dwCreationDisposition == CREATE_NEW) { - dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; - dwDesiredAccessmap = FILE_MAP_WRITE; - flProtect = PAGE_READWRITE; - dwCreationDisposition = OPEN_ALWAYS; - } - } else { - dwDesiredAccess = GENERIC_READ; - flProtect = PAGE_READONLY; - dwDesiredAccessmap = FILE_MAP_READ; - dwCreationDisposition = OPEN_EXISTING; - } - filehandle = CreateFileA(lpFileName, dwDesiredAccess, 0, 0, dwCreationDisposition, FILE_ATTRIBUTE_NORMAL, 0); - if (filehandle != INVALID_HANDLE_VALUE) { - filemaphandle = CreateFileMappingA(filehandle, 0, flProtect, 0, dwNumberOfBytesToMap, 0); - CloseHandle(filehandle); - if (filemaphandle) { - address = MapViewOfFile(filemaphandle, dwDesiredAccessmap, 0, 0, dwNumberOfBytesToMap); - CloseHandle(filemaphandle); - } - } - return address; -} - -/** -* -* rct2: 0x00404C1A -*/ -int map_sound_effects(const char* filename) -{ - if (RCT2_GLOBAL(RCT2_ADDRESS_SOUND_EFFECTS_MAPPING, LPVOID)) { - return 0; - } else { - RCT2_GLOBAL(RCT2_ADDRESS_SOUND_EFFECTS_MAPPING, LPVOID) = map_file(filename, 0, 0); - return RCT2_GLOBAL(RCT2_ADDRESS_SOUND_EFFECTS_MAPPING, LPVOID) != 0; - } -} - -/** -* -* rct2: 0x00405383 -*/ -MMRESULT mmio_read(HMMIO hmmio, uint32 size, char* buffer, LPMMCKINFO mmckinfo, int* read) -{ - MMIOINFO mmioinfo; - MMRESULT result; - result = mmioGetInfo(hmmio, &mmioinfo, 0); - if (result != 0) { - *read = 0; - return 1; - } - int size2 = size; - if (size > mmckinfo->cksize) { - size2 = mmckinfo->cksize; - } - int v8 = 0; - mmckinfo->cksize -= size2; - if (size2) { - while (1) { - HPSTR p = mmioinfo.pchEndRead; - if (mmioinfo.pchNext == mmioinfo.pchEndRead) { - result = mmioAdvance(hmmio, &mmioinfo, 0); - if (result != 0) { - *read = 0; - return result; - } - p = mmioinfo.pchEndRead; - if (mmioinfo.pchNext == mmioinfo.pchEndRead) { - break; - } - } - int q = p - mmioinfo.pchNext; - if (size2 - v8 < p - mmioinfo.pchNext) { - q = size2 - v8; - } - memcpy(&buffer[v8], mmioinfo.pchNext, q); - mmioinfo.pchNext += q; - v8 += q; - if (v8 >= size2) { - result = mmioSetInfo(hmmio, &mmioinfo, 0); - if (result != 0) { - *read = 0; - return result; - } else { - *read = size2; - return result; - } - } - } - *read = 0; - return 57603; - } - result = mmioSetInfo(hmmio, &mmioinfo, 0); - if (result != 0) { - *read = 0; - return result; - } else { - *read = size2; - return result; - } -} - -/** -* -* rct2: 0x00405465 -*/ -MMRESULT mmio_seek(HMMIO* hmmio, LPMMCKINFO mmckinfo1, LPMMCKINFO mmckinfo2, int offset) -{ - mmioSeek(*hmmio, mmckinfo2->dwDataOffset + 4, SEEK_SET); - mmckinfo1->ckid = 1635017060/*DATA*/; - MMRESULT result = mmioDescend(*hmmio, mmckinfo1, mmckinfo2, MMIO_FINDCHUNK); - if (!result) { - mmioSeek(*hmmio, offset, SEEK_CUR); - return 0; - } - return result; -} - -/** -* -* rct2: 0x004015E7 -*/ -int sub_4015E7(int channel) -{ - char* buf1; - int buf1size; - char* buf2; - int buf2size; - int read; - int zero = 0; - rct_sound_channel* sound_channel = &RCT2_ADDRESS(0x014262E0, rct_sound_channel)[channel]; - LPDIRECTSOUNDBUFFER dsbuffer = RCT2_ADDRESS(RCT2_ADDRESS_DSOUND_BUFFERS, LPDIRECTSOUNDBUFFER)[channel]; - int result = dsbuffer->lpVtbl->Lock(dsbuffer, 0, sound_channel->bufsize, (LPVOID*)&buf1, (LPDWORD)&buf1size, (LPVOID*)&buf2, (LPDWORD)&buf2size, 0); - if (SUCCEEDED(result)) { - if (buf1size) { - mmio_read(sound_channel->hmmio, buf1size, buf1, &sound_channel->mmckinfo1, &read); - int r = read; - if (read < buf1size) { - if (sound_channel->var_164) { - char* b = buf1; - int d = buf1size; - do { - d -= r; - b += r; - sub_40153B(channel); - mmio_read(sound_channel->hmmio, d, b, &sound_channel->mmckinfo1, &read); - r = read; - } while(read < d); - } else { - sound_channel->var_168 = 1; - sound_channel->var_15C = read; - LPWAVEFORMATEX waveformat = sound_channel->hmem; - uint16 v = ((waveformat->nBlockAlign != 8) - 1) & 0x80; - memset(&buf1[read], v, buf1size - r); - } - } - } - result = dsbuffer->lpVtbl->Unlock(dsbuffer, buf1, buf1size, buf2, zero); - sound_channel->var_158 = 0; - sound_channel->playpos = 0; - } - return result; -} - -/** -* -* rct2: 0x00401AF3 -*/ -void sub_401AF3(int channel, const char* filename, int a3, int a4) -{ - rct_sound_channel* sound_channel = &RCT2_ADDRESS(RCT2_ADDRESS_SOUND_CHANNEL_LIST, rct_sound_channel)[channel]; - sound_channel->var_4 = 1; - memcpy(sound_channel->filename, filename, sizeof(sound_channel->filename)); - sound_channel->var_10C = 0; - sound_channel->var_110 = a4; - sound_channel->var_114 = a3; - sound_channel->var_164 = 1; -} - -/** -* -* rct2: 0x004016FF -*/ -int sound_channel_load_file(int channel, const char* filename, int offset) -{ - rct_sound_channel* sound_channel = &RCT2_ADDRESS(0x014262E0, rct_sound_channel)[channel]; - sound_channel->hmem; - sound_channel->hmmio; - if (mmio_open(filename, &sound_channel->hmmio, &sound_channel->hmem, &sound_channel->mmckinfo2)) { - return -100; - } - if (*(uint16*)sound_channel->hmem != 1) { - sound_channel_free(&sound_channel->hmmio, &sound_channel->hmem); - return -101; - } - if (mmio_seek(&sound_channel->hmmio, &sound_channel->mmckinfo1, &sound_channel->mmckinfo2, offset)) { - sound_channel_free(&sound_channel->hmmio, &sound_channel->hmem); - return -103; - } - sound_channel->bufsize = 120 * *((uint32*)sound_channel->hmem + 2) / 100; - DSBUFFERDESC bufferdesc; - memset(&bufferdesc, 0, sizeof(bufferdesc)); - bufferdesc.dwFlags = RCT2_GLOBAL(0x009E1AA8, uint32) | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPAN | DSBCAPS_CTRLFREQUENCY; - bufferdesc.dwBufferBytes = sound_channel->bufsize; - bufferdesc.lpwfxFormat = sound_channel->hmem; - bufferdesc.dwSize = sizeof(bufferdesc); - int ret = RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND)->lpVtbl->CreateSoundBuffer(RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND), &bufferdesc, &RCT2_ADDRESS(RCT2_ADDRESS_DSOUND_BUFFERS, LPDIRECTSOUNDBUFFER)[channel], 0); - if (FAILED(ret)) { - return -102; - } - sound_channel->dsbuffer = RCT2_ADDRESS(RCT2_ADDRESS_DSOUND_BUFFERS, LPDIRECTSOUNDBUFFER)[channel]; - sound_channel->var_168 = 0; - sound_channel->var_15C = 0; - sound_channel->var_164 = 1; - sub_4015E7(channel); - sound_channel->var_158 = offset; - sound_channel->var_160 = 0; - return 0; -} - -/** -* -* rct2: 0x00405222 -*/ -MMRESULT mmio_open(const char* filename, HMMIO* hmmio, HGLOBAL* hmem, LPMMCKINFO mmckinfo) -{ - HGLOBAL* hmemold; - HGLOBAL hmemold2; - HMMIO hmmio1; - MMRESULT result; - MMCKINFO mmckinfo1; - WAVEFORMATEX waveformat; - - hmemold = hmem; - *hmem = 0; - hmmio1 = mmioOpenA((char*)filename, 0, MMIO_ALLOCBUF); - if (hmmio1) { - result = mmioDescend(hmmio1, mmckinfo, 0, 0); - if (result != MMSYSERR_NOERROR) { - goto label20; - } - if (mmckinfo->ckid != 1179011410/*RIFF*/ || mmckinfo->fccType != 1163280727/*WAVE*/) { - result = 57601; - goto label20; - } - mmckinfo1.ckid = 544501094/*fmt*/; - result = mmioDescend(hmmio1, &mmckinfo1, mmckinfo, MMIO_FINDCHUNK); - if (result != MMSYSERR_NOERROR) { - goto label20; - } - if (mmckinfo1.cksize < 16) { - label19: - result = 57601; - goto label20; - } - if (mmioRead(hmmio1, (HPSTR)&waveformat, 16) == 16) { - if (waveformat.wFormatTag == 1) { - //strcpy(audio_info.var_0, "\x01"); - hmem = 0; - label11: - hmemold2 = GlobalAlloc(0, (SIZE_T)(hmem + 18)); - *hmemold = hmemold2; - if (!hmemold2) { - result = 57344; - goto label20; - } - memcpy(hmemold2, &waveformat, 16); - *((uint16*)*hmemold + 8) = (uint16)hmem; - if (!hmem || mmioRead(hmmio1, (char*)*hmemold + 18, (LONG)hmem) == (LONG)hmem) { - result = mmioAscend(hmmio1, &mmckinfo1, 0); - if (!result) { - goto label24; - } - goto label20; - } - goto label19; - } - if (mmioRead(hmmio1, (HPSTR)&hmem, 2) == 2) { - goto label11; - } - } - result = 57602; - goto label20; - } - result = 57600; - label20: - if (*hmemold) { - GlobalFree(*hmemold); - *hmemold = 0; - } - if (hmmio1) { - mmioClose(hmmio1, 0); - hmmio1 = 0; - } - label24: - *hmmio = hmmio1; - return result; -} - -/** -* -* rct2: 0x00401822 -*/ -int mmio_open_channel(int channel, char* filename, LONG offset) -{ - rct_sound_channel* sound_channel = &RCT2_ADDRESS(0x014262E0, rct_sound_channel)[channel]; - LPMMCKINFO v4 = &sound_channel->mmckinfo2; - HMMIO* v5 = &sound_channel->hmmio; - if (mmio_open(filename, &sound_channel->hmmio, &sound_channel->hmem, &sound_channel->mmckinfo2)) { - return -100; - } - if (*(uint16*)sound_channel->hmem != 1) { - sound_channel_free(&sound_channel->hmmio, &sound_channel->hmem); - return -101; - } - if (mmio_seek(&sound_channel->hmmio, &sound_channel->mmckinfo1, &sound_channel->mmckinfo2, offset)) { - sound_channel_free(&sound_channel->hmmio, &sound_channel->hmem); - return -103; - } - sound_channel->var_158 = offset; - return 0; -} - -/** -* -* rct2: 0x0040153B -*/ -int sub_40153B(int channel) -{ - rct_sound_channel* sound_channel = &RCT2_ADDRESS(0x014262E0, rct_sound_channel)[channel]; - if (sound_channel->var_4) { - if (sound_channel->hmmio) { - sound_channel_free(&sound_channel->hmmio, &sound_channel->hmem); - } - if (mmio_open_channel(channel, sound_channel->filename, sound_channel->var_110)) { - return 0; - } - sound_channel->var_164 = sound_channel->var_114; - sound_channel->var_118 = sound_channel->var_110; - sound_channel->var_4 = 0; - } else { - int result = mmio_seek(&sound_channel->hmmio, &sound_channel->mmckinfo1, &sound_channel->mmckinfo2, sound_channel->var_118); - sound_channel->var_158 = sound_channel->var_118; - if (result) { - return 0; - } - } - return 1; -} - -/** -* -* rct2: 0x00401000 -*/ -void audio_timefunc(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2, int channel) -{ - rct_sound_channel* sound_channel = &RCT2_ADDRESS(0x014262E0, rct_sound_channel)[channel]; - DWORD status; - DWORD dwCurrentPlayCursor; - DWORD dwCurrentWriteCursor; - uint32 var1; - int var2; - int bufferlost = 0; - char* buf1; - int buf1size; - char* buf2; - int buf2size; - sound_channel->dsbuffer->lpVtbl->GetStatus(sound_channel->dsbuffer, &status); - if (status & DSBSTATUS_BUFFERLOST) { - if (FAILED(sound_channel->dsbuffer->lpVtbl->Restore(sound_channel->dsbuffer))) { - return; - } - sound_channel->playpos = 0; - bufferlost = 1; - } - sound_channel->dsbuffer->lpVtbl->GetCurrentPosition(sound_channel->dsbuffer, &dwCurrentPlayCursor, &dwCurrentWriteCursor); - if (dwCurrentPlayCursor != sound_channel->playpos || bufferlost) { - if (sound_channel->var_168 && !sound_channel->var_15C) { - if (!sound_channel->var_160) { - sound_channel->var_160 = 1; - if (!sound_channel->var_4) { - LPDIRECTSOUNDBUFFER dsbuffer = RCT2_ADDRESS(RCT2_ADDRESS_DSOUND_BUFFERS, LPDIRECTSOUNDBUFFER)[channel]; - sound_channel->var_0 = 0; - if (dsbuffer) { - dsbuffer->lpVtbl->Stop(dsbuffer); - dsbuffer->lpVtbl->Release(dsbuffer); - RCT2_ADDRESS(RCT2_ADDRESS_DSOUND_BUFFERS, LPDIRECTSOUNDBUFFER)[channel] = 0; - } - if (sound_channel->hmmio) { - sound_channel_free(&sound_channel->hmmio, &sound_channel->hmem); - } - } - } - return; - } - if (dwCurrentPlayCursor >= sound_channel->playpos) { - var1 = dwCurrentPlayCursor - sound_channel->playpos; - } else { - var1 = dwCurrentPlayCursor + sound_channel->bufsize - sound_channel->playpos; - } - if (bufferlost) { - var2 = 2 * sound_channel->bufsize / 6; - } else { - var2 = var1; - } - sound_channel->var_158 += var1; - if (sound_channel->var_168) { - uint32 var3 = sound_channel->var_15C; - uint32* var4 = &sound_channel->var_15C; - if (var3) { - if (var1 <= var3) { - *var4 = var3 - var1; - } else { - *var4 = 0; - } - if (SUCCEEDED(sound_channel->dsbuffer->lpVtbl->Lock(sound_channel->dsbuffer, sound_channel->playpos, var2, (LPVOID*)&buf1, (LPDWORD)&buf1size, (LPVOID*)&buf2, (LPDWORD)&buf2size, 0))) { - uint16 var5 = -(sound_channel->mmckinfo1.cksize != 8); - var5 &= 0x80; - memset(buf1, var5 + 128, buf1size); - if (buf2 && buf2size) { - uint16 var5 = -(sound_channel->mmckinfo1.cksize != 8); - var5 &= 0x80; - memset(buf2, var5 + 128, buf2size); - } - sound_channel->dsbuffer->lpVtbl->Unlock(sound_channel->dsbuffer, buf1, buf1size, buf2, buf2size); - sound_channel->playpos += var2; - if (sound_channel->playpos >= sound_channel->bufsize) { - sound_channel->playpos = sound_channel->playpos - sound_channel->bufsize; - } - return; - } - // TimeFunc() could not lock DirectSoundBuffer - return; - } - } - if (FAILED(sound_channel->dsbuffer->lpVtbl->Lock(sound_channel->dsbuffer, sound_channel->playpos, var2, (LPVOID*)&buf1, (LPDWORD)&buf1size, (LPVOID*)&buf2, (LPDWORD)&buf2size, 0))) { - // TimeFunc() could not lock DirectSoundBuffer - return; - } - if (buf1size) { - if (sound_channel->var_160) { - uint16 var5 = -(sound_channel->mmckinfo1.cksize != 8); - var5 &= 0x80; - memset(buf1, var5 + 128, buf1size); - goto label49; - } - } - int var7; - mmio_read(sound_channel->hmmio, buf1size, buf1, &sound_channel->mmckinfo1, &var7); - if (var7 < buf1size) { - if (!sound_channel->var_164) { - int s = sound_channel->mmckinfo1.cksize; - int t = buf1size - var7; - int v; - if (s == 8) { - v = 128; - } else { - if (s != 16) { - goto label42; - } - v = 0; - } - memset(&buf1[var7], v, t); - label42: - sound_channel->var_168 = 1; - if (dwCurrentPlayCursor <= sound_channel->playpos) { - sound_channel->var_15C = sound_channel->playpos - dwCurrentPlayCursor; - } else { - sound_channel->var_15C = sound_channel->playpos + sound_channel->bufsize - dwCurrentPlayCursor; - } - goto label49; - } - char* v21 = buf1; - int v38 = buf1size; - do { - v38 -= var7; - v21 += var7; - sub_40153B(channel); - mmio_read(sound_channel->hmmio, v38, v21, &sound_channel->mmckinfo1, &var7); - } while(var7 < v38); - } - label49: - if (buf2size == 0 || sound_channel->var_160 != 0) { - if(buf2 != 0 && buf2size != 0 && sound_channel->var_160 != 0) { - int var5 = -(sound_channel->mmckinfo1.cksize != 8); - var5 &= 0x80; - memset(buf2, var5 + 128, buf2size); - } - goto label68; - } - mmio_read(sound_channel->hmmio, buf2size, buf2, &sound_channel->mmckinfo1, &var7); - if (var7 >= buf2size) { - label68: - sound_channel->dsbuffer->lpVtbl->Unlock(sound_channel->dsbuffer, buf1, buf1size, buf2, buf2size); - sound_channel->playpos += var2; - if (sound_channel->playpos >= sound_channel->bufsize) { - sound_channel->playpos -= sound_channel->bufsize; - } - if (bufferlost != 0) { - sound_channel->dsbuffer->lpVtbl->Play(sound_channel->dsbuffer, 0, 0, DSBPLAY_LOOPING); - } - return; - } - if (sound_channel->var_164 != 0) { - char* v26 = buf2; - int v27 = buf2size; - do { - v26 += var7; - v27 -= var7; - sub_40153B(channel); - mmio_read(sound_channel->hmmio, v27, v26, &sound_channel->mmckinfo1, &var7); - } while(var7 < v27); - goto label68; - } - int s = buf2size - var7; - int v; - if (sound_channel->hmem == (HGLOBAL)8) { - v = 128; - } else { - if (sound_channel->hmem != (HGLOBAL)16) { - goto label58; - } - v = 0; - } - memset(&buf2[var7], v, s); - label58: - sound_channel->var_168 = 1; - if (dwCurrentPlayCursor <= sound_channel->playpos) { - sound_channel->var_15C = sound_channel->playpos - dwCurrentPlayCursor; - } else { - sound_channel->var_15C = sound_channel->playpos + sound_channel->bufsize - dwCurrentPlayCursor; - } - goto label68; - } -} - -/** -* -* rct2: 0x004014DF -*/ -int CALLBACK audio_timer_callback(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2) -{ - if (_InterlockedExchange(&RCT2_GLOBAL(0x009E1AAC, LONG), 1) == 0) { - for (int i = 0; i < 4; i++) { - rct_sound_channel* sound_channel = &RCT2_ADDRESS(RCT2_ADDRESS_SOUND_CHANNEL_LIST, rct_sound_channel)[i]; - if(sound_channel->var_0){ - audio_timefunc(uTimerID, uMsg, dwUser, dw1, dw2, i); - } - } - return _InterlockedExchange(&RCT2_GLOBAL(0x009E1AAC, LONG), 0); - } - return 0; -} - -/** -* -* rct2: 0x004018A6 -*/ -int audio_create_timer() -{ - if (RCT2_GLOBAL(0x009E1AA4, int)) { - return 0; - } - for (int i = 0; i < 4; i++) { - rct_sound_channel* sound_channel = &RCT2_ADDRESS(RCT2_ADDRESS_SOUND_CHANNEL_LIST, rct_sound_channel)[i]; - sound_channel->var_0 = 0; - } - RCT2_GLOBAL(0x009E1AA0, MMRESULT) = timeSetEvent(50, 10, (LPTIMECALLBACK)audio_timer_callback, 0, TIME_PERIODIC); - if (!RCT2_GLOBAL(0x009E1AA0, MMRESULT)) { - return 0; - } - RCT2_GLOBAL(0x009E1AA4, int) = 1; - return 1; -} - -/** -* -* rct2: 0x006BA8E0 -*/ -void audio_init1() -{ - int devicenum = 0; - if (RCT2_GLOBAL(0x009AAC5C, uint8)) { - rct_dsdevice* dsdevice = &RCT2_GLOBAL(RCT2_ADDRESS_DSOUND_DEVICES, rct_dsdevice*)[0]; - while (dsdevice->guid.Data1 != RCT2_GLOBAL(RCT2_ADDRESS_DSOUND_GUID, GUID).Data1 || - dsdevice->guid.Data2 != RCT2_GLOBAL(RCT2_ADDRESS_DSOUND_GUID, GUID).Data2 || - dsdevice->guid.Data3 != RCT2_GLOBAL(RCT2_ADDRESS_DSOUND_GUID, GUID).Data3 || - memcmp(dsdevice->guid.Data4, RCT2_GLOBAL(RCT2_ADDRESS_DSOUND_GUID, GUID).Data4, sizeof(dsdevice->guid.Data4)) != 0) { - dsdevice++; - devicenum++; - if (devicenum >= RCT2_GLOBAL(RCT2_ADDRESS_NUM_DSOUND_DEVICES, int)) { - devicenum = 0; - break; - } - } - } - 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); - RCT2_GLOBAL(0x014241BC, uint32) = 3; - HANDLE hfile = osinterface_file_open(path); - RCT2_GLOBAL(0x014241BC, uint32) = 0; - if (hfile != INVALID_HANDLE_VALUE) { - RCT2_GLOBAL(0x014241BC, uint32) = 3; - osinterface_file_read(hfile, &RCT2_GLOBAL(0x009AF47E, uint32), 4); - osinterface_file_close(hfile); - RCT2_GLOBAL(0x014241BC, uint32) = 0; - if (RCT2_GLOBAL(0x009AF47E, uint32) == 0x78787878) { - music_info3->var_0 = 0; - } - } - m++; - } while(m + 1 < 0x2E); -} - -/** -* -* rct2: 0x006BA9B5 -*/ -void audio_init2(int device) -{ - audio_close(); - for (int i = 0; i < countof(gVehicleSoundList); i++) { - rct_vehicle_sound* vehicle_sound = &gVehicleSoundList[i];//&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 successdsound = dsound_create_primary_buffer(0, device, 2, 22050, 16); - RCT2_GLOBAL(0x014241BC, uint32) = 0; - if (!successdsound) { - return; - } - const char * filepath = get_file_path(2); - RCT2_GLOBAL(0x014241BC, uint32) = 1; - int successmap = map_sound_effects(filepath); - RCT2_GLOBAL(0x014241BC, uint32) = 0; - if (!successmap) { - RCT2_GLOBAL(0x014241BC, uint32) = 1; - audio_release(); - RCT2_GLOBAL(0x014241BC, uint32) = 0; - return; - } - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SOUND_DEVICE, uint32) = device; - rct_dsdevice dsdevice = RCT2_GLOBAL(RCT2_ADDRESS_DSOUND_DEVICES, rct_dsdevice*)[device]; - RCT2_GLOBAL(RCT2_ADDRESS_DSOUND_GUID, GUID) = dsdevice.guid; - RCT2_GLOBAL(0x009AAC5C, uint8) = 1; - config_save(); - RCT2_GLOBAL(0x014241BC, uint32) = 1; - int successtimer = audio_create_timer(); - 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; - } - } - if (!(RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) & 1 << 4)) { - gSound_config.forced_software_buffering = 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: 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 @@ -1047,150 +1406,6 @@ int get_dsound_devices() return 0; } -/** -* -* rct2: 0x00404D99 -*/ -int sound_duplicate(rct_sound* newsound, rct_sound* sound) -{ - if (FAILED(RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND)->lpVtbl->DuplicateSoundBuffer(RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND), sound->dsbuffer, &newsound->dsbuffer))) { - return 0; - } else { - newsound->id = sound->id; - newsound->has_caps = sound->has_caps; - newsound->var_0C = sound->var_0C; - sound_add(newsound); - return 1; - } -} - -/** -* -* rct2: 0x00405103 -*/ -rct_sound* sound_begin() -{ - return RCT2_GLOBAL(RCT2_ADDRESS_SOUNDLIST_BEGIN, rct_sound*); -} - -/** -* -* rct2: 0x00405109 -*/ -rct_sound* sound_next(rct_sound* sound) -{ - if (RCT2_GLOBAL(RCT2_ADDRESS_SOUNDLIST_END, rct_sound*) == sound) { - return 0; - } else { - return sound->next; - } -} - -/** -* -* rct2: 0x00405206 -*/ -rct_sound_effect* sound_get_effect(uint16 sound_id) -{ - if (RCT2_GLOBAL(RCT2_ADDRESS_SOUND_EFFECTS_MAPPING, LPVOID) && sound_id < RCT2_GLOBAL(RCT2_ADDRESS_SOUND_EFFECTS_MAPPING, uint32*)[0]) { - return (rct_sound_effect*)(RCT2_GLOBAL(RCT2_ADDRESS_SOUND_EFFECTS_MAPPING, int) + RCT2_GLOBAL(RCT2_ADDRESS_SOUND_EFFECTS_MAPPING, uint32*)[sound_id + 1]); - } - return 0; -} - -/** -* -* rct2: 0x00405054 -*/ -int sound_effect_loadvars(rct_sound_effect* sound_effect, LPWAVEFORMATEX* waveformat, char** data, DWORD* buffersize) -{ - *buffersize = sound_effect->size; - *waveformat = &sound_effect->format; - *data = (char*)&sound_effect->data; - return 1; -} - -/** -* -* rct2: 0x00405076 -*/ -int sound_fill_buffer(LPDIRECTSOUNDBUFFER dsbuffer, char* src, DWORD size) -{ - LPVOID buf; - LPVOID buf2; - DWORD buf2size; - if (SUCCEEDED(dsbuffer->lpVtbl->Lock(dsbuffer, 0, size, &buf, &size, &buf2, &buf2size, 0))) { - memset(buf, 0, size); - memcpy(buf, src, size); - if (buf2size) { - memcpy(buf2, &src[size], buf2size); - } - dsbuffer->lpVtbl->Unlock(dsbuffer, buf, size, buf2, buf2size); - return 1; - } - return 0; -} - -/** -* -* rct2: 0x00404C6D -*/ -int sound_prepare(int sound_id, rct_sound *sound, int channels, int software) -{ - DSBUFFERDESC bufferdesc; - char* buffer = 0; - memset(&bufferdesc, 0, sizeof(bufferdesc)); - bufferdesc.dwSize = sizeof(bufferdesc); - rct_sound* tempsound = sound_begin(); - if (tempsound) { - int wasduplicated = 0; - while (!tempsound->dsbuffer || tempsound->id != sound_id || !sound_duplicate(sound, tempsound)) { - tempsound = sound_next(tempsound); - if (!tempsound) { - wasduplicated = 1; - break; - } - } - if (!wasduplicated) { - return 1; - } - } - rct_sound_effect* sound_effect = sound_get_effect(sound_id); - if (sound_effect) { - if (sound_effect_loadvars(sound_effect, &bufferdesc.lpwfxFormat, &buffer, &bufferdesc.dwBufferBytes)) { - bufferdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_STATIC; - if (channels) { - if (channels == 2) { - bufferdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRL3D | DSBCAPS_STATIC; - } else { - bufferdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPAN | DSBCAPS_CTRLFREQUENCY | DSBCAPS_STATIC; - } - if (RCT2_GLOBAL(0x009E2B90, uint32)) { - bufferdesc.dwFlags |= DSBCAPS_CTRLPAN; - } - if (software) { - bufferdesc.dwFlags |= DSBCAPS_LOCSOFTWARE; - } - if (SUCCEEDED(RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND)->lpVtbl->CreateSoundBuffer(RCT2_GLOBAL(RCT2_ADDRESS_DIRECTSOUND, LPDIRECTSOUND), &bufferdesc, &sound->dsbuffer, 0))) { - if (sound_fill_buffer(sound->dsbuffer, buffer, bufferdesc.dwBufferBytes)) { - sound->id = sound_id; - DSBCAPS caps; - caps.dwSize = sizeof(caps); - sound->dsbuffer->lpVtbl->GetCaps(sound->dsbuffer, &caps); - sound->has_caps = caps.dwFlags; - sound_add(sound); - return 1; - } - sound->dsbuffer->lpVtbl->Release(sound->dsbuffer); - sound->dsbuffer = 0; - } - } - sound->dsbuffer = 0; - } - } - return 0; -} - /** * * rct2: 0x006BB76E @@ -1297,36 +1512,28 @@ int sound_play_panned(int sound_id, int ebx, sint16 x, sint16 y, sint16 z) /** * -* rct2: 0x00401B63 +* rct2: 0x006BB991 */ -int sub_401B63(int channel) +void stop_completed_sounds() { - if (RCT2_ADDRESS(RCT2_ADDRESS_SOUND_CHANNEL_LIST, rct_sound_channel)[channel].var_0) { - return RCT2_ADDRESS(RCT2_ADDRESS_SOUND_CHANNEL_LIST, rct_sound_channel)[channel].var_160 == 0; - } else { - return 0; + if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SOUND_DEVICE, uint32) != -1) { + for (int i = 0; i < 7; i++) { + rct_other_sound* other_sound = &RCT2_ADDRESS(0x009AF484, rct_other_sound)[i]; + if (other_sound->id != (uint16)-1) { + RCT2_GLOBAL(0x014241BC, uint32) = 1; + int isplaying = sound_is_playing(&other_sound->sound); + RCT2_GLOBAL(0x014241BC, uint32) = 0; + if (!isplaying) { + RCT2_GLOBAL(0x014241BC, uint32) = 1; + sound_stop(&other_sound->sound); + RCT2_GLOBAL(0x014241BC, uint32) = 0; + other_sound->id = (uint16)-1; + } + } + } } } -/** -* -* rct2: 0x0040194E -*/ -int sound_channel_load_file2(int channel, const char* filename, int offset) -{ - if (!RCT2_GLOBAL(0x009E1AA4, int)) { - return 0; - } - if (sub_401B63(channel)) { - sound_channel_stop(channel); - } - if (!sound_channel_load_file(channel, filename, offset)) { - RCT2_ADDRESS(RCT2_ADDRESS_SOUND_CHANNEL_LIST, rct_sound_channel)[channel].var_4 = 0; - return 1; - } - return 0; -} - /** * * rct2: 0x006BD0F8 @@ -1356,269 +1563,6 @@ void start_title_music() } } -/** -* -* rct2: 0x00401999 -*/ -int sound_channel_play(int channel, int a2, int volume, int pan, int frequency) -{ - 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); - sound_channel->var_0 = 1; - return 1; -} - -/** -* -* rct2: 0x00401A93 -*/ -int sound_channel_set_frequency(int channel, int frequency) -{ - LPDIRECTSOUNDBUFFER dsbuffer = RCT2_ADDRESS(RCT2_ADDRESS_DSOUND_BUFFERS, LPDIRECTSOUNDBUFFER)[channel]; - if (dsbuffer) { - if (SUCCEEDED(dsbuffer->lpVtbl->SetFrequency(dsbuffer, frequency))) - return 1; - - } - return 0; -} - -/** -* -* rct2: 0x00401AB3 -*/ -int sound_channel_set_pan(int channel, int pan) -{ - LPDIRECTSOUNDBUFFER dsbuffer = RCT2_ADDRESS(RCT2_ADDRESS_DSOUND_BUFFERS, LPDIRECTSOUNDBUFFER)[channel]; - if (dsbuffer) { - if (SUCCEEDED(dsbuffer->lpVtbl->SetPan(dsbuffer, pan))) - return 1; - - } - return 0; -} - -/** -* -* rct2: 0x00401AD3 -*/ -int sound_channel_set_volume(int channel, int volume) -{ - LPDIRECTSOUNDBUFFER dsbuffer = RCT2_ADDRESS(RCT2_ADDRESS_DSOUND_BUFFERS, LPDIRECTSOUNDBUFFER)[channel]; - if (dsbuffer) { - if (SUCCEEDED(dsbuffer->lpVtbl->SetVolume(dsbuffer, volume))) - return 1; - - } - return 0; -} - -/** -* -* rct2: 0x006BB991 -*/ -void stop_completed_sounds() -{ - if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SOUND_DEVICE, uint32) != -1) { - for (int i = 0; i < 7; i++) { - rct_other_sound* other_sound = &RCT2_ADDRESS(0x009AF484, rct_other_sound)[i]; - if (other_sound->id != (uint16)-1) { - RCT2_GLOBAL(0x014241BC, uint32) = 1; - int isplaying = sound_is_playing(&other_sound->sound); - RCT2_GLOBAL(0x014241BC, uint32) = 0; - if (!isplaying) { - RCT2_GLOBAL(0x014241BC, uint32) = 1; - sound_stop(&other_sound->sound); - RCT2_GLOBAL(0x014241BC, uint32) = 0; - other_sound->id = (uint16)-1; - } - } - } - } -} - -/** -* -* rct2: 0x00404E7F -*/ -int sound_play(rct_sound* sound, int looping, int volume, int pan, int frequency) -{ - if (sound->dsbuffer) { - sound_set_frequency(sound, frequency); - sound_set_pan(sound, pan); - sound_set_volume(sound, volume); - DWORD playflags; - if (looping) { - if (looping != 1) - return 1; - - playflags = DSBPLAY_LOOPING; - } else { - playflags = 0; - } - if (SUCCEEDED(sound->dsbuffer->lpVtbl->Play(sound->dsbuffer, 0, 0, playflags))) - return 1; - - } - return 0; -} - -/** -* -* rct2: 0x00404E53 -*/ -int sound_is_playing(rct_sound* sound){ - if (sound->dsbuffer) { - DWORD status; - if (SUCCEEDED(sound->dsbuffer->lpVtbl->GetStatus(sound->dsbuffer, &status))) { - if (status & DSBSTATUS_PLAYING || status & DSBSTATUS_LOOPING) - return 1; - - } - } - return 0; -} - -/** -* -* rct2: 0x00404ED7 -*/ -int sound_set_frequency(rct_sound* sound, int frequency) -{ - if (sound->dsbuffer) { - if (SUCCEEDED(sound->dsbuffer->lpVtbl->SetFrequency(sound->dsbuffer, frequency))) - return 1; - - } - return 0; -} - -/** -* -* rct2: 0x00404EF2 -*/ -int sound_set_pan(rct_sound* sound, int pan) -{ - if (sound->dsbuffer) { - if (SUCCEEDED(sound->dsbuffer->lpVtbl->SetPan(sound->dsbuffer, pan))) - return 1; - - } - return 0; -} - -/** -* -* rct2: 0x00404F0D -*/ -int sound_set_volume(rct_sound* sound, int volume) -{ - if (sound->dsbuffer) { - if (SUCCEEDED(sound->dsbuffer->lpVtbl->SetVolume(sound->dsbuffer, volume))) - return 1; - - } - return 0; -} - -/** -* -* rct2: 0x00404DD8 -*/ -int sound_stop(rct_sound* sound) -{ - if (sound->dsbuffer) { - sound->dsbuffer->lpVtbl->Release(sound->dsbuffer); - sound->dsbuffer = 0; - return sound_remove(sound) ? 1 : 0; - } - return 0; -} - -/** -* -* rct2: 0x0040511C -*/ -rct_sound* sound_add(rct_sound* sound) -{ - if (RCT2_GLOBAL(RCT2_ADDRESS_SOUNDLIST_BEGIN, rct_sound*)) { - RCT2_GLOBAL(RCT2_ADDRESS_SOUNDLIST_END, rct_sound*)->next = sound; - } else { - RCT2_GLOBAL(RCT2_ADDRESS_SOUNDLIST_BEGIN, rct_sound*) = sound; - } - RCT2_GLOBAL(RCT2_ADDRESS_SOUNDLIST_END, rct_sound*) = sound; - sound->next = 0; - return sound; -} - -/** -* -* rct2: 0x00405143 -*/ -rct_sound* sound_remove(rct_sound* sound) -{ - rct_sound* result = RCT2_GLOBAL(RCT2_ADDRESS_SOUNDLIST_BEGIN, rct_sound*); - if (sound == result) { - if (sound == RCT2_GLOBAL(RCT2_ADDRESS_SOUNDLIST_END, rct_sound*)) { - RCT2_GLOBAL(RCT2_ADDRESS_SOUNDLIST_END, rct_sound*) = 0; - RCT2_GLOBAL(RCT2_ADDRESS_SOUNDLIST_BEGIN, rct_sound*) = 0; - } - result = sound->next; - RCT2_GLOBAL(RCT2_ADDRESS_SOUNDLIST_BEGIN, rct_sound*) = result; - } else { - while (result->next != sound) - result = result->next; - - if (sound == RCT2_GLOBAL(RCT2_ADDRESS_SOUNDLIST_END, rct_sound*)) { - RCT2_GLOBAL(RCT2_ADDRESS_SOUNDLIST_END, rct_sound*) = result; - result->next = 0; - } else - result->next = sound->next; - - } - sound->next = 0; - return result; -} - -/** -* -* rct2: 0x00405436 -*/ -void sound_channel_free(HMMIO* hmmio, HGLOBAL* hmem) -{ - if(*hmem) - { - GlobalFree(*hmem); - *hmem = 0; - } - if(*hmmio) - { - mmioClose(*hmmio, 0); - *hmmio = 0; - } -} - -/** -* -* rct2: 0x006BABB4 -*/ -void pause_sounds() -{ - if (++RCT2_GLOBAL(0x009AF59C, uint8) == 1) { - stop_other_sounds(); - stop_vehicle_sounds(); - stop_ride_music(); - stop_crowd_sound(); - } - g_sounds_disabled = 1; -} - /** * * rct2: 0x006BCAE5 @@ -1647,40 +1591,6 @@ void stop_other_sounds() } } -/** -* -* rct2: 0x006BABDF -*/ -void stop_vehicle_sounds() -{ - if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SOUND_DEVICE, sint32) != -1) { - for (int i = 0; i < countof(gVehicleSoundList); i++) { - rct_vehicle_sound* vehicle_sound = &gVehicleSoundList[i];//&RCT2_ADDRESS(RCT2_ADDRESS_VEHICLE_SOUND_LIST, rct_vehicle_sound)[i]; - if (vehicle_sound->id != 0xFFFF) { - if (vehicle_sound->sound1_id != 0xFFFF) { -#ifdef USE_MIXER - Mixer_Stop_Channel(vehicle_sound->sound1_channel); -#else - RCT2_GLOBAL(0x014241BC, uint32) = 1; - sound_stop(&vehicle_sound->sound1); - RCT2_GLOBAL(0x014241BC, uint32) = 0; -#endif - } - if (vehicle_sound->sound2_id != 0xFFFF) { -#ifdef USE_MIXER - Mixer_Stop_Channel(vehicle_sound->sound2_channel); -#else - RCT2_GLOBAL(0x014241BC, uint32) = 1; - sound_stop(&vehicle_sound->sound2); - RCT2_GLOBAL(0x014241BC, uint32) = 0; -#endif - } - } - vehicle_sound->id = 0xFFFF; - } - } -} - /** * * rct2: 0x006BCA9F @@ -1748,28 +1658,137 @@ void stop_title_music() /** * -* rct2: 0x00401A05 +* rct2: 0x006BA8E0 */ -int sound_channel_stop(int channel) +void audio_init1() { - 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->hmmio) { - sound_channel_free(&sound_channel->hmmio, &sound_channel->hmem); + int devicenum = 0; + if (RCT2_GLOBAL(0x009AAC5C, uint8)) { + rct_dsdevice* dsdevice = &RCT2_GLOBAL(RCT2_ADDRESS_DSOUND_DEVICES, rct_dsdevice*)[0]; + while (dsdevice->guid.Data1 != RCT2_GLOBAL(RCT2_ADDRESS_DSOUND_GUID, GUID).Data1 || + dsdevice->guid.Data2 != RCT2_GLOBAL(RCT2_ADDRESS_DSOUND_GUID, GUID).Data2 || + dsdevice->guid.Data3 != RCT2_GLOBAL(RCT2_ADDRESS_DSOUND_GUID, GUID).Data3 || + memcmp(dsdevice->guid.Data4, RCT2_GLOBAL(RCT2_ADDRESS_DSOUND_GUID, GUID).Data4, sizeof(dsdevice->guid.Data4)) != 0) { + dsdevice++; + devicenum++; + if (devicenum >= RCT2_GLOBAL(RCT2_ADDRESS_NUM_DSOUND_DEVICES, int)) { + devicenum = 0; + break; + } + } } + 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); + RCT2_GLOBAL(0x014241BC, uint32) = 3; + HANDLE hfile = osinterface_file_open(path); + RCT2_GLOBAL(0x014241BC, uint32) = 0; + if (hfile != INVALID_HANDLE_VALUE) { + RCT2_GLOBAL(0x014241BC, uint32) = 3; + osinterface_file_read(hfile, &RCT2_GLOBAL(0x009AF47E, uint32), 4); + osinterface_file_close(hfile); + RCT2_GLOBAL(0x014241BC, uint32) = 0; + if (RCT2_GLOBAL(0x009AF47E, uint32) == 0x78787878) { + music_info3->var_0 = 0; + } + } + m++; + } while(m + 1 < 0x2E); +} - 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; +/** +* +* rct2: 0x006BA9B5 +*/ +void audio_init2(int device) +{ + audio_close(); + for (int i = 0; i < countof(gVehicleSoundList)/*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; } - _InterlockedExchange(&RCT2_GLOBAL(0x009E1AAC, LONG), 0); - return 1; + 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 successdsound = dsound_create_primary_buffer(0, device, 2, 22050, 16); + RCT2_GLOBAL(0x014241BC, uint32) = 0; + if (!successdsound) { + return; + } + const char * filepath = get_file_path(2); + RCT2_GLOBAL(0x014241BC, uint32) = 1; + int successmap = map_sound_effects(filepath); + RCT2_GLOBAL(0x014241BC, uint32) = 0; + if (!successmap) { + RCT2_GLOBAL(0x014241BC, uint32) = 1; + audio_release(); + RCT2_GLOBAL(0x014241BC, uint32) = 0; + return; + } + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SOUND_DEVICE, uint32) = device; + rct_dsdevice dsdevice = RCT2_GLOBAL(RCT2_ADDRESS_DSOUND_DEVICES, rct_dsdevice*)[device]; + RCT2_GLOBAL(RCT2_ADDRESS_DSOUND_GUID, GUID) = dsdevice.guid; + RCT2_GLOBAL(0x009AAC5C, uint8) = 1; + config_save(); + RCT2_GLOBAL(0x014241BC, uint32) = 1; + int successtimer = audio_create_timer(); + 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; + } + } + if (!(RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) & 1 << 4)) { + gSound_config.forced_software_buffering = 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: 0x006BAB21 +*/ +void audio_close() +{ + if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SOUND_DEVICE, uint32) != -1) { + stop_other_sounds(); + stop_crowd_sound(); + stop_title_music(); + if (RCT2_GLOBAL(0x009AF284, uint32) & (1 << 0)) { + stop_ride_music(); + RCT2_GLOBAL(0x014241BC, uint32) = 1; + audio_remove_timer(); + RCT2_GLOBAL(0x014241BC, uint32) = 0; + } + RCT2_GLOBAL(0x014241BC, uint32) = 1; + unmap_sound_effects(); + audio_release(); + RCT2_GLOBAL(0x014241BC, uint32) = 0; + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SOUND_DEVICE, uint32) = -1; + } +} + +/** +* +* rct2: 0x006BABB4 +*/ +void pause_sounds() +{ + if (++RCT2_GLOBAL(0x009AF59C, uint8) == 1) { + stop_other_sounds(); + stop_vehicle_sounds(); + stop_ride_music(); + stop_crowd_sound(); + } + g_sounds_disabled = 1; } /** @@ -1783,12 +1802,47 @@ void unpause_sounds() } /** -* Update zoom based volume attenuation for ride music +* +* rct2: 0x006BABDF +*/ +void stop_vehicle_sounds() +{ + if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SOUND_DEVICE, sint32) != -1) { + for (int i = 0; i < countof(gVehicleSoundList)/*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]; + if (vehicle_sound->id != 0xFFFF) { + if (vehicle_sound->sound1_id != 0xFFFF) { +#ifdef USE_MIXER + Mixer_Stop_Channel(vehicle_sound->sound1_channel); +#else + RCT2_GLOBAL(0x014241BC, uint32) = 1; + sound_stop(&vehicle_sound->sound1); + RCT2_GLOBAL(0x014241BC, uint32) = 0; +#endif + } + if (vehicle_sound->sound2_id != 0xFFFF) { +#ifdef USE_MIXER + Mixer_Stop_Channel(vehicle_sound->sound2_channel); +#else + RCT2_GLOBAL(0x014241BC, uint32) = 1; + sound_stop(&vehicle_sound->sound2); + RCT2_GLOBAL(0x014241BC, uint32) = 0; +#endif + } + } + vehicle_sound->id = 0xFFFF; + } + } +} + +/** +* Update zoom based volume attenuation for ride music and clear music list * rct2: 0x006BC348 */ void sub_6BC348() { - RCT2_GLOBAL(0x009AF42C, void*) = &RCT2_GLOBAL(0x009AF430, void*); + RCT2_GLOBAL(0x009AF42C, rct_music_info*) = &RCT2_GLOBAL(0x009AF430, rct_music_info); RCT2_GLOBAL(0x00F438A4, rct_viewport*) = (rct_viewport*)-1; rct_window* window = RCT2_GLOBAL(RCT2_ADDRESS_NEW_WINDOW_PTR, rct_window*); while (1) { @@ -1812,7 +1866,176 @@ void sub_6BC348() } /** -* Play/update ride music based on structs updated somewhere else + * + * 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 bx + * @param ebp + * @param di + * @returns ebp register + */ +int sub_6BC3AC(sint16 x, sint16 y, sint16 z, uint16 bx, uint32 ebp, uint16 di) +{ + uint8 bl = LOBYTE(bx); + uint8 bh = HIBYTE(bx); + 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) = di; + 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 != bl && music_info2->var_1 != bh) { + music_info2++; + channel++; + if (channel >= 2) { + rct_music_info3* music_info3 = &RCT2_GLOBAL(0x009AF1C8, rct_music_info3*)[bh]; + a1 = ebp + 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*)[bh].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 = bl; + music_info->var_1 = bh; + 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 = ebp; + ebp = bh; + rct_music_info3* music_info3 = &RCT2_GLOBAL(0x009AF1C8, rct_music_info3*)[bh]; + eax += music_info3->var_4; + if (eax < music_info3->var_0) { + ebp = eax; + } + } + } + return ebp; +} + +/** +* Play/update ride music based on structs updated in 0x006BC3AC * rct2: 0x006BC6D8 */ void sub_6BC6D8() @@ -1822,14 +2045,15 @@ void sub_6BC6D8() 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] + 8; - if (RCT2_ADDRESS(0x009AA0B1, uint8*)[music_info3->var_0]) { + 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; @@ -1844,7 +2068,6 @@ void sub_6BC6D8() } edi->id = -1; } - while (1) { int v8 = 0; int v9 = 1; @@ -1864,6 +2087,8 @@ void sub_6BC6D8() } 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 { @@ -1872,7 +2097,7 @@ void sub_6BC6D8() 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 = sub_401B63(channel); + int v16 = sound_channel_is_playing(channel); RCT2_GLOBAL(0x014241BC, uint32) = 0; if (v16) { goto label32; diff --git a/src/audio/audio.h b/src/audio/audio.h index 350b922a7e..44e52fbaf6 100644 --- a/src/audio/audio.h +++ b/src/audio/audio.h @@ -36,8 +36,6 @@ extern audio_device *gAudioDevices; void audio_init(); void audio_quit(); void audio_get_devices(); -void audio_init1(); -void audio_init2(int device); #include @@ -63,9 +61,9 @@ typedef struct rct_sound { } rct_sound; typedef struct { - uint32 var_0; + uint32 playing; // 0x000 uint32 var_4; - char filename[MAX_PATH]; // 0x8 + char filename[MAX_PATH]; // 0x008 uint32 var_10C; uint32 var_110; uint32 var_114; @@ -75,11 +73,11 @@ typedef struct { MMCKINFO mmckinfo1; // 0x124 MMCKINFO mmckinfo2; // 0x138 LPDIRECTSOUNDBUFFER dsbuffer; // 0x14C - uint32 bufsize; + uint32 bufsize; // 0x150 uint32 playpos; // 0x154 uint32 var_158; uint32 var_15C; - uint32 var_160; + uint32 stopped; // 0x160 uint32 var_164; uint32 var_168; } rct_sound_channel; @@ -92,7 +90,7 @@ typedef struct { typedef struct { uint16 id; - uint16 var_2; + sint16 volume; // 0x02 rct_sound sound1; // 0x04 uint16 sound1_id; // 0x18 sint16 sound1_volume; // 0x1A @@ -103,17 +101,17 @@ typedef struct { sint16 sound2_volume; // 0x36 sint16 sound2_pan; // 0x38 uint16 sound2_freq; // 0x3A - + // added to openrct2: void* sound1_channel; void* sound2_channel; } rct_vehicle_sound; typedef struct { uint16 id; - sint16 pan; // 0x2 - sint16 var_4; + sint16 panx; // 0x2 + sint16 pany; // 0x4 uint16 frequency; // 0x6 - sint16 var_8; + sint16 volume; // 0x8 uint16 var_A; // 0xA } rct_vehicle_sound_params; @@ -140,8 +138,8 @@ typedef struct { } rct_music_info2; typedef struct { - uint8 var_0; - uint8 pad_1[0x7]; + uint32 var_0; + uint32 var_4; uint8 pathid; //0x8 uint8 var_9; } rct_music_info3; @@ -151,53 +149,72 @@ extern rct_vehicle_sound_params gVehicleSoundParamsList[AUDIO_MAX_VEHICLE_SOUNDS extern rct_vehicle_sound_params *gVehicleSoundParamsListEnd; extern void* gMusicChannels[4]; -int get_dsound_devices(); -int dsound_create_primary_buffer(int a, int device, int channels, int samples, int bits); void audio_timefunc(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2, int channel); -int audio_release(); -MMRESULT mmio_read(HMMIO hmmio, uint32 size, char* buffer, LPMMCKINFO mmckinfo, int* read); -MMRESULT mmio_seek(HMMIO* hmmio, LPMMCKINFO mmckinfo1, LPMMCKINFO mmckinfo2, int offset); -MMRESULT mmio_open(const char* filename, HMMIO* hmmio, HGLOBAL* hmem, LPMMCKINFO mmckinfo); +int CALLBACK audio_timer_callback(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2); int sub_40153B(int channel); int sub_4015E7(int channel); -void sub_401AF3(int channel, const char* filename, int a3, int a4); -int sub_401B63(int channel); -void sub_6BC6D8(); +int sound_channel_load_file(int channel, const char* filename, int offset); +int mmio_open_channel(int channel, char* filename, LONG offset); +int audio_create_timer(); int audio_remove_timer(); -void audio_close(); -LPVOID map_file(LPCSTR lpFileName, DWORD dwCreationDisposition, DWORD dwNumberOfBytesToMap); -int unmap_sound_effects(); -int sound_prepare(int sound_id, rct_sound *sound, int channels, int software); -int sound_play_panned(int sound_id, int ebx, sint16 x, sint16 y, sint16 z); -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); +int sound_channel_load_file2(int channel, const char* filename, int offset); int sound_channel_play(int channel, int a2, int volume, int pan, int frequency); +int sound_channel_stop(int channel); 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); -int sound_channel_load_file2(int channel, const char* filename, int offset); -int sound_channel_load_file(int channel, const char* filename, int offset); -void sound_channel_free(HMMIO* hmmio, HGLOBAL* hmem); +void sub_401AF3(int channel, const char* filename, int a3, int a4); +int sub_401B46(int channel); +int sound_channel_is_playing(int channel); +int audio_release(); +int map_sound_effects(const char* filename); +int unmap_sound_effects(); +int sound_prepare(int sound_id, rct_sound *sound, int channels, int software); +int sound_duplicate(rct_sound* newsound, rct_sound* sound); int sound_stop(rct_sound *sound); int sound_stop_all(); -int unmap_file(LPCVOID base); -int sound_channel_stop(int channel); -rct_sound* sound_add(rct_sound* sound); -rct_sound* sound_remove(rct_sound* sound); +void sound_bufferlost_check(); +int sound_is_playing(rct_sound* sound); +int sound_play(rct_sound* sound, int looping, int volume, int pan, int frequency); +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); +int sound_load3dparameters(); +int sound_load3dposition(); +BOOL CALLBACK dsound_enum_callback_count(LPGUID lpGuid, LPCSTR lpcstrDescription, LPCSTR lpcstrModule, LPVOID lpContext); +int dsound_count_devices(); +BOOL CALLBACK dsound_enum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription, LPCSTR lpcstrModule, LPVOID lpContext); +int sound_effect_loadvars(rct_sound_effect* sound_effect, LPWAVEFORMATEX* waveformat, char** data, DWORD* buffersize); +int sound_fill_buffer(LPDIRECTSOUNDBUFFER dsbuffer, char* src, DWORD size); rct_sound* sound_begin(); rct_sound* sound_next(rct_sound* sound); -void pause_sounds(); +rct_sound* sound_add(rct_sound* sound); +rct_sound* sound_remove(rct_sound* sound); +int sound_bufferlost_restore(rct_sound* sound); +rct_sound_effect* sound_get_effect(uint16 sound_id); +MMRESULT mmio_open(const char* filename, HMMIO* hmmio, HGLOBAL* hmem, LPMMCKINFO mmckinfo); +MMRESULT mmio_read(HMMIO hmmio, uint32 size, char* buffer, LPMMCKINFO mmckinfo, int* read); +void sound_channel_free(HMMIO* hmmio, HGLOBAL* hmem); +MMRESULT mmio_seek(HMMIO* hmmio, LPMMCKINFO mmckinfo1, LPMMCKINFO mmckinfo2, int offset); +LPVOID map_file(LPCSTR lpFileName, DWORD dwCreationDisposition, DWORD dwNumberOfBytesToMap); +int unmap_file(LPCVOID base); +int dsound_create_primary_buffer(int a, int device, int channels, int samples, int bits); +int get_dsound_devices(); +int sound_play_panned(int sound_id, int ebx, sint16 x, sint16 y, sint16 z); void stop_completed_sounds(); +void start_title_music(); void stop_other_sounds(); -void stop_vehicle_sounds(); void stop_ride_music(); void stop_crowd_sound(); void stop_title_music(); -void start_title_music(); +void audio_init1(); +void audio_init2(int device); +void audio_close(); +void pause_sounds(); void unpause_sounds(); +void stop_vehicle_sounds(); +void sub_6BC348(); +void sub_6BC6D8(); // 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 8b46d05086..428431f787 100644 --- a/src/audio/mixer.cpp +++ b/src/audio/mixer.cpp @@ -201,8 +201,10 @@ Channel::Channel() resampler = 0; SetRate(1); SetVolume(SDL_MIX_MAXVOLUME); + oldvolume = 0; SetPan(0.5f); done = true; + stopping = false; } Channel::~Channel() @@ -287,7 +289,8 @@ void Mixer::Close() { Lock(); while (channels.begin() != channels.end()) { - Stop(*(*channels.begin())); + delete *(channels.begin()); + channels.erase(channels.begin()); } Unlock(); SDL_CloseAudioDevice(deviceid); @@ -311,6 +314,7 @@ Channel* Mixer::Play(Stream& stream, int loop, bool deleteondone) if (newchannel) { newchannel->Play(stream, loop); newchannel->deleteondone = deleteondone; + newchannel->stopping = false; channels.push_back(newchannel); } Unlock(); @@ -320,8 +324,7 @@ Channel* Mixer::Play(Stream& stream, int loop, bool deleteondone) void Mixer::Stop(Channel& channel) { Lock(); - channels.remove(&channel); - delete &channel; + channel.stopping = true; Unlock(); } @@ -346,7 +349,7 @@ void SDLCALL Mixer::Callback(void* arg, uint8* stream, int length) std::list::iterator i = mixer->channels.begin(); while (i != mixer->channels.end()) { mixer->MixChannel(*(*i), stream, length); - if ((*i)->done && (*i)->deleteondone) { + if (((*i)->done && (*i)->deleteondone) || (*i)->stopping) { delete (*i); i = mixer->channels.erase(i); } else { @@ -358,9 +361,6 @@ void SDLCALL Mixer::Callback(void* arg, uint8* stream, int length) void Mixer::MixChannel(Channel& channel, uint8* data, int length) { if (channel.stream && !channel.done) { - if (!channel.resampler) { - channel.resampler = speex_resampler_init(format.channels, format.freq, format.freq, 0, 0); - } AudioFormat channelformat = *channel.stream->Format(); int loaded = 0; SDL_AudioCVT cvt; @@ -410,6 +410,9 @@ void Mixer::MixChannel(Channel& channel, uint8* data, int length) 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 + 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))); 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; @@ -438,14 +441,38 @@ void Mixer::MixChannel(Channel& channel, uint8* data, int length) mixlength = length - loaded; } - SDL_MixAudioFormat(&data[loaded], tomix, format.format, mixlength, volume); + int startvolume = channel.oldvolume; + int endvolume = channel.volume; + if (channel.stopping) { + endvolume = 0; + } + int mixvolume = volume; + if (startvolume != endvolume) { + // fade between volume levels to smooth out sound and minimize clicks from sudden volume changes + if (!effectbufferloaded) { + memcpy(effectbuffer, tomix, lengthloaded); + effectbufferloaded = true; + tomix = effectbuffer; + } + mixvolume = SDL_MIX_MAXVOLUME; // set to max since we are adjusting the volume ourselves + int fadelength = mixlength / format.BytesPerSample(); + switch (format.format) { + case AUDIO_S16SYS: + EffectFadeS16((sint16*)effectbuffer, fadelength, startvolume, endvolume); + break; + case AUDIO_U8: + EffectFadeU8((uint8*)effectbuffer, fadelength, startvolume, endvolume); + break; + } + } + + SDL_MixAudioFormat(&data[loaded], tomix, format.format, mixlength, mixvolume); if (dataconverted) { delete[] dataconverted; } channel.offset += readfromstream; - } loaded += lengthloaded; @@ -456,7 +483,9 @@ void Mixer::MixChannel(Channel& channel, uint8* data, int length) } channel.offset = 0; } - } while(loaded < length && channel.loop != 0); + } while(loaded < length && channel.loop != 0 && !channel.stopping); + + channel.oldvolume = channel.volume; if (channel.loop == 0 && channel.offset >= channel.stream->Length()) { channel.done = true; } @@ -483,6 +512,26 @@ void Mixer::EffectPanU8(Channel& channel, uint8* data, int length) } } +void Mixer::EffectFadeS16(sint16* data, int length, int startvolume, int endvolume) +{ + float startvolume_f = (float)startvolume / SDL_MIX_MAXVOLUME; + float endvolume_f = (float)endvolume / SDL_MIX_MAXVOLUME; + for (int i = 0; i < length; i++) { + float t = (float)i / length; + data[i] = (sint16)(data[i] * ((1 - t) * startvolume_f + t * endvolume_f)); + } +} + +void Mixer::EffectFadeU8(uint8* data, int length, int startvolume, int endvolume) +{ + float startvolume_f = (float)startvolume / SDL_MIX_MAXVOLUME; + float endvolume_f = (float)endvolume / SDL_MIX_MAXVOLUME; + for (int i = 0; i < length; i++) { + float t = (float)i / length; + data[i] = (uint8)(data[i] * ((1 - t) * startvolume_f + t * endvolume_f)); + } +} + bool Mixer::MustConvert(Stream& stream) { const AudioFormat* streamformat = stream.Format(); diff --git a/src/audio/mixer.h b/src/audio/mixer.h index 58c5c841ef..1775c58b5c 100644 --- a/src/audio/mixer.h +++ b/src/audio/mixer.h @@ -106,6 +106,8 @@ private: float pan; bool done; bool deleteondone; + bool stopping; + int oldvolume; SpeexResamplerState* resampler; Stream* stream; }; @@ -129,6 +131,8 @@ private: void MixChannel(Channel& channel, uint8* buffer, int length); void EffectPanS16(Channel& channel, sint16* data, int length); void EffectPanU8(Channel& channel, uint8* data, int length); + void EffectFadeS16(sint16* data, int length, int startvolume, int endvolume); + void EffectFadeU8(uint8* data, int length, int startvolume, int endvolume); bool MustConvert(Stream& stream); bool Convert(SDL_AudioCVT& cvt, const uint8* data, unsigned long length, uint8** dataout); SDL_AudioDeviceID deviceid; diff --git a/src/drawing/drawing.c b/src/drawing/drawing.c index 247667a24a..af2e47ea5b 100644 --- a/src/drawing/drawing.c +++ b/src/drawing/drawing.c @@ -152,6 +152,75 @@ void gfx_transpose_palette(int pal, unsigned char product) osinterface_update_palette((char*)0x01424680, 10, 236);//Odd would have expected dest_pointer } +/** +* +* rct2: 0x006EC9CE +* @param x (ax) +* @param y (cx) +* @param base_height (di) +* @param clearance_height (si) +*/ +void gfx_invalidate_scrollingtext(int x, int y, int base_height, int clearance_height) +{ + x += 16; + y += 16; + int left, top, right, bottom; + switch (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32)) { + case 0: + left = (-x + y) - 32; + right = (-x + y) + 32; + top = ((y + x) / 2) - 32 - clearance_height; + bottom = ((y + x) / 2) + 32 - base_height; + break; + case 1: + left = (-x - y) - 32; + right = (-x - y) + 32; + top = ((y - x) / 2) - 32 - clearance_height; + bottom = ((y - x) / 2) + 32 - base_height; + break; + case 2: + left = (x - y) - 32; + right = (x - y) + 32; + top = ((-y - x) / 2) - 32 - clearance_height; + bottom = ((-y - x) / 2) + 32 - base_height; + break; + case 3: + left = (x + y) - 32; + right = (x + y) + 32; + top = ((-y + x) / 2) - 32 - clearance_height; + bottom = ((-y + x) / 2) + 32 - base_height; + break; + } + rct_viewport** viewport_p = RCT2_ADDRESS(RCT2_ADDRESS_NEW_VIEWPORT_PTR, rct_viewport*); + while (*viewport_p) { + rct_viewport* viewport = *viewport_p; + if (viewport->zoom < 1) { + if (right > viewport->view_x && bottom > viewport->view_y && left < viewport->view_x + viewport->view_width) { + if (left < viewport->view_x) { + left = viewport->view_x; + } + if (right > viewport->view_x + viewport->view_width) { + right = viewport->view_x + viewport->view_width; + } + if (top < viewport->view_y + viewport->view_height) { + if (top < viewport->view_y) { + top = viewport->view_y; + } + if (bottom > viewport->view_y + viewport->view_height) { + bottom = viewport->view_y + viewport->view_height; + } + left = ((left - viewport->view_x) >> viewport->zoom) + viewport->x; + top = ((top - viewport->view_y) >> viewport->zoom) + viewport->y; + right = ((right - viewport->view_x) >> viewport->zoom) + viewport->x; + bottom = ((bottom - viewport->view_y) >> viewport->zoom) + viewport->y; + gfx_set_dirty_blocks(left, top, right, bottom); + } + } + } + viewport_p++; + } +} + /** * * rct2: 0x006ED7E5 diff --git a/src/drawing/drawing.h b/src/drawing/drawing.h index a9dabe0648..f167d9ba00 100644 --- a/src/drawing/drawing.h +++ b/src/drawing/drawing.h @@ -70,6 +70,7 @@ rct_drawpixelinfo* clip_drawpixelinfo(rct_drawpixelinfo* dpi, int left, int widt void gfx_set_dirty_blocks(int left, int top, int right, int bottom); void gfx_draw_all_dirty_blocks(); void gfx_redraw_screen_rect(short left, short top, short right, short bottom); +void gfx_invalidate_scrollingtext(int x, int y, int base_height, int clearance_height); void gfx_invalidate_screen(); // palette diff --git a/src/ride/ride.h b/src/ride/ride.h index 77cf17829f..fe255e6920 100644 --- a/src/ride/ride.h +++ b/src/ride/ride.h @@ -141,7 +141,9 @@ typedef struct { uint32 var_118; uint8 pad_11C[0x02]; uint8 var_11E; - uint8 pad_11F[0x05]; + uint8 var_11F; + sint16 var_120; + sint16 var_122; sint16 var_124; sint16 var_126; sint16 var_128; @@ -153,7 +155,10 @@ typedef struct { sint16 var_134; sint16 var_136; money16 price; // 0x138 - uint8 pad_13A[0x06]; + sint16 var_13A; + sint16 var_13C; + uint8 var_13E; + uint8 var_13F; union { rating_tuple ratings; // 0x140 struct { @@ -163,7 +168,7 @@ typedef struct { }; }; uint16 reliability; // 0x146 - uint16 pad_148; + uint16 var_148; uint16 var_14A; uint8 pad_14C; uint8 var_14D; @@ -173,9 +178,12 @@ typedef struct { uint16 var_158; uint8 pad_15A; uint8 num_riders; // 0x15B - uint8 pad_15C[2]; - uint16 maze_tiles; - uint8 pad_160[0x20]; + uint8 var_15C; + uint8 var_15D; + uint16 maze_tiles; // 0x15E + uint8 pad_160[0x16]; + uint8 var_176; + uint8 pad_177[0x9]; sint16 build_date; // 0x180 money16 upkeep_cost; // 0x182 uint16 race_winner; // 0x184 diff --git a/src/ride/vehicle.c b/src/ride/vehicle.c index 4b8321d083..6f2bea8b0e 100644 --- a/src/ride/vehicle.c +++ b/src/ride/vehicle.c @@ -36,9 +36,11 @@ void vehicle_update_sound_params(rct_vehicle* vehicle) { if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 2) && (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 4) || RCT2_GLOBAL(0x0141F570, uint8) == 6)) { if (vehicle->sound1_id != (uint8)-1 || vehicle->sound2_id != (uint8)-1) { - if (vehicle->var_16.width != 0x8000) { - RCT2_GLOBAL(0x009AF5A0, rct_widthheight) = vehicle->var_16; - RCT2_GLOBAL(0x009AF5A4, rct_widthheight) = vehicle->view; + if (vehicle->var_16 != 0x8000) { + RCT2_GLOBAL(0x009AF5A0, sint16) = vehicle->var_16; + RCT2_GLOBAL(0x009AF5A2, sint16) = vehicle->var_18; + RCT2_GLOBAL(0x009AF5A4, sint16) = vehicle->var_1A; + RCT2_GLOBAL(0x009AF5A6, sint16) = vehicle->var_1C; sint16 v4 = RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_x; sint16 v5 = RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_y; sint16 v6 = RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_width / 4; @@ -47,14 +49,14 @@ void vehicle_update_sound_params(rct_vehicle* vehicle) v4 -= v6; v5 -= v7; } - if (v4 < RCT2_GLOBAL(0x009AF5A4, rct_widthheight).width && v5 < RCT2_GLOBAL(0x009AF5A4, rct_widthheight).height) { + if (v4 < RCT2_GLOBAL(0x009AF5A4, sint16) && v5 < RCT2_GLOBAL(0x009AF5A6, sint16)) { sint16 t8 = RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_width + v4; sint16 t9 = RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_height + v5; if (!RCT2_GLOBAL(0x00F438A8, rct_window*)->classification) { t8 += v6 + v6; t9 += v7 + v7; } - if (t8 >= RCT2_GLOBAL(0x009AF5A0, rct_widthheight).width && t9 >= RCT2_GLOBAL(0x009AF5A0, rct_widthheight).height) { + if (t8 >= RCT2_GLOBAL(0x009AF5A0, sint16) && t9 >= RCT2_GLOBAL(0x009AF5A2, sint16)) { uint16 v9 = sub_6BC2F3(vehicle); rct_vehicle_sound_params* i; //for (i = RCT2_ADDRESS(0x00F438B4, rct_vehicle_sound_params); i < RCT2_GLOBAL(0x00F438B0, rct_vehicle_sound_params*) && v9 <= i->var_A; i++); @@ -74,28 +76,26 @@ void vehicle_update_sound_params(rct_vehicle* vehicle) *(j + 1) = *j; } i->var_A = v9; - rct_widthheight v12; - v12.height = vehicle->var_16.height; - v12.width = ((uint16)RCT2_GLOBAL(0x009AF5A0, rct_widthheight).width / 2) + ((uint16)RCT2_GLOBAL(0x009AF5A4, rct_widthheight).width / 2) - RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_x; - v12.width >>= RCT2_GLOBAL(0x00F438A4, rct_viewport*)->zoom; - v12.width += RCT2_GLOBAL(0x00F438A4, rct_viewport*)->x; + int panx = (RCT2_GLOBAL(0x009AF5A0, sint16) / 2) + (RCT2_GLOBAL(0x009AF5A4, sint16) / 2) - RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_x; + panx >>= RCT2_GLOBAL(0x00F438A4, rct_viewport*)->zoom; + panx += RCT2_GLOBAL(0x00F438A4, rct_viewport*)->x; - uint16 v14 = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, uint16); - if (v14 < 64) { - v14 = 64; + uint16 screenwidth = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, uint16); + if (screenwidth < 64) { + screenwidth = 64; } - rct_widthheight v15; - i->pan = (((((uint32)v12.width << 16) / v14) - 0x8000) >> 4); - v15.width = 0; - v15.height = (RCT2_GLOBAL(0x009AF5A0, rct_widthheight).height / 2) + (RCT2_GLOBAL(0x009AF5A4, rct_widthheight).height / 2) - RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_y; - v15.height >>= RCT2_GLOBAL(0x00F438A4, rct_viewport*)->zoom; - v15.height += RCT2_GLOBAL(0x00F438A4, rct_viewport*)->y; + i->panx = ((((panx << 16) / screenwidth) - 0x8000) >> 4); - uint16 v18 = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, uint16); - if (v18 < 64) { - v18 = 64; + int pany = (RCT2_GLOBAL(0x009AF5A2, sint16) / 2) + (RCT2_GLOBAL(0x009AF5A6, sint16) / 2) - RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_y; + pany >>= RCT2_GLOBAL(0x00F438A4, rct_viewport*)->zoom; + pany += RCT2_GLOBAL(0x00F438A4, rct_viewport*)->y; + + uint16 screenheight = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, uint16); + if (screenheight < 64) { + screenheight = 64; } - i->var_4 = (sint16)(((v15.both / v18) - 0x8000) >> 4); + i->pany = ((((pany << 16) / screenheight) - 0x8000) >> 4); + sint32 v19 = vehicle->velocity; int testaddr = (vehicle->var_31 * 0x65); @@ -115,14 +115,13 @@ void vehicle_update_sound_params(rct_vehicle* vehicle) v19 += 16 * vehicle->var_BF; i->frequency = (uint16)v19; i->id = vehicle->sprite_index; - i->var_8 = 0; + i->volume = 0; if (vehicle->x != 0x8000) { - uint16 v22 = (vehicle->y & 0xFFE0) << 8; - v22 |= (vehicle->x & 0xFFE0 | v22) & 0xFFFF; + int tile_idx = (((vehicle->y & 0xFFE0) * 256) + (vehicle->x & 0xFFE0)) / 32; rct_map_element* map_element; - for (map_element = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[v22 >> 3]; map_element->type & MAP_ELEMENT_TYPE_MASK; map_element++); - if (map_element->base_height * 8 > vehicle->z) { - i->var_8 = 0x30; + for (map_element = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx]; map_element->type & MAP_ELEMENT_TYPE_MASK; map_element++); + if (map_element->base_height * 8 > vehicle->z) { // vehicle underground + i->volume = 0x30; } } } @@ -149,7 +148,8 @@ int sub_6BC2F3(rct_vehicle* vehicle) v4 = -v4; } result += ((uint16)v4) >> 13; - rct_vehicle_sound* vehicle_sound = &gVehicleSoundList[0];//RCT2_ADDRESS(RCT2_ADDRESS_VEHICLE_SOUND_LIST, rct_vehicle_sound); + rct_vehicle_sound* vehicle_sound = &gVehicleSoundList[0]; + //rct_vehicle_sound* vehicle_sound = RCT2_ADDRESS(RCT2_ADDRESS_VEHICLE_SOUND_LIST, rct_vehicle_sound); while (vehicle_sound->id != vehicle->sprite_index) { vehicle_sound++; //if (vehicle_sound >= RCT2_GLOBAL(0x009AF42C, rct_vehicle_sound*)) { @@ -194,8 +194,6 @@ void vehicle_sounds_update() for (uint16 i = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_VEHICLE, uint16); i != SPRITE_INDEX_NULL; i = g_sprite_list[i].vehicle.next) { vehicle_update_sound_params(&g_sprite_list[i].vehicle); } - //printf("vehicle sounds: %d\n", (gVehicleSoundParamsListEnd - &gVehicleSoundParamsList[0])); - //RCT2_ADDRESS_VEHICLE_SOUND_LIST; //for (rct_vehicle_sound* vehicle_sound = &RCT2_GLOBAL(RCT2_ADDRESS_VEHICLE_SOUND_LIST, rct_vehicle_sound); vehicle_sound != &RCT2_GLOBAL(0x009AF42C, rct_vehicle_sound); vehicle_sound++) { for(int i = 0; i < countof(gVehicleSoundList); i++){ rct_vehicle_sound* vehicle_sound = &gVehicleSoundList[i]; @@ -239,43 +237,43 @@ void vehicle_sounds_update() } uint8 vol1 = 0xFF; uint8 vol2 = 0xFF; - sint16 v = vehicle_sound_params->var_4; - if (v < 0) { - v = -v; + sint16 pany = vehicle_sound_params->pany; + if (pany < 0) { + pany = -pany; } - if (v > 0xFFF) { - v = 0xFFF; + if (pany > 0xFFF) { + pany = 0xFFF; } - v -= 0x800; - if (v > 0) { - v -= 0x400; - v = -v; - v = (uint16)v / 4; - vol1 = LOBYTE(v); - if (HIBYTE(v) != 0) { + pany -= 0x800; + if (pany > 0) { + pany -= 0x400; + pany = -pany; + pany = pany / 4; + vol1 = LOBYTE(pany); + if ((sint8)HIBYTE(pany) != 0) { vol1 = 0xFF; - if (HIBYTE(v) < 0) { + if ((sint8)HIBYTE(pany) < 0) { vol1 = 0; } } } - sint16 w = vehicle_sound_params->pan; - if (w < 0) { - w = -w; + sint16 panx = vehicle_sound_params->panx; + if (panx < 0) { + panx = -panx; } - if (w > 0xFFF) { - w = 0xFFF; + if (panx > 0xFFF) { + panx = 0xFFF; } - w -= 0x800; - if (w > 0) { - w -= 0x400; - w = -w; - w = (uint16)w / 4; - vol2 = LOBYTE(w); - if (HIBYTE(w) != 0) { + panx -= 0x800; + if (panx > 0) { + panx -= 0x400; + panx = -panx; + panx = panx / 4; + vol2 = LOBYTE(panx); + if ((sint8)HIBYTE(panx) != 0) { vol2 = 0xFF; - if (HIBYTE(w) < 0) { + if ((sint8)HIBYTE(panx) < 0) { vol2 = 0; } } @@ -290,17 +288,19 @@ void vehicle_sounds_update() vol1 = vol1 - RCT2_GLOBAL(RCT2_ADDRESS_VOLUME_ADJUST_ZOOM, uint8); } - rct_vehicle_sound* vehicle_sound = &gVehicleSoundList[0];//&RCT2_GLOBAL(RCT2_ADDRESS_VEHICLE_SOUND_LIST, rct_vehicle_sound); + rct_vehicle_sound* vehicle_sound = &gVehicleSoundList[0]; + //rct_vehicle_sound* vehicle_sound = &RCT2_GLOBAL(RCT2_ADDRESS_VEHICLE_SOUND_LIST, rct_vehicle_sound); while (vehicle_sound_params->id != vehicle_sound->id) { - vehicle_sound++; + vehicle_sound++; // went here 2x //if (vehicle_sound >= &RCT2_GLOBAL(0x009AF42C, rct_vehicle_sound)) { if (vehicle_sound >= &gVehicleSoundList[countof(gVehicleSoundList)]) { - vehicle_sound = &gVehicleSoundList[0];//&RCT2_GLOBAL(RCT2_ADDRESS_VEHICLE_SOUND_LIST, rct_vehicle_sound); + //vehicle_sound = &RCT2_GLOBAL(RCT2_ADDRESS_VEHICLE_SOUND_LIST, rct_vehicle_sound); + vehicle_sound = &gVehicleSoundList[0]; int i = 0; while (vehicle_sound->id != (uint16)-1) { vehicle_sound++; i++; - if (i >= countof(gVehicleSoundList)/*RCT2_GLOBAL(0x009AAC75, uint8)*/) { + if (i >= countof(gVehicleSoundList)/*i >= RCT2_GLOBAL(0x009AAC75, uint8)*/) { vehicle_sound_params = (rct_vehicle_sound_params*)((int)vehicle_sound_params + 10); goto label28; } @@ -308,31 +308,31 @@ void vehicle_sounds_update() vehicle_sound->id = vehicle_sound_params->id; vehicle_sound->sound1_id = (uint16)-1; vehicle_sound->sound2_id = (uint16)-1; - vehicle_sound->var_2 = 0x30; + vehicle_sound->volume = 0x30; break; } } - uint8 v21 = vehicle_sound_params->var_8 & 0xFF; - uint8 v22 = vehicle_sound->var_2 & 0xFF; - if (v22 != v21) { - if (v22 < v21) { - v22 += 4; + int tempvolume = vehicle_sound->volume; + if (tempvolume != vehicle_sound_params->volume) { + if (tempvolume < vehicle_sound_params->volume) { + tempvolume += 4; } else { - v22 -= 4; + tempvolume -= 4; } } - vehicle_sound->var_2 = v22; - if (vol1 < v22) { + vehicle_sound->volume = tempvolume; + if (vol1 < tempvolume) { vol1 = 0; } else { - vol1 = vol1 - v22; + vol1 = vol1 - tempvolume; } + // do sound1 stuff, track noise rct_sprite* sprite = &g_sprite_list[vehicle_sound_params->id]; - sint16 volume = sprite->vehicle.sound1_volume; + int volume = sprite->vehicle.sound1_volume; volume *= vol1; - volume = (uint16)volume / 8; + volume = volume / 8; volume -= 0x1FFF; if (volume < -10000) { volume = -10000; @@ -367,7 +367,7 @@ void vehicle_sounds_update() sound_prepare(sprite->vehicle.sound1_id, &vehicle_sound->sound1, 1, RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_SOUND_SW_BUFFER, uint32)); RCT2_GLOBAL(0x014241BC, uint32) = 0; #endif - vehicle_sound->sound1_pan = vehicle_sound_params->pan; + vehicle_sound->sound1_pan = vehicle_sound_params->panx; vehicle_sound->sound1_volume = volume; vehicle_sound->sound1_freq = vehicle_sound_params->frequency; uint16 frequency = vehicle_sound_params->frequency; @@ -375,7 +375,7 @@ void vehicle_sounds_update() frequency = (frequency / 2) + 4000; } uint8 looping = RCT2_ADDRESS(0x009AF51E, uint8)[2 * sprite->vehicle.sound1_id]; - int pan = vehicle_sound_params->pan; + int pan = vehicle_sound_params->panx; if (!RCT2_GLOBAL(0x009AAC6D, uint8)) { pan = 0; } @@ -398,14 +398,14 @@ void vehicle_sounds_update() RCT2_GLOBAL(0x014241BC, uint32) = 0; #endif } - if (vehicle_sound_params->pan != vehicle_sound->sound1_pan) { - vehicle_sound->sound1_pan = vehicle_sound_params->pan; + if (vehicle_sound_params->panx != vehicle_sound->sound1_pan) { + vehicle_sound->sound1_pan = vehicle_sound_params->panx; if (RCT2_GLOBAL(0x009AAC6D, uint8)) { #ifdef USE_MIXER - Mixer_Channel_Pan(vehicle_sound->sound1_channel, DStoMixerPan(vehicle_sound_params->pan)); + Mixer_Channel_Pan(vehicle_sound->sound1_channel, DStoMixerPan(vehicle_sound_params->panx)); #else RCT2_GLOBAL(0x014241BC, uint32) = 1; - sound_set_pan(&vehicle_sound->sound1, vehicle_sound_params->pan); + sound_set_pan(&vehicle_sound->sound1, vehicle_sound_params->panx); RCT2_GLOBAL(0x014241BC, uint32) = 0; #endif } @@ -464,7 +464,7 @@ void vehicle_sounds_update() sound_prepare(sprite->vehicle.sound2_id, &vehicle_sound->sound2, 1, RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_SOUND_SW_BUFFER, uint32)); RCT2_GLOBAL(0x014241BC, uint32) = 0; #endif - vehicle_sound->sound2_pan = vehicle_sound_params->pan; + vehicle_sound->sound2_pan = vehicle_sound_params->panx; vehicle_sound->sound2_volume = volume; vehicle_sound->sound2_freq = vehicle_sound_params->frequency; uint16 frequency = vehicle_sound_params->frequency; @@ -476,7 +476,7 @@ void vehicle_sounds_update() frequency = 25700; } uint8 looping = RCT2_ADDRESS(0x009AF51E, uint8)[2 * sprite->vehicle.sound2_id]; - int pan = vehicle_sound_params->pan; + int pan = vehicle_sound_params->panx; if (!RCT2_GLOBAL(0x009AAC6D, uint8)) { pan = 0; } @@ -499,14 +499,14 @@ void vehicle_sounds_update() #endif vehicle_sound->sound2_volume = volume; } - if (vehicle_sound_params->pan != vehicle_sound->sound2_pan) { - vehicle_sound->sound2_pan = vehicle_sound_params->pan; + if (vehicle_sound_params->panx != vehicle_sound->sound2_pan) { + vehicle_sound->sound2_pan = vehicle_sound_params->panx; if (RCT2_GLOBAL(0x009AAC6D, uint8)) { #ifdef USE_MIXER - Mixer_Channel_Pan(vehicle_sound->sound2_channel, DStoMixerPan(vehicle_sound_params->pan)); + Mixer_Channel_Pan(vehicle_sound->sound2_channel, DStoMixerPan(vehicle_sound_params->panx)); #else RCT2_GLOBAL(0x014241BC, uint32) = 1; - sound_set_pan(&vehicle_sound->sound2, vehicle_sound_params->pan); + sound_set_pan(&vehicle_sound->sound2, vehicle_sound_params->panx); RCT2_GLOBAL(0x014241BC, uint32) = 0; #endif } diff --git a/src/ride/vehicle.h b/src/ride/vehicle.h index 4839a014d1..4f7f0db47c 100644 --- a/src/ride/vehicle.h +++ b/src/ride/vehicle.h @@ -23,14 +23,6 @@ #include "../common.h" -typedef union { - struct { - sint16 width; - sint16 height; - }; - sint32 both; -} rct_widthheight; - typedef struct { uint8 sprite_identifier; // 0x00 uint8 pad_01[0x03]; @@ -44,8 +36,10 @@ typedef struct { sint16 y; // 0x10 sint16 z; // 0x12 uint8 pad_14[0x02]; - rct_widthheight var_16; - rct_widthheight view; // 0x1A + sint16 var_16; + sint16 var_18; + sint16 var_1A; + sint16 var_1C; uint16 var_1E; uint8 pad_20[0x08]; sint32 velocity; // 0x28 diff --git a/src/windows/options.c b/src/windows/options.c index cbad705516..168281a8fb 100644 --- a/src/windows/options.c +++ b/src/windows/options.c @@ -476,11 +476,11 @@ static void window_options_dropdown() audio_init2(dropdownIndex); if (dropdownIndex < gAudioDeviceCount) { #ifdef USE_MIXER - int devicenum = dropdownIndex; - if (devicenum == 0) { - devicenum = 1; + if (dropdownIndex == 0) { + Mixer_Init(NULL); + } else { + Mixer_Init(gAudioDevices[dropdownIndex].name); } - Mixer_Init(gAudioDevices[devicenum].name); #endif } /*#ifdef _MSC_VER