test/testalpha.c
author Sam Lantinga <slouken@libsdl.org>
Tue, 09 May 2006 07:26:58 +0000
changeset 1790 828a17e05192
parent 1779 67fc81efcfc3
child 1662 782fd950bd46
child 1895 c121d94672cb
child 3868 b2f59aadec0d
permissions -rw-r--r--
Date: Mon, 8 May 2006 14:19:30 -0700
From: Bob Ippolito
Subject: SDL trunk (r2346) and Mac OS X

The current state of the trunk doesn't quite compile on Mac OS X,
I've attached a series of patches that gets it to compile and kills a
few warnings.

sdl-trunk-r2346-dlcompat-warnings.diff:
The dlcompat thing is just loaded with incorrect type signatures ..
some of them have changed since 10.2 and others are just flat wrong.
This puts it in sync with the latest headers. People on 10.2 will get
the warnings instead of people with new kits.
slouken@0
     1
slouken@0
     2
/* Simple program:  Fill a colormap with gray and stripe it down the screen,
slouken@0
     3
		    Then move an alpha valued sprite around the screen.
slouken@0
     4
 */
slouken@0
     5
slouken@0
     6
#include <stdio.h>
slouken@0
     7
#include <stdlib.h>
slouken@0
     8
#include <string.h>
slouken@0
     9
#include <math.h>
slouken@0
    10
slouken@0
    11
#include "SDL.h"
slouken@0
    12
slouken@0
    13
#define FRAME_TICKS	(1000/30)		/* 30 frames/second */
slouken@0
    14
icculus@1151
    15
/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
icculus@1151
    16
static void quit(int rc)
icculus@1151
    17
{
icculus@1151
    18
	SDL_Quit();
icculus@1151
    19
	exit(rc);
icculus@1151
    20
}
icculus@1151
    21
slouken@1293
    22
/* Fill the screen with a gradient */
slouken@1293
    23
static void FillBackground(SDL_Surface *screen)
slouken@1293
    24
{
slouken@1293
    25
	Uint8 *buffer;
slouken@1293
    26
	Uint16 *buffer16;
slouken@1293
    27
        Uint16 color;
slouken@1293
    28
        Uint8  gradient;
slouken@1293
    29
	int    i, k;
slouken@1293
    30
slouken@1293
    31
	/* Set the surface pixels and refresh! */
slouken@1293
    32
	if ( SDL_LockSurface(screen) < 0 ) {
slouken@1293
    33
		fprintf(stderr, "Couldn't lock the display surface: %s\n",
slouken@1293
    34
							SDL_GetError());
slouken@1293
    35
		quit(2);
slouken@1293
    36
	}
slouken@1293
    37
	buffer=(Uint8 *)screen->pixels;
slouken@1293
    38
	if (screen->format->BytesPerPixel!=2) {
slouken@1293
    39
		for ( i=0; i<screen->h; ++i ) {
slouken@1293
    40
			memset(buffer,(i*255)/screen->h, screen->w*screen->format->BytesPerPixel);
slouken@1293
    41
			buffer += screen->pitch;
slouken@1293
    42
		}
slouken@1293
    43
	}
slouken@1293
    44
        else
slouken@1293
    45
        {
slouken@1293
    46
		for ( i=0; i<screen->h; ++i ) {
slouken@1293
    47
			gradient=((i*255)/screen->h);
slouken@1465
    48
                        color = (Uint16)SDL_MapRGB(screen->format, gradient, gradient, gradient);
slouken@1293
    49
                        buffer16=(Uint16*)buffer;
slouken@1293
    50
                        for (k=0; k<screen->w; k++)
slouken@1293
    51
                        {
slouken@1293
    52
                            *(buffer16+k)=color;
slouken@1293
    53
                        }
slouken@1293
    54
			buffer += screen->pitch;
slouken@1293
    55
		}
slouken@1293
    56
        }
slouken@1293
    57
slouken@1293
    58
	SDL_UnlockSurface(screen);
slouken@1293
    59
	SDL_UpdateRect(screen, 0, 0, 0, 0);
slouken@1293
    60
}
icculus@1151
    61
slouken@0
    62
/* Create a "light" -- a yellowish surface with variable alpha */
slouken@1516
    63
SDL_Surface *CreateLight(int radius)
slouken@0
    64
{
slouken@0
    65
	Uint8  trans, alphamask;
slouken@0
    66
	int    range, addition;
slouken@0
    67
	int    xdist, ydist;
slouken@0
    68
	Uint16 x, y;
slouken@0
    69
	Uint16 skip;
slouken@0
    70
	Uint32 pixel;
slouken@0
    71
	SDL_Surface *light;
slouken@0
    72
slouken@0
    73
#ifdef LIGHT_16BIT
slouken@0
    74
	Uint16 *buf;
slouken@0
    75
slouken@0
    76
	/* Create a 16 (4/4/4/4) bpp square with a full 4-bit alpha channel */
slouken@0
    77
	/* Note: this isn't any faster than a 32 bit alpha surface */
slouken@0
    78
	alphamask = 0x0000000F;
slouken@0
    79
	light = SDL_CreateRGBSurface(SDL_SWSURFACE, 2*radius, 2*radius, 16,
slouken@0
    80
			0x0000F000, 0x00000F00, 0x000000F0, alphamask);
slouken@0
    81
#else
slouken@0
    82
	Uint32 *buf;
slouken@0
    83
slouken@0
    84
	/* Create a 32 (8/8/8/8) bpp square with a full 8-bit alpha channel */
slouken@0
    85
	alphamask = 0x000000FF;
slouken@0
    86
	light = SDL_CreateRGBSurface(SDL_SWSURFACE, 2*radius, 2*radius, 32,
slouken@0
    87
			0xFF000000, 0x00FF0000, 0x0000FF00, alphamask);
slouken@0
    88
	if ( light == NULL ) {
slouken@0
    89
		fprintf(stderr, "Couldn't create light: %s\n", SDL_GetError());
slouken@0
    90
		return(NULL);
slouken@0
    91
	}
slouken@0
    92
#endif
slouken@0
    93
slouken@0
    94
	/* Fill with a light yellow-orange color */
slouken@0
    95
	skip = light->pitch-(light->w*light->format->BytesPerPixel);
slouken@0
    96
#ifdef LIGHT_16BIT
slouken@0
    97
	buf = (Uint16 *)light->pixels;
slouken@0
    98
#else
slouken@0
    99
	buf = (Uint32 *)light->pixels;
slouken@0
   100
#endif
slouken@0
   101
        /* Get a tranparent pixel value - we'll add alpha later */
slouken@0
   102
	pixel = SDL_MapRGBA(light->format, 0xFF, 0xDD, 0x88, 0);
slouken@0
   103
	for ( y=0; y<light->h; ++y ) {
slouken@0
   104
		for ( x=0; x<light->w; ++x ) {
slouken@0
   105
			*buf++ = pixel;
slouken@0
   106
		}
slouken@0
   107
		buf += skip;	/* Almost always 0, but just in case... */
slouken@0
   108
	}
slouken@0
   109
slouken@0
   110
	/* Calculate alpha values for the surface. */
slouken@0
   111
#ifdef LIGHT_16BIT
slouken@0
   112
	buf = (Uint16 *)light->pixels;
slouken@0
   113
#else
slouken@0
   114
	buf = (Uint32 *)light->pixels;
slouken@0
   115
#endif
slouken@0
   116
	for ( y=0; y<light->h; ++y ) {
slouken@0
   117
		for ( x=0; x<light->w; ++x ) {
slouken@0
   118
			/* Slow distance formula (from center of light) */
slouken@0
   119
			xdist = x-(light->w/2);
slouken@0
   120
			ydist = y-(light->h/2);
slouken@0
   121
			range = (int)sqrt(xdist*xdist+ydist*ydist);
slouken@0
   122
slouken@0
   123
			/* Scale distance to range of transparency (0-255) */
slouken@0
   124
			if ( range > radius ) {
slouken@0
   125
				trans = alphamask;
slouken@0
   126
			} else {
slouken@0
   127
				/* Increasing transparency with distance */
slouken@0
   128
				trans = (Uint8)((range*alphamask)/radius);
slouken@0
   129
slouken@0
   130
				/* Lights are very transparent */
slouken@0
   131
				addition = (alphamask+1)/8;
slouken@0
   132
				if ( (int)trans+addition > alphamask ) {
slouken@0
   133
					trans = alphamask;
slouken@0
   134
				} else {
slouken@0
   135
					trans += addition;
slouken@0
   136
				}
slouken@0
   137
			}
slouken@0
   138
			/* We set the alpha component as the right N bits */
slouken@0
   139
			*buf++ |= (255-trans);
slouken@0
   140
		}
slouken@0
   141
		buf += skip;	/* Almost always 0, but just in case... */
slouken@0
   142
	}
slouken@0
   143
	/* Enable RLE acceleration of this alpha surface */
slouken@0
   144
	SDL_SetAlpha(light, SDL_SRCALPHA|SDL_RLEACCEL, 0);
slouken@0
   145
slouken@0
   146
	/* We're done! */
slouken@0
   147
	return(light);
slouken@0
   148
}
slouken@0
   149
slouken@0
   150
static Uint32 flashes = 0;
slouken@0
   151
static Uint32 flashtime = 0;
slouken@0
   152
slouken@0
   153
void FlashLight(SDL_Surface *screen, SDL_Surface *light, int x, int y)
slouken@0
   154
{
slouken@0
   155
	SDL_Rect position;
slouken@0
   156
	Uint32   ticks1;
slouken@0
   157
	Uint32   ticks2;
slouken@0
   158
slouken@0
   159
	/* Easy, center light */
slouken@0
   160
	position.x = x-(light->w/2);
slouken@0
   161
	position.y = y-(light->h/2);
slouken@0
   162
	position.w = light->w;
slouken@0
   163
	position.h = light->h;
slouken@0
   164
	ticks1 = SDL_GetTicks();
slouken@0
   165
	SDL_BlitSurface(light, NULL, screen, &position);
slouken@0
   166
	ticks2 = SDL_GetTicks();
slouken@0
   167
	SDL_UpdateRects(screen, 1, &position);
slouken@0
   168
	++flashes;
slouken@0
   169
slouken@0
   170
	/* Update time spend doing alpha blitting */
slouken@0
   171
	flashtime += (ticks2-ticks1);
slouken@0
   172
}
slouken@0
   173
slouken@0
   174
static int sprite_visible = 0;
slouken@0
   175
static SDL_Surface *sprite;
slouken@0
   176
static SDL_Surface *backing;
slouken@0
   177
static SDL_Rect    position;
slouken@0
   178
static int         x_vel, y_vel;
slouken@0
   179
static int	   alpha_vel;
slouken@0
   180
slouken@0
   181
int LoadSprite(SDL_Surface *screen, char *file)
slouken@0
   182
{
slouken@0
   183
	SDL_Surface *converted;
slouken@0
   184
slouken@0
   185
	/* Load the sprite image */
slouken@0
   186
	sprite = SDL_LoadBMP(file);
slouken@0
   187
	if ( sprite == NULL ) {
slouken@0
   188
		fprintf(stderr, "Couldn't load %s: %s", file, SDL_GetError());
slouken@0
   189
		return(-1);
slouken@0
   190
	}
slouken@0
   191
slouken@0
   192
	/* Set transparent pixel as the pixel at (0,0) */
slouken@0
   193
	if ( sprite->format->palette ) {
slouken@0
   194
		SDL_SetColorKey(sprite, SDL_SRCCOLORKEY,
slouken@0
   195
						*(Uint8 *)sprite->pixels);
slouken@0
   196
	}
slouken@0
   197
slouken@0
   198
	/* Convert sprite to video format */
slouken@0
   199
	converted = SDL_DisplayFormat(sprite);
slouken@0
   200
	SDL_FreeSurface(sprite);
slouken@0
   201
	if ( converted == NULL ) {
slouken@0
   202
		fprintf(stderr, "Couldn't convert background: %s\n",
slouken@0
   203
							SDL_GetError());
slouken@0
   204
		return(-1);
slouken@0
   205
	}
slouken@0
   206
	sprite = converted;
slouken@0
   207
slouken@0
   208
	/* Create the background */
slouken@0
   209
	backing = SDL_CreateRGBSurface(SDL_SWSURFACE, sprite->w, sprite->h, 8,
slouken@0
   210
								0, 0, 0, 0);
slouken@0
   211
	if ( backing == NULL ) {
slouken@0
   212
		fprintf(stderr, "Couldn't create background: %s\n",
slouken@0
   213
							SDL_GetError());
slouken@0
   214
		SDL_FreeSurface(sprite);
slouken@0
   215
		return(-1);
slouken@0
   216
	}
slouken@0
   217
slouken@0
   218
	/* Convert background to video format */
slouken@0
   219
	converted = SDL_DisplayFormat(backing);
slouken@0
   220
	SDL_FreeSurface(backing);
slouken@0
   221
	if ( converted == NULL ) {
slouken@0
   222
		fprintf(stderr, "Couldn't convert background: %s\n",
slouken@0
   223
							SDL_GetError());
slouken@0
   224
		SDL_FreeSurface(sprite);
slouken@0
   225
		return(-1);
slouken@0
   226
	}
slouken@0
   227
	backing = converted;
slouken@0
   228
slouken@0
   229
	/* Set the initial position of the sprite */
slouken@0
   230
	position.x = (screen->w-sprite->w)/2;
slouken@0
   231
	position.y = (screen->h-sprite->h)/2;
slouken@0
   232
	position.w = sprite->w;
slouken@0
   233
	position.h = sprite->h;
slouken@0
   234
	x_vel = 0; y_vel = 0;
slouken@0
   235
	alpha_vel = 1;
slouken@0
   236
slouken@0
   237
	/* We're ready to roll. :) */
slouken@0
   238
	return(0);
slouken@0
   239
}
slouken@0
   240
slouken@0
   241
void AttractSprite(Uint16 x, Uint16 y)
slouken@0
   242
{
slouken@0
   243
	x_vel = ((int)x-position.x)/10;
slouken@0
   244
	y_vel = ((int)y-position.y)/10;
slouken@0
   245
}
slouken@0
   246
slouken@0
   247
void MoveSprite(SDL_Surface *screen, SDL_Surface *light)
slouken@0
   248
{
slouken@0
   249
	SDL_Rect updates[2];
slouken@0
   250
	int alpha;
slouken@0
   251
slouken@0
   252
	/* Erase the sprite if it was visible */
slouken@0
   253
	if ( sprite_visible ) {
slouken@0
   254
		updates[0] = position;
slouken@0
   255
		SDL_BlitSurface(backing, NULL, screen, &updates[0]);
slouken@0
   256
	} else {
slouken@0
   257
		updates[0].x = 0; updates[0].y = 0;
slouken@0
   258
		updates[0].w = 0; updates[0].h = 0;
slouken@0
   259
		sprite_visible = 1;
slouken@0
   260
	}
slouken@0
   261
slouken@0
   262
	/* Since the sprite is off the screen, we can do other drawing
slouken@0
   263
	   without being overwritten by the saved area behind the sprite.
slouken@0
   264
	 */
slouken@0
   265
	if ( light != NULL ) {
slouken@0
   266
		int x, y;
slouken@0
   267
slouken@0
   268
		SDL_GetMouseState(&x, &y);
slouken@0
   269
		FlashLight(screen, light, x, y);
slouken@0
   270
	}
slouken@0
   271
	   
slouken@0
   272
	/* Move the sprite, bounce at the wall */
slouken@0
   273
	position.x += x_vel;
slouken@0
   274
	if ( (position.x < 0) || (position.x >= screen->w) ) {
slouken@0
   275
		x_vel = -x_vel;
slouken@0
   276
		position.x += x_vel;
slouken@0
   277
	}
slouken@0
   278
	position.y += y_vel;
slouken@0
   279
	if ( (position.y < 0) || (position.y >= screen->h) ) {
slouken@0
   280
		y_vel = -y_vel;
slouken@0
   281
		position.y += y_vel;
slouken@0
   282
	}
slouken@0
   283
slouken@0
   284
	/* Update transparency (fade in and out) */
slouken@0
   285
	alpha = sprite->format->alpha;
slouken@0
   286
	if ( (alpha+alpha_vel) < 0 ) {
slouken@0
   287
		alpha_vel = -alpha_vel;
slouken@0
   288
	} else
slouken@0
   289
	if ( (alpha+alpha_vel) > 255 ) {
slouken@0
   290
		alpha_vel = -alpha_vel;
slouken@0
   291
	}
slouken@0
   292
	SDL_SetAlpha(sprite, SDL_SRCALPHA, (Uint8)(alpha+alpha_vel));
slouken@0
   293
slouken@0
   294
	/* Save the area behind the sprite */
slouken@0
   295
	updates[1] = position;
slouken@0
   296
	SDL_BlitSurface(screen, &updates[1], backing, NULL);
slouken@0
   297
	
slouken@0
   298
	/* Blit the sprite onto the screen */
slouken@0
   299
	updates[1] = position;
slouken@0
   300
	SDL_BlitSurface(sprite, NULL, screen, &updates[1]);
slouken@0
   301
slouken@0
   302
	/* Make it so! */
slouken@0
   303
	SDL_UpdateRects(screen, 2, updates);
slouken@0
   304
}
slouken@0
   305
slouken@0
   306
void WarpSprite(SDL_Surface *screen, int x, int y)
slouken@0
   307
{
slouken@0
   308
	SDL_Rect updates[2];
slouken@0
   309
slouken@0
   310
	/* Erase, move, Draw, update */
slouken@0
   311
	updates[0] = position;
slouken@0
   312
	SDL_BlitSurface(backing, NULL, screen, &updates[0]);
slouken@0
   313
	position.x = x-sprite->w/2;	/* Center about X */
slouken@0
   314
	position.y = y-sprite->h/2;	/* Center about Y */
slouken@0
   315
	updates[1] = position;
slouken@0
   316
	SDL_BlitSurface(screen, &updates[1], backing, NULL);
slouken@0
   317
	updates[1] = position;
slouken@0
   318
	SDL_BlitSurface(sprite, NULL, screen, &updates[1]);
slouken@0
   319
	SDL_UpdateRects(screen, 2, updates);
slouken@0
   320
}
slouken@0
   321
slouken@0
   322
int main(int argc, char *argv[])
slouken@0
   323
{
slouken@0
   324
	const SDL_VideoInfo *info;
slouken@0
   325
	SDL_Surface *screen;
slouken@1293
   326
	int    w, h;
slouken@0
   327
	Uint8  video_bpp;
slouken@0
   328
	Uint32 videoflags;
slouken@1293
   329
	int    i, done;
slouken@0
   330
	SDL_Event event;
slouken@0
   331
	SDL_Surface *light;
slouken@0
   332
	int mouse_pressed;
slouken@0
   333
	Uint32 ticks, lastticks;
slouken@691
   334
slouken@0
   335
slouken@0
   336
	/* Initialize SDL */
slouken@0
   337
	if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
slouken@0
   338
		fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
icculus@1151
   339
		return(1);
slouken@0
   340
	}
slouken@0
   341
slouken@0
   342
	/* Alpha blending doesn't work well at 8-bit color */
slouken@1465
   343
#ifdef _WIN32_WCE
slouken@1465
   344
	/* Pocket PC */
slouken@1465
   345
	w = 240;
slouken@1465
   346
	h = 320;
slouken@1465
   347
#else
slouken@1293
   348
	w = 640;
slouken@1293
   349
	h = 480;
slouken@1465
   350
#endif
slouken@0
   351
	info = SDL_GetVideoInfo();
slouken@0
   352
	if ( info->vfmt->BitsPerPixel > 8 ) {
slouken@0
   353
		video_bpp = info->vfmt->BitsPerPixel;
slouken@0
   354
	} else {
slouken@0
   355
		video_bpp = 16;
slouken@691
   356
                fprintf(stderr, "forced 16 bpp mode\n");
slouken@0
   357
	}
slouken@0
   358
	videoflags = SDL_SWSURFACE;
slouken@1293
   359
	for ( i = 1; argv[i]; ++i ) {
slouken@1293
   360
		if ( strcmp(argv[i], "-bpp") == 0 ) {
slouken@1293
   361
			video_bpp = atoi(argv[++i]);
slouken@691
   362
                        if (video_bpp<=8) {
slouken@691
   363
                            video_bpp=16;
slouken@691
   364
                            fprintf(stderr, "forced 16 bpp mode\n");
slouken@691
   365
                        }
slouken@0
   366
		} else
slouken@1293
   367
		if ( strcmp(argv[i], "-hw") == 0 ) {
slouken@0
   368
			videoflags |= SDL_HWSURFACE;
slouken@0
   369
		} else
slouken@1293
   370
		if ( strcmp(argv[i], "-warp") == 0 ) {
slouken@0
   371
			videoflags |= SDL_HWPALETTE;
slouken@0
   372
		} else
slouken@1293
   373
		if ( strcmp(argv[i], "-width") == 0 && argv[i+1] ) {
slouken@1293
   374
			w = atoi(argv[++i]);
slouken@1293
   375
		} else
slouken@1293
   376
		if ( strcmp(argv[i], "-height") == 0 && argv[i+1] ) {
slouken@1293
   377
			h = atoi(argv[++i]);
slouken@1293
   378
		} else
slouken@1293
   379
		if ( strcmp(argv[i], "-resize") == 0 ) {
slouken@1293
   380
			videoflags |= SDL_RESIZABLE;
slouken@1293
   381
		} else
slouken@1293
   382
		if ( strcmp(argv[i], "-noframe") == 0 ) {
slouken@1293
   383
			videoflags |= SDL_NOFRAME;
slouken@1293
   384
		} else
slouken@1293
   385
		if ( strcmp(argv[i], "-fullscreen") == 0 ) {
slouken@0
   386
			videoflags |= SDL_FULLSCREEN;
slouken@0
   387
		} else {
slouken@0
   388
			fprintf(stderr, 
slouken@1293
   389
			"Usage: %s [-width N] [-height N] [-bpp N] [-warp] [-hw] [-fullscreen]\n",
slouken@0
   390
								argv[0]);
icculus@1151
   391
			quit(1);
slouken@0
   392
		}
slouken@0
   393
	}
slouken@0
   394
slouken@1465
   395
	/* Set video mode */
slouken@1293
   396
	if ( (screen=SDL_SetVideoMode(w,h,video_bpp,videoflags)) == NULL ) {
slouken@1465
   397
		fprintf(stderr, "Couldn't set %dx%dx%d video mode: %s\n",
slouken@1465
   398
						w, h, video_bpp, SDL_GetError());
icculus@1151
   399
		quit(2);
slouken@0
   400
	}
slouken@1293
   401
	FillBackground(screen);
slouken@0
   402
slouken@0
   403
	/* Create the light */
slouken@1516
   404
	light = CreateLight(82);
slouken@0
   405
	if ( light == NULL ) {
icculus@1151
   406
		quit(1);
slouken@0
   407
	}
slouken@0
   408
slouken@0
   409
	/* Load the sprite */
slouken@0
   410
	if ( LoadSprite(screen, "icon.bmp") < 0 ) {
slouken@0
   411
		SDL_FreeSurface(light);
icculus@1151
   412
		quit(1);
slouken@0
   413
	}
slouken@0
   414
slouken@886
   415
	/* Print out information about our surfaces */
slouken@886
   416
	printf("Screen is at %d bits per pixel\n",screen->format->BitsPerPixel);
slouken@886
   417
	if ( (screen->flags & SDL_HWSURFACE) == SDL_HWSURFACE ) {
slouken@886
   418
		printf("Screen is in video memory\n");
slouken@886
   419
	} else {
slouken@886
   420
		printf("Screen is in system memory\n");
slouken@886
   421
	}
slouken@886
   422
	if ( (screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) {
slouken@886
   423
		printf("Screen has double-buffering enabled\n");
slouken@886
   424
	}
slouken@886
   425
	if ( (sprite->flags & SDL_HWSURFACE) == SDL_HWSURFACE ) {
slouken@886
   426
		printf("Sprite is in video memory\n");
slouken@886
   427
	} else {
slouken@886
   428
		printf("Sprite is in system memory\n");
slouken@886
   429
	}
slouken@886
   430
slouken@886
   431
	/* Run a sample blit to trigger blit acceleration */
slouken@1293
   432
	MoveSprite(screen, NULL);
slouken@886
   433
	if ( (sprite->flags & SDL_HWACCEL) == SDL_HWACCEL ) {
slouken@886
   434
		printf("Sprite blit uses hardware alpha acceleration\n");
slouken@886
   435
	} else {
slouken@886
   436
		printf("Sprite blit dosn't uses hardware alpha acceleration\n");
slouken@886
   437
	}
slouken@886
   438
slouken@0
   439
	/* Set a clipping rectangle to clip the outside edge of the screen */
slouken@0
   440
	{ SDL_Rect clip;
slouken@0
   441
		clip.x = 32;
slouken@0
   442
		clip.y = 32;
slouken@0
   443
		clip.w = screen->w-(2*32);
slouken@0
   444
		clip.h = screen->h-(2*32);
slouken@0
   445
		SDL_SetClipRect(screen, &clip);
slouken@0
   446
	}
slouken@0
   447
slouken@0
   448
	/* Wait for a keystroke */
slouken@0
   449
	lastticks = SDL_GetTicks();
slouken@0
   450
	done = 0;
slouken@0
   451
	mouse_pressed = 0;
slouken@0
   452
	while ( !done ) {
slouken@0
   453
		/* Update the frame -- move the sprite */
slouken@0
   454
		if ( mouse_pressed ) {
slouken@0
   455
			MoveSprite(screen, light);
slouken@0
   456
			mouse_pressed = 0;
slouken@0
   457
		} else {
slouken@0
   458
			MoveSprite(screen, NULL);
slouken@0
   459
		}
slouken@0
   460
slouken@0
   461
		/* Slow down the loop to 30 frames/second */
slouken@0
   462
		ticks = SDL_GetTicks();
slouken@0
   463
		if ( (ticks-lastticks) < FRAME_TICKS ) {
slouken@0
   464
#ifdef CHECK_SLEEP_GRANULARITY
slouken@0
   465
fprintf(stderr, "Sleeping %d ticks\n", FRAME_TICKS-(ticks-lastticks));
slouken@0
   466
#endif
slouken@0
   467
			SDL_Delay(FRAME_TICKS-(ticks-lastticks));
slouken@0
   468
#ifdef CHECK_SLEEP_GRANULARITY
slouken@0
   469
fprintf(stderr, "Slept %d ticks\n", (SDL_GetTicks()-ticks));
slouken@0
   470
#endif
slouken@0
   471
		}
slouken@0
   472
		lastticks = ticks;
slouken@0
   473
slouken@0
   474
		/* Check for events */
slouken@0
   475
		while ( SDL_PollEvent(&event) ) {
slouken@0
   476
			switch (event.type) {
slouken@1293
   477
				case SDL_VIDEORESIZE:
slouken@1293
   478
					screen = SDL_SetVideoMode(event.resize.w, event.resize.h, video_bpp, videoflags);
slouken@1293
   479
					if ( screen ) {
slouken@1293
   480
						FillBackground(screen);
slouken@1293
   481
					}
slouken@1293
   482
					break;
slouken@0
   483
				/* Attract sprite while mouse is held down */
slouken@0
   484
				case SDL_MOUSEMOTION:
slouken@0
   485
					if (event.motion.state != 0) {
slouken@0
   486
						AttractSprite(event.motion.x,
slouken@0
   487
								event.motion.y);
slouken@0
   488
						mouse_pressed = 1;
slouken@0
   489
					}
slouken@0
   490
					break;
slouken@0
   491
				case SDL_MOUSEBUTTONDOWN:
slouken@0
   492
					if ( event.button.button == 1 ) {
slouken@0
   493
						AttractSprite(event.button.x,
slouken@0
   494
						              event.button.y);
slouken@0
   495
						mouse_pressed = 1;
slouken@0
   496
					} else {
slouken@0
   497
						SDL_Rect area;
slouken@0
   498
slouken@0
   499
						area.x = event.button.x-16;
slouken@0
   500
						area.y = event.button.y-16;
slouken@0
   501
						area.w = 32;
slouken@0
   502
						area.h = 32;
slouken@0
   503
						SDL_FillRect(screen, &area, 0);
slouken@0
   504
						SDL_UpdateRects(screen,1,&area);
slouken@0
   505
					}
slouken@0
   506
					break;
slouken@0
   507
				case SDL_KEYDOWN:
slouken@1779
   508
					if ( event.key.keysym.sym == SDLK_ESCAPE ) {
slouken@1779
   509
						done = 1;
slouken@1779
   510
					}
slouken@1779
   511
					break;
slouken@0
   512
				case SDL_QUIT:
slouken@0
   513
					done = 1;
slouken@0
   514
					break;
slouken@0
   515
				default:
slouken@0
   516
					break;
slouken@0
   517
			}
slouken@0
   518
		}
slouken@0
   519
	}
slouken@0
   520
	SDL_FreeSurface(light);
slouken@0
   521
	SDL_FreeSurface(sprite);
slouken@0
   522
	SDL_FreeSurface(backing);
slouken@0
   523
slouken@0
   524
	/* Print out some timing information */
slouken@0
   525
	if ( flashes > 0 ) {
slouken@0
   526
		printf("%d alpha blits, ~%4.4f ms per blit\n", 
slouken@0
   527
			flashes, (float)flashtime/flashes);
slouken@0
   528
	}
icculus@1151
   529
icculus@1151
   530
	SDL_Quit();
slouken@0
   531
	return(0);
slouken@0
   532
}