DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
src/dos/cdrom.cpp
00001 /*
00002  *  Copyright (C) 2002-2015  The DOSBox Team
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License
00015  *  along with this program; if not, write to the Free Software
00016  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017  */
00018 
00019 
00020 // ******************************************************
00021 // SDL CDROM 
00022 // ******************************************************
00023 
00024 #include <sys/types.h>
00025 #include <sys/stat.h>
00026 #include <unistd.h>
00027 
00028 #include "dosbox.h"
00029 #include "SDL.h"
00030 #include "support.h"
00031 #include "cdrom.h"
00032 
00033 CDROM_Interface_SDL::CDROM_Interface_SDL(void) {
00034         driveID         = 0;
00035         oldLeadOut      = 0;
00036 #if !defined(C_SDL2)
00037         cd                      = 0;
00038 #endif
00039 }
00040 
00041 CDROM_Interface_SDL::~CDROM_Interface_SDL(void) {
00042         StopAudio();
00043 #if !defined(C_SDL2)
00044         SDL_CDClose(cd);
00045         cd              = 0;
00046 #endif
00047 }
00048 
00049 bool CDROM_Interface_SDL::SetDevice(char* path, int forceCD) { 
00050     (void)forceCD;//UNUSED
00051         char buffer[512];
00052         strcpy(buffer,path);
00053         upcase(buffer);
00054 
00055 #if !defined(C_SDL2)
00056         int num = SDL_CDNumDrives();
00057         if ((forceCD>=0) && (forceCD<num)) {
00058                 driveID = forceCD;
00059                 cd = SDL_CDOpen(driveID);
00060                 SDL_CDStatus(cd);
00061                 return true;
00062         };      
00063         
00064         const char* cdname = 0;
00065         for (int i=0; i<num; i++) {
00066                 cdname = SDL_CDName(i);
00067                 if (strcmp(buffer,cdname)==0) {
00068                         cd = SDL_CDOpen(i);
00069                         SDL_CDStatus(cd);
00070                         driveID = i;
00071                         return true;
00072                 };
00073         };
00074 #endif
00075 
00076         return false; 
00077 }
00078 
00079 bool CDROM_Interface_SDL::ReadSectorsHost(void *buffer, bool raw, unsigned long sector, unsigned long num)
00080 {
00081     (void)sector;//UNUSED
00082     (void)buffer;//UNUSED
00083     (void)raw;//UNUSED
00084     (void)num;//UNUSED
00085         return false;/*TODO*/
00086 }
00087 
00088 bool CDROM_Interface_SDL::GetAudioTracks(int& stTrack, int& end, TMSF& leadOut) {
00089     (void)leadOut;//POSSIBLY UNUSED
00090     (void)stTrack;//POSSIBLY UNUSED
00091     (void)end;//POSSIBLY UNUSED
00092 #if !defined(C_SDL2)
00093         if (CD_INDRIVE(SDL_CDStatus(cd))) {
00094                 stTrack         = 1;
00095                 end                     = cd->numtracks;
00096                 FRAMES_TO_MSF(cd->track[cd->numtracks].offset,&leadOut.min,&leadOut.sec,&leadOut.fr);
00097         }
00098         return CD_INDRIVE(SDL_CDStatus(cd));
00099 #else
00100     return false;
00101 #endif
00102 }
00103 
00104 bool CDROM_Interface_SDL::GetAudioTrackInfo(int track, TMSF& start, unsigned char& attr) {
00105     (void)track;//POSSIBLY UNUSED
00106     (void)start;//POSSIBLY UNUSED
00107     (void)attr;//POSSIBLY UNUSED
00108 #if !defined(C_SDL2)
00109         if (CD_INDRIVE(SDL_CDStatus(cd))) {
00110                 FRAMES_TO_MSF(cd->track[track-1].offset,&start.min,&start.sec,&start.fr);
00111                 attr    = cd->track[track-1].type<<4;//sdl uses 0 for audio and 4 for data. instead of 0x00 and 0x40
00112         }
00113         return CD_INDRIVE(SDL_CDStatus(cd));    
00114 #else
00115     return false;
00116 #endif
00117 }
00118 
00119 bool CDROM_Interface_SDL::GetAudioSub(unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) {
00120     (void)absPos;//POSSIBLY UNUSED
00121     (void)relPos;//POSSIBLY UNUSED
00122     (void)index;//POSSIBLY UNUSED
00123     (void)track;//POSSIBLY UNUSED
00124     (void)attr;//POSSIBLY UNUSED
00125 #if !defined(C_SDL2)
00126         if (CD_INDRIVE(SDL_CDStatus(cd))) {
00127                 track   = cd->cur_track;
00128                 index   = cd->cur_track;
00129                 attr    = cd->track[track].type<<4;
00130                 FRAMES_TO_MSF((unsigned int)cd->cur_frame,&relPos.min,&relPos.sec,&relPos.fr);
00131                 FRAMES_TO_MSF((unsigned int)cd->cur_frame+cd->track[track].offset,&absPos.min,&absPos.sec,&absPos.fr);
00132         }
00133         return CD_INDRIVE(SDL_CDStatus(cd));            
00134 #else
00135     return false;
00136 #endif
00137 }
00138 
00139 bool CDROM_Interface_SDL::GetAudioStatus(bool& playing, bool& pause){
00140     (void)playing;//POSSIBLY UNUSED
00141     (void)pause;//POSSIBLY UNUSED
00142 #if !defined(C_SDL2)
00143         if (CD_INDRIVE(SDL_CDStatus(cd))) {
00144                 playing = (cd->status==CD_PLAYING);
00145                 pause   = (cd->status==CD_PAUSED);
00146         }
00147         return CD_INDRIVE(SDL_CDStatus(cd));
00148 #else
00149     return false;
00150 #endif
00151 }
00152         
00153 bool CDROM_Interface_SDL::GetMediaTrayStatus(bool& mediaPresent, bool& mediaChanged, bool& trayOpen) {
00154     (void)mediaPresent;//POSSIBLY UNUSED
00155     (void)mediaChanged;//POSSIBLY UNUSED
00156     (void)trayOpen;//POSSIBLY UNUSED
00157 #if !defined(C_SDL2)
00158         SDL_CDStatus(cd);
00159         mediaPresent = (cd->status!=CD_TRAYEMPTY) && (cd->status!=CD_ERROR);
00160         mediaChanged = (oldLeadOut!=cd->track[cd->numtracks].offset);
00161         trayOpen         = !mediaPresent;
00162         oldLeadOut       = cd->track[cd->numtracks].offset;
00163         if (mediaChanged) SDL_CDStatus(cd);
00164         return true;
00165 #else
00166     return false;
00167 #endif
00168 }
00169 
00170 bool CDROM_Interface_SDL::PlayAudioSector(unsigned long start,unsigned long len) { 
00171     (void)start;//POSSIBLY UNUSED
00172     (void)len;//POSSIBLY UNUSED
00173 #if !defined(C_SDL2)
00174         // Has to be there, otherwise wrong cd status report (dunno why, sdl bug ?)
00175         SDL_CDClose(cd);
00176         cd = SDL_CDOpen(driveID);
00177         bool success = (SDL_CDPlay(cd,start+150,len)==0);
00178         return success;
00179 #else
00180     return false;
00181 #endif
00182 }
00183 
00184 bool CDROM_Interface_SDL::PauseAudio(bool resume) { 
00185     (void)resume;//POSSIBLY UNUSED
00186 #if !defined(C_SDL2)
00187         bool success;
00188         if (resume) success = (SDL_CDResume(cd)==0);
00189         else            success = (SDL_CDPause (cd)==0);
00190         return success;
00191 #else
00192     return false;
00193 #endif
00194 }
00195 
00196 bool CDROM_Interface_SDL::StopAudio(void) {
00197 #if !defined(C_SDL2)
00198         // Has to be there, otherwise wrong cd status report (dunno why, sdl bug ?)
00199         SDL_CDClose(cd);
00200         cd = SDL_CDOpen(driveID);
00201         bool success = (SDL_CDStop(cd)==0);
00202         return success;
00203 #else
00204     return false;
00205 #endif
00206 }
00207 
00208 bool CDROM_Interface_SDL::LoadUnloadMedia(bool unload) {
00209     (void)unload;//UNUSED
00210 #if !defined(C_SDL2)
00211         bool success = (SDL_CDEject(cd)==0);
00212         return success;
00213 #else
00214     return false;
00215 #endif
00216 }
00217 
00218 int CDROM_GetMountType(char* path, int forceCD) {
00219     (void)forceCD;
00220 // 0 - physical CDROM
00221 // 1 - Iso file
00222 // 2 - subdirectory
00223         // 1. Smells like a real cdrom 
00224         // if ((strlen(path)<=3) && (path[2]=='\\') && (strchr(path,'\\')==strrchr(path,'\\')) &&       (GetDriveType(path)==DRIVE_CDROM)) return 0;
00225 
00226         char buffer[512];
00227         strcpy(buffer,path);
00228 #if defined (WIN32) || defined(OS2)
00229         upcase(buffer);
00230 #endif
00231 
00232 #if !defined(C_SDL2)
00233         const char* cdName;
00234         int num = SDL_CDNumDrives();
00235         // If cd drive is forced then check if its in range and return 0
00236         if ((forceCD>=0) && (forceCD<num)) {
00237                 LOG(LOG_ALL,LOG_ERROR)("CDROM: Using drive %d",forceCD);
00238                 return 0;
00239         }
00240 
00241         // compare names
00242         for (int i=0; i<num; i++) {
00243                 cdName = SDL_CDName(i);
00244                 if (strcmp(buffer,cdName)==0) return 0;
00245         };
00246 #endif
00247         
00248         // Detect ISO
00249         struct stat file_stat;
00250         if ((stat(path, &file_stat) == 0) && (file_stat.st_mode & S_IFREG)) return 1; 
00251         return 2;
00252 }
00253 
00254 // ******************************************************
00255 // Fake CDROM
00256 // ******************************************************
00257 
00258 bool CDROM_Interface_Fake :: GetAudioTracks(int& stTrack, int& end, TMSF& leadOut) {
00259         stTrack = end = 1;
00260         leadOut.min     = 60;
00261         leadOut.sec = leadOut.fr = 0;
00262         return true;
00263 }
00264 
00265 bool CDROM_Interface_Fake :: GetAudioTrackInfo(int track, TMSF& start, unsigned char& attr) {
00266         if (track>1) return false;
00267         start.min = start.fr = 0;
00268         start.sec = 2;
00269         attr      = 0x60; // data / permitted
00270         return true;
00271 }
00272 
00273 bool CDROM_Interface_Fake :: GetAudioSub(unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos){
00274         attr    = 0;
00275         track   = index = 1;
00276         relPos.min = relPos.fr = 0; relPos.sec = 2;
00277         absPos.min = absPos.fr = 0; absPos.sec = 2;
00278         return true;
00279 }
00280 
00281 bool CDROM_Interface_Fake :: GetAudioStatus(bool& playing, bool& pause) {
00282         playing = pause = false;
00283         return true;
00284 }
00285 
00286 bool CDROM_Interface_Fake :: GetMediaTrayStatus(bool& mediaPresent, bool& mediaChanged, bool& trayOpen) {
00287         mediaPresent = true;
00288         mediaChanged = false;
00289         trayOpen     = false;
00290         return true;
00291 }
00292 
00293 bool CDROM_Interface_Fake::ReadSectorsHost(void *buffer, bool raw, unsigned long sector, unsigned long num)
00294 {
00295     (void)buffer;//UNUSED
00296     (void)sector;//UNUSED
00297     (void)raw;//UNUSED
00298     (void)num;//UNUSED
00299         return false;/*TODO*/
00300 }
00301 
00302