test/testgamma.c
author Patrice Mandin <patmandin@gmail.com>
Thu, 19 Jan 2006 21:28:52 +0000
changeset 1257 448a9a64537b
parent 1151 be9c9c8f6d53
child 1662 782fd950bd46
child 1895 c121d94672cb
permissions -rw-r--r--
[PATCH] SDL_GetVideoMode() does not find best mode, part 2

Following commit 1.51, I come accross a problem when SDL must choose between
several video modes that could suit the one asked.

If I ask 320x240 with this list:
768x480 768x240 640x400 640x200 384x480 384x240 320x400 320x200

The smallest selectables modes are 384x240 and 320x400. And SDL choose the later
in this list, but 384x240 is more suitable. So I added a check to compare
the pixel count (surface) of modes, and select the one which has the smallest
pixel count.

In my example, 384x240 has 92160 pixels, and 320x400 has 128000 pixels. So now
SDL will choose 384x240 for the asked 320x240 mode.
     1 
     2 /* Bring up a window and manipulate the gamma on it */
     3 
     4 #include <stdlib.h>
     5 #include <stdio.h>
     6 #include <string.h>
     7 #include <math.h>
     8 
     9 #include "SDL.h"
    10 
    11 /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
    12 static void quit(int rc)
    13 {
    14 	SDL_Quit();
    15 	exit(rc);
    16 }
    17 
    18 /* Turn a normal gamma value into an appropriate gamma ramp */
    19 void CalculateGamma(double gamma, Uint16 *ramp)
    20 {
    21 	int i, value;
    22 
    23 	gamma = 1.0 / gamma;
    24 	for ( i=0; i<256; ++i ) {
    25 		value = (int)(pow((double)i/256.0, gamma)*65535.0 + 0.5);
    26 		if ( value > 65535 ) {
    27 			value = 65535;
    28 		}
    29 		ramp[i] = (Uint16)value;
    30 	}
    31 }
    32 
    33 /* This can be used as a general routine for all of the test programs */
    34 int get_video_args(char *argv[], int *w, int *h, int *bpp, Uint32 *flags)
    35 {
    36 	int i;
    37 
    38 	*w = 640;
    39 	*h = 480;
    40 	*bpp = 0;
    41 	*flags = SDL_SWSURFACE;
    42 
    43 	for ( i=1; argv[i]; ++i ) {
    44 		if ( strcmp(argv[i], "-width") == 0 ) {
    45 			if ( argv[i+1] ) {
    46 				*w = atoi(argv[++i]);
    47 			}
    48 		} else
    49 		if ( strcmp(argv[i], "-height") == 0 ) {
    50 			if ( argv[i+1] ) {
    51 				*h = atoi(argv[++i]);
    52 			}
    53 		} else
    54 		if ( strcmp(argv[i], "-bpp") == 0 ) {
    55 			if ( argv[i+1] ) {
    56 				*bpp = atoi(argv[++i]);
    57 			}
    58 		} else
    59 		if ( strcmp(argv[i], "-fullscreen") == 0 ) {
    60 			*flags |= SDL_FULLSCREEN;
    61 		} else
    62 		if ( strcmp(argv[i], "-hw") == 0 ) {
    63 			*flags |= SDL_HWSURFACE;
    64 		} else
    65 		if ( strcmp(argv[i], "-hwpalette") == 0 ) {
    66 			*flags |= SDL_HWPALETTE;
    67 		} else
    68 			break;
    69 	}
    70 	return i;
    71 }
    72 
    73 int main(int argc, char *argv[])
    74 {
    75 	SDL_Surface *screen;
    76 	SDL_Surface *image;
    77 	float gamma;
    78 	int i;
    79 	int w, h, bpp;
    80 	Uint32 flags;
    81 	Uint16 ramp[256];
    82 	Uint16 red_ramp[256];
    83 	Uint32 then, timeout;
    84 
    85 	/* Check command line arguments */
    86 	argv += get_video_args(argv, &w, &h, &bpp, &flags);
    87 
    88 	/* Initialize SDL */
    89 	if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
    90 		fprintf(stderr,
    91 			"Couldn't initialize SDL: %s\n", SDL_GetError());
    92 		return(1);
    93 	}
    94 
    95 	/* Initialize the display, always use hardware palette */
    96 	screen = SDL_SetVideoMode(w, h, bpp, flags | SDL_HWPALETTE);
    97 	if ( screen == NULL ) {
    98 		fprintf(stderr, "Couldn't set %dx%d video mode: %s\n",
    99 						w, h, SDL_GetError());
   100 		quit(1);
   101 	}
   102 
   103 	/* Set the window manager title bar */
   104 	SDL_WM_SetCaption("SDL gamma test", "testgamma");
   105 
   106 	/* Set the desired gamma, if any */
   107 	gamma = 1.0f;
   108 	if ( *argv ) {
   109 		gamma = (float)atof(*argv);
   110 	}
   111 	if ( SDL_SetGamma(gamma, gamma, gamma) < 0 ) {
   112 		fprintf(stderr, "Unable to set gamma: %s\n", SDL_GetError());
   113 		quit(1);
   114 	}
   115 
   116 #if 0 /* This isn't supported.  Integrating the gamma ramps isn't exact */
   117 	/* See what gamma was actually set */
   118 	float real[3];
   119 	if ( SDL_GetGamma(&real[0], &real[1], &real[2]) < 0 ) {
   120 		printf("Couldn't get gamma: %s\n", SDL_GetError());
   121 	} else {
   122 		printf("Set gamma values: R=%2.2f, G=%2.2f, B=%2.2f\n",
   123 			real[0], real[1], real[2]);
   124 	}
   125 #endif
   126 
   127 	/* Do all the drawing work */
   128 	image = SDL_LoadBMP("sample.bmp");
   129 	if ( image ) {
   130 		SDL_Rect dst;
   131 
   132 		dst.x = (screen->w - image->w)/2;
   133 		dst.y = (screen->h - image->h)/2;
   134 		dst.w = image->w;
   135 		dst.h = image->h;
   136 		SDL_BlitSurface(image, NULL, screen, &dst);
   137 		SDL_UpdateRects(screen, 1, &dst);
   138 	}
   139 
   140 	/* Wait a bit, handling events */
   141 	then = SDL_GetTicks();
   142 	timeout = (5*1000);
   143 	while ( (SDL_GetTicks()-then) < timeout ) {
   144 		SDL_Event event;
   145 
   146 		while ( SDL_PollEvent(&event) ) {
   147 			switch (event.type) {
   148 			    case SDL_QUIT:	/* Quit now */
   149 				timeout = 0;
   150 				break;
   151 			    case SDL_KEYDOWN:
   152 				switch (event.key.keysym.sym) {
   153 				    case SDLK_SPACE:	/* Go longer.. */
   154 					timeout += (5*1000);
   155 					break;
   156 				    case SDLK_UP:
   157 					gamma += 0.2f;
   158 					SDL_SetGamma(gamma, gamma, gamma);
   159 					break;
   160 				    case SDLK_DOWN:
   161 					gamma -= 0.2f;
   162 					SDL_SetGamma(gamma, gamma, gamma);
   163 					break;
   164 				    case SDLK_ESCAPE:
   165 					timeout = 0;
   166 					break;
   167 				    default:
   168 					break;
   169 				}
   170 				break;
   171 			}
   172 		}
   173 	}
   174 
   175 	/* Perform a gamma flash to red using color ramps */
   176 	while ( gamma < 10.0 ) {
   177 		/* Increase the red gamma and decrease everything else... */
   178 		gamma += 0.1f;
   179 		CalculateGamma(gamma, red_ramp);
   180 		CalculateGamma(1.0/gamma, ramp);
   181 		SDL_SetGammaRamp(red_ramp, ramp, ramp);
   182 	}
   183 	/* Finish completely red */
   184 	memset(red_ramp, 255, sizeof(red_ramp));
   185 	memset(ramp, 0, sizeof(ramp));
   186 	SDL_SetGammaRamp(red_ramp, ramp, ramp);
   187 
   188 	/* Now fade out to black */
   189 	for ( i=(red_ramp[0] >> 8); i >= 0; --i ) {
   190 		memset(red_ramp, i, sizeof(red_ramp));
   191 		SDL_SetGammaRamp(red_ramp, NULL, NULL);
   192 	}
   193 	SDL_Delay(1*1000);
   194 
   195 	SDL_Quit();
   196 	return(0);
   197 }