2005-07-24 14:12:37 +00:00
|
|
|
/* $Id$ */
|
|
|
|
|
2005-07-25 07:16:10 +00:00
|
|
|
#include "../stdafx.h"
|
|
|
|
#include "win32_m.h"
|
2005-07-23 15:16:57 +00:00
|
|
|
#include <windows.h>
|
2005-07-25 07:16:10 +00:00
|
|
|
#include <mmsystem.h>
|
2005-07-23 15:16:57 +00:00
|
|
|
|
|
|
|
static struct {
|
|
|
|
bool stop_song;
|
|
|
|
bool terminate;
|
|
|
|
bool playing;
|
|
|
|
int new_vol;
|
|
|
|
HANDLE wait_obj;
|
2007-08-31 23:29:53 +00:00
|
|
|
HANDLE thread;
|
2005-09-25 09:04:59 +00:00
|
|
|
UINT_PTR devid;
|
2005-07-23 15:16:57 +00:00
|
|
|
char start_song[260];
|
|
|
|
} _midi;
|
|
|
|
|
2007-07-05 12:23:54 +00:00
|
|
|
static FMusicDriver_Win32 iFMusicDriver_Win32;
|
|
|
|
|
|
|
|
void MusicDriver_Win32::PlaySong(const char *filename)
|
2005-07-23 15:16:57 +00:00
|
|
|
{
|
|
|
|
strcpy(_midi.start_song, filename);
|
|
|
|
_midi.playing = true;
|
|
|
|
_midi.stop_song = false;
|
|
|
|
SetEvent(_midi.wait_obj);
|
|
|
|
}
|
|
|
|
|
2007-07-05 12:23:54 +00:00
|
|
|
void MusicDriver_Win32::StopSong()
|
2005-07-23 15:16:57 +00:00
|
|
|
{
|
|
|
|
if (_midi.playing) {
|
|
|
|
_midi.stop_song = true;
|
|
|
|
_midi.start_song[0] = '\0';
|
|
|
|
SetEvent(_midi.wait_obj);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-07-05 12:23:54 +00:00
|
|
|
bool MusicDriver_Win32::IsSongPlaying()
|
2005-07-23 15:16:57 +00:00
|
|
|
{
|
|
|
|
return _midi.playing;
|
|
|
|
}
|
|
|
|
|
2007-07-05 12:23:54 +00:00
|
|
|
void MusicDriver_Win32::SetVolume(byte vol)
|
2005-07-23 15:16:57 +00:00
|
|
|
{
|
|
|
|
_midi.new_vol = vol;
|
|
|
|
SetEvent(_midi.wait_obj);
|
|
|
|
}
|
|
|
|
|
2005-10-22 06:39:32 +00:00
|
|
|
static MCIERROR CDECL MidiSendCommand(const char* cmd, ...)
|
|
|
|
{
|
2005-07-23 15:16:57 +00:00
|
|
|
va_list va;
|
|
|
|
char buf[512];
|
|
|
|
|
|
|
|
va_start(va, cmd);
|
2007-02-23 12:56:10 +00:00
|
|
|
vsnprintf(buf, lengthof(buf), cmd, va);
|
2005-07-23 15:16:57 +00:00
|
|
|
va_end(va);
|
|
|
|
return mciSendStringA(buf, NULL, 0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool MidiIntPlaySong(const char *filename)
|
|
|
|
{
|
|
|
|
MidiSendCommand("close all");
|
2007-02-23 12:56:10 +00:00
|
|
|
if (MidiSendCommand("open \"%s\" type sequencer alias song", filename) != 0) return false;
|
2005-07-23 15:16:57 +00:00
|
|
|
|
2007-02-23 12:56:10 +00:00
|
|
|
return MidiSendCommand("play song from 0") == 0;
|
2005-07-23 15:16:57 +00:00
|
|
|
}
|
|
|
|
|
2007-03-07 11:47:46 +00:00
|
|
|
static void MidiIntStopSong()
|
2005-07-23 15:16:57 +00:00
|
|
|
{
|
|
|
|
MidiSendCommand("close all");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void MidiIntSetVolume(int vol)
|
|
|
|
{
|
2005-09-25 09:04:59 +00:00
|
|
|
DWORD v = (vol * 65535 / 127);
|
2005-09-17 13:15:16 +00:00
|
|
|
midiOutSetVolume((HMIDIOUT)_midi.devid, v + (v << 16));
|
2005-07-23 15:16:57 +00:00
|
|
|
}
|
|
|
|
|
2007-03-07 11:47:46 +00:00
|
|
|
static bool MidiIntIsSongPlaying()
|
2005-07-23 15:16:57 +00:00
|
|
|
{
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
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.
|
2007-08-31 23:29:53 +00:00
|
|
|
if (!_midi.playing) WaitForMultipleObjects(1, &_midi.wait_obj, FALSE, 5000);
|
2005-07-23 15:16:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (_midi.stop_song && _midi.playing) {
|
|
|
|
_midi.stop_song = false;
|
|
|
|
_midi.playing = false;
|
|
|
|
MidiIntStopSong();
|
|
|
|
}
|
|
|
|
|
2007-02-23 12:56:10 +00:00
|
|
|
if (_midi.playing && !MidiIntIsSongPlaying()) _midi.playing = false;
|
2005-07-23 15:16:57 +00:00
|
|
|
|
|
|
|
WaitForMultipleObjects(1, &_midi.wait_obj, FALSE, 1000);
|
|
|
|
} while (!_midi.terminate);
|
|
|
|
|
2007-08-31 23:29:53 +00:00
|
|
|
MidiIntStopSong();
|
2005-07-23 15:16:57 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-07-05 12:23:54 +00:00
|
|
|
const char *MusicDriver_Win32::Start(const char * const *parm)
|
2005-07-23 15:16:57 +00:00
|
|
|
{
|
2005-09-17 13:15:16 +00:00
|
|
|
MIDIOUTCAPS midicaps;
|
2005-09-25 09:04:59 +00:00
|
|
|
UINT nbdev;
|
|
|
|
UINT_PTR dev;
|
2005-07-27 21:45:34 +00:00
|
|
|
char buf[16];
|
|
|
|
|
|
|
|
mciSendStringA("capability sequencer has audio", buf, lengthof(buf), 0);
|
|
|
|
if (strcmp(buf, "true") != 0) return "MCI sequencer can't play audio";
|
2005-07-23 15:16:57 +00:00
|
|
|
|
|
|
|
memset(&_midi, 0, sizeof(_midi));
|
|
|
|
_midi.new_vol = -1;
|
2005-07-27 21:45:34 +00:00
|
|
|
|
2005-09-17 13:15:16 +00:00
|
|
|
/* Get midi device */
|
|
|
|
_midi.devid = MIDI_MAPPER;
|
|
|
|
for (dev = 0, nbdev = midiOutGetNumDevs(); dev < nbdev; dev++) {
|
|
|
|
if (midiOutGetDevCaps(dev, &midicaps, sizeof(midicaps)) == 0 && (midicaps.dwSupport & MIDICAPS_VOLUME)) {
|
|
|
|
_midi.devid = dev;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-08-31 23:29:53 +00:00
|
|
|
if (NULL == (_midi.wait_obj = CreateEvent(NULL, FALSE, FALSE, NULL))) return "Failed to create event";
|
|
|
|
if (NULL == (_midi.thread = CreateThread(NULL, 8192, MidiThread, 0, 0, NULL))) return "Failed to create thread";
|
2005-07-27 21:45:34 +00:00
|
|
|
|
|
|
|
return NULL;
|
2005-07-23 15:16:57 +00:00
|
|
|
}
|
|
|
|
|
2007-07-05 12:23:54 +00:00
|
|
|
void MusicDriver_Win32::Stop()
|
2005-07-23 15:16:57 +00:00
|
|
|
{
|
|
|
|
_midi.terminate = true;
|
|
|
|
SetEvent(_midi.wait_obj);
|
2007-08-31 23:29:53 +00:00
|
|
|
WaitForMultipleObjects(1, &_midi.thread, true, INFINITE);
|
|
|
|
CloseHandle(_midi.wait_obj);
|
|
|
|
CloseHandle(_midi.thread);
|
2005-07-23 15:16:57 +00:00
|
|
|
}
|