comparison src/cdrom/macos/SDL_syscdrom.c @ 1895:c121d94672cb

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