Пример #1
0
 public override void ReplaceChild(Chunk xiFrom, Chunk xiTo)
 {
     if (xiFrom == NamedImageGroups)
     {
         NamedImageGroups = (GroupingChunk)xiTo;
     }
     else if (xiFrom == OBJTFalseStart)
     {
         OBJTFalseStart = (RawDataChunk)xiTo;
     }
     else if (xiFrom == OBJT)
     {
         OBJT = (OBJTChunk)xiTo;
     }
     else if (xiFrom == Dunno)
     {
         Dunno = (RawDataChunk)xiTo;
     }
     else if (xiFrom == SHET)
     {
         SHET = (SHETChunk)xiTo;
     }
     else
     {
         throw new ArgumentException("xifrom not found!");
     }
 }
Пример #2
0
 public override void ReplaceChild(Chunk xiFrom, Chunk xiTo)
 {
     if (xiFrom is FlatChunk)
     {
         for (int i = 0; i < Flats.Length; i++)
         {
             if (xiFrom == Flats[i])
             {
                 Flats[i] = (FlatChunk)xiTo;
                 return;
             }
         }
         throw new ArgumentException("xifrom not found!");
     }
     else if (xiFrom == KeyWaypoints)
     {
         KeyWaypoints = (KeyWaypointsChunk)xiTo;
     }
     else if (xiFrom == SteeringImages)
     {
         SteeringImages = (GroupingChunk)xiTo;
     }
     else if (xiFrom == CameraPositions)
     {
         CameraPositions = (GroupingChunk)xiTo;
     }
     else if (xiFrom == BumpImages)
     {
         BumpImages = (GroupingChunk)xiTo;
     }
     else
     {
         throw new ArgumentException("xifrom not found!");
     }
 }
Пример #3
0
        public void Deserialise(Stream inStr, BinaryReader bin)
        {
            //header
            HeaderString1 = StreamUtils.ReadASCIINullTermString(inStr);
            HeaderString2 = StreamUtils.ReadASCIINullTermString(inStr);
            HeaderShort1  = bin.ReadInt16();
            HeaderShort2  = bin.ReadInt16();
            HeaderByte    = bin.ReadByte();
            int lSheetCount = bin.ReadInt16();

            Flats = new FlatChunk[lSheetCount];
            for (int i = 0; i < lSheetCount; i++)
            {
                Flats[i] = new FlatChunk(bin);
            }

            //key waypoints
            KeyWaypoints = new KeyWaypointsChunk(bin);

            //now the first set of images. I don't really know
            //what these do. They might be referred to by TexMetaData[7]
            short steeringImgCount = bin.ReadInt16();

            SteeringImageChunk[] steeringImages = new SteeringImageChunk[steeringImgCount];
            for (int i = 0; i < steeringImgCount; i++)
            {
                steeringImages[i] = new SteeringImageChunk(i, inStr);
            }
            this.SteeringImages = new GroupingChunk("SteeringImages", steeringImages);

            //now some camera positions:
            short cameraPositionCount = bin.ReadInt16();

            CameraPosChunk[] cameraPositions = new CameraPosChunk[cameraPositionCount];
            for (int i = 0; i < cameraPositionCount; i++)
            {
                cameraPositions[i] = new CameraPosChunk(i, bin);
            }
            this.CameraPositions = new GroupingChunk("CameraPositions", cameraPositions);

            //now the bump map prototypes. These are referred to by TexMetaData[6]
            short bumpImgCount = bin.ReadInt16();

            BumpImageChunk[] bumpImages = new BumpImageChunk[bumpImgCount];
            for (int i = 0; i < bumpImgCount; i++)
            {
                bumpImages[i] = new BumpImageChunk(i, inStr);
            }
            this.BumpImages = new GroupingChunk("BumpImages", bumpImages);

            //now trailing zeroes:
            int lNextByte;

            while (-1 != (lNextByte = inStr.ReadByte()))
            {
                if (lNextByte != 0)
                {
                    throw new DeserialisationException(string.Format("Expecting SHET to be followed by a block of zeroes. Found {0}", lNextByte), inStr.Position);
                }
                TrailingZeroByteCount++;
            }
        }
Пример #4
0
        public override void Deserialise(Stream inStr)
        {
            if (inStr is FileStream)
              {
            mName = ((FileStream)inStr).Name;
              }

              //BinaryReader is little-endian
              BinaryReader bin = new BinaryReader(inStr);

              //first, a header of 4 int32s:
              Header = new int[4];
              for (int i = 0; i < Header.Length; i++)
            Header[i] = bin.ReadInt32();

              //then, a block of zero bytes (int32 aligned)
              int nextInt = bin.ReadInt32();
              ZeroByteCount = 0;
              while (nextInt == 0)
              {
            ZeroByteCount += 4;
            nextInt = bin.ReadInt32();
              }

              ArrayList imageGroups = new ArrayList();

              //now, an array of image or comment structs
              int lTIMIdx = 0;
              while (nextInt != 0)
              {
            bin.BaseStream.Seek(-4, SeekOrigin.Current);
            NamedImageGroup nim = new NamedImageGroup(bin.BaseStream, ref lTIMIdx);
            imageGroups.Add(nim);
            nextInt = bin.ReadInt32();
              }

              //nextInt is len == 0.
              //There will be one more zero int32, then OBJTs
              nextInt = bin.ReadInt32();
              if (nextInt != 0)
            throw new DeserialisationException(string.Format("Expecting int32 0, found {0} at offset {1}", nextInt, inStr.Position - 4));

              //make a child to hold the EOF marker
              imageGroups.Add(new RawDataChunk("EOF marker", new byte[8]));

              //put the children so far in a grouping chunk
              NamedImageGroups = new GroupingChunk("textures and sprites", (Chunk[])imageGroups.ToArray(typeof(Chunk)));

              //Now the objects:
              //because of a bizzarre quirk here, the object chunk starts, then stops, then starts again
              long lObjtFalseStartPos = inStr.Position;

              try
              {
            OBJTChunk lFalseObjt = new OBJTChunk();
            lFalseObjt.Deserialise(inStr);
            OBJT = lFalseObjt;
              }
              catch (DeserialisationException e)
              {
            //Console.Error.WriteLine("OBJT false start found, searching for restart...");

            //look for X,0,65,0 in first bit:
            inStr.Seek(lObjtFalseStartPos, SeekOrigin.Begin);
            int lX = bin.ReadInt32();
            if (bin.ReadInt32() != 0) throw new DeserialisationException("Expecting 0", inStr.Position);
            if (bin.ReadInt32() != 65) throw new DeserialisationException("Expecting 65", inStr.Position);
            if (bin.ReadInt32() != 0) throw new DeserialisationException("Expecting 0", inStr.Position);

            if (lX == 65) throw new Exception("I haven't planned for this case!");

            int[] lMatcher = new int[] { 0, 65, 0 };

            //longest observed false starts are Pool3 (1052 bytes) and Rest4 (2032 bytes)
            while (inStr.Position - lObjtFalseStartPos < 2100)
            {
              int lNext = bin.ReadInt32();
              if (lNext == lX)
              {
            if (Utils.ArrayCompare(lMatcher, new int[] { bin.ReadInt32(), bin.ReadInt32(), bin.ReadInt32() }))
            {
              int lFalseStartLen = (int)(inStr.Position - 4 * 4 - lObjtFalseStartPos);
              inStr.Seek(lObjtFalseStartPos, SeekOrigin.Begin);
              OBJTFalseStart = new RawDataChunk("OBJT False Start", bin.ReadBytes(lFalseStartLen));
              OBJT = new OBJTChunk();
              OBJT.Deserialise(inStr);
              break;
            }
              }
            }
            if (OBJT == null)
            {
              string lFileName = inStr is FileStream ? ((FileStream)inStr).Name : "unknown";
              System.Windows.Forms.MessageBox.Show(string.Format("Warning: OBJTs not loaded on level {0}: unable to find false start resumption after: {1}", lFileName, e));
              inStr.Seek(lObjtFalseStartPos, SeekOrigin.Begin);
            }
              }

              //read the rest of the file into a "remainder"
              //byte array so we can search for the SHET
              long lStartOfObjts = inStr.Position;
              byte[] lRest = new byte[inStr.Length - lStartOfObjts];

              StreamUtils.EnsureRead(inStr, lRest);

              //use a heuristic to find the SHET.
              //
              //we need an 8bit char set (ASCII is 7bit). windows-1252 will do
              string lRestAsString = Encoding.GetEncoding("windows-1252").GetString(lRest);
              Regex lSHETStartRegex = new Regex(
              "([a-zA-Z0-9'()*+.\\-_ ]{10,13})\0([a-zA-Z0-9'()*+.\\-_ ]{10,13})\0(.{7})",
              RegexOptions.CultureInvariant | RegexOptions.Singleline);

              MatchCollection matches = lSHETStartRegex.Matches(lRestAsString);
              if (matches.Count != 1)
            throw new DeserialisationException(string.Format("Expecting exactly one match for SHET start regex. Found {0}", matches.Count));

              int SHETstart = matches[0].Index; //(relative to end of images section)

              byte[] dunno = new byte[SHETstart];
              Array.Copy(lRest, 0, dunno, 0, SHETstart);
              Dunno = new RawDataChunk("Dunno", dunno);

              //seek to the start of the SHET, and pretend we got here without cheating!
              dunno = lRest = null;
              inStr.Seek(lStartOfObjts + SHETstart, SeekOrigin.Begin);

              SHET = new SHETChunk(inStr, bin);
        }
Пример #5
0
 public override void ReplaceChild(Chunk xiFrom, Chunk xiTo)
 {
     if (xiFrom == NamedImageGroups)
       {
     NamedImageGroups = (GroupingChunk)xiTo;
       }
       else if (xiFrom == OBJTFalseStart)
       {
     OBJTFalseStart = (RawDataChunk)xiTo;
       }
       else if (xiFrom == OBJT)
       {
     OBJT = (OBJTChunk)xiTo;
       }
       else if (xiFrom == Dunno)
       {
     Dunno = (RawDataChunk)xiTo;
       }
       else if (xiFrom == SHET)
       {
     SHET = (SHETChunk)xiTo;
       }
       else
       {
       throw new ArgumentException("xifrom not found!");
       }
 }
Пример #6
0
        public override void Deserialise(Stream inStr)
        {
            if (inStr is FileStream)
            {
                mName = ((FileStream)inStr).Name;
            }

            //BinaryReader is little-endian
            BinaryReader bin = new BinaryReader(inStr);

            //first, a header of 4 int32s:
            Header = new int[4];
            for (int i = 0; i < Header.Length; i++)
            {
                Header[i] = bin.ReadInt32();
            }

            //then, a block of zero bytes (int32 aligned)
            int nextInt = bin.ReadInt32();

            ZeroByteCount = 0;
            while (nextInt == 0)
            {
                ZeroByteCount += 4;
                nextInt        = bin.ReadInt32();
            }

            ArrayList imageGroups = new ArrayList();

            //now, an array of image or comment structs
            int lTIMIdx = 0;

            while (nextInt != 0)
            {
                bin.BaseStream.Seek(-4, SeekOrigin.Current);
                NamedImageGroup nim = new NamedImageGroup(bin.BaseStream, ref lTIMIdx);
                imageGroups.Add(nim);
                nextInt = bin.ReadInt32();
            }

            //nextInt is len == 0.
            //There will be one more zero int32, then OBJTs
            nextInt = bin.ReadInt32();
            if (nextInt != 0)
            {
                throw new DeserialisationException(string.Format("Expecting int32 0, found {0} at offset {1}", nextInt, inStr.Position - 4));
            }

            //make a child to hold the EOF marker
            imageGroups.Add(new RawDataChunk("EOF marker", new byte[8]));

            //put the children so far in a grouping chunk
            NamedImageGroups = new GroupingChunk("textures and sprites", (Chunk[])imageGroups.ToArray(typeof(Chunk)));

            //Now the objects:
            //because of a bizzarre quirk here, the object chunk starts, then stops, then starts again
            long lObjtFalseStartPos = inStr.Position;

            try
            {
                OBJTChunk lFalseObjt = new OBJTChunk();
                lFalseObjt.Deserialise(inStr);
                OBJT = lFalseObjt;
            }
            catch (DeserialisationException e)
            {
                //Console.Error.WriteLine("OBJT false start found, searching for restart...");

                //look for X,0,65,0 in first bit:
                inStr.Seek(lObjtFalseStartPos, SeekOrigin.Begin);
                int lX = bin.ReadInt32();
                if (bin.ReadInt32() != 0)
                {
                    throw new DeserialisationException("Expecting 0", inStr.Position);
                }
                if (bin.ReadInt32() != 65)
                {
                    throw new DeserialisationException("Expecting 65", inStr.Position);
                }
                if (bin.ReadInt32() != 0)
                {
                    throw new DeserialisationException("Expecting 0", inStr.Position);
                }

                if (lX == 65)
                {
                    throw new Exception("I haven't planned for this case!");
                }

                int[] lMatcher = new int[] { 0, 65, 0 };

                //longest observed false starts are Pool3 (1052 bytes) and Rest4 (2032 bytes)
                while (inStr.Position - lObjtFalseStartPos < 2100)
                {
                    int lNext = bin.ReadInt32();
                    if (lNext == lX)
                    {
                        if (Utils.ArrayCompare(lMatcher, new int[] { bin.ReadInt32(), bin.ReadInt32(), bin.ReadInt32() }))
                        {
                            int lFalseStartLen = (int)(inStr.Position - 4 * 4 - lObjtFalseStartPos);
                            inStr.Seek(lObjtFalseStartPos, SeekOrigin.Begin);
                            OBJTFalseStart = new RawDataChunk("OBJT False Start", bin.ReadBytes(lFalseStartLen));
                            OBJT           = new OBJTChunk();
                            OBJT.Deserialise(inStr);
                            break;
                        }
                    }
                }
                if (OBJT == null)
                {
                    string lFileName = inStr is FileStream ? ((FileStream)inStr).Name : "unknown";
                    System.Windows.Forms.MessageBox.Show(string.Format("Warning: OBJTs not loaded on level {0}: unable to find false start resumption after: {1}", lFileName, e));
                    inStr.Seek(lObjtFalseStartPos, SeekOrigin.Begin);
                }
            }

            //read the rest of the file into a "remainder"
            //byte array so we can search for the SHET
            long lStartOfObjts = inStr.Position;

            byte[] lRest = new byte[inStr.Length - lStartOfObjts];

            StreamUtils.EnsureRead(inStr, lRest);

            //use a heuristic to find the SHET.
            //
            //we need an 8bit char set (ASCII is 7bit). windows-1252 will do
            string lRestAsString   = Encoding.GetEncoding("windows-1252").GetString(lRest);
            Regex  lSHETStartRegex = new Regex(
                "([a-zA-Z0-9'()*+.\\-_ ]{10,13})\0([a-zA-Z0-9'()*+.\\-_ ]{10,13})\0(.{7})",
                RegexOptions.CultureInvariant | RegexOptions.Singleline);

            MatchCollection matches = lSHETStartRegex.Matches(lRestAsString);

            if (matches.Count != 1)
            {
                throw new DeserialisationException(string.Format("Expecting exactly one match for SHET start regex. Found {0}", matches.Count));
            }

            int SHETstart = matches[0].Index; //(relative to end of images section)

            byte[] dunno = new byte[SHETstart];
            Array.Copy(lRest, 0, dunno, 0, SHETstart);
            Dunno = new RawDataChunk("Dunno", dunno);

            //seek to the start of the SHET, and pretend we got here without cheating!
            dunno = lRest = null;
            inStr.Seek(lStartOfObjts + SHETstart, SeekOrigin.Begin);

            SHET = new SHETChunk(inStr, bin);
        }
Пример #7
0
 public override void ReplaceChild(Chunk xiFrom, Chunk xiTo)
 {
     if (xiFrom is FlatChunk)
       {
     for (int i = 0; i < Flats.Length; i++)
       if (xiFrom == Flats[i])
       {
     Flats[i] = (FlatChunk)xiTo;
     return;
       }
     throw new ArgumentException("xifrom not found!");
       }
       else if (xiFrom == KeyWaypoints)
       {
     KeyWaypoints = (KeyWaypointsChunk)xiTo;
       }
       else if (xiFrom == SteeringImages)
       {
     SteeringImages = (GroupingChunk)xiTo;
       }
       else if (xiFrom == CameraPositions)
       {
     CameraPositions = (GroupingChunk)xiTo;
       }
       else if (xiFrom == BumpImages)
       {
     BumpImages = (GroupingChunk)xiTo;
       }
       else
       {
     throw new ArgumentException("xifrom not found!");
       }
 }
Пример #8
0
        public void Deserialise(Stream inStr, BinaryReader bin)
        {
            //header
              HeaderString1 = StreamUtils.ReadASCIINullTermString(inStr);
              HeaderString2 = StreamUtils.ReadASCIINullTermString(inStr);
              HeaderShort1 = bin.ReadInt16();
              HeaderShort2 = bin.ReadInt16();
              HeaderByte = bin.ReadByte();
              int lSheetCount = bin.ReadInt16();

              Flats = new FlatChunk[lSheetCount];
              for (int i = 0; i < lSheetCount; i++)
              {
            Flats[i] = new FlatChunk(bin);
              }

              //key waypoints
              KeyWaypoints = new KeyWaypointsChunk(bin);

              //now the first set of images. I don't really know
              //what these do. They might be referred to by TexMetaData[7]
              short steeringImgCount = bin.ReadInt16();
              SteeringImageChunk[] steeringImages = new SteeringImageChunk[steeringImgCount];
              for (int i = 0; i < steeringImgCount; i++)
              {
            steeringImages[i] = new SteeringImageChunk(i, inStr);
              }
              this.SteeringImages = new GroupingChunk("SteeringImages", steeringImages);

              //now some camera positions:
              short cameraPositionCount = bin.ReadInt16();
              CameraPosChunk[] cameraPositions = new CameraPosChunk[cameraPositionCount];
              for (int i = 0; i < cameraPositionCount; i++)
              {
            cameraPositions[i] = new CameraPosChunk(i, bin);
              }
              this.CameraPositions = new GroupingChunk("CameraPositions", cameraPositions);

              //now the bump map prototypes. These are referred to by TexMetaData[6]
              short bumpImgCount = bin.ReadInt16();
              BumpImageChunk[] bumpImages = new BumpImageChunk[bumpImgCount];
              for (int i = 0; i < bumpImgCount; i++)
              {
            bumpImages[i] = new BumpImageChunk(i, inStr);
              }
              this.BumpImages = new GroupingChunk("BumpImages", bumpImages);

              //now trailing zeroes:
              int lNextByte;
              while (-1 != (lNextByte = inStr.ReadByte()))
              {
            if (lNextByte != 0) throw new DeserialisationException(string.Format("Expecting SHET to be followed by a block of zeroes. Found {0}", lNextByte), inStr.Position);
            TrailingZeroByteCount++;
              }
        }