📄 sdl_syscdrom.c
字号:
/* If we found our drives, there's nothing left to do */ if ( SDL_numcds > 0 ) { return(0); } } CheckMounts(); CheckNonmounts(); return 0;}/* General ioctl() CD-ROM command function */static int SDL_SYS_CDioctl(int id, int command, void *arg){ int retval; retval = ioctl(id, command, arg); if ( retval < 0 ) { SDL_SetError("ioctl() error: %s", strerror(errno)); } return retval;}static const char *SDL_SYS_CDName(int drive){ return(SDL_cdlist[drive]);}static int SDL_SYS_CDOpen(int drive){ int fd; char* lastsl; char* cdromname; size_t len; /* * We found /dev/cd? drives and that is in our list. But we can * open only the /dev/rcd? versions of those devices for Audio CD. */ len = SDL_strlen(SDL_cdlist[drive])+2; cdromname = (char*)SDL_malloc(len); SDL_strlcpy(cdromname,SDL_cdlist[drive],len); lastsl = SDL_strrchr(cdromname,'/'); if (lastsl) { *lastsl = 0; SDL_strlcat(cdromname,"/r",len); lastsl = SDL_strrchr(SDL_cdlist[drive],'/'); if (lastsl) { lastsl++; SDL_strlcat(cdromname,lastsl,len); } }#ifdef DEBUG_CDROM fprintf(stderr, "Should open drive %s, opening %s\n", SDL_cdlist[drive], cdromname);#endif /* * Use exclusive access. Don't use SC_DIAGNOSTICS as xmcd does because they * require root priviledges, and we don't want that. SC_SINGLE provides * exclusive access with less trouble. */ fd = openx(cdromname, O_RDONLY, NULL, SC_SINGLE); if ( fd < 0 ) {#ifdef DEBUG_CDROM fprintf(stderr, "Could not open drive %s (%s)\n", cdromname, strerror(errno));#endif } else { struct mode_form_op cdMode; int ret;#ifdef DEBUG_CDROM cdMode.action = CD_GET_MODE; ret = SDL_SYS_CDioctl(fd, DK_CD_MODE, &cdMode); if ( ret < 0 ) { fprintf(stderr, "Could not get drive mode for %s (%s)\n", cdromname, strerror(errno)); } else { switch(cdMode.cd_mode_form) { case CD_MODE1 : fprintf(stderr, "Drive mode for %s is %s\n", cdromname, "CD-ROM Data Mode 1"); break; case CD_MODE2_FORM1 : fprintf(stderr, "Drive mode for %s is %s\n", cdromname, "CD-ROM XA Data Mode 2 Form 1"); break; case CD_MODE2_FORM2 : fprintf(stderr, "Drive mode for %s is %s\n", cdromname, "CD-ROM XA Data Mode 2 Form 2"); break; case CD_DA : fprintf(stderr, "Drive mode for %s is %s\n", cdromname, "CD-DA"); break; default : fprintf(stderr, "Drive mode for %s is %s\n", cdromname, "unknown"); break; } }#endif cdMode.action = CD_CHG_MODE; cdMode.cd_mode_form = CD_DA; ret = SDL_SYS_CDioctl(fd, DK_CD_MODE, &cdMode); if ( ret < 0 ) {#ifdef DEBUG_CDROM fprintf(stderr, "Could not set drive mode for %s (%s)\n", cdromname, strerror(errno));#endif SDL_SetError("ioctl() error: Could not set CD drive mode, %s", strerror(errno)); } else {#ifdef DEBUG_CDROM fprintf(stderr, "Drive mode for %s set to CD_DA\n", cdromname);#endif } } SDL_free(cdromname); return fd;}static int SDL_SYS_CDGetTOC(SDL_CD *cdrom){ struct cd_audio_cmd cmd; struct cd_audio_cmd entry; int i; int okay; cmd.audio_cmds = CD_TRK_INFO_AUDIO; cmd.msf_flag = FALSE; if ( SDL_SYS_CDioctl(cdrom->id, DKAUDIO, &cmd) < 0 ) { return -1; } okay = 0; cdrom->numtracks = cmd.indexing.track_index.last_track - cmd.indexing.track_index.first_track+1; if ( cdrom->numtracks > SDL_MAX_TRACKS ) { cdrom->numtracks = SDL_MAX_TRACKS; } /* Read all the track TOC entries */ for ( i=0; i<=cdrom->numtracks; ++i ) { if ( i == cdrom->numtracks ) { cdrom->track[i].id = 0xAA;; } else { cdrom->track[i].id = cmd.indexing.track_index.first_track+i; } entry.audio_cmds = CD_GET_TRK_MSF; entry.indexing.track_msf.track = cdrom->track[i].id; if ( SDL_SYS_CDioctl(cdrom->id, DKAUDIO, &entry) < 0 ) { break; } else { cdrom->track[i].type = 0; /* don't know how to detect 0x04 data track */ cdrom->track[i].offset = MSF_TO_FRAMES( entry.indexing.track_msf.mins, entry.indexing.track_msf.secs, entry.indexing.track_msf.frames); cdrom->track[i].length = 0; if ( i > 0 ) { cdrom->track[i-1].length = cdrom->track[i].offset - cdrom->track[i-1].offset; } } } if ( i == (cdrom->numtracks+1) ) { okay = 1; } return(okay ? 0 : -1);}/* Get CD-ROM status */static CDstatus SDL_SYS_CDStatus(SDL_CD *cdrom, int *position){ CDstatus status; struct cd_audio_cmd cmd; cmd.audio_cmds = CD_INFO_AUDIO; if ( SDL_SYS_CDioctl(cdrom->id, DKAUDIO, &cmd) < 0 ) {#ifdef DEBUG_CDROM fprintf(stderr, "ioctl failed in SDL_SYS_CDStatus (%s)\n", SDL_GetError());#endif status = CD_ERROR; } else { switch (cmd.status) { case CD_NO_AUDIO: case CD_COMPLETED: status = CD_STOPPED; break; case CD_PLAY_AUDIO: status = CD_PLAYING; break; case CD_PAUSE_AUDIO: status = CD_PAUSED; break; case CD_NOT_VALID:#ifdef DEBUG_CDROM fprintf(stderr, "cdStatus failed with CD_NOT_VALID\n");#endif status = CD_ERROR; break; case CD_STATUS_ERROR:#ifdef DEBUG_CDROM fprintf(stderr, "cdStatus failed with CD_STATUS_ERROR\n");#endif status = CD_ERROR; break; default:#ifdef DEBUG_CDROM fprintf(stderr, "cdStatus failed with unknown error\n");#endif status = CD_ERROR; break; } } if ( position ) { if ( status == CD_PLAYING || (status == CD_PAUSED) ) { *position = MSF_TO_FRAMES( cmd.indexing.info_audio.current_mins, cmd.indexing.info_audio.current_secs, cmd.indexing.info_audio.current_frames); } else { *position = 0; } } return status;}/* Start play */static int SDL_SYS_CDPlay(SDL_CD *cdrom, int start, int length){ struct cd_audio_cmd cmd; /* * My CD Rom is muted by default. I think I read that this is new with * AIX 4.3. SDL does not change the volume, so I need a kludge. Maybe * its better to do this elsewhere? */ cmd.audio_cmds = CD_PLAY_AUDIO | CD_SET_VOLUME; cmd.msf_flag = TRUE; FRAMES_TO_MSF(start, &cmd.indexing.msf.first_mins, &cmd.indexing.msf.first_secs, &cmd.indexing.msf.first_frames); FRAMES_TO_MSF(start+length, &cmd.indexing.msf.last_mins, &cmd.indexing.msf.last_secs, &cmd.indexing.msf.last_frames); cmd.volume_type = CD_VOLUME_ALL; cmd.all_channel_vol = 255; /* This is a uchar. What is a good value? No docu! */ cmd.out_port_0_sel = CD_AUDIO_CHNL_0; cmd.out_port_1_sel = CD_AUDIO_CHNL_1; cmd.out_port_2_sel = CD_AUDIO_CHNL_2; cmd.out_port_3_sel = CD_AUDIO_CHNL_3;#ifdef DEBUG_CDROM fprintf(stderr, "Trying to play from %d:%d:%d to %d:%d:%d\n", cmd.indexing.msf.first_mins, cmd.indexing.msf.first_secs, cmd.indexing.msf.first_frames, cmd.indexing.msf.last_mins, cmd.indexing.msf.last_secs, cmd.indexing.msf.last_frames);#endif return(SDL_SYS_CDioctl(cdrom->id, DKAUDIO, &cmd));}/* Pause play */static int SDL_SYS_CDPause(SDL_CD *cdrom){ struct cd_audio_cmd cmd; cmd.audio_cmds = CD_PAUSE_AUDIO; return(SDL_SYS_CDioctl(cdrom->id, DKAUDIO, &cmd));}/* Resume play */static int SDL_SYS_CDResume(SDL_CD *cdrom){ struct cd_audio_cmd cmd; cmd.audio_cmds = CD_RESUME_AUDIO; return(SDL_SYS_CDioctl(cdrom->id, DKAUDIO, &cmd));}/* Stop play */static int SDL_SYS_CDStop(SDL_CD *cdrom){ struct cd_audio_cmd cmd; cmd.audio_cmds = CD_STOP_AUDIO; return(SDL_SYS_CDioctl(cdrom->id, DKAUDIO, &cmd));}/* Eject the CD-ROM */static int SDL_SYS_CDEject(SDL_CD *cdrom){ return(SDL_SYS_CDioctl(cdrom->id, DKEJECT, 0));}/* Close the CD-ROM handle */static void SDL_SYS_CDClose(SDL_CD *cdrom){ close(cdrom->id);}void SDL_SYS_CDQuit(void){ int i; if ( SDL_numcds > 0 ) { for ( i=0; i<SDL_numcds; ++i ) { SDL_free(SDL_cdlist[i]); } SDL_numcds = 0; }}#endif /* SDL_CDROM_AIX */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -