
/* Simple program:  Fill a colormap with gray and stripe it down the screen,
		    Then move an alpha valued sprite around the screen.
 */

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

#include "SDL.h"

#define FRAME_TICKS	(1000/30)		/* 30 frames/second */

/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
static void quit(int rc)
{
	SDL_Quit();
	exit(rc);
}

/* Fill the screen with a gradient */
static void FillBackground(SDL_Surface *screen)
{
	Uint8 *buffer;
	Uint16 *buffer16;
        Uint16 color;
        Uint8  gradient;
	int    i, k;

	/* Set the surface pixels and refresh! */
	if ( SDL_LockSurface(screen) < 0 ) {
		fprintf(stderr, "Couldn't lock the display surface: %s\n",
							SDL_GetError());
		quit(2);
	}
	buffer=(Uint8 *)screen->pixels;
	if (screen->format->BytesPerPixel!=2) {
		for ( i=0; i<screen->h; ++i ) {
			memset(buffer,(i*255)/screen->h, screen->w*screen->format->BytesPerPixel);
			buffer += screen->pitch;
		}
	}
        else
        {
		for ( i=0; i<screen->h; ++i ) {
			gradient=((i*255)/screen->h);
                        color = (Uint16)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);
	SDL_UpdateRect(screen, 0, 0, 0, 0);
}

/* Create a "light" -- a yellowish surface with variable alpha */
SDL_Surface *CreateLight(int radius)
{
	Uint8  trans, alphamask;
	int    range, addition;
	int    xdist, ydist;
	Uint16 x, y;
	Uint16 skip;
	Uint32 pixel;
	SDL_Surface *light;

#ifdef LIGHT_16BIT
	Uint16 *buf;

	/* Create a 16 (4/4/4/4) bpp square with a full 4-bit alpha channel */
	/* Note: this isn't any faster than a 32 bit alpha surface */
	alphamask = 0x0000000F;
	light = SDL_CreateRGBSurface(SDL_SWSURFACE, 2*radius, 2*radius, 16,
			0x0000F000, 0x00000F00, 0x000000F0, alphamask);
#else
	Uint32 *buf;

	/* Create a 32 (8/8/8/8) bpp square with a full 8-bit alpha channel */
	alphamask = 0x000000FF;
	light = SDL_CreateRGBSurface(SDL_SWSURFACE, 2*radius, 2*radius, 32,
			0xFF000000, 0x00FF0000, 0x0000FF00, alphamask);
	if ( light == NULL ) {
		fprintf(stderr, "Couldn't create light: %s\n", SDL_GetError());
		return(NULL);
	}
#endif

	/* Fill with a light yellow-orange color */
	skip = light->pitch-(light->w*light->format->BytesPerPixel);
#ifdef LIGHT_16BIT
	buf = (Uint16 *)light->pixels;
#else
	buf = (Uint32 *)light->pixels;
#endif
        /* Get a tranparent pixel value - we'll add alpha later */
	pixel = SDL_MapRGBA(light->format, 0xFF, 0xDD, 0x88, 0);
	for ( y=0; y<light->h; ++y ) {
		for ( x=0; x<light->w; ++x ) {
			*buf++ = pixel;
		}
		buf += skip;	/* Almost always 0, but just in case... */
	}

	/* Calculate alpha values for the surface. */
#ifdef LIGHT_16BIT
	buf = (Uint16 *)light->pixels;
#else
	buf = (Uint32 *)light->pixels;
#endif
	for ( y=0; y<light->h; ++y ) {
		for ( x=0; x<light->w; ++x ) {
			/* Slow distance formula (from center of light) */
			xdist = x-(light->w/2);
			ydist = y-(light->h/2);
			range = (int)sqrt(xdist*xdist+ydist*ydist);

			/* Scale distance to range of transparency (0-255) */
			if ( range > radius ) {
				trans = alphamask;
			} else {
				/* Increasing transparency with distance */
				trans = (Uint8)((range*alphamask)/radius);

				/* Lights are very transparent */
				addition = (alphamask+1)/8;
				if ( (int)trans+addition > alphamask ) {
					trans = alphamask;
				} else {
					trans += addition;
				}
			}
			/* We set the alpha component as the right N bits */
			*buf++ |= (255-trans);
		}
		buf += skip;	/* Almost always 0, but just in case... */
	}
	/* Enable RLE acceleration of this alpha surface */
	SDL_SetAlpha(light, SDL_SRCALPHA|SDL_RLEACCEL, 0);

	/* We're done! */
	return(light);
}

static Uint32 flashes = 0;
static Uint32 flashtime = 0;

void FlashLight(SDL_Surface *screen, SDL_Surface *light, int x, int y)
{
	SDL_Rect position;
	Uint32   ticks1;
	Uint32   ticks2;

	/* Easy, center light */
	position.x = x-(light->w/2);
	position.y = y-(light->h/2);
	position.w = light->w;
	position.h = light->h;
	ticks1 = SDL_GetTicks();
	SDL_BlitSurface(light, NULL, screen, &position);
	ticks2 = SDL_GetTicks();
	SDL_UpdateRects(screen, 1, &position);
	++flashes;

	/* Update time spend doing alpha blitting */
	flashtime += (ticks2-ticks1);
}

static int sprite_visible = 0;
static SDL_Surface *sprite;
static SDL_Surface *backing;
static SDL_Rect    position;
static int         x_vel, y_vel;
static int	   alpha_vel;

int LoadSprite(SDL_Surface *screen, char *file)
{
	SDL_Surface *converted;

	/* Load the sprite image */
	sprite = SDL_LoadBMP(file);
	if ( sprite == NULL ) {
		fprintf(stderr, "Couldn't load %s: %s", file, SDL_GetError());
		return(-1);
	}

	/* Set transparent pixel as the pixel at (0,0) */
	if ( sprite->format->palette ) {
		SDL_SetColorKey(sprite, SDL_SRCCOLORKEY,
						*(Uint8 *)sprite->pixels);
	}

	/* Convert sprite to video format */
	converted = SDL_DisplayFormat(sprite);
	SDL_FreeSurface(sprite);
	if ( converted == NULL ) {
		fprintf(stderr, "Couldn't convert background: %s\n",
							SDL_GetError());
		return(-1);
	}
	sprite = converted;

	/* Create the background */
	backing = SDL_CreateRGBSurface(SDL_SWSURFACE, sprite->w, sprite->h, 8,
								0, 0, 0, 0);
	if ( backing == NULL ) {
		fprintf(stderr, "Couldn't create background: %s\n",
							SDL_GetError());
		SDL_FreeSurface(sprite);
		return(-1);
	}

	/* Convert background to video format */
	converted = SDL_DisplayFormat(backing);
	SDL_FreeSurface(backing);
	if ( converted == NULL ) {
		fprintf(stderr, "Couldn't convert background: %s\n",
							SDL_GetError());
		SDL_FreeSurface(sprite);
		return(-1);
	}
	backing = converted;

	/* Set the initial position of the sprite */
	position.x = (screen->w-sprite->w)/2;
	position.y = (screen->h-sprite->h)/2;
	position.w = sprite->w;
	position.h = sprite->h;
	x_vel = 0; y_vel = 0;
	alpha_vel = 1;

	/* We're ready to roll. :) */
	return(0);
}

void AttractSprite(Uint16 x, Uint16 y)
{
	x_vel = ((int)x-position.x)/10;
	y_vel = ((int)y-position.y)/10;
}

void MoveSprite(SDL_Surface *screen, SDL_Surface *light)
{
	SDL_Rect updates[2];
	int alpha;

	/* Erase the sprite if it was visible */
	if ( sprite_visible ) {
		updates[0] = position;
		SDL_BlitSurface(backing, NULL, screen, &updates[0]);
	} else {
		updates[0].x = 0; updates[0].y = 0;
		updates[0].w = 0; updates[0].h = 0;
		sprite_visible = 1;
	}

	/* Since the sprite is off the screen, we can do other drawing
	   without being overwritten by the saved area behind the sprite.
	 */
	if ( light != NULL ) {
		int x, y;

		SDL_GetMouseState(&x, &y);
		FlashLight(screen, light, x, y);
	}
	   
	/* Move the sprite, bounce at the wall */
	position.x += x_vel;
	if ( (position.x < 0) || (position.x >= screen->w) ) {
		x_vel = -x_vel;
		position.x += x_vel;
	}
	position.y += y_vel;
	if ( (position.y < 0) || (position.y >= screen->h) ) {
		y_vel = -y_vel;
		position.y += y_vel;
	}

	/* Update transparency (fade in and out) */
	alpha = sprite->format->alpha;
	if ( (alpha+alpha_vel) < 0 ) {
		alpha_vel = -alpha_vel;
	} else
	if ( (alpha+alpha_vel) > 255 ) {
		alpha_vel = -alpha_vel;
	}
	SDL_SetAlpha(sprite, SDL_SRCALPHA, (Uint8)(alpha+alpha_vel));

	/* Save the area behind the sprite */
	updates[1] = position;
	SDL_BlitSurface(screen, &updates[1], backing, NULL);
	
	/* Blit the sprite onto the screen */
	updates[1] = position;
	SDL_BlitSurface(sprite, NULL, screen, &updates[1]);

	/* Make it so! */
	SDL_UpdateRects(screen, 2, updates);
}

void WarpSprite(SDL_Surface *screen, int x, int y)
{
	SDL_Rect updates[2];

	/* Erase, move, Draw, update */
	updates[0] = position;
	SDL_BlitSurface(backing, NULL, screen, &updates[0]);
	position.x = x-sprite->w/2;	/* Center about X */
	position.y = y-sprite->h/2;	/* Center about Y */
	updates[1] = position;
	SDL_BlitSurface(screen, &updates[1], backing, NULL);
	updates[1] = position;
	SDL_BlitSurface(sprite, NULL, screen, &updates[1]);
	SDL_UpdateRects(screen, 2, updates);
}

int main(int argc, char *argv[])
{
	const SDL_VideoInfo *info;
	SDL_Surface *screen;
	int    w, h;
	Uint8  video_bpp;
	Uint32 videoflags;
	int    i, done;
	SDL_Event event;
	SDL_Surface *light;
	int mouse_pressed;
	Uint32 ticks, lastticks;


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

	/* Alpha blending doesn't work well at 8-bit color */
#ifdef _WIN32_WCE
	/* Pocket PC */
	w = 240;
	h = 320;
#else
	w = 640;
	h = 480;
#endif
	info = SDL_GetVideoInfo();
	if ( info->vfmt->BitsPerPixel > 8 ) {
		video_bpp = info->vfmt->BitsPerPixel;
	} else {
		video_bpp = 16;
                fprintf(stderr, "forced 16 bpp mode\n");
	}
	videoflags = SDL_SWSURFACE;
	for ( i = 1; argv[i]; ++i ) {
		if ( strcmp(argv[i], "-bpp") == 0 ) {
			video_bpp = atoi(argv[++i]);
                        if (video_bpp<=8) {
                            video_bpp=16;
                            fprintf(stderr, "forced 16 bpp mode\n");
                        }
		} else
		if ( strcmp(argv[i], "-hw") == 0 ) {
			videoflags |= SDL_HWSURFACE;
		} else
		if ( strcmp(argv[i], "-warp") == 0 ) {
			videoflags |= SDL_HWPALETTE;
		} else
		if ( strcmp(argv[i], "-width") == 0 && argv[i+1] ) {
			w = atoi(argv[++i]);
		} else
		if ( strcmp(argv[i], "-height") == 0 && argv[i+1] ) {
			h = atoi(argv[++i]);
		} else
		if ( strcmp(argv[i], "-resize") == 0 ) {
			videoflags |= SDL_RESIZABLE;
		} else
		if ( strcmp(argv[i], "-noframe") == 0 ) {
			videoflags |= SDL_NOFRAME;
		} else
		if ( strcmp(argv[i], "-fullscreen") == 0 ) {
			videoflags |= SDL_FULLSCREEN;
		} else {
			fprintf(stderr, 
			"Usage: %s [-width N] [-height N] [-bpp N] [-warp] [-hw] [-fullscreen]\n",
								argv[0]);
			quit(1);
		}
	}

	/* Set video mode */
	if ( (screen=SDL_SetVideoMode(w,h,video_bpp,videoflags)) == NULL ) {
		fprintf(stderr, "Couldn't set %dx%dx%d video mode: %s\n",
						w, h, video_bpp, SDL_GetError());
		quit(2);
	}
	FillBackground(screen);

	/* Create the light */
	light = CreateLight(82);
	if ( light == NULL ) {
		quit(1);
	}

	/* Load the sprite */
	if ( LoadSprite(screen, "icon.bmp") < 0 ) {
		SDL_FreeSurface(light);
		quit(1);
	}

	/* Print out information about our surfaces */
	printf("Screen is at %d bits per pixel\n",screen->format->BitsPerPixel);
	if ( (screen->flags & SDL_HWSURFACE) == SDL_HWSURFACE ) {
		printf("Screen is in video memory\n");
	} else {
		printf("Screen is in system memory\n");
	}
	if ( (screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) {
		printf("Screen has double-buffering enabled\n");
	}
	if ( (sprite->flags & SDL_HWSURFACE) == SDL_HWSURFACE ) {
		printf("Sprite is in video memory\n");
	} else {
		printf("Sprite is in system memory\n");
	}

	/* Run a sample blit to trigger blit acceleration */
	MoveSprite(screen, NULL);
	if ( (sprite->flags & SDL_HWACCEL) == SDL_HWACCEL ) {
		printf("Sprite blit uses hardware alpha acceleration\n");
	} else {
		printf("Sprite blit dosn't uses hardware alpha acceleration\n");
	}

	/* Set a clipping rectangle to clip the outside edge of the screen */
	{ SDL_Rect clip;
		clip.x = 32;
		clip.y = 32;
		clip.w = screen->w-(2*32);
		clip.h = screen->h-(2*32);
		SDL_SetClipRect(screen, &clip);
	}

	/* Wait for a keystroke */
	lastticks = SDL_GetTicks();
	done = 0;
	mouse_pressed = 0;
	while ( !done ) {
		/* Update the frame -- move the sprite */
		if ( mouse_pressed ) {
			MoveSprite(screen, light);
			mouse_pressed = 0;
		} else {
			MoveSprite(screen, NULL);
		}

		/* Slow down the loop to 30 frames/second */
		ticks = SDL_GetTicks();
		if ( (ticks-lastticks) < FRAME_TICKS ) {
#ifdef CHECK_SLEEP_GRANULARITY
fprintf(stderr, "Sleeping %d ticks\n", FRAME_TICKS-(ticks-lastticks));
#endif
			SDL_Delay(FRAME_TICKS-(ticks-lastticks));
#ifdef CHECK_SLEEP_GRANULARITY
fprintf(stderr, "Slept %d ticks\n", (SDL_GetTicks()-ticks));
#endif
		}
		lastticks = ticks;

		/* Check for events */
		while ( SDL_PollEvent(&event) ) {
			switch (event.type) {
				case SDL_VIDEORESIZE:
					screen = SDL_SetVideoMode(event.resize.w, event.resize.h, video_bpp, videoflags);
					if ( screen ) {
						FillBackground(screen);
					}
					break;
				/* Attract sprite while mouse is held down */
				case SDL_MOUSEMOTION:
					if (event.motion.state != 0) {
						AttractSprite(event.motion.x,
								event.motion.y);
						mouse_pressed = 1;
					}
					break;
				case SDL_MOUSEBUTTONDOWN:
					if ( event.button.button == 1 ) {
						AttractSprite(event.button.x,
						              event.button.y);
						mouse_pressed = 1;
					} else {
						SDL_Rect area;

						area.x = event.button.x-16;
						area.y = event.button.y-16;
						area.w = 32;
						area.h = 32;
						SDL_FillRect(screen, &area, 0);
						SDL_UpdateRects(screen,1,&area);
					}
					break;
				case SDL_KEYDOWN:
#ifdef _WIN32_WCE
					// there is no ESC key at all
					done = 1;
#else
					if ( event.key.keysym.sym == SDLK_ESCAPE ) {
						done = 1;
					} else if (event.key.keysym.sym == SDLK_t) {
						videoflags ^= SDL_FULLSCREEN;
						screen = SDL_SetVideoMode(w, h, video_bpp, videoflags);
						if ( screen == NULL ) {
							fprintf(stderr, "Couldn't toggle video mode: %s\n",
									SDL_GetError());
							quit(2);
						}
						FillBackground(screen);
					}
#endif

					break;
				case SDL_QUIT:
					done = 1;
					break;
				default:
					break;
			}
		}
	}
	SDL_FreeSurface(light);
	SDL_FreeSurface(sprite);
	SDL_FreeSurface(backing);

	/* Print out some timing information */
	if ( flashes > 0 ) {
		printf("%d alpha blits, ~%4.4f ms per blit\n", 
			flashes, (float)flashtime/flashes);
	}

	SDL_Quit();
	return(0);
}
