Пример #1
0
        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);
        }
Пример #2
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());
        }
Пример #3
0
        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;
        }
Пример #4
0
        internal static void ChangeVersion(RomVersion v, bool gctx)
        {
            TOTAL_ACTORS = (v.Game == Game.OcarinaOfTime) ? 0x1D7 : 0x2B2;
            InstanceSize = new ushort[TOTAL_ACTORS];

            version = v;
        }
Пример #5
0
 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>()
     {
     });
 }
Пример #6
0
        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;
        }
Пример #7
0
        //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);
                }
            }
        }
Пример #8
0
            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);
            }
Пример #9
0
        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);
            }
        }
Пример #10
0
        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;
        }
Пример #11
0
        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());
        }
Пример #12
0
        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);
        }
Пример #13
0
 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}");
     }
 }
Пример #14
0
        private static string GetFolder(RomVersion Version)
        {
            string game = Version.Game.ToString()[0].ToString();
            var    dir  = $"{game}/{Version.ToString().ToUpper()}";

            Directory.CreateDirectory(dir);
            return(dir);
        }
Пример #15
0
 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);
 }
Пример #16
0
 private void okButton_Click(object sender, EventArgs e)
 {
     if (versionComboBox.SelectedIndex >= 0)
     {
         Version      = (RomVersion)versionComboBox.SelectedItem;
         DialogResult = DialogResult.OK;
         Close();
     }
 }
Пример #17
0
        public static void UpdateRomVersionUsingTell()
        {
            RomVersion?romVersion = GetRomVersionUsingTell();

            if (romVersion.HasValue)
            {
                Version = romVersion.Value;
            }
        }
Пример #18
0
 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}");
         }
     }
 }
Пример #19
0
 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);
 }
Пример #20
0
 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];
 }
Пример #21
0
        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);
        }
Пример #22
0
        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);
            }
        }
Пример #23
0
        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>());
        }
Пример #24
0
        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}");
                }
            }
        }
Пример #25
0
        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));
        }
Пример #26
0
 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;
 }
Пример #27
0
        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);
        }
Пример #28
0
        private void Initialize()
        {
            if (Version == null)
            {
                Version = DEFAULT_VERSION;
            }

            if (Emulators == null)
            {
                Emulators = new Dictionary <string, Emulator>();
            }

            HiddenActors = new List <int>();
        }
Пример #29
0
        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);
            }
        }
Пример #30
0
        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);
        }
Пример #31
0
        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;
        }