diff --git a/build.gradle b/build.gradle index 1272d49d..fd54d0d8 100644 --- a/build.gradle +++ b/build.gradle @@ -22,6 +22,10 @@ dependencies { modImplementation libs.fabric.api modImplementation libs.fabric.loader + // Why do I need this on 0.15.x ..? + modImplementation libs.mixinextras + annotationProcessor libs.mixinextras + modApi libs.modmenu modApi libs.cloth.config } diff --git a/gradle.properties b/gradle.properties index 34a6eda2..0e0d6cc9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,6 +3,6 @@ org.gradle.parallel = true org.gradle.jvmargs = -Xmx1G # Mod Properties -mod_version = 3.3.1 +mod_version = 3.3.2 maven_group = juliand665 archives_base_name = dynamic-fps diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index cb2320a6..6af47166 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,8 @@ [versions] minecraft = "1.16.5" -fabric_loader = "0.14.22" + +mixinextras = "0.3.2" +fabric_loader = "0.15.3" modmenu = "1.15.0" fabric_api = "0.29.4+1.16" @@ -9,6 +11,8 @@ cloth_config = "4.14.54" [libraries] minecraft = { module = "com.mojang:minecraft", version.ref = "minecraft" } + +mixinextras = { module = "io.github.llamalad7:mixinextras-fabric", version.ref = "mixinextras" } fabric_loader = { module = "net.fabricmc:fabric-loader", version.ref = "fabric_loader" } modmenu = { module = "com.terraformersmc:modmenu", version.ref = "modmenu" } diff --git a/src/main/java/dynamic_fps/impl/mixin/DebugScreenOverlayMixin.java b/src/main/java/dynamic_fps/impl/mixin/DebugScreenOverlayMixin.java index 4d5ad246..f2db191b 100644 --- a/src/main/java/dynamic_fps/impl/mixin/DebugScreenOverlayMixin.java +++ b/src/main/java/dynamic_fps/impl/mixin/DebugScreenOverlayMixin.java @@ -5,8 +5,8 @@ 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.CallbackInfoReturnable; + +import com.llamalad7.mixinextras.injector.ModifyReturnValue; import dynamic_fps.impl.DynamicFPSMod; import dynamic_fps.impl.PowerState; @@ -14,18 +14,20 @@ @Mixin(DebugScreenOverlay.class) public class DebugScreenOverlayMixin { - /* - * Insert information about effective frame rate below misleading FPS counter. + /** + * Show the current power state and effective frame rate below the FPS counter, unless focused. + * + * As we only slow the client loop to a minimum of 15 TPS the vanilla frame rate counter is inaccurate and confusing. */ - @Inject(method = "getGameInformation", at = @At("RETURN")) - private void onGetGameInformation(CallbackInfoReturnable> callbackInfo) { + @ModifyReturnValue(method = "getGameInformation", at = @At("RETURN")) + private List getGameInformation(List result) { PowerState status = DynamicFPSMod.powerState(); if (status != PowerState.FOCUSED) { - List result = callbackInfo.getReturnValue(); int target = DynamicFPSMod.targetFrameRate(); - result.add(2, String.format(Locale.ROOT, "§c[Dynamic FPS] FPS: %s P: %s§r", target, status.toString().toLowerCase())); } + + return result; } } diff --git a/src/main/java/dynamic_fps/impl/mixin/GameRendererMixin.java b/src/main/java/dynamic_fps/impl/mixin/GameRendererMixin.java index 0f134723..bd2775cc 100644 --- a/src/main/java/dynamic_fps/impl/mixin/GameRendererMixin.java +++ b/src/main/java/dynamic_fps/impl/mixin/GameRendererMixin.java @@ -1,10 +1,13 @@ package dynamic_fps.impl.mixin; +import org.objectweb.asm.Opcodes; 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; +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; + import dynamic_fps.impl.DynamicFPSMod; import net.minecraft.client.renderer.GameRenderer; @@ -12,15 +15,16 @@ public class GameRendererMixin { /** * Implements the mod's big feature. + * + * Note: Inject after the pause on lost focus check, + * This allows the feature to work even at zero FPS. */ - @Inject(at = @At("HEAD"), method = "render", cancellable = true) - private void onRender(CallbackInfo callbackInfo) { - if (!DynamicFPSMod.checkForRender()) { - callbackInfo.cancel(); - } + @ModifyExpressionValue(method = "render", at = @At(value = "FIELD", target = "Lnet/minecraft/client/Minecraft;noRender:Z", opcode = Opcodes.GETFIELD)) + private boolean skipRendering(boolean original) { + return original || !DynamicFPSMod.checkForRender(); } - /* + /** * Cancels rendering the world if a it is determined to currently not be visible. */ @Inject(at = @At("HEAD"), method = { "renderLevel", "renderItemActivationAnimation" }, cancellable = true) diff --git a/src/main/java/dynamic_fps/impl/mixin/GuiMixin.java b/src/main/java/dynamic_fps/impl/mixin/GuiMixin.java index cfda5639..061bb8ed 100644 --- a/src/main/java/dynamic_fps/impl/mixin/GuiMixin.java +++ b/src/main/java/dynamic_fps/impl/mixin/GuiMixin.java @@ -10,7 +10,7 @@ @Mixin(Gui.class) public class GuiMixin { - /* + /** * Cancels rendering the GUI if a it is determined to currently not be visible. */ @Inject(at = @At("HEAD"), method = "render", cancellable = true) diff --git a/src/main/java/dynamic_fps/impl/mixin/MinecraftMixin.java b/src/main/java/dynamic_fps/impl/mixin/MinecraftMixin.java index 0b5ab38b..58d81c50 100644 --- a/src/main/java/dynamic_fps/impl/mixin/MinecraftMixin.java +++ b/src/main/java/dynamic_fps/impl/mixin/MinecraftMixin.java @@ -23,8 +23,10 @@ private void onInit(CallbackInfo callbackInfo) { DynamicFPSMod.setWindow(this.window.window); } + /* @Inject(method = "setScreen", at = @At("TAIL")) private void onSetScreen(CallbackInfo callbackInfo) { DynamicFPSMod.onStatusChanged(); } + */ } diff --git a/src/main/java/dynamic_fps/impl/mixin/SoundEngineMixin.java b/src/main/java/dynamic_fps/impl/mixin/SoundEngineMixin.java index a5df320c..0b7aa728 100644 --- a/src/main/java/dynamic_fps/impl/mixin/SoundEngineMixin.java +++ b/src/main/java/dynamic_fps/impl/mixin/SoundEngineMixin.java @@ -9,8 +9,9 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import com.llamalad7.mixinextras.injector.ModifyReturnValue; +import com.llamalad7.mixinextras.sugar.Local; import com.mojang.blaze3d.audio.Listener; import dynamic_fps.impl.DynamicFPSMod; @@ -102,16 +103,14 @@ private void play(SoundInstance instance, CallbackInfo callbackInfo) { /** * Applies the user's requested volume multiplier to any newly played sounds. */ - @Inject(method = "getVolume", at = @At("HEAD"), cancellable = true) - private void getVolume(@Nullable SoundSource source, CallbackInfoReturnable callbackInfo) { - float base = 1.0f; - + @ModifyReturnValue(method = "getVolume", at = @At("RETURN")) + private float getVolume(float original, @Local @Nullable SoundSource source) { // Note: The original doesn't consider the user's setting when the source is MASTER // In vanilla this doesn't matter because it's never called, but we use it when setting the gain - if (source != null) { - base = this.options.getSoundSourceVolume(source); + if (SoundSource.MASTER.equals(source)) { + original = this.options.getSoundSourceVolume(source); } - callbackInfo.setReturnValue(base * DynamicFPSMod.volumeMultiplier(source)); + return original * DynamicFPSMod.volumeMultiplier(source); } } diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 0a3a4e19..a3f2c087 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -42,7 +42,7 @@ "=1.18.1", "=1.18.2" ], - "fabricloader": ">=0.14.22", + "fabricloader": ">=0.15.0", "fabric-resource-loader-v0": "*", "fabric-rendering-v1": "*", "fabric-lifecycle-events-v1": "*",