Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix editor can write invalid config options (e.g. D3D9 gfx driver for Linux) #2260

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Editor/AGS.Editor.Tests/AGS.Editor.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,11 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Editor\AutoComplete\AutoCompleteTests.cs" />
<Compile Include="Editor\BuildTargets\BuildTargetBaseTests.cs" />
<Compile Include="Editor\Panes\FreePanControlTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ScriptCompiler\PreprocessorTests.cs" />
<Compile Include="Types\RuntimeSetupTests.cs" />
<Compile Include="Types\SpriteTests.cs" />
</ItemGroup>
<ItemGroup>
Expand Down
101 changes: 101 additions & 0 deletions Editor/AGS.Editor.Tests/Editor/BuildTargets/BuildTargetBaseTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AGS.Editor;
using AGS.Types;
using NUnit.Framework;

namespace AGS.Editor.BuildTargets
{
class BuildTargetBaseTests
{
[Test]
public void RuntimeSetupClone_ShouldMatchOriginal()
{
Settings gameSettings = new Settings();
RuntimeSetup originalSetup = new RuntimeSetup(gameSettings)
{
GraphicsDriver = GraphicsDriver.OpenGL,
Windowed = true,
FullscreenDesktop = true,
FullscreenGameScaling = GameScaling.MaxInteger,
GameScaling = GameScaling.Integer,
GameScalingMultiplier = 2,
GraphicsFilter = "linear",
VSync = true,
AAScaledSprites = true,
RenderAtScreenResolution = true,
Rotation = ScreenRotationMode.Landscape,
DigitalSound = RuntimeAudioDriver.Default,
UseVoicePack = false,
Translation = "Portuguese",
AutoLockMouse = true,
MouseSpeed = 1.5f,
TouchToMouseEmulation = TouchToMouseEmulationType.TwoFingers,
SpriteCacheSize = 256,
TextureCacheSize = 256,
SoundCacheSize = 64,
UseCustomSavePath = true,
CustomSavePath = "CustomSaves",
UseCustomAppDataPath = true,
CustomAppDataPath = "CustomAppData",
TitleText = "Custom Setup",
ShowFPS = true
};

RuntimeSetup cloneSetup = TestBuildTarget.PublicCloneRuntimeSetup(originalSetup, gameSettings);

Assert.That(cloneSetup, Is.Not.SameAs(originalSetup), "Clone should be a different instance");
Assert.That(cloneSetup.GraphicsDriver, Is.EqualTo(originalSetup.GraphicsDriver), "Clone should match the original (GraphicsDriver)");
Assert.That(cloneSetup.Windowed, Is.EqualTo(originalSetup.Windowed), "Clone should match the original (Windowed)");
Assert.That(cloneSetup.FullscreenDesktop, Is.EqualTo(originalSetup.FullscreenDesktop), "Clone should match the original (FullscreenDesktop)");
Assert.That(cloneSetup.FullscreenGameScaling, Is.EqualTo(originalSetup.FullscreenGameScaling), "Clone should match the original (FullscreenGameScaling)");
Assert.That(cloneSetup.GameScaling, Is.EqualTo(originalSetup.GameScaling), "Clone should match the original (GameScaling)");
Assert.That(cloneSetup.GameScalingMultiplier, Is.EqualTo(originalSetup.GameScalingMultiplier), "Clone should match the original (GameScalingMultiplier)");
Assert.That(cloneSetup.GraphicsFilter, Is.EqualTo(originalSetup.GraphicsFilter), "Clone should match the original(GraphicsFilter)");
Assert.That(cloneSetup.VSync, Is.EqualTo(originalSetup.VSync), "Clone should match the original (VSync)");
Assert.That(cloneSetup.AAScaledSprites, Is.EqualTo(originalSetup.AAScaledSprites), "Clone should match the original (AAScaledSprites)");
Assert.That(cloneSetup.RenderAtScreenResolution, Is.EqualTo(originalSetup.RenderAtScreenResolution), "Clone should match the original (RenderAtScreenResolution)");
Assert.That(cloneSetup.Rotation, Is.EqualTo(originalSetup.Rotation), "Clone should match the original (Rotation)");
Assert.That(cloneSetup.DigitalSound, Is.EqualTo(originalSetup.DigitalSound), "Clone should match the original (DigitalSound)");
Assert.That(cloneSetup.UseVoicePack, Is.EqualTo(originalSetup.UseVoicePack), "Clone should match the original (UseVoicePack)");
Assert.That(cloneSetup.Translation, Is.EqualTo(originalSetup.Translation), "Clone should match the original (Translation)");
Assert.That(cloneSetup.AutoLockMouse, Is.EqualTo(originalSetup.AutoLockMouse), "Clone should match the original (AutoLockMouse)");
Assert.That(cloneSetup.MouseSpeed, Is.EqualTo(originalSetup.MouseSpeed), "Clone should match the original (MouseSpeed)");
Assert.That(cloneSetup.TouchToMouseEmulation, Is.EqualTo(originalSetup.TouchToMouseEmulation), "Clone should match the original (TouchToMouseEmulation)");
Assert.That(cloneSetup.SpriteCacheSize, Is.EqualTo(originalSetup.SpriteCacheSize), "Clone should match the original (SpriteCacheSize)");
Assert.That(cloneSetup.TextureCacheSize, Is.EqualTo(originalSetup.TextureCacheSize), "Clone should match the original (TextureCacheSize)");
Assert.That(cloneSetup.SoundCacheSize, Is.EqualTo(originalSetup.SoundCacheSize), "Clone should match the original (SoundCacheSize)");
Assert.That(cloneSetup.UseCustomSavePath, Is.EqualTo(originalSetup.UseCustomSavePath), "Clone should match the original (UseCustomSavePath)");
Assert.That(cloneSetup.CustomSavePath, Is.EqualTo(originalSetup.CustomSavePath), "Clone should match the original (CustomSavePath)");
Assert.That(cloneSetup.UseCustomAppDataPath, Is.EqualTo(originalSetup.UseCustomAppDataPath), "Clone should match the original");
Assert.That(cloneSetup.CustomAppDataPath, Is.EqualTo(originalSetup.CustomAppDataPath), "Clone should match the original (CustomAppDataPath)");
Assert.That(cloneSetup.TitleText, Is.EqualTo(originalSetup.TitleText), "Clone should match the original (TitleText)");
Assert.That(cloneSetup.ShowFPS, Is.EqualTo(originalSetup.ShowFPS), "Clone should match the original (ShowFPS)");
}

private class TestBuildTarget : BuildTargetBase
{
public static RuntimeSetup PublicCloneRuntimeSetup(RuntimeSetup setup, Settings settings)
{
return BuildTargetBase.CloneRuntimeSetup(setup, settings);
}

public override IDictionary<string, string> GetRequiredLibraryPaths()
{
throw new NotImplementedException();
}

public override string[] GetPlatformStandardSubfolders()
{
throw new NotImplementedException();
}

public override string Name { get { return "TestBuildTarget"; } }

public override string OutputDirectory { get { return "TestOutputDirectory"; } }
}
}
}
67 changes: 67 additions & 0 deletions Editor/AGS.Editor.Tests/Types/RuntimeSetupTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NUnit.Framework;

namespace AGS.Types
{
[TestFixture]
public class RuntimeSetupTests
{
private Settings _dummySettings;

[SetUp]
public void SetUp()
{
_dummySettings = new Settings();
}

[Test]
public void Constructor_InitializesProperties()
{
var runtimeSetup = new RuntimeSetup(_dummySettings);

Assert.IsNotNull(runtimeSetup);
Assert.AreEqual(GraphicsDriver.D3D9, runtimeSetup.GraphicsDriver);
Assert.IsFalse(runtimeSetup.Windowed);
Assert.AreEqual(GameScaling.ProportionalStretch, runtimeSetup.FullscreenGameScaling);
}

[Test]
public void SetDefaults_SetsDefaultValues()
{
var runtimeSetup = new RuntimeSetup(_dummySettings);

runtimeSetup.SetDefaults();

Assert.AreEqual(GraphicsDriver.D3D9, runtimeSetup.GraphicsDriver);
Assert.IsFalse(runtimeSetup.Windowed);
Assert.AreEqual(GameScaling.ProportionalStretch, runtimeSetup.FullscreenGameScaling);
}

[Test]
public void GraphicsDriver_Setter_UpdatesGraphicsFilter()
{
var runtimeSetup = new RuntimeSetup(_dummySettings);

runtimeSetup.GraphicsDriver = GraphicsDriver.OpenGL;

Assert.IsNotNull(runtimeSetup.GraphicsFilter);
Assert.AreEqual(GraphicsDriver.OpenGL, runtimeSetup.GraphicsDriver);
}

[Test]
public void UseCustomSavePath_Setter_UpdatesCustomSavePath()
{
var runtimeSetup = new RuntimeSetup(_dummySettings);

runtimeSetup.UseCustomSavePath = true;
runtimeSetup.CustomSavePath = "CustomPath";

Assert.IsTrue(runtimeSetup.UseCustomSavePath);
Assert.AreEqual("CustomPath", runtimeSetup.CustomSavePath);
}
}
}
55 changes: 27 additions & 28 deletions Editor/AGS.Editor/AGSEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1440,7 +1440,7 @@ private static string MakeGameScalingConfig(GameScaling scaling)
/// <summary>
/// Writes the config file using particular game Settings and DefaultSetup options.
/// </summary>
public void WriteConfigFile(string configFilePath, bool resetFile = true)
public void WriteConfigFile(string configFilePath, RuntimeSetup setup, bool resetFile = true)
{
if (resetFile)
Utilities.TryDeleteFile(configFilePath);
Expand All @@ -1453,56 +1453,55 @@ public void WriteConfigFile(string configFilePath, bool resetFile = true)
sections.Add("sound", new Dictionary<string, string>());
sections.Add("touch", new Dictionary<string, string>());

sections["graphics"]["driver"] = GetGfxDriverConfigID(_game.DefaultSetup.GraphicsDriver);
sections["graphics"]["windowed"] = _game.DefaultSetup.Windowed ? "1" : "0";
sections["graphics"]["fullscreen"] =
_game.DefaultSetup.FullscreenDesktop ? "full_window" : "desktop";
if (_game.DefaultSetup.GameScaling == GameScaling.Integer)
sections["graphics"]["driver"] = GetGfxDriverConfigID(setup.GraphicsDriver);
sections["graphics"]["windowed"] = setup.Windowed ? "1" : "0";
sections["graphics"]["fullscreen"] = setup.FullscreenDesktop ? "full_window" : "desktop";
if (setup.GameScaling == GameScaling.Integer)
sections["graphics"]["window"] =
String.Format("x{0}", _game.DefaultSetup.GameScalingMultiplier);
String.Format("x{0}", setup.GameScalingMultiplier);
else
sections["graphics"]["window"] = "desktop";

sections["graphics"]["game_scale_fs"] = MakeGameScalingConfig(_game.DefaultSetup.FullscreenGameScaling);
sections["graphics"]["game_scale_win"] = MakeGameScalingConfig(_game.DefaultSetup.GameScaling);
sections["graphics"]["game_scale_fs"] = MakeGameScalingConfig(setup.FullscreenGameScaling);
sections["graphics"]["game_scale_win"] = MakeGameScalingConfig(setup.GameScaling);

sections["graphics"]["filter"] = _game.DefaultSetup.GraphicsFilter;
sections["graphics"]["vsync"] = _game.DefaultSetup.VSync ? "1" : "0";
sections["graphics"]["antialias"] = _game.DefaultSetup.AAScaledSprites ? "1" : "0";
sections["graphics"]["filter"] = setup.GraphicsFilter;
sections["graphics"]["vsync"] = setup.VSync ? "1" : "0";
sections["graphics"]["antialias"] = setup.AAScaledSprites ? "1" : "0";
bool render_at_screenres = _game.Settings.RenderAtScreenResolution == RenderAtScreenResolution.UserDefined ?
_game.DefaultSetup.RenderAtScreenResolution : _game.Settings.RenderAtScreenResolution == RenderAtScreenResolution.True;
setup.RenderAtScreenResolution : _game.Settings.RenderAtScreenResolution == RenderAtScreenResolution.True;
sections["graphics"]["render_at_screenres"] = render_at_screenres ? "1" : "0";
string[] rotation_str = new string[] { "unlocked", "portrait", "landscape" };
sections["graphics"]["rotation"] = rotation_str[(int)_game.DefaultSetup.Rotation];
sections["graphics"]["rotation"] = rotation_str[(int)setup.Rotation];

bool audio_enabled = _game.DefaultSetup.DigitalSound != RuntimeAudioDriver.Disabled;
bool audio_enabled = setup.DigitalSound != RuntimeAudioDriver.Disabled;
sections["sound"]["enabled"] = audio_enabled ? "1" : "0";
sections["sound"]["driver"] = ""; // always default
sections["sound"]["usespeech"] = _game.DefaultSetup.UseVoicePack ? "1" : "0";
sections["sound"]["usespeech"] = setup.UseVoicePack ? "1" : "0";

sections["language"]["translation"] = _game.DefaultSetup.Translation;
sections["mouse"]["auto_lock"] = _game.DefaultSetup.AutoLockMouse ? "1" : "0";
sections["mouse"]["speed"] = _game.DefaultSetup.MouseSpeed.ToString(CultureInfo.InvariantCulture);
sections["language"]["translation"] = setup.Translation;
sections["mouse"]["auto_lock"] = setup.AutoLockMouse ? "1" : "0";
sections["mouse"]["speed"] = setup.MouseSpeed.ToString(CultureInfo.InvariantCulture);

// Touch input
string[] emulate_mouse_str = new string[] { "off", "one_finger", "two_fingers" };
sections["touch"]["emul_mouse_mode"] =
emulate_mouse_str[(int)_game.DefaultSetup.TouchToMouseEmulation];
emulate_mouse_str[(int)setup.TouchToMouseEmulation];
sections["touch"]["emul_mouse_relative"] =
((int)_game.DefaultSetup.TouchToMouseMotionMode).ToString();
((int)setup.TouchToMouseMotionMode).ToString();

// Note: the cache sizes are written in KB (while we have it in MB on the editor pane)
sections["graphics"]["sprite_cache_size"] = (_game.DefaultSetup.SpriteCacheSize * 1024).ToString();
sections["graphics"]["texture_cache_size"] = (_game.DefaultSetup.TextureCacheSize * 1024).ToString();
sections["sound"]["cache_size"] = (_game.DefaultSetup.SoundCacheSize * 1024).ToString();
sections["graphics"]["sprite_cache_size"] = (setup.SpriteCacheSize * 1024).ToString();
sections["graphics"]["texture_cache_size"] = (setup.TextureCacheSize * 1024).ToString();
sections["sound"]["cache_size"] = (setup.SoundCacheSize * 1024).ToString();

sections["misc"]["user_data_dir"] = CustomPathForConfig(_game.DefaultSetup.UseCustomSavePath, _game.DefaultSetup.CustomSavePath);
sections["misc"]["shared_data_dir"] = CustomPathForConfig(_game.DefaultSetup.UseCustomAppDataPath, _game.DefaultSetup.CustomAppDataPath);
sections["misc"]["titletext"] = _game.DefaultSetup.TitleText;
sections["misc"]["user_data_dir"] = CustomPathForConfig(setup.UseCustomSavePath, setup.CustomSavePath);
sections["misc"]["shared_data_dir"] = CustomPathForConfig(setup.UseCustomAppDataPath, setup.CustomAppDataPath);
sections["misc"]["titletext"] = setup.TitleText;

if(_game.Settings.DebugMode) // Do not write show_fps in a release build, this is only intended for the developer
{
sections["misc"]["show_fps"] = _game.DefaultSetup.ShowFPS ? "1" : "0";
sections["misc"]["show_fps"] = setup.ShowFPS ? "1" : "0";
}

NativeProxy.Instance.WriteIniFile(configFilePath, sections, true);
Expand Down
22 changes: 21 additions & 1 deletion Editor/AGS.Editor/BuildTargets/BuildTargetBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ public virtual string GetCompiledPath(params string[] parts)
return sb.ToString();
}

public virtual RuntimeSetup FixInvalidSettings(RuntimeSetup setup)
{
return setup;
}

public virtual string[] GetRequiredLibraryNames()
{
return new List<string>(GetRequiredLibraryPaths().Keys).ToArray();
Expand Down Expand Up @@ -148,7 +153,22 @@ protected void GenerateConfigFile(string destDir)
}
catch (Exception) { }
}
AGSEditor.Instance.WriteConfigFile(destPath, false);

RuntimeSetup setup = Factory.AGSEditor.CurrentGame.DefaultSetup;
setup = FixInvalidSettings(CloneRuntimeSetup(setup, Factory.AGSEditor.CurrentGame.Settings));

AGSEditor.Instance.WriteConfigFile(destPath, setup, false);
}

/// <summary>
/// clones a RuntimeSetup.
/// TO-DO: remove this if we decide to implement it in RuntimeSetup itself.
/// </summary>
protected static RuntimeSetup CloneRuntimeSetup(RuntimeSetup setup, Settings settings)
{
RuntimeSetup clone = new RuntimeSetup(settings);
Utilities.NaiveCopyProperties(setup, clone);
return clone;
}

/// <summary>
Expand Down
7 changes: 7 additions & 0 deletions Editor/AGS.Editor/BuildTargets/BuildTargetLinux.cs
Original file line number Diff line number Diff line change
Expand Up @@ -212,5 +212,12 @@ public override string OutputDirectory
return LINUX_DIR;
}
}

public override RuntimeSetup FixInvalidSettings(RuntimeSetup setup)
{
setup.GraphicsDriver = setup.GraphicsDriver == GraphicsDriver.D3D9 ? GraphicsDriver.OpenGL : setup.GraphicsDriver;

return setup;
}
}
}
7 changes: 7 additions & 0 deletions Editor/AGS.Editor/BuildTargets/BuildTargetWeb.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,5 +105,12 @@ public override string OutputDirectory
return WEB_DIR;
}
}

public override RuntimeSetup FixInvalidSettings(RuntimeSetup setup)
{
setup.GraphicsDriver = setup.GraphicsDriver == GraphicsDriver.D3D9 ? GraphicsDriver.OpenGL : setup.GraphicsDriver;

return setup;
}
}
}
16 changes: 16 additions & 0 deletions Editor/AGS.Editor/Utils/Utilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Reflection;

namespace AGS.Editor
{
Expand Down Expand Up @@ -705,5 +706,20 @@ public static string GetConfigString(Dictionary<string, Dictionary<string, strin
return def;
return value;
}

/// <summary>
/// Do a simple shallow copy of properties that are both readableand writeable from one object to the other
/// TO-DO: If we do add a Clone or Duplicate to the objects in AGS.Types, move this to Utilities there.
/// </summary>
public static void NaiveCopyProperties(object source_obj, object clone)
{
IEnumerable<PropertyInfo> properties = source_obj.GetType().GetProperties()
.Where(f => f.CanWrite && f.CanRead);

foreach (PropertyInfo prop in properties)
{
prop.SetValue(clone, prop.GetValue(source_obj));
}
}
}
}