diff --git a/OpenRA.Game/Graphics/ChromeProvider.cs b/OpenRA.Game/Graphics/ChromeProvider.cs index 5a4b6f2995..afebe726da 100644 --- a/OpenRA.Game/Graphics/ChromeProvider.cs +++ b/OpenRA.Game/Graphics/ChromeProvider.cs @@ -54,10 +54,10 @@ namespace OpenRA.Graphics public static IReadOnlyDictionary Collections { get; private set; } static Dictionary collections; - static Dictionary cachedSheets; + static Dictionary> cachedSheets; static Dictionary> cachedSprites; static Dictionary cachedPanelSprites; - static Dictionary cachedCollectionSheets; + static Dictionary> cachedCollectionSheets; static IReadOnlyFileSystem fileSystem; static float dpiScale = 1; @@ -72,10 +72,10 @@ namespace OpenRA.Graphics fileSystem = modData.DefaultFileSystem; collections = new Dictionary(); - cachedSheets = new Dictionary(); + cachedSheets = new Dictionary>(); cachedSprites = new Dictionary>(); cachedPanelSprites = new Dictionary(); - cachedCollectionSheets = new Dictionary(); + cachedCollectionSheets = new Dictionary>(); Collections = new ReadOnlyDictionary(collections); @@ -91,7 +91,7 @@ namespace OpenRA.Graphics { if (cachedSheets != null) foreach (var sheet in cachedSheets.Values) - sheet.Dispose(); + sheet.First.Dispose(); collections = null; cachedSheets = null; @@ -108,47 +108,43 @@ namespace OpenRA.Graphics collections.Add(name, FieldLoader.Load(yaml)); } - static Sheet SheetForCollection(Collection c) + static Pair SheetForCollection(Collection c) { - Sheet sheet; + Pair sheetDensity; // Outer cache avoids recalculating image names - if (!cachedCollectionSheets.TryGetValue(c, out sheet)) + if (!cachedCollectionSheets.TryGetValue(c, out sheetDensity)) { - string sheetImage; - float sheetScale; + var image = c.Image; + var density = 1; if (dpiScale > 2 && !string.IsNullOrEmpty(c.Image3x)) { - sheetImage = c.Image3x; - sheetScale = 3; + image = c.Image3x; + density = 3; } else if (dpiScale > 1 && !string.IsNullOrEmpty(c.Image2x)) { - sheetImage = c.Image2x; - sheetScale = 2; - } - else - { - sheetImage = c.Image; - sheetScale = 1; + image = c.Image2x; + density = 2; } // Inner cache makes sure we share sheets between collections - if (!cachedSheets.TryGetValue(sheetImage, out sheet)) + if (!cachedSheets.TryGetValue(image, out sheetDensity)) { - using (var stream = fileSystem.Open(sheetImage)) + Sheet sheet; + using (var stream = fileSystem.Open(image)) sheet = new Sheet(SheetType.BGRA, stream); sheet.GetTexture().ScaleFilter = TextureScaleFilter.Linear; - sheet.DPIScale = sheetScale; - cachedSheets.Add(sheetImage, sheet); + sheetDensity = Pair.New(sheet, density); + cachedSheets.Add(image, sheetDensity); } - cachedCollectionSheets.Add(c, sheet); + cachedCollectionSheets.Add(c, sheetDensity); } - return sheet; + return sheetDensity; } public static Sprite GetImage(string collectionName, string imageName) @@ -174,14 +170,14 @@ namespace OpenRA.Graphics return null; // Cache the sprite - var sheet = SheetForCollection(collection); + var sheetDensity = SheetForCollection(collection); if (cachedCollection == null) { cachedCollection = new Dictionary(); cachedSprites.Add(collectionName, cachedCollection); } - var image = new Sprite(sheet, mi, TextureChannel.RGBA); + var image = new Sprite(sheetDensity.First, sheetDensity.Second * mi, TextureChannel.RGBA, 1f / sheetDensity.Second); cachedCollection.Add(imageName, image); return image; @@ -214,7 +210,7 @@ namespace OpenRA.Graphics } // Cache the sprites - var sheet = SheetForCollection(collection); + var sheetDensity = SheetForCollection(collection); var pr = collection.PanelRegion; var ps = collection.PanelSides; @@ -231,7 +227,7 @@ namespace OpenRA.Graphics Pair.New(PanelSides.Bottom | PanelSides.Right, new Rectangle(pr[0] + pr[2] + pr[4], pr[1] + pr[3] + pr[5], pr[6], pr[7])) }; - sprites = sides.Select(x => ps.HasSide(x.First) ? new Sprite(sheet, x.Second, TextureChannel.RGBA) : null) + sprites = sides.Select(x => ps.HasSide(x.First) ? new Sprite(sheetDensity.First, sheetDensity.Second * x.Second, TextureChannel.RGBA, 1f / sheetDensity.Second) : null) .ToArray(); } else diff --git a/OpenRA.Game/Graphics/Sheet.cs b/OpenRA.Game/Graphics/Sheet.cs index 3a98412476..51da5762f5 100644 --- a/OpenRA.Game/Graphics/Sheet.cs +++ b/OpenRA.Game/Graphics/Sheet.cs @@ -25,7 +25,6 @@ namespace OpenRA.Graphics public readonly Size Size; public readonly SheetType Type; - public float DPIScale = 1f; public byte[] GetData() { diff --git a/OpenRA.Game/Graphics/SheetBuilder.cs b/OpenRA.Game/Graphics/SheetBuilder.cs index b102de655b..ca0578e453 100644 --- a/OpenRA.Game/Graphics/SheetBuilder.cs +++ b/OpenRA.Game/Graphics/SheetBuilder.cs @@ -88,9 +88,9 @@ namespace OpenRA.Graphics return rect; } - public Sprite Add(Png src) + public Sprite Add(Png src, float scale = 1f) { - var rect = Allocate(new Size(src.Width, src.Height)); + var rect = Allocate(new Size(src.Width, src.Height), scale); Util.FastCopyIntoSprite(rect, src); current.CommitBufferedData(); return rect; @@ -114,8 +114,8 @@ namespace OpenRA.Graphics return (TextureChannel)nextChannel; } - public Sprite Allocate(Size imageSize) { return Allocate(imageSize, 0, float3.Zero); } - public Sprite Allocate(Size imageSize, float zRamp, float3 spriteOffset) + public Sprite Allocate(Size imageSize, float scale = 1f) { return Allocate(imageSize, 0, float3.Zero, scale); } + public Sprite Allocate(Size imageSize, float zRamp, float3 spriteOffset, float scale = 1f) { if (imageSize.Width + p.X + margin > current.Size.Width) { @@ -143,7 +143,7 @@ namespace OpenRA.Graphics p = int2.Zero; } - var rect = new Sprite(current, new Rectangle(p.X + margin, p.Y + margin, imageSize.Width, imageSize.Height), zRamp, spriteOffset, channel, BlendMode.Alpha); + var rect = new Sprite(current, new Rectangle(p.X + margin, p.Y + margin, imageSize.Width, imageSize.Height), zRamp, spriteOffset, channel, BlendMode.Alpha, scale); p += new int2(imageSize.Width + margin, 0); return rect; diff --git a/OpenRA.Game/Graphics/Sprite.cs b/OpenRA.Game/Graphics/Sprite.cs index 506dfe46f4..897c340d0c 100644 --- a/OpenRA.Game/Graphics/Sprite.cs +++ b/OpenRA.Game/Graphics/Sprite.cs @@ -26,25 +26,25 @@ namespace OpenRA.Graphics public readonly float3 FractionalOffset; public readonly float Top, Left, Bottom, Right; - public Sprite(Sheet sheet, Rectangle bounds, TextureChannel channel) - : this(sheet, bounds, 0, float2.Zero, channel) { } + public Sprite(Sheet sheet, Rectangle bounds, TextureChannel channel, float scale = 1) + : this(sheet, bounds, 0, float2.Zero, channel, BlendMode.Alpha, scale) { } - public Sprite(Sheet sheet, Rectangle bounds, float zRamp, float3 offset, TextureChannel channel, BlendMode blendMode = BlendMode.Alpha) + public Sprite(Sheet sheet, Rectangle bounds, float zRamp, float3 offset, TextureChannel channel, BlendMode blendMode = BlendMode.Alpha, float scale = 1f) { Sheet = sheet; Bounds = bounds; Offset = offset; ZRamp = zRamp; Channel = channel; - Size = new float3(bounds.Size.Width, bounds.Size.Height, bounds.Size.Height * zRamp); + Size = scale * new float3(bounds.Size.Width, bounds.Size.Height, bounds.Size.Height * zRamp); BlendMode = blendMode; FractionalOffset = Size.Z != 0 ? offset / Size : new float3(offset.X / Size.X, offset.Y / Size.Y, 0); - Left = (float)Math.Min(bounds.Left, bounds.Right) * sheet.DPIScale / sheet.Size.Width; - Top = (float)Math.Min(bounds.Top, bounds.Bottom) * sheet.DPIScale / sheet.Size.Height; - Right = (float)Math.Max(bounds.Left, bounds.Right) * sheet.DPIScale / sheet.Size.Width; - Bottom = (float)Math.Max(bounds.Top, bounds.Bottom) * sheet.DPIScale / sheet.Size.Height; + Left = (float)Math.Min(bounds.Left, bounds.Right) / sheet.Size.Width; + Top = (float)Math.Min(bounds.Top, bounds.Bottom) / sheet.Size.Height; + Right = (float)Math.Max(bounds.Left, bounds.Right) / sheet.Size.Width; + Bottom = (float)Math.Max(bounds.Top, bounds.Bottom) / sheet.Size.Height; } } @@ -61,10 +61,10 @@ namespace OpenRA.Graphics SecondarySheet = secondarySheet; SecondaryBounds = secondaryBounds; SecondaryChannel = secondaryChannel; - SecondaryLeft = (float)Math.Min(secondaryBounds.Left, secondaryBounds.Right) * secondarySheet.DPIScale / s.Sheet.Size.Width; - SecondaryTop = (float)Math.Min(secondaryBounds.Top, secondaryBounds.Bottom) * secondarySheet.DPIScale / s.Sheet.Size.Height; - SecondaryRight = (float)Math.Max(secondaryBounds.Left, secondaryBounds.Right) * secondarySheet.DPIScale / s.Sheet.Size.Width; - SecondaryBottom = (float)Math.Max(secondaryBounds.Top, secondaryBounds.Bottom) * secondarySheet.DPIScale / s.Sheet.Size.Height; + SecondaryLeft = (float)Math.Min(secondaryBounds.Left, secondaryBounds.Right) / s.Sheet.Size.Width; + SecondaryTop = (float)Math.Min(secondaryBounds.Top, secondaryBounds.Bottom) / s.Sheet.Size.Height; + SecondaryRight = (float)Math.Max(secondaryBounds.Left, secondaryBounds.Right) / s.Sheet.Size.Width; + SecondaryBottom = (float)Math.Max(secondaryBounds.Top, secondaryBounds.Bottom) / s.Sheet.Size.Height; } } diff --git a/OpenRA.Game/Primitives/Rectangle.cs b/OpenRA.Game/Primitives/Rectangle.cs index bc11132d25..4e016f81af 100644 --- a/OpenRA.Game/Primitives/Rectangle.cs +++ b/OpenRA.Game/Primitives/Rectangle.cs @@ -117,6 +117,8 @@ namespace OpenRA.Primitives return rect == Intersect(this, rect); } + public static Rectangle operator *(int a, Rectangle b) { return new Rectangle(a * b.X, a * b.Y, a * b.Width, a * b.Height); } + public override string ToString() { return string.Format("{{X={0},Y={1},Width={2},Height={3}}}", X, Y, Width, Height); diff --git a/OpenRA.Mods.Cnc/CncLoadScreen.cs b/OpenRA.Mods.Cnc/CncLoadScreen.cs index ba71435ad8..066d307f33 100644 --- a/OpenRA.Mods.Cnc/CncLoadScreen.cs +++ b/OpenRA.Mods.Cnc/CncLoadScreen.cs @@ -31,6 +31,7 @@ namespace OpenRA.Mods.Cnc float2 loadingPos, versionPos; Sheet lastSheet; + int lastDensity; Size lastResolution; IReadOnlyDictionary lastFonts; @@ -41,31 +42,32 @@ namespace OpenRA.Mods.Cnc versionText = modData.Manifest.Metadata.Version; } - public override void DisplayInner(Renderer r, Sheet s) + public override void DisplayInner(Renderer r, Sheet s, int density) { - if (s != lastSheet) + if (s != lastSheet || density != lastDensity) { lastSheet = s; + lastDensity = density; border = new[] { - new Sprite(s, new Rectangle(129, 129, 32, 32), TextureChannel.RGBA), - new Sprite(s, new Rectangle(161, 129, 62, 32), TextureChannel.RGBA), - new Sprite(s, new Rectangle(223, 129, 32, 32), TextureChannel.RGBA), - new Sprite(s, new Rectangle(129, 161, 32, 62), TextureChannel.RGBA), + CreateSprite(s, density, new Rectangle(129, 129, 32, 32)), + CreateSprite(s, density, new Rectangle(161, 129, 62, 32)), + CreateSprite(s, density, new Rectangle(223, 129, 32, 32)), + CreateSprite(s, density, new Rectangle(129, 161, 32, 62)), null, - new Sprite(s, new Rectangle(223, 161, 32, 62), TextureChannel.RGBA), - new Sprite(s, new Rectangle(129, 223, 32, 32), TextureChannel.RGBA), - new Sprite(s, new Rectangle(161, 223, 62, 32), TextureChannel.RGBA), - new Sprite(s, new Rectangle(223, 223, 32, 32), TextureChannel.RGBA) + CreateSprite(s, density, new Rectangle(223, 161, 32, 62)), + CreateSprite(s, density, new Rectangle(129, 223, 32, 32)), + CreateSprite(s, density, new Rectangle(161, 223, 62, 32)), + CreateSprite(s, density, new Rectangle(223, 223, 32, 32)) }; - nodLogo = new Sprite(s, new Rectangle(0, 256, 256, 256), TextureChannel.RGBA); - gdiLogo = new Sprite(s, new Rectangle(256, 256, 256, 256), TextureChannel.RGBA); - evaLogo = new Sprite(s, new Rectangle(769, 320, 128, 64), TextureChannel.RGBA); + nodLogo = CreateSprite(s, density, new Rectangle(0, 256, 256, 256)); + gdiLogo = CreateSprite(s, density, new Rectangle(256, 256, 256, 256)); + evaLogo = CreateSprite(s, density, new Rectangle(769, 320, 128, 64)); - brightBlock = new Sprite(s, new Rectangle(777, 385, 16, 35), TextureChannel.RGBA); - dimBlock = new Sprite(s, new Rectangle(794, 385, 16, 35), TextureChannel.RGBA); + brightBlock = CreateSprite(s, density, new Rectangle(777, 385, 16, 35)); + dimBlock = CreateSprite(s, density, new Rectangle(794, 385, 16, 35)); } if (r.Resolution != lastResolution) diff --git a/OpenRA.Mods.Common/LoadScreens/LogoStripeLoadScreen.cs b/OpenRA.Mods.Common/LoadScreens/LogoStripeLoadScreen.cs index b80dda18e0..0a57df524d 100644 --- a/OpenRA.Mods.Common/LoadScreens/LogoStripeLoadScreen.cs +++ b/OpenRA.Mods.Common/LoadScreens/LogoStripeLoadScreen.cs @@ -24,6 +24,7 @@ namespace OpenRA.Mods.Common.LoadScreens Sprite stripe, logo; Sheet lastSheet; + int lastDensity; Size lastResolution; string[] messages = { "Loading..." }; @@ -36,13 +37,14 @@ namespace OpenRA.Mods.Common.LoadScreens messages = info["Text"].Split(','); } - public override void DisplayInner(Renderer r, Sheet s) + public override void DisplayInner(Renderer r, Sheet s, int density) { - if (s != lastSheet) + if (s != lastSheet || density != lastDensity) { lastSheet = s; - logo = new Sprite(s, new Rectangle(0, 0, 256, 256), TextureChannel.RGBA); - stripe = new Sprite(s, new Rectangle(258, 0, 253, 256), TextureChannel.RGBA); + lastDensity = density; + logo = CreateSprite(s, density, new Rectangle(0, 0, 256, 256)); + stripe = CreateSprite(s, density, new Rectangle(258, 0, 253, 256)); } if (r.Resolution != lastResolution) diff --git a/OpenRA.Mods.Common/LoadScreens/ModContentLoadScreen.cs b/OpenRA.Mods.Common/LoadScreens/ModContentLoadScreen.cs index e9e5027465..8f2a607103 100644 --- a/OpenRA.Mods.Common/LoadScreens/ModContentLoadScreen.cs +++ b/OpenRA.Mods.Common/LoadScreens/ModContentLoadScreen.cs @@ -25,14 +25,16 @@ namespace OpenRA.Mods.Common.LoadScreens Rectangle bounds; Sheet lastSheet; + int lastDensity; Size lastResolution; - public override void DisplayInner(Renderer r, Sheet s) + public override void DisplayInner(Renderer r, Sheet s, int density) { - if (s != lastSheet) + if (s != lastSheet || density != lastDensity) { lastSheet = s; - sprite = new Sprite(s, new Rectangle(0, 0, 1024, 480), TextureChannel.RGBA); + lastDensity = density; + sprite = CreateSprite(s, density, new Rectangle(0, 0, 1024, 480)); } if (r.Resolution != lastResolution) diff --git a/OpenRA.Mods.Common/LoadScreens/SheetLoadScreen.cs b/OpenRA.Mods.Common/LoadScreens/SheetLoadScreen.cs index 1033112efb..2c86c4cfec 100644 --- a/OpenRA.Mods.Common/LoadScreens/SheetLoadScreen.cs +++ b/OpenRA.Mods.Common/LoadScreens/SheetLoadScreen.cs @@ -12,6 +12,7 @@ using System.Collections.Generic; using System.Diagnostics; using OpenRA.Graphics; +using OpenRA.Primitives; namespace OpenRA.Mods.Common.LoadScreens { @@ -21,7 +22,9 @@ namespace OpenRA.Mods.Common.LoadScreens protected Dictionary Info { get; private set; } float dpiScale = 1; + Sheet sheet; + int density; public override void Init(ModData modData, Dictionary info) { @@ -29,7 +32,7 @@ namespace OpenRA.Mods.Common.LoadScreens Info = info; } - public abstract void DisplayInner(Renderer r, Sheet s); + public abstract void DisplayInner(Renderer r, Sheet s, int density); public override void Display() { @@ -58,33 +61,37 @@ namespace OpenRA.Mods.Common.LoadScreens if (sheet == null && Info.ContainsKey("Image")) { var key = "Image"; - float sheetScale = 1; + density = 1; if (dpiScale > 2 && Info.ContainsKey("Image3x")) { key = "Image3x"; - sheetScale = 3; + density = 3; } else if (dpiScale > 1 && Info.ContainsKey("Image2x")) { key = "Image2x"; - sheetScale = 2; + density = 2; } using (var stream = ModData.DefaultFileSystem.Open(Info[key])) { sheet = new Sheet(SheetType.BGRA, stream); sheet.GetTexture().ScaleFilter = TextureScaleFilter.Linear; - sheet.DPIScale = sheetScale; } } Game.Renderer.BeginUI(); - DisplayInner(Game.Renderer, sheet); + DisplayInner(Game.Renderer, sheet, density); Game.Renderer.EndFrame(new NullInputHandler()); lastUpdate.Restart(); } + protected static Sprite CreateSprite(Sheet s, int density, Rectangle rect) + { + return new Sprite(s, density * rect, TextureChannel.RGBA, 1f / density); + } + protected override void Dispose(bool disposing) { if (disposing && sheet != null) diff --git a/OpenRA.Mods.Common/Widgets/ColorMixerWidget.cs b/OpenRA.Mods.Common/Widgets/ColorMixerWidget.cs index a7d8a2d49f..abf3565096 100644 --- a/OpenRA.Mods.Common/Widgets/ColorMixerWidget.cs +++ b/OpenRA.Mods.Common/Widgets/ColorMixerWidget.cs @@ -164,8 +164,8 @@ namespace OpenRA.Mods.Common.Widgets Game.Renderer.RgbaSpriteRenderer.DrawSprite(mixerSprite, RenderOrigin, new float2(RenderBounds.Size)); var sprite = ChromeProvider.GetImage("lobby-bits", "colorpicker"); - var pos = RenderOrigin + PxFromValue() - new int2(sprite.Bounds.Width, sprite.Bounds.Height) / 2; - WidgetUtils.FillEllipseWithColor(new Rectangle(pos.X + 1, pos.Y + 1, sprite.Bounds.Width - 2, sprite.Bounds.Height - 2), Color); + var pos = RenderOrigin + PxFromValue() - new int2((int)sprite.Size.X, (int)sprite.Size.Y) / 2; + WidgetUtils.FillEllipseWithColor(new Rectangle(pos.X + 1, pos.Y + 1, (int)sprite.Size.X - 2, (int)sprite.Size.Y - 2), Color); Game.Renderer.RgbaSpriteRenderer.DrawSprite(sprite, pos); } diff --git a/OpenRA.Mods.Common/Widgets/DropDownButtonWidget.cs b/OpenRA.Mods.Common/Widgets/DropDownButtonWidget.cs index 205923aa2f..a7f22b621f 100644 --- a/OpenRA.Mods.Common/Widgets/DropDownButtonWidget.cs +++ b/OpenRA.Mods.Common/Widgets/DropDownButtonWidget.cs @@ -48,10 +48,10 @@ namespace OpenRA.Mods.Common.Widgets var image = ChromeProvider.GetImage("scrollbar", IsDisabled() ? "down_pressed" : "down_arrow"); var rb = RenderBounds; - WidgetUtils.DrawRGBA(image, stateOffset + new float2((rb.Right - (rb.Height + image.Bounds.Width) / 2), rb.Top + (rb.Height - image.Bounds.Height) / 2)); + WidgetUtils.DrawRGBA(image, stateOffset + new float2(rb.Right - (rb.Height + image.Size.X) / 2, rb.Top + (rb.Height - image.Size.Y) / 2)); var separator = ChromeProvider.GetImage(SeparatorCollection, SeparatorImage); - WidgetUtils.DrawRGBA(separator, new float2(-3, 0) + new float2(rb.Right - rb.Height + 4, rb.Top + (rb.Height - separator.Bounds.Height) / 2)); + WidgetUtils.DrawRGBA(separator, stateOffset + new float2(-3, 0) + new float2(rb.Right - rb.Height + 4, rb.Top + (rb.Height - separator.Size.Y) / 2)); } public override Widget Clone() { return new DropDownButtonWidget(this); } diff --git a/OpenRA.Mods.Common/Widgets/HueSliderWidget.cs b/OpenRA.Mods.Common/Widgets/HueSliderWidget.cs index a10aa9046f..ef0224d41e 100644 --- a/OpenRA.Mods.Common/Widgets/HueSliderWidget.cs +++ b/OpenRA.Mods.Common/Widgets/HueSliderWidget.cs @@ -47,7 +47,7 @@ namespace OpenRA.Mods.Common.Widgets Game.Renderer.RgbaSpriteRenderer.DrawSprite(hueSprite, ro, new float2(rb.Size)); var sprite = ChromeProvider.GetImage("lobby-bits", "huepicker"); - var pos = RenderOrigin + new int2(PxFromValue(Value).Clamp(0, rb.Width - 1) - sprite.Bounds.Width / 2, (rb.Height - sprite.Bounds.Height) / 2); + var pos = RenderOrigin + new int2(PxFromValue(Value).Clamp(0, rb.Width - 1) - (int)sprite.Size.X / 2, (rb.Height - (int)sprite.Size.Y) / 2); Game.Renderer.RgbaSpriteRenderer.DrawSprite(sprite, pos); } } diff --git a/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyUtils.cs b/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyUtils.cs index d25d11ce19..72125a62c2 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyUtils.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Lobby/LobbyUtils.cs @@ -252,7 +252,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic if (!orderManager.LocalClient.IsObserver && orderManager.LocalClient.State == Session.ClientState.Ready) return; - var spawnSize = new float2(ChromeProvider.GetImage("lobby-bits", "spawn-unclaimed").Bounds.Size); + var spawnSize = ChromeProvider.GetImage("lobby-bits", "spawn-unclaimed").Size.XY; var selectedSpawn = preview.SpawnPoints .Select((sp, i) => Pair.New(mapPreview.ConvertToPreview(sp, preview.GridType), i)) .Where(a => ((a.First - mi.Location).ToFloat2() / spawnSize * 2).LengthSquared <= 1) diff --git a/OpenRA.Mods.Common/Widgets/MapPreviewWidget.cs b/OpenRA.Mods.Common/Widgets/MapPreviewWidget.cs index 3b1a3fbe81..9fa24764d6 100644 --- a/OpenRA.Mods.Common/Widgets/MapPreviewWidget.cs +++ b/OpenRA.Mods.Common/Widgets/MapPreviewWidget.cs @@ -191,10 +191,10 @@ namespace OpenRA.Mods.Common.Widgets var owned = colors.ContainsKey(p); var pos = ConvertToPreview(p, gridType); var sprite = owned ? spawnClaimed : spawnUnclaimed; - var offset = new int2(sprite.Bounds.Width, sprite.Bounds.Height) / 2; + var offset = sprite.Size.XY.ToInt2() / 2; if (owned) - WidgetUtils.FillEllipseWithColor(new Rectangle(pos.X - offset.X + 1, pos.Y - offset.Y + 1, sprite.Bounds.Width - 2, sprite.Bounds.Height - 2), colors[p]); + WidgetUtils.FillEllipseWithColor(new Rectangle(pos.X - offset.X + 1, pos.Y - offset.Y + 1, (int)sprite.Size.X - 2, (int)sprite.Size.Y - 2), colors[p]); Game.Renderer.RgbaSpriteRenderer.DrawSprite(sprite, pos - offset); var number = Convert.ToChar('A' + spawnPoints.IndexOf(p)).ToString(); diff --git a/OpenRA.Mods.Common/Widgets/WidgetUtils.cs b/OpenRA.Mods.Common/Widgets/WidgetUtils.cs index 01a46f5283..8043e6cf28 100644 --- a/OpenRA.Mods.Common/Widgets/WidgetUtils.cs +++ b/OpenRA.Mods.Common/Widgets/WidgetUtils.cs @@ -47,22 +47,27 @@ namespace OpenRA.Mods.Common.Widgets public static void FillRectWithSprite(Rectangle r, Sprite s) { - for (var x = r.Left; x < r.Right; x += (int)s.Size.X) - for (var y = r.Top; y < r.Bottom; y += (int)s.Size.Y) + var scale = s.Size.X / s.Bounds.Width; + for (var x = (float)r.Left; x < r.Right; x += s.Size.X) + { + for (var y = (float)r.Top; y < r.Bottom; y += s.Size.Y) { var ss = s; - var left = new int2(r.Right - x, r.Bottom - y); - if (left.X < (int)s.Size.X || left.Y < (int)s.Size.Y) + var dx = r.Right - x; + var dy = r.Bottom - y; + if (dx < s.Size.X || dy < s.Size.Y) { - var rr = new Rectangle(s.Bounds.Left, + var rr = new Rectangle( + s.Bounds.Left, s.Bounds.Top, - Math.Min(left.X, (int)s.Size.X), - Math.Min(left.Y, (int)s.Size.Y)); - ss = new Sprite(s.Sheet, rr, s.Channel); + Math.Min(s.Bounds.Width, (int)(dx / scale)), + Math.Min(s.Bounds.Height, (int)(dy / scale))); + ss = new Sprite(s.Sheet, rr, s.Channel, scale); } DrawRGBA(ss, new float2(x, y)); } + } } public static void FillRectWithColor(Rectangle r, Color c)