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 +}