Files
OpenRA/OpenRA.Mods.Common/LoadScreens/SheetLoadScreen.cs
let5sne.win10 9cf6ebb986
Some checks failed
Continuous Integration / Linux (.NET 8.0) (push) Has been cancelled
Continuous Integration / Windows (.NET 8.0) (push) Has been cancelled
Initial commit: OpenRA game engine
Fork from OpenRA/OpenRA with one-click launch script (start-ra.cmd)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 21:46:54 +08:00

102 lines
2.6 KiB
C#

#region Copyright & License Information
/*
* Copyright (c) The OpenRA Developers and Contributors
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version. For more
* information, see COPYING.
*/
#endregion
using System.Collections.Generic;
using System.Diagnostics;
using OpenRA.FileSystem;
using OpenRA.Graphics;
using OpenRA.Primitives;
namespace OpenRA.Mods.Common.LoadScreens
{
public abstract class SheetLoadScreen : BlankLoadScreen
{
Stopwatch lastUpdate;
protected Dictionary<string, string> Info { get; private set; }
float dpiScale = 1;
Sheet sheet;
int density;
public override void Init(Manifest manifest, IReadOnlyFileSystem fileSystem)
{
base.Init(manifest, fileSystem);
Info = manifest.LoadScreen.ToDictionary(my => my.Value);
}
public abstract void DisplayInner(Renderer r, Sheet s, int density);
public override void Display()
{
// Limit load screens to at most 5 FPS
if (Game.Renderer == null || (lastUpdate != null && lastUpdate.Elapsed.TotalSeconds < 0.2))
return;
// Start the timer on the first render
lastUpdate ??= Stopwatch.StartNew();
// Check for window DPI changes
// We can't trust notifications to be working during initialization, so must do this manually
var scale = Game.Renderer.WindowScale;
if (dpiScale != scale)
{
dpiScale = scale;
// Force images to be reloaded on the next display
sheet?.Dispose();
sheet = null;
}
if (sheet == null && Info.TryGetValue("Image", out var image))
{
density = 1;
if (dpiScale > 2 && Info.TryGetValue("Image3x", out var image3))
{
image = image3;
density = 3;
}
else if (dpiScale > 1 && Info.TryGetValue("Image2x", out var image2))
{
image = image2;
density = 2;
}
using (var stream = fileSystem.Open(Platform.ResolvePath(image)))
{
sheet = new Sheet(SheetType.BGRA, stream);
sheet.GetTexture().ScaleFilter = TextureScaleFilter.Linear;
}
}
Game.Renderer.BeginUI();
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?.Dispose();
base.Dispose(disposing);
}
}
}