⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdl_syscdrom.c

📁 SDL库 在进行视频显示程序spcaview安装时必须的库文件
💻 C
字号:
/*    SDL - Simple DirectMedia Layer    Copyright (C) 1997-2006 Sam Lantinga    This library is free software; you can redistribute it and/or    modify it under the terms of the GNU Lesser General Public    License as published by the Free Software Foundation; either    version 2.1 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    Lesser General Public License for more details.    You should have received a copy of the GNU Lesser General Public    License along with this library; if not, write to the Free Software    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA    Sam Lantinga    slouken@libsdl.org*/#include "SDL_config.h"#ifdef SDL_CDROM_MACOS/* 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 */	SDL_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 */	SDL_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 */	SDL_memset(tracks, 0, sizeof(tracks));	SDL_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);	}	SDL_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 */		SDL_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 */	SDL_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 ゥ

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -