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