static void MainExtract(string[] args) { var rom = new Z64Rom(new Rom(args[0])); foreach (var file in rom.Files.Select((f, i) => new { f, i })) { File.WriteAllBytes(string.Format("{0:0000} {1}", file.i, file.f.Name), file.f.Contents.ToArray()); } }
static void MainReal(string[] args) { Console.OutputEncoding = Encoding.UTF8; var extra = _operatingModes.Parse(args); switch (_mode) { case Mode.ShowHelp: Console.Error.WriteLine( typeof(Program) .GetFields(BindingFlags.NonPublic | BindingFlags.Static) .Where(f => f.FieldType == typeof(OptionSet)) .Select(f => f.GetValue(null) as OptionSet) .Select(x => { var ms = new MemoryStream(); using (var sw = new StreamWriter(ms)) x.WriteOptionDescriptions(sw); return(Encoding.UTF8.GetString(ms.ToArray())); }) .Join(Environment.NewLine.Dup(3)) ); break; case Mode.Signatures: { var files = _signatureOptions.Parse(extra); var sigs = new SignatureDatabase(SignaturesOptions.DatabasePath); var action = SignaturesOptions.SlowMode ? new Func <IEnumerable <InstructionWithPc>, IReadOnlyList <SignatureMatch> >(sigs.IdentifySlow) : (x => sigs.Identify(x, SignaturesOptions.Verify)); var results = files .Select(f => action( SignaturesOptions.MemDump ? File.ReadAllBytes(f).ToInstructions().WithPc(0x80000000) : new Rom(f).GetExecutable() )) .First(); if (!SignaturesOptions.ShortMode) { Console.WriteLine(JsonConvert.SerializeObject( !SignaturesOptions.UseHexAddrs ? (results as object) : results .Select(x => new { Start = string.Format("{0:X8}", x.Start), x.Size, Matches = x.Matches.Select(y => new { y.Name, Symbols = y.Symbols .Select(z => new { Key = string.Format("{0:X8}", z.Key), z.Value }) .ToDictionary(a => a.Key, a => a.Value) }) }), SignaturesOptions.IndentJson ? Formatting.Indented : Formatting.None )); } else { Console.WriteLine( string.Join( Environment.NewLine, results .ToShortForm(SignaturesOptions.ShowAll) .Select(g => string.Format("0x{0:x8},{1}", g.Key, string.Join("|", g.Value))) ) ); } } break; case Mode.ImportSignatures: var arFiles = _importSignatureOptions.Parse(extra); var stats = SignatureDatabase.ImportArchiveToDatabase( SignaturesOptions.DatabasePath, SignaturesOptions.CleanDatabase, arFiles.ToArray() ); Console.Error.WriteLine("{0} imported, {1} variants already present, {2} archives already present", stats.CountImported, stats.CountExisting, stats.ArchivesExisting); break; case Mode.Zelda64: { var files = _zelda64Modes.Parse(extra); switch (_zeldaMode) { case ZeldaMode.Extract: MainExtract(files.ToArray()); break; case ZeldaMode.DisassembleOverlay: MainDis(files.ToArray()); break; case ZeldaMode.DisassembleAllOverlays: var rom = new Rom(files[0]); var zrom = new Z64Rom(rom); foreach (var o in zrom.Overlays) { var p = o.File.Name; var ovl = new Overlay(o.VmaStart, o.File.Contents, _overlayOptions); Directory.CreateDirectory(p); File.WriteAllLines( Path.Combine(p, $"{o.File.Name}.S"), ovl.Disassemble(DisassemblyOptions.DebugPc) ); File.WriteAllText( Path.Combine(p, "conf.ld"), ovl.LinkerScript ); File.WriteAllText( Path.Combine(p, "Makefile"), OverlayCreator.GenerateMakefileForOvl(AppContext.BaseDirectory, o.File.Name, o.VmaStart) ); File.WriteAllBytes( Path.Combine(p, $"{o.File.Name}.ovl.orig"), o.File.Contents.ToArray() ); } break; case ZeldaMode.GenerateOverlayRelocs: Console.WriteLine( OverlayCreator.CreateCSourceFromOverlayRelocations( "__relocations", OverlayCreator.GetOverlayRelocationsFromElf(File.ReadAllBytes(files[0])) ) ); break; case ZeldaMode.DumpRelocations: Console.WriteLine( string.Join( Environment.NewLine, new[] { "ID Sec. loc Abs. addr Sym value Type Section Disassembly", //" 0 [0x0000001C/0x808FDEAC] (0x8090EE50) R_MIPS_HI16 .text lui $at,0x8091" }.Concat( LoadOverlay(files) .Relocations .Select((x, i) => string.Format("{0,5} {1}", i, x)) ) ) ); break; } } break; case Mode.EucJpStrings: { var files = _eucJpOptions.Parse(extra); var data = files .Select(x => new { x, data = File.ReadAllBytes(x) }) .Select(x => new { x.x, strings = EucJp.ExtractEucJpStrings(x.data, EucJp.AsciiColorCode, EucJp.UnknownExtraChars) .Where(y => !EucJpOptions.MinStringLength.HasValue || y.String.Length >= EucJpOptions.MinStringLength.Value) .Where(y => !EucJpOptions.OnlyForeign || y.ContainsEucJpCharacters) .Select(y => y.String) }); if (!EucJpOptions.Json) { foreach (var x in data.Select(y => y.strings)) { Console.WriteLine(x); } } else { Console.WriteLine( JsonConvert.SerializeObject( data.Select(x => new { Filename = x.x, Strings = x.strings }), Formatting.Indented ) ); } } break; case Mode.AsmPatch: { _asmPatchOptions.Parse(extra); var assembled = BuildAsmPatch(); if (!AsmPatchOptions.Gameshark) { byte[] input = ApplyAssembledInstructionsToRom( assembled, AsmPatchOptions.InputRom, AsmPatchOptions.OutputRom ); DumpAssembledValues(assembled); Console.Error.WriteLine("Patched {0} bytes.", assembled.Length * 4); if (string.IsNullOrWhiteSpace(AsmPatchOptions.BsdiffPath)) { break; } using (var patchOutput = File.OpenWrite(AsmPatchOptions.BsdiffPath)) deltaq.BsDiff.BsDiff.Create(File.ReadAllBytes(AsmPatchOptions.InputRom), input, patchOutput); Console.Error.WriteLine("`{0}` of size {1} bytes created.", AsmPatchOptions.BsdiffPath, new FileInfo(AsmPatchOptions.BsdiffPath).Length); } else { var codes = assembled .SelectMany(x => new[]