public PaletteMap(IffChunk Chunk)
            : base(Chunk)
        {
            MemoryStream MemStream = new MemoryStream(Chunk.Data);
            BinaryReader Reader = new BinaryReader(MemStream);

            //Reader.BaseStream.Position = INDEX_PALTID;
            /*m_ID = (uint)numPalettes++;
            m_ID = Reader.ReadUInt32();*/

            //m_Colors = new int[256];
            m_Colors = new Color[256];

            Reader.BaseStream.Position = 16;
            /*if (Reader.BaseStream.ReadByte() == 0)
                Reader.BaseStream.Position = 80;
            else
                Reader.BaseStream.Position = 16;*/

            for (int i = 0; i < 256; i++)
            {
                //Reader.BaseStream.Position += 3;
                byte[] colors = new byte[] {};
                if ((Reader.BaseStream.Length - Reader.BaseStream.Position) >= 3)
                    m_Colors[i] = Color.FromArgb(Reader.ReadByte(), Reader.ReadByte(), Reader.ReadByte());
                else
                    m_Colors[i] = Color.FromArgb(255, 0x80, 0x80, 0x80);
            }

            Reader.Close();
        }
Exemple #2
0
        public OBJf(IffChunk Chunk)
            : base(Chunk)
        {
            MemoryStream MemStream = new MemoryStream(Chunk.Data);
            BinaryReader Reader = new BinaryReader(MemStream);

            //Unknown + version (always 0)
            Reader.ReadBytes(8);

            string Header = Encoding.ASCII.GetString(Reader.ReadBytes(4));

            if (Header != "fJBO")
                return; //Error? This shouldn't occur...

            m_NumEntries = Reader.ReadInt32();

            for (int i = 0; i < m_NumEntries; i++)
            {
                IDPair FuncIDs = new IDPair();
                FuncIDs.GuardFuncID = Reader.ReadUInt16();
                FuncIDs.FunctionID = Reader.ReadUInt16();

                m_FuncIDs.Add(FuncIDs);
            }
        }
Exemple #3
0
        /// <summary>
        /// Creates a FBMP instance.
        /// </summary>
        /// <param name="Chunk">The data to create this FBMP instance from.</param>
        public FBMP(IffChunk Chunk)
            : base(Chunk)
        {
            MemoryStream MemStream = new MemoryStream(Chunk.Data);

            m_BitmapData = new Bitmap(MemStream);
        }
Exemple #4
0
        /// <summary>
        /// Creates a new OBJf instance.
        /// </summary>
        /// <param name="Chunk">The data for the chunk.</param>
        public OBJf(IffChunk Chunk) : base(Chunk)
        {
            MemoryStream MemStream = new MemoryStream(Chunk.Data);
            BinaryReader Reader    = new BinaryReader(MemStream);

            //Unknown + version (always 0)
            Reader.ReadBytes(8);

            string Header = Encoding.ASCII.GetString(Reader.ReadBytes(4));

            if (Header != "fJBO")
            {
                return; //Error? This shouldn't occur...
            }
            m_NumEntries = Reader.ReadInt32();

            for (int i = 0; i < m_NumEntries; i++)
            {
                IDPair FuncIDs = new IDPair();
                FuncIDs.GuardFuncID = Reader.ReadUInt16();
                FuncIDs.FunctionID  = Reader.ReadUInt16();

                m_FuncIDs.Add(FuncIDs);
            }
        }
 /// <summary>
 /// Constructs an instance of IffChunk based on an instance of IffChunk.
 /// Used by classes inheriting from this class.
 /// </summary>
 /// <param name="Chunk">The IffChunk instance to construct from.</param>
 public IffChunk(IffChunk Chunk)
 {
     m_ID = Chunk.ID;
     m_Length = Chunk.Length;
     m_NameStr = Chunk.NameString;
     m_Resource = Chunk.Resource;
     m_PadByte = Chunk.PadByte;
 }
Exemple #6
0
 /// <summary>
 /// Constructs an instance of IffChunk based on an instance of IffChunk.
 /// Used by classes inheriting from this class.
 /// </summary>
 /// <param name="Chunk">The IffChunk instance to construct from.</param>
 public IffChunk(IffChunk Chunk)
 {
     m_ID       = Chunk.ID;
     m_Length   = Chunk.Length;
     m_NameStr  = Chunk.NameString;
     m_Resource = Chunk.Resource;
     m_PadByte  = Chunk.PadByte;
 }
        /// <summary>
        /// Creates a new BCON instance.
        /// </summary>
        /// <param name="Chunk">The chunk to create the BCON instance from.</param>
        public BCON(IffChunk Chunk) : base(Chunk)
        {
            MemoryStream MemStream = new MemoryStream(Chunk.Data);
            BinaryReader Reader    = new BinaryReader(MemStream);

            m_NumConstants = Reader.ReadByte();
            m_Type         = Reader.ReadByte();

            for (byte i = 0; i < m_NumConstants; i++)
            {
                short Const = Reader.ReadInt16();
                m_Constants.Add(Const);
            }
        }
Exemple #8
0
        /// <summary>
        /// Creates a new BCON instance.
        /// </summary>
        /// <param name="Chunk">The chunk to create the BCON instance from.</param>
        public BCON(IffChunk Chunk) : base(Chunk)
        {
            MemoryStream MemStream = new MemoryStream(Chunk.Data);
            BinaryReader Reader = new BinaryReader(MemStream);

            m_NumConstants = Reader.ReadByte();
            m_Type = Reader.ReadByte();

            for (byte i = 0; i < m_NumConstants; i++)
            {
                short Const = Reader.ReadInt16();
                m_Constants.Add(Const);
            }
        }
Exemple #9
0
        /// <summary>
        /// Creates a new FCNS instance.
        /// </summary>
        /// <param name="Chunk">The chunk to create this FCNS instance from.</param>
        public FCNS(IffChunk Chunk)
            : base(Chunk)
        {
            MemoryStream MemStream = new MemoryStream(Chunk.Data);
            BinaryReader Reader = new BinaryReader(MemStream);

            Reader.ReadBytes(4); //0
            m_Version = Reader.ReadInt32();
            Reader.ReadBytes(4); //"SNCF"
            m_ConstantCount = Reader.ReadUInt32();

            for(int i = 0; i < m_ConstantCount; i++)
            {
                TuningConstant TConstant = new TuningConstant();

                if (m_Version == 1)
                {
                    TConstant.Name = ReadZeroPaddedString(Reader);

                    byte[] Value = Reader.ReadBytes(4);

                    //This should totally not be neccessary, but once again
                    //Maxis has introduced the concept of 'half-empty-entries'!
                    if (Value.Length == 0)
                    {
                        m_TuningConstants.Add(TConstant);
                        break;
                    }

                    TConstant.Value = BitConverter.ToSingle(Value, 0);
                    TConstant.Description = ReadZeroPaddedString(Reader);
                }
                else if (m_Version == 2)
                {
                    TConstant.Name = Reader.ReadString();
                    TConstant.Value = Reader.ReadSingle();
                    TConstant.Description = Reader.ReadString();
                }

                m_TuningConstants.Add(TConstant);
            }
        }
Exemple #10
0
        /// <summary>
        /// Creates a new FCNS instance.
        /// </summary>
        /// <param name="Chunk">The chunk to create this FCNS instance from.</param>
        public FCNS(IffChunk Chunk)
            : base(Chunk)
        {
            MemoryStream MemStream = new MemoryStream(Chunk.Data);
            BinaryReader Reader    = new BinaryReader(MemStream);

            Reader.ReadBytes(4); //0
            m_Version = Reader.ReadInt32();
            Reader.ReadBytes(4); //"SNCF"
            m_ConstantCount = Reader.ReadUInt32();

            for (int i = 0; i < m_ConstantCount; i++)
            {
                TuningConstant TConstant = new TuningConstant();

                if (m_Version == 1)
                {
                    TConstant.Name = ReadZeroPaddedString(Reader);

                    byte[] Value = Reader.ReadBytes(4);

                    //This should totally not be neccessary, but once again
                    //Maxis has introduced the concept of 'half-empty-entries'!
                    if (Value.Length == 0)
                    {
                        m_TuningConstants.Add(TConstant);
                        break;
                    }

                    TConstant.Value       = BitConverter.ToSingle(Value, 0);
                    TConstant.Description = ReadZeroPaddedString(Reader);
                }
                else if (m_Version == 2)
                {
                    TConstant.Name        = Reader.ReadString();
                    TConstant.Value       = Reader.ReadSingle();
                    TConstant.Description = Reader.ReadString();
                }

                m_TuningConstants.Add(TConstant);
            }
        }
        /// <summary>
        /// Creates a new palettemap instance.
        /// </summary>
        /// <param name="Chunk">The data for the chunk.</param>
        public PaletteMap(IffChunk Chunk) : base(Chunk)
        {
            MemoryStream MemStream = new MemoryStream(Chunk.Data);
            BinaryReader Reader = new BinaryReader(MemStream);
            
            m_Colors = new Color[256];

            Reader.BaseStream.Position = 16;

            for (int i = 0; i < 256; i++)
            {
                byte[] colors = new byte[] {};
                if ((Reader.BaseStream.Length - Reader.BaseStream.Position) >= 3)
                    m_Colors[i] = Color.FromArgb(Reader.ReadByte(), Reader.ReadByte(), Reader.ReadByte());
                else
                    m_Colors[i] = Color.FromArgb(255, 0x80, 0x80, 0x80);
            }

            Reader.Close();
        }
Exemple #12
0
        /// <summary>
        /// Creates a chunk from a ResourceID and an offset in the IFF file.
        /// </summary>
        /// <param name="Resource">The ResourceID for the chunk.</param>
        /// <param name="offset">The offset for the chunk in the IFF file.</param>
        /// <returns>A new IffChunk instance.</returns>
        private IffChunk ToChunk(string Resource, int offset)
        {
            IffChunk Chunk = new IffChunk(Resource);

            Chunk.Length = Endian.SwapUInt32(m_Reader.ReadUInt32()) - 76;
            Chunk.ID     = Endian.SwapUInt16(m_Reader.ReadUInt16());

            ushort Flags = Endian.SwapUInt16(m_Reader.ReadUInt16());

            Chunk.NameString = GetNameString();

            if ((m_Reader.BaseStream.Length - m_Reader.BaseStream.Position) >= Chunk.Length)
            {
                m_Reader.BaseStream.Position = offset + 76;
                Chunk.Data = m_Reader.ReadBytes((int)Chunk.Length);
            }
            else
            {
                Chunk.Data = new byte[Chunk.Length];
            }

            return(Chunk);
        }
Exemple #13
0
        /// <summary>
        /// Creates a new palettemap instance.
        /// </summary>
        /// <param name="Chunk">The data for the chunk.</param>
        public PaletteMap(IffChunk Chunk) : base(Chunk)
        {
            MemoryStream MemStream = new MemoryStream(Chunk.Data);
            BinaryReader Reader    = new BinaryReader(MemStream);

            m_Colors = new Color[256];

            Reader.BaseStream.Position = 16;

            for (int i = 0; i < 256; i++)
            {
                byte[] colors = new byte[] {};
                if ((Reader.BaseStream.Length - Reader.BaseStream.Position) >= 3)
                {
                    m_Colors[i] = Color.FromArgb(Reader.ReadByte(), Reader.ReadByte(), Reader.ReadByte());
                }
                else
                {
                    m_Colors[i] = Color.FromArgb(255, 0x80, 0x80, 0x80);
                }
            }

            Reader.Close();
        }
Exemple #14
0
        /// <summary>
        /// Creates a new drawgroup instance.
        /// </summary>
        /// <param name="ChunkData">The data for the chunk.</param>
        /// <param name="Sprites">The sprites that the DGRP consists of.</param>
        public DrawGroup(IffChunk Chunk, List <SPR2Parser> Sprites) : base(Chunk)
        {
            MemoryStream MemStream = new MemoryStream(Chunk.Data);
            BinaryReader Reader    = new BinaryReader(MemStream);

            m_ID      = ID;
            m_Sprites = Sprites;

            m_Version = Reader.ReadUInt16() - 20000;

            uint Count = (m_Version < 3) ? Reader.ReadUInt16() : Reader.ReadUInt32();
            uint SpriteCount, DirectionFlag, Zoom;

            for (int i = 0; i < Count; i++)
            {
                if (m_Version < 3)
                {
                    SpriteCount   = Reader.ReadUInt16();
                    DirectionFlag = Reader.ReadByte();
                    Zoom          = Reader.ReadByte();
                }
                else
                {
                    DirectionFlag = Reader.ReadUInt32();
                    Zoom          = Reader.ReadUInt32();
                    SpriteCount   = Reader.ReadUInt32();
                }
                DrawGroupImg Image = new DrawGroupImg(SpriteCount, DirectionFlag, Zoom);

                for (int j = 0; j < SpriteCount; j++)
                {
                    ushort Tag = 0;
                    int    PixelX = 0, PixelY = 0;
                    uint   SprID = 0, SprFrameID = 0, Flags = 0;
                    float  ZOffset = 0, XOffset = 0, YOffset = 0;

                    if (m_Version < 3)
                    {
                        Tag        = Reader.ReadUInt16();
                        SprID      = Reader.ReadUInt16();
                        SprFrameID = Reader.ReadUInt16();
                        Flags      = Reader.ReadUInt16();
                        PixelX     = Reader.ReadInt16();
                        PixelY     = Reader.ReadInt16();

                        if (m_Version == 1)
                        {
                            ZOffset = Reader.ReadUInt32();
                        }
                    }
                    else
                    {
                        SprID      = Reader.ReadUInt32();
                        SprFrameID = Reader.ReadUInt32();
                        PixelX     = Reader.ReadInt32();
                        PixelY     = Reader.ReadInt32();
                        ZOffset    = Reader.ReadUInt32();
                        Flags      = Reader.ReadUInt32();
                        if (m_Version == 4)
                        {
                            XOffset = Reader.ReadUInt32();
                            YOffset = Reader.ReadUInt32();
                        }
                    }

                    SpriteFrame Frame = FindSpriteFrame(SprID, SprFrameID);
                    if (Frame != null)
                    {
                        DrawGroupSprite Sprite = new DrawGroupSprite(Tag, Flags, new PixelOffset(PixelX, PixelY),
                                                                     new WorldOffset(XOffset, YOffset, ZOffset), Frame);
                        Image.Sprites.Insert(0, Sprite);
                    }
                }

                m_Images.Add(Image);
            }
        }
Exemple #15
0
        public TTAB(IffChunk Chunk)
            : base(Chunk)
        {
            MemoryStream MemStream = new MemoryStream(Chunk.Data);
            BinaryReader Reader = new BinaryReader(MemStream);

            m_InteractionCount = Reader.ReadUInt16();

            if (m_InteractionCount > 0)
            {
                m_Version = Reader.ReadUInt16();

                try
                {
                    long FieldValue = 0;

                    if (m_Version == 9 || m_Version == 10)
                    {
                        m_CompressionCode = Reader.ReadByte();

                        m_FEncodingData.CompressionCode = m_CompressionCode;
                        m_FEncodingData.FieldWidths = new byte[] { 5, 8, 13, 16, 6, 11, 21, 32 };
                        m_FEncodingData.EncodedDataLength = (uint)(Reader.BaseStream.Length - Reader.BaseStream.Position);
                        m_FEncodingData.EncodedData = Reader.ReadBytes((int)m_FEncodingData.EncodedDataLength);
                    }

                    for (ushort i = 0; i < m_InteractionCount; i++)
                    {
                        if (m_Version == 9 || m_Version == 10)
                        {
                            Interaction Action = new Interaction();
                            m_FReader.DecodeField(ref m_FEncodingData, 0, ref FieldValue);
                            Action.ActionFuncID = (short)FieldValue;

                            m_FReader.DecodeField(ref m_FEncodingData, 0, ref FieldValue);
                            Action.GuardFuncID = (short)FieldValue;

                            m_FReader.DecodeField(ref m_FEncodingData, 1, ref FieldValue);
                            Action.MotiveEntryCount = (uint)FieldValue;

                            m_FReader.DecodeField(ref m_FEncodingData, 1, ref FieldValue);
                            Action.Flags = (uint)FieldValue;

                            m_FReader.DecodeField(ref m_FEncodingData, 1, ref FieldValue);
                            Action.TTAID = (uint)FieldValue;

                            m_FReader.DecodeField(ref m_FEncodingData, 1, ref FieldValue);
                            Action.AttenuationCode = (uint)FieldValue;

                            m_FReader.DecodeField(ref m_FEncodingData, 1, ref FieldValue);
                            Action.AttenuationValue = (float)FieldValue;

                            m_FReader.DecodeField(ref m_FEncodingData, 1, ref FieldValue);
                            Action.AutonomyThreshold = (uint)FieldValue;

                            m_FReader.DecodeField(ref m_FEncodingData, 1, ref FieldValue);
                            Action.JoiningIndex = (int)FieldValue;

                            for (uint j = 0; j < Action.MotiveEntryCount; j++)
                            {
                                Motive MotiveEntry = new Motive();

                                m_FReader.DecodeField(ref m_FEncodingData, 0, ref FieldValue);
                                MotiveEntry.EffectRangeMinimum = (short)FieldValue;

                                m_FReader.DecodeField(ref m_FEncodingData, 0, ref FieldValue);
                                MotiveEntry.EffectRangeMaximum = (short)FieldValue;

                                m_FReader.DecodeField(ref m_FEncodingData, 0, ref FieldValue);
                                MotiveEntry.PersonalityModifier = (ushort)FieldValue;

                                Action.Motives.Add(MotiveEntry);
                            }

                            m_Interactions.Add(Action);

                            if(m_Version == 10)
                                m_FReader.DecodeField(ref m_FEncodingData, 1, ref FieldValue); //Unknown...
                        }
                        else if (m_Version == 5 || m_Version == 7 || m_Version == 8 || m_Version == 11)
                        {
                            Interaction Action = new Interaction();
                            Action.ActionFuncID = Reader.ReadInt16();
                            Action.GuardFuncID = Reader.ReadInt16();
                            Action.MotiveEntryCount = Reader.ReadUInt32();

                            Action.Flags = Reader.ReadUInt32();
                            Action.TTAID = Reader.ReadUInt32();

                            if (m_Version >= 7)
                                Action.AttenuationCode = Reader.ReadUInt32();

                            Action.AttenuationValue = Reader.ReadUInt32();
                            Action.AutonomyThreshold = Reader.ReadUInt32();
                            Action.JoiningIndex = Reader.ReadInt32();

                            for (uint j = 0; j < Action.MotiveEntryCount; j++)
                            {
                                Motive MotiveEntry = new Motive();

                                if (m_Version >= 7)
                                    MotiveEntry.EffectRangeMinimum = Reader.ReadInt16();

                                MotiveEntry.EffectRangeMaximum = Reader.ReadInt16();

                                if(m_Version >= 7)
                                    MotiveEntry.PersonalityModifier = Reader.ReadUInt16();

                                Action.Motives.Add(MotiveEntry);
                            }

                            m_Interactions.Add(Action);

                            if (m_Version == 11)
                                Reader.ReadBytes(4); //Unknown.
                        }
                    }
                }
                catch (Exception E)
                {
                    Log.LogThis("Failed parsing a TTAB chunk!\r\n" +
                        "Version: " + m_Version + "\r\n" + "InteractionCount: " + m_InteractionCount + "\r\n" +
                        E.ToString(), eloglevel.error);
                }
            }

            Reader.Close();
        }
        public SPR2Parser(IffChunk Chunk, List<PaletteMap> PMaps)
            : base(Chunk)
        {
            m_Name = Name;

            int[] offsets;
            MemoryStream MemStream = new MemoryStream(Chunk.Data);
            BinaryReader Reader = new BinaryReader(MemStream);

            m_Version = Reader.ReadUInt32();

            //In version 1001, all frames are decompressed from the beginning, and there's no point in storing
            //the compressed data AS WELL as the decompressed frames...!
            if (m_Version == 1000)
                m_ChunkData = Chunk.Data;

            if (m_Version == 1001)
            {
                m_PaletteID = Reader.ReadUInt32();
                m_FrameCount = Reader.ReadUInt32();
            }
            else
            {
                m_FrameCount = Reader.ReadUInt32();
                m_PaletteID = Reader.ReadUInt32();
            }

            if (PMaps.Count == 1 && m_PaletteID == 1) { m_PMap = PMaps[0]; }
            else
                m_PMap = PMaps.Find(delegate(PaletteMap PMap) { if (PMap.ID == m_PaletteID) { return true; } return false; });

            //Some SPR2s blatantly specify the wrong ID because there's only one palettemap...
            if (m_PMap == null)
            {
                m_PMap = PMaps[0];
            }

            offsets = new int[m_FrameCount];

            if (m_Version == 1000)
            {
                for (int i = 0; i < m_FrameCount; i++)
                {
                    offsets[i] = Reader.ReadInt32();
                    m_FrameOffsets.Add(offsets[i]);
                }
            }

            if (m_Version == 1001)
            {
                for (int l = 0; l < m_FrameCount; l++)
                {
                    SpriteFrame Frame = new SpriteFrame();

                    Frame.Version = Reader.ReadUInt32();
                    Frame.Size = Reader.ReadUInt32();
                    Frame.Width = Reader.ReadUInt16();
                    Frame.Height = Reader.ReadUInt16();
                    Frame.Flag = Reader.ReadUInt32();
                    Frame.PaletteID = Reader.ReadUInt16();
                    Frame.TransparentPixel = m_PMap.GetColorAtIndex(Reader.ReadUInt16());
                    Frame.YLocation = Reader.ReadUInt16();
                    Frame.XLocation = Reader.ReadUInt16();

                    if ((SPR2Flags)Frame.Flag == SPR2Flags.HasAlphaChannel)
                        Frame.Init(true);
                    else
                        Frame.Init(false);

                    DecompressFrame(ref Frame, ref Reader);
                    Frame.BitmapData.Unlock(true); //The bitmapdata is locked when the frame is created.

                    m_Frames.Add(Frame);
                }
            }

            Reader.Close();
        }
        public InteractionList(IffChunk Chunk)
            : base(Chunk)
        {
            MemoryStream MemStream = new MemoryStream(Chunk.Data);
            BinaryReader Reader = new BinaryReader(MemStream);

            if ((Reader.BaseStream.Length - Reader.BaseStream.Position) == 0)
                return; //Empty (strange, but it happens).

            m_NumInteractions = Reader.ReadInt16();

            if ((Reader.BaseStream.Length - Reader.BaseStream.Position) == 0 ||
                (Reader.BaseStream.Length - Reader.BaseStream.Position) < 2)
                return; //Too short (strange, but it happens).

            m_Version = Reader.ReadInt16();

            if (m_NumInteractions <= 0)
                return;

            if (m_Version == 9 || m_Version == 10)
            {
                m_CompressionCode = Reader.ReadByte();

                if (m_CompressionCode != 1)
                    return; //Compressioncode should always be 1.
            }

            switch (m_Version)
            {
                case 2:
                    for (int i = 0; i < m_NumInteractions; i++)
                    {
                        TTABCore Interaction = new TTABCore();

                        Interaction.ActionFunction = Reader.ReadInt16();
                        Interaction.GuardFunction = Reader.ReadInt16();
                        Interaction.MotiveEntries = Reader.ReadInt16();
                        Reader.ReadInt16(); //0xA3A3 (skip)
                        Reader.ReadInt32(); //4-byte float, no idea what it is used for.

                        m_Interactions.Add(Interaction);
                    }

                    break;
                case 3:
                    for (int i = 0; i < m_NumInteractions; i++)
                    {
                        TTABCore Interaction = new TTABCore();

                        Interaction.ActionFunction = Reader.ReadInt16();
                        Interaction.GuardFunction = Reader.ReadInt16();
                        Interaction.MotiveEntries = Reader.ReadInt16();
                        Interaction.Flags = Reader.ReadInt16();
                        Reader.ReadInt32(); //4-byte float, no idea what it is used for.

                        m_Interactions.Add(Interaction);
                    }

                    break;
                case 5:
                    for (int i = 0; i < m_NumInteractions; i++)
                    {
                        TTABCore Interaction = new TTABCore();

                        Interaction.ActionFunction = Reader.ReadInt16();
                        Interaction.GuardFunction = Reader.ReadInt16();
                        Interaction.MotiveEntries = Reader.ReadInt32();
                        Interaction.Flags = Reader.ReadInt32();
                        Interaction.StrTableIndex = Reader.ReadInt32();
                        Interaction.Autonomy = Reader.ReadInt32();
                        Interaction.JoinIndex = Reader.ReadInt32();

                        m_Interactions.Add(Interaction);
                    }

                    break;
                case 7:
                    for (int i = 0; i < m_NumInteractions; i++)
                    {
                        TTABCore Interaction = new TTABCore();

                        Interaction.ActionFunction = Reader.ReadInt16();
                        Interaction.GuardFunction = Reader.ReadInt16();
                        Interaction.MotiveEntries = Reader.ReadInt32();
                        Interaction.Flags = Reader.ReadInt32();
                        Interaction.StrTableIndex = Reader.ReadInt32();
                        Interaction.AttenuationCode = Reader.ReadInt32();
                        Interaction.AttenuationValue = Reader.ReadInt32();
                        Interaction.Autonomy = Reader.ReadInt32();
                        Interaction.JoinIndex = Reader.ReadInt32();

                        m_Interactions.Add(Interaction);
                    }

                    break;
                case 8:
                    for (int i = 0; i < m_NumInteractions; i++)
                    {
                        TTABCore Interaction = new TTABCore();

                        Interaction.ActionFunction = Reader.ReadInt16();
                        Interaction.GuardFunction = Reader.ReadInt16();
                        Interaction.MotiveEntries = Reader.ReadInt32();
                        Interaction.Flags = Reader.ReadInt32();
                        Interaction.StrTableIndex = Reader.ReadInt32();
                        Interaction.AttenuationCode = Reader.ReadInt32();
                        Interaction.AttenuationValue = Reader.ReadInt32();
                        Interaction.Autonomy = Reader.ReadInt32();
                        Interaction.JoinIndex = Reader.ReadInt32();

                        m_Interactions.Add(Interaction);
                    }

                    break;
                case 9:
                    for (int i = 0; i < m_NumInteractions; i++)
                    {
                        TTABCore Interaction = new TTABCore();

                        BitArray BArray = new BitArray(Reader.ReadBytes(2));
                        Interaction.ActionFunction = (short)GetShortBits(BArray);

                        BArray = new BitArray(Reader.ReadBytes(4));
                        Interaction.GuardFunction = (short)GetShortBits(BArray);

                        BArray = new BitArray(Reader.ReadBytes(4));
                        Interaction.MotiveEntries = (int)GetLongBits(BArray);

                        BArray = new BitArray(Reader.ReadBytes(4));
                        Interaction.Flags = (int)GetLongBits(BArray);

                        BArray = new BitArray(Reader.ReadBytes(4));
                        Interaction.StrTableIndex = (int)GetLongBits(BArray);

                        BArray = new BitArray(Reader.ReadBytes(4));
                        Interaction.AttenuationCode = (int)GetLongBits(BArray);

                        BArray = new BitArray(Reader.ReadBytes(4));
                        Interaction.AttenuationValue = (int)GetLongBits(BArray);

                        BArray = new BitArray(Reader.ReadBytes(4));
                        Interaction.Autonomy = (int)GetLongBits(BArray);

                        BArray = new BitArray(Reader.ReadBytes(4));
                        Interaction.JoinIndex = (int)GetLongBits(BArray);

                        m_Interactions.Add(Interaction);
                    }

                    break;
            }

            Reader.Close();
        }
        /// <summary>
        /// Creates a new SPR instance.
        /// </summary>
        /// <param name="Chunk">The data for the chunk.</param>
        /// <param name="PMaps">The palettemaps for this SPR.</param>
        public SPRParser(IffChunk Chunk, List <PaletteMap> PaletteMaps) : base(Chunk)
        {
            MemoryStream MemStream = new MemoryStream(Chunk.Data);
            BinaryReader Reader    = new BinaryReader(MemStream);

            //The two first bytes aren't used by the version...
            ushort FirstBytes = Reader.ReadUInt16();

            if (FirstBytes == 0)
            {
                m_IsBigEndian = true;
                m_Version     = (uint)Endian.SwapUInt16(Reader.ReadUInt16());
            }
            else
            {
                m_Version = (uint)FirstBytes;
                Reader.ReadUInt16();
            }

            //In version 1001, all frames are decompressed from the beginning, and there's no point in storing
            //the compressed data AS WELL as the decompressed frames...!
            if (m_Version != 1001)
            {
                m_ChunkData = Chunk.Data;
            }

            if (m_IsBigEndian)
            {
                if (m_Version != 1001)
                {
                    m_FrameCount = Endian.SwapUInt32(Reader.ReadUInt32());
                    m_PaletteID  = Endian.SwapUInt32(Reader.ReadUInt32());

                    for (uint i = 0; i < m_FrameCount; i++)
                    {
                        m_OffsetTable.Add(Endian.SwapUInt32(Reader.ReadUInt32()));
                    }

                    //Find and set the correct palettemap...
                    if (PaletteMaps.Count == 1 && m_PaletteID == 1)
                    {
                        m_PMap = PaletteMaps[0];
                    }
                    else
                    {
                        m_PMap = PaletteMaps.Find(delegate(PaletteMap PMap) { if (PMap.ID == m_PaletteID)
                                                                              {
                                                                                  return(true);
                                                                              }
                                                                              return(false); });
                    }
                }
                else
                {
                    m_FrameCount = Endian.SwapUInt32(Reader.ReadUInt32());
                    m_PaletteID  = Endian.SwapUInt32(Reader.ReadUInt32());

                    //Find and set the correct palettemap...
                    if (PaletteMaps.Count == 1 && m_PaletteID == 1)
                    {
                        m_PMap = PaletteMaps[0];
                    }
                    else
                    {
                        m_PMap = PaletteMaps.Find(delegate(PaletteMap PMap) { if (PMap.ID == m_PaletteID)
                                                                              {
                                                                                  return(true);
                                                                              }
                                                                              return(false); });
                    }
                }
            }
            else
            {
                if (m_Version != 1001)
                {
                    m_FrameCount = Reader.ReadUInt32();
                    m_PaletteID  = Reader.ReadUInt32();

                    for (uint i = 0; i < m_FrameCount; i++)
                    {
                        m_OffsetTable.Add(Reader.ReadUInt32());
                    }

                    //Find and set the correct palettemap...
                    if (PaletteMaps.Count == 1 && m_PaletteID == 1)
                    {
                        m_PMap = PaletteMaps[0];
                    }
                    else
                    {
                        m_PMap = PaletteMaps.Find(delegate(PaletteMap PMap) { if (PMap.ID == m_PaletteID)
                                                                              {
                                                                                  return(true);
                                                                              }
                                                                              return(false); });
                    }
                }
                else
                {
                    m_FrameCount = Reader.ReadUInt32();
                    m_PaletteID  = Reader.ReadUInt32();

                    //Find and set the correct palettemap...
                    if (PaletteMaps.Count == 1 && m_PaletteID == 1)
                    {
                        m_PMap = PaletteMaps[0];
                    }
                    else
                    {
                        m_PMap = PaletteMaps.Find(delegate(PaletteMap PMap) { if (PMap.ID == m_PaletteID)
                                                                              {
                                                                                  return(true);
                                                                              }
                                                                              return(false); });
                    }
                }
            }

            if (m_Version == 1001)
            {
                //Framecount may be set to -1 and should be ignored...
                while (true)
                {
                    SpriteFrame Frame = new SpriteFrame();

                    Frame.Version = Reader.ReadUInt32();
                    Frame.Size    = Reader.ReadUInt32();

                    Reader.ReadBytes(4); //Reserved.

                    Frame.Height = Reader.ReadUInt16();
                    Frame.Width  = Reader.ReadUInt16();
                    Frame.Init(true, false); //SPR#s don't have alpha channels, but alpha is used to plot transparent pixels.

                    DecompressFrame2(ref Frame, ref Reader);
                    Frame.BitmapData.Unlock(true); //The bitmapdata is locked when the frame is created.

                    m_Frames.Add(Frame);

                    if ((Reader.BaseStream.Position == Reader.BaseStream.Length) ||
                        (Reader.BaseStream.Position - Reader.BaseStream.Length < 14))
                    {
                        break;
                    }
                }
            }

            Reader.Close();
        }
        /// <summary>
        /// Creates a new drawgroup instance.
        /// </summary>
        /// <param name="ChunkData">The data for the chunk.</param>
        /// <param name="Sprites">The sprites that the DGRP consists of.</param>
        public DrawGroup(IffChunk Chunk, List<SPR2Parser> Sprites)
            : base(Chunk)
        {
            MemoryStream MemStream = new MemoryStream(Chunk.Data);
            BinaryReader Reader = new BinaryReader(MemStream);

            m_ID = ID;
            m_Sprites = Sprites;

            m_Version = Reader.ReadUInt16() - 20000;

            uint Count = (m_Version < 3) ? Reader.ReadUInt16() : Reader.ReadUInt32();
            uint SpriteCount, DirectionFlag, Zoom;

            for (int i = 0; i < Count; i++)
            {
                if (m_Version < 3)
                {
                    SpriteCount = Reader.ReadUInt16();
                    DirectionFlag = Reader.ReadByte();
                    Zoom = Reader.ReadByte();
                }
                else
                {
                    DirectionFlag = Reader.ReadUInt32();
                    Zoom = Reader.ReadUInt32();
                    SpriteCount = Reader.ReadUInt32();
                }
                DrawGroupImg Image = new DrawGroupImg(SpriteCount, DirectionFlag, Zoom);

                for (int j = 0; j < SpriteCount; j++)
                {
                    ushort Tag = 0;
                    int PixelX = 0, PixelY = 0;
                    uint SprID = 0, SprFrameID = 0, Flags = 0;
                    float ZOffset = 0, XOffset = 0, YOffset = 0;

                    if (m_Version < 3)
                    {
                        Tag = Reader.ReadUInt16();
                        SprID = Reader.ReadUInt16();
                        SprFrameID = Reader.ReadUInt16();
                        Flags = Reader.ReadUInt16();
                        PixelX = Reader.ReadInt16();
                        PixelY = Reader.ReadInt16();

                        if (m_Version == 1)
                            ZOffset = Reader.ReadUInt32();
                    }
                    else
                    {
                        SprID = Reader.ReadUInt32();
                        SprFrameID = Reader.ReadUInt32();
                        PixelX = Reader.ReadInt32();
                        PixelY = Reader.ReadInt32();
                        ZOffset = Reader.ReadUInt32();
                        Flags = Reader.ReadUInt32();
                        if (m_Version == 4)
                        {
                            XOffset = Reader.ReadUInt32();
                            YOffset = Reader.ReadUInt32();
                        }
                    }

                    SpriteFrame Frame = FindSpriteFrame(SprID, SprFrameID);
                    if (Frame != null)
                    {
                        DrawGroupSprite Sprite = new DrawGroupSprite(Tag, Flags, new PixelOffset(PixelX, PixelY),
                            new WorldOffset(XOffset, YOffset, ZOffset), Frame);
                        Image.Sprites.Insert(0, Sprite);
                    }
                }

                m_Images.Add(Image);
            }
        }
        /// <summary>
        /// Creates a new StringTable instance.
        /// </summary>
        /// <param name="Chunk">The chunk data for this StringTable.</param>
        public StringTable(IffChunk Chunk)
            : base(Chunk)
        {
            MemoryStream MemStream = new MemoryStream(Chunk.Data);
            BinaryReader Reader = new BinaryReader(MemStream);

            //Another example of the grossness of this format; random use of big-endian numbers...
            byte[] FormatCodeBuf = Reader.ReadBytes(2);
            Array.Reverse(FormatCodeBuf);

            m_FormatCode = BitConverter.ToUInt16(FormatCodeBuf, 0);

            switch (m_FormatCode)
            {
                case 0:
                    //Some tables are empty... LITERALLY!
                    if (Reader.BaseStream.Position < Reader.BaseStream.Length)
                    {
                        m_NumEntries = Reader.ReadUInt16();

                        for (int i = 0; i < m_NumEntries; i++)
                        {
                            StringTableString Str = new StringTableString();

                            Str.Str = ReadPascalString(Reader);

                            m_Strings.Add(Str);
                        }
                    }

                    break;
                case 0xFFFF:
                    m_NumEntries = Reader.ReadUInt16();

                    for (int i = 0; i < m_NumEntries; i++)
                    {
                        StringTableString Str = new StringTableString();

                        char C;
                        StringBuilder SB = new StringBuilder();

                        while (true)
                        {
                            C = Reader.ReadChar();
                            SB.Append(C);

                            if (C == '\0')
                                break;
                        }

                        Str.Str = SB.ToString();
                        m_Strings.Add(Str);
                    }

                    break;
                case 0xFEFF:
                    m_NumEntries = Reader.ReadUInt16();

                    for (int i = 0; i < m_NumEntries; i++)
                    {
                        StringTableString Str = new StringTableString();

                        char C;
                        StringBuilder SB = new StringBuilder();

                        //String
                        while (true)
                        {
                            C = Reader.ReadChar();
                            SB.Append(C);

                            if (C == '\0')
                                break;
                        }

                        Str.Str = SB.ToString();
                        m_Strings.Add(Str);
                        SB = new StringBuilder();

                        //Comment
                        while (true)
                        {
                            C = Reader.ReadChar();
                            SB.Append(C);

                            if (C == '\0')
                                break;
                        }
                    }

                    break;
                case 0xFDFF:
                    m_NumEntries = Reader.ReadUInt16();

                    for (int i = 0; i < m_NumEntries; i++)
                    {
                        StringTableString Str = new StringTableString();
                        Str.LanguageCode = Reader.ReadByte();

                        char C;
                        StringBuilder SB = new StringBuilder();

                        while (true)
                        {
                            C = (char)Reader.ReadByte();

                            if (C == '\0')
                                break;

                            SB.Append(C);
                        }

                        Str.Str = SB.ToString();

                        C = new char();
                        SB = new StringBuilder();

                        while (true)
                        {
                            C = (char)Reader.ReadByte();

                            if (C == '\0')
                                break;

                            SB.Append(C);
                        }

                        Str.Str2 = SB.ToString();

                        m_Strings.Add(Str);
                    }

                    break;

                case 0xFCFF: //Only found in TSO-files!
                    m_NumSets = Reader.ReadByte();

                    if (m_NumSets >= 1)
                    {
                        for (int i = 0; i < m_NumSets; i++)
                        {
                            StringSet Set = new StringSet();

                            Set.NumEntries = Reader.ReadInt16();

                            for (int j = 0; j < Set.NumEntries; j++)
                            {
                                // string code, then two specially-counted strings
                                // for some reason, the language code is one below the
                                // documented values.  we adjust this here, which
                                // unfortunately makes non-translated strings strange.
                                StringTableString Str = new StringTableString();
                                Str.LanguageCode = (byte)(Reader.ReadByte() + 1);

                                Str.Str = ReadPascalString1(Reader);
                                Str.Str2 = ReadPascalString1(Reader);

                                Set.Strings.Add(Str);
                            }

                            m_StringSets.Add(Set);
                        }
                    }

                    break;
            }

            Reader.Close();
        }
Exemple #21
0
        /// <summary>
        /// Creates a new BHAV instance.
        /// </summary>
        /// <param name="Chunk">The chunk to create this instance from.</param>
        public BHAV(IffChunk Chunk) : base(Chunk)
        {
            m_ChunkID = ChunkID;

            MemoryStream MemStream = new MemoryStream(Chunk.Data);
            BinaryReader Reader    = new BinaryReader(MemStream);

            m_Instructions = new List <byte[]>();

            byte[] Header = Reader.ReadBytes(12);

            m_Signature = (ushort)((Header[1] << 8) | Header[0]);
            int Count = 0;

            switch (m_Signature)
            {
            case 0x8000:
            case 0x8001:
                m_HeaderLength = 12;

                Count    = (Header[3] << 8) | Header[4];
                m_Locals = 0;     //No locals in code; added in 8002?
                m_Params = 4;     //I can't find this in header; always 4?
                break;

            case 0x8002:
                m_HeaderLength = 12;

                Count    = (Header[3] << 8) | Header[4];
                m_Type   = Header[5];
                m_Params = Header[6];
                m_Locals = (ushort)((Header[7] << 8) | Header[8]);
                m_Flags  = (ushort)((Header[9] << 8) | Header[10]);
                //Byte 11 and 12 are set to 0 in this version, we have no use for them.
                break;

            case 0x8003:
                m_HeaderLength = 13;

                byte LastHeaderByte = Reader.ReadByte();
                Count = (((((LastHeaderByte << 8) | Header[11]) << 8) | Header[10]) << 8) | Header[9];

                m_Type   = Header[3];
                m_Params = Header[4];
                m_Locals = Header[5];
                //Byte number 6 and 7 are unknown in this version, we have no use for them.
                m_Flags = (ushort)((Header[8] << 8) | Header[9]);
                break;
            }

            m_NumInstructions = (byte)Count;

            if (Count <= 0 || Count > 253)
            {
                return;
            }

            //Read all the instructions...
            for (int i = 0; i < Count; i++)
            {
                m_Instructions.Add(Reader.ReadBytes(12));
            }
        }
Exemple #22
0
        /// <summary>
        /// Reads the chunks of the IFF-archive by looking for the RSMP.
        /// </summary>
        private void ReadChunks()
        {
            string Identifier = new string(m_Reader.ReadChars(60)).Replace("\0", "");

            if (Identifier != "IFF FILE 2.5:TYPE FOLLOWED BY SIZE JAMIE DOORNBOS & MAXIS 1")
            {
                throw new Exception("Invalid iff file!");
            }

            uint resMapOffset = Endian.SwapUInt32(m_Reader.ReadUInt32());

            Dictionary <string, List <uint> > files = new Dictionary <string, List <uint> >();

            if (resMapOffset != 0)
            {
                long pos = m_Reader.BaseStream.Position;
                m_Reader.BaseStream.Position = resMapOffset;

                m_Reader.BaseStream.Position += 76;     //Skip the header.

                m_Reader.ReadInt32();                   //Reserved
                uint version = m_Reader.ReadUInt32();
                m_Reader.ReadInt32();                   //pmsr
                m_Reader.ReadInt32();                   //Size
                uint typeCount = m_Reader.ReadUInt32(); //How many types are present in this *.iff...

                for (uint i = 0; i < typeCount; i++)
                {
                    //NOTE: For some types in some files this is empty...
                    string typeCode = new ASCIIEncoding().GetString(m_Reader.ReadBytes(4));

                    if (version == 0)
                    {
                        //Empty RSMP...
                        //numEntries + 1 entry without label = 13 bytes.
                        if ((m_Reader.BaseStream.Length - m_Reader.BaseStream.Position) < 13)
                        {
                            files.Clear();
                            FuckThisShit(ref files);
                            break;
                        }
                    }
                    else if (version == 1)
                    {
                        //Empty RSMP...
                        //numEntries + 1 entry without label = 16 bytes.
                        if ((m_Reader.BaseStream.Length - m_Reader.BaseStream.Position) < 16)
                        {
                            files.Clear();
                            FuckThisShit(ref files);
                            break;
                        }
                    }

                    //How many entries there are...
                    uint numEntries = m_Reader.ReadUInt32();

                    List <uint> offsets = new List <uint>();
                    for (uint j = 0; j < numEntries; j++)
                    {
                        if (version == 0)
                        {
                            //Empty RSMP...
                            //Minimum size for an entry without a label is 9 bytes.
                            if ((m_Reader.BaseStream.Length - m_Reader.BaseStream.Position) < ((numEntries - j) * 9))
                            {
                                files.Clear();
                                FuckThisShit(ref files);
                                break;
                            }
                        }
                        else if (version == 1)
                        {
                            //Empty RSMP...
                            //Minimum size for an entry without a label is 12 bytes.
                            if ((m_Reader.BaseStream.Length - m_Reader.BaseStream.Position) < ((numEntries - j) * 12))
                            {
                                files.Clear();
                                FuckThisShit(ref files);
                                break;
                            }
                        }

                        uint offset = m_Reader.ReadUInt32();
                        m_Reader.ReadInt16(); //ChunkID
                        if (version == 1)
                        {
                            m_Reader.ReadInt16();
                        }                     //ChunkID
                        m_Reader.ReadInt16(); //Flags
                        if (version == 1)
                        {
                            byte Length = m_Reader.ReadByte();
                            if (Length > 0)
                            {
                                m_Reader.ReadBytes(Length);
                            }
                        }
                        else
                        {
                            GetNameString();
                        }
                        offsets.Add(offset);
                    }

                    if (!files.ContainsKey(typeCode))
                    {
                        files.Add(typeCode, offsets);
                    }
                }
            }
            else //There was no offset to the resourcemap, meaning that an RSMP probably doesn't exist.
            {
                List <KeyValuePair <string, uint> > offsets = new List <KeyValuePair <string, uint> >();
                while (true)
                {
                    uint offset = (uint)m_Reader.BaseStream.Position;

                    byte[] TagBytes = m_Reader.ReadBytes(4);
                    Array.Reverse(TagBytes);
                    string tag = new ASCIIEncoding().GetString(TagBytes);

                    byte[] bytes = m_Reader.ReadBytes(4);

                    if (bytes.Length == 0)
                    {
                        break;
                    }

                    uint size = Endian.SwapUInt32(BitConverter.ToUInt32(bytes, 0));

                    m_Reader.BaseStream.Position += (size - 8);

                    if (!tag.Equals("XXXX"))
                    {
                        offsets.Add(new KeyValuePair <string, uint>(tag, offset));
                    }

                    //76 bytes is the size of a chunkheader, so don't bother reading the next one
                    //the stream has less than 76 bytes left.
                    if (m_Reader.BaseStream.Position == m_Reader.BaseStream.Length ||
                        (m_Reader.BaseStream.Length - m_Reader.BaseStream.Position) < 76)
                    {
                        break;
                    }
                }

                List <string> typesFound = new List <string>();

                foreach (KeyValuePair <string, uint> kvp in offsets)
                {
                    if (!typesFound.Exists(delegate(string s) { return(s.CompareTo(kvp.Key) == 0); }))
                    {
                        List <KeyValuePair <string, uint> > theseChunks = offsets.FindAll(delegate(KeyValuePair <string, uint> pair) { return(pair.Key.CompareTo(kvp.Key) == 0); });
                        List <uint> offsetValues = new List <uint>();
                        foreach (KeyValuePair <string, uint> kvp2 in theseChunks)
                        {
                            offsetValues.Add(kvp2.Value);
                        }

                        if (!files.ContainsKey(kvp.Key))
                        {
                            files.Add(kvp.Key, offsetValues);
                        }

                        typesFound.Add(kvp.Key);
                    }
                }
            }

            foreach (KeyValuePair <string, List <uint> > file in files)
            {
                foreach (int offset in file.Value)
                {
                    if (offset > 0)
                    {
                        m_Reader.BaseStream.Position = offset;

                        byte[] Buf         = m_Reader.ReadBytes(4);
                        string StrResource = Encoding.ASCII.GetString(Buf);

                        if (StrResource == "SPR#" || StrResource == "SPR2" || StrResource == "rsmp" || StrResource == "PALT" ||
                            StrResource == "DGRP" || StrResource == "STR#" || StrResource == "BHAV" || StrResource == "FWAV" ||
                            StrResource == "CTSS" || StrResource == "TTAB" || StrResource == "TTAs" || StrResource == "OBJf" ||
                            StrResource == "BCON" || StrResource == "TPRP" || StrResource == "TMPL" || StrResource == "TRCN" ||
                            StrResource == "Optn" || StrResource == "SLOT" || StrResource == "GLOB" || StrResource == "FBMP" ||
                            StrResource == "BMP_" || StrResource == "FCNS")
                        {
                            //MessageBox.Show(StrResource);
                            IffChunk Chunk = ToChunk(StrResource, offset);
                            //i += (int)Chunk.Length;

                            m_Chunks.Add(Chunk);
                        }
                    }
                }
            }
        }
Exemple #23
0
        private byte m_Type; //Usually 0, but may be 1, 2, 3, or 22.

        #endregion Fields

        #region Constructors

        public BHAV(IffChunk Chunk)
            : base(Chunk)
        {
            m_ChunkID = ChunkID;

            MemoryStream MemStream = new MemoryStream(Chunk.Data);
            BinaryReader Reader = new BinaryReader(MemStream);

            m_Instructions = new List<byte[]>();

            byte[] Header = Reader.ReadBytes(12);

            m_Signature = (ushort)((Header[1] << 8) | Header[0]);
            int Count = 0;

            switch (m_Signature)
            {
                case 0x8000: case 0x8001:
                    m_HeaderLength = 12;

                    Count = (Header[3] << 8) | Header[4];
                    m_Locals = 0; //No locals in code; added in 8002?
                    m_Params = 4; //I can't find this in header; always 4?
                    break;
                case 0x8002:
                    m_HeaderLength = 12;

                    Count = (Header[3] << 8) | Header[4];
                    m_Type = Header[5];
                    m_Params = Header[6];
                    m_Locals = (ushort)((Header[7] << 8) | Header[8]);
                    m_Flags = (ushort)((Header[9] << 8) | Header[10]);
                    //Byte 11 and 12 are set to 0 in this version, we have no use for them.
                    break;
                case 0x8003:
                    m_HeaderLength = 13;

                    byte LastHeaderByte = Reader.ReadByte();
                    Count = (((((LastHeaderByte << 8) | Header[11]) << 8) | Header[10]) << 8) | Header[9];

                    m_Type = Header[3];
                    m_Params = Header[4];
                    m_Locals = Header[5];
                    //Byte number 6 and 7 are unknown in this version, we have no use for them.
                    m_Flags = (ushort)((Header[8] << 8) | Header[9]);
                    break;
            }

            m_NumInstructions = (byte)Count;

            if (Count <= 0 || Count > 253)
                return;

            //Read all the instructions...
            for (int i = 0; i < Count; i++)
                m_Instructions.Add(Reader.ReadBytes(12));
        }
        /// <summary>
        /// Creates a new SPR2 instance.
        /// </summary>
        /// <param name="Chunk">The data for the chunk.</param>
        /// <param name="PMaps">The palettemaps for this SPR2.</param>
        public SPR2Parser(IffChunk Chunk, List <PaletteMap> PMaps) : base(Chunk)
        {
            m_Name = Name;

            int[]        offsets;
            MemoryStream MemStream = new MemoryStream(Chunk.Data);
            BinaryReader Reader    = new BinaryReader(MemStream);

            m_Version = Reader.ReadUInt32();

            //In version 1001, all frames are decompressed from the beginning, and there's no point in storing
            //the compressed data AS WELL as the decompressed frames...!
            if (m_Version == 1000)
            {
                m_ChunkData = Chunk.Data;
            }

            if (m_Version == 1001)
            {
                m_PaletteID  = Reader.ReadUInt32();
                m_FrameCount = Reader.ReadUInt32();
            }
            else
            {
                m_FrameCount = Reader.ReadUInt32();
                m_PaletteID  = Reader.ReadUInt32();
            }

            if (PMaps.Count == 1 && m_PaletteID == 1)
            {
                m_PMap = PMaps[0];
            }
            else
            {
                m_PMap = PMaps.Find(delegate(PaletteMap PMap) { if (PMap.ID == m_PaletteID)
                                                                {
                                                                    return(true);
                                                                }
                                                                return(false); });
            }

            //Some SPR2s blatantly specify the wrong ID because there's only one palettemap...
            if (m_PMap == null)
            {
                m_PMap = PMaps[0];
            }

            offsets = new int[m_FrameCount];

            if (m_Version == 1000)
            {
                for (int i = 0; i < m_FrameCount; i++)
                {
                    offsets[i] = Reader.ReadInt32();
                    m_FrameOffsets.Add(offsets[i]);
                }
            }

            if (m_Version == 1001)
            {
                for (int l = 0; l < m_FrameCount; l++)
                {
                    SpriteFrame Frame = new SpriteFrame();

                    Frame.Version          = Reader.ReadUInt32();
                    Frame.Size             = Reader.ReadUInt32();
                    Frame.Width            = Reader.ReadUInt16();
                    Frame.Height           = Reader.ReadUInt16();
                    Frame.Flag             = Reader.ReadUInt32();
                    Frame.PaletteID        = Reader.ReadUInt16();
                    Frame.TransparentPixel = m_PMap.GetColorAtIndex(Reader.ReadUInt16());
                    Frame.YLocation        = Reader.ReadUInt16();
                    Frame.XLocation        = Reader.ReadUInt16();

                    if ((SPR2Flags)Frame.Flag == SPR2Flags.HasAlphaChannel)
                    {
                        Frame.Init(true, true);
                    }
                    else
                    {
                        if ((SPR2Flags)Frame.Flag == SPR2Flags.HasZBufferChannel)
                        {
                            Frame.Init(false, true);
                        }
                        else
                        {
                            Frame.Init(false, false);
                        }
                    }

                    DecompressFrame2(ref Frame, ref Reader);
                    Frame.BitmapData.Unlock(true); //The bitmapdata is locked when the frame is created.

                    if (Frame.HasZBuffer)
                    {
                        Frame.ZBuffer.Unlock(true); //The bitmapdata is locked when the frame is created.
                    }
                    m_Frames.Add(Frame);
                }
            }

            Reader.Close();
        }
Exemple #25
0
        public InteractionList(IffChunk Chunk) : base(Chunk)
        {
            MemoryStream MemStream = new MemoryStream(Chunk.Data);
            BinaryReader Reader    = new BinaryReader(MemStream);

            if ((Reader.BaseStream.Length - Reader.BaseStream.Position) == 0)
            {
                return; //Empty (strange, but it happens).
            }
            m_NumInteractions = Reader.ReadInt16();

            if ((Reader.BaseStream.Length - Reader.BaseStream.Position) == 0 ||
                (Reader.BaseStream.Length - Reader.BaseStream.Position) < 2)
            {
                return; //Too short (strange, but it happens).
            }
            m_Version = Reader.ReadInt16();

            if (m_NumInteractions <= 0)
            {
                return;
            }

            if (m_Version == 9 || m_Version == 10)
            {
                m_CompressionCode = Reader.ReadByte();

                if (m_CompressionCode != 1)
                {
                    return; //Compressioncode should always be 1.
                }
            }

            switch (m_Version)
            {
            case 2:
                for (int i = 0; i < m_NumInteractions; i++)
                {
                    TTABCore Interaction = new TTABCore();

                    Interaction.ActionFunction = Reader.ReadInt16();
                    Interaction.GuardFunction  = Reader.ReadInt16();
                    Interaction.MotiveEntries  = Reader.ReadInt16();
                    Reader.ReadInt16();     //0xA3A3 (skip)
                    Reader.ReadInt32();     //4-byte float, no idea what it is used for.

                    m_Interactions.Add(Interaction);
                }

                break;

            case 3:
                for (int i = 0; i < m_NumInteractions; i++)
                {
                    TTABCore Interaction = new TTABCore();

                    Interaction.ActionFunction = Reader.ReadInt16();
                    Interaction.GuardFunction  = Reader.ReadInt16();
                    Interaction.MotiveEntries  = Reader.ReadInt16();
                    Interaction.Flags          = Reader.ReadInt16();
                    Reader.ReadInt32();     //4-byte float, no idea what it is used for.

                    m_Interactions.Add(Interaction);
                }

                break;

            case 5:
                for (int i = 0; i < m_NumInteractions; i++)
                {
                    TTABCore Interaction = new TTABCore();

                    Interaction.ActionFunction = Reader.ReadInt16();
                    Interaction.GuardFunction  = Reader.ReadInt16();
                    Interaction.MotiveEntries  = Reader.ReadInt32();
                    Interaction.Flags          = Reader.ReadInt32();
                    Interaction.StrTableIndex  = Reader.ReadInt32();
                    Interaction.Autonomy       = Reader.ReadInt32();
                    Interaction.JoinIndex      = Reader.ReadInt32();

                    m_Interactions.Add(Interaction);
                }

                break;

            case 7:
                for (int i = 0; i < m_NumInteractions; i++)
                {
                    TTABCore Interaction = new TTABCore();

                    Interaction.ActionFunction   = Reader.ReadInt16();
                    Interaction.GuardFunction    = Reader.ReadInt16();
                    Interaction.MotiveEntries    = Reader.ReadInt32();
                    Interaction.Flags            = Reader.ReadInt32();
                    Interaction.StrTableIndex    = Reader.ReadInt32();
                    Interaction.AttenuationCode  = Reader.ReadInt32();
                    Interaction.AttenuationValue = Reader.ReadInt32();
                    Interaction.Autonomy         = Reader.ReadInt32();
                    Interaction.JoinIndex        = Reader.ReadInt32();

                    m_Interactions.Add(Interaction);
                }

                break;

            case 8:
                for (int i = 0; i < m_NumInteractions; i++)
                {
                    TTABCore Interaction = new TTABCore();

                    Interaction.ActionFunction   = Reader.ReadInt16();
                    Interaction.GuardFunction    = Reader.ReadInt16();
                    Interaction.MotiveEntries    = Reader.ReadInt32();
                    Interaction.Flags            = Reader.ReadInt32();
                    Interaction.StrTableIndex    = Reader.ReadInt32();
                    Interaction.AttenuationCode  = Reader.ReadInt32();
                    Interaction.AttenuationValue = Reader.ReadInt32();
                    Interaction.Autonomy         = Reader.ReadInt32();
                    Interaction.JoinIndex        = Reader.ReadInt32();

                    m_Interactions.Add(Interaction);
                }

                break;

            case 9:
                for (int i = 0; i < m_NumInteractions; i++)
                {
                    TTABCore Interaction = new TTABCore();

                    BitArray BArray = new BitArray(Reader.ReadBytes(2));
                    Interaction.ActionFunction = (short)GetShortBits(BArray);

                    BArray = new BitArray(Reader.ReadBytes(4));
                    Interaction.GuardFunction = (short)GetShortBits(BArray);

                    BArray = new BitArray(Reader.ReadBytes(4));
                    Interaction.MotiveEntries = (int)GetLongBits(BArray);

                    BArray            = new BitArray(Reader.ReadBytes(4));
                    Interaction.Flags = (int)GetLongBits(BArray);

                    BArray = new BitArray(Reader.ReadBytes(4));
                    Interaction.StrTableIndex = (int)GetLongBits(BArray);

                    BArray = new BitArray(Reader.ReadBytes(4));
                    Interaction.AttenuationCode = (int)GetLongBits(BArray);

                    BArray = new BitArray(Reader.ReadBytes(4));
                    Interaction.AttenuationValue = (int)GetLongBits(BArray);

                    BArray = new BitArray(Reader.ReadBytes(4));
                    Interaction.Autonomy = (int)GetLongBits(BArray);

                    BArray = new BitArray(Reader.ReadBytes(4));
                    Interaction.JoinIndex = (int)GetLongBits(BArray);

                    m_Interactions.Add(Interaction);
                }

                break;
            }

            Reader.Close();
        }
Exemple #26
0
        /// <summary>
        /// Creates a chunk from a ResourceID and an offset in the IFF file.
        /// </summary>
        /// <param name="Resource">The ResourceID for the chunk.</param>
        /// <param name="offset">The offset for the chunk in the IFF file.</param>
        /// <returns>A new IffChunk instance.</returns>
        private IffChunk ToChunk(string Resource, int offset)
        {
            IffChunk Chunk = new IffChunk(Resource);

            Chunk.Length = Endian.SwapUInt32(m_Reader.ReadUInt32()) - 76;
            Chunk.ID = Endian.SwapUInt16(m_Reader.ReadUInt16());

            ushort Flags = Endian.SwapUInt16(m_Reader.ReadUInt16());
            Chunk.NameString = GetNameString();

            if ((m_Reader.BaseStream.Length - m_Reader.BaseStream.Position) >= Chunk.Length)
            {
                m_Reader.BaseStream.Position = offset + 76;
                Chunk.Data = m_Reader.ReadBytes((int)Chunk.Length);
            }
            else
                Chunk.Data = new byte[Chunk.Length];

            return Chunk;
        }
        /// <summary>
        /// Creates a new TTAB instance.
        /// </summary>
        /// <param name="Chunk">The data for the chunk.</param>
        public TTAB(IffChunk Chunk) : base(Chunk)
        {
            MemoryStream MemStream = new MemoryStream(Chunk.Data);
            BinaryReader Reader    = new BinaryReader(MemStream);

            m_InteractionCount = Reader.ReadUInt16();

            if (m_InteractionCount > 0)
            {
                m_Version = Reader.ReadUInt16();

                try
                {
                    long FieldValue = 0;

                    if (m_Version == 9 || m_Version == 10)
                    {
                        m_CompressionCode = Reader.ReadByte();

                        m_FEncodingData.CompressionCode   = m_CompressionCode;
                        m_FEncodingData.FieldWidths       = new byte[] { 5, 8, 13, 16, 6, 11, 21, 32 };
                        m_FEncodingData.EncodedDataLength = (uint)(Reader.BaseStream.Length - Reader.BaseStream.Position);
                        m_FEncodingData.EncodedData       = Reader.ReadBytes((int)m_FEncodingData.EncodedDataLength);
                    }

                    for (ushort i = 0; i < m_InteractionCount; i++)
                    {
                        if (m_Version == 9 || m_Version == 10)
                        {
                            Interaction Action = new Interaction();
                            m_FReader.DecodeField(ref m_FEncodingData, 0, ref FieldValue);
                            Action.ActionFuncID = (short)FieldValue;

                            m_FReader.DecodeField(ref m_FEncodingData, 0, ref FieldValue);
                            Action.GuardFuncID = (short)FieldValue;

                            m_FReader.DecodeField(ref m_FEncodingData, 1, ref FieldValue);
                            Action.MotiveEntryCount = (uint)FieldValue;

                            m_FReader.DecodeField(ref m_FEncodingData, 1, ref FieldValue);
                            Action.Flags = (uint)FieldValue;

                            m_FReader.DecodeField(ref m_FEncodingData, 1, ref FieldValue);
                            Action.TTAID = (uint)FieldValue;

                            m_FReader.DecodeField(ref m_FEncodingData, 1, ref FieldValue);
                            Action.AttenuationCode = (uint)FieldValue;

                            m_FReader.DecodeField(ref m_FEncodingData, 1, ref FieldValue);
                            Action.AttenuationValue = (float)FieldValue;

                            m_FReader.DecodeField(ref m_FEncodingData, 1, ref FieldValue);
                            Action.AutonomyThreshold = (uint)FieldValue;

                            m_FReader.DecodeField(ref m_FEncodingData, 1, ref FieldValue);
                            Action.JoiningIndex = (int)FieldValue;

                            for (uint j = 0; j < Action.MotiveEntryCount; j++)
                            {
                                Motive MotiveEntry = new Motive();

                                m_FReader.DecodeField(ref m_FEncodingData, 0, ref FieldValue);
                                MotiveEntry.EffectRangeMinimum = (short)FieldValue;

                                m_FReader.DecodeField(ref m_FEncodingData, 0, ref FieldValue);
                                MotiveEntry.EffectRangeMaximum = (short)FieldValue;

                                m_FReader.DecodeField(ref m_FEncodingData, 0, ref FieldValue);
                                MotiveEntry.PersonalityModifier = (ushort)FieldValue;

                                Action.Motives.Add(MotiveEntry);
                            }

                            m_Interactions.Add(Action);

                            if (m_Version == 10)
                            {
                                m_FReader.DecodeField(ref m_FEncodingData, 1, ref FieldValue); //Unknown...
                            }
                        }
                        else if (m_Version == 5 || m_Version == 7 || m_Version == 8 || m_Version == 11)
                        {
                            Interaction Action = new Interaction();
                            Action.ActionFuncID     = Reader.ReadInt16();
                            Action.GuardFuncID      = Reader.ReadInt16();
                            Action.MotiveEntryCount = Reader.ReadUInt32();

                            Action.Flags = Reader.ReadUInt32();
                            Action.TTAID = Reader.ReadUInt32();

                            if (m_Version >= 7)
                            {
                                Action.AttenuationCode = Reader.ReadUInt32();
                            }

                            Action.AttenuationValue  = Reader.ReadUInt32();
                            Action.AutonomyThreshold = Reader.ReadUInt32();
                            Action.JoiningIndex      = Reader.ReadInt32();

                            for (uint j = 0; j < Action.MotiveEntryCount; j++)
                            {
                                Motive MotiveEntry = new Motive();

                                if (m_Version >= 7)
                                {
                                    MotiveEntry.EffectRangeMinimum = Reader.ReadInt16();
                                }

                                MotiveEntry.EffectRangeMaximum = Reader.ReadInt16();

                                if (m_Version >= 7)
                                {
                                    MotiveEntry.PersonalityModifier = Reader.ReadUInt16();
                                }

                                Action.Motives.Add(MotiveEntry);
                            }

                            m_Interactions.Add(Action);

                            if (m_Version == 11)
                            {
                                Reader.ReadBytes(4); //Unknown.
                            }
                        }
                    }
                }
                catch (Exception E)
                {
                    Log.LogThis("Failed parsing a TTAB chunk!\r\n" +
                                "Version: " + m_Version + "\r\n" + "InteractionCount: " + m_InteractionCount + "\r\n" +
                                E.ToString(), eloglevel.error);
                }
            }

            Reader.Close();
        }
Exemple #28
0
        /// <summary>
        /// A PALT (palette) chunk was not found when searching through this archive's rsmp,
        /// so find it manually.
        /// </summary>
        private void FindPALT()
        {
            m_Reader.BaseStream.Position = 64;

            List <KeyValuePair <string, uint> > PALTOffsets = new List <KeyValuePair <string, uint> >();

            while (true)
            {
                uint offset = (uint)m_Reader.BaseStream.Position;

                byte[] TagBytes = m_Reader.ReadBytes(4);
                Array.Reverse(TagBytes);
                string tag = new ASCIIEncoding().GetString(TagBytes);

                byte[] bytes = m_Reader.ReadBytes(4);

                if (bytes.Length == 0)
                {
                    break;
                }

                uint size = Endian.SwapUInt32(BitConverter.ToUInt32(bytes, 0));

                m_Reader.BaseStream.Position += (size - 8);

                if (tag.Equals("PALT"))
                {
                    PALTOffsets.Add(new KeyValuePair <string, uint>(tag, offset));
                }

                //76 bytes is the size of a chunkheader, so don't bother reading the next one
                //the stream has less than 76 bytes left.
                if (m_Reader.BaseStream.Position == m_Reader.BaseStream.Length ||
                    (m_Reader.BaseStream.Length - m_Reader.BaseStream.Position) < 76)
                {
                    break;
                }
            }

            foreach (KeyValuePair <string, uint> KVP in PALTOffsets)
            {
                m_Reader.BaseStream.Position = KVP.Value;

                IffChunk Chunk = new IffChunk(KVP.Key);

                Chunk.Length = Endian.SwapUInt32(m_Reader.ReadUInt32()) - 76;
                Chunk.ID     = Endian.SwapUInt16(m_Reader.ReadUInt16());

                ushort Flags = Endian.SwapUInt16(m_Reader.ReadUInt16());
                Chunk.NameString = GetNameString();

                if ((m_Reader.BaseStream.Length - m_Reader.BaseStream.Position) >= Chunk.Length)
                {
                    m_Reader.BaseStream.Position = KVP.Value + 76;
                    Chunk.Data = m_Reader.ReadBytes((int)Chunk.Length);
                }
                else
                {
                    Chunk.Data = new byte[Chunk.Length];
                }

                m_PMaps.Add(new PaletteMap(Chunk));
            }
        }
Exemple #29
0
        /// <summary>
        /// A PALT (palette) chunk was not found when searching through this archive's rsmp,
        /// so find it manually.
        /// </summary>
        private void FindPALT()
        {
            m_Reader.BaseStream.Position = 64;

            List<KeyValuePair<string, uint>> PALTOffsets = new List<KeyValuePair<string, uint>>();
            while (true)
            {
                uint offset = (uint)m_Reader.BaseStream.Position;

                byte[] TagBytes = m_Reader.ReadBytes(4);
                Array.Reverse(TagBytes);
                string tag = new ASCIIEncoding().GetString(TagBytes);

                byte[] bytes = m_Reader.ReadBytes(4);

                if (bytes.Length == 0)
                    break;

                uint size = Endian.SwapUInt32(BitConverter.ToUInt32(bytes, 0));

                m_Reader.BaseStream.Position += (size - 8);

                if (tag.Equals("PALT"))
                    PALTOffsets.Add(new KeyValuePair<string, uint>(tag, offset));

                //76 bytes is the size of a chunkheader, so don't bother reading the next one
                //the stream has less than 76 bytes left.
                if (m_Reader.BaseStream.Position == m_Reader.BaseStream.Length ||
                    (m_Reader.BaseStream.Length - m_Reader.BaseStream.Position) < 76)
                    break;
            }

            foreach (KeyValuePair<string, uint> KVP in PALTOffsets)
            {
                m_Reader.BaseStream.Position = KVP.Value;

                IffChunk Chunk = new IffChunk(KVP.Key);

                Chunk.Length = Endian.SwapUInt32(m_Reader.ReadUInt32()) - 76;
                Chunk.ID = Endian.SwapUInt16(m_Reader.ReadUInt16());

                ushort Flags = Endian.SwapUInt16(m_Reader.ReadUInt16());
                Chunk.NameString = GetNameString();

                if ((m_Reader.BaseStream.Length - m_Reader.BaseStream.Position) >= Chunk.Length)
                {
                    m_Reader.BaseStream.Position = KVP.Value + 76;
                    Chunk.Data = m_Reader.ReadBytes((int)Chunk.Length);
                }
                else
                    Chunk.Data = new byte[Chunk.Length];

                m_PMaps.Add(new PaletteMap(Chunk));
            }
        }
        /// <summary>
        /// Creates a new StringTable instance.
        /// </summary>
        /// <param name="Chunk">The chunk data for this StringTable.</param>
        public StringTable(IffChunk Chunk) : base(Chunk)
        {
            MemoryStream MemStream = new MemoryStream(Chunk.Data);
            BinaryReader Reader    = new BinaryReader(MemStream);

            //Another example of the grossness of this format; random use of big-endian numbers...
            byte[] FormatCodeBuf = Reader.ReadBytes(2);
            Array.Reverse(FormatCodeBuf);

            m_FormatCode = BitConverter.ToUInt16(FormatCodeBuf, 0);

            switch (m_FormatCode)
            {
            case 0:
                //Some tables are empty... LITERALLY!
                if (Reader.BaseStream.Position < Reader.BaseStream.Length)
                {
                    m_NumEntries = Reader.ReadUInt16();

                    for (int i = 0; i < m_NumEntries; i++)
                    {
                        StringTableString Str = new StringTableString();

                        Str.Str = ReadPascalString(Reader);

                        m_Strings.Add(Str);
                    }
                }

                break;

            case 0xFFFF:
                m_NumEntries = Reader.ReadUInt16();

                for (int i = 0; i < m_NumEntries; i++)
                {
                    StringTableString Str = new StringTableString();

                    char          C;
                    StringBuilder SB = new StringBuilder();

                    while (true)
                    {
                        C = Reader.ReadChar();
                        SB.Append(C);

                        if (C == '\0')
                        {
                            break;
                        }
                    }

                    Str.Str = SB.ToString();
                    m_Strings.Add(Str);
                }

                break;

            case 0xFEFF:
                m_NumEntries = Reader.ReadUInt16();

                for (int i = 0; i < m_NumEntries; i++)
                {
                    StringTableString Str = new StringTableString();

                    char          C;
                    StringBuilder SB = new StringBuilder();

                    //String
                    while (true)
                    {
                        C = Reader.ReadChar();
                        SB.Append(C);

                        if (C == '\0')
                        {
                            break;
                        }
                    }

                    Str.Str = SB.ToString();
                    m_Strings.Add(Str);
                    SB = new StringBuilder();

                    //Comment
                    while (true)
                    {
                        C = Reader.ReadChar();
                        SB.Append(C);

                        if (C == '\0')
                        {
                            break;
                        }
                    }
                }

                break;

            case 0xFDFF:
                m_NumEntries = Reader.ReadUInt16();

                for (int i = 0; i < m_NumEntries; i++)
                {
                    StringTableString Str = new StringTableString();
                    Str.LanguageCode = Reader.ReadByte();

                    char          C;
                    StringBuilder SB = new StringBuilder();

                    while (true)
                    {
                        C = (char)Reader.ReadByte();

                        if (C == '\0')
                        {
                            break;
                        }

                        SB.Append(C);
                    }

                    Str.Str = SB.ToString();

                    C  = new char();
                    SB = new StringBuilder();

                    while (true)
                    {
                        C = (char)Reader.ReadByte();

                        if (C == '\0')
                        {
                            break;
                        }

                        SB.Append(C);
                    }

                    Str.Str2 = SB.ToString();


                    m_Strings.Add(Str);
                }

                break;

            case 0xFCFF:     //Only found in TSO-files!
                m_NumSets = Reader.ReadByte();

                if (m_NumSets >= 1)
                {
                    for (int i = 0; i < m_NumSets; i++)
                    {
                        StringSet Set = new StringSet();

                        Set.NumEntries = Reader.ReadInt16();

                        for (int j = 0; j < Set.NumEntries; j++)
                        {
                            // string code, then two specially-counted strings
                            // for some reason, the language code is one below the
                            // documented values.  we adjust this here, which
                            // unfortunately makes non-translated strings strange.
                            StringTableString Str = new StringTableString();
                            Str.LanguageCode = (byte)(Reader.ReadByte() + 1);

                            Str.Str  = ReadPascalString1(Reader);
                            Str.Str2 = ReadPascalString1(Reader);

                            Set.Strings.Add(Str);
                        }

                        m_StringSets.Add(Set);
                    }
                }

                break;
            }

            Reader.Close();
        }
Exemple #31
0
 /// <summary>
 /// Casts a chunk to an OBJD instance.
 /// </summary>
 /// <param name="Chunk">The chunk to cast.</param>
 private void ToOBJD(IffChunk Chunk)
 {
     OBJD Obj = new OBJD(Chunk.Data, Chunk.ID);
     m_OBJDs.Add(Obj);
 }
        /// <summary>
        /// Creates a new SPR instance.
        /// </summary>
        /// <param name="Chunk">The data for the chunk.</param>
        /// <param name="PMaps">The palettemaps for this SPR.</param>
        public SPRParser(IffChunk Chunk, List<PaletteMap> PaletteMaps)
            : base(Chunk)
        {
            MemoryStream MemStream = new MemoryStream(Chunk.Data);
            BinaryReader Reader = new BinaryReader(MemStream);

            //The two first bytes aren't used by the version...
            ushort FirstBytes = Reader.ReadUInt16();

            if (FirstBytes == 0)
            {
                m_IsBigEndian = true;
                m_Version = (uint)Endian.SwapUInt16(Reader.ReadUInt16());
            }
            else
            {
                m_Version = (uint)FirstBytes;
                Reader.ReadUInt16();
            }

            //In version 1001, all frames are decompressed from the beginning, and there's no point in storing
            //the compressed data AS WELL as the decompressed frames...!
            if (m_Version != 1001)
                m_ChunkData = Chunk.Data;

            if (m_IsBigEndian)
            {
                if (m_Version != 1001)
                {
                    m_FrameCount = Endian.SwapUInt32(Reader.ReadUInt32());
                    m_PaletteID = Endian.SwapUInt32(Reader.ReadUInt32());

                    for (uint i = 0; i < m_FrameCount; i++)
                        m_OffsetTable.Add(Endian.SwapUInt32(Reader.ReadUInt32()));

                    //Find and set the correct palettemap...
                    if (PaletteMaps.Count == 1 && m_PaletteID == 1) { m_PMap = PaletteMaps[0]; }
                    else
                        m_PMap = PaletteMaps.Find(delegate(PaletteMap PMap) { if (PMap.ID == m_PaletteID) { return true; } return false; });
                }
                else
                {
                    m_FrameCount = Endian.SwapUInt32(Reader.ReadUInt32());
                    m_PaletteID = Endian.SwapUInt32(Reader.ReadUInt32());

                    //Find and set the correct palettemap...
                    if (PaletteMaps.Count == 1 && m_PaletteID == 1) { m_PMap = PaletteMaps[0]; }
                    else
                        m_PMap = PaletteMaps.Find(delegate(PaletteMap PMap) { if (PMap.ID == m_PaletteID) { return true; } return false; });
                }
            }
            else
            {
                if (m_Version != 1001)
                {
                    m_FrameCount = Reader.ReadUInt32();
                    m_PaletteID = Reader.ReadUInt32();

                    for (uint i = 0; i < m_FrameCount; i++)
                        m_OffsetTable.Add(Reader.ReadUInt32());

                    //Find and set the correct palettemap...
                    if (PaletteMaps.Count == 1 && m_PaletteID == 1) { m_PMap = PaletteMaps[0]; }
                    else
                        m_PMap = PaletteMaps.Find(delegate(PaletteMap PMap) { if (PMap.ID == m_PaletteID) { return true; } return false; });
                }
                else
                {
                    m_FrameCount = Reader.ReadUInt32();
                    m_PaletteID = Reader.ReadUInt32();

                    //Find and set the correct palettemap...
                    if (PaletteMaps.Count == 1 && m_PaletteID == 1) { m_PMap = PaletteMaps[0]; }
                    else
                        m_PMap = PaletteMaps.Find(delegate(PaletteMap PMap) { if (PMap.ID == m_PaletteID) { return true; } return false; });
                }
            }

            if (m_Version == 1001)
            {
                //Framecount may be set to -1 and should be ignored...
                while(true)
                {
                    SpriteFrame Frame = new SpriteFrame();

                    Frame.Version = Reader.ReadUInt32();
                    Frame.Size = Reader.ReadUInt32();

                    Reader.ReadBytes(4); //Reserved.

                    Frame.Height = Reader.ReadUInt16();
                    Frame.Width = Reader.ReadUInt16();
                    Frame.Init(true, false); //SPR#s don't have alpha channels, but alpha is used to plot transparent pixels.

                    DecompressFrame2(ref Frame, ref Reader);
                    Frame.BitmapData.Unlock(true); //The bitmapdata is locked when the frame is created.

                    m_Frames.Add(Frame);

                    if ((Reader.BaseStream.Position == Reader.BaseStream.Length) ||
                        (Reader.BaseStream.Position - Reader.BaseStream.Length < 14))
                        break;
                }
            }

            Reader.Close();
        }
        /// <summary>
        /// Creates a new BMP_ file.
        /// </summary>
        /// <param name="Chunk">The chunk to create the BMP_ file from.</param>
        public BMP_(IffChunk Chunk) : base(Chunk)
        {
            MemoryStream MemStream = new MemoryStream(Chunk.Data);

            m_BitmapData = new Bitmap(MemStream);
        }
Exemple #34
0
        /// <summary>
        /// Casts a chunk to an OBJD instance.
        /// </summary>
        /// <param name="Chunk">The chunk to cast.</param>
        private void ToOBJD(IffChunk Chunk)
        {
            OBJD Obj = new OBJD(Chunk.Data, Chunk.ID);

            m_OBJDs.Add(Obj);
        }