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

Compatibility rework #59

Closed
wants to merge 36 commits into from
Closed
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
c6e523a
First successful build and launch.
rankynbass Jun 17, 2023
903ee25
Reposition submodule
rankynbass Jun 17, 2023
8363495
Merge branch 'main' into compatibility-rework
rankynbass Jun 17, 2023
9b05879
Minor fixes
rankynbass Jun 17, 2023
e687d03
Update submodule
rankynbass Jun 17, 2023
3878e84
Merge branch 'main' into compatibility-rework
rankynbass Jun 18, 2023
3de5ce9
Move more login into runners
rankynbass Jun 18, 2023
3a7aca8
More work done
rankynbass Jun 22, 2023
c522e0f
Move WineRunner, DxvkRunner to FFQL repo
rankynbass Jun 24, 2023
272f4d1
Fix gamemode, update submodule
rankynbass Jun 24, 2023
8fd716d
Move MacVideoFix to xlcore
rankynbass Jun 24, 2023
380e62a
Replace directives with GetDistro function
rankynbass Jun 25, 2023
8314140
Move distro function to Program.cs, add flatpak detection
rankynbass Jun 25, 2023
2142c7d
Use Dictionary instead of iterating array
rankynbass Jun 25, 2023
0637558
Fix error by switching to .ContainsKey()
rankynbass Jun 25, 2023
74b4912
Move distro detection to own class, use enum
rankynbass Jun 25, 2023
5d75345
Forgot to save a couple files
rankynbass Jun 25, 2023
94f34c4
Revert "Move MacVideoFix to xlcore"
rankynbass Jun 25, 2023
9067d4e
Merge branch 'main' into compatibility-rework
rankynbass Jun 25, 2023
ad51095
Update submodule so it will build
rankynbass Jun 25, 2023
0098371
Fix slightly wrong WINEDLLOVERRIDE.
rankynbass Jun 26, 2023
6fe1b6b
Changes to match with main XL repo. More to come.
rankynbass Jun 28, 2023
7afb7a2
Remove WineD3D Vulkan
rankynbass Jun 28, 2023
f7162a4
Move Wine, Dxvk, Distro to UnixCompatibility
rankynbass Jun 29, 2023
64a3a62
Cleaned up some Distro-related stuff.
rankynbass Jun 29, 2023
ea617f2
Update submodule
rankynbass Jun 29, 2023
c80b205
Touched up the Wine Tab
rankynbass Jun 29, 2023
c5331d0
Switch to using XIVLauncher.Common.Platform enum
rankynbass Jun 29, 2023
f8a236b
Added some code in Distro for MacOS & FreeBSD.
rankynbass Jun 29, 2023
2334b28
Minor cleanup of code and rewording some options.
rankynbass Jul 1, 2023
ccf30a7
Update submodule
rankynbass Jul 1, 2023
3b07474
Fixed flatpak path for mangohud
rankynbass Jul 1, 2023
92a7cff
Changed default wine to 7.10
rankynbass Jul 8, 2023
7ab0524
Update WineVersion descriptions
rankynbass Jul 8, 2023
22bfcbb
Update submodule
rankynbass Jul 8, 2023
387d17d
Update Distro.cs to correct namespace.
rankynbass Jul 11, 2023
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
18 changes: 14 additions & 4 deletions src/XIVLauncher.Core/Components/MainPage/MainPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -738,15 +738,15 @@ public async Task<Process> StartGameAndAddon(Launcher.LoginResult loginResult, b
}
else if (Environment.OSVersion.Platform == PlatformID.Unix)
{
if (App.Settings.WineStartupType == WineStartupType.Custom)
if (App.Settings.WineType == WineType.Custom)
{
if (App.Settings.WineBinaryPath == null)
throw new Exception("Custom wine binary path wasn't set.");
else if (!Directory.Exists(App.Settings.WineBinaryPath))
throw new Exception("Custom wine binary path is invalid: no such directory.\n" +
"Check path carefully for typos: " + App.Settings.WineBinaryPath);
else if (!File.Exists(Path.Combine(App.Settings.WineBinaryPath,"wine64")))
throw new Exception("Custom wine binary path is invalid: no wine64 found at that location.\n" +
else if (!File.Exists(Path.Combine(App.Settings.WineBinaryPath, "wine64")) && !File.Exists(Path.Combine(App.Settings.WineBinaryPath, "wine")))
throw new Exception("Custom wine binary path is invalid: no wine or wine64 found at that location.\n" +
"Check path carefully for typos: " + App.Settings.WineBinaryPath);
}

Expand All @@ -761,7 +761,17 @@ public async Task<Process> StartGameAndAddon(Launcher.LoginResult loginResult, b
await Program.CompatibilityTools.EnsureTool(tempPath).ConfigureAwait(false);
Program.CompatibilityTools.RunInPrefix($"winecfg /v {winver}");

var gameFixApply = new GameFixApply(App.Settings.GamePath, App.Settings.GameConfigPath, Program.CompatibilityTools.Settings.Prefix, tempPath);
if (Program.Config.DxvkVersion == DxvkVersion.Disabled)
{
if (Program.Config.WineD3DUseVK ?? false)
Program.CompatibilityTools.AddRegistryKey("HKEY_CURRENT_USER\\Software\\Wine\\Direct3D", "renderer", "vulkan");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These wine registry calls can be blocking for up to a few seconds, not sure if it is a good idea to put them here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one isn't really that important, and can easily be removed. It's just an option to use WineD3D in Vulkan mode, which is not terribly stable to begin with. As for putting it somewhere else, the only other place is in UnixGameRunner, and it'd still probably lock up for a few seconds. I'm just going to get rid of the WineD3D vulkan stuff. Chances are the only reason someone would want to use WineD3D is to use openGL anyway.

else
Program.CompatibilityTools.AddRegistryKey("HKEY_CURRENT_USER\\Software\\Wine\\Direct3D", "renderer", "gl");
}

Program.CompatibilityTools.RunInPrefix($"winecfg /v {winver}");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here


var gameFixApply = new GameFixApply(App.Settings.GamePath, App.Settings.GameConfigPath, Program.CompatibilityTools.Prefix, tempPath);
gameFixApply.UpdateProgress += (text, hasProgress, progress) =>
{
App.LoadingPage.Line1 = "Applying game-specific fixes...";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public class SettingsPage : Page
new SettingsTabGame(),
new SettingsTabPatching(),
new SettingsTabWine(),
new SettingsTabDxvk(),
new SettingsTabDalamud(),
new SettingsTabAutoStart(),
new SettingsTabAbout(),
Expand Down
5 changes: 3 additions & 2 deletions src/XIVLauncher.Core/Components/SettingsPage/SettingsTab.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ public override void Draw()
foreach (SettingsEntry settingsEntry in Entries)
{
if (settingsEntry.IsVisible)
{
settingsEntry.Draw();

ImGui.Dummy(new Vector2(10) * ImGuiHelpers.GlobalScale);
ImGui.Dummy(new Vector2(10) * ImGuiHelpers.GlobalScale);
}
}

base.Draw();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public override void Draw()
{
ImGui.TextUnformatted("Generic Information");
ImGui.Separator();
ImGui.TextUnformatted($"Operating System: {Environment.OSVersion}");
ImGui.TextUnformatted($"Operating System: {Distro.Name} - {Environment.OSVersion}");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is should ideally be a XIVLauncher.Common Platform

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might go through and fix all of this at some point; do the full initialization of OS info in the Distro object (maybe rename it), and then change all the Environment.OSVersion.Platform checks to refer to the XIVLauncher.Common Platform value set in said Distro object. But I think there's enough going on atm. For now, I've added in some checks to make sure the Linux-specific stuff only shows up if it's actually on Linux.

ImGui.TextUnformatted($"Runtime Version: {Environment.Version}");

if (Program.IsSteamDeckHardware)
Expand All @@ -21,9 +21,10 @@ public override void Draw()
if (Program.IsSteamDeckGamingMode)
ImGui.Text("Steam Deck Gaming Mode Detected");

#if FLATPAK
if (Distro.IsFlatpak)
ImGui.Text("Running as a Flatpak");
#endif
else
ImGui.Text("Running a native build");

ImGui.Spacing();

Expand Down
100 changes: 100 additions & 0 deletions src/XIVLauncher.Core/Components/SettingsPage/Tabs/SettingsTabDxvk.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
using System.IO;
using System.Numerics;
using System.Runtime.InteropServices;
using ImGuiNET;
using XIVLauncher.Common.Unix.Compatibility;
using XIVLauncher.Common.Util;

namespace XIVLauncher.Core.Components.SettingsPage.Tabs;

public class SettingsTabDxvk : SettingsTab
{
private SettingsEntry<DxvkVersion> dxvkVersionSetting;
private SettingsEntry<bool> wineD3DUseVk;
private SettingsEntry<DxvkHudType> dxvkHudSetting;

public SettingsTabDxvk()
{
Entries = new SettingsEntry[]
{
dxvkVersionSetting = new SettingsEntry<DxvkVersion>("DXVK Version", "Choose which version of DXVK to use.", () => Program.Config.DxvkVersion ?? DxvkVersion.v1_10_3, type => Program.Config.DxvkVersion = type)
{
CheckWarning = type =>
{
if (new [] {DxvkVersion.v2_1, DxvkVersion.v2_2}.Contains(type))
return "May not work with older graphics cards. AMD users may need to use env variable RADV_PERFTEST=gpl";
return null;
},
},
wineD3DUseVk = new SettingsEntry<bool>("Use WineD3D Vulkan renderer", "Use Vulkan instead of OpenGL for WineD3D. Unstable. May cause system to lock up.", () => Program.Config.WineD3DUseVK ?? false, b => Program.Config.WineD3DUseVK = b)
{
CheckVisibility = () => dxvkVersionSetting.Value == DxvkVersion.Disabled,
CheckWarning = b =>
{
if (b)
return "WARNING! This is very experimental, and may cause your system to crash or hang. If you still want to use it, disable Dalamud.";
return null;
},
},
new SettingsEntry<bool>("Enable DXVK ASYNC", "Enable DXVK ASYNC patch.", () => Program.Config.DxvkAsyncEnabled ?? true, b => Program.Config.DxvkAsyncEnabled = b)
{
CheckVisibility = () => (new [] {DxvkVersion.v1_10_3, DxvkVersion.v2_0}.Contains(dxvkVersionSetting.Value)),
CheckWarning = b =>
{
if (!b && dxvkVersionSetting.Value == DxvkVersion.v2_0)
return "AMD users may need to use env variable RADV_PERFTEST=gpl";
return null;
},
},
dxvkHudSetting = new SettingsEntry<DxvkHudType>("DXVK Overlay", "DXVK Hud is included with Dxvk. It doesn't work if Dxvk is disabled.\nMangoHud must be installed separately. Flatpak XIVLauncher needs flatpak MangoHud.", () => Program.Config.DxvkHudType, type => Program.Config.DxvkHudType = type)
{
CheckVisibility = () => dxvkVersionSetting.Value != DxvkVersion.Disabled || wineD3DUseVk.Value,
CheckValidity = type =>
{
if ((type == DxvkHudType.MangoHud || type == DxvkHudType.MangoHudCustom || type == DxvkHudType.MangoHudFull)
&& (!File.Exists("/usr/lib/mangohud/libMangoHud.so") && !File.Exists("/usr/lib64/mangohud/libMangoHud.so") && !File.Exists("/usr/lib/extensions/vulkan/MangoHud/lib/x86_64-linux-gnu/libMangoHud.so")))
return "MangoHud not detected.";

return null;
}
},
new SettingsEntry<string>("DXVK Hud Custom String", "Set a custom string for the built in DXVK Hud. Warning: If it's invalid, the game may hang.", () => Program.Config.DxvkHudCustom, s => Program.Config.DxvkHudCustom = s)
{
CheckVisibility = () => dxvkHudSetting.Value == DxvkHudType.Custom && dxvkVersionSetting.Value != DxvkVersion.Disabled,
CheckWarning = s =>
{
if(!DxvkManager.CheckDxvkHudString(s))
return "That's not a valid hud string";
return null;
},
},
new SettingsEntry<string>("MangoHud Custom Path", "Set a custom path for MangoHud config file.", () => Program.Config.DxvkMangoCustom, s => Program.Config.DxvkMangoCustom = s)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a Linux-only config option, and even then only useful when MangoHUD is actually installed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the moment, there's a function that looks for specific paths where Linux installs MangoHud, and it won't let you save your selection if it doesn't find it (it will show an error). I think the whole DXVK tab is really linux only. Only the Disabled/WineD3D setting would work on MacOS atm (if that), and only if you manually provided a wine release. Maybe there's DXVK for freebsd? Not sure

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DXVK is a PE only binary that translates Windows dx calls into Windows Vulkan calls (simplified), so it will run on any platform that supports the necessary Windows Vulkan feature level which is Wine on Linux, FreeBSD, macOS (if the native unix implementation has all needed extensions) and even on Windows itself (where it is sometimes used to provide better frame pacing, or just in general better performance that the native Windows dx driver)

{
CheckVisibility = () => dxvkHudSetting.Value == DxvkHudType.MangoHudCustom && !(dxvkVersionSetting.Value == DxvkVersion.Disabled && !wineD3DUseVk.Value),
CheckWarning = s =>
{
if(!File.Exists(s))
return "That's not a valid file.";
return null;
},
},
new NumericSettingsEntry("Frame Rate Limit", "Set a frame rate limit, and DXVK will try not exceed it. Use 0 for unlimited.", () => Program.Config.DxvkFrameRate ?? 0, i => Program.Config.DxvkFrameRate = i, 0, 1000)
{
CheckVisibility = () => dxvkVersionSetting.Value != DxvkVersion.Disabled,
},
};
}

public override SettingsEntry[] Entries { get; }

public override bool IsUnixExclusive => true;

public override string Title => "DXVK";

public override void Save()
{
base.Save();
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
Program.CreateCompatToolsInstance();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,6 @@ public override void Draw()

ImGui.Separator();

ImGui.Text("\nReset settings to default.");
if (ImGui.Button("Clear Settings"))
{
Program.ClearSettings(true);
}

ImGui.Text("\nClear the Wine Prefix - delete the ~/.xlcore/wineprefix folder");
if (ImGui.Button("Clear Prefix"))
{
Expand All @@ -55,6 +49,12 @@ public override void Draw()
Program.ClearLogs(true);
}

ImGui.Text("\nReset settings to default.");
if (ImGui.Button("Clear Settings"))
{
Program.ClearSettings(true);
}

ImGui.Text("\nDo all of the above.");
if (ImGui.Button("Clear Everything"))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,25 @@ namespace XIVLauncher.Core.Components.SettingsPage.Tabs;

public class SettingsTabWine : SettingsTab
{
private SettingsEntry<WineStartupType> startupTypeSetting;
private SettingsEntry<WineType> startupTypeSetting;

public SettingsTabWine()
{
Entries = new SettingsEntry[]
{
startupTypeSetting = new SettingsEntry<WineStartupType>("Wine Version", "Choose how XIVLauncher will start and manage your wine installation.",
() => Program.Config.WineStartupType ?? WineStartupType.Managed, x => Program.Config.WineStartupType = x),
startupTypeSetting = new SettingsEntry<WineType>("Installation Type", "Choose how XIVLauncher will start and manage your game installation.",
() => Program.Config.WineType ?? WineType.Managed, x => Program.Config.WineType = x),

new SettingsEntry<WineVersion>("Wine Version", "Choose a patched wine version.", () => Program.Config.WineVersion ?? WineVersion.Wine8_5, x => Program.Config.WineVersion = x)
{
CheckVisibility = () => startupTypeSetting.Value == WineType.Managed
},

new SettingsEntry<string>("Wine Binary Path",
"Set the path XIVLauncher will use to run applications via wine.\nIt should be an absolute path to a folder containing wine64 and wineserver binaries.",
() => Program.Config.WineBinaryPath, s => Program.Config.WineBinaryPath = s)
{
CheckVisibility = () => startupTypeSetting.Value == WineStartupType.Custom
CheckVisibility = () => startupTypeSetting.Value == WineType.Custom
},

new SettingsEntry<bool>("Enable Feral's GameMode", "Enable launching with Feral Interactive's GameMode CPU optimizations.", () => Program.Config.GameModeEnabled ?? true, b => Program.Config.GameModeEnabled = b)
Expand All @@ -36,8 +41,8 @@ public SettingsTabWine()
}
},

new SettingsEntry<bool>("Enable DXVK ASYNC", "Enable DXVK ASYNC patch.", () => Program.Config.DxvkAsyncEnabled ?? true, b => Program.Config.DxvkAsyncEnabled = b),
new SettingsEntry<bool>("Enable ESync", "Enable eventfd-based synchronization.", () => Program.Config.ESyncEnabled ?? true, b => Program.Config.ESyncEnabled = b),

new SettingsEntry<bool>("Enable FSync", "Enable fast user mutex (futex2).", () => Program.Config.FSyncEnabled ?? true, b => Program.Config.FSyncEnabled = b)
{
CheckVisibility = () => RuntimeInformation.IsOSPlatform(OSPlatform.Linux),
Expand All @@ -49,10 +54,7 @@ public SettingsTabWine()
return null;
}
},

new SettingsEntry<bool>("Set Windows version to 7", "Default for Wine 8.1+ is Windows 10, but this causes issues with some Dalamud plugins. Windows 7 is recommended for now.", () => Program.Config.SetWin7 ?? true, b => Program.Config.SetWin7 = b),

new SettingsEntry<Dxvk.DxvkHudType>("DXVK Overlay", "Configure how much of the DXVK overlay is to be shown.", () => Program.Config.DxvkHudType, type => Program.Config.DxvkHudType = type),
new SettingsEntry<bool>("Set Windows version to 7", "Default for Wine 8.1+ is Windows 10, but this can cause issues with some Dalamud plugins. Windows 7 is recommended for now.", () => Program.Config.SetWin7 ?? true, b => Program.Config.SetWin7 = b),
new SettingsEntry<string>("WINEDEBUG Variables", "Configure debug logging for wine. Useful for troubleshooting.", () => Program.Config.WineDebugVars ?? string.Empty, s => Program.Config.WineDebugVars = s)
};
}
Expand All @@ -77,7 +79,7 @@ public override void Draw()

if (ImGui.Button("Open prefix"))
{
PlatformHelpers.OpenBrowser(Program.CompatibilityTools.Settings.Prefix.FullName);
PlatformHelpers.OpenBrowser(Program.CompatibilityTools.Prefix.FullName);
}

ImGui.SameLine();
Expand Down
16 changes: 14 additions & 2 deletions src/XIVLauncher.Core/Configuration/ILauncherConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,13 @@ public interface ILauncherConfig

#region Linux

public WineStartupType? WineStartupType { get; set; }
public WineType? WineType { get; set; }

public WineVersion? WineVersion { get; set; }

public DxvkVersion? DxvkVersion { get; set; }

public bool? WineD3DUseVK { get; set; }

public string? WineBinaryPath { get; set; }

Expand All @@ -74,7 +80,13 @@ public interface ILauncherConfig

public bool? FSyncEnabled { get; set; }

public Dxvk.DxvkHudType DxvkHudType { get; set; }
public DxvkHudType DxvkHudType { get; set; }

public string? DxvkHudCustom { get; set; }

public string? DxvkMangoCustom { get; set; }

public int? DxvkFrameRate { get; set; }

public string? WineDebugVars { get; set; }

Expand Down
76 changes: 76 additions & 0 deletions src/XIVLauncher.Core/Distro.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
using System.Numerics;
using System.IO;
using System.Collections.Generic;

namespace XIVLauncher.Core;

public enum WinePackage
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feels a bit weird having the wine package enum inside the Distro file..
This seems to be completely unused anyways

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's actually used in the WineManager to determine which wine package to download. I've renamed to DistroPackage now.

{
ubuntu,

fedora,

arch,
}

public static class Distro
{
public static WinePackage Package { get; private set; }

public static string Name { get; private set; }

public static bool IsFlatpak { get; private set; }

public static void GetInfo()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is called GetInfo() and returns nothing, which is not very intuitive to use, especially with the static properties next to it.

All of this also only makes sense on a target system that needs wine (and even then only on Linux).

Each csproj has WIN32, OSX and LINUX constants defined, which could be used here.

Also not sure if this needs to be a top-level file here at all, there is also https://github.com/goatcorp/FFXIVQuickLauncher/blob/410cc9ed0624c37879b747ad69ba6e61c18c6f0f/src/XIVLauncher.Common/Platform.cs#L7

{
try
{
if (!File.Exists("/etc/os-release"))
{
Package = WinePackage.ubuntu;
Name = "Unknown distribution";
IsFlatpak = false;
return;
}
var osRelease = File.ReadAllLines("/etc/os-release");
var distro = WinePackage.ubuntu;
var flatpak = false;
var OSInfo = new Dictionary<string, string>();
foreach (var line in osRelease)
{
var keyValue = line.Split('=', 2);
if (keyValue.Length == 1)
OSInfo.Add(keyValue[0], "");
else
OSInfo.Add(keyValue[0], keyValue[1]);
}

var name = (OSInfo.ContainsKey("NAME") ? OSInfo["NAME"] : "").Trim('"');
var pretty = (OSInfo.ContainsKey("PRETTY_NAME") ? OSInfo["PRETTY_NAME"] : "").Trim('"');
var idLike = OSInfo.ContainsKey("ID_LIKE") ? OSInfo["ID_LIKE"] : "";
if (idLike.Contains("arch"))
distro = WinePackage.arch;
else if (idLike.Contains("fedora"))
distro = WinePackage.fedora;
else
distro = WinePackage.ubuntu;

var id = OSInfo.ContainsKey("ID") ? OSInfo["ID"] : "";
if (id.Contains("tumbleweed") || id.Contains("fedora"))
distro = WinePackage.fedora;
if (id == "org.freedesktop.platform")
flatpak = true;

Package = distro;
Name = pretty == "" ? (name == "" ? "Unknown distribution" : name) : pretty;
IsFlatpak = flatpak;
}
catch
{
// If there's any kind of error opening the file or even finding it, just go with default.
Package = WinePackage.ubuntu;
Name = "Unknown distribution";
IsFlatpak = false;
}
}
}
Loading