Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5131 clevermous 1
/*
2
Copyright (C) 1996-1997 Id Software, Inc.
3
 
4
This program is free software; you can redistribute it and/or
5
modify it under the terms of the GNU General Public License
6
as published by the Free Software Foundation; either version 2
7
of the License, or (at your option) any later version.
8
 
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
 
13
See the GNU General Public License for more details.
14
 
15
You should have received a copy of the GNU General Public License
16
along with this program; if not, write to the Free Software
17
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
 
19
*/
20
// Quake is a trademark of Id Software, Inc., (c) 1996 Id Software, Inc. All
21
// rights reserved.
22
 
23
#include 
24
#include "quakedef.h"
25
 
26
extern	HWND	mainwindow;
27
extern	cvar_t	bgmvolume;
28
 
29
static qboolean cdValid = false;
30
static qboolean	playing = false;
31
static qboolean	wasPlaying = false;
32
static qboolean	initialized = false;
33
static qboolean	enabled = false;
34
static qboolean playLooping = false;
35
static float	cdvolume;
36
static byte 	remap[100];
37
static byte		cdrom;
38
static byte		playTrack;
39
static byte		maxTrack;
40
 
41
UINT	wDeviceID;
42
 
43
 
44
static void CDAudio_Eject(void)
45
{
46
	DWORD	dwReturn;
47
 
48
    if (dwReturn = mciSendCommand(wDeviceID, MCI_SET, MCI_SET_DOOR_OPEN, (DWORD)NULL))
49
		Con_DPrintf("MCI_SET_DOOR_OPEN failed (%i)\n", dwReturn);
50
}
51
 
52
 
53
static void CDAudio_CloseDoor(void)
54
{
55
	DWORD	dwReturn;
56
 
57
    if (dwReturn = mciSendCommand(wDeviceID, MCI_SET, MCI_SET_DOOR_CLOSED, (DWORD)NULL))
58
		Con_DPrintf("MCI_SET_DOOR_CLOSED failed (%i)\n", dwReturn);
59
}
60
 
61
 
62
static int CDAudio_GetAudioDiskInfo(void)
63
{
64
	DWORD				dwReturn;
65
	MCI_STATUS_PARMS	mciStatusParms;
66
 
67
 
68
	cdValid = false;
69
 
70
	mciStatusParms.dwItem = MCI_STATUS_READY;
71
    dwReturn = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_WAIT, (DWORD) (LPVOID) &mciStatusParms);
72
	if (dwReturn)
73
	{
74
		Con_DPrintf("CDAudio: drive ready test - get status failed\n");
75
		return -1;
76
	}
77
	if (!mciStatusParms.dwReturn)
78
	{
79
		Con_DPrintf("CDAudio: drive not ready\n");
80
		return -1;
81
	}
82
 
83
	mciStatusParms.dwItem = MCI_STATUS_NUMBER_OF_TRACKS;
84
    dwReturn = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_WAIT, (DWORD) (LPVOID) &mciStatusParms);
85
	if (dwReturn)
86
	{
87
		Con_DPrintf("CDAudio: get tracks - status failed\n");
88
		return -1;
89
	}
90
	if (mciStatusParms.dwReturn < 1)
91
	{
92
		Con_DPrintf("CDAudio: no music tracks\n");
93
		return -1;
94
	}
95
 
96
	cdValid = true;
97
	maxTrack = mciStatusParms.dwReturn;
98
 
99
	return 0;
100
}
101
 
102
 
103
void CDAudio_Play(byte track, qboolean looping)
104
{
105
	DWORD				dwReturn;
106
    MCI_PLAY_PARMS		mciPlayParms;
107
	MCI_STATUS_PARMS	mciStatusParms;
108
 
109
	if (!enabled)
110
		return;
111
 
112
	if (!cdValid)
113
	{
114
		CDAudio_GetAudioDiskInfo();
115
		if (!cdValid)
116
			return;
117
	}
118
 
119
	track = remap[track];
120
 
121
	if (track < 1 || track > maxTrack)
122
	{
123
		Con_DPrintf("CDAudio: Bad track number %u.\n", track);
124
		return;
125
	}
126
 
127
	// don't try to play a non-audio track
128
	mciStatusParms.dwItem = MCI_CDA_STATUS_TYPE_TRACK;
129
	mciStatusParms.dwTrack = track;
130
    dwReturn = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_TRACK | MCI_WAIT, (DWORD) (LPVOID) &mciStatusParms);
131
	if (dwReturn)
132
	{
133
		Con_DPrintf("MCI_STATUS failed (%i)\n", dwReturn);
134
		return;
135
	}
136
	if (mciStatusParms.dwReturn != MCI_CDA_TRACK_AUDIO)
137
	{
138
		Con_Printf("CDAudio: track %i is not audio\n", track);
139
		return;
140
	}
141
 
142
	// get the length of the track to be played
143
	mciStatusParms.dwItem = MCI_STATUS_LENGTH;
144
	mciStatusParms.dwTrack = track;
145
    dwReturn = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_TRACK | MCI_WAIT, (DWORD) (LPVOID) &mciStatusParms);
146
	if (dwReturn)
147
	{
148
		Con_DPrintf("MCI_STATUS failed (%i)\n", dwReturn);
149
		return;
150
	}
151
 
152
	if (playing)
153
	{
154
		if (playTrack == track)
155
			return;
156
		CDAudio_Stop();
157
	}
158
 
159
    mciPlayParms.dwFrom = MCI_MAKE_TMSF(track, 0, 0, 0);
160
	mciPlayParms.dwTo = (mciStatusParms.dwReturn << 8) | track;
161
    mciPlayParms.dwCallback = (DWORD)mainwindow;
162
    dwReturn = mciSendCommand(wDeviceID, MCI_PLAY, MCI_NOTIFY | MCI_FROM | MCI_TO, (DWORD)(LPVOID) &mciPlayParms);
163
	if (dwReturn)
164
	{
165
		Con_DPrintf("CDAudio: MCI_PLAY failed (%i)\n", dwReturn);
166
		return;
167
	}
168
 
169
	playLooping = looping;
170
	playTrack = track;
171
	playing = true;
172
 
173
	if (cdvolume == 0.0)
174
		CDAudio_Pause ();
175
}
176
 
177
 
178
void CDAudio_Stop(void)
179
{
180
	DWORD	dwReturn;
181
 
182
	if (!enabled)
183
		return;
184
 
185
	if (!playing)
186
		return;
187
 
188
    if (dwReturn = mciSendCommand(wDeviceID, MCI_STOP, 0, (DWORD)NULL))
189
		Con_DPrintf("MCI_STOP failed (%i)", dwReturn);
190
 
191
	wasPlaying = false;
192
	playing = false;
193
}
194
 
195
 
196
void CDAudio_Pause(void)
197
{
198
	DWORD				dwReturn;
199
	MCI_GENERIC_PARMS	mciGenericParms;
200
 
201
	if (!enabled)
202
		return;
203
 
204
	if (!playing)
205
		return;
206
 
207
	mciGenericParms.dwCallback = (DWORD)mainwindow;
208
    if (dwReturn = mciSendCommand(wDeviceID, MCI_PAUSE, 0, (DWORD)(LPVOID) &mciGenericParms))
209
		Con_DPrintf("MCI_PAUSE failed (%i)", dwReturn);
210
 
211
	wasPlaying = playing;
212
	playing = false;
213
}
214
 
215
 
216
void CDAudio_Resume(void)
217
{
218
	DWORD			dwReturn;
219
    MCI_PLAY_PARMS	mciPlayParms;
220
 
221
	if (!enabled)
222
		return;
223
 
224
	if (!cdValid)
225
		return;
226
 
227
	if (!wasPlaying)
228
		return;
229
 
230
    mciPlayParms.dwFrom = MCI_MAKE_TMSF(playTrack, 0, 0, 0);
231
    mciPlayParms.dwTo = MCI_MAKE_TMSF(playTrack + 1, 0, 0, 0);
232
    mciPlayParms.dwCallback = (DWORD)mainwindow;
233
    dwReturn = mciSendCommand(wDeviceID, MCI_PLAY, MCI_TO | MCI_NOTIFY, (DWORD)(LPVOID) &mciPlayParms);
234
	if (dwReturn)
235
	{
236
		Con_DPrintf("CDAudio: MCI_PLAY failed (%i)\n", dwReturn);
237
		return;
238
	}
239
	playing = true;
240
}
241
 
242
 
243
static void CD_f (void)
244
{
245
	char	*command;
246
	int		ret;
247
	int		n;
248
	int		startAddress;
249
 
250
	if (Cmd_Argc() < 2)
251
		return;
252
 
253
	command = Cmd_Argv (1);
254
 
255
	if (Q_strcasecmp(command, "on") == 0)
256
	{
257
		enabled = true;
258
		return;
259
	}
260
 
261
	if (Q_strcasecmp(command, "off") == 0)
262
	{
263
		if (playing)
264
			CDAudio_Stop();
265
		enabled = false;
266
		return;
267
	}
268
 
269
	if (Q_strcasecmp(command, "reset") == 0)
270
	{
271
		enabled = true;
272
		if (playing)
273
			CDAudio_Stop();
274
		for (n = 0; n < 100; n++)
275
			remap[n] = n;
276
		CDAudio_GetAudioDiskInfo();
277
		return;
278
	}
279
 
280
	if (Q_strcasecmp(command, "remap") == 0)
281
	{
282
		ret = Cmd_Argc() - 2;
283
		if (ret <= 0)
284
		{
285
			for (n = 1; n < 100; n++)
286
				if (remap[n] != n)
287
					Con_Printf("  %u -> %u\n", n, remap[n]);
288
			return;
289
		}
290
		for (n = 1; n <= ret; n++)
291
			remap[n] = Q_atoi(Cmd_Argv (n+1));
292
		return;
293
	}
294
 
295
	if (Q_strcasecmp(command, "close") == 0)
296
	{
297
		CDAudio_CloseDoor();
298
		return;
299
	}
300
 
301
	if (!cdValid)
302
	{
303
		CDAudio_GetAudioDiskInfo();
304
		if (!cdValid)
305
		{
306
			Con_Printf("No CD in player.\n");
307
			return;
308
		}
309
	}
310
 
311
	if (Q_strcasecmp(command, "play") == 0)
312
	{
313
		CDAudio_Play((byte)Q_atoi(Cmd_Argv (2)), false);
314
		return;
315
	}
316
 
317
	if (Q_strcasecmp(command, "loop") == 0)
318
	{
319
		CDAudio_Play((byte)Q_atoi(Cmd_Argv (2)), true);
320
		return;
321
	}
322
 
323
	if (Q_strcasecmp(command, "stop") == 0)
324
	{
325
		CDAudio_Stop();
326
		return;
327
	}
328
 
329
	if (Q_strcasecmp(command, "pause") == 0)
330
	{
331
		CDAudio_Pause();
332
		return;
333
	}
334
 
335
	if (Q_strcasecmp(command, "resume") == 0)
336
	{
337
		CDAudio_Resume();
338
		return;
339
	}
340
 
341
	if (Q_strcasecmp(command, "eject") == 0)
342
	{
343
		if (playing)
344
			CDAudio_Stop();
345
		CDAudio_Eject();
346
		cdValid = false;
347
		return;
348
	}
349
 
350
	if (Q_strcasecmp(command, "info") == 0)
351
	{
352
		Con_Printf("%u tracks\n", maxTrack);
353
		if (playing)
354
			Con_Printf("Currently %s track %u\n", playLooping ? "looping" : "playing", playTrack);
355
		else if (wasPlaying)
356
			Con_Printf("Paused %s track %u\n", playLooping ? "looping" : "playing", playTrack);
357
		Con_Printf("Volume is %f\n", cdvolume);
358
		return;
359
	}
360
}
361
 
362
 
363
LONG CDAudio_MessageHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
364
{
365
	if (lParam != wDeviceID)
366
		return 1;
367
 
368
	switch (wParam)
369
	{
370
		case MCI_NOTIFY_SUCCESSFUL:
371
			if (playing)
372
			{
373
				playing = false;
374
				if (playLooping)
375
					CDAudio_Play(playTrack, true);
376
			}
377
			break;
378
 
379
		case MCI_NOTIFY_ABORTED:
380
		case MCI_NOTIFY_SUPERSEDED:
381
			break;
382
 
383
		case MCI_NOTIFY_FAILURE:
384
			Con_DPrintf("MCI_NOTIFY_FAILURE\n");
385
			CDAudio_Stop ();
386
			cdValid = false;
387
			break;
388
 
389
		default:
390
			Con_DPrintf("Unexpected MM_MCINOTIFY type (%i)\n", wParam);
391
			return 1;
392
	}
393
 
394
	return 0;
395
}
396
 
397
 
398
void CDAudio_Update(void)
399
{
400
	if (!enabled)
401
		return;
402
 
403
	if (bgmvolume.value != cdvolume)
404
	{
405
		if (cdvolume)
406
		{
407
			Cvar_SetValue ("bgmvolume", 0.0);
408
			cdvolume = bgmvolume.value;
409
			CDAudio_Pause ();
410
		}
411
		else
412
		{
413
			Cvar_SetValue ("bgmvolume", 1.0);
414
			cdvolume = bgmvolume.value;
415
			CDAudio_Resume ();
416
		}
417
	}
418
}
419
 
420
 
421
int CDAudio_Init(void)
422
{
423
	DWORD	dwReturn;
424
	MCI_OPEN_PARMS	mciOpenParms;
425
    MCI_SET_PARMS	mciSetParms;
426
	int				n;
427
 
428
	if (cls.state == ca_dedicated)
429
		return -1;
430
 
431
	if (COM_CheckParm("-nocdaudio"))
432
		return -1;
433
 
434
	mciOpenParms.lpstrDeviceType = "cdaudio";
435
	if (dwReturn = mciSendCommand(0, MCI_OPEN, MCI_OPEN_TYPE | MCI_OPEN_SHAREABLE, (DWORD) (LPVOID) &mciOpenParms))
436
	{
437
		Con_Printf("CDAudio_Init: MCI_OPEN failed (%i)\n", dwReturn);
438
		return -1;
439
	}
440
	wDeviceID = mciOpenParms.wDeviceID;
441
 
442
    // Set the time format to track/minute/second/frame (TMSF).
443
    mciSetParms.dwTimeFormat = MCI_FORMAT_TMSF;
444
    if (dwReturn = mciSendCommand(wDeviceID, MCI_SET, MCI_SET_TIME_FORMAT, (DWORD)(LPVOID) &mciSetParms))
445
    {
446
		Con_Printf("MCI_SET_TIME_FORMAT failed (%i)\n", dwReturn);
447
        mciSendCommand(wDeviceID, MCI_CLOSE, 0, (DWORD)NULL);
448
		return -1;
449
    }
450
 
451
	for (n = 0; n < 100; n++)
452
		remap[n] = n;
453
	initialized = true;
454
	enabled = true;
455
 
456
	if (CDAudio_GetAudioDiskInfo())
457
	{
458
		Con_Printf("CDAudio_Init: No CD in player.\n");
459
		cdValid = false;
460
	}
461
 
462
	Cmd_AddCommand ("cd", CD_f);
463
 
464
	Con_Printf("CD Audio Initialized\n");
465
 
466
	return 0;
467
}
468
 
469
 
470
void CDAudio_Shutdown(void)
471
{
472
	if (!initialized)
473
		return;
474
	CDAudio_Stop();
475
	if (mciSendCommand(wDeviceID, MCI_CLOSE, MCI_WAIT, (DWORD)NULL))
476
		Con_DPrintf("CDAudio_Shutdown: MCI_CLOSE failed\n");
477
}