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

📄 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_MACOSX#include "SDL_syscdrom_c.h"#pragma mark -- Globals --static FSRef**         tracks;static FSVolumeRefNum* volumes;static CDstatus        status;static int             nextTrackFrame;static int             nextTrackFramesRemaining;static int             fakeCD;static int             currentTrack;static int             didReadTOC;static int             cacheTOCNumTracks;static int             currentDrive; /* Only allow 1 drive in use at a time */#pragma mark -- Prototypes --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);#pragma mark -- Helper Functions --/* Read a list of tracks from the volume */static int LoadTracks (SDL_CD *cdrom){    /* Check if tracks are already loaded */    if  ( tracks[cdrom->id] != NULL )        return 0;            /* Allocate memory for tracks */    tracks[cdrom->id] = (FSRef*) SDL_calloc (1, sizeof(**tracks) * cdrom->numtracks);    if (tracks[cdrom->id] == NULL) {        SDL_OutOfMemory ();        return -1;    }        /* Load tracks */    if (ListTrackFiles (volumes[cdrom->id], tracks[cdrom->id], cdrom->numtracks) < 0)        return -1;    return 0;}/* Find a file for a given start frame and length */static FSRef* GetFileForOffset (SDL_CD *cdrom, int start, int length,  int *outStartFrame, int *outStopFrame){    int i;        for (i = 0; i < cdrom->numtracks; i++) {            if (cdrom->track[i].offset <= start &&            start < (cdrom->track[i].offset + cdrom->track[i].length))            break;    }        if (i == cdrom->numtracks)        return NULL;            currentTrack = i;    *outStartFrame = start - cdrom->track[i].offset;        if ((*outStartFrame + length) < cdrom->track[i].length) {        *outStopFrame = *outStartFrame + length;        length = 0;        nextTrackFrame = -1;        nextTrackFramesRemaining = -1;    }    else {        *outStopFrame = -1;        length -= cdrom->track[i].length - *outStartFrame;        nextTrackFrame = cdrom->track[i+1].offset;        nextTrackFramesRemaining = length;    }        return &tracks[cdrom->id][i];}/* Setup another file for playback, or stop playback (called from another thread) */static void CompletionProc (SDL_CD *cdrom){        Lock ();        if (nextTrackFrame > 0 && nextTrackFramesRemaining > 0) {            /* Load the next file to play */        int startFrame, stopFrame;        FSRef *file;                PauseFile ();        ReleaseFile ();                        file = GetFileForOffset (cdrom, nextTrackFrame,             nextTrackFramesRemaining, &startFrame, &stopFrame);                if (file == NULL) {            status = CD_STOPPED;            Unlock ();            return;        }                LoadFile (file, startFrame, stopFrame);                SetCompletionProc (CompletionProc, cdrom);                PlayFile ();    }    else {            /* Release the current file */        PauseFile ();        ReleaseFile ();        status = CD_STOPPED;    }        Unlock ();}#pragma mark -- Driver Functions --/* Initialize */int SDL_SYS_CDInit (void) {    /* Initialize globals */    volumes = NULL;    tracks  = NULL;    status  = CD_STOPPED;    nextTrackFrame = -1;    nextTrackFramesRemaining = -1;    fakeCD  = SDL_FALSE;    currentTrack = -1;    didReadTOC = SDL_FALSE;    cacheTOCNumTracks = -1;    currentDrive = -1;        /* Fill in function pointers */    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;    /*         Read the list of "drives"                This is currently a hack that infers drives from        mounted audio CD volumes, rather than        actual CD-ROM devices - which means it may not        act as expected sometimes.    */        /* Find out how many cd volumes are mounted */    SDL_numcds = DetectAudioCDVolumes (NULL, 0);    /*        If there are no volumes, fake a cd device        so tray empty can be reported.    */    if (SDL_numcds == 0) {            fakeCD = SDL_TRUE;        SDL_numcds = 1;        status = CD_TRAYEMPTY;                return 0;    }        /* Allocate space for volumes */    volumes = (FSVolumeRefNum*) SDL_calloc (1, sizeof(*volumes) * SDL_numcds);    if (volumes == NULL) {        SDL_OutOfMemory ();        return -1;    }        /* Allocate space for tracks */    tracks = (FSRef**) SDL_calloc (1, sizeof(*tracks) * (SDL_numcds + 1));    if (tracks == NULL) {        SDL_OutOfMemory ();        return -1;    }        /* Mark the end of the tracks array */    tracks[ SDL_numcds ] = (FSRef*)-1;        /*         Redetect, now save all volumes for later        Update SDL_numcds just in case it changed    */    {        int numVolumes = SDL_numcds;                SDL_numcds = DetectAudioCDVolumes (volumes, numVolumes);                /* If more cds suddenly show up, ignore them */        if (SDL_numcds > numVolumes) {            SDL_SetError ("Some CD's were added but they will be ignored");            SDL_numcds = numVolumes;        }    }        return 0;}/* Shutdown and cleanup */void SDL_SYS_CDQuit(void){    ReleaseFile();        if (volumes != NULL)        free (volumes);            if (tracks != NULL) {            FSRef **ptr;        for (ptr = tracks; *ptr != (FSRef*)-1; ptr++)            if (*ptr != NULL)                free (*ptr);                    free (tracks);    }}/* Get the Unix disk name of the volume */static const char *SDL_SYS_CDName (int drive){    OSStatus     err = noErr;    HParamBlockRec  pb;    GetVolParmsInfoBuffer   volParmsInfo;       if (fakeCD)        return "Fake CD-ROM Device";    pb.ioParam.ioNamePtr = NULL;    pb.ioParam.ioVRefNum = volumes[drive];    pb.ioParam.ioBuffer = (Ptr)&volParmsInfo;    pb.ioParam.ioReqCount = (SInt32)sizeof(volParmsInfo);    err = PBHGetVolParmsSync(&pb);    if (err != noErr) {        SDL_SetError ("PBHGetVolParmsSync returned %d", err);        return NULL;    }    return volParmsInfo.vMDeviceID;}/* Open the "device" */static int SDL_SYS_CDOpen (int drive){    /* Only allow 1 device to be open */    if (currentDrive >= 0) {        SDL_SetError ("Only one cdrom is supported");        return -1;    }    else        currentDrive = drive;    return drive;}/* Get the table of contents */static int SDL_SYS_CDGetTOC (SDL_CD *cdrom){    if (fakeCD) {        SDL_SetError (kErrorFakeDevice);        return -1;    }        if (didReadTOC) {        cdrom->numtracks = cacheTOCNumTracks;        return 0;    }            ReadTOCData (volumes[cdrom->id], cdrom);    didReadTOC = SDL_TRUE;    cacheTOCNumTracks = cdrom->numtracks;        return 0;}/* Get CD-ROM status */static CDstatus SDL_SYS_CDStatus (SDL_CD *cdrom, int *position){    if (position) {        int trackFrame;                Lock ();        trackFrame = GetCurrentFrame ();        Unlock ();            *position = cdrom->track[currentTrack].offset + trackFrame;    }        return status;}/* Start playback */static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length){    int startFrame, stopFrame;    FSRef *ref;        if (fakeCD) {        SDL_SetError (kErrorFakeDevice);        return -1;    }        Lock();        if (LoadTracks (cdrom) < 0)        return -2;        if (PauseFile () < 0)        return -3;            if (ReleaseFile () < 0)        return -4;        ref = GetFileForOffset (cdrom, start, length, &startFrame, &stopFrame);    if (ref == NULL) {        SDL_SetError ("SDL_SYS_CDPlay: No file for start=%d, length=%d", start, length);        return -5;    }        if (LoadFile (ref, startFrame, stopFrame) < 0)        return -6;        SetCompletionProc (CompletionProc, cdrom);        if (PlayFile () < 0)        return -7;        status = CD_PLAYING;        Unlock();        return 0;}/* Pause playback */static int SDL_SYS_CDPause(SDL_CD *cdrom){    if (fakeCD) {        SDL_SetError (kErrorFakeDevice);        return -1;    }        Lock ();        if (PauseFile () < 0) {        Unlock ();        return -2;    }        status = CD_PAUSED;        Unlock ();        return 0;}/* Resume playback */static int SDL_SYS_CDResume(SDL_CD *cdrom){    if (fakeCD) {        SDL_SetError (kErrorFakeDevice);        return -1;    }        Lock ();        if (PlayFile () < 0) {        Unlock ();        return -2;    }            status = CD_PLAYING;        Unlock ();        return 0;}/* Stop playback */static int SDL_SYS_CDStop(SDL_CD *cdrom){    if (fakeCD) {        SDL_SetError (kErrorFakeDevice);        return -1;    }        Lock ();        if (PauseFile () < 0) {        Unlock ();        return -2;    }            if (ReleaseFile () < 0) {        Unlock ();        return -3;    }            status = CD_STOPPED;        Unlock ();        return 0;}/* Eject the CD-ROM (Unmount the volume) */static int SDL_SYS_CDEject(SDL_CD *cdrom){    OSStatus err;    pid_t dissenter;    if (fakeCD) {        SDL_SetError (kErrorFakeDevice);        return -1;    }        Lock ();        if (PauseFile () < 0) {        Unlock ();        return -2;    }            if (ReleaseFile () < 0) {        Unlock ();        return -3;    }        status = CD_STOPPED;    	/* Eject the volume */	err = FSEjectVolumeSync(volumes[cdrom->id], kNilOptions, &dissenter);	if (err != noErr) {        Unlock ();		SDL_SetError ("PBUnmountVol returned %d", err);		return -4;	}        status = CD_TRAYEMPTY;    /* Invalidate volume and track info */    volumes[cdrom->id] = 0;    free (tracks[cdrom->id]);    tracks[cdrom->id] = NULL;        Unlock ();        return 0;}/* Close the CD-ROM */static void SDL_SYS_CDClose(SDL_CD *cdrom){    currentDrive = -1;    return;}#endif /* SDL_CDROM_MACOSX */

⌨️ 快捷键说明

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