Exemple #1
0
        /// <summary>
        /// Overwrite the clockspeed (see Settings.ClockSpeed for details)
        /// </summary>
        /// <param name="clockSpeed"></param>
        private void WriteClockSpeed(ClockSpeed clockSpeed)
        {
            byte  speed;
            short invertedModifier;

            switch (clockSpeed)
            {
            default:
            case ClockSpeed.Default:
                speed            = 3;
                invertedModifier = -2;
                break;

            case ClockSpeed.VerySlow:
                speed            = 1;
                invertedModifier = 0;
                break;

            case ClockSpeed.Slow:
                speed            = 2;
                invertedModifier = -1;
                break;

            case ClockSpeed.Fast:
                speed            = 6;
                invertedModifier = -4;
                break;

            case ClockSpeed.VeryFast:
                speed            = 9;
                invertedModifier = -6;
                break;

            case ClockSpeed.SuperFast:
                speed            = 18;
                invertedModifier = -12;
                break;
            }

            ResourceUtils.ApplyHack(Values.ModsDirectory + "fix-clock-speed");

            var codeFileAddress    = 0xB3C000;
            var hackAddressOffset  = 0x8A674;
            var modificationOffset = 0x1B;

            ReadWriteUtils.WriteToROM(codeFileAddress + hackAddressOffset + modificationOffset, speed);

            var invertedModifierOffsets = new List <int>
            {
                0xB1B8E,
                0x7405E
            };

            foreach (var offset in invertedModifierOffsets)
            {
                ReadWriteUtils.WriteToROM(codeFileAddress + offset, (ushort)invertedModifier);
            }
        }
Exemple #2
0
 private void WriteMuteMusic()
 {
     if (_settings.NoBGM)
     {
         var codeFileAddress = 0xB3C000;
         var offset          = 0x102350;                              // address for branch when scene music is loaded
         ReadWriteUtils.WriteToROM(codeFileAddress + offset, 0x1000); // change to always branch (do not load)
     }
 }
Exemple #3
0
 /// <summary>
 /// Patch existing <see cref="MMFile"/> files.
 /// </summary>
 public void WriteToROM(Symbols symbols)
 {
     foreach (var data in _data)
     {
         if (TABLE_END <= data.Address && data.Address < symbols.PayloadStart)
         {
             ReadWriteUtils.WriteToROM((int)data.Address, data.Data);
         }
     }
 }
Exemple #4
0
        /// <summary>
        /// Write a <see cref="DPadConfig"/> to the ROM.
        /// </summary>
        /// <remarks>Assumes <see cref="Patcher"/> file has been inserted.</remarks>
        /// <param name="config">D-Pad config</param>
        public void WriteDPadConfig(DPadConfig config)
        {
            // Write DPad config bytes.
            var addr = this["DPAD_CONFIG"];

            ReadWriteUtils.WriteToROM((int)addr, config.Pad.Bytes);

            // Write DPad state
            WriteDPadState(config.State);
        }
Exemple #5
0
        /// <summary>
        /// Write a <see cref="DPadConfig"/> to the ROM.
        /// </summary>
        /// <remarks>Assumes <see cref="Patcher"/> file has been inserted.</remarks>
        /// <param name="config">D-Pad config</param>
        void WriteDPadConfigLegacy(DPadConfig config)
        {
            // Write DPad config bytes.
            var addr = this["DPAD_CONFIG"];

            ReadWriteUtils.WriteToROM((int)addr, config.Pad.Bytes);

            // Write DPad state byte.
            addr = this["DPAD_STATE"];
            ReadWriteUtils.WriteToROM((int)addr, (byte)config.State);
        }
Exemple #6
0
        private void WriteFreeItems(params Item[] items)
        {
            Dictionary <int, byte> startingItems = new Dictionary <int, byte>();

            PutOrCombine(startingItems, 0xC5CE72, 0x10); // add Song of Time

            var itemList = items.ToList();

            if (_settings.CustomStartingItemList != null)
            {
                itemList.AddRange(_settings.CustomStartingItemList);
            }

            itemList.Add(Item.StartingHeartContainer1);
            while (itemList.Count(item => item.Name() == "Piece of Heart") >= 4)
            {
                itemList.Add(Item.StartingHeartContainer1);
                for (var i = 0; i < 4; i++)
                {
                    var heartPiece = itemList.First(item => item.Name() == "Piece of Heart");
                    itemList.Remove(heartPiece);
                }
            }

            itemList = itemList
                       .GroupBy(item => ItemUtils.ForbiddenStartTogether.FirstOrDefault(fst => fst.Contains(item)))
                       .SelectMany(g => g.Key == null ? g.ToList() : g.OrderByDescending(item => g.Key.IndexOf(item)).Take(1))
                       .ToList();

            foreach (var item in itemList)
            {
                var startingItemValues = item.GetAttributes <StartingItemAttribute>();
                if (!startingItemValues.Any() && !_settings.NoStartingItems)
                {
                    throw new Exception($@"Invalid starting item ""{item}""");
                }
                foreach (var startingItem in startingItemValues)
                {
                    PutOrCombine(startingItems, startingItem.Address, startingItem.Value, startingItem.IsAdditional);
                }
            }

            foreach (var kvp in startingItems)
            {
                ReadWriteUtils.WriteToROM(kvp.Key, kvp.Value);
            }

            if (itemList.Count(item => item.Name() == "Heart Container") == 1)
            {
                ReadWriteUtils.WriteToROM(0x00B97E8F, 0x0C); // reduce low health beep threshold
            }
        }
Exemple #7
0
        private void WriteFreeItem(int Item)
        {
            ReadWriteUtils.WriteToROM(Items.ITEM_ADDRS[Item], Items.ITEM_VALUES[Item]);
            switch (Item)
            {
            case Items.ItemBow:
                ReadWriteUtils.WriteToROM(0xC5CE6F, (byte)0x01);
                break;

            case Items.ItemBombBag:
                ReadWriteUtils.WriteToROM(0xC5CE6F, (byte)0x08);
                break;

            case Items.UpgradeRazorSword:     //sword upgrade
                ReadWriteUtils.WriteToROM(0xC5CE00, (byte)0x4E);
                break;

            case Items.UpgradeGildedSword:
                ReadWriteUtils.WriteToROM(0xC5CE00, (byte)0x4F);
                break;

            case Items.UpgradeBigQuiver:     //quiver upgrade
                ReadWriteUtils.WriteToROM(0xC5CE6F, (byte)0x02);
                break;

            case Items.UpgradeBiggestQuiver:
                ReadWriteUtils.WriteToROM(0xC5CE6F, (byte)0x03);
                break;

            case Items.UpgradeBigBombBag:    //bomb bag upgrade
                ReadWriteUtils.WriteToROM(0xC5CE6F, (byte)0x10);
                break;

            case Items.UpgradeBiggestBombBag:
                ReadWriteUtils.WriteToROM(0xC5CE6F, (byte)0x18);
                break;

            default:
                break;
            }
        }
Exemple #8
0
        private void WriteFreeItems(params Item[] items)
        {
            Dictionary <int, byte> startingItems = new Dictionary <int, byte>();

            PutOrCombine(startingItems, 0xC5CE72, 0x10); // add Song of Time

            // can't start with more than 15 hearts with this method. heart container value is two bytes
            PutOrCombine(startingItems, 0xC5CDE9, 0x10, true); // add Heart Container
            PutOrCombine(startingItems, 0xC5CDEB, 0x10, true); // add current health
            PutOrCombine(startingItems, 0xC40E1B, 0x10, true); // add respawn health

            var itemList = items.ToList();

            while (itemList.Count(item => item.Name() == "Piece of Heart") >= 4)
            {
                itemList.Add(Item.StartingHeartContainer1);
                for (var i = 0; i < 4; i++)
                {
                    var heartPiece = itemList.First(item => item.Name() == "Piece of Heart");
                    itemList.Remove(heartPiece);
                }
            }

            foreach (var item in itemList)
            {
                var startingItemValues = item.GetAttributes <StartingItemAttribute>();
                if (!startingItemValues.Any() && !_settings.NoStartingItems)
                {
                    throw new Exception($@"Invalid starting item ""{item}""");
                }
                foreach (var startingItem in startingItemValues)
                {
                    PutOrCombine(startingItems, startingItem.Address, startingItem.Value, startingItem.IsAdditional);
                }
            }

            foreach (var kvp in startingItems)
            {
                ReadWriteUtils.WriteToROM(kvp.Key, kvp.Value);
            }
        }
Exemple #9
0
        private void WriteBlastMaskCooldown()
        {
            ushort value;

            switch (_settings.BlastMaskCooldown)
            {
            default:
            case BlastMaskCooldown.Default:
                value = 0x136;     // 310 frames
                break;

            case BlastMaskCooldown.Instant:
                value = 0x1;     // 1 frame
                break;

            case BlastMaskCooldown.VeryShort:
                value = 0x20;     // 32 frames
                break;

            case BlastMaskCooldown.Short:
                value = 0x80;     // 128 frames
                break;

            case BlastMaskCooldown.Long:
                value = 0x200;     // 512 frames
                break;

            case BlastMaskCooldown.VeryLong:
                value = 0x400;     // 1024 frames
                break;
            }

            var codeFileAddress = 0x00CA7F00;
            var offset          = 0x002766;

            ReadWriteUtils.WriteToROM(codeFileAddress + offset, value);
        }
Exemple #10
0
        private void WriteFreeItems(params int[] itemIds)
        {
            Dictionary <int, byte> startingItems = new Dictionary <int, byte>();

            if (!itemIds.Contains(Items.UpgradeRazorSword) && !itemIds.Contains(Items.UpgradeGildedSword))
            {
                PutOrCombine(startingItems, 0xC5CE21, 0x01); // add Kokiri Sword
            }
            if (!itemIds.Contains(Items.UpgradeMirrorShield))
            {
                PutOrCombine(startingItems, 0xC5CE21, 0x10); // add Hero's Shield
            }
            PutOrCombine(startingItems, 0xC5CE72, 0x10);     // add Song of Time

            foreach (var id in itemIds)
            {
                var itemAddress = Items.ITEM_ADDRS[id];
                var itemValue   = Items.ITEM_VALUES[id];
                PutOrCombine(startingItems, itemAddress, itemValue, ItemUtils.IsHeartPiece(id));

                switch (id)
                {
                case Items.ItemBow:
                    PutOrCombine(startingItems, 0xC5CE6F, 0x01);
                    break;

                case Items.ItemBombBag:
                    PutOrCombine(startingItems, 0xC5CE6F, 0x08);
                    break;

                case Items.UpgradeRazorSword:     //sword upgrade
                    startingItems[0xC5CE00] = 0x4E;
                    break;

                case Items.UpgradeGildedSword:
                    startingItems[0xC5CE00] = 0x4F;
                    break;

                case Items.UpgradeBigQuiver:     //quiver upgrade
                    PutOrCombine(startingItems, 0xC5CE6F, 0x02);
                    break;

                case Items.UpgradeBiggestQuiver:
                    PutOrCombine(startingItems, 0xC5CE6F, 0x03);
                    break;

                case Items.UpgradeBigBombBag:    //bomb bag upgrade
                    PutOrCombine(startingItems, 0xC5CE6F, 0x10);
                    break;

                case Items.UpgradeBiggestBombBag:
                    PutOrCombine(startingItems, 0xC5CE6F, 0x18);
                    break;

                default:
                    break;
                }
            }

            foreach (var kvp in startingItems)
            {
                ReadWriteUtils.WriteToROM(kvp.Key, kvp.Value);
            }
        }
Exemple #11
0
        /// <summary>
        /// Write <see cref="MimicItemTable"/> table to ROM.
        /// </summary>
        /// <param name="table">Table</param>
        public void WriteMimicItemTable(MimicItemTable table)
        {
            var addr = this["ITEM_OVERRIDE_ENTRIES"];

            ReadWriteUtils.WriteToROM((int)addr, table.Build());
        }