diff --git a/platforms/common/src/main/java/dynamic_fps/impl/DynamicFPSMod.java b/platforms/common/src/main/java/dynamic_fps/impl/DynamicFPSMod.java index ef4e890b..76ce8a60 100644 --- a/platforms/common/src/main/java/dynamic_fps/impl/DynamicFPSMod.java +++ b/platforms/common/src/main/java/dynamic_fps/impl/DynamicFPSMod.java @@ -161,6 +161,10 @@ public static int targetFrameRate() { return config.frameRateTarget(); } + public static boolean enableVsync() { + return config.enableVsync(); + } + public static float volumeMultiplier(SoundSource source) { return config.volumeMultiplier(source); } @@ -237,6 +241,13 @@ public static void handleStateChange(PowerState previous, PowerState current) { OptionHolder.applyOptions(minecraft.options, config.graphicsState()); } + + // The FOCUSED config doesn't have the user's actual vsync preference sadly ... + boolean enableVsync = current != PowerState.FOCUSED ? config.enableVsync() : minecraft.options.enableVsync().get(); + + if (enableVsync != before.enableVsync()) { + minecraft.getWindow().updateVsync(enableVsync); + } } private static void checkForStateChanges() { diff --git a/platforms/common/src/main/java/dynamic_fps/impl/compat/ClothConfig.java b/platforms/common/src/main/java/dynamic_fps/impl/compat/ClothConfig.java index 4bcd855f..994584bf 100644 --- a/platforms/common/src/main/java/dynamic_fps/impl/compat/ClothConfig.java +++ b/platforms/common/src/main/java/dynamic_fps/impl/compat/ClothConfig.java @@ -217,6 +217,16 @@ public static Screen genConfigScreen(Screen parent) { .build() ); + category.addEntry( + entryBuilder.startBooleanToggle( + Component.translatable("options.vsync"), + instance.enableVsync() + ) + .setDefaultValue(standard.enableVsync()) + .setSaveConsumer(instance::setEnableVsync) + .build() + ); + // Further options are not allowed since this state is used while active. if (state.configurabilityLevel == PowerState.ConfigurabilityLevel.SOME) { continue; diff --git a/platforms/common/src/main/java/dynamic_fps/impl/config/Config.java b/platforms/common/src/main/java/dynamic_fps/impl/config/Config.java index 0ede2ed4..13ca9097 100644 --- a/platforms/common/src/main/java/dynamic_fps/impl/config/Config.java +++ b/platforms/common/src/main/java/dynamic_fps/impl/config/Config.java @@ -11,6 +11,7 @@ public class Config { private int frameRateTarget; + private boolean enableVsync; private final Map volumeMultipliers; private GraphicsState graphicsState; private boolean showToasts; @@ -18,10 +19,11 @@ public class Config { protected transient PowerState state; // Set by main config, allows retrieving values from the default power state config - public static final Config ACTIVE = new Config(-1, new HashMap<>(), GraphicsState.DEFAULT, true, false); + public static final Config ACTIVE = new Config(-1, false, new HashMap<>(), GraphicsState.DEFAULT, true, false); - public Config(int frameRateTarget, Map volumeMultipliers, GraphicsState graphicsState, boolean showToasts, boolean runGarbageCollector) { + public Config(int frameRateTarget, boolean enableVsync, Map volumeMultipliers, GraphicsState graphicsState, boolean showToasts, boolean runGarbageCollector) { this.frameRateTarget = frameRateTarget; + this.enableVsync = enableVsync; this.volumeMultipliers = new HashMap<>(volumeMultipliers); // Ensure the map is mutable this.graphicsState = graphicsState; this.showToasts = showToasts; @@ -44,6 +46,14 @@ public void setFrameRateTarget(int value) { } } + public boolean enableVsync() { + return this.enableVsync; + } + + public void setEnableVsync(boolean value) { + this.enableVsync = value; + } + public float volumeMultiplier(SoundSource source) { if (this.rawVolumeMultiplier(SoundSource.MASTER) == 0.0f) { return 0.0f; diff --git a/platforms/common/src/main/java/dynamic_fps/impl/mixin/DebugScreenOverlayMixin.java b/platforms/common/src/main/java/dynamic_fps/impl/mixin/DebugScreenOverlayMixin.java index dbd2fc0d..c72803a4 100644 --- a/platforms/common/src/main/java/dynamic_fps/impl/mixin/DebugScreenOverlayMixin.java +++ b/platforms/common/src/main/java/dynamic_fps/impl/mixin/DebugScreenOverlayMixin.java @@ -29,12 +29,14 @@ private List getGameInformation(List result) { PowerState status = DynamicFPSMod.powerState(); if (status != PowerState.FOCUSED) { - int target = DynamicFPSMod.targetFrameRate(); - String fps = target == Constants.NO_FRAME_RATE_LIMIT ? "inf" : Integer.toString(target); + int fps = DynamicFPSMod.targetFrameRate(); + + String vsync = DynamicFPSMod.enableVsync() ? " vsync": ""; + String target = fps == Constants.NO_FRAME_RATE_LIMIT ? "inf" : Integer.toString(fps); result.add( 2, - this.format("§c[Dynamic FPS] FPS: %s P: %s§r", fps, status.toString().toLowerCase()) + this.format("§c[Dynamic FPS] FPS: %s%s P: %s§r", target, vsync, status.toString().toLowerCase()) ); } } diff --git a/platforms/common/src/main/resources/assets/dynamic_fps/data/default_config.json b/platforms/common/src/main/resources/assets/dynamic_fps/data/default_config.json index 0ae97790..fb43c342 100644 --- a/platforms/common/src/main/resources/assets/dynamic_fps/data/default_config.json +++ b/platforms/common/src/main/resources/assets/dynamic_fps/data/default_config.json @@ -21,6 +21,7 @@ "states": { "hovered": { "frame_rate_target": 60, + "enable_vsync": "false", "volume_multipliers": {}, "graphics_state": "default", "show_toasts": true, @@ -28,6 +29,7 @@ }, "unfocused": { "frame_rate_target": 1, + "enable_vsync": "false", "volume_multipliers": { "master": 0.25 }, @@ -37,6 +39,7 @@ }, "invisible": { "frame_rate_target": 0, + "enable_vsync": "false", "volume_multipliers": { "master": 0.0 }, @@ -45,7 +48,8 @@ "run_garbage_collector": false }, "unplugged": { - "frame_rate_target": 60, + "frame_rate_target": -1, + "enable_vsync": "true", "volume_multipliers": {}, "graphics_state": "default", "show_toasts": true, @@ -53,6 +57,7 @@ }, "abandoned": { "frame_rate_target": 10, + "enable_vsync": "false", "volume_multipliers": {}, "graphics_state": "default", "show_toasts": false,