X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=pcsx_rearmed.git;a=blobdiff_plain;f=libpcsxcore%2Fcdriso.c;h=2d371dd232604d9ba18fbcd730665cef4c04dc5a;hp=18b0de922b3bb8cc75c6fbafe5ff8cde814d26c9;hb=009faf24e665b66283558234920faab03b781d6c;hpb=ef79bbde537d6b9c745a7d86cb9df1d04c35590d diff --git a/libpcsxcore/cdriso.c b/libpcsxcore/cdriso.c index 18b0de92..2d371dd2 100644 --- a/libpcsxcore/cdriso.c +++ b/libpcsxcore/cdriso.c @@ -22,6 +22,7 @@ #include "plugins.h" #include "cdrom.h" #include "cdriso.h" +#include "ppf.h" #ifdef _WIN32 #include @@ -51,9 +52,10 @@ static HANDLE threadid; static pthread_t threadid; #endif static unsigned int initial_offset = 0; -static volatile boolean playing = FALSE; +static boolean playing = FALSE; static boolean cddaBigEndian = FALSE; -static volatile unsigned int cddaCurOffset = 0; +static unsigned int cddaCurOffset = 0; +static unsigned int cddaStartOffset; char* CALLBACK CDR__getDriveLetter(void); long CALLBACK CDR__configure(void); @@ -68,6 +70,7 @@ struct trackinfo { enum {DATA, CDDA} type; char start[3]; // MSF-format char length[3]; // MSF-format + FILE *handle; // for multi-track images CDDA }; #define MAXTRACKS 100 /* How many tracks can a CD hold? */ @@ -157,6 +160,12 @@ static void *playthread(void *param) #else usleep(d * 1000); #endif + // HACK: stop feeding data while emu is paused + extern int stop; + if (stop) { + usleep(100000); + continue; + } t = GetTickCount() + CDDA_FRAMETIME; @@ -182,8 +191,6 @@ static void *playthread(void *param) if (s == 0) { playing = FALSE; - fclose(cddaHandle); - cddaHandle = NULL; initial_offset = 0; break; } @@ -224,11 +231,6 @@ static void stopCDDA() { pthread_join(threadid, NULL); #endif - if (cddaHandle != NULL) { - fclose(cddaHandle); - cddaHandle = NULL; - } - initial_offset = 0; } @@ -241,11 +243,6 @@ static void startCDDA(unsigned int offset) { stopCDDA(); } - cddaHandle = fopen(GetIsoFile(), "rb"); - if (cddaHandle == NULL) { - return; - } - initial_offset = offset; cddaCurOffset = initial_offset; fseek(cddaHandle, initial_offset, SEEK_SET); @@ -363,12 +360,15 @@ static int parsetoc(const char *isofile) { // the necessary data is put into the ti (trackinformation)-array static int parsecue(const char *isofile) { char cuename[MAXPATHLEN]; + char filepath[MAXPATHLEN]; + char *incue_fname; FILE *fi; char *token; char time[20]; char *tmp; char linebuf[256], dummy[256]; - unsigned int t; + unsigned int incue_max_len; + unsigned int t, i, total, file_len; numtracks = 0; @@ -399,6 +399,18 @@ static int parsecue(const char *isofile) { fseek(fi, 0, SEEK_SET); } + // build a path for files referenced in .cue + strncpy(filepath, cuename, sizeof(filepath)); + tmp = strrchr(filepath, '/') + 1; + if (tmp == NULL) + tmp = strrchr(filepath, '\\') + 1; + if (tmp == NULL) + tmp = filepath; + *tmp = 0; + filepath[sizeof(filepath) - 1] = 0; + incue_fname = tmp; + incue_max_len = sizeof(filepath) - (tmp - filepath) - 1; + memset(&ti, 0, sizeof(ti)); while (fgets(linebuf, sizeof(linebuf), fi) != NULL) { @@ -431,22 +443,65 @@ static int parsecue(const char *isofile) { t = msf2sec(ti[numtracks].start) + 2 * 75; sec2msf(t, ti[numtracks].start); + } + else if (!strcmp(token, "FILE")) { + tmp = strstr(linebuf, "FILE"); + if (tmp == NULL) { + continue; + } + tmp += 4; + while (*tmp == ' ') + tmp++; + if (*tmp == '"') { + token = tmp + 1; + tmp = strchr(token, '"'); + if (tmp != NULL) + *tmp = 0; + } + else { + token = tmp; + tmp = strchr(token, ' '); + if (tmp != NULL) + *tmp = 0; + } - // If we've already seen another track, this is its end - if (numtracks > 1) { - t = msf2sec(ti[numtracks].start) - msf2sec(ti[numtracks - 1].start); - sec2msf(t, ti[numtracks - 1].length); + strncpy(incue_fname, token, incue_max_len); + ti[numtracks + 1].handle = fopen(filepath, "rb"); + if (ti[numtracks + 1].handle == NULL) { + SysPrintf(_("could not open: %s\n"), filepath); + } + else if (numtracks == 0 && strlen(isofile) >= 4 && + strcmp(isofile + strlen(isofile) - 4, ".cue") == 0) { + // user selected .cue as image file, use it's data track instead + fclose(cdHandle); + cdHandle = fopen(filepath, "rb"); } } } fclose(fi); - // Fill out the last track's end based on size - if (numtracks >= 1) { - fseek(cdHandle, 0, SEEK_END); - t = ftell(cdHandle) / 2352 - msf2sec(ti[numtracks].start) + 2 * 75; - sec2msf(t, ti[numtracks].length); + // make corrections for multi-track .cue, fill track lengths + total = 2 * 75; + file_len = 0; + for (i = 1; i <= numtracks; i++) { + if (ti[i].handle != NULL) { + sec2msf(total, ti[i].start); + fseek(ti[i].handle, 0, SEEK_END); + file_len = ftell(ti[i].handle) / 2352; + sec2msf(file_len, ti[i].length); + total += file_len; + } + else { + // this track uses the same file as the last, + // start of this track is last track's end + if (i > 1) { + t = msf2sec(ti[i].start) - msf2sec(ti[i - 1].start); + sec2msf(t, ti[i - 1].length); + } + t = file_len - msf2sec(ti[i].start) + 2 * 75; + sec2msf(t, ti[i].length); + } } return 0; @@ -631,24 +686,23 @@ static int opensubfile(const char *isoname) { return 0; } -static long CALLBACK ISOinit(void) { - assert(cdHandle == NULL); - assert(subHandle == NULL); - - return 0; // do nothing -} +static int opensbifile(const char *isoname) { + char sbiname[MAXPATHLEN]; + int s; -static long CALLBACK ISOshutdown(void) { - if (cdHandle != NULL) { - fclose(cdHandle); - cdHandle = NULL; + strncpy(sbiname, isoname, sizeof(sbiname)); + sbiname[MAXPATHLEN - 1] = '\0'; + if (strlen(sbiname) >= 4) { + strcpy(sbiname + strlen(sbiname) - 4, ".sbi"); } - if (subHandle != NULL) { - fclose(subHandle); - subHandle = NULL; + else { + return -1; } - stopCDDA(); - return 0; + + fseek(cdHandle, 0, SEEK_END); + s = ftell(cdHandle) / 2352; + + return LoadSBI(sbiname, s); } static void PrintTracks(void) { @@ -696,15 +750,26 @@ static long CALLBACK ISOopen(void) { if (!subChanMixed && opensubfile(GetIsoFile()) == 0) { SysPrintf("[+sub]"); } + if (opensbifile(GetIsoFile()) == 0) { + SysPrintf("[+sbi]"); + } SysPrintf(".\n"); PrintTracks(); + // make sure we have another handle open for cdda + if (numtracks > 1 && ti[1].handle == NULL) { + ti[1].handle = fopen(GetIsoFile(), "rb"); + } + cddaCurOffset = cddaStartOffset = 0; + return 0; } static long CALLBACK ISOclose(void) { + int i; + if (cdHandle != NULL) { fclose(cdHandle); cdHandle = NULL; @@ -714,6 +779,29 @@ static long CALLBACK ISOclose(void) { subHandle = NULL; } stopCDDA(); + cddaHandle = NULL; + + for (i = 1; i <= numtracks; i++) { + if (ti[i].handle != NULL) { + fclose(ti[i].handle); + ti[i].handle = NULL; + } + } + numtracks = 0; + UnloadSBI(); + + return 0; +} + +static long CALLBACK ISOinit(void) { + assert(cdHandle == NULL); + assert(subHandle == NULL); + + return 0; // do nothing +} + +static long CALLBACK ISOshutdown(void) { + ISOclose(); return 0; } @@ -740,7 +828,17 @@ static long CALLBACK ISOgetTN(unsigned char *buffer) { // byte 1 - second // byte 2 - minute static long CALLBACK ISOgetTD(unsigned char track, unsigned char *buffer) { - if (numtracks > 0 && track <= numtracks) { + if (track == 0) { + // CD length according pcsxr-svn (done a bit different here) + unsigned int sect; + unsigned char time[3]; + sect = msf2sec(ti[numtracks].start) + msf2sec(ti[numtracks].length); + sec2msf(sect, time); + buffer[2] = time[0]; + buffer[1] = time[1]; + buffer[0] = time[2]; + } + else if (numtracks > 0 && track <= numtracks) { buffer[2] = ti[track].start[0]; buffer[1] = ti[track].start[1]; buffer[0] = ti[track].start[2]; @@ -809,12 +907,32 @@ static unsigned char * CALLBACK ISOgetBuffer(void) { // sector: byte 0 - minute; byte 1 - second; byte 2 - frame // does NOT uses bcd format static long CALLBACK ISOplay(unsigned char *time) { + unsigned int i, sect; + + if (numtracks <= 1) + return 0; + + // find the track + sect = msf2sec(time); + for (i = numtracks; i > 1; i--) + if (msf2sec(ti[i].start) <= sect + 2 * 75) + break; + + // find the file that contains this track + for (; i > 1; i--) + if (ti[i].handle != NULL) + break; + + cddaStartOffset = msf2sec(ti[i].start); + sect -= cddaStartOffset - 2 * 75; + cddaHandle = ti[i].handle; + if (SPU_playCDDAchannel != NULL) { if (subChanMixed) { - startCDDA(MSF2SECT(time[0], time[1], time[2]) * (CD_FRAMESIZE_RAW + SUB_FRAMESIZE)); + startCDDA(sect * (CD_FRAMESIZE_RAW + SUB_FRAMESIZE)); } else { - startCDDA(MSF2SECT(time[0], time[1], time[2]) * CD_FRAMESIZE_RAW); + startCDDA(sect * CD_FRAMESIZE_RAW); } } return 0; @@ -843,13 +961,14 @@ static long CALLBACK ISOgetStatus(struct CdrStat *stat) { if (playing) { stat->Type = 0x02; stat->Status |= 0x80; - sec = cddaCurOffset / CD_FRAMESIZE_RAW; - sec2msf(sec, (char *)stat->Time); } else { stat->Type = 0x01; } + sec = (cddaStartOffset + cddaCurOffset) / CD_FRAMESIZE_RAW; + sec2msf(sec, (char *)stat->Time); + return 0; }