public MobdRenderFlags(SegmentStream stream, Version version) { /*Type = */ stream.ReadASCII(4); var flags = stream.ReadUInt32(); if (version == Version.KKND2) { var paletteOffset = stream.ReadUInt32() - stream.BaseOffset; var returnPos = stream.Position; stream.Position = paletteOffset; stream.ReadUInt32(); // 00 00 00 80 stream.ReadUInt32(); // 00 00 00 80 stream.ReadUInt32(); // 00 00 00 80 var numColors = stream.ReadUInt16(); Palette = new uint[256]; for (var i = 0; i < numColors; i++) { var color16 = stream.ReadUInt16(); // aRRRRRGGGGGBBBBB var r = ((color16 & 0x7c00) >> 7) & 0xff; var g = ((color16 & 0x03e0) >> 2) & 0xff; var b = ((color16 & 0x001f) << 3) & 0xff; Palette[i] = (uint)((0xff << 24) | (r << 16) | (g << 8) | b); } stream.Position = returnPos; } var imageOffset = stream.ReadUInt32() - stream.BaseOffset; stream.Position = imageOffset; Image = new MobdImage(stream, flags, version); }
public override bool TryParseSprite(Stream s, string filename, out ISpriteFrame[] frames, out TypeDictionary metadata) { metadata = null; if (!IsDdf(s)) { frames = null; return(false); } var aniStream = s as DdfPackageLoader.AniSegmentStream; aniStream.Position = aniStream.AniPosition; frames = new ISpriteFrame[aniStream.ReadUInt32()]; for (var i = 0; i < frames.Length; i++) { var metaName = aniStream.ReadASCII(32).Replace("\0", string.Empty); aniStream.Position += 4 * 2; var numScripts = aniStream.ReadUInt32(); aniStream.Position += 32 * numScripts; var returnPosition = aniStream.Position; long metaPosition; if (aniStream.MetaIndex.TryGetValue(metaName, out metaPosition)) { var metaStream = new SegmentStream(aniStream, 0, aniStream.Length); metaStream.Position = metaPosition; var ddfName = metaStream.ReadASCII(32).Replace("\0", string.Empty); metaStream.Position += 4 * 3; var offset = new float2(metaStream.ReadInt32(), metaStream.ReadInt32()); long ddfPosition; if (aniStream.DdfIndex.TryGetValue(ddfName, out ddfPosition)) { var ddfStream = aniStream.DdfStream; ddfStream.Position = ddfPosition; frames[i] = new DdfSpriteFrame(ddfStream, offset); } } aniStream.Position = returnPosition; } return(true); }
public MobdRenderFlags(SegmentStream stream) { var type = new string(stream.ReadASCII(4).Reverse().ToArray()); var flags = stream.ReadUInt32(); var generation = Generation.Unknown; if (type == "SPRT") { generation = Generation.Gen1; } else if (type == "SPNS" || type == "SPRC") { generation = Generation.Gen2; } if (generation == Generation.Gen2) { var paletteOffset = stream.ReadUInt32() - stream.BaseOffset; var returnPos = stream.Position; stream.Position = paletteOffset; stream.ReadUInt32(); // 00 00 00 80 stream.ReadUInt32(); // 00 00 00 80 stream.ReadUInt32(); // 00 00 00 80 var numColors = stream.ReadUInt16(); Palette = new uint[256]; for (var i = 0; i < numColors; i++) { var color16 = stream.ReadUInt16(); // aRRRRRGGGGGBBBBB var r = ((color16 & 0x7c00) >> 7) & 0xff; var g = ((color16 & 0x03e0) >> 2) & 0xff; var b = ((color16 & 0x001f) << 3) & 0xff; Palette[i] = (uint)((0xff << 24) | (r << 16) | (g << 8) | b); } stream.Position = returnPos; } var imageOffset = stream.ReadUInt32() - stream.BaseOffset; stream.Position = imageOffset; Image = new MobdImage(stream, flags, generation); }
public Blit(SegmentStream stream) { // This is damn ugly, but it seems BLIT uses offsets from lvl start. var basePosition = (int)((SegmentStream)stream.BaseStream).BaseStream.Position - 8; Frames = new BlitFrame[stream.ReadInt32()]; var frameOffsets = new int[Frames.Length]; stream.ReadInt32(); // Unk var paletteOffset = stream.ReadInt32() - basePosition; var identifier = new string(stream.ReadASCII(4).Reverse().ToArray()); if (identifier != "BLT8") { throw new Exception("Unknwon blit type."); } for (var i = 0; i < Frames.Length; i++) { frameOffsets[i] = stream.ReadInt32() - basePosition; } stream.Position = paletteOffset; var palette = new byte[256 * 4]; for (var i = 0; i < palette.Length;) { var color16 = stream.ReadUInt16(); // aRRRRRGGGGGBBBBB palette[i++] = (byte)(((color16 & 0x001f) << 3) & 0xff); palette[i++] = (byte)(((color16 & 0x03e0) >> 2) & 0xff); palette[i++] = (byte)(((color16 & 0x7c00) >> 7) & 0xff); palette[i++] = 0xff; } for (var i = 0; i < Frames.Length; i++) { stream.Position = frameOffsets[i]; Frames[i] = new BlitFrame(stream, palette); } }
public Mapd(SegmentStream stream) { // This is damn ugly, but it seems MAPD uses offsets from lvl start. var basePosition = ((SegmentStream)stream.BaseStream).BaseStream.Position - 8; var test = stream.ReadInt32(); stream.Position += test * 4; var generation = stream.ReadInt32() == 256 ? Generation.Gen1 : Generation.Gen2; stream.Position -= (test + 2) * 4; if (generation == Generation.Gen2) { stream.ReadInt32(); // Unk } var layerOffsets = new int[stream.ReadInt32()]; Layers = new MapdLayer[layerOffsets.Length]; for (var i = 0; i < layerOffsets.Length; i++) { layerOffsets[i] = stream.ReadInt32(); } var palette = new byte[stream.ReadInt32() * 4]; if (generation == Generation.Gen2) { for (var i = 0; i < palette.Length;) { var color16 = stream.ReadUInt16(); // aRRRRRGGGGGBBBBB palette[i++] = (byte)(((color16 & 0x7c00) >> 7) & 0xff); palette[i++] = (byte)(((color16 & 0x03e0) >> 2) & 0xff); palette[i++] = (byte)(((color16 & 0x001f) << 3) & 0xff); palette[i++] = 0xff; } } else { stream.Read(palette); for (var i = 0; i < palette.Length / 4; i++) { palette[i * 4 + 3] = 0xff; } } for (var i = 0; i < Layers.Length; i++) { stream.Position = layerOffsets[i] - basePosition; var type = new string(stream.ReadASCII(4).Reverse().ToArray()); if (type != "SCRL") { throw new Exception("Unknown type."); } var tileWidth = stream.ReadInt32(); var tileHeight = stream.ReadInt32(); var tilesX = stream.ReadInt32(); var tilesY = stream.ReadInt32(); if (generation == Generation.Gen2) { stream.ReadInt32(); // Unk stream.ReadInt32(); // Unk stream.ReadInt32(); // Unk } var tilePixels = new Dictionary <int, byte[]>(); var tiles = new List <int>(); for (var y = 0; y < tilesY; y++) { for (var x = 0; x < tilesX; x++) { var tile = stream.ReadInt32(); if (generation == Generation.Gen2) { tile -= tile % 4; } tiles.Add(tile); if (tile != 0 && !tilePixels.ContainsKey(tile)) { tilePixels.Add(tile, new byte[tileWidth * tileHeight * 4]); } } } foreach (var(offset, pixels) in tilePixels) { stream.Position = offset - basePosition; if (generation == Generation.Gen1) { stream.ReadInt32(); // Unk } for (var y = 0; y < tileHeight; y++) { for (var x = 0; x < tileWidth; x++) { var index = stream.ReadByte(); if (index == 0 && i != 0) { continue; } Array.Copy(palette, index * 4, pixels, (y * tileWidth + x) * 4, 4); } } } var layer = new MapdLayer(tilesX * tileWidth, tilesY * tileHeight); Layers[i] = layer; for (var y = 0; y < tilesY; y++) { for (var x = 0; x < tilesX; x++) { var tile = tiles[y * tilesX + x]; if (tile == 0) { continue; } var pixels = tilePixels[tile]; var offset = (y * tileHeight * tilesX + x) * tileWidth; for (var row = 0; row < tileHeight; row++) { Array.Copy(pixels, row * tileWidth * 4, layer.Pixels, (offset + row * layer.Width) * 4, tileWidth * 4); } } } } }