Skip to content

Commit c06d1ab

Browse files
committed
fix: Initialize SDL manually first before applying hints without patching
For some reason SDL_video was getting into a weird state if this wasn't done Harmony doesn't work when published to single file
1 parent fe4c11a commit c06d1ab

File tree

5 files changed

+95
-14
lines changed

5 files changed

+95
-14
lines changed

Intersect.Client.Core/Interface/Menu/SelectCharacterWindow.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using HarmonyLib;
21
using Intersect.Client.Core;
32
using Intersect.Client.Framework.Content;
43
using Intersect.Client.Framework.File_Management;

Intersect.Client.Core/Intersect.Client.Core.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@
8787
</ItemGroup>
8888

8989
<ItemGroup>
90-
<PackageReference Include="Lib.Harmony.Thin" Version="2.3.3" />
9190
<PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.1.303" GeneratePathProperty="True" />
9291
<PackageReference Include="MonoGame.Library.SDL" Version="2.26.5.5" GeneratePathProperty="True" />
9392
<PackageReference Include="Steamworks.NET" Version="20.1.0" />

Intersect.Client.Core/MonoGame/IntersectGame.cs

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using Intersect.Client.Core;
2-
using Intersect.Client.Core.Controls;
32
using Intersect.Client.Framework.Gwen.Input;
43
using Intersect.Client.Framework.Gwen.Renderer;
54
using Intersect.Client.Framework.Input;
@@ -15,7 +14,6 @@
1514
using Microsoft.Xna.Framework.Graphics;
1615
using System.Diagnostics;
1716
using System.Reflection;
18-
using HarmonyLib;
1917
using Intersect.Client.Framework.Database;
2018
using Intersect.Client.Framework.Graphics;
2119
using Intersect.Client.ThirdParty;
@@ -556,30 +554,40 @@ public void Start(IClientContext context, Action postStartupAction)
556554
{
557555
try
558556
{
559-
var assemblyMonoGameFramework = AppDomain.CurrentDomain.GetAssemblies()
560-
.FirstOrDefault(assembly => assembly.FullName?.StartsWith("MonoGame.Framework") ?? false);
561-
var typeInternalSdl = assemblyMonoGameFramework?.GetType("Sdl");
562-
var methodSdlInit = typeInternalSdl?.GetMethod("Init");
563-
564-
var harmonyPatch = new Harmony(typeof(MonoGameRunner).Assembly.FullName ?? "Intersect.Client.Core");
565-
harmonyPatch.Patch(methodSdlInit, postfix: SymbolExtensions.GetMethodInfo(() => SdlInitPost()));
557+
DoSdlInit(12832);
566558
}
567559
catch (Exception exception)
568560
{
569-
ApplicationContext.Context.Value?.Logger.LogWarning(exception, "Error occurred when trying to apply Harmony patch, this is not a fatal error");
561+
ApplicationContext.Context.Value?.Logger.LogWarning(
562+
exception,
563+
"Error occurred while trying to initialize SDL"
564+
);
570565
}
571566

572567
using var game = new IntersectGame(context, postStartupAction);
573568
game.Run();
574569
}
575570

576-
private static void SdlInitPost()
571+
private delegate void SdlInit(int flags);
572+
573+
private static void DoSdlInit(int flags)
577574
{
578575
if (PlatformHelper.CurrentPlatform != Platform.Linux)
579576
{
580577
return;
581578
}
582579

580+
var assemblyMonoGameFramework = AppDomain.CurrentDomain.GetAssemblies()
581+
.FirstOrDefault(assembly => assembly.FullName?.StartsWith("MonoGame.Framework") ?? false);
582+
var typeInternalSdl = assemblyMonoGameFramework?.GetType("Sdl");
583+
var methodSdlInit = typeInternalSdl?.GetMethod("Init");
584+
var delegateSdlInit = methodSdlInit?.CreateDelegate<SdlInit>();
585+
if (delegateSdlInit == null)
586+
{
587+
throw new InvalidOperationException("Missing Sdl.Init() from MonoGame");
588+
}
589+
delegateSdlInit(flags);
590+
583591
if (!Sdl2.SDL_SetHint(Sdl2.SDL_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, false))
584592
{
585593
ApplicationContext.Context.Value?.Logger.LogWarning("Failed to set X11 Compositor hint");

Intersect.Client.Core/MonoGame/NativeInterop/Sdl2.Hints.cs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,33 @@ public partial class Sdl2
88
public const string SDL_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR = "SDL_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR";
99

1010
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
11-
public unsafe delegate int SDL_SetHint_d(byte* name, byte* value);
11+
private unsafe delegate byte* SDL_GetHint_d(byte* name);
12+
13+
private static SDL_GetHint_d SDL_GetHint_f = Loader.Functions.LoadFunction<SDL_GetHint_d>(nameof(SDL_GetHint));
14+
15+
public static unsafe string? SDL_GetHint(string name)
16+
{
17+
fixed (byte* pName = Encoding.UTF8.GetBytes(name))
18+
{
19+
var textBytes = SDL_GetHint_f(pName);
20+
if (textBytes == default)
21+
{
22+
return null;
23+
}
24+
25+
var endTextBytes = textBytes;
26+
while (*endTextBytes != default)
27+
{
28+
++endTextBytes;
29+
}
30+
31+
var hintText = Encoding.UTF8.GetString(textBytes, (int)(endTextBytes - textBytes));
32+
return hintText;
33+
}
34+
}
35+
36+
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
37+
private unsafe delegate int SDL_SetHint_d(byte* name, byte* value);
1238

1339
private static SDL_SetHint_d SDL_SetHint_f = Loader.Functions.LoadFunction<SDL_SetHint_d>(nameof(SDL_SetHint));
1440

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using System.Runtime.InteropServices;
2+
using System.Text;
3+
4+
namespace Intersect.Client.MonoGame.NativeInterop;
5+
6+
public partial class Sdl2
7+
{
8+
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
9+
private unsafe delegate byte* SDL_getenv_d(byte* name);
10+
11+
private static SDL_getenv_d SDL_getenv_f = Loader.Functions.LoadFunction<SDL_getenv_d>(nameof(SDL_getenv));
12+
13+
public static unsafe string? SDL_getenv(string name)
14+
{
15+
fixed (byte* pName = Encoding.UTF8.GetBytes(name))
16+
{
17+
var textBytes = SDL_GetHint_f(pName);
18+
if (textBytes == default)
19+
{
20+
return null;
21+
}
22+
23+
var endTextBytes = textBytes;
24+
while (*endTextBytes != default)
25+
{
26+
++endTextBytes;
27+
}
28+
29+
var hintText = Encoding.UTF8.GetString(textBytes, (int)(endTextBytes - textBytes));
30+
return hintText;
31+
}
32+
}
33+
34+
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
35+
private unsafe delegate int SDL_setenv_d(byte* name, byte* value, int overwrite);
36+
37+
private static SDL_setenv_d SDL_setenv_f = Loader.Functions.LoadFunction<SDL_setenv_d>(nameof(SDL_setenv));
38+
39+
public static unsafe bool SDL_setenv(string name, string value, bool overwrite)
40+
{
41+
fixed (byte* pValue = Encoding.UTF8.GetBytes(value))
42+
{
43+
fixed (byte* pName = Encoding.UTF8.GetBytes(name))
44+
{
45+
return SDL_setenv_f(pName, pValue, overwrite ? 1 : 0) != 0;
46+
}
47+
}
48+
}
49+
}

0 commit comments

Comments
 (0)