begin rebuilding cue loading based on the new cue compiling system
This commit is contained in:
parent
3c26d48a59
commit
7deb5e8575
|
@ -258,7 +258,7 @@ namespace BizHawk.Client.DiscoHawk
|
||||||
//verify sector count
|
//verify sector count
|
||||||
if (src_disc.LBACount != dst_disc.LBACount)
|
if (src_disc.LBACount != dst_disc.LBACount)
|
||||||
{
|
{
|
||||||
sw.Write("LBACount count {0} vs {1}", src_disc.LBACount, dst_disc.LBACount);
|
sw.Write("LBACount count {0} vs {1}\n", src_disc.LBACount, dst_disc.LBACount);
|
||||||
goto SKIPPO;
|
goto SKIPPO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,7 +71,8 @@
|
||||||
<Compile Include="cdfs\ISONode.cs" />
|
<Compile Include="cdfs\ISONode.cs" />
|
||||||
<Compile Include="cdfs\ISONodeRecord.cs" />
|
<Compile Include="cdfs\ISONodeRecord.cs" />
|
||||||
<Compile Include="cdfs\ISOVolumeDescriptor.cs" />
|
<Compile Include="cdfs\ISOVolumeDescriptor.cs" />
|
||||||
<Compile Include="CUE\CUE_Analyze.cs" />
|
<Compile Include="CUE\CueFileResolver.cs" />
|
||||||
|
<Compile Include="CUE\CUE_Compile.cs" />
|
||||||
<Compile Include="CUE\CUE_Format.cs" />
|
<Compile Include="CUE\CUE_Format.cs" />
|
||||||
<Compile Include="CUE\CUE_Load.cs" />
|
<Compile Include="CUE\CUE_Load.cs" />
|
||||||
<Compile Include="CUE\CUE_Parse.cs" />
|
<Compile Include="CUE\CUE_Parse.cs" />
|
||||||
|
|
|
@ -127,7 +127,7 @@ namespace BizHawk.Emulation.DiscSystem
|
||||||
waveDataStreamPos = dataChunk.Position;
|
waveDataStreamPos = dataChunk.Position;
|
||||||
mDataLength = dataChunk.Length;
|
mDataLength = dataChunk.Length;
|
||||||
}
|
}
|
||||||
catch(Exception ex)
|
catch(Exception)
|
||||||
{
|
{
|
||||||
Dispose();
|
Dispose();
|
||||||
throw;
|
throw;
|
||||||
|
|
|
@ -253,13 +253,25 @@ namespace BizHawk.Emulation.DiscSystem
|
||||||
//TODO - check for mismatches between track types and file types, or is that best done when interpreting the commands?
|
//TODO - check for mismatches between track types and file types, or is that best done when interpreting the commands?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CreateTrack1Pregap()
|
||||||
|
{
|
||||||
|
if (OUT_CompiledCueTracks[1].PregapLength.Sector == 0) { }
|
||||||
|
else if (OUT_CompiledCueTracks[1].PregapLength.Sector == 150) { }
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Error("Track 1 specified an illegal pregap. It's being ignored and replaced with a 00:02:00 pregap");
|
||||||
|
}
|
||||||
|
OUT_CompiledCueTracks[1].PregapLength = new Timestamp(150);
|
||||||
|
}
|
||||||
|
|
||||||
void FinalAnalysis()
|
void FinalAnalysis()
|
||||||
{
|
{
|
||||||
//some quick checks:
|
//some quick checks:
|
||||||
if (OUT_CompiledCueFiles.Count == 0)
|
if (OUT_CompiledCueFiles.Count == 0)
|
||||||
Error("Cue file doesn't specify any input files!");
|
Error("Cue file doesn't specify any input files!");
|
||||||
|
|
||||||
//we can't readily analyze the length of files here, because we'd have to be interpreting the commands to know the track types. Not really worth the trouble
|
//we can't reliably analyze the length of files here, because we might have to be decoding to get lengths (VBR mp3s)
|
||||||
|
//So, it's not really worth the trouble. We'll cope with lengths later
|
||||||
//we could check the format of the wav file here, though
|
//we could check the format of the wav file here, though
|
||||||
|
|
||||||
//score the cost of loading the file
|
//score the cost of loading the file
|
||||||
|
@ -297,7 +309,7 @@ namespace BizHawk.Emulation.DiscSystem
|
||||||
if (curr_track.Indexes[0].Number != 0)
|
if (curr_track.Indexes[0].Number != 0)
|
||||||
{
|
{
|
||||||
var index0 = new CompiledCueIndex();
|
var index0 = new CompiledCueIndex();
|
||||||
var index1 = curr_track.Indexes[1];
|
var index1 = curr_track.Indexes[0];
|
||||||
index0.Number = 0;
|
index0.Number = 0;
|
||||||
index0.FileMSF = index1.FileMSF;
|
index0.FileMSF = index1.FileMSF;
|
||||||
curr_track.Indexes.Insert(0, index0);
|
curr_track.Indexes.Insert(0, index0);
|
||||||
|
@ -335,14 +347,22 @@ namespace BizHawk.Emulation.DiscSystem
|
||||||
|
|
||||||
public void Run()
|
public void Run()
|
||||||
{
|
{
|
||||||
//params
|
//in params
|
||||||
var cue = IN_CueFile;
|
var cue = IN_CueFile;
|
||||||
|
|
||||||
|
//output state
|
||||||
OUT_GlobalCDText = new CompiledCDText();
|
OUT_GlobalCDText = new CompiledCDText();
|
||||||
OUT_CompiledDiscInfo = new CompiledDiscInfo();
|
OUT_CompiledDiscInfo = new CompiledDiscInfo();
|
||||||
OUT_CompiledCueFiles = new List<CompiledCueFile>();
|
OUT_CompiledCueFiles = new List<CompiledCueFile>();
|
||||||
OUT_CompiledCueTracks = new List<CompiledCueTrack>();
|
OUT_CompiledCueTracks = new List<CompiledCueTrack>();
|
||||||
|
|
||||||
|
//add a track 0, for addressing convenience.
|
||||||
|
//note: for future work, track 0 may need emulation (accessible by very negative LBA--the TOC is stored there)
|
||||||
|
var track0 = new CompiledCueTrack() {
|
||||||
|
Number = 0,
|
||||||
|
};
|
||||||
|
OUT_CompiledCueTracks.Add(track0);
|
||||||
|
|
||||||
//global cd text will acquire the cdtext commands set before track commands
|
//global cd text will acquire the cdtext commands set before track commands
|
||||||
curr_cdtext = OUT_GlobalCDText;
|
curr_cdtext = OUT_GlobalCDText;
|
||||||
|
|
||||||
|
@ -367,7 +387,10 @@ namespace BizHawk.Emulation.DiscSystem
|
||||||
//flags can only be set when a track command is running
|
//flags can only be set when a track command is running
|
||||||
if (cmd is CueFile.Command.FLAGS)
|
if (cmd is CueFile.Command.FLAGS)
|
||||||
{
|
{
|
||||||
curr_track.Flags = (cmd as CueFile.Command.FLAGS).Flags;
|
if (curr_track == null)
|
||||||
|
Warn("Ignoring invalid flag commands outside of a track command");
|
||||||
|
else
|
||||||
|
curr_track.Flags = (cmd as CueFile.Command.FLAGS).Flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd is CueFile.Command.TRACK)
|
if (cmd is CueFile.Command.TRACK)
|
||||||
|
@ -383,14 +406,31 @@ namespace BizHawk.Emulation.DiscSystem
|
||||||
|
|
||||||
if (cmd is CueFile.Command.INDEX)
|
if (cmd is CueFile.Command.INDEX)
|
||||||
{
|
{
|
||||||
|
//todo - validate no postgap specified
|
||||||
AddIndex(cmd as CueFile.Command.INDEX);
|
AddIndex(cmd as CueFile.Command.INDEX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cmd is CueFile.Command.PREGAP)
|
||||||
|
{
|
||||||
|
//validate track open
|
||||||
|
//validate no indexes
|
||||||
|
curr_track.PregapLength = (cmd as CueFile.Command.PREGAP).Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd is CueFile.Command.POSTGAP)
|
||||||
|
{
|
||||||
|
curr_track.PostgapLength = (cmd as CueFile.Command.POSTGAP).Length;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CloseTrack();
|
CloseTrack();
|
||||||
|
|
||||||
|
|
||||||
|
CreateTrack1Pregap();
|
||||||
|
FinalAnalysis();
|
||||||
|
|
||||||
} //Run()
|
} //Run()
|
||||||
|
|
||||||
} //class CompileCueJob
|
} //class CompileCueJob
|
||||||
|
|
||||||
} //partial class CUE_Format2
|
} //partial class CUE_Format2
|
||||||
|
|
|
@ -49,11 +49,6 @@ namespace BizHawk.Emulation.DiscSystem
|
||||||
Normal, Pregap, Postgap
|
Normal, Pregap, Postgap
|
||||||
}
|
}
|
||||||
|
|
||||||
//some sloshy output tracking:
|
|
||||||
int sloshy_firstRecordedTrackNumber = -1, sloshy_lastRecordedTrackNumber = -1;
|
|
||||||
DiscTOCRaw.SessionFormat sloshy_session1Format = DiscTOCRaw.SessionFormat.Type00_CDROM_CDDA;
|
|
||||||
bool sloshy_session1Format_determined = false;
|
|
||||||
|
|
||||||
//current blob file state
|
//current blob file state
|
||||||
int file_cfi_index = -1;
|
int file_cfi_index = -1;
|
||||||
IBlob file_blob = null;
|
IBlob file_blob = null;
|
||||||
|
@ -221,23 +216,122 @@ namespace BizHawk.Emulation.DiscSystem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MountBlobs()
|
||||||
|
{
|
||||||
|
foreach (var ccf in IN_CompileJob.OUT_CompiledCueFiles)
|
||||||
|
{
|
||||||
|
switch (ccf.Type)
|
||||||
|
{
|
||||||
|
case CompiledCueFileType.BIN:
|
||||||
|
case CompiledCueFileType.Unknown:
|
||||||
|
{
|
||||||
|
//raw files:
|
||||||
|
var blob = new Disc.Blob_RawFile { PhysicalPath = ccf.FullPath };
|
||||||
|
OUT_Disc.DisposableResources.Add(file_blob = blob);
|
||||||
|
file_len = blob.Length;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CompiledCueFileType.ECM:
|
||||||
|
{
|
||||||
|
var blob = new Disc.Blob_ECM();
|
||||||
|
OUT_Disc.DisposableResources.Add(file_blob = blob);
|
||||||
|
blob.Load(ccf.FullPath);
|
||||||
|
file_len = blob.Length;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CompiledCueFileType.WAVE:
|
||||||
|
{
|
||||||
|
var blob = new Disc.Blob_WaveFile();
|
||||||
|
OUT_Disc.DisposableResources.Add(file_blob = blob);
|
||||||
|
blob.Load(ccf.FullPath);
|
||||||
|
file_len = blob.Length;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CompiledCueFileType.DecodeAudio:
|
||||||
|
{
|
||||||
|
FFMpeg ffmpeg = new FFMpeg();
|
||||||
|
if (!ffmpeg.QueryServiceAvailable())
|
||||||
|
{
|
||||||
|
throw new DiscReferenceException(ccf.FullPath, "No decoding service was available (make sure ffmpeg.exe is available. even though this may be a wav, ffmpeg is used to load oddly formatted wave files. If you object to this, please send us a note and we'll see what we can do. It shouldn't be too hard.)");
|
||||||
|
}
|
||||||
|
AudioDecoder dec = new AudioDecoder();
|
||||||
|
byte[] buf = dec.AcquireWaveData(ccf.FullPath);
|
||||||
|
var blob = new Disc.Blob_WaveFile();
|
||||||
|
OUT_Disc.DisposableResources.Add(file_blob = blob);
|
||||||
|
blob.Load(new MemoryStream(buf));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void Run()
|
public void Run()
|
||||||
{
|
{
|
||||||
////params
|
//params
|
||||||
//var cue = IN_AnalyzeJob.IN_CueFile;
|
var compiled = IN_CompileJob;
|
||||||
//OUT_Disc = new Disc();
|
OUT_Disc = new Disc();
|
||||||
|
|
||||||
////add sectors for the "mandatory track 1 pregap", which isn't stored in the CCD file
|
//mount all input files
|
||||||
////THIS IS JUNK. MORE CORRECTLY SYNTHESIZE IT
|
MountBlobs();
|
||||||
//for (int i = 0; i < 150; i++)
|
|
||||||
//{
|
|
||||||
// var zero_sector = new Sector_Zero();
|
|
||||||
// var zero_subSector = new ZeroSubcodeSector();
|
|
||||||
// var se_leadin = new SectorEntry(zero_sector);
|
|
||||||
// se_leadin.SubcodeSector = zero_subSector;
|
|
||||||
// OUT_Disc.Sectors.Add(se_leadin);
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
//make a lookup from track number to CompiledCueTrack
|
||||||
|
Dictionary<int, CompiledCueTrack> trackLookup = new Dictionary<int, CompiledCueTrack>();
|
||||||
|
foreach (var cct in compiled.OUT_CompiledCueTracks)
|
||||||
|
trackLookup[cct.Number] = cct;
|
||||||
|
|
||||||
|
//loop from track 1 to 99
|
||||||
|
//(track 0 isnt handled yet, that's way distant work)
|
||||||
|
for (int t = 1; t <= 99; t++)
|
||||||
|
{
|
||||||
|
CompiledCueTrack cct;
|
||||||
|
if (!trackLookup.TryGetValue(t, out cct))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
//---------------------------------
|
||||||
|
//generate track pregap
|
||||||
|
//per "Example 05" on digitalx.org, pregap can come from index specification and pregap command
|
||||||
|
int specifiedPregapLength = cct.PregapLength.Sector;
|
||||||
|
int impliedPregapLength = cct.Indexes[1].FileMSF.Sector - cct.Indexes[0].FileMSF.Sector;
|
||||||
|
//total pregap is needed for subQ addressing of the entire pregap area
|
||||||
|
int totalPregapLength = specifiedPregapLength + impliedPregapLength;
|
||||||
|
for (int s = 0; s < specifiedPregapLength; s++)
|
||||||
|
{
|
||||||
|
//TODO - do a better job synthesizing
|
||||||
|
var zero_sector = new Sector_Zero();
|
||||||
|
var zero_subSector = new ZeroSubcodeSector();
|
||||||
|
var se_pregap = new SectorEntry(zero_sector);
|
||||||
|
se_pregap.SubcodeSector = zero_subSector;
|
||||||
|
se_pregap.SectorSynth = new SS_Mode1_2048();
|
||||||
|
OUT_Disc.Sectors.Add(se_pregap);
|
||||||
|
}
|
||||||
|
|
||||||
|
//after this, pregap sectors are generated like a normal sector, but the subQ is specified as a pregap instead of a normal track
|
||||||
|
//---------------------------------
|
||||||
|
|
||||||
|
//---------------------------------
|
||||||
|
//WE ARE NOW AT INDEX 1
|
||||||
|
//---------------------------------
|
||||||
|
|
||||||
|
//---------------------------------
|
||||||
|
//generate the RawTOCEntry for this track
|
||||||
|
SubchannelQ sq = new SubchannelQ();
|
||||||
|
//absent some kind of policy for how to set it, this is a safe assumption:
|
||||||
|
byte ADR = 1;
|
||||||
|
sq.SetStatus(ADR, (EControlQ)(int)cct.Flags);
|
||||||
|
sq.q_tno.BCDValue = 0; //kind of a little weird here.. the track number becomes the 'point' and put in the index instead. 0 is the track number here.
|
||||||
|
sq.q_index = BCD2.FromDecimal(cct.Number);
|
||||||
|
//not too sure about these yet
|
||||||
|
sq.min = BCD2.FromDecimal(0);
|
||||||
|
sq.sec = BCD2.FromDecimal(0);
|
||||||
|
sq.frame = BCD2.FromDecimal(0);
|
||||||
|
sq.AP_Timestamp = new Timestamp(OUT_Disc.Sectors.Count + 150); //its supposed to be an absolute timestamp
|
||||||
|
OUT_Disc.RawTOCEntries.Add(new RawTOCEntry { QData = sq });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////now for the magic. Process commands in order
|
////now for the magic. Process commands in order
|
||||||
//for (int i = 0; i < cue.Commands.Count; i++)
|
//for (int i = 0; i < cue.Commands.Count; i++)
|
||||||
//{
|
//{
|
||||||
|
|
|
@ -70,6 +70,8 @@ namespace BizHawk.Emulation.DiscSystem
|
||||||
}
|
}
|
||||||
if (ext == ".cue")
|
if (ext == ".cue")
|
||||||
{
|
{
|
||||||
|
//TODO - make sure code is designed so no matter what happens, a disc is disposed in case of errors.
|
||||||
|
//perhaps the CUE_Format2 (once renamed to something like Context) can handle that
|
||||||
var cuePath = IN_FromPath;
|
var cuePath = IN_FromPath;
|
||||||
var cue2 = new CUE_Format2();
|
var cue2 = new CUE_Format2();
|
||||||
|
|
||||||
|
@ -85,15 +87,17 @@ namespace BizHawk.Emulation.DiscSystem
|
||||||
if (parseJob.OUT_Log != "") Console.WriteLine(parseJob.OUT_Log);
|
if (parseJob.OUT_Log != "") Console.WriteLine(parseJob.OUT_Log);
|
||||||
ConcatenateJobLog(parseJob);
|
ConcatenateJobLog(parseJob);
|
||||||
|
|
||||||
//resolve required bin files and find out what it's gonna take to load the cue
|
//compile the cue file:
|
||||||
var analyzeJob = new CUE_Format2.AnalyzeCueJob();
|
//includes this work: resolve required bin files and find out what it's gonna take to load the cue
|
||||||
analyzeJob.IN_CueFile = parseJob.OUT_CueFile;
|
var compileJob = new CUE_Format2.CompileCueJob();
|
||||||
cue2.AnalyzeCueFile(analyzeJob);
|
compileJob.IN_CueFormat = new CUE_Format2() { Resolver = cfr };
|
||||||
if (analyzeJob.OUT_Log != "") Console.WriteLine(analyzeJob.OUT_Log);
|
compileJob.IN_CueFile = parseJob.OUT_CueFile;
|
||||||
ConcatenateJobLog(analyzeJob);
|
compileJob.Run();
|
||||||
|
if (compileJob.OUT_Log != "") Console.WriteLine(compileJob.OUT_Log);
|
||||||
|
ConcatenateJobLog(compileJob);
|
||||||
|
|
||||||
//check slow loading threshold
|
//check slow loading threshold
|
||||||
if (analyzeJob.OUT_LoadTime >= IN_SlowLoadAbortThreshold)
|
if (compileJob.OUT_LoadTime >= IN_SlowLoadAbortThreshold)
|
||||||
{
|
{
|
||||||
Warn("Loading terminated due to slow load threshold");
|
Warn("Loading terminated due to slow load threshold");
|
||||||
goto DONE;
|
goto DONE;
|
||||||
|
@ -101,10 +105,10 @@ namespace BizHawk.Emulation.DiscSystem
|
||||||
|
|
||||||
//actually load it all up
|
//actually load it all up
|
||||||
var loadJob = new CUE_Format2.LoadCueJob();
|
var loadJob = new CUE_Format2.LoadCueJob();
|
||||||
loadJob.IN_AnalyzeJob = analyzeJob;
|
loadJob.IN_CompileJob = compileJob;
|
||||||
loadJob.Run();
|
loadJob.Run();
|
||||||
if (loadJob.OUT_Log != "") Console.WriteLine(loadJob.OUT_Log);
|
if (loadJob.OUT_Log != "") Console.WriteLine(loadJob.OUT_Log);
|
||||||
ConcatenateJobLog(analyzeJob);
|
ConcatenateJobLog(loadJob);
|
||||||
|
|
||||||
OUT_Disc = loadJob.OUT_Disc;
|
OUT_Disc = loadJob.OUT_Disc;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue