mbrot-mt

view 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 source
1 #include <stdio.h>
2 #include <complex.h>
3 #include <SDL/SDL.h>
5 void display(void);
6 int mandelbrot(float x, float y, int max_iter, int *iter);
7 int handle_event(SDL_Event *ev);
9 static SDL_Surface *fbsurf;
10 static int win_width, win_height;
11 static float win_aspect;
12 static float xoffs, yoffs, zoom = 1.0;
13 static int max_iter = 64;
15 int main(void)
16 {
17 win_width = 800;
18 win_height = 600;
19 win_aspect = (float)win_width / (float)win_height;
21 SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);
22 if(!(fbsurf = SDL_SetVideoMode(win_width, win_height, 32, SDL_SWSURFACE | SDL_RESIZABLE))) {
23 fprintf(stderr, "failed to create framebuffer\n");
24 return 1;
25 }
27 SDL_WM_SetCaption("Mandelbrot", 0);
29 for(;;) {
30 SDL_Event ev;
32 while(SDL_PollEvent(&ev)) {
33 if(handle_event(&ev) == -1) {
34 goto done;
35 }
36 }
38 display();
39 }
41 done:
42 SDL_Quit();
43 return 0;
44 }
46 void display(void)
47 {
48 unsigned char *fbuf, *pixptr;
49 int i, j, xsz, ysz;
51 if(SDL_MUSTLOCK(fbsurf)) {
52 SDL_LockSurface(fbsurf);
53 }
54 fbuf = fbsurf->pixels;
55 xsz = fbsurf->w;
56 ysz = fbsurf->h;
58 pixptr = fbuf;
59 for(i=0; i<ysz; i++) {
60 float y = 2.0 * (float)i / (float)ysz - 1.0;
61 for(j=0; j<xsz; j++) {
62 float x = (2.0 * (float)j / (float)xsz - 1.0) * win_aspect;
64 int iter, r, g, b;
65 int inset = mandelbrot((x - xoffs) * zoom, (y - yoffs) * zoom, max_iter, &iter);
66 if(!inset) {
67 r = iter * 256 / max_iter;
68 g = 0;
69 b = 0;
70 } else {
71 r = g = b = 0;
72 }
74 pixptr[0] = b;
75 pixptr[1] = g;
76 pixptr[2] = r;
77 pixptr[3] = 255;
78 pixptr += 4;
79 }
80 }
82 if(SDL_MUSTLOCK(fbsurf)) {
83 SDL_UnlockSurface(fbsurf);
84 }
85 SDL_Flip(fbsurf);
86 }
88 int mandelbrot(float x, float y, int max_iter, int *iter)
89 {
90 int i;
91 complex float c = x + y * I;
92 complex float z = c;
94 for(i=0; i<max_iter; i++) {
95 float re = creal(z);
96 float im = cimag(z);
97 if(re * re + im * im > 4) {
98 if(iter) *iter = i;
99 return 0;
100 }
102 z = z * z + c;
103 }
105 return 1;
106 }
108 int handle_event(SDL_Event *ev)
109 {
110 static int prev_x, prev_y;
111 static int bnstate[32];
113 switch(ev->type) {
114 case SDL_KEYDOWN:
115 if(ev->key.keysym.sym == SDLK_ESCAPE) {
116 return -1;
117 }
119 case SDL_MOUSEBUTTONDOWN:
120 prev_x = ev->button.x;
121 prev_y = ev->button.y;
122 bnstate[ev->button.button - SDL_BUTTON_LEFT] = 1;
123 break;
125 case SDL_MOUSEBUTTONUP:
126 bnstate[ev->button.button - SDL_BUTTON_LEFT] = 0;
127 break;
129 case SDL_MOUSEMOTION:
130 {
131 int dx = ev->button.x - prev_x;
132 int dy = ev->button.y - prev_y;
133 prev_x = ev->button.x;
134 prev_y = ev->button.y;
136 if(!dx && !dy) break;
138 if(bnstate[0]) {
139 xoffs += win_aspect * 2.0 * (float)dx / (float)win_width;
140 yoffs += 2.0 * (float)dy / (float)win_height;
141 }
142 if(bnstate[2]) {
143 zoom += (float)dy / (float)win_height;
144 if(zoom < 1e-6) zoom = 1e-6;
145 }
146 }
147 break;
149 case SDL_VIDEORESIZE:
150 win_width = ev->resize.w;
151 win_height = ev->resize.h;
152 win_aspect = (float)win_width / (float)win_height;
153 break;
155 default:
156 break;
157 }
158 return 0;
159 }