/// <summary> /// Decrypts a spriteframe's rowheader. /// </summary> /// <param name="P">The rowheader that was read from the spriteframe's data.</param> /// <returns></returns> private EncryptedRowHeader GetDecryptedValues(ushort P) { EncryptedRowHeader RowHeader = new EncryptedRowHeader(); // 0xe000 = 1110 0000 0000 0000 : high order 3 bits // 0x1fff = 0001 1111 1111 1111 : low order 13 bits // 0xd = shift 13 bits to the right // as documented, 0xa000 is the stop value, with value 5 in the high order 3 bits -> // 0xa000 = 1010 0000 0000 0000 little endian // high order 3 bits are 101, or value 5 RowHeader.Code = ((P & 0xe000) << 0xd); RowHeader.Count = (P & 0x1fff); return(RowHeader); }
public SpriteParser(byte[] ChunkData, List <PaletteMap> PMaps, int ChunkID) { m_ChunkID = ChunkID; MemoryStream MemStream = new MemoryStream(ChunkData); BinaryReader Reader = new BinaryReader(MemStream); Reader.BaseStream.Position = INDEX_SPRID; m_ID = Reader.ReadByte(); Reader.BaseStream.Position = INDEX_SPRVERSION; m_Version = Reader.ReadUInt32(); if (m_Version != 1000 && m_Version != 1001) { throw new Exception("Version was: " + m_Version); } m_FrameCount = Reader.ReadUInt32(); if (m_Version == 1000) { m_PaletteID = Reader.ReadUInt32(); } bool PaletteFound = false; foreach (PaletteMap Map in PMaps) { if (Map.ID == m_PaletteID) { m_PMap = Map; PaletteFound = true; } } //This is guesswork, but when the PaletteID is 1, it seems to typically indicate //that there's only one palette to choose from... if (m_PaletteID == 1) { m_PMap = PMaps[0]; PaletteFound = true; } if (!PaletteFound) { throw new Exception("No palette found!"); } for (int i = 0; i < m_FrameCount; i++) { SpriteFrame Frame = new SpriteFrame(); Reader.BaseStream.Position = INDEX_SPROFFSETTABLE + 4 * i; Reader.BaseStream.Position = Reader.ReadUInt32() + INDEX_SPRVERSION; Frame.Width = Reader.ReadUInt16(); Frame.Height = Reader.ReadUInt16(); Frame.Flag = Reader.ReadUInt16(); //Zero value skipped. Reader.BaseStream.Position += 2; Frame.PaletteID = Reader.ReadUInt16(); Frame.PalMap = PMaps[0]; foreach (PaletteMap PMap in PMaps) { if (PMap.ID == m_PaletteID) { Frame.PalMap = PMap; } } Frame.TransparentPixel = m_PMap.GetColorAtIndex(Reader.ReadUInt16()); Frame.XLocation = Reader.ReadUInt16(); Frame.YLocation = Reader.ReadUInt16(); Frame.Init(); EncryptedRowHeader RowHeader = new EncryptedRowHeader(); int RowID = 0; for (int j = 0; j < Frame.Height; j++) { long InitPos = Reader.BaseStream.Position; RowHeader = GetDecryptedValues(Reader.ReadUInt16()); if (RowHeader.Code == 0) { //byte[] RowSegmentData = Reader.ReadBytes(RowHeader.Count - 2); ReadRowSegment(Reader, RowID, ref Frame); Reader.BaseStream.Position = InitPos + RowHeader.Count; RowID++; } else if (RowHeader.Code == 4) { RowID += RowHeader.Count; } else if (RowHeader.Code == 5) { break; } } m_Frames.Add(Frame); } Reader.Close(); }
public SpriteParser(byte[] ChunkData, List<PaletteMap> PMaps, int ChunkID) { m_ChunkID = ChunkID; MemoryStream MemStream = new MemoryStream(ChunkData); BinaryReader Reader = new BinaryReader(MemStream); Reader.BaseStream.Position = INDEX_SPRID; m_ID = Reader.ReadByte(); Reader.BaseStream.Position = INDEX_SPRVERSION; m_Version = Reader.ReadUInt32(); if (m_Version != 1000 && m_Version != 1001) throw new Exception("Version was: " + m_Version); m_FrameCount = Reader.ReadUInt32(); if (m_Version == 1000) m_PaletteID = Reader.ReadUInt32(); bool PaletteFound = false; foreach (PaletteMap Map in PMaps) { if (Map.ID == m_PaletteID) { m_PMap = Map; PaletteFound = true; } } //This is guesswork, but when the PaletteID is 1, it seems to typically indicate //that there's only one palette to choose from... if (m_PaletteID == 1) { m_PMap = PMaps[0]; PaletteFound = true; } if (!PaletteFound) throw new Exception("No palette found!"); for (int i = 0; i < m_FrameCount; i++) { SpriteFrame Frame = new SpriteFrame(); Reader.BaseStream.Position = INDEX_SPROFFSETTABLE + 4 * i; Reader.BaseStream.Position = Reader.ReadUInt32() + INDEX_SPRVERSION; Frame.Width = Reader.ReadUInt16(); Frame.Height = Reader.ReadUInt16(); Frame.Flag = Reader.ReadUInt16(); //Zero value skipped. Reader.BaseStream.Position += 2; Frame.PaletteID = Reader.ReadUInt16(); Frame.PalMap = PMaps[0]; foreach (PaletteMap PMap in PMaps) { if (PMap.ID == m_PaletteID) Frame.PalMap = PMap; } Frame.TransparentPixel = m_PMap.GetColorAtIndex(Reader.ReadUInt16()); Frame.XLocation = Reader.ReadUInt16(); Frame.YLocation = Reader.ReadUInt16(); Frame.Init(); EncryptedRowHeader RowHeader = new EncryptedRowHeader(); int RowID = 0; for (int j = 0; j < Frame.Height; j++) { long InitPos = Reader.BaseStream.Position; RowHeader = GetDecryptedValues(Reader.ReadUInt16()); if (RowHeader.Code == 0) { //byte[] RowSegmentData = Reader.ReadBytes(RowHeader.Count - 2); ReadRowSegment(Reader, RowID, ref Frame); Reader.BaseStream.Position = InitPos + RowHeader.Count; RowID++; } else if (RowHeader.Code == 4) { RowID += RowHeader.Count; } else if (RowHeader.Code == 5) { break; } } m_Frames.Add(Frame); } Reader.Close(); }
/// <summary> /// Decrypts a spriteframe's rowheader. /// </summary> /// <param name="P">The rowheader that was read from the spriteframe's data.</param> /// <returns></returns> private EncryptedRowHeader GetDecryptedValues(ushort P) { EncryptedRowHeader RowHeader = new EncryptedRowHeader(); // 0xe000 = 1110 0000 0000 0000 : high order 3 bits // 0x1fff = 0001 1111 1111 1111 : low order 13 bits // 0xd = shift 13 bits to the right // as documented, 0xa000 is the stop value, with value 5 in the high order 3 bits -> // 0xa000 = 1010 0000 0000 0000 little endian // high order 3 bits are 101, or value 5 RowHeader.Code = ((P & 0xe000) << 0xd); RowHeader.Count = (P & 0x1fff); return RowHeader; }