diff src/video/dga/SDL_dgavideo.c @ 1785:dcec47a019e2

Fixed DGA mode sorting and eliminated doublescan and interlaced modes
author Sam Lantinga <slouken@libsdl.org>
date Tue, 09 May 2006 06:14:11 +0000
parents 45669d4efd02
children 473abd216edb
line wrap: on
line diff
--- a/src/video/dga/SDL_dgavideo.c	Mon May 08 06:54:20 2006 +0000
+++ b/src/video/dga/SDL_dgavideo.c	Tue May 09 06:14:11 2006 +0000
@@ -41,6 +41,8 @@
 /* get function pointers... */
 #include "../x11/SDL_x11dyn.h"
 
+/*#define DGA_DEBUG*/
+
 /* Heheh we're using X11 event code */
 extern void X11_SaveScreenSaver(Display *display, int *saved_timeout, BOOL *dpms);
 extern void X11_DisableScreenSaver(Display *display);
@@ -182,8 +184,8 @@
 		return(0);
 	}
 	index = ((bpp+7)/8)-1;
-	for ( i=0; i<SDL_nummodes[index]; ++i ) {
-		mode = SDL_modelist[index][i];
+	if ( SDL_nummodes[index] > 0 ) {
+		mode = SDL_modelist[index][SDL_nummodes[index]-1];
 		if ( (mode->w == w) && (mode->h == h) ) {
 			return(0);
 		}
@@ -286,14 +288,21 @@
     const SDL_NAME(XDGAMode) *a = (const SDL_NAME(XDGAMode) *)va;
     const SDL_NAME(XDGAMode) *b = (const SDL_NAME(XDGAMode) *)vb;
 
-    /* Prefer DirectColor visuals for otherwise equal modes */
     if ( (a->viewportWidth == b->viewportWidth) &&
          (b->viewportHeight == a->viewportHeight) ) {
-        if ( a->visualClass == DirectColor )
+        /* Prefer 32 bpp over 24 bpp, 16 bpp over 15 bpp */
+        int a_bpp = a->depth == 24 ? a->bitsPerPixel : a->depth;
+        int b_bpp = b->depth == 24 ? b->bitsPerPixel : b->depth;
+        if ( a_bpp != b_bpp ) {
+            return b_bpp - a_bpp;
+        }
+        /* Prefer DirectColor visuals, for gamma support */
+        if ( a->visualClass == DirectColor && b->visualClass != DirectColor )
             return -1;
-        if ( b->visualClass == DirectColor )
+        if ( b->visualClass == DirectColor && a->visualClass != DirectColor )
             return 1;
-        return 0;
+        /* Maintain server refresh rate sorting */
+        return a->num - b->num;
     } else if ( a->viewportWidth == b->viewportWidth ) {
         return b->viewportHeight - a->viewportHeight;
     } else {
@@ -400,12 +409,13 @@
 	modes = SDL_NAME(XDGAQueryModes)(DGA_Display, DGA_Screen, &num_modes);
 	SDL_qsort(modes, num_modes, sizeof *modes, cmpmodes);
 	for ( i=0; i<num_modes; ++i ) {
+		if ( ((modes[i].visualClass == PseudoColor) ||
+		      (modes[i].visualClass == DirectColor) ||
+		      (modes[i].visualClass == TrueColor)) && 
+		     !(modes[i].flags & (XDGAInterlaced|XDGADoublescan)) ) {
 #ifdef DGA_DEBUG
-		PrintMode(&modes[i]);
+			PrintMode(&modes[i]);
 #endif
-		if ( (modes[i].visualClass == PseudoColor) ||
-		     (modes[i].visualClass == DirectColor) ||
-		     (modes[i].visualClass == TrueColor) ) {
 			DGA_AddMode(this, modes[i].bitsPerPixel,
 			            modes[i].viewportWidth,
 			            modes[i].viewportHeight);
@@ -461,7 +471,6 @@
 	for ( i=0; i<num_modes; ++i ) {
 		int depth;
 
-		
 		depth = modes[i].depth;
 		if ( depth == 24 ) { /* Distinguish between 24 and 32 bpp */
 			depth = modes[i].bitsPerPixel;
@@ -471,7 +480,8 @@
 		     (modes[i].viewportHeight == height) &&
 		     ((modes[i].visualClass == PseudoColor) ||
 		      (modes[i].visualClass == DirectColor) ||
-		      (modes[i].visualClass == TrueColor)) ) {
+		      (modes[i].visualClass == TrueColor)) &&
+		     !(modes[i].flags & (XDGAInterlaced|XDGADoublescan)) ) {
 			break;
 		}
 	}
@@ -479,6 +489,9 @@
 		SDL_SetError("No matching video mode found");
 		return(NULL);
 	}
+#ifdef DGA_DEBUG
+	PrintMode(&modes[i]);
+#endif
 
 	/* Set the video mode */
 	mode = SDL_NAME(XDGASetMode)(DGA_Display, DGA_Screen, modes[i].num);