12 #include "../stdafx.h" 
   13 #include "../string_func.h" 
   17 #include "../os/windows/win32.h" 
   19 #include "../safeguards.h" 
   29   char start_song[MAX_PATH];
 
   36   assert(filename != NULL);
 
   39   _midi.stop_song = 
false;
 
   40   SetEvent(
_midi.wait_obj);
 
   46     _midi.stop_song = 
true;
 
   47     _midi.start_song[0] = 
'\0';
 
   48     SetEvent(
_midi.wait_obj);
 
   60   SetEvent(
_midi.wait_obj);
 
   69   _vsntprintf(buf, 
lengthof(buf), cmd, va);
 
   71   return mciSendString(buf, NULL, 0, 0);
 
   74 static bool MidiIntPlaySong(
const char *filename)
 
   81     if (GetShortPathName(
OTTD2FS(filename), buf, MAX_PATH) == 0) 
return false;
 
   82     if (
MidiSendCommand(_T(
"open \"%s\" type sequencer alias song"), buf) != 0) 
return false;
 
   89 static void MidiIntStopSong()
 
   94 static void MidiIntSetVolume(
int vol)
 
   96   DWORD v = (vol * 65535 / 127);
 
   97   midiOutSetVolume((HMIDIOUT)
_midi.devid, v + (v << 16));
 
  100 static bool MidiIntIsSongPlaying()
 
  103   mciSendStringA(
"status song mode", buf, 
sizeof(buf), 0);
 
  104   return strcmp(buf, 
"playing") == 0 || strcmp(buf, 
"seeking") == 0;
 
  107 static DWORD WINAPI MidiThread(LPVOID arg)
 
  109   SetWin32ThreadName(-1, 
"ottd:win-midi");
 
  118       MidiIntSetVolume(vol);
 
  121     s = 
_midi.start_song;
 
  123       _midi.playing = MidiIntPlaySong(s);
 
  127       if (!
_midi.playing) WaitForMultipleObjects(1, &
_midi.wait_obj, FALSE, 5000);
 
  131       _midi.stop_song = 
false;
 
  132       _midi.playing = 
false;
 
  136     if (
_midi.playing && !MidiIntIsSongPlaying()) 
_midi.playing = 
false;
 
  138     WaitForMultipleObjects(1, &
_midi.wait_obj, FALSE, 1000);
 
  139   } 
while (!
_midi.terminate);
 
  147   MIDIOUTCAPS midicaps;
 
  152   mciSendStringA(
"capability sequencer has audio", buf, 
lengthof(buf), 0);
 
  153   if (strcmp(buf, 
"true") != 0) 
return "MCI sequencer can't play audio";
 
  159   _midi.devid = MIDI_MAPPER;
 
  160   for (dev = 0, nbdev = midiOutGetNumDevs(); dev < nbdev; dev++) {
 
  161     if (midiOutGetDevCaps(dev, &midicaps, 
sizeof(midicaps)) == 0 && (midicaps.dwSupport & MIDICAPS_VOLUME)) {
 
  167   if (NULL == (
_midi.wait_obj = CreateEvent(NULL, FALSE, FALSE, NULL))) 
return "Failed to create event";
 
  172   if (NULL == (
_midi.thread = CreateThread(NULL, 8192, MidiThread, 0, 0, &threadId))) 
return "Failed to create thread";
 
  179   _midi.terminate = 
true;
 
  180   SetEvent(
_midi.wait_obj);
 
  181   WaitForMultipleObjects(1, &
_midi.thread, 
true, INFINITE);
 
  182   CloseHandle(
_midi.wait_obj);
 
  183   CloseHandle(
_midi.thread);