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(); }
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(); }
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 })); }