Here's the patch (hope I generated it in the proper format) for what I've done so far. You may notice that I didn't deal with the possible exceptions other than to just ignore them and move on. You may also notice that I still only use a specific set of resolutions: it would be easy to grab all the possible resolutions and display them instead, but from a gamer's perspective, I'd rather not have the option of viewing in a bunch of weird resolutions. I had the code working by the time I posted last for getting the proper modes and such, but hadn't integrated it with the panel code until now…been busy with skybox issues.
This is VERY useful for me, especially since in Mepis right now using the Nvidia drivers I have weird frequencies displayed on the user end (like 50,53, etc), while it's actually using the proper ones (75, 60, respectively) on the backend. Can tell this easily by using vsync and checking the fps.
Index: GameSettingsPanel.java
===================================================================
RCS file: /cvs/jme/src/com/jmex/editors/swing/settings/GameSettingsPanel.java,v
retrieving revision 1.7
diff -u -r1.7 GameSettingsPanel.java
--- GameSettingsPanel.java 25 Feb 2007 22:15:18 -0000 1.7
+++ GameSettingsPanel.java 15 Jul 2007 07:56:09 -0000
@@ -40,6 +40,8 @@
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
import java.util.*;
import javax.swing.JButton;
@@ -49,6 +51,9 @@
import javax.swing.JPanel;
import javax.swing.SwingConstants;
+import org.lwjgl.opengl.Display;
+import org.lwjgl.opengl.DisplayMode;
+
import com.jme.system.GameSettings;
/**
@@ -56,8 +61,12 @@
*/
public class GameSettingsPanel extends JPanel {
private static final long serialVersionUID = 1L;
+ public static final int[][] RESOLUTIONS = { {640,480}, {800,600}, {1024,768}, {1280,1024},
+ {1600,1200}, {1440, 900} };
+ public static final int[] DEPTHS = {16, 24, 32};
private GameSettings settings;
+ private DisplayMode[] allModes;
private GridBagLayout layout;
private GridBagConstraints constraints;
@@ -80,6 +89,11 @@
public GameSettingsPanel(GameSettings settings) {
this.settings = settings;
+
+ try{
+ allModes = Display.getAvailableDisplayModes();
+ }catch(Exception e){}
+
map = new HashMap<String, JComboBox>();
defaults = new HashMap<String, Object>();
init();
@@ -161,21 +175,22 @@
}
protected Component createResolution() {
- resolution = new JComboBox(new Object[] {
- "640x480",
- "800x600",
- "1024x768",
- "1280x1024",
- "1600x1200",
- "1440x900"});
+ resolution = new JComboBox(getResolutionArray());
resolution.setName("Resolution");
+
+ ItemListener itemListener = new ItemListener() {
+ public void itemStateChanged(ItemEvent event) {
+ // The resolution combobox is all we care about
+ String[] parser = ((String)resolution.getSelectedItem()).split("x");
+ setMenuOptions(Integer.parseInt(parser[0]), Integer.parseInt(parser[1]));
+ }
+ };
+ resolution.addItemListener(itemListener);
return resolution;
}
protected Component createDepth() {
- depth = new JComboBox(new Object[] {
- "16",
- "32"});
+ depth = new JComboBox(getDepthArray());
depth.setName("Depth");
return depth;
}
@@ -343,4 +358,83 @@
Thread.sleep(50);
}
}
+
+ /**
+ * Sets the other menu options based on the given width and height parameters.
+ *
+ * @param width
+ * @param height
+ */
+ public void setMenuOptions(int width, int height)
+ {
+ Vector<DisplayMode> availableModes = getAvailableModesRes(allModes, width, height);
+ depth.removeAllItems();
+ frequency.removeAllItems();
+ HashSet<String> depths = new HashSet<String>();
+ HashSet<String> frequencies = new HashSet<String>();
+
+ for(DisplayMode aMode : availableModes)
+ {
+ depths.add(String.valueOf(aMode.getBitsPerPixel()));
+ frequencies.add(String.valueOf(aMode.getFrequency()));
+ }
+ for(String oneDepth : depths)
+ {
+ depth.addItem(oneDepth);
+ }
+ for(String oneFreq : frequencies)
+ {
+ frequency.addItem(oneFreq);
+ }
+ depth.updateUI();
+ frequency.updateUI();
+ }
+
+ /**
+ * Gets the available modes based on the set of modes for the system and a resolution.
+ *
+ * @param theModes
+ * @param width
+ * @param height
+ * @return
+ */
+ public static Vector<DisplayMode> getAvailableModesRes(DisplayMode[] theModes, int width, int height)
+ {
+ Vector<DisplayMode> modes = new Vector<DisplayMode>();
+
+ for(int[] res : RESOLUTIONS)
+ {
+ if(res[0] == width && res[1] == height)
+ {
+ for(DisplayMode aMode : theModes)
+ {
+ if(aMode.getHeight() == height && aMode.getWidth() == width)
+ {
+ modes.add(aMode);
+ }
+ }
+ }
+ }
+ return modes;
+ }
+
+ public static Object[] getResolutionArray()
+ {
+ Object[] resolutions = new Object[RESOLUTIONS.length];
+ for(int i=0; i<resolutions.length; i++)
+ {
+ resolutions[i] = RESOLUTIONS[i][0]+"x"+RESOLUTIONS[i][1];
+ }
+ return resolutions;
+ }
+
+ public static Object[] getDepthArray()
+ {
+ Object[] depths = new Object[DEPTHS.length];
+ for(int i=0; i<depths.length; i++)
+ {
+ depths[i] = String.valueOf(depths[i]);
+ }
+ return depths;
+ }
}
No newline at end of file