Exemple #1
0
        public override void InitializeTab()
        {
            base.InitializeTab();

            // Pu Controller initialize and register click events
            buttonPuConHome.Click  += (sender, e) => PuUtilities.SetMarioPu(0, 0, 0);
            buttonPuConZnQpu.Click += (sender, e) => PuUtilities.TranslateMarioPu(0, 0, -4);
            buttonPuConZpQpu.Click += (sender, e) => PuUtilities.TranslateMarioPu(0, 0, 4);
            buttonPuConXnQpu.Click += (sender, e) => PuUtilities.TranslateMarioPu(-4, 0, 0);
            buttonPuConXpQpu.Click += (sender, e) => PuUtilities.TranslateMarioPu(4, 0, 0);
            buttonPuConZnPu.Click  += (sender, e) => PuUtilities.TranslateMarioPu(0, 0, -1);
            buttonPuConZpPu.Click  += (sender, e) => PuUtilities.TranslateMarioPu(0, 0, 1);
            buttonPuConXnPu.Click  += (sender, e) => PuUtilities.TranslateMarioPu(-1, 0, 0);
            buttonPuConXpPu.Click  += (sender, e) => PuUtilities.TranslateMarioPu(1, 0, 0);

            ControlUtilities.InitializeThreeDimensionController(
                CoordinateSystem.Euler,
                false,
                groupBoxMarioPu,
                "MarioPu",
                (float hOffset, float vOffset, float nOffset, bool useQpu) =>
            {
                int hOffsetInt = ParsingUtilities.ParseInt(hOffset);
                int vOffsetInt = ParsingUtilities.ParseInt(vOffset);
                int nOffsetInt = ParsingUtilities.ParseInt(nOffset);
                int multiplier = useQpu ? 4 : 1;
                PuUtilities.TranslateMarioPu(
                    hOffsetInt * multiplier,
                    nOffsetInt * multiplier,
                    -1 * vOffsetInt * multiplier);
            });
        }
Exemple #2
0
        public override void Update(bool updateView)
        {
            if (!updateView)
            {
                return;
            }

            _puController.Controls["labelPuConPuValue"].Text  = PuUtilities.GetPuIndexString(false, false);
            _puController.Controls["labelPuConQpuValue"].Text = PuUtilities.GetPuIndexString(true, false);

            base.Update(updateView);
        }
Exemple #3
0
        public void Update(bool updateView)
        {
            if (!updateView)
            {
                return;
            }

            //base.Update();

            _puController.Controls["labelPuConPuValue"].Text  = PuUtilities.GetPuPosString();
            _puController.Controls["labelPuConQpuValue"].Text = PuUtilities.GetQpuPosString();
        }
Exemple #4
0
        public PuManager(string varFilePath, TabPage tabControl, WatchVariableFlowLayoutPanel watchVariablePanel)
            : base(varFilePath, watchVariablePanel, ALL_VAR_GROUPS, VISIBLE_VAR_GROUPS)
        {
            SplitContainer splitContainerFile = tabControl.Controls["splitContainerPu"] as SplitContainer;

            _puController = splitContainerFile.Panel1.Controls["groupBoxPuController"] as GroupBox;

            // Pu Controller initialize and register click events
            _puController.Controls["buttonPuConHome"].Click  += (sender, e) => PuUtilities.SetMarioPu(0, 0, 0);
            _puController.Controls["buttonPuConZnQpu"].Click += (sender, e) => PuUtilities.TranslateMarioPu(0, 0, -4);
            _puController.Controls["buttonPuConZpQpu"].Click += (sender, e) => PuUtilities.TranslateMarioPu(0, 0, 4);
            _puController.Controls["buttonPuConXnQpu"].Click += (sender, e) => PuUtilities.TranslateMarioPu(-4, 0, 0);
            _puController.Controls["buttonPuConXpQpu"].Click += (sender, e) => PuUtilities.TranslateMarioPu(4, 0, 0);
            _puController.Controls["buttonPuConZnPu"].Click  += (sender, e) => PuUtilities.TranslateMarioPu(0, 0, -1);
            _puController.Controls["buttonPuConZpPu"].Click  += (sender, e) => PuUtilities.TranslateMarioPu(0, 0, 1);
            _puController.Controls["buttonPuConXnPu"].Click  += (sender, e) => PuUtilities.TranslateMarioPu(-1, 0, 0);
            _puController.Controls["buttonPuConXpPu"].Click  += (sender, e) => PuUtilities.TranslateMarioPu(1, 0, 0);

            GroupBox groupBoxMarioPu = splitContainerFile.Panel1.Controls["groupBoxMarioPu"] as GroupBox;

            ControlUtilities.InitializeThreeDimensionController(
                CoordinateSystem.Euler,
                false,
                groupBoxMarioPu,
                groupBoxMarioPu.Controls["buttonMarioPuXn"] as Button,
                groupBoxMarioPu.Controls["buttonMarioPuXp"] as Button,
                groupBoxMarioPu.Controls["buttonMarioPuZn"] as Button,
                groupBoxMarioPu.Controls["buttonMarioPuZp"] as Button,
                groupBoxMarioPu.Controls["buttonMarioPuXnZn"] as Button,
                groupBoxMarioPu.Controls["buttonMarioPuXnZp"] as Button,
                groupBoxMarioPu.Controls["buttonMarioPuXpZn"] as Button,
                groupBoxMarioPu.Controls["buttonMarioPuXpZp"] as Button,
                groupBoxMarioPu.Controls["buttonMarioPuYp"] as Button,
                groupBoxMarioPu.Controls["buttonMarioPuYn"] as Button,
                groupBoxMarioPu.Controls["textBoxMarioPuXZ"] as TextBox,
                groupBoxMarioPu.Controls["textBoxMarioPuY"] as TextBox,
                groupBoxMarioPu.Controls["checkBoxMarioPuQpu"] as CheckBox,
                (float hOffset, float vOffset, float nOffset, bool useQpu) =>
            {
                int hOffsetInt = ParsingUtilities.ParseInt(hOffset);
                int vOffsetInt = ParsingUtilities.ParseInt(vOffset);
                int nOffsetInt = ParsingUtilities.ParseInt(nOffset);
                int multiplier = useQpu ? 4 : 1;
                PuUtilities.TranslateMarioPu(
                    hOffsetInt * multiplier,
                    nOffsetInt * multiplier,
                    -1 * vOffsetInt * multiplier);
            });
        }
Exemple #5
0
        public static (float x, float z) ConvertCoordsForControlOrthographicView(float x, float y, float z)
        {
            x = Config.MapGraphics.MapViewEnablePuView ? x : (float)PuUtilities.GetRelativeCoordinate(x);
            y = Config.MapGraphics.MapViewEnablePuView ? y : (float)PuUtilities.GetRelativeCoordinate(y);
            z = Config.MapGraphics.MapViewEnablePuView ? z : (float)PuUtilities.GetRelativeCoordinate(z);
            float  xOffset      = x - Config.MapGraphics.MapViewCenterXValue;
            float  yOffset      = y - Config.MapGraphics.MapViewCenterYValue;
            float  zOffset      = z - Config.MapGraphics.MapViewCenterZValue;
            double angleRadians = MoreMath.AngleUnitsToRadians(Config.MapGraphics.MapViewYawValue);
            float  hOffset      = (float)(Math.Sin(angleRadians) * zOffset - Math.Cos(angleRadians) * xOffset);

            (double x0, double y0, double z0, double t0) =
                MoreMath.GetPlaneLineIntersection(
                    Config.MapGraphics.MapViewCenterXValue,
                    Config.MapGraphics.MapViewCenterYValue,
                    Config.MapGraphics.MapViewCenterZValue,
                    Config.MapGraphics.MapViewYawValue,
                    Config.MapGraphics.MapViewPitchValue,
                    x, y, z,
                    Config.MapGraphics.MapViewYawValue,
                    Config.MapGraphics.MapViewPitchValue);
            double rightYaw = MoreMath.RotateAngleCW(
                Config.MapGraphics.MapViewYawValue, 16384);

            (double x1, double y1, double z1, double t1) =
                MoreMath.GetPlaneLineIntersection(
                    x0, y0, z0, rightYaw, 0,
                    Config.MapGraphics.MapViewCenterXValue,
                    Config.MapGraphics.MapViewCenterYValue,
                    Config.MapGraphics.MapViewCenterZValue,
                    rightYaw, 0);
            double hDiff            = MoreMath.GetDistanceBetween(x1, z1, x0, z0);
            double yDiff            = y1 - y0;
            double yDiffSign        = Math.Sign(yDiff);
            double vOffsetMagnitude = MoreMath.GetHypotenuse(hDiff, yDiff);
            float  vOffset          = (float)(vOffsetMagnitude * yDiffSign);

            float hOffsetPixels = hOffset * Config.MapGraphics.MapViewScaleValue;
            float vOffsetPixels = vOffset * Config.MapGraphics.MapViewScaleValue;
            float centerH       = Config.MapGui.GLControlMap2D.Width / 2 + hOffsetPixels;
            float centerV       = Config.MapGui.GLControlMap2D.Height / 2 + vOffsetPixels;

            return(centerH, centerV);
        }
        protected override List <(float x, float y, float z)> GetGridlineIntersectionPositionsTopDownView()
        {
            if (_setting != PuGridlineSetting.SETTING1)
            {
                return(new List <(float x, float y, float z)>());
            }

            float marioY = Config.Stream.GetFloat(MarioConfig.StructAddress + MarioConfig.YOffset);

            long size    = (long)Math.Max(Size, 1);
            long spacing = (long)(puSize * size);

            long xOffset        = 0;
            long zOffset        = 0;
            long xOffsetReverse = 0;
            long zOffsetReverse = 0;

            if (_useMarioAsOrigin)
            {
                (int puXIndex, int puYIndex, int puZIndex) = PuUtilities.GetMarioPuIndexes();
                xOffset        = (long)MoreMath.NonNegativeModulus(puXIndex, size);
                zOffset        = (long)MoreMath.NonNegativeModulus(puZIndex, size);
                xOffsetReverse = size - xOffset;
                zOffsetReverse = size - zOffset;
            }

            long xMin = ((((long)Config.CurrentMapGraphics.MapViewXMin) / spacing) - 1) * spacing - puSize * xOffsetReverse;
            long xMax = ((((long)Config.CurrentMapGraphics.MapViewXMax) / spacing) + 1) * spacing + puSize * xOffset;
            long zMin = ((((long)Config.CurrentMapGraphics.MapViewZMin) / spacing) - 1) * spacing - puSize * zOffsetReverse;
            long zMax = ((((long)Config.CurrentMapGraphics.MapViewZMax) / spacing) + 1) * spacing + puSize * zOffset;

            List <(float x, float y, float z)> vertices = new List <(float x, float y, float z)>();

            for (long x = xMin; x <= xMax; x += spacing)
            {
                for (long z = zMin; z <= zMax; z += spacing)
                {
                    vertices.Add((x, marioY, z));
                }
            }
            return(vertices);
        }
Exemple #7
0
        private void PuControl_Click(object sender, EventArgs e, PuControl controlType)
        {
            switch (controlType)
            {
            case PuControl.Home:
                PuUtilities.MoveToPu(0, 0, 0);
                break;

            case PuControl.PuUp:
                PuUtilities.MoveToRelativePu(0, 0, -1);
                break;

            case PuControl.PuDown:
                PuUtilities.MoveToRelativePu(0, 0, 1);
                break;

            case PuControl.PuLeft:
                PuUtilities.MoveToRelativePu(-1, 0, 0);
                break;

            case PuControl.PuRight:
                PuUtilities.MoveToRelativePu(1, 0, 0);
                break;

            case PuControl.QpuUp:
                PuUtilities.MoveToRelativePu(0, 0, -4);
                break;

            case PuControl.QpuDown:
                PuUtilities.MoveToRelativePu(0, 0, 4);
                break;

            case PuControl.QpuLeft:
                PuUtilities.MoveToRelativePu(-4, 0, 0);
                break;

            case PuControl.QpuRight:
                PuUtilities.MoveToRelativePu(4, 0, 0);
                break;
            }
        }
Exemple #8
0
        /** Takes in in-game coordinates, outputs control coordinates. */
        public static (float x, float z) ConvertCoordsForControlTopDownView(float x, float z)
        {
            x = Config.MapGraphics.MapViewEnablePuView ? x : (float)PuUtilities.GetRelativeCoordinate(x);
            z = Config.MapGraphics.MapViewEnablePuView ? z : (float)PuUtilities.GetRelativeCoordinate(z);
            float xOffset = x - Config.MapGraphics.MapViewCenterXValue;
            float zOffset = z - Config.MapGraphics.MapViewCenterZValue;

            (float xOffsetRotated, float zOffsetRotated) =
                ((float, float))MoreMath.RotatePointAboutPointAnAngularDistance(
                    xOffset,
                    zOffset,
                    0,
                    0,
                    -1 * Config.MapGraphics.MapViewYawValue);
            float xOffsetPixels = xOffsetRotated * Config.MapGraphics.MapViewScaleValue;
            float zOffsetPixels = zOffsetRotated * Config.MapGraphics.MapViewScaleValue;
            float centerX       = Config.MapGui.GLControlMap2D.Width / 2 + xOffsetPixels;
            float centerZ       = Config.MapGui.GLControlMap2D.Height / 2 + zOffsetPixels;

            return(centerX, centerZ);
        }
Exemple #9
0
        public void Update(bool updateView)
        {
            // Update watch variables
            foreach (var watchVar in _watchVarControls)
            {
                watchVar.Update();
            }

            if (!updateView)
            {
                return;
            }

            // Update the rng index
            int rngIndex = RngIndexer.GetRngIndex(BitConverter.ToUInt16(_stream.ReadRam(Config.RngAddress, 2), 0));

            _rngIndex.Text = (rngIndex < 0) ? "N/A [" + (-rngIndex).ToString() + "]" : rngIndex.ToString();

            _rngPerFrame.Text = GetRngCallsPerFrame().ToString();

            _activeObjCnt.Text = ActiveObjectCount.ToString();
            _puController.Controls["labelPuConPuValue"].Text  = PuUtilities.GetPuPosString(_stream);
            _puController.Controls["labelPuConQpuValue"].Text = PuUtilities.GetQpuPosString(_stream);
        }
Exemple #10
0
        public void Update()
        {
            // Make sure the control has successfully loaded
            if (!_isLoaded)
            {
                return;
            }

            UpdateFromMarioTab();

            // Get level and area
            byte   level         = Config.Stream.GetByte(MiscConfig.LevelAddress);
            byte   area          = Config.Stream.GetByte(MiscConfig.AreaAddress);
            ushort loadingPoint  = Config.Stream.GetUInt16(MiscConfig.LoadingPointAddress);
            ushort missionLayout = Config.Stream.GetUInt16(MiscConfig.MissionAddress);

            // Find new map list
            if (_currentMapList == null || _currentLevel != level || _currentArea != area ||
                _currentLoadingPoint != loadingPoint || _currentMissionLayout != missionLayout)
            {
                _currentLevel         = level;
                _currentArea          = area;
                _currentLoadingPoint  = loadingPoint;
                _currentMissionLayout = missionLayout;
                _currentMapList       = Config.MapAssociations.GetLevelAreaMaps(level, area);

                // Look for maps with correct loading points
                var mapListLPFiltered = _currentMapList.Where((map) => map.LoadingPoint == loadingPoint).ToList();
                if (mapListLPFiltered.Count > 0)
                {
                    _currentMapList = mapListLPFiltered;
                }
                else
                {
                    _currentMapList = _currentMapList.Where((map) => !map.LoadingPoint.HasValue).ToList();
                }

                var mapListMLFiltered = _currentMapList.Where((map) => map.MissionLayout == missionLayout).ToList();
                if (mapListMLFiltered.Count > 0)
                {
                    _currentMapList = mapListMLFiltered;
                }
                else
                {
                    _currentMapList = _currentMapList.Where((map) => !map.MissionLayout.HasValue).ToList();
                }
            }

            // ---- Update PU -----
            int puX = PuUtilities.GetPuIndex(_marioMapObj.X);
            int puY = PuUtilities.GetPuIndex(_marioMapObj.Y);
            int puZ = PuUtilities.GetPuIndex(_marioMapObj.Z);

            // Update Qpu
            double qpuX = puX / 4d;
            double qpuY = puY / 4d;
            double qpuZ = puZ / 4d;

            // Update labels
            _mapGui.PuValueLabel.Text    = string.Format("[{0}:{1}:{2}]", puX, puY, puZ);
            _mapGui.QpuValueLabel.Text   = string.Format("[{0}:{1}:{2}]", qpuX, qpuY, qpuZ);
            _mapGui.MapIdLabel.Text      = string.Format("[{0}:{1}:{2}:{3}]", level, area, loadingPoint, missionLayout);
            _mapGui.MapNameLabel.Text    = _currentMap.Name;
            _mapGui.MapSubNameLabel.Text = (_currentMap.SubName != null) ? _currentMap.SubName : "";

            var marioCoord = new PointF(_marioMapObj.RelX, _marioMapObj.RelZ);

            // Filter out all maps that are lower than Mario
            float marioY           = _artificialMarioY ?? _marioMapObj.RelY;
            var   mapListYFiltered = _currentMapList.Where((map) => map.Y <= marioY).ToList();

            // If no map is available display the default image
            if (mapListYFiltered.Count <= 0)
            {
                ChangeCurrentMap(Config.MapAssociations.DefaultMap);
            }
            else
            {
                // Pick the map closest to mario (yet still above Mario)
                MapLayout bestMap = mapListYFiltered[0];
                foreach (MapLayout map in mapListYFiltered)
                {
                    if (map.Y > bestMap.Y)
                    {
                        bestMap = map;
                    }
                }

                ChangeCurrentMap(bestMap);
            }

            // Calculate mario's location on the OpenGl control
            var mapView = _mapGraphics.MapView;

            _marioMapObj.LocationOnContol = CalculateLocationOnControl(marioCoord, mapView);
            _marioMapObj.Draw             = _mapGui.MapShowMario.Checked;

            var holpCoord = new PointF(_holpMapObj.RelX, _holpMapObj.RelZ);

            _holpMapObj.Draw             = _mapGui.MapShowHolp.Checked;
            _holpMapObj.LocationOnContol = CalculateLocationOnControl(holpCoord, mapView);

            var intendedNextPositionCoord = new PointF(_intendedNextPositionMapObj.RelX, _intendedNextPositionMapObj.RelZ);

            _intendedNextPositionMapObj.Draw             = _mapGui.MapShowIntendedNextPosition.Checked;
            _intendedNextPositionMapObj.LocationOnContol = CalculateLocationOnControl(intendedNextPositionCoord, mapView);

            var cameraCoord = new PointF(_cameraMapObj.RelX, _cameraMapObj.RelZ);

            _cameraMapObj.Draw             = _mapGui.MapShowCamera.Checked;
            _cameraMapObj.LocationOnContol = CalculateLocationOnControl(cameraCoord, mapView);

            _floorTriangleMapObj.P1OnControl = CalculateLocationOnControl(new PointF(_floorTriangleMapObj.RelX1, _floorTriangleMapObj.RelZ1), mapView);
            _floorTriangleMapObj.P2OnControl = CalculateLocationOnControl(new PointF(_floorTriangleMapObj.RelX2, _floorTriangleMapObj.RelZ2), mapView);
            _floorTriangleMapObj.P3OnControl = CalculateLocationOnControl(new PointF(_floorTriangleMapObj.RelX3, _floorTriangleMapObj.RelZ3), mapView);
            _floorTriangleMapObj.Draw        = _floorTriangleMapObj.Show & _mapGui.MapShowFloorTriangle.Checked;

            _ceilingTriangleMapObj.P1OnControl = CalculateLocationOnControl(new PointF(_ceilingTriangleMapObj.RelX1, _ceilingTriangleMapObj.RelZ1), mapView);
            _ceilingTriangleMapObj.P2OnControl = CalculateLocationOnControl(new PointF(_ceilingTriangleMapObj.RelX2, _ceilingTriangleMapObj.RelZ2), mapView);
            _ceilingTriangleMapObj.P3OnControl = CalculateLocationOnControl(new PointF(_ceilingTriangleMapObj.RelX3, _ceilingTriangleMapObj.RelZ3), mapView);
            _ceilingTriangleMapObj.Draw        = _ceilingTriangleMapObj.Show & _mapGui.MapShowCeilingTriangle.Checked;

            foreach (TriangleMap2Object cogFloorTri in _cogFloorTris)
            {
                cogFloorTri.P1OnControl = CalculateLocationOnControl(new PointF(cogFloorTri.RelX1, cogFloorTri.RelZ1), mapView);
                cogFloorTri.P2OnControl = CalculateLocationOnControl(new PointF(cogFloorTri.RelX2, cogFloorTri.RelZ2), mapView);
                cogFloorTri.P3OnControl = CalculateLocationOnControl(new PointF(cogFloorTri.RelX3, cogFloorTri.RelZ3), mapView);
                cogFloorTri.Draw        = cogFloorTri.Show && TestingConfig.ShowCogTris;
            }

            foreach (TriangleMap2Object cogFloorTri in _cog2FloorTris)
            {
                cogFloorTri.P1OnControl = CalculateLocationOnControl(new PointF(cogFloorTri.RelX1, cogFloorTri.RelZ1), mapView);
                cogFloorTri.P2OnControl = CalculateLocationOnControl(new PointF(cogFloorTri.RelX2, cogFloorTri.RelZ2), mapView);
                cogFloorTri.P3OnControl = CalculateLocationOnControl(new PointF(cogFloorTri.RelX3, cogFloorTri.RelZ3), mapView);
                cogFloorTri.Draw        = cogFloorTri.Show && TestingConfig.ShowCogTris;
            }

            foreach (TriangleMap2Object cogWallTri in _cogWallTris)
            {
                cogWallTri.P1OnControl = CalculateLocationOnControl(new PointF(cogWallTri.RelX1, cogWallTri.RelZ1), mapView);
                cogWallTri.P2OnControl = CalculateLocationOnControl(new PointF(cogWallTri.RelX2, cogWallTri.RelZ2), mapView);
                cogWallTri.P3OnControl = CalculateLocationOnControl(new PointF(cogWallTri.RelX3, cogWallTri.RelZ3), mapView);
                cogWallTri.Draw        = cogWallTri.Show && TestingConfig.ShowCogTris;
            }

            foreach (List <TriangleMap2Object> tris in _triObjectFloors)
            {
                foreach (TriangleMap2Object tri in tris)
                {
                    tri.P1OnControl = CalculateLocationOnControl(new PointF(tri.RelX1, tri.RelZ1), mapView);
                    tri.P2OnControl = CalculateLocationOnControl(new PointF(tri.RelX2, tri.RelZ2), mapView);
                    tri.P3OnControl = CalculateLocationOnControl(new PointF(tri.RelX3, tri.RelZ3), mapView);
                    tri.Draw        = tri.Show && TestingConfig.ShowShapes;
                }
            }

            foreach (List <TriangleMap2Object> tris in _triObjectWalls)
            {
                foreach (TriangleMap2Object tri in tris)
                {
                    tri.P1OnControl = CalculateLocationOnControl(new PointF(tri.RelX1, tri.RelZ1), mapView);
                    tri.P2OnControl = CalculateLocationOnControl(new PointF(tri.RelX2, tri.RelZ2), mapView);
                    tri.P3OnControl = CalculateLocationOnControl(new PointF(tri.RelX3, tri.RelZ3), mapView);
                    tri.Draw        = tri.Show && TestingConfig.ShowShapes;
                }
            }

            // Calculate object slot's cooridnates
            foreach (var mapObj in _mapObjects)
            {
                mapObj.Draw = (mapObj.Show && (_mapGui.MapShowInactiveObjects.Checked || mapObj.IsActive));
                if (!mapObj.Draw)
                {
                    continue;
                }

                var objCoords = new PointF(mapObj.RelX, mapObj.RelZ);

                // Calculate object's location on control
                mapObj.LocationOnContol = CalculateLocationOnControl(objCoords, mapView);
            }

            // Update gui by drawing images (invokes _mapGraphics.OnPaint())
            _mapGraphics.Control.Invalidate();
        }
Exemple #11
0
        public void Update()
        {
            // Make sure the control has successfully loaded
            if (!_isLoaded)
            {
                return;
            }

            // Get level and area
            byte   level         = _stream.ReadRam(Config.LevelAddress, 1)[0];
            byte   area          = _stream.ReadRam(Config.AreaAddress, 1)[0];
            ushort loadingPoint  = BitConverter.ToUInt16(_stream.ReadRam(Config.LoadingPointAddress, 2), 0);
            ushort missionLayout = BitConverter.ToUInt16(_stream.ReadRam(Config.MissionAddress, 2), 0);

            // Find new map list
            if (_currentMapList == null || _currentLevel != level || _currentArea != area ||
                _currentLoadingPoint != loadingPoint || _currentMissionLayout != missionLayout)
            {
                _currentLevel         = level;
                _currentArea          = area;
                _currentLoadingPoint  = loadingPoint;
                _currentMissionLayout = missionLayout;
                _currentMapList       = MapAssoc.GetLevelAreaMaps(level, area);

                // Look for maps with correct loading points
                var mapListLPFiltered = _currentMapList.Where((map) => map.LoadingPoint == loadingPoint).ToList();
                if (mapListLPFiltered.Count > 0)
                {
                    _currentMapList = mapListLPFiltered;
                }
                else
                {
                    _currentMapList = _currentMapList.Where((map) => !map.LoadingPoint.HasValue).ToList();
                }

                var mapListMLFiltered = _currentMapList.Where((map) => map.MissionLayout == missionLayout).ToList();
                if (mapListMLFiltered.Count > 0)
                {
                    _currentMapList = mapListMLFiltered;
                }
                else
                {
                    _currentMapList = _currentMapList.Where((map) => !map.MissionLayout.HasValue).ToList();
                }
            }

            // ---- Update PU -----
            int puX = PuUtilities.GetPUFromCoord(_marioMapObj.X);
            int puY = PuUtilities.GetPUFromCoord(_marioMapObj.Y);
            int puZ = PuUtilities.GetPUFromCoord(_marioMapObj.Z);

            // Update Qpu
            double qpuX = puX / 4d;
            double qpuY = puY / 4d;
            double qpuZ = puZ / 4d;

            // Update labels
            _mapGui.PuValueLabel.Text    = string.Format("[{0}:{1}:{2}]", puX, puY, puZ);
            _mapGui.QpuValueLabel.Text   = string.Format("[{0}:{1}:{2}]", qpuX, qpuY, qpuZ);
            _mapGui.MapIdLabel.Text      = string.Format("[{0}:{1}:{2}:{3}]", level, area, loadingPoint, missionLayout);
            _mapGui.MapNameLabel.Text    = _currentMap.Name;
            _mapGui.MapSubNameLabel.Text = (_currentMap.SubName != null) ? _currentMap.SubName : "";

            // Adjust mario coordinates relative from current PU
            float marioRelX  = PuUtilities.GetRelativePuPosition(_marioMapObj.X, puX);
            float marioRelY  = PuUtilities.GetRelativePuPosition(_marioMapObj.Y, puY);
            float marioRelZ  = PuUtilities.GetRelativePuPosition(_marioMapObj.Z, puZ);
            var   marioCoord = new PointF(marioRelX, marioRelZ);

            // Filter out all maps that are lower than Mario
            var mapListYFiltered = _currentMapList.Where((map) => map.Y <= marioRelY).ToList();

            // If no map is available display the default image
            if (mapListYFiltered.Count <= 0)
            {
                ChangeCurrentMap(MapAssoc.DefaultMap);
            }
            else
            {
                // Pick the map closest to mario (yet still above Mario)
                Map bestMap = mapListYFiltered[0];
                foreach (Map map in mapListYFiltered)
                {
                    if (map.Y > bestMap.Y)
                    {
                        bestMap = map;
                    }
                }

                ChangeCurrentMap(bestMap);
            }

            // Calculate mario's location on the OpenGl control
            var mapView = _mapGraphics.MapView;

            _marioMapObj.LocationOnContol = CalculateLocationOnControl(marioCoord, mapView);
            _marioMapObj.Draw             = _mapGui.MapShowMario.Checked;

            int   holpPuX   = PuUtilities.GetPUFromCoord(_holpMapObj.X);
            int   holpPuY   = PuUtilities.GetPUFromCoord(_holpMapObj.Y);
            int   holpPuZ   = PuUtilities.GetPUFromCoord(_holpMapObj.Z);
            float holpRelX  = PuUtilities.GetRelativePuPosition(_holpMapObj.X, holpPuX);
            float holpRelZ  = PuUtilities.GetRelativePuPosition(_holpMapObj.Z, holpPuZ);
            var   holpCoord = new PointF(holpRelX, holpRelZ);

            _holpMapObj.Draw             = _mapGui.MapShowHolp.Checked && puX == holpPuX && puY == holpPuY && puZ == holpPuZ;
            _holpMapObj.LocationOnContol = CalculateLocationOnControl(holpCoord, mapView);

            int   cameraPuX   = PuUtilities.GetPUFromCoord(_cameraMapObj.X);
            int   cameraPuY   = PuUtilities.GetPUFromCoord(_cameraMapObj.Y);
            int   cameraPuZ   = PuUtilities.GetPUFromCoord(_cameraMapObj.Z);
            float cameraRelX  = PuUtilities.GetRelativePuPosition(_cameraMapObj.X, cameraPuX);
            float cameraRelZ  = PuUtilities.GetRelativePuPosition(_cameraMapObj.Z, cameraPuZ);
            var   cameraCoord = new PointF(cameraRelX, cameraRelZ);

            _cameraMapObj.Draw             = _mapGui.MapShowCamera.Checked && puX == cameraPuX && puY == cameraPuY && puZ == cameraPuZ;
            _cameraMapObj.LocationOnContol = CalculateLocationOnControl(cameraCoord, mapView);

            float trianglePuX1 = PuUtilities.GetRelativePuPosition(_floorTriangleMapObj.X1);
            float trianglePuZ1 = PuUtilities.GetRelativePuPosition(_floorTriangleMapObj.Z1);
            float trianglePuX2 = PuUtilities.GetRelativePuPosition(_floorTriangleMapObj.X2);
            float trianglePuZ2 = PuUtilities.GetRelativePuPosition(_floorTriangleMapObj.Z2);
            float trianglePuX3 = PuUtilities.GetRelativePuPosition(_floorTriangleMapObj.X3);
            float trianglePuZ3 = PuUtilities.GetRelativePuPosition(_floorTriangleMapObj.Z3);

            _floorTriangleMapObj.P1OnControl = CalculateLocationOnControl(new PointF(trianglePuX1, trianglePuZ1), mapView);
            _floorTriangleMapObj.P2OnControl = CalculateLocationOnControl(new PointF(trianglePuX2, trianglePuZ2), mapView);
            _floorTriangleMapObj.P3OnControl = CalculateLocationOnControl(new PointF(trianglePuX3, trianglePuZ3), mapView);
            _floorTriangleMapObj.Draw        = _floorTriangleMapObj.Show & _mapGui.MapShowFloorTriangle.Checked;


            // Calculate object slot's cooridnates
            foreach (var mapObj in _mapObjects)
            {
                if (!_mapGui.MapShowObjects.Checked)
                {
                    mapObj.Draw = false;
                    continue;
                }

                // Make sure the object is in the same PU as Mario
                var objPuX = PuUtilities.GetPUFromCoord(mapObj.X);
                var objPuY = PuUtilities.GetPUFromCoord(mapObj.Y);
                var objPuZ = PuUtilities.GetPUFromCoord(mapObj.Z);

                // Don't draw the object if it is in a separate PU as mario
                mapObj.Draw = (mapObj.Show && objPuX == puX && objPuY == puY && objPuZ == puZ &&
                               (_mapGui.MapShowInactiveObjects.Checked || mapObj.IsActive));
                if (!mapObj.Draw)
                {
                    continue;
                }

                // Adjust object coordinates relative from current PU
                float objPosX   = PuUtilities.GetRelativePuPosition(mapObj.X, objPuX);
                float objPosZ   = PuUtilities.GetRelativePuPosition(mapObj.Z, objPuZ);
                var   objCoords = new PointF(objPosX, objPosZ);

                // Calculate object's location on control
                mapObj.LocationOnContol = CalculateLocationOnControl(objCoords, mapView);
            }

            // Update gui by drawing images (invokes _mapGraphics.OnPaint())
            _mapGraphics.Control.Invalidate();
        }
        protected override List <(float x, float y, float z)> GetGridlineIntersectionPositionsOrthographicView()
        {
            if (_setting != PuGridlineSetting.SETTING1)
            {
                return(new List <(float x, float y, float z)>());
            }

            long size    = (long)Math.Max(Size, 1);
            long spacing = (long)(puSize * size);

            long xOffset        = 0;
            long yOffset        = 0;
            long zOffset        = 0;
            long xOffsetReverse = 0;
            long yOffsetReverse = 0;
            long zOffsetReverse = 0;

            if (_useMarioAsOrigin)
            {
                (int puXIndex, int puYIndex, int puZIndex) = PuUtilities.GetMarioPuIndexes();
                xOffset        = (long)MoreMath.NonNegativeModulus(puXIndex, size);
                yOffset        = (long)MoreMath.NonNegativeModulus(puYIndex, size);
                zOffset        = (long)MoreMath.NonNegativeModulus(puZIndex, size);
                xOffsetReverse = size - xOffset;
                yOffsetReverse = size - yOffset;
                zOffsetReverse = size - zOffset;
            }

            float xCenter = Config.CurrentMapGraphics.MapViewCenterXValue;
            float zCenter = Config.CurrentMapGraphics.MapViewCenterZValue;
            long  xMin    = ((((long)Config.CurrentMapGraphics.MapViewXMin) / spacing) - 1) * spacing - puSize * xOffsetReverse;
            long  xMax    = ((((long)Config.CurrentMapGraphics.MapViewXMax) / spacing) + 1) * spacing + puSize * xOffset;
            long  yMin    = ((((long)Config.CurrentMapGraphics.MapViewYMin) / spacing) - 1) * spacing - puSize * yOffsetReverse;
            long  yMax    = ((((long)Config.CurrentMapGraphics.MapViewYMax) / spacing) + 1) * spacing + puSize * yOffset;
            long  zMin    = ((((long)Config.CurrentMapGraphics.MapViewZMin) / spacing) - 1) * spacing - puSize * zOffsetReverse;
            long  zMax    = ((((long)Config.CurrentMapGraphics.MapViewZMax) / spacing) + 1) * spacing + puSize * zOffset;

            if (Config.CurrentMapGraphics.MapViewPitchValue == 0 &&
                (Config.CurrentMapGraphics.MapViewYawValue == 0 ||
                 Config.CurrentMapGraphics.MapViewYawValue == 32768))
            {
                List <(float x, float y, float z)> vertices = new List <(float x, float y, float z)>();
                for (long x = xMin; x <= xMax; x += spacing)
                {
                    for (long y = yMin; y <= yMax; y += spacing)
                    {
                        vertices.Add((x, y, zCenter));
                    }
                }
                return(vertices);
            }
            else if (Config.CurrentMapGraphics.MapViewPitchValue == 0 &&
                     (Config.CurrentMapGraphics.MapViewYawValue == 16384 ||
                      Config.CurrentMapGraphics.MapViewYawValue == 49152))
            {
                List <(float x, float y, float z)> vertices = new List <(float x, float y, float z)>();
                for (long z = zMin; z <= zMax; z += spacing)
                {
                    for (long y = yMin; y <= yMax; y += spacing)
                    {
                        vertices.Add((xCenter, y, z));
                    }
                }
                return(vertices);
            }
            else
            {
                return(new List <(float x, float y, float z)>());
            }
        }
        protected override List <(float x, float y, float z)> GetVerticesTopDownView()
        {
            switch (_setting)
            {
            case PuGridlineSetting.SETTING1:
            {
                float marioY = Config.Stream.GetFloat(MarioConfig.StructAddress + MarioConfig.YOffset);

                long size    = (long)Math.Max(Size, 1);
                long spacing = puSize * size;

                long xOffset        = 0;
                long zOffset        = 0;
                long xOffsetReverse = 0;
                long zOffsetReverse = 0;
                if (_useMarioAsOrigin)
                {
                    (int puXIndex, int puYIndex, int puZIndex) = PuUtilities.GetMarioPuIndexes();
                    xOffset        = (long)MoreMath.NonNegativeModulus(puXIndex, size);
                    zOffset        = (long)MoreMath.NonNegativeModulus(puZIndex, size);
                    xOffsetReverse = size - xOffset;
                    zOffsetReverse = size - zOffset;
                }

                long xMin = ((((long)Config.CurrentMapGraphics.MapViewXMin) / spacing) - 1) * spacing - puSize * xOffsetReverse;
                long xMax = ((((long)Config.CurrentMapGraphics.MapViewXMax) / spacing) + 1) * spacing + puSize * xOffset;
                long zMin = ((((long)Config.CurrentMapGraphics.MapViewZMin) / spacing) - 1) * spacing - puSize * zOffsetReverse;
                long zMax = ((((long)Config.CurrentMapGraphics.MapViewZMax) / spacing) + 1) * spacing + puSize * zOffset;

                List <(float x, float y, float z)> vertices = new List <(float x, float y, float z)>();
                for (long x = xMin; x <= xMax; x += spacing)
                {
                    vertices.Add((x, marioY, zMin));
                    vertices.Add((x, marioY, zMax));
                }
                for (long z = zMin; z <= zMax; z += spacing)
                {
                    vertices.Add((xMin, marioY, z));
                    vertices.Add((xMax, marioY, z));
                }
                return(vertices);
            }

            case PuGridlineSetting.SETTING2:
            {
                float marioY = Config.Stream.GetFloat(MarioConfig.StructAddress + MarioConfig.YOffset);

                int xMin = ((((int)Config.CurrentMapGraphics.MapViewXMin) / puSize) - 1) * puSize - halfPuSize;
                int xMax = ((((int)Config.CurrentMapGraphics.MapViewXMax) / puSize) + 1) * puSize + halfPuSize;
                int zMin = ((((int)Config.CurrentMapGraphics.MapViewZMin) / puSize) - 1) * puSize - halfPuSize;
                int zMax = ((((int)Config.CurrentMapGraphics.MapViewZMax) / puSize) + 1) * puSize + halfPuSize;

                List <(float x, float y, float z)> vertices = new List <(float x, float y, float z)>();
                for (int x = xMin; x <= xMax; x += puSize)
                {
                    vertices.Add((x, marioY, zMin));
                    vertices.Add((x, marioY, zMax));
                }
                for (int z = zMin; z <= zMax; z += puSize)
                {
                    vertices.Add((xMin, marioY, z));
                    vertices.Add((xMax, marioY, z));
                }
                return(vertices);
            }

            case PuGridlineSetting.SETTING3:
            {
                float marioY = Config.Stream.GetFloat(MarioConfig.StructAddress + MarioConfig.YOffset);

                int xMin = ((((int)Config.CurrentMapGraphics.MapViewXMin) / puSize) - 1) * puSize;
                int xMax = ((((int)Config.CurrentMapGraphics.MapViewXMax) / puSize) + 1) * puSize;
                int zMin = ((((int)Config.CurrentMapGraphics.MapViewZMin) / puSize) - 1) * puSize;
                int zMax = ((((int)Config.CurrentMapGraphics.MapViewZMax) / puSize) + 1) * puSize;

                List <(float x, float y, float z)> vertices = new List <(float x, float y, float z)>();
                for (int x = xMin; x <= xMax; x += puSize)
                {
                    for (int z = zMin; z <= zMax; z += puSize)
                    {
                        float x1 = x - halfCourseSize;
                        float x2 = x + halfCourseSize;
                        float z1 = z - halfCourseSize;
                        float z2 = z + halfCourseSize;

                        vertices.Add((x1, marioY, z1));
                        vertices.Add((x1, marioY, z2));

                        vertices.Add((x2, marioY, z1));
                        vertices.Add((x2, marioY, z2));

                        vertices.Add((x1, marioY, z1));
                        vertices.Add((x2, marioY, z1));

                        vertices.Add((x1, marioY, z2));
                        vertices.Add((x2, marioY, z2));
                    }
                }
                return(vertices);
            }

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
        protected override List <(float x, float y, float z)> GetVerticesOrthographicView()
        {
            switch (_setting)
            {
            case PuGridlineSetting.SETTING1:
            {
                long size    = (long)Math.Max(Size, 1);
                long spacing = (long)(puSize * size);

                long xOffset        = 0;
                long yOffset        = 0;
                long zOffset        = 0;
                long xOffsetReverse = 0;
                long yOffsetReverse = 0;
                long zOffsetReverse = 0;
                if (_useMarioAsOrigin)
                {
                    (int puXIndex, int puYIndex, int puZIndex) = PuUtilities.GetMarioPuIndexes();
                    xOffset        = (long)MoreMath.NonNegativeModulus(puXIndex, size);
                    yOffset        = (long)MoreMath.NonNegativeModulus(puYIndex, size);
                    zOffset        = (long)MoreMath.NonNegativeModulus(puZIndex, size);
                    xOffsetReverse = size - xOffset;
                    yOffsetReverse = size - yOffset;
                    zOffsetReverse = size - zOffset;
                }

                float xCenter = Config.CurrentMapGraphics.MapViewCenterXValue;
                float zCenter = Config.CurrentMapGraphics.MapViewCenterZValue;
                long  xMin    = ((((long)Config.CurrentMapGraphics.MapViewXMin) / spacing) - 1) * spacing - puSize * xOffsetReverse;
                long  xMax    = ((((long)Config.CurrentMapGraphics.MapViewXMax) / spacing) + 1) * spacing + puSize * xOffset;
                long  yMin    = ((((long)Config.CurrentMapGraphics.MapViewYMin) / spacing) - 1) * spacing - puSize * yOffsetReverse;
                long  yMax    = ((((long)Config.CurrentMapGraphics.MapViewYMax) / spacing) + 1) * spacing + puSize * yOffset;
                long  zMin    = ((((long)Config.CurrentMapGraphics.MapViewZMin) / spacing) - 1) * spacing - puSize * zOffsetReverse;
                long  zMax    = ((((long)Config.CurrentMapGraphics.MapViewZMax) / spacing) + 1) * spacing + puSize * zOffset;

                if (Config.CurrentMapGraphics.MapViewPitchValue == 0 &&
                    (Config.CurrentMapGraphics.MapViewYawValue == 0 ||
                     Config.CurrentMapGraphics.MapViewYawValue == 32768))
                {
                    List <(float x, float y, float z)> vertices = new List <(float x, float y, float z)>();
                    for (long x = xMin; x <= xMax; x += spacing)
                    {
                        vertices.Add((x, yMin, zCenter));
                        vertices.Add((x, yMax, zCenter));
                    }
                    for (long y = yMin; y <= yMax; y += spacing)
                    {
                        vertices.Add((xMin, y, zCenter));
                        vertices.Add((xMax, y, zCenter));
                    }
                    return(vertices);
                }
                else if (Config.CurrentMapGraphics.MapViewPitchValue == 0 &&
                         (Config.CurrentMapGraphics.MapViewYawValue == 16384 ||
                          Config.CurrentMapGraphics.MapViewYawValue == 49152))
                {
                    List <(float x, float y, float z)> vertices = new List <(float x, float y, float z)>();
                    for (long z = zMin; z <= zMax; z += spacing)
                    {
                        vertices.Add((xCenter, yMin, z));
                        vertices.Add((xCenter, yMax, z));
                    }
                    for (long y = yMin; y <= yMax; y += spacing)
                    {
                        vertices.Add((zCenter, y, zMin));
                        vertices.Add((xCenter, y, zMax));
                    }
                    return(vertices);
                }
                else
                {
                    return(new List <(float x, float y, float z)>());
                }
            }

            case PuGridlineSetting.SETTING2:
            {
                float xCenter = Config.CurrentMapGraphics.MapViewCenterXValue;
                float zCenter = Config.CurrentMapGraphics.MapViewCenterZValue;
                int   xMin    = ((((int)Config.CurrentMapGraphics.MapViewXMin) / puSize) - 1) * puSize - halfPuSize;
                int   xMax    = ((((int)Config.CurrentMapGraphics.MapViewXMax) / puSize) + 1) * puSize + halfPuSize;
                int   yMin    = ((((int)Config.CurrentMapGraphics.MapViewYMin) / puSize) - 1) * puSize - halfPuSize;
                int   yMax    = ((((int)Config.CurrentMapGraphics.MapViewYMax) / puSize) + 1) * puSize + halfPuSize;
                int   zMin    = ((((int)Config.CurrentMapGraphics.MapViewZMin) / puSize) - 1) * puSize - halfPuSize;
                int   zMax    = ((((int)Config.CurrentMapGraphics.MapViewZMax) / puSize) + 1) * puSize + halfPuSize;

                if (Config.CurrentMapGraphics.MapViewPitchValue == 0 &&
                    (Config.CurrentMapGraphics.MapViewYawValue == 0 ||
                     Config.CurrentMapGraphics.MapViewYawValue == 32768))
                {
                    List <(float x, float y, float z)> vertices = new List <(float x, float y, float z)>();
                    for (int x = xMin; x <= xMax; x += puSize)
                    {
                        vertices.Add((x, yMin, zCenter));
                        vertices.Add((x, yMax, zCenter));
                    }
                    for (int y = yMin; y <= yMax; y += puSize)
                    {
                        vertices.Add((xMin, y, zCenter));
                        vertices.Add((xMax, y, zCenter));
                    }
                    return(vertices);
                }
                else if (Config.CurrentMapGraphics.MapViewPitchValue == 0 &&
                         (Config.CurrentMapGraphics.MapViewYawValue == 16384 ||
                          Config.CurrentMapGraphics.MapViewYawValue == 49152))
                {
                    List <(float x, float y, float z)> vertices = new List <(float x, float y, float z)>();
                    for (int z = zMin; z <= zMax; z += puSize)
                    {
                        vertices.Add((xCenter, yMin, z));
                        vertices.Add((xCenter, yMax, z));
                    }
                    for (int y = yMin; y <= yMax; y += puSize)
                    {
                        vertices.Add((zCenter, y, zMin));
                        vertices.Add((xCenter, y, zMax));
                    }
                    return(vertices);
                }
                else
                {
                    return(new List <(float x, float y, float z)>());
                }
            }

            case PuGridlineSetting.SETTING3:
            {
                float xCenter = Config.CurrentMapGraphics.MapViewCenterXValue;
                float zCenter = Config.CurrentMapGraphics.MapViewCenterZValue;
                int   xMin    = ((((int)Config.CurrentMapGraphics.MapViewXMin) / puSize) - 1) * puSize;
                int   xMax    = ((((int)Config.CurrentMapGraphics.MapViewXMax) / puSize) + 1) * puSize;
                int   yMin    = ((((int)Config.CurrentMapGraphics.MapViewYMin) / puSize) - 1) * puSize;
                int   yMax    = ((((int)Config.CurrentMapGraphics.MapViewYMax) / puSize) + 1) * puSize;
                int   zMin    = ((((int)Config.CurrentMapGraphics.MapViewZMin) / puSize) - 1) * puSize;
                int   zMax    = ((((int)Config.CurrentMapGraphics.MapViewZMax) / puSize) + 1) * puSize;

                if (Config.CurrentMapGraphics.MapViewPitchValue == 0 &&
                    (Config.CurrentMapGraphics.MapViewYawValue == 0 ||
                     Config.CurrentMapGraphics.MapViewYawValue == 32768))
                {
                    List <(float x, float y, float z)> vertices = new List <(float x, float y, float z)>();
                    for (int x = xMin; x <= xMax; x += puSize)
                    {
                        for (int y = yMin; y <= yMax; y += puSize)
                        {
                            float x1 = x - halfCourseSize;
                            float x2 = x + halfCourseSize;
                            float y1 = y - halfCourseSize;
                            float y2 = y + halfCourseSize;

                            vertices.Add((x1, y1, zCenter));
                            vertices.Add((x1, y2, zCenter));

                            vertices.Add((x2, y1, zCenter));
                            vertices.Add((x2, y2, zCenter));

                            vertices.Add((x1, y1, zCenter));
                            vertices.Add((x2, y1, zCenter));

                            vertices.Add((x1, y2, zCenter));
                            vertices.Add((x2, y2, zCenter));
                        }
                    }
                    return(vertices);
                }
                else if (Config.CurrentMapGraphics.MapViewPitchValue == 0 &&
                         (Config.CurrentMapGraphics.MapViewYawValue == 16384 ||
                          Config.CurrentMapGraphics.MapViewYawValue == 49152))
                {
                    List <(float x, float y, float z)> vertices = new List <(float x, float y, float z)>();
                    for (int z = zMin; z <= zMax; z += puSize)
                    {
                        for (int y = yMin; y <= yMax; y += puSize)
                        {
                            float z1 = z - halfCourseSize;
                            float z2 = z + halfCourseSize;
                            float y1 = y - halfCourseSize;
                            float y2 = y + halfCourseSize;

                            vertices.Add((xCenter, y1, z1));
                            vertices.Add((xCenter, y2, z1));

                            vertices.Add((xCenter, y1, z2));
                            vertices.Add((xCenter, y2, z2));

                            vertices.Add((xCenter, y1, z1));
                            vertices.Add((xCenter, y1, z2));

                            vertices.Add((xCenter, y2, z1));
                            vertices.Add((xCenter, y2, z2));
                        }
                    }
                    return(vertices);
                }
                else
                {
                    return(new List <(float x, float y, float z)>());
                }
            }

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Exemple #15
0
        private void ProcessSpecialVars()
        {
            var floorY = Config.Stream.GetSingle(Config.Mario.StructAddress + Config.Mario.FloorYOffset);

            // Get Mario position
            float marioX = Config.Stream.GetSingle(Config.Mario.StructAddress + Config.Mario.XOffset);
            float marioY = Config.Stream.GetSingle(Config.Mario.StructAddress + Config.Mario.YOffset);
            float marioZ = Config.Stream.GetSingle(Config.Mario.StructAddress + Config.Mario.ZOffset);

            marioX = PuUtilities.GetRelativePuPosition(marioX);
            marioY = PuUtilities.GetRelativePuPosition(marioY);
            marioZ = PuUtilities.GetRelativePuPosition(marioZ);

            float normX      = Config.Stream.GetSingle(TriangleAddress + Config.TriangleOffsets.NormX);
            float normY      = Config.Stream.GetSingle(TriangleAddress + Config.TriangleOffsets.NormY);
            float normZ      = Config.Stream.GetSingle(TriangleAddress + Config.TriangleOffsets.NormZ);
            float normOffset = Config.Stream.GetSingle(TriangleAddress + Config.TriangleOffsets.NormOffset);

            double uphillAngleRadians = Math.PI + Math.Atan2(normX, normZ);

            if (normX == 0 && normZ == 0)
            {
                uphillAngleRadians = double.NaN;
            }
            if (normY < -0.01)
            {
                uphillAngleRadians += Math.PI;
            }
            double downhillAngleRadians  = uphillAngleRadians + Math.PI;
            double lefthillAngleRadians  = uphillAngleRadians + Math.PI / 2;
            double righthillAngleRadians = uphillAngleRadians - Math.PI / 2;
            double uphillAngle           = MoreMath.RadiansToAngleUnits(uphillAngleRadians);
            double downhillAngle         = MoreMath.RadiansToAngleUnits(downhillAngleRadians);
            double lefthillAngle         = MoreMath.RadiansToAngleUnits(lefthillAngleRadians);
            double righthillAngle        = MoreMath.RadiansToAngleUnits(righthillAngleRadians);

            ushort marioAngle = Config.Stream.GetUInt16(Config.Mario.StructAddress + Config.Mario.YawFacingOffset);

            short v1X = Config.Stream.GetInt16(TriangleAddress + Config.TriangleOffsets.X1);
            short v1Y = Config.Stream.GetInt16(TriangleAddress + Config.TriangleOffsets.Y1);
            short v1Z = Config.Stream.GetInt16(TriangleAddress + Config.TriangleOffsets.Z1);
            short v2X = Config.Stream.GetInt16(TriangleAddress + Config.TriangleOffsets.X2);
            short v2Y = Config.Stream.GetInt16(TriangleAddress + Config.TriangleOffsets.Y2);
            short v2Z = Config.Stream.GetInt16(TriangleAddress + Config.TriangleOffsets.Z2);
            short v3X = Config.Stream.GetInt16(TriangleAddress + Config.TriangleOffsets.X3);
            short v3Y = Config.Stream.GetInt16(TriangleAddress + Config.TriangleOffsets.Y3);
            short v3Z = Config.Stream.GetInt16(TriangleAddress + Config.TriangleOffsets.Z3);

            var disToV = new double[]
            {
                Math.Pow(marioX - v1X, 2) + Math.Pow(marioY - v1Y, 2) + Math.Pow(marioZ - v1Z, 2),
                Math.Pow(marioX - v2X, 2) + Math.Pow(marioY - v2Y, 2) + Math.Pow(marioZ - v2Z, 2),
                Math.Pow(marioX - v3X, 2) + Math.Pow(marioY - v3Y, 2) + Math.Pow(marioZ - v3Z, 2)
            };

            _closestVertex = disToV.IndexOfMin() + 1;

            double angleMarioToV1 = MoreMath.AngleTo_AngleUnits(marioX, marioZ, v1X, v1Z);
            double angleV1ToMario = MoreMath.AngleTo_AngleUnits(v1X, v1Z, marioX, marioZ);
            double angleMarioToV2 = MoreMath.AngleTo_AngleUnits(marioX, marioZ, v2X, v2Z);
            double angleV2ToMario = MoreMath.AngleTo_AngleUnits(v2X, v2Z, marioX, marioZ);
            double angleMarioToV3 = MoreMath.AngleTo_AngleUnits(marioX, marioZ, v3X, v3Z);
            double angleV3ToMario = MoreMath.AngleTo_AngleUnits(v3X, v3Z, marioX, marioZ);

            foreach (IDataContainer specialVar in _specialWatchVars)
            {
                switch (specialVar.SpecialName)
                {
                case "DistanceAboveFloor":
                    (specialVar as DataContainer).Text = (marioY - floorY).ToString();
                    break;

                case "DistanceBelowCeiling":
                    (specialVar as DataContainer).Text = (Config.Stream.GetSingle(Config.Mario.StructAddress + Config.Mario.CeilingYOffset)
                                                          - marioY).ToString();
                    break;

                case "ClosestVertex":
                    (specialVar as DataContainer).Text = String.Format("V{0}", _closestVertex);
                    goto case "CheckTriangleExists";

                case "ClosestVertexX":
                    short coordX = 0;
                    switch (_closestVertex)
                    {
                    case 1:
                        coordX = v1X;
                        break;

                    case 2:
                        coordX = v2X;
                        break;

                    case 3:
                        coordX = v3X;
                        break;
                    }
                    (specialVar as DataContainer).Text = coordX.ToString();
                    goto case "CheckTriangleExists";

                case "ClosestVertexY":
                    short coordY = 0;
                    switch (_closestVertex)
                    {
                    case 1:
                        coordY = v1Y;
                        break;

                    case 2:
                        coordY = v2Y;
                        break;

                    case 3:
                        coordY = v3Y;
                        break;
                    }
                    (specialVar as DataContainer).Text = coordY.ToString();
                    goto case "CheckTriangleExists";

                case "ClosestVertexZ":
                    short coordZ = 0;
                    switch (_closestVertex)
                    {
                    case 1:
                        coordZ = v1Z;
                        break;

                    case 2:
                        coordZ = v2Z;
                        break;

                    case 3:
                        coordZ = v3Z;
                        break;
                    }
                    (specialVar as DataContainer).Text = coordZ.ToString();
                    goto case "CheckTriangleExists";

                case "UpHillAngle":
                    (specialVar as AngleDataContainer).AngleValue = uphillAngle;
                    goto case "CheckTriangleExistsAngle";

                case "DownHillAngle":
                    (specialVar as AngleDataContainer).AngleValue = downhillAngle;
                    goto case "CheckTriangleExistsAngle";

                case "LeftHillAngle":
                    (specialVar as AngleDataContainer).AngleValue = lefthillAngle;
                    goto case "CheckTriangleExistsAngle";

                case "RightHillAngle":
                    (specialVar as AngleDataContainer).AngleValue = righthillAngle;
                    goto case "CheckTriangleExistsAngle";

                case "UpHillDeltaAngle":
                    (specialVar as AngleDataContainer).AngleValue = marioAngle - uphillAngle;
                    goto case "CheckTriangleExistsAngle";

                case "DownHillDeltaAngle":
                    (specialVar as AngleDataContainer).AngleValue = marioAngle - downhillAngle;
                    goto case "CheckTriangleExistsAngle";

                case "LeftHillDeltaAngle":
                    (specialVar as AngleDataContainer).AngleValue = marioAngle - lefthillAngle;
                    goto case "CheckTriangleExistsAngle";

                case "RightHillDeltaAngle":
                    (specialVar as AngleDataContainer).AngleValue = marioAngle - righthillAngle;
                    goto case "CheckTriangleExistsAngle";

                case "Classification":
                    if (normY > 0.01)
                    {
                        (specialVar as DataContainer).Text = "Floor";
                    }
                    else if (normY < -0.01)
                    {
                        (specialVar as DataContainer).Text = "Ceiling";
                    }
                    else
                    {
                        (specialVar as DataContainer).Text = "Wall";
                    }
                    goto case "CheckTriangleExists";

                case "Steepness":
                    (specialVar as AngleDataContainer).AngleValue = MoreMath.RadiansToAngleUnits(Math.Acos(normY));
                    goto case "CheckTriangleExistsAngle";

                case "NormalDistAway":
                    (specialVar as DataContainer).Text = Math.Round(marioX * normX + marioY * normY + marioZ * normZ + normOffset, 3).ToString();
                    goto case "CheckTriangleExists";

                case "VerticalDistAway":
                    (specialVar as DataContainer).Text = Math.Round(marioY + (marioX * normX + marioZ * normZ + normOffset) / normY, 3).ToString();
                    goto case "CheckTriangleExists";

                case "HeightOnSlope":
                    (specialVar as DataContainer).Text = Math.Round((-marioX * normX - marioZ * normZ - normOffset) / normY, 3).ToString();
                    goto case "CheckTriangleExists";

                case "DistanceToV1":
                    (specialVar as DataContainer).Text = Math.Round(MoreMath.GetDistanceBetween(marioX, marioY, marioZ, v1X, v1Y, v1Z), 3).ToString();
                    goto case "CheckTriangleExists";

                case "YDistanceToV1":
                    (specialVar as DataContainer).Text = Math.Round(marioY - v1Y, 3).ToString();
                    goto case "CheckTriangleExists";

                case "XDistanceToV1":
                    (specialVar as DataContainer).Text = Math.Round(marioX - v1X, 3).ToString();
                    goto case "CheckTriangleExists";

                case "ZDistanceToV1":
                    (specialVar as DataContainer).Text = Math.Round(marioZ - v1Z, 3).ToString();
                    goto case "CheckTriangleExists";

                case "HDistanceToV1":
                    (specialVar as DataContainer).Text = Math.Round(MoreMath.GetDistanceBetween(marioX, marioZ, v1X, v1Z), 3).ToString();
                    goto case "CheckTriangleExists";

                case "DistanceToV2":
                    (specialVar as DataContainer).Text = Math.Round(MoreMath.GetDistanceBetween(marioX, marioY, marioZ, v2X, v2Y, v2Z), 3).ToString();
                    goto case "CheckTriangleExists";

                case "YDistanceToV2":
                    (specialVar as DataContainer).Text = Math.Round(marioY - v2Y, 3).ToString();
                    goto case "CheckTriangleExists";

                case "XDistanceToV2":
                    (specialVar as DataContainer).Text = Math.Round(marioX - v2X, 3).ToString();
                    goto case "CheckTriangleExists";

                case "ZDistanceToV2":
                    (specialVar as DataContainer).Text = Math.Round(marioZ - v2Z, 3).ToString();
                    goto case "CheckTriangleExists";

                case "HDistanceToV2":
                    (specialVar as DataContainer).Text = Math.Round(MoreMath.GetDistanceBetween(marioX, marioZ, v2X, v2Z), 3).ToString();
                    goto case "CheckTriangleExists";

                case "DistanceToV3":
                    (specialVar as DataContainer).Text = Math.Round(MoreMath.GetDistanceBetween(marioX, marioY, marioZ, v3X, v3Y, v3Z), 3).ToString();
                    goto case "CheckTriangleExists";

                case "YDistanceToV3":
                    (specialVar as DataContainer).Text = Math.Round(marioY - v3Y, 3).ToString();
                    goto case "CheckTriangleExists";

                case "XDistanceToV3":
                    (specialVar as DataContainer).Text = Math.Round(marioX - v3X, 3).ToString();
                    goto case "CheckTriangleExists";

                case "ZDistanceToV3":
                    (specialVar as DataContainer).Text = Math.Round(marioZ - v3Z, 3).ToString();
                    goto case "CheckTriangleExists";

                case "HDistanceToV3":
                    (specialVar as DataContainer).Text = Math.Round(MoreMath.GetDistanceBetween(marioX, marioZ, v3X, v3Z), 3).ToString();
                    goto case "CheckTriangleExists";

                case "DistanceToLine12":
                {
                    double signedDistToLine = MoreMath.GetSignedDistanceFromPointToLine(marioX, marioZ, v1X, v1Z, v2X, v2Z, v3X, v3Z, 1, 2);
                    (specialVar as DataContainer).Text = Math.Round(signedDistToLine, 3).ToString();
                }
                    goto case "CheckTriangleExists";

                case "DistanceToLine23":
                {
                    double signedDistToLine = MoreMath.GetSignedDistanceFromPointToLine(marioX, marioZ, v1X, v1Z, v2X, v2Z, v3X, v3Z, 2, 3);
                    (specialVar as DataContainer).Text = Math.Round(signedDistToLine, 3).ToString();
                }
                    goto case "CheckTriangleExists";

                case "DistanceToLine13":
                {
                    double signedDistToLine = MoreMath.GetSignedDistanceFromPointToLine(marioX, marioZ, v1X, v1Z, v2X, v2Z, v3X, v3Z, 3, 1);
                    (specialVar as DataContainer).Text = Math.Round(signedDistToLine, 3).ToString();
                }
                    goto case "CheckTriangleExists";

                case "AngleMarioToV1":
                    (specialVar as AngleDataContainer).AngleValue = angleMarioToV1;
                    goto case "CheckTriangleExistsAngle";

                case "DeltaAngleMarioToV1":
                    (specialVar as AngleDataContainer).AngleValue = marioAngle - angleMarioToV1;
                    goto case "CheckTriangleExistsAngle";

                case "AngleV1ToMario":
                    (specialVar as AngleDataContainer).AngleValue = angleV1ToMario;
                    goto case "CheckTriangleExistsAngle";

                case "AngleMarioToV2":
                    (specialVar as AngleDataContainer).AngleValue = angleMarioToV2;
                    goto case "CheckTriangleExistsAngle";

                case "DeltaAngleMarioToV2":
                    (specialVar as AngleDataContainer).AngleValue = marioAngle - angleMarioToV2;
                    goto case "CheckTriangleExistsAngle";

                case "AngleV2ToMario":
                    (specialVar as AngleDataContainer).AngleValue = angleV2ToMario;
                    goto case "CheckTriangleExistsAngle";

                case "AngleMarioToV3":
                    (specialVar as AngleDataContainer).AngleValue = angleMarioToV3;
                    goto case "CheckTriangleExistsAngle";

                case "DeltaAngleMarioToV3":
                    (specialVar as AngleDataContainer).AngleValue = marioAngle - angleMarioToV3;
                    goto case "CheckTriangleExistsAngle";

                case "AngleV3ToMario":
                    (specialVar as AngleDataContainer).AngleValue = angleV3ToMario;
                    goto case "CheckTriangleExistsAngle";

                case "AngleV1ToV2":
                    (specialVar as AngleDataContainer).AngleValue = MoreMath.AngleTo_AngleUnits(v1X, v1Z, v2X, v2Z);
                    goto case "CheckTriangleExistsAngle";

                case "AngleV2ToV1":
                    (specialVar as AngleDataContainer).AngleValue = MoreMath.AngleTo_AngleUnits(v2X, v2Z, v1X, v1Z);
                    goto case "CheckTriangleExistsAngle";

                case "AngleV2ToV3":
                    (specialVar as AngleDataContainer).AngleValue = MoreMath.AngleTo_AngleUnits(v2X, v2Z, v3X, v3Z);
                    goto case "CheckTriangleExistsAngle";

                case "AngleV3ToV2":
                    (specialVar as AngleDataContainer).AngleValue = MoreMath.AngleTo_AngleUnits(v3X, v3Z, v2X, v2Z);
                    goto case "CheckTriangleExistsAngle";

                case "AngleV1ToV3":
                    (specialVar as AngleDataContainer).AngleValue = MoreMath.AngleTo_AngleUnits(v1X, v1Z, v3X, v3Z);
                    goto case "CheckTriangleExistsAngle";

                case "AngleV3ToV1":
                    (specialVar as AngleDataContainer).AngleValue = MoreMath.AngleTo_AngleUnits(v3X, v3Z, v1X, v1Z);
                    goto case "CheckTriangleExistsAngle";

                case "ObjectTriCount":
                    (specialVar as DataContainer).Text =
                        (Config.Stream.GetInt32(Config.Triangle.TotalTriangleCountAddress) - Config.Stream.GetInt32(Config.Triangle.LevelTriangleCountAddress)).ToString();
                    break;

                case "ObjectNodeCount":
                    (specialVar as DataContainer).Text =
                        (Config.Stream.GetInt32(Config.Triangle.TotalNodeCountAddress) - Config.Stream.GetInt32(Config.Triangle.LevelNodeCountAddress)).ToString();
                    break;

                // Special
                case "CheckTriangleExists":
                    if (TriangleAddress == 0x0000)
                    {
                        (specialVar as DataContainer).Text = "(none)";
                        break;
                    }
                    break;

                case "CheckTriangleExistsAngle":
                    (specialVar as AngleDataContainer).ValueExists = (TriangleAddress != 0);
                    break;
                }
            }
        }
Exemple #16
0
        public static (float x, float z) ConvertCoordsForControlOrthographicView(float rawX, float rawY, float rawZ, bool useRelativeCoordinates)
        {
            float x = rawX;
            float y = rawY;
            float z = rawZ;

            if (useRelativeCoordinates)
            {
                x = (float)PuUtilities.GetRelativeCoordinate(rawX);
                y = (float)PuUtilities.GetRelativeCoordinate(rawY);
                z = (float)PuUtilities.GetRelativeCoordinate(rawZ);
            }
            float  xOffset      = x - Config.CurrentMapGraphics.MapViewCenterXValue;
            float  yOffset      = y - Config.CurrentMapGraphics.MapViewCenterYValue;
            float  zOffset      = z - Config.CurrentMapGraphics.MapViewCenterZValue;
            double angleRadians = MoreMath.AngleUnitsToRadians(Config.CurrentMapGraphics.MapViewYawValue);
            float  hOffset      = (float)(Math.Sin(angleRadians) * zOffset - Math.Cos(angleRadians) * xOffset);

            (double x0, double y0, double z0, double t0) =
                MoreMath.GetPlaneLineIntersection(
                    Config.CurrentMapGraphics.MapViewCenterXValue,
                    Config.CurrentMapGraphics.MapViewCenterYValue,
                    Config.CurrentMapGraphics.MapViewCenterZValue,
                    Config.CurrentMapGraphics.MapViewYawValue,
                    Config.CurrentMapGraphics.MapViewPitchValue,
                    x, y, z,
                    Config.CurrentMapGraphics.MapViewYawValue,
                    Config.CurrentMapGraphics.MapViewPitchValue);
            double rightYaw = MoreMath.RotateAngleCW(
                Config.CurrentMapGraphics.MapViewYawValue, 16384);

            (double x1, double y1, double z1, double t1) =
                MoreMath.GetPlaneLineIntersection(
                    x0, y0, z0, rightYaw, 0,
                    Config.CurrentMapGraphics.MapViewCenterXValue,
                    Config.CurrentMapGraphics.MapViewCenterYValue,
                    Config.CurrentMapGraphics.MapViewCenterZValue,
                    rightYaw, 0);
            double hDiff            = MoreMath.GetDistanceBetween(x1, z1, x0, z0);
            double yDiff            = y1 - y0;
            double yDiffSign        = yDiff >= 0 ? 1 : -1;
            double vOffsetMagnitude = MoreMath.GetHypotenuse(hDiff, yDiff);
            float  vOffset          = (float)(vOffsetMagnitude * yDiffSign);

            float hOffsetPixels = hOffset * Config.CurrentMapGraphics.MapViewScaleValue;
            float vOffsetPixels = vOffset * Config.CurrentMapGraphics.MapViewScaleValue;
            float centerH       = Config.MapGui.CurrentControl.Width / 2 + hOffsetPixels;
            float centerV       = Config.MapGui.CurrentControl.Height / 2 + vOffsetPixels;

            if (Config.CurrentMapGraphics.MapViewPitchValue == 0 && float.IsInfinity(rawX))
            {
                float yOffsetPixels = yOffset * Config.CurrentMapGraphics.MapViewScaleValue;
                float centerY       = Config.MapGui.CurrentControl.Height / 2 - yOffsetPixels;
                if (float.IsNegativeInfinity(rawX))
                {
                    return(0, centerY);
                }
                else
                {
                    return(Config.MapGui.CurrentControl.Width, centerY);
                }
            }

            return(centerH, centerV);
        }