changeset 2:0684158d38a8

Before cleanup. Still has experimental code in it.
author Eris Caffee <discordia@eldalin.com>
date Fri, 22 Oct 2010 02:21:52 -0500
parents 455406f5f021
children 0f4ad525f49a
files TODO include/App.h include/EventHandler.h include/Fractal.h include/Julia.h src/App.cpp src/EventHandler.cpp src/Fractal.cpp src/Julia.cpp src/Mandelbrot.cpp
diffstat 10 files changed, 481 insertions(+), 230 deletions(-) [+]
line diff
     1.1 --- a/TODO	Tue Oct 19 03:37:31 2010 -0500
     1.2 +++ b/TODO	Fri Oct 22 02:21:52 2010 -0500
     1.3 @@ -6,6 +6,27 @@
     1.4  
     1.5  - Read saved image and continue calculation.
     1.6  
     1.7 +- Zoom feature that zooms in while staying centered on the same spot.
     1.8  - Unzoom feature that enlarges the area while keeping the image cenetered on the same spot.
     1.9 +- Pan feature to let you move side to side while staying at the same zoom level.
    1.10 +
    1.11 +- Windows file handling
    1.12 +- Better file handling in general
    1.13 +
    1.14 +- real GUI interface
    1.15 +	- gtk?
    1.16 +
    1.17 +- More color options
    1.18 +
    1.19 +- More factal types
    1.20 +
    1.21 +- Fix the lag of the selection box.  It needs to appear instantly and in the exact place the mouse is clicked.
    1.22 +	Using a timer callback function and SDL_WaitEvent is noticably better
    1.23 +	than my wait_event_timeout() function
    1.24 +
    1.25 +- Clean up the fractal class.  No more direct access to fractal settings.
    1.26  
    1.27  - Performance improvment ideas:
    1.28 +	- Create a partial rendering mechanism.
    1.29 +	OK - Use window events correctly to determine when a redraw is needed!  
    1.30 +	OK - Use a better way of handling events.  A timer callback and an SDL_WaitEvent/ SDL_PollEvent combo.  See here http://people.freedesktop.org/~idr/OpenGL_tutorials/01-SDL-intro.html
    1.31 \ No newline at end of file
     2.1 --- a/include/App.h	Tue Oct 19 03:37:31 2010 -0500
     2.2 +++ b/include/App.h	Fri Oct 22 02:21:52 2010 -0500
     2.3 @@ -40,24 +40,28 @@
     2.4     // Overrides of EventHandler:
     2.5     void on_event(SDL_Event * event);
     2.6     void on_KeyDown(SDLKey sym, SDLMod mod, Uint16 unicode);
     2.7 +   void on_KeyUp(SDLKey sym, SDLMod mod, Uint16 unicode);
     2.8     void on_Exit();
     2.9     void on_LButtonDown(int mx, int my);
    2.10     void on_LButtonUp(int mx, int my);
    2.11     void on_MouseMove(int mx, int my, 
    2.12  		     int relx, int rely, 
    2.13  		     bool left, bool right, bool middle);
    2.14 +   void on_Resize(int w, int h);
    2.15 +   void on_Expose();
    2.16 +
    2.17  
    2.18     int mouse_move_width(int mx, int my);
    2.19     bool create_new_surface(SDL_Surface * &surface);
    2.20     void restore_view();
    2.21     void set_caption();
    2.22 -   // void png_user_warning(png_structp png, png_const_charp s);
    2.23 -   // void png_user_error(png_structp png, png_const_charp s);
    2.24     bool save_image();
    2.25  
    2.26 +   static Uint32 timer_callback(Uint32 interval, void *param);
    2.27  
    2.28  
    2.29     bool running;
    2.30 +   bool redraw;
    2.31  
    2.32     SDL_Surface * surf_display;
    2.33     SDL_Surface * surf_selection;
    2.34 @@ -65,16 +69,15 @@
    2.35  
    2.36     int selection_x, selection_y, selection_width;
    2.37     bool setting_zoom;
    2.38 -   bool can_set_julia_K;
    2.39 -   bool setting_julia_K;
    2.40 +   bool can_set_julia_k;
    2.41 +   bool setting_julia_k;
    2.42  
    2.43     struct view
    2.44        {
    2.45 -      double Re_min, Im_max, size;
    2.46 +      double re_min, im_max, size;
    2.47        };
    2.48     static std::vector<view *> old_views;
    2.49  
    2.50 -
    2.51     Fractal * fractal;
    2.52     };
    2.53  
     3.1 --- a/include/EventHandler.h	Tue Oct 19 03:37:31 2010 -0500
     3.2 +++ b/include/EventHandler.h	Fri Oct 22 02:21:52 2010 -0500
     3.3 @@ -24,6 +24,10 @@
     3.4     EventHandler();
     3.5     virtual ~EventHandler();
     3.6  
     3.7 +#ifndef USE_SDL_WAITEVENT
     3.8 +   virtual int wait_event_timeout(SDL_Event * event, Uint32 timeout);
     3.9 +#endif
    3.10 +
    3.11     virtual void on_event(SDL_Event * event);
    3.12  
    3.13     virtual void on_InputFocus();
     4.1 --- a/include/Fractal.h	Tue Oct 19 03:37:31 2010 -0500
     4.2 +++ b/include/Fractal.h	Fri Oct 22 02:21:52 2010 -0500
     4.3 @@ -22,20 +22,35 @@
     4.4  
     4.5     virtual bool calc_set() = 0;
     4.6     virtual bool init(SDL_Surface * surf) = 0;
     4.7 -   const char * name();
     4.8 +   void set_re_min(const double r_min);
     4.9 +   void set_im_max(const double i_max);
    4.10 +   void set_size(const double s);
    4.11 +   void set_max_iter(const unsigned int iter);
    4.12 +   void inc_max_iter();
    4.13 +   void dec_max_iter();
    4.14 +   void set_calc_needed();
    4.15  
    4.16 -   double Re_min;
    4.17 -   double Im_max;
    4.18 -   double size;
    4.19 -   unsigned int max_iter;
    4.20 +   double get_re_min();
    4.21 +   double get_im_max();
    4.22 +   double get_size();
    4.23 +   unsigned int get_max_iter();
    4.24 +   const char * get_name();
    4.25 +
    4.26  
    4.27     protected:
    4.28  
    4.29     virtual void draw_pixel(int x, int y, Uint32 * color);
    4.30  
    4.31 -   std::string the_name;
    4.32 +   std::string name;
    4.33 +   double re_min;
    4.34 +   double im_max;
    4.35 +   double size;
    4.36 +   unsigned int max_iter;
    4.37 +   bool calc_needed;
    4.38 +
    4.39     SDL_Surface * surface;
    4.40  
    4.41 +
    4.42     };
    4.43  
    4.44  #endif
     5.1 --- a/include/Julia.h	Tue Oct 19 03:37:31 2010 -0500
     5.2 +++ b/include/Julia.h	Fri Oct 22 02:21:52 2010 -0500
     5.3 @@ -26,16 +26,16 @@
     5.4     bool calc_set();
     5.5     bool init(SDL_Surface * surf);
     5.6  
     5.7 -   void get_K(double & Re, double & Im);
     5.8 -   void set_K(double Re, double Im);
     5.9 +   void get_k(double & re, double & im);
    5.10 +   void set_k(double re, double im);
    5.11  
    5.12     private:
    5.13  
    5.14     void draw_pixel(int x, int y, Uint32 * color);
    5.15     void set_name();
    5.16  
    5.17 -   double K_Re;
    5.18 -   double K_Im;
    5.19 +   double k_re;
    5.20 +   double k_im;
    5.21     };
    5.22  
    5.23  #endif
     6.1 --- a/src/App.cpp	Tue Oct 19 03:37:31 2010 -0500
     6.2 +++ b/src/App.cpp	Fri Oct 22 02:21:52 2010 -0500
     6.3 @@ -9,10 +9,10 @@
     6.4  //
     6.5  ////////////////////////////////////////////////////////////////////////////////
     6.6  
     6.7 -#include <iostream>
     6.8 -#include <cstdio>
     6.9  #include <cstdlib>
    6.10  #include <cstring>
    6.11 +#include <iostream>
    6.12 +#include <sstream>
    6.13  #include <vector>
    6.14  
    6.15  #include <dirent.h>
    6.16 @@ -27,7 +27,7 @@
    6.17  #include "Julia.h"
    6.18  
    6.19  
    6.20 -#define SAVE_AS_BMP
    6.21 +#define USE_SDL_WAITEVENT
    6.22  
    6.23  std::vector<App::view *> App::old_views;
    6.24  
    6.25 @@ -35,6 +35,7 @@
    6.26  
    6.27  App::App() :
    6.28     running (true),
    6.29 +   redraw (false),
    6.30     surf_display (NULL),
    6.31     surf_selection (NULL),
    6.32     surf_fractal (NULL),
    6.33 @@ -42,8 +43,8 @@
    6.34     selection_y (-1),
    6.35     selection_width (-1),
    6.36     setting_zoom (false),
    6.37 -   can_set_julia_K (false),
    6.38 -   setting_julia_K (false)
    6.39 +   can_set_julia_k (false),
    6.40 +   setting_julia_k (false)
    6.41     {
    6.42     }
    6.43  
    6.44 @@ -69,12 +70,24 @@
    6.45  
    6.46     while (running)
    6.47        {
    6.48 -      while (SDL_PollEvent(&event))
    6.49 +#ifdef USE_SDL_WAITEVENT
    6.50 +      SDL_WaitEvent(&event);
    6.51 +      do
    6.52  	 {
    6.53  	 on_event(&event);
    6.54  	 }
    6.55 +      while (SDL_PollEvent(&event));
    6.56 +#else
    6.57 +      while (wait_event_timeout(&event, 30) == 1)
    6.58 +	 {
    6.59 +	 on_event(&event);
    6.60 +	 }
    6.61 +#endif
    6.62 +
    6.63        update();
    6.64 -      render();
    6.65 +
    6.66 +      if (redraw)
    6.67 +	 render();
    6.68        }
    6.69  
    6.70     cleanup();
    6.71 @@ -83,10 +96,28 @@
    6.72     }
    6.73  
    6.74  ////////////////////////////////////////////////////////////////////////////////
    6.75 +// Sample callback from
    6.76 +// http://people.freedesktop.org/~idr/OpenGL_tutorials/01-SDL-intro.html
    6.77  
    6.78 +#ifdef USE_SDL_WAITEVENT
    6.79 +Uint32 App::timer_callback(Uint32 interval, void *param)
    6.80 +   {
    6.81 +   SDL_Event e;
    6.82 + 
    6.83 +   e.type = SDL_USEREVENT;
    6.84 +   e.user.code = 0;
    6.85 +   e.user.data1 = NULL;
    6.86 +   e.user.data2 = NULL;
    6.87 +   SDL_PushEvent(& e);
    6.88 + 
    6.89 +   return interval;
    6.90 +   }
    6.91 +#endif
    6.92 +
    6.93 +////////////////////////////////////////////////////////////////////////////////
    6.94  bool App::init()
    6.95     {
    6.96 -   if ((SDL_Init(SDL_INIT_VIDEO)) == -1)
    6.97 +   if ((SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER)) == -1)
    6.98        {
    6.99        std::cerr << "SDL_Init() failed: " << SDL_GetError() << std::endl;
   6.100        return false;
   6.101 @@ -110,10 +141,15 @@
   6.102  
   6.103     fractal = new Mandelbrot();
   6.104     fractal->init(surf_fractal);
   6.105 -   can_set_julia_K = true;
   6.106 +   can_set_julia_k = true;
   6.107 +   redraw = true;
   6.108  
   6.109     set_caption();
   6.110  
   6.111 +#ifdef USE_SDL_WAITEVENT
   6.112 +   SDL_TimerID timer_id = SDL_AddTimer(10, App::timer_callback, NULL);
   6.113 +#endif
   6.114 +
   6.115     return true;
   6.116     }
   6.117  
   6.118 @@ -127,22 +163,26 @@
   6.119  
   6.120  void App::render()
   6.121     {
   6.122 -   // Start with a clean slate.
   6.123 -   SDL_FillRect(surf_display, &surf_display->clip_rect, 
   6.124 -		SDL_MapRGB(surf_display->format, 0, 0, 255));
   6.125 +   if (redraw)
   6.126 +      {
   6.127 +      // Start with a clean slate.
   6.128 +      SDL_FillRect(surf_display, &surf_display->clip_rect, 
   6.129 +		   SDL_MapRGB(surf_display->format, 0, 0, 255));
   6.130  
   6.131 -   fractal->calc_set();
   6.132 -   SDL_BlitSurface(surf_fractal, NULL, surf_display, NULL);
   6.133 +      fractal->calc_set();
   6.134 +      SDL_BlitSurface(surf_fractal, NULL, surf_display, NULL);
   6.135  
   6.136 -   // draw a selection box
   6.137 -   if (setting_zoom)
   6.138 -      {
   6.139 -      SDL_BlitSurface(surf_selection, NULL, surf_display, NULL);
   6.140 +      // draw a selection box
   6.141 +      if (setting_zoom)
   6.142 +	 {
   6.143 +	 SDL_BlitSurface(surf_selection, NULL, surf_display, NULL);
   6.144 +	 }
   6.145 +
   6.146 +      // Show it to the user.
   6.147 +      SDL_Flip(surf_display);
   6.148 +
   6.149 +      redraw = false;
   6.150        }
   6.151 -
   6.152 -   // Show it to the user.
   6.153 -   SDL_Flip(surf_display);
   6.154 -
   6.155     }
   6.156  
   6.157  ////////////////////////////////////////////////////////////////////////////////
   6.158 @@ -186,6 +226,8 @@
   6.159  
   6.160        case SDLK_b:
   6.161        	 restore_view();
   6.162 +	 fractal->set_calc_needed();
   6.163 +	 redraw = true;
   6.164  	 set_caption();
   6.165        	 break;
   6.166  
   6.167 @@ -194,11 +236,11 @@
   6.168        	 break;
   6.169  
   6.170        case SDLK_UP:
   6.171 -	 fractal->max_iter++;
   6.172 +	 fractal->inc_max_iter();
   6.173  	 set_caption();
   6.174  	 break;
   6.175        case SDLK_DOWN:
   6.176 -	 fractal->max_iter--;
   6.177 +	 fractal->dec_max_iter();
   6.178  	 set_caption();
   6.179  	 break;
   6.180  
   6.181 @@ -209,8 +251,10 @@
   6.182  	    delete fractal;
   6.183  	    fractal = new Mandelbrot();
   6.184  	    fractal->init(surf_fractal);
   6.185 +	    fractal->set_calc_needed();
   6.186 +	    redraw = true;
   6.187  	    set_caption();
   6.188 -	    can_set_julia_K = true;
   6.189 +	    can_set_julia_k = true;
   6.190  	    }
   6.191  	 break;
   6.192        case SDLK_j:
   6.193 @@ -219,17 +263,18 @@
   6.194  	    delete fractal;
   6.195  	    fractal = new Julia();
   6.196  	    fractal->init(surf_fractal);
   6.197 +	    fractal->set_calc_needed();
   6.198 +	    redraw = true;
   6.199  	    set_caption();
   6.200 -	    can_set_julia_K = false;
   6.201 +	    can_set_julia_k = false;
   6.202  	    }
   6.203  	 break;
   6.204  
   6.205        case SDLK_k:
   6.206 -	 std::cerr << "can_set_julia_K " << can_set_julia_K << std::endl;
   6.207 -	 if (can_set_julia_K)
   6.208 +	 if (can_set_julia_k)
   6.209  	    {
   6.210 -	    if (setting_julia_K)setting_julia_K = false;
   6.211 -	    else setting_julia_K = true;
   6.212 +	    if (setting_julia_k) setting_julia_k = false;
   6.213 +	    else setting_julia_k = true;
   6.214  	    }
   6.215  	 break;
   6.216  
   6.217 @@ -240,6 +285,23 @@
   6.218  
   6.219  
   6.220  ////////////////////////////////////////////////////////////////////////////////
   6.221 +void App::on_KeyUp(SDLKey sym, SDLMod mod, Uint16 unicode)
   6.222 +   {
   6.223 +   switch (sym)
   6.224 +      {
   6.225 +      case SDLK_UP:
   6.226 +	 fractal->set_calc_needed();
   6.227 +	 redraw = true;
   6.228 +	 break;
   6.229 +      case SDLK_DOWN:
   6.230 +	 fractal->set_calc_needed();
   6.231 +	 redraw = true;
   6.232 +	 break;
   6.233 +      }   
   6.234 +   }
   6.235 +
   6.236 +
   6.237 +////////////////////////////////////////////////////////////////////////////////
   6.238  
   6.239  void App::on_Exit()
   6.240     {
   6.241 @@ -251,18 +313,22 @@
   6.242  
   6.243  void App::on_LButtonDown(int mx, int my)
   6.244     {
   6.245 -   if (setting_julia_K)
   6.246 +   if (setting_julia_k)
   6.247        {
   6.248 -      double K_Re = fractal->Re_min + mx * (fractal->size)/(Options::width-1);
   6.249 -      double K_Im = fractal->Im_max - my * (fractal->size)/(Options::height-1);
   6.250 +      double K_Re = fractal->get_re_min() + mx * 
   6.251 +	    (fractal->get_size())/(Options::width-1);
   6.252 +      double K_Im = fractal->get_im_max() - my * 
   6.253 +	    (fractal->get_size())/(Options::height-1);
   6.254  
   6.255        delete fractal;
   6.256        fractal = new Julia();
   6.257        fractal->init(surf_fractal);
   6.258 -      ((Julia *)fractal)->set_K(K_Re, K_Im);
   6.259 +      ((Julia *)fractal)->set_k(K_Re, K_Im);
   6.260 +      fractal->set_calc_needed();
   6.261 +      redraw = true;
   6.262  
   6.263        set_caption();
   6.264 -      setting_julia_K = false;
   6.265 +      setting_julia_k = false;
   6.266        }
   6.267     else
   6.268        {
   6.269 @@ -292,24 +358,25 @@
   6.270        selection_width = mouse_move_width(mx, my);
   6.271  
   6.272        // calculate new min/max re/im
   6.273 -      double Re_scale = (fractal->size)/(Options::width-1);
   6.274 -      double Im_scale = (fractal->size)/(Options::height-1);
   6.275 +      double Re_scale = (fractal->get_size())/(Options::width-1);
   6.276 +      double Im_scale = (fractal->get_size())/(Options::height-1);
   6.277  
   6.278 -      double new_Re_min = fractal->Re_min + (selection_x) * Re_scale;
   6.279 -      double new_Im_max = fractal->Im_max - (selection_y) * Im_scale;
   6.280 +      double new_re_min = fractal->get_re_min() + (selection_x) * Re_scale;
   6.281 +      double new_im_max = fractal->get_im_max() - (selection_y) * Im_scale;
   6.282        double new_size = selection_width * Re_scale;
   6.283  
   6.284        
   6.285        view * v = new view;
   6.286 -      v->Re_min = fractal->Re_min;
   6.287 -      v->Im_max = fractal->Im_max;
   6.288 -      v->size = fractal->size;
   6.289 +      v->re_min = fractal->get_re_min();
   6.290 +      v->im_max = fractal->get_im_max();
   6.291 +      v->size = fractal->get_size();
   6.292        old_views.push_back(v);
   6.293  
   6.294 -      fractal->Re_min = new_Re_min;
   6.295 -      fractal->Im_max = new_Im_max;
   6.296 -      fractal->size = new_size;
   6.297 -      //      std::cerr << "Set new bounds at (" << fractal->Re_min << "," << fractal->Im_max << ")  size " << fractal->size << std::endl;
   6.298 +      fractal->set_re_min(new_re_min);
   6.299 +      fractal->set_im_max(new_im_max);
   6.300 +      fractal->set_size(new_size);
   6.301 +      fractal->set_calc_needed();
   6.302 +      redraw = true;
   6.303  
   6.304        set_caption();
   6.305  
   6.306 @@ -345,11 +412,27 @@
   6.307        rect.w = rect.h = w - 2;
   6.308  
   6.309        SDL_FillRect(surf_selection, &rect, clear);
   6.310 +
   6.311 +      redraw = true;
   6.312        }
   6.313     }
   6.314  
   6.315  
   6.316  ////////////////////////////////////////////////////////////////////////////////
   6.317 +void App::on_Resize(int w, int h)
   6.318 +   {
   6.319 +   redraw = true;
   6.320 +   }
   6.321 +
   6.322 +
   6.323 +////////////////////////////////////////////////////////////////////////////////
   6.324 +void App::on_Expose()
   6.325 +   {
   6.326 +   redraw = true;
   6.327 +   }
   6.328 +
   6.329 +
   6.330 +////////////////////////////////////////////////////////////////////////////////
   6.331  int App::mouse_move_width(int mx, int my)
   6.332     {
   6.333     int move_width = (mx - selection_x);
   6.334 @@ -407,9 +490,9 @@
   6.335        {
   6.336        view * v = old_views.back();
   6.337        old_views.pop_back();
   6.338 -      fractal->Re_min = v->Re_min;
   6.339 -      fractal->Im_max = v->Im_max;
   6.340 -      fractal->size = v->size;
   6.341 +      fractal->set_re_min(v->re_min);
   6.342 +      fractal->set_im_max(v->im_max);
   6.343 +      fractal->set_size(v->size);
   6.344        delete v;
   6.345        }
   6.346     }
   6.347 @@ -418,16 +501,63 @@
   6.348  ////////////////////////////////////////////////////////////////////////////////
   6.349  void App::set_caption()
   6.350     {
   6.351 -   char title[100];
   6.352 -   sprintf(title, "%s - "
   6.353 -	   "Real: %f to %f - "
   6.354 -	   "Imaginary %f to %f - "
   6.355 -	   "Max iterations: %d", 
   6.356 -	   fractal->name(),
   6.357 -	   fractal->Re_min, fractal->Re_min + fractal->size, 
   6.358 -	   fractal->Im_max, fractal->Im_max + fractal->size, 
   6.359 -	   fractal->max_iter);
   6.360 -   SDL_WM_SetCaption(title, NULL);
   6.361 +   std::stringstream ss;
   6.362 +   ss << fractal->get_name() << " / "
   6.363 +      << "Real: " << fractal->get_re_min()
   6.364 +       << " to "<< fractal->get_re_min() + fractal->get_size()
   6.365 +      << " / Imaginary: " << fractal->get_im_max() - fractal->get_size()
   6.366 +      << " to " << fractal->get_im_max()
   6.367 +      << " / Max iterations: " << fractal->get_max_iter();
   6.368 +   SDL_WM_SetCaption(ss.str().c_str(), NULL);
   6.369 +   }
   6.370 +
   6.371 +
   6.372 +////////////////////////////////////////////////////////////////////////////////
   6.373 +// This file name generation is kuldgy.  Need to learn how to do file i/o for 
   6.374 +// real!
   6.375 +
   6.376 +int scandir_filter(const struct dirent * d)
   6.377 +   {
   6.378 +   if (memcmp(d->d_name, "mandelbrot-", 11) != 0) return 0;
   6.379 +   if (memcmp(d->d_name+14, ".bmp", 4) != 0) return 0;
   6.380 +   if (isdigit(d->d_name[11]) 
   6.381 +       && isdigit(d->d_name[12]) 
   6.382 +       && isdigit(d->d_name[13])) 
   6.383 +      return 1;
   6.384 +   return 0;
   6.385 +   }
   6.386 +
   6.387 +
   6.388 +bool App::save_image()
   6.389 +   {
   6.390 +   static int i = 0;
   6.391 +   char name[20];
   6.392 +
   6.393 +   if (i == 0)
   6.394 +      {
   6.395 +      struct dirent ** file_list;
   6.396 +      int num_files = scandir(".", &file_list, scandir_filter, alphasort);
   6.397 +      if (num_files != 0)
   6.398 +	 sscanf(file_list[num_files-1]->d_name, "mandelbrot-%03d.bmp", &i);
   6.399 +      }
   6.400 +   i++;
   6.401 +   sprintf(name, "mandelbrot-%03d.bmp", i);
   6.402 +
   6.403 +   FILE * file;
   6.404 +   if ((file = fopen(name, "wb")) == NULL)
   6.405 +      {
   6.406 +      std::cerr << "fopen() failed in save_image() on file " 
   6.407 +		<< name << " for saving." << std::endl;
   6.408 +      return false;
   6.409 +      }
   6.410 +
   6.411 +   if (SDL_SaveBMP(surf_display, name) != 0)
   6.412 +      {
   6.413 +      std::cerr << "Unable to save image file " << name << "" << std::endl;
   6.414 +      return false;
   6.415 +      }
   6.416 +
   6.417 +   return true;
   6.418     }
   6.419  
   6.420  
   6.421 @@ -528,56 +658,3 @@
   6.422     return true;
   6.423     }
   6.424  #endif
   6.425 -
   6.426 -////////////////////////////////////////////////////////////////////////////////
   6.427 -#ifdef SAVE_AS_BMP
   6.428 -
   6.429 -// This file name generation is kuldgy.  Need to learn how to do file i/o for 
   6.430 -// real!
   6.431 -
   6.432 -int scandir_filter(const struct dirent * d)
   6.433 -   {
   6.434 -   if (memcmp(d->d_name, "mandelbrot-", 11) != 0) return 0;
   6.435 -   if (memcmp(d->d_name+14, ".bmp", 4) != 0) return 0;
   6.436 -   if (isdigit(d->d_name[11]) 
   6.437 -       && isdigit(d->d_name[12]) 
   6.438 -       && isdigit(d->d_name[13])) 
   6.439 -      return 1;
   6.440 -   return 0;
   6.441 -   }
   6.442 -
   6.443 -
   6.444 -bool App::save_image()
   6.445 -   {
   6.446 -   static int i = 0;
   6.447 -   char name[20];
   6.448 -
   6.449 -   if (i == 0)
   6.450 -      {
   6.451 -      struct dirent ** file_list;
   6.452 -      int num_files = scandir(".", &file_list, scandir_filter, alphasort);
   6.453 -      if (num_files != 0)
   6.454 -	 sscanf(file_list[num_files-1]->d_name, "mandelbrot-%03d.bmp", &i);
   6.455 -      }
   6.456 -   i++;
   6.457 -   sprintf(name, "mandelbrot-%03d.bmp", i);
   6.458 -
   6.459 -   FILE * file;
   6.460 -   if ((file = fopen(name, "wb")) == NULL)
   6.461 -      {
   6.462 -      std::cerr << "fopen() failed in save_image() on file " 
   6.463 -		<< name << " for saving." << std::endl;
   6.464 -      return false;
   6.465 -      }
   6.466 -
   6.467 -   if (SDL_SaveBMP(surf_display, name) != 0)
   6.468 -      {
   6.469 -      std::cerr << "Unable to save image file " << name << "" << std::endl;
   6.470 -      return false;
   6.471 -      }
   6.472 -
   6.473 -   return true;
   6.474 -   }
   6.475 -#endif
   6.476 -
   6.477 -
     7.1 --- a/src/EventHandler.cpp	Tue Oct 19 03:37:31 2010 -0500
     7.2 +++ b/src/EventHandler.cpp	Fri Oct 22 02:21:52 2010 -0500
     7.3 @@ -8,6 +8,7 @@
     7.4  // EventHandler class implementation.
     7.5  //
     7.6  ////////////////////////////////////////////////////////////////////////////////
     7.7 +#include <iostream>
     7.8  
     7.9  #include "EventHandler.h"
    7.10  
    7.11 @@ -27,6 +28,37 @@
    7.12  
    7.13  
    7.14  ////////////////////////////////////////////////////////////////////////////////
    7.15 +// Note: SDL 1.3 adds an official SDL_WaitEventTimeout function.
    7.16 +#ifndef USE_SDL_WAIEVENT
    7.17 +int EventHandler::wait_event_timeout(SDL_Event * event, Uint32 timeout)
    7.18 +   {
    7.19 +   Uint32 end = SDL_GetTicks() + timeout;
    7.20 +   int i;
    7.21 +
    7.22 +   for (;;) 
    7.23 +      {
    7.24 +      SDL_PumpEvents();
    7.25 +      i = SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS);
    7.26 +      switch (i) 
    7.27 +	 {
    7.28 +	 case -1:
    7.29 +	    return 0;
    7.30 +	 case 1:
    7.31 +	    return 1;
    7.32 +	 case 0:
    7.33 +	    if (SDL_GetTicks() >= end)
    7.34 +	       {
    7.35 +	       return 0;
    7.36 +	       }
    7.37 +	    SDL_Delay(10);
    7.38 +	    break;
    7.39 +	 }
    7.40 +      }
    7.41 +   }
    7.42 +#endif
    7.43 +
    7.44 +
    7.45 +////////////////////////////////////////////////////////////////////////////////
    7.46  void EventHandler::on_event(SDL_Event * event)
    7.47     {
    7.48     switch(event->type)
     8.1 --- a/src/Fractal.cpp	Tue Oct 19 03:37:31 2010 -0500
     8.2 +++ b/src/Fractal.cpp	Fri Oct 22 02:21:52 2010 -0500
     8.3 @@ -20,19 +20,104 @@
     8.4  ////////////////////////////////////////////////////////////////////////////////
     8.5  
     8.6  Fractal::Fractal() :
     8.7 -   the_name ("No fractal selected"),
     8.8 -   Re_min (0),
     8.9 -   Im_max (0),
    8.10 +   name ("No fractal selected"),
    8.11 +   re_min (0),
    8.12 +   im_max (0),
    8.13     size (0),
    8.14     max_iter (0),
    8.15 -   surface (NULL)
    8.16 +   surface (NULL),
    8.17 +   calc_needed (false)
    8.18     {
    8.19     }
    8.20  
    8.21  ////////////////////////////////////////////////////////////////////////////////
    8.22 -const char * Fractal::name()
    8.23 +void Fractal::set_re_min(const double r_min)
    8.24     {
    8.25 -   return the_name.c_str();
    8.26 +   re_min = r_min;
    8.27 +   }
    8.28 +
    8.29 +
    8.30 +////////////////////////////////////////////////////////////////////////////////
    8.31 +void Fractal::set_im_max(const double i_max)
    8.32 +   {
    8.33 +   im_max = i_max;
    8.34 +   }
    8.35 +
    8.36 +
    8.37 +////////////////////////////////////////////////////////////////////////////////
    8.38 +void Fractal::set_size(const double s)
    8.39 +   {
    8.40 +   if (s > 0.0)
    8.41 +      size = s;
    8.42 +   else
    8.43 +      size = 1.0;
    8.44 +   }
    8.45 +
    8.46 +
    8.47 +////////////////////////////////////////////////////////////////////////////////
    8.48 +void Fractal::set_max_iter(const unsigned int iter)
    8.49 +   {
    8.50 +   if (iter > 0)
    8.51 +      max_iter = iter;
    8.52 +   else
    8.53 +      max_iter = 1;
    8.54 +   }
    8.55 +
    8.56 +
    8.57 +////////////////////////////////////////////////////////////////////////////////
    8.58 +void Fractal::inc_max_iter()
    8.59 +   {
    8.60 +   max_iter++;
    8.61 +   }
    8.62 +
    8.63 +
    8.64 +////////////////////////////////////////////////////////////////////////////////
    8.65 +void Fractal::dec_max_iter()
    8.66 +   {
    8.67 +   if (max_iter > 0)
    8.68 +      max_iter--;
    8.69 +   }
    8.70 +
    8.71 +
    8.72 +////////////////////////////////////////////////////////////////////////////////
    8.73 +void Fractal::set_calc_needed()
    8.74 +   {
    8.75 +   calc_needed = true;
    8.76 +   }
    8.77 +
    8.78 +
    8.79 +////////////////////////////////////////////////////////////////////////////////
    8.80 +double Fractal::get_re_min()
    8.81 +   {
    8.82 +   return re_min;
    8.83 +   }
    8.84 +
    8.85 +
    8.86 +////////////////////////////////////////////////////////////////////////////////
    8.87 +double Fractal::get_im_max()
    8.88 +   {
    8.89 +   return im_max;
    8.90 +   }
    8.91 +
    8.92 +
    8.93 +////////////////////////////////////////////////////////////////////////////////
    8.94 +double Fractal::get_size()
    8.95 +   {
    8.96 +   return size;
    8.97 +   }
    8.98 +
    8.99 +
   8.100 +////////////////////////////////////////////////////////////////////////////////
   8.101 +unsigned int Fractal::get_max_iter()
   8.102 +   {
   8.103 +   return max_iter;
   8.104 +   }
   8.105 +
   8.106 +
   8.107 +////////////////////////////////////////////////////////////////////////////////
   8.108 +const char * Fractal::get_name()
   8.109 +   {
   8.110 +   return name.c_str();
   8.111     }
   8.112  
   8.113  ////////////////////////////////////////////////////////////////////////////////
     9.1 --- a/src/Julia.cpp	Tue Oct 19 03:37:31 2010 -0500
     9.2 +++ b/src/Julia.cpp	Fri Oct 22 02:21:52 2010 -0500
     9.3 @@ -12,6 +12,7 @@
     9.4  #include <cstdlib>
     9.5  #include <iostream>
     9.6  #include <string>
     9.7 +#include <sstream>
     9.8  
     9.9  #include "Julia.h"
    9.10  #include "Options.h"
    9.11 @@ -19,14 +20,15 @@
    9.12  ////////////////////////////////////////////////////////////////////////////////
    9.13  
    9.14  Julia::Julia() :
    9.15 -   K_Re (-0.565072),
    9.16 -   K_Im ( 0.491657)
    9.17 +   k_re (-0.565072),
    9.18 +   k_im ( 0.491657)
    9.19     {
    9.20 -   Re_min = -2.0;
    9.21 -   Im_max = 2.0;
    9.22 +   re_min = -2.0;
    9.23 +   im_max = 2.0;
    9.24     size = 4.0;
    9.25     max_iter = 50;
    9.26     set_name();
    9.27 +   calc_needed = true;
    9.28     }
    9.29  
    9.30  
    9.31 @@ -38,59 +40,64 @@
    9.32  
    9.33     // Code from http://warp.povusers.org/Julia/
    9.34  
    9.35 -   double Re_scale = (size)/(Options::width-1);
    9.36 -   double Im_scale = (size)/(Options::height-1);
    9.37 +   if (calc_needed)
    9.38 +      {
    9.39 +      double re_scale = (size)/(Options::width-1);
    9.40 +      double im_scale = (size)/(Options::height-1);
    9.41  
    9.42 -   int r, g, b;
    9.43 +      int r, g, b;
    9.44  
    9.45 -   Uint32 black = SDL_MapRGB(surface->format, 0, 0, 0);
    9.46 -   Uint32 color;
    9.47 -   int halfway = max_iter/2 - 1;
    9.48 -   float step = (float) 255 / halfway;
    9.49 +      Uint32 black = SDL_MapRGB(surface->format, 0, 0, 0);
    9.50 +      Uint32 color;
    9.51 +      int halfway = max_iter/2 - 1;
    9.52 +      float step = (float) 255 / halfway;
    9.53  
    9.54 -   unsigned x, y, n;
    9.55 +      unsigned x, y, n;
    9.56  
    9.57 -   for(y = 0; y < Options::height; ++y)
    9.58 -      {
    9.59 -      double c_im = Im_max - y * Im_scale;
    9.60 -      for(x = 0; x < Options::width; ++x)
    9.61 +      for(y = 0; y < Options::height; ++y)
    9.62  	 {
    9.63 -	 double c_re = Re_min + x * Re_scale;
    9.64 +	 double c_im = im_max - y * im_scale;
    9.65 +	 for(x = 0; x < Options::width; ++x)
    9.66 +	    {
    9.67 +	    double c_re = re_min + x * re_scale;
    9.68  
    9.69 -	 double Z_re = c_re, Z_im = c_im;
    9.70 -	 bool in_set = true;
    9.71 -	 for(n = 0; n < max_iter; ++n)
    9.72 -	    {
    9.73 -            double Z_re2 = Z_re * Z_re, Z_im2 = Z_im * Z_im;
    9.74 -            if(Z_re2 + Z_im2 > 4)
    9.75 +	    double z_re = c_re, z_im = c_im;
    9.76 +	    bool in_set = true;
    9.77 +	    for(n = 0; n < max_iter; ++n)
    9.78  	       {
    9.79 -	       in_set = false;
    9.80 -	       break;
    9.81 +	       double z_re2 = z_re * z_re, z_im2 = z_im * z_im;
    9.82 +	       if(z_re2 + z_im2 > 4)
    9.83 +		  {
    9.84 +		  in_set = false;
    9.85 +		  break;
    9.86 +		  }
    9.87 +	       z_im = 2*z_re * z_im + k_im;
    9.88 +	       z_re = z_re2 - z_im2 + k_re;
    9.89  	       }
    9.90 -            Z_im = 2*Z_re * Z_im + K_Im;
    9.91 -            Z_re = Z_re2 - Z_im2 + K_Re;
    9.92 -	    }
    9.93 -	 if(in_set) 
    9.94 -	    { 
    9.95 -	    draw_pixel(x, y, &black); 
    9.96 -	    }
    9.97 -	 else
    9.98 -	    {
    9.99 -	    if (n <= halfway)
   9.100 +	    if(in_set) 
   9.101 +	       { 
   9.102 +	       draw_pixel(x, y, &black); 
   9.103 +	       }
   9.104 +	    else
   9.105  	       {
   9.106 -	       r = n * step;
   9.107 -	       b = g = 0;
   9.108 +	       if (n <= halfway)
   9.109 +		  {
   9.110 +		  r = n * step;
   9.111 +		  b = g = 0;
   9.112 +		  }
   9.113 +	       else 
   9.114 +		  {
   9.115 +		  r = 255;
   9.116 +		  b = g = (n - halfway) * step;
   9.117 +		  }
   9.118 +	       color = SDL_MapRGB(surface->format, r, g, b);
   9.119 +	       draw_pixel(x, y, &color); 
   9.120  	       }
   9.121 -	    else 
   9.122 -	       {
   9.123 -	       r = 255;
   9.124 -	       b = g = (n - halfway) * step;
   9.125 -	       }
   9.126 -	    color = SDL_MapRGB(surface->format, r, g, b);
   9.127 -	    draw_pixel(x, y, &color); 
   9.128  	    }
   9.129  	 }
   9.130        }
   9.131 +
   9.132 +   calc_needed = false;
   9.133     return true;
   9.134     }
   9.135  
   9.136 @@ -106,23 +113,24 @@
   9.137        {
   9.138        surface = surf;
   9.139        }
   9.140 +   calc_needed = true;
   9.141     return true;
   9.142     }
   9.143  
   9.144  
   9.145  ////////////////////////////////////////////////////////////////////////////////
   9.146 -void Julia::get_K(double & Re, double & Im)
   9.147 +void Julia::get_k(double & re, double & im)
   9.148     {
   9.149 -   Re = K_Re;
   9.150 -   Im = K_Im;
   9.151 +   re = k_re;
   9.152 +   im = k_im;
   9.153     }
   9.154  
   9.155  
   9.156  ////////////////////////////////////////////////////////////////////////////////
   9.157 -void Julia::set_K(double Re, double Im)
   9.158 +void Julia::set_k(double re, double im)
   9.159     {
   9.160 -   K_Re = Re;
   9.161 -   K_Im = Im;
   9.162 +   k_re = re;
   9.163 +   k_im = im;
   9.164     set_name();
   9.165     }
   9.166  
   9.167 @@ -138,7 +146,7 @@
   9.168  ////////////////////////////////////////////////////////////////////////////////
   9.169  void Julia::set_name()
   9.170     {
   9.171 -   char tmp[100];
   9.172 -   sprintf(tmp, "Julia set K = (%f,%f)", K_Re, K_Im);
   9.173 -   the_name.assign(tmp);
   9.174 +   std::stringstream ss;
   9.175 +   ss <<"Julia set K = (" << k_re << "," << k_im << ")";
   9.176 +   name = ss.str();
   9.177     }
    10.1 --- a/src/Mandelbrot.cpp	Tue Oct 19 03:37:31 2010 -0500
    10.2 +++ b/src/Mandelbrot.cpp	Fri Oct 22 02:21:52 2010 -0500
    10.3 @@ -19,9 +19,9 @@
    10.4  
    10.5  Mandelbrot::Mandelbrot()
    10.6     {
    10.7 -   the_name.assign("Mandelbrot set");
    10.8 -   Re_min = -2.5;
    10.9 -   Im_max = 2.5;
   10.10 +   name.assign("Mandelbrot set");
   10.11 +   re_min = -2.5;
   10.12 +   im_max = 2.5;
   10.13     size = 5.0;
   10.14     max_iter = 50;
   10.15     }
   10.16 @@ -38,6 +38,7 @@
   10.17        {
   10.18        surface = surf;
   10.19        }
   10.20 +   calc_needed = true;
   10.21     return true;
   10.22     }
   10.23  
   10.24 @@ -50,59 +51,64 @@
   10.25  
   10.26     // Code from http://warp.povusers.org/Mandelbrot/
   10.27  
   10.28 -   double Re_scale = (size)/(Options::width-1);
   10.29 -   double Im_scale = (size)/(Options::height-1);
   10.30 +   if (calc_needed)
   10.31 +      {
   10.32 +      double re_scale = (size)/(Options::width-1);
   10.33 +      double im_scale = (size)/(Options::height-1);
   10.34  
   10.35 -   int r, g, b;
   10.36 +      int r, g, b;
   10.37  
   10.38 -   Uint32 black = SDL_MapRGB(surface->format, 0, 0, 0);
   10.39 -   Uint32 color;
   10.40 -   int halfway = max_iter/2 - 1;
   10.41 -   float step = (float) 255 / halfway;
   10.42 +      Uint32 black = SDL_MapRGB(surface->format, 0, 0, 0);
   10.43 +      Uint32 color;
   10.44 +      int halfway = max_iter/2 - 1;
   10.45 +      float step = (float) 255 / halfway;
   10.46  
   10.47 -   unsigned x, y, n;
   10.48 +      unsigned x, y, n;
   10.49  
   10.50 -   for(y = 0; y < Options::height; ++y)
   10.51 -      {
   10.52 -      double c_im = Im_max - y * Im_scale;
   10.53 -      for(x = 0; x < Options::width; ++x)
   10.54 +      for(y = 0; y < Options::height; ++y)
   10.55  	 {
   10.56 -	 double c_re = Re_min + x * Re_scale;
   10.57 +	 double c_im = im_max - y * im_scale;
   10.58 +	 for(x = 0; x < Options::width; ++x)
   10.59 +	    {
   10.60 +	    double c_re = re_min + x * re_scale;
   10.61  
   10.62 -	 double Z_re = c_re, Z_im = c_im;
   10.63 -	 bool in_set = true;
   10.64 -	 for(n=0; n < max_iter; ++n)
   10.65 -	    {
   10.66 -            double Z_re2 = Z_re * Z_re, Z_im2 = Z_im * Z_im;
   10.67 -            if(Z_re2 + Z_im2 > 4)
   10.68 +	    double z_re = c_re, z_im = c_im;
   10.69 +	    bool in_set = true;
   10.70 +	    for(n=0; n < max_iter; ++n)
   10.71  	       {
   10.72 -	       in_set = false;
   10.73 -	       break;
   10.74 +	       double z_re2 = z_re * z_re, z_im2 = z_im * z_im;
   10.75 +	       if(z_re2 + z_im2 > 4)
   10.76 +		  {
   10.77 +		  in_set = false;
   10.78 +		  break;
   10.79 +		  }
   10.80 +	       z_im = 2 * z_re * z_im + c_im;
   10.81 +	       z_re = z_re2 - z_im2 + c_re;
   10.82  	       }
   10.83 -            Z_im = 2 * Z_re * Z_im + c_im;
   10.84 -            Z_re = Z_re2 - Z_im2 + c_re;
   10.85 -	    }
   10.86 -	 if(in_set) 
   10.87 -	    { 
   10.88 -	    draw_pixel(x, y, &black); 
   10.89 -	    }
   10.90 -	 else
   10.91 -	    {
   10.92 -	    if (n <= halfway)
   10.93 +	    if(in_set) 
   10.94 +	       { 
   10.95 +	       draw_pixel(x, y, &black); 
   10.96 +	       }
   10.97 +	    else
   10.98  	       {
   10.99 -	       b = n * step;
  10.100 -	       r = g = 0;
  10.101 +	       if (n <= halfway)
  10.102 +		  {
  10.103 +		  b = n * step;
  10.104 +		  r = g = 0;
  10.105 +		  }
  10.106 +	       else 
  10.107 +		  {
  10.108 +		  b = 255;
  10.109 +		  r = g = (n - halfway) * step;
  10.110 +		  }
  10.111 +	       color = SDL_MapRGB(surface->format, r, g, b);
  10.112 +	       draw_pixel(x, y, &color); 
  10.113  	       }
  10.114 -	    else 
  10.115 -	       {
  10.116 -	       b = 255;
  10.117 -	       r = g = (n - halfway) * step;
  10.118 -	       }
  10.119 -	    color = SDL_MapRGB(surface->format, r, g, b);
  10.120 -	    draw_pixel(x, y, &color); 
  10.121  	    }
  10.122  	 }
  10.123        }
  10.124 +
  10.125 +   calc_needed = false;
  10.126     return true;
  10.127     }
  10.128