9 Commits

Author SHA1 Message Date
Martin Prokoph
695fa67270 feat: various improvements
- Update to MidnightLib 1.7.0 and use its features to make the config screen more reliable
- Fix background gradient being opaque briefly when fading out while not in a world
- Fix 1.21.5 compat (still compatible with 1.21.4 as well :D)
2025-03-28 23:35:46 +01:00
Martin Prokoph
5f9738da38 fix: add null-check for Minecraft options
- Fixes #119
2025-02-02 21:00:03 +01:00
Martin Prokoph
881709c165 readme: remove duplicate banner 2025-01-27 16:39:08 +01:00
Martin Prokoph
50ed77006d chore: bump version 2025-01-27 12:24:13 +01:00
Martin Prokoph
e99572eb4d fix: crash in production when opening config screen 2025-01-27 12:23:07 +01:00
Martin Prokoph
f7465ee08e feat: title screen blur
- Also fix config changes not being saved
2025-01-25 18:53:32 +01:00
Martin Prokoph
75bfeb2ce3 feat: add mirror of blur radius to config screen
- The blur radius can normally be configured in Minecraft's Accessibility settings. However, this has caused confusion for some users, so it can now also be configured via the config screen.
2025-01-20 16:44:35 +01:00
Martin Prokoph
e5c2a542f4 fix: container blur not working on NeoForge 2025-01-14 11:50:04 +01:00
Martin Prokoph
a13cdd11a7 Update dependencies to 1.21.4 2024-12-08 18:11:51 +01:00
16 changed files with 149 additions and 39 deletions

View File

@@ -1,5 +1,3 @@
![Banner art for the mod Blur+](https://i.ibb.co/GM4HVDC/PoBrnNM.png)
Ever thought that the world behind your inventory was just too distracting? Ever thought that the world behind your inventory was just too distracting?
Or that the default Minecraft blur effect is just too boring? Or that the default Minecraft blur effect is just too boring?
Then this mod is just right for you! Then this mod is just right for you!

View File

@@ -3,6 +3,7 @@ package eu.midnightdust.blur;
import eu.midnightdust.blur.config.BlurConfig; import eu.midnightdust.blur.config.BlurConfig;
import eu.midnightdust.blur.util.RainbowColor; import eu.midnightdust.blur.util.RainbowColor;
import eu.midnightdust.lib.util.MidnightColorUtil; import eu.midnightdust.lib.util.MidnightColorUtil;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.DrawContext;
import org.joml.Math; import org.joml.Math;
import org.joml.Matrix4f; import org.joml.Matrix4f;
@@ -15,12 +16,29 @@ import static eu.midnightdust.blur.util.RainbowColor.hue;
import static eu.midnightdust.blur.util.RainbowColor.hue2; import static eu.midnightdust.blur.util.RainbowColor.hue2;
public class Blur { public class Blur {
public static final String MOD_ID = "blur";
public static void init() { public static void init() {
BlurConfig.init("blur", BlurConfig.class); BlurConfig.init(MOD_ID, BlurConfig.class);
} }
public static boolean doFade = false; public static boolean doFade = false;
static float lastDelta;
public static void onRender(DrawContext context, int width, int height, MinecraftClient client, float delta) {
if (!BlurInfo.doTest && BlurInfo.screenChanged) { // After the tests for blur and background color have been completed
Blur.onScreenChange();
BlurInfo.screenChanged = false;
}
if (BlurInfo.start >= 0 && !BlurInfo.screenHasBlur && BlurInfo.prevScreenHasBlur) { // Fade out in non-blurred screens
client.gameRenderer.renderBlur();
if (BlurInfo.prevScreenHasBackground && BlurConfig.useGradient && lastDelta != delta) Blur.renderRotatedGradient(context, width, height);
lastDelta = delta;
}
BlurInfo.doTest = false; // Set the test state to completed, as tests will happen in the same tick.
}
public static void onScreenChange() { public static void onScreenChange() {
if (screenHasBlur) { if (screenHasBlur) {
if (doFade) { if (doFade) {
@@ -61,10 +79,7 @@ public class Blur {
int b = (col.getRGB() >> 8) & 0xFF; int b = (col.getRGB() >> 8) & 0xFF;
int g = col.getRGB() & 0xFF; int g = col.getRGB() & 0xFF;
float prog = progress; float prog = progress;
a *= prog; a *= prog; r *= prog; g *= prog; b *= prog;
r *= prog;
g *= prog;
b *= prog;
return a << 24 | r << 16 | b << 8 | g; return a << 24 | r << 16 | b << 8 | g;
} }
public static int getRotation() { public static int getRotation() {

View File

@@ -2,6 +2,7 @@ package eu.midnightdust.blur.config;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import eu.midnightdust.lib.config.MidnightConfig; import eu.midnightdust.lib.config.MidnightConfig;
import net.minecraft.client.MinecraftClient;
import java.util.List; import java.util.List;
import java.util.function.Function; import java.util.function.Function;
@@ -16,22 +17,34 @@ public class BlurConfig extends MidnightConfig {
@Entry(category = SCREENS) @Entry(category = SCREENS)
public static boolean blurContainers = true; public static boolean blurContainers = true;
@Entry(category = SCREENS)
public static boolean blurTitleScreen = false;
@Condition(requiredOption = "blurTitleScreen", visibleButLocked = true)
@Entry(category = SCREENS)
public static boolean darkenTitleScreen = false;
@Entry(category = ANIMATIONS, min = 0, max = 2000, isSlider = true) @Entry(category = ANIMATIONS, min = 0, max = 2000, isSlider = true)
public static int fadeTimeMillis = 300; public static int fadeTimeMillis = 300;
@Entry(category = ANIMATIONS, min = 0, max = 2000, isSlider = true) @Entry(category = ANIMATIONS, min = 0, max = 2000, isSlider = true)
public static int fadeOutTimeMillis = 300; public static int fadeOutTimeMillis = 300;
@Entry(category = ANIMATIONS) @Entry(category = ANIMATIONS)
public static BlurConfig.Easing animationCurve = Easing.FLAT; public static BlurConfig.Easing animationCurve = Easing.FLAT;
@Entry(category = STYLE, isSlider = true, min = 0, max = 20)
public static int radius = 5;
@Entry(category = STYLE) @Entry(category = STYLE)
public static boolean useGradient = true; public static boolean useGradient = true;
@Condition(requiredOption = "useGradient", visibleButLocked = true)
@Entry(category = STYLE, isColor = true, width = 7, min = 7) @Entry(category = STYLE, isColor = true, width = 7, min = 7)
public static String gradientStart = "#000000"; public static String gradientStart = "#000000";
@Condition(requiredOption = "useGradient", visibleButLocked = true)
@Entry(category = STYLE, isSlider = true, min = 0, max = 255) @Entry(category = STYLE, isSlider = true, min = 0, max = 255)
public static int gradientStartAlpha = 75; public static int gradientStartAlpha = 75;
@Condition(requiredOption = "useGradient", visibleButLocked = true)
@Entry(category = STYLE, isColor = true, width = 7, min = 7) @Entry(category = STYLE, isColor = true, width = 7, min = 7)
public static String gradientEnd = "#000000"; public static String gradientEnd = "#000000";
@Condition(requiredOption = "useGradient", visibleButLocked = true)
@Entry(category = STYLE, isSlider = true, min = 0, max = 255) @Entry(category = STYLE, isSlider = true, min = 0, max = 255)
public static int gradientEndAlpha = 75; public static int gradientEndAlpha = 75;
@Condition(requiredOption = "useGradient", visibleButLocked = true)
@Entry(category = STYLE, isSlider = true, min = 0, max = 360) @Entry(category = STYLE, isSlider = true, min = 0, max = 360)
public static int gradientRotation = 0; public static int gradientRotation = 0;
@Entry(category = STYLE) @Entry(category = STYLE)
@@ -43,6 +56,13 @@ public class BlurConfig extends MidnightConfig {
@Entry(category = SCREENS) // Screens where the vanilla blur effect should be force disabled @Entry(category = SCREENS) // Screens where the vanilla blur effect should be force disabled
public static List<String> forceDisabledScreens = Lists.newArrayList(); public static List<String> forceDisabledScreens = Lists.newArrayList();
@Override
public void writeChanges(String modid) {
super.writeChanges(modid);
if (MinecraftClient.getInstance().options != null)
MinecraftClient.getInstance().options.getMenuBackgroundBlurriness().setValue(radius);
}
public enum Easing { public enum Easing {
// Based on https://gist.github.com/dev-hydrogen/21a66f83f0386123e0c0acf107254843 // Based on https://gist.github.com/dev-hydrogen/21a66f83f0386123e0c0acf107254843
// Thank you very much! // Thank you very much!

View File

@@ -1,6 +1,8 @@
package eu.midnightdust.blur.mixin; package eu.midnightdust.blur.mixin;
import eu.midnightdust.blur.Blur;
import eu.midnightdust.blur.config.BlurConfig; import eu.midnightdust.blur.config.BlurConfig;
import eu.midnightdust.lib.util.PlatformFunctions;
import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.ingame.HandledScreen; import net.minecraft.client.gui.screen.ingame.HandledScreen;
@@ -20,4 +22,8 @@ public class MixinHandledScreen extends Screen {
private void blur$renderContainerBlur(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) { // Applies the blur effect in containers (Inventory, Chest, etc.) private void blur$renderContainerBlur(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) { // Applies the blur effect in containers (Inventory, Chest, etc.)
if (BlurConfig.blurContainers) this.applyBlur(); if (BlurConfig.blurContainers) this.applyBlur();
} }
@Inject(at = @At("HEAD"), method = "render")
public void blur$processScreenChange(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) {
if (PlatformFunctions.getPlatformName().equals("neoforge")) Blur.onRender(context, width, height, this.client, delta);
}
} }

View File

@@ -23,7 +23,6 @@ public class MixinInGameHud {
BlurInfo.doTest = false; BlurInfo.doTest = false;
BlurInfo.screenChanged = false; BlurInfo.screenChanged = false;
this.client.gameRenderer.renderBlur(); this.client.gameRenderer.renderBlur();
this.client.getFramebuffer().beginWrite(false);
if (BlurInfo.prevScreenHasBackground) Blur.renderRotatedGradient(context, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight()); if (BlurInfo.prevScreenHasBackground) Blur.renderRotatedGradient(context, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight());
} }

View File

@@ -0,0 +1,26 @@
package eu.midnightdust.blur.mixin;
import eu.midnightdust.blur.Blur;
import eu.midnightdust.lib.config.MidnightConfig;
import net.minecraft.client.MinecraftClient;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Objects;
@Mixin(value = MidnightConfig.EntryInfo.class, remap = false)
public abstract class MixinMidnightConfig$EntryInfo {
@Shadow @Final public String modid;
@Shadow @Final public String fieldName;
@Shadow Object value;
@Inject(at = @At(value = "TAIL"), method = "updateFieldValue")
private void blur$instantlyApplyRadius(CallbackInfo ci) {
if (Objects.equals(modid, Blur.MOD_ID) && Objects.equals(fieldName, "radius"))
MinecraftClient.getInstance().options.getMenuBackgroundBlurriness().setValue((int) value);
}
}

View File

@@ -0,0 +1,17 @@
package eu.midnightdust.blur.mixin;
import eu.midnightdust.blur.config.BlurConfig;
import eu.midnightdust.lib.config.MidnightConfig;
import net.minecraft.client.MinecraftClient;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(MidnightConfig.class)
public abstract class MixinMidnightConfig {
@Inject(at = @At(value = "INVOKE", target = "Lcom/google/gson/Gson;fromJson(Ljava/io/Reader;Ljava/lang/Class;)Ljava/lang/Object;", shift = At.Shift.AFTER), remap = false, method = "loadValuesFromJson")
private static void blur$syncRadius(CallbackInfo ci) {
BlurConfig.radius = MinecraftClient.getInstance().options.getMenuBackgroundBlurrinessValue();
}
}

View File

@@ -26,18 +26,7 @@ public abstract class MixinScreen {
@Inject(at = @At("HEAD"), method = "render") @Inject(at = @At("HEAD"), method = "render")
public void blur$processScreenChange(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) { public void blur$processScreenChange(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) {
if (!BlurInfo.doTest && BlurInfo.screenChanged) { // After the tests for blur and background color have been completed Blur.onRender(context, width, height, this.client, delta);
Blur.onScreenChange();
BlurInfo.screenChanged = false;
}
if (BlurInfo.start >= 0 && !BlurInfo.screenHasBlur && BlurInfo.prevScreenHasBlur) { // Fade out in non-blurred screens
this.client.gameRenderer.renderBlur();
this.client.getFramebuffer().beginWrite(false);
if (BlurInfo.prevScreenHasBackground) Blur.renderRotatedGradient(context, width, height);
}
BlurInfo.doTest = false; // Set the test state to completed, as tests will happen in the same tick.
} }
@Inject(at = @At("HEAD"), method = "renderInGameBackground") @Inject(at = @At("HEAD"), method = "renderInGameBackground")
public void blur$getBackgroundEnabled(DrawContext context, CallbackInfo ci) { public void blur$getBackgroundEnabled(DrawContext context, CallbackInfo ci) {

View File

@@ -0,0 +1,28 @@
package eu.midnightdust.blur.mixin;
import eu.midnightdust.blur.Blur;
import eu.midnightdust.blur.config.BlurConfig;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.TitleScreen;
import net.minecraft.text.Text;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(TitleScreen.class)
public abstract class MixinTitleScreen extends Screen {
protected MixinTitleScreen(Text title) {
super(title);
}
@Inject(method = "renderPanoramaBackground", at = @At("TAIL"))
private void blur$renderTitleBlur(DrawContext context, float delta, CallbackInfo ci) { // Applies the blur effect in containers (Inventory, Chest, etc.)
if (BlurConfig.blurTitleScreen) {
Blur.updateProgress(true);
this.applyBlur();
if (BlurConfig.darkenTitleScreen) this.renderDarkening(context);
}
}
}

View File

@@ -3,6 +3,8 @@
"blur.midnightconfig.category.animations": "Animationen", "blur.midnightconfig.category.animations": "Animationen",
"blur.midnightconfig.category.style": "Stil", "blur.midnightconfig.category.style": "Stil",
"blur.midnightconfig.blurContainers": "Unschärfe in Containern", "blur.midnightconfig.blurContainers": "Unschärfe in Containern",
"blur.midnightconfig.blurTitleScreen": "Unschärfe im Titelbildschirm",
"blur.midnightconfig.darkenTitleScreen": "Abgedunkelter Titelhintergrund",
"blur.midnightconfig.fadeTimeMillis": "Überblendzeit (in Millisekunden)", "blur.midnightconfig.fadeTimeMillis": "Überblendzeit (in Millisekunden)",
"blur.midnightconfig.fadeOutTimeMillis": "Ausblendzeit (in Millisekunden)", "blur.midnightconfig.fadeOutTimeMillis": "Ausblendzeit (in Millisekunden)",
"blur.midnightconfig.animationCurve": "Animationskurve", "blur.midnightconfig.animationCurve": "Animationskurve",

View File

@@ -4,6 +4,8 @@
"blur.midnightconfig.category.style": "Style", "blur.midnightconfig.category.style": "Style",
"blur.midnightconfig.category.screens": "Screens", "blur.midnightconfig.category.screens": "Screens",
"blur.midnightconfig.blurContainers": "Apply Blur to Containers", "blur.midnightconfig.blurContainers": "Apply Blur to Containers",
"blur.midnightconfig.blurTitleScreen": "Apply Blur to Title Screen",
"blur.midnightconfig.darkenTitleScreen": "Darken Title Screen Background",
"blur.midnightconfig.fadeTimeMillis": "Fade Time (in milliseconds)", "blur.midnightconfig.fadeTimeMillis": "Fade Time (in milliseconds)",
"blur.midnightconfig.fadeOutTimeMillis": "Fade Out Time (in milliseconds)", "blur.midnightconfig.fadeOutTimeMillis": "Fade Out Time (in milliseconds)",
"blur.midnightconfig.animationCurve": "Animation Curve", "blur.midnightconfig.animationCurve": "Animation Curve",
@@ -18,6 +20,7 @@
"blur.midnightconfig.enum.Easing.BACK": "Back", "blur.midnightconfig.enum.Easing.BACK": "Back",
"blur.midnightconfig.enum.Easing.ELASTIC": "Elastic", "blur.midnightconfig.enum.Easing.ELASTIC": "Elastic",
"blur.midnightconfig.radius": "Radius", "blur.midnightconfig.radius": "Radius",
"blur.midnightconfig.radius.label.tooltip": "Mirror of \"Menu Background Blur\" found in Minecraft's Accessibility Settings",
"blur.midnightconfig.rainbowMode": "Rainbow Mode \uD83C\uDF08", "blur.midnightconfig.rainbowMode": "Rainbow Mode \uD83C\uDF08",
"blur.midnightconfig.useGradient": "Gradient as Background", "blur.midnightconfig.useGradient": "Gradient as Background",
"blur.midnightconfig.gradientStart": "Gradient Start Color", "blur.midnightconfig.gradientStart": "Gradient Start Color",

View File

@@ -4,13 +4,16 @@
"package": "eu.midnightdust.blur.mixin", "package": "eu.midnightdust.blur.mixin",
"compatibilityLevel": "JAVA_21", "compatibilityLevel": "JAVA_21",
"client": [ "client": [
"MixinScreen", "MixinGameOptions",
"ScreenAccessor",
"MixinHandledScreen",
"MixinMinecraftClient",
"MixinGameRenderer", "MixinGameRenderer",
"MixinHandledScreen",
"MixinInGameHud", "MixinInGameHud",
"MixinGameOptions" "MixinMidnightConfig",
"MixinMidnightConfig$EntryInfo",
"MixinMinecraftClient",
"MixinScreen",
"MixinTitleScreen",
"ScreenAccessor"
], ],
"injectors": { "injectors": {
"defaultRequire": 1 "defaultRequire": 1

View File

@@ -83,7 +83,8 @@ unifiedPublishing {
curseforge { curseforge {
token = CURSEFORGE_TOKEN token = CURSEFORGE_TOKEN
id = rootProject.curseforge_id id = rootProject.curseforge_id
gameVersions.addAll "Java 21", project.minecraft_version, project.supported_versions gameVersions.addAll "Java 21", project.minecraft_version
if (project.supported_versions != "") gameVersions.addAll project.supported_versions
} }
} }
@@ -93,7 +94,8 @@ unifiedPublishing {
token = MODRINTH_TOKEN token = MODRINTH_TOKEN
id = rootProject.modrinth_id id = rootProject.modrinth_id
version = "$rootProject.version-$project.name" version = "$rootProject.version-$project.name"
gameVersions.addAll project.minecraft_version, project.supported_versions gameVersions.addAll project.minecraft_version
if (project.supported_versions != "") gameVersions.addAll project.supported_versions
} }
} }
} }

View File

@@ -2,13 +2,13 @@
org.gradle.jvmargs=-Xmx2G org.gradle.jvmargs=-Xmx2G
org.gradle.parallel=true org.gradle.parallel=true
minecraft_version=1.21.3 minecraft_version=1.21.4
supported_versions=1.21.2 supported_versions=1.21.5
yarn_mappings=1.21.3+build.2 yarn_mappings=1.21.4+build.1
enabled_platforms=fabric,neoforge enabled_platforms=fabric,neoforge
# Mod Properties # Mod Properties
mod_version=5.0.1 mod_version=5.2.0
maven_group=eu.midnightdust.blur maven_group=eu.midnightdust.blur
archives_base_name=blur archives_base_name=blur
release_type=release release_type=release
@@ -17,11 +17,11 @@ modrinth_id=NK39zBp2
# Modloaders # Modloaders
fabric_loader_version=0.16.9 fabric_loader_version=0.16.9
fabric_api_version=0.107.0+1.21.3 fabric_api_version=0.111.0+1.21.4
neoforge_version=21.3.11-beta neoforge_version=21.4.10-beta
yarn_mappings_patch_neoforge_version = 1.21+build.4 yarn_mappings_patch_neoforge_version = 1.21+build.4
# Libraries # Libraries
midnightlib_version = 1.6.4 midnightlib_version = 1.7.0+1.21.4
modmenu_version = 11.0.2 modmenu_version = 11.0.2

View File

@@ -96,7 +96,8 @@ unifiedPublishing {
curseforge { curseforge {
token = CURSEFORGE_TOKEN token = CURSEFORGE_TOKEN
id = rootProject.curseforge_id id = rootProject.curseforge_id
gameVersions.addAll "Java 21", project.minecraft_version, project.supported_versions gameVersions.addAll "Java 21", project.minecraft_version
if (project.supported_versions != "") gameVersions.addAll project.supported_versions
} }
} }
@@ -106,7 +107,8 @@ unifiedPublishing {
token = MODRINTH_TOKEN token = MODRINTH_TOKEN
id = rootProject.modrinth_id id = rootProject.modrinth_id
version = "$rootProject.version-$project.name" version = "$rootProject.version-$project.name"
gameVersions.addAll project.minecraft_version, project.supported_versions gameVersions.addAll project.minecraft_version
if (project.supported_versions != "") gameVersions.addAll project.supported_versions
} }
} }
} }

View File

@@ -8,13 +8,13 @@ import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.fml.common.Mod; import net.neoforged.fml.common.Mod;
import net.neoforged.neoforge.client.event.ClientTickEvent; import net.neoforged.neoforge.client.event.ClientTickEvent;
@Mod(value = "blur", dist = Dist.CLIENT) @Mod(value = Blur.MOD_ID, dist = Dist.CLIENT)
public class BlurNeoForge { public class BlurNeoForge {
public BlurNeoForge() { public BlurNeoForge() {
Blur.init(); Blur.init();
} }
@EventBusSubscriber(modid = "blur", bus = EventBusSubscriber.Bus.GAME, value = Dist.CLIENT) @EventBusSubscriber(modid = Blur.MOD_ID, bus = EventBusSubscriber.Bus.GAME, value = Dist.CLIENT)
public static class ClientGameEvents { public static class ClientGameEvents {
@SubscribeEvent @SubscribeEvent
public static void endClientTick(ClientTickEvent.Post event) { public static void endClientTick(ClientTickEvent.Post event) {