Beispiel #1
0
        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));
        }
Beispiel #2
0
        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()));
            }
        }
Beispiel #3
0
        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));
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
 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);
 }
Beispiel #6
0
 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]);
 }
Beispiel #7
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);
        }
Beispiel #8
0
        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());
                }
            }
        }
Beispiel #9
0
        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);
        }
Beispiel #10
0
        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);
        }