Mercurial > sdl-ios-xcode
annotate src/cdrom/macos/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:
0
diff
changeset
|
20 slouken@libsdl.org |
0 | 21 */ |
22 | |
23 #ifdef SAVE_RCSID | |
24 static char rcsid = | |
25 "@(#) $Id$"; | |
26 #endif | |
27 | |
28 /* MacOS functions for system-level CD-ROM audio control */ | |
29 | |
30 #include <Devices.h> | |
31 #include <Files.h> | |
32 #include <LowMem.h> /* Use entry table macros, not functions in InterfaceLib */ | |
33 | |
34 #include "SDL_cdrom.h" | |
35 #include "SDL_syscdrom.h" | |
36 #include "SDL_syscdrom_c.h" | |
37 | |
38 /* Added by Matt Slot */ | |
39 #if !defined(LMGetUnitTableEntryCount) | |
40 #define LMGetUnitTableEntryCount() *(short *)0x01D2 | |
41 #endif | |
42 | |
43 /* The maximum number of CD-ROM drives we'll detect */ | |
44 #define MAX_DRIVES 26 | |
45 | |
46 /* A list of available CD-ROM drives */ | |
47 static long SDL_cdversion = 0; | |
48 static struct { | |
49 short dRefNum; | |
50 short driveNum; | |
51 long frames; | |
52 char name[256]; | |
53 Boolean hasAudio; | |
54 } SDL_cdlist[MAX_DRIVES]; | |
55 static StringPtr gDriverName = "\p.AppleCD"; | |
56 | |
57 /* The system-dependent CD control functions */ | |
58 static const char *SDL_SYS_CDName(int drive); | |
59 static int SDL_SYS_CDOpen(int drive); | |
60 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom); | |
61 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position); | |
62 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length); | |
63 static int SDL_SYS_CDPause(SDL_CD *cdrom); | |
64 static int SDL_SYS_CDResume(SDL_CD *cdrom); | |
65 static int SDL_SYS_CDStop(SDL_CD *cdrom); | |
66 static int SDL_SYS_CDEject(SDL_CD *cdrom); | |
67 static void SDL_SYS_CDClose(SDL_CD *cdrom); | |
68 | |
69 static short SDL_SYS_ShortToBCD(short value) | |
70 { | |
71 return((value % 10) + (value / 10) * 0x10); /* Convert value to BCD */ | |
72 } | |
73 | |
74 static short SDL_SYS_BCDToShort(short value) | |
75 { | |
76 return((value % 0x10) + (value / 0x10) * 10); /* Convert value from BCD */ | |
77 } | |
78 | |
79 int SDL_SYS_CDInit(void) | |
80 { | |
81 SInt16 dRefNum = 0; | |
82 SInt16 first, last; | |
83 | |
84 SDL_numcds = 0; | |
85 | |
86 /* Check that the software is available */ | |
87 if (Gestalt(kGestaltAudioCDSelector, &SDL_cdversion) || | |
88 !SDL_cdversion) return(0); | |
89 | |
90 /* Fill in our driver capabilities */ | |
91 SDL_CDcaps.Name = SDL_SYS_CDName; | |
92 SDL_CDcaps.Open = SDL_SYS_CDOpen; | |
93 SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC; | |
94 SDL_CDcaps.Status = SDL_SYS_CDStatus; | |
95 SDL_CDcaps.Play = SDL_SYS_CDPlay; | |
96 SDL_CDcaps.Pause = SDL_SYS_CDPause; | |
97 SDL_CDcaps.Resume = SDL_SYS_CDResume; | |
98 SDL_CDcaps.Stop = SDL_SYS_CDStop; | |
99 SDL_CDcaps.Eject = SDL_SYS_CDEject; | |
100 SDL_CDcaps.Close = SDL_SYS_CDClose; | |
101 | |
102 /* Walk the list, count each AudioCD driver, and save the refnums */ | |
103 first = -1; | |
104 last = 0 - LMGetUnitTableEntryCount(); | |
105 for(dRefNum = first; dRefNum >= last; dRefNum--) { | |
106 Str255 driverName; | |
107 StringPtr namePtr; | |
108 DCtlHandle deviceEntry; | |
109 | |
110 deviceEntry = GetDCtlEntry(dRefNum); | |
111 if (! deviceEntry) continue; | |
112 | |
113 /* Is this an .AppleCD ? */ | |
114 namePtr = (*deviceEntry)->dCtlFlags & (1L << dRAMBased) ? | |
115 ((StringPtr) ((DCtlPtr) deviceEntry)->dCtlDriver + 18) : | |
116 ((StringPtr) (*deviceEntry)->dCtlDriver + 18); | |
117 BlockMoveData(namePtr, driverName, namePtr[0]+1); | |
118 if (driverName[0] > gDriverName[0]) driverName[0] = gDriverName[0]; | |
119 if (! EqualString(driverName, gDriverName, false, false)) continue; | |
120 | |
121 /* Record the basic info for each drive */ | |
122 SDL_cdlist[SDL_numcds].dRefNum = dRefNum; | |
123 BlockMoveData(namePtr + 1, SDL_cdlist[SDL_numcds].name, namePtr[0]); | |
124 SDL_cdlist[SDL_numcds].name[namePtr[0]] = 0; | |
125 SDL_cdlist[SDL_numcds].hasAudio = false; | |
126 SDL_numcds++; | |
127 } | |
128 return(0); | |
129 } | |
130 | |
131 static const char *SDL_SYS_CDName(int drive) | |
132 { | |
133 return(SDL_cdlist[drive].name); | |
134 } | |
135 | |
136 static int get_drivenum(int drive) | |
137 { | |
138 QHdr *driveQ = GetDrvQHdr(); | |
139 DrvQEl *driveElem; | |
140 | |
141 /* Update the drive number */ | |
142 SDL_cdlist[drive].driveNum = 0; | |
143 if ( driveQ->qTail ) { | |
144 driveQ->qTail->qLink = 0; | |
145 } | |
146 for ( driveElem=(DrvQEl *)driveQ->qHead; driveElem; | |
147 driveElem = (DrvQEl *)driveElem->qLink ) { | |
148 if ( driveElem->dQRefNum == SDL_cdlist[drive].dRefNum ) { | |
149 SDL_cdlist[drive].driveNum = driveElem->dQDrive; | |
150 break; | |
151 } | |
152 } | |
153 return(SDL_cdlist[drive].driveNum); | |
154 } | |
155 | |
156 static int SDL_SYS_CDOpen(int drive) | |
157 { | |
158 return(drive); | |
159 } | |
160 | |
161 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom) | |
162 { | |
163 CDCntrlParam cdpb; | |
164 CDTrackData tracks[SDL_MAX_TRACKS]; | |
165 long i, leadout; | |
166 | |
167 /* Get the number of tracks on the CD by examining the TOC */ | |
168 memset(&cdpb, 0, sizeof(cdpb)); | |
169 cdpb.ioVRefNum = SDL_cdlist[cdrom->id].driveNum; | |
170 cdpb.ioCRefNum = SDL_cdlist[cdrom->id].dRefNum; | |
171 cdpb.csCode = kReadTOC; | |
172 cdpb.csParam.words[0] = kGetTrackRange; | |
173 if ( PBControlSync((ParmBlkPtr)&cdpb) != noErr ) { | |
174 SDL_SetError("PBControlSync() failed"); | |
175 return(-1); | |
176 } | |
177 | |
178 cdrom->numtracks = | |
179 SDL_SYS_BCDToShort(cdpb.csParam.bytes[1]) - | |
180 SDL_SYS_BCDToShort(cdpb.csParam.bytes[0]) + 1; | |
181 if ( cdrom->numtracks > SDL_MAX_TRACKS ) | |
182 cdrom->numtracks = SDL_MAX_TRACKS; | |
183 cdrom->status = CD_STOPPED; | |
184 cdrom->cur_track = 0; /* Apparently these are set elsewhere */ | |
185 cdrom->cur_frame = 0; /* Apparently these are set elsewhere */ | |
186 | |
187 | |
188 /* Get the lead out area of the CD by examining the TOC */ | |
189 memset(&cdpb, 0, sizeof(cdpb)); | |
190 cdpb.ioVRefNum = SDL_cdlist[cdrom->id].driveNum; | |
191 cdpb.ioCRefNum = SDL_cdlist[cdrom->id].dRefNum; | |
192 cdpb.csCode = kReadTOC; | |
193 cdpb.csParam.words[0] = kGetLeadOutArea; | |
194 if ( PBControlSync((ParmBlkPtr)&cdpb) != noErr ) { | |
195 SDL_SetError("PBControlSync() failed"); | |
196 return(-1); | |
197 } | |
198 | |
199 leadout = MSF_TO_FRAMES( | |
200 SDL_SYS_BCDToShort(cdpb.csParam.bytes[0]), | |
201 SDL_SYS_BCDToShort(cdpb.csParam.bytes[1]), | |
202 SDL_SYS_BCDToShort(cdpb.csParam.bytes[2])); | |
203 | |
204 /* Get an array of track locations by examining the TOC */ | |
205 memset(tracks, 0, sizeof(tracks)); | |
206 memset(&cdpb, 0, sizeof(cdpb)); | |
207 cdpb.ioVRefNum = SDL_cdlist[cdrom->id].driveNum; | |
208 cdpb.ioCRefNum = SDL_cdlist[cdrom->id].dRefNum; | |
209 cdpb.csCode = kReadTOC; | |
210 cdpb.csParam.words[0] = kGetTrackEntries; /* Type of Query */ | |
211 * ((long *) (cdpb.csParam.words+1)) = (long) tracks; | |
212 cdpb.csParam.words[3] = cdrom->numtracks * sizeof(tracks[0]); | |
213 * ((char *) (cdpb.csParam.words+4)) = 1; /* First track */ | |
214 if ( PBControlSync((ParmBlkPtr)&cdpb) != noErr ) { | |
215 SDL_SetError("PBControlSync() failed"); | |
216 return(-1); | |
217 } | |
218 | |
219 /* Read all the track TOC entries */ | |
220 SDL_cdlist[cdrom->id].hasAudio = false; | |
221 for ( i=0; i<cdrom->numtracks; ++i ) | |
222 { | |
223 cdrom->track[i].id = i+1; | |
224 if (tracks[i].entry.control & kDataTrackMask) | |
225 cdrom->track[i].type = SDL_DATA_TRACK; | |
226 else | |
227 { | |
228 cdrom->track[i].type = SDL_AUDIO_TRACK; | |
229 SDL_cdlist[SDL_numcds].hasAudio = true; | |
230 } | |
231 | |
232 cdrom->track[i].offset = MSF_TO_FRAMES( | |
233 SDL_SYS_BCDToShort(tracks[i].entry.min), | |
234 SDL_SYS_BCDToShort(tracks[i].entry.min), | |
235 SDL_SYS_BCDToShort(tracks[i].entry.frame)); | |
236 cdrom->track[i].length = MSF_TO_FRAMES( | |
237 SDL_SYS_BCDToShort(tracks[i+1].entry.min), | |
238 SDL_SYS_BCDToShort(tracks[i+1].entry.min), | |
239 SDL_SYS_BCDToShort(tracks[i+1].entry.frame)) - | |
240 cdrom->track[i].offset; | |
241 } | |
242 | |
243 /* Apparently SDL wants a fake last entry */ | |
244 cdrom->track[i].offset = leadout; | |
245 cdrom->track[i].length = 0; | |
246 | |
247 return(0); | |
248 } | |
249 | |
250 /* Get CD-ROM status */ | |
251 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position) | |
252 { | |
253 CDCntrlParam cdpb; | |
254 CDstatus status = CD_ERROR; | |
255 Boolean spinning = false; | |
256 | |
257 if (position) *position = 0; | |
258 | |
259 /* Get the number of tracks on the CD by examining the TOC */ | |
260 if ( ! get_drivenum(cdrom->id) ) { | |
261 return(CD_TRAYEMPTY); | |
262 } | |
263 memset(&cdpb, 0, sizeof(cdpb)); | |
264 cdpb.ioVRefNum = SDL_cdlist[cdrom->id].driveNum; | |
265 cdpb.ioCRefNum = SDL_cdlist[cdrom->id].dRefNum; | |
266 cdpb.csCode = kReadTOC; | |
267 cdpb.csParam.words[0] = kGetTrackRange; | |
268 if ( PBControlSync((ParmBlkPtr)&cdpb) != noErr ) { | |
269 SDL_SetError("PBControlSync() failed"); | |
270 return(CD_ERROR); | |
271 } | |
272 | |
273 cdrom->numtracks = | |
274 SDL_SYS_BCDToShort(cdpb.csParam.bytes[1]) - | |
275 SDL_SYS_BCDToShort(cdpb.csParam.bytes[0]) + 1; | |
276 if ( cdrom->numtracks > SDL_MAX_TRACKS ) | |
277 cdrom->numtracks = SDL_MAX_TRACKS; | |
278 cdrom->cur_track = 0; /* Apparently these are set elsewhere */ | |
279 cdrom->cur_frame = 0; /* Apparently these are set elsewhere */ | |
280 | |
281 | |
282 if (1 || SDL_cdlist[cdrom->id].hasAudio) { | |
283 /* Get the current playback status */ | |
284 memset(&cdpb, 0, sizeof(cdpb)); | |
285 cdpb.ioVRefNum = SDL_cdlist[cdrom->id].driveNum; | |
286 cdpb.ioCRefNum = SDL_cdlist[cdrom->id].dRefNum; | |
287 cdpb.csCode = kAudioStatus; | |
288 if ( PBControlSync((ParmBlkPtr)&cdpb) != noErr ) { | |
289 SDL_SetError("PBControlSync() failed"); | |
290 return(-1); | |
291 } | |
292 | |
293 switch(cdpb.csParam.cd.status) { | |
294 case kStatusPlaying: | |
295 status = CD_PLAYING; | |
296 spinning = true; | |
297 break; | |
298 case kStatusPaused: | |
299 status = CD_PAUSED; | |
300 spinning = true; | |
301 break; | |
302 case kStatusMuted: | |
303 status = CD_PLAYING; /* What should I do here? */ | |
304 spinning = true; | |
305 break; | |
306 case kStatusDone: | |
307 status = CD_STOPPED; | |
308 spinning = true; | |
309 break; | |
310 case kStatusStopped: | |
311 status = CD_STOPPED; | |
312 spinning = false; | |
313 break; | |
314 case kStatusError: | |
315 default: | |
316 status = CD_ERROR; | |
317 spinning = false; | |
318 break; | |
319 } | |
320 | |
321 if (spinning && position) *position = MSF_TO_FRAMES( | |
322 SDL_SYS_BCDToShort(cdpb.csParam.cd.minute), | |
323 SDL_SYS_BCDToShort(cdpb.csParam.cd.second), | |
324 SDL_SYS_BCDToShort(cdpb.csParam.cd.frame)); | |
325 } | |
326 else | |
327 status = CD_ERROR; /* What should I do here? */ | |
328 | |
329 return(status); | |
330 } | |
331 | |
332 /* Start play */ | |
333 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length) | |
334 { | |
335 CDCntrlParam cdpb; | |
336 | |
337 /* Pause the current audio playback to avoid audible artifacts */ | |
338 if ( SDL_SYS_CDPause(cdrom) < 0 ) { | |
339 return(-1); | |
340 } | |
341 | |
342 /* Specify the AudioCD playback mode */ | |
343 memset(&cdpb, 0, sizeof(cdpb)); | |
344 cdpb.ioVRefNum = SDL_cdlist[cdrom->id].driveNum; | |
345 cdpb.ioCRefNum = SDL_cdlist[cdrom->id].dRefNum; | |
346 cdpb.csCode = kSetPlayMode; | |
347 cdpb.csParam.bytes[0] = false; /* Repeat? */ | |
348 cdpb.csParam.bytes[1] = kPlayModeSequential; /* Play mode */ | |
349 /* ¥¥¥ÊTreat as soft error, NEC Drive doesnt support this call ¥¥¥ */ | |
350 PBControlSync((ParmBlkPtr) &cdpb); | |
351 | |
352 #if 1 | |
353 /* Specify the end of audio playback */ | |
354 memset(&cdpb, 0, sizeof(cdpb)); | |
355 cdpb.ioVRefNum = SDL_cdlist[cdrom->id].driveNum; | |
356 cdpb.ioCRefNum = SDL_cdlist[cdrom->id].dRefNum; | |
357 cdpb.csCode = kAudioStop; | |
358 cdpb.csParam.words[0] = kBlockPosition; /* Position Mode */ | |
359 *(long *) (cdpb.csParam.words + 1) = start+length-1; /* Search Address */ | |
360 if ( PBControlSync((ParmBlkPtr)&cdpb) != noErr ) { | |
361 SDL_SetError("PBControlSync() failed"); | |
362 return(-1); | |
363 } | |
364 | |
365 /* Specify the start of audio playback, and start it */ | |
366 memset(&cdpb, 0, sizeof(cdpb)); | |
367 cdpb.ioVRefNum = SDL_cdlist[cdrom->id].driveNum; | |
368 cdpb.ioCRefNum = SDL_cdlist[cdrom->id].dRefNum; | |
369 cdpb.csCode = kAudioPlay; | |
370 cdpb.csParam.words[0] = kBlockPosition; /* Position Mode */ | |
371 *(long *) (cdpb.csParam.words + 1) = start+1; /* Search Address */ | |
372 cdpb.csParam.words[3] = false; /* Stop address? */ | |
373 cdpb.csParam.words[4] = kStereoPlayMode; /* Audio Play Mode */ | |
374 if ( PBControlSync((ParmBlkPtr)&cdpb) != noErr ) { | |
375 SDL_SetError("PBControlSync() failed"); | |
376 return(-1); | |
377 } | |
378 #else | |
379 /* Specify the end of audio playback */ | |
380 FRAMES_TO_MSF(start+length, &m, &s, &f); | |
381 memset(&cdpb, 0, sizeof(cdpb)); | |
382 cdpb.ioVRefNum = SDL_cdlist[cdrom->id].driveNum; | |
383 cdpb.ioCRefNum = SDL_cdlist[cdrom->id].dRefNum; | |
384 cdpb.csCode = kAudioStop; | |
385 cdpb.csParam.words[0] = kTrackPosition; /* Position Mode */ | |
386 cdpb.csParam.words[1] = 0; /* Search Address (hiword)*/ | |
387 cdpb.csParam.words[2] = /* Search Address (loword)*/ | |
388 SDL_SYS_ShortToBCD(cdrom->numtracks); | |
389 if ( PBControlSync((ParmBlkPtr)&cdpb) != noErr ) { | |
390 SDL_SetError("PBControlSync() failed"); | |
391 return(-1); | |
392 } | |
393 | |
394 /* Specify the start of audio playback, and start it */ | |
395 FRAMES_TO_MSF(start, &m, &s, &f); | |
396 memset(&cdpb, 0, sizeof(cdpb)); | |
397 cdpb.ioVRefNum = SDL_cdlist[cdrom->id].driveNum; | |
398 cdpb.ioCRefNum = SDL_cdlist[cdrom->id].dRefNum; | |
399 cdpb.csCode = kAudioPlay; | |
400 cdpb.csParam.words[0] = kTrackPosition; /* Position Mode */ | |
401 cdpb.csParam.words[1] = 0; /* Search Address (hiword)*/ | |
402 cdpb.csParam.words[2] = SDL_SYS_ShortToBCD(1); /* Search Address (loword)*/ | |
403 cdpb.csParam.words[3] = false; /* Stop address? */ | |
404 cdpb.csParam.words[4] = kStereoPlayMode; /* Audio Play Mode */ | |
405 if ( PBControlSync((ParmBlkPtr)&cdpb) != noErr ) { | |
406 SDL_SetError("PBControlSync() failed"); | |
407 return(-1); | |
408 } | |
409 #endif | |
410 | |
411 return(0); | |
412 } | |
413 | |
414 /* Pause play */ | |
415 static int SDL_SYS_CDPause(SDL_CD *cdrom) | |
416 { | |
417 CDCntrlParam cdpb; | |
418 | |
419 memset(&cdpb, 0, sizeof(cdpb)); | |
420 cdpb.ioVRefNum = SDL_cdlist[cdrom->id].driveNum; | |
421 cdpb.ioCRefNum = SDL_cdlist[cdrom->id].dRefNum; | |
422 cdpb.csCode = kAudioPause; | |
423 cdpb.csParam.words[0] = 0; /* Pause/Continue Flag (hiword) */ | |
424 cdpb.csParam.words[1] = 1; /* Pause/Continue Flag (loword) */ | |
425 if ( PBControlSync((ParmBlkPtr)&cdpb) != noErr ) { | |
426 SDL_SetError("PBControlSync() failed"); | |
427 return(-1); | |
428 } | |
429 return(0); | |
430 } | |
431 | |
432 /* Resume play */ | |
433 static int SDL_SYS_CDResume(SDL_CD *cdrom) | |
434 { | |
435 CDCntrlParam cdpb; | |
436 | |
437 memset(&cdpb, 0, sizeof(cdpb)); | |
438 cdpb.ioVRefNum = SDL_cdlist[cdrom->id].driveNum; | |
439 cdpb.ioCRefNum = SDL_cdlist[cdrom->id].dRefNum; | |
440 cdpb.csCode = kAudioPause; | |
441 cdpb.csParam.words[0] = 0; /* Pause/Continue Flag (hiword) */ | |
442 cdpb.csParam.words[1] = 0; /* Pause/Continue Flag (loword) */ | |
443 if ( PBControlSync((ParmBlkPtr)&cdpb) != noErr ) { | |
444 SDL_SetError("PBControlSync() failed"); | |
445 return(-1); | |
446 } | |
447 return(0); | |
448 } | |
449 | |
450 /* Stop play */ | |
451 static int SDL_SYS_CDStop(SDL_CD *cdrom) | |
452 { | |
453 CDCntrlParam cdpb; | |
454 | |
455 memset(&cdpb, 0, sizeof(cdpb)); | |
456 cdpb.ioVRefNum = SDL_cdlist[cdrom->id].driveNum; | |
457 cdpb.ioCRefNum = SDL_cdlist[cdrom->id].dRefNum; | |
458 cdpb.csCode = kAudioStop; | |
459 cdpb.csParam.words[0] = 0; /* Position Mode */ | |
460 cdpb.csParam.words[1] = 0; /* Search Address (hiword) */ | |
461 cdpb.csParam.words[2] = 0; /* Search Address (loword) */ | |
462 if ( PBControlSync((ParmBlkPtr)&cdpb) != noErr ) { | |
463 SDL_SetError("PBControlSync() failed"); | |
464 return(-1); | |
465 } | |
466 return(0); | |
467 } | |
468 | |
469 /* Eject the CD-ROM */ | |
470 static int SDL_SYS_CDEject(SDL_CD *cdrom) | |
471 { | |
472 Boolean disk = false; | |
473 QHdr *driveQ = GetDrvQHdr(); | |
474 DrvQEl *driveElem; | |
475 HParamBlockRec hpb; | |
476 ParamBlockRec cpb; | |
477 | |
478 for ( driveElem = (DrvQEl *) driveQ->qHead; driveElem; driveElem = | |
479 (driveElem) ? ((DrvQEl *) driveElem->qLink) : | |
480 ((DrvQEl *) driveQ->qHead) ) { | |
481 if ( driveQ->qTail ) { | |
482 driveQ->qTail->qLink = 0; | |
483 } | |
484 if ( driveElem->dQRefNum != SDL_cdlist[cdrom->id].dRefNum ) { | |
485 continue; | |
486 } | |
487 | |
488 /* Does drive contain mounted volume? If not, skip */ | |
489 memset(&hpb, 0, sizeof(hpb)); | |
490 hpb.volumeParam.ioVRefNum = driveElem->dQDrive; | |
491 if ( PBHGetVInfoSync(&hpb) != noErr ) { | |
492 continue; | |
493 } | |
494 if ( (UnmountVol(0, driveElem->dQDrive) == noErr) && | |
495 (Eject(0, driveElem->dQDrive) == noErr) ) { | |
496 driveElem = 0; /* Clear pointer to reset our loop */ | |
497 disk = true; | |
498 } | |
499 } | |
500 | |
501 /* If no disk is present, just eject the tray */ | |
502 if (! disk) { | |
503 memset(&cpb, 0, sizeof(cpb)); | |
504 cpb.cntrlParam.ioVRefNum = 0; /* No Drive */ | |
505 cpb.cntrlParam.ioCRefNum = SDL_cdlist[cdrom->id].dRefNum; | |
506 cpb.cntrlParam.csCode = kEjectTheDisc; | |
507 if ( PBControlSync((ParmBlkPtr)&cpb) != noErr ) { | |
508 SDL_SetError("PBControlSync() failed"); | |
509 return(-1); | |
510 } | |
511 } | |
512 return(0); | |
513 } | |
514 | |
515 /* Close the CD-ROM handle */ | |
516 static void SDL_SYS_CDClose(SDL_CD *cdrom) | |
517 { | |
518 return; | |
519 } | |
520 | |
521 void SDL_SYS_CDQuit(void) | |
522 { | |
523 while(SDL_numcds--) | |
524 memset(SDL_cdlist + SDL_numcds, 0, sizeof(SDL_cdlist[0])); | |
525 } | |
526 |