public void Visit(BitArray array, byte data) { using (ModelCacheScope.CreateScope(model)) { var table = (ITableRun)model.GetNextRun(array.Source); var offset = table.ConvertByteOffsetToArrayOffset(array.Source); var segment = (ArrayRunBitArraySegment)table.ElementContent[offset.SegmentIndex]; var options = segment.GetOptions(model)?.ToList(); if (options == null) { return; } for (int i = 0; i < array.Length; i++) { var group = i * 8; for (int j = 0; j < 8 && group + j < options.Count; j++) { var bit = ((model[array.Source + i] >> j) & 1); if (bit != 0) { Content.Add(options[group + j]); } } } if (Content.Count == 0) { Content.Add("- None -"); } } }
private void DecodeTablesFromReference(GameReferenceTables tables) { foreach (var table in tables) { if (isCFRU && table.Name == "graphics.pokemon.sprites.coordinates.front") { continue; } if (isCFRU && table.Name == EggMovesTableName) { continue; } using (ModelCacheScope.CreateScope(this)) { var format = table.Format; if (isCFRU && table.Name == LevelMovesTableName) { format = $"[movesFromLevel<[move:{MoveNamesTable} level.]!0000FF>]{PokemonNameTable}"; } if (isCFRU && table.Name == AbilityNamesTable) { format = $"[name\"\"17]"; } AddTable(table.Address, table.Offset, table.Name, format); } } }
public static object BuildContentForRun(IDataModel model, int source, int destination, IFormattedRun destinationRun, int preferredPaletteStart = -1, int preferredSpritePage = 0) { if (destination != destinationRun.Start) { return(null); } if (destinationRun is PCSRun pcs) { return(PCSString.Convert(model, pcs.Start, pcs.Length)); } else if (destinationRun is ISpriteRun sprite) { if (sprite is LzTilemapRun tilemap) { tilemap.FindMatchingTileset(model); } var paletteRuns = sprite.FindRelatedPalettes(model, source); var paletteRun = paletteRuns.FirstOrDefault(); if (preferredPaletteStart >= 0) { paletteRun = paletteRuns.FirstOrDefault(pRun => pRun.Start == preferredPaletteStart) ?? model.GetNextRun(preferredPaletteStart) as IPaletteRun; } var pixels = sprite.GetPixels(model, preferredSpritePage); if (pixels == null) { return(null); } var colors = paletteRun?.AllColors(model) ?? TileViewModel.CreateDefaultPalette((int)Math.Pow(2, sprite.SpriteFormat.BitsPerPixel)); var imageData = SpriteTool.Render(pixels, colors, paletteRun?.PaletteFormat.InitialBlankPages ?? 0, 0); return(new ReadonlyPixelViewModel(sprite.SpriteFormat, imageData)); } else if (destinationRun is IPaletteRun paletteRun) { var colors = paletteRun.GetPalette(model, 0); return(new ReadonlyPaletteCollection(colors)); } else if (destinationRun is IStreamRun streamRun) { using (ModelCacheScope.CreateScope(model)) { var lines = streamRun.SerializeRun().Split(Environment.NewLine); if (lines.Length > 20) { lines = lines.Take(20).ToArray(); } return(Environment.NewLine.Join(lines)); } } else if (destinationRun is ArrayRun arrayRun) { var stream = new StringBuilder(); arrayRun.AppendTo(model, stream, arrayRun.Start, arrayRun.ElementLength * Math.Min(20, arrayRun.ElementCount), false); return(stream.ToString()); } else { return(null); } }
private void DecodeTablesFromReference(GameReferenceTables tables) { foreach (var table in tables) { using (ModelCacheScope.CreateScope(this)) { AddTable(table.Address, table.Name, table.Format); } } }
public override IDataFormat CreateDataFormat(IDataModel data, int index) { var scope = ModelCacheScope.GetCache(data); if (previousScope != scope) { UpdateCache(scope, data); } return(cache[index - Start]); }
public override void Write(IDataModel model, ModelDelta token, int start, string data) { using (ModelCacheScope.CreateScope(model)) { if (!TryParse(model, data, out int value)) { base.Write(model, token, start, data); return; } base.Write(model, token, start, value.ToString()); } }
/// <summary> /// Find a table given an address for that table /// </summary> private void AddTableDirect(int destination, string name, string format, bool validatePointerFound = false) { using (ModelCacheScope.CreateScope(this)) { var errorInfo = ApplyAnchor(this, noChangeDelta, destination, "^" + name + format, allowAnchorOverwrite: true); validatePointerFound &= !errorInfo.HasError; } if (validatePointerFound) { CheckForEmptyAnchors(destination, name); } }
public void CanGetOptionsFromStringPointerTable() { ViewPort.Edit("^aSpot FF @aSpot ^aSpot\"\" Content1\""); // 9 bytes ViewPort.Edit("^bSpot FF @bSpot ^bSpot\"\" Content2\""); // 9 bytes ViewPort.Edit("^cSpot FF @cSpot ^cSpot\"\" Content3\""); // 9 bytes ViewPort.Edit("@20 <aSpot> <bSpot> <cSpot> @20 "); ViewPort.Edit("^table[pointer<\"\">]3 "); // 12 bytes using (ModelCacheScope.CreateScope(Model)) { var options = ModelCacheScope.GetCache(Model).GetOptions("table"); Assert.Equal(3, options.Count); Assert.Equal("Content1", options[0]); Assert.Equal("Content2", options[1]); Assert.Equal("Content3", options[2]); } }
public void EnumFromEnumFromStringUsesIndexValueAsOptions() { SetupNameTable(0x180); viewPort.Edit($"@00 ^enum1[value.]{HardcodeTablesModel.PokemonNameTable}-1 2 3 4 5 6 7 1 "); using (ModelCacheScope.CreateScope(model)) { var options = ModelCacheScope.GetCache(model).GetOptions("enum1"); Assert.Equal("Horton", options[1]); // option 0 should be Horton because enum[Horton] = 0 Assert.Equal("Bob", options[2]); Assert.Equal("Carl", options[3]); Assert.Equal("Dave", options[4]); Assert.Equal("Elen", options[5]); Assert.Equal("Fred", options[6]); Assert.Equal("Gary", options[7]); Assert.Equal(8, options.Count); } }
public string GetEnumValue(string fieldName) { var elementOffset = table.ElementContent.Until(segment => segment.Name == fieldName).Sum(segment => segment.Length); var valueAddress = table.Start + table.ElementLength * arrayIndex + elementOffset; var seg = table.ElementContent.Single(segment => segment.Name == fieldName); if (seg is ArrayRunEnumSegment enumSeg) { using (ModelCacheScope.CreateScope(model)) { return(enumSeg.ToText(model, valueAddress, false)); } } else { throw new NotImplementedException(); } }
public void GotoAutocompleteIncludesTableFields() { var test = new BaseViewModelTestClass(); test.ViewPort.Edit("^table[field1:: field2<>]2 "); using (ModelCacheScope.CreateScope(test.Model)) { var options = test.Model.GetAutoCompleteAnchorNameOptions("table/0/"); Assert.Contains("table/0/field1", options); Assert.Contains("table/0/field2", options); options = test.Model.GetAutoCompleteAnchorNameOptions("table//field2/"); Assert.Contains("table/0/field2/", options); Assert.Contains("table/1/field2/", options); } }
private void DecodeTablesFromReference(GameReferenceTables tables) { foreach (var table in tables) { if (isCFRU && table.Name == "graphics.pokemon.sprites.coordinates.front") { continue; } if (isCFRU && table.Name == EggMovesTableName) { continue; } using (ModelCacheScope.CreateScope(this)) { var format = table.Format; AddTable(table.Address, table.Offset, table.Name, format); } } }
public override string ToText(IDataModel model, int address, bool deep) { using (ModelCacheScope.CreateScope(model)) { var options = GetOptions(model).ToList(); if (options == null) { return(base.ToText(model, address, deep)); } var resultAsInteger = ToInteger(model, address, Length) - ValueOffset; if (resultAsInteger >= options.Count || resultAsInteger < 0) { return(resultAsInteger.ToString()); } var value = options[resultAsInteger] ?? resultAsInteger.ToString(); // use ~2 postfix for a value if an earlier entry in the array has the same string var elementsUpToHereWithThisName = 1; for (int i = resultAsInteger - 1; i >= 0; i--) { var previousValue = options[i]; if (previousValue == value) { elementsUpToHereWithThisName++; } } if (value.StartsWith("\"") && value.EndsWith("\"")) { value = value.Substring(1, value.Length - 2); } if (elementsUpToHereWithThisName > 1) { value += "~" + elementsUpToHereWithThisName; } // add quotes around it if it contains a space if (value.Contains(' ')) { value = $"\"{value}\""; } return(value); } }
public IReadOnlyList <string> GetOptions(IDataModel model) { var cache = ModelCacheScope.GetCache(model); return(cache.GetBitOptions(SourceArrayName)); }
protected void ClearCacheScope() => currentCacheScope = null;
/// <summary> /// Find a table given an address for that table /// </summary> private void AddTableDirect(int destination, string name, string format) { using (ModelCacheScope.CreateScope(this)) { ApplyAnchor(this, noChangeDelta, destination, "^" + name + format, allowAnchorOverwrite: true); } }
public IEnumerable <string> GetOptions(IDataModel model) { var cache = ModelCacheScope.GetCache(model); return(cache.GetBitOptions(SourceArrayName)); }