예제 #1
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++];
					}
				}
			}
		}
예제 #2
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;
					}
				}
			}
		}
예제 #3
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;
		}
예제 #4
0
		public static byte[] Encode(byte[] source, int format) {
			var dest = new byte[source.Length * 2];
			var src = new MemoryFile(source);

			int w = 0;
			while (!src.Eof) {
				var cb_in = (short)Math.Min(src.Remaining, 8192);
				var chunk_in = src.Read(cb_in);
				var chunk_out = format == 80 ? Format80.Encode(chunk_in) : EncodeSection(chunk_in);
				uint cb_out = (ushort)chunk_out.Length;

				Array.Copy(BitConverter.GetBytes(cb_out), 0, dest, w, 2);
				w += 2;
				Array.Copy(BitConverter.GetBytes(cb_in), 0, dest, w, 2);
				w += 2;
				Array.Copy(chunk_out, 0, dest, w, chunk_out.Length);
				w += chunk_out.Length;
			}
			Array.Resize(ref dest, w);
			return dest;
		}
예제 #5
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();
		}
예제 #6
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();
                byte subtile = mf.ReadByte();
                byte 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);
        }