Beispiel #1
0
        public static LoadResults LoadCCDPath(string path)
        {
            var ret = new LoadResults
            {
                CcdPath = path,
                ImgPath = Path.ChangeExtension(path, ".img"),
                SubPath = Path.ChangeExtension(path, ".sub")
            };

            try
            {
                if (!File.Exists(path))
                {
                    throw new CCDParseException("Malformed CCD format: nonexistent CCD file!");
                }

                CCDFile ccdf;
                using (var infCCD = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
                    ccdf = new CCD_Format().ParseFrom(infCCD);

                ret.ParsedCCDFile = ccdf;

                ret.Valid = true;
            }
            catch (CCDParseException ex)
            {
                ret.FailureException = ex;
            }

            return(ret);
        }
Beispiel #2
0
        public static LoadResults LoadCCDPath(string path)
        {
            LoadResults ret = new LoadResults();

            ret.CcdPath = path;
            ret.ImgPath = Path.ChangeExtension(path, ".img");
            ret.SubPath = Path.ChangeExtension(path, ".sub");
            try
            {
                if (!File.Exists(path))
                {
                    throw new CCDParseException("Malformed CCD format: nonexistent CCD file!");
                }
                if (!File.Exists(ret.ImgPath))
                {
                    throw new CCDParseException("Malformed CCD format: nonexistent IMG file!");
                }
                if (!File.Exists(ret.SubPath))
                {
                    throw new CCDParseException("Malformed CCD format: nonexistent SUB file!");
                }

                //quick check of .img and .sub sizes
                long imgLen = new FileInfo(ret.ImgPath).Length;
                long subLen = new FileInfo(ret.SubPath).Length;
                if (imgLen % 2352 != 0)
                {
                    throw new CCDParseException("Malformed CCD format: IMG file length not multiple of 2352");
                }
                ret.NumImgSectors = (int)(imgLen / 2352);
                if (subLen != ret.NumImgSectors * 96)
                {
                    throw new CCDParseException("Malformed CCD format: SUB file length not matching IMG");
                }

                CCDFile ccdf;
                using (var infCCD = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
                    ccdf = new CCD_Format().ParseFrom(infCCD);

                ret.ParsedCCDFile = ccdf;

                ret.Valid = true;
            }
            catch (CCDParseException ex)
            {
                ret.FailureException = ex;
            }

            return(ret);
        }
Beispiel #3
0
        public static bool HawkAndWriteFile(string inputPath, Action <string> errorCallback, DiscInterface discInterface = DiscInterface.BizHawk)
        {
            DiscMountJob job = new(inputPath, discInterface);

            job.Run();
            var disc = job.OUT_Disc;

            if (job.OUT_ErrorLevel)
            {
                errorCallback(job.OUT_Log);
                return(false);
            }
            var baseName = Path.GetFileNameWithoutExtension(inputPath);
            var outfile  = Path.Combine(Path.GetDirectoryName(inputPath), $"{baseName}_hawked.ccd");

            CCD_Format.Dump(disc, outfile);
            return(true);
        }
Beispiel #4
0
        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 = string.Format(@"
						FILE ""{0}"" BINARY
							TRACK 01 MODE1/2048
								INDEX 01 00:00:00"                                ,
                                            filebase);
                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);
            }


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;
            }
        }
Beispiel #5
0
        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
                }
            }
            ;
        }
    }
Beispiel #6
0
        public static Disc FromCCDPath(string ccdPath)
        {
            CCD_Format ccdLoader = new CCD_Format();

            return(ccdLoader.LoadCCDToDisc(ccdPath));
        }