示例#1
0
        private void RenderEvents()
        {
            if (Program.CurrentRoute.Tracks[0].Elements == null)
            {
                return;
            }

            GL.Enable(EnableCap.CullFace);
            GL.Enable(EnableCap.DepthTest);
            GL.DepthMask(true);
            OptionLighting = false;

            double da = -Camera.BackwardViewingDistance - Camera.ExtraViewingDistance;
            double db = Camera.ForwardViewingDistance + Camera.ExtraViewingDistance;

            bool[] sta = new bool[Program.CurrentRoute.Stations.Length];

            // events
            for (int i = 0; i < Program.CurrentRoute.Tracks[0].Elements.Length; i++)
            {
                double p = Program.CurrentRoute.Tracks[0].Elements[i].StartingTrackPosition;
                double d = p - CameraTrackFollower.TrackPosition;

                if (d >= da & d <= db)
                {
                    foreach (GeneralEvent e in Program.CurrentRoute.Tracks[0].Elements[i].Events)
                    {
                        double  dy, dx = 0.0, dz = 0.0;
                        double  s;
                        Texture t;

                        if (e is BrightnessChangeEvent)
                        {
                            s  = 0.15;
                            dy = 4.0;
                            t  = BrightnessChangeTexture;
                        }
                        else if (e is BackgroundChangeEvent)
                        {
                            s  = 0.25;
                            dy = 3.5;
                            t  = BackgroundChangeTexture;
                        }
                        else if (e is StationStartEvent)
                        {
                            s  = 0.25;
                            dy = 1.6;
                            t  = StationStartTexture;
                            StationStartEvent f = (StationStartEvent)e;
                            sta[f.StationIndex] = true;
                        }
                        else if (e is StationEndEvent)
                        {
                            s  = 0.25;
                            dy = 1.6;
                            t  = StationEndTexture;
                            StationEndEvent f = (StationEndEvent)e;
                            sta[f.StationIndex] = true;
                        }
                        else if (e is LimitChangeEvent)
                        {
                            s  = 0.2;
                            dy = 1.1;
                            t  = LimitTexture;
                        }
                        else if (e is SectionChangeEvent)
                        {
                            s  = 0.2;
                            dy = 0.8;
                            t  = SectionTexture;
                        }
                        else if (e is TransponderEvent)
                        {
                            s  = 0.15;
                            dy = 0.4;
                            t  = TransponderTexture;
                        }
                        else if (e is SoundEvent)
                        {
                            SoundEvent f = (SoundEvent)e;
                            s  = 0.2;
                            dx = f.Position.X;
                            dy = f.Position.Y < 0.1 ? 0.1 : f.Position.Y;
                            dz = f.Position.Z;
                            t  = f.SoundBuffer == null ? PointSoundTexture : SoundTexture;
                        }
                        else if (e is RailSoundsChangeEvent)
                        {
                            s  = 0.2;
                            dy = 0.8;
                            t  = RunSoundTexture;
                        }
                        else
                        {
                            s  = 0.2;
                            dy = 1.0;
                            t  = null;
                        }

                        if (t != null)
                        {
                            TrackFollower f = new TrackFollower(Program.CurrentHost)
                            {
                                TriggerType   = EventTriggerType.None,
                                TrackPosition = p
                            };
                            f.UpdateAbsolute(p + e.TrackPositionDelta, true, false);
                            f.WorldPosition.X += dx * f.WorldSide.X + dy * f.WorldUp.X + dz * f.WorldDirection.X;
                            f.WorldPosition.Y += dx * f.WorldSide.Y + dy * f.WorldUp.Y + dz * f.WorldDirection.Y;
                            f.WorldPosition.Z += dx * f.WorldSide.Z + dy * f.WorldUp.Z + dz * f.WorldDirection.Z;

                            Cube.Draw(f.WorldPosition, f.WorldDirection, f.WorldUp, f.WorldSide, s, Camera.AbsolutePosition, t);
                        }
                    }
                }
            }

            // stops
            for (int i = 0; i < sta.Length; i++)
            {
                if (sta[i])
                {
                    for (int j = 0; j < Program.CurrentRoute.Stations[i].Stops.Length; j++)
                    {
                        const double  dy = 1.4;
                        const double  s  = 0.2;
                        double        p  = Program.CurrentRoute.Stations[i].Stops[j].TrackPosition;
                        TrackFollower f  = new TrackFollower(Program.CurrentHost)
                        {
                            TriggerType   = EventTriggerType.None,
                            TrackPosition = p
                        };
                        f.UpdateAbsolute(p, true, false);
                        f.WorldPosition.X += dy * f.WorldUp.X;
                        f.WorldPosition.Y += dy * f.WorldUp.Y;
                        f.WorldPosition.Z += dy * f.WorldUp.Z;

                        Cube.Draw(f.WorldPosition, f.WorldDirection, f.WorldUp, f.WorldSide, s, Camera.AbsolutePosition, StopTexture);
                    }
                }
            }

            // buffers
            foreach (double p in Program.CurrentRoute.BufferTrackPositions)
            {
                double d = p - CameraTrackFollower.TrackPosition;

                if (d >= da & d <= db)
                {
                    const double  dy = 2.5;
                    const double  s  = 0.25;
                    TrackFollower f  = new TrackFollower(Program.CurrentHost)
                    {
                        TriggerType   = EventTriggerType.None,
                        TrackPosition = p
                    };
                    f.UpdateAbsolute(p, true, false);
                    f.WorldPosition.X += dy * f.WorldUp.X;
                    f.WorldPosition.Y += dy * f.WorldUp.Y;
                    f.WorldPosition.Z += dy * f.WorldUp.Z;

                    Cube.Draw(f.WorldPosition, f.WorldDirection, f.WorldUp, f.WorldSide, s, Camera.AbsolutePosition, BufferTexture);
                }
            }

            OptionLighting = true;
        }
示例#2
0
        //
        // CREATE ROUTE MAP
        //
        /// <summary>Creates and returns the route map as Bitmap.</summary>
        /// <returns>The route map.</returns>
        /// <param name="Width">The width of the bitmap to create.</param>
        /// <param name="Height">The height of the bitmap to create.</param>
        /// <param name="inGame"><c>true</c> = bitmap for in-game overlay | <c>false</c> = for standard window.</param>
        internal static Bitmap CreateRouteMap(int Width, int Height, bool inGame)
        {
            int n, n0, n1;

            RouteRange(out n, out n0, out n1);
            // find dimensions
            double x0 = double.PositiveInfinity, z0 = double.PositiveInfinity;
            double x1 = double.NegativeInfinity, z1 = double.NegativeInfinity;

            for (int i = n0; i <= n1; i++)
            {
                double x = Program.CurrentRoute.Tracks[0].Elements[i].WorldPosition.X;
                double z = Program.CurrentRoute.Tracks[0].Elements[i].WorldPosition.Z;
                if (x < x0)
                {
                    x0 = x;
                }
                if (x > x1)
                {
                    x1 = x;
                }
                if (z < z0)
                {
                    z0 = z;
                }
                if (z > z1)
                {
                    z1 = z;
                }
            }
            // avoid 0 or negative height or width
            if (x0 >= x1 - 1.0)
            {
                x0 = x1 - 1.0;
            }
            if (z0 >= z1 - 1.0)
            {
                z0 = z1 - 1.0;
            }
            // remember area occupied so far
            double xMin, xMax, zMin, zMax;                              // used to track the bitmap area actually occupied by drawings

            xMin = x0;
            xMax = x1;
            zMin = z1;                                                                          // bitmap z goes down, while world z goes up
            zMax = z0;
            // fit route w/h ratio in image w/h ratio
            double wrh = (double)Width / (double)Height;

            if ((x1 - x0) / (z1 - z0) <= wrh)                           // if route ratio is taller than bitmap ratio
            {
                double dx = 0.5 * (z1 - z0) * wrh;                      //	scale (half of) x range as much as (half of) z range
                double px = 0.5 * (x0 + x1);                            //	x range mid point
                x0 = px - dx;                                           //	centre scaled x range around mid point
                x1 = px + dx;
            }
            else                                                                                // if route ratio is wider than bitmap ratio
            {                                                                                   //	do the opposite (scale z range on x)
                double dz = 0.5 * (x1 - x0) / wrh;
                double pz = 0.5 * (z0 + z1);
                z0 = pz - dz;
                z1 = pz + dz;
            }
            double ox = LeftPad, oy = TopPad;
            double w = (double)(Width - (LeftPad + RightPad));
            double h = (double)(Height - (TopPad + BottomPad));
            // horizontal and vertical scales
            double xd = w / (x1 - x0);
            double zd = h / (z1 - z0);

            // convert bitmap occupied area from world to bitmap coordinates
            xMin = ox + (xMin - x0) * xd;
            xMax = ox + (xMax - x0) * xd;
            zMin = oy + (z0 - zMin) * zd + h;
            zMax = oy + (z0 - zMax) * zd + h;
            // create bitmap
            int    mode = inGame ? 1 : 0;
            Bitmap b    = new Bitmap(Width, Height, inGame ? System.Drawing.Imaging.PixelFormat.Format32bppArgb
                                : System.Drawing.Imaging.PixelFormat.Format24bppRgb);

            System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(b);
            g.SmoothingMode     = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
            g.Clear(mapColors[mode].background);

            // ROUTE PATH
            {
                int  start = 0;
                bool atc   = false;
                n = n1 - n0 + 1;
                PointF[] p = new PointF[n];
                for (int i = 0; i < n; i++)
                {
                    double x = Program.CurrentRoute.Tracks[0].Elements[i + n0].WorldPosition.X;
                    double z = Program.CurrentRoute.Tracks[0].Elements[i + n0].WorldPosition.Z;
                    x    = ox + (x - x0) * xd;
                    z    = oy + (z0 - z) * zd + h;
                    p[i] = new PointF((float)x, (float)z);
                    // ATS / ATC
                    // for each track element, look for a StationStartEvent
                    for (int j = 0; j < Program.CurrentRoute.Tracks[0].Elements[i + n0].Events.Length; j++)
                    {
                        if (Program.CurrentRoute.Tracks[0].Elements[i + n0].Events[j] is StationStartEvent)
                        {
                            StationStartEvent e =
                                (StationStartEvent)Program.CurrentRoute.Tracks[0].Elements[i + n0].Events[j];
                            // if StationStartEvent found, look for a change in ATS/ATC control;
                            // if there is a change, draw all previous track elements
                            // with colour for the previous control state
                            if (Program.CurrentRoute.Stations[e.StationIndex].SafetySystem == SafetySystem.Atc)
                            {
                                if (!atc)
                                {
                                    atc = true;
                                    if (i - start - 1 > 0)
                                    {
                                        g.DrawCurve(mapColors[mode].normalMap, p, start, i - start - 1);
                                    }
                                    start = i;
                                }
                            }
                            else
                            {
                                if (atc)
                                {
                                    atc = false;
                                    if (i - start - 1 > 0)
                                    {
                                        g.DrawCurve(mapColors[mode].atcMap, p, start, i - start - 1);
                                    }
                                    start = i;
                                }
                            }
                            break;
                        }
                    }
                }
                // draw all remaining track element not drawn yet
                DrawSegmentedCurve(g, atc ? mapColors[mode].atcMap : mapColors[mode].normalMap, p, start, n - start - 1);
            }

            // STATION ICONS
            for (int i = n0; i <= n1; i++)
            {
                for (int j = 0; j < Program.CurrentRoute.Tracks[0].Elements[i].Events.Length; j++)
                {
                    if (Program.CurrentRoute.Tracks[0].Elements[i].Events[j] is StationStartEvent)
                    {
                        StationStartEvent e = (StationStartEvent)Program.CurrentRoute.Tracks[0].Elements[i].Events[j];
                        if (Program.CurrentRoute.Stations[e.StationIndex].Name != string.Empty)
                        {
                            double x = Program.CurrentRoute.Tracks[0].Elements[i].WorldPosition.X;
                            double y = Program.CurrentRoute.Tracks[0].Elements[i].WorldPosition.Z;
                            x = ox + (x - x0) * xd;
                            y = oy + (z0 - y) * zd + h;
                            // station circle
                            RectangleF r = new RectangleF((float)x - StationRadius, (float)y - StationRadius,
                                                          StationDiameter, StationDiameter);
                            bool q = Program.CurrentRoute.Stations[e.StationIndex].PlayerStops();
                            g.FillEllipse(q ? mapColors[mode].actStatnFill : mapColors[mode].inactStatnFill, r);
                            g.DrawEllipse(q ? mapColors[mode].actStatnBrdr : mapColors[mode].inactStatnBrdr, r);
                            // adjust bitmap occupied area
                            if (r.Left < xMin)
                            {
                                xMin = r.Left;
                            }
                            if (r.Top < zMin)
                            {
                                zMin = r.Top;
                            }
                            if (r.Right > xMax)
                            {
                                xMax = r.Right;
                            }
                            if (r.Bottom > zMax)
                            {
                                zMax = r.Bottom;
                            }
                        }
                    }
                }
            }

            // STATION NAMES
            {
                double wh = w * h;
                Font   f  = new Font(FontFamily.GenericSansSerif, wh < 65536.0 ? 9.0f : 10.0f, GraphicsUnit.Pixel);
                for (int i = n0; i <= n1; i++)
                {
                    for (int j = 0; j < Program.CurrentRoute.Tracks[0].Elements[i].Events.Length; j++)
                    {
                        if (Program.CurrentRoute.Tracks[0].Elements[i].Events[j] is StationStartEvent)
                        {
                            StationStartEvent e = (StationStartEvent)Program.CurrentRoute.Tracks[0].Elements[i].Events[j];
                            if (Program.CurrentRoute.Stations[e.StationIndex].Name != string.Empty)
                            {
                                double x = Program.CurrentRoute.Tracks[0].Elements[i].WorldPosition.X;
                                double y = Program.CurrentRoute.Tracks[0].Elements[i].WorldPosition.Z;
                                x = ox + (x - x0) * xd;
                                y = oy + (z0 - y) * zd + h;
                                bool   stop = Program.CurrentRoute.Stations[e.StationIndex].PlayerStops();
                                string t = Program.CurrentRoute.Stations[e.StationIndex].Name;
                                SizeF  m = g.MeasureString(t, f, Width, StringFormat.GenericDefault);
                                double sx = Program.CurrentRoute.Tracks[0].Elements[i].WorldSide.X;
                                double sz = Program.CurrentRoute.Tracks[0].Elements[i].WorldSide.Z;
                                double xt, yt;
                                if (Math.Sign(sx) == Math.Sign(sz))
                                {
                                    // descending
                                    bool o = (x - ox) * (h - y) <= (w - x) * (y - oy);
                                    if (o)
                                    {
                                        // up-right
                                        xt = x + StationTextPad;
                                        yt = y - StationTextPad - m.Height;
                                    }
                                    else
                                    {
                                        // down-left
                                        xt = x - StationTextPad - m.Width;
                                        yt = y + StationTextPad;
                                    }
                                }
                                else
                                {
                                    // ascending
                                    bool o = (h - y) * (w - x) <= (x - ox) * (y - oy);
                                    if (o)
                                    {
                                        // up-left
                                        xt = x - StationTextPad - m.Width;
                                        yt = y - StationTextPad - m.Height;
                                    }
                                    else
                                    {
                                        // down-right
                                        xt = x + StationTextPad;
                                        yt = y + StationTextPad;
                                    }
                                }
                                // constrain text within bitmap edges (taking into account also paddings)
                                if (xt < ox)
                                {
                                    xt = ox;
                                }
                                else if (xt + m.Width > w)
                                {
                                    xt = w - m.Width;
                                }
                                if (yt < oy)
                                {
                                    yt = oy;
                                }
                                else if (yt + m.Height > h)
                                {
                                    yt = h - m.Height;
                                }
                                RectangleF r = new RectangleF((float)xt - 1.0f, (float)yt - 1.0f, m.Width + 2.0f, m.Height + 2.0f);
                                g.FillRectangle(stop ? mapColors[mode].actNameFill : mapColors[mode].inactNameFill,
                                                r.Left, r.Top, r.Width, r.Height);
                                g.DrawRectangle(stop ? mapColors[mode].actNameBrdr : mapColors[mode].inactNameBrdr,
                                                r.Left, r.Top, r.Width, r.Height);
                                g.DrawString(t, f, stop ? mapColors[mode].actNameText : mapColors[mode].inactNameText,
                                             (float)xt, (float)yt);
                                // adjust bitmap occupied area
                                if (r.Left < xMin)
                                {
                                    xMin = r.Left;
                                }
                                if (r.Top < zMin)
                                {
                                    zMin = r.Top;
                                }
                                if (r.Right > xMax)
                                {
                                    xMax = r.Right;
                                }
                                if (r.Bottom > zMax)
                                {
                                    zMax = r.Bottom;
                                }
                            }
                        }
                    }
                }
            }
            // if in-game, trim unused parts of the bitmap
            if (inGame)
            {
                xMin -= LeftPad;
                xMax += RightPad;
                zMin -= TopPad;
                zMax += BottomPad;
                if (xMin < 0)
                {
                    xMin = 0;
                }
                if (xMax >= Width)
                {
                    xMax = Width - 1;
                }
                if (zMin < 0)
                {
                    zMin = 0;
                }
                if (zMax >= Height)
                {
                    zMax = Height - 1;
                }
                Bitmap nb = new Bitmap((int)(xMax - xMin + 1.0), (int)(zMax - zMin + 1.0));                     // round up
                g = System.Drawing.Graphics.FromImage(nb);
                g.DrawImage(b, (int)-xMin, (int)-zMin);                                                         // round down
                // set total bitmap world X and Z ranges from bitmap ranges
                lastRouteMinX = (int)((xMin - ox) / xd + x0);
                lastRouteMaxX = (int)((xMax - ox) / xd + x0);
                lastRouteMinZ = (int)(z0 - (zMax - oy - h) / zd);
                lastRouteMaxZ = (int)(z0 - (zMin - oy - h) / zd);
                return(nb);
            }
            //set total bitmap X and Z ranges
            lastRouteMinX = (int)(x0 - ox * (x1 - x0) / w);
            lastRouteMaxX = (int)(x1 + (Width - w - ox) * (x1 - x0) / w);
            lastRouteMinZ = (int)(z0 - oy * (z1 - z0) / h);
            lastRouteMaxZ = (int)(z1 + (Height - h - oy) * (z1 - z0) / h);
            return(b);
        }
示例#3
0
        //
        // CREATE GRADIENT PROFILE
        //
        /// <summary>Creates the route gradient profile.</summary>
        /// <returns>The route gradient profile as Bitmap.</returns>
        /// <param name="Width">The width of the bitmap to create.</param>
        /// <param name="Height">The height of the bitmap to create.</param>
        /// <param name="inGame"><c>true</c> = bitmap for in-game overlay | <c>false</c> = for standard window.</param>
        internal static Bitmap CreateRouteGradientProfile(int Width, int Height, bool inGame)
        {
            if (Program.CurrentRoute.Tracks[0].Elements.Length > 36 && Program.CurrentRoute.Stations.Length == 0)
            {
                // If we have track elements, but no stations, show a specific error message, rather
                // than the more generic one thrown later
                // NOTE: Will throw the generic error message on routes shorter than 900m with no stations
                throw new InvalidDataException(Translations.GetInterfaceString("errors_route_corrupt_nostations"));
            }
            // Track elements are assumed to be all of the same length, and this length
            // is used as measure unit, rather than computing the incremental track length
            // in any 'real world' unit (like m).

            // HORIZONTAL RANGE: find first and last used element based on stations
            int n, n0, n1;

            RouteRange(out n, out n0, out n1);
            // VERTICAL RANGE
            double y0 = double.PositiveInfinity, y1 = double.NegativeInfinity;

            for (int i = n0; i <= n1; i++)
            {
                double y = Program.CurrentRoute.Tracks[0].Elements[i].WorldPosition.Y;
                if (y < y0)
                {
                    y0 = y;
                }
                if (y > y1)
                {
                    y1 = y;
                }
            }
            if (y0 >= y1 - 1.0)
            {
                y0 = y1 - 1.0;
            }

            // allow for some padding around actual data
            double ox = LeftPad, oy = TopPad;
            double w = (double)(Width - (LeftPad + RightPad));
            double h = (double)(Height - (TopPad + BottomPad + TrackOffsPad));
            // horizontal and vertical scale
            double nd = w / (double)(n1 - n0);
            double yd = h / (double)(y1 - y0);
            // set total bitmap track position range; used by in-game profile to place
            // the current position of the trains; as the train positions are known as track positions,
            // actual track positions are needed here, rather than indices into the track element array.
            double minX = Program.CurrentRoute.Tracks[0].Elements[n0].StartingTrackPosition;
            double maxX = Program.CurrentRoute.Tracks[0].Elements[n1].StartingTrackPosition;
            double offX = ox * (maxX - minX) / w;

            lastGradientMinTrack = (int)(minX - offX);
            lastGradientMaxTrack = (int)(maxX + offX);

            // BITMAP (in-game display needs transparency)
            Bitmap b = new Bitmap(Width, Height,
                                  inGame ? System.Drawing.Imaging.PixelFormat.Format32bppArgb
                                        : System.Drawing.Imaging.PixelFormat.Format24bppRgb);

            System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(b);
            g.SmoothingMode     = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
            int mode = inGame ? 1 : 0;

            g.Clear(mapColors[mode].background);

            // BELOW SEA LEVEL
            {
                double y  = oy + (h - 0.5 * (double)(-Program.CurrentRoute.Atmosphere.InitialElevation - y0) * yd);
                double x0 = ox - (double)(0) * nd;
                double x1 = ox + (double)(n1 - n0) * nd;
                g.FillRectangle(mapColors[mode].belowSeaFill, (float)x0, (float)y, (float)x1, (float)(oy + h) - (float)y);
                g.DrawLine(mapColors[mode].belowSeaBrdr, (float)x0, (float)y, (float)x1, (float)y);
            }
            // GRADIENT PROFILE
            {
                n = n1 - n0 + 1;
                PointF[] p = new PointF[n + 2];
                p[0] = new PointF((float)ox, (float)(oy + h));
                for (int i = n0; i <= n1; i++)
                {
                    double x = ox + (double)(i - n0) * nd;
                    double y = oy + (h - 0.5 *
                                     (double)(Program.CurrentRoute.Tracks[0].Elements[i].WorldPosition.Y - y0) * yd);
                    p[i - n0 + 1] = new PointF((float)x, (float)y);
                }
                p[n + 1] = new PointF((float)(ox + (double)(n - 1) * nd), (float)(oy + h));
                g.FillPolygon(mapColors[mode].elevFill, p);
                for (int i = 1; i < n; i++)
                {
                    g.DrawLine(mapColors[mode].elevBrdr, p[i], p[i + 1]);
                }
                g.DrawLine(mapColors[mode].elevBrdr, 0.0f, (float)(oy + h), (float)Width, (float)(oy + h));
            }
            // STATION NAMES
            {
                Font         f = new Font(FontFamily.GenericSansSerif, 12.0f, GraphicsUnit.Pixel);
                StringFormat m = new StringFormat();
                for (int i = n0; i <= n1; i++)
                {
                    for (int j = 0; j < Program.CurrentRoute.Tracks[0].Elements[i].Events.Length; j++)
                    {
                        if (Program.CurrentRoute.Tracks[0].Elements[i].Events[j] is StationStartEvent)
                        {
                            StationStartEvent e = (StationStartEvent)Program.CurrentRoute.Tracks[0].Elements[i].Events[j];
                            if (Program.CurrentRoute.Stations[e.StationIndex].Name != string.Empty)
                            {
                                bool stop = Program.CurrentRoute.Stations[e.StationIndex].PlayerStops();
                                if (Program.CurrentRoute.Stations[e.StationIndex].Name.IsJapanese())
                                {
                                    m.Alignment     = StringAlignment.Near;
                                    m.LineAlignment = StringAlignment.Near;
                                    double x = ox + (double)(i - n0) * nd;
                                    double y = oy + (h - 0.5 *
                                                     (double)(Program.CurrentRoute.Tracks[0].Elements[i].WorldPosition.Y - y0) * yd);
                                    string t = Program.CurrentRoute.Stations[e.StationIndex].Name;
                                    float  tx = 0.0f, ty = (float)oy;
                                    for (int k = 0; k < t.Length; k++)
                                    {
                                        SizeF s = g.MeasureString(t.Substring(k, 1), f, 65536, StringFormat.GenericTypographic);
                                        if (s.Width > tx)
                                        {
                                            tx = s.Width;
                                        }
                                    }
                                    for (int k = 0; k < t.Length; k++)
                                    {
                                        g.DrawString(t.Substring(k, 1), f,
                                                     stop ? mapColors[mode].actNameText : mapColors[mode].inactNameText,
                                                     (float)x - 0.5f * tx, ty);
                                        SizeF s = g.MeasureString(t.Substring(k, 1), f, 65536, StringFormat.GenericTypographic);
                                        ty += s.Height;
                                    }
                                    g.DrawLine(stop ? mapColors[mode].actNameBrdr : mapColors[mode].inactNameBrdr,
                                               new PointF((float)x, ty + 4.0f), new PointF((float)x, (float)y));
                                }
                                else
                                {
                                    m.Alignment     = StringAlignment.Far;
                                    m.LineAlignment = StringAlignment.Near;
                                    double x = ox + (double)(i - n0) * nd;
                                    double y = oy + (h - 0.5 *
                                                     (double)(Program.CurrentRoute.Tracks[0].Elements[i].WorldPosition.Y - y0) * yd);
                                    g.RotateTransform(-90.0f);
                                    g.TranslateTransform((float)x, (float)oy, System.Drawing.Drawing2D.MatrixOrder.Append);
                                    g.DrawString(Program.CurrentRoute.Stations[e.StationIndex].Name, f,
                                                 stop ? mapColors[mode].actNameText : mapColors[mode].inactNameText,
                                                 new PointF(0.0f, -5.0f), m);
                                    g.ResetTransform();
                                    SizeF s = g.MeasureString(Program.CurrentRoute.Stations[e.StationIndex].Name, f);
                                    g.DrawLine(stop ? mapColors[mode].actNameBrdr : mapColors[mode].inactNameBrdr,
                                               new PointF((float)x, (float)(oy + s.Width + 4)), new PointF((float)x, (float)y));
                                }
                            }
                        }
                    }
                }
            }
            // ROUTE MARKERS
            {
                Font         f  = new Font(FontFamily.GenericSansSerif, 10.0f, GraphicsUnit.Pixel);
                Font         fs = new Font(FontFamily.GenericSansSerif, 9.0f, GraphicsUnit.Pixel);
                StringFormat m  = new StringFormat
                {
                    Alignment     = StringAlignment.Far,
                    LineAlignment = StringAlignment.Center
                };
                System.Globalization.CultureInfo Culture = System.Globalization.CultureInfo.InvariantCulture;
                int k = TrackOffDist * n / Width;
                if (k == 0)
                {
                    if (!inGame)
                    {
                        //If k is equal to zero, this generally means that the WithTrack section is missing from our routefile
                        //Adding zero to the loop control variable will also produce an infinite loop, so that's a bad idea too
                        throw new InvalidDataException(Translations.GetInterfaceString("errors_route_corrupt_withtrack"));
                    }

                    /*
                     * A route with a single station can somehow sometimes work OK in preview but not in-game
                     * Whilst the routefile is probably broken don't chuck the exception here as it takes down the loader
                     */
                    k = 1;
                }

                for (int i = n0; i <= n1; i += k)
                {
                    double x = ox + (double)(i - n0) * nd;
                    double y = (double)(Program.CurrentRoute.Tracks[0].Elements[i].WorldPosition.Y - y0) * yd;
                    // track offset label
                    if (x < w)
                    {
                        string t = ((int)Math.Round(Program.CurrentRoute.Tracks[0].Elements[i].StartingTrackPosition)).ToString(Culture);
                        g.DrawString(t + "m", f, mapColors[mode].actNameText, (float)x, (float)(oy + h + TrackOffY));
                    }
                    // route height at track offset (with measure and vertical line)
                    {
                        y = oy + (h - 0.5 * y) + 2.0f;
                        string t = ((int)Math.Round(Program.CurrentRoute.Atmosphere.InitialElevation + Program.CurrentRoute.Tracks[0].Elements[i].WorldPosition.Y)).ToString(Culture);
                        SizeF  s = g.MeasureString(t, fs);
                        if (y < oy + h - (double)s.Width - 10.0)
                        {
                            g.RotateTransform(-90.0f);
                            g.TranslateTransform((float)x, (float)y + 4.0f, System.Drawing.Drawing2D.MatrixOrder.Append);
                            g.DrawString(t + "m", fs, mapColors[mode].actNameText, 0.0f, 0.0f, m);
                            g.ResetTransform();
                            g.DrawLine(mapColors[mode].inactNameBrdr,
                                       (float)x, (float)(y + s.Width + 12.0), (float)x, (float)(oy + h));
                        }
                    }
                }
            }
            // finalize
            return(b);
        }
示例#4
0
            /// <summary>Collects the timetable data for the current route</summary>
            internal void CollectData()
            {
                System.Globalization.CultureInfo Culture = System.Globalization.CultureInfo.InvariantCulture;
                Stations = new Station[16];
                Tracks   = new Track[16];
                int    n = 0;
                double Limit = -1.0, LastLimit = 6.94444444444444;
                int    LastArrivalHours = -1, LastDepartureHours = -1;
                double LastTime = -1.0;

                for (int i = 0; i < Program.CurrentRoute.Tracks[0].Elements.Length; i++)
                {
                    for (int j = 0; j < Program.CurrentRoute.Tracks[0].Elements[i].Events.Length; j++)
                    {
                        StationStartEvent sse = Program.CurrentRoute.Tracks[0].Elements[i].Events[j] as StationStartEvent;
                        if (sse != null && Program.CurrentRoute.Stations[sse.StationIndex].Name != string.Empty)
                        {
                            if (Limit == -1.0)
                            {
                                Limit = LastLimit;
                            }
                            // update station
                            if (n == Stations.Length)
                            {
                                Array.Resize <Station>(ref Stations, Stations.Length << 1);
                            }

                            Stations[n].Name         = Program.CurrentRoute.Stations[sse.StationIndex].Name;
                            Stations[n].NameJapanese = Program.CurrentRoute.Stations[sse.StationIndex].Name.IsJapanese();
                            Stations[n].Pass         = !Program.CurrentRoute.Stations[sse.StationIndex].PlayerStops();
                            Stations[n].Terminal     = Program.CurrentRoute.Stations[sse.StationIndex].Type != StationType.Normal;
                            double x;
                            if (Program.CurrentRoute.Stations[sse.StationIndex].ArrivalTime >= 0.0)
                            {
                                x  = Program.CurrentRoute.Stations[sse.StationIndex].ArrivalTime;
                                x -= 86400.0 * Math.Floor(x / 86400.0);
                                int hours = (int)Math.Floor(x / 3600.0);
                                x -= 3600.0 * (double)hours;
                                int minutes = (int)Math.Floor(x / 60.0);
                                x -= 60.0 * (double)minutes;
                                int seconds = (int)Math.Floor(x);
                                Stations[n].Arrival.Hour = hours != LastArrivalHours?hours.ToString("00", Culture) : "";

                                Stations[n].Arrival.Minute = minutes.ToString("00", Culture);
                                Stations[n].Arrival.Second = seconds.ToString("00", Culture);
                                LastArrivalHours           = hours;
                            }
                            else
                            {
                                Stations[n].Arrival.Hour   = "";
                                Stations[n].Arrival.Minute = "";
                                Stations[n].Arrival.Second = "";
                            }

                            if (Program.CurrentRoute.Stations[sse.StationIndex].DepartureTime >= 0.0)
                            {
                                x  = Program.CurrentRoute.Stations[sse.StationIndex].DepartureTime;
                                x -= 86400.0 * Math.Floor(x / 86400.0);
                                int hours = (int)Math.Floor(x / 3600.0);
                                x -= 3600.0 * (double)hours;
                                int minutes = (int)Math.Floor(x / 60.0);
                                x -= 60.0 * (double)minutes;
                                int seconds = (int)Math.Floor(x);
                                Stations[n].Departure.Hour = hours != LastDepartureHours?hours.ToString("00", Culture) : "";

                                Stations[n].Departure.Minute = minutes.ToString("00", Culture);
                                Stations[n].Departure.Second = seconds.ToString("00", Culture);
                                LastDepartureHours           = hours;
                            }
                            else
                            {
                                Stations[n].Departure.Hour   = "";
                                Stations[n].Departure.Minute = "";
                                Stations[n].Departure.Second = "";
                            }

                            // update track
                            if (n >= 1)
                            {
                                int m = n - 1;
                                if (m == Tracks.Length)
                                {
                                    Array.Resize <Track>(ref Tracks, Tracks.Length << 1);
                                }

                                // speed
                                x = Math.Round(3.6 * Limit);
                                Tracks[m].Speed = x.ToString(Culture);
                                // time
                                if (LastTime >= 0.0)
                                {
                                    if (Program.CurrentRoute.Stations[sse.StationIndex].ArrivalTime >= 0.0)
                                    {
                                        x = Program.CurrentRoute.Stations[sse.StationIndex].ArrivalTime;
                                    }
                                    else if (Program.CurrentRoute.Stations[sse.StationIndex].DepartureTime >= 0.0)
                                    {
                                        x = Program.CurrentRoute.Stations[sse.StationIndex].DepartureTime;
                                    }
                                    else
                                    {
                                        x = -1.0;
                                    }

                                    if (x >= 0.0)
                                    {
                                        x -= LastTime;
                                        int hours = (int)Math.Floor(x / 3600.0);
                                        x -= 3600.0 * (double)hours;
                                        int minutes = (int)Math.Floor(x / 60.0);
                                        x -= 60.0 * (double)minutes;
                                        int seconds = (int)Math.Floor(x);
                                        Tracks[m].Time.Hour   = hours != 0 ? hours.ToString("0", Culture) : "";
                                        Tracks[m].Time.Minute = minutes != 0 ? minutes.ToString("00", Culture) : "";
                                        Tracks[m].Time.Second = seconds != 0 ? seconds.ToString("00", Culture) : "";
                                    }
                                    else
                                    {
                                        Tracks[m].Time.Hour   = "";
                                        Tracks[m].Time.Minute = "";
                                        Tracks[m].Time.Second = "";
                                    }
                                }
                                else
                                {
                                    Tracks[m].Time.Hour   = "";
                                    Tracks[m].Time.Minute = "";
                                    Tracks[m].Time.Second = "";
                                }
                            }

                            // update last data
                            if (Program.CurrentRoute.Stations[sse.StationIndex].DepartureTime >= 0.0)
                            {
                                LastTime = Program.CurrentRoute.Stations[sse.StationIndex].DepartureTime;
                            }
                            else if (Program.CurrentRoute.Stations[sse.StationIndex].ArrivalTime >= 0.0)
                            {
                                LastTime = Program.CurrentRoute.Stations[sse.StationIndex].ArrivalTime;
                            }
                            else
                            {
                                LastTime = -1.0;
                            }

                            LastLimit = Limit;
                            Limit     = -1.0;
                            n++;
                        }

                        if (n >= 1)
                        {
                            LimitChangeEvent lce = Program.CurrentRoute.Tracks[0].Elements[i].Events[j] as LimitChangeEvent;
                            if (lce != null)
                            {
                                if (lce.NextSpeedLimit != double.PositiveInfinity & lce.NextSpeedLimit > Limit)
                                {
                                    Limit = lce.NextSpeedLimit;
                                }
                            }
                        }
                    }
                }

                Array.Resize <Station>(ref Stations, n);
                if (n >= 2)
                {
                    Array.Resize <Track>(ref Tracks, n - 1);
                }
                else
                {
                    Tracks = new Track[] { };
                }
            }