private static Vector2 GetSubPixelTextSize()
 {
     if (TasSettings.InfoSubpixelIndicator)
     {
         return(JetBrainsMonoFont.Measure("0.".PadRight(TasSettings.SubpixelIndicatorDecimals + 2, '0')) * GetSubPixelFontSize());
     }
     else
     {
         return(default);
 private static Vector2 GetSubPixelTextSize()
 {
     if (TasSettings.InfoSubPixelIndicator)
     {
         return(JetBrainsMonoFont.Measure("0.00") * GetSubPixelFontSize());
     }
     else
     {
         return(default);
        public static void DrawIndicator(float y, float padding, float alpha)
        {
            if (!TasSettings.InfoSubPixelIndicator)
            {
                return;
            }

            float subPixelLeft   = 0.5f;
            float subPixelRight  = 0.5f;
            float subPixelTop    = 0.5f;
            float subPixelBottom = 0.5f;

            Player player = Engine.Scene.Tracker.GetEntity <Player>();

            if (player != null)
            {
                subPixelLeft   = player.PositionRemainder.X + 0.5f;
                subPixelRight  = 1f - subPixelLeft;
                subPixelTop    = player.PositionRemainder.Y + 0.5f;
                subPixelBottom = 1f - subPixelTop;
            }

            Vector2 textSize   = GetSubPixelTextSize();
            float   textWidth  = textSize.X;
            float   textHeight = textSize.Y;
            float   rectSide   = GetSubPixelRectSize();
            float   x          = TasSettings.InfoPosition.X + textWidth + padding * 2;

            y = y - rectSide - padding * 1.5f - textHeight;
            float thickness = PixelScale * TasSettings.InfoSubPixelIndicatorSize / 20f;

            DrawHollowRect(x, y, rectSide, rectSide, Color.Green * alpha, thickness);

            float pointSize = thickness * 1.1f;

            Draw.Rect(x + (rectSide - pointSize) * subPixelLeft, y + (rectSide - pointSize) * subPixelTop, pointSize, pointSize,
                      Color.Red * alpha);

            JetBrainsMonoFont.Draw(subPixelLeft.ToString("F2"), new Vector2(x - textWidth - padding / 2f, y + (rectSide - textHeight) / 2f),
                                   Vector2.Zero, new Vector2(GetSubPixelFontSize()), Color.White * alpha);
            JetBrainsMonoFont.Draw(subPixelRight.ToString("F2"), new Vector2(x + rectSide + padding / 2f, y + (rectSide - textHeight) / 2f),
                                   Vector2.Zero, new Vector2(GetSubPixelFontSize()), Color.White * alpha);
            JetBrainsMonoFont.Draw(subPixelTop.ToString("F2"), new Vector2(x + (rectSide - textWidth) / 2f, y - textHeight - padding / 2f),
                                   Vector2.Zero, new Vector2(GetSubPixelFontSize()), Color.White * alpha);
            JetBrainsMonoFont.Draw(subPixelBottom.ToString("F2"), new Vector2(x + (rectSide - textWidth) / 2f, y + rectSide + padding / 2f),
                                   Vector2.Zero, new Vector2(GetSubPixelFontSize()), Color.White * alpha);
        }
        private static void DrawInfo(Level level)
        {
            if (!TasSettings.Enabled || !TasSettings.InfoHud)
            {
                return;
            }

            StringBuilder stringBuilder = new();

            if (TasSettings.InfoTasInput)
            {
                WriteTasInput(stringBuilder);
            }

            string hudInfo = GameInfo.HudInfo;

            if (hudInfo.IsNotEmpty())
            {
                if (stringBuilder.Length > 0)
                {
                    stringBuilder.AppendLine();
                }

                stringBuilder.Append(hudInfo);
            }

            string text = stringBuilder.ToString().Trim();

            if (string.IsNullOrEmpty(text) && !TasSettings.InfoSubpixelIndicator)
            {
                return;
            }

            int viewWidth  = Engine.ViewWidth;
            int viewHeight = Engine.ViewHeight;

            float pixelScale = Engine.ViewWidth / 320f;
            float margin     = 2 * pixelScale;
            float padding    = 2 * pixelScale;
            float fontSize   = 0.15f * pixelScale * TasSettings.InfoTextSize / 10f;
            float alpha      = TasSettings.InfoOpacity / 10f;
            float infoAlpha  = 1f;

            Size = JetBrainsMonoFont.Measure(text) * fontSize;
            Size = InfoSubPixelIndicator.TryExpandSize(Size, padding);

            float maxX = viewWidth - Size.X - margin - padding * 2;
            float maxY = viewHeight - Size.Y - margin - padding * 2;

            if (maxY > 0f)
            {
                TasSettings.InfoPosition = TasSettings.InfoPosition.Clamp(margin, margin, maxX, maxY);
            }

            float x = TasSettings.InfoPosition.X;
            float y = TasSettings.InfoPosition.Y;

            Rectangle bgRect = new((int)x, (int)y, (int)(Size.X + padding * 2), (int)(Size.Y + padding * 2));

            if (!Hotkeys.InfoHud.Check && (level.Paused || CollidePlayer(level, bgRect)))
            {
                alpha     *= TasSettings.InfoMaskedOpacity / 10f;
                infoAlpha *= alpha;
            }

            Draw.SpriteBatch.Begin();

            Draw.Rect(bgRect, Color.Black * alpha);

            InfoSubPixelIndicator.DrawIndicator(bgRect.Bottom, padding, infoAlpha);

            Vector2 textPosition = new(x + padding, y + padding);
            Vector2 scale        = new(fontSize);

            JetBrainsMonoFont.Draw(text, textPosition, Vector2.Zero, scale, Color.White * infoAlpha);

            Draw.SpriteBatch.End();
        }
 private static void FontsOnPrepare(On.Celeste.Fonts.orig_Prepare orig)
 {
     orig();
     JetBrainsMonoFont.LoadFont();
 }
Esempio n. 6
0
        private static void DrawInfo(Level self)
        {
            if (!TasSettings.Enabled || !TasSettings.InfoHud)
            {
                return;
            }

            StringBuilder stringBuilder = new();

            if (TasSettings.InfoTasInput)
            {
                WriteTasInput(stringBuilder);
            }

            string hudInfo = GameInfo.HudInfo;

            if (hudInfo.IsNotEmpty())
            {
                if (stringBuilder.Length > 0)
                {
                    stringBuilder.AppendLine();
                }

                stringBuilder.Append(hudInfo);
            }

            string text = stringBuilder.ToString().Trim();

            if (string.IsNullOrEmpty(text) && !TasSettings.InfoSubPixelIndicator)
            {
                return;
            }

            int viewWidth  = Engine.ViewWidth;
            int viewHeight = Engine.ViewHeight;

            float pixelScale = Engine.ViewWidth / 320f;
            float margin     = 2 * pixelScale;
            float padding    = 2 * pixelScale;
            float fontSize   = 0.15f * pixelScale * TasSettings.InfoTextSize / 10f;
            float alpha      = TasSettings.InfoOpacity / 10f;
            float infoAlpha  = 1f;

            Vector2 size = JetBrainsMonoFont.Measure(text) * fontSize;

            size = InfoSubPixelIndicator.TryExpandSize(size, padding);

            float maxX = viewWidth - size.X - margin - padding * 2;
            float maxY = viewHeight - size.Y - margin - padding * 2;

            if (maxY > 0f)
            {
                TasSettings.InfoPosition = TasSettings.InfoPosition.Clamp(margin, margin, maxX, maxY);
            }

            float x = TasSettings.InfoPosition.X;
            float y = TasSettings.InfoPosition.Y;

            Rectangle bgRect = new((int)x, (int)y, (int)(size.X + padding * 2), (int)(size.Y + padding * 2));

            if (self.GetPlayer() is { } player)
            {
                Vector2   playerPosition = self.Camera.CameraToScreen(player.TopLeft) * pixelScale;
                Rectangle playerRect     = new((int)playerPosition.X, (int)playerPosition.Y, (int)(8 * pixelScale), (int)(11 * pixelScale));
                Rectangle mirrorBgRect   = bgRect;
                if (SaveData.Instance?.Assists.MirrorMode == true)
                {
                    mirrorBgRect.X = (int)Math.Abs(x - viewWidth + size.X + padding * 2);
                }

                if (self.Paused || playerRect.Intersects(mirrorBgRect))
                {
                    alpha     *= TasSettings.InfoMaskedOpacity / 10f;
                    infoAlpha *= alpha;
                }
            }

            Draw.SpriteBatch.Begin();

            Draw.Rect(bgRect, Color.Black * alpha);

            InfoSubPixelIndicator.DrawIndicator(bgRect.Bottom, padding, infoAlpha);

            Vector2 textPosition = new(x + padding, y + padding);
            Vector2 scale        = new(fontSize);

            JetBrainsMonoFont.Draw(text, textPosition, Vector2.Zero, scale, Color.White * infoAlpha);

            Draw.SpriteBatch.End();
        }
        public static void DrawIndicator(float y, float padding, float alpha)
        {
            if (!TasSettings.InfoSubpixelIndicator)
            {
                return;
            }

            float subPixelLeft   = 0.5f;
            float subPixelRight  = 0.5f;
            float subPixelTop    = 0.5f;
            float subPixelBottom = 0.5f;
            int   decimals       = TasSettings.SubpixelIndicatorDecimals;

            Player player = Engine.Scene.Tracker.GetEntity <Player>();

            if (player != null)
            {
                subPixelLeft   = (float)Math.Round(player.PositionRemainder.X + 0.5f, decimals, MidpointRounding.AwayFromZero);
                subPixelTop    = (float)Math.Round(player.PositionRemainder.Y + 0.5f, decimals, MidpointRounding.AwayFromZero);
                subPixelRight  = 1f - subPixelLeft;
                subPixelBottom = 1f - subPixelTop;
            }

            Vector2 textSize   = GetSubPixelTextSize();
            float   textWidth  = textSize.X;
            float   textHeight = textSize.Y;
            float   rectSide   = GetSubPixelRectSize();
            float   x          = TasSettings.InfoPosition.X + textWidth + padding * 2;

            y = y - rectSide - padding * 1.5f - textHeight;
            float thickness = PixelScale * TasSettings.InfoSubpixelIndicatorSize / 20f;

            DrawHollowRect(x, y, rectSide, rectSide, Color.Green * alpha, thickness);

            float pointSize = thickness * 1.2f;

            Draw.Rect(x + (rectSide - pointSize) * subPixelLeft, y + (rectSide - pointSize) * subPixelTop, pointSize, pointSize,
                      Color.Red * alpha);

            Vector2 remainder = player?.PositionRemainder ?? Vector2.One;
            int     hDecimals = Math.Abs(remainder.X) switch {
                0.5f => 0,
                _ => decimals
            };
            int vDecimals = Math.Abs(remainder.Y) switch {
                0.5f => 0,
                _ => decimals
            };

            string left   = subPixelLeft.ToFormattedString(hDecimals).PadLeft(TasSettings.SubpixelIndicatorDecimals + 2, ' ');
            string right  = subPixelRight.ToFormattedString(hDecimals);
            string top    = subPixelTop.ToFormattedString(vDecimals).PadLeft(TasSettings.SubpixelIndicatorDecimals / 2 + 2, ' ');
            string bottom = subPixelBottom.ToFormattedString(vDecimals).PadLeft(TasSettings.SubpixelIndicatorDecimals / 2 + 2, ' ');

            JetBrainsMonoFont.Draw(left, new Vector2(x - textWidth - padding / 2f, y + (rectSide - textHeight) / 2f),
                                   Vector2.Zero, new Vector2(GetSubPixelFontSize()), Color.White * alpha);
            JetBrainsMonoFont.Draw(right, new Vector2(x + rectSide + padding / 2f, y + (rectSide - textHeight) / 2f),
                                   Vector2.Zero, new Vector2(GetSubPixelFontSize()), Color.White * alpha);

            float tweakX = vDecimals == 0 && decimals % 2 == 0 ? padding / 2 : 0;

            JetBrainsMonoFont.Draw(top, new Vector2(x + (rectSide - textWidth) / 2f - tweakX, y - textHeight - padding / 2f),
                                   Vector2.Zero, new Vector2(GetSubPixelFontSize()), Color.White * alpha);
            JetBrainsMonoFont.Draw(bottom, new Vector2(x + (rectSide - textWidth) / 2f - tweakX, y + rectSide + padding / 2f),
                                   Vector2.Zero, new Vector2(GetSubPixelFontSize()), Color.White * alpha);
        }