symbian-qemu-0.9.1-12/libsdl-trunk/src/cdrom/mint/SDL_syscdrom.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /*
       
     2     SDL - Simple DirectMedia Layer
       
     3     Copyright (C) 1997-2004 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@libsdl.org
       
    21 */
       
    22 #include "SDL_config.h"
       
    23 
       
    24 #ifdef SDL_CDROM_MINT
       
    25 
       
    26 /*
       
    27 	Atari MetaDOS CD-ROM functions
       
    28 
       
    29 	Patrice Mandin
       
    30 */
       
    31 
       
    32 #include <errno.h>
       
    33 
       
    34 #include <cdromio.h>
       
    35 #include <metados.h>
       
    36 
       
    37 #include "SDL_cdrom.h"
       
    38 #include "../SDL_syscdrom.h"
       
    39 
       
    40 /* Some ioctl() errno values which occur when the tray is empty */
       
    41 #ifndef ENOMEDIUM
       
    42 #define ENOMEDIUM ENOENT
       
    43 #endif
       
    44 #define ERRNO_TRAYEMPTY(errno)	\
       
    45 	((errno == EIO)    || (errno == ENOENT) || \
       
    46 	 (errno == EINVAL) || (errno == ENOMEDIUM))
       
    47 
       
    48 /* The maximum number of CD-ROM drives we'll detect */
       
    49 #define MAX_DRIVES	32	
       
    50 
       
    51 typedef struct {
       
    52 	unsigned char device[3];	/* Physical device letter + ':' + '\0' */
       
    53 	metaopen_t	metaopen;		/* Infos on opened drive */
       
    54 } metados_drive_t;
       
    55 
       
    56 static metados_drive_t metados_drives[MAX_DRIVES];
       
    57 
       
    58 /* The system-dependent CD control functions */
       
    59 static const char *SDL_SYS_CDName(int drive);
       
    60 static int SDL_SYS_CDOpen(int drive);
       
    61 static void SDL_SYS_CDClose(SDL_CD *cdrom);
       
    62 static int SDL_SYS_CDioctl(int id, int command, void *arg);
       
    63 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom);
       
    64 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position);
       
    65 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length);
       
    66 static int SDL_SYS_CDPause(SDL_CD *cdrom);
       
    67 static int SDL_SYS_CDResume(SDL_CD *cdrom);
       
    68 static int SDL_SYS_CDStop(SDL_CD *cdrom);
       
    69 static int SDL_SYS_CDEject(SDL_CD *cdrom);
       
    70 
       
    71 int SDL_SYS_CDInit(void)
       
    72 {
       
    73 	metainit_t	metainit={0,0,0,0};
       
    74 	metaopen_t	metaopen;
       
    75 	int i, handle;
       
    76 	struct cdrom_subchnl info;
       
    77 
       
    78 	Metainit(&metainit);
       
    79 	if (metainit.version == NULL) {
       
    80 #ifdef DEBUG_CDROM
       
    81 		fprintf(stderr, "MetaDOS not installed\n");
       
    82 #endif
       
    83 		return -1;
       
    84 	}
       
    85 
       
    86 	if (metainit.drives_map == 0) {
       
    87 #ifdef DEBUG_CDROM
       
    88 		fprintf(stderr, "No MetaDOS devices present\n");
       
    89 #endif
       
    90 		return -1;
       
    91 	}
       
    92 
       
    93 	SDL_numcds = 0;
       
    94 	
       
    95 	for (i='A'; i<='Z'; i++) {
       
    96 		metados_drives[SDL_numcds].device[0] = 0;
       
    97 		metados_drives[SDL_numcds].device[1] = ':';
       
    98 		metados_drives[SDL_numcds].device[2] = 0;
       
    99 
       
   100 		if (metainit.drives_map & (1<<(i-'A'))) {
       
   101 			handle = Metaopen(i, &metaopen);
       
   102 			if (handle == 0) {
       
   103 
       
   104 				info.cdsc_format = CDROM_MSF;
       
   105 				if ( (Metaioctl(i, METADOS_IOCTL_MAGIC, CDROMSUBCHNL, &info) == 0) || ERRNO_TRAYEMPTY(errno) ) {
       
   106 					metados_drives[SDL_numcds].device[0] = i;
       
   107 					++SDL_numcds;
       
   108 				}
       
   109 
       
   110 				Metaclose(i);
       
   111 			}
       
   112 		}
       
   113 	}
       
   114 
       
   115 	/* Fill in our driver capabilities */
       
   116 	SDL_CDcaps.Name = SDL_SYS_CDName;
       
   117 	SDL_CDcaps.Open = SDL_SYS_CDOpen;
       
   118 	SDL_CDcaps.Close = SDL_SYS_CDClose;
       
   119 
       
   120 	SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC;
       
   121 	SDL_CDcaps.Status = SDL_SYS_CDStatus;
       
   122 	SDL_CDcaps.Play = SDL_SYS_CDPlay;
       
   123 	SDL_CDcaps.Pause = SDL_SYS_CDPause;
       
   124 	SDL_CDcaps.Resume = SDL_SYS_CDResume;
       
   125 	SDL_CDcaps.Stop = SDL_SYS_CDStop;
       
   126 	SDL_CDcaps.Eject = SDL_SYS_CDEject;
       
   127 
       
   128 	return 0;
       
   129 }
       
   130 
       
   131 void SDL_SYS_CDQuit(void)
       
   132 {
       
   133 	SDL_numcds = 0;
       
   134 }
       
   135 
       
   136 static const char *SDL_SYS_CDName(int drive)
       
   137 {
       
   138 	return(metados_drives[drive].device);
       
   139 }
       
   140 
       
   141 static int SDL_SYS_CDOpen(int drive)
       
   142 {
       
   143 	int handle;
       
   144 
       
   145 	handle = Metaopen(metados_drives[drive].device[0], &(metados_drives[drive].metaopen));
       
   146 	if (handle == 0) {
       
   147 		return drive;
       
   148 	}
       
   149 
       
   150 	return -1;
       
   151 }
       
   152 
       
   153 static void SDL_SYS_CDClose(SDL_CD *cdrom)
       
   154 {
       
   155 	Metaclose(metados_drives[cdrom->id].device[0]);
       
   156 }
       
   157 
       
   158 static int SDL_SYS_CDioctl(int id, int command, void *arg)
       
   159 {
       
   160 	int retval;
       
   161 
       
   162 	retval = Metaioctl(metados_drives[id].device[0], METADOS_IOCTL_MAGIC, command, arg);
       
   163 	if ( retval < 0 ) {
       
   164 		SDL_SetError("ioctl() error: %s", strerror(errno));
       
   165 	}
       
   166 	return(retval);
       
   167 }
       
   168 
       
   169 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom)
       
   170 {
       
   171 	int i,okay;
       
   172 	struct cdrom_tochdr toc;
       
   173 	struct cdrom_tocentry entry;
       
   174 
       
   175 	/* Use standard ioctl() */	
       
   176 	if (SDL_SYS_CDioctl(cdrom->id, CDROMREADTOCHDR, &toc)<0) {
       
   177 		return -1;
       
   178 	}
       
   179 
       
   180 	cdrom->numtracks = toc.cdth_trk1-toc.cdth_trk0+1;
       
   181 	if ( cdrom->numtracks > SDL_MAX_TRACKS ) {
       
   182 		cdrom->numtracks = SDL_MAX_TRACKS;
       
   183 	}
       
   184 
       
   185 	/* Read all the track TOC entries */
       
   186 	okay=1;
       
   187 	for ( i=0; i<=cdrom->numtracks; ++i ) {
       
   188 		if ( i == cdrom->numtracks ) {
       
   189 			cdrom->track[i].id = CDROM_LEADOUT;
       
   190 		} else {
       
   191 			cdrom->track[i].id = toc.cdth_trk0+i;
       
   192 		}
       
   193 		entry.cdte_track = cdrom->track[i].id;
       
   194 		entry.cdte_format = CDROM_MSF;
       
   195 		if ( SDL_SYS_CDioctl(cdrom->id, CDROMREADTOCENTRY, &entry) < 0 ) {
       
   196 			okay=0;
       
   197 			break;
       
   198 		} else {
       
   199 			if ( entry.cdte_ctrl & CDROM_DATA_TRACK ) {
       
   200 				cdrom->track[i].type = SDL_DATA_TRACK;
       
   201 			} else {
       
   202 				cdrom->track[i].type = SDL_AUDIO_TRACK;
       
   203 			}
       
   204 			cdrom->track[i].offset = MSF_TO_FRAMES(
       
   205 				entry.cdte_addr.msf.minute,
       
   206 				entry.cdte_addr.msf.second,
       
   207 				entry.cdte_addr.msf.frame);
       
   208 				cdrom->track[i].length = 0;
       
   209 			if ( i > 0 ) {
       
   210 				cdrom->track[i-1].length = cdrom->track[i].offset-cdrom->track[i-1].offset;
       
   211 			}
       
   212 		}
       
   213 	}
       
   214 
       
   215 	return(okay ? 0 : -1);
       
   216 }
       
   217 
       
   218 /* Get CD-ROM status */
       
   219 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position)
       
   220 {
       
   221 	CDstatus status;
       
   222 	struct cdrom_tochdr toc;
       
   223 	struct cdrom_subchnl info;
       
   224 
       
   225 	info.cdsc_format = CDROM_MSF;
       
   226 	if ( SDL_SYS_CDioctl(cdrom->id, CDROMSUBCHNL, &info) < 0 ) {
       
   227 		if ( ERRNO_TRAYEMPTY(errno) ) {
       
   228 			status = CD_TRAYEMPTY;
       
   229 		} else {
       
   230 			status = CD_ERROR;
       
   231 		}
       
   232 	} else {
       
   233 		switch (info.cdsc_audiostatus) {
       
   234 			case CDROM_AUDIO_INVALID:
       
   235 			case CDROM_AUDIO_NO_STATUS:
       
   236 				/* Try to determine if there's a CD available */
       
   237 				if (SDL_SYS_CDioctl(cdrom->id, CDROMREADTOCHDR, &toc)==0) {
       
   238 					status = CD_STOPPED;
       
   239 				} else {
       
   240 					status = CD_TRAYEMPTY;
       
   241 				}
       
   242 				break;
       
   243 			case CDROM_AUDIO_COMPLETED:
       
   244 				status = CD_STOPPED;
       
   245 				break;
       
   246 			case CDROM_AUDIO_PLAY:
       
   247 				status = CD_PLAYING;
       
   248 				break;
       
   249 			case CDROM_AUDIO_PAUSED:
       
   250 				/* Workaround buggy CD-ROM drive */
       
   251 				if ( info.cdsc_trk == CDROM_LEADOUT ) {
       
   252 					status = CD_STOPPED;
       
   253 				} else {
       
   254 					status = CD_PAUSED;
       
   255 				}
       
   256 				break;
       
   257 			default:
       
   258 				status = CD_ERROR;
       
   259 				break;
       
   260 		}
       
   261 	}
       
   262 	if ( position ) {
       
   263 		if ( status == CD_PLAYING || (status == CD_PAUSED) ) {
       
   264 			*position = MSF_TO_FRAMES(
       
   265 					info.cdsc_absaddr.msf.minute,
       
   266 					info.cdsc_absaddr.msf.second,
       
   267 					info.cdsc_absaddr.msf.frame);
       
   268 		} else {
       
   269 			*position = 0;
       
   270 		}
       
   271 	}
       
   272 	return(status);
       
   273 }
       
   274 
       
   275 /* Start play */
       
   276 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length)
       
   277 {
       
   278 	struct cdrom_msf playtime;
       
   279 
       
   280 	FRAMES_TO_MSF(start,
       
   281 	   &playtime.cdmsf_min0, &playtime.cdmsf_sec0, &playtime.cdmsf_frame0);
       
   282 	FRAMES_TO_MSF(start+length,
       
   283 	   &playtime.cdmsf_min1, &playtime.cdmsf_sec1, &playtime.cdmsf_frame1);
       
   284 #ifdef DEBUG_CDROM
       
   285   fprintf(stderr, "Trying to play from %d:%d:%d to %d:%d:%d\n",
       
   286 	playtime.cdmsf_min0, playtime.cdmsf_sec0, playtime.cdmsf_frame0,
       
   287 	playtime.cdmsf_min1, playtime.cdmsf_sec1, playtime.cdmsf_frame1);
       
   288 #endif
       
   289 
       
   290 	return SDL_SYS_CDioctl(cdrom->id, CDROMPLAYMSF, &playtime);
       
   291 }
       
   292 
       
   293 /* Pause play */
       
   294 static int SDL_SYS_CDPause(SDL_CD *cdrom)
       
   295 {
       
   296 	return SDL_SYS_CDioctl(cdrom->id, CDROMPAUSE, 0);
       
   297 }
       
   298 
       
   299 /* Resume play */
       
   300 static int SDL_SYS_CDResume(SDL_CD *cdrom)
       
   301 {
       
   302 	return SDL_SYS_CDioctl(cdrom->id, CDROMRESUME, 0);
       
   303 }
       
   304 
       
   305 /* Stop play */
       
   306 static int SDL_SYS_CDStop(SDL_CD *cdrom)
       
   307 {
       
   308 	return SDL_SYS_CDioctl(cdrom->id, CDROMSTOP, 0);
       
   309 }
       
   310 
       
   311 /* Eject the CD-ROM */
       
   312 static int SDL_SYS_CDEject(SDL_CD *cdrom)
       
   313 {
       
   314 	return SDL_SYS_CDioctl(cdrom->id, CDROMEJECT, 0);
       
   315 }
       
   316 
       
   317 #endif /* SDL_CDROM_MINT */