summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97>2009-09-26 14:52:00 +0000
committerSND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97>2009-09-26 14:52:00 +0000
commit29a2bae5f28da187a94ec5d266e164d784277e70 (patch)
tree5d842409e4002b09e8acfe75c9161c75d6c840f0
parentb760cc0d5899b62bd321c6723be6413759bf7715 (diff)
downloadpcsxr-29a2bae5f28da187a94ec5d266e164d784277e70.tar.gz
git-svn-id: https://pcsxr.svn.codeplex.com/svn/pcsxr@30493 e17a0e51-4ae3-4d35-97c3-1a29b211df97
-rw-r--r--ChangeLog3
-rw-r--r--libpcsxcore/cdriso.c185
-rw-r--r--win32/gui/WndMain.c16
3 files changed, 163 insertions, 41 deletions
diff --git a/ChangeLog b/ChangeLog
index 76463254..ac0dc7d3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -5,6 +5,9 @@ September 26, 2009 Wei Mingzhi <weimingzhi@gmail.com>
and BIOS".
* gui/Gtk2Gui.c: Likewise.
* po/pcsx.pot, po/zh_CN.po, po/zh_TW.po, po/pt_BR.po: Updated.
+ * libpcsxcore/cdriso.c: Implemented MDS parsing. MDF files with interleaved
+ subchannel data is now supported.
+ * win32/gui/WndMain.c: Moved States submenu from File menu to Emulator menu.
September 24, 2009 Wei Mingzhi <weimingzhi@gmail.com>
diff --git a/libpcsxcore/cdriso.c b/libpcsxcore/cdriso.c
index 891af0f2..65493aaf 100644
--- a/libpcsxcore/cdriso.c
+++ b/libpcsxcore/cdriso.c
@@ -35,20 +35,21 @@
#define CD_FRAMESIZE_RAW 2352
#define DATA_SIZE (CD_FRAMESIZE_RAW - 12)
-#define CDDA_DATA_SIZE (CD_FRAMESIZE_RAW - 12 - 4)
#define SUB_FRAMESIZE 96
FILE *cdHandle = NULL;
FILE *cddaHandle = NULL;
-FILE *subHandle = NULL;
+FILE *subHandle = NULL;
+
+static char subChanInterleaved = 0;
static unsigned char cdbuffer[DATA_SIZE];
static unsigned char subbuffer[SUB_FRAMESIZE];
-static unsigned char sndbuffer[CDDA_DATA_SIZE * 10];
+static unsigned char sndbuffer[CD_FRAMESIZE_RAW * 10];
-#define CDDA_FRAMETIME (1000 * (sizeof(sndbuffer) / CDDA_DATA_SIZE) / 75)
+#define CDDA_FRAMETIME (1000 * (sizeof(sndbuffer) / CD_FRAMESIZE_RAW) / 75)
#ifdef _WIN32
static HANDLE threadid;
@@ -56,8 +57,8 @@ static HANDLE threadid;
static pthread_t threadid;
#endif
static int initial_offset = 0;
-static int playing = 0;
-static int cdda_bigendian = 0;
+static char playing = 0;
+static char cddaBigEndian = 0;
char* CALLBACK CDR__getDriveLetter(void);
long CALLBACK CDR__configure(void);
@@ -164,19 +165,24 @@ static void *playthread(void *param)
t = GetTickCount() + CDDA_FRAMETIME;
- s = 0;
-
- for (i = 0; i < sizeof(sndbuffer) / CDDA_DATA_SIZE; i++) {
- // disregard the synchronization information and header data
- fseek(cddaHandle, CD_FRAMESIZE_RAW - CDDA_DATA_SIZE, SEEK_CUR);
-
- // read one sector
- d = fread(sndbuffer + CDDA_DATA_SIZE * i, 1, CDDA_DATA_SIZE, cddaHandle);
- if (d < CDDA_DATA_SIZE) {
- break;
+ if (subChanInterleaved) {
+ s = 0;
+
+ for (i = 0; i < sizeof(sndbuffer) / CD_FRAMESIZE_RAW; i++) {
+ // read one sector
+ d = fread(sndbuffer + CD_FRAMESIZE_RAW * i, 1, CD_FRAMESIZE_RAW, cddaHandle);
+ if (d < CD_FRAMESIZE_RAW) {
+ break;
+ }
+
+ s += d;
+
+ // skip the subchannel data
+ fseek(cddaHandle, SUB_FRAMESIZE, SEEK_CUR);
}
-
- s += d;
+ }
+ else {
+ s = fread(sndbuffer, 1, sizeof(sndbuffer), cddaHandle);
}
if (s == 0) {
@@ -188,7 +194,7 @@ static void *playthread(void *param)
}
if (!cdr.Muted && playing) {
- if (cdda_bigendian) {
+ if (cddaBigEndian) {
for (i = 0; i < s / 2; i++) {
tmp = sndbuffer[i * 2];
sndbuffer[i * 2] = sndbuffer[i * 2 + 1];
@@ -246,8 +252,6 @@ static void startCDDA(unsigned int offset) {
initial_offset = offset;
fseek(cddaHandle, initial_offset, SEEK_SET);
- offset /= CD_FRAMESIZE_RAW;
-
playing = 1;
#ifdef _WIN32
threadid = (HANDLE)_beginthread(playthread, 0, NULL);
@@ -469,6 +473,105 @@ static int parseccd(const char *isofile) {
}
return 0;
+}
+
+// this function tries to get the .mds file of the given .mdf
+// the necessary data is put into the ti (trackinformation)-array
+static int parsemds(const char *isofile) {
+ char mdsname[MAXPATHLEN];
+ FILE *fi;
+ unsigned int offset, extra_offset, l, i;
+ unsigned short s;
+
+ numtracks = 0;
+
+ // copy name of the iso and change extension from .mdf to .mds
+ strncpy(mdsname, isofile, sizeof(mdsname));
+ mdsname[MAXPATHLEN - 1] = '\0';
+ if (strlen(mdsname) >= 4) {
+ strcpy(mdsname + strlen(mdsname) - 4, ".mds");
+ }
+ else {
+ return -1;
+ }
+
+ if ((fi = fopen(mdsname, "rb")) == NULL) {
+ return -1;
+ }
+
+ memset(&ti, 0, sizeof(ti));
+
+ // check if it's a valid mds file
+ fread(&i, 1, sizeof(unsigned int), fi);
+ i = SWAP32(i);
+ if (i != 0x4944454D) {
+ // not an valid mds file
+ fclose(fi);
+ return -1;
+ }
+
+ // get offset to session block
+ fseek(fi, 0x50, SEEK_SET);
+ fread(&offset, 1, sizeof(unsigned int), fi);
+ offset = SWAP32(offset);
+
+ // get total number of tracks
+ offset += 14;
+ fseek(fi, offset, SEEK_SET);
+ fread(&s, 1, sizeof(unsigned short), fi);
+ s = SWAP16(s);
+ numtracks = s;
+
+ // get offset to track blocks
+ fseek(fi, 4, SEEK_CUR);
+ fread(&offset, 1, sizeof(unsigned int), fi);
+ offset = SWAP32(offset);
+
+ // skip lead-in data
+ while (1) {
+ fseek(fi, offset + 4, SEEK_SET);
+ if (fgetc(fi) < 0xA0) {
+ break;
+ }
+ offset += 0x50;
+ }
+
+ // check if the image contains interleaved subchannel data
+ fseek(fi, offset + 1, SEEK_SET);
+ subChanInterleaved = fgetc(fi);
+
+ // read track data
+ for (i = 1; i <= numtracks; i++) {
+ fseek(fi, offset, SEEK_SET);
+
+ // get the track type
+ ti[i].type = ((fgetc(fi) == 0xA9) ? CDDA : DATA);
+ fseek(fi, 8, SEEK_CUR);
+
+ // get the track starting point
+ ti[i].start[0] = fgetc(fi);
+ ti[i].start[1] = fgetc(fi);
+ ti[i].start[2] = fgetc(fi);
+
+ if (i > 1) {
+ l = msf2sec(ti[i].start);
+ sec2msf(l - 2 * 75, ti[i].start); // ???
+ }
+
+ // get the track length
+ fread(&extra_offset, 1, sizeof(unsigned int), fi);
+ extra_offset = SWAP32(extra_offset);
+
+ fseek(fi, extra_offset + 4, SEEK_SET);
+ fread(&l, 1, sizeof(unsigned int), fi);
+ l = SWAP32(l);
+ sec2msf(l, ti[i].length);
+
+ offset += 0x50;
+ }
+
+ fclose(fi);
+ return 0;
}
// this function tries to get the .sub file of the given .img
@@ -527,10 +630,11 @@ static long CALLBACK ISOopen(void) {
SysPrintf(_("Loaded CD Image: %s"), cdrfilename);
- cdda_bigendian = 0;
+ cddaBigEndian = 0;
+ subChanInterleaved = 0;
if (parsetoc(cdrfilename) == 0) {
- cdda_bigendian = 1; // cdrdao uses big-endian for CD Audio
+ cddaBigEndian = 1; // cdrdao uses big-endian for CD Audio
SysPrintf("[+toc]");
}
else if (parsecue(cdrfilename) == 0) {
@@ -538,9 +642,12 @@ static long CALLBACK ISOopen(void) {
}
else if (parseccd(cdrfilename) == 0) {
SysPrintf("[+ccd]");
+ }
+ else if (parsemds(cdrfilename) == 0) {
+ SysPrintf("[+mds]");
}
- if (opensubfile(cdrfilename) == 0) {
+ if (!subChanInterleaved && opensubfile(cdrfilename) == 0) {
SysPrintf("[+sub]");
}
@@ -606,13 +713,20 @@ static long CALLBACK ISOreadTrack(unsigned char *time) {
if (cdHandle == NULL) {
return -1;
}
+
+ if (subChanInterleaved) {
+ fseek(cdHandle, MSF2SECT(btoi(time[0]), btoi(time[1]), btoi(time[2])) * (CD_FRAMESIZE_RAW + SUB_FRAMESIZE) + 12, SEEK_SET);
+ fread(cdbuffer, 1, DATA_SIZE, cdHandle);
+ fread(subbuffer, 1, SUB_FRAMESIZE, cdHandle);
+ }
+ else {
+ fseek(cdHandle, MSF2SECT(btoi(time[0]), btoi(time[1]), btoi(time[2])) * CD_FRAMESIZE_RAW + 12, SEEK_SET);
+ fread(cdbuffer, 1, DATA_SIZE, cdHandle);
- fseek(cdHandle, MSF2SECT(btoi(time[0]), btoi(time[1]), btoi(time[2])) * CD_FRAMESIZE_RAW + 12, SEEK_SET);
- fread(cdbuffer, 1, DATA_SIZE, cdHandle);
-
- if (subHandle != NULL) {
- fseek(subHandle, MSF2SECT(btoi(time[0]), btoi(time[1]), btoi(time[2])) * SUB_FRAMESIZE, SEEK_SET);
- fread(subbuffer, 1, SUB_FRAMESIZE, subHandle);
+ if (subHandle != NULL) {
+ fseek(subHandle, MSF2SECT(btoi(time[0]), btoi(time[1]), btoi(time[2])) * SUB_FRAMESIZE, SEEK_SET);
+ fread(subbuffer, 1, SUB_FRAMESIZE, subHandle);
+ }
}
return 0;
@@ -627,8 +741,13 @@ 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) {
- if (SPU_playCDDAchannel != NULL) {
- startCDDA(MSF2SECT(time[0], time[1], time[2]) * CD_FRAMESIZE_RAW);
+ if (SPU_playCDDAchannel != NULL) {
+ if (subChanInterleaved) {
+ startCDDA(MSF2SECT(time[0], time[1], time[2]) * (CD_FRAMESIZE_RAW + SUB_FRAMESIZE));
+ }
+ else {
+ startCDDA(MSF2SECT(time[0], time[1], time[2]) * CD_FRAMESIZE_RAW);
+ }
}
return 0;
}
@@ -641,7 +760,7 @@ static long CALLBACK ISOstop(void) {
// gets subchannel data
unsigned char* CALLBACK ISOgetBufferSub(void) {
- if (subHandle != NULL) {
+ if (subHandle != NULL || subChanInterleaved) {
return subbuffer;
}
diff --git a/win32/gui/WndMain.c b/win32/gui/WndMain.c
index 6825ea13..3b7a289e 100644
--- a/win32/gui/WndMain.c
+++ b/win32/gui/WndMain.c
@@ -1468,12 +1468,18 @@ void CreateMainMenu() {
ADDSUBMENU(0, _("&File"));
ADDMENUITEM(0, _("E&xit"), ID_FILE_EXIT);
ADDSEPARATOR(0);
- ADDSUBMENUS(0, 1, _("&States"));
- ADDSEPARATOR(0);
ADDMENUITEM(0, _("Run &EXE..."), ID_FILE_RUN_EXE);
ADDMENUITEM(0, _("Run &BIOS"), ID_FILE_RUNBIOS);
ADDMENUITEM(0, _("Run &ISO..."), ID_FILE_RUN_ISO);
ADDMENUITEM(0, _("Run &CD"), ID_FILE_RUN_CD);
+
+ ADDSUBMENU(0, _("&Emulator"));
+ ADDSUBMENUS(0, 1, _("&States"));
+ ADDSEPARATOR(0);
+ ADDMENUITEM(0, _("S&witch ISO..."), ID_EMULATOR_SWITCH_ISO);
+ ADDSEPARATOR(0);
+ ADDMENUITEM(0, _("Re&set"), ID_EMULATOR_RESET);
+ ADDMENUITEM(0, _("&Run"), ID_EMULATOR_RUN);
ADDSUBMENUS(1, 3, _("&Save"));
ADDSUBMENUS(1, 2, _("&Load"));
ADDMENUITEM(2, _("&Other..."), ID_FILE_STATES_LOAD_OTHER);
@@ -1489,12 +1495,6 @@ void CreateMainMenu() {
ADDMENUITEM(3, _("Slot &2"), ID_FILE_STATES_SAVE_SLOT2);
ADDMENUITEM(3, _("Slot &1"), ID_FILE_STATES_SAVE_SLOT1);
- ADDSUBMENU(0, _("&Emulator"));
- ADDMENUITEM(0, _("S&witch ISO..."), ID_EMULATOR_SWITCH_ISO);
- ADDSEPARATOR(0);
- ADDMENUITEM(0, _("Re&set"), ID_EMULATOR_RESET);
- ADDMENUITEM(0, _("&Run"), ID_EMULATOR_RUN);
-
ADDSUBMENU(0, _("&Configuration"));
ADDMENUITEM(0, _("Cheat &Search..."), ID_CONFIGURATION_CHEATSEARCH);
ADDMENUITEM(0, _("Ch&eat Code..."), ID_CONFIGURATION_CHEATLIST);