diff --git a/src/main/java/net/vulkanmod/config/Config.java b/src/main/java/net/vulkanmod/config/Config.java index 05b4e7c62..511ef5eb2 100644 --- a/src/main/java/net/vulkanmod/config/Config.java +++ b/src/main/java/net/vulkanmod/config/Config.java @@ -15,6 +15,7 @@ public class Config { public VideoModeSet.VideoMode videoMode = VideoModeManager.getFirstAvailable().getVideoMode(); public int windowMode = 0; + public String monitor = ""; // monitor is a pointer and can't be reused so name is used instead public int advCulling = 2; public boolean indirectDraw = true; diff --git a/src/main/java/net/vulkanmod/config/option/Options.java b/src/main/java/net/vulkanmod/config/option/Options.java index c52a8de73..a134ae526 100644 --- a/src/main/java/net/vulkanmod/config/option/Options.java +++ b/src/main/java/net/vulkanmod/config/option/Options.java @@ -15,6 +15,8 @@ import net.vulkanmod.vulkan.Renderer; import net.vulkanmod.vulkan.device.DeviceManager; +import static org.lwjgl.glfw.GLFW.glfwGetMonitorName; + import java.util.stream.IntStream; public abstract class Options { @@ -49,7 +51,7 @@ public static OptionBlock[] getVideoOpts() { () -> VideoModeManager.selectedVideoMode.refreshRate) .setTranslator(refreshRate -> Component.nullToEmpty(refreshRate.toString())); - Option resolutionOption = new CyclingOption<>( + CyclingOption resolutionOption = (CyclingOption) new CyclingOption<>( Component.translatable("options.fullscreen.resolution"), VideoModeManager.getVideoResolutions(), (value) -> { @@ -75,8 +77,26 @@ public static OptionBlock[] getVideoOpts() { RefreshRate.setNewValue(newRefreshRates[newRefreshRates.length - 1]); }); + CyclingOption monitorOption = (CyclingOption) new CyclingOption<>( + Component.translatable("vulkanmod.options.monitor"), + VideoModeManager.getMonitors(), + (value) -> { + VideoModeManager.setSelectedMonitor(value); + VideoModeManager.applySelectedMonitor(); + VideoModeManager.applySelectedVideoMode(); + + if (minecraftOptions.fullscreen().get()) + fullscreenDirty = true; + + resolutionOption.setValues(VideoModeManager.getVideoResolutions()); + resolutionOption.setNewValue(VideoModeManager.getFirstAvailable()); + }, + VideoModeManager::getSelectedMonitor + ).setTranslator(monitor_address -> Component.nullToEmpty(glfwGetMonitorName(monitor_address))); + return new OptionBlock[]{ new OptionBlock("", new Option[]{ + monitorOption, resolutionOption, RefreshRate, new CyclingOption<>(Component.translatable("vulkanmod.options.windowMode"), diff --git a/src/main/java/net/vulkanmod/config/video/VideoModeManager.java b/src/main/java/net/vulkanmod/config/video/VideoModeManager.java index 985455a63..a35e00b2f 100644 --- a/src/main/java/net/vulkanmod/config/video/VideoModeManager.java +++ b/src/main/java/net/vulkanmod/config/video/VideoModeManager.java @@ -10,15 +10,17 @@ import static org.lwjgl.glfw.GLFW.*; public abstract class VideoModeManager { + private static Long[] monitors; private static VideoModeSet.VideoMode osVideoMode; private static VideoModeSet[] videoModeSets; + private static long selectedMonitor; public static VideoModeSet.VideoMode selectedVideoMode; public static void init() { - long monitor = glfwGetPrimaryMonitor(); - osVideoMode = getCurrentVideoMode(monitor); - videoModeSets = populateVideoResolutions(GLFW.glfwGetPrimaryMonitor()); + monitors = populateMonitors(); + setSelectedMonitor(glfwGetPrimaryMonitor()); + } public static void applySelectedVideoMode() { @@ -93,4 +95,38 @@ public static VideoModeSet getFromVideoMode(VideoModeSet.VideoMode videoMode) { return null; } + + public static Long[] populateMonitors() { + List monitors = new ArrayList<>(); + + var monitorsRaw = glfwGetMonitors(); + for (int i = 0; i < monitorsRaw.limit(); i++) { + var m = monitorsRaw.get(i); + monitors.add(m); + } + + Long[] arr = new Long[monitors.size()]; + monitors.toArray(arr); + + return arr; + } + + public static Long[] getMonitors() { + return monitors; + } + + public static long getSelectedMonitor() { + return selectedMonitor; + } + + public static void setSelectedMonitor(long new_monitor) { + selectedMonitor = new_monitor; + osVideoMode = getCurrentVideoMode(selectedMonitor); + videoModeSets = populateVideoResolutions(selectedMonitor); + selectedVideoMode = getFirstAvailable().getVideoMode(); + } + + public static void applySelectedMonitor() { + Initializer.CONFIG.monitor = glfwGetMonitorName(selectedMonitor); + } } diff --git a/src/main/java/net/vulkanmod/mixin/window/WindowMixin.java b/src/main/java/net/vulkanmod/mixin/window/WindowMixin.java index 5f4c71ce8..640bfc358 100644 --- a/src/main/java/net/vulkanmod/mixin/window/WindowMixin.java +++ b/src/main/java/net/vulkanmod/mixin/window/WindowMixin.java @@ -128,7 +128,20 @@ public void updateDisplay() { private void setMode() { Config config = Initializer.CONFIG; - long monitor = GLFW.glfwGetPrimaryMonitor(); + // Try to recover a monitor pointer + long monitor = 0; + for (var m : VideoModeManager.getMonitors()) { + var name = glfwGetMonitorName(m); + if (name.equals(config.monitor)) { + monitor = m; + break; + } + } + // if the save monitor is not present / there was no saved monitor fallback + if (monitor == 0) { + monitor = glfwGetPrimaryMonitor(); + } + VideoModeManager.setSelectedMonitor(monitor); // refresh video mode manager if (this.fullscreen) { { VideoModeSet.VideoMode videoMode = config.videoMode; diff --git a/src/main/resources/assets/vulkanmod/lang/en_us.json b/src/main/resources/assets/vulkanmod/lang/en_us.json index 6947a8a90..d144203b3 100644 --- a/src/main/resources/assets/vulkanmod/lang/en_us.json +++ b/src/main/resources/assets/vulkanmod/lang/en_us.json @@ -44,5 +44,7 @@ "vulkanmod.options.windowMode.windowedFullscreen": "Windowed Fullscreen", "vulkanmod.options.builderThreads": "Chunk Builder Threads", - "vulkanmod.options.builderThreads.auto": "Auto" + "vulkanmod.options.builderThreads.auto": "Auto", + + "vulkanmod.options.monitor": "Monitor" } \ No newline at end of file