summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSND\shalma_cp <SND\shalma_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97>2010-11-20 02:47:28 +0000
committerSND\shalma_cp <SND\shalma_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97>2010-11-20 02:47:28 +0000
commit7ee1a71ccceee4ea417dc30fdb4cf4a07d46916e (patch)
tree764f5d59ee4300834ab00740b91f34acb458c0da
parente0f61d14cb139df504d25ff205b6f5a9d34a0cdb (diff)
downloadpcsxr-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.c188
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;