示例#1
0
 public static void GetMaps()
 {
     for (int i = 0; i < RomData.SceneList.Count; i++)
     {
         int f = RomData.SceneList[i].File;
         RomUtils.CheckCompressed(f);
         int j = 0;
         while (true)
         {
             byte cmd = RomData.MMFileList[f].Data[j];
             if (cmd == 0x04)
             {
                 byte mapcount = RomData.MMFileList[f].Data[j + 1];
                 int  mapsaddr = (int)ReadWriteUtils.Arr_ReadU32(RomData.MMFileList[f].Data, j + 4) & 0xFFFFFF;
                 for (int k = 0; k < mapcount; k++)
                 {
                     Map m = new Map();
                     m.File = RomUtils.AddrToFile((int)ReadWriteUtils.Arr_ReadU32(RomData.MMFileList[f].Data, mapsaddr));
                     RomData.SceneList[i].Maps.Add(m);
                     mapsaddr += 8;
                 }
                 break;
             }
             if (cmd == 0x14)
             {
                 break;
             }
             j += 8;
         }
     }
 }
示例#2
0
 public static void GetActors()
 {
     for (int i = 0; i < RomData.SceneList.Count; i++)
     {
         for (int j = 0; j < RomData.SceneList[i].Maps.Count; j++)
         {
             int f = RomData.SceneList[i].Maps[j].File;
             RomUtils.CheckCompressed(f);
             int k = RomData.SceneList[i].Maps[j].Header;
             while (true)
             {
                 byte cmd = RomData.MMFileList[f].Data[k];
                 if (cmd == 0x01)
                 {
                     byte ActorCount = RomData.MMFileList[f].Data[k + 1];
                     int  ActorAddr  = (int)ReadWriteUtils.Arr_ReadU32(RomData.MMFileList[f].Data, k + 4) & 0xFFFFFF;
                     RomData.SceneList[i].Maps[j].ActorAddr = ActorAddr;
                     RomData.SceneList[i].Maps[j].Actors    = ReadMapActors(RomData.MMFileList[f].Data, ActorAddr, ActorCount);
                 }
                 if (cmd == 0x0B)
                 {
                     byte ObjectCount = RomData.MMFileList[f].Data[k + 1];
                     int  ObjectAddr  = (int)ReadWriteUtils.Arr_ReadU32(RomData.MMFileList[f].Data, k + 4) & 0xFFFFFF;
                     RomData.SceneList[i].Maps[j].ObjAddr = ObjectAddr;
                     RomData.SceneList[i].Maps[j].Objects = ReadMapObjects(RomData.MMFileList[f].Data, ObjectAddr, ObjectCount);
                 }
                 if (cmd == 0x14)
                 {
                     break;
                 }
                 k += 8;
             }
         }
     }
 }
示例#3
0
        public static void ReenableNightBGM()
        {
            // summary: there is a scene header which has a single byte that determines what plays at night, setting to 13 re-enables BGM at night

            // since scene table is only read previously on enemizer, if not loaded we have to load now
            if (RomData.SceneList == null)
            {
                ReadSceneTable();
            }

            // TODO since this is static, it can be moved
            var TargetSceneEnums = new GameObjects.Scene[]
            {
                GameObjects.Scene.TerminaField,
                GameObjects.Scene.RoadToSouthernSwamp,
                GameObjects.Scene.SouthernSwamp,
                GameObjects.Scene.SouthernSwampClear,
                GameObjects.Scene.PathToMountainVillage,
                GameObjects.Scene.MountainVillage,
                GameObjects.Scene.MountainVillageSpring,
                GameObjects.Scene.TwinIslands,
                GameObjects.Scene.TwinIslandsSpring,
                GameObjects.Scene.GoronRacetrack,
                GameObjects.Scene.GoronVillage,
                GameObjects.Scene.GoronVillageSpring,
                GameObjects.Scene.PathToSnowhead,
                GameObjects.Scene.Snowhead,
                GameObjects.Scene.MilkRoad,
                GameObjects.Scene.GreatBayCoast,
                GameObjects.Scene.PinnacleRock,
                GameObjects.Scene.ZoraCape,
                GameObjects.Scene.WaterfallRapids,
                GameObjects.Scene.RoadToIkana,
                GameObjects.Scene.IkanaCanyon,
                GameObjects.Scene.EastClockTown,
                GameObjects.Scene.WestClockTown,
                GameObjects.Scene.NorthClockTown,
                GameObjects.Scene.SouthClockTown,
                GameObjects.Scene.LaundryPool,
                GameObjects.Scene.Woodfall,
            }.ToList();

            foreach (var SceneEnum in TargetSceneEnums)
            {
                ReenableNightBGMSingle(RomData.SceneList.Find(u => u.Number == SceneEnum.Id()).File);
            }

            // Kamaro the dancing ghost in Termina Field breaks night music
            //   he calls a function that sets an unknown actor flag unk39 & 20, he calls this function per frame from multiple places
            // if we nop it his music never plays, and might music is never interupted by him
            var kamaroFID = 593; //GameObjects.Actor.En_Yb.FileListIndex();

            RomUtils.CheckCompressed(kamaroFID);
            var kamaroData = RomData.MMFileList[kamaroFID].Data;

            // null function call to func_800B9084 -> NOP
            ReadWriteUtils.Arr_WriteU32(kamaroData, 0x618, 0x00000000);
        }
示例#4
0
 public static void GetMapHeaders()
 {
     for (int i = 0; i < RomData.SceneList.Count; i++)
     {
         int maps = RomData.SceneList[i].Maps.Count;
         for (int j = 0; j < maps; j++)
         {
             int f = RomData.SceneList[i].Maps[j].File;
             RomUtils.CheckCompressed(f);
             int k          = 0;
             int setupsaddr = -1;
             int nextlowest = -1;
             while (true)
             {
                 byte cmd = RomData.MMFileList[f].Data[k];
                 if (cmd == 0x18)
                 {
                     setupsaddr = (int)ReadWriteUtils.Arr_ReadU32(RomData.MMFileList[f].Data, k + 4) & 0xFFFFFF;
                 }
                 else if (cmd == 0x14)
                 {
                     break;
                 }
                 else
                 {
                     if (RomData.MMFileList[f].Data[k + 4] == 0x03)
                     {
                         int p = (int)ReadWriteUtils.Arr_ReadU32(RomData.MMFileList[f].Data, k + 4) & 0xFFFFFF;
                         if (((p < nextlowest) || (nextlowest == -1)) && ((p > setupsaddr) && (setupsaddr != -1)))
                         {
                             nextlowest = p;
                         }
                     }
                 }
                 k += 8;
             }
             if ((setupsaddr == -1) || (nextlowest == -1))
             {
                 continue;
             }
             for (k = setupsaddr; k < nextlowest; k += 4)
             {
                 byte s = RomData.MMFileList[f].Data[k];
                 if (s != 0x03)
                 {
                     break;
                 }
                 int p = (int)ReadWriteUtils.Arr_ReadU32(RomData.MMFileList[f].Data, k) & 0xFFFFFF;
                 Map m = new Map();
                 m.File   = f;
                 m.Header = p;
                 RomData.SceneList[i].Maps.Add(m);
             }
         }
     }
 }
示例#5
0
 public static void ReenableNightBGMSingle(int SceneFileID, byte NewMusicByte = 0x13)
 {
     // search for the bgm music header in the scene headers and replace the night sfx with a value that plays day BGM
     RomUtils.CheckCompressed(SceneFileID);
     for (int Byte = 0; Byte < 0x10 * 70; Byte += 8)
     {
         if (RomData.MMFileList[SceneFileID].Data[Byte] == 0x15)              // header command starts with 0x15
         {
             RomData.MMFileList[SceneFileID].Data[Byte + 0x6] = NewMusicByte; // 6th/8 byte is night BGM behavior, 0x13 is daytime BGM
             return;
         }
     }
 }
示例#6
0
        public static void ReassignSkulltulaHousesMusic(byte replacement_slot = 0x75)
        {
            // changes the skulltulla house BGM to a separate slot so it plays a new music that isn't generic cave music (overused)
            // the BGM for a scene is specified by a single byte in the scene headers

            // to modify the scene header, which is in the scene, we need the scene as a file
            //  we can get this from the Romdata.SceneList but this only gets populated on enemizer
            //  and we don't NEED to populate it since vanilla scenes are static, we can just hard code it here
            //  at re-encode, we'll have fewer decoded files to re-encode too
            int swamp_spider_house_fid = 1284; // taken from ultimate MM spreadsheet (US File list -> A column)

            // scan the files for the header that contains scene music (0x15 first byte)
            // 15xx0000 0000yyzz where zz is the sequence pointer byte
            RomUtils.CheckCompressed(swamp_spider_house_fid);
            for (int b = 0; b < 0x10 * 70; b += 8)
            {
                if (RomData.MMFileList[swamp_spider_house_fid].Data[b] == 0x15 &&
                    RomData.MMFileList[swamp_spider_house_fid].Data[b + 0x7] == 0x3B)
                {
                    RomData.MMFileList[swamp_spider_house_fid].Data[b + 0x7] = replacement_slot;
                    break;
                }
            }

            int ocean_spider_house_fid = 1291; // taken from ultimate MM spreadsheet

            RomUtils.CheckCompressed(ocean_spider_house_fid);
            for (int b = 0; b < 0x10 * 70; b += 8)
            {
                if (RomData.MMFileList[ocean_spider_house_fid].Data[b] == 0x15 &&
                    RomData.MMFileList[ocean_spider_house_fid].Data[b + 0x7] == 0x3B)
                {
                    RomData.MMFileList[ocean_spider_house_fid].Data[b + 0x7] = replacement_slot;
                    break;
                }
            }


            SequenceInfo new_music_slot = new SequenceInfo
            {
                Name     = "mm-spiderhouse-replacement",
                MM_seq   = replacement_slot,
                Replaces = replacement_slot,
                Type     = new List <int> {
                    2
                },
                Instrument = 3
            };

            RomData.TargetSequences.Add(new_music_slot);
        }
示例#7
0
        public static byte[] GetObjectData(int objectIndex)
        {
            var objectTableFileIndex = RomUtils.GetFileIndexForWriting(OBJECT_TABLE);
            var baseAddress          = OBJECT_TABLE - RomData.MMFileList[objectTableFileIndex].Addr;
            var objectAddress        = ReadWriteUtils.Arr_ReadU32(RomData.MMFileList[objectTableFileIndex].Data, baseAddress + (objectIndex * 8));
            var objectFileIndex      = RomData.MMFileList.FindIndex(f => f.Addr == objectAddress);

            if (objectFileIndex == -1)
            {
                return(null);
            }
            RomUtils.CheckCompressed(objectFileIndex);
            return(RomData.MMFileList[objectFileIndex].Data);
        }
示例#8
0
        /// <summary>
        /// Get image data for the 4 stray fairy icons.
        /// </summary>
        /// <returns>Array of image bytes.</returns>
        public static byte[][] GetStrayFairyIcons()
        {
            // Stray Fairy icons start at: 0xA0A000 + 0x1B80
            RomUtils.CheckCompressed(11);
            var fileData = RomData.MMFileList[11].Data;

            // Extract HUD icon for Stray Fairy icons.
            var fairies = new List <byte[]>(4);

            for (int i = 0; i < 4; i++)
            {
                var imageData = new byte[0xC00];
                var offset    = 0x1B80 + (imageData.Length * i);
                Buffer.BlockCopy(fileData, offset, imageData, 0, imageData.Length);
                fairies.Add(imageData);
            }

            return(fairies.ToArray());
        }
示例#9
0
 public static void GetMaps()
 {
     foreach (var scene in RomData.SceneList)
     {
         int f = scene.File;
         RomUtils.CheckCompressed(f);
         int j = 0;
         while (true)
         {
             byte cmd = RomData.MMFileList[f].Data[j];
             if (cmd == 0x04)
             {
                 byte mapcount = RomData.MMFileList[f].Data[j + 1];
                 int  mapsaddr = (int)ReadWriteUtils.Arr_ReadU32(RomData.MMFileList[f].Data, j + 4) & 0xFFFFFF;
                 for (int k = 0; k < mapcount; k++)
                 {
                     Map m = new Map();
                     m.File = RomUtils.AddrToFile((int)ReadWriteUtils.Arr_ReadU32(RomData.MMFileList[f].Data, mapsaddr));
                     scene.Maps.Add(m);
                     mapsaddr += 8;
                 }
                 break;
             }
             if (cmd == 0x14)
             {
                 break;
             }
             j += 8;
         }
         CheckHeaderForExits(f, 0, scene);
         if (scene.Number == 108) // avoid modifying unused setup in East Clock Town. doesn't seem to actually affect anything in-game, but best not to touch it.
         {
             scene.Setups.RemoveAt(2);
         }
     }
 }
示例#10
0
 /// <summary>
 /// Get the <see cref="MMFile"/> at a <see cref="FileIndex"/>.
 /// </summary>
 /// <param name="index">File index.</param>
 /// <returns></returns>
 static MMFile GetFile(FileIndex index)
 {
     RomUtils.CheckCompressed((int)index);
     return(RomData.MMFileList[(int)index]);
 }