forked from mirror/OpenTTD
(svn r2688) MSVC and Watcom can't handle identical file names in different directories, oh my...
This commit is contained in:
146
music/win32_m.c
Normal file
146
music/win32_m.c
Normal file
@@ -0,0 +1,146 @@
|
||||
#include "stdafx.h"
|
||||
#include "openttd.h"
|
||||
#include "music/win32_m.h"
|
||||
#include <windows.h>
|
||||
|
||||
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,
|
||||
};
|
Reference in New Issue
Block a user