public override void Serialise(Stream outStr) { BinaryWriter bout = new BinaryWriter(outStr); bout.Write((int)Label.Length); bout.Write((int)1); bout.Write(Label); foreach (Chunk child in mChildren) { if (child is TIMChunk) { TIMChunk childTim = (TIMChunk)child; bout.Write((int)childTim.DataLength); bout.Write((int)0); childTim.Serialise(outStr); } else if (child is RawDataChunk) { RawDataChunk childRaw = (RawDataChunk)child; bout.Write((int)childRaw.mData.Length); bout.Write((int)0); childRaw.Serialise(outStr); } else { throw new Exception("Expecting TIMChunk or RawDataChunk"); } } }
public override List <string> GetDifferences(Chunk xiChunk) { TIMChunk lOther = xiChunk as TIMChunk; if (BPP != lOther.BPP || ClutSize != lOther.ClutSize || PaletteOrgX != lOther.PaletteOrgX || PaletteOrgY != lOther.PaletteOrgY || ClutColors != lOther.ClutColors || ClutCount != lOther.ClutCount || !Utils.ArrayCompare(Palette, lOther.Palette) || ImageDataSize != lOther.ImageDataSize || ImageOrgX != lOther.ImageOrgX || ImageOrgY != lOther.ImageOrgY || ImageWidth != lOther.ImageWidth || ImageHeight != lOther.ImageHeight || !Utils.ArrayCompare(ImageData, lOther.ImageData) || !Utils.ArrayCompare(ZeroPadding, lOther.ZeroPadding)) { List <string> lRet = base.GetDifferences(xiChunk); lRet.Add("Changed TIM #" + mIdx.ToString()); return(lRet); } return(base.GetDifferences(xiChunk)); }
public void Deserialise(Stream inStr, ref int xbTIMIdx) { BinaryReader bin = new BinaryReader(inStr); int length = bin.ReadInt32(); int type = bin.ReadInt32(); if (type != 1) { throw new DeserialisationException(string.Format("Expecting type 1, found type {0}", type), inStr.Position - 8); } Label = bin.ReadBytes(length); // are there any children? ArrayList children = new ArrayList(); while (true) { int nextLen = bin.ReadInt32(); int nextType = bin.ReadInt32(); if (nextLen != 0 && nextType == 0) { try { TIMChunk tim = new TIMChunk(xbTIMIdx++, inStr, nextLen); children.Add(tim); } catch (TIMChunk.TIMTypeNotImplementedException e) { if (e.Offset < 0) { throw; } //store it as a BLOB instead inStr.Seek(e.Offset, SeekOrigin.Begin); byte[] data = new byte[nextLen]; inStr.Read(data, 0, data.Length); children.Add(new RawDataChunk(string.Format("[{0}] TIM of unsupported type ({1})", children.Count, e.Message), data)); } } else { inStr.Seek(-8, SeekOrigin.Current); break; } } mChildren = (Chunk[])children.ToArray(typeof(Chunk)); }
public void Deserialise(Stream inStr, ref int xbTIMIdx) { BinaryReader bin = new BinaryReader(inStr); int length = bin.ReadInt32(); int type = bin.ReadInt32(); if (type != 1) { throw new DeserialisationException(string.Format("Expecting type 1, found type {0}", type), inStr.Position - 8); } Label = bin.ReadBytes(length); // are there any children? ArrayList children = new ArrayList(); while (true) { int nextLen = bin.ReadInt32(); int nextType = bin.ReadInt32(); if (nextLen != 0 && nextType == 0) { try { TIMChunk tim = new TIMChunk(xbTIMIdx++, inStr, nextLen); children.Add(tim); } catch (TIMChunk.TIMTypeNotImplementedException e) { if (e.Offset < 0) throw; //store it as a BLOB instead inStr.Seek(e.Offset, SeekOrigin.Begin); byte[] data = new byte[nextLen]; inStr.Read(data, 0, data.Length); children.Add(new RawDataChunk(string.Format("[{0}] TIM of unsupported type ({1})", children.Count, e.Message), data)); } } else { inStr.Seek(-8, SeekOrigin.Current); break; } } mChildren = (Chunk[])children.ToArray(typeof(Chunk)); }
public override void Deserialise(Stream inStr) { if (inStr is FileStream) { mName = ((FileStream)inStr).Name; } List <Chunk> lChildren = new List <Chunk>(); MemoryStream lUnparseableBuff = new MemoryStream(); long lUnparseableBuffStart = 0; int lNextRead = inStr.ReadByte(); //what are bytes 1-8 of the two structs? byte[] lTIMStart4bpp = new byte[] { 0, 0, 0, 8, 0, 0, 0 }; byte[] lTIMStart8bpp = new byte[] { 0, 0, 0, 9, 0, 0, 0 }; byte[] lTMDStart = new byte[] { 0, 0, 0, 0, 0, 0, 0 }; byte[] lSevenBuff = new byte[7]; while (lNextRead != -1) { byte lNextByte = (byte)lNextRead; bool lByteParsed = false; // might it be a TIM? if (lNextByte == (byte)TIMChunk.TIM_MAGIC_NUMBER) { long lPos = inStr.Position; try { inStr.Read(lSevenBuff, 0, 7); if (SixOfSevenAreZero(lSevenBuff)) { inStr.Seek(-8, SeekOrigin.Current); TIMChunk lTIM = new TIMChunk(inStr, string.Format("TIM at {0}", inStr.Position)); if (lUnparseableBuff.Length != 0) { lChildren.Add(new RawDataChunk( string.Format("data at {0}", lUnparseableBuffStart), lUnparseableBuff.ToArray())); lUnparseableBuff.SetLength(0); lUnparseableBuffStart = inStr.Position; } lChildren.Add(lTIM); lByteParsed = true; } else { inStr.Seek(-7, SeekOrigin.Current); } } catch { inStr.Seek(lPos, SeekOrigin.Begin); } } else if (lNextByte == (byte)TMDChunk.TMD_MAGIC_NUMBER) // maybe a TMD? { long lPos = inStr.Position; try { inStr.Read(lSevenBuff, 0, 7); if (CompareSevenBytes(lSevenBuff, lTMDStart)) { inStr.Seek(-8, SeekOrigin.Current); TMDChunk lTMD = new TMDChunk(inStr, string.Format("TMD at {0}", inStr.Position)); if (lUnparseableBuff.Length != 0) { lChildren.Add(new RawDataChunk( string.Format("data at {0}", lUnparseableBuffStart), lUnparseableBuff.ToArray())); lUnparseableBuff.SetLength(0); lUnparseableBuffStart = inStr.Position; } lChildren.Add(lTMD); lByteParsed = true; } else { inStr.Seek(-7, SeekOrigin.Current); } } catch (Exception) { inStr.Seek(lPos, SeekOrigin.Begin); } } if (!lByteParsed) // dunno what this is { lUnparseableBuff.WriteByte(lNextByte); } lNextRead = inStr.ReadByte(); } // add any left over bytes as a child if (lUnparseableBuff.Length != 0) { lChildren.Add(new RawDataChunk("data", lUnparseableBuff.ToArray())); } // finish mChildren = lChildren.ToArray(); }
private void AddChunkToImage(TIMChunk c, Graphics g) { int lPixelsPerTwoBytes; switch (c.BPP) { case TIMChunk.TimBPP._4BPP: lPixelsPerTwoBytes = 4; break; case TIMChunk.TimBPP._8BPP: lPixelsPerTwoBytes = 2; break; case TIMChunk.TimBPP._16BPP: lPixelsPerTwoBytes = 1; break; default: throw new Exception("Can't deal with this BPP"); } RectangleF lDestRect = new RectangleF( WIDTH_SCALE * c.ImageOrgX, c.ImageOrgY, c.ImageWidth * WIDTH_SCALE / lPixelsPerTwoBytes, c.ImageHeight); RectangleF lClipRect = g.ClipBounds; if (!(lClipRect.IntersectsWith(lDestRect))) { return; } g.DrawImage(c.ToBitmap(), lDestRect); if (c.Palette != null) { if (c.ClutCount != 1) throw new Exception("Don't know what to do with multi-CLUT TIMs"); for (int palIdx=0; palIdx<c.Palette.Length; palIdx++) { Color col = Color.FromArgb(Utils.PS16bitColorToARGB(c.Palette[palIdx])); Brush br = new SolidBrush(col); Rectangle rect = new Rectangle( WIDTH_SCALE * (c.PaletteOrgX + palIdx), c.PaletteOrgY, WIDTH_SCALE, 1); g.FillRectangle(br, rect); } } }
public override void Deserialise(Stream inStr) { if (inStr is FileStream) { mName = ((FileStream)inStr).Name; } List<Chunk> lChildren = new List<Chunk>(); MemoryStream lUnparseableBuff = new MemoryStream(); long lUnparseableBuffStart = 0; int lNextRead = inStr.ReadByte(); //what are bytes 1-8 of the two structs? byte[] lTIMStart4bpp = new byte[] { 0, 0, 0, 8, 0, 0, 0 }; byte[] lTIMStart8bpp = new byte[] { 0, 0, 0, 9, 0, 0, 0 }; byte[] lTMDStart = new byte[] { 0, 0, 0, 0, 0, 0, 0 }; byte[] lSevenBuff = new byte[7]; while (lNextRead != -1) { byte lNextByte = (byte)lNextRead; bool lByteParsed = false; // might it be a TIM? if (lNextByte == (byte)TIMChunk.TIM_MAGIC_NUMBER) { long lPos = inStr.Position; try { inStr.Read(lSevenBuff, 0, 7); if (SixOfSevenAreZero(lSevenBuff)) { inStr.Seek(-8, SeekOrigin.Current); TIMChunk lTIM = new TIMChunk(inStr, string.Format("TIM at {0}", inStr.Position)); if (lUnparseableBuff.Length != 0) { lChildren.Add(new RawDataChunk( string.Format("data at {0}", lUnparseableBuffStart), lUnparseableBuff.ToArray())); lUnparseableBuff.SetLength(0); lUnparseableBuffStart = inStr.Position; } lChildren.Add(lTIM); lByteParsed = true; } else { inStr.Seek(-7, SeekOrigin.Current); } } catch { inStr.Seek(lPos, SeekOrigin.Begin); } } else if (lNextByte == (byte)TMDChunk.TMD_MAGIC_NUMBER) // maybe a TMD? { long lPos = inStr.Position; try { inStr.Read(lSevenBuff, 0, 7); if (CompareSevenBytes(lSevenBuff, lTMDStart)) { inStr.Seek(-8, SeekOrigin.Current); TMDChunk lTMD = new TMDChunk(inStr, string.Format("TMD at {0}", inStr.Position)); if (lUnparseableBuff.Length != 0) { lChildren.Add(new RawDataChunk( string.Format("data at {0}", lUnparseableBuffStart), lUnparseableBuff.ToArray())); lUnparseableBuff.SetLength(0); lUnparseableBuffStart = inStr.Position; } lChildren.Add(lTMD); lByteParsed = true; } else { inStr.Seek(-7, SeekOrigin.Current); } } catch (Exception) { inStr.Seek(lPos, SeekOrigin.Begin); } } if (!lByteParsed) // dunno what this is { lUnparseableBuff.WriteByte(lNextByte); } lNextRead = inStr.ReadByte(); } // add any left over bytes as a child if (lUnparseableBuff.Length != 0) { lChildren.Add(new RawDataChunk("data", lUnparseableBuff.ToArray())); } // finish mChildren = lChildren.ToArray(); }
private GLTK.Entity GetSurfaceEntity(Level xiLevel, eTextureMode xiTextureMode, eTexMetaDataEntries xiSelectedMetadata) { // notes: // invert the textures along the y-axis // use level co-ords, so z is down ///////////////////////////////////////////////////// // The surface Entity lSurface = new MMEdEntity(this); Font lNumberFont = null; Brush lNumberFGBrush = null, lNumberBGBrush = null; Pen lWaypointPen = null, lKeyWaypointPen = null; if (xiTextureMode == eTextureMode.NormalTexturesWithMetadata) { lNumberFont = new Font(FontFamily.GenericMonospace, 10); lNumberFGBrush = new SolidBrush(Color.Black); lNumberBGBrush = new SolidBrush(Color.White); lWaypointPen = new Pen(Color.Black, 1f); lKeyWaypointPen = new Pen(Color.Red, 2f); } for (int x = 0; x < Width; x++) { for (int y = 0; y < Height; y++) { Mesh lSquare = new OwnedMesh(this, PolygonMode.Quads); lSquare.AddFace( new Vertex(new Point(x, y, -GetTerrainHeightSafe(x, y)), 0, 0), new Vertex(new Point(x + 1, y, -GetTerrainHeightSafe(x + 1, y)), 1, 0), new Vertex(new Point(x + 1, y + 1, -GetTerrainHeightSafe(x + 1, y + 1)), 1, 1), new Vertex(new Point(x, y + 1, -GetTerrainHeightSafe(x, y + 1)), 0, 1)); switch (xiTextureMode) { case eTextureMode.WireFrame: lSquare.RenderMode = RenderMode.Wireframe; break; // normal textures, optionally with metadata drawn on case eTextureMode.NormalTextures: case eTextureMode.NormalTexturesWithMetadata: TIMChunk lTIM = xiLevel.GetTileById(TextureIds[x][y]); if (lTIM != null) { //some TIMs can't be loaded yet: they're null Bitmap lTexture = lTIM.ToBitmap(); if (xiTextureMode == eTextureMode.NormalTexturesWithMetadata && TexMetaData != null) { byte lVal = TexMetaData[x][y][(int)xiSelectedMetadata]; if (lVal != 0) { // we create a new bitmap based on the given texture // a) so that we can modify it freely // and b) to change it from indexed to full colour mode, to allow us // to draw on it (otherwise we'll get an exception) lTexture = new Bitmap(lTexture); Graphics g = Graphics.FromImage(lTexture); string lText = lVal.ToString(); SizeF size = g.MeasureString(lText, lNumberFont); float xf = lTexture.Width / 2.0f - size.Width / 2.0f; float yf = lTexture.Height / 2.0f - size.Height / 2.0f; g.FillRectangle(lNumberBGBrush, xf, yf, size.Width, size.Height); g.DrawString( lText, lNumberFont, lNumberFGBrush, xf, yf); if (xiSelectedMetadata == eTexMetaDataEntries.Waypoint) { Pen lPen = xiLevel.WaypointIsKeyWaypoint(lVal) ? lKeyWaypointPen : lWaypointPen; g.DrawRectangle( lPen, 0, 0, lTexture.Width - 1, lTexture.Height - 1); } } } lSquare.Texture = AbstractRenderer.ImageToTextureId(lTexture); } break; //draw the bumpmap textures on: case eTextureMode.BumpmapTextures: if (TexMetaData != null) { BumpImageChunk lBIC = xiLevel.GetBumpById(TexMetaData[x][y][(int)eTexMetaDataEntries.Bumpmap]); if (lBIC != null) { Bitmap lTexture = lBIC.ToBitmap(); lSquare.Texture = AbstractRenderer.ImageToTextureId(lTexture); } } break; default: throw new Exception("Unexpected case"); } //end switch lSurface.Meshes.Add(lSquare); } } lSurface.Scale(ScaleX, ScaleY, 1.0); if (RotationVector.Norm() != 0) { //the rotation is z-y-x lSurface.RotateAboutWorldOrigin(RotationVector.Z / 1024.0 * Math.PI / 2.0, Vector.ZAxis); lSurface.RotateAboutWorldOrigin(-RotationVector.Y / 1024.0 * Math.PI / 2.0, Vector.YAxis); lSurface.RotateAboutWorldOrigin(-RotationVector.X / 1024.0 * Math.PI / 2.0, Vector.XAxis); } Point lNewPos = ThreeDeeViewer.Short3CoordToPoint(OriginPosition); lSurface.Position = new Point(lNewPos.x, lNewPos.y, -lNewPos.z); return(lSurface); }