Exemplo n.º 1
0
        static int Main(string[] args)
        {
            Console.WriteLine($"Famicom Dumper Client v{Assembly.GetExecutingAssembly().GetName().Version.Major}.{Assembly.GetExecutingAssembly().GetName().Version.Minor}");
            Console.WriteLine($"  Commit {Properties.Resources.gitCommit} @ https://github.com/ClusterM/famicom-dumper-client");
            Console.WriteLine("  (c) Alexey 'Cluster' Avdyukhin / https://clusterrr.com / [email protected]");
            Console.WriteLine();
            startTime = DateTime.Now;
            string port     = "auto";
            string mapper   = "0";
            string psize    = null;
            string csize    = null;
            string filename = null;
            bool   battery  = false;
            string csFile   = null;

            string[]   csArgs             = new string[0];
            string     unifName           = null;
            string     unifAuthor         = null;
            bool       reset              = false;
            bool       silent             = true;
            bool       needCheck          = false;
            bool       writePBBs          = false;
            List <int> badSectors         = new List <int>();
            int        testCount          = -1;
            uint       tcpPort            = 26672;
            bool       ignoreBadSectors   = false;
            string     remoteHost         = null;
            byte       fdsSides           = 1;
            bool       fdsUseHeader       = true;
            bool       fdsDumpHiddenFiles = false;

            try
            {
                if (args.Length == 0 || args.Contains("help") || args.Contains("--help"))
                {
                    PrintHelp();
                    return(0);
                }

                string command = args[0].ToLower();

                for (int i = 1; i < args.Length; i++)
                {
                    string param = args[i];
                    if (param == "-")
                    {
                        csArgs = args.Skip(i + 1).ToArray();
                        break;
                    }
                    while (param.StartsWith("-") || param.StartsWith("—"))
                    {
                        param = param.Substring(1);
                    }
                    string value = i < args.Length - 1 ? args[i + 1] : "";
                    switch (param.ToLower())
                    {
                    case "p":
                    case "port":
                        port = value;
                        i++;
                        break;

                    case "m":
                    case "mapper":
                        mapper = value;
                        i++;
                        break;

                    case "f":
                    case "file":
                        filename = value;
                        i++;
                        break;

                    case "fds-sides":
                        fdsSides = byte.Parse(value);
                        i++;
                        break;

                    case "fds-no-header":
                        fdsUseHeader = false;
                        break;

                    case "fds-dump-hidden":
                        fdsDumpHiddenFiles = true;
                        break;

                    case "csfile":
                    case "cs-file":
                    case "scriptfile":
                    case "script-file":
                        csFile = value;
                        i++;
                        break;

                    case "psize":
                    case "prg-size":
                        psize = value;
                        i++;
                        break;

                    case "csize":
                    case "chr-size":
                        csize = value;
                        i++;
                        break;

                    case "battery":
                        battery = true;
                        break;

                    case "unifname":
                    case "unif-name":
                        unifName = value;
                        i++;
                        break;

                    case "unifauthor":
                    case "unif-author":
                        unifAuthor = value;
                        i++;
                        break;

                    case "reset":
                        reset = true;
                        break;

                    case "sound":
                        silent = false;
                        break;

                    case "check":
                    case "verify":
                        needCheck = true;
                        break;

                    case "lock":
                        writePBBs = true;
                        break;

                    case "testcount":
                    case "test-count":
                        testCount = int.Parse(value);
                        i++;
                        break;

                    case "badsectors":
                    case "bad-sectors":
                        foreach (var v in value.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
                        {
                            badSectors.Add(int.Parse(v));
                        }
                        i++;
                        break;

                    case "tcpport":
                    case "tcp-port":
                        tcpPort = uint.Parse(value);
                        i++;
                        break;

                    case "host":
                        remoteHost = value;
                        i++;
                        break;

                    case "ignorebadsectors":
                    case "ignore-bad-sectors":
                        ignoreBadSectors = true;
                        break;

                    default:
                        Console.WriteLine("Unknown option: " + param);
                        PrintHelp();
                        return(2);
                    }
                }

                if (command == "list-mappers")
                {
                    ListMappers();
                    return(0);
                }

                FamicomDumperConnection dumper;
                if (string.IsNullOrEmpty(remoteHost))
                {
                    dumper = new FamicomDumperConnection(port);
                    dumper.Open();
                }
                else
                {
                    BinaryServerFormatterSinkProvider binaryServerFormatterSinkProvider
                        = new BinaryServerFormatterSinkProvider();
                    BinaryClientFormatterSinkProvider binaryClientFormatterSinkProvider
                        = new BinaryClientFormatterSinkProvider();
                    binaryServerFormatterSinkProvider.TypeFilterLevel
                        = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;
                    var dict = new System.Collections.Hashtable();
                    dict["name"]   = "FamicomDumperClient";
                    dict["secure"] = false;
                    var channel = new TcpChannel(dict, binaryClientFormatterSinkProvider, binaryServerFormatterSinkProvider);
                    ChannelServices.RegisterChannel(channel, false);
                    dumper = (FamicomDumperConnection)Activator.GetObject(typeof(IFamicomDumperConnection), $"tcp://{remoteHost}:{tcpPort}/dumper");
                    var lifetime = dumper.GetLifetimeService();
                }
                try
                {
                    Console.Write("Dumper initialization... ");
                    bool prgInit = dumper.DumperInit();
                    if (!prgInit)
                    {
                        throw new IOException("Can't init dumper");
                    }
                    Console.WriteLine("OK");

                    if (reset)
                    {
                        Reset(dumper);
                    }

                    if (!string.IsNullOrEmpty(csFile))
                    {
                        CompileAndExecute(csFile, dumper, csArgs);
                    }

                    switch (command)
                    {
                    case "reset":
                        if (!reset)
                        {
                            Reset(dumper);
                        }
                        break;

                    case "list-mappers":
                        ListMappers();
                        break;

                    case "dump":
                        Dump(dumper, filename ?? "output.nes", mapper, ParseSize(psize), ParseSize(csize), unifName, unifAuthor, battery);
                        break;

                    case "dump-fds":
                        FDS.DumpFDS(dumper, filename ?? "output.fds", fdsSides, fdsDumpHiddenFiles, fdsUseHeader);
                        break;

                    case "read-prg-ram":
                    case "dump-prg-ram":
                    case "dump-sram":
                        ReadPrgRam(dumper, filename ?? "savegame.sav", mapper);
                        break;

                    case "write-fds":
                        if (string.IsNullOrEmpty(filename))
                        {
                            throw new ArgumentNullException("Please specify ROM filename using --file argument");
                        }
                        FDS.WriteFDS(dumper, filename, needCheck);
                        break;

                    case "write-prg-ram":
                    case "write-sram":
                        if (string.IsNullOrEmpty(filename))
                        {
                            throw new ArgumentNullException("Please specify ROM filename using --file argument");
                        }
                        WritePrgRam(dumper, filename, mapper);
                        break;

                    case "test-prg-ram":
                    case "test-sram":
                        TestPrgRam(dumper, mapper);
                        break;

                    case "test-prg-coolgirl":
                    case "test-prg-ram-coolgirl":
                    case "test-sram-coolgirl":
                        CoolgirlWriter.TestPrgRam(dumper);
                        break;

                    case "test-battery":
                        TestBattery(dumper, mapper);
                        break;

                    case "test-chr-ram":
                        TestChrRam(dumper);
                        break;

                    case "test-chr-coolgirl":
                    case "test-chr-ram-coolgirl":
                        CoolgirlWriter.TestChrRam(dumper, chrSize: ParseSize(csize));
                        break;

                    case "test-coolgirl":
                        CoolgirlWriter.FullTest(dumper, testCount, chrSize: ParseSize(csize));
                        break;

                    case "test-bads-coolgirl":
                        CoolgirlWriter.FindBads(dumper, silent);
                        break;

                    case "read-crc-coolgirl":
                        CoolgirlWriter.ReadCrc(dumper);
                        break;

                    case "dump-tiles":
                        DumpTiles(dumper, filename ?? "output.png", mapper, ParseSize(csize));
                        break;

                    case "write-coolboy":
                    case "write-coolboy-direct":
                    case "write-coolboy-gpio":     // for backward compatibility
                        if (string.IsNullOrEmpty(filename))
                        {
                            throw new ArgumentNullException("Please specify ROM filename using --file argument");
                        }
                        CoolboyWriter.Write(dumper, filename, badSectors, silent, needCheck, writePBBs, ignoreBadSectors);
                        break;

                    case "write-coolgirl":
                        if (string.IsNullOrEmpty(filename))
                        {
                            throw new ArgumentNullException("Please specify ROM filename using --file argument");
                        }
                        CoolgirlWriter.Write(dumper, filename, badSectors, silent, needCheck, writePBBs, ignoreBadSectors);
                        break;

                    case "write-eeprom":
                        if (string.IsNullOrEmpty(filename))
                        {
                            throw new ArgumentNullException("Please specify ROM filename using --file argument");
                        }
                        WriteEeprom(dumper, filename);
                        break;

                    case "info-coolboy":
                        CoolboyWriter.PrintFlashInfo(dumper);
                        break;

                    case "info-coolgirl":
                        CoolgirlWriter.PringFlashInfo(dumper);
                        break;

                    case "bootloader":
                        Bootloader(dumper);
                        break;

                    case "script":
                        if (string.IsNullOrEmpty(csFile))
                        {
                            throw new ArgumentNullException("Please specify C# script using --cs-file argument");
                        }
                        break;

                    case "server":
                        StartServer(dumper, tcpPort);
                        break;

                    default:
                        Console.WriteLine("Unknown command: " + command);
                        PrintHelp();
                        return(2);
                    }
#if DEBUG
                    var timePassed = DateTime.Now - startTime;
                    if (timePassed.TotalMinutes >= 60)
                    {
                        Console.WriteLine($"Done in {timePassed.Hours}:{timePassed.Minutes:D2}:{timePassed.Seconds:D2}");
                    }
                    else if (timePassed.TotalSeconds >= 10)
                    {
                        Console.WriteLine($"Done in {timePassed.Minutes:D2}:{timePassed.Seconds:D2}");
                    }
                    else
                    {
                        Console.WriteLine($"Done in {(int)timePassed.TotalMilliseconds}ms");
                    }
#endif
                    if (!silent)
                    {
                        PlayDoneSound();
                    }
                }
                finally
                {
                    if (string.IsNullOrEmpty(remoteHost))
                    {
                        dumper.Dispose();
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"ERROR {ex.GetType()}: " + ex.Message
#if DEBUG
                                  + ex.StackTrace
#endif
                                  );
                if (!silent)
                {
                    PlayErrorSound();
                }
                return(1);
            }
            return(0);
        }