public void Parse(Stream s)
        {
            BinaryReader br       = new BinaryReader(s);
            long         startPos = s.Position;

            formatToken = br.ReadChars(8);
            version     = br.ReadUInt32();
            flags       = br.ReadUInt32();
            tickLength  = br.ReadSingle();
            numTicks    = br.ReadUInt16();
            padding     = br.ReadUInt16();
            uint channelCount          = br.ReadUInt32();
            uint f1PaletteSize         = br.ReadUInt32();
            uint channelDataOffset     = br.ReadUInt32();
            uint f1PaletteDataOffset   = br.ReadUInt32();
            uint nameOffset            = br.ReadUInt32();
            uint sourceAssetNameOffset = br.ReadUInt32();
            long currPos = s.Position;

            s.Position           = startPos + nameOffset;
            this.clipName        = br.ReadZString();
            s.Position           = startPos + sourceAssetNameOffset;
            this.sourceAssetName = br.ReadZString();
            s.Position           = startPos + f1PaletteDataOffset;
            this.f1Palette       = new F1PaletteList(handler, s, f1PaletteSize);
            s.Position           = startPos + channelDataOffset;
            this.channels        = new S3ChannelList(handler, s, channelCount, startPos);
            s.Position           = startPos;
        }
        public void UnParse(Stream s)
        {
            BinaryWriter bw       = new BinaryWriter(s);
            long         startPos = s.Position;

            bw.Write(formatToken);
            bw.Write(version);
            bw.Write(flags);
            bw.Write(tickLength);
            bw.Write(numTicks);
            bw.Write(padding);
            if (this.channels == null)
            {
                this.channels = new S3ChannelList(handler);
            }
            if (this.f1Palette == null)
            {
                this.f1Palette = new F1PaletteList(handler);
            }
            bw.Write((uint)channels.Count);
            bw.Write((uint)f1Palette.Count);
            long offsetsPos = s.Position;

            bw.Write(0U);           //channel data offset
            bw.Write(0U);           //pallette data offset
            bw.Write(0U);           //name offset
            bw.Write(0U);           //source asset name offset

            long channelPos = s.Position;

            for (int i = 0; i < this.channels.Count; i++)
            {
                this.channels[i].UnParse(s);
            }

            long namePos = s.Position;

            if (this.clipName == null)
            {
                this.clipName = "";
            }
            bw.WriteZString(clipName);

            long sourcePos = s.Position;

            if (this.sourceAssetName == null)
            {
                this.sourceAssetName = "";
            }
            bw.WriteZString(sourceAssetName);

            long palettePos = s.Position;

            f1Palette.UnParse(s);

            long channelsPos = channelPos;

            for (int i = 0; i < this.channels.Count; i++)
            {
                long dataPos = s.Position;
                s.Position = channelsPos;
                this.channels[i].UpdateOffset(s, startPos, dataPos);
                channelsPos = s.Position;
                s.Position  = dataPos;
                this.channels[i].UnParseFrames(s);
            }
            long currPos = s.Position;

            s.Position = offsetsPos;
            bw.Write((uint)(channelPos - startPos));   //channelDataOffset
            bw.Write((uint)(palettePos - startPos));   //f1PaletteDataOffset
            bw.Write((uint)(namePos - startPos));      //nameOffset
            bw.Write((uint)(sourcePos - startPos));    //sourceAssetNameOffset

            s.Position = currPos;
        }
 public S3CLIP(int apiVersion, EventHandler handler) : base(apiVersion, handler)
 {
     this.formatToken = new char[8];
     this.f1Palette   = new F1PaletteList(handler);
     this.channels    = new S3ChannelList(handler);
 }