Skip to content

Commit

Permalink
Get display modes via LWJGL rather than AWT. Abstracts video modes
Browse files Browse the repository at this point in the history
  • Loading branch information
tonihele committed Jun 16, 2024
1 parent c90f5d6 commit a11a706
Show file tree
Hide file tree
Showing 9 changed files with 459 additions and 69 deletions.
15 changes: 7 additions & 8 deletions src/toniarts/openkeeper/game/state/MainMenuScreenController.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@
import de.lessvoid.nifty.screen.Screen;
import de.lessvoid.nifty.tools.Color;
import de.lessvoid.nifty.tools.SizeValue;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.io.File;
import java.io.IOException;
import java.lang.System.Logger;
Expand Down Expand Up @@ -84,6 +82,8 @@
import toniarts.openkeeper.tools.convert.map.KwdFile;
import toniarts.openkeeper.tools.modelviewer.SoundsLoader;
import toniarts.openkeeper.utils.AssetUtils;
import toniarts.openkeeper.utils.DisplayMode;
import toniarts.openkeeper.utils.DisplayModeUtils;
import toniarts.openkeeper.utils.PathUtils;
import toniarts.openkeeper.utils.Utils;

Expand Down Expand Up @@ -271,7 +271,7 @@ public void applyGraphicsSettings() {
DropDown aa = screen.findNiftyControl("antialiasing", DropDown.class);
DropDown af = screen.findNiftyControl("anisotropicFiltering", DropDown.class);
CheckBox ssao = screen.findNiftyControl("ssao", CheckBox.class);
MyDisplayMode mdm = (MyDisplayMode) res.getSelection();
DisplayMode mdm = (DisplayMode) res.getSelection();

// TODO: See if we need a restart, but keep in mind that the settings are saved in the restart
// Set the settings
Expand Down Expand Up @@ -568,7 +568,7 @@ private void setScreen(Screen screen) {
}

@NiftyEventSubscriber(id = "resolution")
public void onResolutionChanged(final String id, final DropDownSelectionChangedEvent<MyDisplayMode> event) {
public void onResolutionChanged(final String id, final DropDownSelectionChangedEvent<DisplayMode> event) {

// Set the bit depths
DropDown bitDepth = screen.findNiftyControl("bitDepth", DropDown.class);
Expand Down Expand Up @@ -729,9 +729,8 @@ private void setGraphicsSettingsToGUI() {
// Application settings
AppSettings settings = Main.getUserSettings().getAppSettings();

GraphicsDevice device = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
MyDisplayMode mdm = new MyDisplayMode(settings);
List<MyDisplayMode> resolutions = state.getResolutions(device);
DisplayMode mdm = new DisplayMode(settings);
List<DisplayMode> resolutions = DisplayModeUtils.getInstance().getDisplayModes();
int resolutionSelectedIndex = Collections.binarySearch(resolutions, mdm);

// Get values to the settings screen
Expand Down Expand Up @@ -762,7 +761,7 @@ private void setGraphicsSettingsToGUI() {
// Fullscreen
CheckBox fullscreen = screen.findNiftyControl("fullscreen", CheckBox.class);
fullscreen.setChecked(settings.isFullscreen());
fullscreen.setEnabled(device.isFullScreenSupported());
fullscreen.setEnabled(DisplayModeUtils.getInstance().isFullScreenSupported());

// VSync
CheckBox vsync = screen.findNiftyControl("verticalSync", CheckBox.class);
Expand Down
36 changes: 0 additions & 36 deletions src/toniarts/openkeeper/game/state/MainMenuState.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,12 @@
import com.simsilica.es.EntityData;
import com.simsilica.es.EntityId;
import com.simsilica.es.base.DefaultEntityData;
import java.awt.DisplayMode;
import java.awt.GraphicsDevice;
import java.io.File;
import java.io.IOException;
import java.lang.System.Logger;
import java.lang.System.Logger.Level;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import toniarts.openkeeper.Main;
import static toniarts.openkeeper.Main.getDkIIFolder;
import toniarts.openkeeper.cinematics.CameraSweepData;
Expand Down Expand Up @@ -532,38 +528,6 @@ protected void clearLevelBriefingNarration() {
levelBriefing = null;
}

/**
* Gets the resolutions supported by the given device. The resolutions are
* sorted by their native order
*
* @param device the graphics device to query resolutions from
* @return sorted list of available resolutions
*/
protected List<MyDisplayMode> getResolutions(GraphicsDevice device) {

// Get from the system
DisplayMode[] modes = device.getDisplayModes();

List<MyDisplayMode> displayModes = new ArrayList<>(modes.length);

// Loop them through
for (DisplayMode dm : modes) {

// They may already exist, then just add the possible resfresh rate
MyDisplayMode mdm = new MyDisplayMode(dm);
int index = Collections.binarySearch(displayModes, mdm);
if (index > -1) {
mdm = displayModes.get(index);
mdm.addRefreshRate(dm);
mdm.addBitDepth(dm);
} else {
displayModes.add(~index, mdm);
}
}

return displayModes;
}

public void doDebriefing(GameResult result) {
setEnabled(true);
if (selectedLevel != null && result != null) {
Expand Down
75 changes: 75 additions & 0 deletions src/toniarts/openkeeper/utils/AwtDisplayModeProvider.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* Copyright (C) 2014-2024 OpenKeeper
*
* OpenKeeper is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenKeeper is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenKeeper. If not, see <http://www.gnu.org/licenses/>.
*/
package toniarts.openkeeper.utils;

import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.util.ArrayList;
import java.util.List;

/**
* Uses Java's own way of getting available display modes. Often errorenious and
* locks up on MacOS with LWJGL 3
*
* @author Toni Helenius <[email protected]>
*/
class AwtDisplayModeProvider extends DefaultDisplayModeProvider {

public AwtDisplayModeProvider() {
}

@Override
public List<DisplayMode> getDisplayModes() {
GraphicsDevice device = getGraphicsDevice();

java.awt.DisplayMode[] modes = device.getDisplayModes();

List<DisplayMode> displayModes = new ArrayList<>(modes.length);

// Loop them through
for (java.awt.DisplayMode dm : modes) {
DisplayMode mdm = getDisplayMode(dm);
addDisplayMode(displayModes, mdm);
}

return displayModes;
}

private GraphicsDevice getGraphicsDevice() {
return GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
}

private DisplayMode getDisplayMode(java.awt.DisplayMode dm) {
DisplayMode displayMode = new DisplayMode(dm.getWidth(), dm.getHeight());
if (dm.getRefreshRate() != java.awt.DisplayMode.REFRESH_RATE_UNKNOWN) {
displayMode.addRefreshRate(dm.getRefreshRate());
}
if (dm.getBitDepth() != java.awt.DisplayMode.BIT_DEPTH_MULTI) {
displayMode.addBitDepth(dm.getBitDepth());
}

return displayMode;
}

@Override
public boolean isFullScreenSupported() {
GraphicsDevice device = getGraphicsDevice();

return device.isFullScreenSupported();
}

}
44 changes: 44 additions & 0 deletions src/toniarts/openkeeper/utils/DefaultDisplayModeProvider.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (C) 2014-2024 OpenKeeper
*
* OpenKeeper is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenKeeper is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenKeeper. If not, see <http://www.gnu.org/licenses/>.
*/
package toniarts.openkeeper.utils;

import java.util.Collections;
import java.util.List;

/**
* Simple groups some common methods for display mode providers
*
* @author Toni Helenius <[email protected]>
*/
abstract class DefaultDisplayModeProvider implements DisplayModeProvider {

protected void addDisplayMode(List<DisplayMode> displayModes, DisplayMode mdm) {
int index = Collections.binarySearch(displayModes, mdm);
if (index > -1) {
DisplayMode existingDm = displayModes.get(index);
for (Integer refreshRate : mdm.getRefreshRates()) {
existingDm.addRefreshRate(refreshRate);
}
for (Integer bitDepth : mdm.getBitDepths()) {
existingDm.addBitDepth(bitDepth);
}
} else {
displayModes.add(~index, mdm);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,48 +14,43 @@
* You should have received a copy of the GNU General Public License
* along with OpenKeeper. If not, see <http://www.gnu.org/licenses/>.
*/
package toniarts.openkeeper.game.state;
package toniarts.openkeeper.utils;

import com.jme3.system.AppSettings;
import java.awt.DisplayMode;
import java.util.Collection;
import java.util.Set;
import java.util.TreeSet;

/**
* Our own presentation of display mode. Groups everything under resolution.
*
* @author ArchDemon
*/
public final class MyDisplayMode implements Comparable<MyDisplayMode> {
public final class DisplayMode implements Comparable<DisplayMode> {

private final int height;
private final int width;
private final Collection<Integer> refreshRates = new TreeSet<>();
private final Collection<Integer> bitDepths = new TreeSet<>();
private final int height;
private final Set<Integer> refreshRates = new TreeSet<>();
private final Set<Integer> bitDepths = new TreeSet<>();

public MyDisplayMode(DisplayMode dm) {
height = dm.getHeight();
width = dm.getWidth();
addBitDepth(dm);
addRefreshRate(dm);
public DisplayMode(int width, int height) {
this.width = width;
this.height = height;
}

MyDisplayMode(AppSettings settings) {
public DisplayMode(AppSettings settings) {
height = settings.getHeight();
width = settings.getWidth();
bitDepths.add(settings.getBitsPerPixel());
refreshRates.add(settings.getFrequency());
}

public void addRefreshRate(DisplayMode dm) {
if (dm.getRefreshRate() != DisplayMode.REFRESH_RATE_UNKNOWN && !refreshRates.contains(dm.getRefreshRate())) {
refreshRates.add(dm.getRefreshRate());
}
protected void addRefreshRate(Integer refreshRate) {
refreshRates.add(refreshRate);
}

public void addBitDepth(DisplayMode dm) {
if (dm.getBitDepth() != DisplayMode.BIT_DEPTH_MULTI && !bitDepths.contains(dm.getBitDepth())) {
bitDepths.add(dm.getBitDepth());
}
protected void addBitDepth(Integer bitDepth) {
bitDepths.add(bitDepth);
}

public int getWidth() {
Expand All @@ -67,9 +62,6 @@ public int getHeight() {
}

public Collection<Integer> getBitDepths() {
if (bitDepths.isEmpty()) {
bitDepths.add(24); // Add default
}
return bitDepths;
}

Expand All @@ -85,7 +77,7 @@ public boolean equals(Object obj) {
if (getClass() != obj.getClass()) {
return false;
}
final MyDisplayMode other = (MyDisplayMode) obj;
final DisplayMode other = (DisplayMode) obj;
if (this.height != other.height) {
return false;
}
Expand All @@ -106,7 +98,7 @@ public String toString() {
}

@Override
public int compareTo(MyDisplayMode o) {
public int compareTo(DisplayMode o) {
int result = Integer.compare(width, o.width);
if (result == 0) {
result = Integer.compare(height, o.height);
Expand Down
36 changes: 36 additions & 0 deletions src/toniarts/openkeeper/utils/DisplayModeProvider.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright (C) 2014-2024 OpenKeeper
*
* OpenKeeper is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenKeeper is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenKeeper. If not, see <http://www.gnu.org/licenses/>.
*/
package toniarts.openkeeper.utils;

import java.util.List;

/**
*
* @author Toni Helenius <[email protected]>
*/
public interface DisplayModeProvider {

/**
* Gets the diplay modes supported by the current device. The resolutions
* are sorted by their native order
*
* @return sorted list of available display modes
*/
List<DisplayMode> getDisplayModes();

boolean isFullScreenSupported();
}
Loading

0 comments on commit a11a706

Please sign in to comment.