diff --git a/README.MD b/README.MD index a13c2d1..725631c 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 and 26.1**, 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, 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. ## Features diff --git a/VERSION_GUIDE.md b/VERSION_GUIDE.md index 431f8e0..e2d0624 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, and 26.1) 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, 26.1 and 26.2) 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,7 @@ 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. 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. 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. 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. @@ -50,7 +50,7 @@ When a newer version leaves something out that an older one implements, keep the A whole class that only exists for some versions (such as `MatrixStackMixin`, which only makes sense before 1.21.6's GUI rewrite) can keep an empty class body on the other versions. Before splitting a class like that, look for a hook that works on every version: nametags used to hook label rendering, which 1.21.9 changed, and now replace the name while the render state is built (`LivingEntityRendererMixin`), with no version condition at all. An empty mixin changes nothing, and it keeps the mixin configs the same for every version, since JSON can't hold version comments. -Inactive code sits inside a `/* … */` comment, so it can't contain `/* … */` comments itself: use `//` comments in code that's only active for some versions. For the same reason, don't nest multi-line version blocks; use `//?} else if {` for more than two version ranges, as in `PlayerEntityRendererMixin` and `SaturnRenderState`. +Inactive code sits inside a `/* … */` comment, so it can't contain `/* … */` comments itself: use `//` comments in code that's only active for some versions. Version blocks can nest (Stonecutter writes an inactive block inside another as `/^ … ^/`, as in `GlassRenderer`), but for more than two ranges of the same thing, prefer `//?} else if {`, as in `PlayerEntityRendererMixin` and `SaturnRenderState`. - `./gradlew "Set active project to "` (or the Stonecutter IntelliJ plugin) rewrites `src/` so that version's code is the uncommented one, for editing it in the IDE. - `./gradlew "Reset active project"` switches back to 1.21.11. **Run it before committing**, so `src/` is always committed with 1.21.11 active. diff --git a/common b/common index 6537385..e8f686b 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 653738568a9c7b1f9ab76bd86eb01cedc166f057 +Subproject commit e8f686b2d3dfdb609cf5104927a7d0455c2214bb diff --git a/settings.gradle.kts b/settings.gradle.kts index 26c4dc0..2166843 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.1", "26.2", ) stonecutter { diff --git a/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java b/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java index a8f8bbe..9b96307 100644 --- a/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java +++ b/src/main/java/org/saturnclient/impl/features/mixins/render/GameRendererMixin.java @@ -8,6 +8,8 @@ import net.minecraft.client.renderer.GameRenderer; //? if >=1.21.6 import org.saturnclient.impl.ui.SaturnScreenFabric; +//? if >=1.21.6 +import org.saturnclient.impl.ui.Screens; import org.saturnclient.impl.features.render.ZoomFov; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -53,7 +55,7 @@ public class GameRendererMixin { @Redirect(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Options;getMenuBackgroundBlurriness()I")) private int useSaturnBlur(Options options) { - if (Minecraft.getInstance().screen instanceof SaturnScreenFabric saturnScreen) { + if (Screens.current() instanceof SaturnScreenFabric saturnScreen) { return saturnScreen.screen.getBackgroundBlur(); } diff --git a/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java b/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java index b827d0d..16953cb 100644 --- a/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java +++ b/src/main/java/org/saturnclient/impl/features/mixins/render/RenderMixin.java @@ -2,11 +2,15 @@ package org.saturnclient.impl.features.mixins.render; import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphics; +//? if >=26.2 { +/*import net.minecraft.client.gui.Hud; +*///?} else import net.minecraft.client.gui.Gui; import net.minecraft.client.DeltaTracker; import org.saturnclient.impl.ui.RenderScopeImpl; import org.saturnclient.impl.ui.SaturnScreenFabric; +import org.saturnclient.impl.ui.Screens; import org.saturnclient.mod.HudMod; import org.saturnclient.mod.Mod; import org.saturnclient.mod.ModLayout; @@ -37,6 +41,10 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; * {@link SaturnScreenFabric} / {@link HudEditor} pair; that is * unchanged infrastructure. */ +// The HUD is drawn by Hud from 26.2 (by Gui before). +//? if >=26.2 { +/*@Mixin(Hud.class) +*///?} else @Mixin(Gui.class) public class RenderMixin { @@ -51,7 +59,7 @@ public class RenderMixin { // can draw its own preview layout without double-drawing. if (textRenderer == null) return; - if (SaturnClient.client.screen instanceof SaturnScreenFabric f + if (Screens.current() instanceof SaturnScreenFabric f && f.screen instanceof HudEditor) return; diff --git a/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java b/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java index b34a78e..1d9017d 100644 --- a/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java +++ b/src/main/java/org/saturnclient/impl/mixins/MinecraftClientMixin.java @@ -4,11 +4,11 @@ import java.io.File; import java.io.InputStream; import java.util.UUID; -import org.jetbrains.annotations.Nullable; import org.saturnclient.common.ref.asset.IdentifierRef; import org.saturnclient.common.ref.game.MinecraftClientRef; import org.saturnclient.common.ref.render.WindowRef; import org.saturnclient.impl.ui.SaturnScreenFabric; +import org.saturnclient.impl.ui.Screens; import org.saturnclient.ui.SaturnScreen; import org.saturnclient.ui.screens.TitleMenu; import org.spongepowered.asm.mixin.Mixin; @@ -16,7 +16,6 @@ import org.spongepowered.asm.mixin.Shadow; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.multiplayer.JoinMultiplayerScreen; import net.minecraft.client.gui.screens.options.OptionsScreen; import net.minecraft.client.gui.screens.worldselection.SelectWorldScreen; @@ -43,9 +42,6 @@ public abstract class MinecraftClientMixin implements MinecraftClientRef { @Shadow private User user; - @Shadow - public abstract void setScreen(@Nullable Screen screen); - @Shadow public abstract void stop(); @@ -75,7 +71,7 @@ public abstract class MinecraftClientMixin implements MinecraftClientRef { @Override public void setScreen(SaturnScreen screen) { - this.setScreen(new SaturnScreenFabric(screen)); + Screens.set(new SaturnScreenFabric(screen)); } @Override @@ -84,18 +80,18 @@ public abstract class MinecraftClientMixin implements MinecraftClientRef { switch (screen) { case SelectWorld: - this.setScreen(new SelectWorldScreen(exitTarget)); + Screens.set(new SelectWorldScreen(exitTarget)); break; case Multiplayer: - this.setScreen(new JoinMultiplayerScreen(exitTarget)); + Screens.set(new JoinMultiplayerScreen(exitTarget)); break; case Options: //? if >=26.1 { - /*this.setScreen(new OptionsScreen(exitTarget, this.options, ((Minecraft) (Object) this).level != null)); + /*Screens.set(new OptionsScreen(exitTarget, this.options, ((Minecraft) (Object) this).level != null)); *///?} else - this.setScreen(new OptionsScreen(exitTarget, this.options)); + Screens.set(new OptionsScreen(exitTarget, this.options)); break; } } diff --git a/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java b/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java index 1d06413..9c9f9b3 100644 --- a/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java +++ b/src/main/java/org/saturnclient/impl/mixins/StatusEffectMixin.java @@ -8,6 +8,9 @@ import org.saturnclient.common.ref.game.EffectRef; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; +//? if >=26.2 { +/*import net.minecraft.client.gui.Hud; +*///?} else import net.minecraft.client.gui.Gui; import net.minecraft.world.effect.MobEffect; import net.minecraft.world.effect.MobEffectInstance; @@ -55,6 +58,9 @@ public abstract class StatusEffectMixin implements EffectRef { //? if >=1.21.6 { @Override public IdentifierRef getIconId() { + //? if >=26.2 { + /*Identifier id = Hud.getMobEffectSprite(getEffect()); + *///?} else Identifier id = Gui.getMobEffectSprite(getEffect()); return IdentifierRef.of(id.getNamespace(), "textures/" + id.getPath() + ".png"); diff --git a/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java b/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java index 85eb7ba..a2756ed 100644 --- a/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java +++ b/src/main/java/org/saturnclient/impl/provider/GLFWProviderImpl.java @@ -2,6 +2,7 @@ package org.saturnclient.impl.provider; import org.lwjgl.glfw.GLFW; import org.saturnclient.common.provider.GLFWProvider; +import org.saturnclient.impl.ui.Screens; import org.saturnclient.saturnclient.SaturnClient; public class GLFWProviderImpl implements GLFWProvider { @@ -12,7 +13,7 @@ public class GLFWProviderImpl implements GLFWProvider { //?} else //long window = SaturnClient.client.getWindow().getWindow(); return GLFW.glfwGetKey(window, key) == GLFW.GLFW_PRESS - && SaturnClient.client.screen == null; + && Screens.current() == null; } @Override diff --git a/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java b/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java index e76c79d..a000892 100644 --- a/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java +++ b/src/main/java/org/saturnclient/impl/provider/SaturnProviderImpl.java @@ -86,8 +86,13 @@ public class SaturnProviderImpl implements SaturnProvider { @Override public void showWarning(String title, String message) { Minecraft client = Minecraft.getInstance(); + //? if >=26.2 { + /*client.execute(() -> SystemToast.add(client.gui.toastManager(), WARNING_TOAST, Component.literal(title), + Component.literal(message))); + *///?} else { client.execute(() -> client.getToastManager().addToast( SystemToast.multiline(client, WARNING_TOAST, Component.literal(title), Component.literal(message)))); + //?} } @Override diff --git a/src/main/java/org/saturnclient/impl/ui/GlassRenderer.java b/src/main/java/org/saturnclient/impl/ui/GlassRenderer.java index fbcd17a..d1264fd 100644 --- a/src/main/java/org/saturnclient/impl/ui/GlassRenderer.java +++ b/src/main/java/org/saturnclient/impl/ui/GlassRenderer.java @@ -17,7 +17,11 @@ package org.saturnclient.impl.ui; //? if >=1.21.6 { import java.io.Reader; import java.util.HashMap; +//? if >=26.1 +//import java.util.LinkedHashSet; import java.util.Map; +//? if >=26.1 +//import java.util.Set; import com.google.gson.JsonElement; import com.google.gson.JsonObject; @@ -37,6 +41,10 @@ import net.minecraft.client.renderer.PostChain; import net.minecraft.client.renderer.RenderPipelines; import com.mojang.blaze3d.pipeline.TextureTarget; import net.minecraft.client.renderer.LevelTargetBundle; +//? if >=26.2 { +/*import com.mojang.blaze3d.GpuFormat; +import net.minecraft.client.renderer.BindGroupLayouts; +*///?} //? if >=26.1 { /*import net.minecraft.client.renderer.Projection; import net.minecraft.client.renderer.ProjectionMatrixBuffer; @@ -51,6 +59,9 @@ public final class GlassRenderer { public static final RenderPipeline PIPELINE = RenderPipeline.builder(RenderPipelines.GUI_TEXTURED_SNIPPET) .withLocation(Identifier.fromNamespaceAndPath("saturnclient", "pipeline/glass")) .withFragmentShader(Identifier.fromNamespaceAndPath("saturnclient", "core/glass")) + //? if >=26.2 { + /*.withBindGroupLayout(BindGroupLayouts.SAMPLER1) + *///?} else .withSampler("Sampler1") // The transforms block ends with LineWidth before 1.21.11 (see glass.fsh). //? if <1.21.11 @@ -78,15 +89,32 @@ public final class GlassRenderer { private GlassRenderer() { } + // From 26.1 the GUI is built before the frame's world is drawn, so the main framebuffer still + // holds the last frame, glass included. The copies wait until the GUI renderer is about to draw + // (GuiRendererMixin), when it holds this frame's world and panorama. + //? if >=26.1 { + /*private static final Set PENDING = new LinkedHashSet<>(); + *///?} + + private static RenderTarget mainTarget() { + //? if >=26.2 { + /*return SaturnClient.client.gameRenderer.mainRenderTarget(); + *///?} else + return SaturnClient.client.getMainRenderTarget(); + } + // Copies the main framebuffer and blurs the copy by blur. Call once a frame for each blur, while // the screen builds its GUI, before drawing glass with it. public static void captureBackdrop(int blur) { - RenderTarget main = SaturnClient.client.getMainRenderTarget(); + RenderTarget main = mainTarget(); int width = main.width; int height = main.height; TextureTarget backdrop = BACKDROPS.get(blur); if (backdrop == null) { + //? 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); BACKDROPS.put(blur, backdrop); } else if (backdrop.width != width || backdrop.height != height) { @@ -95,6 +123,29 @@ public final class GlassRenderer { //? if <1.21.11 //backdrop.getColorTexture().setTextureFilter(FilterMode.LINEAR, false); + //? if >=26.1 { + /*PENDING.add(blur); + } + + // Copies and blurs the backdrops the GUI asked for this frame. GuiRendererMixin calls it once the + // world and the panorama are drawn, before the GUI. + public static void blurPendingBackdrops() { + RenderTarget main = mainTarget(); + for (int blur : PENDING) { + TextureTarget backdrop = BACKDROPS.get(blur); + // The GUI already refers to the backdrop's texture, so after a resize it keeps the last + // frame's until the next one. + if (backdrop != null && backdrop.width == main.width && backdrop.height == main.height) { + blurBackdrop(main, backdrop, blur); + } + } + PENDING.clear(); + } + + private static void blurBackdrop(RenderTarget main, TextureTarget backdrop, int blur) { + int width = main.width; + int height = main.height; + *///?} RenderSystem.getDevice().createCommandEncoder().copyTextureToTexture( main.getColorTexture(), backdrop.getColorTexture(), 0, 0, 0, 0, 0, width, height); @@ -119,6 +170,9 @@ public final class GlassRenderer { private static void release(int kept) { BACKDROPS.entrySet().removeIf(entry -> { boolean unused = entry.getKey() != kept && !isSet(entry.getKey()); + // The GUI already refers to this frame's pending backdrops. + //? if >=26.1 + //unused &= !PENDING.contains(entry.getKey()); if (unused) { entry.getValue().destroyBuffers(); } @@ -126,6 +180,9 @@ public final class GlassRenderer { }); BLURS.entrySet().removeIf(entry -> { boolean unused = entry.getKey() != kept && !isSet(entry.getKey()); + // The GUI already refers to this frame's pending backdrops. + //? if >=26.1 + //unused &= !PENDING.contains(entry.getKey()); if (unused && entry.getValue() != null) { entry.getValue().close(); } diff --git a/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java b/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java index ede40e2..68d15a7 100644 --- a/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java +++ b/src/main/java/org/saturnclient/impl/ui/SaturnScreenFabric.java @@ -146,7 +146,9 @@ public class SaturnScreenFabric extends Screen implements ScreenProvider { // The panorama renderer has no opacity (and takes no delta) from 1.21.6, so it's drawn fully // opaque. if (isShowingPanorama()) { - //? if >=26.1 { + //? if >=26.2 { + /*ROTATING_PANORAMA_RENDERER.extractRenderState(context, this.width, this.height); + *///?} else if >=26.1 { /*ROTATING_PANORAMA_RENDERER.extractRenderState(context, this.width, this.height, true); *///?} else ROTATING_PANORAMA_RENDERER.render(context, this.width, this.height, true); diff --git a/src/main/java/org/saturnclient/impl/ui/Screens.java b/src/main/java/org/saturnclient/impl/ui/Screens.java new file mode 100644 index 0000000..24ca159 --- /dev/null +++ b/src/main/java/org/saturnclient/impl/ui/Screens.java @@ -0,0 +1,33 @@ +package org.saturnclient.impl.ui; + +import org.jetbrains.annotations.Nullable; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screens.Screen; + +/** The open screen and overlay, which Minecraft holds before 26.2 and its Gui from 26.2. */ +public final class Screens { + private Screens() { + } + + public static @Nullable Screen current() { + //? if >=26.2 { + /*return Minecraft.getInstance().gui.screen(); + *///?} else + return Minecraft.getInstance().screen; + } + + public static void set(@Nullable Screen screen) { + //? if >=26.2 { + /*Minecraft.getInstance().gui.setScreen(screen); + *///?} else + Minecraft.getInstance().setScreen(screen); + } + + public static void clearOverlay() { + //? if >=26.2 { + /*Minecraft.getInstance().gui.setOverlay(null); + *///?} else + Minecraft.getInstance().setOverlay(null); + } +} diff --git a/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java b/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java index bd5bdbb..d304670 100644 --- a/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java +++ b/src/main/java/org/saturnclient/saturnclient/event/KeyInputHandler.java @@ -16,6 +16,7 @@ import org.saturnclient.common.provider.Providers; import org.saturnclient.client.ServiceClient; import org.saturnclient.emotes.fabric.Emotes; import org.saturnclient.impl.ui.SaturnScreenFabric; +import org.saturnclient.impl.ui.Screens; import org.saturnclient.ui.screens.EmoteWheel; import org.saturnclient.ui.screens.ShiftMenu; @@ -69,9 +70,9 @@ public class KeyInputHandler { && !InputConstants.isKeyDown(client.getWindow(), GLFW.GLFW_KEY_F3)) { //?} else //&& !InputConstants.isKeyDown(client.getWindow().getWindow(), GLFW.GLFW_KEY_F3)) { - if (client.screen == null) { + if (Screens.current() == null) { Providers.saturn.getClient().setScreen(new EmoteWheel()); - } else if (client.screen instanceof SaturnScreenFabric saturnScreen + } else if (Screens.current() instanceof SaturnScreenFabric saturnScreen && saturnScreen.screen instanceof EmoteWheel) { saturnScreen.onClose(); } diff --git a/src/main/java/org/saturnclient/saturnclient/mixin/GuiRendererMixin.java b/src/main/java/org/saturnclient/saturnclient/mixin/GuiRendererMixin.java index 2cdd373..3181893 100644 --- a/src/main/java/org/saturnclient/saturnclient/mixin/GuiRendererMixin.java +++ b/src/main/java/org/saturnclient/saturnclient/mixin/GuiRendererMixin.java @@ -3,18 +3,22 @@ package org.saturnclient.saturnclient.mixin; //? if >=26.1 { /*import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; -import net.minecraft.client.Minecraft; import net.minecraft.client.gui.render.GuiRenderer; import net.minecraft.client.renderer.CubeMap; +import org.saturnclient.impl.ui.GlassRenderer; import org.saturnclient.impl.ui.SaturnScreenFabric; +import org.saturnclient.impl.ui.Screens; import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; *///?} else import net.minecraft.client.Minecraft; import org.spongepowered.asm.mixin.Mixin; /** * From 26.1 GuiRenderer draws the menu panorama from its own cube map, which is vanilla's. While a - * Saturn screen is open, this draws Saturn's panorama instead. Before 26.1 SaturnScreenFabric draws + * Saturn screen is open, this draws Saturn's panorama instead. It also blurs the glass backdrops + * once the panorama is drawn. Before 26.1 SaturnScreenFabric draws * the panorama itself, so this mixin is empty there, and it targets Minecraft because GuiRenderer * doesn't exist before 1.21.6. It stays registered, keeping saturnclient.mixins.json the same for * every version. @@ -24,9 +28,16 @@ import org.spongepowered.asm.mixin.Mixin; public class GuiRendererMixin { @WrapOperation(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/CubeMap;render(FF)V")) private void saturn$drawSaturnPanorama(CubeMap cubeMap, float xRot, float yRot, Operation original) { - boolean saturnScreen = Minecraft.getInstance().screen instanceof SaturnScreenFabric; + boolean saturnScreen = Screens.current() instanceof SaturnScreenFabric; original.call(saturnScreen ? SaturnScreenFabric.PANORAMA_RENDERER : cubeMap, xRot, yRot); } + + // The glass backdrops are copied here, with the frame's world and panorama drawn and the GUI not + // yet: the GUI is built before the frame is drawn (see GlassRenderer). + @Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/render/GuiRenderer;prepare()V")) + private void saturn$blurGlassBackdrops(CallbackInfo ci) { + GlassRenderer.blurPendingBackdrops(); + } } *///?} else { @Mixin(Minecraft.class) diff --git a/src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java b/src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java index e5e5624..ab68586 100644 --- a/src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java +++ b/src/main/java/org/saturnclient/saturnclient/mixin/SetScreenMixin.java @@ -8,9 +8,15 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.ModifyVariable; import net.minecraft.client.Minecraft; +//? if >=26.2 +//import net.minecraft.client.gui.Gui; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.TitleScreen; +// Screens are opened through Gui from 26.2 (through Minecraft before). +//? if >=26.2 { +/*@Mixin(Gui.class) +*///?} else @Mixin(Minecraft.class) public class SetScreenMixin { @ModifyVariable(method = "setScreen", at = @At("HEAD"), argsOnly = true) @@ -18,7 +24,7 @@ public class SetScreenMixin { if (Config.saturnTitleScreen.value) { if (screen instanceof TitleScreen) return new SaturnScreenFabric(new TitleMenu()); - if (screen == null && ((Minecraft) (Object) this).level == null) + if (screen == null && Minecraft.getInstance().level == null) return new SaturnScreenFabric(new TitleMenu()); } diff --git a/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java b/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java index 791a20f..340a1fd 100644 --- a/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java +++ b/src/main/java/org/saturnclient/saturnclient/mixin/SplashOverlayMixin.java @@ -1,5 +1,7 @@ package org.saturnclient.saturnclient.mixin; +import org.saturnclient.impl.ui.Screens; + import java.util.Optional; import java.util.function.Consumer; @@ -110,7 +112,7 @@ public abstract class SplashOverlayMixin { // Remove overlay after fade-out completes if (fadeOutProgress >= 2.0F) { - minecraft.setOverlay(null); + Screens.clearOverlay(); } // Handle reload completion and exceptions @@ -118,11 +120,11 @@ public abstract class SplashOverlayMixin { } private void renderCurrentScreen(GuiGraphics context, int mouseX, int mouseY, float delta) { - if (minecraft.screen != null) { + if (Screens.current() != null) { //? if >=26.1 { - /*minecraft.screen.extractRenderState(context, mouseX, mouseY, delta); + /*Screens.current().extractRenderState(context, mouseX, mouseY, delta); *///?} else - minecraft.screen.render(context, mouseX, mouseY, delta); + Screens.current().render(context, mouseX, mouseY, delta); } } @@ -173,11 +175,11 @@ public abstract class SplashOverlayMixin { //? if >=1.21.11 Window window = minecraft.getWindow(); - if (minecraft.screen != null) { + if (Screens.current() != null) { //? if >=1.21.11 { - minecraft.screen.init(window.getGuiScaledWidth(), window.getGuiScaledHeight()); + Screens.current().init(window.getGuiScaledWidth(), window.getGuiScaledHeight()); //?} else - //minecraft.screen.init(minecraft, context.guiWidth(), context.guiHeight()); + //Screens.current().init(minecraft, context.guiWidth(), context.guiHeight()); } } } diff --git a/versions/26.2/gradle.properties b/versions/26.2/gradle.properties new file mode 100644 index 0000000..9e3e1ba --- /dev/null +++ b/versions/26.2/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.2 +loader_version=0.19.5 + +fabric_api_version=0.161.0+26.2 + +# Mod Properties +maven_group=org.saturnclient +archives_base_name=saturn-client