Allow mods to customise the default rendering scale.

This commit is contained in:
Paul Chote
2022-12-22 08:40:59 +13:00
committed by Matthias Mailänder
parent e21f94f36a
commit 6d438a9d61
8 changed files with 59 additions and 50 deletions

View File

@@ -227,14 +227,14 @@ namespace OpenRA.Graphics
var vd = graphicSettings.ViewportDistance; var vd = graphicSettings.ViewportDistance;
if (viewportSizes.AllowNativeZoom && vd == WorldViewport.Native) if (viewportSizes.AllowNativeZoom && vd == WorldViewport.Native)
minZoom = 1; minZoom = viewportSizes.DefaultScale;
else else
{ {
var range = viewportSizes.GetSizeRange(vd); var range = viewportSizes.GetSizeRange(vd);
minZoom = CalculateMinimumZoom(range.X, range.Y); minZoom = CalculateMinimumZoom(range.X, range.Y) * viewportSizes.DefaultScale;
} }
maxZoom = Math.Min(minZoom * viewportSizes.MaxZoomScale, Game.Renderer.NativeResolution.Height * 1f / viewportSizes.MaxZoomWindowHeight); maxZoom = Math.Min(minZoom * viewportSizes.MaxZoomScale, Game.Renderer.NativeResolution.Height * viewportSizes.DefaultScale / viewportSizes.MaxZoomWindowHeight);
if (unlockMinZoom) if (unlockMinZoom)
{ {

View File

@@ -19,6 +19,7 @@ namespace OpenRA
public readonly int2 MediumWindowHeights = new int2(600, 900); public readonly int2 MediumWindowHeights = new int2(600, 900);
public readonly int2 FarWindowHeights = new int2(900, 1300); public readonly int2 FarWindowHeights = new int2(900, 1300);
public readonly float DefaultScale = 1.0f;
public readonly float MaxZoomScale = 2.0f; public readonly float MaxZoomScale = 2.0f;
public readonly int MaxZoomWindowHeight = 240; public readonly int MaxZoomWindowHeight = 240;
public readonly bool AllowNativeZoom = true; public readonly bool AllowNativeZoom = true;

View File

@@ -177,10 +177,10 @@ namespace OpenRA.Mods.Common.Traits
var sprite = tileCache.TileSprite(tile, 0); var sprite = tileCache.TileSprite(tile, 0);
var u = gridType == MapGridType.Rectangular ? x : (x - y) / 2f; var u = gridType == MapGridType.Rectangular ? x : (x - y) / 2f;
var v = gridType == MapGridType.Rectangular ? y : (x + y) / 2f; var v = gridType == MapGridType.Rectangular ? y : (x + y) / 2f;
var offset = (new float2(u * ts.Width, (v - 0.5f * tileInfo.Height) * ts.Height) - 0.5f * sprite.Size.XY).ToInt2(); var offset = scale * (new float2(u * ts.Width, (v - 0.5f * tileInfo.Height) * ts.Height) - 0.5f * sprite.Size.XY);
var palette = template.Palette ?? terrainInfo.Palette; var palette = template.Palette ?? terrainInfo.Palette;
yield return new UISpriteRenderable(sprite, WPos.Zero, origin + offset, 0, wr.Palette(palette), scale); yield return new UISpriteRenderable(sprite, WPos.Zero, origin + offset.ToInt2(), 0, wr.Palette(palette), scale);
} }
} }
} }

View File

@@ -25,14 +25,16 @@ namespace OpenRA.Mods.Common.Widgets
public Func<float> GetScale = () => 1f; public Func<float> GetScale = () => 1f;
readonly WorldRenderer worldRenderer; readonly WorldRenderer worldRenderer;
readonly WorldViewportSizes viewportSizes;
IActorPreview[] preview = Array.Empty<IActorPreview>(); IActorPreview[] preview = Array.Empty<IActorPreview>();
public int2 PreviewOffset { get; private set; } public int2 PreviewOffset { get; private set; }
public int2 IdealPreviewSize { get; private set; } public int2 IdealPreviewSize { get; private set; }
[ObjectCreator.UseCtor] [ObjectCreator.UseCtor]
public ActorPreviewWidget(WorldRenderer worldRenderer) public ActorPreviewWidget(ModData modData, WorldRenderer worldRenderer)
{ {
viewportSizes = modData.Manifest.Get<WorldViewportSizes>();
this.worldRenderer = worldRenderer; this.worldRenderer = worldRenderer;
} }
@@ -41,6 +43,7 @@ namespace OpenRA.Mods.Common.Widgets
{ {
preview = other.preview; preview = other.preview;
worldRenderer = other.worldRenderer; worldRenderer = other.worldRenderer;
viewportSizes = other.viewportSizes;
} }
public override Widget Clone() { return new ActorPreviewWidget(this); } public override Widget Clone() { return new ActorPreviewWidget(this); }
@@ -55,14 +58,14 @@ namespace OpenRA.Mods.Common.Widgets
// Calculate the preview bounds // Calculate the preview bounds
var r = preview.SelectMany(p => p.ScreenBounds(worldRenderer, WPos.Zero)); var r = preview.SelectMany(p => p.ScreenBounds(worldRenderer, WPos.Zero));
var b = r.Union(); var b = r.Union();
IdealPreviewSize = new int2(b.Width, b.Height); IdealPreviewSize = new int2((int)(b.Width * viewportSizes.DefaultScale), (int)(b.Height * viewportSizes.DefaultScale));
PreviewOffset = -new int2(b.Left, b.Top) - IdealPreviewSize / 2; PreviewOffset = -new int2((int)(b.Left * viewportSizes.DefaultScale), (int)(b.Top * viewportSizes.DefaultScale)) - IdealPreviewSize / 2;
} }
IFinalizedRenderable[] renderables; IFinalizedRenderable[] renderables;
public override void PrepareRenderables() public override void PrepareRenderables()
{ {
var scale = GetScale(); var scale = GetScale() * viewportSizes.DefaultScale;
var origin = RenderOrigin + PreviewOffset + new int2(RenderBounds.Size.Width / 2, RenderBounds.Size.Height / 2); var origin = RenderOrigin + PreviewOffset + new int2(RenderBounds.Size.Width / 2, RenderBounds.Size.Height / 2);
renderables = preview renderables = preview

View File

@@ -41,8 +41,6 @@ namespace OpenRA.Mods.Common.Widgets.Logic
void IntializeLayerPreview() void IntializeLayerPreview()
{ {
layerTemplateList.RemoveChildren(); layerTemplateList.RemoveChildren();
var rules = worldRenderer.World.Map.Rules;
var tileSize = worldRenderer.World.Map.Grid.TileSize;
foreach (var resourceRenderer in worldRenderer.World.WorldActor.TraitsImplementing<IResourceRenderer>()) foreach (var resourceRenderer in worldRenderer.World.WorldActor.TraitsImplementing<IResourceRenderer>())
{ {
foreach (var resourceType in resourceRenderer.ResourceTypes) foreach (var resourceType in resourceRenderer.ResourceTypes)
@@ -55,12 +53,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic
newResourcePreviewTemplate.Bounds.Y = 0; newResourcePreviewTemplate.Bounds.Y = 0;
var layerPreview = newResourcePreviewTemplate.Get<ResourcePreviewWidget>("LAYER_PREVIEW"); var layerPreview = newResourcePreviewTemplate.Get<ResourcePreviewWidget>("LAYER_PREVIEW");
var size = layerPreview.IdealPreviewSize;
layerPreview.IsVisible = () => true; layerPreview.IsVisible = () => true;
layerPreview.ResourceType = resourceType; layerPreview.ResourceType = resourceType;
layerPreview.Bounds.Width = tileSize.Width; layerPreview.Bounds.Width = size.Width;
layerPreview.Bounds.Height = tileSize.Height; layerPreview.Bounds.Height = size.Height;
newResourcePreviewTemplate.Bounds.Width = tileSize.Width + (layerPreview.Bounds.X * 2); newResourcePreviewTemplate.Bounds.Width = size.Width + (layerPreview.Bounds.X * 2);
newResourcePreviewTemplate.Bounds.Height = tileSize.Height + (layerPreview.Bounds.Y * 2); newResourcePreviewTemplate.Bounds.Height = size.Height + (layerPreview.Bounds.Y * 2);
newResourcePreviewTemplate.IsVisible = () => true; newResourcePreviewTemplate.IsVisible = () => true;
newResourcePreviewTemplate.GetTooltipText = () => resourceType; newResourcePreviewTemplate.GetTooltipText = () => resourceType;

View File

@@ -38,7 +38,6 @@ namespace OpenRA.Mods.Common.Widgets.Logic
} }
readonly ITemplatedTerrainInfo terrainInfo; readonly ITemplatedTerrainInfo terrainInfo;
readonly ITiledTerrainRenderer terrainRenderer;
readonly TileSelectorTemplate[] allTemplates; readonly TileSelectorTemplate[] allTemplates;
readonly EditorCursorLayer editorCursor; readonly EditorCursorLayer editorCursor;
@@ -50,10 +49,6 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (terrainInfo == null) if (terrainInfo == null)
throw new InvalidDataException("TileSelectorLogic requires a template-based tileset."); throw new InvalidDataException("TileSelectorLogic requires a template-based tileset.");
terrainRenderer = world.WorldActor.TraitOrDefault<ITiledTerrainRenderer>();
if (terrainRenderer == null)
throw new InvalidDataException("TileSelectorLogic requires a tile-based terrain renderer.");
allTemplates = terrainInfo.Templates.Values.Select(t => new TileSelectorTemplate(t)).ToArray(); allTemplates = terrainInfo.Templates.Values.Select(t => new TileSelectorTemplate(t)).ToArray();
editorCursor = world.WorldActor.Trait<EditorCursorLayer>(); editorCursor = world.WorldActor.Trait<EditorCursorLayer>();
@@ -115,18 +110,16 @@ namespace OpenRA.Mods.Common.Widgets.Logic
() => Editor.SetBrush(new EditorTileBrush(Editor, tileId, WorldRenderer))); () => Editor.SetBrush(new EditorTileBrush(Editor, tileId, WorldRenderer)));
var preview = item.Get<TerrainTemplatePreviewWidget>("TILE_PREVIEW"); var preview = item.Get<TerrainTemplatePreviewWidget>("TILE_PREVIEW");
var template = terrainInfo.Templates[tileId]; preview.SetTemplate(terrainInfo.Templates[tileId]);
var bounds = terrainRenderer.TemplateBounds(template);
// Scale templates to fit within the panel // Scale templates to fit within the panel
var scale = 1f; var scale = 1f;
while (scale * bounds.Width > ItemTemplate.Bounds.Width) if (scale * preview.IdealPreviewSize.X > ItemTemplate.Bounds.Width)
scale /= 2; scale = (ItemTemplate.Bounds.Width - Panel.ItemSpacing) / (float)preview.IdealPreviewSize.X;
preview.Template = template;
preview.GetScale = () => scale; preview.GetScale = () => scale;
preview.Bounds.Width = (int)(scale * bounds.Width); preview.Bounds.Width = (int)(scale * preview.IdealPreviewSize.X);
preview.Bounds.Height = (int)(scale * bounds.Height); preview.Bounds.Height = (int)(scale * preview.IdealPreviewSize.Y);
item.Bounds.Width = preview.Bounds.Width + 2 * preview.Bounds.X; item.Bounds.Width = preview.Bounds.Width + 2 * preview.Bounds.X;
item.Bounds.Height = preview.Bounds.Height + 2 * preview.Bounds.Y; item.Bounds.Height = preview.Bounds.Height + 2 * preview.Bounds.Y;

View File

@@ -23,6 +23,7 @@ namespace OpenRA.Mods.Common.Widgets
public Func<float> GetScale = () => 1f; public Func<float> GetScale = () => 1f;
readonly WorldRenderer worldRenderer; readonly WorldRenderer worldRenderer;
readonly WorldViewportSizes viewportSizes;
readonly IResourceRenderer[] resourceRenderers; readonly IResourceRenderer[] resourceRenderers;
readonly Size tileSize; readonly Size tileSize;
@@ -43,12 +44,18 @@ namespace OpenRA.Mods.Common.Widgets
} }
} }
public Size IdealPreviewSize { get; private set; }
[ObjectCreator.UseCtor] [ObjectCreator.UseCtor]
public ResourcePreviewWidget(WorldRenderer worldRenderer, World world) public ResourcePreviewWidget(ModData modData, WorldRenderer worldRenderer, World world)
{ {
this.worldRenderer = worldRenderer; this.worldRenderer = worldRenderer;
viewportSizes = modData.Manifest.Get<WorldViewportSizes>();
resourceRenderers = world.WorldActor.TraitsImplementing<IResourceRenderer>().ToArray(); resourceRenderers = world.WorldActor.TraitsImplementing<IResourceRenderer>().ToArray();
tileSize = world.Map.Grid.TileSize; tileSize = world.Map.Grid.TileSize;
IdealPreviewSize = new Size(
(int)(viewportSizes.DefaultScale * tileSize.Width),
(int)(viewportSizes.DefaultScale * tileSize.Height));
} }
protected ResourcePreviewWidget(ResourcePreviewWidget other) protected ResourcePreviewWidget(ResourcePreviewWidget other)
@@ -56,10 +63,12 @@ namespace OpenRA.Mods.Common.Widgets
{ {
GetScale = other.GetScale; GetScale = other.GetScale;
worldRenderer = other.worldRenderer; worldRenderer = other.worldRenderer;
viewportSizes = other.viewportSizes;
resourceRenderers = other.resourceRenderers; resourceRenderers = other.resourceRenderers;
tileSize = other.tileSize; tileSize = other.tileSize;
resourceType = other.resourceType; resourceType = other.resourceType;
resourceRenderer = other.resourceRenderer; resourceRenderer = other.resourceRenderer;
IdealPreviewSize = other.IdealPreviewSize;
} }
public override Widget Clone() { return new ResourcePreviewWidget(this); } public override Widget Clone() { return new ResourcePreviewWidget(this); }
@@ -69,8 +78,11 @@ namespace OpenRA.Mods.Common.Widgets
if (resourceRenderer == null) if (resourceRenderer == null)
return; return;
var scale = GetScale(); var scale = GetScale() * viewportSizes.DefaultScale;
var origin = RenderOrigin + new int2((RenderBounds.Size.Width - tileSize.Width) / 2, (RenderBounds.Size.Height - tileSize.Height) / 2); var origin = RenderOrigin + new int2(
(int)(0.5f * (RenderBounds.Size.Width - scale * tileSize.Width)),
(int)(0.5f * (RenderBounds.Size.Height - scale * tileSize.Height)));
foreach (var r in resourceRenderer.RenderUIPreview(worldRenderer, resourceType, origin, scale)) foreach (var r in resourceRenderer.RenderUIPreview(worldRenderer, resourceType, origin, scale))
r.PrepareRender(worldRenderer).Render(worldRenderer); r.PrepareRender(worldRenderer).Render(worldRenderer);
} }

View File

@@ -13,7 +13,6 @@ using System;
using OpenRA.Graphics; using OpenRA.Graphics;
using OpenRA.Mods.Common.Terrain; using OpenRA.Mods.Common.Terrain;
using OpenRA.Mods.Common.Traits; using OpenRA.Mods.Common.Traits;
using OpenRA.Primitives;
using OpenRA.Widgets; using OpenRA.Widgets;
namespace OpenRA.Mods.Common.Widgets namespace OpenRA.Mods.Common.Widgets
@@ -24,28 +23,19 @@ namespace OpenRA.Mods.Common.Widgets
readonly ITiledTerrainRenderer terrainRenderer; readonly ITiledTerrainRenderer terrainRenderer;
readonly WorldRenderer worldRenderer; readonly WorldRenderer worldRenderer;
readonly WorldViewportSizes viewportSizes;
TerrainTemplateInfo template; TerrainTemplateInfo template;
Rectangle bounds;
public TerrainTemplateInfo Template public int2 PreviewOffset { get; private set; }
{ public int2 IdealPreviewSize { get; private set; }
get => template;
set
{
template = value;
if (template == null)
return;
bounds = terrainRenderer.TemplateBounds(template);
}
}
[ObjectCreator.UseCtor] [ObjectCreator.UseCtor]
public TerrainTemplatePreviewWidget(WorldRenderer worldRenderer, World world) public TerrainTemplatePreviewWidget(ModData modData, WorldRenderer worldRenderer, World world)
{ {
this.worldRenderer = worldRenderer; this.worldRenderer = worldRenderer;
viewportSizes = modData.Manifest.Get<WorldViewportSizes>();
terrainRenderer = world.WorldActor.TraitOrDefault<ITiledTerrainRenderer>(); terrainRenderer = world.WorldActor.TraitOrDefault<ITiledTerrainRenderer>();
if (terrainRenderer == null) if (terrainRenderer == null)
throw new YamlException("TerrainTemplatePreviewWidget requires a tile-based terrain renderer."); throw new YamlException("TerrainTemplatePreviewWidget requires a tile-based terrain renderer.");
@@ -55,21 +45,32 @@ namespace OpenRA.Mods.Common.Widgets
: base(other) : base(other)
{ {
worldRenderer = other.worldRenderer; worldRenderer = other.worldRenderer;
viewportSizes = other.viewportSizes;
terrainRenderer = other.terrainRenderer; terrainRenderer = other.terrainRenderer;
Template = other.Template; template = other.template;
GetScale = other.GetScale; GetScale = other.GetScale;
} }
public override Widget Clone() { return new TerrainTemplatePreviewWidget(this); } public override Widget Clone() { return new TerrainTemplatePreviewWidget(this); }
public void SetTemplate(TerrainTemplateInfo template)
{
this.template = template;
var b = terrainRenderer.TemplateBounds(template);
IdealPreviewSize = new int2((int)(b.Width * viewportSizes.DefaultScale), (int)(b.Height * viewportSizes.DefaultScale));
// Measured from the middle of the widget to the middle of the top-left cell of the template
PreviewOffset = -new int2((int)(b.Left * viewportSizes.DefaultScale), (int)(b.Top * viewportSizes.DefaultScale)) - IdealPreviewSize / 2;
}
public override void Draw() public override void Draw()
{ {
if (template == null) if (template == null)
return; return;
var scale = GetScale(); var scale = GetScale() * viewportSizes.DefaultScale;
var sb = new Rectangle((int)(scale * bounds.X), (int)(scale * bounds.Y), (int)(scale * bounds.Width), (int)(scale * bounds.Height)); var origin = RenderOrigin + PreviewOffset + new int2(RenderBounds.Size.Width / 2, RenderBounds.Size.Height / 2);
var origin = RenderOrigin + new int2((RenderBounds.Size.Width - sb.Width) / 2 - sb.X, (RenderBounds.Size.Height - sb.Height) / 2 - sb.Y);
foreach (var r in terrainRenderer.RenderUIPreview(worldRenderer, template, origin, scale)) foreach (var r in terrainRenderer.RenderUIPreview(worldRenderer, template, origin, scale))
r.PrepareRender(worldRenderer).Render(worldRenderer); r.PrepareRender(worldRenderer).Render(worldRenderer);
} }