diff --git a/README.MD b/README.MD index 725631c..9e6f40d 100644 --- a/README.MD +++ b/README.MD @@ -18,7 +18,7 @@ Saturn Client is a free, open-source Minecraft client designed to enhance the gameplay experience while staying lightweight and customizable. Our goal is to build a clean, optimized client that the community can contribute to and improve together. -Saturn runs on Fabric and supports **Minecraft 1.21.4 to 1.21.11, 26.1 and 26.2**, with one build per version (the 26.1 build also runs on 26.1.1 and 26.1.2). If something doesn't work on your version, please open an issue. +Saturn runs on Fabric and supports **Minecraft 1.21.4 to 1.21.11 and 26.1 to 26.3**, with one build per version (the 26.1 build also runs on 26.1.1 and 26.1.2). If something doesn't work on your version, please open an issue. ## Features diff --git a/VERSION_GUIDE.md b/VERSION_GUIDE.md index e2d0624..8cec624 100644 --- a/VERSION_GUIDE.md +++ b/VERSION_GUIDE.md @@ -4,7 +4,7 @@ How Saturn Client supports several Minecraft versions, and how to change or add ## Layout -Every supported Minecraft version (1.21.4 to 1.21.11, 26.1 and 26.2) builds from one copy of the version-specific code with [Stonecutter](https://stonecutter.kikugie.dev/): +Every supported Minecraft version (1.21.4 to 1.21.11, and 26.1 to 26.3) builds from one copy of the version-specific code with [Stonecutter](https://stonecutter.kikugie.dev/): - `common/`: all version-independent code (mods, UI, cosmetics, the server client). It has no Minecraft dependency and reaches the game only through the interfaces in `org.saturnclient.common`. - `src/`: the version-specific code (providers, refs, mixins and the three mixin configs), one copy for every version. Where Minecraft's API differs between versions, the code goes behind version comments (see below). @@ -18,7 +18,11 @@ Minecraft is obfuscated up to 1.21.11 and ships with Mojang's names from 26.1. T Every version is built with Mojang's official names (`loom.officialMojangMappings()`), the names Minecraft itself ships from 26.1 on. Yarn isn't used any more: 1.21.11 has the last Yarn release. -Mojang renames things between versions. `src/` uses the active version's (1.21.11's) names, and `stonecutter.gradle.kts` lists replacements that swap in each version's name when Stonecutter processes it: for example `Identifier`, which was `ResourceLocation` before 1.21.11, `AvatarRenderState`, which was `PlayerRenderState` before 1.21.9, and `GuiGraphics`, which is `GuiGraphicsExtractor` from 26.1. Add a replacement there when a rename touches many lines. From 26.2 the open screen and overlay live on `Gui` rather than `Minecraft`, so code goes through `impl.ui.Screens` for them. A class that only moved package needs just a version comment on its import, and a renamed method a version comment where it's called. +Mojang renames things between versions. `src/` uses the active version's (1.21.11's) names, and `stonecutter.gradle.kts` lists replacements that swap in each version's name when Stonecutter processes it: for example `Identifier`, which was `ResourceLocation` before 1.21.11, `AvatarRenderState`, which was `PlayerRenderState` before 1.21.9, and `GuiGraphics`, which is `GuiGraphicsExtractor` from 26.1. Add a replacement there when a rename touches many lines, and only for a name that appears nowhere else in `src/`: replacements work both ways, so the new name is also turned back into the old one for older versions (a `mulPose`/`rotate` replacement would rename `MatrixStackRef.rotate` too). From 26.2 the open screen and overlay live on `Gui` rather than `Minecraft`, so code goes through `impl.ui.Screens` for them. + +From 26.3 Minecraft uses SDL instead of GLFW, with SDL's numbers for keys (scancodes), modifiers and mouse buttons. Saturn keeps GLFW's numbers, which `common` uses and the config's keybinds store, and `impl.provider.Keys` converts at the boundary: key events and mouse buttons coming in, and key codes going to the game. Use `InputConstants`' key constants rather than GLFW's in version-specific code. + +26.3 also compiles every shader through SPIR-V, so shader inputs and outputs need an explicit `layout(location = …)`. Saturn's `glass.fsh` is shared by every version from 1.21.6 and switches its layout with the defines `GlassRenderer` sets, as it already did for `HAS_LINE_WIDTH`. A class that only moved package needs just a version comment on its import, and a renamed method a version comment where it's called. Released 1.21.x jars run on intermediary names (`method_1234`), not Mojang's, and Loom renames everything that refers to Minecraft when it builds them. So a mixin can't implement one of `common`'s Ref interfaces by relying on a vanilla method that happens to have the same name: the vanilla method is renamed in the jar, and the interface method is left without an implementation (`AbstractMethodError`). Shadow the vanilla method and implement the Ref method explicitly, as `WindowMixin` does. For the same reason, Ref methods mustn't share a name and parameters with a method of the class they're mixed into, or the mixin replaces the vanilla method in development. diff --git a/settings.gradle.kts b/settings.gradle.kts index 2166843..c7ace8b 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -24,7 +24,7 @@ include("common") // versions//gradle.properties holds its Minecraft, Fabric Loader and Fabric API versions. val stonecutterVersions = listOf( "1.21.4", "1.21.5", "1.21.6", "1.21.7", "1.21.8", "1.21.9", "1.21.10", "1.21.11", - "26.1", "26.2", + "26.1", "26.2", "26.3", ) stonecutter { diff --git a/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java b/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java index 59d6f5e..3ef1368 100644 --- a/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java +++ b/src/main/java/org/saturnclient/impl/cosmetics/CloakFeatureRenderer.java @@ -435,7 +435,11 @@ public class CloakFeatureRenderer extends RenderLayer=26.3 { + /*matrices.rotate(rotation); + *///?} else + matrices.mulPose(rotation); } // Shift array left and insert new value at the start diff --git a/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjModel.java b/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjModel.java index f290e4c..2d611c4 100644 --- a/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjModel.java +++ b/src/main/java/org/saturnclient/impl/cosmetics/obj/ObjModel.java @@ -18,6 +18,7 @@ import net.minecraft.client.renderer.SubmitNodeCollector; //?} else //import net.minecraft.client.renderer.MultiBufferSource; import com.mojang.blaze3d.vertex.PoseStack; +import org.joml.Quaternionf; import net.minecraft.server.packs.resources.Resource; import net.minecraft.server.packs.resources.ResourceManager; import net.minecraft.resources.Identifier; @@ -89,21 +90,29 @@ public class ObjModel { int light, int overlay) { matrices.pushPose(); - matrices.mulPose(com.mojang.math.Axis.XP.rotationDegrees(180.0f)); - matrices.mulPose(com.mojang.math.Axis.YP.rotationDegrees(180.0f)); + rotate(matrices, com.mojang.math.Axis.XP.rotationDegrees(180.0f)); + rotate(matrices, com.mojang.math.Axis.YP.rotationDegrees(180.0f)); if (this.config != null) { matrices.translate(config.transform.x, config.transform.y, config.transform.z); matrices.scale(config.scale.x, config.scale.y, config.scale.z); - matrices.mulPose(com.mojang.math.Axis.XP.rotationDegrees(config.rotation.x)); - matrices.mulPose(com.mojang.math.Axis.YP.rotationDegrees(config.rotation.y)); - matrices.mulPose(com.mojang.math.Axis.ZP.rotationDegrees(config.rotation.z)); + rotate(matrices, com.mojang.math.Axis.XP.rotationDegrees(config.rotation.x)); + rotate(matrices, com.mojang.math.Axis.YP.rotationDegrees(config.rotation.y)); + rotate(matrices, com.mojang.math.Axis.ZP.rotationDegrees(config.rotation.z)); } ObjRenderer.renderObj(this.obj, mtlMap, matrices, output, light, overlay); matrices.popPose(); } + + // 26.3 renamed PoseStack's quaternion mulPose to rotate. + private static void rotate(PoseStack matrices, Quaternionf rotation) { + //? if >=26.3 { + /*matrices.rotate(rotation); + *///?} else + matrices.mulPose(rotation); + } } diff --git a/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java b/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java index 40bab50..4079666 100644 --- a/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java +++ b/src/main/java/org/saturnclient/impl/cosmetics/utils/ShaderUtils.java @@ -26,6 +26,8 @@ import net.minecraft.client.renderer.blockentity.AbstractEndPortalRenderer; import net.minecraft.client.renderer.blockentity.TheEndPortalRenderer; *///?} import net.minecraft.resources.Identifier; +//? if >=26.3 +//import com.mojang.renderpearl.api.pipeline.ColorTargetState; //? if >=26.1 { /*import java.util.HashMap; import java.util.Map; @@ -103,6 +105,9 @@ public class ShaderUtils { .withShaderDefine("NO_CARDINAL_LIGHTING") .withShaderDefine("NO_OVERLAY") .withCull(false) + // From 26.3 the snippet leaves the color target to each pipeline. + //? if >=26.3 + //.withColorTargetState(ColorTargetState.DEFAULT) .build()); private static final Map UNLIT_CUTOUT = new HashMap<>(); *///?} diff --git a/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java b/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java index 1d9017d..5225c90 100644 --- a/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java +++ b/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java @@ -88,7 +88,10 @@ public abstract class MinecraftClientMixin implements MinecraftClientRef { break; case Options: - //? if >=26.1 { + // Only 26.1 and 26.2 take whether a world is open. + //? if >=26.3 { + /*Screens.set(new OptionsScreen(exitTarget, this.options)); + *///?} else if >=26.1 { /*Screens.set(new OptionsScreen(exitTarget, this.options, ((Minecraft) (Object) this).level != null)); *///?} else Screens.set(new OptionsScreen(exitTarget, this.options)); diff --git a/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java b/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java index a2756ed..5be0f5a 100644 --- a/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java +++ b/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java @@ -1,5 +1,9 @@ package org.saturnclient.impl.provider; +// 26.3 uses SDL, not GLFW; Keys converts Saturn's GLFW key codes to its own. +//? if >=26.3 { +/*import com.mojang.blaze3d.platform.InputConstants; +*///?} else import org.lwjgl.glfw.GLFW; import org.saturnclient.common.provider.GLFWProvider; import org.saturnclient.impl.ui.Screens; @@ -8,16 +12,25 @@ import org.saturnclient.saturnclient.SaturnClient; public class GLFWProviderImpl implements GLFWProvider { @Override public boolean isKeyPressed(int key) { + //? if >=26.3 { + /*int gameKey = Keys.toGame(key); + return gameKey >= 0 && InputConstants.isKeyDown(gameKey) && Screens.current() == null; + *///?} else { //? if >=1.21.9 { long window = SaturnClient.client.getWindow().handle(); //?} else //long window = SaturnClient.client.getWindow().getWindow(); return GLFW.glfwGetKey(window, key) == GLFW.GLFW_PRESS && Screens.current() == null; + //?} } @Override public String getKeyName(int key) { + //? if >=26.3 { + /*int gameKey = Keys.toGame(key); + return gameKey < 0 ? null : InputConstants.Type.KEYBOARD.getOrCreate(gameKey).getDisplayName().getString(); + *///?} else return GLFW.glfwGetKeyName(key, GLFW.glfwGetKeyScancode(key)); } } diff --git a/src/main/java/org/saturnclient/impl/provider/Keys.java b/src/main/java/org/saturnclient/impl/provider/Keys.java new file mode 100644 index 0000000..f04ff88 --- /dev/null +++ b/src/main/java/org/saturnclient/impl/provider/Keys.java @@ -0,0 +1,189 @@ +package org.saturnclient.impl.provider; + +//? if >=26.3 { +/*import com.mojang.blaze3d.platform.InputConstants; +import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; +import org.saturnclient.common.provider.GLFWProvider; +*///?} + +/** + * Saturn's key codes are GLFW's, which the config's keybinds store. From 26.3 Minecraft uses SDL, + * whose keys (scancodes), modifiers and mouse buttons are numbered differently, so these convert + * between the two there. Before 26.3 Minecraft's numbers are GLFW's and pass through. + */ +public final class Keys { + private Keys() { + } + + //? if >=26.3 { + /*private static final Int2IntOpenHashMap TO_GAME = new Int2IntOpenHashMap(); + private static final Int2IntOpenHashMap TO_SATURN = new Int2IntOpenHashMap(); + + private static void key(int glfw, int game) { + TO_GAME.put(glfw, game); + TO_SATURN.put(game, glfw); + } + + // GLFW's key codes, and the same keys' constants in 26.3 + static { + TO_GAME.defaultReturnValue(-1); + TO_SATURN.defaultReturnValue(-1); + key(32, InputConstants.KEY_SPACE); + key(39, InputConstants.KEY_APOSTROPHE); + key(44, InputConstants.KEY_COMMA); + key(45, InputConstants.KEY_MINUS); + key(46, InputConstants.KEY_PERIOD); + key(47, InputConstants.KEY_SLASH); + key(48, InputConstants.KEY_0); + key(49, InputConstants.KEY_1); + key(50, InputConstants.KEY_2); + key(51, InputConstants.KEY_3); + key(52, InputConstants.KEY_4); + key(53, InputConstants.KEY_5); + key(54, InputConstants.KEY_6); + key(55, InputConstants.KEY_7); + key(56, InputConstants.KEY_8); + key(57, InputConstants.KEY_9); + key(59, InputConstants.KEY_SEMICOLON); + key(61, InputConstants.KEY_EQUALS); + key(65, InputConstants.KEY_A); + key(66, InputConstants.KEY_B); + key(67, InputConstants.KEY_C); + key(68, InputConstants.KEY_D); + key(69, InputConstants.KEY_E); + key(70, InputConstants.KEY_F); + key(71, InputConstants.KEY_G); + key(72, InputConstants.KEY_H); + key(73, InputConstants.KEY_I); + key(74, InputConstants.KEY_J); + key(75, InputConstants.KEY_K); + key(76, InputConstants.KEY_L); + key(77, InputConstants.KEY_M); + key(78, InputConstants.KEY_N); + key(79, InputConstants.KEY_O); + key(80, InputConstants.KEY_P); + key(81, InputConstants.KEY_Q); + key(82, InputConstants.KEY_R); + key(83, InputConstants.KEY_S); + key(84, InputConstants.KEY_T); + key(85, InputConstants.KEY_U); + key(86, InputConstants.KEY_V); + key(87, InputConstants.KEY_W); + key(88, InputConstants.KEY_X); + key(89, InputConstants.KEY_Y); + key(90, InputConstants.KEY_Z); + key(91, InputConstants.KEY_LBRACKET); + key(92, InputConstants.KEY_BACKSLASH); + key(93, InputConstants.KEY_RBRACKET); + key(96, InputConstants.KEY_GRAVE); + key(256, InputConstants.KEY_ESCAPE); + key(257, InputConstants.KEY_RETURN); + key(258, InputConstants.KEY_TAB); + key(259, InputConstants.KEY_BACKSPACE); + key(260, InputConstants.KEY_INSERT); + key(261, InputConstants.KEY_DELETE); + key(262, InputConstants.KEY_RIGHT); + key(263, InputConstants.KEY_LEFT); + key(264, InputConstants.KEY_DOWN); + key(265, InputConstants.KEY_UP); + key(266, InputConstants.KEY_PAGEUP); + key(267, InputConstants.KEY_PAGEDOWN); + key(268, InputConstants.KEY_HOME); + key(269, InputConstants.KEY_END); + key(280, InputConstants.KEY_CAPSLOCK); + key(281, InputConstants.KEY_SCROLLLOCK); + key(282, InputConstants.KEY_NUMLOCK); + key(283, InputConstants.KEY_PRINTSCREEN); + key(284, InputConstants.KEY_PAUSE); + key(290, InputConstants.KEY_F1); + key(291, InputConstants.KEY_F2); + key(292, InputConstants.KEY_F3); + key(293, InputConstants.KEY_F4); + key(294, InputConstants.KEY_F5); + key(295, InputConstants.KEY_F6); + key(296, InputConstants.KEY_F7); + key(297, InputConstants.KEY_F8); + key(298, InputConstants.KEY_F9); + key(299, InputConstants.KEY_F10); + key(300, InputConstants.KEY_F11); + key(301, InputConstants.KEY_F12); + key(302, InputConstants.KEY_F13); + key(303, InputConstants.KEY_F14); + key(304, InputConstants.KEY_F15); + key(305, InputConstants.KEY_F16); + key(306, InputConstants.KEY_F17); + key(307, InputConstants.KEY_F18); + key(308, InputConstants.KEY_F19); + key(309, InputConstants.KEY_F20); + key(310, InputConstants.KEY_F21); + key(311, InputConstants.KEY_F22); + key(312, InputConstants.KEY_F23); + key(313, InputConstants.KEY_F24); + key(320, InputConstants.KEY_NUMPAD0); + key(321, InputConstants.KEY_NUMPAD1); + key(322, InputConstants.KEY_NUMPAD2); + key(323, InputConstants.KEY_NUMPAD3); + key(324, InputConstants.KEY_NUMPAD4); + key(325, InputConstants.KEY_NUMPAD5); + key(326, InputConstants.KEY_NUMPAD6); + key(327, InputConstants.KEY_NUMPAD7); + key(328, InputConstants.KEY_NUMPAD8); + key(329, InputConstants.KEY_NUMPAD9); + key(330, InputConstants.KEY_NUMPADCOMMA); + key(332, InputConstants.KEY_MULTIPLY); + key(334, InputConstants.KEY_ADD); + key(335, InputConstants.KEY_NUMPADENTER); + key(336, InputConstants.KEY_NUMPADEQUALS); + key(340, InputConstants.KEY_LSHIFT); + key(341, InputConstants.KEY_LCONTROL); + key(342, InputConstants.KEY_LALT); + key(343, InputConstants.KEY_LGUI); + key(344, InputConstants.KEY_RSHIFT); + key(345, InputConstants.KEY_RCONTROL); + key(346, InputConstants.KEY_RALT); + key(347, InputConstants.KEY_RGUI); + } + *///?} + + /** A Saturn (GLFW) key code as the game's, or -1 */ + public static int toGame(int key) { + //? if >=26.3 { + /*return TO_GAME.get(key); + *///?} else + return key; + } + + /** A key code from the game as Saturn's (GLFW), or -1 */ + public static int toSaturn(int key) { + //? if >=26.3 { + /*return TO_SATURN.get(key); + *///?} else + return key; + } + + /** The game's modifier flags as GLFW's */ + public static int modifiersToSaturn(int modifiers) { + //? if >=26.3 { + /*int glfw = 0; + if ((modifiers & InputConstants.MOD_SHIFT) != 0) glfw |= GLFWProvider.GLFW_MOD_SHIFT; + if ((modifiers & InputConstants.MOD_CONTROL) != 0) glfw |= GLFWProvider.GLFW_MOD_CONTROL; + if ((modifiers & InputConstants.MOD_ALT) != 0) glfw |= GLFWProvider.GLFW_MOD_ALT; + if ((modifiers & InputConstants.MOD_SUPER) != 0) glfw |= GLFWProvider.GLFW_MOD_SUPER; + if ((modifiers & InputConstants.MOD_CAPS_LOCK) != 0) glfw |= GLFWProvider.GLFW_MOD_CAPS_LOCK; + if ((modifiers & InputConstants.MOD_NUM_LOCK) != 0) glfw |= GLFWProvider.GLFW_MOD_NUM_LOCK; + return glfw; + *///?} else + return modifiers; + } + + /** A mouse button from the game as GLFW's (left 0, right 1, middle 2, then the side buttons) */ + public static int mouseButtonToSaturn(int button) { + //? if >=26.3 { + /*if (button == InputConstants.MOUSE_BUTTON_LEFT) return 0; + if (button == InputConstants.MOUSE_BUTTON_RIGHT) return 1; + if (button == InputConstants.MOUSE_BUTTON_MIDDLE) return 2; + return button - 1; + *///?} else + return button; + } +} diff --git a/src/main/java/org/saturnclient/impl/ui/GlassRenderer.java b/src/main/java/org/saturnclient/impl/ui/GlassRenderer.java index d1264fd..0d64b66 100644 --- a/src/main/java/org/saturnclient/impl/ui/GlassRenderer.java +++ b/src/main/java/org/saturnclient/impl/ui/GlassRenderer.java @@ -66,6 +66,9 @@ public final class GlassRenderer { // The transforms block ends with LineWidth before 1.21.11 (see glass.fsh). //? if <1.21.11 //.withShaderDefine("HAS_LINE_WIDTH") + // 26.3 compiles through SPIR-V and moved TextureMat up the transforms block. + //? if >=26.3 + //.withShaderDefine("EXPLICIT_LOCATIONS").withShaderDefine("TEXTURE_MAT_SECOND") .build(); private static final Identifier BLUR = Identifier.withDefaultNamespace("post_effect/blur.json"); @@ -112,7 +115,10 @@ public final class GlassRenderer { TextureTarget backdrop = BACKDROPS.get(blur); if (backdrop == null) { - //? if >=26.2 { + // From 26.3 the depth format picks the depth buffer (none here); 26.2 takes a flag. + //? if >=26.3 { + /*backdrop = new TextureTarget("Saturn glass " + blur, width, height, GpuFormat.RGBA8_UNORM, null); + *///?} else if >=26.2 { /*backdrop = new TextureTarget("Saturn glass " + blur, width, height, false, GpuFormat.RGBA8_UNORM); *///?} else backdrop = new TextureTarget("Saturn glass " + blur, width, height, false); diff --git a/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java b/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java index 68d15a7..82edb5d 100644 --- a/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java +++ b/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java @@ -4,6 +4,7 @@ import java.time.Duration; import java.time.Instant; import org.saturnclient.config.Config; +import org.saturnclient.impl.provider.Keys; import org.saturnclient.ui.RenderScope; import org.saturnclient.ui.SaturnScreen; import org.saturnclient.ui.SaturnScreen.ScreenProvider; @@ -176,7 +177,7 @@ public class SaturnScreenFabric extends Screen implements ScreenProvider { //? if >=1.21.9 { @Override public boolean mouseClicked(MouseButtonEvent click, boolean doubled) { - if (screen.mouseClicked(click.x(), click.y(), click.button())) { + if (screen.mouseClicked(click.x(), click.y(), Keys.mouseButtonToSaturn(click.button()))) { return true; } @@ -186,7 +187,7 @@ public class SaturnScreenFabric extends Screen implements ScreenProvider { @Override public boolean mouseDragged(MouseButtonEvent click, double offsetX, double offsetY) { // offsetX and offsetY are the drag deltas, as mouseDragged's deltaX and deltaY were before 1.21.9. - if (screen.mouseDragged(click.x(), click.y(), click.button(), offsetX, offsetY)) { + if (screen.mouseDragged(click.x(), click.y(), Keys.mouseButtonToSaturn(click.button()), offsetX, offsetY)) { return true; } @@ -195,7 +196,7 @@ public class SaturnScreenFabric extends Screen implements ScreenProvider { @Override public boolean mouseReleased(MouseButtonEvent click) { - if (screen.mouseReleased(click.x(), click.y(), click.button())) { + if (screen.mouseReleased(click.x(), click.y(), Keys.mouseButtonToSaturn(click.button()))) { return true; } @@ -238,6 +239,10 @@ public class SaturnScreenFabric extends Screen implements ScreenProvider { //? if >=1.21.9 { @Override public boolean keyPressed(KeyEvent input) { + // 26.3's key() is SDL's scancode; Saturn's key codes are GLFW's (see Keys). + //? if >=26.3 { + /*if (screen.keyPressed(Keys.toSaturn(input.key()), input.key(), Keys.modifiersToSaturn(input.modifiers()))) { + *///?} else if (screen.keyPressed(input.input(), input.scancode(), input.modifiers())) { return true; } diff --git a/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java b/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java index d304670..1098b15 100644 --- a/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java +++ b/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java @@ -20,7 +20,6 @@ import org.saturnclient.impl.ui.Screens; import org.saturnclient.ui.screens.EmoteWheel; import org.saturnclient.ui.screens.ShiftMenu; -import org.lwjgl.glfw.GLFW; /** * Handles keyboard input events for the Saturn Client. @@ -32,7 +31,7 @@ public class KeyInputHandler { //?} else //private static final String KEY_CATEGORY = "key.category.saturnclient"; private static final String MAIN_MENU_KEY_ID = "key.saturnclient.main_menu"; - private static final int DEFAULT_MENU_KEY = GLFW.GLFW_KEY_RIGHT_SHIFT; + private static final int DEFAULT_MENU_KEY = InputConstants.KEY_RSHIFT; private static KeyMapping mainMenuKeyBinding; public static void register() { @@ -66,10 +65,12 @@ public class KeyInputHandler { // from the screen's own key handling would reopen it on the next tick, since the key is // still down and no screen is open by then. if (Config.openEmoteWheel.wasKeyPressed() - //? if >=1.21.9 { - && !InputConstants.isKeyDown(client.getWindow(), GLFW.GLFW_KEY_F3)) { + //? if >=26.3 { + /*&& !InputConstants.isKeyDown(InputConstants.KEY_F3)) { + *///?} else if >=1.21.9 { + && !InputConstants.isKeyDown(client.getWindow(), InputConstants.KEY_F3)) { //?} else - //&& !InputConstants.isKeyDown(client.getWindow().getWindow(), GLFW.GLFW_KEY_F3)) { + //&& !InputConstants.isKeyDown(client.getWindow().getWindow(), InputConstants.KEY_F3)) { if (Screens.current() == null) { Providers.saturn.getClient().setScreen(new EmoteWheel()); } else if (Screens.current() instanceof SaturnScreenFabric saturnScreen diff --git a/src/main/resources/assets/saturnclient/shaders/core/glass.fsh b/src/main/resources/assets/saturnclient/shaders/core/glass.fsh index e58609c..4d5a0b3 100644 --- a/src/main/resources/assets/saturnclient/shaders/core/glass.fsh +++ b/src/main/resources/assets/saturnclient/shaders/core/glass.fsh @@ -1,16 +1,26 @@ #version 330 +// 26.3 compiles shaders through SPIR-V, which needs every input and output's location. +#ifdef EXPLICIT_LOCATIONS +#extension GL_ARB_separate_shader_objects : require +#endif // Saturn's glass: the blurred game behind the screen, cut to a panel's shape. For 1.21.6 and // later; glass_pre_1_21_6.fsh (with glass.json, the program 1.21.4 loads) is for older versions. // Vanilla's transforms, laid out as the version has them: 1.21.6 to 1.21.10 end with LineWidth, which -// 1.21.11 dropped (GlassRenderer defines HAS_LINE_WIDTH there). Not imported: the include only exists -// from 1.21.6, and 1.21.4 and 1.21.5 still read every shader's imports while loading resources. +// 1.21.11 dropped (GlassRenderer defines HAS_LINE_WIDTH there), and 26.3 moved TextureMat up +// (TEXTURE_MAT_SECOND). Not imported: the include only exists from 1.21.6, and 1.21.4 and 1.21.5 still +// read every shader's imports while loading resources. layout(std140) uniform DynamicTransforms { mat4 ModelViewMat; +#ifdef TEXTURE_MAT_SECOND + mat4 TextureMat; +#endif vec4 ColorModulator; vec3 ModelOffset; +#ifndef TEXTURE_MAT_SECOND mat4 TextureMat; +#endif #ifdef HAS_LINE_WIDTH float LineWidth; #endif @@ -21,10 +31,17 @@ uniform sampler2D Sampler0; // The game behind the screen, blurred, the size of the framebuffer uniform sampler2D Sampler1; +#ifdef EXPLICIT_LOCATIONS +layout(location = 0) in vec2 texCoord0; +layout(location = 1) in vec4 vertexColor; + +layout(location = 0) out vec4 fragColor; +#else in vec2 texCoord0; in vec4 vertexColor; out vec4 fragColor; +#endif void main() { float mask = texture(Sampler0, texCoord0).a * vertexColor.a; diff --git a/stonecutter.gradle.kts b/stonecutter.gradle.kts index f6092e1..2235272 100644 --- a/stonecutter.gradle.kts +++ b/stonecutter.gradle.kts @@ -20,6 +20,10 @@ stonecutter parameters { Triple("26.1", "submitText", "addText"), Triple("26.1", "submitItem", "addItem"), Triple("26.1", "submitPicturesInPictureState", "addPicturesInPictureState"), + // 26.3 moves Blaze3D's API to renderpearl + Triple("26.3", "com.mojang.blaze3d.GpuFormat", "com.mojang.renderpearl.api.GpuFormat"), + Triple("26.3", "com.mojang.blaze3d.pipeline.RenderPipeline", "com.mojang.renderpearl.api.pipeline.RenderPipeline"), + Triple("26.3", "com.mojang.blaze3d.textures", "com.mojang.renderpearl.api.textures"), )) { replacements.regex(eval(current.version, ">=$since")) { replace("\\b${Regex.escape(old)}\\b", new, "\\b${Regex.escape(new)}\\b", old) diff --git a/versions/26.3/gradle.properties b/versions/26.3/gradle.properties new file mode 100644 index 0000000..91f10fd --- /dev/null +++ b/versions/26.3/gradle.properties @@ -0,0 +1,17 @@ +# Done to increase the memory available to gradle. +org.gradle.jvmargs=-Xmx1G +org.gradle.parallel=true + +# IntelliJ IDEA is not yet fully compatible with configuration cache, see: https://github.com/FabricMC/fabric-loom/issues/1349 +org.gradle.configuration-cache=false + +# Fabric Properties +# check these on https://fabricmc.net/develop +minecraft_version=26.3 +loader_version=0.19.5 + +fabric_api_version=0.161.0+26.3 + +# Mod Properties +maven_group=org.saturnclient +archives_base_name=saturn-client