public static LoadResults LoadMDSPath(string path) { var ret = new LoadResults { MdsPath = path }; //ret.MdfPath = Path.ChangeExtension(path, ".mdf"); try { if (!File.Exists(path)) { throw new MDSParseException("Malformed MDS format: nonexistent MDS file!"); } AFile mdsf; using (var infMDS = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)) mdsf = new MDS_Format().Parse(infMDS); ret.ParsedMDSFile = mdsf; ret.Valid = true; } catch (MDSParseException ex) { ret.FailureException = ex; } return(ret); }
private void RunBizHawk() { void LoadCue(string cueDirPath, string cueContent) { //TODO major renovation of error handling needed //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 cfr = new CueFileResolver(); var cueContext = new CUE_Context { DiscMountPolicy = IN_DiscMountPolicy, Resolver = cfr }; if (!cfr.IsHardcodedResolve) { cfr.SetBaseDirectory(cueDirPath); } // parse the cue file var parseJob = new ParseCueJob(); parseJob.IN_CueString = cueContent; var okParse = true; try { parseJob.Run(); } catch (DiscJobAbortException) { okParse = false; parseJob.FinishLog(); } if (!string.IsNullOrEmpty(parseJob.OUT_Log)) { Console.WriteLine(parseJob.OUT_Log); } ConcatenateJobLog(parseJob); if (!okParse) { return; } // compile the cue file // includes resolving required bin files and finding out what would processing would need to happen in order to load the cue var compileJob = new CompileCueJob { IN_CueContext = cueContext, IN_CueFile = parseJob.OUT_CueFile }; var okCompile = true; try { compileJob.Run(); } catch (DiscJobAbortException) { okCompile = false; compileJob.FinishLog(); } if (!string.IsNullOrEmpty(compileJob.OUT_Log)) { Console.WriteLine(compileJob.OUT_Log); } ConcatenateJobLog(compileJob); if (!okCompile || compileJob.OUT_ErrorLevel) { return; } // check slow loading threshold if (compileJob.OUT_LoadTime > IN_SlowLoadAbortThreshold) { Warn("Loading terminated due to slow load threshold"); OUT_SlowLoadAborted = true; return; } // actually load it all up var loadJob = new LoadCueJob { IN_CompileJob = compileJob }; loadJob.Run(); //TODO need better handling of log output if (!string.IsNullOrEmpty(loadJob.OUT_Log)) { Console.WriteLine(loadJob.OUT_Log); } ConcatenateJobLog(loadJob); OUT_Disc = loadJob.OUT_Disc; // OUT_Disc.DiscMountPolicy = IN_DiscMountPolicy; // NOT SURE WE NEED THIS (only makes sense for cue probably) } switch (Path.GetExtension(IN_FromPath).ToLowerInvariant()) { case ".ccd": OUT_Disc = new CCD_Format().LoadCCDToDisc(IN_FromPath, IN_DiscMountPolicy); break; case ".cue": LoadCue(Path.GetDirectoryName(IN_FromPath), File.ReadAllText(IN_FromPath)); break; case ".iso": { // make a fake .cue file to represent this .iso and mount that //however... to save many users from a stupid mistake, check if the size is NOT a multiple of 2048 (but IS a multiple of 2352) and in that case consider it a mode2 disc //TODO - try it both ways and check the disc type to use whichever one succeeds in identifying a disc type var len = new FileInfo(IN_FromPath).Length; string mode1cue = $@" FILE ""{Path.GetFileName(IN_FromPath)}"" BINARY TRACK 01 MODE1/2048 INDEX 01 00:00:00" ; string mode2cue = $@" FILE ""{Path.GetFileName(IN_FromPath)}"" BINARY TRACK 01 MODE2/2352 INDEX 01 00:00:00" ; if (len % 2048 != 0 && len % 2352 == 0) { LoadCue(Path.GetDirectoryName(IN_FromPath), mode2cue); } else { LoadCue(Path.GetDirectoryName(IN_FromPath), mode1cue); } break; } case ".mds": OUT_Disc = new MDS_Format().LoadMDSToDisc(IN_FromPath, IN_DiscMountPolicy); break; } // set up the lowest level synth provider if (OUT_Disc != null) { OUT_Disc.SynthProvider = new ArraySectorSynthProvider { Sectors = OUT_Disc._Sectors, FirstLBA = -150 } } ; } }
void RunBizHawk() { string infile = IN_FromPath; string cue_content = null; var cfr = new CueFileResolver(); RERUN: var ext = Path.GetExtension(infile).ToLowerInvariant(); if (ext == ".iso") { //make a fake cue file to represent this iso file and rerun it as a cue string filebase = Path.GetFileName(infile); cue_content = $@" FILE ""{filebase}"" BINARY TRACK 01 MODE1/2048 INDEX 01 00:00:00" ; infile = Path.ChangeExtension(infile, ".cue"); goto RERUN; } if (ext == ".cue") { //TODO - major renovation of error handling needed //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 cueContext = new CUE_Context(); cueContext.DiscMountPolicy = IN_DiscMountPolicy; cueContext.Resolver = cfr; if (!cfr.IsHardcodedResolve) { cfr.SetBaseDirectory(Path.GetDirectoryName(infile)); } //parse the cue file var parseJob = new ParseCueJob(); if (cue_content == null) { cue_content = File.ReadAllText(cuePath); } parseJob.IN_CueString = cue_content; bool okParse = true; try { parseJob.Run(parseJob); } catch (DiscJobAbortException) { okParse = false; parseJob.FinishLog(); } if (!string.IsNullOrEmpty(parseJob.OUT_Log)) { Console.WriteLine(parseJob.OUT_Log); } ConcatenateJobLog(parseJob); if (!okParse) { goto DONE; } //compile the cue file: //includes this work: resolve required bin files and find out what it's gonna take to load the cue var compileJob = new CompileCueJob(); compileJob.IN_CueContext = cueContext; compileJob.IN_CueFile = parseJob.OUT_CueFile; bool okCompile = true; try { compileJob.Run(); } catch (DiscJobAbortException) { okCompile = false; compileJob.FinishLog(); } if (!string.IsNullOrEmpty(compileJob.OUT_Log)) { Console.WriteLine(compileJob.OUT_Log); } ConcatenateJobLog(compileJob); if (!okCompile || compileJob.OUT_ErrorLevel) { goto DONE; } //check slow loading threshold if (compileJob.OUT_LoadTime > IN_SlowLoadAbortThreshold) { Warn("Loading terminated due to slow load threshold"); OUT_SlowLoadAborted = true; goto DONE; } //actually load it all up var loadJob = new LoadCueJob(); loadJob.IN_CompileJob = compileJob; loadJob.Run(); //TODO - need better handling of log output if (!string.IsNullOrEmpty(loadJob.OUT_Log)) { Console.WriteLine(loadJob.OUT_Log); } ConcatenateJobLog(loadJob); OUT_Disc = loadJob.OUT_Disc; //OUT_Disc.DiscMountPolicy = IN_DiscMountPolicy; //NOT SURE WE NEED THIS (only makes sense for cue probably) } else if (ext == ".ccd") { CCD_Format ccdLoader = new CCD_Format(); OUT_Disc = ccdLoader.LoadCCDToDisc(IN_FromPath, IN_DiscMountPolicy); } else if (ext == ".mds") { MDS_Format mdsLoader = new MDS_Format(); OUT_Disc = mdsLoader.LoadMDSToDisc(IN_FromPath, IN_DiscMountPolicy); } DONE: //setup the lowest level synth provider if (OUT_Disc != null) { var sssp = new ArraySectorSynthProvider() { Sectors = OUT_Disc._Sectors, FirstLBA = -150 }; OUT_Disc.SynthProvider = sssp; } }