public override Resource LoadResourceData(ScummBinaryReader reader, string resourceId, IDictionary <string, object> parameters) { ScummString scummString = new ScummString(resourceId); var data = new List <byte>(); byte b; b = reader.ReadByte(); while (b != 0x00) { data.Add(b); b = reader.ReadByte(); if (b == 0xFF) { for (int i = 0; i < 3; ++i) { b = reader.ReadByte(); data.Add(b); } } } scummString.Stream = new string(System.Text.Encoding.GetEncoding("IBM437").GetChars(data.ToArray())); return(scummString); }
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 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 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; }
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) { Verb verb = new Verb(resourceId); int length = 0; byte b = 0xFF; while (b != 0x00) { b = reader.ReadByte(); verb.Stream = verb.Stream + (char)b; ++length; if (b == 0xFF) { for (int i = 0; i < 3; ++i) { byte c = reader.ReadByte(); verb.Stream = verb.Stream + (char)c; ++length; } } } return(verb); }
public BoxmBlock Read(ScummBlockHeader header, ScummBinaryReader reader) { var pathList = new List<List<byte>>(); long endIndex = reader.BaseStream.Position + header.ContentLength; List<byte> path = null; while (reader.BaseStream.Position < endIndex) { if (path == null) path = new List<byte>(); var curByte = reader.ReadByte(); if (curByte != 0xff) { path.Add(curByte); } else { pathList.Add(path); path = null; } } return new BoxmBlock { Header = header, AllPossibleBlockPaths = pathList }; }
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 void ReadIndexFile() { var indexPath = Path.Combine(this.GamePath, string.Format("{0}.000", this.GameId)); int blockCount = 0; using (var reader = new ScummBinaryReader(new ScummStream(indexPath, this.ScummVersion))) { var blockType = new string(reader.ReadChars(4)); var itemSize = reader.ReadUInt32BigEndian(); while (reader.BaseStream.Position <= reader.BaseStream.Length) { blockCount++; ReadIndexBlock(reader, blockType); blockType = new string(reader.ReadChars(4)); itemSize = reader.ReadUInt32BigEndian(); if (blockCount >= 9) { break; } } } }
public BoxmBlock Read(ScummBlockHeader header, ScummBinaryReader reader) { var pathList = new List <List <byte> >(); long endIndex = reader.BaseStream.Position + header.ContentLength; List <byte> path = null; while (reader.BaseStream.Position < endIndex) { if (path == null) { path = new List <byte>(); } var curByte = reader.ReadByte(); if (curByte != 0xff) { path.Add(curByte); } else { pathList.Add(path); path = null; } } return(new BoxmBlock { Header = header, AllPossibleBlockPaths = pathList }); }
public NlscBlock Read(ScummBlockHeader header, ScummBinaryReader reader) { return(new NlscBlock { Header = header, Content = reader.ReadBytes((int)header.ContentLength) }); }
public TrnsBlock Read(ScummBlockHeader header, ScummBinaryReader reader) { return new TrnsBlock { Header = header, Content = reader.ReadBytes((int)header.ContentLength) }; }
private static List<LflfBlock> ReadLflfRecords(ScummBinaryReader reader) { var list = new List<LflfBlock>(); while (reader.BaseStream.Position < reader.BaseStream.Length) { list.Add(new LflfReader().Read(reader)); } return list; }
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 ScummFile Read(string fileName) { using (var inputStream = new FileStream(fileName, FileMode.Open)) { using (var reader = new ScummBinaryReader(inputStream, 0x69)) { return(Read(reader)); } } }
private static List <LflfBlock> ReadLflfRecords(ScummBinaryReader reader) { var list = new List <LflfBlock>(); while (reader.BaseStream.Position < reader.BaseStream.Length) { list.Add(new LflfReader().Read(reader)); } return(list); }
public RmhdBlock Read(ScummBlockHeader header, ScummBinaryReader reader) { return(new RmhdBlock { Header = header, Width = reader.ReadUInt16(), Height = reader.ReadUInt16(), NumObjects = reader.ReadUInt16(), }); }
public ScummFile Read(string fileName) { using (var inputStream = new FileStream(fileName, FileMode.Open)) { using (var reader = new ScummBinaryReader(inputStream, 0x69)) { return Read(reader); } } }
private ScummFile Read(ScummBinaryReader reader) { var result = new ScummFile { Header = reader.ReadBlockHeader(), LoffBlock = (LoffBlock) new LoffReader().Read(reader), LflfBlocks = ReadLflfRecords(reader) }; return(result); }
public ScummBlock Read(ScummBinaryReader reader) { var header = reader.ReadBlockHeader(); var numRooms = reader.ReadByte(); return new LoffBlock { Header = header, NumRooms = numRooms, RoomOffsets = ReadRoomOffsets(reader, numRooms) }; }
private ScummFile Read(ScummBinaryReader reader) { var result = new ScummFile { Header = reader.ReadBlockHeader(), LoffBlock = (LoffBlock)new LoffReader().Read(reader), LflfBlocks = ReadLflfRecords(reader) }; return result; }
public ScummBlock Read(ScummBinaryReader reader) { var header = reader.ReadBlockHeader(); var numRooms = reader.ReadByte(); return(new LoffBlock { Header = header, NumRooms = numRooms, RoomOffsets = ReadRoomOffsets(reader, numRooms) }); }
private static List<LoffBlock.RoomOffset> ReadRoomOffsets(ScummBinaryReader reader, byte numRooms) { var result = new List<LoffBlock.RoomOffset>(); for (int i = 0; i < numRooms; i++) { var offset = new LoffBlock.RoomOffset { RoomId = reader.ReadByte(), Offset = reader.ReadUInt32() }; result.Add(offset); } return result; }
private byte[] DecodeUnkCStripe(ScummBinaryReader reader, byte codingShift, int stripHeight, Color[] roomPalette) { var data = new byte[32 * stripHeight]; var color = (int)reader.ReadByte(); var stripePixelsLeft = 8 * stripHeight; var pixelIndex = 0; int inc = -1; while (stripePixelsLeft > 0) { var x = pixelIndex / stripHeight; var y = pixelIndex % stripHeight; var pixelAddress = y * 32 + x * 4; data[pixelAddress] = roomPalette[color].R; data[pixelAddress + 1] = roomPalette[color].G; data[pixelAddress + 2] = roomPalette[color].B; data[pixelAddress + 3] = 255; stripePixelsLeft--; pixelIndex++; if (reader.ReadBit() > 0) { if (reader.ReadBit() == 0) { color = reader.ReadBits(codingShift); inc = -1; } else { if (reader.ReadBit() > 0) { inc = -inc; } color += inc; } } } reader.ResetBitCursor(); return(data); }
private static List <LoffBlock.RoomOffset> ReadRoomOffsets(ScummBinaryReader reader, byte numRooms) { var result = new List <LoffBlock.RoomOffset>(); for (int i = 0; i < numRooms; i++) { var offset = new LoffBlock.RoomOffset { RoomId = reader.ReadByte(), Offset = reader.ReadUInt32() }; result.Add(offset); } return(result); }
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); }
protected void ReadImageDataBlock(ScummBinaryReader reader, Image image, Color[] roomPalette) { Tuple <uint, string> findResult = reader.FindOneDataBlockOf("SMAP", "BOMP"); if (findResult.Item1 == 0) { throw new InvalidOperationException("Could not find image data block."); } if (findResult.Item2 == "SMAP") { ReadSMAP(reader, image, roomPalette); } //else // reader.BaseStream.Position += findResult.Item1 - 8; }
public T Load <T>(string resourceType, int resourceId, ScummBinaryReader reader, IDictionary <string, object> parameters) where T : Resource { if (this.loaders.ContainsKey(resourceType)) { var loader = this.loaders[resourceType]; // Load the resource string resourceIdName = string.Format("{0}_{1}", resourceType, resourceId); var resource = loader.LoadResourceData(reader, resourceIdName, parameters); // Return the resource return((T)resource); } else { throw new InvalidOperationException(string.Format("No resource loaders for blockType '{0}' were found.", resourceType)); } }
public LflfBlock Read(ScummBinaryReader reader) { var result = new LflfBlock { Header = reader.ReadBlockHeader() }; long endIndex = reader.BaseStream.Position + result.Header.ContentLength; while (reader.BaseStream.Position < endIndex) { var childHeader = reader.ReadBlockHeader(); switch (childHeader.HeaderName) { case "ROOM": if (result.Room != null) { throw new DuplicateBlockException(childHeader.HeaderName); } result.Room = new RoomReader().Read(childHeader, reader); break; case "SCRP": result.Scripts.Add(new ScriptReader().Read(childHeader, reader)); break; case "SOUN": result.Sounds.Add(new SoundReader().Read(childHeader, reader)); break; case "COST": result.Costumes.Add(new CostumeReader().Read(childHeader, reader)); break; case "CHAR": result.Charsets.Add(new CharsetReader().Read(childHeader, reader)); break; default: throw new UnexpectedBlockException(childHeader.HeaderName); } } return(result); }
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); }
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); }
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 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); }
public override Resource LoadResourceData(ScummBinaryReader reader, string resourceId, IDictionary <string, object> parameters) { // should never happen return(null); }
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); }
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); }
private void DecodeImageData(ScummBinaryReader reader, LayeredImageData imageData, int width, int height, byte[] palette, Color[] roomPalette) { byte shift; byte mask; if (palette.Length == 16) { shift = 4; mask = 0xF; } else { shift = 3; mask = 0x7; } int x = 0; int y = 0; bool end = false; while (end == false) { var rep = reader.ReadByte(); var colorPaletteIndex = (byte)(rep >> shift); Color color = Color.Black; var roomColor = roomPalette[palette[colorPaletteIndex]]; color.R = roomColor.R; color.G = roomColor.G; color.B = roomColor.B; rep &= mask; if (rep == 0) { rep = reader.ReadByte(); } while (rep > 0) { if (colorPaletteIndex != 0) { imageData.SetPixel(x, y, color); } rep--; y++; if (y >= height) { y = 0; x++; if (x >= width) { end = true; } } } } }
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 ReadSMAP(ScummBinaryReader reader, Image image, Color[] roomPalette) { var smapStartOffset = reader.BaseStream.Position; var stripesCount = image.Width / 8; // Create the texture data array var textureData = new byte[image.Width * image.Height * 4]; var stripeOffsets = new uint[stripesCount]; // Read the offset table for (int i = 0; i < stripesCount; i++) { var offset = reader.ReadUInt32() - 8; stripeOffsets[i] = offset; } // Read and decode each stripes for (int i = 0; i < stripesCount; i++) { reader.BaseStream.Position = smapStartOffset + stripeOffsets[i]; var stripeHeader = reader.ReadByte(); var codingShift = (byte)(stripeHeader % 10); var encoderType = stripeHeader / 10; byte[] decodedData = null; if (encoderType == (int)EncoderType.UnkAOpaque) { decodedData = DecodeUnkAStripe(reader, codingShift, image.Height, roomPalette); } else if (encoderType == (int)EncoderType.UnkBOpaque) { decodedData = DecodeUnkBStripe(reader, codingShift, image.Height, roomPalette); } else if (encoderType == (int)EncoderType.UnkCOpaque) { decodedData = DecodeUnkCStripe(reader, codingShift, image.Height, roomPalette); } if (decodedData != null) { int decodedDataIndex = 0; for (int j = 0; j < image.Height; j++) { for (int k = 0; k < 8; k++) { var pixelIndex = i * 32 + j * image.Width * 4 + k * 4; textureData[pixelIndex] = decodedData[decodedDataIndex]; textureData[pixelIndex + 1] = decodedData[decodedDataIndex + 1]; textureData[pixelIndex + 2] = decodedData[decodedDataIndex + 2]; textureData[pixelIndex + 3] = decodedData[decodedDataIndex + 3]; decodedDataIndex += 4; } } } } image.Texture = new Microsoft.Xna.Framework.Graphics.Texture2D(graphicsDevice, image.Width, image.Height, false, Microsoft.Xna.Framework.Graphics.SurfaceFormat.Color); image.Texture.SetData(textureData); }
public RoomBlock Read(ScummBlockHeader header, ScummBinaryReader reader) { var result = new RoomBlock { Header = header }; long endIndex = reader.BaseStream.Position + result.Header.ContentLength; while (reader.BaseStream.Position < endIndex) { var childHeader = reader.ReadBlockHeader(); switch (childHeader.HeaderName) { case "RMHD": if (result.RoomHeader != null) throw new DuplicateBlockException(childHeader.HeaderName); result.RoomHeader = new RoomHeaderReader().Read(childHeader, reader); break; case "EPAL": if (result.EgaPalette != null) throw new DuplicateBlockException(childHeader.HeaderName); result.EgaPalette = new EgaPaletteReader().Read(childHeader, reader); break; case "CLUT": if (result.Clut != null) throw new DuplicateBlockException(childHeader.HeaderName); result.Clut = new ClutReader().Read(childHeader, reader); break; case "CYCL": if (result.ColorCycle != null) throw new DuplicateBlockException(childHeader.HeaderName); result.ColorCycle = new ColorCycleReader().Read(childHeader, reader); break; case "TRNS": if (result.Transparent != null) throw new DuplicateBlockException(childHeader.HeaderName); result.Transparent = new TransparentReader().Read(childHeader, reader); break; case "PALS": if (result.Palette != null) throw new DuplicateBlockException(childHeader.HeaderName); result.Palette = new PaletteReader().Read(childHeader, reader); break; case "RMIM": if (result.RoomImage != null) throw new DuplicateBlockException(childHeader.HeaderName); result.RoomImage = new RoomImageReader().Read(childHeader, reader); break; case "OBIM": result.ObjImages.Add(new ObjImageReader().Read(childHeader, reader)); break; case "OBCD": result.ObjectScripts.Add(new ObjectScriptReader().Read(childHeader, reader)); break; case "EXCD": if (result.ExitScript != null) throw new DuplicateBlockException(childHeader.HeaderName); result.ExitScript = new ExitScriptReader().Read(childHeader, reader); break; case "ENCD": if (result.EntryScript != null) throw new DuplicateBlockException(childHeader.HeaderName); result.EntryScript = new EntryScriptReader().Read(childHeader, reader); break; case "NLSC": if (result.NumScripts != null) throw new DuplicateBlockException(childHeader.HeaderName); result.NumScripts = new NumScriptsReader().Read(childHeader, reader); break; case "LSCR": result.LocalScripts.Add(new LocalScriptReader().Read(childHeader, reader)); break; case "BOXD": if (result.BoxData != null) throw new DuplicateBlockException(childHeader.HeaderName); result.BoxData = new BoxDataReader().Read(childHeader, reader); break; case "BOXM": if (result.BoxMatrix != null) throw new DuplicateBlockException(childHeader.HeaderName); result.BoxMatrix = new BoxMatrixReader().Read(childHeader, reader); break; case "SCAL": if (result.ScaleSlots != null) throw new DuplicateBlockException(childHeader.HeaderName); result.ScaleSlots = new ScaleSlotsReader().Read(childHeader, reader); break; default: throw new UnexpectedRoomBlockException(childHeader.HeaderName); } } return result; }