Esempio n. 1
0
        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));
        }
Esempio n. 2
0
        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);
                }
            }
        }