mbrot-mt
changeset 0:e9ae6289e14f
initial commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Fri, 07 Mar 2014 07:42:48 +0200 |
parents | |
children | 3a893f9831ac |
files | Makefile src/mbrot-mt.c |
diffstat | 2 files changed, 172 insertions(+), 0 deletions(-) [+] |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/Makefile Fri Mar 07 07:42:48 2014 +0200 1.3 @@ -0,0 +1,13 @@ 1.4 +src = $(wildcard src/*.c) 1.5 +obj = $(src:.c=.o) 1.6 +bin = mbrot 1.7 + 1.8 +CFLAGS = -pedantic -Wall -g `pkg-config --cflags sdl` 1.9 +LDFLAGS = `pkg-config --libs sdl` 1.10 + 1.11 +$(bin): $(obj) 1.12 + $(CC) -o $@ $(obj) $(LDFLAGS) 1.13 + 1.14 +.PHONY: clean 1.15 +clean: 1.16 + rm -f $(obj) $(bin)
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/src/mbrot-mt.c Fri Mar 07 07:42:48 2014 +0200 2.3 @@ -0,0 +1,159 @@ 2.4 +#include <stdio.h> 2.5 +#include <complex.h> 2.6 +#include <SDL/SDL.h> 2.7 + 2.8 +void display(void); 2.9 +int mandelbrot(float x, float y, int max_iter, int *iter); 2.10 +int handle_event(SDL_Event *ev); 2.11 + 2.12 +static SDL_Surface *fbsurf; 2.13 +static int win_width, win_height; 2.14 +static float win_aspect; 2.15 +static float xoffs, yoffs, zoom = 1.0; 2.16 +static int max_iter = 64; 2.17 + 2.18 +int main(void) 2.19 +{ 2.20 + win_width = 800; 2.21 + win_height = 600; 2.22 + win_aspect = (float)win_width / (float)win_height; 2.23 + 2.24 + SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER); 2.25 + if(!(fbsurf = SDL_SetVideoMode(win_width, win_height, 32, SDL_SWSURFACE | SDL_RESIZABLE))) { 2.26 + fprintf(stderr, "failed to create framebuffer\n"); 2.27 + return 1; 2.28 + } 2.29 + 2.30 + SDL_WM_SetCaption("Mandelbrot", 0); 2.31 + 2.32 + for(;;) { 2.33 + SDL_Event ev; 2.34 + 2.35 + while(SDL_PollEvent(&ev)) { 2.36 + if(handle_event(&ev) == -1) { 2.37 + goto done; 2.38 + } 2.39 + } 2.40 + 2.41 + display(); 2.42 + } 2.43 + 2.44 +done: 2.45 + SDL_Quit(); 2.46 + return 0; 2.47 +} 2.48 + 2.49 +void display(void) 2.50 +{ 2.51 + unsigned char *fbuf, *pixptr; 2.52 + int i, j, xsz, ysz; 2.53 + 2.54 + if(SDL_MUSTLOCK(fbsurf)) { 2.55 + SDL_LockSurface(fbsurf); 2.56 + } 2.57 + fbuf = fbsurf->pixels; 2.58 + xsz = fbsurf->w; 2.59 + ysz = fbsurf->h; 2.60 + 2.61 + pixptr = fbuf; 2.62 + for(i=0; i<ysz; i++) { 2.63 + float y = 2.0 * (float)i / (float)ysz - 1.0; 2.64 + for(j=0; j<xsz; j++) { 2.65 + float x = (2.0 * (float)j / (float)xsz - 1.0) * win_aspect; 2.66 + 2.67 + int iter, r, g, b; 2.68 + int inset = mandelbrot((x - xoffs) * zoom, (y - yoffs) * zoom, max_iter, &iter); 2.69 + if(!inset) { 2.70 + r = iter * 256 / max_iter; 2.71 + g = 0; 2.72 + b = 0; 2.73 + } else { 2.74 + r = g = b = 0; 2.75 + } 2.76 + 2.77 + pixptr[0] = b; 2.78 + pixptr[1] = g; 2.79 + pixptr[2] = r; 2.80 + pixptr[3] = 255; 2.81 + pixptr += 4; 2.82 + } 2.83 + } 2.84 + 2.85 + if(SDL_MUSTLOCK(fbsurf)) { 2.86 + SDL_UnlockSurface(fbsurf); 2.87 + } 2.88 + SDL_Flip(fbsurf); 2.89 +} 2.90 + 2.91 +int mandelbrot(float x, float y, int max_iter, int *iter) 2.92 +{ 2.93 + int i; 2.94 + complex float c = x + y * I; 2.95 + complex float z = c; 2.96 + 2.97 + for(i=0; i<max_iter; i++) { 2.98 + float re = creal(z); 2.99 + float im = cimag(z); 2.100 + if(re * re + im * im > 4) { 2.101 + if(iter) *iter = i; 2.102 + return 0; 2.103 + } 2.104 + 2.105 + z = z * z + c; 2.106 + } 2.107 + 2.108 + return 1; 2.109 +} 2.110 + 2.111 +int handle_event(SDL_Event *ev) 2.112 +{ 2.113 + static int prev_x, prev_y; 2.114 + static int bnstate[32]; 2.115 + 2.116 + switch(ev->type) { 2.117 + case SDL_KEYDOWN: 2.118 + if(ev->key.keysym.sym == SDLK_ESCAPE) { 2.119 + return -1; 2.120 + } 2.121 + 2.122 + case SDL_MOUSEBUTTONDOWN: 2.123 + prev_x = ev->button.x; 2.124 + prev_y = ev->button.y; 2.125 + bnstate[ev->button.button - SDL_BUTTON_LEFT] = 1; 2.126 + break; 2.127 + 2.128 + case SDL_MOUSEBUTTONUP: 2.129 + bnstate[ev->button.button - SDL_BUTTON_LEFT] = 0; 2.130 + break; 2.131 + 2.132 + case SDL_MOUSEMOTION: 2.133 + { 2.134 + int dx = ev->button.x - prev_x; 2.135 + int dy = ev->button.y - prev_y; 2.136 + prev_x = ev->button.x; 2.137 + prev_y = ev->button.y; 2.138 + 2.139 + if(!dx && !dy) break; 2.140 + 2.141 + if(bnstate[0]) { 2.142 + xoffs += win_aspect * 2.0 * (float)dx / (float)win_width; 2.143 + yoffs += 2.0 * (float)dy / (float)win_height; 2.144 + } 2.145 + if(bnstate[2]) { 2.146 + zoom += (float)dy / (float)win_height; 2.147 + if(zoom < 1e-6) zoom = 1e-6; 2.148 + } 2.149 + } 2.150 + break; 2.151 + 2.152 + case SDL_VIDEORESIZE: 2.153 + win_width = ev->resize.w; 2.154 + win_height = ev->resize.h; 2.155 + win_aspect = (float)win_width / (float)win_height; 2.156 + break; 2.157 + 2.158 + default: 2.159 + break; 2.160 + } 2.161 + return 0; 2.162 +}