Bei einigen Spielen kann es sinnvoll sein, wenn man seinen "Kunden" die Wahl lässt, in welchen Bildschirmauflösungen sie/er das Spiel spielen will. GLBasic bietet zur Zeit hier noch keine Hilfestellung. Man kann zwar mit dem Befehl SETSCREEN diverse Auflösungen einstellen, kann sich dabei aber nicht wirklich sicher sein, daß diese auch auf allen möglichen Computern laufen.
Abhilfe schafft hier das Einbinden einer Funktion der Window-API, die die möglichen Auflösungen der Grafikkarte zurückliefert. Das folgende Beispielprogramm demonstriert die Verwendung dieser Funktion.
An dieser Stelle nochmal "special thanks to Gernot" für die Hilfe beim Aufruf der Funktion
Herzstück ist die Funktion GetScreenModes(), die auf zwei Arten aufgerufen werden kann.
GetScreenModes(0)
--> liefert alle Auflösungen zurück, die von der Grafikkarte unterstützt werden. Hierbei können sich einzelne Auflösungen häufig wiederholen, da viele Auflösungen mit unterschiedlicher Farbtiefe und Bildwiederholfrequenz möglich sind (je nach Grafikkarte). Farbtiefe und Frequenz spielen für GLBasic noch keine Rolle, da sie mit den Standardbefehlen z.B. SETSCREEN nicht beeinflusst werden können (aber was nicht ist, kann ja noch kommen)
GetScreenModes(1)
--> liefert alle möglichen Auflösungen zurück, wobei doppelte Einträge bezüglich der Auflösung aus der Liste entfernt werden.
// --------------------------------- //
// Project: ScreenModes
// Start: Thursday, July 05, 2007
// IDE Version: 4.237
// diese Struktur wird immer benötigt, wenn man die Funktion GetScreenModes() nutzen will
TYPE tScreenMode
width
height
bits
frequency
ENDTYPE
GLOBAL ScreenMode[] AS tScreenMode
GLOBAL scrmode AS tScreenMode
// Testprogramm Teil 1
LOADFONT "arial.bmp", 0 // <-- hier bitte eigenen Font einsetzen !!!!!!
GETFONTSIZE fontx, fonty
GetScreenModes(0)
PRINT "Alle möglichen Auflösungen:", 0, 0
y = 2 * fonty
FOREACH scrmode IN ScreenMode[]
PRINT scrmode.width + " x " + scrmode.height + " Farbtiefe: "+scrmode.bits+" Bits " + "Frequenz: "+scrmode.frequency, 0, y
INC y, fonty
NEXT
SHOWSCREEN
KEYWAIT
// Testprogramm Teil 2
GetScreenModes(1)
PRINT "Auflösungen ohne Doppelnennungen:", 0, 0
y = 2 * fonty
FOREACH scrmode IN ScreenMode[]
PRINT scrmode.width + " x " + scrmode.height, 0, y
INC y, fonty
NEXT
SHOWSCREEN
KEYWAIT
// Testprogramm Teil 3
LOCAL maxres = BOUNDS(ScreenMode[], 0) - 1
SETSCREEN ScreenMode[maxres].width, ScreenMode[maxres].height, 1
PRINT "Das ist die höchstmögliche Auflösung im Vollbildmodus", 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
// alle möglichen Auflösungen ermitteln. Wenn die Funktion als
// Wiederholfrequenz eine "0" oder eine "1" zurückliefert, kann
// Windows nicht genau feststellen, um welche Frequenz es sich handelt.
// Sicherheitshalber bleibt dieser Modus dann unberücksichtigt.
WHILE found
IF EnumDisplaySettings("", mode)
IF scrmode.frequency > 1
DIMPUSH ScreenMode[], scrmode
ENDIF
ELSE
found = FALSE
ENDIF
INC mode, 1
WEND
// Liste sortieren nach der Auflösung
// Ein einfacher Bubble-Sort ist hier schnell genug
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
// wenn gewünscht, werden alle doppelten Einträge entfernt
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
Um diese Funktionalität in den eigenen Programmen zu nutzen, einfach das Coding in das eigene einbinden und die Testblöcke löschen.
Wer es gebrauchen kann, viel Spaß damit.
sag ich nur eins dazu:
FREAK ! :D
lol
Jawull!
Vorschlag Schranzor:
Du schreibst das Teil um, daß man statt dem TYPE DIM verwendet ;) dann ist das was für jeden Geschmack.
Hmm brauchts doch in dem fall net :D
mir ist grad noch etwas aufgefallen.
Funktion EnumDisplaySettings (bzw. EnumDisplaySettingsA) liefert nur die Modi zurück, die auch vom angeschlossenen Monitor unterstützt werden. Versuchhalber habe ich einmal Funktion EnumDisplaySettingsEx (bzw. EnumDisplaySettingsExA) eingebaut, die wirklich alle Modi zurückgibt, die von der Grafikkarte unterstützt werden.
Bin mir jetzt nicht sicher, ob man das wirklich auf die Menschheit loslassen sollte. Zwar reizvoll, aber mit der ersten Variante wäre man wohl eher auf der sichern Seite.
Meinungen dazu?
Sichere Seite!