public BoxdBlock Read(ScummBlockHeader header, ScummBinaryReader reader) { var numBlocks = reader.ReadUInt16(); var boxList = new List <BoxdBlock.Box>(); for (int i = 0; i < numBlocks; i++) { var box = new BoxdBlock.Box() { UpperLeftX = reader.ReadUInt16(), UpperLeftY = reader.ReadUInt16(), UpperRightX = reader.ReadUInt16(), UpperRightY = reader.ReadUInt16(), LowerRightX = reader.ReadUInt16(), LowerRightY = reader.ReadUInt16(), LowerLeftX = reader.ReadUInt16(), LowerLeftY = reader.ReadUInt16(), Mask = reader.ReadByte(), Flags = reader.ReadByte(), Scale = reader.ReadUInt16() }; boxList.Add(box); } var result = new BoxdBlock { Header = header, BoxList = boxList }; return(result); }
public BoxdBlock Read(ScummBlockHeader header, ScummBinaryReader reader) { var numBlocks = reader.ReadUInt16(); var boxList = new List<BoxdBlock.Box>(); for (int i = 0; i < numBlocks; i++) { var box = new BoxdBlock.Box() { UpperLeftX = reader.ReadUInt16(), UpperLeftY = reader.ReadUInt16(), UpperRightX = reader.ReadUInt16(), UpperRightY = reader.ReadUInt16(), LowerRightX = reader.ReadUInt16(), LowerRightY = reader.ReadUInt16(), LowerLeftX = reader.ReadUInt16(), LowerLeftY = reader.ReadUInt16(), Mask = reader.ReadByte(), Flags = reader.ReadByte(), Scale = reader.ReadUInt16() }; boxList.Add(box); } var result = new BoxdBlock { Header = header, BoxList = boxList }; return result; }
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 RmhdBlock Read(ScummBlockHeader header, ScummBinaryReader reader) { return new RmhdBlock { Header = header, Width = reader.ReadUInt16(), Height = reader.ReadUInt16(), NumObjects = reader.ReadUInt16(), }; }
public RmhdBlock Read(ScummBlockHeader header, ScummBinaryReader reader) { return(new RmhdBlock { Header = header, Width = reader.ReadUInt16(), Height = reader.ReadUInt16(), NumObjects = reader.ReadUInt16(), }); }
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; }
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); }
private ResourceIndexEntry[] ReadResourceReferenceList(ScummBinaryReader reader, ref ushort itemsCount) { itemsCount = reader.ReadUInt16(); var resourceReferenceList = new ResourceIndexEntry[itemsCount]; var roomIdList = new byte[itemsCount]; for (int i = 0; i < itemsCount; i++) { roomIdList[i] = reader.ReadByte(); } for (int i = 0; i < itemsCount; i++) { var resourceOffset = reader.ReadUInt32(); resourceReferenceList[i] = new ResourceIndexEntry(roomIdList[i], resourceOffset); } return(resourceReferenceList); }
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); }
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); }
private CostumeAnimation LoadAnimation(ScummBinaryReader reader, string resourceId, int animationIndex, long startOffset, ushort[] animationOffsets, ushort[] limbOffsets, ushort animationCommandOffset, byte[] palette, Color[] roomPalette, bool containsRedirection, bool mirror) { if (animationOffsets[animationIndex] == 0) { return(null); } reader.BaseStream.Position = startOffset + animationOffsets[animationIndex]; var costumeAnimation = new CostumeAnimation(); costumeAnimation.IsMirrored = mirror; var currentFrameIndex = 0; var framesCount = 0; var startAnimationPosition = reader.BaseStream.Position; while (currentFrameIndex < framesCount || currentFrameIndex == 0) { var mask = reader.ReadUInt16(); var costumeFrame = new CostumeFrame(); var imageData = new LayeredImageData(); var i = 0; do { if ((mask & 0x8000) != 0) { var startAnimationCommandOffset = reader.ReadUInt16(); if (startAnimationCommandOffset != 0xFFFF) { var flags = reader.ReadByte(); var loop = flags & 0x8000; var endFrame = flags & 0x7F; if (currentFrameIndex == 0 && framesCount == 0) { framesCount = Math.Max(framesCount, endFrame) + 1; } var oldStreamPosition = reader.BaseStream.Position; reader.BaseStream.Position = startOffset + animationCommandOffset + startAnimationCommandOffset + Math.Min(currentFrameIndex, endFrame); var animationCommandValue = reader.ReadByte(); if (animationCommandValue == 0x71) { // TODO: Handle special commands (sounds, etc.) } else if (animationCommandValue == 0x7A) { // TODO: Implement start command } else if (animationCommandValue == 0x79) { // TODO: Implement stopped command } else { reader.BaseStream.Position = startOffset + limbOffsets[i] + animationCommandValue * 2; var pictOffset = reader.ReadUInt16(); reader.BaseStream.Position = startOffset + pictOffset; var width = reader.ReadUInt16(); var height = reader.ReadUInt16(); var relativeX = reader.ReadInt16(); var relativeY = reader.ReadInt16(); var movementX = reader.ReadInt16(); var movementY = reader.ReadInt16(); if (containsRedirection) { var redirectionLimb = reader.ReadByte(); var redirectionPict = reader.ReadByte(); } imageData.CreateLayer(width, height, new Vector2(relativeX, relativeY)); DecodeImageData(reader, imageData, width, height, palette, roomPalette); } reader.BaseStream.Position = oldStreamPosition; } } mask = (ushort)(mask << 1); i++; } while ((mask & 0xFFFF) != 0); costumeFrame.FrameType = CostumeFrameType.Frame; // TODO: Fill offset and movement vector var textureData = imageData.GetBytes(); costumeFrame.Data = new Microsoft.Xna.Framework.Graphics.Texture2D(this.graphicsDevice, imageData.Width, imageData.Height, false, Microsoft.Xna.Framework.Graphics.SurfaceFormat.Color); costumeFrame.Data.SetData(textureData); costumeAnimation.Frames.Add(costumeFrame); if (!Directory.Exists("DebugAnims\\" + resourceId)) { Directory.CreateDirectory("DebugAnims\\" + resourceId); } costumeFrame.Data.SaveAsPng(File.Create(string.Format("DebugAnims\\" + resourceId + "\\Anim{0}_{1}.png", animationIndex, currentFrameIndex)), costumeFrame.Data.Width, costumeFrame.Data.Height); reader.BaseStream.Position = startAnimationPosition; currentFrameIndex++; } return(costumeAnimation); }
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); }
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)); } }
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); }