From c998f088f639f79f80dc14773c879074f25fc92e Mon Sep 17 00:00:00 2001 From: annabunches Date: Thu, 13 Feb 2025 13:38:46 -0500 Subject: [PATCH] Fix sprite-based rendering, add checkmark, add automatic scaling. --- AirMonitor/AirMonitorDisplay.cs | 108 ++++++++++++++++---------------- 1 file changed, 55 insertions(+), 53 deletions(-) diff --git a/AirMonitor/AirMonitorDisplay.cs b/AirMonitor/AirMonitorDisplay.cs index 47e362b..0aa1b49 100644 --- a/AirMonitor/AirMonitorDisplay.cs +++ b/AirMonitor/AirMonitorDisplay.cs @@ -8,29 +8,41 @@ namespace IngameScript { partial class Program { + // TODO: refactor this, possibly into a SpriteFactory mixin + public static MySprite[] BuildCheckMark(Vector2 position, float scale) + { + MySprite[] result = new MySprite[2]; + + result[0] = new MySprite(SpriteType.TEXTURE, "SquareSimple", new Vector2(-6f, 5f) * scale + position, new Vector2(12f, 3f) * scale, Color.Green, null, TextAlignment.CENTER, 1.0472f); // short + result[1] = new MySprite(SpriteType.TEXTURE, "SquareSimple", position, new Vector2(3f, 22f) * scale, Color.Green, null, TextAlignment.CENTER, 0.4189f); // long + + return result; + } + public class AirMonitorDisplay { private class ZoneRow { public AirZone Zone { get; private set; } public MySprite Name { get; private set; } - public MySprite Level; // { get; private set; } public MySprite Triggered { get; private set; } + public MySprite[] Ok; + public MySprite Level; - public ZoneRow(RectangleF viewport, AirZone zone, float yPosition, float scale) + public ZoneRow(RectangleF viewport, AirZone zone, float xPadding, float xIncrement, float yIndex, float yIncrement, float scale) { - float xIncrement = viewport.Size.X / 3; + float textureSize = 25f * scale; Zone = zone; - Name = new MySprite(SpriteType.TEXT, Zone.Name, new Vector2(0, yPosition) + viewport.Position, null, Color.White, "Debug", TextAlignment.LEFT, scale); - Level = new MySprite(SpriteType.TEXT, "----", new Vector2(xIncrement, yPosition) + viewport.Position, null, Color.White, "Debug", TextAlignment.LEFT, scale); - Triggered = new MySprite(SpriteType.TEXTURE, "Danger", new Vector2(xIncrement * 2, yPosition) + viewport.Position, new Vector2(32f, 32f), Color.White, null, TextAlignment.CENTER, 0f); + Name = new MySprite(SpriteType.TEXT, Zone.Name, new Vector2(xPadding, yIndex) + viewport.Position, null, Color.White, "White", TextAlignment.LEFT, scale); + Level = new MySprite(SpriteType.TEXT, "----", new Vector2(xIncrement, yIndex) + viewport.Position, null, Color.White, "White", TextAlignment.LEFT, scale); + Triggered = new MySprite(SpriteType.TEXTURE, "Danger", new Vector2(xIncrement * 2, yIndex + textureSize / 2) + viewport.Position, new Vector2(textureSize, textureSize), Color.White, null, TextAlignment.LEFT, 0f); + Ok = Program.BuildCheckMark(new Vector2(xIncrement * 2 + textureSize / 2, yIndex + (textureSize / 2)) + viewport.Position, scale); } } private IMyTextSurface _surface; - private List _staticSprites = new List(); + private Dictionary _staticSprites = new Dictionary(); private List _rows = new List(); - private float _scale = 1f; public AirMonitorDisplay(IMyTextSurface surface, List zones) { @@ -39,26 +51,42 @@ namespace IngameScript _surface.ScriptBackgroundColor = new Color(0, 0, 0, 255); _surface.ContentType = ContentType.SCRIPT; _surface.Script = ""; - buildSprites(zones); + + RectangleF viewport = new RectangleF( + (_surface.TextureSize - _surface.SurfaceSize) / 2f, + _surface.SurfaceSize + ); + + // The tuning values here are derived experimentally + float scale = viewport.Size.Y / 400; + + float yIndex = 5f; + float yIncrement = 35f; + + float xPadding = 2f; + float xIncrement = viewport.Size.X / 3; + + // build static sprites + _staticSprites["title"] = new MySprite(SpriteType.TEXT, "OXYGEN REPORT", new Vector2(viewport.Size.X / 2, yIndex) + viewport.Position, null, Color.White, "Debug", TextAlignment.CENTER, 1.3f * scale); + yIndex += yIncrement * scale * 1.2f; + _staticSprites["zoneHeading"] = new MySprite(SpriteType.TEXT, "ZONE", new Vector2(xPadding, yIndex) + viewport.Position, null, Color.Blue, "Debug", TextAlignment.LEFT, 1.2f * scale); + _staticSprites["levelHeading"] = new MySprite(SpriteType.TEXT, "O2 LEVEL", new Vector2(xIncrement, yIndex) + viewport.Position, null, Color.Blue, "Debug", TextAlignment.LEFT, 1.2f * scale); + _staticSprites["statusHeading"] = new MySprite(SpriteType.TEXT, "STATUS", new Vector2(xIncrement * 2, yIndex) + viewport.Position, null, Color.Blue, "Debug", TextAlignment.LEFT, 1.2f * scale); + yIndex += yIncrement * scale * 1.1f; + + // build dynamic sprites + foreach (AirZone zone in zones) + { + _rows.Add(new ZoneRow(viewport, zone, xPadding, xIncrement, yIndex, yIncrement, scale)); + yIndex += yIncrement * scale; + } } public void Draw() { - if (_surface.FontSize != _scale) { - _scale = _surface.FontSize; - - // Is it worth it to save this list? Maybe, but we don't anticipate - // this changing often at all. - List zones = new List(); - foreach (ZoneRow row in _rows) { - zones.Add(row.Zone); - } - buildSprites(zones); - } - MySpriteDrawFrame frame = _surface.DrawFrame(); - foreach (MySprite sprite in _staticSprites) + foreach (MySprite sprite in _staticSprites.Values) { frame.Add(sprite); } @@ -66,44 +94,18 @@ namespace IngameScript // for (int i=0; i < _rows.Count; i++) foreach (ZoneRow row in _rows) { - frame.Add(row.Name); row.Level.Data = row.Zone.OxygenLevel.ToString("P2"); frame.Add(row.Level); if (row.Zone.Triggered) frame.Add(row.Triggered); + else + { + frame.Add(row.Ok[0]); + frame.Add(row.Ok[1]); + } } frame.Dispose(); } - - private void buildSprites(List zones) - { - RectangleF viewport = new RectangleF( - (_surface.TextureSize - _surface.SurfaceSize) / 2f, - _surface.SurfaceSize - ); - - // build static sprites - float yPosition = 0f; - float xIncrement = viewport.Size.X / 3; -// float scale = 500 / Math.Min(viewport.Size.X, viewport.Size.Y); - - _staticSprites.Clear(); - - _staticSprites.Add(new MySprite(SpriteType.TEXT, "OXYGEN REPORT", new Vector2(viewport.Size.X / 2, yPosition) + viewport.Position, null, Color.White, "Debug", TextAlignment.CENTER, 1.25f * _scale)); // title - yPosition += 30f; - _staticSprites.Add(new MySprite(SpriteType.TEXT, "ZONE", new Vector2(0, yPosition) + viewport.Position, null, Color.Blue, "Debug", TextAlignment.LEFT, 1.2f * _scale)); // title - _staticSprites.Add(new MySprite(SpriteType.TEXT, "O2 LEVEL", new Vector2(xIncrement, yPosition) + viewport.Position, null, Color.Blue, "Debug", TextAlignment.LEFT, 1.2f * _scale)); // title - _staticSprites.Add(new MySprite(SpriteType.TEXT, "STATUS", new Vector2(xIncrement * 2, yPosition) + viewport.Position, null, Color.Blue, "Debug", TextAlignment.LEFT, 1.2f * _scale)); // title - yPosition += 30f; - - // build dynamic sprites - _rows.Clear(); - foreach (AirZone zone in zones) - { - _rows.Add(new ZoneRow(viewport, zone, yPosition, _scale)); - yPosition += 30f; - } - } } } } \ No newline at end of file