tron@2186: /* $Id$ */ tron@2186: tron@2189: #include "../stdafx.h" tron@2189: #include "../openttd.h" tron@2189: #include "../driver.h" tron@2189: #include "../functions.h" tron@2189: #include "../mixer.h" rubidium@5838: #include "../helpers.hpp" tron@2189: #include "win32_s.h" truelight@0: #include tron@2189: #include truelight@0: truelight@0: static HWAVEOUT _waveout; truelight@0: static WAVEHDR _wave_hdr[2]; truelight@0: static int _bufsize; tron@2171: truelight@0: static void PrepareHeader(WAVEHDR *hdr) truelight@0: { tron@1468: hdr->dwBufferLength = _bufsize * 4; truelight@0: hdr->dwFlags = 0; KUDr@5860: hdr->lpData = MallocT(_bufsize * 4); tron@1468: if (hdr->lpData == NULL || tron@1468: waveOutPrepareHeader(_waveout, hdr, sizeof(WAVEHDR)) != MMSYSERR_NOERROR) truelight@0: error("waveOutPrepareHeader failed"); truelight@0: } truelight@0: darkvater@1102: static void FillHeaders(void) truelight@0: { truelight@0: WAVEHDR *hdr; tron@1468: tron@1468: for (hdr = _wave_hdr; hdr != endof(_wave_hdr); hdr++) { truelight@0: if (!(hdr->dwFlags & WHDR_INQUEUE)) { tron@2977: MxMixSamples(hdr->lpData, hdr->dwBufferLength / 4); truelight@0: if (waveOutWrite(_waveout, hdr, sizeof(WAVEHDR)) != MMSYSERR_NOERROR) truelight@0: error("waveOutWrite failed"); truelight@0: } truelight@0: } truelight@0: } truelight@0: tron@2449: static void CALLBACK waveOutProc(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, tron@1468: DWORD dwParam1, DWORD dwParam2) truelight@0: { tron@1468: switch (uMsg) { tron@1468: case WOM_DONE: tron@1468: if (_waveout) FillHeaders(); tron@1468: break; tron@1468: tron@1468: default: tron@1468: break; truelight@0: } truelight@0: } truelight@0: tron@2171: static const char *Win32SoundStart(const char* const* parm) truelight@0: { truelight@0: WAVEFORMATEX wfex; truelight@0: int hz; truelight@193: truelight@0: _bufsize = GetDriverParamInt(parm, "bufsize", 1024); truelight@0: hz = GetDriverParamInt(parm, "hz", 11025); truelight@0: wfex.wFormatTag = WAVE_FORMAT_PCM; truelight@0: wfex.nChannels = 2; truelight@0: wfex.nSamplesPerSec = hz; tron@2171: wfex.nAvgBytesPerSec = hz * 2 * 2; truelight@0: wfex.nBlockAlign = 4; truelight@0: wfex.wBitsPerSample = 16; tron@2449: if (waveOutOpen(&_waveout, WAVE_MAPPER, &wfex, (DWORD_PTR)&waveOutProc, 0, CALLBACK_FUNCTION) != MMSYSERR_NOERROR) truelight@0: return "waveOutOpen failed"; truelight@0: PrepareHeader(&_wave_hdr[0]); truelight@0: PrepareHeader(&_wave_hdr[1]); truelight@0: FillHeaders(); truelight@0: return NULL; truelight@0: } truelight@0: darkvater@1102: static void Win32SoundStop(void) truelight@0: { truelight@0: HWAVEOUT waveout = _waveout; tron@1468: truelight@0: _waveout = NULL; truelight@0: waveOutReset(waveout); truelight@0: waveOutUnprepareHeader(waveout, &_wave_hdr[0], sizeof(WAVEHDR)); truelight@0: waveOutUnprepareHeader(waveout, &_wave_hdr[1], sizeof(WAVEHDR)); truelight@0: waveOutClose(waveout); truelight@0: } truelight@0: truelight@0: const HalSoundDriver _win32_sound_driver = { truelight@0: Win32SoundStart, truelight@0: Win32SoundStop, truelight@0: };