public static ITilemapRun SetPixels(ITilemapRun run, IDataModel model, ModelDelta token, int page, int[,] pixels, ref int arrayTilesetAddress, Func <byte[], ModelDelta, ITilemapRun> replaceData) { var tileData = Tilize(pixels, run.Format.BitsPerPixel); var tiles = GetUniqueTiles(tileData, run.BytesPerTile == 2); var tilesetAddress = model.GetAddressFromAnchor(new NoDataChangeDeltaModel(), -1, run.Format.MatchingTileset); var tileset = model.GetNextRun(tilesetAddress) as ITilesetRun; if (tileset == null) { FindMatchingTileset(run, model, ref arrayTilesetAddress); tileset = model.GetNextRun(arrayTilesetAddress) as ITilesetRun; } var tilesToKeep = new HashSet <int>((tileset.DecompressedLength / tileset.TilesetFormat.BitsPerPixel / 8).Range()); var originalUsedTiles = GetUsedTiles(run).ToHashSet(); foreach (var tile in originalUsedTiles) { tilesToKeep.Remove(tile); } foreach (var tilemap in tileset.FindDependentTilemaps(model).Except(run)) { tilesToKeep.AddRange(GetUsedTiles(tilemap)); } var oldTileDataRaw = tileset.GetData(); var previousTiles = Tilize(oldTileDataRaw, run.Format.BitsPerPixel); tiles = MergeTilesets(previousTiles, tilesToKeep, tiles, run.BytesPerTile == 2); tileset.SetPixels(model, token, tiles); var mapData = run.GetTilemapData(); 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, run.BytesPerTile == 2); if (tileIndex == -1) { tileIndex = 0; } if (run.BytesPerTile == 2) { var mapping = PackMapping(paletteIndex, matchType, tileIndex); mapData[i * 2 + 0] = (byte)mapping; mapData[i * 2 + 1] = (byte)(mapping >> 8); } else { mapData[i] = (byte)tileIndex; } } } return(replaceData(mapData, token)); }
public static IEnumerable <int> GetUsedTiles(ITilemapRun tilemap) { var mapData = tilemap.GetTilemapData(); for (int y = 0; y < tilemap.Format.TileHeight; y++) { for (int x = 0; x < tilemap.Format.TileWidth; x++) { var map = mapData.ReadMultiByteValue((tilemap.Format.TileWidth * y + x) * tilemap.BytesPerTile, tilemap.BytesPerTile); var tile = map & 0x3FF; yield return(tile); } } }