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); }
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); }
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); }
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); }
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); }