ZPlane ReadZPlane() { var chunk = ChunkIterator5.ReadChunk(_reader); if (chunk.Tag != "ZSTR") { throw new NotSupportedException("ZSTR block was expected."); } var chunkWrap = ChunkIterator5.ReadChunk(_reader); if (chunkWrap.Tag != "WRAP") { throw new NotSupportedException("WRAP block was expected."); } var chunkOffs = ChunkIterator5.ReadChunk(_reader); if (chunkOffs.Tag != "OFFS") { throw new NotSupportedException("OFFS block was expected."); } var num = (chunkOffs.Size - 8) / 4; var offs = new int?[num]; for (int i = 0; i < num; i++) { offs[i] = (int)(_reader.ReadInt32() - chunkOffs.Size); } var data = _reader.ReadBytes((int)(chunkWrap.Size - 8 - chunkOffs.Size)); return(new ZPlane(data, offs)); }
IEnumerable <Palette> ReadPalettes() { var chunk = ChunkIterator5.ReadChunk(_reader); if (chunk.Tag != "WRAP") { throw new NotSupportedException("WRAP block was expected."); } chunk = ChunkIterator5.ReadChunk(_reader); if (chunk.Tag != "OFFS") { throw new NotSupportedException("OFFS block was expected."); } var num = (int)(chunk.Size - 8) / 4; var offsets = _reader.ReadUInt32s(num); for (int i = 0; i < num; i++) { chunk = ChunkIterator5.ReadChunk(_reader); if (chunk.Tag != "APAL") { throw new NotSupportedException("APAL block was expected."); } yield return(new Palette(ReadCLUT())); } }
public override byte[] ReadCostume(long offset) { GotoResourceHeader(offset); var chunk = ChunkIterator5.ReadChunk(_reader); if (chunk.Tag != "AKOS") { throw new NotSupportedException("Expected AKOS block."); } return(_reader.ReadBytes((int)chunk.Size - 8)); }
public override Room ReadRoom(long offset) { GotoResourceHeader(offset); var chunk = ChunkIterator5.ReadChunk(_reader); if (chunk.Tag != "ROOM") { throw new NotSupportedException("Room block was expected."); } var room = ReadRoomCore(offset, chunk.Size); return(room); }
public static long FindOffset(byte[] input, string tag) { using (var ms = new MemoryStream(input)) { var reader = new BinaryReader(ms); var it = new ChunkIterator5(reader, input.Length); while (it.MoveNext()) { if (it.Current.Tag == tag) { return(reader.BaseStream.Position); } } } return(-1); }
public static byte[] ReadData(byte[] input, string tag) { using (var ms = new MemoryStream(input)) { var reader = new BinaryReader(ms); var it = new ChunkIterator5(reader, input.Length); while (it.MoveNext()) { if (it.Current.Tag == tag) { return(reader.ReadBytes((int)(it.Current.Size - 8))); } } } return(new byte[0]); }
void ReadRoomImage(Room room) { var chunk = ChunkIterator5.ReadChunk(_reader); if (chunk.Tag != "RMIH") { throw new NotSupportedException("Room Header block was expected."); } // number of z buffers room.NumZBuffer = _reader.ReadUInt16() + 1; chunk = ChunkIterator5.ReadChunk(_reader); if (!chunk.Tag.StartsWith("IM", StringComparison.Ordinal)) { throw new NotSupportedException("Image block was expected."); } room.Image = ReadImage(chunk.Size - 8, room.Header.Width / 8); }
protected override void ReadRoomImages(Room room) { var chunkWrap = ChunkIterator5.ReadChunk(_reader); if (chunkWrap.Tag != "WRAP") { throw new NotSupportedException("WRAP block was expected."); } var chunk = ChunkIterator5.ReadChunk(_reader); if (chunk.Tag != "OFFS") { throw new NotSupportedException("OFFS block was expected."); } _reader.BaseStream.Seek(chunk.Size - 8, SeekOrigin.Current); var smapChunk = ChunkIterator5.ReadChunk(_reader); if (smapChunk.Tag != "SMAP") { throw new NotSupportedException("SMAP block was expected."); } List <Chunk> zplaneChunks = new List <Chunk>(); var it = CreateChunkIterator(smapChunk.Size - 8); while (it.MoveNext()) { switch (it.Current.Tag) { case "ZPLN": chunk = ChunkIterator5.ReadChunk(_reader); if (chunk.Tag != "WRAP") { throw new NotSupportedException("WRAP block was expected."); } it = CreateChunkIterator(chunk.Size - 8); break; case "ZSTR": zplaneChunks.Add(it.Current); break; } } if (zplaneChunks.Count == 0) { // Read smap _reader.BaseStream.Seek(smapChunk.Offset, SeekOrigin.Begin); room.Image = new ImageData { Data = _reader.ReadBytes((int)(smapChunk.Size - 8)) }; } else { _reader.BaseStream.Seek(smapChunk.Offset, SeekOrigin.Begin); var zplanesSize = 0; for (int i = 0; i < zplaneChunks.Count; i++) { zplanesSize += (int)zplaneChunks[i].Size; } room.Image = new ImageData { Data = _reader.ReadBytes((int)(smapChunk.Size - 8 - zplanesSize)) }; for (int i = 0; i < zplaneChunks.Count; i++) { room.Image.ZPlanes.Add(ReadZPlane()); } } }
public override Room ReadRoom(long offset) { Room room = null; GotoResourceHeader(offset); var chunk = ChunkIterator5.ReadChunk(_reader); if (chunk.Tag != "LFLF") { throw new NotSupportedException("LFLF block expected"); } var it = CreateChunkIterator(chunk.Size); while (it.MoveNext()) { if (it.Current.Tag == "ROOM") { room = base.ReadRoom(offset + 8); room.TransparentColor = (byte)room.Header.Transparency; } else if (it.Current.Tag == "RMSC") { it = CreateChunkIterator(it.Current.Size); while (it.MoveNext()) { switch (it.Current.Tag) { case "ENCD": { // Entry script room.EntryScript.Data = _reader.ReadBytes((int)(it.Current.Size - 8)); } break; case "EXCD": { // exit script room.ExitScript.Data = _reader.ReadBytes((int)(it.Current.Size - 8)); } break; case "LSCR": // local script var pos = _reader.BaseStream.Position; var index = ReadScriptIndex(); var size = 8 + _reader.BaseStream.Position - pos; room.LocalScripts[index - GetNumGlobalScripts()] = new ScriptData { Data = _reader.ReadBytes((int)(it.Current.Size - size)) }; break; case "OBCD": { // object script var obj = ReadObjectCode(it.Current.Size - 8); var objImg = room.Objects.FirstOrDefault(o => o.Number == obj.Number); if (objImg != null) { room.Objects.Remove(objImg); room.Objects.Add(Merge(objImg, obj)); } else { room.Objects.Add(obj); } } break; default: UnknownChunk(chunk); break; } } return(room); } } return(room); }
Room ReadRoomCore(long offset, long chunkSize) { var room = new Room { Size = (int)chunkSize }; var it = new ChunkIterator5(_reader, chunkSize); var images = new Dictionary <ushort, ObjectData>(); var objCodes = new Dictionary <ushort, ObjectData>(); while (it.MoveNext()) { switch (it.Current.Tag) { case "TRNS": { // transparent color room.TransparentColor = _reader.ReadByte(); var unknown = _reader.ReadByte(); } break; case "RMHD": // ROOM Header room.Header = ReadRMHD(); break; case "RMIM": // room image ReadRoomImage(room); break; case "IMAG": ReadRoomImages(room); break; case "CYCL": // CYCL room.ColorCycle = ReadCYCL(); break; case "EPAL": // EPAL ReadEPAL(); break; case "BOXD": // box data { var numBoxes = ReadNumBoxes(); for (int i = 0; i < numBoxes; i++) { var box = ReadBox(); room.Boxes.Add(box); } } break; case "BOXM": // box matrix { var size = (int)(it.Current.Size - 8); room.BoxMatrix.Clear(); room.BoxMatrix.AddRange(_reader.ReadBytes(size)); } break; case "PALS": { room.HasPalette = true; var palettes = ReadPalettes().ToArray(); room.Palettes.Clear(); room.Palettes.AddRange(palettes); } break; case "SCAL": // SCAL if (it.Current.Size > 8) { room.Scales = ReadSCAL(); } break; case "ENCD": { // Entry script room.EntryScript.Data = _reader.ReadBytes((int)(it.Current.Size - 8)); } break; case "EXCD": { // exit script room.ExitScript.Data = _reader.ReadBytes((int)(it.Current.Size - 8)); } break; case "NLSC": { // number of local scripts var numLocalScripts = _reader.ReadUInt16(); } break; case "LSCR": { // local script var pos = _reader.BaseStream.Position; var index = ReadScriptIndex(); var size = 8 + _reader.BaseStream.Position - pos; room.LocalScripts[index - GetNumGlobalScripts()] = new ScriptData { Data = _reader.ReadBytes((int)(it.Current.Size - size)) }; } break; case "OBIM": { // Object Image var obj = ReadObjectImages(it.Current.Size - 8); images[obj.Number] = obj; } break; case "OBCD": { // object script var obj = ReadObjectCode(it.Current.Size - 8); objCodes[obj.Number] = obj; } break; default: UnknownChunk(it.Current); break; } } var objIds = objCodes.Values.Concat(images.Values).Select(o => o.Number).Distinct().ToList(); foreach (var objId in objIds) { if (images.ContainsKey(objId)) { if (objCodes.ContainsKey(objId)) { room.Objects.Add(Merge(images[objId], objCodes[objId])); } else { room.Objects.Add(images[objId]); } } else { room.Objects.Add(objCodes[objId]); } } return(room); }