Exemple #1
0
 public VersionList(Level xiInitialLevel, string xiCourseName, string xiCDFilename)
 {
     CurrentLevel = xiInitialLevel;
       CourseName = xiCourseName;
       CDFilename = xiCDFilename;
       AddLevel(CurrentLevel);
 }
Exemple #2
0
        ///========================================================================
        /// Method : AddLevel
        /// 
        /// <summary>
        /// 	Add a new level to the version list
        /// </summary>
        /// <param name="xiNewLevel"></param>
        ///========================================================================
        public void AddLevel(Level xiNewLevel)
        {
            Version lDiffFrom = GetLastVersion();
              bool lStoreAsDiff = (Versions.Count % 5 != 0);
              long lExpectedSize = CDFilename == null ? -1L : MMCD.Courses.Find(new Predicate<MMCD.Course>(
            delegate(MMCD.Course xiCourse) { return xiCourse.FileName == CDFilename; })).CDLength;

              Version lNewVersion = new Version(xiNewLevel, lDiffFrom, lStoreAsDiff, lExpectedSize);
              Versions.Add(lNewVersion);
              CurrentLevel = xiNewLevel;
        }
Exemple #3
0
 public FileHolder(string xiFileName, Level xiLevel)
 {
     FileName = xiFileName;
     Level = xiLevel;
 }
Exemple #4
0
        private static Files LoadAllFilesFromRootPath(DirectoryInfo xiTreeRoot)
        {
            Files lAcc = new Files();
              Regex lLevelNameRegex = new Regex("[A-Z]+\\\\[A-Z]+[0-9]\\.DAT$", RegexOptions.IgnoreCase);
              foreach (FileInfo file in xiTreeRoot.GetFiles("*.DAT", SearchOption.AllDirectories))
              {
            Level lev;

            if (lLevelNameRegex.IsMatch(file.FullName))
            {
              using (FileStream fs = file.OpenRead())
              {
            lev = new Level(fs);
            FileHolder fh = new FileHolder(file.FullName, lev);
            lAcc.FileHolders.Add(fh);
              }
            }
              }
              return lAcc;
        }
Exemple #5
0
        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            NewForm lForm = new NewForm(this);

              if (lForm.ShowDialog() == DialogResult.OK)
              {
            //=====================================================================
            // Load the file from the CD image
            //=====================================================================
            CDImage lCDImage = new CDImage(new FileInfo(lForm.CDImageTextBox.Text));
            MMCD.Course lCourse = (MMCD.Course)lForm.CourseDropDown.SelectedItem;
            byte[] lLevelBinary = lCDImage.Extract(lCourse.CDOffset, lCourse.CDLength);
            MemoryStream lLevelStream = new MemoryStream(lLevelBinary);

            Level lNewLevel = new Level(lLevelStream);

            //=====================================================================
            // Check that the whole file has been read
            //=====================================================================
            if (lLevelStream.Length != lLevelStream.Position)
            {
              throw new DeserialisationException(string.Format("Deserialisation terminated early at byte {0} of {1}", lLevelStream.Position, lLevelStream.Length));
            }

            //=====================================================================
            // Create a new VersionList based on this level, and set it up
            //=====================================================================
            VersionList lVersionList = new VersionList(lNewLevel, lCourse.CourseName, lCourse.FileName);
            RootChunk = lVersionList;
            mCurrentFile = null;
              }
        }
Exemple #6
0
        private void LoadInternal(eOpenType xiOpenType, string xiFilename)
        {
            Chunk lNewRootChunk = null;
              string lExceptionWhen = "opening file";
              try
              {
            using (FileStream fs = File.OpenRead(xiFilename))
            {
              lExceptionWhen = "deserialising the file";
              switch (xiOpenType)
              {
            case eOpenType.LevelBinary:
              lNewRootChunk = new Level(fs);
              break;
            case eOpenType.UnknownBinary:
              lNewRootChunk = new FileChunk(fs);
              break;
            case eOpenType.Mmv:
              lNewRootChunk = new VersionList(fs);
              break;
            case eOpenType.Xml:
              XmlSerializer xs = new XmlSerializer(typeof(Chunk));
              lNewRootChunk = (Chunk)xs.Deserialize(fs);
              break;
            default: throw new Exception("unreachable case");
              }

              if (fs.Length != fs.Position)
              {
            //check the whole file has been read
            throw new DeserialisationException(string.Format("Deserialisation terminated early at byte {0} of {1}", fs.Position, fs.Length));
              }
            }
              }
              catch (Exception err)
              {
            Trace.WriteLine(err);
            MessageBox.Show(string.Format("Exception occurred while {0}: {1}", lExceptionWhen, err.Message), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            return;
              }
              // level loaded OK, now fill tree:
              RootChunk = lNewRootChunk;
              mLocalSettings.LastOpenedFile = xiFilename;
              mLocalSettings.LastOpenedType = xiOpenType;
              mCurrentFile = xiFilename;
              mCurrentFileMode = xiOpenType == eOpenType.Mmv ? eSaveMode.Mmv : xiOpenType == eOpenType.Xml ? eSaveMode.Xml : eSaveMode.Binary;
        }
Exemple #7
0
        //tests that both XML and Binary serialisation is invertible
        private void TestSerialisationIsInvertible(string xiFilename)
        {
            Console.Out.WriteLine("Testing file {0}", xiFilename);
              using (Stream inStr = File.OpenRead(xiFilename))
              {
            Level levelFromBinary = new Level();
            levelFromBinary.Deserialise(inStr);
            StringWriter sw = new StringWriter();
            XmlSerializer xs = new XmlSerializer(typeof(Level));
            xs.Serialize(sw, levelFromBinary);

            //now the XML version of the level is in sw
            Level levelFromXMLfromBinary = (Level)xs.Deserialize(new StringReader(sw.ToString()));

            //first check that the XML serialisation is the same
            StringWriter sw2 = new StringWriter();
            xs.Serialize(sw2, levelFromBinary);
            Assert.AreEqual(sw.ToString(), sw2.ToString());

            //now see if the XML-ified level will still write binary correctly:
            MemoryStream memStr = new MemoryStream();
            inStr.Seek(0, SeekOrigin.Begin);
            DebugOutputStreamWithExpectations outStr = new DebugOutputStreamWithExpectations(inStr, memStr);
            levelFromXMLfromBinary.Serialise(outStr);
            inStr.Seek(0, SeekOrigin.Begin);
            memStr.Seek(0, SeekOrigin.Begin);
            Assert.IsTrue(StreamUtils.StreamsAreEqual(inStr, memStr));
              }
        }
Exemple #8
0
        /*
        private string[] GetSampleLevelFiles()
        {
        string baseDir = GetBaseDir();

        if (false)
        {
            //qq just one level for now (TODO: make the tests below work for all levels)
            return new string[] { baseDir + @"\MICRO\BREAKY\BREAKY1.DAT" };
        }
        else
        {
            ArrayList acc = new ArrayList();
            foreach (string file in Directory.GetFiles(baseDir + @"\MICRO", "*.DAT", SearchOption.AllDirectories))
            {
                if (Regex.IsMatch(file, "[A-Z]+\\\\[A-Z]+[0-9]\\.DAT$"))
                    acc.Add(file);
            }
            return (string[])acc.ToArray(typeof(string));
        }
        }
        */
        //this is a weaker test than TestSerialisationIsInvertible
        //but has been left here as it's sometimes handy for debugging
        private void TestBinarySerialisationIsInvertible(string xiFilename)
        {
            Console.Out.WriteLine("Testing file {0}", xiFilename);
              using (Stream inStr = File.OpenRead(xiFilename))
              {
            Level deserLev = new Level();
            deserLev.Deserialise(inStr);
            MemoryStream memStr = new MemoryStream();
            inStr.Seek(0, SeekOrigin.Begin);
            DebugOutputStreamWithExpectations outStr = new DebugOutputStreamWithExpectations(inStr, memStr);
            deserLev.Serialise(outStr);
            inStr.Seek(0, SeekOrigin.Begin);
            memStr.Seek(0, SeekOrigin.Begin);
            Assert.IsTrue(StreamUtils.StreamsAreEqual(inStr, memStr));
              }
        }
Exemple #9
0
        public override void Deserialise(Stream xiInStream)
        {
            BinaryReader lInput = new BinaryReader(xiInStream);

              //=======================================================================
              // Check the magic number
              //=======================================================================
              int lMagicNumber = lInput.ReadInt32();

              if (lMagicNumber != MAGIC_NUMBER)
              {
            throw new DeserialisationException(string.Format(
              "VersionList has the wrong magic number! Expected {0}, found {1}", MAGIC_NUMBER, lMagicNumber));
              }

              //=======================================================================
              // Read the versions
              //=======================================================================
              int lVersionCount = lInput.ReadInt32();
              Versions = new List<Version>(lVersionCount);

              for (int ii = 0; ii < lVersionCount; ii++)
              {
            Versions.Add(new Version(xiInStream));
              }

              //=======================================================================
              // Read the strings
              //=======================================================================
              BinaryFilename = StreamUtils.ReadASCIINullTermString(xiInStream);
              CDFilename = StreamUtils.ReadASCIINullTermString(xiInStream);
              CourseName = StreamUtils.ReadASCIINullTermString(xiInStream);

              //=======================================================================
              // Set the CurrentLevel
              //=======================================================================
              CurrentLevel = GetLastVersion().GetLevel(null);
        }
Exemple #10
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;
        }
Exemple #11
0
        public IEnumerable<GLTK.Entity> GetEntities(Level xiLevel, eTextureMode xiTextureMode, eTexMetaDataEntries xiSelectedMetadata)
        {
            List<Entity> lAcc = new List<Entity>();

              //a bit hacky:
              if (!this.TreeNode.Checked)
              {
            lAcc.Add(GetSurfaceEntity(xiLevel, xiTextureMode, xiSelectedMetadata));
              }

              /////////////////////////////////////////////////////
              // The child weapons
              if (Weapons != null)
              {
            foreach (WeaponEntry lWeapon in Weapons)
            {
              lAcc.AddRange(lWeapon.GetEntities(xiLevel, xiTextureMode, xiSelectedMetadata));
            }
              }

              /////////////////////////////////////////////////////
              // The child objects
              if (Objects != null)
              {
            foreach (ObjectEntry oe in Objects)
            {
              lAcc.AddRange(oe.GetEntities(xiLevel, xiTextureMode, xiSelectedMetadata));
            }
              }

              return lAcc;
        }
Exemple #12
0
        ///========================================================================
        /// Constructor : Version
        /// 
        /// <summary>
        /// 	Create a new version
        /// </summary>
        /// <param name="xiLevel"></param>
        /// <param name="xiPreviousVersion"></param>
        /// <param name="xiStoreAsDiff"></param>
        /// <param name="xiExpectedSize"></param>
        ///========================================================================
        internal Version(Level xiLevel, Version xiPreviousVersion, bool xiStoreAsDiff, long xiExpectedSize)
        {
            CreationDate = DateTime.Now;

              //=======================================================================
              // Serialise the level
              //=======================================================================
              while (true)
              {
            using (MemoryStream lLevelStream = new MemoryStream())
            {
              xiLevel.Serialise(lLevelStream);
              lLevelStream.Seek(0, SeekOrigin.Begin);
              SerialisedLevel = new byte[lLevelStream.Length];
              lLevelStream.Read(SerialisedLevel, 0, SerialisedLevel.Length);
            }

            if (xiExpectedSize > 0 && SerialisedLevel.Length != xiExpectedSize)
            {
              long lSizeAdjustment = SerialisedLevel.Length - xiExpectedSize;

              if (lSizeAdjustment > 0 && xiLevel.SHET.TrailingZeroByteCount < lSizeAdjustment)
              {
            MessageBox.Show(string.Format(@"WARNING: The level is too large to fit in the expected size of file. Please remove some content from the level. Your level can be saved, but attempts to play the course will fail.

            Expected size: {0} bytes
            Actual size: {1} bytes
            Spare space: {2} bytes
            Space required: {3} bytes",
                         xiExpectedSize,
                         SerialisedLevel.Length,
                         xiLevel.SHET.TrailingZeroByteCount,
                         lSizeAdjustment - xiLevel.SHET.TrailingZeroByteCount), "MMEd", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
              }
              else if (MessageBox.Show("WARNING: The level is not of the expected size for this course. Do you want to adjust the file size to match? This can be done without corrupting the level.", "MMEd", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
              {
            xiLevel.SHET.TrailingZeroByteCount -= (int)lSizeAdjustment;
            continue;
              }
            }

            break;
              }

              //=======================================================================
              // Calculate differences, and store as a diff if appropriate
              //=======================================================================
              if (xiPreviousVersion != null)
              {
            Changes = string.Join("\r\n", xiLevel.GetDifferences(xiPreviousVersion.GetLevel(null)).ToArray());
              }
              else
              {
            Changes = "";
              }

              if (xiStoreAsDiff)
              {
            DifferentialLevel = DiffBlock.GetDifferences(xiPreviousVersion.SerialisedLevel, SerialisedLevel);
              }
        }
Exemple #13
0
        public override void SetSubject(Chunk xiChunk)
        {
            mOptionsMenu.Visible = (mSubject != null);

              if (xiChunk == null)
              {
            if (mMainForm.ViewerTabControl.SelectedTab == null
              || !(mMainForm.ViewerTabControl.SelectedTab.Tag is ThreeDeeViewer))
            {
              // the view has switched to another tab - reset the tree
              mMainForm.ChunkTreeView.CheckBoxes = false;
            }
            return;
              }

              if (mSubject != mMainForm.CurrentLevel)
              {
            mSubject = mMainForm.CurrentLevel;
            RebuildScene();
            ResetCamera();
              }

              mMainForm.ChunkTreeView.CheckBoxes = (mSubject != null);

              ActiveObject = xiChunk;
        }