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