public AutoSearchModel(byte[] data, StoredMetadata metadata = null) : base(data, metadata)
        {
            if (metadata != null && !metadata.IsEmpty)
            {
                return;
            }

            gameCode = string.Concat(Enumerable.Range(0xAC, 4).Select(i => ((char)data[i]).ToString()));

            // in vanilla emerald, this pointer isn't four-byte aligned
            // it's at the very front of the ROM, so if there's no metadata we can be pretty sure that the pointer is still there
            if (gameCode == Emerald && data[0x1C3] == 0x08)
            {
                ObserveRunWritten(noChangeDelta, new PointerRun(0x1C0));
            }

            var gamesToDecode = new[] { Ruby, Sapphire, Emerald, FireRed, LeafGreen };

            if (gamesToDecode.Contains(gameCode))
            {
                DecodeHeader();
                DecodeNameArrays();
                DecodeDataArrays();
                DecodeStreams();
            }

            ResolveConflicts();
        }
Example #2
0
        public HardcodeTablesModel(Singletons singletons, byte[] data, StoredMetadata metadata = null) : base(data, metadata, singletons)
        {
            if (metadata != null && !metadata.IsEmpty)
            {
                return;
            }

            gameCode = this.GetGameCode();

            // in vanilla emerald, this pointer isn't four-byte aligned
            // it's at the very front of the ROM, so if there's no metadata we can be pretty sure that the pointer is still there
            if (gameCode == Emerald && data.Length > EarliestAllowedAnchor && data[0x1C3] == 0x08)
            {
                ObserveRunWritten(noChangeDelta, new PointerRun(0x1C0));
            }

            var gamesToDecode = new[] { Ruby, Sapphire, Emerald, FireRed, LeafGreen, Ruby1_1, Sapphire1_1, FireRed1_1, LeafGreen1_1 };

            if (gamesToDecode.Contains(gameCode))
            {
                LoadDefaultMetadata(gameCode.Substring(0, 4).ToLower());
                DecodeHeader();
                if (singletons.GameReferenceTables.TryGetValue(gameCode, out var referenceTables))
                {
                    DecodeTablesFromReference(referenceTables);
                }
            }

            ResolveConflicts();
        }
Example #3
0
        private void LoadDefaultMetadata(string code)
        {
            if (File.Exists("resources/default.toml"))
            {
                var lines    = File.ReadAllLines("resources/default.toml");
                var metadata = new StoredMetadata(lines);
                foreach (var list in metadata.Lists)
                {
                    SetList(list.Name, list.Contents);
                }
                foreach (var anchor in metadata.NamedAnchors)
                {
                    ApplyAnchor(this, new NoDataChangeDeltaModel(), anchor.Address, BaseRun.AnchorStart + anchor.Name + anchor.Format, allowAnchorOverwrite: true);
                }
            }

            foreach (var fileName in Directory.GetFiles("resources", "default.*.toml"))
            {
                if (!fileName.ToLower().Contains($".{code}."))
                {
                    continue;
                }
                var lines    = File.ReadAllLines(fileName);
                var metadata = new StoredMetadata(lines);
                foreach (var list in metadata.Lists)
                {
                    SetList(list.Name, list.Contents);
                }
                foreach (var anchor in metadata.NamedAnchors)
                {
                    ApplyAnchor(this, new NoDataChangeDeltaModel(), anchor.Address, BaseRun.AnchorStart + anchor.Name + anchor.Format, allowAnchorOverwrite: true);
                }
            }
        }
        public HardcodeTablesModel(Singletons singletons, byte[] data, StoredMetadata metadata = null) : base(data, metadata, singletons)
        {
            gameCode = this.GetGameCode();
            if (metadata != null && !metadata.IsEmpty)
            {
                InitializationWorkload = (singletons?.WorkDispatcher ?? InstantDispatch.Instance).RunBackgroundWork(() => Initialize(metadata));
                return;
            }

            InitializationWorkload = (singletons?.WorkDispatcher ?? InstantDispatch.Instance).RunBackgroundWork(() => {
                {
                    if (singletons.GameReferenceConstants.TryGetValue(gameCode, out var referenceConstants))
                    {
                        metadata = DecodeConstantsFromReference(this, singletons.MetadataInfo, metadata, referenceConstants);
                    }
                    Initialize(metadata);
                    isCFRU = GetIsCFRU();

                    // in vanilla emerald, this pointer isn't four-byte aligned
                    // it's at the very front of the ROM, so if there's no metadata we can be pretty sure that the pointer is still there
                    if (gameCode == Emerald && data.Length > EarliestAllowedAnchor && data[0x1C3] == 0x08)
                    {
                        ObserveRunWritten(noChangeDelta, new PointerRun(0x1C0));
                    }

                    var gamesToDecode = new[] { Ruby, Sapphire, Emerald, FireRed, LeafGreen, Ruby1_1, Sapphire1_1, FireRed1_1, LeafGreen1_1, "BPRF0" };
                    if (gamesToDecode.Contains(gameCode))
                    {
                        foreach (var defaultMetadata in GetDefaultMetadatas(gameCode.Substring(0, 4).ToLower(), gameCode.ToLower()))
                        {
                            this.LoadMetadata(defaultMetadata);
                        }
                        if (singletons.GameReferenceTables.TryGetValue(gameCode, out var referenceTables))
                        {
                            DecodeTablesFromReference(referenceTables);
                        }
                    }

                    ResolveConflicts();
                }
            });
        }
        public static StoredMetadata DecodeConstantsFromReference(IReadOnlyList <byte> model, IMetadataInfo info, StoredMetadata metadata, GameReferenceConstants constants)
        {
            if (metadata == null)
            {
                return(metadata);
            }
            var words       = metadata.MatchedWords.ToList();
            var constantSet = new Dictionary <string, IList <StoredMatchedWord> >();

            foreach (var constant in constants.SelectMany(c => c.ToStoredMatchedWords()))
            {
                if (!constantSet.ContainsKey(constant.Name))
                {
                    constantSet[constant.Name] = new List <StoredMatchedWord>();
                }
                constantSet[constant.Name].Add(constant);
            }
            foreach (var constant in constantSet.Values)
            {
                if (constant.Any(c => c.Address + c.Length > model.Count))
                {
                    continue;
                }
                var virtualValues = constant.Select(c => (model.ReadMultiByteValue(c.Address, c.Length) - c.AddOffset) / c.MultOffset).ToList();
                var match         = virtualValues.All(vv => vv == virtualValues[0]);
                if (match)
                {
                    words.AddRange(constant);
                }
            }
            return(new StoredMetadata(metadata.NamedAnchors, metadata.UnmappedPointers, words, metadata.OffsetPointers, metadata.Lists, metadata.UnmappedConstants, metadata.GotoShortcuts, info,
                                      new StoredMetadataFields {
                FreeSpaceSearch = metadata.FreeSpaceSearch,
                FreeSpaceBuffer = metadata.FreeSpaceBuffer,
                NextExportID = metadata.NextExportID,
                ShowRawIVByteForTrainer = metadata.ShowRawIVByteForTrainer
            }));
        }