diff --git a/src/audio.c b/src/audio.c index 6fe7726f63..0299246ac7 100644 --- a/src/audio.c +++ b/src/audio.c @@ -344,7 +344,185 @@ int map_sound_info(const char* filename) */ void sub_401000(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2, int channel) { - RCT2_CALLFUNC_6(0x00401000, void, UINT, UINT, DWORD_PTR, DWORD_PTR, DWORD_PTR, int, uTimerID, uMsg, dwUser, dw1, dw2, channel); + //RCT2_CALLFUNC_6(0x00401000, void, UINT, UINT, DWORD_PTR, DWORD_PTR, DWORD_PTR, int, uTimerID, uMsg, dwUser, dw1, dw2, channel); + rct_sound_unknown* unknown = &RCT2_ADDRESS(0x014262E0, rct_sound_unknown)[channel]; + DWORD status; + DWORD dwCurrentPlayCursor; + DWORD dwCurrentWriteCursor; + int var1; + int var2; + int bufferlost = 0; + char* buf1; + int buf1size; + char* buf2; + int buf2size; + unknown->dsbuffer->lpVtbl->GetStatus(unknown->dsbuffer, &status); + if (status & DSBSTATUS_BUFFERLOST) { + if (FAILED(unknown->dsbuffer->lpVtbl->Restore(unknown->dsbuffer))) { + return; + } + unknown->playpos = 0; + bufferlost = 1; + } + unknown->dsbuffer->lpVtbl->GetCurrentPosition(unknown->dsbuffer, &dwCurrentPlayCursor, &dwCurrentWriteCursor); + if (dwCurrentPlayCursor != unknown->playpos || bufferlost) { + if (unknown->var_168 && !unknown->var_15C) { + if (!unknown->var_160) { + unknown->var_160 = 1; + if (!unknown->var_4) { + LPDIRECTSOUNDBUFFER dsbuffer = RCT2_ADDRESS(RCT2_ADDRESS_DSOUND_BUFFERS, LPDIRECTSOUNDBUFFER)[channel]; + unknown->var_0 = 0; + if (dsbuffer) { + dsbuffer->lpVtbl->Stop(dsbuffer); + dsbuffer->lpVtbl->Release(dsbuffer); + RCT2_ADDRESS(RCT2_ADDRESS_DSOUND_BUFFERS, LPDIRECTSOUNDBUFFER)[channel] = 0; + } + if (unknown->var_120) { + sound_channel_free(&unknown->var_120, &unknown->var_11C); + } + } + } + return; + } + if (dwCurrentPlayCursor >= unknown->playpos) { + var1 = dwCurrentPlayCursor - unknown->playpos; + } else { + var1 = dwCurrentPlayCursor + unknown->var_150 - unknown->playpos; + } + if (bufferlost) { + var2 = 2 * unknown->var_150 / 6; + } else { + var2 = var1; + } + unknown->var_158 += var1; + if (unknown->var_168) { + int var3 = unknown->var_15C; + int* var4 = &unknown->var_15C; + if (var3) { + if (var1 <= var3) { + *var4 = var3 - var1; + } else { + *var4 = 0; + } + if (SUCCEEDED(unknown->dsbuffer->lpVtbl->Lock(unknown->dsbuffer, unknown->playpos, var2, &buf1, &buf1size, &buf2, &buf2size, 0))) { + char var5 = -(((char*)unknown->var_11C + 14) != (char *)8); + var5 &= 0x80; + memset(buf1, var5 + 128, buf1size); + if (buf2 && buf2size) { + char var5 = -(((char*)unknown->var_11C + 14) != (char *)8); + var5 &= 0x80; + memset(buf2, var5 + 128, buf2size); + } + unknown->dsbuffer->lpVtbl->Unlock(unknown->dsbuffer, buf1, buf1size, buf2, buf2size); + unknown->playpos += var2; + if( unknown->playpos >= unknown->var_150) { + unknown->playpos = unknown->playpos - unknown->var_150; + } + return; + } + // TimeFunc() could not lock DirectSoundBuffer + return; + } + } + if (FAILED(unknown->dsbuffer->lpVtbl->Lock(unknown->dsbuffer, unknown->playpos, var2, &buf1, &buf1size, &buf2, &buf2size, 0))) { + // TimeFunc() could not lock DirectSoundBuffer + return; + } + if (buf1size) { + if (unknown->var_160) { + int var5 = -(((char*)unknown->var_11C + 14) != (char *)8); + var5 &= 0x80; + memset(buf1, var5 + 128, buf1size); + goto label49; + } + } + int var7; + RCT2_CALLFUNC_5(0x00405383, int, HMMIO, int, char*, int*, int*, unknown->var_120, buf1size, buf1, &unknown->var_124, &var7); + if (var7 < buf1size) { + if (!unknown->var_164) { + int s = *(char*)((char*)unknown->var_11C + 14); + 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: + unknown->var_168 = 1; + if (dwCurrentPlayCursor <= unknown->playpos) { + unknown->var_15C = unknown->playpos - dwCurrentPlayCursor; + } else { + unknown->var_15C = unknown->playpos + unknown->var_150 - dwCurrentPlayCursor; + } + goto label49; + } + char* v21 = buf1; + int v38 = buf1size; + do { + v38 -= var7; + v21 += var7; + RCT2_CALLFUNC_1(0x0040153B, int, int, channel); + RCT2_CALLFUNC_5(0x00405383, int, HMMIO, int, char*, int*, int*, unknown->var_120, v38, v21, &unknown->var_124, &var7); + } while(var7 < v38); + } + label49: + if (buf2size == 0 || unknown->var_160 != 0) { + if(buf2 != 0 && buf2size != 0 && unknown->var_160 != 0) { + int var5 = -(*(char*)((char*)unknown->var_11C + 14) != 8); + var5 &= 0x80; + memset(buf2, var5 + 128, buf2size); + } + goto label68; + } + RCT2_CALLFUNC_5(0x00405383, int, HMMIO, int, char*, int*, int*, unknown->var_120, buf2size, buf2, &unknown->var_124, &var7); + if (var7 >= buf2size) { + label68: + unknown->dsbuffer->lpVtbl->Unlock(unknown->dsbuffer, buf1, buf1size, buf2, buf2size); + unknown->playpos += var2; + if( unknown->playpos >= unknown->var_150 ) { + unknown->playpos -= unknown->var_150; + } + if (bufferlost != 0) { + unknown->dsbuffer->lpVtbl->Play(unknown->dsbuffer, 0, 0, DSBPLAY_LOOPING); + } + return; + } + if (unknown->var_164 != 0) { + char* v26 = buf2; + int v27 = buf2size; + do { + v26 += var7; + v27 -= var7; + RCT2_CALLFUNC_1(0x0040153B, int, int, channel); + RCT2_CALLFUNC_5(0x00405383, int, HMMIO, int, char*, int*, int*, unknown->var_120, v27, v26, &unknown->var_124, &var7); + } while(var7 < v27); + goto label68; + } + int s = buf2size - var7; + int v; + if (unknown->var_11C == (HGLOBAL)8) { + v = 128; + } else { + if (unknown->var_11C != (HGLOBAL)16) { + goto label58; + } + v = 0; + } + memset(&buf2[var7], v, s); + label58: + unknown->var_168 = 1; + if (dwCurrentPlayCursor <= unknown->playpos) { + unknown->var_15C = unknown->playpos - dwCurrentPlayCursor; + } else { + unknown->var_15C = unknown->playpos + unknown->var_150 - dwCurrentPlayCursor; + } + goto label68; + } } /** diff --git a/src/audio.h b/src/audio.h index 85aba58db8..b630ba92ce 100644 --- a/src/audio.h +++ b/src/audio.h @@ -100,6 +100,101 @@ typedef struct { rct_sound sound; } rct_other_sound; +typedef struct { + uint32 var_0; + uint32 var_4; + uint32 var_8; + uint16 var_C; + uint16 var_E; + uint32 var_10; + uint32 var_14; + uint32 var_18; + uint32 var_1C; + uint32 var_20; + uint32 var_24; + uint32 var_28; + uint32 var_2C; + uint32 var_30; + uint32 var_34; + uint32 var_38; + uint32 var_3C; + uint32 var_40; + uint32 var_44; + uint32 var_48; + uint32 var_4C; + uint32 var_50; + uint32 var_54; + uint32 var_58; + uint32 var_5C; + uint32 var_60; + uint32 var_64; + uint32 var_68; + uint32 var_6C; + uint32 var_70; + uint32 var_74; + uint32 var_78; + uint32 var_7C; + uint32 var_80; + uint32 var_84; + uint32 var_88; + uint32 var_8C; + uint32 var_90; + uint32 var_94; + uint32 var_98; + uint32 var_9C; + uint32 var_A0; + uint32 var_A4; + uint32 var_A8; + uint32 var_AC; + uint32 var_B0; + uint32 var_B4; + uint32 var_B8; + uint32 var_BC; + uint32 var_C0; + uint32 var_C4; + uint32 var_C8; + uint32 var_CC; + uint32 var_D0; + uint32 var_D4; + uint32 var_D8; + uint32 var_DC; + uint32 var_E0; + uint32 var_E4; + uint32 var_E8; + uint32 var_EC; + uint32 var_F0; + uint32 var_F4; + uint32 var_F8; + uint32 var_FC; + uint32 var_100; + uint32 var_104; + uint32 var_108; + uint32 var_10C; + uint32 var_110; + uint32 var_114; + uint32 var_118; + HGLOBAL var_11C; + HMMIO var_120; + uint32 var_124; + uint32 var_128; + uint32 var_12C; + uint32 var_130; + uint32 var_134; + uint32 var_138; + uint32 var_13C; + uint32 var_140; + uint32 var_144; + uint32 var_148; + LPDIRECTSOUNDBUFFER dsbuffer; // 0x14C + uint32 var_150; + uint32 playpos; // 0x154 + uint32 var_158; + uint32 var_15C; + uint32 var_160; + uint32 var_164; + uint32 var_168; +} rct_sound_unknown; + int get_dsound_devices(); int sound_prepare(int sound_id, rct_sound *sound, int channels, int software); int sound_play_panned(int sound_id, int x); @@ -112,6 +207,7 @@ int sound_channel_play(int channel, int a2, int volume, int pan, int frequency); int sound_channel_set_frequency(int channel, int frequency); int sound_channel_set_pan(int channel, int pan); int sound_channel_set_volume(int channel, int volume); +void sound_channel_free(HMMIO* hmmio, HGLOBAL* hmem); int sound_stop(rct_sound *sound); int sound_stop_all(); int unmap_file(LPCVOID base);