From 51b15b32d5a4624da0bf1012887236d302006d46 Mon Sep 17 00:00:00 2001 From: Skalfate Date: Wed, 7 Jan 2026 22:36:57 -0700 Subject: [PATCH 1/4] These changes fix the HD-Mode lag and crashes that happen when the client is launched into HD-Mode or when changing into HD-Mode.. In Windows, on first launch into HD-Mode or at launch going from SD-Mods to HD-Mode, the CPU maxes out and music issues, and is unable to enter into HD-Mode without lag or multiple crashes. This is because when the code that is supposed to execute GLProfile.initSingleton() waits for its turn on syncronized function queue and then a while loop keeps sleeping the thread until a status code of 1 is returned. Additionally, starting with jogl version 2.0 GLProfile.initSingleton() is not even necessary as its automatically done. The code commented out has no purpose other than just to execute GLProfile.initSingleton(). Commented out the code and made comments to preserve the original code. --- client/src/main/java/rt4/DisplayMode.java | 29 +++++++++++++++++------ signlink/src/main/java/rt4/SignLink.java | 2 +- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/client/src/main/java/rt4/DisplayMode.java b/client/src/main/java/rt4/DisplayMode.java index 440e79d..3f56f62 100644 --- a/client/src/main/java/rt4/DisplayMode.java +++ b/client/src/main/java/rt4/DisplayMode.java @@ -178,13 +178,28 @@ public final class DisplayMode { } else { SoftwareRaster.frameBuffer = null; } - @Pc(300) PrivilegedRequest local300 = GameShell.signLink.loadGlNatives(client.instance.getClass()); - while (local300.status == 0) { - ThreadUtils.sleep(100L); - } - if (local300.status == 1) { - aBoolean73 = true; - } + + /** + * Code below tries to trigger GLProfile.initSingleton() through a queue in PrivilegedRequest where it waits + * for its turn. This along with the while loop waits to return status code 1 which causes + * lag and delay when switching to HD Mode. + * GLProfile.initSingleton() is automatically run starting with jogl 2.0 and later. So no need to execute it. + * After it returns status code 1, it also sets an important variable aBoolean73 to true + * when the queue executes successfully. + * This triggers the needed GLRenderer.init() function which we can control to be true manually. + **/ + + /** + @Pc(300) PrivilegedRequest local300 = GameShell.signLink.loadGlNatives(client.instance.getClass()); + while (local300.status == 0) { + ThreadUtils.sleep(100L); + } + if (local300.status == 1) { + aBoolean73 = true; + } + */ + + aBoolean73 = true; // Manually set here to allow GLRenderer.init() to execute. } if (aBoolean73) { GlRenderer.init(GameShell.canvas, Preferences.antiAliasingMode * 2); diff --git a/signlink/src/main/java/rt4/SignLink.java b/signlink/src/main/java/rt4/SignLink.java index fe733a0..abc5caf 100644 --- a/signlink/src/main/java/rt4/SignLink.java +++ b/signlink/src/main/java/rt4/SignLink.java @@ -410,7 +410,7 @@ public final class SignLink implements Runnable { } request.result = ((Class) args[0]).getDeclaredField((String) args[1]); } else if (type == 10) { - GLProfile.initSingleton(); + //GLProfile.initSingleton(); //this is no longer necessary with jogl versions 2.0+. } else if (type == 11) { GLProfile.shutdown(); } else if (type == 12) { From 832a10a2144442233656e0dbe24f512f0af924c6 Mon Sep 17 00:00:00 2001 From: Skalfate Date: Thu, 15 Jan 2026 01:56:36 -0700 Subject: [PATCH 2/4] Some Code is documented with comments to help for better readability. --- client/src/main/java/rt4/DisplayMode.java | 42 +++++++++++++++------- client/src/main/java/rt4/ScriptRunner.java | 1 + client/src/main/java/rt4/client.java | 8 ++++- 3 files changed, 38 insertions(+), 13 deletions(-) diff --git a/client/src/main/java/rt4/DisplayMode.java b/client/src/main/java/rt4/DisplayMode.java index 3f56f62..80cc560 100644 --- a/client/src/main/java/rt4/DisplayMode.java +++ b/client/src/main/java/rt4/DisplayMode.java @@ -14,7 +14,7 @@ public final class DisplayMode { @OriginalMember(owner = "client!ib", name = "i", descriptor = "[Lclient!od;") public static DisplayMode[] aClass114Array1; @OriginalMember(owner = "client!rc", name = "M", descriptor = "Z") - public static boolean aBoolean73 = false; + public static boolean start_GLRenderer = false; @OriginalMember(owner = "client!jk", name = "y", descriptor = "Z") public static boolean resizable = false; @OriginalMember(owner = "client!hi", name = "f", descriptor = "J") @@ -94,6 +94,10 @@ public final class DisplayMode { Preferences.write(GameShell.signLink); } } + /** + * If somehow the above code block fails to produce a frame for Fullscreen then this block is a safeguard + * to fall back to Standard Mode. + */ if (newMode == 3 && GameShell.fullScreenFrame == null) { setWindowMode(true, Preferences.favoriteWorlds, true, currentMode, -1, -1); return; @@ -125,6 +129,11 @@ public final class DisplayMode { GameShell.canvasWidth = 765; GameShell.canvasHeight = 503; } + /** + * This code bock executes for Fullscreen mode and removes current canvas in main frame window + * with a new canvas for the fullscreen frame window. Else if no canvas is replaced then just makes + * size adjustments to current canvas. + */ if (replaceCanvas) { Keyboard.stop(GameShell.canvas); Mouse.stop(GameShell.canvas); @@ -149,12 +158,18 @@ public final class DisplayMode { GameShell.canvas.setLocation(GameShell.leftMargin, GameShell.topMargin); } } + /** + * newMode 0 is no mode, so this would be a reset of the canvas and glrenderer + */ if (newMode == 0 && currentMode > 0) { GlRenderer.createAndDestroyContext(GameShell.canvas); } + /** + * This Code block starts on mode 1=HD,2=HDResize,3=Fullscreen. It also Starts the GLrenderer. + */ if (useHD && newMode > 0) { GameShell.canvas.setIgnoreRepaint(true); - if (!aBoolean73) { + if (!start_GLRenderer) { SceneGraph.clear(); SoftwareRaster.frameBuffer = null; SoftwareRaster.frameBuffer = FrameBuffer.create(GameShell.canvasHeight, GameShell.canvasWidth, GameShell.canvas); @@ -169,7 +184,7 @@ public final class DisplayMode { SoftwareRaster.frameBuffer.draw(graphics); } catch (@Pc(277) Exception local277) { } - GameShell.method2704(); + GameShell.method2704(); // Creates a black background for SD Mode window, gameplay frame will render on top of. if (currentMode == 0) { if(resizableSD) SoftwareRaster.frameBuffer = FrameBuffer.create(GameShell.frameHeight, GameShell.frameWidth, GameShell.canvas); @@ -181,12 +196,11 @@ public final class DisplayMode { /** * Code below tries to trigger GLProfile.initSingleton() through a queue in PrivilegedRequest where it waits - * for its turn. This along with the while loop waits to return status code 1 which causes - * lag and delay when switching to HD Mode. + * for its turn. This along with the while loop waits long enough to cause a desync in the start process which causes + * lag and delay when switching to HD Mode and when launchingt he client in HD Mode. * GLProfile.initSingleton() is automatically run starting with jogl 2.0 and later. So no need to execute it. - * After it returns status code 1, it also sets an important variable aBoolean73 to true - * when the queue executes successfully. - * This triggers the needed GLRenderer.init() function which we can control to be true manually. + * After it returns status code 1, it also sets an important variable aBoolean73(Start_Renderer) to true. + * This triggers the needed GLRenderer.init() function which we can control to be true manually as intended. **/ /** @@ -199,16 +213,20 @@ public final class DisplayMode { } */ - aBoolean73 = true; // Manually set here to allow GLRenderer.init() to execute. + start_GLRenderer = true; // Manually set here to allow GLRenderer.init() to execute. } - if (aBoolean73) { + if (start_GLRenderer) { GlRenderer.init(GameShell.canvas, Preferences.antiAliasingMode * 2); } } + // If HD Mode fails, this restarts the whole process to enter into SD Mode if (!GlRenderer.enabled && newMode > 0) { setWindowMode(true, 0, true, currentMode, -1, -1); return; } + /** + * Executes once when the client is launched. Doesn't need to be executed more than that. + */ if (newMode > 0 && currentMode == 0) { GameShell.thread.setPriority(5); SoftwareRaster.frameBuffer = null; @@ -218,7 +236,7 @@ public final class DisplayMode { Rasteriser.setBrightness(0.7F); } LoginManager.method4637(); - } else if (newMode == 0 && currentMode > 0) { + } else if (newMode == 0 && currentMode > 0) { // This is when client switches from any other mode to SD Mode GameShell.thread.setPriority(1); if(resizableSD) SoftwareRaster.frameBuffer = FrameBuffer.create(GameShell.frameHeight, GameShell.frameWidth, GameShell.canvas); @@ -248,7 +266,7 @@ public final class DisplayMode { if (useHD) { client.method2721(); } - resizable = newMode >= 2; + resizable = newMode == 2; // resizeable should only be done in HD-Resizeable mode and full screen mode. if (InterfaceList.topLevelInterface != -1) { InterfaceList.method3712(true); } diff --git a/client/src/main/java/rt4/ScriptRunner.java b/client/src/main/java/rt4/ScriptRunner.java index 24af9ea..cd55e4e 100644 --- a/client/src/main/java/rt4/ScriptRunner.java +++ b/client/src/main/java/rt4/ScriptRunner.java @@ -4668,6 +4668,7 @@ public final class ScriptRunner { if (int1 < 0 || int1 > 2) { int1 = 0; } + // Gets called on every mode change. DisplayMode.setWindowMode(false, int1, -1, -1); continue; } diff --git a/client/src/main/java/rt4/client.java b/client/src/main/java/rt4/client.java index 7a77445..99fa8b2 100644 --- a/client/src/main/java/rt4/client.java +++ b/client/src/main/java/rt4/client.java @@ -840,6 +840,12 @@ public final class client extends GameShell { DisplayMode.aLong89 = MonotonicClock.currentTimeMillis() + 500L; } } + /** + * If the game is running fine and is in fullscreen mode and a user wants to leave the mode then + * this will reset the window to Standard mode and exist fullscreen. + * This line can also launch back into full screen when out of focus and refocused by mode 3 + * with the right width and height, by Preference.width and Preference.height. + */ if (GameShell.fullScreenFrame != null && !GameShell.focus && (gameState == 30 || gameState == 10)) { DisplayMode.setWindowMode(false, Preferences.favoriteWorlds, -1, -1); } @@ -849,7 +855,7 @@ public final class client extends GameShell { GameShell.fullRedraw = false; } if (local158) { - GameShell.method2704(); + GameShell.method2704(); // Creates a black background for SD Mode gameplay frame to render on top of. } if (GlRenderer.enabled) { for (local80 = 0; local80 < 100; local80++) { From 8da1097d03ca8ee9aabe0bb5b13a87a381944eeb Mon Sep 17 00:00:00 2001 From: Skalfate Date: Thu, 15 Jan 2026 01:59:06 -0700 Subject: [PATCH 3/4] Fixed some typos --- client/src/main/java/rt4/DisplayMode.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/src/main/java/rt4/DisplayMode.java b/client/src/main/java/rt4/DisplayMode.java index 80cc560..be719d3 100644 --- a/client/src/main/java/rt4/DisplayMode.java +++ b/client/src/main/java/rt4/DisplayMode.java @@ -196,8 +196,8 @@ public final class DisplayMode { /** * Code below tries to trigger GLProfile.initSingleton() through a queue in PrivilegedRequest where it waits - * for its turn. This along with the while loop waits long enough to cause a desync in the start process which causes - * lag and delay when switching to HD Mode and when launchingt he client in HD Mode. + * for its turn. This along with the while loop waits long enough to cause a de-sync in the start process which causes + * lag and delay when switching to HD Mode and when launching the client in HD Mode. * GLProfile.initSingleton() is automatically run starting with jogl 2.0 and later. So no need to execute it. * After it returns status code 1, it also sets an important variable aBoolean73(Start_Renderer) to true. * This triggers the needed GLRenderer.init() function which we can control to be true manually as intended. @@ -266,7 +266,7 @@ public final class DisplayMode { if (useHD) { client.method2721(); } - resizable = newMode == 2; // resizeable should only be done in HD-Resizeable mode and full screen mode. + resizable = newMode == 2; // resizeable should only be done in HD-Resizeable mode and not full screen mode. if (InterfaceList.topLevelInterface != -1) { InterfaceList.method3712(true); } From 3c07616fa81439a23106fb8b89cf59340463ec72 Mon Sep 17 00:00:00 2001 From: Skalfate Date: Thu, 15 Jan 2026 08:52:20 -0700 Subject: [PATCH 4/4] Fixed some typos --- client/src/main/java/rt4/client.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/src/main/java/rt4/client.java b/client/src/main/java/rt4/client.java index 99fa8b2..3f897c5 100644 --- a/client/src/main/java/rt4/client.java +++ b/client/src/main/java/rt4/client.java @@ -841,10 +841,10 @@ public final class client extends GameShell { } } /** - * If the game is running fine and is in fullscreen mode and a user wants to leave the mode then - * this will reset the window to Standard mode and exist fullscreen. - * This line can also launch back into full screen when out of focus and refocused by mode 3 - * with the right width and height, by Preference.width and Preference.height. + * If the game is running in fullscreen mode and focus is lost, by alt tab or ctrl alt tab, the client exits + * fullscreen mode and enters window mode. + * This line can also be used to launch back into full screen when out of focus and refocused by sending mode 3 + * with the right width and height, by Preference.width and Preference.height for exmaple. */ if (GameShell.fullScreenFrame != null && !GameShell.focus && (gameState == 30 || gameState == 10)) { DisplayMode.setWindowMode(false, Preferences.favoriteWorlds, -1, -1);