public static ITilesetRun SetPixels(ITilesetRun run, IDataModel model, ModelDelta token, IReadOnlyList <int[, ]> tiles, Func <int, SortedSpan <int>, ITilesetRun> construct) { var tileSize = 8 * run.TilesetFormat.BitsPerPixel; var data = new byte[tiles.Count * tileSize]; for (int i = 0; i < tiles.Count; i++) { SpriteRun.SetPixels(data, i * tileSize, tiles[i], run.TilesetFormat.BitsPerPixel); } var newModelData = Compress(data, 0, data.Length); var newRun = model.RelocateForExpansion(token, run, newModelData.Count); for (int i = 0; i < newModelData.Count; i++) { token.ChangeData(model, newRun.Start + i, newModelData[i]); } for (int i = newModelData.Count; i < run.Length; i++) { token.ChangeData(model, newRun.Start + i, 0xFF); } newRun = construct(newRun.Start, newRun.PointerSources); model.ObserveRunWritten(token, newRun); return(newRun); }
public ISpriteRun SetPixels(IDataModel model, ModelDelta token, int page, int[,] pixels) { var data = Decompress(model, Start, allowLengthErrors: true); page %= Pages; var pageLength = SpriteFormat.TileWidth * SpriteFormat.TileHeight * 8 * SpriteFormat.BitsPerPixel; SpriteRun.SetPixels(data, page * pageLength, pixels, SpriteFormat.BitsPerPixel); var newModelData = Compress(data, 0, data.Length); var newRun = (ISpriteRun)model.RelocateForExpansion(token, this, newModelData.Count); for (int i = 0; i < newModelData.Count; i++) { token.ChangeData(model, newRun.Start + i, newModelData[i]); } for (int i = newModelData.Count; i < Length; i++) { token.ChangeData(model, newRun.Start + i, 0xFF); } newRun = new LzSpriteRun(SpriteFormat, model, newRun.Start, newRun.PointerSources); model.ObserveRunWritten(token, newRun); return(newRun); }
public ISpriteRun SetPixels(IDataModel model, ModelDelta token, int[][,] tiles) { var tileSize = 8 * Format.BitsPerPixel; var data = new byte[tiles.Length * tileSize]; for (int i = 0; i < tiles.Length; i++) { SpriteRun.SetPixels(data, i * tileSize, tiles[i], Format.BitsPerPixel); } var newModelData = Compress(data, 0, data.Length); var newRun = (LzTilesetRun)model.RelocateForExpansion(token, this, newModelData.Count); for (int i = 0; i < newModelData.Count; i++) { token.ChangeData(model, newRun.Start + i, newModelData[i]); } for (int i = newModelData.Count; i < Length; i++) { token.ChangeData(model, newRun.Start + i, 0xFF); } newRun = new LzTilesetRun(Format, model, newRun.Start, newRun.PointerSources); model.ObserveRunWritten(token, newRun); return(newRun); }
public void WriteNewFormat(IDataModel owner, ModelDelta token, int source, int destination, IReadOnlyList <ArrayRunElementSegment> sourceSegments) { owner.WritePointer(token, source, destination); var newRun = Factory.GetStrategy(InnerFormat).WriteNewRun(owner, token, source, destination, Name, sourceSegments); owner.ObserveRunWritten(token, newRun.MergeAnchor(new SortedSpan <int>(source))); }
public ISpriteRun SetPixels(IDataModel model, ModelDelta token, int page, int[,] pixels) { // TODO handle the fact that pixels[,] may contain a different number of tiles compared to the existing tileset var data = Decompress(model, Start); for (int x = 0; x < pixels.GetLength(0); x++) { for (int y = 0; y < pixels.GetLength(1); y++) { pixels[x, y] %= (int)Math.Pow(2, TilesetFormat.BitsPerPixel); } } SpriteRun.SetPixels(data, 0, pixels, TilesetFormat.BitsPerPixel); var newModelData = Compress(data, 0, data.Length); var newRun = model.RelocateForExpansion(token, this, newModelData.Count); for (int i = 0; i < newModelData.Count; i++) { token.ChangeData(model, newRun.Start + i, newModelData[i]); } for (int i = newModelData.Count; i < Length; i++) { token.ChangeData(model, newRun.Start + i, 0xFF); } newRun = new LzTilesetRun(TilesetFormat, model, newRun.Start, newRun.PointerSources); model.ObserveRunWritten(token, newRun); return(newRun); }
public override bool TryAddFormatAtDestination(IDataModel owner, ModelDelta token, int source, int destination, string name, IReadOnlyList <ArrayRunElementSegment> sourceSegments, int parentIndex) { var newRun = new TilemapRun(owner, destination, format); if (!(token is NoDataChangeDeltaModel)) { owner.ObserveRunWritten(token, newRun); } return(true); }
public override bool TryAddFormatAtDestination(IDataModel owner, ModelDelta token, int source, int destination, string name, IReadOnlyList <ArrayRunElementSegment> sourceSegments, int parentIndex) { var run = new ASERun(destination, new SortedSpan <int>(source)); if (run.Length < 1) { return(false); } owner.ClearFormat(token, run.Start, run.Length); owner.ObserveRunWritten(token, run); return(true); }
public override bool TryAddFormatAtDestination(IDataModel owner, ModelDelta token, int source, int destination, string name, IReadOnlyList <ArrayRunElementSegment> sourceSegments) { if (TableStreamRun.TryParseTableStream(owner, destination, new SortedSpan <int>(source), name, Format, sourceSegments, out var tsRun)) { if (!(token is NoDataChangeDeltaModel)) { owner.ObserveRunWritten(token, tsRun); } return(true); } return(false); }
public void Visit(StreamEndDecorator decorator, byte data) { if (CurrentText == "[]") { var run = (TableStreamRun)Model.GetNextRun(memoryLocation); var newDesiredElementCount = (memoryLocation - run.Start) / run.ElementLength; var newRun = run.Append(CurrentChange, newDesiredElementCount - run.ElementCount); Model.ObserveRunWritten(CurrentChange, newRun); for (int i = newRun.Length; i < run.Length; i++) { CurrentChange.ChangeData(Model, newRun.Start + i, 0xFF); } var endTokenLength = run.Length - run.ElementLength * run.ElementCount; NewDataIndex = memoryLocation + endTokenLength; Result = true; } else { decorator.OriginalFormat.Visit(this, data); } }
public ISpriteRun SetPixels(IDataModel model, ModelDelta token, int page, int[,] pixels) { var tileData = Tilize(pixels); var tiles = GetUniqueTiles(tileData); var tilesetAddress = model.GetAddressFromAnchor(new NoDataChangeDeltaModel(), -1, Format.MatchingTileset); var tileset = model.GetNextRun(tilesetAddress) as LzTilesetRun; if (tileset == null) { tileset = model.GetNextRun(arrayTilesetAddress) as LzTilesetRun; } tileset.SetPixels(model, token, tiles); if (tiles.Length > 0x400) { // TODO fail: too many unique tiles return(this); } var mapData = Decompress(model, Start); var tileWidth = tileData.GetLength(0); var tileHeight = tileData.GetLength(1); for (int y = 0; y < tileHeight; y++) { for (int x = 0; x < tileWidth; x++) { var i = y * tileWidth + x; var(tile, paletteIndex) = tileData[x, y]; var(tileIndex, matchType) = FindMatch(tile, tiles); var mapping = PackMapping(paletteIndex, matchType, tileIndex); mapData[i * 2 + 0] = (byte)mapping; mapData[i * 2 + 1] = (byte)(mapping >> 8); } } var newModelData = Compress(mapData, 0, mapData.Length); var newRun = (ISpriteRun)model.RelocateForExpansion(token, this, newModelData.Count); for (int i = 0; i < newModelData.Count; i++) { token.ChangeData(model, newRun.Start + i, newModelData[i]); } for (int i = newModelData.Count; i < Length; i++) { token.ChangeData(model, newRun.Start + i, 0xFF); } newRun = new LzTilemapRun(Format, model, newRun.Start, newRun.PointerSources); model.ObserveRunWritten(token, newRun); return(newRun); }
public override bool TryAddFormatAtDestination(IDataModel owner, ModelDelta token, int source, int destination, string name, IReadOnlyList <ArrayRunElementSegment> sourceSegments, int parentIndex) { var plmRun = new PLMRun(owner, destination); var length = plmRun.Length; if (length < 2) { return(false); } if (!(token is NoDataChangeDeltaModel)) { owner.ObserveRunWritten(token, plmRun); } return(true); }
public override bool TryAddFormatAtDestination(IDataModel owner, ModelDelta token, int source, int destination, string name, IReadOnlyList <ArrayRunElementSegment> sourceSegments) { var teamRun = new TrainerPokemonTeamRun(owner, destination, new SortedSpan <int>(source)); var length = teamRun.Length; if (length < 2) { return(false); } if (!(token is NoDataChangeDeltaModel)) { owner.ObserveRunWritten(token, teamRun); } return(true); }
public override bool TryAddFormatAtDestination(IDataModel owner, ModelDelta token, int source, int destination, string name, IReadOnlyList <ArrayRunElementSegment> sourceSegments) { var length = PCSString.ReadString(owner, destination, true); if (length < 1) { return(false); } // our token will be a no-change token if we're in the middle of exploring the data. // If so, don't actually add the run. It's enough to know that we _can_ add the run. if (!(token is NoDataChangeDeltaModel)) { owner.ObserveRunWritten(token, new PCSRun(owner, destination, length)); } // even if we didn't add the format, we're _capable_ of adding it... so return true return(true); }
public override bool TryAddFormatAtDestination(IDataModel owner, ModelDelta token, int source, int destination, string name, IReadOnlyList <ArrayRunElementSegment> sourceSegments, int parentIndex) { if (TableStreamRun.TryParseTableStream(owner, destination, new SortedSpan <int>(source), name, Format, sourceSegments, out var tsRun)) { if (token is not NoDataChangeDeltaModel) { // we know that the data format matches, but there may already be a run there that starts sooner if (owner.GetNextRun(tsRun.Start) is ITableRun existingTable && existingTable.Start < tsRun.Start) { // there is already a format that starts sooner: do nothing, but return true because the format matches } else { owner.ClearFormat(token, tsRun.Start + 1, tsRun.Length - 1); owner.ObserveRunWritten(token, tsRun); } } return(true); }
public MapAnimationTilesRun UpdateFromParent(ModelDelta token, int segmentIndex, int pointerSource, out bool childrenMoved) { childrenMoved = false; if (segmentIndex == 1) { var newTableCount = model.ReadMultiByteValue(pointerSource + 4, 2); var self = model.RelocateForExpansion(token, this, newTableCount * 4); for (int i = ElementCount; i < newTableCount; i++) { model.WritePointer(token, self.Start + 4 * i, Pointer.NULL); } return(new MapAnimationTilesRun(model, self.Start, self.PointerSources)); } else if (segmentIndex == 3) { var newTileCount = model[pointerSource + 7]; var tilesetFormat = new TilesetFormat(4, newTileCount, -1, default); for (int i = 0; i < ElementCount; i++) { var destination = model.ReadPointer(Start + ElementLength * i); if (destination == Pointer.NULL) { continue; } var child = (ISpriteRun)model.GetNextRun(destination); var newChild = model.RelocateForExpansion(token, child, newTileCount * 32); if (newChild.Start != child.Start) { childrenMoved = true; } model.ObserveRunWritten(token, new TilesetRun(tilesetFormat, model, newChild.Start, newChild.PointerSources)); } return(this); } else { return(this); } }
public IPaletteRun SetPalette(IDataModel model, ModelDelta token, int page, IReadOnlyList <short> colors) { var data = Decompress(model, Start); var colorCount = (int)Math.Pow(2, PaletteFormat.Bits); var pageLength = colorCount * 2; page %= Pages; PaletteRun.SetPalette(data, page * pageLength, colors); var newModelData = Compress(data, 0, data.Length); var newRun = (IPaletteRun)model.RelocateForExpansion(token, this, newModelData.Count); for (int i = 0; i < newModelData.Count; i++) { token.ChangeData(model, newRun.Start + i, newModelData[i]); } for (int i = newModelData.Count; i < Length; i++) { token.ChangeData(model, newRun.Start + i, 0xFF); } newRun = new LzPaletteRun(PaletteFormat, model, newRun.Start, newRun.PointerSources); model.ObserveRunWritten(token, newRun); return(newRun); }
public void Visit(PlmItem item, byte data) { var memoryLocation = this.memoryLocation; var run = (PLMRun)Model.GetNextRun(memoryLocation); // part 1: contraction (if they entered the end token) if (CurrentText == EggMoveRun.GroupStart + EggMoveRun.GroupEnd) { for (int i = this.memoryLocation; i < run.Start + run.Length; i += 2) { Model.WriteMultiByteValue(i, 2, CurrentChange, 0xFFFF); } Model.ObserveRunWritten(CurrentChange, new PLMRun(Model, run.Start)); return; } // part 2: validation if (!CurrentText.Contains(" ")) { return; } var quoteCount = CurrentText.Count(c => c == StringDelimeter); if (quoteCount % 2 != 0) { return; } if (!CurrentText.EndsWith(StringDelimeter.ToString()) && !CurrentText.EndsWith(" ")) { return; } ErrorText = ValidatePlmText(run, quoteCount, out var level, out var move); if (ErrorText != null || move == -1) { return; } // part 3: write to the model NewDataIndex = memoryLocation + 2; Result = true; var value = (level << 9) + move; var initialItemValue = Model.ReadMultiByteValue(memoryLocation, 2); Model.WriteMultiByteValue(memoryLocation, 2, CurrentChange, value); // part 4: expansion if (initialItemValue == 0xFFFF) { var newRun = Model.RelocateForExpansion(CurrentChange, run, run.Length + 2); if (newRun.Start != run.Start) { MessageText = $"Level Up Moves were automatically moved to {newRun.Start.ToString("X6")}. Pointers were updated."; memoryLocation += newRun.Start - run.Start; NewDataIndex = memoryLocation + 2; DataMoved = true; } Model.WriteMultiByteValue(memoryLocation + 2, 2, CurrentChange, 0xFFFF); var lvlRun = new PLMRun(Model, newRun.Start); Model.ObserveRunWritten(CurrentChange, lvlRun); } }