author | terom@terom-desktop |
Thu, 24 Jul 2008 16:18:29 +0300 | |
changeset 11185 | 5036deb1fcaf |
parent 10429 | 1b99254f9607 |
permissions | -rw-r--r-- |
2186 | 1 |
/* $Id$ */ |
2 |
||
10429
1b99254f9607
(svn r12971) -Documentation: add @file in files that missed them and add something more than whitespace as description of files that don't have a description.
rubidium
parents:
9196
diff
changeset
|
3 |
/** @file win32_m.cpp Music playback for Windows. */ |
1b99254f9607
(svn r12971) -Documentation: add @file in files that missed them and add something more than whitespace as description of files that don't have a description.
rubidium
parents:
9196
diff
changeset
|
4 |
|
2189
d240b9097139
(svn r2704) Remove . from include path again, too much trouble. Also add some #ifdefs and #includes for the Windows build
tron
parents:
2186
diff
changeset
|
5 |
#include "../stdafx.h" |
d240b9097139
(svn r2704) Remove . from include path again, too much trouble. Also add some #ifdefs and #includes for the Windows build
tron
parents:
2186
diff
changeset
|
6 |
#include "win32_m.h" |
0 | 7 |
#include <windows.h> |
2189
d240b9097139
(svn r2704) Remove . from include path again, too much trouble. Also add some #ifdefs and #includes for the Windows build
tron
parents:
2186
diff
changeset
|
8 |
#include <mmsystem.h> |
0 | 9 |
|
1468
8073826fe82d
(svn r1972) Several cleanups and fix some latent bugs
tron
parents:
1466
diff
changeset
|
10 |
static struct { |
0 | 11 |
bool stop_song; |
12 |
bool terminate; |
|
13 |
bool playing; |
|
14 |
int new_vol; |
|
15 |
HANDLE wait_obj; |
|
8010
a924bdae75ab
(svn r11029) -Fix [FS#1164]: win32 midi doesn't stop when closing openttd
glx
parents:
7666
diff
changeset
|
16 |
HANDLE thread; |
2458
c95808cd2ac9
(svn r2984) Use adequate types, this should aid portability a bit
tron
parents:
2434
diff
changeset
|
17 |
UINT_PTR devid; |
9189
40f723073fef
(svn r12366) -Codechange: use MAX_PATH instead hardcoded value
glx
parents:
8119
diff
changeset
|
18 |
char start_song[MAX_PATH]; |
0 | 19 |
} _midi; |
20 |
||
7666
a5fccd76176a
(svn r10444) -Codechange: switch to c++ classes and inheritance for sound/music/video drivers, using self-registration based on the blitter-model.
peter1138
parents:
6573
diff
changeset
|
21 |
static FMusicDriver_Win32 iFMusicDriver_Win32; |
a5fccd76176a
(svn r10444) -Codechange: switch to c++ classes and inheritance for sound/music/video drivers, using self-registration based on the blitter-model.
peter1138
parents:
6573
diff
changeset
|
22 |
|
a5fccd76176a
(svn r10444) -Codechange: switch to c++ classes and inheritance for sound/music/video drivers, using self-registration based on the blitter-model.
peter1138
parents:
6573
diff
changeset
|
23 |
void MusicDriver_Win32::PlaySong(const char *filename) |
0 | 24 |
{ |
25 |
strcpy(_midi.start_song, filename); |
|
26 |
_midi.playing = true; |
|
27 |
_midi.stop_song = false; |
|
28 |
SetEvent(_midi.wait_obj); |
|
29 |
} |
|
30 |
||
7666
a5fccd76176a
(svn r10444) -Codechange: switch to c++ classes and inheritance for sound/music/video drivers, using self-registration based on the blitter-model.
peter1138
parents:
6573
diff
changeset
|
31 |
void MusicDriver_Win32::StopSong() |
0 | 32 |
{ |
33 |
if (_midi.playing) { |
|
34 |
_midi.stop_song = true; |
|
1468
8073826fe82d
(svn r1972) Several cleanups and fix some latent bugs
tron
parents:
1466
diff
changeset
|
35 |
_midi.start_song[0] = '\0'; |
0 | 36 |
SetEvent(_midi.wait_obj); |
37 |
} |
|
38 |
} |
|
39 |
||
7666
a5fccd76176a
(svn r10444) -Codechange: switch to c++ classes and inheritance for sound/music/video drivers, using self-registration based on the blitter-model.
peter1138
parents:
6573
diff
changeset
|
40 |
bool MusicDriver_Win32::IsSongPlaying() |
0 | 41 |
{ |
42 |
return _midi.playing; |
|
43 |
} |
|
44 |
||
7666
a5fccd76176a
(svn r10444) -Codechange: switch to c++ classes and inheritance for sound/music/video drivers, using self-registration based on the blitter-model.
peter1138
parents:
6573
diff
changeset
|
45 |
void MusicDriver_Win32::SetVolume(byte vol) |
0 | 46 |
{ |
47 |
_midi.new_vol = vol; |
|
48 |
SetEvent(_midi.wait_obj); |
|
49 |
} |
|
50 |
||
9195
b83118d81d4b
(svn r12372) -Fix: win32 music driver fails if path contains non-latin chars
glx
parents:
9189
diff
changeset
|
51 |
static MCIERROR CDECL MidiSendCommand(const TCHAR* cmd, ...) |
2548
97ada3bd2702
(svn r3077) static, const, bracing, indentation, 0 -> '\0'/NULL, typos in comments, excess empty lines, minor other changes
tron
parents:
2458
diff
changeset
|
52 |
{ |
0 | 53 |
va_list va; |
9195
b83118d81d4b
(svn r12372) -Fix: win32 music driver fails if path contains non-latin chars
glx
parents:
9189
diff
changeset
|
54 |
TCHAR buf[512]; |
1468
8073826fe82d
(svn r1972) Several cleanups and fix some latent bugs
tron
parents:
1466
diff
changeset
|
55 |
|
0 | 56 |
va_start(va, cmd); |
9195
b83118d81d4b
(svn r12372) -Fix: win32 music driver fails if path contains non-latin chars
glx
parents:
9189
diff
changeset
|
57 |
_vsntprintf(buf, lengthof(buf), cmd, va); |
0 | 58 |
va_end(va); |
9195
b83118d81d4b
(svn r12372) -Fix: win32 music driver fails if path contains non-latin chars
glx
parents:
9189
diff
changeset
|
59 |
return mciSendString(buf, NULL, 0, 0); |
0 | 60 |
} |
61 |
||
62 |
static bool MidiIntPlaySong(const char *filename) |
|
63 |
{ |
|
9195
b83118d81d4b
(svn r12372) -Fix: win32 music driver fails if path contains non-latin chars
glx
parents:
9189
diff
changeset
|
64 |
MidiSendCommand(_T("close all")); |
0 | 65 |
|
9196
5e28b70db025
(svn r12373) -Fix [FS#1849]: win32 music driver fails if path is too long (128 chars is too much for mci it seems), so retry using the short path name (8.3 style) if available
glx
parents:
9195
diff
changeset
|
66 |
if (MidiSendCommand(_T("open \"%s\" type sequencer alias song"), OTTD2FS(filename)) != 0) { |
5e28b70db025
(svn r12373) -Fix [FS#1849]: win32 music driver fails if path is too long (128 chars is too much for mci it seems), so retry using the short path name (8.3 style) if available
glx
parents:
9195
diff
changeset
|
67 |
/* Let's try the "short name" */ |
5e28b70db025
(svn r12373) -Fix [FS#1849]: win32 music driver fails if path is too long (128 chars is too much for mci it seems), so retry using the short path name (8.3 style) if available
glx
parents:
9195
diff
changeset
|
68 |
TCHAR buf[MAX_PATH]; |
5e28b70db025
(svn r12373) -Fix [FS#1849]: win32 music driver fails if path is too long (128 chars is too much for mci it seems), so retry using the short path name (8.3 style) if available
glx
parents:
9195
diff
changeset
|
69 |
if (GetShortPathName(OTTD2FS(filename), buf, MAX_PATH) == 0) return false; |
5e28b70db025
(svn r12373) -Fix [FS#1849]: win32 music driver fails if path is too long (128 chars is too much for mci it seems), so retry using the short path name (8.3 style) if available
glx
parents:
9195
diff
changeset
|
70 |
if (MidiSendCommand(_T("open \"%s\" type sequencer alias song"), buf) != 0) return false; |
5e28b70db025
(svn r12373) -Fix [FS#1849]: win32 music driver fails if path is too long (128 chars is too much for mci it seems), so retry using the short path name (8.3 style) if available
glx
parents:
9195
diff
changeset
|
71 |
} |
9195
b83118d81d4b
(svn r12372) -Fix: win32 music driver fails if path contains non-latin chars
glx
parents:
9189
diff
changeset
|
72 |
|
b83118d81d4b
(svn r12372) -Fix: win32 music driver fails if path contains non-latin chars
glx
parents:
9189
diff
changeset
|
73 |
return MidiSendCommand(_T("play song from 0")) == 0; |
0 | 74 |
} |
75 |
||
6573 | 76 |
static void MidiIntStopSong() |
0 | 77 |
{ |
9195
b83118d81d4b
(svn r12372) -Fix: win32 music driver fails if path contains non-latin chars
glx
parents:
9189
diff
changeset
|
78 |
MidiSendCommand(_T("close all")); |
0 | 79 |
} |
80 |
||
81 |
static void MidiIntSetVolume(int vol) |
|
82 |
{ |
|
2458
c95808cd2ac9
(svn r2984) Use adequate types, this should aid portability a bit
tron
parents:
2434
diff
changeset
|
83 |
DWORD v = (vol * 65535 / 127); |
2434
3428947c9c87
(svn r2960) - Fix: [ 1227779 ] Fix win32 midi volume level control which didn't work (glx)
Darkvater
parents:
2212
diff
changeset
|
84 |
midiOutSetVolume((HMIDIOUT)_midi.devid, v + (v << 16)); |
0 | 85 |
} |
86 |
||
6573 | 87 |
static bool MidiIntIsSongPlaying() |
0 | 88 |
{ |
89 |
char buf[16]; |
|
90 |
mciSendStringA("status song mode", buf, sizeof(buf), 0); |
|
91 |
return strcmp(buf, "playing") == 0 || strcmp(buf, "seeking") == 0; |
|
92 |
} |
|
93 |
||
94 |
static DWORD WINAPI MidiThread(LPVOID arg) |
|
95 |
{ |
|
96 |
do { |
|
1468
8073826fe82d
(svn r1972) Several cleanups and fix some latent bugs
tron
parents:
1466
diff
changeset
|
97 |
char *s; |
8073826fe82d
(svn r1972) Several cleanups and fix some latent bugs
tron
parents:
1466
diff
changeset
|
98 |
int vol; |
8073826fe82d
(svn r1972) Several cleanups and fix some latent bugs
tron
parents:
1466
diff
changeset
|
99 |
|
8073826fe82d
(svn r1972) Several cleanups and fix some latent bugs
tron
parents:
1466
diff
changeset
|
100 |
vol = _midi.new_vol; |
8073826fe82d
(svn r1972) Several cleanups and fix some latent bugs
tron
parents:
1466
diff
changeset
|
101 |
if (vol != -1) { |
0 | 102 |
_midi.new_vol = -1; |
103 |
MidiIntSetVolume(vol); |
|
104 |
} |
|
1468
8073826fe82d
(svn r1972) Several cleanups and fix some latent bugs
tron
parents:
1466
diff
changeset
|
105 |
|
8073826fe82d
(svn r1972) Several cleanups and fix some latent bugs
tron
parents:
1466
diff
changeset
|
106 |
s = _midi.start_song; |
8073826fe82d
(svn r1972) Several cleanups and fix some latent bugs
tron
parents:
1466
diff
changeset
|
107 |
if (s[0] != '\0') { |
0 | 108 |
_midi.playing = MidiIntPlaySong(s); |
1468
8073826fe82d
(svn r1972) Several cleanups and fix some latent bugs
tron
parents:
1466
diff
changeset
|
109 |
s[0] = '\0'; |
193
0a7025304867
(svn r194) -Codechange: stripping trailing-spaces. Please keep this that way!
truelight
parents:
164
diff
changeset
|
110 |
|
0 | 111 |
// Delay somewhat in case we don't manage to play. |
8010
a924bdae75ab
(svn r11029) -Fix [FS#1164]: win32 midi doesn't stop when closing openttd
glx
parents:
7666
diff
changeset
|
112 |
if (!_midi.playing) WaitForMultipleObjects(1, &_midi.wait_obj, FALSE, 5000); |
0 | 113 |
} |
1468
8073826fe82d
(svn r1972) Several cleanups and fix some latent bugs
tron
parents:
1466
diff
changeset
|
114 |
|
8073826fe82d
(svn r1972) Several cleanups and fix some latent bugs
tron
parents:
1466
diff
changeset
|
115 |
if (_midi.stop_song && _midi.playing) { |
0 | 116 |
_midi.stop_song = false; |
117 |
_midi.playing = false; |
|
118 |
MidiIntStopSong(); |
|
119 |
} |
|
120 |
||
6450
1c2016673250
(svn r8860) -Cleanup: some style changes, proper #endif comments, variable initialisation, WINCE ifdef and a vsprintf to vsnprintf change.
Darkvater
parents:
5835
diff
changeset
|
121 |
if (_midi.playing && !MidiIntIsSongPlaying()) _midi.playing = false; |
0 | 122 |
|
123 |
WaitForMultipleObjects(1, &_midi.wait_obj, FALSE, 1000); |
|
124 |
} while (!_midi.terminate); |
|
125 |
||
8010
a924bdae75ab
(svn r11029) -Fix [FS#1164]: win32 midi doesn't stop when closing openttd
glx
parents:
7666
diff
changeset
|
126 |
MidiIntStopSong(); |
0 | 127 |
return 0; |
128 |
} |
|
129 |
||
7666
a5fccd76176a
(svn r10444) -Codechange: switch to c++ classes and inheritance for sound/music/video drivers, using self-registration based on the blitter-model.
peter1138
parents:
6573
diff
changeset
|
130 |
const char *MusicDriver_Win32::Start(const char * const *parm) |
0 | 131 |
{ |
2434
3428947c9c87
(svn r2960) - Fix: [ 1227779 ] Fix win32 midi volume level control which didn't work (glx)
Darkvater
parents:
2212
diff
changeset
|
132 |
MIDIOUTCAPS midicaps; |
2458
c95808cd2ac9
(svn r2984) Use adequate types, this should aid portability a bit
tron
parents:
2434
diff
changeset
|
133 |
UINT nbdev; |
c95808cd2ac9
(svn r2984) Use adequate types, this should aid portability a bit
tron
parents:
2434
diff
changeset
|
134 |
UINT_PTR dev; |
2212
7e53bdecc115
(svn r2730) -Fix: Fail if the sequencer can't play audio
tron
parents:
2189
diff
changeset
|
135 |
char buf[16]; |
7e53bdecc115
(svn r2730) -Fix: Fail if the sequencer can't play audio
tron
parents:
2189
diff
changeset
|
136 |
|
7e53bdecc115
(svn r2730) -Fix: Fail if the sequencer can't play audio
tron
parents:
2189
diff
changeset
|
137 |
mciSendStringA("capability sequencer has audio", buf, lengthof(buf), 0); |
7e53bdecc115
(svn r2730) -Fix: Fail if the sequencer can't play audio
tron
parents:
2189
diff
changeset
|
138 |
if (strcmp(buf, "true") != 0) return "MCI sequencer can't play audio"; |
1468
8073826fe82d
(svn r1972) Several cleanups and fix some latent bugs
tron
parents:
1466
diff
changeset
|
139 |
|
0 | 140 |
memset(&_midi, 0, sizeof(_midi)); |
141 |
_midi.new_vol = -1; |
|
2212
7e53bdecc115
(svn r2730) -Fix: Fail if the sequencer can't play audio
tron
parents:
2189
diff
changeset
|
142 |
|
2434
3428947c9c87
(svn r2960) - Fix: [ 1227779 ] Fix win32 midi volume level control which didn't work (glx)
Darkvater
parents:
2212
diff
changeset
|
143 |
/* Get midi device */ |
3428947c9c87
(svn r2960) - Fix: [ 1227779 ] Fix win32 midi volume level control which didn't work (glx)
Darkvater
parents:
2212
diff
changeset
|
144 |
_midi.devid = MIDI_MAPPER; |
3428947c9c87
(svn r2960) - Fix: [ 1227779 ] Fix win32 midi volume level control which didn't work (glx)
Darkvater
parents:
2212
diff
changeset
|
145 |
for (dev = 0, nbdev = midiOutGetNumDevs(); dev < nbdev; dev++) { |
3428947c9c87
(svn r2960) - Fix: [ 1227779 ] Fix win32 midi volume level control which didn't work (glx)
Darkvater
parents:
2212
diff
changeset
|
146 |
if (midiOutGetDevCaps(dev, &midicaps, sizeof(midicaps)) == 0 && (midicaps.dwSupport & MIDICAPS_VOLUME)) { |
3428947c9c87
(svn r2960) - Fix: [ 1227779 ] Fix win32 midi volume level control which didn't work (glx)
Darkvater
parents:
2212
diff
changeset
|
147 |
_midi.devid = dev; |
3428947c9c87
(svn r2960) - Fix: [ 1227779 ] Fix win32 midi volume level control which didn't work (glx)
Darkvater
parents:
2212
diff
changeset
|
148 |
break; |
3428947c9c87
(svn r2960) - Fix: [ 1227779 ] Fix win32 midi volume level control which didn't work (glx)
Darkvater
parents:
2212
diff
changeset
|
149 |
} |
3428947c9c87
(svn r2960) - Fix: [ 1227779 ] Fix win32 midi volume level control which didn't work (glx)
Darkvater
parents:
2212
diff
changeset
|
150 |
} |
3428947c9c87
(svn r2960) - Fix: [ 1227779 ] Fix win32 midi volume level control which didn't work (glx)
Darkvater
parents:
2212
diff
changeset
|
151 |
|
8010
a924bdae75ab
(svn r11029) -Fix [FS#1164]: win32 midi doesn't stop when closing openttd
glx
parents:
7666
diff
changeset
|
152 |
if (NULL == (_midi.wait_obj = CreateEvent(NULL, FALSE, FALSE, NULL))) return "Failed to create event"; |
8119
9505a65c30d5
(svn r11154) -Fix [FS#1239]: MIDI failing to play under Windows 95, 98 and ME.
rubidium
parents:
8010
diff
changeset
|
153 |
|
9505a65c30d5
(svn r11154) -Fix [FS#1239]: MIDI failing to play under Windows 95, 98 and ME.
rubidium
parents:
8010
diff
changeset
|
154 |
/* The lpThreadId parameter of CreateThread (the last parameter) |
9505a65c30d5
(svn r11154) -Fix [FS#1239]: MIDI failing to play under Windows 95, 98 and ME.
rubidium
parents:
8010
diff
changeset
|
155 |
* may NOT be NULL on Windows 95, 98 and ME. */ |
9505a65c30d5
(svn r11154) -Fix [FS#1239]: MIDI failing to play under Windows 95, 98 and ME.
rubidium
parents:
8010
diff
changeset
|
156 |
DWORD threadId; |
9505a65c30d5
(svn r11154) -Fix [FS#1239]: MIDI failing to play under Windows 95, 98 and ME.
rubidium
parents:
8010
diff
changeset
|
157 |
if (NULL == (_midi.thread = CreateThread(NULL, 8192, MidiThread, 0, 0, &threadId))) return "Failed to create thread"; |
2212
7e53bdecc115
(svn r2730) -Fix: Fail if the sequencer can't play audio
tron
parents:
2189
diff
changeset
|
158 |
|
7e53bdecc115
(svn r2730) -Fix: Fail if the sequencer can't play audio
tron
parents:
2189
diff
changeset
|
159 |
return NULL; |
0 | 160 |
} |
161 |
||
7666
a5fccd76176a
(svn r10444) -Codechange: switch to c++ classes and inheritance for sound/music/video drivers, using self-registration based on the blitter-model.
peter1138
parents:
6573
diff
changeset
|
162 |
void MusicDriver_Win32::Stop() |
0 | 163 |
{ |
164 |
_midi.terminate = true; |
|
165 |
SetEvent(_midi.wait_obj); |
|
8010
a924bdae75ab
(svn r11029) -Fix [FS#1164]: win32 midi doesn't stop when closing openttd
glx
parents:
7666
diff
changeset
|
166 |
WaitForMultipleObjects(1, &_midi.thread, true, INFINITE); |
a924bdae75ab
(svn r11029) -Fix [FS#1164]: win32 midi doesn't stop when closing openttd
glx
parents:
7666
diff
changeset
|
167 |
CloseHandle(_midi.wait_obj); |
a924bdae75ab
(svn r11029) -Fix [FS#1164]: win32 midi doesn't stop when closing openttd
glx
parents:
7666
diff
changeset
|
168 |
CloseHandle(_midi.thread); |
0 | 169 |
} |