summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97>2010-07-02 01:07:34 +0000
committerSND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97>2010-07-02 01:07:34 +0000
commit5dcf4b91e7d25dfcf589caaee8fff4a878e5f812 (patch)
tree5a7173ada4f17dcde230dece09def3c73df6ab02
parent38f379212bfe18667cfc754f4f0c8f303d34f930 (diff)
downloadpcsxr-5dcf4b91e7d25dfcf589caaee8fff4a878e5f812.tar.gz
support for subchannel data ripped by cdrdao
git-svn-id: https://pcsxr.svn.codeplex.com/svn/pcsxr@54050 e17a0e51-4ae3-4d35-97c3-1a29b211df97
-rw-r--r--ChangeLog7
-rw-r--r--libpcsxcore/cdriso.c50
2 files changed, 50 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index e7eacd65..c54c9852 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+July 2, 2010 Wei Mingzhi <whistler_wmz@users.sf.net>
+
+ * libpcsxcore/cdriso.c: Fixed subchannel data handling with images ripped
+ with cdrdao. Removed support for AcetoneISO. Parse .cue file as .toc file
+ when needed to satisfy some stupid tutorials which tell users to use cdrdao
+ to rip a "bin/cue" image which is in fact a "bin/toc" image.
+
July 2, 2010 edgbla <edgbla@yandex.ru>
* po/ru_RU.po: Updated.
diff --git a/libpcsxcore/cdriso.c b/libpcsxcore/cdriso.c
index bdd21554..a6beecf4 100644
--- a/libpcsxcore/cdriso.c
+++ b/libpcsxcore/cdriso.c
@@ -36,6 +36,7 @@ static FILE *cddaHandle = NULL;
static FILE *subHandle = NULL;
static boolean subChanInterleaved = FALSE;
+static boolean subChanRaw = FALSE;
static unsigned char cdbuffer[DATA_SIZE];
static unsigned char subbuffer[SUB_FRAMESIZE];
@@ -139,7 +140,7 @@ static void *playthread(void *param)
#endif
{
long d, t, i, s;
- unsigned char tmp;
+ unsigned short tmp;
t = GetTickCount();
@@ -281,8 +282,8 @@ static int parsetoc(const char *isofile) {
}
if ((fi = fopen(tocname, "r")) == NULL) {
- // check for image.bin.toc (for AcetoneISO)
- sprintf(tocname, "%s.toc", isofile);
+ // try changing extension to .cue (to satisfy some stupid tutorials)
+ strcpy(tocname + strlen(tocname) - 4, ".cue");
if ((fi = fopen(tocname, "r")) == NULL) {
// if filename is image.toc.bin, try removing .bin (for Brasero)
strcpy(tocname, isofile);
@@ -323,6 +324,7 @@ static int parsetoc(const char *isofile) {
token = strtok(NULL, " ");
if (token != NULL && !strncmp(token, "RW_RAW", 6)) {
subChanInterleaved = TRUE;
+ subChanRaw = TRUE;
}
}
else if (!strncmp(token, "AUDIO", 5)) {
@@ -384,6 +386,19 @@ static int parsecue(const char *isofile) {
return -1;
}
+ // Some stupid tutorials wrongly tell users to use cdrdao to rip a
+ // "bin/cue" image, which is in fact a "bin/toc" image. So let's check
+ // that...
+ if (fgets(linebuf, sizeof(linebuf), fi) != NULL) {
+ if (!strncmp(linebuf, "CD_ROM_XA", 9)) {
+ // Don't proceed further, as this is actually a .toc file rather
+ // than a .cue file.
+ fclose(fi);
+ return parsetoc(isofile);
+ }
+ fseek(fi, 0, SEEK_SET);
+ }
+
memset(&ti, 0, sizeof(ti));
while (fgets(linebuf, sizeof(linebuf), fi) != NULL) {
@@ -663,13 +678,14 @@ static long CALLBACK ISOopen(void) {
cddaBigEndian = FALSE;
subChanInterleaved = FALSE;
+ subChanRaw = FALSE;
- if (parsetoc(GetIsoFile()) == 0) {
- SysPrintf("[+toc]");
- }
- else if (parsecue(GetIsoFile()) == 0) {
+ if (parsecue(GetIsoFile()) == 0) {
SysPrintf("[+cue]");
}
+ else if (parsetoc(GetIsoFile()) == 0) {
+ SysPrintf("[+toc]");
+ }
else if (parseccd(GetIsoFile()) == 0) {
SysPrintf("[+ccd]");
}
@@ -782,6 +798,22 @@ static unsigned short calcCrc(unsigned char *d, int len) {
return ~crc;
}
+// decode 'raw' subchannel data ripped by cdrdao
+static void DecodeRawSubData(void) {
+ unsigned char subQData[12];
+ int i;
+
+ memset(subQData, 0, sizeof(subQData));
+
+ for (i = 0; i < 8 * 12; i++) {
+ if (subbuffer[i] & (1 << 6)) { // only subchannel Q is needed
+ subQData[i >> 3] |= (1 << (7 - (i & 7)));
+ }
+ }
+
+ memcpy(&subbuffer[12], subQData, 12);
+}
+
// read track
// time: byte 0 - minute; byte 1 - second; byte 2 - frame
// uses bcd format
@@ -795,6 +827,8 @@ static long CALLBACK ISOreadTrack(unsigned char *time) {
fread(cdbuffer, 1, DATA_SIZE, cdHandle);
fread(subbuffer, 1, SUB_FRAMESIZE, cdHandle);
+ if (subChanRaw) DecodeRawSubData();
+
if ((((u16)subbuffer[22] << 8) | (u16)subbuffer[23]) != calcCrc(&subbuffer[12], 10)) {
memset(&subbuffer[15], 0, 7); // CRC wrong, wipe out time data
}
@@ -807,6 +841,8 @@ static long CALLBACK ISOreadTrack(unsigned char *time) {
fseek(subHandle, MSF2SECT(btoi(time[0]), btoi(time[1]), btoi(time[2])) * SUB_FRAMESIZE, SEEK_SET);
fread(subbuffer, 1, SUB_FRAMESIZE, subHandle);
+ if (subChanRaw) DecodeRawSubData();
+
if ((((u16)subbuffer[22] << 8) | (u16)subbuffer[23]) != calcCrc(&subbuffer[12], 10)) {
memset(&subbuffer[15], 0, 7); // CRC wrong, wipe out time data
}