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 "quakedef.h"
24 #include <windows.h>
25 #include <mmsystem.h>
26 
27 #include "cdaudio.h"
28 
29 #if defined(_MSC_VER) && (_MSC_VER < 1300)
30 typedef DWORD DWORD_PTR;
31 #endif
32 
33 extern	HWND	mainwindow;
34 
35 UINT	wDeviceID;
36 
CDAudio_SysEject(void)37 void CDAudio_SysEject(void)
38 {
39 	DWORD	dwReturn;
40 
41 	if ((dwReturn = mciSendCommand(wDeviceID, MCI_SET, MCI_SET_DOOR_OPEN, (DWORD_PTR)NULL)))
42 		Con_Printf("MCI_SET_DOOR_OPEN failed (%x)\n", (unsigned)dwReturn);
43 }
44 
45 
CDAudio_SysCloseDoor(void)46 void CDAudio_SysCloseDoor(void)
47 {
48 	DWORD	dwReturn;
49 
50 	if ((dwReturn = mciSendCommand(wDeviceID, MCI_SET, MCI_SET_DOOR_CLOSED, (DWORD_PTR)NULL)))
51 		Con_Printf("MCI_SET_DOOR_CLOSED failed (%x)\n", (unsigned)dwReturn);
52 }
53 
CDAudio_SysGetAudioDiskInfo(void)54 int CDAudio_SysGetAudioDiskInfo(void)
55 {
56 	DWORD				dwReturn;
57 	MCI_STATUS_PARMS	mciStatusParms;
58 
59 	mciStatusParms.dwItem = MCI_STATUS_READY;
60 	dwReturn = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_WAIT, (DWORD_PTR) (LPVOID) &mciStatusParms);
61 	if (dwReturn)
62 	{
63 		Con_Print("CDAudio_SysGetAudioDiskInfo: drive ready test - get status failed\n");
64 		return -1;
65 	}
66 	if (!mciStatusParms.dwReturn)
67 	{
68 		Con_Print("CDAudio_SysGetAudioDiskInfo: drive not ready\n");
69 		return -1;
70 	}
71 
72 	mciStatusParms.dwItem = MCI_STATUS_NUMBER_OF_TRACKS;
73 	dwReturn = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_WAIT, (DWORD_PTR) (LPVOID) &mciStatusParms);
74 	if (dwReturn)
75 	{
76 		Con_Print("CDAudio_SysGetAudioDiskInfo: get tracks - status failed\n");
77 		return -1;
78 	}
79 	if (mciStatusParms.dwReturn < 1)
80 	{
81 		Con_Print("CDAudio_SysGetAudioDiskInfo: no music tracks\n");
82 		return -1;
83 	}
84 
85 	return mciStatusParms.dwReturn;
86 }
87 
88 
CDAudio_SysGetVolume(void)89 float CDAudio_SysGetVolume (void)
90 {
91 	// IMPLEMENTME
92 	return -1.0f;
93 }
94 
95 
CDAudio_SysSetVolume(float fvolume)96 void CDAudio_SysSetVolume (float fvolume)
97 {
98 	// IMPLEMENTME
99 }
100 
101 
CDAudio_SysPlay(int track)102 int CDAudio_SysPlay (int track)
103 {
104 	DWORD				dwReturn;
105 	MCI_PLAY_PARMS		mciPlayParms;
106 	MCI_STATUS_PARMS	mciStatusParms;
107 
108 	// don't try to play a non-audio track
109 	mciStatusParms.dwItem = MCI_CDA_STATUS_TYPE_TRACK;
110 	mciStatusParms.dwTrack = track;
111 	dwReturn = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_TRACK | MCI_WAIT, (DWORD_PTR) (LPVOID) &mciStatusParms);
112 	if (dwReturn)
113 	{
114 		Con_Printf("CDAudio_SysPlay: MCI_STATUS failed (%x)\n", (unsigned)dwReturn);
115 		return -1;
116 	}
117 	if (mciStatusParms.dwReturn != MCI_CDA_TRACK_AUDIO)
118 	{
119 		Con_Printf("CDAudio_SysPlay: track %i is not audio\n", track);
120 		return -1;
121 	}
122 
123 	if (cdPlaying)
124 		CDAudio_Stop();
125 
126 	// get the length of the track to be played
127 	mciStatusParms.dwItem = MCI_STATUS_LENGTH;
128 	mciStatusParms.dwTrack = track;
129 	dwReturn = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_TRACK | MCI_WAIT, (DWORD_PTR) (LPVOID) &mciStatusParms);
130 	if (dwReturn)
131 	{
132 		Con_Printf("CDAudio_SysPlay: MCI_STATUS failed (%x)\n", (unsigned)dwReturn);
133 		return -1;
134 	}
135 
136 	mciPlayParms.dwFrom = MCI_MAKE_TMSF(track, 0, 0, 0);
137 	mciPlayParms.dwTo = (mciStatusParms.dwReturn << 8) | track;
138 	mciPlayParms.dwCallback = (DWORD_PTR)mainwindow;
139 	dwReturn = mciSendCommand(wDeviceID, MCI_PLAY, MCI_NOTIFY | MCI_FROM | MCI_TO, (DWORD_PTR)(LPVOID) &mciPlayParms);
140 	if (dwReturn)
141 	{
142 		Con_Printf("CDAudio_SysPlay: MCI_PLAY failed (%x)\n", (unsigned)dwReturn);
143 		return -1;
144 	}
145 
146 	return 0;
147 }
148 
149 
CDAudio_SysStop(void)150 int CDAudio_SysStop (void)
151 {
152 	DWORD	dwReturn;
153 
154 	if ((dwReturn = mciSendCommand(wDeviceID, MCI_STOP, 0, (DWORD_PTR)NULL)))
155 	{
156 		Con_Printf("MCI_STOP failed (%x)\n", (unsigned)dwReturn);
157 		return -1;
158 	}
159 	return 0;
160 }
161 
CDAudio_SysPause(void)162 int CDAudio_SysPause (void)
163 {
164 	DWORD				dwReturn;
165 	MCI_GENERIC_PARMS	mciGenericParms;
166 
167 	mciGenericParms.dwCallback = (DWORD_PTR)mainwindow;
168 	if ((dwReturn = mciSendCommand(wDeviceID, MCI_PAUSE, 0, (DWORD_PTR)(LPVOID) &mciGenericParms)))
169 	{
170 		Con_Printf("MCI_PAUSE failed (%x)\n", (unsigned)dwReturn);
171 		return -1;
172 	}
173 	return 0;
174 }
175 
176 
CDAudio_SysResume(void)177 int CDAudio_SysResume (void)
178 {
179 	DWORD			dwReturn;
180 	MCI_PLAY_PARMS	mciPlayParms;
181 
182 	mciPlayParms.dwFrom = MCI_MAKE_TMSF(cdPlayTrack, 0, 0, 0);
183 	mciPlayParms.dwTo = MCI_MAKE_TMSF(cdPlayTrack + 1, 0, 0, 0);
184 	mciPlayParms.dwCallback = (DWORD_PTR)mainwindow;
185 	dwReturn = mciSendCommand(wDeviceID, MCI_PLAY, MCI_TO | MCI_NOTIFY, (DWORD_PTR)(LPVOID) &mciPlayParms);
186 	if (dwReturn)
187 	{
188 		Con_Printf("CDAudio_SysResume: MCI_PLAY failed (%x)\n", (unsigned)dwReturn);
189 		return -1;
190 	}
191 	return 0;
192 }
193 
CDAudio_MessageHandler(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)194 LONG CDAudio_MessageHandler (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
195 {
196 	if (lParam != (LPARAM)wDeviceID)
197 		return 1;
198 
199 	switch (wParam)
200 	{
201 		case MCI_NOTIFY_SUCCESSFUL:
202 			if (cdPlaying)
203 			{
204 				cdPlaying = false;
205 				if (cdPlayLooping)
206 					CDAudio_Play(cdPlayTrack, true);
207 			}
208 			break;
209 
210 		case MCI_NOTIFY_ABORTED:
211 		case MCI_NOTIFY_SUPERSEDED:
212 			break;
213 
214 		case MCI_NOTIFY_FAILURE:
215 			Con_Print("MCI_NOTIFY_FAILURE\n");
216 			CDAudio_Stop ();
217 			cdValid = false;
218 			break;
219 
220 		default:
221 			Con_Printf("Unexpected MM_MCINOTIFY type (%i)\n", (int)wParam);
222 			return 1;
223 	}
224 
225 	return 0;
226 }
227 
228 
CDAudio_SysUpdate(void)229 int CDAudio_SysUpdate (void)
230 {
231 	return 0;
232 }
233 
CDAudio_SysInit(void)234 void CDAudio_SysInit (void)
235 {
236 }
237 
CDAudio_SysStartup(void)238 int CDAudio_SysStartup (void)
239 {
240 	DWORD	dwReturn;
241 	MCI_OPEN_PARMS	mciOpenParms;
242 	MCI_SET_PARMS	mciSetParms;
243 
244 	mciOpenParms.lpstrDeviceType = "cdaudio";
245 	if ((dwReturn = mciSendCommand(0, MCI_OPEN, MCI_OPEN_TYPE | MCI_OPEN_SHAREABLE, (DWORD_PTR) (LPVOID) &mciOpenParms)))
246 	{
247 		Con_Printf("CDAudio_SysStartup: MCI_OPEN failed (%x)\n", (unsigned)dwReturn);
248 		return -1;
249 	}
250 	wDeviceID = mciOpenParms.wDeviceID;
251 
252 	// Set the time format to track/minute/second/frame (TMSF).
253 	mciSetParms.dwTimeFormat = MCI_FORMAT_TMSF;
254 	if ((dwReturn = mciSendCommand(wDeviceID, MCI_SET, MCI_SET_TIME_FORMAT, (DWORD_PTR)(LPVOID) &mciSetParms)))
255 	{
256 		Con_Printf("CDAudio_SysStartup: MCI_SET_TIME_FORMAT failed (%x)\n", (unsigned)dwReturn);
257 		mciSendCommand(wDeviceID, MCI_CLOSE, 0, (DWORD_PTR)NULL);
258 		return -1;
259 	}
260 
261 	return 0;
262 }
263 
CDAudio_SysShutdown(void)264 void CDAudio_SysShutdown (void)
265 {
266 	if (mciSendCommand(wDeviceID, MCI_CLOSE, MCI_WAIT, (DWORD_PTR)NULL))
267 		Con_Print("CDAudio_SysShutdown: MCI_CLOSE failed\n");
268 }
269