コード例 #1
0
 public void FinalizeSettings(CosmeticSettings settings)
 {
     if (settings.Music == Models.Music.Random)
     {
         SequenceMaskFileIndex = RomUtils.AppendFile(new byte[0x80 * SEQUENCE_DATA_SIZE]);
     }
     else
     {
         SequenceMaskFileIndex = null;
     }
 }
コード例 #2
0
ファイル: Builder.cs プロジェクト: colinthackston/mm-rando
        private void WriteStartupStrings()
        {
            if (_settings.LogicMode == LogicMode.Vanilla)
            {
                //ResourceUtils.ApplyHack(ModsDir + "postman-testing");
                return;
            }
            Version v = Assembly.GetExecutingAssembly().GetName().Version;

            RomUtils.SetStrings(Values.ModsDirectory + "logo-text", $"v{v}", _settings.ToString());
        }
コード例 #3
0
        /// <summary>
        /// Load <see cref="Symbols"/> from a special <see cref="MMFile"/> already in the ROM.
        /// </summary>
        /// <returns>Symbols</returns>
        public static Symbols FromROM()
        {
            int index = RomUtils.AddrToFile((int)MMFILE_START);

            // Might be unable to find MMFile with Symbols data for older patch files
            if (index < 0)
            {
                return(null);
            }

            var file = RomData.MMFileList[index];

            return(Symbols.FromMMFile(file));
        }
コード例 #4
0
        public void InitializeTable()
        {
            Dictionary <ushort, MessageEntry> messageTable = new Dictionary <ushort, MessageEntry>();

            int    fileIndex     = RomUtils.GetFileIndexForWriting(MESSAGE_TABLE_ADDRESS);
            MMFile file          = RomData.MMFileList[fileIndex];
            int    code_baseAddr = MESSAGE_TABLE_ADDRESS - file.Addr;
            var    code_data     = file.Data;

            fileIndex = RomUtils.GetFileIndexForWriting(MESSAGE_DATA_ADDRESS);
            file      = RomData.MMFileList[fileIndex];

            var message_data = file.Data;

            while (true)
            {
                ushort textId = ReadWriteUtils.Arr_ReadU16(code_data, code_baseAddr);
                if (textId >= 0xFFFF)
                {
                    break;
                }

                int address = ReadWriteUtils.Arr_ReadS32(code_data, code_baseAddr + 4) & 0xFFFFFF;

                byte[] header = new byte[11];
                Array.Copy(message_data, address, header, 0, 11);

                int    cur     = address + 11 - 1;
                string message = "";

                do
                {
                    cur++;
                    message += (char)message_data[cur];
                }while (message_data[cur] != 0xBF);


                MessageEntry messageEntry = new MessageEntry()
                {
                    Id      = textId,
                    Header  = header,
                    Message = message
                };
                messageTable.Add(textId, messageEntry);
                code_baseAddr += 8;
            }

            messages = messageTable;
        }
コード例 #5
0
        public static void WriteEntrances(int[] olde, int[] newe)
        {
            int f = RomUtils.GetFileIndexForWriting(0xC5BC64);

            uint[] data = new uint[newe.Length];

            for (int i = 0; i < newe.Length; i++)
            {
                data[i] = ReadWriteUtils.Arr_ReadU32(RomData.MMFileList[f].Data, GetEntranceAddr(newe[i]));
            }

            for (int i = 0; i < newe.Length; i++)
            {
                ReadWriteUtils.Arr_WriteU32(RomData.MMFileList[f].Data, GetEntranceAddr(olde[i]), data[i]);
            }
        }
コード例 #6
0
        private static int GetEntranceAddr(int ent)
        {
            int offset = ((ent >> 9) * 12) + 0xC5BC64;
            int f      = RomUtils.GetFileIndexForWriting(offset);

            offset -= RomData.MMFileList[f].Addr;
            uint p1 = ReadWriteUtils.Arr_ReadU32(RomData.MMFileList[f].Data, offset);

            offset = ((ent >> 4) & 0x1F) * 4;

            p1 = (uint)((p1 & 0xFFFFFF) + 0xA96540 - RomData.MMFileList[f].Addr);
            p1 = ReadWriteUtils.Arr_ReadU32(RomData.MMFileList[f].Data, (int)(p1 + offset));
            p1 = (uint)((p1 & 0xFFFFFF) + 0xA96540 - RomData.MMFileList[f].Addr);

            offset = (ent & 0xF) << 2;
            return((int)p1 + offset);
        }
コード例 #7
0
ファイル: Patcher.cs プロジェクト: jet082/mm-rando
        /// <summary>
        /// Apply patches.
        /// </summary>
        /// <param name="symbols">Symbols</param>
        /// <param name="options">Options</param>
        public void Apply(Symbols symbols, AsmOptionsGameplay options)
        {
            // Write patch data to existing MMFiles
            WriteToROM(symbols);

            // For our custom data, create and insert our own MMFile
            var file = CreateMMFile(symbols);

            RomUtils.AppendFile(file);

            // Encode Symbols into a special MMFile and insert that too
            var symbolsFile = symbols.CreateMMFile();

            RomUtils.AppendFile(symbolsFile);

            // Write subset of configuration (hardcoded into patch)
            symbols.ApplyConfiguration(options);
        }
コード例 #8
0
ファイル: Patcher.cs プロジェクト: colinthackston/mm-rando
        /// <summary>
        /// Apply patches.
        /// </summary>
        /// <param name="symbols">Symbols</param>
        /// <param name="options">Options</param>
        public void Apply(Symbols symbols, PatcherOptions options)
        {
            // Write patch data to existing MMFiles
            WriteToROM(symbols);

            // For our custom data, create and insert our own MMFile
            var file = CreateMMFile(symbols);

            RomUtils.AppendFile(file);

            // Encode Symbols into a special MMFile and insert that too
            var symbolsFile = symbols.CreateMMFile();

            RomUtils.AppendFile(symbolsFile);

            // Write our D-Pad config
            symbols.WriteDPadConfig(options.DPadConfig);
        }
コード例 #9
0
ファイル: Enemies.cs プロジェクト: ZoeyZolotova/mm-rando
        public static void DisableCombatMusicOnEnemy(GameObjects.Actor actor)
        {
            int actorInitVarRomAddr = actor.GetAttribute<ActorInitVarOffsetAttribute>().Offset;
            /// each enemy actor has actor init variables, 
            /// if they have combat music is determined if a flag is set in the seventh byte
            /// disabling combat music means disabling this bit for most enemies
            int actorFileID = (int)actor;
            RomUtils.CheckCompressed(actorFileID);
            int actorFlagLocation = (actorInitVarRomAddr + 7);// - RomData.MMFileList[ActorFID].Addr; // file offset
            byte flagByte = RomData.MMFileList[actorFileID].Data[actorFlagLocation];
            RomData.MMFileList[actorFileID].Data[actorFlagLocation] = (byte)(flagByte & 0xFB);

            if (actor == GameObjects.Actor.DekuBabaWithered) // special case: when they regrow music returns
            {
                // when they finish regrowing their combat music bit is reset, we need to no-op this to stop it
                // 	[ori t3,t1,0x0005] which is [35 2B 00 05] becomes [35 2B 00 01] as the 4 bit is combat music, 1 is R-targetable
                RomData.MMFileList[actorFileID].Data[0x12BF] = 0x01;
            }
        }
コード例 #10
0
        private void WriteShopObjects()
        {
            RomUtils.CheckCompressed(1325); // trading post
            var data = RomData.MMFileList[1325].Data.ToList();

            data.RemoveRange(0x15C, 4);                                    // reduce end padding from actors list
            data.InsertRange(0x62, new byte[] { 0x00, 0xC1, 0x00, 0xAF }); // add extra objects
            data[0x29] += 2;                                               // increase object count by 2
            data[0x37] += 4;                                               // add 4 to actor list address
            RomData.MMFileList[1325].Data = data.ToArray();

            RomUtils.CheckCompressed(1503);                                // bomb shop
            RomData.MMFileList[1503].Data[0x53]  = 0x98;                   // add extra objects
            RomData.MMFileList[1503].Data[0x29] += 1;                      // increase object count by 1

            RomUtils.CheckCompressed(1142);                                // witch shop
            data = RomData.MMFileList[1142].Data.ToList();
            data.RemoveRange(0x78, 4);                                     // reduce end padding from actors list
            data.InsertRange(0x48, new byte[] { 0x00, 0xC1, 0x00, 0xC1 }); // add extra objects
            data[0x29] += 2;                                               // increase object count by 2
            data[0x37] += 4;                                               // add 4 to actor list address
            RomData.MMFileList[1142].Data = data.ToArray();
        }
コード例 #11
0
        /// <summary>
        /// Try to perform randomization and make rom
        /// </summary>
        private void TryRandomize(BackgroundWorker worker, DoWorkEventArgs e)
        {
            if (!_settings.GenerateROM && !_settings.GenerateSpoilerLog && !_settings.GeneratePatch)
            {
                MessageBox.Show($"No output selected", "Error",
                                MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            RandomizedResult randomized;

            if (string.IsNullOrWhiteSpace(_settings.InputPatchFilename))
            {
                try
                {
                    randomized = _randomizer.Randomize(worker, e);
                }
                catch (InvalidDataException ex)
                {
                    MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
                catch (Exception ex)
                {
                    string nl = Environment.NewLine;
                    MessageBox.Show($"Error randomizing logic: {ex.Message}{nl}{nl}Please try a different seed", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                if (_settings.GenerateSpoilerLog &&
                    _settings.LogicMode != LogicMode.Vanilla)
                {
                    SpoilerUtils.CreateSpoilerLog(randomized, _settings);
                }
            }
            else
            {
                randomized = new RandomizedResult(_settings, null);
            }

            if (_settings.GenerateROM || _settings.GeneratePatch)
            {
                if (!ValidateInputFile())
                {
                    return;
                }

                if (!RomUtils.ValidateROM(_settings.InputROMFilename))
                {
                    MessageBox.Show("Cannot verify input ROM is Majora's Mask (U).",
                                    "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                _builder = new Builder(randomized);

                try
                {
                    _builder.MakeROM(_settings.InputROMFilename, _settings.OutputROMFilename, worker);
                }
                catch (Exception ex)
                {
                    string nl = Environment.NewLine;
                    MessageBox.Show($"Error building ROM: {ex.Message}{nl}{nl}Please contact the development team and provide them more information", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
            }

            _settings.InputPatchFilename = null;

            MessageBox.Show("Generation complete!",
                            "Success", MessageBoxButtons.OK, MessageBoxIcon.None);
        }
コード例 #12
0
ファイル: Builder.cs プロジェクト: robertsmatt97/mm-rando
        public void MakeROM(string InFile, string FileName, BackgroundWorker worker)
        {
            using (BinaryReader OldROM = new BinaryReader(File.Open(InFile, FileMode.Open, FileAccess.Read)))
            {
                RomUtils.ReadFileTable(OldROM);
                _messageTable.InitializeTable();
            }

            List <MMFile> originalMMFileList = null;

            if (_settings.GeneratePatch)
            {
                originalMMFileList = RomData.MMFileList.Select(file => file.Clone()).ToList();
            }

            if (!string.IsNullOrWhiteSpace(_settings.InputPatchFilename))
            {
                worker.ReportProgress(50, "Applying patch...");
                RomUtils.ApplyPatch(_settings.InputPatchFilename);
            }
            else
            {
                // todo music randomizer doesn't work if this is called after WriteItems(); because the reloc-audio hack is hardcoded
                worker.ReportProgress(50, "Writing audio...");
                WriteAudioSeq();

                worker.ReportProgress(55, "Writing player model...");
                WritePlayerModel();

                if (_settings.LogicMode != LogicMode.Vanilla)
                {
                    worker.ReportProgress(60, "Applying hacks...");
                    ResourceUtils.ApplyHack(Values.ModsDirectory + "title-screen");
                    ResourceUtils.ApplyHack(Values.ModsDirectory + "misc-changes");
                    ResourceUtils.ApplyHack(Values.ModsDirectory + "cm-cs");
                    ResourceUtils.ApplyHack(Values.ModsDirectory + "fix-song-of-healing");
                    WriteFileSelect();
                }
                ResourceUtils.ApplyHack(Values.ModsDirectory + "init-file");
                ResourceUtils.ApplyHack(Values.ModsDirectory + "fierce-deity-anywhere");

                worker.ReportProgress(61, "Writing quick text...");
                WriteQuickText();

                worker.ReportProgress(62, "Writing cutscenes...");
                WriteCutscenes();

                worker.ReportProgress(63, "Writing dungeons...");
                WriteDungeons();

                worker.ReportProgress(64, "Writing gimmicks...");
                WriteGimmicks();

                worker.ReportProgress(65, "Writing enemies...");
                WriteEnemies();

                worker.ReportProgress(66, "Writing items...");
                WriteItems();

                worker.ReportProgress(67, "Writing messages...");
                WriteGossipQuotes();
                MessageTable.WriteMessageTable(_messageTable);

                worker.ReportProgress(68, "Writing startup...");
                WriteStartupStrings();

                if (_settings.GeneratePatch)
                {
                    worker.ReportProgress(70, "Generating patch...");
                    RomUtils.CreatePatch(FileName, originalMMFileList);
                }
            }

            worker.ReportProgress(72, "Writing Tatl color...");
            WriteTatlColour();

            worker.ReportProgress(73, "Writing tunic color...");
            WriteTunicColor();

            if (_settings.GenerateROM)
            {
                worker.ReportProgress(75, "Building ROM...");

                byte[] ROM = RomUtils.BuildROM(FileName);
                if (_settings.OutputVC)
                {
                    worker.ReportProgress(90, "Building VC...");
                    VCInjectionUtils.BuildVC(ROM, Values.VCDirectory, Path.ChangeExtension(FileName, "wad"));
                }
            }
            worker.ReportProgress(100, "Done!");
        }
コード例 #13
0
ファイル: Builder.cs プロジェクト: colinthackston/mm-rando
        public void MakeROM(string InFile, string FileName, BackgroundWorker worker)
        {
            using (BinaryReader OldROM = new BinaryReader(File.Open(InFile, FileMode.Open, FileAccess.Read)))
            {
                RomUtils.ReadFileTable(OldROM);
                _messageTable.InitializeTable();
            }

            var originalMMFileList = RomData.MMFileList.Select(file => file.Clone()).ToList();

            byte[] hash;
            if (!string.IsNullOrWhiteSpace(_settings.InputPatchFilename))
            {
                worker.ReportProgress(50, "Applying patch...");
                hash = RomUtils.ApplyPatch(_settings.InputPatchFilename);

                // Apply Asm configuration post-patch
                WriteAsmConfigPostPatch();
            }
            else
            {
                worker.ReportProgress(55, "Writing player model...");
                WritePlayerModel();

                if (_settings.LogicMode != LogicMode.Vanilla)
                {
                    worker.ReportProgress(60, "Applying hacks...");
                    ResourceUtils.ApplyHack(Values.ModsDirectory + "title-screen");
                    ResourceUtils.ApplyHack(Values.ModsDirectory + "misc-changes");
                    ResourceUtils.ApplyHack(Values.ModsDirectory + "cm-cs");
                    ResourceUtils.ApplyHack(Values.ModsDirectory + "fix-song-of-healing");
                    WriteFileSelect();
                }
                ResourceUtils.ApplyHack(Values.ModsDirectory + "init-file");
                ResourceUtils.ApplyHack(Values.ModsDirectory + "fierce-deity-anywhere");

                worker.ReportProgress(61, "Writing quick text...");
                WriteQuickText();

                worker.ReportProgress(62, "Writing cutscenes...");
                WriteCutscenes();

                worker.ReportProgress(63, "Writing dungeons...");
                WriteDungeons();

                worker.ReportProgress(64, "Writing gimmicks...");
                WriteGimmicks();

                worker.ReportProgress(65, "Writing speedups...");
                WriteSpeedUps();

                worker.ReportProgress(66, "Writing enemies...");
                WriteEnemies();

                // if shop should match given items
                {
                    WriteShopObjects();
                }

                worker.ReportProgress(67, "Writing items...");
                WriteItems();

                worker.ReportProgress(68, "Writing messages...");
                WriteGossipQuotes();

                MessageTable.WriteMessageTable(_messageTable, _settings.QuickTextEnabled);

                worker.ReportProgress(69, "Writing startup...");
                WriteStartupStrings();

                worker.ReportProgress(70, "Writing ASM patch...");
                WriteAsmPatch();

                worker.ReportProgress(71, _settings.GeneratePatch ? "Generating patch..." : "Computing hash...");
                hash = RomUtils.CreatePatch(_settings.GeneratePatch ? FileName : null, originalMMFileList);
            }

            worker.ReportProgress(72, "Writing cosmetics...");
            WriteTatlColour();
            WriteTunicColor();

            worker.ReportProgress(73, "Writing music...");
            WriteAudioSeq(new Random(BitConverter.ToInt32(hash, 0)));
            WriteMuteMusic();

            worker.ReportProgress(74, "Writing sound effects...");
            WriteSoundEffects(new Random(BitConverter.ToInt32(hash, 0)));

            if (_settings.GenerateROM)
            {
                worker.ReportProgress(75, "Building ROM...");

                byte[] ROM = RomUtils.BuildROM(FileName);
                if (_settings.OutputVC)
                {
                    worker.ReportProgress(90, "Building VC...");
                    VCInjectionUtils.BuildVC(ROM, _settings.PatcherOptions, Values.VCDirectory, Path.ChangeExtension(FileName, "wad"));
                }
            }
            worker.ReportProgress(100, "Done!");
        }
コード例 #14
0
        public static string Process(Configuration configuration, int seed, IProgressReporter progressReporter)
        {
            var randomizer = new Randomizer(configuration.GameplaySettings, seed);
            RandomizedResult randomized = null;

            if (string.IsNullOrWhiteSpace(configuration.OutputSettings.InputPatchFilename))
            {
                try
                {
                    randomized = randomizer.Randomize(progressReporter);
                }
                catch (RandomizationException ex)
                {
                    string nl = Environment.NewLine;
                    return($"Error randomizing logic: {ex.Message}{nl}{nl}Please try a different seed");
                }
                catch (Exception ex)
                {
                    return(ex.Message);
                }

                if (configuration.OutputSettings.GenerateSpoilerLog &&
                    configuration.GameplaySettings.LogicMode != LogicMode.Vanilla)
                {
                    SpoilerUtils.CreateSpoilerLog(randomized, configuration.GameplaySettings, configuration.OutputSettings);
                }
            }

            if (configuration.OutputSettings.GenerateROM || configuration.OutputSettings.OutputVC || configuration.OutputSettings.GeneratePatch)
            {
                if (!RomUtils.ValidateROM(configuration.OutputSettings.InputROMFilename))
                {
                    return("Cannot verify input ROM is Majora's Mask (U).");
                }

                var builder = new Builder(randomized, configuration.CosmeticSettings);

                try
                {
                    builder.MakeROM(configuration.OutputSettings, progressReporter);
                }
                catch (PatchMagicException)
                {
                    return($"Error applying patch: Not a valid patch file");
                }
                catch (PatchVersionException ex)
                {
                    return($"Error applying patch: {ex.Message}");
                }
                catch (Exception ex)
                {
                    string nl = Environment.NewLine;
                    return($"Error building ROM: {ex.Message}{nl}{nl}Please contact the development team and provide them more information");
                }
            }

            //settings.InputPatchFilename = null;

            return(null);
            //return "Generation complete!";
        }
コード例 #15
0
        public static string Process(Configuration configuration, int seed, IProgressReporter progressReporter)
        {
            var randomizer = new Randomizer(configuration.GameplaySettings, seed);
            RandomizedResult randomized = null;

            if (string.IsNullOrWhiteSpace(configuration.OutputSettings.InputPatchFilename))
            {
                try
                {
                    randomized = randomizer.Randomize(progressReporter);

                    if ((configuration.OutputSettings.GenerateSpoilerLog || configuration.OutputSettings.GenerateHTMLLog) &&
                        configuration.GameplaySettings.LogicMode != LogicMode.Vanilla)
                    {
                        SpoilerUtils.CreateSpoilerLog(randomized, configuration.GameplaySettings, configuration.OutputSettings);
                    }
                }
                catch (RandomizationException ex)
                {
                    string nl = Environment.NewLine;
                    return($"Error randomizing logic: {ex.Message}{nl}{nl}Please try a different seed");
                }
                catch (Exception ex)
                {
                    return(ex.Message);
                }
            }

            if (configuration.OutputSettings.GenerateROM || configuration.OutputSettings.OutputVC || configuration.OutputSettings.GeneratePatch)
            {
                if (!RomUtils.ValidateROM(configuration.OutputSettings.InputROMFilename))
                {
                    return("Cannot verify input ROM is Majora's Mask (U).");
                }
                if (configuration.OutputSettings.OutputVC && !Directory.Exists(Values.VCDirectory))
                {
                    return("Error: vc folder is missing and WiiVC wad creation was selected.\n\n"
                           + "If you did not extract the whole randomizer, you must extract the vc folder. If this is a beta release, copy the vc folder from the main release.");
                }

                var builder = new Builder(randomized, configuration.CosmeticSettings);

                try
                {
                    builder.MakeROM(configuration.OutputSettings, progressReporter);
                }
                catch (ROMOverflowException ex)
                {
                    return($"Error: {ex.Message}");
                }
                catch (PatchMagicException)
                {
                    return($"Error applying patch: Not a valid patch file");
                }
                catch (PatchVersionException ex)
                {
                    return($"Error applying patch: {ex.Message}");
                }
                catch (IOException ex)
                {
                    return(ex.Message);
                }
                catch (Exception ex)
                {
                    string nl = Environment.NewLine;
                    return($"Error building ROM: {ex.Message}{nl}{nl}Please contact the development team and provide them more information");
                }
            }

            //settings.InputPatchFilename = null;

            return(null);
            //return "Generation complete!";
        }