fireworks demo gsoc2008_iphone
authorHolmes Futrell <hfutrell@umail.ucsb.edu>
Fri, 18 Jul 2008 20:51:34 +0000
branchgsoc2008_iphone
changeset 238236bcf13ccb48
parent 2381 d3952f445f4d
child 2383 1cfe7fd15dad
fireworks demo
XCodeiPhoneOS/Demos/src/fireworks.c
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/XCodeiPhoneOS/Demos/src/fireworks.c	Fri Jul 18 20:51:34 2008 +0000
     1.3 @@ -0,0 +1,438 @@
     1.4 +/*
     1.5 + *	fireworks.c
     1.6 + *	written by Holmes Futrell
     1.7 + *	use however you want
     1.8 + */
     1.9 +
    1.10 +#include "SDL.h"
    1.11 +#include "math.h"
    1.12 +#include "common.h"
    1.13 +#include <math.h>
    1.14 +#include <time.h>
    1.15 +#include <OpenGLES/ES1/gl.h>
    1.16 +
    1.17 +#define MILLESECONDS_PER_FRAME 16	/* about 60 frames per second */
    1.18 +#define ACCEL 0.0001f
    1.19 +#define WIND_RESISTANCE 0.00005f
    1.20 +#define MAX_PARTICLES 2000
    1.21 +#define VEL_BEFORE_EXPLODE 0.0f
    1.22 +
    1.23 +SDL_TextureID flashTextureID;
    1.24 +
    1.25 +
    1.26 +enum particleType {
    1.27 +	emitter = 0,
    1.28 +	trail,
    1.29 +	dust
    1.30 +};
    1.31 +
    1.32 +struct glformat {
    1.33 +	int SDL_GL_RED_SIZE;
    1.34 +	int SDL_GL_GREEN_SIZE;
    1.35 +	int SDL_GL_BLUE_SIZE;
    1.36 +	int SDL_GL_ALPHA_SIZE;
    1.37 +	int SDL_GL_BUFFER_SIZE;
    1.38 +	int SDL_GL_DOUBLEBUFFER;
    1.39 +	int SDL_GL_DEPTH_SIZE;
    1.40 +	int SDL_GL_STENCIL_SIZE;
    1.41 +	int SDL_GL_ACCUM_RED_SIZE;
    1.42 +	int SDL_GL_ACCUM_GREEN_SIZE;
    1.43 +	int SDL_GL_ACCUM_BLUE_SIZE;
    1.44 +	int SDL_GL_ACCUM_ALPHA_SIZE;
    1.45 +	int SDL_GL_STEREO;
    1.46 +	int SDL_GL_MULTISAMPLEBUFFERS;
    1.47 +	int SDL_GL_MULTISAMPLESAMPLES;
    1.48 +	int SDL_GL_ACCELERATED_VISUAL;
    1.49 +	int SDL_GL_RETAINED_BACKING;
    1.50 +};
    1.51 +
    1.52 +struct particle {
    1.53 +
    1.54 +	GLfloat x;
    1.55 +	GLfloat y;
    1.56 +	GLubyte color[4];
    1.57 +	GLfloat size;
    1.58 +	GLfloat xvel;
    1.59 +	GLfloat yvel;
    1.60 +	int isActive;
    1.61 +	enum particleType type;
    1.62 +	int framesSinceEmission;
    1.63 +} particles[MAX_PARTICLES];
    1.64 +
    1.65 +void spawnParticleFromEmitter(struct particle *emitter);
    1.66 +void explodeEmitter(struct particle *emitter);
    1.67 +
    1.68 +static int num_active_particles;
    1.69 +
    1.70 +static void getError(const char *prefix)
    1.71 +{
    1.72 +    const char *error;
    1.73 +	
    1.74 +	GLenum result = glGetError();
    1.75 +	if (result == GL_NO_ERROR)
    1.76 +		return;
    1.77 +	
    1.78 +    switch (result) {
    1.79 +		case GL_NO_ERROR:
    1.80 +			error = "GL_NO_ERROR";
    1.81 +			break;
    1.82 +		case GL_INVALID_ENUM:
    1.83 +			error = "GL_INVALID_ENUM";
    1.84 +			break;
    1.85 +		case GL_INVALID_VALUE:
    1.86 +			error = "GL_INVALID_VALUE";
    1.87 +			break;
    1.88 +		case GL_INVALID_OPERATION:
    1.89 +			error = "GL_INVALID_OPERATION";
    1.90 +			break;
    1.91 +		case GL_STACK_OVERFLOW:
    1.92 +			error = "GL_STACK_OVERFLOW";
    1.93 +			break;
    1.94 +		case GL_STACK_UNDERFLOW:
    1.95 +			error = "GL_STACK_UNDERFLOW";
    1.96 +			break;
    1.97 +		case GL_OUT_OF_MEMORY:
    1.98 +			error = "GL_OUT_OF_MEMORY";
    1.99 +			break;
   1.100 +		default:
   1.101 +			error = "UNKNOWN";
   1.102 +			break;
   1.103 +    }
   1.104 +    printf("%s: %s\n", prefix, error);
   1.105 +}
   1.106 +
   1.107 +void render(void) {
   1.108 +		
   1.109 +	/* draw the background */
   1.110 +	glClear(GL_COLOR_BUFFER_BIT);
   1.111 +	
   1.112 +	struct particle *slot = particles;
   1.113 +	struct particle *curr = particles;
   1.114 +	int i;
   1.115 +	for (i=0; i<num_active_particles; i++) {
   1.116 +		if (curr->isActive) {
   1.117 +			
   1.118 +			if (curr->y > SCREEN_HEIGHT) curr->isActive = 0;
   1.119 +			if (curr->y < 0) curr->isActive = 0;
   1.120 +			if (curr->x > SCREEN_WIDTH) curr->isActive = 0;
   1.121 +			if (curr->x < 0) curr->isActive = 0;
   1.122 +
   1.123 +			curr->yvel += ACCEL * MILLESECONDS_PER_FRAME;
   1.124 +			curr->xvel += 0.0f;
   1.125 +			curr->y += curr->yvel * MILLESECONDS_PER_FRAME;
   1.126 +			curr->x += curr->xvel * MILLESECONDS_PER_FRAME;
   1.127 +			
   1.128 +			if (curr->type == emitter) {
   1.129 +				spawnParticleFromEmitter(curr);
   1.130 +				curr->framesSinceEmission = 0;
   1.131 +				if (curr->yvel > -VEL_BEFORE_EXPLODE) {
   1.132 +					explodeEmitter(curr);
   1.133 +				}
   1.134 +				curr->framesSinceEmission++;
   1.135 +			}
   1.136 +			else {
   1.137 +				
   1.138 +				float speed = sqrt(curr->xvel*curr->xvel + curr->yvel*curr->yvel);
   1.139 +				
   1.140 +				if (WIND_RESISTANCE * MILLESECONDS_PER_FRAME < speed) {
   1.141 +					float normx = curr->xvel / speed;
   1.142 +					float normy = curr->yvel / speed;
   1.143 +					curr->xvel -= normx * WIND_RESISTANCE * MILLESECONDS_PER_FRAME;
   1.144 +					curr->yvel -= normy * WIND_RESISTANCE * MILLESECONDS_PER_FRAME;
   1.145 +				}
   1.146 +				else {
   1.147 +					curr->xvel = 0;
   1.148 +					curr->yvel = 0;
   1.149 +				}
   1.150 +				
   1.151 +				if (curr->color[3] <= MILLESECONDS_PER_FRAME * 0.0005f * 255) {
   1.152 +					curr->isActive = 0;
   1.153 +
   1.154 +				}
   1.155 +				else {
   1.156 +					curr->color[3] -= MILLESECONDS_PER_FRAME * 0.0005f * 255;
   1.157 +				}
   1.158 +				
   1.159 +				if (curr->type == dust)
   1.160 +					curr->size -= MILLESECONDS_PER_FRAME * 0.010f;
   1.161 +				
   1.162 +			}
   1.163 +			
   1.164 +			*(slot++) = *curr;
   1.165 +		}
   1.166 +		curr++;
   1.167 +	}
   1.168 +	num_active_particles = slot - particles;
   1.169 +	
   1.170 +	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
   1.171 +	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   1.172 +	glTexEnvi(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, 1);
   1.173 +
   1.174 +	glEnableClientState(GL_VERTEX_ARRAY);
   1.175 +	glVertexPointer(2, GL_FLOAT, sizeof(struct particle), particles + 0);
   1.176 +	getError("vertices");
   1.177 +	
   1.178 +	glEnableClientState(GL_COLOR_ARRAY);
   1.179 +	glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(struct particle), particles[0].color);
   1.180 +	getError("colors");
   1.181 +
   1.182 +	glEnableClientState(GL_POINT_SIZE_ARRAY_OES);
   1.183 +	getError("enable client state");
   1.184 +	glPointSizePointerOES(GL_FLOAT, sizeof(struct particle), &(particles[0].size));	
   1.185 +	getError("point size");
   1.186 +
   1.187 +	glEnable(GL_POINT_SPRITE_OES);
   1.188 +	glDrawArrays(GL_POINTS, 0, num_active_particles);	
   1.189 +	getError("glDrawArrays");
   1.190 +
   1.191 +		
   1.192 +	/* update screen */
   1.193 +	SDL_RenderPresent();
   1.194 +	
   1.195 +}
   1.196 +
   1.197 +void printOpenGLAttributes(struct glformat *format) {
   1.198 +	printf("\tSDL_GL_RED_SIZE = %d\n", format->SDL_GL_RED_SIZE);
   1.199 +	printf("\tSDL_GL_GREEN_SIZE = %d\n", format->SDL_GL_GREEN_SIZE);
   1.200 +	printf("\tSDL_GL_BLUE_SIZE = %d\n", format->SDL_GL_BLUE_SIZE);
   1.201 +	printf("\tSDL_GL_ALPHA_SIZE = %d\n", format->SDL_GL_ALPHA_SIZE);
   1.202 +	printf("\tSDL_GL_BUFFER_SIZE = %d\n", format->SDL_GL_BUFFER_SIZE);
   1.203 +	printf("\tSDL_GL_DOUBLEBUFFER = %d\n", format->SDL_GL_DOUBLEBUFFER);
   1.204 +	printf("\tSDL_GL_DEPTH_SIZE = %d\n", format->SDL_GL_DEPTH_SIZE);
   1.205 +	printf("\tSDL_GL_STENCIL_SIZE = %d\n", format->SDL_GL_STENCIL_SIZE);
   1.206 +	printf("\tSDL_GL_ACCUM_RED_SIZE = %d\n", format->SDL_GL_ACCUM_RED_SIZE);
   1.207 +	printf("\tSDL_GL_ACCUM_GREEN_SIZE = %d\n", format->SDL_GL_ACCUM_GREEN_SIZE);
   1.208 +	printf("\tSDL_GL_ACCUM_BLUE_SIZE = %d\n", format->SDL_GL_ACCUM_BLUE_SIZE);
   1.209 +	printf("\tSDL_GL_ACCUM_ALPHA_SIZE = %d\n", format->SDL_GL_ACCUM_ALPHA_SIZE);
   1.210 +	printf("\tSDL_GL_STEREO = %d\n", format->SDL_GL_STEREO);
   1.211 +	printf("\tSDL_GL_MULTISAMPLEBUFFERS = %d\n", format->SDL_GL_MULTISAMPLEBUFFERS);
   1.212 +	printf("\tSDL_GL_MULTISAMPLESAMPLES = %d\n", format->SDL_GL_MULTISAMPLESAMPLES);
   1.213 +	printf("\tSDL_GL_ACCELERATED_VISUAL = %d\n", format->SDL_GL_ACCELERATED_VISUAL);
   1.214 +	printf("\tSDL_GL_RETAINED_BACKING = %d\n", format->SDL_GL_RETAINED_BACKING);	
   1.215 +}
   1.216 +
   1.217 +void setOpenGLAttributes(struct glformat *format) {
   1.218 +	SDL_GL_SetAttribute(SDL_GL_RED_SIZE, format->SDL_GL_RED_SIZE);
   1.219 +	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, format->SDL_GL_GREEN_SIZE);
   1.220 +	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, format->SDL_GL_BLUE_SIZE);
   1.221 +	SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, format->SDL_GL_ALPHA_SIZE);
   1.222 +	SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, format->SDL_GL_BUFFER_SIZE);
   1.223 +	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, format->SDL_GL_DOUBLEBUFFER);
   1.224 +	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, format->SDL_GL_DEPTH_SIZE);
   1.225 +	SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, format->SDL_GL_STENCIL_SIZE);
   1.226 +	SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, format->SDL_GL_ACCUM_RED_SIZE);
   1.227 +	SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, format->SDL_GL_ACCUM_GREEN_SIZE);
   1.228 +	SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, format->SDL_GL_ACCUM_BLUE_SIZE);
   1.229 +	SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, format->SDL_GL_ACCUM_ALPHA_SIZE);
   1.230 +	SDL_GL_SetAttribute(SDL_GL_STEREO, format->SDL_GL_STEREO);
   1.231 +	SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, format->SDL_GL_MULTISAMPLEBUFFERS);
   1.232 +	SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, format->SDL_GL_MULTISAMPLESAMPLES);
   1.233 +	SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, format->SDL_GL_ACCELERATED_VISUAL);
   1.234 +	SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, format->SDL_GL_RETAINED_BACKING);
   1.235 +}
   1.236 +
   1.237 +void getOpenGLAttributes(struct glformat *format) {
   1.238 +		
   1.239 +	SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &(format->SDL_GL_RED_SIZE));
   1.240 +	SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &(format->SDL_GL_GREEN_SIZE));
   1.241 +	SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &(format->SDL_GL_BLUE_SIZE));
   1.242 +	SDL_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &(format->SDL_GL_ALPHA_SIZE));
   1.243 +	SDL_GL_GetAttribute(SDL_GL_BUFFER_SIZE, &(format->SDL_GL_BUFFER_SIZE));
   1.244 +	SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &(format->SDL_GL_DOUBLEBUFFER));
   1.245 +	SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &(format->SDL_GL_DEPTH_SIZE));
   1.246 +	SDL_GL_GetAttribute(SDL_GL_STENCIL_SIZE, &(format->SDL_GL_STENCIL_SIZE));
   1.247 +	SDL_GL_GetAttribute(SDL_GL_ACCUM_RED_SIZE, &(format->SDL_GL_ACCUM_RED_SIZE));
   1.248 +	SDL_GL_GetAttribute(SDL_GL_ACCUM_GREEN_SIZE, &(format->SDL_GL_ACCUM_GREEN_SIZE));
   1.249 +	SDL_GL_GetAttribute(SDL_GL_ACCUM_BLUE_SIZE, &(format->SDL_GL_ACCUM_BLUE_SIZE));
   1.250 +	SDL_GL_GetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, &(format->SDL_GL_ACCUM_ALPHA_SIZE));
   1.251 +	SDL_GL_GetAttribute(SDL_GL_STEREO, &(format->SDL_GL_STEREO));
   1.252 +	SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &(format->SDL_GL_MULTISAMPLEBUFFERS));
   1.253 +	SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &(format->SDL_GL_MULTISAMPLESAMPLES));
   1.254 +	SDL_GL_GetAttribute(SDL_GL_ACCELERATED_VISUAL, &(format->SDL_GL_ACCELERATED_VISUAL));
   1.255 +	SDL_GL_GetAttribute(SDL_GL_RETAINED_BACKING, &(format->SDL_GL_RETAINED_BACKING));
   1.256 +}
   1.257 +
   1.258 +void explodeEmitter(struct particle *emitter) {
   1.259 +
   1.260 +	emitter->isActive = 0;
   1.261 +	
   1.262 +	int i;
   1.263 +	for (i=0; i<200; i++) {
   1.264 +		
   1.265 +		if (num_active_particles >= MAX_PARTICLES) return;
   1.266 +		
   1.267 +		float theta = randomFloat(0, 2.0f * 3.141592);
   1.268 +		float max = 3.0f;
   1.269 +		float speed = randomFloat(0.00, powf(0.17, max));
   1.270 +		speed = powf(speed, 1.0f / max);
   1.271 +		
   1.272 +		struct particle *p = &particles[num_active_particles];
   1.273 +		p->xvel = speed * cos(theta);
   1.274 +		p->yvel = speed * sin(theta);
   1.275 +		p->x = emitter->x + emitter->xvel;
   1.276 +		p->y = emitter->y + emitter->yvel;
   1.277 +		p->isActive = 1;
   1.278 +		p->type = dust;
   1.279 +		p->color[0] = emitter->color[0];
   1.280 +		p->color[1] = emitter->color[1];
   1.281 +		p->color[2] = emitter->color[2];
   1.282 +		p->color[3] = 255;
   1.283 +
   1.284 +		p->size = 15;
   1.285 +		
   1.286 +		num_active_particles++;
   1.287 +		
   1.288 +	}
   1.289 +	
   1.290 +}
   1.291 +
   1.292 +void spawnParticleFromEmitter(struct particle *emitter) {
   1.293 +	
   1.294 +	if (num_active_particles >= MAX_PARTICLES) return;
   1.295 +	
   1.296 +	struct particle *p = &particles[num_active_particles];
   1.297 +	p->x = emitter->x + randomFloat(-3.0, 3.0);
   1.298 +	p->y = emitter->y + emitter->size / 2.0f;
   1.299 +	p->xvel = emitter->xvel + randomFloat(-0.005, 0.005);
   1.300 +	p->yvel = emitter->yvel + 0.1;
   1.301 +	p->color[0] = (0.8f + randomFloat(-0.1, 0.0)) * 255;
   1.302 +	p->color[1] = (0.4f + randomFloat(-0.1, 0.1)) * 255;
   1.303 +	p->color[2] = (0.0f + randomFloat(0.0, 0.2)) * 255;
   1.304 +	p->color[3] = (0.7f) * 255;
   1.305 +	p->size = 10;
   1.306 +	p->type = trail;
   1.307 +	p->isActive = 1;
   1.308 +	num_active_particles++;
   1.309 +	
   1.310 +}
   1.311 +	
   1.312 +void spawnEmitterParticle(int x, int y) {
   1.313 +
   1.314 +	if (num_active_particles >= MAX_PARTICLES) return;
   1.315 +	
   1.316 +	struct particle *p = &particles[num_active_particles];
   1.317 +	p->x = x;
   1.318 +	p->y = SCREEN_HEIGHT;
   1.319 +	p->xvel = 0;
   1.320 +	p->yvel = -sqrt(2*ACCEL*(SCREEN_HEIGHT-y) + VEL_BEFORE_EXPLODE * VEL_BEFORE_EXPLODE);
   1.321 +	p->color[0] = 1.0 * 255;
   1.322 +	p->color[1] = 0.4 * 255;
   1.323 +	p->color[2] = 0.4 * 255;
   1.324 +	p->color[3] = 1.0f * 255;
   1.325 +	p->size = 10;
   1.326 +	p->type = emitter;
   1.327 +	p->framesSinceEmission = 0;
   1.328 +	p->isActive = 1;
   1.329 +	num_active_particles++;
   1.330 +}
   1.331 +
   1.332 +void initializeParticles(void) {
   1.333 +	
   1.334 +	num_active_particles = 0;
   1.335 +	
   1.336 +}
   1.337 +
   1.338 +/*
   1.339 + loads the brush texture
   1.340 + */
   1.341 +void initializeTexture() {
   1.342 +	SDL_Surface *bmp_surface;
   1.343 +	bmp_surface = SDL_LoadBMP("stroke.bmp");
   1.344 +	if (bmp_surface == NULL) {
   1.345 +		fatalError("could not load stroke.bmp");
   1.346 +	}
   1.347 +	flashTextureID = SDL_CreateTextureFromSurface(SDL_PIXELFORMAT_ABGR8888, bmp_surface);
   1.348 +	SDL_FreeSurface(bmp_surface);
   1.349 +	if (flashTextureID == 0) {
   1.350 +		fatalError("could not create brush texture");
   1.351 +	}
   1.352 +	glEnable(GL_TEXTURE_2D);
   1.353 +	glEnable(GL_BLEND);
   1.354 +	glBlendFunc(GL_SRC_ALPHA, GL_ONE);
   1.355 +}
   1.356 +
   1.357 +int main(int argc, char *argv[]) {
   1.358 +	
   1.359 +	SDL_WindowID windowID;	/* ID of main window */
   1.360 +	Uint32 startFrame;		/* time frame began to process */
   1.361 +	Uint32 endFrame;		/* time frame ended processing */
   1.362 +	Uint32 delay;			/* time to pause waiting to draw next frame */
   1.363 +	int done;				/* should we clean up and exit? */
   1.364 +	
   1.365 +	struct glformat requested, obtained;
   1.366 +	
   1.367 +	/* initialize SDL */
   1.368 +	if (SDL_Init(SDL_INIT_VIDEO) < 0) {
   1.369 +		fatalError("Could not initialize SDL");
   1.370 +	}
   1.371 +	
   1.372 +	srand(time(NULL));
   1.373 +	
   1.374 +	SDL_GL_LoadLibrary(NULL);
   1.375 +		
   1.376 +	SDL_memset(&requested, 0, sizeof(requested));
   1.377 +	requested.SDL_GL_RED_SIZE = 5;
   1.378 +	requested.SDL_GL_GREEN_SIZE = 6; 
   1.379 +	requested.SDL_GL_BLUE_SIZE = 5;
   1.380 +	requested.SDL_GL_ALPHA_SIZE = 0;
   1.381 +	requested.SDL_GL_DEPTH_SIZE = 0;
   1.382 +	requested.SDL_GL_RETAINED_BACKING = 0;
   1.383 +	requested.SDL_GL_ACCELERATED_VISUAL = 1;	
   1.384 +	
   1.385 +	setOpenGLAttributes(&requested);
   1.386 +	
   1.387 +	/* create main window and renderer */
   1.388 +	windowID = SDL_CreateWindow(NULL, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT,\
   1.389 +								SDL_WINDOW_OPENGL|SDL_WINDOW_SHOWN|SDL_WINDOW_BORDERLESS);
   1.390 +	SDL_CreateRenderer(windowID, 0, 0);		
   1.391 +	
   1.392 +	printf("Requested:\n");
   1.393 +	printOpenGLAttributes(&requested);
   1.394 +	
   1.395 +	printf("obtained:\n");
   1.396 +	getOpenGLAttributes(&obtained);
   1.397 +	printOpenGLAttributes(&obtained);	
   1.398 +	
   1.399 +	initializeTexture();
   1.400 +
   1.401 +	done = 0;
   1.402 +	/* enter main loop */
   1.403 +	while(!done) {
   1.404 +		startFrame = SDL_GetTicks();
   1.405 +		SDL_Event event;
   1.406 +        while (SDL_PollEvent(&event)) {
   1.407 +            if (event.type == SDL_QUIT) {
   1.408 +				done = 1;
   1.409 +            }
   1.410 +			if (event.type == SDL_MOUSEBUTTONDOWN) {
   1.411 +				printf("mouse down\n");
   1.412 +				int which = event.button.which;
   1.413 +				int x, y;
   1.414 +				SDL_SelectMouse(which);
   1.415 +				SDL_GetMouseState(&x, &y);
   1.416 +				spawnEmitterParticle(x, y);
   1.417 +			}
   1.418 +        }
   1.419 +		render();
   1.420 +		endFrame = SDL_GetTicks();
   1.421 +		
   1.422 +		/* figure out how much time we have left, and then sleep */
   1.423 +		delay = MILLESECONDS_PER_FRAME - (endFrame - startFrame);
   1.424 +		if (delay > MILLESECONDS_PER_FRAME) {
   1.425 +			delay = MILLESECONDS_PER_FRAME;
   1.426 +		}
   1.427 +		if (delay > 0) {
   1.428 +			SDL_Delay(delay);
   1.429 +		}
   1.430 +			
   1.431 +		//SDL_Delay(delay);
   1.432 +	}
   1.433 +	
   1.434 +	/* delete textures */
   1.435 +	
   1.436 +	/* shutdown SDL */
   1.437 +	SDL_Quit();
   1.438 +	
   1.439 +	return 0;
   1.440 +	
   1.441 +}
   1.442 \ No newline at end of file