예제 #1
0
        /// <summary>Reads the tiles. </summary>
        private void ReadTiles()
        {
            var mapSection = GetSection("IsoMapPack5");

            byte[] lzoData     = Convert.FromBase64String(mapSection.ConcatenatedValues());
            int    cells       = (FullSize.Width * 2 - 1) * FullSize.Height;
            int    lzoPackSize = cells * 11 + 4;          // last 4 bytes contains a lzo pack header saying no more data is left

            var  isoMapPack          = new byte[lzoPackSize];
            uint totalDecompressSize = Format5.DecodeInto(lzoData, isoMapPack);

            var mf       = new MemoryFile(isoMapPack);
            int numtiles = 0;

            for (int i = 0; i < cells; i++)
            {
                ushort rx      = mf.ReadUInt16();
                ushort ry      = mf.ReadUInt16();
                short  tilenum = mf.ReadInt16();
                short  zero1   = mf.ReadInt16();
                ushort subtile = mf.ReadByte();
                short  z       = mf.ReadByte();
                byte   zero2   = mf.ReadByte();

                int dx = rx - ry + FullSize.Width - 1;
                int dy = rx + ry - FullSize.Width - 1;
                numtiles++;
                if (dx >= 0 && dx < 2 * Tiles.Width &&
                    dy >= 0 && dy < 2 * Tiles.Height)
                {
                    var tile = new IsoTile((ushort)dx, (ushort)dy, rx, ry, z, tilenum, subtile);
                    Tiles[(ushort)dx, (ushort)dy / 2] = tile;
                }
            }

            // fix missing tiles

            // import tiles
            for (ushort y = 0; y < FullSize.Height; y++)
            {
                for (ushort x = 0; x <= FullSize.Width * 2 - 2; x++)
                {
                    var isoTile = Tiles[x, y];
                    if (isoTile == null)
                    {
                        // fix null tiles to blank
                        ushort dx = (ushort)(x);
                        ushort dy = (ushort)(y * 2 + x % 2);
                        ushort rx = (ushort)((dx + dy) / 2 + 1);
                        ushort ry = (ushort)(dy - rx + FullSize.Width + 1);
                        Tiles[x, y] = new IsoTile(dx, dy, rx, ry, 0, 0, 0);
                    }
                }
            }


            Logger.Debug("Read {0} tiles", numtiles);
        }
예제 #2
0
        public void WriteAndReadByteViaMemoryFile()
        {
            var file = new MemoryFile("rwb");

            Assert.NotNull(file);
            Assert.True(file.CanWrite);
            file.WriteByte(13);
            file.WriteByte(17);
            file.Seek(0);
            var rd = file.ReadByte();

            Assert.Equal(13, rd);
            rd = file.ReadByte();
            Assert.Equal(17, rd);
            file.Close();
            Assert.False(file.IsOpen);
        }
예제 #3
0
        public static byte[] Encode(byte[] src)
        {
            /* quick & dirty format80 encoder -- only uses raw copy operator, terminated with a zero-run. */
            /* this does not produce good compression, but it's valid format80 */
            var ctx = new MemoryFile(src);
            var ms  = new MemoryStream();

            do
            {
                var len = Math.Min(ctx.Position, 0x3F);
                ms.WriteByte((byte)(0x80 | len));
                while (len-- > 0)
                {
                    ms.WriteByte(ctx.ReadByte());
                }
            } while (!ctx.Eof);

            ms.WriteByte(0x80);             // terminator -- 0-length run.

            return(ms.ToArray());
        }
예제 #4
0
        public static uint DecodeInto(byte[] src, byte[] dest)
        {
            VirtualFile vfile = new MemoryFile(src);
            uint        i     = 0;

            while (vfile.CanRead)
            {
                byte cmd = vfile.ReadByte();
                if (cmd == 0)
                {
                    byte count = vfile.ReadUInt8();
                    while (count-- > 0)
                    {
                        dest[i++] = 0;
                    }
                }
                else
                {
                    dest[i++] = cmd;
                }
            }
            return(i);
        }
예제 #5
0
        public static int DecodeInto(byte[] src, byte[] dest)
        {
            var ctx       = new MemoryFile(src);
            int destIndex = 0;

            while (true)
            {
                byte i = ctx.ReadByte();
                if ((i & 0x80) == 0)
                {
                    int count = i & 0x7F;
                    if (count == 0)
                    {
                        // case 6
                        count = ctx.ReadByte();
                        byte value = ctx.ReadByte();
                        int  end   = destIndex + count;
                        for (; destIndex < end; destIndex++)
                        {
                            dest[destIndex] ^= value;
                        }
                    }
                    else
                    {
                        // case 5
                        for (int end = destIndex + count; destIndex < end; destIndex++)
                        {
                            dest[destIndex] ^= ctx.ReadByte();
                        }
                    }
                }
                else
                {
                    int count = i & 0x7F;
                    if (count == 0)
                    {
                        count = ctx.ReadInt16();
                        if (count == 0)
                        {
                            return(destIndex);
                        }

                        if ((count & 0x8000) == 0)
                        {
                            // case 2, skip
                            destIndex += (count & 0x7FFF);
                        }
                        else if ((count & 0x4000) == 0)
                        {
                            // case 3
                            for (int end = destIndex + (count & 0x3FFF); destIndex < end; destIndex++)
                            {
                                dest[destIndex] ^= ctx.ReadByte();
                            }
                        }
                        else
                        {
                            // case 4
                            byte value = ctx.ReadByte();
                            for (int end = destIndex + (count & 0x3FFF); destIndex < end; destIndex++)
                            {
                                dest[destIndex] ^= value;
                            }
                        }
                    }
                    else
                    {
                        // case 1
                        destIndex += count;
                    }
                }
            }
        }
예제 #6
0
        public static int DecodeInto(byte[] src, byte[] dest)
        {
            VirtualFile ctx       = new MemoryFile(src);
            int         destIndex = 0;

            while (true)
            {
                byte i = ctx.ReadByte();
                if ((i & 0x80) == 0)
                {
                    // case 2
                    byte secondByte = ctx.ReadByte();
                    int  count      = ((i & 0x70) >> 4) + 3;
                    int  rpos       = ((i & 0xf) << 8) + secondByte;

                    ReplicatePrevious(dest, destIndex, destIndex - rpos, count);
                    destIndex += count;
                }
                else if ((i & 0x40) == 0)
                {
                    // case 1
                    int count = i & 0x3F;
                    if (count == 0)
                    {
                        return(destIndex);
                    }

                    ctx.Read(dest, destIndex, count);
                    destIndex += count;
                }
                else
                {
                    int count3 = i & 0x3F;
                    if (count3 == 0x3E)
                    {
                        // case 4
                        int  count = ctx.ReadInt16();
                        byte color = ctx.ReadByte();

                        for (int end = destIndex + count; destIndex < end; destIndex++)
                        {
                            dest[destIndex] = color;
                        }
                    }
                    else if (count3 == 0x3F)
                    {
                        // case 5
                        int count    = ctx.ReadInt16();
                        int srcIndex = ctx.ReadInt16();
                        if (srcIndex >= destIndex)
                        {
                            throw new NotImplementedException(string.Format("srcIndex >= destIndex  {0}  {1}", srcIndex, destIndex));
                        }

                        for (int end = destIndex + count; destIndex < end; destIndex++)
                        {
                            dest[destIndex] = dest[srcIndex++];
                        }
                    }
                    else
                    {
                        // case 3
                        int count    = count3 + 3;
                        int srcIndex = ctx.ReadInt16();
                        if (srcIndex >= destIndex)
                        {
                            throw new NotImplementedException(string.Format("srcIndex >= destIndex  {0}  {1}", srcIndex, destIndex));
                        }

                        for (int end = destIndex + count; destIndex < end; destIndex++)
                        {
                            dest[destIndex] = dest[srcIndex++];
                        }
                    }
                }
            }
        }
예제 #7
0
    private void InitializeTiles()
    {
        MapSection section = GetSection("IsoMapPack5");

        if (section != null)
        {
            tiles = new List <Tile>();
            StringBuilder sb = new StringBuilder();
            foreach (KeyValuePair <string, string> entry in section.Entries)
            {
                sb.Append(entry.Value);
            }
            byte[] lzoData     = Convert.FromBase64String(sb.ToString());
            int    cells       = (MapWidth * 2 - 1) * MapHeight;
            int    lzoPackSize = cells * 11 + 4;          // last 4 bytes used for termination
            byte[] isoMapPack  = new byte[lzoPackSize];

            int j = 0;
            for (int i = 0; i < cells; i++)
            {
                isoMapPack[j]     = 0x88;
                isoMapPack[j + 1] = 0x40;
                isoMapPack[j + 2] = 0x88;
                isoMapPack[j + 3] = 0x40;
                j += 11;
            }

            Format5.DecodeInto(lzoData, isoMapPack);

            foreach (Tuple <int, int> cellCoordinate in coordList)
            {
                tiles.Add(new Tile(0, 0, 0, 0, cellCoordinate.Item1, cellCoordinate.Item2));
            }

            MemoryFile mf = new MemoryFile(isoMapPack);
            for (int i = 0; i < cells; i++)
            {
                int  rx          = (int)mf.ReadUInt16();
                int  ry          = (int)mf.ReadUInt16();
                int  tileIndex   = mf.ReadInt32();
                byte subIndex    = mf.ReadByte();
                byte heightLevel = mf.ReadByte();
                byte iceGrowth   = mf.ReadByte();

                if (tileIndex >= 65535)
                {
                    tileIndex = 0;                                     // Tile 0xFFFF used as empty/clear
                }
                if (rx < 512 && ry < 512)
                {
                    int index = tiles.FindIndex(tile => tile.MapX == rx && tile.MapY == ry);
                    if (index >= 0)
                    {
                        tiles[index].TileIndex = tileIndex;
                        tiles[index].SubIndex  = subIndex;
                        tiles[index].Level     = heightLevel;
                        tiles[index].IceGrowth = iceGrowth;
                    }
                }
            }
        }
    }
예제 #8
0
        /// <summary>Reads the tiles. </summary>
        private void ReadTiles()
        {
            var mapSection = GetSection("IsoMapPack5");

            byte[] lzoData     = Convert.FromBase64String(mapSection.ConcatenatedValues());
            int    cells       = (FullSize.Width * 2 - 1) * FullSize.Height;
            int    lzoPackSize = cells * 11 + 4;          // last 4 bytes contains a lzo pack header saying no more data is left

            var isoMapPack = new byte[lzoPackSize];

            // In case, IsoMapPack5 contains less entries than the number of cells, fill up any number greater
            // than 511 and filter later.
            int j = 0;

            for (int i = 0; i < cells; i++)
            {
                isoMapPack[j]     = 0x88;
                isoMapPack[j + 1] = 0x40;
                isoMapPack[j + 2] = 0x88;
                isoMapPack[j + 3] = 0x40;
                j += 11;
            }

            Format5.DecodeInto(lzoData, isoMapPack);

            // Fill level 0 clear tiles for all array values
            for (ushort y = 0; y < FullSize.Height; y++)
            {
                for (ushort x = 0; x <= FullSize.Width * 2 - 2; x++)
                {
                    ushort dx = (ushort)(x);
                    ushort dy = (ushort)(y * 2 + x % 2);
                    ushort rx = (ushort)((dx + dy) / 2 + 1);
                    ushort ry = (ushort)(dy - rx + FullSize.Width + 1);
                    Tiles[x, y] = new IsoTile(dx, dy, rx, ry, 0, 0, 0, 0);
                }
            }

            // Overwrite with actual entries found in IsoMapPack5
            var mf       = new MemoryFile(isoMapPack);
            int numtiles = 0;

            for (int i = 0; i < cells; i++)
            {
                ushort rx        = mf.ReadUInt16();
                ushort ry        = mf.ReadUInt16();
                int    tilenum   = mf.ReadInt32();
                byte   subtile   = mf.ReadByte();
                byte   z         = mf.ReadByte();
                byte   icegrowth = mf.ReadByte();

                if (tilenum >= 65535)
                {
                    tilenum = 0;                                   // Tile 0xFFFF used as empty/clear
                }
                if (rx <= 511 && ry <= 511)
                {
                    int dx = rx - ry + FullSize.Width - 1;
                    int dy = rx + ry - FullSize.Width - 1;
                    numtiles++;
                    if (dx >= 0 && dx < 2 * Tiles.Width && dy >= 0 && dy < 2 * Tiles.Height)
                    {
                        var tile = new IsoTile((ushort)dx, (ushort)dy, rx, ry, z, tilenum, subtile, icegrowth);
                        Tiles[(ushort)dx, (ushort)dy / 2] = tile;
                    }
                }
            }

            Logger.Debug("Read {0} tiles", numtiles);
        }