X-Git-Url: http://git.itanic.dy.fi/?p=mandelbrot;a=blobdiff_plain;f=mandelbrot.c;fp=mandelbrot.c;h=926b6af0a827be7f7b3ed99db094c35bf2d0a27f;hp=624fcf2ebda615e2275021d1d50aa59b91624a30;hb=de02d2ee032bad5bdfb8d5aa05f13784ae6afe06;hpb=ba47e789a437c348b1d0a1a3cfa2c91e517762c7 diff --git a/mandelbrot.c b/mandelbrot.c index 624fcf2..926b6af 100644 --- a/mandelbrot.c +++ b/mandelbrot.c @@ -2,6 +2,15 @@ #include #include #include +#include + +struct context { + struct SDL_Surface *screen; + double origo_x, origo_y; + int motion_x, motion_y; + double zoom; + int scroll_enabled; +}; static void putpixel(struct SDL_Surface *screen, const int x, const int y, const unsigned char r, const unsigned char g, @@ -40,6 +49,8 @@ int draw_mandelbrot(struct SDL_Surface *screen, double x1, double x2, double x0, y0, xlen, ylen, xstep, ystep; int iteration, xs, ys; + printf("Drawing area (%f, %f)(%f, %f)\n", x1, y1, x2, y2); + xlen = x2 - x1; ylen = y2 - y1; xstep = xlen / (double)screen->w; @@ -67,12 +78,107 @@ int draw_mandelbrot(struct SDL_Surface *screen, double x1, double x2, return 0; } +static int read_events(struct context *ctx) +{ + SDL_Event event; + int wait = 1, ret, exit = 0, delayed_exit = 0; + + while (!exit) { + if (wait) { + SDL_WaitEvent(&event); + wait = 0; + } else { + ret = SDL_PollEvent(&event); + if (!ret) { + wait = 1; + exit = delayed_exit; + } + } + + switch (event.type) { + case SDL_KEYDOWN: + switch (event.key.keysym.sym) { + case SDLK_ESCAPE: + goto quit; + default: + break; + } + break; + case SDL_KEYUP: + switch (event.key.keysym.sym) { + default: + break; + } + break; + case SDL_MOUSEBUTTONDOWN: + if (event.button.button == 4) { + ctx->zoom *= 1.5; + exit++; + } else if (event.button.button == 5) { + ctx->zoom /= 1.5; + delayed_exit++; + } else { + ctx->scroll_enabled = 1; + } + break; + case SDL_MOUSEBUTTONUP: + ctx->scroll_enabled = 0; + exit++; + break; + case SDL_MOUSEMOTION: + if (!ctx->scroll_enabled) + break; + + ctx->motion_x -= event.motion.xrel; + ctx->motion_y -= event.motion.yrel; + delayed_exit++; + break; + case SDL_VIDEORESIZE: + ctx->screen = + SDL_SetVideoMode(event.resize.w, + event.resize.h, + 32, + ctx->screen->flags); + exit++; + break; + case SDL_QUIT: + goto quit; + } + } + + return 0; +quit: + printf("\nExiting. Good bye!\n"); + return 1; +} + +static void loop(struct context *ctx) +{ + double aspect_ratio; + + do { + aspect_ratio = ctx->screen->w / ctx->screen->h; + ctx->origo_x += ctx->motion_x / ctx->zoom / ctx->screen->w; + ctx->origo_y += ctx->motion_y / ctx->zoom / ctx->screen->h; + ctx->motion_x = ctx->motion_y = 0; + + draw_mandelbrot(ctx->screen, + ctx->origo_x - aspect_ratio / ctx->zoom, + ctx->origo_x + aspect_ratio / ctx->zoom, + ctx->origo_y - 1 / ctx->zoom, + ctx->origo_y + 1 / ctx->zoom); + } while (!read_events(ctx)); +} + int main(int argc, char *argv[]) { - SDL_Surface *screen; + struct context ctx; int flags = SDL_DOUBLEBUF | SDL_HWSURFACE | SDL_RESIZABLE; int xres = 800, yres = 600; + memset(&ctx, 0, sizeof(ctx)); + ctx.zoom = 1; + if (SDL_Init(SDL_INIT_VIDEO) != 0) { fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError()); @@ -81,8 +187,8 @@ int main(int argc, char *argv[]) } atexit(SDL_Quit); - screen = SDL_SetVideoMode(xres, yres, 32, flags); - if (screen == NULL) { + ctx.screen = SDL_SetVideoMode(xres, yres, 32, flags); + if (ctx.screen == NULL) { fprintf(stderr, "Unable to set video mode: %s\n", SDL_GetError()); return 2; @@ -90,9 +196,7 @@ int main(int argc, char *argv[]) SDL_WM_SetCaption(argv[0], NULL); - draw_mandelbrot(screen, -2.5, 1, -1, 1); - - yres = read(0, &xres, 1); + loop(&ctx); return 0; }