public override Resource LoadResourceData(ScummBinaryReader reader, string resourceId, IDictionary <string, object> parameters)
        {
            reader.FindDataBlockNoInfo("OBIM");
            // read header
            uint blockSize = reader.FindDataBlock("IMHD");

            UInt16 id  = reader.ReadUInt16();
            var    obj = ResourceManager.FindObject(id);

            UInt16 numImages = reader.ReadUInt16();
            UInt16 numZs     = reader.ReadUInt16();
            Byte   flags     = reader.ReadByte();
            Byte   unknown   = reader.ReadByte();
            UInt16 x         = reader.ReadUInt16();
            UInt16 y         = reader.ReadUInt16();
            UInt16 width     = reader.ReadUInt16();
            UInt16 height    = reader.ReadUInt16();

            obj.Position = new Vector2(x, y);
            obj.Image    = new Image(width, height);

            var roomPalette = (Color[])parameters["RoomPalette"];

            for (int i = 0; i < numImages; ++i)
            {
                string blockName = String.Format("IM{0:X2}", i + 1);
                if (reader.FindDataBlock(blockName) == 0)
                {
                    throw new InvalidOperationException("Could not find image block.");
                }
                ReadImageDataBlock(reader, obj.Image, roomPalette);
            }

            return(obj.Image);
        }
Exemple #2
0
        public override Resource LoadResourceData(ScummBinaryReader reader, string resourceId, IDictionary <string, object> parameters)
        {
            reader.FindDataBlockNoInfo("OBCD");

            // read header
            uint   blockSize = reader.FindDataBlock("CDHD");
            UInt16 id        = reader.ReadUInt16();

            var obj  = ResourceManager.FindObject(id);
            var data = reader.ReadBytes((int)blockSize - 10);

            // read verb block
            blockSize = reader.FindDataBlock("VERB");
            long verbPos = reader.BaseStream.Position - 8;

            // read verbs and offsets
            byte[]   verbs   = new byte[100];
            UInt16[] offsets = new UInt16[100];

            int totalVerbs = 0;

            verbs[totalVerbs] = reader.ReadByte();
            while (verbs[totalVerbs] != 0)
            {
                offsets[totalVerbs] = reader.ReadUInt16();
                verbs[++totalVerbs] = reader.ReadByte();
            }
            // final offset found reading the next block - needed for blocksize
            reader.FindDataBlockNoInfo("OBNA");
            long endPos = reader.BaseStream.Position - 8;

            // read object name
            byte a = reader.ReadByte();

            while (a != 0)
            {
                obj.Name += (char)a;
                a         = reader.ReadByte();
            }
            long backupPos = reader.BaseStream.Position;

            // load verb scripts
            for (int i = 0; i < totalVerbs; ++i)
            {
                long startPos = verbPos + offsets[i];
                uint size     = (uint)(endPos - startPos);

                obj.VerbScript[verbs[i]] =
                    (ScriptV5)resourceManager.Load <Script>("SCRP", id, reader, new Dictionary <string, object>()
                {
                    { "Position", startPos }, { "Blocksize", size }
                });
            }
            reader.BaseStream.Position = backupPos;

            return(obj);
        }
Exemple #3
0
        public override Resource LoadResourceData(ScummBinaryReader reader, string resourceId, IDictionary <string, object> parameters)
        {
            uint blockSize;

            if (!parameters.ContainsKey("Type") && !parameters.ContainsKey("Position"))
            {
                blockSize = reader.FindDataBlock("SCRP");
            }
            else
            {
                if (parameters.ContainsKey("Type"))
                {
                    blockSize = reader.FindDataBlock((string)parameters["Type"]);
                    if ((string)parameters["Type"] == "LSCR")
                    {
                        byte id = reader.ReadByte();
                        resourceId = String.Format("LSCRP_{0}", id);
                        --blockSize;
                    }
                    else if ((string)parameters["Type"] == "EXCD")
                    {
                        resourceId = String.Format("SCRP_{0}", 10001);
                    }
                    else if ((string)parameters["Type"] == "ENCD")
                    {
                        resourceId = String.Format("SCRP_{0}", 10002);
                    }
                }
                else
                {
                    reader.BaseStream.Position = (long)parameters["Position"];
                    blockSize  = (uint)parameters["Blocksize"];
                    blockSize += 8;
                }
            }

            // Read script Header information
            if (blockSize == 0)
            {
                throw new InvalidOperationException("Could not find the script header block.");
            }

            // Read the opcode blocks
            var data   = reader.ReadBytes((int)blockSize - 8);
            var script = new ScriptV5(resourceId, data, scriptManager, resourceManager, sceneManager, scummState, this.logFile);

            return(script);
        }
Exemple #4
0
        public override Resource LoadResourceData(ScummBinaryReader reader, string resourceId, IDictionary <string, object> parameters)
        {
            var image       = new Image((int)parameters["Width"], (int)parameters["Height"]);
            var roomPalette = (Color[])parameters["RoomPalette"];

            // Read the image header
            if (reader.FindDataBlock("RMIH", (uint)parameters["RoomOffset"]) == 0)
            {
                throw new InvalidOperationException("Could not find the room background header block.");
            }

            var zbufferCount = reader.ReadUInt16();

            // TODO: Add code to take into account multiple image blocks (object images)
            if (reader.FindDataBlock("IM00") == 0)
            {
                throw new InvalidOperationException("Could not find image block.");
            }

            ReadImageDataBlock(reader, image, roomPalette);

            return(image);
        }
        private void ReadDataFile()
        {
            // Read the entire game data file into memory for now
            var dataPath = Path.Combine(this.GamePath, string.Format("{0}.001", this.GameId));

            this.dataFileReader = new ScummBinaryReader(new ScummStream(dataPath, this.ScummVersion));

            // Read first block with room offset - other offsets are just wrong
            if (dataFileReader.FindDataBlock("LOFF") > 0)
            {
                this.roomsCount     = this.dataFileReader.ReadByte();
                this.roomsIndexList = new Dictionary <byte, uint>();

                for (int i = 0; i < this.roomsCount; i++)
                {
                    var roomId     = this.dataFileReader.ReadByte();
                    var roomOffset = this.dataFileReader.ReadUInt32();

                    this.roomsIndexList.Add(roomId, roomOffset);
                }
            }
        }
        public override Resource LoadResourceData(ScummBinaryReader reader, string resourceId, IDictionary <string, object> parameters)
        {
            var charset = new Charset(resourceId);

            uint blockSize = reader.FindDataBlock("CHAR");

            if (blockSize == 0)
            {
                throw new InvalidOperationException("Could not find the script header block.");
            }

            // Load the room palette associated with the charset
            // (huge hack - I have no idea what to do when room is 0)
            if ((byte)parameters["RoomId"] == 0)
            {
                parameters["RoomId"] = (byte)10;
            }

            long keepPos     = reader.BaseStream.Position;
            var  roomPalette = this.resourceManager.Load <Room>("ROOM", (byte)parameters["RoomId"]).Palette;

            reader.BaseStream.Position = keepPos;

            // Read charset header information
            var unknown = reader.ReadBytes(6);

            byte[] colormap = new byte[16];
            colormap[0] = 0;
            for (int i = 0; i < 15; ++i)
            {
                colormap[i + 1] = reader.ReadByte();
            }

            long initPosition = reader.BaseStream.Position;

            byte numBitsPerPixel = reader.ReadByte();
            byte bitMask         = (byte)(0xFF << (8 - numBitsPerPixel));

            byte  fontHeight = reader.ReadByte();
            short numChars   = reader.ReadInt16();

            uint[] offsets = new uint[numChars];
            for (int i = 0; i < numChars; ++i)
            {
                offsets[i] = reader.ReadUInt32();
            }

            // Read each char
            for (int i = 0; i < numChars; ++i)
            {
                if (offsets[i] == 0)
                {
                    continue;
                }

                reader.BaseStream.Position = initPosition + offsets[i];

                charset.Chars[i].width  = reader.ReadByte();
                charset.Chars[i].height = reader.ReadByte();
                // a flag is needed to disable offX
                charset.Chars[i].offX = 0; reader.ReadByte();
                charset.Chars[i].offY = reader.ReadByte();
                charset.Chars[i].pic  = new Texture2D(graphicsDevice, charset.Chars[i].width, charset.Chars[i].height);

                byte[] bytes = new byte[charset.Chars[i].width * charset.Chars[i].height * 4];

                Byte bits          = reader.ReadByte();
                Byte remainingBits = 8;
                for (int y = 0; y < charset.Chars[i].height; ++y)
                {
                    for (int x = 0; x < charset.Chars[i].width; ++x)
                    {
                        long colorId = (bits & bitMask) >> (8 - numBitsPerPixel);
                        long color   = colormap[colorId];

                        byte alpha = 255;
                        if (colorId == 0)
                        {
                            alpha = 0;
                        }

                        bytes[(y * charset.Chars[i].width + x) * 4]     = roomPalette[color].R;
                        bytes[(y * charset.Chars[i].width + x) * 4 + 1] = roomPalette[color].G;
                        bytes[(y * charset.Chars[i].width + x) * 4 + 2] = roomPalette[color].B;
                        bytes[(y * charset.Chars[i].width + x) * 4 + 3] = alpha;

                        bits           = (byte)(bits << numBitsPerPixel);
                        remainingBits -= numBitsPerPixel;
                        if (remainingBits <= 0)
                        {
                            bits          = reader.ReadByte();
                            remainingBits = 8;
                        }
                    }
                }

                charset.Chars[i].pic.SetData(bytes);
            }

            return(charset);
        }
        public override Resource LoadResourceData(ScummBinaryReader reader, string resourceId, IDictionary <string, object> parameters)
        {
            // TODO: If the anim is mirrored, point to the same textures and do a matrix transform while rendering the costume
            var costume = new Costume(resourceId);

            // Read Room Header information
            if (reader.FindDataBlock("COST") == 0)
            {
                throw new InvalidOperationException("Could not find the costume header block.");
            }

            reader.BaseStream.Position -= 6;
            var startOffset = reader.BaseStream.Position;

            var size = reader.ReadUInt32();
            var test = ((char)reader.ReadByte()).ToString() + ((char)reader.ReadByte()).ToString();

            var animationsCount = reader.ReadByte();

            var format              = reader.ReadByte();
            var paletteSize         = ((format & 0x7F) == 0x58 || (format & 0x7F) == 0x60) ? 16 : 32;
            var containsRedirection = ((format & 0x7E) == 0x60);
            var mirrorWestPositions = (format & 0x80) == 0;

            // TODO: Decode bit 7

            // TODO : Read the full palette
            var palette = new byte[paletteSize];

            for (int i = 0; i < paletteSize; i++)
            {
                palette[i] = reader.ReadByte();
            }

            var animationCommandOffset = reader.ReadUInt16();

            // Read limb offsets
            var limbOffsets = new ushort[16];

            for (int i = 0; i < 16; i++)
            {
                limbOffsets[i] = reader.ReadUInt16();
            }

            // Read animation offsets
            var animationOffsets = new ushort[animationsCount];

            for (int i = 0; i < animationOffsets.Length; i++)
            {
                animationOffsets[i] = reader.ReadUInt16();
            }

            // Load the room palette associated with the costume
            // (huge hack - I have no idea what to do when room is 0)
            if ((byte)parameters["RoomId"] == 0)
            {
                parameters["RoomId"] = (byte)10;
            }
            var roomPalette = this.resourceManager.Load <Room>("ROOM", (byte)parameters["RoomId"]).Palette;

            for (int i = 4; i < animationsCount; i++)
            {
                try
                {
                    var animation = LoadAnimation(reader, resourceId, i, startOffset, animationOffsets, limbOffsets, animationCommandOffset, palette, roomPalette, containsRedirection, (i % 4) == 0 && mirrorWestPositions);
                    costume.Animations.Add(animation);
                }
                // TODO: Remove the empty catch later
                catch { }
            }

            return(costume);
        }
Exemple #8
0
        public override Resource LoadResourceData(ScummBinaryReader reader, string resourceId, IDictionary <string, object> parameters)
        {
            var room       = new Room(resourceId);
            var roomOffset = (uint)reader.BaseStream.Position;

            // Read Room Header information
            if (reader.FindDataBlock("RMHD", roomOffset) == 0)
            {
                throw new InvalidOperationException("Could not find the room header block.");
            }

            var width        = reader.ReadUInt16();
            var height       = reader.ReadUInt16();
            var objectsCount = reader.ReadUInt16();

            // Read palette data
            if (reader.FindDataBlock("CLUT", roomOffset) == 0)
            {
                throw new InvalidOperationException("Could not find the room palette block.");
            }

            // Load only the first palette for now
            room.Palette = new Color[256];
            for (int i = 0; i < 256; ++i)
            {
                room.Palette[i].R = reader.ReadByte();
                room.Palette[i].G = reader.ReadByte();
                room.Palette[i].B = reader.ReadByte();
            }

            // Read background image
            room.BackgroundImage = ResourceManager.Load <Image>("RMIM", new Dictionary <string, object>()
            {
                { "Width", (int)width }, { "Height", (int)height }, { "RoomOffset", roomOffset }, { "RoomPalette", room.Palette }
            });

            room.Objects = new Object[objectsCount];

            Image[] images = new Image[objectsCount];
            if (objectsCount == 13)
            {
                objectsCount -= 1;
            }

            if (objectsCount == 90)
            {
                objectsCount -= 7;
            }

            for (int i = 0; i < objectsCount; ++i)
            {
                ResourceManager.Load <Image>("OBIM", new Dictionary <string, object>()
                {
                    { "RoomPalette", room.Palette }
                });
            }

            if (objectsCount == 12)
            {
                objectsCount += 1;
            }

            if (objectsCount == 83)
            {
                objectsCount += 7;
            }

            for (int i = 0; i < objectsCount; ++i)
            {
                ResourceManager.Load <Object>("OBJC", new Dictionary <string, object>());
            }

            // Read entry/exit scripts
            room.ExitScript = ResourceManager.Load <Script>("SCRP", new Dictionary <string, object>()
            {
                { "Type", "EXCD" }
            });
            room.EntryScript = ResourceManager.Load <Script>("SCRP", new Dictionary <string, object>()
            {
                { "Type", "ENCD" }
            });

            // Read local script
            if (reader.FindDataBlock("NLSC") != 0)
            {
                byte totalLocal = reader.ReadByte();
                byte padding    = reader.ReadByte();
                if (totalLocal != 0)
                {
                    room.Scripts = new Script[totalLocal];
                    for (int i = 0; i < totalLocal; ++i)
                    {
                        room.Scripts[i] = resourceManager.Load <Script>("SCRP", new Dictionary <string, object>()
                        {
                            { "Type", "LSCR" }
                        });
                    }
                }
            }

            return(room);
        }