diff --git a/OpenRA.Game/Game.cs b/OpenRA.Game/Game.cs
index 3757169fc8..ad920d2da8 100644
--- a/OpenRA.Game/Game.cs
+++ b/OpenRA.Game/Game.cs
@@ -17,6 +17,7 @@ using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Net;
+using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using OpenRA.Chat;
@@ -252,16 +253,26 @@ namespace OpenRA
Log.AddChannel("irc", "irc.log");
Log.AddChannel("nat", "nat.log");
- var renderers = new[] { Settings.Graphics.Renderer, "Default", null };
- foreach (var r in renderers)
+ var platforms = new[] { Settings.Game.Platform, "Default", null };
+ foreach (var p in platforms)
{
- if (r == null)
- throw new InvalidOperationException("No suitable renderers were found. Check graphics.log for details.");
+ if (p == null)
+ throw new InvalidOperationException("Failed to initialize platform-integration library. Check graphics.log for details.");
- Settings.Graphics.Renderer = r;
+ Settings.Game.Platform = p;
try
{
- Renderer = new Renderer(Settings.Graphics, Settings.Server);
+ var rendererPath = Platform.ResolvePath(Path.Combine(".", "OpenRA.Platforms." + p + ".dll"));
+ var assembly = Assembly.LoadFile(rendererPath);
+
+ var platformType = assembly.GetTypes().SingleOrDefault(t => typeof(IPlatform).IsAssignableFrom(t));
+ if (platformType == null)
+ throw new InvalidOperationException("Platform dll must include exactly one IPlatform implementation.");
+
+ var platform = (IPlatform)platformType.GetConstructor(Type.EmptyTypes).Invoke(null);
+ Renderer = new Renderer(platform, Settings.Graphics);
+ Sound = new Sound(platform, Settings.Sound);
+
break;
}
catch (Exception e)
@@ -281,8 +292,6 @@ namespace OpenRA
Game.Settings.Server.AllowPortForward = true;
}
- Sound = new Sound(Settings.Sound.Engine);
-
GlobalChat = new GlobalChat();
Console.WriteLine("Available mods:");
diff --git a/OpenRA.Game/Graphics/IGraphicsDevice.cs b/OpenRA.Game/Graphics/PlatformInterfaces.cs
similarity index 87%
rename from OpenRA.Game/Graphics/IGraphicsDevice.cs
rename to OpenRA.Game/Graphics/PlatformInterfaces.cs
index bd788c2338..06addf16b8 100644
--- a/OpenRA.Game/Graphics/IGraphicsDevice.cs
+++ b/OpenRA.Game/Graphics/PlatformInterfaces.cs
@@ -15,23 +15,10 @@ using OpenRA.Graphics;
namespace OpenRA
{
- [AttributeUsage(AttributeTargets.Assembly)]
- public sealed class PlatformAttribute : Attribute
- {
- public readonly Type Type;
-
- public PlatformAttribute(Type graphicsDeviceType)
- {
- if (!typeof(IDeviceFactory).IsAssignableFrom(graphicsDeviceType))
- throw new InvalidOperationException("Incorrect type in RendererAttribute");
- Type = graphicsDeviceType;
- }
- }
-
- public interface IDeviceFactory
+ public interface IPlatform
{
IGraphicsDevice CreateGraphics(Size size, WindowMode windowMode);
- ISoundEngine CreateSound();
+ ISoundEngine CreateSound(string device);
}
public interface IHardwareCursor : IDisposable { }
diff --git a/OpenRA.Game/OpenRA.Game.csproj b/OpenRA.Game/OpenRA.Game.csproj
index 7fee351f18..cef048ee0f 100644
--- a/OpenRA.Game/OpenRA.Game.csproj
+++ b/OpenRA.Game/OpenRA.Game.csproj
@@ -214,7 +214,7 @@
-
+
diff --git a/OpenRA.Game/Renderer.cs b/OpenRA.Game/Renderer.cs
index 5aab34bdc0..1adacbfd5b 100644
--- a/OpenRA.Game/Renderer.cs
+++ b/OpenRA.Game/Renderer.cs
@@ -12,9 +12,7 @@
using System;
using System.Collections.Generic;
using System.Drawing;
-using System.IO;
using System.Linq;
-using System.Reflection;
using OpenRA.Graphics;
using OpenRA.Support;
@@ -49,14 +47,12 @@ namespace OpenRA
ITexture currentPaletteTexture;
IBatchRenderer currentBatchRenderer;
- public Renderer(GraphicSettings graphicSettings, ServerSettings serverSettings)
+ public Renderer(IPlatform platform, GraphicSettings graphicSettings)
{
var resolution = GetResolution(graphicSettings);
- var rendererName = graphicSettings.Renderer;
- var rendererPath = Platform.ResolvePath(Path.Combine(".", "OpenRA.Platforms." + rendererName + ".dll"));
+ Device = platform.CreateGraphics(new Size(resolution.Width, resolution.Height), graphicSettings.Mode);
- Device = CreateDevice(Assembly.LoadFile(rendererPath), resolution.Width, resolution.Height, graphicSettings.Mode);
TempBufferSize = graphicSettings.BatchSize;
SheetSize = graphicSettings.SheetSize;
@@ -79,17 +75,6 @@ namespace OpenRA
return new Size(size.X, size.Y);
}
- static IGraphicsDevice CreateDevice(Assembly platformDll, int width, int height, WindowMode window)
- {
- foreach (PlatformAttribute r in platformDll.GetCustomAttributes(typeof(PlatformAttribute), false))
- {
- var factory = (IDeviceFactory)r.Type.GetConstructor(Type.EmptyTypes).Invoke(null);
- return factory.CreateGraphics(new Size(width, height), window);
- }
-
- throw new InvalidOperationException("Renderer DLL is missing RendererAttribute to tell us what type to use!");
- }
-
public void InitializeFonts(ModData modData)
{
if (Fonts != null)
diff --git a/OpenRA.Game/Settings.cs b/OpenRA.Game/Settings.cs
index 612323c00e..4fdd3aee30 100644
--- a/OpenRA.Game/Settings.cs
+++ b/OpenRA.Game/Settings.cs
@@ -102,8 +102,6 @@ namespace OpenRA
public class GraphicSettings
{
- public string Renderer = "Default";
-
[Desc("This can be set to Windowed, Fullscreen or PseudoFullscreen.")]
public WindowMode Mode = WindowMode.PseudoFullscreen;
@@ -142,7 +140,6 @@ namespace OpenRA
public bool Shuffle = false;
public bool Repeat = false;
- public string Engine = "Default";
public string Device = null;
public bool CashTicks = true;
@@ -162,6 +159,8 @@ namespace OpenRA
public string Mod = "modchooser";
public string PreviousMod = "ra";
+ public string Platform = "Default";
+
public bool ShowShellmap = true;
public bool ViewportEdgeScroll = true;
diff --git a/OpenRA.Game/Sound/Sound.cs b/OpenRA.Game/Sound/Sound.cs
index 4abfcee29b..4c2ce54884 100644
--- a/OpenRA.Game/Sound/Sound.cs
+++ b/OpenRA.Game/Sound/Sound.cs
@@ -11,8 +11,6 @@
using System;
using System.IO;
-using System.Linq;
-using System.Reflection;
using OpenRA.FileSystem;
using OpenRA.GameRules;
using OpenRA.Primitives;
@@ -42,21 +40,12 @@ namespace OpenRA
ISound video;
MusicInfo currentMusic;
- public Sound(string engineName)
+ public Sound(IPlatform platform, SoundSettings soundSettings)
{
- var enginePath = Platform.ResolvePath(".", "OpenRA.Platforms." + engineName + ".dll");
- soundEngine = CreateDevice(Assembly.LoadFile(enginePath));
- }
+ soundEngine = platform.CreateSound(soundSettings.Device);
- static ISoundEngine CreateDevice(Assembly platformDll)
- {
- foreach (PlatformAttribute r in platformDll.GetCustomAttributes(typeof(PlatformAttribute), false))
- {
- var factory = (IDeviceFactory)r.Type.GetConstructor(Type.EmptyTypes).Invoke(null);
- return factory.CreateSound();
- }
-
- throw new InvalidOperationException("Platform DLL is missing PlatformAttribute to tell us what type to use!");
+ if (soundSettings.Mute)
+ MuteAudio();
}
ISoundSource LoadSound(ISoundLoader[] loaders, IReadOnlyFileSystem fileSystem, string filename)
@@ -92,12 +81,7 @@ namespace OpenRA
public SoundDevice[] AvailableDevices()
{
- var defaultDevices = new[]
- {
- new SoundDevice("Null", null, "Output Disabled")
- };
-
- return defaultDevices.Concat(soundEngine.AvailableDevices()).ToArray();
+ return soundEngine.AvailableDevices();
}
public void SetListenerPosition(WPos position)
@@ -242,12 +226,6 @@ namespace OpenRA
soundEngine.PauseSound(music, true);
}
- public float GlobalVolume
- {
- get { return soundEngine.Volume; }
- set { soundEngine.Volume = value; }
- }
-
float soundVolumeModifier = 1.0f;
public float SoundVolumeModifier
{
diff --git a/OpenRA.Game/Sound/SoundDevice.cs b/OpenRA.Game/Sound/SoundDevice.cs
index ed8a98521f..6c16aa4c47 100644
--- a/OpenRA.Game/Sound/SoundDevice.cs
+++ b/OpenRA.Game/Sound/SoundDevice.cs
@@ -29,13 +29,11 @@ namespace OpenRA
public class SoundDevice
{
- public readonly string Engine;
public readonly string Device;
public readonly string Label;
- public SoundDevice(string engine, string device, string label)
+ public SoundDevice(string device, string label)
{
- Engine = engine;
Device = device;
Label = label;
}
diff --git a/OpenRA.Mods.Common/Widgets/Logic/SettingsLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/SettingsLogic.cs
index a7f5c120a2..ce2fc4ca65 100644
--- a/OpenRA.Mods.Common/Widgets/Logic/SettingsLogic.cs
+++ b/OpenRA.Mods.Common/Widgets/Logic/SettingsLogic.cs
@@ -23,9 +23,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
enum PanelType { Display, Audio, Input, Advanced }
static readonly string OriginalSoundDevice;
- static readonly string OriginalSoundEngine;
static readonly WindowMode OriginalGraphicsMode;
- static readonly string OriginalGraphicsRenderer;
static readonly int2 OriginalGraphicsWindowedSize;
static readonly int2 OriginalGraphicsFullscreenSize;
@@ -43,9 +41,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
var original = Game.Settings;
OriginalSoundDevice = original.Sound.Device;
- OriginalSoundEngine = original.Sound.Engine;
OriginalGraphicsMode = original.Graphics.Mode;
- OriginalGraphicsRenderer = original.Graphics.Renderer;
OriginalGraphicsWindowedSize = original.Graphics.WindowedSize;
OriginalGraphicsFullscreenSize = original.Graphics.FullscreenSize;
}
@@ -72,9 +68,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
Action closeAndExit = () => { Ui.CloseWindow(); onExit(); };
if (OriginalSoundDevice != current.Sound.Device ||
- OriginalSoundEngine != current.Sound.Engine ||
OriginalGraphicsMode != current.Graphics.Mode ||
- OriginalGraphicsRenderer != current.Graphics.Renderer ||
OriginalGraphicsWindowedSize != current.Graphics.WindowedSize ||
OriginalGraphicsFullscreenSize != current.Graphics.FullscreenSize)
ConfirmationDialogs.ButtonPrompt(
@@ -336,7 +330,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
}
var devices = Game.Sound.AvailableDevices();
- soundDevice = devices.FirstOrDefault(d => d.Engine == ss.Engine && d.Device == ss.Device) ?? devices.First();
+ soundDevice = devices.FirstOrDefault(d => d.Device == ss.Device) ?? devices.First();
var audioDeviceDropdown = panel.Get("AUDIO_DEVICE");
audioDeviceDropdown.OnMouseDown = _ => ShowAudioDeviceDropdown(audioDeviceDropdown, devices);
@@ -349,7 +343,6 @@ namespace OpenRA.Mods.Common.Widgets.Logic
return () =>
{
ss.Device = soundDevice.Device;
- ss.Engine = soundDevice.Engine;
};
}
@@ -365,7 +358,6 @@ namespace OpenRA.Mods.Common.Widgets.Logic
ss.CashTicks = dss.CashTicks;
ss.Mute = dss.Mute;
ss.Device = dss.Device;
- ss.Engine = dss.Engine;
panel.Get("SOUND_VOLUME").Value = ss.SoundVolume;
Game.Sound.SoundVolume = ss.SoundVolume;
diff --git a/OpenRA.Platforms.Default/DefaultPlatform.cs b/OpenRA.Platforms.Default/DefaultPlatform.cs
index 8b86f7c360..90eaa3e718 100644
--- a/OpenRA.Platforms.Default/DefaultPlatform.cs
+++ b/OpenRA.Platforms.Default/DefaultPlatform.cs
@@ -12,20 +12,18 @@
using System.Drawing;
using OpenRA;
-[assembly: Platform(typeof(OpenRA.Platforms.Default.DeviceFactory))]
-
namespace OpenRA.Platforms.Default
{
- public class DeviceFactory : IDeviceFactory
+ public class DefaultPlatform : IPlatform
{
public IGraphicsDevice CreateGraphics(Size size, WindowMode windowMode)
{
return new Sdl2GraphicsDevice(size, windowMode);
}
- public ISoundEngine CreateSound()
+ public ISoundEngine CreateSound(string device)
{
- return new OpenAlSoundEngine();
+ return new OpenAlSoundEngine(device);
}
}
}
diff --git a/OpenRA.Platforms.Default/OpenAlSoundEngine.cs b/OpenRA.Platforms.Default/OpenAlSoundEngine.cs
index 55b02f4c61..b39f79da15 100644
--- a/OpenRA.Platforms.Default/OpenAlSoundEngine.cs
+++ b/OpenRA.Platforms.Default/OpenAlSoundEngine.cs
@@ -24,11 +24,10 @@ namespace OpenRA.Platforms.Default
{
var defaultDevices = new[]
{
- new SoundDevice("Default", null, "Default Output"),
- new SoundDevice("Null", null, "Output Disabled")
+ new SoundDevice(null, "Default Output"),
};
- var physicalDevices = PhysicalDevices().Select(d => new SoundDevice("Default", d, d));
+ var physicalDevices = PhysicalDevices().Select(d => new SoundDevice(d, d));
return defaultDevices.Concat(physicalDevices).ToArray();
}
@@ -86,16 +85,14 @@ namespace OpenRA.Platforms.Default
return new string[] { };
}
- public OpenAlSoundEngine()
+ public OpenAlSoundEngine(string deviceName)
{
- Console.WriteLine("Using OpenAL sound engine");
-
- if (Game.Settings.Sound.Device != null)
- Console.WriteLine("Using device `{0}`", Game.Settings.Sound.Device);
+ if (deviceName != null)
+ Console.WriteLine("Using sound device `{0}`", deviceName);
else
- Console.WriteLine("Using default device");
+ Console.WriteLine("Using default sound device");
- device = ALC10.alcOpenDevice(Game.Settings.Sound.Device);
+ device = ALC10.alcOpenDevice(deviceName);
if (device == IntPtr.Zero)
{
Console.WriteLine("Failed to open device. Falling back to default");
@@ -210,9 +207,6 @@ namespace OpenRA.Platforms.Default
if (!TryGetSourceFromPool(out source))
return null;
- if (Game.Settings.Sound.Mute)
- Game.Sound.MuteAudio();
-
var slot = sourcePool[source];
slot.Pos = pos;
slot.FrameStarted = currFrame;