示例#1
0
        public VerbBlock Read(ScummBlockHeader header, ScummBinaryReader reader)
        {
            //var bytes = reader.ReadBytes(100).Select(x => (char) x);
            List<VerbBlock.VerbEntry> verbEntries = new List<VerbBlock.VerbEntry>();
            while (true)
            {
                var verb = reader.ReadByte();
                if (verb == 0)
                    break;
                verbEntries.Add(new VerbBlock.VerbEntry
                {
                    Verb = verb,
                    Offset = reader.ReadUInt16()
                });
            }

            uint endIndex = header.ContentLength;
            foreach (var verb in verbEntries.OrderByDescending(x => x.Offset))
            {
                verb.Length = endIndex - (verb.Offset - 8);
                verb.Content = reader.ReadBytes((int)verb.Length);
                endIndex = (uint)(verb.Offset - 8);
            }

            var result = new VerbBlock
            {
                Header = header,
                VerbEntries = verbEntries
            };
            return result;
        }
示例#2
0
        public ObcdBlock Read(ScummBlockHeader header, ScummBinaryReader reader)
        {
            var result = new ObcdBlock
            {
                Header = header
            };

            long endIndex = reader.BaseStream.Position + result.Header.ContentLength;
            while (reader.BaseStream.Position < endIndex)
            {
                var childHeader = reader.ReadBlockHeader();
                switch (childHeader.HeaderName)
                {
                    case "CDHD":
                        //if (result.Room != null) throw new DuplicateBlockException(childHeader.HeaderName);
                        reader.BaseStream.Seek(childHeader.ContentLength, SeekOrigin.Current);
                        break;
                    case "VERB":
                        if (result.Verb != null) throw new DuplicateBlockException(childHeader.HeaderName);
                        result.Verb = new VerbReader().Read(childHeader, reader);
                        break;
                    case "OBNA":
                        if (result.Name != null) throw new DuplicateBlockException(childHeader.HeaderName);
                        var bytes = reader.ReadBytes((int)childHeader.ContentLength);
                        result.Name = System.Text.Encoding.ASCII.GetString(bytes);
                        result.Name = result.Name.TrimEnd('\0');
                        break;
                    default:
                        throw new UnexpectedObjectScriptBlockException(childHeader.HeaderName);
                }
            }
            return result;
        }
示例#3
0
 public NlscBlock Read(ScummBlockHeader header, ScummBinaryReader reader)
 {
     return(new NlscBlock
     {
         Header = header,
         Content = reader.ReadBytes((int)header.ContentLength)
     });
 }
示例#4
0
 public TrnsBlock Read(ScummBlockHeader header, ScummBinaryReader reader)
 {
     return new TrnsBlock
     {
         Header = header,
         Content = reader.ReadBytes((int)header.ContentLength)
     };
 }
示例#5
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);
        }
示例#6
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);
        }
示例#7
0
        public ObcdBlock Read(ScummBlockHeader header, ScummBinaryReader reader)
        {
            var result = new ObcdBlock
            {
                Header = header
            };

            long endIndex = reader.BaseStream.Position + result.Header.ContentLength;

            while (reader.BaseStream.Position < endIndex)
            {
                var childHeader = reader.ReadBlockHeader();
                switch (childHeader.HeaderName)
                {
                case "CDHD":
                    //if (result.Room != null) throw new DuplicateBlockException(childHeader.HeaderName);
                    reader.BaseStream.Seek(childHeader.ContentLength, SeekOrigin.Current);
                    break;

                case "VERB":
                    if (result.Verb != null)
                    {
                        throw new DuplicateBlockException(childHeader.HeaderName);
                    }
                    result.Verb = new VerbReader().Read(childHeader, reader);
                    break;

                case "OBNA":
                    if (result.Name != null)
                    {
                        throw new DuplicateBlockException(childHeader.HeaderName);
                    }
                    var bytes = reader.ReadBytes((int)childHeader.ContentLength);
                    result.Name = System.Text.Encoding.ASCII.GetString(bytes);
                    result.Name = result.Name.TrimEnd('\0');
                    break;

                default:
                    throw new UnexpectedObjectScriptBlockException(childHeader.HeaderName);
                }
            }
            return(result);
        }
示例#8
0
        public VerbBlock Read(ScummBlockHeader header, ScummBinaryReader reader)
        {
            //var bytes = reader.ReadBytes(100).Select(x => (char) x);
            List <VerbBlock.VerbEntry> verbEntries = new List <VerbBlock.VerbEntry>();

            while (true)
            {
                var verb = reader.ReadByte();
                if (verb == 0)
                {
                    break;
                }
                verbEntries.Add(new VerbBlock.VerbEntry
                {
                    Verb   = verb,
                    Offset = reader.ReadUInt16()
                });
            }


            uint endIndex = header.ContentLength;

            foreach (var verb in verbEntries.OrderByDescending(x => x.Offset))
            {
                verb.Length  = endIndex - (verb.Offset - 8);
                verb.Content = reader.ReadBytes((int)verb.Length);
                endIndex     = (uint)(verb.Offset - 8);
            }

            var result = new VerbBlock
            {
                Header      = header,
                VerbEntries = verbEntries
            };

            return(result);
        }
示例#9
0
        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);
        }
示例#10
0
        private void ReadIndexBlock(ScummBinaryReader reader, string blockType)
        {
            if (blockType == "RNAM")
            {
                byte roomId = reader.ReadByte();
                while (roomId != 0)
                {
                    var roomNameData = reader.ReadBytes(9);
                    var roomName     = string.Empty;

                    for (int i = 0; i < roomNameData.Length; i++)
                    {
                        roomName += (char)(roomNameData[i] ^ 0xFF);
                    }

                    roomId = reader.ReadByte();
                }
            }

            else if (blockType == "MAXS")
            {
                var variablesCount = reader.ReadUInt16();

                // Skip 2 bytes
                reader.ReadUInt16();

                uint bitVariablesCount     = reader.ReadUInt16();
                uint localObjectsCount     = reader.ReadUInt16();
                uint newNamesCount         = reader.ReadUInt16();
                uint charsetsCount         = reader.ReadUInt16();
                uint verbsCount            = reader.ReadUInt16();
                uint arraysCount           = reader.ReadUInt16();
                uint inventoryObjectsCount = reader.ReadUInt16();
            }

            else if (blockType == "DROO")
            {
                // just read, not keeping anything besides roomsCount
                ReadResourceReferenceList(reader, ref roomsCount);
            }

            else if (blockType == "DSCR")
            {
                this.scriptsIndexList = ReadResourceReferenceList(reader, ref scriptsCount);
            }

            else if (blockType == "DSOU")
            {
                this.soundsIndexList = ReadResourceReferenceList(reader, ref soundsCount);
            }

            else if (blockType == "DCOS")
            {
                this.costumesIndexList = ReadResourceReferenceList(reader, ref costumesCount);
            }

            else if (blockType == "DCHR")
            {
                this.charsetsIndexList = ReadResourceReferenceList(reader, ref charsetsCount);
            }

            else if (blockType == "DOBJ")
            {
                uint itemsCount = reader.ReadUInt16();
                objects = new Object[itemsCount];

                for (int i = 0; i < itemsCount; i++)
                {
                    objects[i]            = new Object();
                    objects[i].Id         = (UInt16)i;
                    objects[i].OwnerState = reader.ReadByte();
                }
                for (int i = 0; i < itemsCount; i++)
                {
                    objects[i].ClassData = reader.ReadUInt32();
                }
            }
            else if (blockType == "AARY")
            {
            }
            else
            {
                //throw new InvalidOperationException(string.Format("Cannot read block of type '{0}' in the index file.", blockType));
            }
        }