
/* Simple program:  Fill a colormap with gray and stripe it down the screen */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#include "SDL.h"

#ifdef TEST_VGA16 /* Define this if you want to test VGA 16-color video modes */
#define NUM_COLORS	16
#else
#define NUM_COLORS	256
#endif

/* Draw a randomly sized and colored box centered about (X,Y) */
void DrawBox(SDL_Surface *screen, int X, int Y, int width, int height)
{
	static unsigned int seeded = 0;
	SDL_Rect area;
	Uint32 color;
        Uint32 randc;

	/* Seed the random number generator */
	if ( seeded == 0 ) {
		srand(time(NULL));
		seeded = 1;
	}

	/* Get the bounds of the rectangle */
	area.w = (rand()%width);
	area.h = (rand()%height);
	area.x = X-(area.w/2);
	area.y = Y-(area.h/2);
        randc = (rand()%NUM_COLORS);

        if (screen->format->BytesPerPixel==1)
        {
            color = randc;
        }
        else
        {
            color = SDL_MapRGB(screen->format, randc, randc, randc);
        }

	/* Do it! */
	SDL_FillRect(screen, &area, color);
	if ( screen->flags & SDL_DOUBLEBUF ) {
		SDL_Flip(screen);
	} else {
		SDL_UpdateRects(screen, 1, &area);
	}
}

void DrawBackground(SDL_Surface *screen)
{
	int i, j, k;
	Uint8  *buffer;
	Uint16 *buffer16;
        Uint16 color;
        Uint8  gradient;

	/* Set the surface pixels and refresh! */
	/* Use two loops in case the surface is double-buffered (both sides) */

	for ( j=0; j<2; ++j ) {
		if ( SDL_LockSurface(screen) < 0 ) {
			fprintf(stderr, "Couldn't lock display surface: %s\n",
								SDL_GetError());
			return;
		}
		buffer = (Uint8 *)screen->pixels;

		if (screen->format->BytesPerPixel!=2) {
			for ( i=0; i<screen->h; ++i ) {
				memset(buffer,(i*(NUM_COLORS-1))/screen->h, screen->w * screen->format->BytesPerPixel);
				buffer += screen->pitch;
			}
		}
                else
                {
			for ( i=0; i<screen->h; ++i ) {
				gradient=((i*(NUM_COLORS-1))/screen->h);
                                color = SDL_MapRGB(screen->format, gradient, gradient, gradient);
                                buffer16=(Uint16*)buffer;
                                for (k=0; k<screen->w; k++)
                                {
                                   *(buffer16+k)=color;
                                }
				buffer += screen->pitch;
			}
                }

		SDL_UnlockSurface(screen);
		if ( screen->flags & SDL_DOUBLEBUF ) {
			SDL_Flip(screen);
		} else {
			SDL_UpdateRect(screen, 0, 0, 0, 0);
                        break;
		}
	}
}

SDL_Surface *CreateScreen(Uint16 w, Uint16 h, Uint8 bpp, Uint32 flags)
{
	SDL_Surface *screen;
	int i;
	SDL_Color palette[NUM_COLORS];

	/* Set the video mode */
	screen = SDL_SetVideoMode(w, h, bpp, flags);
	if ( screen == NULL ) {
		fprintf(stderr, "Couldn't set display mode: %s\n",
							SDL_GetError());
		return(NULL);
	}
	fprintf(stderr, "Screen is in %s mode\n",
		(screen->flags & SDL_FULLSCREEN) ? "fullscreen" : "windowed");

	if (bpp==8) {
		/* Set a gray colormap, reverse order from white to black */
		for ( i=0; i<NUM_COLORS; ++i ) {
			palette[i].r = (NUM_COLORS-1)-i * (256 / NUM_COLORS);
			palette[i].g = (NUM_COLORS-1)-i * (256 / NUM_COLORS);
			palette[i].b = (NUM_COLORS-1)-i * (256 / NUM_COLORS);
		}
		SDL_SetColors(screen, palette, 0, NUM_COLORS);
	}

	return(screen);
}

int main(int argc, char *argv[])
{
	SDL_Surface *screen;
	Uint32 videoflags;
	int    done;
	SDL_Event event;
	int width, height, bpp;

	/* Initialize SDL */
	if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
		fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
		exit(1);
	}

	/* See if we try to get a hardware colormap */
	width = 640;
	height = 480;
	bpp = 8;
	videoflags = SDL_SWSURFACE;
	while ( argc > 1 ) {
		--argc;
		if ( argv[argc-1] && (strcmp(argv[argc-1], "-width") == 0) ) {
			width = atoi(argv[argc]);
			--argc;
		} else
		if ( argv[argc-1] && (strcmp(argv[argc-1], "-height") == 0) ) {
			height = atoi(argv[argc]);
			--argc;
		} else
		if ( argv[argc-1] && (strcmp(argv[argc-1], "-bpp") == 0) ) {
			bpp = atoi(argv[argc]);
			--argc;
		} else
		if ( argv[argc] && (strcmp(argv[argc], "-hw") == 0) ) {
			videoflags |= SDL_HWSURFACE;
		} else
		if ( argv[argc] && (strcmp(argv[argc], "-hwpalette") == 0) ) {
			videoflags |= SDL_HWPALETTE;
		} else
		if ( argv[argc] && (strcmp(argv[argc], "-flip") == 0) ) {
			videoflags |= SDL_DOUBLEBUF;
		} else
		if ( argv[argc] && (strcmp(argv[argc], "-noframe") == 0) ) {
			videoflags |= SDL_NOFRAME;
		} else
		if ( argv[argc] && (strcmp(argv[argc], "-resize") == 0) ) {
			videoflags |= SDL_RESIZABLE;
		} else
		if ( argv[argc] && (strcmp(argv[argc], "-fullscreen") == 0) ) {
			videoflags |= SDL_FULLSCREEN;
		} else {
			fprintf(stderr, "Usage: %s [-width] [-height] [-bpp] [-hw] [-hwpalette] [-flip] [-noframe] [-fullscreen] [-resize]\n",
								argv[0]);
			exit(1);
		}
	}

	/* Set a video mode */
	screen = CreateScreen(width, height, bpp, videoflags);
	if ( screen == NULL ) {
		exit(2);
	}
        
        DrawBackground(screen);
		
	/* Wait for a keystroke */
	done = 0;
	while ( !done && SDL_WaitEvent(&event) ) {
		switch (event.type) {
			case SDL_MOUSEBUTTONDOWN:
				DrawBox(screen, event.button.x, event.button.y, width, height);
				break;
			case SDL_KEYDOWN:
				/* Ignore ALT-TAB for windows */
				if ( (event.key.keysym.sym == SDLK_LALT) ||
				     (event.key.keysym.sym == SDLK_TAB) ) {
					break;
				}
				/* Center the mouse on <SPACE> */
				if ( event.key.keysym.sym == SDLK_SPACE ) {
					SDL_WarpMouse(width/2, height/2);
					break;
				}
				/* Toggle fullscreen mode on <RETURN> */
				if ( event.key.keysym.sym == SDLK_RETURN ) {
					videoflags ^= SDL_FULLSCREEN;
					screen = CreateScreen(
						screen->w, screen->h,
						screen->format->BitsPerPixel,
								videoflags);
					if ( screen == NULL ) {
						fprintf(stderr,
					"Couldn't toggle fullscreen mode\n");
						done = 1;
					}
                                        DrawBackground(screen);
					break;
				}
				/* Any other key quits the application... */
			case SDL_QUIT:
				done = 1;
				break;
			case SDL_VIDEOEXPOSE:
				DrawBackground(screen);
				break;
			case SDL_VIDEORESIZE:
					screen = CreateScreen(
						event.resize.w, event.resize.h,
						screen->format->BitsPerPixel,
								videoflags);
					if ( screen == NULL ) {
						fprintf(stderr,
					"Couldn't resize video mode\n");
						done = 1;
					}
					DrawBackground(screen);
				break;
			default:
				break;
		}
	}
	SDL_Quit();
	return(0);
}
