src/cdrom/SDL_cdrom.c

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. SDL_CDROMInit
  2. CheckInit
  3. SDL_CDNumDrives
  4. SDL_CDName
  5. SDL_CDOpen
  6. SDL_CDStatus
  7. SDL_CDPlayTracks
  8. SDL_CDPlay
  9. SDL_CDPause
  10. SDL_CDResume
  11. SDL_CDStop
  12. SDL_CDEject
  13. SDL_CDClose
  14. SDL_CDROMQuit

   1 /*
   2     SDL - Simple DirectMedia Layer
   3     Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
   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
  20     slouken@devolution.com
  21 */
  22 
  23 #ifdef SAVE_RCSID
  24 static char rcsid =
  25  "@(#) $Id: SDL_cdrom.c,v 1.3.2.4 2001/02/10 07:20:03 hercules Exp $";
  26 #endif
  27 
  28 /* This is the CD-audio control API for Simple DirectMedia Layer */
  29 
  30 #include <stdio.h>
  31 #include <stdlib.h>
  32 #include <string.h>
  33 
  34 #include "SDL_error.h"
  35 #include "SDL_cdrom.h"
  36 #include "SDL_syscdrom.h"
  37 
  38 #if !defined(macintosh)
  39 #define CLIP_FRAMES     10      /* Some CD-ROMs won't go all the way */
  40 #endif
  41 
  42 static int SDL_cdinitted = 0;
  43 static SDL_CD *default_cdrom;
  44 
  45 /* The system level CD-ROM control functions */
  46 struct CDcaps SDL_CDcaps = {
  47         NULL,                                   /* Name */
  48         NULL,                                   /* Open */
  49         NULL,                                   /* GetTOC */
  50         NULL,                                   /* Status */
  51         NULL,                                   /* Play */
  52         NULL,                                   /* Pause */
  53         NULL,                                   /* Resume */
  54         NULL,                                   /* Stop */
  55         NULL,                                   /* Eject */
  56         NULL,                                   /* Close */
  57 };
  58 int SDL_numcds;
  59 
  60 int SDL_CDROMInit(void)
     /* [<][>][^][v][top][bottom][index][help] */
  61 {
  62         int retval;
  63 
  64         SDL_numcds = 0;
  65         retval = SDL_SYS_CDInit();
  66         if ( retval == 0 ) {
  67                 SDL_cdinitted = 1;
  68         }
  69         default_cdrom = NULL;
  70         return(retval);
  71 }
  72 
  73 /* Check to see if the CD-ROM subsystem has been initialized */
  74 static int CheckInit(int check_cdrom, SDL_CD **cdrom)
     /* [<][>][^][v][top][bottom][index][help] */
  75 {
  76         int okay;
  77 
  78         okay = SDL_cdinitted;
  79         if ( check_cdrom && (*cdrom == NULL) ) {
  80                 *cdrom = default_cdrom;
  81                 if ( *cdrom == NULL ) {
  82                         SDL_SetError("CD-ROM not opened");
  83                         okay = 0;
  84                 }
  85         }
  86         if ( ! SDL_cdinitted ) {
  87                 SDL_SetError("CD-ROM subsystem not initialized");
  88         }
  89         return(okay);
  90 }
  91 
  92 int SDL_CDNumDrives(void)
     /* [<][>][^][v][top][bottom][index][help] */
  93 {
  94         if ( ! CheckInit(0, NULL) ) {
  95                 return(-1);
  96         }
  97         return(SDL_numcds);
  98 }
  99 
 100 const char *SDL_CDName(int drive)
     /* [<][>][^][v][top][bottom][index][help] */
 101 {
 102         if ( ! CheckInit(0, NULL) ) {
 103                 return(NULL);
 104         }
 105         if ( drive >= SDL_numcds ) {
 106                 SDL_SetError("Invalid CD-ROM drive index");
 107                 return(NULL);
 108         }
 109         if ( SDL_CDcaps.Name ) {
 110                 return(SDL_CDcaps.Name(drive));
 111         } else {
 112                 return("");
 113         }
 114 }
 115 
 116 SDL_CD *SDL_CDOpen(int drive)
     /* [<][>][^][v][top][bottom][index][help] */
 117 {
 118         struct SDL_CD *cdrom;
 119 
 120         if ( ! CheckInit(0, NULL) ) {
 121                 return(NULL);
 122         }
 123         if ( drive >= SDL_numcds ) {
 124                 SDL_SetError("Invalid CD-ROM drive index");
 125                 return(NULL);
 126         }
 127         cdrom = (SDL_CD *)malloc(sizeof(*cdrom));
 128         if ( cdrom == NULL ) {
 129                 SDL_OutOfMemory();
 130                 return(NULL);
 131         }
 132         memset(cdrom, 0, sizeof(*cdrom));
 133         cdrom->id = SDL_CDcaps.Open(drive);
 134         if ( cdrom->id < 0 ) {
 135                 free(cdrom);
 136                 return(NULL);
 137         }
 138         default_cdrom = cdrom;
 139         return(cdrom);
 140 }
 141 
 142 CDstatus SDL_CDStatus(SDL_CD *cdrom)
     /* [<][>][^][v][top][bottom][index][help] */
 143 {
 144         CDstatus status;
 145         int i;
 146         Uint32 position;
 147 
 148         /* Check if the CD-ROM subsystem has been initialized */
 149         if ( ! CheckInit(1, &cdrom) ) {
 150                 return(CD_ERROR);
 151         }
 152 
 153         /* Get the current status of the drive */
 154         cdrom->numtracks = 0;
 155         cdrom->cur_track = 0;
 156         cdrom->cur_frame = 0;
 157         status = SDL_CDcaps.Status(cdrom, &i);
 158         position = (Uint32)i;
 159         cdrom->status = status;
 160 
 161         /* Get the table of contents, if there's a CD available */
 162         if ( CD_INDRIVE(status) ) {
 163                 if ( SDL_CDcaps.GetTOC(cdrom) < 0 ) {
 164                         status = CD_ERROR;
 165                 }
 166                 /* If the drive is playing, get current play position */
 167                 if ( (status == CD_PLAYING) || (status == CD_PAUSED) ) {
 168                         for ( i=1; cdrom->track[i].offset <= position; ++i ) {
 169                                 /* Keep looking */;
 170                         }
 171 #ifdef DEBUG_CDROM
 172   fprintf(stderr, "Current position: %d, track = %d (offset is %d)\n",
 173                                 position, i-1, cdrom->track[i-1].offset);
 174 #endif
 175                         cdrom->cur_track = i-1;
 176                         position -= cdrom->track[cdrom->cur_track].offset;
 177                         cdrom->cur_frame = position;
 178                 }
 179         }
 180         return(status);
 181 }
 182 
 183 int SDL_CDPlayTracks(SDL_CD *cdrom,
     /* [<][>][^][v][top][bottom][index][help] */
 184                         int strack, int sframe, int ntracks, int nframes)
 185 {
 186         int etrack, eframe;
 187         int start, length;
 188 
 189         /* Check if the CD-ROM subsystem has been initialized */
 190         if ( ! CheckInit(1, &cdrom) ) {
 191                 return(CD_ERROR);
 192         }
 193 
 194         /* Determine the starting and ending tracks */
 195         if ( (strack < 0) || (strack >= cdrom->numtracks) ) {
 196                 SDL_SetError("Invalid starting track");
 197                 return(CD_ERROR);
 198         }
 199         if ( ! ntracks && ! nframes ) {
 200                 etrack = cdrom->numtracks;
 201                 eframe = 0;
 202         } else {
 203                 etrack = strack+ntracks;
 204                 if ( etrack == strack ) {
 205                         eframe = sframe + nframes;
 206                 } else {
 207                         eframe = nframes;
 208                 }
 209         }
 210         if ( etrack > cdrom->numtracks ) {
 211                 SDL_SetError("Invalid play length");
 212                 return(CD_ERROR);
 213         }
 214 
 215         /* Skip data tracks and verify frame offsets */
 216         while ( (strack <= etrack) &&
 217                         (cdrom->track[strack].type == SDL_DATA_TRACK) ) {
 218                 ++strack;
 219         }
 220         if ( sframe >= (int)cdrom->track[strack].length ) {
 221                 SDL_SetError("Invalid starting frame for track %d", strack);
 222                 return(CD_ERROR);
 223         }
 224         while ( (etrack > strack) &&
 225                         (cdrom->track[etrack-1].type == SDL_DATA_TRACK) ) {
 226                 --etrack;
 227         }
 228         if ( eframe > (int)cdrom->track[etrack].length ) {
 229                 SDL_SetError("Invalid ending frame for track %d", etrack);
 230                 return(CD_ERROR);
 231         }
 232 
 233         /* Determine start frame and play length */
 234         start = (cdrom->track[strack].offset+sframe);
 235         length = (cdrom->track[etrack].offset+eframe)-start;
 236 #ifdef CLIP_FRAMES
 237         /* I've never seen this necessary, but xmcd does it.. */
 238         length -= CLIP_FRAMES;  /* CLIP_FRAMES == 10 */
 239 #endif
 240         if ( length < 0 ) {
 241                 return(0);
 242         }
 243 
 244         /* Play! */
 245 #ifdef DEBUG_CDROM
 246   fprintf(stderr, "Playing %d frames at offset %d\n", length, start);
 247 #endif
 248         return(SDL_CDcaps.Play(cdrom, start, length));
 249 }
 250 
 251 int SDL_CDPlay(SDL_CD *cdrom, int sframe, int length)
     /* [<][>][^][v][top][bottom][index][help] */
 252 {
 253         /* Check if the CD-ROM subsystem has been initialized */
 254         if ( ! CheckInit(1, &cdrom) ) {
 255                 return(CD_ERROR);
 256         }
 257 
 258         return(SDL_CDcaps.Play(cdrom, sframe, length));
 259 }
 260 
 261 int SDL_CDPause(SDL_CD *cdrom)
     /* [<][>][^][v][top][bottom][index][help] */
 262 {
 263         CDstatus status;
 264         int retval;
 265 
 266         /* Check if the CD-ROM subsystem has been initialized */
 267         if ( ! CheckInit(1, &cdrom) ) {
 268                 return(CD_ERROR);
 269         }
 270 
 271         status = SDL_CDcaps.Status(cdrom, NULL);
 272         switch (status) {
 273                 case CD_PLAYING:
 274                         retval = SDL_CDcaps.Pause(cdrom);
 275                         break;
 276                 default:
 277                         retval = 0;
 278                         break;
 279         }
 280         return(retval);
 281 }
 282 
 283 int SDL_CDResume(SDL_CD *cdrom)
     /* [<][>][^][v][top][bottom][index][help] */
 284 {
 285         CDstatus status;
 286         int retval;
 287 
 288         /* Check if the CD-ROM subsystem has been initialized */
 289         if ( ! CheckInit(1, &cdrom) ) {
 290                 return(CD_ERROR);
 291         }
 292 
 293         status = SDL_CDcaps.Status(cdrom, NULL);
 294         switch (status) {
 295                 case CD_PAUSED:
 296                         retval = SDL_CDcaps.Resume(cdrom);
 297                 default:
 298                         retval = 0;
 299                         break;
 300         }
 301         return(retval);
 302 }
 303 
 304 int SDL_CDStop(SDL_CD *cdrom)
     /* [<][>][^][v][top][bottom][index][help] */
 305 {
 306         CDstatus status;
 307         int retval;
 308 
 309         /* Check if the CD-ROM subsystem has been initialized */
 310         if ( ! CheckInit(1, &cdrom) ) {
 311                 return(CD_ERROR);
 312         }
 313 
 314         status = SDL_CDcaps.Status(cdrom, NULL);
 315         switch (status) {
 316                 case CD_PLAYING:
 317                 case CD_PAUSED:
 318                         retval = SDL_CDcaps.Stop(cdrom);
 319                 default:
 320                         retval = 0;
 321                         break;
 322         }
 323         return(retval);
 324 }
 325 
 326 int SDL_CDEject(SDL_CD *cdrom)
     /* [<][>][^][v][top][bottom][index][help] */
 327 {
 328         /* Check if the CD-ROM subsystem has been initialized */
 329         if ( ! CheckInit(1, &cdrom) ) {
 330                 return(CD_ERROR);
 331         }
 332         return(SDL_CDcaps.Eject(cdrom));
 333 }
 334 
 335 void SDL_CDClose(SDL_CD *cdrom)
     /* [<][>][^][v][top][bottom][index][help] */
 336 {
 337         /* Check if the CD-ROM subsystem has been initialized */
 338         if ( ! CheckInit(1, &cdrom) ) {
 339                 return;
 340         }
 341         SDL_CDcaps.Close(cdrom);
 342         free(cdrom);
 343         default_cdrom = NULL;
 344 }
 345 
 346 void SDL_CDROMQuit(void)
     /* [<][>][^][v][top][bottom][index][help] */
 347 {
 348         SDL_SYS_CDQuit();
 349         SDL_cdinitted = 0;
 350 }

/* [<][>][^][v][top][bottom][index][help] */