mbrot-mt

view src/mbrot-mt.c @ 1:3a893f9831ac

ported to SDL2
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 14 Mar 2014 03:39:37 +0200
parents e9ae6289e14f
children
line source
1 #include <stdio.h>
2 #include <complex.h>
3 #include <SDL2/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_Window *win;
10 static SDL_Surface *winsurf;
11 static int win_width, win_height;
12 static float win_aspect;
13 static float xoffs, yoffs, zoom = 1.0;
14 static int max_iter = 64;
16 static void trysdl2stuff(void)
17 {
18 int i, j, num_modes, num_scr;
20 num_scr = SDL_GetNumVideoDisplays();
22 for(i=0; i<num_scr; i++) {
23 printf("Screen %d: %s\n", i, SDL_GetDisplayName(i));
25 num_modes = SDL_GetNumDisplayModes(i);
26 for(j=0; j<num_modes; j++) {
27 SDL_DisplayMode mode;
28 int bpp;
29 unsigned int rmask, gmask, bmask, amask;
31 SDL_GetDisplayMode(i, j, &mode);
32 SDL_PixelFormatEnumToMasks(mode.format, &bpp, &rmask, &gmask, &bmask, &amask);
34 printf(" %dx%d %dbpp %dhz\n", mode.w, mode.h, bpp, mode.refresh_rate);
35 }
36 }
38 SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Information", "Mandelbrot rules!", 0);
39 }
41 int main(void)
42 {
43 win_width = 800;
44 win_height = 600;
45 win_aspect = (float)win_width / (float)win_height;
47 SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);
48 trysdl2stuff();
50 if(!(win = SDL_CreateWindow("Mandelbrot", 0, 0, win_width, win_height, SDL_WINDOW_RESIZABLE))) {
51 fprintf(stderr, "failed to create framebuffer\n");
52 return 1;
53 }
54 winsurf = SDL_GetWindowSurface(win);
56 for(;;) {
57 SDL_Event ev;
59 while(SDL_PollEvent(&ev)) {
60 if(handle_event(&ev) == -1) {
61 goto done;
62 }
63 }
65 display();
66 }
68 done:
69 SDL_Quit();
70 return 0;
71 }
73 void display(void)
74 {
75 unsigned char *fbuf, *pixptr;
76 int i, j, xsz, ysz;
78 if(SDL_MUSTLOCK(winsurf)) {
79 SDL_LockSurface(winsurf);
80 }
81 fbuf = winsurf->pixels;
82 xsz = winsurf->w;
83 ysz = winsurf->h;
85 pixptr = fbuf;
86 for(i=0; i<ysz; i++) {
87 float y = 2.0 * (float)i / (float)ysz - 1.0;
88 for(j=0; j<xsz; j++) {
89 float x = (2.0 * (float)j / (float)xsz - 1.0) * win_aspect;
91 int iter, r, g, b;
92 int inset = mandelbrot((x - xoffs) * zoom, (y - yoffs) * zoom, max_iter, &iter);
93 if(!inset) {
94 r = iter * 256 / max_iter;
95 g = 0;
96 b = 0;
97 } else {
98 r = g = b = 0;
99 }
101 pixptr[0] = b;
102 pixptr[1] = g;
103 pixptr[2] = r;
104 pixptr[3] = 255;
105 pixptr += 4;
106 }
107 }
109 if(SDL_MUSTLOCK(winsurf)) {
110 SDL_UnlockSurface(winsurf);
111 }
112 SDL_UpdateWindowSurface(win);
113 }
115 int mandelbrot(float x, float y, int max_iter, int *iter)
116 {
117 int i;
118 complex float c = x + y * I;
119 complex float z = c;
121 for(i=0; i<max_iter; i++) {
122 float re = creal(z);
123 float im = cimag(z);
124 if(re * re + im * im > 4) {
125 if(iter) *iter = i;
126 return 0;
127 }
129 z = z * z + c;
130 }
132 return 1;
133 }
135 int handle_event(SDL_Event *ev)
136 {
137 static int prev_x, prev_y;
138 static int bnstate[32];
140 switch(ev->type) {
141 case SDL_KEYDOWN:
142 if(ev->key.keysym.sym == SDLK_ESCAPE) {
143 return -1;
144 }
146 case SDL_MOUSEBUTTONDOWN:
147 prev_x = ev->button.x;
148 prev_y = ev->button.y;
149 bnstate[ev->button.button - SDL_BUTTON_LEFT] = 1;
150 break;
152 case SDL_MOUSEBUTTONUP:
153 bnstate[ev->button.button - SDL_BUTTON_LEFT] = 0;
154 break;
156 case SDL_MOUSEMOTION:
157 {
158 int dx = ev->button.x - prev_x;
159 int dy = ev->button.y - prev_y;
160 prev_x = ev->button.x;
161 prev_y = ev->button.y;
163 if(!dx && !dy) break;
165 if(bnstate[0]) {
166 xoffs += win_aspect * 2.0 * (float)dx / (float)win_width;
167 yoffs += 2.0 * (float)dy / (float)win_height;
168 }
169 if(bnstate[2]) {
170 zoom += (float)dy / (float)win_height;
171 if(zoom < 1e-6) zoom = 1e-6;
172 }
173 }
174 break;
176 case SDL_WINDOWEVENT:
177 if(ev->window.event == SDL_WINDOWEVENT_RESIZED) {
178 win_width = ev->window.data1;
179 win_height = ev->window.data2;
180 win_aspect = (float)win_width / (float)win_height;
181 }
182 break;
184 default:
185 break;
186 }
187 return 0;
188 }