diff options
| author | SND\shalma_cp <SND\shalma_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2010-11-20 02:47:28 +0000 |
|---|---|---|
| committer | SND\shalma_cp <SND\shalma_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2010-11-20 02:47:28 +0000 |
| commit | 7ee1a71ccceee4ea417dc30fdb4cf4a07d46916e (patch) | |
| tree | 764f5d59ee4300834ab00740b91f34acb458c0da | |
| parent | e0f61d14cb139df504d25ff205b6f5a9d34a0cdb (diff) | |
| download | pcsxr-7ee1a71ccceee4ea417dc30fdb4cf4a07d46916e.tar.gz | |
cdrom.c
- add basic internal subq faking (cdda games)
- allows ccd/img/no sub, bin/cue, direct cdrom (no subchannel reading), ..
git-svn-id: https://pcsxr.svn.codeplex.com/svn/pcsxr@59816 e17a0e51-4ae3-4d35-97c3-1a29b211df97
| -rw-r--r-- | libpcsxcore/cdrom.c | 188 |
1 files changed, 165 insertions, 23 deletions
diff --git a/libpcsxcore/cdrom.c b/libpcsxcore/cdrom.c index a0517bb1..25b14b69 100644 --- a/libpcsxcore/cdrom.c +++ b/libpcsxcore/cdrom.c @@ -499,6 +499,7 @@ void cdrPlayInterrupt() {
if( !cdr.Play ) return;
+ if( (cdr.Mode & 0x02) == 0 ) return;
if( CDR_getStatus(&stat) != -1) {
subq = (struct SubQ *)CDR_getBufferSub();
@@ -516,9 +517,31 @@ void cdrPlayInterrupt() Tomb Raider 1 ($7)
*/
- if( (cdr.Mode & 0x02) && cdr.CurTrack < btoi( subq->TrackNumber ) ) {
+ if( cdr.CurTrack < btoi( subq->TrackNumber ) ) {
StopCdda();
}
+ } else {
+ if (CDR_getTN(cdr.ResultTN) != -1) {
+ if( cdr.CurTrack+1 <= cdr.ResultTN[1] ) {
+ if( CDR_getTD(cdr.CurTrack+1, cdr.ResultTD) != -1 ) {
+ u8 temp_cur[3], temp_next[3];
+
+ temp_cur[0] = stat.Time[0];
+ temp_cur[1] = stat.Time[1];
+ temp_cur[2] = stat.Time[2];
+
+ temp_next[0] = cdr.ResultTD[2];
+ temp_next[1] = cdr.ResultTD[1];
+ temp_next[2] = cdr.ResultTD[0];
+
+ if( msf2sec(temp_cur) >= msf2sec( temp_next ) ) {
+ StopCdda();
+
+ cdr.CurTrack++;
+ }
+ }
+ }
+ }
}
}
@@ -602,7 +625,74 @@ void cdrRepplayInterrupt() report_time = 0; } - } + } else {
+ // Rayman: check track change
+ if (CDR_getTN(cdr.ResultTN) != -1) {
+ if( cdr.CurTrack+1 <= cdr.ResultTN[1] ) {
+ if( CDR_getTD(cdr.CurTrack+1, cdr.ResultTD) != -1 ) {
+ u8 temp_cur[3], temp_next[3];
+
+ temp_cur[0] = stat.Time[0];
+ temp_cur[1] = stat.Time[1];
+ temp_cur[2] = stat.Time[2];
+
+ temp_next[0] = cdr.ResultTD[2];
+ temp_next[1] = cdr.ResultTD[1];
+ temp_next[2] = cdr.ResultTD[0];
+
+ if( msf2sec(temp_cur) >= msf2sec( temp_next ) ) {
+ cdr.Result[0] |= 0x10;
+
+ cdr.CurTrack++;
+ }
+ }
+ }
+ }
+
+
+ // track # / index # (assume no pregaps)
+ cdr.Result[1] = cdr.CurTrack;
+ cdr.Result[2] = 1;
+
+ if( report_time == 0 ) {
+ // absolute
+ cdr.Result[3] = stat.Time[0];
+ cdr.Result[4] = stat.Time[1];
+ cdr.Result[5] = itob( stat.Time[2] );
+
+ // m:s adjustment
+ if ((s8)cdr.Result[4] < 0) {
+ cdr.Result[4] += 60;
+ cdr.Result[3] -= 1;
+ }
+
+ cdr.Result[4] = itob(cdr.Result[4]);
+ cdr.Result[5] = itob(cdr.Result[5]);
+
+ report_time = 1;
+ } else {
+ // local
+ cdr.Result[3] = stat.Time[0];
+ cdr.Result[4] = stat.Time[1] - 2;
+ cdr.Result[5] = itob( stat.Time[2] );
+
+ // m:s adjustment
+ if ((s8)cdr.Result[4] < 0) {
+ cdr.Result[4] += 60;
+ cdr.Result[3] -= 1;
+ }
+
+ cdr.Result[4] = itob(cdr.Result[4]);
+ cdr.Result[5] = itob(cdr.Result[5]);
+
+ cdr.Result[4] |= 0x80;
+
+ report_time = 0;
+ }
+
+ cdr.Result[6] = 0;
+ cdr.Result[7] = 0;
+ }
} // Rayman: Logo freeze @@ -753,6 +843,7 @@ void cdrInterrupt() { cdr.Stat = Acknowledge; cdr.StatP |= 0x80; + cdr.Play = TRUE;
// Lemmings: report play times if ((cdr.Mode & 0x5) == 0x5) { @@ -915,26 +1006,75 @@ void cdrInterrupt() { memset(cdr.Result + 2, 0, 3 + 3); // CRC wrong, wipe out time data } } - } else { - cdr.Result[0] = 1; - cdr.Result[1] = 1; - - // NOTE: This only works for TRACK 01 - cdr.Result[2] = btoi(cdr.Prev[0]); - cdr.Result[3] = btoi(cdr.Prev[1]) - 2; - cdr.Result[4] = cdr.Prev[2]; - - // m:s adjustment - if ((s8)cdr.Result[3] < 0) { - cdr.Result[3] += 60; - cdr.Result[2] -= 1; - } - - cdr.Result[2] = itob(cdr.Result[2]); - cdr.Result[3] = itob(cdr.Result[3]); - - memcpy(cdr.Result + 5, cdr.Prev, 3); - } + } else {
+ // check track change
+ if (CDR_getTN(cdr.ResultTN) != -1) {
+ if( cdr.CurTrack+1 <= cdr.ResultTN[1] ) {
+ if( CDR_getTD(cdr.CurTrack+1, cdr.ResultTD) != -1 ) {
+ u8 temp_cur[3], temp_next[3];
+
+ temp_cur[0] = btoi( stat.Time[0] );
+ temp_cur[1] = btoi( stat.Time[1] );
+ temp_cur[2] = btoi( stat.Time[2] );
+
+ temp_next[0] = cdr.ResultTD[2];
+ temp_next[1] = cdr.ResultTD[1];
+ temp_next[2] = cdr.ResultTD[0];
+
+ if( msf2sec(temp_cur) >= msf2sec( temp_next ) ) {
+ cdr.CurTrack++;
+ }
+ }
+ }
+ }
+
+
+ // assume no pregaps
+ cdr.Result[0] = cdr.CurTrack;
+ cdr.Result[1] = 1;
+
+
+ if( cdr.Play ) {
+ // NOTE: This only works for TRACK 01 (local)
+ cdr.Result[2] = stat.Time[0];
+ cdr.Result[3] = stat.Time[1]- 2;
+ cdr.Result[4] = itob( stat.Time[2] );
+
+ // m:s adjustment
+ if ((s8)cdr.Result[3] < 0) {
+ cdr.Result[3] += 60;
+ cdr.Result[2] -= 1;
+ }
+
+ cdr.Result[2] = itob(cdr.Result[2]);
+ cdr.Result[3] = itob(cdr.Result[3]);
+
+
+
+ // absolute time
+ cdr.Result[5] = itob( stat.Time[0] );
+ cdr.Result[6] = itob( stat.Time[1] );
+ cdr.Result[7] = itob( stat.Time[2] );
+ }
+ else {
+ // NOTE: This only works for TRACK 01 (local)
+ cdr.Result[2] = btoi(cdr.Prev[0]);
+ cdr.Result[3] = btoi(cdr.Prev[1]) - 2;
+ cdr.Result[4] = cdr.Prev[2];
+
+ // m:s adjustment
+ if ((s8)cdr.Result[3] < 0) {
+ cdr.Result[3] += 60;
+ cdr.Result[2] -= 1;
+ }
+
+ cdr.Result[2] = itob(cdr.Result[2]);
+ cdr.Result[3] = itob(cdr.Result[3]);
+
+
+ memcpy(cdr.Result + 5, cdr.Prev, 3);
+ }
+ }
cdr.Stat = Acknowledge; break; @@ -1994,7 +2134,9 @@ int cdrFreeze(gzFile f, int Mode) { void LidInterrupt() { cdr.LidCheck = 0x20; // start checker - +
+ CDRLID_INT( cdReadTime * 3 );
+
// generate interrupt if none active - open or close if (cdr.Irq == 0 || cdr.Irq == 0xff) { cdr.Ctrl |= 0x80; |
