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);
void Stop()
Stop this driver.
Factory for Windows' music player.
Base for Windows music playback.
#define lastof(x)
Get the last element of an fixed size array.
void PlaySong(const char *filename)
Play a particular song.
static long CDECL MidiSendCommand(const char *cmd,...)
Send a midi command.
#define lengthof(x)
Return the length of an fixed size array.
const char * Start(const char *const *param)
Start this driver.
bool IsSongPlaying()
Are we currently playing a song?
const TCHAR * OTTD2FS(const char *name, bool console_cp)
Convert from OpenTTD's encoding to that of the local environment.
char * strecpy(char *dst, const char *src, const char *last)
Copies characters from one buffer to another.
void SetVolume(byte vol)
Set the volume, if possible.
void StopSong()
Stop playing the current song.
static struct @24 _midi
Metadata about the midi we're playing.