public MobdImage(SegmentStream stream, uint flags, Version version) { bool flipped; Width = stream.ReadUInt32(); Height = stream.ReadUInt32(); Pixels = new byte[Width * Height]; if (version == Version.KKND1) { flipped = (flags & 0x1) == 1; var isCompressed = stream.ReadUInt8() == 2; if (isCompressed) { DecompressKknd1(stream); } else { stream.ReadBytes(Pixels, 0, Pixels.Length); } } else { flipped = ((flags >> 31) & 0x1) == 1; var isCompressed = ((flags >> 27) & 0x1) == 1; var has256Colors = ((flags >> 26) & 0x1) == 1; if (isCompressed) { DecompressKknd2(stream, has256Colors); } else { stream.ReadBytes(Pixels, 0, Pixels.Length); } } if (!flipped) { return; } for (var i = 0; i < Height; i++) { var row = new byte[Width]; Array.Copy(Pixels, i * Width, row, 0, Width); Array.Reverse(row); Array.Copy(row, 0, Pixels, i * Width, Width); } }
public Mobd(SegmentStream stream, Version version) { var fileOffset = (uint)stream.BaseOffset; var firstFrameStart = stream.Length; var justReadFrameOffset = false; var animationOffsets = new List <uint>(); var rotationalAnimations = new List <MobdAnimation>(); var simpleAnimations = new List <MobdAnimation>(); while (stream.Position < firstFrameStart) { var value = stream.ReadUInt32(); // This parsing method is trash, because animation offsets are hardcoded in .exe but it seems to work. if ((value == 0xffffffff || value == 0x00000000) && justReadFrameOffset) { // terminator justReadFrameOffset = false; } else if (value - fileOffset > stream.Position && value - fileOffset < stream.Length) { // frame justReadFrameOffset = true; firstFrameStart = Math.Min(firstFrameStart, value - fileOffset); } else if (value - fileOffset < stream.Position && value >= fileOffset) { // animation pointer animationOffsets.Remove(value - fileOffset); var returnPosition = stream.Position; stream.Position = value - fileOffset; rotationalAnimations.Add(new MobdAnimation(stream, version)); stream.Position = returnPosition; } else if (value == 0) { // TODO filler ? Sprite Invisible? } else { animationOffsets.Add((uint)(stream.Position - 4)); } } foreach (var animationOffset in animationOffsets) { try { stream.Position = animationOffset; simpleAnimations.Add(new MobdAnimation(stream, version)); } catch (Exception) { // TODO crashes on kknd2, fix me! } } RotationalAnimations = rotationalAnimations.ToArray(); SimpleAnimations = simpleAnimations.ToArray(); }