Possible screen resolutions

I’m writing a config routine for my program. I have it mostly done. At the end it saves the configuration to a file which is loaded on start-up to allow for different effects to be turned on or off. One of the parameters is screen resolution.

Right now I have a list of some common ones, 800x600, 1024x768, 1280x1024. The user can cycle through them and save the configuration file and exit the program. When the program is restarted the changes will be effected.

The issue I have is that on some screens like on certain laptops they don’t have a resolution above 1024x768 and if the user unaware of this fact sets the resolution to 1280x1024 then exits the program- then restarts with the new config. Panda will crash because the screen resolution isn’t supported on that computer. But now that the configuration is saved to the file the user would have no ability to fix the problem since the program itself is used to fix the configuration file.

Is there a better way to go about this? Is there a way to return a list of the possible screen resolutions on a given machine? That way I wouldn’t provide an option that isn’t possible.

Thanks.

my laptop has a resolution of 1280x768 and no game does this right! Lower screen display find but blurry. Its also happen to be a tablet so i can set it to be 768x1280 some high res modes resort to that for some reason and showing half the screen (realy odd things happen) … basically i will kill any game maker where the resolution can not be specifies by the users as text field or a config of some sort … so if you hard code 4 o or so resolution choices you are greatly limiting your self! best to do it as text and i could enter 320x200 (hey its linux you know) or 4048x4048 if i want (think of the future!)

the other good reason no to do a list of 800x600, 1024x768, 1280x1024 … is because if you do i would have to kill you!

Maybe this will help you:

import direct.directbase.DirectStart

info = base.pipe.getDisplayInformation( )

for idx in range( info.getTotalDisplayModes( ) ):
    width  = info.getDisplayModeWidth( idx )
    height = info.getDisplayModeHeight( idx )
    bits   = info.getDisplayModeBitsPerPixel( idx )

    print width, height, bits

enn0x

oh, it’s already there.
But it doesn’t work without having any graphics context, ie. before opening any window, or using “window-type none” config.

On win32, the following works without involving any graphics API :
(adapted from gamedev.net/reference/articl … le1009.asp)

#include <windows.h>
#include <iostream>
#include <Python.h>

using namespace std;

static PyObject*
GetResolutions(PyObject* self, PyObject* args)
{
  int minWidth=0, minHeight=0, minBitDepth=0, nModeExist;
  if (PyTuple_Size(args)>0)
     PyArg_ParseTuple(args,"iii", &minWidth, &minHeight, &minBitDepth);
  cout <<"Checking for min resolution : "<<minWidth<<" x "<<minHeight<<"  "<<minBitDepth
       <<" bpp\nChecking for 60 Hz only\n\n";

  DEVMODE devMode;
  PyObject* modesList=PyList_New(0);

  for (int i=0; ;i++)
  {
    nModeExist = EnumDisplaySettings(NULL, i, &devMode);

    if (nModeExist != 1)
      // End of modes.  bail out.
      break;
    else if (devMode.dmPelsWidth>=minWidth &&
             devMode.dmPelsHeight>=minHeight &&
             devMode.dmBitsPerPel>=minBitDepth &&
             devMode.dmDisplayFrequency==60 // <--- 60 Hz hard-coded
    ) {
      // pack the bitdepth, width, height in a tuple
      PyObject* mode =
                PyTuple_Pack(3,
                     PyInt_FromLong(devMode.dmBitsPerPel),
                     PyInt_FromLong(devMode.dmPelsWidth),
                     PyInt_FromLong(devMode.dmPelsHeight)
                     );
      // and add the tuple to the list
      PyList_Append(modesList,mode);
    }
  }
  // sort it prior to bitdepth, then resolution
  PyList_Sort(modesList);
  // reverse it so we get descending list
  PyList_Reverse(modesList);
  return modesList;
}


static PyMethodDef module_methods[ ] = {
  { "GetResolutions", ( PyCFunction ) GetResolutions, METH_VARARGS, "" },
  { NULL }
};


PyMODINIT_FUNC initVideoModes( void )
{
  ( void ) Py_InitModule( "VideoModes", module_methods );
}

ynjh.panda3dprojects.com/VideoMo … oModes.zip (it’s newbish C++ attempt)

usage :

import VideoModes

# result : a list of (bitdepth, width, height) tuples
vidModesList=VideoModes.GetResolutions( 640, 480, 16 ) # pass the minimum width, height, bitdepth

for m in vidModesList:
    print '%i x %i  (%i bpp)' %(m[1], m[2], m[0])
print '\n %i video resolutions available' %len(vidModesList)

[EDIT]:
1 more tiny thing, there is DisplaySearchParameters class.
Description : Parameters used for searching display capabilities.

How should I use it ?
I read the src and ShowBase.py, it doesn’t seem to be used anywhere.

Hehe… finally I have been faster. Took me many, many attempts wink

Another way would be using the win32 API, to do roughly the same as the C++ code above:

import win32api

n = 0
while 1:
    try:
        devmod = win32api.EnumDisplaySettings( None, n )
        print devmod.PelsWidth, devmod.PelsHeight, devmod.BitsPerPel, devmod.DisplayFrequency
    except:
        break
    else:
        n += 1

About the DisplaySearchParameters: I have grep’ed through the source too, and found it being used in panda/src/windisplay/winDetectDx.h and panda/src/windisplay/winGraphicsPipe.cxx. Seems to be required by the DirectX implementation for GraphicsPipe.getDisplayInformation( ). To my surprise the OpenGL implementation seems to be fine without DisplaySearchParameters.

enn0x

so is that it ?
just DLed it. Thanks for the hint ! :slight_smile:

about the DSP, there should be 1 global pointer which can be used at anytime, but there isn’t and we can create more than 1 instance. Doesn’t it a way to set the thresholds for building the array ?

Yep, that’s it. Great package. I am using it for several years now, mainly the COM server/client stuff, for reading or writing EXCEL/Word/OpenOffice/ACCESS files.

But I have a vague feeling that using system-level and windows-only calls is not the right way. And that on Monday drwr or Yosh will be back at work and point us to some Panda3D functionality that solves the problem in a better way. And of course has been in the documentation since the first Panda release, but we just didn’t see it :slight_smile:

enn0x

ah…ha, finally I found what I need : current setting query. It’s already supported on Linux (via base.pipe.getDisplayWidth/Height), but not yet on Win.

import win32api,win32con

dm = win32api.EnumDisplaySettings( None, win32con.ENUM_CURRENT_SETTINGS )
print 'CURRENT SETTING : %i x %i  %i bpp  %i Hz' %(dm.PelsWidth, dm.PelsHeight, dm.BitsPerPel, dm.DisplayFrequency)

It’s for the best fullscreen resolution, no halt.

Well, I’m not sure what the right way is, but here’s what I gather by reading the code in showbase. The following will probably work.

  1. Set “window-type” to none in the config file.

  2. Call “base.makeDefaultPipe()”. This will initialize base.pipe.

  3. Call “base.pipe.getDisplayInformation()”, and examine the options.

  4. Create a WindowProperties structure with the desired properties.

  5. Call "base.openDefaultWindow(props=myprops)

Advantage of using the panda calls: it will work on Linux and MacOS too.

Josh, I think you’ve got a good solution, but I don’t see “window-type” anywhere in the config.prc file. I tried this line in the code:

loadPrcFileData("", "win-type None")

Which didn’t work, I didn’t think it would.

I get an assertion error

assert self.pipe == None

“window-type none” works for me…