Beispiel #1
0
        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");
                }
            }
        }
Beispiel #2
0
        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));
        }
Beispiel #3
0
        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));
        }
Beispiel #4
0
        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));
        }
Beispiel #5
0
        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();
        }
Beispiel #6
0
        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);
            }
              }
        }
Beispiel #7
0
        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();
        }
Beispiel #8
0
        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);
        }