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 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 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 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; }
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 ScummBlock Read(ScummBinaryReader reader) { var header = reader.ReadBlockHeader(); var numRooms = reader.ReadByte(); return new LoffBlock { Header = header, NumRooms = numRooms, RoomOffsets = ReadRoomOffsets(reader, numRooms) }; }
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); }
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 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); }
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); }
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 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)); } }
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); }
private byte[] DecodeUnkAStripe(ScummBinaryReader reader, byte codingShift, int stripHeight, Color[] roomPalette) { var data = new byte[32 * stripHeight]; var color = reader.ReadByte(); var stripePixelsLeft = 8 * stripHeight; data[0] = roomPalette[color].R; data[1] = roomPalette[color].G; data[2] = roomPalette[color].B; data[3] = 255; var pixelIndex = 1; stripePixelsLeft--; while (stripePixelsLeft > 0) { var pixelsCount = 1; if (reader.ReadBit() > 0) { if (reader.ReadBit() == 0) { color = reader.ReadBits(codingShift); } else { var inc = (reader.ReadBits(3) - 4); if (inc != 0) { color += (byte)inc; } else { pixelsCount = reader.ReadBits(8); } } } for (int j = 0; j < pixelsCount; j++) { var x = pixelIndex % 8; var y = pixelIndex / 8; 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 (stripePixelsLeft == 0) { break; } } } reader.ResetBitCursor(); return(data); }
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); }