Sometimes it would be useful to let decide the "customer" in which screen resolution she or he wants to play your game. Currently GLBasic offers no support for this. In fact it's possible to set different screen resolutions with the SETSCREEN command but however one can not be sure if this resolution is working on every graphic card.
To find a remedy we can use a function of the Windows API which will deliver all possible resolutions of a graphic card. The following example program will show how to use this function in own programs.
From this place once more "special thanks to Gernot" for the help to find the right way calling this function.
The core is the function GetScreenModes() which can be called in two ways.
GetScreenModes(0)
--> will deliver all resolutions which were supported by the graphic car. Some resolutions are shown several times as many resolutions could be used with differnt color depth and frequency. Color depth and frequency are not important for GLBasic at the time as they could not be affected with the normal commands like SETSCREEN (but who knows what future brings)
GetScreenModes(1)
--> will deliver all resolutions too but double entries will be deleted from the list.
// --------------------------------- //
// Project: ScreenModes
// Start: Thursday, July 05, 2007
// IDE Version: 4.237
// this structure is needed to use function GetScreenModes()
TYPE tScreenMode
width
height
bits
frequency
ENDTYPE
GLOBAL ScreenMode[] AS tScreenMode
GLOBAL scrmode AS tScreenMode
// test program part 1
LOADFONT "arial.bmp", 0 // <-- here please enter an own font !!!!!!
GETFONTSIZE fontx, fonty
GetScreenModes(0)
PRINT "All possible resolutions:", 0, 0
y = 2 * fonty
FOREACH scrmode IN ScreenMode[]
PRINT scrmode.width + " x " + scrmode.height + " Color depth: "+scrmode.bits+" Bits " + "Frequency: "+scrmode.frequency, 0, y
INC y, fonty
NEXT
SHOWSCREEN
KEYWAIT
// test program part 2
GetScreenModes(1)
PRINT "Distinct resolutions:", 0, 0
y = 2 * fonty
FOREACH scrmode IN ScreenMode[]
PRINT scrmode.width + " x " + scrmode.height, 0, y
INC y, fonty
NEXT
SHOWSCREEN
KEYWAIT
// test program part 3
LOCAL maxres = BOUNDS(ScreenMode[], 0) - 1
SETSCREEN ScreenMode[maxres].width, ScreenMode[maxres].height, 1
PRINT "This is the highest resolution possible in fullscreen mode", 0, 0
y = 2 * fonty
FOREACH scrmode IN ScreenMode[]
PRINT scrmode.width + " x " + scrmode.height, 0, y
INC y, fonty
NEXT
SHOWSCREEN
KEYWAIT
END
FUNCTION WeNeedOne:
ENDFUNCTION
// In __GLBASIC__ namespace, outside of functions make a pointer to a function
INLINE
DECLARE_ALIAS( user32_EnumDisplaySettings, "user32.dll", \
"EnumDisplaySettingsA", (const char*, unsigned int, void*), \
int);
ENDINLINE
FUNCTION EnumDisplaySettings: disp$, num
LOCAL retcode
INLINE
struct DEVMODE {
char dmDeviceName[32];
short dmSpecVersion;
short dmDriverVersion;
short dmSize;
short dmDriverExtra;
long dmFields;
short dmOrientation;
short dmPaperSize;
short dmPaperLength;
short dmPaperWidth;
short dmScale;
short dmCopies;
short dmDefaultSource;
short dmPrintQuality;
short dmColor;
short dmDuplex;
short dmYResolution;
short dmTTOption;
short dmCollate;
char dmFormName[32];
short dmUnusedPadding;
long dmBitsPerPel;
long dmPelsWidth;
long dmPelsHeight;
long dmDisplayFlags;
long dmDisplayFrequency;
};
DEVMODE devmode;
devmode.dmSize = sizeof(DEVMODE);
// if disp$ = "", pass NULL instead!
if (user32_EnumDisplaySettings(LEN(disp_Str) ? disp_Str.c_str() : NULL, num, &devmode))
{
scrmode.width = devmode.dmPelsWidth;
scrmode.height = devmode.dmPelsHeight;
scrmode.bits = devmode.dmBitsPerPel;
scrmode.frequency = devmode.dmDisplayFrequency;
retcode = 1;
}
else
{
retcode = 0;
}
ENDINLINE
RETURN retcode
ENDFUNCTION
// ------------------------------------------------------------- //
// -=# SCREENMODES #=-
// ------------------------------------------------------------- //
FUNCTION GetScreenModes: restrict
LOCAL found = TRUE
LOCAL mode = 0
LOCAL notsorted = TRUE
LOCAL count, i
LOCAL swapmode AS tScreenMode
// get all resolutions possible. If the function returns a "0" or a "1"
// as frequency then Windows is not sure about the frequency so
// we will ignore this one as a precaution
WHILE found
IF EnumDisplaySettings("", mode)
IF scrmode.frequency > 1
DIMPUSH ScreenMode[], scrmode
ENDIF
ELSE
found = FALSE
ENDIF
INC mode, 1
WEND
// sort the list ascending by the resolution
// a simple bubble sort should be fast enough
count = BOUNDS(ScreenMode[], 0)
WHILE notsorted
notsorted = FALSE
FOR i = 0 TO count - 2
IF ScreenMode[i].width > ScreenMode[i+1].width AND _
ScreenMode[i].height > ScreenMode[i+1].height
swapmode = ScreenMode[i]
ScreenMode[i] = ScreenMode[i+1]
ScreenMode[i+1] = swapmode
notsorted = TRUE
ENDIF
NEXT
WEND
// if wanted delete all double entries
IF restrict = 1
swapmode.width = 0
swapmode.height = 0
FOREACH scrmode IN ScreenMode[]
IF scrmode.width = swapmode.width AND scrmode.height = swapmode.height
DELETE scrmode
ENDIF
swapmode = scrmode
NEXT
ENDIF
ENDFUNCTION // SCREENMODES
To use this functionallity in your own programs just copy the coding to your own one and delete the parts of the test programs.
If someone find this useful, have fun!
I only discovered it now. Great function.
Thank you :booze:
Wow, this still works? Good old Win32 API, it will never die!