Skip to content

Commit

Permalink
Allow mods to customize application icon and title.
Browse files Browse the repository at this point in the history
  • Loading branch information
Mailaender committed Jul 16, 2021
1 parent 902006b commit 17ff2cf
Show file tree
Hide file tree
Showing 10 changed files with 110 additions and 3 deletions.
5 changes: 4 additions & 1 deletion OpenRA.Game/Game.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public static class Game
public static Settings Settings;
public static CursorManager Cursor;
public static bool HideCursor;
public static IconManager Icon;
static WorldRenderer worldRenderer;
static string modLaunchWrapper;

Expand Down Expand Up @@ -463,9 +464,11 @@ public static void InitializeMod(string mod, Arguments args)
Renderer.InitializeDepthBuffer(grid);

Cursor?.Dispose();

Cursor = new CursorManager(ModData.CursorProvider);

Icon?.Dispose();
Icon = new IconManager(ModData);

PerfHistory.Items["render"].HasNormalTick = false;
PerfHistory.Items["batches"].HasNormalTick = false;
PerfHistory.Items["render_world"].HasNormalTick = false;
Expand Down
63 changes: 63 additions & 0 deletions OpenRA.Game/Graphics/IconManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* 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 OpenRA.FileFormats;

namespace OpenRA.Graphics
{
public sealed class IconManager
{
readonly Sprite icon;
readonly SheetBuilder sheetBuilder;

public IconManager(ModData modData)
{
var metadata = modData.Manifest.Metadata;

if (!string.IsNullOrEmpty(metadata.ApplicationTitle))
Game.Renderer.Window.SetApplicationTitle(metadata.ApplicationTitle);

if (string.IsNullOrEmpty(metadata.ApplicationIcon))
return;

sheetBuilder = new SheetBuilder(SheetType.BGRA);
var fileSystem = modData.DefaultFileSystem;
using (var stream = fileSystem.Open(metadata.ApplicationIcon))
icon = sheetBuilder.Add(new Png(stream));

var size = icon.Bounds.Size;
var srcStride = icon.Sheet.Size.Width;
var srcData = icon.Sheet.GetData();
var rgbaData = new byte[4 * size.Width * size.Height];

for (var j = 0; j < size.Height; j++)
{
for (var i = 0; i < size.Width; i++)
{
var src = 4 * (j * srcStride + i);
var dest = 4 * (j * size.Width + i);
Array.Copy(srcData, src, rgbaData, dest, 4);
}
}

Game.Renderer.Window.SetApplicationIcon(size, rgbaData);

foreach (var s in sheetBuilder.AllSheets)
s.ReleaseBuffer();
}

public void Dispose()
{
sheetBuilder.Dispose();
}
}
}
2 changes: 2 additions & 0 deletions OpenRA.Game/Graphics/PlatformInterfaces.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ public interface IPlatformWindow : IDisposable

IHardwareCursor CreateHardwareCursor(string name, Size size, byte[] data, int2 hotspot, bool pixelDouble);
void SetHardwareCursor(IHardwareCursor cursor);
void SetApplicationIcon(Size size, byte[] data);
void SetApplicationTitle(string title);
void SetRelativeMouseMode(bool mode);
void SetScaleModifier(float scale);

Expand Down
2 changes: 2 additions & 0 deletions OpenRA.Game/Manifest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ public class ModMetadata
public string Version;
public string Website;
public string WebIcon32;
public string ApplicationTitle;
public string ApplicationIcon;
public bool Hidden;
}

Expand Down
2 changes: 1 addition & 1 deletion OpenRA.Mods.Common/Widgets/Logic/ConnectionLogic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ public ConnectionFailedLogic(Widget widget, OrderManager orderManager, NetworkCo
public class ConnectionSwitchModLogic : ChromeLogic
{
[ObjectCreator.UseCtor]
public ConnectionSwitchModLogic(Widget widget, OrderManager orderManager, string password, NetworkConnection connection, Action onAbort, Action<string> onRetry)
public ConnectionSwitchModLogic(Widget widget, OrderManager orderManager, NetworkConnection connection, Action onAbort, Action<string> onRetry)
{
var panel = widget;
var abortButton = panel.Get<ButtonWidget>("ABORT_BUTTON");
Expand Down
31 changes: 30 additions & 1 deletion OpenRA.Platforms.Default/Sdl2PlatformWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using OpenRA.Primitives;
Expand All @@ -31,7 +32,7 @@ sealed class Sdl2PlatformWindow : ThreadAffine, IPlatformWindow
bool disposed;

readonly object syncObject = new object();
Size windowSize;
readonly Size windowSize;
Size surfaceSize;
float windowScale = 1f;
int2? lockedMousePosition;
Expand Down Expand Up @@ -365,6 +366,34 @@ public void SetHardwareCursor(IHardwareCursor cursor)
SDL.SDL_ShowCursor((int)SDL.SDL_bool.SDL_FALSE);
}

public void SetApplicationTitle(string title)
{
VerifyThreadAffinity();
SDL.SDL_SetWindowTitle(window, title);
}

public void SetApplicationIcon(Size size, byte[] data)
{
VerifyThreadAffinity();
var surfacePointer = IntPtr.Zero;
try
{
surfacePointer = SDL.SDL_CreateRGBSurface(0, size.Width, size.Height, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
if (surfacePointer == IntPtr.Zero)
throw new InvalidDataException($"Failed to set icon: {SDL.SDL_GetError()}");

var iconSurface = (SDL.SDL_Surface)Marshal.PtrToStructure(surfacePointer, typeof(SDL.SDL_Surface));
Marshal.Copy(data, 0, iconSurface.pixels, data.Length);

SDL.SDL_SetWindowIcon(window, surfacePointer);
}
catch
{
if (surfacePointer != IntPtr.Zero)
SDL.SDL_FreeSurface(surfacePointer);
}
}

public void SetRelativeMouseMode(bool mode)
{
if (mode)
Expand Down
2 changes: 2 additions & 0 deletions mods/cnc/mod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ Metadata:
Version: {DEV_VERSION}
Website: https://www.openra.net
WebIcon32: https://www.openra.net/images/icons/cnc_32x32.png
ApplicationIcon: icon.png
ApplicationTitle: Tiberian Dawn - OpenRA

PackageFormats: Mix

Expand Down
2 changes: 2 additions & 0 deletions mods/d2k/mod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ Metadata:
Version: {DEV_VERSION}
Website: https://www.openra.net
WebIcon32: https://www.openra.net/images/icons/d2k_32x32.png
ApplicationIcon: icon.png
ApplicationTitle: Dune 2000 - OpenRA

PackageFormats: D2kSoundResources

Expand Down
2 changes: 2 additions & 0 deletions mods/ra/mod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ Metadata:
Version: {DEV_VERSION}
Website: https://www.openra.net
WebIcon32: https://www.openra.net/images/icons/ra_32x32.png
ApplicationIcon: icon.png
ApplicationTitle: Red Alert - OpenRA

PackageFormats: Mix

Expand Down
2 changes: 2 additions & 0 deletions mods/ts/mod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ Metadata:
Version: {DEV_VERSION}
Website: https://www.openra.net
WebIcon32: https://www.openra.net/images/icons/ts_32x32.png
ApplicationIcon: icon.png
ApplicationTitle: Tiberian Sun - OpenRA

PackageFormats: Mix

Expand Down

0 comments on commit 17ff2cf

Please sign in to comment.