comparison src/cdrom/qnx/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
comparison
equal deleted inserted replaced
570:04d6411da49d 571:8e3ce997621c
31 #include <stdlib.h> 31 #include <stdlib.h>
32 #include <sys/stat.h> 32 #include <sys/stat.h>
33 #include <sys/ioctl.h> 33 #include <sys/ioctl.h>
34 #include <fcntl.h> 34 #include <fcntl.h>
35 #include <stdio.h> 35 #include <stdio.h>
36 #include <errno.h>
36 #include <string.h> 37 #include <string.h>
37 #include <errno.h>
38 #include <unistd.h> 38 #include <unistd.h>
39 #include <sys/cdrom.h> 39 #include <sys/cdrom.h>
40 #include <sys/dcmd_cam.h> 40 #include <sys/dcmd_cam.h>
41 41
42
43 #include "SDL_error.h" 42 #include "SDL_error.h"
44 #include "SDL_cdrom.h" 43 #include "SDL_cdrom.h"
44 #include "SDL_timer.h"
45 #include "SDL_syscdrom.h" 45 #include "SDL_syscdrom.h"
46 46
47
48 /* The maximum number of CD-ROM drives we'll detect */ 47 /* The maximum number of CD-ROM drives we'll detect */
49 #define MAX_DRIVES 16 48 #define MAX_DRIVES 16
49
50 #define QNX_CD_OPENMODE O_RDONLY | O_EXCL
50 51
51 /* A list of available CD-ROM drives */ 52 /* A list of available CD-ROM drives */
52 static char *SDL_cdlist[MAX_DRIVES]; 53 static char *SDL_cdlist[MAX_DRIVES];
53 static dev_t SDL_cdmode[MAX_DRIVES]; 54 static dev_t SDL_cdmode[MAX_DRIVES];
55 static int SDL_cdopen[MAX_DRIVES];
54 56
55 /* The system-dependent CD control functions */ 57 /* The system-dependent CD control functions */
56 static const char *SDL_SYS_CDName(int drive); 58 static const char *SDL_SYS_CDName(int drive);
57 static int SDL_SYS_CDOpen(int drive); 59 static int SDL_SYS_CDOpen(int drive);
58 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom); 60 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom);
62 static int SDL_SYS_CDResume(SDL_CD *cdrom); 64 static int SDL_SYS_CDResume(SDL_CD *cdrom);
63 static int SDL_SYS_CDStop(SDL_CD *cdrom); 65 static int SDL_SYS_CDStop(SDL_CD *cdrom);
64 static int SDL_SYS_CDEject(SDL_CD *cdrom); 66 static int SDL_SYS_CDEject(SDL_CD *cdrom);
65 static void SDL_SYS_CDClose(SDL_CD *cdrom); 67 static void SDL_SYS_CDClose(SDL_CD *cdrom);
66 68
67 /* Some ioctl() errno values which occur when the tray is empty */
68 #define ERRNO_TRAYEMPTY(errno) \
69 ((errno == EIO) || (errno == ENOENT) || (errno == EINVAL))
70
71 /* Check a drive to see if it is a CD-ROM */ 69 /* Check a drive to see if it is a CD-ROM */
72 static int CheckDrive(char *drive, char *mnttype, struct stat *stbuf) 70 static int CheckDrive(char *drive, struct stat *stbuf)
73 { 71 {
74 int is_cd, cdfd; 72 int is_cd, cdfd;
75 cdrom_subch_data_t info; 73 cam_devinfo_t dinfo;
76 74 int devctlret=0;
77 /* If it doesn't exist, return -1 */ 75
78 if ( stat(drive, stbuf) < 0 ) { 76 int atapi;
79 return(-1); 77 int removable;
80 } 78 int cdb10;
81 79
82 /* If it does exist, verify that it's an available CD-ROM */ 80 /* If it doesn't exist, return -1 */
83 is_cd = 0; 81 if (stat(drive, stbuf) < 0)
84 if ( S_ISCHR(stbuf->st_mode) || S_ISBLK(stbuf->st_mode) ) { 82 {
85 cdfd = open(drive, (O_RDONLY|O_EXCL|O_NONBLOCK), 0); 83 return(-1);
86 if ( cdfd >= 0 ) { 84 }
87 info.subch_command.data_format = CDROM_MSF; 85
88 /* Under Linux, EIO occurs when a disk is not present. 86 /* If it does exist, verify that it's an available CD-ROM */
89 */ 87 is_cd = 0;
90 if ((devctl(cdfd,DCMD_CAM_CDROMSUBCHNL,&info,sizeof(info),0) == 0) || 88
91 ERRNO_TRAYEMPTY(errno) ) 89 if (S_ISCHR(stbuf->st_mode) || S_ISBLK(stbuf->st_mode))
92 { 90 {
93 is_cd = 1; 91 cdfd = open(drive, QNX_CD_OPENMODE);
94 } 92 if ( cdfd >= 0 )
95 close(cdfd); 93 {
96 } 94 devctlret=devctl(cdfd, DCMD_CAM_DEVINFO, &dinfo, sizeof(cam_devinfo_t), NULL);
97 } 95
98 return(is_cd); 96 if (devctlret==EOK)
97 {
98 atapi=dinfo.flags & DEV_ATAPI;
99 removable=dinfo.flags & DEV_REMOVABLE;
100 cdb10=dinfo.flags & DEV_CDB_10; /* I'm not sure about that flag */
101
102 /* in the near future need to add more checks for splitting cdroms from other devices */
103 if ((atapi)&&(removable))
104 {
105 is_cd = 1;
106 }
107 }
108
109 close(cdfd);
110 }
111 }
112 return(is_cd);
99 } 113 }
100 114
101 /* Add a CD-ROM drive to our list of valid drives */ 115 /* Add a CD-ROM drive to our list of valid drives */
102 static void AddDrive(char *drive, struct stat *stbuf) 116 static void AddDrive(char *drive, struct stat *stbuf)
103 { 117 {
104 int i; 118 int i;
105 119
106 if ( SDL_numcds < MAX_DRIVES ) { 120 if (SDL_numcds < MAX_DRIVES)
107 /* Check to make sure it's not already in our list. 121 {
108 This can happen when we see a drive via symbolic link. 122 /* Check to make sure it's not already in our list.
109 */ 123 This can happen when we see a drive via symbolic link. */
110 for ( i=0; i<SDL_numcds; ++i ) { 124
111 if ( stbuf->st_rdev == SDL_cdmode[i] ) { 125 for (i=0; i<SDL_numcds; ++i)
112 #ifdef DEBUG_CDROM 126 {
113 fprintf(stderr, "Duplicate drive detected: %s == %s\n", drive, SDL_cdlist[i]); 127 if (stbuf->st_rdev == SDL_cdmode[i])
114 #endif 128 {
115 return; 129 return;
116 } 130 }
117 } 131 }
118 132
119 /* Add this drive to our list */ 133 /* Add this drive to our list */
120 i = SDL_numcds; 134
121 SDL_cdlist[i] = (char *)malloc(strlen(drive)+1); 135 i = SDL_numcds;
122 if ( SDL_cdlist[i] == NULL ) { 136 SDL_cdlist[i] = (char *)malloc(strlen(drive)+1);
123 SDL_OutOfMemory(); 137 if (SDL_cdlist[i] == NULL)
124 return; 138 {
125 } 139 SDL_OutOfMemory();
126 strcpy(SDL_cdlist[i], drive); 140 return;
127 SDL_cdmode[i] = stbuf->st_rdev; 141 }
128 ++SDL_numcds; 142 strcpy(SDL_cdlist[i], drive);
129 #ifdef DEBUG_CDROM 143 SDL_cdmode[i] = stbuf->st_rdev;
130 fprintf(stderr, "Added CD-ROM drive: %s\n", drive); 144 ++SDL_numcds;
131 #endif 145 }
132 } 146 }
133 } 147
134 148 int SDL_SYS_CDInit(void)
135 int SDL_SYS_CDInit(void) 149 {
136 { 150 /* checklist: /dev/cdrom, /dev/cd?, /dev/scd? */
137 /* checklist: /dev/cdrom, /dev/hd?, /dev/scd? /dev/sr? */ 151 static char *checklist[]={"cdrom", "?0 cd?", "?1 cd?", "?0 scd?", NULL};
138 static char *checklist[] = { 152
139 "cdrom", "?0 cd?", "?1 cd?", "?a hd?", "?0 scd?", "?0 sr?", NULL 153 char *SDLcdrom;
140 }; 154 int i, j, exists;
141 char *SDLcdrom; 155 char drive[32];
142 int i, j, exists; 156 struct stat stbuf;
143 char drive[32]; 157
144 struct stat stbuf; 158 /* Fill in our driver capabilities */
145 159 SDL_CDcaps.Name = SDL_SYS_CDName;
146 /* Fill in our driver capabilities */ 160 SDL_CDcaps.Open = SDL_SYS_CDOpen;
147 SDL_CDcaps.Name = SDL_SYS_CDName; 161 SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC;
148 SDL_CDcaps.Open = SDL_SYS_CDOpen; 162 SDL_CDcaps.Status = SDL_SYS_CDStatus;
149 SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC; 163 SDL_CDcaps.Play = SDL_SYS_CDPlay;
150 SDL_CDcaps.Status = SDL_SYS_CDStatus; 164 SDL_CDcaps.Pause = SDL_SYS_CDPause;
151 SDL_CDcaps.Play = SDL_SYS_CDPlay; 165 SDL_CDcaps.Resume = SDL_SYS_CDResume;
152 SDL_CDcaps.Pause = SDL_SYS_CDPause; 166 SDL_CDcaps.Stop = SDL_SYS_CDStop;
153 SDL_CDcaps.Resume = SDL_SYS_CDResume; 167 SDL_CDcaps.Eject = SDL_SYS_CDEject;
154 SDL_CDcaps.Stop = SDL_SYS_CDStop; 168 SDL_CDcaps.Close = SDL_SYS_CDClose;
155 SDL_CDcaps.Eject = SDL_SYS_CDEject; 169
156 SDL_CDcaps.Close = SDL_SYS_CDClose; 170 /* clearing device open status */
157 171 for (i=0; i<MAX_DRIVES; i++)
158 /* Look in the environment for our CD-ROM drive list */ 172 {
159 SDLcdrom = getenv("SDL_CDROM"); /* ':' separated list of devices */ 173 SDL_cdopen[i]=0;
160 if ( SDLcdrom != NULL ) { 174 }
161 char *cdpath, *delim; 175
162 cdpath = malloc(strlen(SDLcdrom)+1); 176 /* Look in the environment for our CD-ROM drive list */
163 if ( cdpath != NULL ) { 177 SDLcdrom = getenv("SDL_CDROM"); /* ':' separated list of devices */
164 strcpy(cdpath, SDLcdrom); 178 if ( SDLcdrom != NULL )
165 SDLcdrom = cdpath; 179 {
166 do { 180 char *cdpath, *delim;
167 delim = strchr(SDLcdrom, ':'); 181
168 if ( delim ) { 182 cdpath = malloc(strlen(SDLcdrom)+1);
169 *delim++ = '\0'; 183 if (cdpath != NULL)
170 } 184 {
171 #ifdef DEBUG_CDROM 185 strcpy(cdpath, SDLcdrom);
172 fprintf(stderr, "Checking CD-ROM drive from SDL_CDROM: %s\n", SDLcdrom); 186 SDLcdrom = cdpath;
173 #endif 187 do {
174 if ( CheckDrive(SDLcdrom, NULL, &stbuf) > 0 ) { 188 delim = strchr(SDLcdrom, ':');
175 AddDrive(SDLcdrom, &stbuf); 189 if (delim)
176 } 190 {
177 if ( delim ) { 191 *delim++ = '\0';
178 SDLcdrom = delim; 192 }
179 } else { 193 if (CheckDrive(SDLcdrom, &stbuf) > 0)
180 SDLcdrom = NULL; 194 {
181 } 195 AddDrive(SDLcdrom, &stbuf);
182 } while ( SDLcdrom ); 196 }
183 free(cdpath); 197 if (delim)
184 } 198 {
185 199 SDLcdrom = delim;
186 /* If we found our drives, there's nothing left to do */ 200 }
187 if ( SDL_numcds > 0 ) { 201 else
188 return(0); 202 {
189 } 203 SDLcdrom = NULL;
190 } 204 }
191 205 } while (SDLcdrom);
192 /* Scan the system for CD-ROM drives */ 206 free(cdpath);
193 for ( i=0; checklist[i]; ++i ) { 207 }
194 if ( checklist[i][0] == '?' ) { 208
195 char *insert; 209 /* If we found our drives, there's nothing left to do */
196 exists = 1; 210 if (SDL_numcds > 0)
197 for ( j=checklist[i][1]; exists; ++j ) { 211 {
198 sprintf(drive, "/dev/%s", &checklist[i][3]); 212 return(0);
199 insert = strchr(drive, '?'); 213 }
200 if ( insert != NULL ) { 214 }
201 *insert = j; 215
202 } 216 /* Scan the system for CD-ROM drives */
203 #ifdef DEBUG_CDROM 217 for ( i=0; checklist[i]; ++i )
204 fprintf(stderr, "Checking possible CD-ROM drive: %s\n", drive); 218 {
205 #endif 219 if (checklist[i][0] == '?')
206 switch (CheckDrive(drive, NULL, &stbuf)) { 220 {
207 /* Drive exists and is a CD-ROM */ 221 char* insert;
208 case 1: 222 exists = 1;
209 AddDrive(drive, &stbuf); 223
210 break; 224 for ( j=checklist[i][1]; exists; ++j )
211 /* Drive exists, but isn't a CD-ROM */ 225 {
212 case 0: 226 sprintf(drive, "/dev/%s", &checklist[i][3]);
213 break; 227 insert = strchr(drive, '?');
214 /* Drive doesn't exist */ 228 if (insert != NULL)
215 case -1: 229 {
216 exists = 0; 230 *insert = j;
217 break; 231 }
218 } 232 switch (CheckDrive(drive, &stbuf))
219 } 233 {
220 } else { 234 /* Drive exists and is a CD-ROM */
221 sprintf(drive, "/dev/%s", checklist[i]); 235 case 1:
222 #ifdef DEBUG_CDROM 236 AddDrive(drive, &stbuf);
223 fprintf(stderr, "Checking possible CD-ROM drive: %s\n", drive); 237 break;
224 #endif 238 /* Drive exists, but isn't a CD-ROM */
225 if ( CheckDrive(drive, NULL, &stbuf) > 0 ) { 239 case 0:
226 AddDrive(drive, &stbuf); 240 break;
227 } 241 /* Drive doesn't exist */
228 } 242 case -1:
229 } 243 exists = 0;
230 return(0); 244 break;
245 }
246 }
247 }
248 else
249 {
250 sprintf(drive, "/dev/%s", checklist[i]);
251 if (CheckDrive(drive, &stbuf) > 0)
252 {
253 AddDrive(drive, &stbuf);
254 }
255 }
256 }
257 return(0);
231 } 258 }
232 259
233 static const char *SDL_SYS_CDName(int drive) 260 static const char *SDL_SYS_CDName(int drive)
234 { 261 {
235 return(SDL_cdlist[drive]); 262 return(SDL_cdlist[drive]);
236 } 263 }
237 264
238 static int SDL_SYS_CDOpen(int drive) 265 static int SDL_SYS_CDOpen(int drive)
239 { 266 {
240 return(open(SDL_cdlist[drive], (O_RDONLY|O_EXCL|O_NONBLOCK), 0)); 267 int handle;
268
269 handle=open(SDL_cdlist[drive], QNX_CD_OPENMODE);
270
271 if (handle>0)
272 {
273 SDL_cdopen[drive]=handle;
274 }
275
276 return (handle);
241 } 277 }
242 278
243 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom) 279 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom)
244 { 280 {
245 cdrom_read_toc_t toc; 281 cdrom_read_toc_t toc;
246 int i, okay; 282 int i, okay;
247 283
248 okay = 0; 284 okay = 0;
249 if (devctl(cdrom->id, DCMD_CAM_CDROMREADTOC, &toc, sizeof(toc), 0) == 0) { 285 if (devctl(cdrom->id, DCMD_CAM_CDROMREADTOC, &toc, sizeof(toc), NULL) == 0)
250 cdrom->numtracks = toc.last_track - toc.first_track + 1; 286 {
251 if ( cdrom->numtracks > SDL_MAX_TRACKS ) { 287 cdrom->numtracks = toc.last_track - toc.first_track + 1;
252 cdrom->numtracks = SDL_MAX_TRACKS; 288 if (cdrom->numtracks > SDL_MAX_TRACKS)
253 } 289 {
254 /* Read all the track TOC entries */ 290 cdrom->numtracks = SDL_MAX_TRACKS;
255 for ( i=0; i<=cdrom->numtracks; ++i ) { 291 }
256 if ( i == cdrom->numtracks ) { 292 /* Read all the track TOC entries */
257 cdrom->track[i].id = CDROM_LEADOUT; 293 for (i=0; i<=cdrom->numtracks; ++i)
258 } else { 294 {
259 #if 0 /* Sam 11/6/00 - an obsolete field? */ 295 if (i == cdrom->numtracks)
260 cdrom->track[i].id = toc.cdth_trk0+i; 296 {
261 #else 297 cdrom->track[i].id = CDROM_LEADOUT;
262 cdrom->track[i].id = toc.first_track+i; 298 }
263 #endif 299 else
264 } 300 {
265 cdrom->track[i].type = toc.toc_entry[i].control_adr; 301 cdrom->track[i].id = toc.first_track+i;
266 cdrom->track[i].offset = MSF_TO_FRAMES( 302 }
267 toc.toc_entry[i].addr.msf.minute, 303
268 toc.toc_entry[i].addr.msf.second, 304 cdrom->track[i].type = toc.toc_entry[i].control_adr & 0x0F;
269 toc.toc_entry[i].addr.msf.frame); 305 cdrom->track[i].offset = toc.toc_entry[i].addr.lba;
270 cdrom->track[i].length = 0; 306 cdrom->track[i].length = 0;
271 if ( i > 0 ) { 307
272 cdrom->track[i-1].length = 308 if (i > 0)
273 cdrom->track[i].offset- 309 {
274 cdrom->track[i-1].offset; 310 cdrom->track[i-1].length = cdrom->track[i].offset-cdrom->track[i-1].offset;
275 } 311 }
276 } 312 }
277 if ( i == (cdrom->numtracks+1) ) { 313 if (i == (cdrom->numtracks+1))
278 okay = 1; 314 {
279 } 315 okay = 1;
280 } 316 }
281 return(okay ? 0 : -1); 317 }
318 return (okay ? 0 : -1);
282 } 319 }
283 320
284 /* Get CD-ROM status */ 321 /* Get CD-ROM status */
285 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position) 322 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position)
286 { 323 {
287 CDstatus status; 324 CDstatus status;
288 cdrom_read_toc_t toc; 325
289 subch_current_position_t info; 326 cdrom_read_toc_t toc;
290 327 cdrom_subch_data_t info;
291 #if 0 /* Sam 11/6/00 - an obsolete field? */ 328 cam_devinfo_t dinfo;
292 info.subch_command.data_format = CDROM_SUBCH_CURRENT_POSITION; 329
293 info.subch_command.track_number = 0; 330 int devctlret=0;
294 #else 331 int drive=-1;
295 info.data_format = CDROM_SUBCH_CURRENT_POSITION; 332 int i;
296 info.track_number = 0; 333 int eagaincnt=0;
297 #endif 334
298 if (devctl(cdrom->id, DCMD_CAM_CDROMSUBCHNL, &info, sizeof(info), 0) != 0) { 335 /* check media presence before read subchannel call, some cdroms can lockups */
299 if ( ERRNO_TRAYEMPTY(errno) ) { 336 /* if no media, while calling read subchannel functions. */
300 status = CD_TRAYEMPTY; 337 devctlret=devctl(cdrom->id, DCMD_CAM_DEVINFO, &dinfo, sizeof(cam_devinfo_t), NULL);
301 } else { 338
302 status = CD_ERROR; 339 if (devctlret==EOK)
303 } 340 {
304 } else { 341 if ((dinfo.flags & DEV_NO_MEDIA)!=0)
305 switch (info.header.audio_status) { 342 {
306 case CDROM_AUDIO_INVALID: 343 status = CD_TRAYEMPTY;
307 case CDROM_AUDIO_NO_STATUS: 344 if (position)
308 /* Try to determine if there's a CD available */ 345 {
309 if (devctl(cdrom->id, DCMD_CAM_CDROMREADTOC, &toc, sizeof(toc), 0)==0) 346 *position = 0;
310 status = CD_STOPPED; 347 }
311 else 348 return (status);
312 status = CD_TRAYEMPTY; 349 }
313 break; 350 }
314 case CDROM_AUDIO_COMPLETED: 351
315 status = CD_STOPPED; 352 /* if media exists, then do other stuff */
316 break; 353
317 case CDROM_AUDIO_PLAY: 354 memset(&info, 0x00, sizeof(info));
318 status = CD_PLAYING; 355 info.subch_command.data_format = CDROM_SUBCH_CURRENT_POSITION;
319 break; 356
320 case CDROM_AUDIO_PAUSED: 357 do {
321 /* Workaround buggy CD-ROM drive */ 358 devctlret=devctl(cdrom->id, DCMD_CAM_CDROMSUBCHNL, &info, sizeof(info), NULL);
322 if ( info.data_format == CDROM_LEADOUT ) { 359 if (devctlret==EIO)
323 status = CD_STOPPED; 360 {
324 } else { 361 /* big workaround for media change, handle is unusable after that,
325 status = CD_PAUSED; 362 that bug was found in QNX 6.2, 6.2.1 is not released yet. */
326 } 363
327 break; 364 for (i=0; i<MAX_DRIVES; i++)
328 default: 365 {
329 status = CD_ERROR; 366 if (SDL_cdopen[i]==cdrom->id)
330 break; 367 {
331 } 368 drive=i;
332 } 369 break;
333 if ( position ) { 370 }
334 if ( status == CD_PLAYING || (status == CD_PAUSED) ) { 371 }
335 *position = MSF_TO_FRAMES( 372 if (drive==-1)
336 info.addr.msf.minute, 373 {
337 info.addr.msf.second, 374 /* that cannot happen, but ... */
338 info.addr.msf.frame); 375 break;
339 } else { 376 }
340 *position = 0; 377 close(cdrom->id);
341 } 378 cdrom->id=open(SDL_cdlist[drive], QNX_CD_OPENMODE);
342 } 379 devctlret=EAGAIN;
343 return(status); 380 }
381 if (devctlret==EAGAIN)
382 {
383 eagaincnt++;
384 }
385 if (eagaincnt==2)
386 {
387 /* workaround for broken cdroms, which can return always EAGAIN when its not ready, */
388 /* that mean errornous media or just no media avail */
389 devctlret=ENXIO;
390 break;
391 }
392 } while ((devctlret==EAGAIN)||(devctlret==ESTALE));
393
394 if (devctlret != 0)
395 {
396 if (devctlret==ENXIO)
397 {
398 status = CD_TRAYEMPTY;
399 }
400 else
401 {
402 status = CD_ERROR;
403 }
404 }
405 else
406 {
407 switch (info.current_position.header.audio_status)
408 {
409 case CDROM_AUDIO_INVALID:
410 case CDROM_AUDIO_NO_STATUS:
411 /* Try to determine if there's a CD available */
412 if (devctl(cdrom->id, DCMD_CAM_CDROMREADTOC, &toc, sizeof(toc), NULL)==0)
413 status = CD_STOPPED;
414 else
415 status = CD_TRAYEMPTY;
416 break;
417 case CDROM_AUDIO_COMPLETED:
418 status = CD_STOPPED;
419 break;
420 case CDROM_AUDIO_PLAY:
421 status = CD_PLAYING;
422 break;
423 case CDROM_AUDIO_PAUSED:
424 /* Workaround buggy CD-ROM drive */
425 if (info.current_position.data_format == CDROM_LEADOUT)
426 {
427 status = CD_STOPPED;
428 }
429 else
430 {
431 status = CD_PAUSED;
432 }
433 break;
434 default:
435 status = CD_ERROR;
436 break;
437 }
438 }
439
440 if (position)
441 {
442 if (status==CD_PLAYING || (status==CD_PAUSED))
443 {
444 *position = MSF_TO_FRAMES(info.current_position.addr.msf.minute,
445 info.current_position.addr.msf.second,
446 info.current_position.addr.msf.frame);
447 }
448 else
449 {
450 *position = 0;
451 }
452 }
453
454 return (status);
344 } 455 }
345 456
346 /* Start play */ 457 /* Start play */
347 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length) 458 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length)
348 { 459 {
349 cdrom_playmsf_t playtime; 460 cdrom_playmsf_t playtime;
350 461
351 FRAMES_TO_MSF(start, 462 FRAMES_TO_MSF(start, &playtime.start_minute, &playtime.start_second, &playtime.start_frame);
352 &playtime.start_minute, &playtime.start_second, &playtime.start_frame); 463 FRAMES_TO_MSF(start+length, &playtime.end_minute, &playtime.end_second, &playtime.end_frame);
353 FRAMES_TO_MSF(start+length, 464
354 &playtime.end_minute, &playtime.end_second, &playtime.end_frame); 465 if (devctl(cdrom->id, DCMD_CAM_CDROMPLAYMSF, &playtime, sizeof(playtime), NULL) != 0)
355 #ifdef DEBUG_CDROM 466 {
356 fprintf(stderr, "Trying to play from %d:%d:%d to %d:%d:%d\n", 467 return -1;
357 playtime.start_minute, playtime.start_second, playtime.start_frame, 468 }
358 playtime.end_minute, playtime.end_second, playtime.end_frame); 469 else
359 #endif 470 {
360 return(devctl(cdrom->id, DCMD_CAM_CDROMPLAYMSF, &playtime, sizeof(playtime), 0)); 471 return 0;
472 }
361 } 473 }
362 474
363 /* Pause play */ 475 /* Pause play */
364 static int SDL_SYS_CDPause(SDL_CD *cdrom) 476 static int SDL_SYS_CDPause(SDL_CD *cdrom)
365 { 477 {
366 return(devctl(cdrom->id, DCMD_CAM_CDROMPAUSE, NULL, 0, 0)); 478 if (devctl(cdrom->id, DCMD_CAM_CDROMPAUSE, NULL, 0, NULL)!=0)
479 {
480 return -1;
481 }
482 else
483 {
484 return 0;
485 }
367 } 486 }
368 487
369 /* Resume play */ 488 /* Resume play */
370 static int SDL_SYS_CDResume(SDL_CD *cdrom) 489 static int SDL_SYS_CDResume(SDL_CD *cdrom)
371 { 490 {
372 return(devctl(cdrom->id, DCMD_CAM_CDROMRESUME, NULL, 0, 0)); 491 if (devctl(cdrom->id, DCMD_CAM_CDROMRESUME, NULL, 0, NULL)!=0)
492 {
493 return -1;
494 }
495 else
496 {
497 return 0;
498 }
373 } 499 }
374 500
375 /* Stop play */ 501 /* Stop play */
376 static int SDL_SYS_CDStop(SDL_CD *cdrom) 502 static int SDL_SYS_CDStop(SDL_CD *cdrom)
377 { 503 {
378 return(devctl(cdrom->id, DCMD_CAM_CDROMSTOP, NULL, 0, 0)); 504 if (devctl(cdrom->id, DCMD_CAM_CDROMSTOP, NULL, 0, NULL)!=0)
505 {
506 return -1;
507 }
508 else
509 {
510 return 0;
511 }
379 } 512 }
380 513
381 /* Eject the CD-ROM */ 514 /* Eject the CD-ROM */
382 static int SDL_SYS_CDEject(SDL_CD *cdrom) 515 static int SDL_SYS_CDEject(SDL_CD *cdrom)
383 { 516 {
384 return(devctl(cdrom->id, DCMD_CAM_EJECT_MEDIA, NULL, 0, 0)); 517 if (devctl(cdrom->id, DCMD_CAM_EJECT_MEDIA, NULL, 0, NULL)!=0)
518 {
519 return -1;
520 }
521 else
522 {
523 return 0;
524 }
385 } 525 }
386 526
387 /* Close the CD-ROM handle */ 527 /* Close the CD-ROM handle */
388 static void SDL_SYS_CDClose(SDL_CD *cdrom) 528 static void SDL_SYS_CDClose(SDL_CD *cdrom)
389 { 529 {
390 close(cdrom->id); 530 int i;
531
532 for (i=0; i<MAX_DRIVES; i++)
533 {
534 if (SDL_cdopen[i]==cdrom->id)
535 {
536 SDL_cdopen[i]=0;
537 break;
538 }
539 }
540
541 close(cdrom->id);
391 } 542 }
392 543
393 void SDL_SYS_CDQuit(void) 544 void SDL_SYS_CDQuit(void)
394 { 545 {
395 int i; 546 int i;
396 547
397 if ( SDL_numcds > 0 ) { 548 if (SDL_numcds > 0)
398 for ( i=0; i<SDL_numcds; ++i ) { 549 {
399 free(SDL_cdlist[i]); 550 for (i=0; i<SDL_numcds; ++i)
400 } 551 {
401 SDL_numcds = 0; 552 free(SDL_cdlist[i]);
402 } 553 }
403 } 554 SDL_numcds = 0;
404 555 }
556 }