/// <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); }
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); }
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()); }
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); }
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; } } } }
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++]; } } } } }
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; } } } } }
/// <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); }