SDL_syscdrom.c
资源名称:NETVIDEO.rar [点击查看]
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:16k
源码类别:
流媒体/Mpeg4/MP4
开发平台:
Visual C++
- /*
- SDL - Simple DirectMedia Layer
- Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- Sam Lantinga
- slouken@libsdl.org
- */
- #ifdef SAVE_RCSID
- static char rcsid =
- "@(#) $Id: SDL_syscdrom.c,v 1.4 2002/04/22 21:38:02 wmay Exp $";
- #endif
- /* MacOS functions for system-level CD-ROM audio control */
- #include <Devices.h>
- #include <Files.h>
- #include <LowMem.h> /* Use entry table macros, not functions in InterfaceLib */
- #include "SDL_cdrom.h"
- #include "SDL_syscdrom.h"
- #include "SDL_syscdrom_c.h"
- /* Added by Matt Slot */
- #if !defined(LMGetUnitTableEntryCount)
- #define LMGetUnitTableEntryCount() *(short *)0x01D2
- #endif
- /* The maximum number of CD-ROM drives we'll detect */
- #define MAX_DRIVES 26
- /* A list of available CD-ROM drives */
- static long SDL_cdversion = 0;
- static struct {
- short dRefNum;
- short driveNum;
- long frames;
- char name[256];
- Boolean hasAudio;
- } SDL_cdlist[MAX_DRIVES];
- static StringPtr gDriverName = "p.AppleCD";
- /* The system-dependent CD control functions */
- static const char *SDL_SYS_CDName(int drive);
- static int SDL_SYS_CDOpen(int drive);
- static int SDL_SYS_CDGetTOC(SDL_CD *cdrom);
- static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position);
- static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length);
- static int SDL_SYS_CDPause(SDL_CD *cdrom);
- static int SDL_SYS_CDResume(SDL_CD *cdrom);
- static int SDL_SYS_CDStop(SDL_CD *cdrom);
- static int SDL_SYS_CDEject(SDL_CD *cdrom);
- static void SDL_SYS_CDClose(SDL_CD *cdrom);
- static short SDL_SYS_ShortToBCD(short value)
- {
- return((value % 10) + (value / 10) * 0x10); /* Convert value to BCD */
- }
- static short SDL_SYS_BCDToShort(short value)
- {
- return((value % 0x10) + (value / 0x10) * 10); /* Convert value from BCD */
- }
- int SDL_SYS_CDInit(void)
- {
- SInt16 dRefNum = 0;
- SInt16 first, last;
- SDL_numcds = 0;
- /* Check that the software is available */
- if (Gestalt(kGestaltAudioCDSelector, &SDL_cdversion) ||
- !SDL_cdversion) return(0);
- /* Fill in our driver capabilities */
- SDL_CDcaps.Name = SDL_SYS_CDName;
- SDL_CDcaps.Open = SDL_SYS_CDOpen;
- SDL_CDcaps.GetTOC = SDL_SYS_CDGetTOC;
- SDL_CDcaps.Status = SDL_SYS_CDStatus;
- SDL_CDcaps.Play = SDL_SYS_CDPlay;
- SDL_CDcaps.Pause = SDL_SYS_CDPause;
- SDL_CDcaps.Resume = SDL_SYS_CDResume;
- SDL_CDcaps.Stop = SDL_SYS_CDStop;
- SDL_CDcaps.Eject = SDL_SYS_CDEject;
- SDL_CDcaps.Close = SDL_SYS_CDClose;
- /* Walk the list, count each AudioCD driver, and save the refnums */
- first = -1;
- last = 0 - LMGetUnitTableEntryCount();
- for(dRefNum = first; dRefNum >= last; dRefNum--) {
- Str255 driverName;
- StringPtr namePtr;
- DCtlHandle deviceEntry;
- deviceEntry = GetDCtlEntry(dRefNum);
- if (! deviceEntry) continue;
- /* Is this an .AppleCD ? */
- namePtr = (*deviceEntry)->dCtlFlags & (1L << dRAMBased) ?
- ((StringPtr) ((DCtlPtr) deviceEntry)->dCtlDriver + 18) :
- ((StringPtr) (*deviceEntry)->dCtlDriver + 18);
- BlockMoveData(namePtr, driverName, namePtr[0]+1);
- if (driverName[0] > gDriverName[0]) driverName[0] = gDriverName[0];
- if (! EqualString(driverName, gDriverName, false, false)) continue;
- /* Record the basic info for each drive */
- SDL_cdlist[SDL_numcds].dRefNum = dRefNum;
- BlockMoveData(namePtr + 1, SDL_cdlist[SDL_numcds].name, namePtr[0]);
- SDL_cdlist[SDL_numcds].name[namePtr[0]] = 0;
- SDL_cdlist[SDL_numcds].hasAudio = false;
- SDL_numcds++;
- }
- return(0);
- }
- static const char *SDL_SYS_CDName(int drive)
- {
- return(SDL_cdlist[drive].name);
- }
- static int get_drivenum(int drive)
- {
- QHdr *driveQ = GetDrvQHdr();
- DrvQEl *driveElem;
- /* Update the drive number */
- SDL_cdlist[drive].driveNum = 0;
- if ( driveQ->qTail ) {
- driveQ->qTail->qLink = 0;
- }
- for ( driveElem=(DrvQEl *)driveQ->qHead; driveElem;
- driveElem = (DrvQEl *)driveElem->qLink ) {
- if ( driveElem->dQRefNum == SDL_cdlist[drive].dRefNum ) {
- SDL_cdlist[drive].driveNum = driveElem->dQDrive;
- break;
- }
- }
- return(SDL_cdlist[drive].driveNum);
- }
- static int SDL_SYS_CDOpen(int drive)
- {
- return(drive);
- }
- static int SDL_SYS_CDGetTOC(SDL_CD *cdrom)
- {
- CDCntrlParam cdpb;
- CDTrackData tracks[SDL_MAX_TRACKS];
- long i, leadout;
- /* Get the number of tracks on the CD by examining the TOC */
- memset(&cdpb, 0, sizeof(cdpb));
- cdpb.ioVRefNum = SDL_cdlist[cdrom->id].driveNum;
- cdpb.ioCRefNum = SDL_cdlist[cdrom->id].dRefNum;
- cdpb.csCode = kReadTOC;
- cdpb.csParam.words[0] = kGetTrackRange;
- if ( PBControlSync((ParmBlkPtr)&cdpb) != noErr ) {
- SDL_SetError("PBControlSync() failed");
- return(-1);
- }
- cdrom->numtracks =
- SDL_SYS_BCDToShort(cdpb.csParam.bytes[1]) -
- SDL_SYS_BCDToShort(cdpb.csParam.bytes[0]) + 1;
- if ( cdrom->numtracks > SDL_MAX_TRACKS )
- cdrom->numtracks = SDL_MAX_TRACKS;
- cdrom->status = CD_STOPPED;
- cdrom->cur_track = 0; /* Apparently these are set elsewhere */
- cdrom->cur_frame = 0; /* Apparently these are set elsewhere */
- /* Get the lead out area of the CD by examining the TOC */
- memset(&cdpb, 0, sizeof(cdpb));
- cdpb.ioVRefNum = SDL_cdlist[cdrom->id].driveNum;
- cdpb.ioCRefNum = SDL_cdlist[cdrom->id].dRefNum;
- cdpb.csCode = kReadTOC;
- cdpb.csParam.words[0] = kGetLeadOutArea;
- if ( PBControlSync((ParmBlkPtr)&cdpb) != noErr ) {
- SDL_SetError("PBControlSync() failed");
- return(-1);
- }
- leadout = MSF_TO_FRAMES(
- SDL_SYS_BCDToShort(cdpb.csParam.bytes[0]),
- SDL_SYS_BCDToShort(cdpb.csParam.bytes[1]),
- SDL_SYS_BCDToShort(cdpb.csParam.bytes[2]));
- /* Get an array of track locations by examining the TOC */
- memset(tracks, 0, sizeof(tracks));
- memset(&cdpb, 0, sizeof(cdpb));
- cdpb.ioVRefNum = SDL_cdlist[cdrom->id].driveNum;
- cdpb.ioCRefNum = SDL_cdlist[cdrom->id].dRefNum;
- cdpb.csCode = kReadTOC;
- cdpb.csParam.words[0] = kGetTrackEntries; /* Type of Query */
- * ((long *) (cdpb.csParam.words+1)) = (long) tracks;
- cdpb.csParam.words[3] = cdrom->numtracks * sizeof(tracks[0]);
- * ((char *) (cdpb.csParam.words+4)) = 1; /* First track */
- if ( PBControlSync((ParmBlkPtr)&cdpb) != noErr ) {
- SDL_SetError("PBControlSync() failed");
- return(-1);
- }
- /* Read all the track TOC entries */
- SDL_cdlist[cdrom->id].hasAudio = false;
- for ( i=0; i<cdrom->numtracks; ++i )
- {
- cdrom->track[i].id = i+1;
- if (tracks[i].entry.control & kDataTrackMask)
- cdrom->track[i].type = SDL_DATA_TRACK;
- else
- {
- cdrom->track[i].type = SDL_AUDIO_TRACK;
- SDL_cdlist[SDL_numcds].hasAudio = true;
- }
- cdrom->track[i].offset = MSF_TO_FRAMES(
- SDL_SYS_BCDToShort(tracks[i].entry.min),
- SDL_SYS_BCDToShort(tracks[i].entry.min),
- SDL_SYS_BCDToShort(tracks[i].entry.frame));
- cdrom->track[i].length = MSF_TO_FRAMES(
- SDL_SYS_BCDToShort(tracks[i+1].entry.min),
- SDL_SYS_BCDToShort(tracks[i+1].entry.min),
- SDL_SYS_BCDToShort(tracks[i+1].entry.frame)) -
- cdrom->track[i].offset;
- }
- /* Apparently SDL wants a fake last entry */
- cdrom->track[i].offset = leadout;
- cdrom->track[i].length = 0;
- return(0);
- }
- /* Get CD-ROM status */
- static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position)
- {
- CDCntrlParam cdpb;
- CDstatus status = CD_ERROR;
- Boolean spinning = false;
- if (position) *position = 0;
- /* Get the number of tracks on the CD by examining the TOC */
- if ( ! get_drivenum(cdrom->id) ) {
- return(CD_TRAYEMPTY);
- }
- memset(&cdpb, 0, sizeof(cdpb));
- cdpb.ioVRefNum = SDL_cdlist[cdrom->id].driveNum;
- cdpb.ioCRefNum = SDL_cdlist[cdrom->id].dRefNum;
- cdpb.csCode = kReadTOC;
- cdpb.csParam.words[0] = kGetTrackRange;
- if ( PBControlSync((ParmBlkPtr)&cdpb) != noErr ) {
- SDL_SetError("PBControlSync() failed");
- return(CD_ERROR);
- }
- cdrom->numtracks =
- SDL_SYS_BCDToShort(cdpb.csParam.bytes[1]) -
- SDL_SYS_BCDToShort(cdpb.csParam.bytes[0]) + 1;
- if ( cdrom->numtracks > SDL_MAX_TRACKS )
- cdrom->numtracks = SDL_MAX_TRACKS;
- cdrom->cur_track = 0; /* Apparently these are set elsewhere */
- cdrom->cur_frame = 0; /* Apparently these are set elsewhere */
- if (1 || SDL_cdlist[cdrom->id].hasAudio) {
- /* Get the current playback status */
- memset(&cdpb, 0, sizeof(cdpb));
- cdpb.ioVRefNum = SDL_cdlist[cdrom->id].driveNum;
- cdpb.ioCRefNum = SDL_cdlist[cdrom->id].dRefNum;
- cdpb.csCode = kAudioStatus;
- if ( PBControlSync((ParmBlkPtr)&cdpb) != noErr ) {
- SDL_SetError("PBControlSync() failed");
- return(-1);
- }
- switch(cdpb.csParam.cd.status) {
- case kStatusPlaying:
- status = CD_PLAYING;
- spinning = true;
- break;
- case kStatusPaused:
- status = CD_PAUSED;
- spinning = true;
- break;
- case kStatusMuted:
- status = CD_PLAYING; /* What should I do here? */
- spinning = true;
- break;
- case kStatusDone:
- status = CD_STOPPED;
- spinning = true;
- break;
- case kStatusStopped:
- status = CD_STOPPED;
- spinning = false;
- break;
- case kStatusError:
- default:
- status = CD_ERROR;
- spinning = false;
- break;
- }
- if (spinning && position) *position = MSF_TO_FRAMES(
- SDL_SYS_BCDToShort(cdpb.csParam.cd.minute),
- SDL_SYS_BCDToShort(cdpb.csParam.cd.second),
- SDL_SYS_BCDToShort(cdpb.csParam.cd.frame));
- }
- else
- status = CD_ERROR; /* What should I do here? */
- return(status);
- }
- /* Start play */
- static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length)
- {
- CDCntrlParam cdpb;
- /* Pause the current audio playback to avoid audible artifacts */
- if ( SDL_SYS_CDPause(cdrom) < 0 ) {
- return(-1);
- }
- /* Specify the AudioCD playback mode */
- memset(&cdpb, 0, sizeof(cdpb));
- cdpb.ioVRefNum = SDL_cdlist[cdrom->id].driveNum;
- cdpb.ioCRefNum = SDL_cdlist[cdrom->id].dRefNum;
- cdpb.csCode = kSetPlayMode;
- cdpb.csParam.bytes[0] = false; /* Repeat? */
- cdpb.csParam.bytes[1] = kPlayModeSequential; /* Play mode */
- /* ゥナTreat as soft error, NEC Drive doesnt support this call ゥ