Пример #1
0
        public static int[,] GetPixels(byte[] mapData, byte[] tiles, TilemapFormat format, int bytesPerTile)
        {
            var tileSize = format.BitsPerPixel * 8;
            var result   = new int[format.TileWidth * 8, format.TileHeight * 8];

            for (int y = 0; y < format.TileHeight; y++)
            {
                var yStart = y * 8;
                for (int x = 0; x < format.TileWidth; x++)
                {
                    var(pal, hFlip, vFlip, tile) = ReadTileData(mapData, format.TileWidth * y + x, bytesPerTile);

                    pal <<= 4;
                    var tileStart = tile * tileSize;
                    var pixels    = SpriteRun.GetPixels(tiles, tileStart, 1, 1, format.BitsPerPixel); // TODO cache this during this method so we don't load the same tile more than once
                    var xStart    = x * 8;
                    for (int yy = 0; yy < 8; yy++)
                    {
                        for (int xx = 0; xx < 8; xx++)
                        {
                            var inX = hFlip ? 7 - xx : xx;
                            var inY = vFlip ? 7 - yy : yy;
                            result[xStart + xx, yStart + yy] = pixels[inX, inY] + pal;
                        }
                    }
                }
            }

            return(result);
        }
Пример #2
0
 public LzTilemapRun(TilemapFormat format, IDataModel data, int start, SortedSpan <int> sources = null) : base(data, start, allowLengthErrors: false, sources)
 {
     Format       = format;
     BytesPerTile = 2;
     if (format.TileWidth * format.TileHeight * BytesPerTile > DecompressedLength)
     {
         BytesPerTile = 1;
     }
 }
Пример #3
0
 public static bool TryParseTilemapFormat(string format, out TilemapFormat tilemapFormat)
 {
     tilemapFormat = default;
     if (!(format.StartsWith("`ucm") && format.EndsWith("`")))
     {
         return(false);
     }
     format = format.Substring(4, format.Length - 5);
     return(LzTilemapRun.TryParseGeneralTilemapFormat(format, out tilemapFormat));
 }
Пример #4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Tilemap"/> class from the specified file.
        /// </summary>
        /// <param name="filename"></param>
        /// <param name="format"></param>
        /// <param name="width"></param>
        public Tilemap(string filename, TilemapFormat format, int width)
        {
            const int IndexMask   = 0x3FF;
            const int FlipXMask   = 0x400;
            const int FlipYMask   = 0x800;
            const int PaletteMask = 0xF;

            using (var fs = File.OpenRead(filename))
                using (var br = new BinaryReader(fs))
                {
                    // --------------------------------
                    var tileCount = (int)br.BaseStream.Length / (format == TilemapFormat.RotationScaling ? 1 : 2);

                    // --------------------------------
                    this.width  = width;
                    this.height = tileCount / width;

                    // --------------------------------
                    tiles = new TilemapEntry[width * height];
                    for (int y = 0; y < height; y++)
                    {
                        for (int x = 0; x < width; x++)
                        {
                            if (format == TilemapFormat.Text4)
                            {
                                var u = br.ReadUInt16();
                                tiles[x + y * width] = new TilemapEntry(
                                    (short)(u & IndexMask),
                                    (byte)((u >> 12) & PaletteMask),
                                    (u & FlipXMask) == FlipXMask,
                                    (u & FlipYMask) == FlipYMask
                                    );
                            }
                            else if (format == TilemapFormat.Text8)
                            {
                                var u = br.ReadUInt16();
                                tiles[x + y * width] = new TilemapEntry(
                                    (short)(u & IndexMask),
                                    (u & FlipXMask) == FlipXMask,
                                    (u & FlipYMask) == FlipYMask
                                    );
                            }
                            else // RotationScaling
                            {
                                tiles[x + y * width] = new TilemapEntry(br.ReadByte());
                            }
                        }
                    }
                }
        }
        public static bool TryParseTilemapFormat(string format, out TilemapFormat tilemapFormat)
        {
            tilemapFormat = default;
            if (!(format.StartsWith("`lzm") && format.EndsWith("`")))
            {
                return(false);
            }
            format = format.Substring(4, format.Length - 5);

            // parse the tilesetHint
            string hint = null, tableMember = null;
            var    pipeIndex = format.IndexOf('|');

            if (pipeIndex != -1)
            {
                hint      = format.Substring(pipeIndex + 1);
                format    = format.Substring(0, pipeIndex);
                pipeIndex = hint.IndexOf('|');
                if (pipeIndex != -1)
                {
                    tableMember = hint.Substring(pipeIndex + 1);
                    hint        = hint.Substring(0, pipeIndex);
                }
            }

            var parts = format.Split('x');

            if (parts.Length != 3)
            {
                return(false);
            }
            if (!int.TryParse(parts[0], out int bits))
            {
                return(false);
            }
            if (!int.TryParse(parts[1], out int width))
            {
                return(false);
            }
            if (!int.TryParse(parts[2], out int height))
            {
                return(false);
            }

            tilemapFormat = new TilemapFormat(bits, width, height, hint, tableMember);
            return(true);
        }
Пример #6
0
        private void SaveGBA(Stream stream, TilemapFormat format, int padding)
        {
            using (var writer = new BinaryWriter(stream))
            {
                for (int y = 0; y < height; y++)
                {
                    for (int x = 0; x < width; x++)
                    {
                        ref TilemapEntry tile = ref this[x, y];

                        if (format == TilemapFormat.Text4)
                        {
                            writer.Write((ushort)(
                                             (tile.Index & 0x3FF) |
                                             (tile.FlipX ? 0x400 : 0) |
                                             (tile.FlipY ? 0x800 : 0) |
                                             (tile.Palette << 12)
                                             ));
                        }
                        else if (format == TilemapFormat.Text8)
                        {
                            writer.Write((ushort)(
                                             (tile.Index & 0x3FF) |
                                             (tile.FlipX ? 0x400 : 0) |
                                             (tile.FlipY ? 0x800 : 0)
                                             ));
                        }
                        else // TilemapFormat.RotationScaling
                        {
                            writer.Write((byte)tile.Index);
                        }
                    }
                }

                for (int i = 0; i < padding; i++)
                {
                    writer.Write(byte.MinValue);
                }
            }
Пример #7
0
        public TilemapRun(IDataModel model, int start, TilemapFormat format, SortedSpan <int> sources = null) : base(start, sources)
        {
            Model  = model;
            Format = format;

            string hint    = null;
            var    address = Model.GetAddressFromAnchor(new NoDataChangeDeltaModel(), -1, Format.MatchingTileset);

            if (address >= 0 && address < Model.Count)
            {
                var tileset = Model.GetNextRun(address) as ISpriteRun;
                if (tileset == null)
                {
                    tileset = Model.GetNextRun(arrayTilesetAddress) as ISpriteRun;
                }
                if (tileset != null && !(tileset is LzTilemapRun))
                {
                    hint = tileset.SpriteFormat.PaletteHint;
                }
            }

            SpriteFormat = new SpriteFormat(format.BitsPerPixel, format.TileWidth, format.TileHeight, hint);
        }
Пример #8
0
 public TilemapRun Duplicate(TilemapFormat format) => new TilemapRun(Model, Start, format, PointerSources);
Пример #9
0
 ITilemapRun ITilemapRun.Duplicate(TilemapFormat format) => Duplicate(format);
Пример #10
0
 public TilemapRunContentStrategy(TilemapFormat format)
 {
     this.format = format;
 }
Пример #11
0
 public LzTilemapRun(TilemapFormat format, IDataModel data, int start, SortedSpan <int> sources = null) : base(data, start, sources)
 {
     Format = format;
 }
Пример #12
0
 public static byte[] GetData(byte[] mapData, byte[] tiles, TilemapFormat format, int bytesPerTile)
 {
     throw new NotImplementedException();
 }
Пример #13
0
 public LzTilemapRunContentStrategy(TilemapFormat format) => TilemapFormat = format;