mbrot-mt

diff src/mbrot-mt.c @ 0:e9ae6289e14f

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 07 Mar 2014 07:42:48 +0200
parents
children 3a893f9831ac
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/mbrot-mt.c	Fri Mar 07 07:42:48 2014 +0200
     1.3 @@ -0,0 +1,159 @@
     1.4 +#include <stdio.h>
     1.5 +#include <complex.h>
     1.6 +#include <SDL/SDL.h>
     1.7 +
     1.8 +void display(void);
     1.9 +int mandelbrot(float x, float y, int max_iter, int *iter);
    1.10 +int handle_event(SDL_Event *ev);
    1.11 +
    1.12 +static SDL_Surface *fbsurf;
    1.13 +static int win_width, win_height;
    1.14 +static float win_aspect;
    1.15 +static float xoffs, yoffs, zoom = 1.0;
    1.16 +static int max_iter = 64;
    1.17 +
    1.18 +int main(void)
    1.19 +{
    1.20 +	win_width = 800;
    1.21 +	win_height = 600;
    1.22 +	win_aspect = (float)win_width / (float)win_height;
    1.23 +
    1.24 +	SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);
    1.25 +	if(!(fbsurf = SDL_SetVideoMode(win_width, win_height, 32, SDL_SWSURFACE | SDL_RESIZABLE))) {
    1.26 +		fprintf(stderr, "failed to create framebuffer\n");
    1.27 +		return 1;
    1.28 +	}
    1.29 +
    1.30 +	SDL_WM_SetCaption("Mandelbrot", 0);
    1.31 +
    1.32 +	for(;;) {
    1.33 +		SDL_Event ev;
    1.34 +
    1.35 +		while(SDL_PollEvent(&ev)) {
    1.36 +			if(handle_event(&ev) == -1) {
    1.37 +				goto done;
    1.38 +			}
    1.39 +		}
    1.40 +
    1.41 +		display();
    1.42 +	}
    1.43 +
    1.44 +done:
    1.45 +	SDL_Quit();
    1.46 +	return 0;
    1.47 +}
    1.48 +
    1.49 +void display(void)
    1.50 +{
    1.51 +	unsigned char *fbuf, *pixptr;
    1.52 +	int i, j, xsz, ysz;
    1.53 +
    1.54 +	if(SDL_MUSTLOCK(fbsurf)) {
    1.55 +		SDL_LockSurface(fbsurf);
    1.56 +	}
    1.57 +	fbuf = fbsurf->pixels;
    1.58 +	xsz = fbsurf->w;
    1.59 +	ysz = fbsurf->h;
    1.60 +
    1.61 +	pixptr = fbuf;
    1.62 +	for(i=0; i<ysz; i++) {
    1.63 +		float y = 2.0 * (float)i / (float)ysz - 1.0;
    1.64 +		for(j=0; j<xsz; j++) {
    1.65 +			float x = (2.0 * (float)j / (float)xsz - 1.0) * win_aspect;
    1.66 +
    1.67 +			int iter, r, g, b;
    1.68 +			int inset = mandelbrot((x - xoffs) * zoom, (y - yoffs) * zoom, max_iter, &iter);
    1.69 +			if(!inset) {
    1.70 +				r = iter * 256 / max_iter;
    1.71 +				g = 0;
    1.72 +				b = 0;
    1.73 +			} else {
    1.74 +				r = g = b = 0;
    1.75 +			}
    1.76 +
    1.77 +			pixptr[0] = b;
    1.78 +			pixptr[1] = g;
    1.79 +			pixptr[2] = r;
    1.80 +			pixptr[3] = 255;
    1.81 +			pixptr += 4;
    1.82 +		}
    1.83 +	}
    1.84 +
    1.85 +	if(SDL_MUSTLOCK(fbsurf)) {
    1.86 +		SDL_UnlockSurface(fbsurf);
    1.87 +	}
    1.88 +	SDL_Flip(fbsurf);
    1.89 +}
    1.90 +
    1.91 +int mandelbrot(float x, float y, int max_iter, int *iter)
    1.92 +{
    1.93 +	int i;
    1.94 +	complex float c = x + y * I;
    1.95 +	complex float z = c;
    1.96 +
    1.97 +	for(i=0; i<max_iter; i++) {
    1.98 +		float re = creal(z);
    1.99 +		float im = cimag(z);
   1.100 +		if(re * re + im * im > 4) {
   1.101 +			if(iter) *iter = i;
   1.102 +			return 0;
   1.103 +		}
   1.104 +
   1.105 +		z = z * z + c;
   1.106 +	}
   1.107 +
   1.108 +	return 1;
   1.109 +}
   1.110 +
   1.111 +int handle_event(SDL_Event *ev)
   1.112 +{
   1.113 +	static int prev_x, prev_y;
   1.114 +	static int bnstate[32];
   1.115 +
   1.116 +	switch(ev->type) {
   1.117 +	case SDL_KEYDOWN:
   1.118 +		if(ev->key.keysym.sym == SDLK_ESCAPE) {
   1.119 +			return -1;
   1.120 +		}
   1.121 +
   1.122 +	case SDL_MOUSEBUTTONDOWN:
   1.123 +		prev_x = ev->button.x;
   1.124 +		prev_y = ev->button.y;
   1.125 +		bnstate[ev->button.button - SDL_BUTTON_LEFT] = 1;
   1.126 +		break;
   1.127 +
   1.128 +	case SDL_MOUSEBUTTONUP:
   1.129 +		bnstate[ev->button.button - SDL_BUTTON_LEFT] = 0;
   1.130 +		break;
   1.131 +
   1.132 +	case SDL_MOUSEMOTION:
   1.133 +		{
   1.134 +			int dx = ev->button.x - prev_x;
   1.135 +			int dy = ev->button.y - prev_y;
   1.136 +			prev_x = ev->button.x;
   1.137 +			prev_y = ev->button.y;
   1.138 +
   1.139 +			if(!dx && !dy) break;
   1.140 +
   1.141 +			if(bnstate[0]) {
   1.142 +				xoffs += win_aspect * 2.0 * (float)dx / (float)win_width;
   1.143 +				yoffs += 2.0 * (float)dy / (float)win_height;
   1.144 +			}
   1.145 +			if(bnstate[2]) {
   1.146 +				zoom += (float)dy / (float)win_height;
   1.147 +				if(zoom < 1e-6) zoom = 1e-6;
   1.148 +			}
   1.149 +		}
   1.150 +		break;
   1.151 +
   1.152 +	case SDL_VIDEORESIZE:
   1.153 +		win_width = ev->resize.w;
   1.154 +		win_height = ev->resize.h;
   1.155 +		win_aspect = (float)win_width / (float)win_height;
   1.156 +		break;
   1.157 +
   1.158 +	default:
   1.159 +		break;
   1.160 +	}
   1.161 +	return 0;
   1.162 +}