private static int TryDisassemble(DisassemblyOptions opts, Func <RomVersion, string, Func <DisassemblyTask, bool> > getFilter) { string path; if (!RomVersion.TryGet(opts.GameId, opts.VersionId, out RomVersion version)) { Console.WriteLine($"Unrecognized version {opts.GameId} {opts.VersionId}"); return(-1); } if (opts.RomPath != null) { path = opts.RomPath; } else if (!PathUtil.TryGetRomLocation(version, out path)) { Console.WriteLine($"Cannot find path for {opts.GameId} {opts.VersionId}"); return(-1); } Disassemble.MipsToC = opts.MipsToCOutput; Disassemble.GccOutput = Disassemble.MipsToC || !opts.ReadableOutput; Disassemble.PrintRelocations = true; Disassemble.SetGprNames(); Func <DisassemblyTask, bool> filter = getFilter(version, path); if (filter == null) { return(-1); } DisassembleRom(version, path, filter); return(0); }
static void DisassembleRom(RomVersion ver, string path) { Rom rom; Console.Write("Initializing task list: "); if (ver.Game == Game.OcarinaOfTime) { rom = new ORom(path, ver); } else { rom = new MRom(path, ver); } List <DisassemblyTask> taskList = DisassemblyTask.CreateTaskList(rom); taskList = taskList.Where(x => x.VRom.End > 0).ToList(); Console.WriteLine("DONE!"); Console.Write($"Building symbol table: "); Stream getFile(FileAddress x) => rom.Files.GetFile(x); LoadFunctionDatabase(ver); GetSymbols(taskList, rom.Version, getFile); Console.WriteLine("DONE!"); Console.WriteLine("Disassembling files: "); DisassembleTasks(rom.Version, taskList, getFile); DumpFoundFunctions(rom.Version, Disassemble.GetFunctions()); }
private static void DisassembleTasks(RomVersion ver, List <DisassemblyTask> taskList, Func <FileAddress, Stream> getFile) { var folder = GetFolder(ver); Console.CursorVisible = false; foreach (var task in taskList) { string filename = $"{folder}/{task.Name}.txt"; Console.Write($"\r{filename.PadRight(Console.BufferWidth)}"); using (StreamWriter sw = new StreamWriter(new FileStream(filename, FileMode.Create, FileAccess.Write))) { var reader = new BinaryReader(getFile(task.VRom)); if (Disassemble.GccOutput) { sw.WriteLine("#include <mips.h>"); sw.WriteLine(".set noreorder"); sw.WriteLine(".set noat"); sw.WriteLine(); } Disassemble.Task(sw, reader, task); } } Console.CursorVisible = true; }
internal static void ChangeVersion(RomVersion v, bool gctx) { TOTAL_ACTORS = (v.Game == Game.OcarinaOfTime) ? 0x1D7 : 0x2B2; InstanceSize = new ushort[TOTAL_ACTORS]; version = v; }
public static List <N64Ptr> GetFramebufferPointers(RomVersion version) { if (version.Game == Game.OcarinaOfTime) { if (version == ORom.Build.DBGMQ) { return(new List <N64Ptr>() { 0x80400E80, FRAMEBUFFER_SIZE + 0x80400E80 }); } else { return new List <N64Ptr>() { 0x803B5000, 0x803DA800 } }; } else if (version.Game == Game.MajorasMask) { if (version == MRom.Build.U0) { return(new List <N64Ptr>() { 0x80000500, 0x80785000, 0x80383AC0, 0x80383AC0 + FRAMEBUFFER_SIZE }); } } return(new List <N64Ptr>() { }); }
private static void DisassembleTasks(RomVersion ver, List <DisassemblyTask> taskList, Func <FileAddress, Stream> getFile) { var folder = GetFolder(ver); Console.CursorVisible = false; foreach (var task in taskList) { string filename = $"{folder}/{task.Name}.txt"; Console.Write($"\r{filename.PadRight(Console.BufferWidth)}"); var file = getFile(task.VRom); foreach (var action in task.PreparseActions) { action(file); } foreach (var item in task.Functions) { Disassemble.AddFunction(item); } using var br = new BinaryReader(file); Disassemble.FirstParse(br, task); using var sw = File.CreateText(filename); Disassemble.Task(sw, br, task); } Console.CursorVisible = true; }
//get scene file from mqd folder //get file size //add file to location ref by FileTable_Open //update file table record after FileTable_Open //add rooms //update root scene's room addresses /// <summary> /// Imports a select set of scenes into a designated rom /// </summary> /// <param name="romfile">The rom being modified</param> /// <param name="scenesLocation">The location of the scene/room files</param> /// <param name="version">The target version of the rom</param> /// <param name="importScenes">the scenes to import</param> public static void ImportToUncompressedRom(string romfile, RomVersion version, string sceneFilesLocation, List <int> importScenes) { FileTable_Off = Addresser.GetRom(ORom.FileList.dmadata, version, "Scenes_Start"); SceneTable_Start = Addresser.GetRom(ORom.FileList.code, version, "SceneTable_Start"); int NextWriteAddress; using (FileStream fs_r = new FileStream(romfile, FileMode.Open, FileAccess.ReadWrite)) { BinaryReader addrReader = new BinaryReader(fs_r); addrReader.BaseStream.Position = FileTable_Off; NextWriteAddress = addrReader.ReadBigInt32(); BinaryWriter bw = new BinaryWriter(fs_r); //wipe the scene table for (int i = 0; i < 101; i++) { UpdateSceneTable(bw, i, new FileAddress(0, 0)); } foreach (int sceneIndex in importScenes) { AddSceneAndRooms(sceneIndex, ref NextWriteAddress, sceneFilesLocation, bw); } } }
public Record(BgActor actor, IFile file, RomVersion version) { Initialize(); int ramStart = 0; if (file is RamObject) { var obj = (RamObject)file; ramStart = (int)obj.Ram.Start; File = new FileData(obj.Object, FileType.Object); } else if (file is OvlActor) { var af = (OvlActor)file; ramStart = (int)af.Ram.Start; File = new FileData(af.Actor, FileType.Actor); } else { throw new NotImplementedException(); } Offset = ((int)actor.MeshPtr & 0xFFFFFF) - (ramStart & 0xFFFFFF); Versions.Add(version); Actors.Add(actor.ActorId); }
static void BindSegment(RomVersion version, ORom.FileList fileO, MRom.FileList fileM, ref Ptr ram, ref Ptr rom) { RomFileToken token = RomFileToken.Select(version, fileO, fileM); if (Options.MapfileOptions.CanUseMap(version)) { Segment seg = Options.MapfileOptions.SymbolMap.GetSegment(token.ToString()); if (seg != null) { ram = SPtr.New(seg.Address); rom = SPtr.New(seg.LoadAddress); } else { Console.WriteLine($"Segment {token} not found."); } } else { Addresser.TryGetRam(token, version, out var t1); ram = SPtr.New(t1); Addresser.TryGetRom(token, version, t1, out var t2); rom = SPtr.New(t2); } }
public DynaCollisionContext(Ptr ctx, RomVersion version) { for (int i = 0; i < BG_ACTOR_MAX; i++) { bgActors[i] = new BgActor(ctx.RelOff(i * 0x64 + 0x54)); } polyList = ctx.Deref(0x1440); vtxList = ctx.Deref(0x1444); if (version.Game == Game.OcarinaOfTime) { polyNodes_tbl = ctx.Deref(0x1448); polyNodes_count = ctx.ReadInt32(0x144C); polyNodes_max = ctx.ReadInt32(0x1450); polyNodesMax = ctx.ReadInt32(0x1454); polyListMax = ctx.ReadInt32(0x1458); vtxListMax = ctx.ReadInt32(0x145C); } else if (version.Game == Game.MajorasMask) { mm_0x1448 = ctx.ReadInt32(0x1448); waterBoxList = ctx.Deref(0x144C); polyNodes_tbl = ctx.Deref(0x1450); polyNodes_count = ctx.ReadInt32(0x1454); polyNodes_max = ctx.ReadInt32(0x1458); polyNodesMax = ctx.ReadInt32(0x145C); polyListMax = ctx.ReadInt32(0x1460); vtxListMax = ctx.ReadInt32(0x1464); } this.version = version; }
static void DisassembleRom(RomVersion version, string path, Func <DisassemblyTask, bool> filter) { Console.WriteLine($"{version} {path}"); Console.Write("Initializing task list: "); Rom rom = Rom.New(path, version); List <DisassemblyTask> taskList = DisassemblyTask.CreateTaskList(rom); taskList = taskList.Where(filter).Where(x => x.VRom.End > 0).ToList(); if (taskList.Count == 0) { Console.WriteLine("Error: No tasks to process!"); return; } Console.WriteLine("DONE!"); Console.Write($"Loading symbol table from file: "); LoadFunctionDatabase(version); Console.WriteLine("DONE!"); Console.WriteLine("Disassembling files: "); Stream getFile(FileAddress x) => rom.Files.GetFile(x); DisassembleTasks(rom.Version, taskList, getFile); DumpFoundFunctions(rom.Version, Disassemble.GetFunctions()); }
private static List <ParserTask> GetParserTasks(List <SettingsToken> settings) { List <ParserTask> tasks = new(); List <string> builds = (List <string>)Get(settings, SettingsTokens.build); List <FormatTypesEnum> outputFormats = (List <FormatTypesEnum>)Get(settings, SettingsTokens.format); for (int i = 0; i < builds.Count; i++) { var build = builds[i]; foreach (var format in outputFormats) { var game = (string)GetSingle(settings, SettingsTokens.game, i); ParserTask task = new() { Name = (string)GetSingle(settings, SettingsTokens.name, i), Version = new RomVersion(game, build), Format = format, StartAddress = (long)GetSingle(settings, SettingsTokens.start, i), LoopFor = (long)GetSingle(settings, SettingsTokens.loop, i), Inc = (long)GetSingle(settings, SettingsTokens.inc, i), Index = (long)GetSingle(settings, SettingsTokens.iterator, i) }; tasks.Add(task); } } return(tasks); }
private static void DumpFoundFunctions(RomVersion Version, IEnumerable <Label> funcList) { using var outputf = File.CreateText($"{GetFolder(Version)}/~~func.txt"); foreach (var func in funcList.OrderBy(x => x.Addr)) { outputf.WriteLine($"{func.Addr:X8},{func.Name}"); } }
private static string GetFolder(RomVersion Version) { string game = Version.Game.ToString()[0].ToString(); var dir = $"{game}/{Version.ToString().ToUpper()}"; Directory.CreateDirectory(dir); return(dir); }
public JFileInfo(string file, RomVersion version, FileAddress rom, FileAddress ram, JSectionInfo section) { File = file; Game = version.Game.ToString(); Version = version.ToString(); Rom = rom; Ram = ram; Sections.Add(section); }
private void okButton_Click(object sender, EventArgs e) { if (versionComboBox.SelectedIndex >= 0) { Version = (RomVersion)versionComboBox.SelectedItem; DialogResult = DialogResult.OK; Close(); } }
public static void UpdateRomVersionUsingTell() { RomVersion?romVersion = GetRomVersionUsingTell(); if (romVersion.HasValue) { Version = romVersion.Value; } }
private static void DumpFoundFunctions(RomVersion Version, IEnumerable <Label> funcList) { using (StreamWriter outputf = new StreamWriter(new FileStream($"{GetFolder(Version)}/~~func.txt", FileMode.Create, FileAccess.Write))) { foreach (var func in funcList.OrderBy(x => x.Addr)) { outputf.WriteLine($"{func.Addr:X8},{func.Name}"); } } }
public bool IsSupported(RomVersion version) { if (version.Game == Game.OcarinaOfTime) { return((Sup & Supported.OoT) == Supported.OoT); } if (version.Game == Game.MajorasMask) { return((Sup & Supported.MM) == Supported.MM); } return(false); }
internal static void ChangeVersion(RomVersion v, bool g) { if (v.Game == Game.OcarinaOfTime) { TOTAL_PARTICLE_EFFECTS = 0x19; } else { TOTAL_PARTICLE_EFFECTS = 0x27; } //InstanceSize = new ushort[TOTAL_PARTICLE_EFFECTS]; }
private static string GetFolder(RomVersion Version) { string game = Version.Game.ToString()[0].ToString(); var dir = $"{game}/{Version.ToString().ToUpper()}"; if (!Disassemble.GccOutput) { dir += "_r"; } Directory.CreateDirectory(dir); return(dir); }
public CollisionCtx(Ptr ctx, RomVersion version) { this.version = version; SceneMeshPtr = ctx.Deref(0); boxmin = new Vector3 <float>( ctx.ReadFloat(0x04), ctx.ReadFloat(0x08), ctx.ReadFloat(0x0C) ); boxmax = new Vector3 <float>( ctx.ReadFloat(0x10), ctx.ReadFloat(0x14), ctx.ReadFloat(0x18) ); max = new Vector3 <int>( ctx.ReadInt32(0x1C), ctx.ReadInt32(0x20), ctx.ReadInt32(0x24) ); unitSize = new Vector3 <float>( ctx.ReadFloat(0x28), ctx.ReadFloat(0x2C), ctx.ReadFloat(0x30) ); factor = new Vector3 <float>( ctx.ReadFloat(0x34), ctx.ReadFloat(0x38), ctx.ReadFloat(0x3C) ); Table = ctx.Deref(0x40); SSNodeMax = ctx.ReadInt16(0x44); SSNodeCount = ctx.ReadInt16(0x46); SSNodeTbl = ctx.Deref(0x48); polyCheckTbl = ctx.Deref(0x4C); dyna = new DynaCollisionContext(ctx, version); if (version.Game == Game.OcarinaOfTime) { mem_size = ctx.ReadInt32(0x1460); } else if (version.Game == Game.MajorasMask) { mem_size = ctx.ReadInt32(0x1468); flags = ctx.ReadInt32(0x146C); } }
public static List <FunctionInfo> GetFunctionInfo(RomVersion ver) { string game = ver.GetGameAbbr(); string filepath = $"data/{game}-{ver}.json"; if (File.Exists(filepath)) { return((List <FunctionInfo>)Deserialize(typeof(List <FunctionInfo>), filepath)); } return(new List <FunctionInfo>()); }
static void OverlayTest(RomVersion ver, string testOvl) { PathUtil.TryGetRomLocation(ver, out string path); Rom rom = Rom.New(path, ver); var tasks = DisassemblyTask.CreateTaskList(rom); Disassemble.PrintRelocations = true; Disassemble.GccOutput = true; var task = tasks.SingleOrDefault(x => x.Name == testOvl || x.Name == $"ovl_{testOvl}"); if (task == null) { Console.WriteLine("Cannot find overlay"); return; } //var taskbss = tasks.Where(x => x.Sections["bss"]?.Size > 0).ToList(); var reader = new BinaryReader(rom.Files.GetFile(task.VRom)); //using (StreamWriter sw = new StreamWriter("__test.txt")) //{ // foreach (var rel in task.Map.Relocations.Where(x => x.SectionId == Overlay.RelocationWord.Section.text)) // { // reader.BaseStream.Position = rel.Offset; // sw.WriteLine($"{rel.Offset:X6}: {rel.RelocType} {GetOP(reader.ReadBigInt32())}"); // } //} using (StreamWriter sw = new StreamWriter($"__{testOvl}.txt")) { BinaryReader br = new BinaryReader(rom.Files.GetFile(task.VRom)); Disassemble.FirstParse(br, task); if (Disassemble.GccOutput) { sw.WriteLine("#include <mips.h>"); sw.WriteLine(".set noreorder"); sw.WriteLine(".set noat"); sw.WriteLine(); } Disassemble.Task(sw, br, task); } using (StreamWriter sw = new StreamWriter($"__{testOvl}_f.txt")) { foreach (var item in Disassemble.Symbols.OrderBy(x => x.Key)) { sw.WriteLine($"{item.Value.ToString()} = 0x{item.Key}"); } } }
public static bool TryGetRomLocation(RomVersion input, out string path) { var key = input.UniqueKey; XPath rPath = settings.Rom.SingleOrDefault(x => x.key == key); if (rPath == null) { path = ""; return(false); } path = rPath.Value; return(File.Exists(path)); }
public RomHeader(RomVersion version, MemorySizes program, MemorySizes character, int mapper, int submapper, CpuTimingMode cpuTiming, RomFlags flags, ConsoleType console, int consoleTypeDetail, int miscellaneousRomCount, int defaultExpansionDevice) { Version = version; Program = program; Character = character; Mapper = mapper; Submapper = submapper; CpuTiming = cpuTiming; Flags = flags; Console = console; ConsoleTypeDetail = consoleTypeDetail; MiscellaneousRomCount = miscellaneousRomCount; DefaultExpansionDevice = defaultExpansionDevice; }
private void SetRomTypeSettings(RomVersion version) { OpenFileDialog openFile = new OpenFileDialog(); DialogResult result = DialogResult.OK; RomVersion inputVersion = version; //Set openFile title in case we need to look for a rom openFile.Title = $"Open {version} rom"; string romLocation; if (!version.IsCustomBuild()) { if (!PathUtil.TryGetRomLocation(version, out romLocation)) { result = openFile.ShowDialog(); if (result == DialogResult.OK) { PathUtil.SetRomLocation(version, openFile.FileName); PathUtil.TryGetRomLocation(version, out romLocation); } } } else { result = openFile.ShowDialog(); romLocation = openFile.FileName; if (result == DialogResult.OK) { using (VersionSelector vs = new VersionSelector()) { vs.Game = version.Game; result = vs.ShowDialog(); version = vs.Version; } } } openFile.Dispose(); rom = result == DialogResult.OK ? Rom.New(romLocation, version) : null; //update string romStats = rom == null ? $"Error: No Rom!" : $"{inputVersion.Game}, File Stats Mode: {version}{Environment.NewLine}{romLocation}"; outputRichTextBox.Clear(); outputRichTextBox.AppendText(romStats); }
private void Initialize() { if (Version == null) { Version = DEFAULT_VERSION; } if (Emulators == null) { Emulators = new Dictionary <string, Emulator>(); } HiddenActors = new List <int>(); }
private static void GetSymbols(List <DisassemblyTask> tasks, RomVersion ver, Func <FileAddress, Stream> getFile) { foreach (var task in tasks) { BinaryReader FileReader = new BinaryReader(getFile(task.VRom)); foreach (var item in task.Functions) { Disassemble.AddFunction(item); } //Get a list of function names Disassemble.FirstParse(FileReader, task); } }
static void MMDebugTest() { RomVersion ver = MRom.Build.DBG; PathUtil.TryGetRomLocation(ver, out string path); Rom rom = new MRom(path, ver); DisassemblyTask task = null; Disassemble.PrintRelocations = true; using StreamWriter sw = File.CreateText("__code.txt"); using BinaryReader br = new BinaryReader(rom.Files.GetFile(task.VRom)); Disassemble.FirstParse(br, task); Disassemble.Task(sw, br, task); }
public static int LoadRom(string filename) { if (!File.Exists(filename)) return -1; try { Rom = File.ReadAllBytes(filename); } catch { return -2; } if (Rom.Length != 0x2000000) return -3; string header = "MOTHER3\0\0\0\0\0A3UJ"; string headerTest = string.Empty; for (int i = 0xA0; i < 0xB0; i++) headerTest += (char)Rom[i]; if (!header.Equals(headerTest)) return -4; IsLoaded = true; switch (Rom[0x124C18]) { case 0x9C: Version = RomVersion.English; break; case 0x1C: Version = RomVersion.Englishv12; break; default: Version = RomVersion.Japanese; break; } if (Rom[0x1DB4] == 0x73) { DecodeAddress = 0x13C5F2; DecodeMod = 0x10E; } else { DecodeAddress = 0x13C5D8; DecodeMod = 0x126; } GfxProvider.RomTileCache.Clear(); M3CC.Init(); TextProvider.Init(); TextItemNames.Init(); TextEnemyNames.Init(); TextEnemyShortNames.Init(); TextMusicNames.Init(); TextItemDescriptions.Init(); TextEnemyDescriptions.Init(); TextBattle.Init(); TextMain.Init(); TextMapNames.Init(); TextPsiNames.Init(); TextCharNames.Init(); TextDontCareNames.Init(); GfxBattleTable.Init(); GfxBattleSprites.Init(); GfxItems.Init(); GfxBattleAnimations.Init(); GfxBattleBgTable.Init(); GfxBattleBg.Init(); GfxTownMaps.Init(); GfxLogoTitle.Init(); SpriteData.Init(); MusicPlayerTable.Init(); ActionTable.Init(); SongTable.Init(); return 0; }