Exemple #1
0
        /// <summary>Renders the list of game (textual) messages</summary>
        /// <param name="Element">The HUD element these are to be rendered onto</param>
        /// <param name="TimeElapsed">The time elapsed</param>
        private static void RenderGameMessages(HUD.Element Element, double TimeElapsed)
        {
            //Calculate the size of the viewing plane
            int n = MessageManager.TextualMessages.Count;
            //Minimum initial width is 16px
            double totalwidth = 16.0f;

            for (int j = 0; j < n; j++)
            {
                //Update font size for the renderer
                System.Drawing.Size size = Renderer.MeasureString(Element.Font, (string)MessageManager.TextualMessages[j].MessageToDisplay);
                MessageManager.TextualMessages[j].Width  = size.Width;
                MessageManager.TextualMessages[j].Height = size.Height;
                //Run through the list of current messages
                double a = MessageManager.TextualMessages[j].Width - j * (double)Element.Value1;
                //If our width is wider than the old, use this as the NEW viewing plane width
                if (a > totalwidth)
                {
                    totalwidth = a;
                }
            }
            //Calculate the X-width of the viewing plane
            Game.MessagesRendererSize.X += 16.0 * TimeElapsed * ((double)totalwidth - Game.MessagesRendererSize.X);
            totalwidth = (float)Game.MessagesRendererSize.X;
            double lcrh, lw, rw;

            //Calculate final viewing plane size to pass to openGL
            CalculateViewingPlaneSize(Element, out lw, out rw, out lcrh);

            // start
            double w = totalwidth + lw + rw;
            double h = Element.Value2 * n;
            double x = Element.Alignment.X < 0 ? 0.0 : Element.Alignment.X > 0 ? Screen.Width - w : 0.5 * (Screen.Width - w);
            double y = Element.Alignment.Y < 0 ? 0.0 : Element.Alignment.Y > 0 ? Screen.Height - h : 0.5 * (Screen.Height - h);

            x += Element.Position.X;
            y += Element.Position.Y;
            int m = 0;

            for (int j = 0; j < n; j++)
            {
                var   mm = MessageManager.TextualMessages[j];
                float br, bg, bb, ba;
                CreateBackColor(Element.BackgroundColor, mm.Color, out br, out bg, out bb, out ba);
                float tr, tg, tb, ta;
                CreateTextColor(Element.TextColor, mm.Color, out tr, out tg, out tb, out ta);
                float or, og, ob, oa;
                CreateBackColor(Element.OverlayColor, mm.Color, out or, out og, out ob, out oa);
                double tx, ty;
                bool   preserve = false;
                if ((Element.Transition & HUD.Transition.Move) != 0)
                {
                    if (Game.SecondsSinceMidnight < mm.Timeout)
                    {
                        if (mm.RendererAlpha == 0.0)
                        {
                            mm.RendererPosition.X = x + Element.TransitionVector.X;
                            mm.RendererPosition.Y = y + Element.TransitionVector.Y;
                            mm.RendererAlpha      = 1.0;
                        }
                        tx       = x;
                        ty       = y + m * Element.Value2;
                        preserve = true;
                    }
                    else if (Element.Transition == HUD.Transition.MoveAndFade)
                    {
                        tx = x;
                        ty = y + m * Element.Value2;
                    }
                    else
                    {
                        tx = x + Element.TransitionVector.X;
                        ty = y + (j + 1) * Element.TransitionVector.Y;
                    }
                    const double speed = 2.0;
                    double       dx    = (speed * Math.Abs(tx - mm.RendererPosition.X) + 0.1) * TimeElapsed;
                    double       dy    = (speed * Math.Abs(ty - mm.RendererPosition.Y) + 0.1) * TimeElapsed;
                    if (Math.Abs(tx - mm.RendererPosition.X) < dx)
                    {
                        mm.RendererPosition.X = tx;
                    }
                    else
                    {
                        mm.RendererPosition.X += Math.Sign(tx - mm.RendererPosition.X) * dx;
                    }
                    if (Math.Abs(ty - mm.RendererPosition.Y) < dy)
                    {
                        mm.RendererPosition.Y = ty;
                    }
                    else
                    {
                        mm.RendererPosition.Y += Math.Sign(ty - mm.RendererPosition.Y) * dy;
                    }
                }
                else
                {
                    tx = x;
                    ty = y + m * Element.Value2;
                    mm.RendererPosition.X = 0.0;
                    const double speed = 12.0;
                    double       dy    = (speed * Math.Abs(ty - mm.RendererPosition.Y) + 0.1) * TimeElapsed;
                    mm.RendererPosition.X = x;
                    if (Math.Abs(ty - mm.RendererPosition.Y) < dy)
                    {
                        mm.RendererPosition.Y = ty;
                    }
                    else
                    {
                        mm.RendererPosition.Y += Math.Sign(ty - mm.RendererPosition.Y) * dy;
                    }
                }
                if ((Element.Transition & HUD.Transition.Fade) != 0)
                {
                    if (Game.SecondsSinceMidnight >= mm.Timeout)
                    {
                        mm.RendererAlpha -= TimeElapsed;
                        if (mm.RendererAlpha < 0.0)
                        {
                            mm.RendererAlpha = 0.0;
                        }
                    }
                    else
                    {
                        mm.RendererAlpha += TimeElapsed;
                        if (mm.RendererAlpha > 1.0)
                        {
                            mm.RendererAlpha = 1.0;
                        }
                        preserve = true;
                    }
                }
                else if (Game.SecondsSinceMidnight > mm.Timeout)
                {
                    if (Math.Abs(mm.RendererPosition.X - tx) < 0.1 & Math.Abs(mm.RendererPosition.Y - ty) < 0.1)
                    {
                        mm.RendererAlpha = 0.0;
                    }
                }
                if (preserve)
                {
                    m++;
                }
                double px    = mm.RendererPosition.X + (double)j * (double)Element.Value1;
                double py    = mm.RendererPosition.Y;
                float  alpha = (float)(mm.RendererAlpha * mm.RendererAlpha);
                // graphics
                HUD.Image Left = j == 0
                                        ? Element.TopLeft
                                        : j < n - 1
                                                ? Element.CenterLeft
                                                : Element.BottomLeft;
                HUD.Image Middle = j == 0
                                        ? Element.TopMiddle
                                        : j < n - 1
                                                ? Element.CenterMiddle
                                                : Element.BottomMiddle;
                HUD.Image Right = j == 0
                                        ? Element.TopRight
                                        : j < n - 1
                                                ? Element.CenterRight
                                                : Element.BottomRight;
                // left background
                if (Left.BackgroundTexture != null)
                {
                    if (Textures.LoadTexture(Left.BackgroundTexture, Textures.OpenGlTextureWrapMode.ClampClamp))
                    {
                        double u = (double)Left.BackgroundTexture.Width;
                        double v = (double)Left.BackgroundTexture.Height;
                        GL.Color4(br, bg, bb, ba * alpha);
                        RenderOverlayTexture(Left.BackgroundTexture, px, py, px + u, py + v);
                    }
                }
                // right background
                if (Right.BackgroundTexture != null)
                {
                    if (Textures.LoadTexture(Right.BackgroundTexture, Textures.OpenGlTextureWrapMode.ClampClamp))
                    {
                        double u = (double)Right.BackgroundTexture.Width;
                        double v = (double)Right.BackgroundTexture.Height;
                        GL.Color4(br, bg, bb, ba * alpha);
                        RenderOverlayTexture(Right.BackgroundTexture, px + w - u, py, px + w, py + v);
                    }
                }
                // middle background
                if (Middle.BackgroundTexture != null)
                {
                    if (Textures.LoadTexture(Middle.BackgroundTexture, Textures.OpenGlTextureWrapMode.ClampClamp))
                    {
                        double v = (double)Middle.BackgroundTexture.Height;
                        GL.Color4(br, bg, bb, ba * alpha);
                        RenderOverlayTexture(Middle.BackgroundTexture, px + lw, py, px + w - rw, py + v);
                    }
                }
                {
                    // text
                    string t = (string)mm.MessageToDisplay;
                    double u = mm.Width;
                    double v = mm.Height;
                    double p =
                        Math.Round(
                            (Element.TextAlignment.X < 0
                                                                ? px
                                                                : Element.TextAlignment.X > 0
                                                                        ? px + w - u
                                                                        : px + 0.5 * (w - u)) - j * Element.Value1);
                    double q = Math.Round(Element.TextAlignment.Y < 0
                                                ? py
                                                : Element.TextAlignment.Y > 0
                                                        ? py + lcrh - v
                                                        : py + 0.5 * (lcrh - v));
                    p += Element.TextPosition.X;
                    q += Element.TextPosition.Y;
                    DrawString(Element.Font, t, new System.Drawing.Point((int)p, (int)q),
                               TextAlignment.TopLeft, new Color128(tr, tg, tb, ta * alpha), Element.TextShadow);
                }
                // left overlay
                if (Left.OverlayTexture != null)
                {
                    if (Textures.LoadTexture(Left.OverlayTexture, Textures.OpenGlTextureWrapMode.ClampClamp))
                    {
                        double u = (double)Left.OverlayTexture.Width;
                        double v = (double)Left.OverlayTexture.Height;
                        GL.Color4(or, og, ob, oa * alpha);
                        RenderOverlayTexture(Left.OverlayTexture, px, py, px + u, py + v);
                    }
                }
                // right overlay
                if (Right.OverlayTexture != null)
                {
                    if (Textures.LoadTexture(Right.OverlayTexture, Textures.OpenGlTextureWrapMode.ClampClamp))
                    {
                        double u = (double)Right.OverlayTexture.Width;
                        double v = (double)Right.OverlayTexture.Height;
                        GL.Color4(or, og, ob, oa * alpha);
                        RenderOverlayTexture(Right.OverlayTexture, px + w - u, py, px + w, py + v);
                    }
                }
                // middle overlay
                if (Middle.OverlayTexture != null)
                {
                    if (Textures.LoadTexture(Middle.OverlayTexture, Textures.OpenGlTextureWrapMode.ClampClamp))
                    {
                        double v = (double)Middle.OverlayTexture.Height;
                        GL.Color4(or, og, ob, oa * alpha);
                        RenderOverlayTexture(Middle.OverlayTexture, px + lw, py, px + w - rw, py + v);
                    }
                }
            }
        }
Exemple #2
0
 /// <summary>Calculates the viewing plane size for the given HUD element</summary>
 /// <param name="Element">The element</param>
 /// <param name="LeftWidth">The left width of the viewing plane</param>
 /// <param name="RightWidth">The right width of the viewing plane</param>
 /// <param name="LCrH">The center point of the viewing plane</param>
 private static void CalculateViewingPlaneSize(HUD.Element Element, out double LeftWidth, out double RightWidth, out double LCrH)
 {
     LCrH = 0.0;
     // left width/height
     LeftWidth = 0.0;
     if (Element.TopLeft.BackgroundTexture != null)
     {
         if (Textures.LoadTexture(Element.TopLeft.BackgroundTexture, OpenGlTextureWrapMode.ClampClamp))
         {
             double u = (double)Element.TopLeft.BackgroundTexture.Width;
             double v = (double)Element.TopLeft.BackgroundTexture.Height;
             if (u > LeftWidth)
             {
                 LeftWidth = u;
             }
             if (v > LCrH)
             {
                 LCrH = v;
             }
         }
     }
     if (Element.CenterLeft.BackgroundTexture != null)
     {
         if (Textures.LoadTexture(Element.CenterLeft.BackgroundTexture, OpenGlTextureWrapMode.ClampClamp))
         {
             double u = (double)Element.CenterLeft.BackgroundTexture.Width;
             double v = (double)Element.CenterLeft.BackgroundTexture.Height;
             if (u > LeftWidth)
             {
                 LeftWidth = u;
             }
             if (v > LCrH)
             {
                 LCrH = v;
             }
         }
     }
     if (Element.BottomLeft.BackgroundTexture != null)
     {
         if (Textures.LoadTexture(Element.BottomLeft.BackgroundTexture, OpenGlTextureWrapMode.ClampClamp))
         {
             double u = (double)Element.BottomLeft.BackgroundTexture.Width;
             double v = (double)Element.BottomLeft.BackgroundTexture.Height;
             if (u > LeftWidth)
             {
                 LeftWidth = u;
             }
             if (v > LCrH)
             {
                 LCrH = v;
             }
         }
     }
     // center height
     if (Element.TopMiddle.BackgroundTexture != null)
     {
         if (Textures.LoadTexture(Element.TopMiddle.BackgroundTexture, OpenGlTextureWrapMode.ClampClamp))
         {
             double v = (double)Element.TopMiddle.BackgroundTexture.Height;
             if (v > LCrH)
             {
                 LCrH = v;
             }
         }
     }
     if (Element.CenterMiddle.BackgroundTexture != null)
     {
         if (Textures.LoadTexture(Element.CenterMiddle.BackgroundTexture, OpenGlTextureWrapMode.ClampClamp))
         {
             double v = (double)Element.CenterMiddle.BackgroundTexture.Height;
             if (v > LCrH)
             {
                 LCrH = v;
             }
         }
     }
     if (Element.BottomMiddle.BackgroundTexture != null)
     {
         if (Textures.LoadTexture(Element.BottomMiddle.BackgroundTexture, OpenGlTextureWrapMode.ClampClamp))
         {
             double v = (double)Element.BottomMiddle.BackgroundTexture.Height;
             if (v > LCrH)
             {
                 LCrH = v;
             }
         }
     }
     // right width/height
     RightWidth = 0.0;
     if (Element.TopRight.BackgroundTexture != null)
     {
         if (Textures.LoadTexture(Element.TopRight.BackgroundTexture, OpenGlTextureWrapMode.ClampClamp))
         {
             double u = (double)Element.TopRight.BackgroundTexture.Width;
             double v = (double)Element.TopRight.BackgroundTexture.Height;
             if (u > RightWidth)
             {
                 RightWidth = u;
             }
             if (v > LCrH)
             {
                 LCrH = v;
             }
         }
     }
     if (Element.CenterRight.BackgroundTexture != null)
     {
         if (Textures.LoadTexture(Element.CenterRight.BackgroundTexture, OpenGlTextureWrapMode.ClampClamp))
         {
             double u = (double)Element.CenterRight.BackgroundTexture.Width;
             double v = (double)Element.CenterRight.BackgroundTexture.Height;
             if (u > RightWidth)
             {
                 RightWidth = u;
             }
             if (v > LCrH)
             {
                 LCrH = v;
             }
         }
     }
     if (Element.BottomRight.BackgroundTexture != null)
     {
         if (Textures.LoadTexture(Element.BottomRight.BackgroundTexture, OpenGlTextureWrapMode.ClampClamp))
         {
             double u = (double)Element.BottomRight.BackgroundTexture.Width;
             double v = (double)Element.BottomRight.BackgroundTexture.Height;
             if (u > RightWidth)
             {
                 RightWidth = u;
             }
             if (v > LCrH)
             {
                 LCrH = v;
             }
         }
     }
 }
Exemple #3
0
        /// <summary>Renders the ATS lamp overlay</summary>
        /// <param name="Element">The HUD element these are to be rendererd onto</param>
        /// <param name="TimeElapsed">The time elapsed</param>
        private static void RenderATSLamps(HUD.Element Element, double TimeElapsed)
        {
            // ats lamps
            if (CurrentLampCollection.Lamps == null)
            {
                InitializeLamps();
            }
            double lcrh, lw, rw;

            CalculateViewingPlaneSize(Element, out lw, out rw, out lcrh);
            // start

            // ReSharper disable once PossibleNullReferenceException
            int    n = CurrentLampCollection.Lamps.Length;
            double w = (double)CurrentLampCollection.Width + lw + rw;
            double h = Element.Value2 * n;
            double x = Element.Alignment.X < 0 ? 0.0 : Element.Alignment.X > 0 ? Screen.Width - w : 0.5 * (Screen.Width - w);
            double y = Element.Alignment.Y < 0 ? 0.0 : Element.Alignment.Y > 0 ? Screen.Height - h : 0.5 * (Screen.Height - h);

            x += Element.Position.X;
            y += Element.Position.Y;
            for (int j = 0; j < n; j++)
            {
                if (CurrentLampCollection.Lamps[j].Type != LampType.None)
                {
                    int o;
                    if (j == 0)
                    {
                        o = -1;
                    }
                    else if (CurrentLampCollection.Lamps[j - 1].Type == LampType.None)
                    {
                        o = -1;
                    }
                    else if (j < n - 1 && CurrentLampCollection.Lamps[j + 1].Type == LampType.None)
                    {
                        o = 1;
                    }
                    else if (j == n - 1)
                    {
                        o = 1;
                    }
                    else
                    {
                        o = 0;
                    }
                    HUD.Image    Left   = o < 0 ? Element.TopLeft : o == 0 ? Element.CenterLeft : Element.BottomLeft;
                    HUD.Image    Middle = o < 0 ? Element.TopMiddle : o == 0 ? Element.CenterMiddle : Element.BottomMiddle;
                    HUD.Image    Right  = o < 0 ? Element.TopRight : o == 0 ? Element.CenterRight : Element.BottomRight;
                    MessageColor sc     = MessageColor.Gray;
                    if (TrainManager.PlayerTrain.Plugin.Panel.Length >= 272)
                    {
                        switch (CurrentLampCollection.Lamps[j].Type)
                        {
                        case LampType.Ats:
                            if (TrainManager.PlayerTrain.Plugin.Panel[256] != 0)
                            {
                                sc = MessageColor.Orange;
                            }
                            break;

                        case LampType.AtsOperation:
                            if (TrainManager.PlayerTrain.Plugin.Panel[258] != 0)
                            {
                                sc = MessageColor.Red;
                            }
                            break;

                        case LampType.AtsPPower:
                            if (TrainManager.PlayerTrain.Plugin.Panel[259] != 0)
                            {
                                sc = MessageColor.Green;
                            }
                            break;

                        case LampType.AtsPPattern:
                            if (TrainManager.PlayerTrain.Plugin.Panel[260] != 0)
                            {
                                sc = MessageColor.Orange;
                            }
                            break;

                        case LampType.AtsPBrakeOverride:
                            if (TrainManager.PlayerTrain.Plugin.Panel[261] != 0)
                            {
                                sc = MessageColor.Orange;
                            }
                            break;

                        case LampType.AtsPBrakeOperation:
                            if (TrainManager.PlayerTrain.Plugin.Panel[262] != 0)
                            {
                                sc = MessageColor.Orange;
                            }
                            break;

                        case LampType.AtsP:
                            if (TrainManager.PlayerTrain.Plugin.Panel[263] != 0)
                            {
                                sc = MessageColor.Green;
                            }
                            break;

                        case LampType.AtsPFailure:
                            if (TrainManager.PlayerTrain.Plugin.Panel[264] != 0)
                            {
                                sc = MessageColor.Red;
                            }
                            break;

                        case LampType.Atc:
                            if (TrainManager.PlayerTrain.Plugin.Panel[265] != 0)
                            {
                                sc = MessageColor.Orange;
                            }
                            break;

                        case LampType.AtcPower:
                            if (TrainManager.PlayerTrain.Plugin.Panel[266] != 0)
                            {
                                sc = MessageColor.Orange;
                            }
                            break;

                        case LampType.AtcUse:
                            if (TrainManager.PlayerTrain.Plugin.Panel[267] != 0)
                            {
                                sc = MessageColor.Orange;
                            }
                            break;

                        case LampType.AtcEmergency:
                            if (TrainManager.PlayerTrain.Plugin.Panel[268] != 0)
                            {
                                sc = MessageColor.Red;
                            }
                            break;

                        case LampType.Eb:
                            if (TrainManager.PlayerTrain.Plugin.Panel[270] != 0)
                            {
                                sc = MessageColor.Green;
                            }
                            break;

                        case LampType.ConstSpeed:
                            if (TrainManager.PlayerTrain.Plugin.Panel[269] != 0)
                            {
                                sc = MessageColor.Orange;
                            }
                            break;
                        }
                    }
                    // colors
                    float br, bg, bb, ba;
                    CreateBackColor(Element.BackgroundColor, sc, out br, out bg, out bb, out ba);
                    float tr, tg, tb, ta;
                    CreateTextColor(Element.TextColor, sc, out tr, out tg, out tb, out ta);
                    float or, og, ob, oa;
                    CreateBackColor(Element.OverlayColor, sc, out or, out og, out ob, out oa);
                    // left background
                    if (Left.BackgroundTexture != null)
                    {
                        if (Textures.LoadTexture(Left.BackgroundTexture, OpenGlTextureWrapMode.ClampClamp))
                        {
                            double u = (double)Left.BackgroundTexture.Width;
                            double v = (double)Left.BackgroundTexture.Height;
                            GL.Color4(br, bg, bb, ba);
                            RenderOverlayTexture(Left.BackgroundTexture, x, y, x + u, y + v);
                        }
                    }
                    // right background
                    if (Right.BackgroundTexture != null)
                    {
                        if (Textures.LoadTexture(Right.BackgroundTexture, OpenGlTextureWrapMode.ClampClamp))
                        {
                            double u = (double)Right.BackgroundTexture.Width;
                            double v = (double)Right.BackgroundTexture.Height;
                            GL.Color4(br, bg, bb, ba);
                            RenderOverlayTexture(Right.BackgroundTexture, x + w - u, y, x + w, y + v);
                        }
                    }
                    // middle background
                    if (Middle.BackgroundTexture != null)
                    {
                        if (Textures.LoadTexture(Middle.BackgroundTexture, OpenGlTextureWrapMode.ClampClamp))
                        {
                            double v = (double)Middle.BackgroundTexture.Height;
                            GL.Color4(br, bg, bb, ba);
                            RenderOverlayTexture(Middle.BackgroundTexture, x + lw, y, x + w - rw, y + v);
                        }
                    }
                    {                     // text
                        string t = CurrentLampCollection.Lamps[j].Text;
                        double u = CurrentLampCollection.Lamps[j].Width;
                        double v = CurrentLampCollection.Lamps[j].Height;
                        double p = Math.Round(Element.TextAlignment.X < 0 ? x : Element.TextAlignment.X > 0 ? x + w - u : x + 0.5 * (w - u));
                        double q = Math.Round(Element.TextAlignment.Y < 0 ? y : Element.TextAlignment.Y > 0 ? y + lcrh - v : y + 0.5 * (lcrh - v));
                        p += Element.TextPosition.X;
                        q += Element.TextPosition.Y;
                        DrawString(Element.Font, t, new System.Drawing.Point((int)p, (int)q), TextAlignment.TopLeft, new Color128(tr, tg, tb, ta), Element.TextShadow);
                    }
                    // left overlay
                    if (Left.OverlayTexture != null)
                    {
                        if (Textures.LoadTexture(Left.OverlayTexture, OpenGlTextureWrapMode.ClampClamp))
                        {
                            double u = (double)Left.OverlayTexture.Width;
                            double v = (double)Left.OverlayTexture.Height;
                            GL.Color4(or, og, ob, oa);
                            RenderOverlayTexture(Left.OverlayTexture, x, y, x + u, y + v);
                        }
                    }
                    // right overlay
                    if (Right.OverlayTexture != null)
                    {
                        if (Textures.LoadTexture(Right.OverlayTexture, OpenGlTextureWrapMode.ClampClamp))
                        {
                            double u = (double)Right.OverlayTexture.Width;
                            double v = (double)Right.OverlayTexture.Height;
                            GL.Color4(or, og, ob, oa);
                            RenderOverlayTexture(Right.OverlayTexture, x + w - u, y, x + w, y + v);
                        }
                    }
                    // middle overlay
                    if (Middle.OverlayTexture != null)
                    {
                        if (Textures.LoadTexture(Middle.OverlayTexture, OpenGlTextureWrapMode.ClampClamp))
                        {
                            double v = (double)Middle.OverlayTexture.Height;
                            GL.Color4(or, og, ob, oa);
                            RenderOverlayTexture(Middle.OverlayTexture, x + lw, y, x + w - rw, y + v);
                        }
                    }
                }
                y += (double)Element.Value2;
            }
        }
Exemple #4
0
        /// <summary>Renders all default HUD elements</summary>
        /// <param name="Element">The HUD element these are to be rendererd onto</param>
        /// <param name="TimeElapsed">The time elapsed</param>
        private static void RenderHUDElement(HUD.Element Element, double TimeElapsed)
        {
            TrainManager.TrainDoorState      LeftDoors  = TrainManager.GetDoorsState(TrainManager.PlayerTrain, true, false);
            TrainManager.TrainDoorState      RightDoors = TrainManager.GetDoorsState(TrainManager.PlayerTrain, false, true);
            System.Globalization.CultureInfo Culture    = System.Globalization.CultureInfo.InvariantCulture;
            string Command = Element.Subject.ToLowerInvariant();
            // default
            double w, h;

            if (Element.CenterMiddle.BackgroundTexture != null)
            {
                if (Program.CurrentHost.LoadTexture(Element.CenterMiddle.BackgroundTexture, OpenGlTextureWrapMode.ClampClamp))
                {
                    w = (double)Element.CenterMiddle.BackgroundTexture.Width;
                    h = (double)Element.CenterMiddle.BackgroundTexture.Height;
                }
                else
                {
                    w = 0.0; h = 0.0;
                }
            }
            else
            {
                w = 0.0; h = 0.0;
            }
            double x = Element.Alignment.X < 0 ? 0.0 : Element.Alignment.X == 0 ? 0.5 * (LibRender.Screen.Width - w) : LibRender.Screen.Width - w;
            double y = Element.Alignment.Y < 0 ? 0.0 : Element.Alignment.Y == 0 ? 0.5 * (LibRender.Screen.Height - h) : LibRender.Screen.Height - h;

            x += Element.Position.X;
            y += Element.Position.Y;
            // command
            const double speed = 1.0;
            MessageColor sc    = MessageColor.None;
            string       t;

            switch (Command)
            {
            case "reverser":
                if (TrainManager.PlayerTrain.Handles.Reverser.Driver < 0)
                {
                    sc = MessageColor.Orange;
                    if (TrainManager.PlayerTrain.ReverserDescriptions != null && TrainManager.PlayerTrain.ReverserDescriptions.Length > 2)
                    {
                        t = TrainManager.PlayerTrain.ReverserDescriptions[2];
                    }
                    else
                    {
                        t = Translations.QuickReferences.HandleBackward;
                    }
                }
                else if (TrainManager.PlayerTrain.Handles.Reverser.Driver > 0)
                {
                    sc = MessageColor.Blue;
                    if (TrainManager.PlayerTrain.ReverserDescriptions != null && TrainManager.PlayerTrain.ReverserDescriptions.Length > 0)
                    {
                        t = TrainManager.PlayerTrain.ReverserDescriptions[0];
                    }
                    else
                    {
                        t = Translations.QuickReferences.HandleForward;
                    }
                }
                else
                {
                    sc = MessageColor.Gray;
                    if (TrainManager.PlayerTrain.ReverserDescriptions != null && TrainManager.PlayerTrain.ReverserDescriptions.Length > 1)
                    {
                        t = TrainManager.PlayerTrain.ReverserDescriptions[1];
                    }
                    else
                    {
                        t = Translations.QuickReferences.HandleNeutral;
                    }
                }
                Element.TransitionState = 0.0;
                break;

            case "power":
                if (TrainManager.PlayerTrain.Handles.SingleHandle)
                {
                    return;
                }
                if (TrainManager.PlayerTrain.Handles.Power.Driver == 0)
                {
                    sc = MessageColor.Gray;
                    if (TrainManager.PlayerTrain.PowerNotchDescriptions != null && TrainManager.PlayerTrain.PowerNotchDescriptions.Length > 0)
                    {
                        t = TrainManager.PlayerTrain.PowerNotchDescriptions[0];
                    }
                    else
                    {
                        t = Translations.QuickReferences.HandlePowerNull;
                    }
                }
                else
                {
                    sc = MessageColor.Blue;
                    if (TrainManager.PlayerTrain.PowerNotchDescriptions != null && TrainManager.PlayerTrain.Handles.Power.Driver < TrainManager.PlayerTrain.PowerNotchDescriptions.Length)
                    {
                        t = TrainManager.PlayerTrain.PowerNotchDescriptions[TrainManager.PlayerTrain.Handles.Power.Driver];
                    }
                    else
                    {
                        t = Translations.QuickReferences.HandlePower + TrainManager.PlayerTrain.Handles.Power.Driver.ToString(Culture);
                    }
                }
                Element.TransitionState = 0.0;
                break;

            case "brake":
                if (TrainManager.PlayerTrain.Handles.SingleHandle)
                {
                    return;
                }
                if (TrainManager.PlayerTrain.Handles.Brake is TrainManager.AirBrakeHandle)
                {
                    if (TrainManager.PlayerTrain.Handles.EmergencyBrake.Driver)
                    {
                        sc = MessageColor.Red;
                        if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 0)
                        {
                            t = TrainManager.PlayerTrain.BrakeNotchDescriptions[0];
                        }
                        else
                        {
                            t = Translations.QuickReferences.HandleEmergency;
                        }
                    }
                    else if (TrainManager.PlayerTrain.Handles.Brake.Driver == (int)TrainManager.AirBrakeHandleState.Release)
                    {
                        sc = MessageColor.Gray;
                        if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 1)
                        {
                            t = TrainManager.PlayerTrain.BrakeNotchDescriptions[1];
                        }
                        else
                        {
                            t = Translations.QuickReferences.HandleRelease;
                        }
                    }
                    else if (TrainManager.PlayerTrain.Handles.Brake.Driver == (int)TrainManager.AirBrakeHandleState.Lap)
                    {
                        sc = MessageColor.Blue;
                        if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 2)
                        {
                            t = TrainManager.PlayerTrain.BrakeNotchDescriptions[2];
                        }
                        else
                        {
                            t = Translations.QuickReferences.HandleLap;
                        }
                    }
                    else
                    {
                        sc = MessageColor.Orange;
                        if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 3)
                        {
                            t = TrainManager.PlayerTrain.BrakeNotchDescriptions[3];
                        }
                        else
                        {
                            t = Translations.QuickReferences.HandleService;
                        }
                    }
                }
                else
                {
                    if (TrainManager.PlayerTrain.Handles.EmergencyBrake.Driver)
                    {
                        sc = MessageColor.Red;
                        if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 0)
                        {
                            t = TrainManager.PlayerTrain.BrakeNotchDescriptions[0];
                        }
                        else
                        {
                            t = Translations.QuickReferences.HandleEmergency;
                        }
                    }
                    else if (TrainManager.PlayerTrain.Handles.HoldBrake.Driver)
                    {
                        sc = MessageColor.Green;
                        if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 2)
                        {
                            t = TrainManager.PlayerTrain.BrakeNotchDescriptions[2];
                        }
                        else
                        {
                            t = Translations.QuickReferences.HandleHoldBrake;
                        }
                    }
                    else if (TrainManager.PlayerTrain.Handles.Brake.Driver == 0)
                    {
                        sc = MessageColor.Gray;
                        if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 1)
                        {
                            t = TrainManager.PlayerTrain.BrakeNotchDescriptions[1];
                        }
                        else
                        {
                            t = Translations.QuickReferences.HandleBrakeNull;
                        }
                    }
                    else
                    {
                        sc = MessageColor.Orange;
                        if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && ((TrainManager.PlayerTrain.Handles.HasHoldBrake && TrainManager.PlayerTrain.Handles.Brake.Driver + 2 < TrainManager.PlayerTrain.BrakeNotchDescriptions.Length) || (!TrainManager.PlayerTrain.Handles.HasHoldBrake && TrainManager.PlayerTrain.Handles.Brake.Driver + 1 < TrainManager.PlayerTrain.BrakeNotchDescriptions.Length)))
                        {
                            t = TrainManager.PlayerTrain.Handles.HasHoldBrake ? TrainManager.PlayerTrain.BrakeNotchDescriptions[TrainManager.PlayerTrain.Handles.Brake.Driver + 2] : TrainManager.PlayerTrain.BrakeNotchDescriptions[TrainManager.PlayerTrain.Handles.Brake.Driver + 1];
                        }
                        else
                        {
                            t = Translations.QuickReferences.HandleBrake + TrainManager.PlayerTrain.Handles.Brake.Driver.ToString(Culture);
                        }
                    }
                }
                Element.TransitionState = 0.0;
                break;

            case "locobrake":
                if (!TrainManager.PlayerTrain.Handles.HasLocoBrake)
                {
                    return;
                }

                if (TrainManager.PlayerTrain.Handles.LocoBrake is TrainManager.LocoAirBrakeHandle)
                {
                    if (TrainManager.PlayerTrain.Handles.LocoBrake.Driver == (int)TrainManager.AirBrakeHandleState.Release)
                    {
                        sc = MessageColor.Gray;
                        if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 1)
                        {
                            t = TrainManager.PlayerTrain.BrakeNotchDescriptions[1];
                        }
                        else
                        {
                            t = Translations.QuickReferences.HandleRelease;
                        }
                    }
                    else if (TrainManager.PlayerTrain.Handles.LocoBrake.Driver == (int)TrainManager.AirBrakeHandleState.Lap)
                    {
                        sc = MessageColor.Blue;
                        if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 2)
                        {
                            t = TrainManager.PlayerTrain.BrakeNotchDescriptions[2];
                        }
                        else
                        {
                            t = Translations.QuickReferences.HandleLap;
                        }
                    }
                    else
                    {
                        sc = MessageColor.Orange;
                        if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 3)
                        {
                            t = TrainManager.PlayerTrain.BrakeNotchDescriptions[3];
                        }
                        else
                        {
                            t = Translations.QuickReferences.HandleService;
                        }
                    }
                }
                else
                {
                    if (TrainManager.PlayerTrain.Handles.LocoBrake.Driver == 0)
                    {
                        sc = MessageColor.Gray;
                        if (TrainManager.PlayerTrain.LocoBrakeNotchDescriptions != null && TrainManager.PlayerTrain.LocoBrakeNotchDescriptions.Length > 1)
                        {
                            t = TrainManager.PlayerTrain.LocoBrakeNotchDescriptions[1];
                        }
                        else
                        {
                            t = Translations.QuickReferences.HandleBrakeNull;
                        }
                    }
                    else
                    {
                        sc = MessageColor.Orange;
                        if (TrainManager.PlayerTrain.LocoBrakeNotchDescriptions != null && TrainManager.PlayerTrain.Handles.LocoBrake.Driver < TrainManager.PlayerTrain.LocoBrakeNotchDescriptions.Length)
                        {
                            t = TrainManager.PlayerTrain.LocoBrakeNotchDescriptions[TrainManager.PlayerTrain.Handles.LocoBrake.Driver];
                        }
                        else
                        {
                            t = Translations.QuickReferences.HandleLocoBrake + TrainManager.PlayerTrain.Handles.LocoBrake.Driver.ToString(Culture);
                        }
                    }
                }
                Element.TransitionState = 0.0;
                break;

            case "single":
                if (!TrainManager.PlayerTrain.Handles.SingleHandle)
                {
                    return;
                }
                if (TrainManager.PlayerTrain.Handles.EmergencyBrake.Driver)
                {
                    sc = MessageColor.Red;
                    if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 0)
                    {
                        t = TrainManager.PlayerTrain.BrakeNotchDescriptions[0];
                    }
                    else
                    {
                        t = Translations.QuickReferences.HandleEmergency;
                    }
                }
                else if (TrainManager.PlayerTrain.Handles.HoldBrake.Driver)
                {
                    sc = MessageColor.Green;
                    if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 1)
                    {
                        t = TrainManager.PlayerTrain.BrakeNotchDescriptions[1];
                    }
                    else
                    {
                        t = Translations.QuickReferences.HandleHoldBrake;
                    }
                }
                else if (TrainManager.PlayerTrain.Handles.Brake.Driver > 0)
                {
                    sc = MessageColor.Orange;
                    if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.Handles.Brake.Driver + 3 < TrainManager.PlayerTrain.BrakeNotchDescriptions.Length)
                    {
                        t = TrainManager.PlayerTrain.BrakeNotchDescriptions[TrainManager.PlayerTrain.Handles.Brake.Driver + 3];
                    }
                    else
                    {
                        t = Translations.QuickReferences.HandleBrake + TrainManager.PlayerTrain.Handles.Brake.Driver.ToString(Culture);
                    }
                }
                else if (TrainManager.PlayerTrain.Handles.Power.Driver > 0)
                {
                    sc = MessageColor.Blue;
                    if (TrainManager.PlayerTrain.PowerNotchDescriptions != null && TrainManager.PlayerTrain.Handles.Power.Driver < TrainManager.PlayerTrain.PowerNotchDescriptions.Length)
                    {
                        t = TrainManager.PlayerTrain.PowerNotchDescriptions[TrainManager.PlayerTrain.Handles.Power.Driver];
                    }
                    else
                    {
                        t = Translations.QuickReferences.HandlePower + TrainManager.PlayerTrain.Handles.Power.Driver.ToString(Culture);
                    }
                }
                else
                {
                    sc = MessageColor.Gray;
                    if (TrainManager.PlayerTrain.PowerNotchDescriptions != null && TrainManager.PlayerTrain.PowerNotchDescriptions.Length > 0)
                    {
                        t = TrainManager.PlayerTrain.PowerNotchDescriptions[0];
                    }
                    else
                    {
                        t = Translations.QuickReferences.HandlePowerNull;
                    }
                }
                Element.TransitionState = 0.0;
                break;

            case "doorsleft":
            case "doorsright":
            {
                if ((LeftDoors & TrainManager.TrainDoorState.AllClosed) == 0 | (RightDoors & TrainManager.TrainDoorState.AllClosed) == 0)
                {
                    Element.TransitionState -= speed * TimeElapsed;
                    if (Element.TransitionState < 0.0)
                    {
                        Element.TransitionState = 0.0;
                    }
                }
                else
                {
                    Element.TransitionState += speed * TimeElapsed;
                    if (Element.TransitionState > 1.0)
                    {
                        Element.TransitionState = 1.0;
                    }
                }
                TrainManager.TrainDoorState Doors = Command == "doorsleft" ? LeftDoors : RightDoors;
                if ((Doors & TrainManager.TrainDoorState.Mixed) != 0)
                {
                    sc = MessageColor.Orange;
                }
                else if ((Doors & TrainManager.TrainDoorState.AllClosed) != 0)
                {
                    sc = MessageColor.Gray;
                }
                else if (TrainManager.PlayerTrain.Specs.DoorCloseMode == TrainManager.DoorMode.Manual)
                {
                    sc = MessageColor.Green;
                }
                else
                {
                    sc = MessageColor.Blue;
                }
                t = Command == "doorsleft" ? Translations.QuickReferences.DoorsLeft : Translations.QuickReferences.DoorsRight;
            } break;

            case "stopleft":
            case "stopright":
            case "stopnone":
            {
                int s = TrainManager.PlayerTrain.Station;
                if (s >= 0 && CurrentRoute.Stations[s].PlayerStops() && Interface.CurrentOptions.GameMode != GameMode.Expert)
                {
                    bool cond;
                    if (Command == "stopleft")
                    {
                        cond = CurrentRoute.Stations[s].OpenLeftDoors;
                    }
                    else if (Command == "stopright")
                    {
                        cond = CurrentRoute.Stations[s].OpenRightDoors;
                    }
                    else
                    {
                        cond = !CurrentRoute.Stations[s].OpenLeftDoors & !CurrentRoute.Stations[s].OpenRightDoors;
                    }
                    if (TrainManager.PlayerTrain.StationState == TrainStopState.Pending & cond)
                    {
                        Element.TransitionState -= speed * TimeElapsed;
                        if (Element.TransitionState < 0.0)
                        {
                            Element.TransitionState = 0.0;
                        }
                    }
                    else
                    {
                        Element.TransitionState += speed * TimeElapsed;
                        if (Element.TransitionState > 1.0)
                        {
                            Element.TransitionState = 1.0;
                        }
                    }
                }
                else
                {
                    Element.TransitionState += speed * TimeElapsed;
                    if (Element.TransitionState > 1.0)
                    {
                        Element.TransitionState = 1.0;
                    }
                }
                t = Element.Text;
            } break;

            case "stoplefttick":
            case "stoprighttick":
            case "stopnonetick":
            {
                int s = TrainManager.PlayerTrain.Station;
                if (s >= 0 && CurrentRoute.Stations[s].PlayerStops() && Interface.CurrentOptions.GameMode != GameMode.Expert)
                {
                    int c = CurrentRoute.Stations[s].GetStopIndex(TrainManager.PlayerTrain.Cars.Length);
                    if (c >= 0)
                    {
                        bool cond;
                        if (Command == "stoplefttick")
                        {
                            cond = CurrentRoute.Stations[s].OpenLeftDoors;
                        }
                        else if (Command == "stoprighttick")
                        {
                            cond = CurrentRoute.Stations[s].OpenRightDoors;
                        }
                        else
                        {
                            cond = !CurrentRoute.Stations[s].OpenLeftDoors & !CurrentRoute.Stations[s].OpenRightDoors;
                        }
                        if (TrainManager.PlayerTrain.StationState == TrainStopState.Pending & cond)
                        {
                            Element.TransitionState -= speed * TimeElapsed;
                            if (Element.TransitionState < 0.0)
                            {
                                Element.TransitionState = 0.0;
                            }
                        }
                        else
                        {
                            Element.TransitionState += speed * TimeElapsed;
                            if (Element.TransitionState > 1.0)
                            {
                                Element.TransitionState = 1.0;
                            }
                        }
                        double d = TrainManager.PlayerTrain.StationDistanceToStopPoint;
                        double r;
                        if (d > 0.0)
                        {
                            r = d / CurrentRoute.Stations[s].Stops[c].BackwardTolerance;
                        }
                        else
                        {
                            r = d / CurrentRoute.Stations[s].Stops[c].ForwardTolerance;
                        }
                        if (r < -1.0)
                        {
                            r = -1.0;
                        }
                        if (r > 1.0)
                        {
                            r = 1.0;
                        }
                        y -= r * (double)Element.Value1;
                    }
                    else
                    {
                        Element.TransitionState += speed * TimeElapsed;
                        if (Element.TransitionState > 1.0)
                        {
                            Element.TransitionState = 1.0;
                        }
                    }
                }
                else
                {
                    Element.TransitionState += speed * TimeElapsed;
                    if (Element.TransitionState > 1.0)
                    {
                        Element.TransitionState = 1.0;
                    }
                }
                t = Element.Text;
            } break;

            case "clock":
            {
                int hours   = (int)Math.Floor(Game.SecondsSinceMidnight);
                int seconds = hours % 60; hours /= 60;
                int minutes = hours % 60; hours /= 60;
                hours %= 24;
                t      = hours.ToString(Culture).PadLeft(2, '0') + ":" + minutes.ToString(Culture).PadLeft(2, '0') + ":" + seconds.ToString(Culture).PadLeft(2, '0');
                if (OptionClock)
                {
                    Element.TransitionState -= speed * TimeElapsed;
                    if (Element.TransitionState < 0.0)
                    {
                        Element.TransitionState = 0.0;
                    }
                }
                else
                {
                    Element.TransitionState += speed * TimeElapsed;
                    if (Element.TransitionState > 1.0)
                    {
                        Element.TransitionState = 1.0;
                    }
                }
            } break;

            case "gradient":
                if (OptionGradient == GradientDisplayMode.Percentage)
                {
                    if (World.CameraTrackFollower.Pitch != 0)
                    {
                        double pc = World.CameraTrackFollower.Pitch;
                        t = Math.Abs(pc).ToString("0.00", Culture) + "%" + (Math.Abs(pc) == pc ? " ↗" : " ↘");
                    }
                    else
                    {
                        t = "Level";
                    }
                    Element.TransitionState -= speed * TimeElapsed;
                    if (Element.TransitionState < 0.0)
                    {
                        Element.TransitionState = 0.0;
                    }
                }
                else if (OptionGradient == GradientDisplayMode.UnitOfChange)
                {
                    if (World.CameraTrackFollower.Pitch != 0)
                    {
                        double gr = 1000 / World.CameraTrackFollower.Pitch;
                        t = "1 in " + Math.Abs(gr).ToString("0", Culture) + (Math.Abs(gr) == gr ? " ↗" : " ↘");
                    }
                    else
                    {
                        t = "Level";
                    }
                    Element.TransitionState -= speed * TimeElapsed;
                    if (Element.TransitionState < 0.0)
                    {
                        Element.TransitionState = 0.0;
                    }
                }
                else if (OptionGradient == GradientDisplayMode.Permil)
                {
                    if (World.CameraTrackFollower.Pitch != 0)
                    {
                        double pm = World.CameraTrackFollower.Pitch;
                        t = Math.Abs(pm).ToString("0.00", Culture) + "‰" + (Math.Abs(pm) == pm ? " ↗" : " ↘");
                    }
                    else
                    {
                        t = "Level";
                    }
                    Element.TransitionState -= speed * TimeElapsed;
                    if (Element.TransitionState < 0.0)
                    {
                        Element.TransitionState = 0.0;
                    }
                }
                else
                {
                    if (World.CameraTrackFollower.Pitch != 0)
                    {
                        double gr = 1000 / World.CameraTrackFollower.Pitch;
                        t = "1 in " + Math.Abs(gr).ToString("0", Culture) + (Math.Abs(gr) == gr ? " ↗" : " ↘");
                    }
                    else
                    {
                        t = "Level";
                    }
                    Element.TransitionState += speed * TimeElapsed;
                    if (Element.TransitionState > 1.0)
                    {
                        Element.TransitionState = 1.0;
                    }
                } break;

            case "speed":
                if (OptionSpeed == SpeedDisplayMode.Kmph)
                {
                    double kmph = Math.Abs(TrainManager.PlayerTrain.CurrentSpeed) * 3.6;
                    t = kmph.ToString("0.00", Culture) + " km/h";
                    Element.TransitionState -= speed * TimeElapsed;
                    if (Element.TransitionState < 0.0)
                    {
                        Element.TransitionState = 0.0;
                    }
                }
                else if (OptionSpeed == SpeedDisplayMode.Mph)
                {
                    double mph = Math.Abs(TrainManager.PlayerTrain.CurrentSpeed) * 2.2369362920544;
                    t = mph.ToString("0.00", Culture) + " mph";
                    Element.TransitionState -= speed * TimeElapsed;
                    if (Element.TransitionState < 0.0)
                    {
                        Element.TransitionState = 0.0;
                    }
                }
                else
                {
                    double mph = Math.Abs(TrainManager.PlayerTrain.CurrentSpeed) * 2.2369362920544;
                    t = mph.ToString("0.00", Culture) + " mph";
                    Element.TransitionState += speed * TimeElapsed;
                    if (Element.TransitionState > 1.0)
                    {
                        Element.TransitionState = 1.0;
                    }
                } break;

            case "dist_next_station":
                int i;
                if (TrainManager.PlayerTrain.Station >= 0 && TrainManager.PlayerTrain.StationState != TrainStopState.Completed)
                {
                    i = TrainManager.PlayerTrain.LastStation;
                }
                else
                {
                    i = TrainManager.PlayerTrain.LastStation + 1;
                }
                if (i > CurrentRoute.Stations.Length - 1)
                {
                    i = TrainManager.PlayerTrain.LastStation;
                }
                int    n  = CurrentRoute.Stations[i].GetStopIndex(TrainManager.PlayerTrain.NumberOfCars);
                double p0 = TrainManager.PlayerTrain.FrontCarTrackPosition();
                double p1;
                if (CurrentRoute.Stations[i].Stops.Length > 0)
                {
                    p1 = CurrentRoute.Stations[i].Stops[n].TrackPosition;
                }
                else
                {
                    p1 = CurrentRoute.Stations[i].DefaultTrackPosition;
                }
                double m = p1 - p0;
                if (OptionDistanceToNextStation == DistanceToNextStationDisplayMode.Km)
                {
                    if (CurrentRoute.Stations[i].PlayerStops())
                    {
                        t = "Stop: ";
                        if (Math.Abs(m) <= 10.0)
                        {
                            t += m.ToString("0.00", Culture) + " m";
                        }
                        else
                        {
                            m /= 1000.0;
                            t += m.ToString("0.000", Culture) + " km";
                        }
                    }
                    else
                    {
                        m /= 1000.0;
                        t  = "Pass: "******"0.000", Culture) + " km";
                    }
                    Element.TransitionState -= speed * TimeElapsed;
                    if (Element.TransitionState < 0.0)
                    {
                        Element.TransitionState = 0.0;
                    }
                }
                else if (OptionDistanceToNextStation == DistanceToNextStationDisplayMode.Mile)
                {
                    m /= 1609.34;
                    if (CurrentRoute.Stations[i].PlayerStops())
                    {
                        t = "Stop: ";
                    }
                    else
                    {
                        t = "Pass: "******"0.0000", Culture) + " miles";
                    Element.TransitionState -= speed * TimeElapsed;
                    if (Element.TransitionState < 0.0)
                    {
                        Element.TransitionState = 0.0;
                    }
                }
                else
                {
                    m /= 1609.34;
                    if (CurrentRoute.Stations[i].PlayerStops())
                    {
                        t = "Stop: ";
                    }
                    else
                    {
                        t = "Pass: "******"0.0000", Culture) + " miles";
                    Element.TransitionState += speed * TimeElapsed;
                    if (Element.TransitionState > 1.0)
                    {
                        Element.TransitionState = 1.0;
                    }
                } break;

            case "fps":
                int fps = (int)Math.Round(LibRender.Renderer.FrameRate);
                t = fps.ToString(Culture) + " fps";
                if (OptionFrameRates)
                {
                    Element.TransitionState -= speed * TimeElapsed;
                    if (Element.TransitionState < 0.0)
                    {
                        Element.TransitionState = 0.0;
                    }
                }
                else
                {
                    Element.TransitionState += speed * TimeElapsed;
                    if (Element.TransitionState > 1.0)
                    {
                        Element.TransitionState = 1.0;
                    }
                } break;

            case "ai":
                t = "A.I.";
                if (TrainManager.PlayerTrain.AI != null)
                {
                    Element.TransitionState -= speed * TimeElapsed;
                    if (Element.TransitionState < 0.0)
                    {
                        Element.TransitionState = 0.0;
                    }
                }
                else
                {
                    Element.TransitionState += speed * TimeElapsed;
                    if (Element.TransitionState > 1.0)
                    {
                        Element.TransitionState = 1.0;
                    }
                } break;

            case "score":
                if (Interface.CurrentOptions.GameMode == GameMode.Arcade)
                {
                    t = Game.CurrentScore.CurrentValue.ToString(Culture) + " / " + Game.CurrentScore.Maximum.ToString(Culture);
                    if (Game.CurrentScore.CurrentValue < 0)
                    {
                        sc = MessageColor.Red;
                    }
                    else if (Game.CurrentScore.CurrentValue > 0)
                    {
                        sc = MessageColor.Green;
                    }
                    else
                    {
                        sc = MessageColor.Gray;
                    }
                    Element.TransitionState = 0.0;
                }
                else
                {
                    Element.TransitionState = 1.0;
                    t = "";
                } break;

            default:
                t = Element.Text;
                break;
            }
            // transitions
            float alpha = 1.0f;

            if ((Element.Transition & HUD.Transition.Move) != 0)
            {
                double s = Element.TransitionState;
                x += Element.TransitionVector.X * s * s;
                y += Element.TransitionVector.Y * s * s;
            }
            if ((Element.Transition & HUD.Transition.Fade) != 0)
            {
                alpha = (float)(1.0 - Element.TransitionState);
            }
            else if (Element.Transition == HUD.Transition.None)
            {
                alpha = (float)(1.0 - Element.TransitionState);
            }
            // render
            if (alpha != 0.0f)
            {
                // background
                if (Element.Subject == "reverser")
                {
                    w = Math.Max(w, TrainManager.PlayerTrain.MaxReverserWidth);
                    //X-Pos doesn't need to be changed
                }
                if (Element.Subject == "power")
                {
                    w = Math.Max(w, TrainManager.PlayerTrain.MaxPowerNotchWidth);
                    if (TrainManager.PlayerTrain.MaxReverserWidth > 48)
                    {
                        x += (TrainManager.PlayerTrain.MaxReverserWidth - 48);
                    }
                }
                if (Element.Subject == "brake")
                {
                    w = Math.Max(w, TrainManager.PlayerTrain.MaxBrakeNotchWidth);
                    if (TrainManager.PlayerTrain.MaxReverserWidth > 48)
                    {
                        x += (TrainManager.PlayerTrain.MaxReverserWidth - 48);
                    }
                    if (TrainManager.PlayerTrain.MaxPowerNotchWidth > 48)
                    {
                        x += (TrainManager.PlayerTrain.MaxPowerNotchWidth - 48);
                    }
                }
                if (Element.Subject == "single")
                {
                    w = Math.Max(Math.Max(w, TrainManager.PlayerTrain.MaxPowerNotchWidth), TrainManager.PlayerTrain.MaxBrakeNotchWidth);
                    if (TrainManager.PlayerTrain.MaxReverserWidth > 48)
                    {
                        x += (TrainManager.PlayerTrain.MaxReverserWidth - 48);
                    }
                }
                if (Element.CenterMiddle.BackgroundTexture != null)
                {
                    if (Program.CurrentHost.LoadTexture(Element.CenterMiddle.BackgroundTexture, OpenGlTextureWrapMode.ClampClamp))
                    {
                        Color128 c = Element.BackgroundColor.CreateBackColor(sc, alpha);
                        GL.Color4(c.R, c.G, c.B, c.A);
                        LibRender.Renderer.RenderOverlayTexture(Element.CenterMiddle.BackgroundTexture, x, y, x + w, y + h);
                    }
                }
                {                 // text
                    System.Drawing.Size size = Element.Font.MeasureString(t);
                    float  u = size.Width;
                    float  v = size.Height;
                    double p = Math.Round(Element.TextAlignment.X < 0 ? x : Element.TextAlignment.X == 0 ? x + 0.5 * (w - u) : x + w - u);
                    double q = Math.Round(Element.TextAlignment.Y < 0 ? y : Element.TextAlignment.Y == 0 ? y + 0.5 * (h - v) : y + h - v);
                    p += Element.TextPosition.X;
                    q += Element.TextPosition.Y;
                    Color128 c = Element.TextColor.CreateTextColor(sc, alpha);
                    LibRender.Renderer.DrawString(Element.Font, t, new System.Drawing.Point((int)p, (int)q), TextAlignment.TopLeft, c, Element.TextShadow);
                }
                // overlay
                if (Element.CenterMiddle.OverlayTexture != null)
                {
                    if (Program.CurrentHost.LoadTexture(Element.CenterMiddle.OverlayTexture, OpenGlTextureWrapMode.ClampClamp))
                    {
                        Color128 c = Element.OverlayColor.CreateBackColor(sc, alpha);
                        GL.Color4(c.R, c.G, c.B, c.A);
                        LibRender.Renderer.RenderOverlayTexture(Element.CenterMiddle.OverlayTexture, x, y, x + w, y + h);
                    }
                }
            }
        }
        /// <summary>Renders the list of score messages</summary>
        /// <param name="Element">The HUD element these are to be rendererd onto</param>
        /// <param name="TimeElapsed">The time elapsed</param>
        private static void RenderScoreMessages(HUD.Element Element, double TimeElapsed)
        {
            // score messages
            int   n          = Game.ScoreMessages.Length;
            float totalwidth = 16.0f;

            float[] widths  = new float[n];
            float[] heights = new float[n];
            for (int j = 0; j < n; j++)
            {
                System.Drawing.Size size = MeasureString(Element.Font, Game.ScoreMessages[j].Text);
                widths[j]  = size.Width;
                heights[j] = size.Height;
                float a = widths[j] - j * Element.Value1;
                if (a > totalwidth)
                {
                    totalwidth = a;
                }
            }
            Game.ScoreMessagesRendererSize.X += 16.0 * TimeElapsed * ((double)totalwidth - Game.ScoreMessagesRendererSize.X);
            totalwidth = (float)Game.ScoreMessagesRendererSize.X;
            double lcrh, lw, rw;

            CalculateViewingPlaneSize(Element, out lw, out rw, out lcrh);
            // start
            double w = Element.Alignment.X == 0 ? lw + rw + 128 : totalwidth + lw + rw;
            double h = Element.Value2 * n;
            double x = Element.Alignment.X < 0 ? 0.0 : Element.Alignment.X > 0 ? Screen.Width - w : 0.5 * (Screen.Width - w);
            double y = Element.Alignment.Y < 0 ? 0.0 : Element.Alignment.Y > 0 ? Screen.Height - h : 0.5 * (Screen.Height - h);

            x += Element.Position.X;
            y += Element.Position.Y;
            int m = 0;

            for (int j = 0; j < n; j++)
            {
                float br, bg, bb, ba;
                CreateBackColor(Element.BackgroundColor, Game.ScoreMessages[j].Color, out br, out bg, out bb, out ba);
                float tr, tg, tb, ta;
                CreateTextColor(Element.TextColor, Game.ScoreMessages[j].Color, out tr, out tg, out tb, out ta);
                float or, og, ob, oa;
                CreateBackColor(Element.OverlayColor, Game.ScoreMessages[j].Color, out or, out og, out ob, out oa);
                double tx, ty;
                bool   preserve = false;
                if ((Element.Transition & HUD.Transition.Move) != 0)
                {
                    if (Game.SecondsSinceMidnight < Game.ScoreMessages[j].Timeout)
                    {
                        if (Game.ScoreMessages[j].RendererAlpha == 0.0)
                        {
                            Game.ScoreMessages[j].RendererPosition.X = x + Element.TransitionVector.X;
                            Game.ScoreMessages[j].RendererPosition.Y = y + Element.TransitionVector.Y;
                            Game.ScoreMessages[j].RendererAlpha      = 1.0;
                        }
                        tx       = x;
                        ty       = y + m * Element.Value2;
                        preserve = true;
                    }
                    else if (Element.Transition == HUD.Transition.MoveAndFade)
                    {
                        tx = x;
                        ty = y + m * Element.Value2;
                    }
                    else
                    {
                        tx = x + Element.TransitionVector.X;
                        ty = y + (j + 1) * Element.TransitionVector.Y;
                    }
                    const double speed = 2.0;
                    double       dx    = (speed * Math.Abs(tx - Game.ScoreMessages[j].RendererPosition.X) + 0.1) * TimeElapsed;
                    double       dy    = (speed * Math.Abs(ty - Game.ScoreMessages[j].RendererPosition.Y) + 0.1) * TimeElapsed;
                    if (Math.Abs(tx - Game.ScoreMessages[j].RendererPosition.X) < dx)
                    {
                        Game.ScoreMessages[j].RendererPosition.X = tx;
                    }
                    else
                    {
                        Game.ScoreMessages[j].RendererPosition.X += Math.Sign(tx - Game.ScoreMessages[j].RendererPosition.X) * dx;
                    }
                    if (Math.Abs(ty - Game.ScoreMessages[j].RendererPosition.Y) < dy)
                    {
                        Game.ScoreMessages[j].RendererPosition.Y = ty;
                    }
                    else
                    {
                        Game.ScoreMessages[j].RendererPosition.Y += Math.Sign(ty - Game.ScoreMessages[j].RendererPosition.Y) * dy;
                    }
                }
                else
                {
                    tx = x;
                    ty = y + m * Element.Value2;
                    Game.ScoreMessages[j].RendererPosition.X = 0.0;
                    const double speed = 12.0;
                    double       dy    = (speed * Math.Abs(ty - Game.ScoreMessages[j].RendererPosition.Y) + 0.1) * TimeElapsed;
                    Game.ScoreMessages[j].RendererPosition.X = x;
                    if (Math.Abs(ty - Game.ScoreMessages[j].RendererPosition.Y) < dy)
                    {
                        Game.ScoreMessages[j].RendererPosition.Y = ty;
                    }
                    else
                    {
                        Game.ScoreMessages[j].RendererPosition.Y += Math.Sign(ty - Game.ScoreMessages[j].RendererPosition.Y) * dy;
                    }
                }
                if ((Element.Transition & HUD.Transition.Fade) != 0)
                {
                    if (Game.SecondsSinceMidnight >= Game.ScoreMessages[j].Timeout)
                    {
                        Game.ScoreMessages[j].RendererAlpha -= TimeElapsed;
                        if (Game.ScoreMessages[j].RendererAlpha < 0.0)
                        {
                            Game.ScoreMessages[j].RendererAlpha = 0.0;
                        }
                    }
                    else
                    {
                        Game.ScoreMessages[j].RendererAlpha += TimeElapsed;
                        if (Game.ScoreMessages[j].RendererAlpha > 1.0)
                        {
                            Game.ScoreMessages[j].RendererAlpha = 1.0;
                        }

                        preserve = true;
                    }
                }
                else if (Game.SecondsSinceMidnight > Game.ScoreMessages[j].Timeout)
                {
                    if (Math.Abs(Game.ScoreMessages[j].RendererPosition.X - tx) < 0.1 & Math.Abs(Game.ScoreMessages[j].RendererPosition.Y - ty) < 0.1)
                    {
                        Game.ScoreMessages[j].RendererAlpha = 0.0;
                    }
                }
                if (preserve)
                {
                    m++;
                }

                double px    = Game.ScoreMessages[j].RendererPosition.X + (double)j * (double)Element.Value1;
                double py    = Game.ScoreMessages[j].RendererPosition.Y;
                float  alpha = (float)(Game.ScoreMessages[j].RendererAlpha * Game.ScoreMessages[j].RendererAlpha);
                // graphics
                HUD.Image Left   = j == 0 ? Element.TopLeft : j < n - 1 ? Element.CenterLeft : Element.BottomLeft;
                HUD.Image Middle = j == 0 ? Element.TopMiddle : j < n - 1 ? Element.CenterMiddle : Element.BottomMiddle;
                HUD.Image Right  = j == 0 ? Element.TopRight : j < n - 1 ? Element.CenterRight : Element.BottomRight;
                // left background
                if (Left.BackgroundTexture != null)
                {
                    if (Textures.LoadTexture(Left.BackgroundTexture, OpenGlTextureWrapMode.ClampClamp))
                    {
                        double u = (double)Left.BackgroundTexture.Width;
                        double v = (double)Left.BackgroundTexture.Height;
                        GL.Color4(br, bg, bb, ba * alpha);
                        RenderOverlayTexture(Left.BackgroundTexture, px, py, px + u, py + v);
                    }
                }
                // right background
                if (Right.BackgroundTexture != null)
                {
                    if (Textures.LoadTexture(Right.BackgroundTexture, OpenGlTextureWrapMode.ClampClamp))
                    {
                        double u = (double)Right.BackgroundTexture.Width;
                        double v = (double)Right.BackgroundTexture.Height;
                        GL.Color4(br, bg, bb, ba * alpha);
                        RenderOverlayTexture(Right.BackgroundTexture, px + w - u, py, px + w, py + v);
                    }
                }
                // middle background
                if (Middle.BackgroundTexture != null)
                {
                    if (Textures.LoadTexture(Middle.BackgroundTexture, OpenGlTextureWrapMode.ClampClamp))
                    {
                        double v = (double)Middle.BackgroundTexture.Height;
                        GL.Color4(br, bg, bb, ba * alpha);
                        RenderOverlayTexture(Middle.BackgroundTexture, px + lw, py, px + w - rw, py + v);
                    }
                }
                {                 // text
                    string t = Game.ScoreMessages[j].Text;
                    double u = widths[j];
                    double v = heights[j];
                    double p = Math.Round((Element.TextAlignment.X < 0 ? px : Element.TextAlignment.X > 0 ? px + w - u : px + 0.5 * (w - u)) - j * Element.Value1);
                    double q = Math.Round(Element.TextAlignment.Y < 0 ? py : Element.TextAlignment.Y > 0 ? py + lcrh - v : py + 0.5 * (lcrh - v));
                    p += Element.TextPosition.X;
                    q += Element.TextPosition.Y;
                    DrawString(Element.Font, t, new System.Drawing.Point((int)p, (int)q), TextAlignment.TopLeft, new Color128(tr, tg, tb, ta * alpha), Element.TextShadow);
                }
                // left overlay
                if (Left.OverlayTexture != null)
                {
                    if (Textures.LoadTexture(Left.OverlayTexture, OpenGlTextureWrapMode.ClampClamp))
                    {
                        double u = (double)Left.OverlayTexture.Width;
                        double v = (double)Left.OverlayTexture.Height;
                        GL.Color4(or, og, ob, oa * alpha);
                        RenderOverlayTexture(Left.OverlayTexture, px, py, px + u, py + v);
                    }
                }
                // right overlay
                if (Right.OverlayTexture != null)
                {
                    if (Textures.LoadTexture(Right.OverlayTexture, OpenGlTextureWrapMode.ClampClamp))
                    {
                        double u = (double)Right.OverlayTexture.Width;
                        double v = (double)Right.OverlayTexture.Height;
                        GL.Color4(or, og, ob, oa * alpha);
                        RenderOverlayTexture(Right.OverlayTexture, px + w - u, py, px + w, py + v);
                    }
                }
                // middle overlay
                if (Middle.OverlayTexture != null)
                {
                    if (Textures.LoadTexture(Middle.OverlayTexture, OpenGlTextureWrapMode.ClampClamp))
                    {
                        double v = (double)Middle.OverlayTexture.Height;
                        GL.Color4(or, og, ob, oa * alpha);
                        RenderOverlayTexture(Middle.OverlayTexture, px + lw, py, px + w - rw, py + v);
                    }
                }
            }
        }