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. */
12static void quit(int rc)
13{
14	SDL_Quit();
15	exit(rc);
16}
17
18/* Turn a normal gamma value into an appropriate gamma ramp */
19void 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 */
34int 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
73int 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}
198