1
2/* Simple program:  Fill a colormap with gray and stripe it down the screen */
3
4#include <stdio.h>
5#include <stdlib.h>
6#include <string.h>
7#include <time.h>
8
9#include "SDL.h"
10
11#ifdef TEST_VGA16 /* Define this if you want to test VGA 16-color video modes */
12#define NUM_COLORS	16
13#else
14#define NUM_COLORS	256
15#endif
16
17/* Draw a randomly sized and colored box centered about (X,Y) */
18void DrawBox(SDL_Surface *screen, int X, int Y, int width, int height)
19{
20	static unsigned int seeded = 0;
21	SDL_Rect area;
22	Uint32 color;
23        Uint32 randc;
24
25	/* Seed the random number generator */
26	if ( seeded == 0 ) {
27		srand(time(NULL));
28		seeded = 1;
29	}
30
31	/* Get the bounds of the rectangle */
32	area.w = (rand()%width);
33	area.h = (rand()%height);
34	area.x = X-(area.w/2);
35	area.y = Y-(area.h/2);
36        randc = (rand()%NUM_COLORS);
37
38        if (screen->format->BytesPerPixel==1)
39        {
40            color = randc;
41        }
42        else
43        {
44            color = SDL_MapRGB(screen->format, randc, randc, randc);
45        }
46
47	/* Do it! */
48	SDL_FillRect(screen, &area, color);
49	if ( screen->flags & SDL_DOUBLEBUF ) {
50		SDL_Flip(screen);
51	} else {
52		SDL_UpdateRects(screen, 1, &area);
53	}
54}
55
56void DrawBackground(SDL_Surface *screen)
57{
58	int i, j, k;
59	Uint8  *buffer;
60	Uint16 *buffer16;
61        Uint16 color;
62        Uint8  gradient;
63
64	/* Set the surface pixels and refresh! */
65	/* Use two loops in case the surface is double-buffered (both sides) */
66
67	for ( j=0; j<2; ++j ) {
68		if ( SDL_LockSurface(screen) < 0 ) {
69			fprintf(stderr, "Couldn't lock display surface: %s\n",
70								SDL_GetError());
71			return;
72		}
73		buffer = (Uint8 *)screen->pixels;
74
75		if (screen->format->BytesPerPixel!=2) {
76			for ( i=0; i<screen->h; ++i ) {
77				memset(buffer,(i*(NUM_COLORS-1))/screen->h, screen->w * screen->format->BytesPerPixel);
78				buffer += screen->pitch;
79			}
80		}
81                else
82                {
83			for ( i=0; i<screen->h; ++i ) {
84				gradient=((i*(NUM_COLORS-1))/screen->h);
85                                color = SDL_MapRGB(screen->format, gradient, gradient, gradient);
86                                buffer16=(Uint16*)buffer;
87                                for (k=0; k<screen->w; k++)
88                                {
89                                   *(buffer16+k)=color;
90                                }
91				buffer += screen->pitch;
92			}
93                }
94
95		SDL_UnlockSurface(screen);
96		if ( screen->flags & SDL_DOUBLEBUF ) {
97			SDL_Flip(screen);
98		} else {
99			SDL_UpdateRect(screen, 0, 0, 0, 0);
100                        break;
101		}
102	}
103}
104
105SDL_Surface *CreateScreen(Uint16 w, Uint16 h, Uint8 bpp, Uint32 flags)
106{
107	SDL_Surface *screen;
108	int i;
109	SDL_Color palette[NUM_COLORS];
110
111	/* Set the video mode */
112	screen = SDL_SetVideoMode(w, h, bpp, flags);
113	if ( screen == NULL ) {
114		fprintf(stderr, "Couldn't set display mode: %s\n",
115							SDL_GetError());
116		return(NULL);
117	}
118	fprintf(stderr, "Screen is in %s mode\n",
119		(screen->flags & SDL_FULLSCREEN) ? "fullscreen" : "windowed");
120
121	if (bpp==8) {
122		/* Set a gray colormap, reverse order from white to black */
123		for ( i=0; i<NUM_COLORS; ++i ) {
124			palette[i].r = (NUM_COLORS-1)-i * (256 / NUM_COLORS);
125			palette[i].g = (NUM_COLORS-1)-i * (256 / NUM_COLORS);
126			palette[i].b = (NUM_COLORS-1)-i * (256 / NUM_COLORS);
127		}
128		SDL_SetColors(screen, palette, 0, NUM_COLORS);
129	}
130
131	return(screen);
132}
133
134int main(int argc, char *argv[])
135{
136	SDL_Surface *screen;
137	Uint32 videoflags;
138	int    done;
139	SDL_Event event;
140	int width, height, bpp;
141
142	/* Initialize SDL */
143	if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
144		fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
145		exit(1);
146	}
147
148	/* See if we try to get a hardware colormap */
149	width = 640;
150	height = 480;
151	bpp = 8;
152	videoflags = SDL_SWSURFACE;
153	while ( argc > 1 ) {
154		--argc;
155		if ( argv[argc-1] && (strcmp(argv[argc-1], "-width") == 0) ) {
156			width = atoi(argv[argc]);
157			--argc;
158		} else
159		if ( argv[argc-1] && (strcmp(argv[argc-1], "-height") == 0) ) {
160			height = atoi(argv[argc]);
161			--argc;
162		} else
163		if ( argv[argc-1] && (strcmp(argv[argc-1], "-bpp") == 0) ) {
164			bpp = atoi(argv[argc]);
165			--argc;
166		} else
167		if ( argv[argc] && (strcmp(argv[argc], "-hw") == 0) ) {
168			videoflags |= SDL_HWSURFACE;
169		} else
170		if ( argv[argc] && (strcmp(argv[argc], "-hwpalette") == 0) ) {
171			videoflags |= SDL_HWPALETTE;
172		} else
173		if ( argv[argc] && (strcmp(argv[argc], "-flip") == 0) ) {
174			videoflags |= SDL_DOUBLEBUF;
175		} else
176		if ( argv[argc] && (strcmp(argv[argc], "-noframe") == 0) ) {
177			videoflags |= SDL_NOFRAME;
178		} else
179		if ( argv[argc] && (strcmp(argv[argc], "-resize") == 0) ) {
180			videoflags |= SDL_RESIZABLE;
181		} else
182		if ( argv[argc] && (strcmp(argv[argc], "-fullscreen") == 0) ) {
183			videoflags |= SDL_FULLSCREEN;
184		} else {
185			fprintf(stderr, "Usage: %s [-width] [-height] [-bpp] [-hw] [-hwpalette] [-flip] [-noframe] [-fullscreen] [-resize]\n",
186								argv[0]);
187			exit(1);
188		}
189	}
190
191	/* Set a video mode */
192	screen = CreateScreen(width, height, bpp, videoflags);
193	if ( screen == NULL ) {
194		exit(2);
195	}
196
197        DrawBackground(screen);
198
199	/* Wait for a keystroke */
200	done = 0;
201	while ( !done && SDL_WaitEvent(&event) ) {
202		switch (event.type) {
203			case SDL_MOUSEBUTTONDOWN:
204				DrawBox(screen, event.button.x, event.button.y, width, height);
205				break;
206			case SDL_KEYDOWN:
207				/* Ignore ALT-TAB for windows */
208				if ( (event.key.keysym.sym == SDLK_LALT) ||
209				     (event.key.keysym.sym == SDLK_TAB) ) {
210					break;
211				}
212				/* Center the mouse on <SPACE> */
213				if ( event.key.keysym.sym == SDLK_SPACE ) {
214					SDL_WarpMouse(width/2, height/2);
215					break;
216				}
217				/* Toggle fullscreen mode on <RETURN> */
218				if ( event.key.keysym.sym == SDLK_RETURN ) {
219					videoflags ^= SDL_FULLSCREEN;
220					screen = CreateScreen(
221						screen->w, screen->h,
222						screen->format->BitsPerPixel,
223								videoflags);
224					if ( screen == NULL ) {
225						fprintf(stderr,
226					"Couldn't toggle fullscreen mode\n");
227						done = 1;
228					}
229                                        DrawBackground(screen);
230					break;
231				}
232				/* Any other key quits the application... */
233			case SDL_QUIT:
234				done = 1;
235				break;
236			case SDL_VIDEOEXPOSE:
237				DrawBackground(screen);
238				break;
239			case SDL_VIDEORESIZE:
240					screen = CreateScreen(
241						event.resize.w, event.resize.h,
242						screen->format->BitsPerPixel,
243								videoflags);
244					if ( screen == NULL ) {
245						fprintf(stderr,
246					"Couldn't resize video mode\n");
247						done = 1;
248					}
249					DrawBackground(screen);
250				break;
251			default:
252				break;
253		}
254	}
255	SDL_Quit();
256	return(0);
257}
258