Mercurial > sdl-ios-xcode
annotate src/cdrom/win32/SDL_syscdrom.c @ 571:8e3ce997621c
Date: Thu, 16 Jan 2003 13:48:31 +0200
From: "Mike Gorchak"
Subject: All QNX patches
whole patches concerning QNX. Almost all code has been rewritten by Julian
and me. Added initial support for hw overlays in QNX and many many others
fixes.
P.S. This patches has been reviewed by Dave Rempel from QSSL and included in
SDL 1.2.5 distribution, which coming on 3rd party CD for newest 6.2.1
version of QNX, which will be available soon.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Mon, 20 Jan 2003 01:38:37 +0000 |
parents | f6ffac90895c |
children | b8d311d90021 |
rev | line source |
---|---|
0 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
297
f6ffac90895c
Updated copyright information for 2002
Sam Lantinga <slouken@libsdl.org>
parents:
252
diff
changeset
|
3 Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga |
0 | 4 |
5 This library is free software; you can redistribute it and/or | |
6 modify it under the terms of the GNU Library General Public | |
7 License as published by the Free Software Foundation; either | |
8 version 2 of the License, or (at your option) any later version. | |
9 | |
10 This library is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 Library General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU Library General Public | |
16 License along with this library; if not, write to the Free | |
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 | |
19 Sam Lantinga | |
252
e8157fcb3114
Updated the source with the correct e-mail address
Sam Lantinga <slouken@libsdl.org>
parents:
201
diff
changeset
|
20 slouken@libsdl.org |
0 | 21 */ |
22 | |
23 #ifdef SAVE_RCSID | |
24 static char rcsid = | |
25 "@(#) $Id$"; | |
26 #endif | |
27 | |
28 /* Functions for system-level CD-ROM audio control */ | |
29 | |
30 #include <stdlib.h> | |
31 #include <stdio.h> | |
32 #include <windows.h> | |
33 #include <mmsystem.h> | |
34 | |
35 #include "SDL_error.h" | |
36 #include "SDL_cdrom.h" | |
37 #include "SDL_syscdrom.h" | |
38 | |
39 /* This really broken?? */ | |
40 #define BROKEN_MCI_PAUSE /* Pausing actually stops play -- Doh! */ | |
41 | |
42 /* The maximum number of CD-ROM drives we'll detect (Don't change!) */ | |
43 #define MAX_DRIVES 26 | |
44 | |
45 /* A list of available CD-ROM drives */ | |
46 static char *SDL_cdlist[MAX_DRIVES]; | |
47 static MCIDEVICEID SDL_mciID[MAX_DRIVES]; | |
48 #ifdef BROKEN_MCI_PAUSE | |
49 static int SDL_paused[MAX_DRIVES]; | |
50 #endif | |
51 | |
52 /* The system-dependent CD control functions */ | |
53 static const char *SDL_SYS_CDName(int drive); | |
54 static int SDL_SYS_CDOpen(int drive); | |
55 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom); | |
56 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position); | |
57 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length); | |
58 static int SDL_SYS_CDPause(SDL_CD *cdrom); | |
59 static int SDL_SYS_CDResume(SDL_CD *cdrom); | |
60 static int SDL_SYS_CDStop(SDL_CD *cdrom); | |
61 static int SDL_SYS_CDEject(SDL_CD *cdrom); | |
62 static void SDL_SYS_CDClose(SDL_CD *cdrom); | |
63 | |
64 | |
65 /* Add a CD-ROM drive to our list of valid drives */ | |
66 static void AddDrive(char *drive) | |
67 { | |
68 int i; | |
69 | |
70 if ( SDL_numcds < MAX_DRIVES ) { | |
71 /* Add this drive to our list */ | |
72 i = SDL_numcds; | |
73 SDL_cdlist[i] = (char *)malloc(strlen(drive)+1); | |
74 if ( SDL_cdlist[i] == NULL ) { | |
75 SDL_OutOfMemory(); | |
76 return; | |
77 } | |
78 strcpy(SDL_cdlist[i], drive); | |
79 ++SDL_numcds; | |
80 #ifdef CDROM_DEBUG | |
81 fprintf(stderr, "Added CD-ROM drive: %s\n", drive); | |
82 #endif | |
83 } | |
84 } | |
85 | |
86 int SDL_SYS_CDInit(void) | |
87 { | |
88 /* checklist: Drive 'A' - 'Z' */ | |
89 int i; | |
90 char drive[4]; | |
91 | |
92 /* Fill in our driver capabilities */ | |
93 SDL_CDcaps.Name = SDL_SYS_CDName; | |
94 SDL_CDcaps.Open = SDL_SYS_CDOpen; | |
95 SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC; | |
96 SDL_CDcaps.Status = SDL_SYS_CDStatus; | |
97 SDL_CDcaps.Play = SDL_SYS_CDPlay; | |
98 SDL_CDcaps.Pause = SDL_SYS_CDPause; | |
99 SDL_CDcaps.Resume = SDL_SYS_CDResume; | |
100 SDL_CDcaps.Stop = SDL_SYS_CDStop; | |
101 SDL_CDcaps.Eject = SDL_SYS_CDEject; | |
102 SDL_CDcaps.Close = SDL_SYS_CDClose; | |
103 | |
104 /* Scan the system for CD-ROM drives */ | |
105 for ( i='A'; i<='Z'; ++i ) { | |
106 sprintf(drive, "%c:\\", i); | |
107 if ( GetDriveType(drive) == DRIVE_CDROM ) { | |
108 AddDrive(drive); | |
109 } | |
110 } | |
111 memset(SDL_mciID, 0, sizeof(SDL_mciID)); | |
112 return(0); | |
113 } | |
114 | |
115 /* General ioctl() CD-ROM command function */ | |
116 static int SDL_SYS_CDioctl(int id, UINT msg, DWORD flags, void *arg) | |
117 { | |
118 MCIERROR mci_error; | |
119 | |
120 mci_error = mciSendCommand(SDL_mciID[id], msg, flags, (DWORD)arg); | |
121 if ( mci_error ) { | |
122 char error[256]; | |
123 | |
124 mciGetErrorString(mci_error, error, 256); | |
125 SDL_SetError("mciSendCommand() error: %s", error); | |
126 } | |
127 return(!mci_error ? 0 : -1); | |
128 } | |
129 | |
130 static const char *SDL_SYS_CDName(int drive) | |
131 { | |
132 return(SDL_cdlist[drive]); | |
133 } | |
134 | |
135 static int SDL_SYS_CDOpen(int drive) | |
136 { | |
137 MCI_OPEN_PARMS mci_open; | |
138 MCI_SET_PARMS mci_set; | |
139 char device[3]; | |
140 DWORD flags; | |
141 | |
142 /* Open the requested device */ | |
143 mci_open.lpstrDeviceType = (LPCSTR) MCI_DEVTYPE_CD_AUDIO; | |
144 device[0] = *SDL_cdlist[drive]; | |
145 device[1] = ':'; | |
146 device[2] = '\0'; | |
147 mci_open.lpstrElementName = device; | |
148 flags = | |
149 (MCI_OPEN_TYPE|MCI_OPEN_SHAREABLE|MCI_OPEN_TYPE_ID|MCI_OPEN_ELEMENT); | |
150 if ( SDL_SYS_CDioctl(0, MCI_OPEN, flags, &mci_open) < 0 ) { | |
151 flags &= ~MCI_OPEN_SHAREABLE; | |
152 if ( SDL_SYS_CDioctl(0, MCI_OPEN, flags, &mci_open) < 0 ) { | |
153 return(-1); | |
154 } | |
155 } | |
156 SDL_mciID[drive] = mci_open.wDeviceID; | |
157 | |
158 /* Set the minute-second-frame time format */ | |
159 mci_set.dwTimeFormat = MCI_FORMAT_MSF; | |
160 SDL_SYS_CDioctl(drive, MCI_SET, MCI_SET_TIME_FORMAT, &mci_set); | |
161 | |
162 #ifdef BROKEN_MCI_PAUSE | |
163 SDL_paused[drive] = 0; | |
164 #endif | |
165 return(drive); | |
166 } | |
167 | |
168 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom) | |
169 { | |
170 MCI_STATUS_PARMS mci_status; | |
171 int i, okay; | |
172 DWORD flags; | |
173 | |
174 okay = 0; | |
175 mci_status.dwItem = MCI_STATUS_NUMBER_OF_TRACKS; | |
176 flags = MCI_STATUS_ITEM | MCI_WAIT; | |
177 if ( SDL_SYS_CDioctl(cdrom->id, MCI_STATUS, flags, &mci_status) == 0 ) { | |
178 cdrom->numtracks = mci_status.dwReturn; | |
179 if ( cdrom->numtracks > SDL_MAX_TRACKS ) { | |
180 cdrom->numtracks = SDL_MAX_TRACKS; | |
181 } | |
182 /* Read all the track TOC entries */ | |
183 flags = MCI_STATUS_ITEM | MCI_TRACK | MCI_WAIT; | |
184 for ( i=0; i<cdrom->numtracks; ++i ) { | |
185 cdrom->track[i].id = i+1; | |
186 mci_status.dwTrack = cdrom->track[i].id; | |
187 #ifdef MCI_CDA_STATUS_TYPE_TRACK | |
188 mci_status.dwItem = MCI_CDA_STATUS_TYPE_TRACK; | |
189 if ( SDL_SYS_CDioctl(cdrom->id, MCI_STATUS, flags, | |
190 &mci_status) < 0 ) { | |
191 break; | |
192 } | |
193 if ( mci_status.dwReturn == MCI_CDA_TRACK_AUDIO ) { | |
194 cdrom->track[i].type = SDL_AUDIO_TRACK; | |
195 } else { | |
196 cdrom->track[i].type = SDL_DATA_TRACK; | |
197 } | |
198 #else | |
199 cdrom->track[i].type = SDL_AUDIO_TRACK; | |
200 #endif | |
201 mci_status.dwItem = MCI_STATUS_POSITION; | |
202 if ( SDL_SYS_CDioctl(cdrom->id, MCI_STATUS, flags, | |
203 &mci_status) < 0 ) { | |
204 break; | |
205 } | |
206 cdrom->track[i].offset = MSF_TO_FRAMES( | |
207 MCI_MSF_MINUTE(mci_status.dwReturn), | |
208 MCI_MSF_SECOND(mci_status.dwReturn), | |
209 MCI_MSF_FRAME(mci_status.dwReturn)); | |
210 cdrom->track[i].length = 0; | |
211 if ( i > 0 ) { | |
212 cdrom->track[i-1].length = | |
213 cdrom->track[i].offset- | |
214 cdrom->track[i-1].offset; | |
215 } | |
216 } | |
217 if ( i == cdrom->numtracks ) { | |
201
ddee60057806
Fixed last track time calculation (thanks Tchi Southivong)
Sam Lantinga <slouken@libsdl.org>
parents:
192
diff
changeset
|
218 mci_status.dwTrack = cdrom->track[i - 1].id; |
0 | 219 mci_status.dwItem = MCI_STATUS_LENGTH; |
220 if ( SDL_SYS_CDioctl(cdrom->id, MCI_STATUS, flags, | |
221 &mci_status) == 0 ) { | |
201
ddee60057806
Fixed last track time calculation (thanks Tchi Southivong)
Sam Lantinga <slouken@libsdl.org>
parents:
192
diff
changeset
|
222 cdrom->track[i - 1].length = MSF_TO_FRAMES( |
0 | 223 MCI_MSF_MINUTE(mci_status.dwReturn), |
224 MCI_MSF_SECOND(mci_status.dwReturn), | |
201
ddee60057806
Fixed last track time calculation (thanks Tchi Southivong)
Sam Lantinga <slouken@libsdl.org>
parents:
192
diff
changeset
|
225 MCI_MSF_FRAME(mci_status.dwReturn)) + 1; /* +1 to fix */ |
ddee60057806
Fixed last track time calculation (thanks Tchi Southivong)
Sam Lantinga <slouken@libsdl.org>
parents:
192
diff
changeset
|
226 /* MCI last track length bug */ |
ddee60057806
Fixed last track time calculation (thanks Tchi Southivong)
Sam Lantinga <slouken@libsdl.org>
parents:
192
diff
changeset
|
227 /* compute lead-out offset */ |
ddee60057806
Fixed last track time calculation (thanks Tchi Southivong)
Sam Lantinga <slouken@libsdl.org>
parents:
192
diff
changeset
|
228 cdrom->track[i].offset = cdrom->track[i - 1].offset + |
ddee60057806
Fixed last track time calculation (thanks Tchi Southivong)
Sam Lantinga <slouken@libsdl.org>
parents:
192
diff
changeset
|
229 cdrom->track[i - 1].length; |
0 | 230 cdrom->track[i].length = 0; |
231 okay = 1; | |
232 } | |
233 } | |
234 } | |
235 return(okay ? 0 : -1); | |
236 } | |
237 | |
238 /* Get CD-ROM status */ | |
239 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position) | |
240 { | |
241 CDstatus status; | |
242 MCI_STATUS_PARMS mci_status; | |
243 DWORD flags; | |
244 | |
245 flags = MCI_STATUS_ITEM | MCI_WAIT; | |
246 mci_status.dwItem = MCI_STATUS_MODE; | |
247 if ( SDL_SYS_CDioctl(cdrom->id, MCI_STATUS, flags, &mci_status) < 0 ) { | |
248 status = CD_ERROR; | |
249 } else { | |
250 switch (mci_status.dwReturn) { | |
251 case MCI_MODE_NOT_READY: | |
252 case MCI_MODE_OPEN: | |
253 status = CD_TRAYEMPTY; | |
254 break; | |
255 case MCI_MODE_STOP: | |
256 #ifdef BROKEN_MCI_PAUSE | |
257 if ( SDL_paused[cdrom->id] ) { | |
258 status = CD_PAUSED; | |
259 } else { | |
260 status = CD_STOPPED; | |
261 } | |
262 #else | |
263 status = CD_STOPPED; | |
264 #endif /* BROKEN_MCI_PAUSE */ | |
265 break; | |
266 case MCI_MODE_PLAY: | |
192
e31f8d815aaa
Fixed resuming a paused CD on Win2K (thanks Aragorn)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
267 #ifdef BROKEN_MCI_PAUSE |
e31f8d815aaa
Fixed resuming a paused CD on Win2K (thanks Aragorn)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
268 if ( SDL_paused[cdrom->id] ) { |
e31f8d815aaa
Fixed resuming a paused CD on Win2K (thanks Aragorn)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
269 status = CD_PAUSED; |
e31f8d815aaa
Fixed resuming a paused CD on Win2K (thanks Aragorn)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
270 } else { |
e31f8d815aaa
Fixed resuming a paused CD on Win2K (thanks Aragorn)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
271 status = CD_PLAYING; |
e31f8d815aaa
Fixed resuming a paused CD on Win2K (thanks Aragorn)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
272 } |
e31f8d815aaa
Fixed resuming a paused CD on Win2K (thanks Aragorn)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
273 #else |
0 | 274 status = CD_PLAYING; |
192
e31f8d815aaa
Fixed resuming a paused CD on Win2K (thanks Aragorn)
Sam Lantinga <slouken@libsdl.org>
parents:
0
diff
changeset
|
275 #endif /* BROKEN_MCI_PAUSE */ |
0 | 276 break; |
277 case MCI_MODE_PAUSE: | |
278 status = CD_PAUSED; | |
279 break; | |
280 default: | |
281 status = CD_ERROR; | |
282 break; | |
283 } | |
284 } | |
285 if ( position ) { | |
286 if ( status == CD_PLAYING || (status == CD_PAUSED) ) { | |
287 mci_status.dwItem = MCI_STATUS_POSITION; | |
288 if ( SDL_SYS_CDioctl(cdrom->id, MCI_STATUS, flags, | |
289 &mci_status) == 0 ) { | |
290 *position = MSF_TO_FRAMES( | |
291 MCI_MSF_MINUTE(mci_status.dwReturn), | |
292 MCI_MSF_SECOND(mci_status.dwReturn), | |
293 MCI_MSF_FRAME(mci_status.dwReturn)); | |
294 } else { | |
295 *position = 0; | |
296 } | |
297 } else { | |
298 *position = 0; | |
299 } | |
300 } | |
301 return(status); | |
302 } | |
303 | |
304 /* Start play */ | |
305 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length) | |
306 { | |
307 MCI_PLAY_PARMS mci_play; | |
308 int m, s, f; | |
309 DWORD flags; | |
310 | |
311 flags = MCI_FROM | MCI_TO | MCI_NOTIFY; | |
312 mci_play.dwCallback = 0; | |
313 FRAMES_TO_MSF(start, &m, &s, &f); | |
314 mci_play.dwFrom = MCI_MAKE_MSF(m, s, f); | |
315 FRAMES_TO_MSF(start+length, &m, &s, &f); | |
316 mci_play.dwTo = MCI_MAKE_MSF(m, s, f); | |
317 return(SDL_SYS_CDioctl(cdrom->id, MCI_PLAY, flags, &mci_play)); | |
318 } | |
319 | |
320 /* Pause play */ | |
321 static int SDL_SYS_CDPause(SDL_CD *cdrom) | |
322 { | |
323 #ifdef BROKEN_MCI_PAUSE | |
324 SDL_paused[cdrom->id] = 1; | |
325 #endif | |
326 return(SDL_SYS_CDioctl(cdrom->id, MCI_PAUSE, MCI_WAIT, NULL)); | |
327 } | |
328 | |
329 /* Resume play */ | |
330 static int SDL_SYS_CDResume(SDL_CD *cdrom) | |
331 { | |
332 #ifdef BROKEN_MCI_PAUSE | |
333 MCI_STATUS_PARMS mci_status; | |
334 int okay; | |
335 int flags; | |
336 | |
337 okay = 0; | |
338 /* Play from the current play position to end of CD */ | |
339 flags = MCI_STATUS_ITEM | MCI_WAIT; | |
340 mci_status.dwItem = MCI_STATUS_POSITION; | |
341 if ( SDL_SYS_CDioctl(cdrom->id, MCI_STATUS, flags, &mci_status) == 0 ) { | |
342 MCI_PLAY_PARMS mci_play; | |
343 | |
344 flags = MCI_FROM | MCI_NOTIFY; | |
345 mci_play.dwCallback = 0; | |
346 mci_play.dwFrom = mci_status.dwReturn; | |
347 if (SDL_SYS_CDioctl(cdrom->id,MCI_PLAY,flags,&mci_play) == 0) { | |
348 okay = 1; | |
349 SDL_paused[cdrom->id] = 0; | |
350 } | |
351 } | |
352 return(okay ? 0 : -1); | |
353 #else | |
354 return(SDL_SYS_CDioctl(cdrom->id, MCI_RESUME, MCI_WAIT, NULL)); | |
355 #endif /* BROKEN_MCI_PAUSE */ | |
356 } | |
357 | |
358 /* Stop play */ | |
359 static int SDL_SYS_CDStop(SDL_CD *cdrom) | |
360 { | |
361 return(SDL_SYS_CDioctl(cdrom->id, MCI_STOP, MCI_WAIT, NULL)); | |
362 } | |
363 | |
364 /* Eject the CD-ROM */ | |
365 static int SDL_SYS_CDEject(SDL_CD *cdrom) | |
366 { | |
367 return(SDL_SYS_CDioctl(cdrom->id, MCI_SET, MCI_SET_DOOR_OPEN, NULL)); | |
368 } | |
369 | |
370 /* Close the CD-ROM handle */ | |
371 static void SDL_SYS_CDClose(SDL_CD *cdrom) | |
372 { | |
373 SDL_SYS_CDioctl(cdrom->id, MCI_CLOSE, MCI_WAIT, NULL); | |
374 } | |
375 | |
376 void SDL_SYS_CDQuit(void) | |
377 { | |
378 int i; | |
379 | |
380 if ( SDL_numcds > 0 ) { | |
381 for ( i=0; i<SDL_numcds; ++i ) { | |
382 free(SDL_cdlist[i]); | |
383 } | |
384 SDL_numcds = 0; | |
385 } | |
386 } |