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); } }
// TODO do some sort of caching: rendering these images every time probably sucks for performance. public IEnumerable <ComboOption> GetComboOptions(IDataModel model) { var defaultOptions = GetOptions(model) .Select((option, i) => new ComboOption(option, i)) .Where(combo => combo.Text != null) .ToList(); if (!(model.GetNextRun(model.GetAddressFromAnchor(new NoDataChangeDeltaModel(), -1, EnumName)) is ITableRun tableRun)) { return(defaultOptions); } if (!(tableRun.ElementContent[0] is ArrayRunPointerSegment pointerSegment)) { return(defaultOptions); } if (!LzSpriteRun.TryParseSpriteFormat(pointerSegment.InnerFormat, out var _) && !SpriteRun.TryParseSpriteFormat(pointerSegment.InnerFormat, out var _)) { return(defaultOptions); } var imageOptions = new List <ComboOption>(); for (int i = 0; i < tableRun.ElementCount; i++) { var destination = model.ReadPointer(tableRun.Start + tableRun.ElementLength * i); if (!(model.GetNextRun(destination) is ISpriteRun run)) { return(defaultOptions); } var sprite = run.GetPixels(model, 0); var paletteAddress = SpriteTool.FindMatchingPalette(model, run, 0); var paletteRun = model.GetNextRun(paletteAddress) as IPaletteRun; var palette = paletteRun?.GetPalette(model, paletteRun.PaletteFormat.InitialBlankPages) ?? TileViewModel.CreateDefaultPalette(16); var image = SpriteTool.Render(sprite, palette, paletteRun?.PaletteFormat.InitialBlankPages ?? default, 0); var option = VisualComboOption.CreateFromSprite(defaultOptions[i].Text, image, sprite.GetLength(0), i); imageOptions.Add(option); } return(imageOptions); }