handle mixed mode cues more properly

This commit is contained in:
zeromus 2015-07-01 06:17:57 -05:00
parent 1de6033c0a
commit 675853e7a3
1 changed files with 73 additions and 59 deletions

View File

@ -197,7 +197,7 @@ namespace BizHawk.Emulation.DiscSystem
CompiledCueTrack cct = ti.CompiledCueTrack; CompiledCueTrack cct = ti.CompiledCueTrack;
//--------------------------------- //---------------------------------
//generate track pregap //setup track pregap processing
//per "Example 05" on digitalx.org, pregap can come from index specification and pregap command //per "Example 05" on digitalx.org, pregap can come from index specification and pregap command
int specifiedPregapLength = cct.PregapLength.Sector; int specifiedPregapLength = cct.PregapLength.Sector;
int impliedPregapLength = cct.Indexes[1].FileMSF.Sector - cct.Indexes[0].FileMSF.Sector; int impliedPregapLength = cct.Indexes[1].FileMSF.Sector - cct.Indexes[0].FileMSF.Sector;
@ -209,31 +209,6 @@ namespace BizHawk.Emulation.DiscSystem
//read more at policies declaration //read more at policies declaration
if (!context.DiscMountPolicy.CUE_PauseContradictionModeA) if (!context.DiscMountPolicy.CUE_PauseContradictionModeA)
relMSF += 1; relMSF += 1;
for (int s = 0; s < specifiedPregapLength; s++)
{
var se = new SectorEntry(null);
SS_Base ss;
if (cct.TrackType == CueFile.TrackType.Audio) ss = new SS_AudioGap();
else ss = new SS_DataGap();
//-subq-
byte ADR = 1;
ss.sq.SetStatus(ADR, (EControlQ)(int)cct.Flags);
ss.sq.q_tno = BCD2.FromDecimal(cct.Number);
ss.sq.q_index = BCD2.FromDecimal(0);
ss.sq.AP_Timestamp = new Timestamp(OUT_Disc.Sectors.Count);
ss.sq.Timestamp = new Timestamp(relMSF);
//-subP-
//always paused--is this good enough? (probably not, theres detailed handling commented out at the end of this file)
ss.Pause = true;
se.SectorSynth = ss;
OUT_Disc.Sectors.Add(se);
relMSF++;
}
//--------------------------------- //---------------------------------
@ -255,54 +230,94 @@ namespace BizHawk.Emulation.DiscSystem
{ {
bool trackDone = false; bool trackDone = false;
//select the appropriate index by inspecting the next index and seeing if we've reached it if (specifiedPregapLength > 0)
for (; ; )
{ {
if (curr_index == cct.Indexes.Count - 1) //if burning through a specified pregap, count it down
break; specifiedPregapLength--;
if (curr_blobMSF >= cct.Indexes[curr_index + 1].FileMSF.Sector) }
else
{
//if burning through the file, select the appropriate index by inspecting the next index and seeing if we've reached it
for (; ; )
{ {
curr_index++; if (curr_index == cct.Indexes.Count - 1)
if (curr_index == 1) break;
if (curr_blobMSF >= cct.Indexes[curr_index + 1].FileMSF.Sector)
{ {
//WE ARE NOW AT INDEX 1: generate the RawTOCEntry for this track curr_index++;
EmitRawTOCEntry(cct); if (curr_index == 1)
} {
//WE ARE NOW AT INDEX 1: generate the RawTOCEntry for this track
EmitRawTOCEntry(cct);
}
//in the weird mednafen mode, we need to adjust relMSF to be 0 since we pre-adjusted it once //in the weird mednafen mode, we need to adjust relMSF to be 0 since we pre-adjusted it once
if (!context.DiscMountPolicy.CUE_PauseContradictionModeA && relMSF == 1) if (!context.DiscMountPolicy.CUE_PauseContradictionModeA && relMSF == 1)
relMSF = 0; relMSF = 0;
else else
if (relMSF != 0) throw new InvalidOperationException(); if (relMSF != 0) throw new InvalidOperationException();
}
else break;
} }
else break;
} }
//generate a sector: //generate a sector:
SS_Base ss = null; SS_Base ss = null;
switch (cct.TrackType) EControlQ qFlags = (EControlQ)(int)cct.Flags;
if (curr_index == 0)
{ {
case CueFile.TrackType.Mode1_2048: //generating pregap:
ss = new SS_Mode1_2048() { Blob = curr_blobInfo.Blob, BlobOffset = curr_blobOffset }; bool audioGap = true;
curr_blobOffset += 2048;
break;
default: //normally the gap takes this track's type
case CueFile.TrackType.Mode2_2336: if (cct.TrackType != CueFile.TrackType.Audio) audioGap = false;
throw new InvalidOperationException("Not supported: " + cct.TrackType);
case CueFile.TrackType.CDI_2352: //now for something special.
case CueFile.TrackType.Mode1_2352: //[IEC10149] says there's two "intervals" of a pregap.
case CueFile.TrackType.Mode2_2352: //mednafen's pseudocode interpretation of this:
case CueFile.TrackType.Audio: //if this is a data track and the previous track was not data, the last 150 sectors of the pregap match this track and the earlier sectors (at least 75) math the previous track
ss = new SS_2352() { Blob = curr_blobInfo.Blob, BlobOffset = curr_blobOffset }; //I agree, so let's do it that way
curr_blobOffset += 2352; if (t != 1 && cct.TrackType != CueFile.TrackType.Audio && TrackInfos[t - 1].CompiledCueTrack.TrackType == CueFile.TrackType.Audio)
break; {
//there may be an off by one error here depending on the CUE_PauseContradictionModeA setting.. not really sure.
if (relMSF <= -150)
{
qFlags = (EControlQ)(int)TrackInfos[t - 1].CompiledCueTrack.Flags;
audioGap = true;
}
}
if(audioGap) ss = new SS_AudioGap(); else ss = new SS_DataGap();
}
else
{
//generating normal index 1+ sector
switch (cct.TrackType)
{
case CueFile.TrackType.Mode1_2048:
ss = new SS_Mode1_2048() { Blob = curr_blobInfo.Blob, BlobOffset = curr_blobOffset };
curr_blobOffset += 2048;
break;
case CueFile.TrackType.CDI_2352:
case CueFile.TrackType.Mode1_2352:
case CueFile.TrackType.Mode2_2352:
case CueFile.TrackType.Audio:
ss = new SS_2352() { Blob = curr_blobInfo.Blob, BlobOffset = curr_blobOffset };
curr_blobOffset += 2352;
break;
default:
case CueFile.TrackType.Mode2_2336:
throw new InvalidOperationException("Not supported: " + cct.TrackType);
}
curr_blobMSF++;
} }
//setup subQ //setup subQ
byte ADR = 1; //absent some kind of policy for how to set it, this is a safe assumption: byte ADR = 1; //absent some kind of policy for how to set it, this is a safe assumption:
ss.sq.SetStatus(ADR, (EControlQ)(int)cct.Flags); ss.sq.SetStatus(ADR, qFlags);
ss.sq.q_tno = BCD2.FromDecimal(cct.Number); ss.sq.q_tno = BCD2.FromDecimal(cct.Number);
ss.sq.q_index = BCD2.FromDecimal(curr_index); ss.sq.q_index = BCD2.FromDecimal(curr_index);
ss.sq.AP_Timestamp = new Timestamp(OUT_Disc.Sectors.Count); ss.sq.AP_Timestamp = new Timestamp(OUT_Disc.Sectors.Count);
@ -316,7 +331,6 @@ namespace BizHawk.Emulation.DiscSystem
var se = new SectorEntry(null); var se = new SectorEntry(null);
se.SectorSynth = ss; se.SectorSynth = ss;
OUT_Disc.Sectors.Add(se); OUT_Disc.Sectors.Add(se);
curr_blobMSF++;
relMSF++; relMSF++;
if (cct.IsFinalInFile) if (cct.IsFinalInFile)