12 #include "../stdafx.h" 
   13 #include "../openttd.h" 
   14 #include "../driver.h" 
   16 #include "../core/alloc_func.hpp" 
   17 #include "../core/bitmath_func.hpp" 
   18 #include "../core/math_func.hpp" 
   22 #include "../os/windows/win32.h" 
   24 #include "../safeguards.h" 
   28 static HWAVEOUT _waveout;
 
   29 static WAVEHDR _wave_hdr[2];
 
   31 static HANDLE _thread;
 
   32 static DWORD _threadId;
 
   35 static void PrepareHeader(WAVEHDR *hdr)
 
   37   hdr->dwBufferLength = _bufsize * 4;
 
   39   hdr->lpData = MallocT<char>(_bufsize * 4);
 
   40   if (waveOutPrepareHeader(_waveout, hdr, 
sizeof(WAVEHDR)) != MMSYSERR_NOERROR) 
throw "waveOutPrepareHeader failed";
 
   43 static DWORD WINAPI SoundThread(LPVOID arg)
 
   45   SetWin32ThreadName(-1, 
"ottd:win-sound");
 
   48     for (WAVEHDR *hdr = _wave_hdr; hdr != 
endof(_wave_hdr); hdr++) {
 
   49       if ((hdr->dwFlags & WHDR_INQUEUE) != 0) 
continue;
 
   50       MxMixSamples(hdr->lpData, hdr->dwBufferLength / 4);
 
   51       if (waveOutWrite(_waveout, hdr, 
sizeof(WAVEHDR)) != MMSYSERR_NOERROR) {
 
   52         MessageBox(NULL, _T(
"Sounds are disabled until restart."), _T(
"waveOutWrite failed"), MB_ICONINFORMATION);
 
   56     WaitForSingleObject(_event, INFINITE);
 
   57   } 
while (_waveout != NULL);
 
   65   wfex.wFormatTag = WAVE_FORMAT_PCM;
 
   67   wfex.wBitsPerSample = 16;
 
   69   wfex.nBlockAlign = (wfex.nChannels * wfex.wBitsPerSample) / 8;
 
   70   wfex.nAvgBytesPerSec = wfex.nSamplesPerSec * wfex.nBlockAlign;
 
   74   _bufsize = 
min(_bufsize, UINT16_MAX);
 
   77     if (NULL == (_event = CreateEvent(NULL, FALSE, FALSE, NULL))) 
throw "Failed to create event";
 
   79     if (waveOutOpen(&_waveout, WAVE_MAPPER, &wfex, (DWORD_PTR)_event, 0, CALLBACK_EVENT) != MMSYSERR_NOERROR) 
throw "waveOutOpen failed";
 
   81     MxInitialize(wfex.nSamplesPerSec);
 
   83     PrepareHeader(&_wave_hdr[0]);
 
   84     PrepareHeader(&_wave_hdr[1]);
 
   86     if (NULL == (_thread = CreateThread(NULL, 8192, SoundThread, 0, 0, &_threadId))) 
throw "Failed to create thread";
 
   87   } 
catch (
const char *
error) {
 
   97   HWAVEOUT waveout = _waveout;
 
  102   WaitForSingleObject(_thread, INFINITE);
 
  105   waveOutReset(waveout);
 
  106   waveOutUnprepareHeader(waveout, &_wave_hdr[0], 
sizeof(WAVEHDR));
 
  107   waveOutUnprepareHeader(waveout, &_wave_hdr[1], 
sizeof(WAVEHDR));
 
  108   waveOutClose(waveout);
 
  110   CloseHandle(_thread);