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>
This commit is contained in:
134
OpenRA.Mods.Common/LoadScreens/BlankLoadScreen.cs
Normal file
134
OpenRA.Mods.Common/LoadScreens/BlankLoadScreen.cs
Normal file
@@ -0,0 +1,134 @@
|
||||
#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;
|
||||
using System.IO;
|
||||
using OpenRA.FileFormats;
|
||||
using OpenRA.FileSystem;
|
||||
using OpenRA.Mods.Common.FileSystem;
|
||||
using OpenRA.Mods.Common.Widgets.Logic;
|
||||
using OpenRA.Widgets;
|
||||
|
||||
namespace OpenRA.Mods.Common.LoadScreens
|
||||
{
|
||||
public class BlankLoadScreen : ILoadScreen
|
||||
{
|
||||
public LaunchArguments Launch;
|
||||
protected IReadOnlyFileSystem fileSystem;
|
||||
bool initialized;
|
||||
|
||||
public virtual void Init(Manifest manifest, IReadOnlyFileSystem fileSystem)
|
||||
{
|
||||
this.fileSystem = fileSystem;
|
||||
}
|
||||
|
||||
public virtual void Display()
|
||||
{
|
||||
if (Game.Renderer == null || initialized)
|
||||
return;
|
||||
|
||||
// Draw a black screen
|
||||
Game.Renderer.BeginUI();
|
||||
Game.Renderer.EndFrame(new NullInputHandler());
|
||||
|
||||
// PERF: draw the screen only once
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
public virtual void StartGame(Arguments args)
|
||||
{
|
||||
Launch = new LaunchArguments(args);
|
||||
Ui.ResetAll();
|
||||
Game.Settings.Save();
|
||||
|
||||
if (!string.IsNullOrEmpty(Launch.Benchmark))
|
||||
{
|
||||
Console.WriteLine($"Saving benchmark data into {Path.Combine(Platform.SupportDir, "Logs")}");
|
||||
|
||||
Game.BenchmarkMode(Launch.Benchmark);
|
||||
}
|
||||
|
||||
// Join a server directly
|
||||
var connect = Launch.GetConnectEndPoint();
|
||||
if (connect != null)
|
||||
{
|
||||
Game.LoadShellMap();
|
||||
Game.RemoteDirectConnect(connect);
|
||||
return;
|
||||
}
|
||||
|
||||
// Start a map directly
|
||||
if (!string.IsNullOrEmpty(Launch.Map))
|
||||
{
|
||||
Game.LoadMap(Launch.Map);
|
||||
return;
|
||||
}
|
||||
|
||||
// Load a replay directly
|
||||
if (!string.IsNullOrEmpty(Launch.Replay))
|
||||
{
|
||||
ReplayMetadata replayMeta = null;
|
||||
try
|
||||
{
|
||||
replayMeta = ReplayMetadata.Read(Launch.Replay);
|
||||
}
|
||||
catch { }
|
||||
|
||||
if (ReplayUtils.PromptConfirmReplayCompatibility(replayMeta, Game.ModData, Game.LoadShellMap))
|
||||
Game.JoinReplay(Launch.Replay);
|
||||
|
||||
if (replayMeta != null)
|
||||
{
|
||||
var modID = replayMeta.GameInfo.Mod;
|
||||
if (modID != null && modID != Game.ModData.Manifest.Id && Game.Mods.TryGetValue(modID, out var mod))
|
||||
Game.InitializeMod(mod, args);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Game.LoadShellMap();
|
||||
Game.Settings.Save();
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing) { }
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
public virtual bool BeforeLoad(ModData modData)
|
||||
{
|
||||
var graphicSettings = Game.Settings.Graphics;
|
||||
|
||||
// Reset the UI scaling if the user has configured a UI scale that pushes us below the minimum allowed effective resolution
|
||||
var minResolution = modData.GetOrCreate<WorldViewportSizes>().MinEffectiveResolution;
|
||||
var resolution = Game.Renderer.Resolution;
|
||||
if ((resolution.Width < minResolution.Width || resolution.Height < minResolution.Height) && Game.Settings.Graphics.UIScale > 1.0f)
|
||||
{
|
||||
graphicSettings.UIScale = 1.0f;
|
||||
Game.Renderer.SetUIScale(1.0f);
|
||||
}
|
||||
|
||||
// Saved settings may have been invalidated by a hardware change
|
||||
graphicSettings.VideoDisplay = Game.Renderer.CurrentDisplay;
|
||||
if (graphicSettings.GLProfile != GLProfile.Automatic && graphicSettings.GLProfile != Game.Renderer.GLProfile)
|
||||
graphicSettings.GLProfile = GLProfile.Automatic;
|
||||
|
||||
if (modData.FileSystemLoader is not IFileSystemExternalContent content)
|
||||
return true;
|
||||
|
||||
return !content.InstallContentIfRequired(modData);
|
||||
}
|
||||
}
|
||||
}
|
||||
73
OpenRA.Mods.Common/LoadScreens/LogoStripeLoadScreen.cs
Normal file
73
OpenRA.Mods.Common/LoadScreens/LogoStripeLoadScreen.cs
Normal file
@@ -0,0 +1,73 @@
|
||||
#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.Linq;
|
||||
using OpenRA.FileSystem;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Mods.Common.Widgets;
|
||||
using OpenRA.Primitives;
|
||||
|
||||
namespace OpenRA.Mods.Common.LoadScreens
|
||||
{
|
||||
public sealed class LogoStripeLoadScreen : SheetLoadScreen
|
||||
{
|
||||
[FluentReference]
|
||||
const string Loading = "loadscreen-loading";
|
||||
|
||||
Rectangle stripeRect;
|
||||
float2 logoPos;
|
||||
Sprite stripe, logo;
|
||||
|
||||
Sheet lastSheet;
|
||||
int lastDensity;
|
||||
Size lastResolution;
|
||||
|
||||
string[] messages = [];
|
||||
|
||||
public override void Init(Manifest manifest, IReadOnlyFileSystem fileSystem)
|
||||
{
|
||||
base.Init(manifest, fileSystem);
|
||||
|
||||
messages = FluentProvider.GetMessage(Loading).Split(',').Select(x => x.Trim()).ToArray();
|
||||
}
|
||||
|
||||
public override void DisplayInner(Renderer r, Sheet s, int density)
|
||||
{
|
||||
if (s != lastSheet || density != lastDensity)
|
||||
{
|
||||
lastSheet = s;
|
||||
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)
|
||||
{
|
||||
lastResolution = r.Resolution;
|
||||
stripeRect = new Rectangle(0, lastResolution.Height / 2 - 128, lastResolution.Width, 256);
|
||||
logoPos = new float2(lastResolution.Width / 2 - 128, lastResolution.Height / 2 - 128);
|
||||
}
|
||||
|
||||
if (stripe != null)
|
||||
WidgetUtils.FillRectWithSprite(stripeRect, stripe);
|
||||
|
||||
if (logo != null)
|
||||
r.RgbaSpriteRenderer.DrawSprite(logo, logoPos);
|
||||
|
||||
if (r.Fonts != null && messages.Length > 0)
|
||||
{
|
||||
var text = messages.Random(Game.CosmeticRandom);
|
||||
var textSize = r.Fonts["Bold"].Measure(text);
|
||||
r.Fonts["Bold"].DrawText(text, new float2(r.Resolution.Width - textSize.X - 20, r.Resolution.Height - textSize.Y - 20), Color.White);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
56
OpenRA.Mods.Common/LoadScreens/ModContentLoadScreen.cs
Normal file
56
OpenRA.Mods.Common/LoadScreens/ModContentLoadScreen.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
#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 OpenRA.Graphics;
|
||||
using OpenRA.Mods.Common.Widgets;
|
||||
using OpenRA.Primitives;
|
||||
using OpenRA.Widgets;
|
||||
|
||||
namespace OpenRA.Mods.Common.LoadScreens
|
||||
{
|
||||
public sealed class ModContentLoadScreen : SheetLoadScreen
|
||||
{
|
||||
Sprite sprite;
|
||||
Rectangle bounds;
|
||||
|
||||
Sheet lastSheet;
|
||||
int lastDensity;
|
||||
Size lastResolution;
|
||||
|
||||
public override void DisplayInner(Renderer r, Sheet s, int density)
|
||||
{
|
||||
if (s != lastSheet || density != lastDensity)
|
||||
{
|
||||
lastSheet = s;
|
||||
lastDensity = density;
|
||||
sprite = CreateSprite(s, density, new Rectangle(0, 0, 1024, 480));
|
||||
}
|
||||
|
||||
if (r.Resolution != lastResolution)
|
||||
{
|
||||
lastResolution = r.Resolution;
|
||||
bounds = new Rectangle(0, 0, lastResolution.Width, lastResolution.Height);
|
||||
}
|
||||
|
||||
WidgetUtils.FillRectWithSprite(bounds, sprite);
|
||||
}
|
||||
|
||||
public override void StartGame(Arguments args)
|
||||
{
|
||||
Ui.LoadWidget("MODCONTENT_BACKGROUND", Ui.Root, []);
|
||||
}
|
||||
|
||||
public override bool BeforeLoad(ModData modData)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
101
OpenRA.Mods.Common/LoadScreens/SheetLoadScreen.cs
Normal file
101
OpenRA.Mods.Common/LoadScreens/SheetLoadScreen.cs
Normal file
@@ -0,0 +1,101 @@
|
||||
#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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user