public GameScreen()
 {
     RacingGameManager.LoadLevel(TrackSelection.SelectedTrack);
     RacingGameManager.Player.Reset();
     BaseGame.LightDirection = LensFlare.DefaultLightPos;
     Sound.StartGearSound();
     Sound.Play(Sound.Sounds.GameMusic);
 }
Beispiel #2
0
        public GamePage()
        {
            this.InitializeComponent();

            // Create the game.
            var launchArguments = string.Empty;

            _game = MonoGame.Framework.XamlGame <RacingGameManager> .Create(launchArguments, Window.Current.CoreWindow, swapChainPanel);
        }
        /// <summary>
        /// Create game screen
        /// </summary>
        public GameScreen()
        {
            // Load level
            RacingGameManager.LoadLevel(TrackSelection.SelectedTrack);

            // Reset player variables (start new game, reset time and position)
            RacingGameManager.Player.Reset();

            // Fix light direction (was changed by CarSelection screen!)
            // LightDirection will normalize
            BaseGame.LightDirection = LensFlare.DefaultLightPos;

            // Start gear sound
            Sound.StartGearSound();

            // Play game music
            Sound.Play(Sound.Sounds.GameMusic);
        }
        /// <summary>
        /// Create game screen
        /// </summary>
        public GameScreen(RacingGameManager.Level mapName)
        {
            // Load level
            RacingGameManager.LoadLevel(mapName);

            // Reset player variables (start new game, reset time and position)
            RacingGameManager.Player.Reset();

            // Fix light direction (was changed by CarSelection screen!)
            // LightDirection will normalize
            BaseGame.LightDirection = LensFlare.DefaultLightPos;

            // Start gear sound
            Sound.StartGearSound();

            // Play game music
            Sound.Play(Sound.Sounds.GameMusic);

            RacingGameManager.InputInterface.Escape += InputInterface_Escape;
        }
Beispiel #5
0
        // Rest of car variables is automatically calculated below!
        #endregion

        #region Render
        /// <summary>
        /// Render
        /// </summary>
        /// <returns>Bool</returns>
        public bool Render()
        {
            if (BaseGame.AllowShadowMapping)
            {
                // Let camera point directly at the center, around 10 units away.
                BaseGame.ViewMatrix = Matrix.CreateLookAt(
                    new Vector3(0, 10.45f, 2.75f),
                    new Vector3(0, 0, -1),
                    new Vector3(0, 0, 1));

                // Let the light come from the front!
                Vector3 lightDir = -LensFlare.DefaultLightPos;
                lightDir = new Vector3(lightDir.X, lightDir.Y, -lightDir.Z);
                // LightDirection will normalize
                BaseGame.LightDirection = lightDir;

                // Show 3d cars
                // Rotate all 3 cars depending on the current selection
                float perCarRot = MathHelper.Pi * 2.0f / 3.0f;
                float newCarSelectionRotationZ =
                    RacingGameManager.currentCarNumber * perCarRot;
                carSelectionRotationZ = InterpolateRotation(
                    carSelectionRotationZ, newCarSelectionRotationZ,
                    BaseGame.MoveFactorPerSecond * 5.0f);
                // Prebuild all render matrices, we will use them for several times
                // here.
                Matrix[] renderMatrices = new Matrix[3];
                for (int carNum = 0; carNum < 3; carNum++)
                {
                    renderMatrices[carNum] =
                        Matrix.CreateRotationZ(BaseGame.TotalTime / 3.9f) *
                        Matrix.CreateTranslation(new Vector3(0, 5.0f, 0)) *
                        Matrix.CreateRotationZ(-carSelectionRotationZ + carNum * perCarRot) *
                        Matrix.CreateTranslation(new Vector3(1.5f, 0.0f, 1.0f));
                }
                // Last translation translates the position of the cars in the UI;

                // For shadows make sure the car position is the origin
                RacingGameManager.Player.SetCarPosition(Vector3.Zero,
                                                        new Vector3(0, 1, 0), new Vector3(0, 0, 1));

                // Generate shadows
                ShaderEffect.shadowMapping.GenerateShadows(
                    delegate
                {
                    for (int carNum = 0; carNum < 3; carNum++)
                    {
                        // Only the car throws shadows
                        RacingGameManager.CarModel.GenerateShadow(
                            renderMatrices[carNum]);
                    }
                });

                // Render shadows
                ShaderEffect.shadowMapping.RenderShadows(
                    delegate
                {
                    for (int carNum = 0; carNum < 3; carNum++)
                    {
                        // Both the car and the selection plate receive shadows
                        RacingGameManager.CarSelectionPlate.UseShadow(
                            renderMatrices[carNum]);
                        RacingGameManager.CarModel.UseShadow(renderMatrices[carNum]);
                    }
                });
            }

            // This starts both menu and in game post screen shader!
            // It will render into the sceneMap texture which we will use
            // later then.
            BaseGame.UI.PostScreenMenuShader.Start();

            // Render background and black bar
            BaseGame.UI.RenderMenuBackground();
            BaseGame.UI.RenderBlackBar(170, 390);

            // Immediately paint here, else post screen UI will
            // be drawn over!
            Texture.additiveSprite.End();
            Texture.alphaSprite.End();
            //SpriteHelper.DrawAllSprites();

            // Restart the sprites after the paint
            Texture.additiveSprite.Begin(SpriteBlendMode.Additive);
            Texture.alphaSprite.Begin(SpriteBlendMode.AlphaBlend);

            // Cars header
            int posX = 10;
            int posY = 18;

            if (Environment.OSVersion.Platform != PlatformID.Win32NT)
            {
                posX += 36;
                posY += 26;
            }

            BaseGame.UI.Headers.RenderOnScreenRelative1600(
                posX, posY, UIRenderer.HeaderChooseCarGfxRect);

            // Allow selecting the car color
            TextureFont.WriteText(BaseGame.XToRes(85), BaseGame.YToRes(512),
                                  "Car Color: ");
            for (int num = 0; num < RacingGameManager.CarColors.Count; num++)
            {
                Rectangle rect =
                    RacingGameManager.currentCarColor == num?
                    BaseGame.CalcRectangle(250 + num * 50 - 6, 500 - 6, 46 + 12, 46 + 12) :
                        BaseGame.CalcRectangle(250 + num * 50, 500, 46, 46);

                RacingGameManager.colorSelectionTexture.RenderOnScreen(
                    rect, RacingGameManager.colorSelectionTexture.GfxRectangle,
                    RacingGameManager.CarColors[num]);

                if (Input.MouseInBox(rect) &&
                    Input.MouseLeftButtonPressed)
                {
                    if (RacingGameManager.currentCarColor != num)
                    {
                        Sound.Play(Sound.Sounds.Highlight);
                    }
                    RacingGameManager.currentCarColor = num;
                }
            }

            // Show car maxSpeed, Acceleration and Mass values.
            // Also show braking, friction and engine values based on that.
            CarPhysics.SetCarVariablesForCarType(
                CarTypeMaxSpeed[RacingGameManager.currentCarNumber],
                CarTypeMass[RacingGameManager.currentCarNumber],
                CarTypeMaxAcceleration[RacingGameManager.currentCarNumber]);

            // Show info and helper texts
            //TextureFont.WriteText(30, BaseGame.YToRes(280),
            //    "Car: Left/Right");
            //TextureFont.WriteText(30, BaseGame.YToRes(370),
            //    "Color: Up/Down");

            // Calculate values
            float maxSpeed =
                -1.5f + 2.45f *
                (CarTypeMaxSpeed[RacingGameManager.currentCarNumber] /
                 CarPhysics.DefaultMaxSpeed);
            float acceleration =
                -1.25f + 1.85f *
                (CarTypeMaxAcceleration[RacingGameManager.currentCarNumber] /
                 CarPhysics.DefaultMaxAccelerationPerSec);
            float mass =
                -0.65f + 1.5f *
                (CarTypeMass[RacingGameManager.currentCarNumber] /
                 CarPhysics.DefaultCarMass);
            float braking =
                -0.2f + acceleration - mass + maxSpeed;
            float friction =
                -1 + (1 / mass + maxSpeed / 5);
            float engine =
                -0.2f + 0.5f * (maxSpeed / mass + acceleration - maxSpeed * 5 + 5);

            if (engine > 0.95f)
            {
                engine = 0.95f;
            }

            ShowCarPropertyBar(
                BaseGame.XToRes(1024 - 258), BaseGame.YToRes(190),
                "Max Speed: " +
                (int)(CarTypeMaxSpeed[RacingGameManager.currentCarNumber] /
                      CarPhysics.MphToMeterPerSec) + "mph",
                maxSpeed);
            ShowCarPropertyBar(
                BaseGame.XToRes(1024 - 258), BaseGame.YToRes(235),
                "Acceleration:", acceleration);
            ShowCarPropertyBar(
                BaseGame.XToRes(1024 - 258), BaseGame.YToRes(280),
                "Car Mass:",
                mass);
            ShowCarPropertyBar(
                BaseGame.XToRes(1024 - 258), BaseGame.YToRes(335),
                "Braking:", braking);
            ShowCarPropertyBar(
                BaseGame.XToRes(1024 - 258), BaseGame.YToRes(390),
                "Friction:", friction);
            ShowCarPropertyBar(
                BaseGame.XToRes(1024 - 258), BaseGame.YToRes(445),
                "Engine:", engine);

            // Also show bouncing arrow on top of car
            float arrowWave =
                (float)Math.Sin(BaseGame.TotalTime / 0.46f) *
                (float)Math.Cos(BaseGame.TotalTime / 0.285f);
            float     arrowScale = 0.75f - 0.065f * arrowWave;
            Rectangle arrowRect  = BaseGame.CalcRectangle(512, 120,
                                                          (int)Math.Round(UIRenderer.BigArrowGfxRect.Width * arrowScale),
                                                          (int)Math.Round(UIRenderer.BigArrowGfxRect.Width * arrowScale));

            arrowRect.X -= arrowRect.Width / 2;
            // Not displayed anymore ..

            // Show left/right arrows
            Rectangle selArrowGfxRect = UIRenderer.SelectionArrowGfxRect;
            Rectangle leftRect        = BaseGame.CalcRectangle(35, 250,
                                                               selArrowGfxRect.Width, selArrowGfxRect.Height);

            leftRect.Y  = BaseGame.YToRes(300 + 60) + arrowRect.Y / 3;
            leftRect.X += (int)Math.Round(BaseGame.XToRes(12) * arrowWave);
            BaseGame.UI.Buttons.RenderOnScreen(
                leftRect, new Rectangle(selArrowGfxRect.X + selArrowGfxRect.Width,
                                        selArrowGfxRect.Y, -selArrowGfxRect.Width, selArrowGfxRect.Height));

            Rectangle rightRect = BaseGame.CalcRectangle(
                1024 - 335 - selArrowGfxRect.Width, 250,
                selArrowGfxRect.Width, selArrowGfxRect.Height);

            rightRect.Y  = BaseGame.YToRes(300 + 60) + arrowRect.Y / 3;
            rightRect.X -= (int)Math.Round(BaseGame.XToRes(12) * arrowWave);
            BaseGame.UI.Buttons.RenderOnScreen(
                rightRect, UIRenderer.SelectionArrowGfxRect);

            // Also handle xbox controller input
            if (Input.GamePadLeftJustPressed ||
                Input.KeyboardLeftJustPressed ||
                Input.MouseLeftButtonJustPressed &&
                Input.MouseInBoxRelative(new Rectangle(512 + 50, 170, 512 - 150, 135)))
            {
                Sound.Play(Sound.Sounds.Highlight);
                RacingGameManager.currentCarNumber =
                    (RacingGameManager.currentCarNumber + 1) % 3;
            }
            else if (Input.GamePadRightJustPressed ||
                     Input.KeyboardRightJustPressed ||
                     Input.MouseLeftButtonJustPressed &&
                     Input.MouseInBoxRelative(new Rectangle(100, 170, 512 - 200, 135)))
            {
                Sound.Play(Sound.Sounds.Highlight);
                RacingGameManager.currentCarNumber =
                    (RacingGameManager.currentCarNumber + 2) % 3;
            }

            // Mouse input is handled in RacingGameManager.cs
            if (Input.GamePadUpJustPressed ||
                Input.KeyboardUpJustPressed)
            {
                Sound.Play(Sound.Sounds.Highlight);
                RacingGameManager.currentCarColor = (RacingGameManager.currentCarColor +
                                                     RacingGameManager.NumberOfCarColors - 1) %
                                                    RacingGameManager.NumberOfCarColors;
            }
            else if (Input.GamePadDownJustPressed ||
                     Input.KeyboardDownJustPressed)
            {
                Sound.Play(Sound.Sounds.Highlight);
                RacingGameManager.currentCarColor =
                    (RacingGameManager.currentCarColor + 1) %
                    RacingGameManager.NumberOfCarColors;
            }

            bool aButtonPressed = BaseGame.UI.RenderBottomButtons(false);

            if (Input.GamePadAJustPressed ||
                Input.KeyboardSpaceJustPressed ||
                aButtonPressed)
            {
                RacingGameManager.AddGameScreen(new TrackSelection());
                return(false);
            }

            if (Input.KeyboardEscapeJustPressed ||
                Input.GamePadBJustPressed ||
                Input.GamePadBackJustPressed ||
                BaseGame.UI.backButtonPressed)
            {
                return(true);
            }

            return(false);
        }
Beispiel #6
0
        /// <summary>
        /// Render
        /// </summary>
        /// <returns>Bool</returns>
        public bool Render()
        {
            // This starts both menu and in game post screen shader!
            if (BaseGame.UsePostScreenShaders)
            {
                BaseGame.UI.PostScreenMenuShader.Start();
            }

            // Render background and black bar
            BaseGame.UI.RenderMenuBackground();
            BaseGame.UI.RenderBlackBar(280, 192);

            // Show logos
            // Little helper to keep track if mouse is actually over a button.
            // Required because buttons are selected even when not hovering over
            // them for GamePad support, but we still want the mouse only to
            // be apply when we are actually over the button.
            int mouseIsOverButton = -1;

            // If the user manipulated the mouse, stop ignoring the mouse
            // This allows the mouse to override the game pad or keyboard selection
            if (Input.HasMouseMoved || Input.MouseLeftButtonJustPressed)
            {
                ignoreMouse = false;
            }

            // Show buttons
            // Part 1: Calculate global variables for our buttons
            Rectangle activeRect = BaseGame.CalcRectangleCenteredWithGivenHeight(
                0, 0, ActiveButtonWidth, ButtonRects[0]);
            Rectangle inactiveRect = BaseGame.CalcRectangleCenteredWithGivenHeight(
                0, 0, InactiveButtonWidth, ButtonRects[0]);
            int totalWidth = activeRect.Width +
                             (NumberOfButtons - 1) * inactiveRect.Width +
                             (NumberOfButtons - 1) * BaseGame.XToRes(DistanceBetweenButtons);
            int xPos = BaseGame.XToRes(512) - totalWidth / 2;
            int yPos = BaseGame.YToRes(316);

            for (int num = 0; num < NumberOfButtons; num++)
            {
                // Is this button currently selected?
                bool selected = num == SelectedButton;

                // Increase size if selected, decrease otherwise
                currentButtonSizes[num] +=
                    (selected ? 1 : -1) * BaseGame.MoveFactorPerSecond * 2;
                if (currentButtonSizes[num] < 0)
                {
                    currentButtonSizes[num] = 0;
                }
                if (currentButtonSizes[num] > 1)
                {
                    currentButtonSizes[num] = 1;
                }

                // Use this size to build rect
                Rectangle thisRect =
                    InterpolateRect(activeRect, inactiveRect, currentButtonSizes[num]);
                Rectangle renderRect = new Rectangle(
                    xPos, yPos - (thisRect.Height - inactiveRect.Height) / 2,
                    thisRect.Width, thisRect.Height);
                BaseGame.UI.Buttons.RenderOnScreen(renderRect, ButtonRects[num],
                                                   selected ? Color.White : new Color(192, 192, 192, 192));

                // Add border effect if selected
                if (selected)
                {
                    BaseGame.UI.Buttons.RenderOnScreen(renderRect,
                                                       UIRenderer.MenuButtonSelectionGfxRect);
                }

                // Also add text below button
                Rectangle textRenderRect = new Rectangle(
                    xPos, renderRect.Bottom + BaseGame.YToRes(5),
                    renderRect.Width,
                    renderRect.Height * TextRects[0].Height / ButtonRects[0].Height);
                if (selected)
                {
                    BaseGame.UI.Buttons.RenderOnScreen(textRenderRect, TextRects[num],
                                                       selected ? Color.White : new Color(192, 192, 192, 192));
                }

                // Also check if the user hovers with the mouse over this button
                if (Input.MouseInBox(renderRect))
                {
                    mouseIsOverButton = num;
                }

                xPos += thisRect.Width + BaseGame.XToRes(DistanceBetweenButtons);
            }

            if (!ignoreMouse && mouseIsOverButton >= 0)
            {
                SelectedButton = mouseIsOverButton;
            }

            // Handle input, we have 2 modes: Immediate response if one of the
            // keys is pressed to move our selected menu entry and after a timeout we
            // move even more. Controlling feels more natural this way.
            if (Input.KeyboardLeftPressed ||
                Input.GamePadLeftPressed)
            {
                pressedLeftMs += BaseGame.ElapsedTimeThisFrameInMilliseconds;
            }
            else
            {
                pressedLeftMs = 0;
            }
            if (Input.KeyboardRightPressed ||
                Input.GamePadRightPressed)
            {
                pressedRightMs += BaseGame.ElapsedTimeThisFrameInMilliseconds;
            }
            else
            {
                pressedRightMs = 0;
            }

            // Handle GamePad input, and also allow keyboard input
            if (Input.GamePadLeftJustPressed ||
                Input.KeyboardLeftJustPressed ||
                (pressedLeftMs > 250 &&
                 (Input.KeyboardLeftPressed ||
                  Input.GamePadLeftPressed)))
            {
                pressedLeftMs -= 250;
                Sound.Play(Sound.Sounds.Highlight);
                SelectedButton =
                    (SelectedButton + NumberOfButtons - 1) % NumberOfButtons;
                ignoreMouse = true;
            }
            else if (Input.GamePadRightJustPressed ||
                     Input.KeyboardRightJustPressed ||
                     (pressedRightMs > 250 &&
                      (Input.KeyboardRightPressed ||
                       Input.GamePadRightPressed)))
            {
                pressedRightMs -= 250;
                Sound.Play(Sound.Sounds.Highlight);
                SelectedButton = (SelectedButton + 1) % NumberOfButtons;
                ignoreMouse    = true;
            }

            // If user presses the mouse button or the game pad A or Space,
            // start the game screen for the currently selected game part.
            if ((mouseIsOverButton >= 0 && Input.MouseLeftButtonJustPressed) ||
                Input.GamePadAJustPressed ||
                Input.KeyboardSpaceJustPressed)
            {
                idleTime = 0.0f;

                // Start game screen
                switch (SelectedButton)
                {
                case 0:
                    RacingGameManager.AddGameScreen(new CarSelection());
                    break;

                case 1:
                    RacingGameManager.AddGameScreen(new Highscores());
                    break;

                case 2:
                    RacingGameManager.AddGameScreen(new Options());
                    break;

                case 3:
                    RacingGameManager.AddGameScreen(new Help());
                    break;

                case 4:
                    // Exit
                    return(true);
                }
            }

            if (Input.KeyboardEscapeJustPressed ||
                Input.GamePadBackJustPressed)
            {
                return(true);
            }

            // If the game sits idle at the menu for too long,
            // return to the splash screen
            idleTime += BaseGame.ElapsedTimeThisFrameInMilliseconds;
            if (idleTime > TimeOutMenu)
            {
                idleTime = 0.0f;
                RacingGameManager.AddGameScreen(new SplashScreen());
            }

            return(false);
        }
Beispiel #7
0
        /// <summary>
        /// Render car model with this seperate method because we
        /// render it in 2 steps, first the solid stuff, then the alpha glass.
        /// We also rotate the wheels around :)
        /// </summary>
        /// <param name="carNumber">Car type number (0, 1 or 2) for the car
        /// texture</param>
        /// <param name="carColor">Car color we are currently using.</param>
        /// <param name="shadowCarMode">In the shadow car mode we render
        /// everything (including wheels and glass) with a special ShadowCar
        /// shader, that is very transparent. Used for the shadow car when
        /// playing that shows how we drove the last time.</param>
        /// <param name="renderMatrix">Render matrix for the car</param>
        public void RenderCar(int carNumber, Color carColor, bool shadowCarMode,
                              Matrix renderMatrix)
        {
            // Multiply object matrix by render matrix, result is used multiple
            // times here.
            renderMatrix = objectMatrix * renderMatrix;

            // Do we just want to render the shadow car? Then do this in a
            // simpified way here instead of messing with the already complicated
            // code below.
            if (shadowCarMode)
            {
                // Start shadow car shader
                ShaderEffect simpleShader = ShaderEffect.lighting;
                simpleShader.Render(
                    "ShadowCar",
                    delegate
                {
                    int wheelNumber = 0;
                    // And just render all meshes with it!
                    for (int meshNum = 0; meshNum < xnaModel.Meshes.Count; meshNum++)
                    {
                        ModelMesh mesh = xnaModel.Meshes[meshNum];

                        Matrix meshMatrix = transforms[mesh.ParentBone.Index];

                        // Only the wheels have 2 mesh parts (gummi and chrome)
                        if (mesh.MeshParts.Count == 2)
                        {
                            wheelNumber++;
                            meshMatrix =
                                Matrix.CreateRotationX(
                                    // Rotate left 2 wheels forward, the other 2 backward
                                    (wheelNumber == 2 || wheelNumber == 4 ? 1 : -1) *
                                    RacingGameManager.Player.CarWheelPos) *
                                meshMatrix;
                        }

                        // Assign world matrix
                        BaseGame.WorldMatrix =
                            meshMatrix *
                            renderMatrix;

                        // Set all matrices
                        simpleShader.SetParameters();
                        simpleShader.Update();

                        // And render (must be done without mesh.Draw, which would
                        // just use the original shaders for the model)
                        for (int partNum = 0; partNum < mesh.MeshParts.Count; partNum++)
                        {
                            ModelMeshPart part = mesh.MeshParts[partNum];
                            // Make sure vertex declaration is correct
                            // Set vertex buffer and index buffer
                            BaseGame.Device.SetVertexBuffer(part.VertexBuffer);
                            BaseGame.Device.Indices = part.IndexBuffer;

                            // And render all primitives
                            BaseGame.Device.DrawIndexedPrimitives(
                                PrimitiveType.TriangleList,
                                part.VertexOffset, 0, part.NumVertices,
                                part.StartIndex, part.PrimitiveCount);
                        }
                    }
                });

                // And get outta here
                return;
            }

            // Usually use default color values
            Color ambientColor = Material.DefaultAmbientColor;
            Color diffuseColor = Material.DefaultDiffuseColor;


            EffectTechnique remCurrentTechnique = null;

            for (int alphaPass = 0; alphaPass < 2; alphaPass++)
            {
                int wheelNumber = 0;

                int effectParameterIndex = 0;
                int effectTechniqueIndex = 0;

                for (int meshNum = 0; meshNum < xnaModel.Meshes.Count; meshNum++)
                {
                    ModelMesh mesh       = xnaModel.Meshes[meshNum];
                    bool      dontRender = false;

                    for (int effectNum = 0; effectNum < mesh.Effects.Count; effectNum++)
                    {
                        Effect effect = mesh.Effects[effectNum];
                        if (effectNum == 0)
                        {
                            remCurrentTechnique = effect.CurrentTechnique;
                        }

                        // Find out if this is ReflectionSimpleGlass.fx,
                        // NormalMapping.fx will also use reflection, but the techniques
                        // are named in another way (SpecularWithReflection, etc.)
                        if (cachedIsReflectionSpecularTechnique[effectTechniqueIndex++])
                        {
                            if (alphaPass == 0)
                            {
                                dontRender            = true;
                                effectParameterIndex += 7;
                                break;
                            }

                            // Skip the first 3 effect parameters
                            effectParameterIndex += 3;
                        }
                        else
                        {
                            if (alphaPass == 1)
                            {
                                dontRender            = true;
                                effectParameterIndex += 7;
                                break;
                            }

                            // To improve performance we only have to set this when it
                            // changes! Doesn't do much, because this eats only 10%
                            // performance, 5-10% are the matrices below and most of the
                            // performance is just rendering the car with Draw!

                            // Overwrite car diffuse textures depending on the car number
                            // we want to render.
                            cachedEffectParameters[effectParameterIndex++].SetValue(
                                RacingGameManager.CarTexture(carNumber).XnaTexture);

                            // Also set color
                            cachedEffectParameters[effectParameterIndex++].SetValue(
                                ambientColor.ToVector4());
                            cachedEffectParameters[effectParameterIndex++].SetValue(
                                diffuseColor.ToVector4());

                            // Change shader to
                            // VertexOutput_SpecularWithReflectionForCar20
                            // if we changed the color.
                            if (RacingGameManager.currentCarColor != 0 &&
                                effectNum == 0)
                            {
                                effect.CurrentTechnique =
                                    effect.Techniques["SpecularWithReflectionForCar20"];
                                // And set carHueColorChange
                                effect.Parameters["carHueColor"].SetValue(
                                    carColor.ToVector3());
                            }
                        }

                        Matrix meshMatrix = transforms[mesh.ParentBone.Index];

                        // Only the wheels have 2 mesh parts (gummi and chrome)
                        if (mesh.MeshParts.Count == 2)
                        {
                            wheelNumber++;
                            meshMatrix =
                                Matrix.CreateRotationX(
                                    // Rotate left 2 wheels forward, the other 2 backward!
                                    (wheelNumber == 2 || wheelNumber == 4 ? 1 : -1) *
                                    RacingGameManager.Player.CarWheelPos) *
                                meshMatrix;
                        }

                        // Assign world matrix
                        BaseGame.WorldMatrix =
                            meshMatrix *
                            renderMatrix;

                        // Set matrices
                        cachedEffectParameters[effectParameterIndex++].SetValue(
                            BaseGame.WorldMatrix);

                        // These values should only be set once every frame (see above)!
                        // to improve performance again, also we should access them
                        // with EffectParameter and not via name!
                        // But since we got only 1 car it doesn't matter so much ..
                        cachedEffectParameters[effectParameterIndex++].SetValue(
                            BaseGame.ViewProjectionMatrix);
                        cachedEffectParameters[effectParameterIndex++].SetValue(
                            BaseGame.InverseViewMatrix);
                        // Set light direction
                        cachedEffectParameters[effectParameterIndex++].SetValue(
                            BaseGame.LightDirection);
                    }

                    // Render
                    if (dontRender == false)
                    {
                        mesh.Draw();
                    }

                    // Change shader back to default render technique.
                    // We only have to do this if the color was changed
                    if (RacingGameManager.currentCarColor != 0 &&
                        remCurrentTechnique != null)
                    {
                        mesh.Effects[0].CurrentTechnique = remCurrentTechnique;
                    }
                }
            }
        }
Beispiel #8
0
        /// <summary>
        /// Create landscape.
        /// This constructor should only be called
        /// from the RacingGame main class!
        /// </summary>
        /// <param name="setLevel">Level we want to load</param>
        internal Landscape(RacingGameManager.Level setLevel)
        {
            #region Load map height data
            #if OBS_DOESNT_WORK_ON_XBOX360
            // Ok, load map grid heights. We can't load this as a Bitmap
            // because we don't have the System.Drawing namespace in XNA.
            // We also can't use BitmapContent or PixelBitmapContent<Color> from
            // the Microsoft.XNA.Framework.Content.Pipeline namespace because
            // our content is not compatible with that (its just a texture).
            Texture2D tex =
                BaseGame.Content.Load<Texture2D>(
                Path.Combine(Directories.ContentDirectory, "LandscapeGridHeights"));
            /*old
                Texture2D.FromFile(BaseGame.Device,
                "Textures\\LandscapeGridHeights.png");
             */

            if (tex.Width != GridWidth ||
                tex.Height != GridHeight)
                throw new Exception(tex.Name + " has the resolution of " +
                    tex.Width + "x" + tex.Height + ", but for the landscape we need " +
                    GridWidth + "x" + GridHeight + "!");

            // With help of GetData we can get to the data.
            Color[] texData = new Color[GridWidth * GridHeight];
            tex.GetData<Color>(texData, 0, GridWidth * GridHeight);
            //tst: Log.Write("Pixel 0, 0=" + texData[0]);
            #endif
            FileStream file = FileHelper.LoadGameContentFile(
                "Content\\"+LandscapeHeightsDataFilename);
            byte[] heights = new byte[GridWidth * GridHeight];
            file.Read(heights, 0, GridWidth*GridHeight);
            file.Close();

            mapHeights = new float[GridWidth, GridHeight];
            #endregion

            #region Build tangent vertices
            // Build our tangent vertices
            for (int x = 0; x < GridWidth; x++)
                for (int y = 0; y < GridHeight; y++)
                {
                    // Step 1: Calculate position
                    int index = x + y * GridWidth;
                    Vector3 pos = CalcLandscapePos(x, y, heights);//texData);
                    mapHeights[x, y] = pos.Z;
                    vertices[index].pos = pos;

                    //if (x == 0)
                    //	Log.Write("vertices " + y + ": " + pos);

                    // Step 2: Calculate all edge vectors (for normals and tangents)
                    // This involves quite complicated optimizations and mathematics,
                    // hard to explain with just a comment. Read my book :D
                    Vector3 edge1 = pos - CalcLandscapePos(x, y + 1, heights);//texData);
                    Vector3 edge2 = pos - CalcLandscapePos(x + 1, y, heights);//texData);
                    Vector3 edge3 = pos - CalcLandscapePos(x - 1, y + 1, heights);//texData);
                    Vector3 edge4 = pos - CalcLandscapePos(x + 1, y + 1, heights);//texData);
                    Vector3 edge5 = pos - CalcLandscapePos(x - 1, y - 1, heights);//texData);

                    // Step 3: Calculate normal based on the edges (interpolate
                    // from 3 cross products we build from our edges).
                    vertices[index].normal = Vector3.Normalize(
                        Vector3.Cross(edge2, edge1) +
                        Vector3.Cross(edge4, edge3) +
                        Vector3.Cross(edge3, edge5));

                    // Step 4: Set tangent data, just use edge1
                    vertices[index].tangent = Vector3.Normalize(edge1);

                    // Step 5: Set texture coordinates, use full 0.0f to 1.0f range!
                    vertices[index].uv = new Vector2(
                        //x / (float)(GridWidth - 1),
                        //y / (float)(GridHeight - 1));
                        y / (float)(GridHeight - 1),
                        x / (float)(GridWidth - 1));
                } // for for (int)
            #endregion

            #region Smooth normals
            // Smooth all normals, first copy them over, then smooth everything
            Vector3[,] normalsForSmoothing = new Vector3[GridWidth, GridHeight];
            for (int x = 0; x < GridWidth; x++)
                for (int y = 0; y < GridHeight; y++)
                {
                    int index = x + y * GridWidth;
                    normalsForSmoothing[x, y] = vertices[index].normal;
                } // for for (int)

            // Time to smooth to normals we just saved
            for (int x = 1; x < GridWidth - 1; x++)
                for (int y = 1; y < GridHeight - 1; y++)
                {
                    int index = x + y * GridWidth;

                    // Smooth 3x3 normals, but still use old normal to 40% (5 of 13)
                    Vector3 normal = vertices[index].normal * 4;
                    for (int xAdd = -1; xAdd <= 1; xAdd++)
                        for (int yAdd = -1; yAdd <= 1; yAdd++)
                            normal += normalsForSmoothing[x+xAdd, y+yAdd];
                    vertices[index].normal = Vector3.Normalize(normal);

                    // Also recalculate tangent to let it stay 90 degrees on the normal
                    Vector3 helperVector = Vector3.Cross(
                        vertices[index].normal,
                        vertices[index].tangent);
                    vertices[index].tangent = Vector3.Cross(
                        helperVector,
                        vertices[index].normal);
                } // for for (int)
            #endregion

            #region Set vertex buffer
            // Set vertex buffer
            vertexBuffer = new VertexBuffer(
                BaseGame.Device,
                typeof(TangentVertex),
                vertices.Length,
                BufferUsage.WriteOnly);
            vertexBuffer.SetData(vertices);
            #endregion

            #region Calc index buffer
            // Calc index buffer (Note: have to use uint, ushort is not sufficiant
            // in our case because we have MANY vertices ^^)
            uint[] indices = new uint[(GridWidth - 1) * (GridHeight - 1) * 6];
            int currentIndex = 0;
            for (int x = 0; x < GridWidth - 1; x++)
                for (int y = 0; y < GridHeight - 1; y++)
                {
                    // Set landscape data (Note: Right handed)
                    indices[currentIndex + 0] = (uint)(x * GridHeight + y);
                    indices[currentIndex + 2] =
                        (uint)((x + 1) * GridHeight + (y + 1));
                    indices[currentIndex + 1] = (uint)((x + 1) * GridHeight + y);
                    indices[currentIndex + 3] =
                        (uint)((x + 1) * GridHeight + (y + 1));
                    indices[currentIndex + 5] = (uint)(x * GridHeight + y);
                    indices[currentIndex + 4] = (uint)(x * GridHeight + (y + 1));

                    // Add indices
                    currentIndex += 6;
                } // for for (int)
            #endregion

            #region Set index buffer
            indexBuffer = new IndexBuffer(
                BaseGame.Device,
                typeof(uint),
                (GridWidth - 1) * (GridHeight - 1) * 6,
                BufferUsage.WriteOnly);
            indexBuffer.SetData(indices);
            #endregion

            #region Load track (and replay inside ReloadLevel method)
            // Load track based on the level selection and set car pos with
            // help of the ReloadLevel method.
            ReloadLevel(setLevel);
            #endregion

            #region Add city planes
            // Just set one giant plane for the whole city!
            foreach (LandscapeObject obj in landscapeObjects)
                if (obj.IsBigBuilding)
                {
                    cityPlane = new PlaneRenderer(
                        obj.Position,
                        new Plane(new Vector3(0, 0, 1), 0.1f),
                        cityMat, Math.Min(obj.Position.X, obj.Position.Y));//);
                    break;
                } // foreach if (obj.IsBigBuilding)
            #endregion
        }
Beispiel #9
0
        /// <summary>
        /// Reload level
        /// </summary>
        /// <param name="setLevel">Level</param>
        internal void ReloadLevel(RacingGameManager.Level setLevel)
        {
            level = setLevel;

            // Load track based on the level selection, do this after
            // we got all the height data because the track might be adjusted.
            if (track == null)
                track = new Track("Track" + level.ToString(), this);
            else
                track.Reload("Track" + level.ToString(), this);

            // Load replay for this track to show best player
            bestReplay = new Replay((int)level, false, track);
            newReplay = new Replay((int)level, true, track);

            // Kill brake tracks
            brakeTracksVertices.Clear();
            brakeTracksVerticesArray = null;

            // Set car at start pos
            SetCarToStartPosition();
        }
Beispiel #10
0
        /// <summary>
        /// Render game screen. Called each frame.
        /// </summary>
        public bool Render()
        {
            // This starts both menu and in game post screen shader!
            if (BaseGame.UI.PostScreenMenuShader != null)
            {
                BaseGame.UI.PostScreenMenuShader.Start();
            }

            // Render background and black bar
            BaseGame.UI.RenderMenuBackground();
            BaseGame.UI.RenderBlackBar(220, 280);

            // Track header
            int posX = 10;
            int posY = 18;

            if (Environment.OSVersion.Platform != PlatformID.Win32NT)
            {
                posX += 36;
                posY += 26;
            }
            BaseGame.UI.Headers.RenderOnScreenRelative1600(
                posX, posY, UIRenderer.HeaderSelectTrackGfxRect);

            // Little helper to keep track if mouse is actually over a button.
            // Required because buttons are selected even when not hovering over
            // them for GamePad support, but we still want the mouse only to
            // be apply when we are actually over the button.
            int mouseIsOverButton = -1;

            // If the user manipulated the mouse, stop ignoring the mouse
            // This allows the mouse to override the game pad or keyboard selection
            if (Input.HasMouseMoved || Input.MouseLeftButtonJustPressed)
            {
                ignoreMouse = false;
            }

            // Show buttons
            // Part 1: Calculate global variables for our buttons
            Rectangle activeRect = BaseGame.CalcRectangleCenteredWithGivenHeight(
                0, 0,
                ActiveButtonWidth * ButtonRects[0].Height / ButtonRects[0].Width,
                ButtonRects[0]);
            Rectangle inactiveRect = BaseGame.CalcRectangleCenteredWithGivenHeight(
                0, 0,
                InactiveButtonWidth * ButtonRects[0].Height / ButtonRects[0].Width,
                ButtonRects[0]);
            int totalWidth = activeRect.Width +
                             2 * inactiveRect.Width +
                             2 * BaseGame.XToRes(DistanceBetweenButtons);
            int xPos = BaseGame.XToRes(512) - totalWidth / 2;
            int yPos = BaseGame.YToRes(258);

            for (int num = 0; num < NumberOfButtons; num++)
            {
                // Is this button currently selected?
                bool selected = num == selectedButton;

                // Increase size if selected, decrease otherwise
                currentButtonSizes[num] +=
                    (selected ? 1 : -1) * BaseGame.MoveFactorPerSecond * 2;
                if (currentButtonSizes[num] < 0)
                {
                    currentButtonSizes[num] = 0;
                }
                if (currentButtonSizes[num] > 1)
                {
                    currentButtonSizes[num] = 1;
                }

                Rectangle thisRect = MainMenu.
                                     InterpolateRect(activeRect, inactiveRect, currentButtonSizes[num]);
                Rectangle renderRect = new Rectangle(
                    xPos, yPos - (thisRect.Height - inactiveRect.Height) / 2,
                    thisRect.Width, thisRect.Height);
                BaseGame.UI.Buttons.RenderOnScreen(renderRect, ButtonRects[num],
                                                   selected ? Color.White : new Color(192, 192, 192, 192));

                // Add border effect if selected
                if (selected)
                {
                    BaseGame.UI.Buttons.RenderOnScreen(renderRect,
                                                       UIRenderer.TrackButtonSelectionGfxRect);
                }

                // Also add text below button
                Rectangle textRenderRect = new Rectangle(
                    xPos, renderRect.Bottom + BaseGame.YToRes(5),
                    renderRect.Width,
                    renderRect.Height * TextRects[0].Height / ButtonRects[0].Height);
                if (selected)
                {
                    BaseGame.UI.Buttons.RenderOnScreen(textRenderRect, TextRects[num],
                                                       selected ? Color.White : Color.Gray);
                }

                // Also check if the user hovers with the mouse over this button
                if (Input.MouseInBox(renderRect))
                {
                    mouseIsOverButton = num;
                }

                xPos += thisRect.Width + BaseGame.XToRes(DistanceBetweenButtons);
            }

            if (!ignoreMouse && mouseIsOverButton >= 0)
            {
                selectedButton = mouseIsOverButton;
            }

            // Handle GamePad input, and also allow keyboard input
            if (Input.GamePadLeftJustPressed ||
                Input.KeyboardLeftJustPressed)
            {
                Sound.Play(Sound.Sounds.ButtonClick);
                selectedButton =
                    (selectedButton + NumberOfButtons - 1) % NumberOfButtons;
                ignoreMouse = true;
            }
            else if (Input.GamePadRightJustPressed ||
                     Input.KeyboardRightJustPressed)
            {
                Sound.Play(Sound.Sounds.ButtonClick);
                selectedButton = (selectedButton + 1) % NumberOfButtons;
                ignoreMouse    = true;
            }

            bool aButtonPressed = BaseGame.UI.RenderBottomButtons(false);

            // If user presses the mouse button or the game pad A or Space,
            // start the game screen for the currently selected game part.
            if ((mouseIsOverButton >= 0 && Input.MouseLeftButtonJustPressed) ||
                aButtonPressed ||
                Input.GamePadAJustPressed ||
                Input.KeyboardSpaceJustPressed)
            {
                // Track selection is handled through SelectedTrackNumber
                RacingGameManager.AddGameScreen(new GameScreen());
            }

            if (Input.KeyboardEscapeJustPressed ||
                Input.GamePadBJustPressed ||
                Input.GamePadBackJustPressed ||
                BaseGame.UI.backButtonPressed)
            {
                return(true);
            }

            return(false);
        }
Beispiel #11
0
 public void Awake()
 {
     RacingGameManager = GameObject.FindGameObjectWithTag("MinigameManager").GetComponent <RacingGameManager>();
 }
        /// <summary>
        /// Create landscape.
        /// This constructor should only be called
        /// from the RacingGame main class!
        /// </summary>
        /// <param name="setLevel">Level we want to load</param>
        internal Landscape(RacingGameManager.Level setLevel)
        {
            #region Load map height data
            Stream file = TitleContainer.OpenStream(
                "Content\\LandscapeHeights.data");
            byte[] heights = new byte[GridWidth * GridHeight];
            file.Read(heights, 0, GridWidth * GridHeight);
            file.Close();

            mapHeights = new float[GridWidth, GridHeight];
            #endregion

            #region Build tangent vertices
            // Build our tangent vertices
            for (int x = 0; x < GridWidth; x++)
                for (int y = 0; y < GridHeight; y++)
                {
                    // Step 1: Calculate position
                    int index = x + y * GridWidth;
                    Vector3 pos = CalcLandscapePos(x, y, heights);//texData);
                    mapHeights[x, y] = pos.Z;
                    vertices[index].pos = pos;

                    //if (x == 0)
                    //    Log.Write("vertices " + y + ": " + pos);

                    // Step 2: Calculate all edge vectors (for normals and tangents)
                    // This involves quite complicated optimizations and mathematics,
                    // hard to explain with just a comment. Read my book :D
                    Vector3 edge1 = pos - CalcLandscapePos(x, y + 1, heights);
                    Vector3 edge2 = pos - CalcLandscapePos(x + 1, y, heights);
                    Vector3 edge3 = pos - CalcLandscapePos(x - 1, y + 1, heights);
                    Vector3 edge4 = pos - CalcLandscapePos(x + 1, y + 1, heights);
                    Vector3 edge5 = pos - CalcLandscapePos(x - 1, y - 1, heights);

                    // Step 3: Calculate normal based on the edges (interpolate
                    // from 3 cross products we build from our edges).
                    vertices[index].normal = Vector3.Normalize(
                        Vector3.Cross(edge2, edge1) +
                        Vector3.Cross(edge4, edge3) +
                        Vector3.Cross(edge3, edge5));

                    // Step 4: Set tangent data, just use edge1
                    vertices[index].tangent = Vector3.Normalize(edge1);

                    // Step 5: Set texture coordinates, use full 0.0f to 1.0f range!
                    vertices[index].uv = new Vector2(
                        //x / (float)(GridWidth - 1),
                        //y / (float)(GridHeight - 1));
                        y / (float)(GridHeight - 1),
                        x / (float)(GridWidth - 1));
                }
            #endregion

            #region Smooth normals
            // Smooth all normals, first copy them over, then smooth everything
            Vector3[,] normalsForSmoothing = new Vector3[GridWidth, GridHeight];
            for (int x = 0; x < GridWidth; x++)
                for (int y = 0; y < GridHeight; y++)
                {
                    int index = x + y * GridWidth;
                    normalsForSmoothing[x, y] = vertices[index].normal;
                }

            // Time to smooth to normals we just saved
            for (int x = 1; x < GridWidth - 1; x++)
                for (int y = 1; y < GridHeight - 1; y++)
                {
                    int index = x + y * GridWidth;

                    // Smooth 3x3 normals, but still use old normal to 40% (5 of 13)
                    Vector3 normal = vertices[index].normal * 4;
                    for (int xAdd = -1; xAdd <= 1; xAdd++)
                        for (int yAdd = -1; yAdd <= 1; yAdd++)
                            normal += normalsForSmoothing[x + xAdd, y + yAdd];
                    vertices[index].normal = Vector3.Normalize(normal);

                    // Also recalculate tangent to let it stay 90 degrees on the normal
                    Vector3 helperVector = Vector3.Cross(
                        vertices[index].normal,
                        vertices[index].tangent);
                    vertices[index].tangent = Vector3.Cross(
                        helperVector,
                        vertices[index].normal);
                }
            #endregion

            #region Set vertex buffer
            // Set vertex buffer
            // fix
            //vertexBuffer = new VertexBuffer(
            //    BaseGame.Device,
            //    typeof(TangentVertex),
            //    vertices.Length,
            //    ResourceUsage.WriteOnly,
            //    ResourceManagementMode.Automatic);
            //vertexBuffer.SetData(vertices);
            vertexBuffer = new VertexBuffer(
                BaseGame.Device,
                typeof(TangentVertex),
                vertices.Length, 
                BufferUsage.WriteOnly);
            vertexBuffer.SetData(vertices);
            #endregion

            #region Calc index buffer
            // Calc index buffer (Note: have to use uint, ushort is not sufficiant
            // in our case because we have MANY vertices ^^)
            uint[] indices = new uint[(GridWidth - 1) * (GridHeight - 1) * 6];
            int currentIndex = 0;
            for (int x = 0; x < GridWidth - 1; x++)
                for (int y = 0; y < GridHeight - 1; y++)
                {
                    // Set landscape data (Note: Right handed)
                    indices[currentIndex + 0] = (uint)(x * GridHeight + y);
                    indices[currentIndex + 2] =
                        (uint)((x + 1) * GridHeight + (y + 1));
                    indices[currentIndex + 1] = (uint)((x + 1) * GridHeight + y);
                    indices[currentIndex + 3] =
                        (uint)((x + 1) * GridHeight + (y + 1));
                    indices[currentIndex + 5] = (uint)(x * GridHeight + y);
                    indices[currentIndex + 4] = (uint)(x * GridHeight + (y + 1));

                    // Add indices
                    currentIndex += 6;
                }
            #endregion

            #region Set index buffer
            // fix
            //indexBuffer = new IndexBuffer(
            //    BaseGame.Device,
            //    typeof(uint),
            //    (GridWidth - 1) * (GridHeight - 1) * 6,
            //    ResourceUsage.WriteOnly,
            //    ResourceManagementMode.Automatic);

            indexBuffer = new IndexBuffer(
                BaseGame.Device,
                typeof(uint),
                (GridWidth - 1) * (GridHeight - 1) * 6,
                BufferUsage.WriteOnly);

            indexBuffer.SetData(indices);
            #endregion

            #region Load track (and replay inside ReloadLevel method)
            // Load track based on the level selection and set car pos with
            // help of the ReloadLevel method.
            ReloadLevel(setLevel);
            #endregion

            #region Add city planes
            // Just set one giant plane for the whole city!
            foreach (LandscapeObject obj in landscapeObjects)
                if (obj.IsBigBuilding)
                {
                    cityPlane = new PlaneRenderer(
                        obj.Position,
                        new Plane(new Vector3(0, 0, 1), 0.1f),
                        cityMat, Math.Min(obj.Position.X, obj.Position.Y));
                    break;
                }
            #endregion
        }
        /// <summary>
        /// Render game screen. Called each frame.
        /// </summary>
        public bool Render()
        {
            #region Background
            // This starts both menu and in game post screen shader!
            BaseGame.UI.PostScreenMenuShader.Start();

            // Render background and black bar
            BaseGame.UI.RenderMenuBackground();

            // Options header
            int posX = 10;
            int posY = 18;
            if (Environment.OSVersion.Platform != PlatformID.Win32NT)
            {
                posX += 36;
                posY += 26;
            }
            BaseGame.UI.Headers.RenderOnScreenRelative1600(
                posX, posY, UIRenderer.HeaderOptionsGfxRect);

            // Options background
            BaseGame.UI.OptionsScreen.RenderOnScreenRelative4To3(
                0, 125, BaseGame.UI.OptionsScreen.GfxRectangle);
            #endregion

            #region Edit player name
            // Edit player name
            int xPos = BaseGame.XToRes(352);
            int yPos = BaseGame.YToRes768(125 + 65 - 20);
            TextureFont.WriteText(xPos, yPos,
                                  currentPlayerName +
                                  // Add blinking |
                                  ((int)(BaseGame.TotalTime / 0.35f) % 2 == 0 ? "|" : ""));
            Input.HandleKeyboardInput(ref currentPlayerName);
            #endregion


            #region Select resolution
            // Select resolution
            // Use inverted color for selection (see below for sprite blend mode)
            Color selColor = new Color(255, 156, 0, 160);

            Rectangle res0Rect = BaseGame.CalcRectangleKeep4To3(
                Resolution640x480GfxRect);
            res0Rect.Y += BaseGame.YToRes768(125);
            bool inRes0Rect = Input.MouseInBox(res0Rect);
            if (currentResolution == 0)
            {
                BaseGame.UI.OptionsScreen.RenderOnScreen(
                    res0Rect, Resolution640x480GfxRect,
                    selColor, BlendState.AlphaBlend);
            }
            if (inRes0Rect && Input.MouseLeftButtonJustPressed)
            {
                Sound.Play(Sound.Sounds.ButtonClick);
                currentResolution = 0;
            }

            Rectangle res1Rect = BaseGame.CalcRectangleKeep4To3(
                Resolution800x600GfxRect);
            res1Rect.Y += BaseGame.YToRes768(125);
            bool inRes1Rect = Input.MouseInBox(res1Rect);
            if (currentResolution == 1)
            {
                BaseGame.UI.OptionsScreen.RenderOnScreen(
                    res1Rect, Resolution800x600GfxRect,
                    selColor, BlendState.AlphaBlend);
            }
            if (inRes1Rect && Input.MouseLeftButtonJustPressed)
            {
                Sound.Play(Sound.Sounds.ButtonClick);
                currentResolution = 1;
            }

            Rectangle res2Rect = BaseGame.CalcRectangleKeep4To3(
                Resolution1024x768GfxRect);
            res2Rect.Y += BaseGame.YToRes768(125);
            bool inRes2Rect = Input.MouseInBox(res2Rect);
            if (currentResolution == 2)
            {
                BaseGame.UI.OptionsScreen.RenderOnScreen(
                    res2Rect, Resolution1024x768GfxRect,
                    selColor, BlendState.AlphaBlend);
            }
            if (inRes2Rect && Input.MouseLeftButtonJustPressed)
            {
                Sound.Play(Sound.Sounds.ButtonClick);
                currentResolution = 2;
            }

            Rectangle res3Rect = BaseGame.CalcRectangleKeep4To3(
                Resolution1280x1024GfxRect);
            res3Rect.Y += BaseGame.YToRes768(125);
            bool inRes3Rect = Input.MouseInBox(res3Rect);
            if (currentResolution == 3)
            {
                BaseGame.UI.OptionsScreen.RenderOnScreen(
                    res3Rect, Resolution1280x1024GfxRect,
                    selColor, BlendState.AlphaBlend);
            }
            if (inRes3Rect && Input.MouseLeftButtonJustPressed)
            {
                Sound.Play(Sound.Sounds.ButtonClick);
                currentResolution = 3;
            }

            Rectangle res4Rect = BaseGame.CalcRectangleKeep4To3(
                ResolutionAutoGfxRect);
            res4Rect.Y += BaseGame.YToRes768(125);
            bool inRes4Rect = Input.MouseInBox(res4Rect);
            if (currentResolution == 4)
            {
                BaseGame.UI.OptionsScreen.RenderOnScreen(
                    res4Rect, ResolutionAutoGfxRect,
                    selColor, BlendState.AlphaBlend);
            }
            if (inRes4Rect && Input.MouseLeftButtonJustPressed)
            {
                Sound.Play(Sound.Sounds.ButtonClick);
                currentResolution = 4;
            }
            #endregion

            #region Graphics options

            Rectangle fsRect = BaseGame.CalcRectangleKeep4To3(
                FullscreenGfxRect);
            fsRect.Y += BaseGame.YToRes768(125);
            bool inFsRect = Input.MouseInBox(fsRect);
            if (fullscreen)
            {
                BaseGame.UI.OptionsScreen.RenderOnScreen(
                    fsRect, FullscreenGfxRect,
                    selColor, BlendState.AlphaBlend);
            }
            if (inFsRect && Input.MouseLeftButtonJustPressed)
            {
                Sound.Play(Sound.Sounds.ButtonClick);
                fullscreen = !fullscreen;
            }

            Rectangle pseRect = BaseGame.CalcRectangleKeep4To3(
                PostScreenEffectsGfxRect);
            pseRect.Y += BaseGame.YToRes768(125);
            bool inPseRect = Input.MouseInBox(pseRect);
            if (usePostScreenShaders)
            {
                BaseGame.UI.OptionsScreen.RenderOnScreen(
                    pseRect, PostScreenEffectsGfxRect,
                    selColor, BlendState.AlphaBlend);
            }
            if (inPseRect && Input.MouseLeftButtonJustPressed)
            {
                Sound.Play(Sound.Sounds.ButtonClick);
                usePostScreenShaders = !usePostScreenShaders;
            }

            Rectangle smRect = BaseGame.CalcRectangleKeep4To3(
                ShadowsGfxRect);
            smRect.Y += BaseGame.YToRes768(125);
            bool inSmRect = Input.MouseInBox(smRect);
            if (useShadowMapping)
            {
                BaseGame.UI.OptionsScreen.RenderOnScreen(
                    smRect, ShadowsGfxRect,
                    selColor, BlendState.AlphaBlend);
            }
            if (inSmRect && Input.MouseLeftButtonJustPressed)
            {
                Sound.Play(Sound.Sounds.ButtonClick);
                useShadowMapping = !useShadowMapping;
            }

            Rectangle hdRect = BaseGame.CalcRectangleKeep4To3(
                HighDetailGfxRect);
            hdRect.Y += BaseGame.YToRes768(125);
            bool inHdRect = Input.MouseInBox(hdRect);
            if (useHighDetail)
            {
                BaseGame.UI.OptionsScreen.RenderOnScreen(
                    hdRect, HighDetailGfxRect,
                    selColor, BlendState.AlphaBlend);
            }
            if (inHdRect && Input.MouseLeftButtonJustPressed)
            {
                Sound.Play(Sound.Sounds.ButtonClick);
                useHighDetail = !useHighDetail;
            }
            #endregion


            #region Sound volume
            Rectangle soundRect = BaseGame.CalcRectangleKeep4To3(
                SoundGfxRect);
            soundRect.Y += BaseGame.YToRes768(125);
            if (Input.MouseInBox(soundRect))
            {
                if (Input.MouseLeftButtonJustPressed)
                {
                    currentSoundVolume =
                        (Input.MousePos.X - soundRect.X) / (float)soundRect.Width;
                    Sound.Play(Sound.Sounds.Highlight);
                }
            }

            // Handel controller input
            if (currentOptionsNumber == 0)
            {
                if (Input.GamePadLeftJustPressed ||
                    Input.KeyboardLeftJustPressed)
                {
                    currentSoundVolume -= 0.1f;
                    Sound.Play(Sound.Sounds.Highlight);
                }
                if (Input.GamePadRightJustPressed ||
                    Input.KeyboardRightJustPressed)
                {
                    currentSoundVolume += 0.1f;
                    Sound.Play(Sound.Sounds.Highlight);
                }
                if (currentSoundVolume < 0)
                {
                    currentSoundVolume = 0;
                }
                if (currentSoundVolume > 1)
                {
                    currentSoundVolume = 1;
                }
            }

            // Render slider handle
            Rectangle gfxRect = UIRenderer.SelectionRadioButtonGfxRect;
            BaseGame.UI.Buttons.RenderOnScreen(new Rectangle(
                                                   soundRect.X + (int)(soundRect.Width * currentSoundVolume) -
                                                   BaseGame.XToRes(gfxRect.Width) / 2,
                                                   soundRect.Y,
                                                   BaseGame.XToRes(gfxRect.Width), BaseGame.YToRes768(gfxRect.Height)),
                                               gfxRect);
            #endregion

            #region Music volume
            Rectangle musicRect = BaseGame.CalcRectangleKeep4To3(
                MusicGfxRect);
            musicRect.Y += BaseGame.YToRes768(125);
            if (Input.MouseInBox(musicRect))
            {
                if (Input.MouseLeftButtonJustPressed)
                {
                    currentMusicVolume =
                        (Input.MousePos.X - musicRect.X) / (float)musicRect.Width;
                    Sound.Play(Sound.Sounds.Highlight);
                }
            }

            // Handel controller input
            if (currentOptionsNumber == 1)
            {
                if (Input.GamePadLeftJustPressed ||
                    Input.KeyboardLeftJustPressed)
                {
                    currentMusicVolume -= 0.1f;
                    Sound.Play(Sound.Sounds.Highlight);
                }
                if (Input.GamePadRightJustPressed ||
                    Input.KeyboardRightJustPressed)
                {
                    currentMusicVolume += 0.1f;
                    Sound.Play(Sound.Sounds.Highlight);
                }
                if (currentMusicVolume < 0)
                {
                    currentMusicVolume = 0;
                }
                if (currentMusicVolume > 1)
                {
                    currentMusicVolume = 1;
                }
            }

            // Render slider handle
            BaseGame.UI.Buttons.RenderOnScreen(new Rectangle(
                                                   musicRect.X + (int)(musicRect.Width * currentMusicVolume) -
                                                   BaseGame.XToRes(gfxRect.Width) / 2,
                                                   musicRect.Y,
                                                   BaseGame.XToRes(gfxRect.Width), BaseGame.YToRes768(gfxRect.Height)),
                                               gfxRect);
            #endregion

            Sound.SetVolumes(currentSoundVolume, currentMusicVolume);

            #region Controller sensitivity
            Rectangle sensitivityRect = BaseGame.CalcRectangleKeep4To3(
                SensitivityGfxRect);
            sensitivityRect.Y += BaseGame.YToRes768(125);
            if (Input.MouseInBox(sensitivityRect))
            {
                if (Input.MouseLeftButtonJustPressed)
                {
                    currentSensitivity =
                        (Input.MousePos.X - sensitivityRect.X) /
                        (float)sensitivityRect.Width;
                    Sound.Play(Sound.Sounds.Highlight);
                }
            }

            // Handel controller input
            if (currentOptionsNumber == 2)
            {
                if (Input.GamePadLeftJustPressed ||
                    Input.KeyboardLeftJustPressed)
                {
                    currentSensitivity -= 0.1f;
                    Sound.Play(Sound.Sounds.Highlight);
                }
                if (Input.GamePadRightJustPressed ||
                    Input.KeyboardRightJustPressed)
                {
                    currentSensitivity += 0.1f;
                    Sound.Play(Sound.Sounds.Highlight);
                }
                if (currentSensitivity < 0)
                {
                    currentSensitivity = 0;
                }
                if (currentSensitivity > 1)
                {
                    currentSensitivity = 1;
                }
            }

            // Render slider handle
            BaseGame.UI.Buttons.RenderOnScreen(new Rectangle(
                                                   sensitivityRect.X +
                                                   (int)(sensitivityRect.Width * currentSensitivity) -
                                                   BaseGame.XToRes(gfxRect.Width) / 2,
                                                   sensitivityRect.Y,
                                                   BaseGame.XToRes(gfxRect.Width), BaseGame.YToRes768(gfxRect.Height)),
                                               gfxRect);
            #endregion

            #region Show selected line
            Rectangle[] lineArrowGfxRects = new Rectangle[]
            {
                Line4ArrowGfxRect,
                Line5ArrowGfxRect,
                Line6ArrowGfxRect,
            };
            for (int num = 0; num < lineArrowGfxRects.Length; num++)
            {
                Rectangle lineRect = BaseGame.CalcRectangleKeep4To3(
                    lineArrowGfxRects[num]);
                lineRect.Y += BaseGame.YToRes768(125);
                lineRect.X -= BaseGame.XToRes(8 + (int)Math.Round(8 *
                                                                  Math.Sin(BaseGame.TotalTime / 0.21212f)));

                // Draw selection arrow
                if (currentOptionsNumber == num)
                {
                    BaseGame.UI.Buttons.RenderOnScreen(
                        lineRect, UIRenderer.SelectionArrowGfxRect, Color.White);
                }
            }

            // Game pad selection
            if (Input.GamePadUpJustPressed ||
                Input.KeyboardUpJustPressed)
            {
                Sound.Play(Sound.Sounds.Highlight);
                currentOptionsNumber = (lineArrowGfxRects.Length +
                                        currentOptionsNumber - 1) % lineArrowGfxRects.Length;
            }
            else if (Input.GamePadDownJustPressed ||
                     Input.KeyboardDownJustPressed)
            {
                Sound.Play(Sound.Sounds.Highlight);
                currentOptionsNumber = (currentOptionsNumber + 1) %
                                       lineArrowGfxRects.Length;
            }
            #endregion

            #region Bottom buttons

            //*** Added booth mode screen flow
            bool aButtonPressed = BaseGame.UI.RenderBottomButtons(!GameSettings.BoothMode);

            if ((Input.GamePadAJustPressed ||
                 //Input.KeyboardSpaceJustPressed ||
                 aButtonPressed) && GameSettings.BoothMode && !string.IsNullOrEmpty(currentPlayerName))
            {
                //RacingGameManager.AddGameScreen(new CarSelection());
                GameSettings.Default.PlayerName = currentPlayerName;
                RacingGameManager.AddGameScreen(new GameScreen());
                switch (currentResolution)
                {
                case 0:
                    GameSettings.Default.ResolutionWidth  = 640;
                    GameSettings.Default.ResolutionHeight = 480;
                    break;

                case 1:
                    GameSettings.Default.ResolutionWidth  = 800;
                    GameSettings.Default.ResolutionHeight = 600;
                    break;

                case 2:
                    GameSettings.Default.ResolutionWidth  = 1024;
                    GameSettings.Default.ResolutionHeight = 768;
                    break;

                case 3:
                    GameSettings.Default.ResolutionWidth  = 1280;
                    GameSettings.Default.ResolutionHeight = 1024;
                    break;

                case 4:
                    // Try to use best resolution available
                    GameSettings.Default.ResolutionWidth  = 0;
                    GameSettings.Default.ResolutionHeight = 0;
                    break;
                }
                GameSettings.Default.Fullscreen            = fullscreen;
                GameSettings.Default.PostScreenEffects     = usePostScreenShaders;
                GameSettings.Default.ShadowMapping         = useShadowMapping;
                GameSettings.Default.HighDetail            = useHighDetail;
                GameSettings.Default.MusicVolume           = currentMusicVolume;
                GameSettings.Default.SoundVolume           = currentSoundVolume;
                GameSettings.Default.ControllerSensitivity = currentSensitivity;

                // Save all
                GameSettings.Save();
                // Update game settings
                BaseGame.CheckOptionsAndPSVersion();
            }
            #endregion

            #region Apply settings when quitting
            if (Input.KeyboardEscapeJustPressed ||
                Input.GamePadBJustPressed ||
                Input.GamePadBackJustPressed ||
                BaseGame.UI.backButtonPressed)
            {
                // Apply settings, for xbox only set music/sound and sensitivity!
                GameSettings.Default.PlayerName = currentPlayerName;
                switch (currentResolution)
                {
                case 0:
                    GameSettings.Default.ResolutionWidth  = 640;
                    GameSettings.Default.ResolutionHeight = 480;
                    break;

                case 1:
                    GameSettings.Default.ResolutionWidth  = 800;
                    GameSettings.Default.ResolutionHeight = 600;
                    break;

                case 2:
                    GameSettings.Default.ResolutionWidth  = 1024;
                    GameSettings.Default.ResolutionHeight = 768;
                    break;

                case 3:
                    GameSettings.Default.ResolutionWidth  = 1280;
                    GameSettings.Default.ResolutionHeight = 1024;
                    break;

                case 4:
                    // Try to use best resolution available
                    GameSettings.Default.ResolutionWidth  = 0;
                    GameSettings.Default.ResolutionHeight = 0;
                    break;
                }
                GameSettings.Default.Fullscreen            = fullscreen;
                GameSettings.Default.PostScreenEffects     = usePostScreenShaders;
                GameSettings.Default.ShadowMapping         = useShadowMapping;
                GameSettings.Default.HighDetail            = useHighDetail;
                GameSettings.Default.MusicVolume           = currentMusicVolume;
                GameSettings.Default.SoundVolume           = currentSoundVolume;
                GameSettings.Default.ControllerSensitivity = currentSensitivity;

                // Save all
                GameSettings.Save();
                // Update game settings
                BaseGame.CheckOptionsAndPSVersion();

                return(true);
            }
            #endregion

            return(false);
        }