8 struct SDL_Surface *screen;
9 long double origo_x, origo_y;
10 int motion_x, motion_y; /* mouse motion */
11 int mx, my; /* mouse position */
17 static void putpixel(struct SDL_Surface *screen, const int x, const int y,
18 const unsigned char r, const unsigned char g,
19 const unsigned char b)
21 int offset = y * screen->pitch + x * 4;
22 unsigned char *buf = screen->pixels;
29 #define MAX_ITERATION 1000
31 int get_mandelbrot_iterations(long double x0, long double y0)
33 long double x = 0, y = 0, xtemp;
36 while ((x * x + y * y < 2 * 2) && iteration < MAX_ITERATION) {
38 xtemp = x * x - y * y + x0;
48 int draw_mandelbrot(struct SDL_Surface *screen, long double x1, long double x2,
49 long double y1, long double y2)
51 long double x0, y0, xlen, ylen, xstep, ystep;
52 int iteration, xs, ys;
56 xstep = xlen / (long double)screen->w;
57 ystep = ylen / (long double)screen->h;
60 #pragma omp parallel for private(xs, ys, x0, y0)
61 for (ys = 0; ys < screen->h; ys++) {
64 for (xs = 0; xs < screen->w; xs++) {
65 iteration = get_mandelbrot_iterations(x0, y0);
67 if (iteration == MAX_ITERATION)
68 putpixel(screen, xs, ys, 255, 255, 255);
70 putpixel(screen, xs, ys,
71 iteration * 8, iteration,
81 #define ZOOM_FACTOR 1.5
83 static int read_events(struct context *ctx)
86 int wait = 1, ret, exit = 0, delayed_exit = 0;
90 SDL_WaitEvent(&event);
93 ret = SDL_PollEvent(&event);
100 switch (event.type) {
102 switch (event.key.keysym.sym) {
110 switch (event.key.keysym.sym) {
115 case SDL_MOUSEBUTTONDOWN:
116 if (event.button.button == 4) {
119 } else if (event.button.button == 5) {
123 ctx->scroll_enabled = 1;
126 case SDL_MOUSEBUTTONUP:
127 ctx->scroll_enabled = 0;
130 case SDL_MOUSEMOTION:
131 ctx->mx = event.motion.x;
132 ctx->my = event.motion.y;
133 if (!ctx->scroll_enabled)
136 ctx->motion_x -= event.motion.xrel;
137 ctx->motion_y -= event.motion.yrel;
140 case SDL_VIDEORESIZE:
142 SDL_SetVideoMode(event.resize.w,
155 printf("\nExiting. Good bye!\n");
159 static void loop(struct context *ctx)
161 long double aspect_ratio;
162 long double x1, x2, y1, y2;
166 aspect_ratio = ctx->screen->w / (long double)ctx->screen->h;
167 ctx->origo_x += ctx->motion_x / ctx->zoom / ctx->screen->w;
168 ctx->origo_y += ctx->motion_y / ctx->zoom / ctx->screen->h;
169 ctx->motion_x = ctx->motion_y = 0;
171 if (ctx->zooms != last_zoom) {
174 dx = ctx->mx - ctx->screen->w / 2;
175 dy = ctx->my - ctx->screen->h / 2;
177 if (ctx->zooms > last_zoom) {
178 ctx->zoom *= ZOOM_FACTOR;
179 ctx->origo_x += dx / ctx->zoom /
180 (long double) ctx->screen->w;
181 ctx->origo_y += dy / ctx->zoom /
182 (long double) ctx->screen->h;
184 ctx->origo_x -= dx / ctx->zoom /
185 (long double) ctx->screen->w;
186 ctx->origo_y -= dy / ctx->zoom /
187 (long double) ctx->screen->h;
188 ctx->zoom /= ZOOM_FACTOR;
191 last_zoom = ctx->zooms;
194 x1 = ctx->origo_x - aspect_ratio / ctx->zoom;
195 x2 = ctx->origo_x + aspect_ratio / ctx->zoom;
196 y1 = ctx->origo_y - 1 / ctx->zoom;
197 y2 = ctx->origo_y + 1 / ctx->zoom;
199 printf("Drawing area (%LF, %LF)(%LF, %LF), zoom %d\n",
200 x1, y1, x2, y2, ctx->zooms);
202 draw_mandelbrot(ctx->screen, x1, x2, y1, y2);
203 } while (!read_events(ctx));
206 int main(int argc, char *argv[])
209 int flags = SDL_DOUBLEBUF | SDL_HWSURFACE | SDL_RESIZABLE;
210 int xres = 800, yres = 600;
212 memset(&ctx, 0, sizeof(ctx));
215 if (SDL_Init(SDL_INIT_VIDEO) != 0) {
216 fprintf(stderr, "Unable to initialize SDL: %s\n",
223 ctx.screen = SDL_SetVideoMode(xres, yres, 32, flags);
224 if (ctx.screen == NULL) {
225 fprintf(stderr, "Unable to set video mode: %s\n",
230 SDL_WM_SetCaption(argv[0], NULL);