#include "stdafx.h" #include "openttd.h" #include "music/win32.h" #include static struct { bool stop_song; bool terminate; bool playing; int new_vol; HANDLE wait_obj; char start_song[260]; } _midi; static void Win32MidiPlaySong(const char *filename) { strcpy(_midi.start_song, filename); _midi.playing = true; _midi.stop_song = false; SetEvent(_midi.wait_obj); } static void Win32MidiStopSong(void) { if (_midi.playing) { _midi.stop_song = true; _midi.start_song[0] = '\0'; SetEvent(_midi.wait_obj); } } static bool Win32MidiIsSongPlaying(void) { return _midi.playing; } static void Win32MidiSetVolume(byte vol) { _midi.new_vol = vol; SetEvent(_midi.wait_obj); } static long CDECL MidiSendCommand(const char *cmd, ...) { va_list va; char buf[512]; va_start(va, cmd); vsprintf(buf, cmd, va); va_end(va); return mciSendStringA(buf, NULL, 0, 0); } static bool MidiIntPlaySong(const char *filename) { MidiSendCommand("close all"); if (MidiSendCommand("open \"%s\" type sequencer alias song", filename) != 0) return false; if (MidiSendCommand("play song from 0") != 0) return false; return true; } static void MidiIntStopSong(void) { MidiSendCommand("close all"); } static void MidiIntSetVolume(int vol) { uint v = (vol * 65535 / 127); midiOutSetVolume((HMIDIOUT)-1, v + (v << 16)); } static bool MidiIntIsSongPlaying(void) { char buf[16]; mciSendStringA("status song mode", buf, sizeof(buf), 0); return strcmp(buf, "playing") == 0 || strcmp(buf, "seeking") == 0; } static DWORD WINAPI MidiThread(LPVOID arg) { _midi.wait_obj = CreateEvent(NULL, FALSE, FALSE, NULL); do { char *s; int vol; vol = _midi.new_vol; if (vol != -1) { _midi.new_vol = -1; MidiIntSetVolume(vol); } s = _midi.start_song; if (s[0] != '\0') { _midi.playing = MidiIntPlaySong(s); s[0] = '\0'; // Delay somewhat in case we don't manage to play. if (!_midi.playing) { Sleep(5000); } } if (_midi.stop_song && _midi.playing) { _midi.stop_song = false; _midi.playing = false; MidiIntStopSong(); } if (_midi.playing && !MidiIntIsSongPlaying()) _midi.playing = false; WaitForMultipleObjects(1, &_midi.wait_obj, FALSE, 1000); } while (!_midi.terminate); DeleteObject(_midi.wait_obj); return 0; } static const char *Win32MidiStart(const char * const *parm) { DWORD threadId; memset(&_midi, 0, sizeof(_midi)); _midi.new_vol = -1; CreateThread(NULL, 8192, MidiThread, 0, 0, &threadId); return 0; } static void Win32MidiStop(void) { _midi.terminate = true; SetEvent(_midi.wait_obj); } const HalMusicDriver _win32_music_driver = { Win32MidiStart, Win32MidiStop, Win32MidiPlaySong, Win32MidiStopSong, Win32MidiIsSongPlaying, Win32MidiSetVolume, };