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!"); } }
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!"); } }
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++; } }
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); }
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); }
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!"); } }
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++; } }