symbian-qemu-0.9.1-12/libsdl-trunk/src/cdrom/os2/SDL_syscdrom.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /*
       
     2     SDL - Simple DirectMedia Layer
       
     3     Copyright (C) 1997-2006 Sam Lantinga
       
     4 
       
     5     This library is free software; you can redistribute it and/or
       
     6     modify it under the terms of the GNU Lesser General Public
       
     7     License as published by the Free Software Foundation; either
       
     8     version 2.1 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     Lesser General Public License for more details.
       
    14 
       
    15     You should have received a copy of the GNU Lesser General Public
       
    16     License along with this library; if not, write to the Free Software
       
    17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
       
    18 
       
    19     Sam Lantinga
       
    20     slouken@libsdl.org
       
    21 */
       
    22 #include "SDL_config.h"
       
    23 
       
    24 #ifdef SDL_CDROM_OS2
       
    25 
       
    26 /* Functions for system-level CD-ROM audio control */
       
    27 
       
    28 #define INCL_MCIOS2
       
    29 #include <os2.h>
       
    30 #include <os2me.h>
       
    31 
       
    32 #include "SDL_cdrom.h"
       
    33 #include "../SDL_syscdrom.h"
       
    34 
       
    35 /* Size of MCI result buffer (in bytes) */
       
    36 #define MCI_CMDRETBUFSIZE	128
       
    37 
       
    38 /* The maximum number of CD-ROM drives we'll detect */
       
    39 #define MAX_DRIVES	16	
       
    40 
       
    41 /* A list of available CD-ROM drives */
       
    42 static char *SDL_cdlist[MAX_DRIVES];
       
    43 //static dev_t SDL_cdmode[MAX_DRIVES];
       
    44 
       
    45 /* The system-dependent CD control functions */
       
    46 static const char *SDL_SYS_CDName(int drive);
       
    47 static int SDL_SYS_CDOpen(int drive);
       
    48 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom);
       
    49 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position);
       
    50 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length);
       
    51 static int SDL_SYS_CDPause(SDL_CD *cdrom);
       
    52 static int SDL_SYS_CDResume(SDL_CD *cdrom);
       
    53 static int SDL_SYS_CDStop(SDL_CD *cdrom);
       
    54 static int SDL_SYS_CDEject(SDL_CD *cdrom);
       
    55 static void SDL_SYS_CDClose(SDL_CD *cdrom);
       
    56 
       
    57 /* MCI Timing Functions */
       
    58 #define	MCI_MMTIMEPERSECOND		3000
       
    59 #define	FRAMESFROMMM(mmtime)		(((mmtime)*CD_FPS)/MCI_MMTIMEPERSECOND)
       
    60 
       
    61 
       
    62 /* Ready for MCI CDAudio Devices */
       
    63 int  SDL_SYS_CDInit(void)
       
    64 {
       
    65 int i; /* generig counter */
       
    66 MCI_SYSINFO_PARMS		msp;	/* Structure to MCI SysInfo parameters */
       
    67 CHAR 						SysInfoRet[MCI_CMDRETBUFSIZE];	/* Buffer for MCI Command result */
       
    68 
       
    69 /* Fill in our driver capabilities */
       
    70 SDL_CDcaps.Name = SDL_SYS_CDName;
       
    71 SDL_CDcaps.Open = SDL_SYS_CDOpen;
       
    72 SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC;
       
    73 SDL_CDcaps.Status = SDL_SYS_CDStatus;
       
    74 SDL_CDcaps.Play = SDL_SYS_CDPlay;
       
    75 SDL_CDcaps.Pause = SDL_SYS_CDPause;
       
    76 SDL_CDcaps.Resume = SDL_SYS_CDResume;
       
    77 SDL_CDcaps.Stop = SDL_SYS_CDStop;
       
    78 SDL_CDcaps.Eject = SDL_SYS_CDEject;
       
    79 SDL_CDcaps.Close = SDL_SYS_CDClose;
       
    80 
       
    81 /* Get the number of CD ROMs in the System */
       
    82 /* Clean SysInfo structure */
       
    83 SDL_memset(&msp, 0x00, sizeof(MCI_SYSINFO_PARMS));
       
    84 /* Prepare structure to Ask Numer of Audio CDs */
       
    85 msp.usDeviceType = MCI_DEVTYPE_CD_AUDIO;	/* CD Audio Type */
       
    86 msp.pszReturn = (PSZ)&SysInfoRet; 	/* Return Structure */
       
    87 msp.ulRetSize = MCI_CMDRETBUFSIZE; 	/* Size of ret struct */
       
    88 if (LOUSHORT(mciSendCommand(0,MCI_SYSINFO, MCI_SYSINFO_QUANTITY | MCI_WAIT, (PVOID)&msp, 0)) != MCIERR_SUCCESS) return(CD_ERROR);
       
    89 SDL_numcds = atoi(SysInfoRet);
       
    90 if (SDL_numcds > MAX_DRIVES) SDL_numcds = MAX_DRIVES; /* Limit maximum CD number */
       
    91 
       
    92 /* Get and Add their system name to the SDL_cdlist */
       
    93 msp.pszReturn = (PSZ)&SysInfoRet; 				/* Return Structure */
       
    94 msp.ulRetSize = MCI_CMDRETBUFSIZE; 			/* Size of ret struct */
       
    95 msp.usDeviceType = MCI_DEVTYPE_CD_AUDIO;		/* CD Audio Type */
       
    96 for (i=0; i<SDL_numcds; i++)
       
    97 	{
       
    98 	msp.ulNumber = i+1;
       
    99 	mciSendCommand(0,MCI_SYSINFO, MCI_SYSINFO_NAME | MCI_WAIT,&msp, 0);
       
   100 	SDL_cdlist[i] = SDL_strdup(SysInfoRet);
       
   101 	if ( SDL_cdlist[i] == NULL )
       
   102 		{
       
   103 		SDL_OutOfMemory();
       
   104 		return(-1);
       
   105 		}
       
   106 	}
       
   107 return(0);
       
   108 }
       
   109 
       
   110 /* Return CDAudio System Dependent Device Name - Ready for MCI*/
       
   111 static const char *SDL_SYS_CDName(int drive)
       
   112 {
       
   113 return(SDL_cdlist[drive]);
       
   114 }
       
   115 
       
   116 /* Open CDAudio Device - Ready for MCI */
       
   117 static int SDL_SYS_CDOpen(int drive)
       
   118 {
       
   119 MCI_OPEN_PARMS	mop;
       
   120 MCI_SET_PARMS msp;
       
   121 MCI_GENERIC_PARMS mgp;
       
   122 
       
   123 /* Open the device */
       
   124 mop.hwndCallback = (HWND)NULL;		// None
       
   125 mop.usDeviceID = (USHORT)NULL;		// Will be returned.
       
   126 mop.pszDeviceType = (PSZ)SDL_cdlist[drive];		// CDAudio Device
       
   127 if (LOUSHORT(mciSendCommand(0,MCI_OPEN,MCI_WAIT,&mop, 0)) != MCIERR_SUCCESS) return(CD_ERROR);
       
   128 /* Set time format */
       
   129 msp.hwndCallback = (HWND)NULL;		// None
       
   130 msp.ulTimeFormat = MCI_FORMAT_MSF;	// Minute : Second : Frame structure
       
   131 msp.ulSpeedFormat = (ULONG)NULL;		// No change
       
   132 msp.ulAudio = (ULONG)NULL;				// No Channel
       
   133 msp.ulLevel = (ULONG)NULL;				// No Volume
       
   134 msp.ulOver = (ULONG)NULL;				// No Delay
       
   135 msp.ulItem = (ULONG)NULL;				// No item
       
   136 msp.ulValue = (ULONG)NULL;				// No value for item flag
       
   137 if (LOUSHORT(mciSendCommand(mop.usDeviceID,MCI_SET,MCI_WAIT | MCI_SET_TIME_FORMAT,&msp, 0)) == MCIERR_SUCCESS) return (mop.usDeviceID);
       
   138 /* Error setting time format? - Close opened device */
       
   139 mgp.hwndCallback = (HWND)NULL;		// None
       
   140 mciSendCommand(mop.usDeviceID,MCI_CLOSE,MCI_WAIT,&mgp, 0);
       
   141 return(CD_ERROR);
       
   142 }
       
   143 
       
   144 /* Get CD Table Of Contents - Ready for MCI */
       
   145 static int SDL_SYS_CDGetTOC(SDL_CD *cdrom)
       
   146 {
       
   147 MCI_TOC_PARMS mtp;
       
   148 MCI_STATUS_PARMS msp;
       
   149 MCI_TOC_REC * mtr;
       
   150 INT i;
       
   151 
       
   152 /* Correction because MCI cannot read TOC while CD is playing (it'll stop!) */
       
   153 if (cdrom->status == CD_PLAYING || cdrom->status == CD_PAUSED) return 0;
       
   154 
       
   155 /* Get Number of Tracks */
       
   156 msp.hwndCallback = (HWND)NULL; /* None */
       
   157 msp.ulReturn = (ULONG)NULL; /* We want this information */
       
   158 msp.ulItem = MCI_STATUS_NUMBER_OF_TRACKS;
       
   159 msp.ulValue = (ULONG)NULL; /* No additional information */
       
   160 if (LOUSHORT(mciSendCommand(cdrom->id,MCI_STATUS,MCI_WAIT | MCI_STATUS_ITEM,&msp, 0)) != MCIERR_SUCCESS) return(CD_ERROR);
       
   161 cdrom->numtracks = msp.ulReturn;
       
   162 if ( cdrom->numtracks > SDL_MAX_TRACKS )
       
   163 	{
       
   164 	cdrom->numtracks = SDL_MAX_TRACKS;
       
   165 	}
       
   166 /* Alocate space for TOC data */
       
   167 mtr = (MCI_TOC_REC *)SDL_malloc(cdrom->numtracks*sizeof(MCI_TOC_REC));
       
   168 if ( mtr == NULL )
       
   169 	{
       
   170 	SDL_OutOfMemory();
       
   171 	return(-1);
       
   172 	}
       
   173 /* Get TOC from CD */
       
   174 mtp.pBuf = mtr;
       
   175 mtp.ulBufSize = cdrom->numtracks*sizeof(MCI_TOC_REC);
       
   176 if (LOUSHORT(mciSendCommand(cdrom->id,MCI_GETTOC,MCI_WAIT,&mtp, 0)) != MCIERR_SUCCESS)
       
   177 	{
       
   178 	SDL_OutOfMemory();
       
   179 	SDL_free(mtr);
       
   180 	return(CD_ERROR);
       
   181 	}
       
   182 /* Fill SDL Tracks Structure */
       
   183 for (i=0; i<cdrom->numtracks; i++)
       
   184 	{
       
   185 	/* Set Track ID */
       
   186 	cdrom->track[i].id = (mtr+i)->TrackNum;
       
   187 	/* Set Track Type */
       
   188 	msp.hwndCallback = (HWND)NULL; /* None */
       
   189 	msp.ulReturn = (ULONG)NULL; /* We want this information */
       
   190 	msp.ulItem = MCI_CD_STATUS_TRACK_TYPE;
       
   191 	msp.ulValue = (ULONG)((mtr+i)->TrackNum); /* Track Number? */
       
   192 	if (LOUSHORT(mciSendCommand(cdrom->id,MCI_STATUS,MCI_WAIT | MCI_TRACK | MCI_STATUS_ITEM,&msp, 0)) != MCIERR_SUCCESS)
       
   193 		{
       
   194 		SDL_free(mtr);
       
   195 		return (CD_ERROR);
       
   196 		}
       
   197 	if (msp.ulReturn==MCI_CD_TRACK_AUDIO) cdrom->track[i].type = SDL_AUDIO_TRACK;
       
   198 	else cdrom->track[i].type = SDL_DATA_TRACK;
       
   199 	/* Set Track Length - values from MCI are in MMTIMEs - 3000 MMTIME = 1 second */
       
   200 	cdrom->track[i].length = FRAMESFROMMM((mtr+i)->ulEndAddr - (mtr+i)->ulStartAddr);
       
   201 	/* Set Track Offset */
       
   202 	cdrom->track[i].offset = FRAMESFROMMM((mtr+i)->ulStartAddr);
       
   203 	}
       
   204 SDL_free(mtr);
       
   205 return(0);
       
   206 }
       
   207 
       
   208 
       
   209 /* Get CD-ROM status - Ready for MCI */
       
   210 static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position)
       
   211 {
       
   212 CDstatus status;
       
   213 MCI_STATUS_PARMS msp;
       
   214 
       
   215 /* Get Status from MCI */
       
   216 msp.hwndCallback = (HWND)NULL; /* None */
       
   217 msp.ulReturn = (ULONG)NULL; /* We want this information */
       
   218 msp.ulItem = MCI_STATUS_MODE;
       
   219 msp.ulValue = (ULONG)NULL; /* No additional information */
       
   220 if (LOUSHORT(mciSendCommand(cdrom->id,MCI_STATUS,MCI_WAIT | MCI_STATUS_ITEM,&msp, 0)) != MCIERR_SUCCESS) status = CD_ERROR;
       
   221 else
       
   222 	{
       
   223 	switch(msp.ulReturn)
       
   224 		{
       
   225 		case	MCI_MODE_NOT_READY:
       
   226 			status = CD_TRAYEMPTY;
       
   227 			break;
       
   228 		case	MCI_MODE_PAUSE:
       
   229 			status = CD_PAUSED;
       
   230 			break;
       
   231 		case	MCI_MODE_PLAY:
       
   232 			status = CD_PLAYING;
       
   233 			break;
       
   234 		case	MCI_MODE_STOP:
       
   235 			status = CD_STOPPED;
       
   236 			break;
       
   237 		/* These cases should not occour */
       
   238 		case	MCI_MODE_RECORD:
       
   239 		case	MCI_MODE_SEEK:
       
   240 		default:
       
   241 			status = CD_ERROR;
       
   242 			break;
       
   243 		}
       
   244 	}
       
   245 
       
   246 /* Determine position */
       
   247 if (position != NULL) /* The SDL $&$&%# CDROM call sends NULL pointer here! */
       
   248 	{
       
   249 		if ((status == CD_PLAYING) || (status == CD_PAUSED))
       
   250 		{
       
   251 		/* Get Position */
       
   252 		msp.hwndCallback = (HWND)NULL; /* None */
       
   253 		msp.ulReturn = (ULONG)NULL; /* We want this information */
       
   254 		msp.ulItem = MCI_STATUS_POSITION;
       
   255 		msp.ulValue = (ULONG)NULL; /* No additiona info */
       
   256 		if (LOUSHORT(mciSendCommand(cdrom->id,MCI_STATUS,MCI_WAIT | MCI_STATUS_ITEM,&msp, 0)) != MCIERR_SUCCESS) return (CD_ERROR);
       
   257 		/* Convert from MSF (format selected in the Open process) to Frames (format that will be returned) */
       
   258 		*position = MSF_TO_FRAMES(MSF_MINUTE(msp.ulReturn),MSF_SECOND(msp.ulReturn),MSF_FRAME(msp.ulReturn));
       
   259 		}
       
   260 	else *position = 0;
       
   261 	}
       
   262 return(status);
       
   263 }
       
   264 
       
   265 /* Start play - Ready for MCI */
       
   266 static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length)
       
   267 {
       
   268 MCI_GENERIC_PARMS mgp;
       
   269 MCI_STATUS_PARMS msp;
       
   270 MCI_PLAY_PARMS	mpp;
       
   271 ULONG min,sec,frm;
       
   272 
       
   273 /* Start MSF */
       
   274 FRAMES_TO_MSF(start, &min, &sec, &frm);
       
   275 MSF_MINUTE(mpp.ulFrom) = min;
       
   276 MSF_SECOND(mpp.ulFrom) = sec;
       
   277 MSF_FRAME(mpp.ulFrom) = frm;
       
   278 /* End MSF */
       
   279 FRAMES_TO_MSF(start+length, &min, &sec, &frm);
       
   280 MSF_MINUTE(mpp.ulTo) = min;
       
   281 MSF_SECOND(mpp.ulTo) = sec;
       
   282 MSF_FRAME(mpp.ulTo) = frm;
       
   283 #ifdef DEBUG_CDROM
       
   284 	fprintf(stderr, "Trying to play from %d:%d:%d to %d:%d:%d\n",
       
   285 	playtime.cdmsf_min0, playtime.cdmsf_sec0, playtime.cdmsf_frame0,
       
   286 	playtime.cdmsf_min1, playtime.cdmsf_sec1, playtime.cdmsf_frame1);
       
   287 #endif
       
   288 /* Verifies if it is paused first... and if it is, unpause before stopping it. */
       
   289 msp.hwndCallback = (HWND)NULL; /* None */
       
   290 msp.ulReturn = (ULONG)NULL; /* We want this information */
       
   291 msp.ulItem = MCI_STATUS_MODE;
       
   292 msp.ulValue = (ULONG)NULL; /* No additional information */
       
   293 if (LOUSHORT(mciSendCommand(cdrom->id,MCI_STATUS,MCI_WAIT | MCI_STATUS_ITEM,&msp, 0)) == MCIERR_SUCCESS)
       
   294 	{
       
   295 	if (msp.ulReturn == MCI_MODE_PAUSE)
       
   296 		{
       
   297 		mgp.hwndCallback = (HWND)NULL;		// None
       
   298 		mciSendCommand(cdrom->id,MCI_RESUME,0,&mgp, 0);
       
   299 		}
       
   300 	}
       
   301 /* Now play it. */
       
   302 mpp.hwndCallback = (HWND)NULL;		// We do not want the info. temp
       
   303 if (LOUSHORT(mciSendCommand(cdrom->id,MCI_PLAY,MCI_FROM | MCI_TO,&mpp, 0)) == MCIERR_SUCCESS) return 0;
       
   304 return (CD_ERROR);
       
   305 }
       
   306 
       
   307 /* Pause play - Ready for MCI */
       
   308 static int SDL_SYS_CDPause(SDL_CD *cdrom)
       
   309 {
       
   310 MCI_GENERIC_PARMS mgp;
       
   311 
       
   312 mgp.hwndCallback = (HWND)NULL;		// None
       
   313 if (LOUSHORT(mciSendCommand(cdrom->id,MCI_PAUSE,MCI_WAIT,&mgp, 0)) == MCIERR_SUCCESS) return 0;
       
   314 return(CD_ERROR);
       
   315 }
       
   316 
       
   317 /* Resume play - Ready for MCI */
       
   318 static int SDL_SYS_CDResume(SDL_CD *cdrom)
       
   319 {
       
   320 MCI_GENERIC_PARMS mgp;
       
   321 
       
   322 mgp.hwndCallback = (HWND)NULL;		// None
       
   323 if (LOUSHORT(mciSendCommand(cdrom->id,MCI_RESUME,MCI_WAIT,&mgp, 0)) == MCIERR_SUCCESS) return 0;
       
   324 return(CD_ERROR);
       
   325 }
       
   326 
       
   327 /* Stop play - Ready for MCI */
       
   328 static int SDL_SYS_CDStop(SDL_CD *cdrom)
       
   329 {
       
   330 MCI_GENERIC_PARMS mgp;
       
   331 MCI_STATUS_PARMS msp;
       
   332 
       
   333 /* Verifies if it is paused first... and if it is, unpause before stopping it. */
       
   334 msp.hwndCallback = (HWND)NULL; /* None */
       
   335 msp.ulReturn = (ULONG)NULL; /* We want this information */
       
   336 msp.ulItem = MCI_STATUS_MODE;
       
   337 msp.ulValue = (ULONG)NULL; /* No additional information */
       
   338 if (LOUSHORT(mciSendCommand(cdrom->id,MCI_STATUS,MCI_WAIT | MCI_STATUS_ITEM,&msp, 0)) == MCIERR_SUCCESS)
       
   339 	{
       
   340 	if (msp.ulReturn == MCI_MODE_PAUSE)
       
   341 		{
       
   342 		mgp.hwndCallback = (HWND)NULL;		// None
       
   343 		mciSendCommand(cdrom->id,MCI_RESUME,0,&mgp, 0);
       
   344 		}
       
   345 	}
       
   346 /* Now stops the media */
       
   347 mgp.hwndCallback = (HWND)NULL;		// None
       
   348 if (LOUSHORT(mciSendCommand(cdrom->id,MCI_STOP,MCI_WAIT,&mgp, 0)) == MCIERR_SUCCESS) return 0;
       
   349 return(CD_ERROR);
       
   350 }
       
   351 
       
   352 /* Eject the CD-ROM - Ready for MCI */
       
   353 static int SDL_SYS_CDEject(SDL_CD *cdrom)
       
   354 {
       
   355 MCI_SET_PARMS msp;
       
   356 
       
   357 msp.hwndCallback = (HWND)NULL;		// None
       
   358 msp.ulTimeFormat = (ULONG)NULL;		// No change
       
   359 msp.ulSpeedFormat = (ULONG)NULL;		// No change
       
   360 msp.ulAudio = (ULONG)NULL;				// No Channel
       
   361 msp.ulLevel = (ULONG)NULL;				// No Volume
       
   362 msp.ulOver = (ULONG)NULL;				// No Delay
       
   363 msp.ulItem = (ULONG)NULL;					// No item
       
   364 msp.ulValue = (ULONG)NULL;					// No value for item flag
       
   365 if (LOUSHORT(mciSendCommand(cdrom->id,MCI_SET,MCI_WAIT | MCI_SET_DOOR_OPEN,&msp, 0)) == MCIERR_SUCCESS) return 0;
       
   366 return(CD_ERROR);
       
   367 }
       
   368 
       
   369 /* Close the CD-ROM handle - Ready for MCI */
       
   370 static void SDL_SYS_CDClose(SDL_CD *cdrom)
       
   371 {
       
   372 MCI_GENERIC_PARMS mgp;
       
   373 
       
   374 mgp.hwndCallback = (HWND)NULL;		// None
       
   375 mciSendCommand(cdrom->id,MCI_CLOSE,MCI_WAIT,&mgp, 0);
       
   376 }
       
   377 
       
   378 /* Finalize CDROM Subsystem - Ready for MCI */
       
   379 void SDL_SYS_CDQuit(void)
       
   380 {
       
   381 int i;
       
   382 
       
   383 if ( SDL_numcds > 0 )
       
   384 	{
       
   385 	for ( i=0; i<SDL_numcds; ++i )
       
   386 		{
       
   387 		SDL_free(SDL_cdlist[i]);
       
   388 		}
       
   389 	SDL_numcds = 0;
       
   390 	}
       
   391 }
       
   392 
       
   393 #endif /* SDL_CDROM_OS2 */