diff --git a/src/main/java/legend/core/opengl/Window.java b/src/main/java/legend/core/opengl/Window.java index ce20f47d2..ee7c058fd 100644 --- a/src/main/java/legend/core/opengl/Window.java +++ b/src/main/java/legend/core/opengl/Window.java @@ -10,6 +10,7 @@ import legend.game.modding.coremod.CoreMod; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.lwjgl.PointerBuffer; import org.lwjgl.Version; import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFWErrorCallback; @@ -51,8 +52,9 @@ import static org.lwjgl.glfw.GLFW.glfwDestroyWindow; import static org.lwjgl.glfw.GLFW.glfwGetClipboardString; import static org.lwjgl.glfw.GLFW.glfwGetFramebufferSize; -import static org.lwjgl.glfw.GLFW.glfwGetInputMode; import static org.lwjgl.glfw.GLFW.glfwGetKey; +import static org.lwjgl.glfw.GLFW.glfwGetMonitorPos; +import static org.lwjgl.glfw.GLFW.glfwGetMonitors; import static org.lwjgl.glfw.GLFW.glfwGetPrimaryMonitor; import static org.lwjgl.glfw.GLFW.glfwGetVideoMode; import static org.lwjgl.glfw.GLFW.glfwGetWindowContentScale; @@ -126,13 +128,15 @@ public static void free() { private final float scale = 1.0f; private boolean hasFocus; - private final GLFWVidMode vidMode; + private long monitor; + private GLFWVidMode vidMode; private final List actions = new ArrayList<>(); private final Action render = this.addAction(new Action(this::tickFrame, 60)); public Window(final String title, final int width, final int height) { - this.vidMode = glfwGetVideoMode(glfwGetPrimaryMonitor()); + this.monitor = this.getMonitorFromConfig(); + this.vidMode = glfwGetVideoMode(this.monitor); if(this.vidMode == null) { throw new RuntimeException("Failed to get video mode"); @@ -153,8 +157,10 @@ public Window(final String title, final int width, final int height) { if(CONFIG.getConfig(CoreMod.FULLSCREEN_CONFIG.get())) { glfwWindowHint(GLFW_DECORATED, GLFW_FALSE); this.window = glfwCreateWindow(this.vidMode.width(), this.vidMode.height(), title, NULL, NULL); + this.makeFullscreen(); } else { this.window = glfwCreateWindow(width, height, title, NULL, NULL); + this.centerWindow(); } glfwSetWindowSizeLimits(this.window, 320, 240, GLFW_DONT_CARE, GLFW_DONT_CARE); @@ -178,7 +184,6 @@ public Window(final String title, final int width, final int height) { } }); - this.centerWindow(); this.makeContextCurrent(); GL.createCapabilities(); @@ -191,6 +196,19 @@ public Window(final String title, final int width, final int height) { } } + private long getMonitorFromConfig() { + if(CONFIG.getConfig(CoreMod.FULLSCREEN_CONFIG.get())) { + final int monitorIndex = CONFIG.getConfig(CoreMod.MONITOR_CONFIG.get()); + final PointerBuffer monitorPtrs = glfwGetMonitors(); + + if(monitorIndex >= 0 && monitorIndex < monitorPtrs.limit()) { + return monitorPtrs.get(monitorIndex); + } + } + + return glfwGetPrimaryMonitor(); + } + public void centerWindow() { try(final MemoryStack stack = stackPush()) { final IntBuffer pWidth = stack.mallocInt(1); @@ -198,18 +216,31 @@ public void centerWindow() { glfwGetFramebufferSize(this.window, pWidth, pHeight); + final int[] x = new int[1]; + final int[] y = new int[1]; + glfwGetMonitorPos(this.monitor, x, y); + glfwSetWindowPos( this.window, - (this.vidMode.width() - pWidth.get(0)) / 2, - (this.vidMode.height() - pHeight.get(0)) / 2 + x[0] + (this.vidMode.width() - pWidth.get(0)) / 2, + y[0] + (this.vidMode.height() - pHeight.get(0)) / 2 ); } } + private void moveToMonitor() { + final int[] x = new int[1]; + final int[] y = new int[1]; + glfwGetMonitorPos(this.monitor, x, y); + glfwSetWindowPos(this.window, x[0], y[0]); + this.vidMode = glfwGetVideoMode(this.monitor); + } + public void makeFullscreen() { + this.monitor = this.getMonitorFromConfig(); + this.moveToMonitor(); glfwSetWindowAttrib(this.window, GLFW_DECORATED, GLFW_FALSE); glfwSetWindowSize(this.window, this.vidMode.width(), this.vidMode.height()); - this.centerWindow(); } public void makeWindowed() { @@ -218,6 +249,14 @@ public void makeWindowed() { this.centerWindow(); } + public void updateMonitor() { + this.monitor = this.getMonitorFromConfig(); + + if(CONFIG.getConfig(CoreMod.FULLSCREEN_CONFIG.get())) { + this.makeFullscreen(); + } + } + public Action addAction(final Action action) { this.actions.add(action); return action; diff --git a/src/main/java/legend/game/modding/coremod/CoreMod.java b/src/main/java/legend/game/modding/coremod/CoreMod.java index 5309de348..54b35ec55 100644 --- a/src/main/java/legend/game/modding/coremod/CoreMod.java +++ b/src/main/java/legend/game/modding/coremod/CoreMod.java @@ -20,6 +20,7 @@ import legend.game.modding.coremod.config.IndicatorModeConfigEntry; import legend.game.modding.coremod.config.InventorySizeConfigEntry; import legend.game.modding.coremod.config.MashModeConfigEntry; +import legend.game.modding.coremod.config.MonitorConfigEntry; import legend.game.modding.coremod.config.MusicVolumeConfigEntry; import legend.game.modding.coremod.config.DisableMouseInputConfigEntry; import legend.game.modding.coremod.config.ResolutionConfig; @@ -84,6 +85,7 @@ public class CoreMod { public static final RegistryDelegate HIGH_QUALITY_PROJECTION_CONFIG = CONFIG_REGISTRAR.register("high_quality_projection", HighQualityProjectionConfigEntry::new); public static final RegistryDelegate FULLSCREEN_CONFIG = CONFIG_REGISTRAR.register("fullscreen", FullscreenConfigEntry::new); public static final RegistryDelegate RESOLUTION_CONFIG = CONFIG_REGISTRAR.register("resolution", ResolutionConfig::new); + public static final RegistryDelegate MONITOR_CONFIG = CONFIG_REGISTRAR.register("monitor", MonitorConfigEntry::new); public static final RegistryDelegate AUDIO_DEVICE_CONFIG = CONFIG_REGISTRAR.register("audio_device", AudioDeviceConfig::new); public static final RegistryDelegate MUSIC_VOLUME_CONFIG = CONFIG_REGISTRAR.register("music_volume", MusicVolumeConfigEntry::new); diff --git a/src/main/java/legend/game/modding/coremod/config/MonitorConfigEntry.java b/src/main/java/legend/game/modding/coremod/config/MonitorConfigEntry.java new file mode 100644 index 000000000..df2cea8c3 --- /dev/null +++ b/src/main/java/legend/game/modding/coremod/config/MonitorConfigEntry.java @@ -0,0 +1,46 @@ +package legend.game.modding.coremod.config; + +import legend.game.inventory.screens.controls.Dropdown; +import legend.game.saves.ConfigCategory; +import legend.game.saves.ConfigCollection; +import legend.game.saves.ConfigEntry; +import legend.game.saves.ConfigStorageLocation; +import org.lwjgl.PointerBuffer; + +import static legend.core.GameEngine.CONFIG; +import static legend.core.GameEngine.RENDERER; +import static org.lwjgl.glfw.GLFW.glfwGetMonitorName; +import static org.lwjgl.glfw.GLFW.glfwGetMonitors; + +public class MonitorConfigEntry extends ConfigEntry { + public MonitorConfigEntry() { + super( + 0, + ConfigStorageLocation.GLOBAL, + ConfigCategory.GRAPHICS, + i -> new byte[] {i.byteValue()}, + bytes -> (int)bytes[0] + ); + + this.setEditControl((current, gameState) -> { + final Dropdown dropdown = new Dropdown(); + dropdown.onSelection(index -> gameState.setConfig(this, index)); + + final PointerBuffer monitorPtrs = glfwGetMonitors(); + + for(int i = 0; i < monitorPtrs.limit(); i++) { + final long ptr = monitorPtrs.get(i); + dropdown.addOption(glfwGetMonitorName(ptr)); + } + + dropdown.setSelectedIndex(CONFIG.getConfig(this)); + return dropdown; + }); + } + + @Override + public void onChange(final ConfigCollection configCollection, final Integer oldValue, final Integer newValue) { + super.onChange(configCollection, oldValue, newValue); + RENDERER.window().updateMonitor(); + } +} diff --git a/src/main/resources/lod_core/lang/en.lang b/src/main/resources/lod_core/lang/en.lang index a3eb92a12..8cae17dfb 100644 --- a/src/main/resources/lod_core/lang/en.lang +++ b/src/main/resources/lod_core/lang/en.lang @@ -33,6 +33,7 @@ lod_core.config.resolution._1440=1440p lod_core.config.resolution._4K=4K lod_core.config.resolution._8K=8K lod_core.config.resolution.NATIVE=Native (window size) +lod_core.config.monitor.label=Monitor lod_core.config.audio_device.label=Audio Device lod_core.config.music_volume.label=Music Volume