Rube Goldberg Machine 1.0
This is the base code for Rube Goldberg designed for the CS296 Software Systems Lab
src/callbacks.cpp
Go to the documentation of this file.
00001 /* 
00002  * Base code for CS 296 Software Systems Lab 
00003  * Department of Computer Science and Engineering, IIT Bombay
00004  * Instructor: Parag Chaudhuri
00005  */
00006 
00009 #include "callbacks.hpp"
00010 
00011 #ifndef __APPLE__
00012 #include "GL/glui.h"
00013 #else
00014 #include "GL/glui.h"
00015 #endif
00016 
00021 namespace cs296
00022 {
00023   int32 test_index = 0;
00024   int32 test_selection = 0;
00025   int32 test_count = 0;
00026   cs296::sim_t* entry;
00027   cs296::base_sim_t* test;
00028   cs296::settings_t settings;
00029   int32 width = 640;
00030   int32 height = 480;
00031   int32 frame_period = 16;
00032   int32 main_window;
00033   float settings_hz = 60.0;
00034   float32 view_zoom = 1.0f;
00035   int tx, ty, tw, th;
00036   bool r_mouse_down;
00037   b2Vec2 lastp;
00038 
00039   b2Vec2 callbacks_t::convert_screen_to_world(int32 x, int32 y)
00040   {
00041     float32 u = x / static_cast<float32>(tw);
00042     float32 v = (th - y) / float32(th);
00043     
00044     float32 ratio = static_cast<float32>(tw) / static_cast<float32>(th);
00045     b2Vec2 extents(ratio * 25.0f, 25.0f);
00046     extents *= view_zoom;
00047     
00048     b2Vec2 lower = settings.view_center - extents;
00049     b2Vec2 upper = settings.view_center + extents;
00050   
00051     b2Vec2 p;
00052     p.x = (1.0f - u) * lower.x + u * upper.x;
00053     p.y = (1.0f - v) * lower.y + v * upper.y;
00054     return p;
00055   }
00056   
00057   
00058   void callbacks_t::resize_cb(int32 w, int32 h)
00059   {
00060     width = w;
00061     height = h;
00062     
00063     GLUI_Master.get_viewport_area(&tx, &ty, &tw, &th);
00064     glViewport(tx, ty, tw, th);
00065     
00066     glMatrixMode(GL_PROJECTION);
00067     glLoadIdentity();
00068     
00071     float32 ratio = static_cast<float32>(tw) / static_cast<float32>(th);
00072     
00073     b2Vec2 extents(ratio * 25.0f, 25.0f);
00074     extents *= view_zoom;
00075     
00076     b2Vec2 lower = settings.view_center - extents;
00077     b2Vec2 upper = settings.view_center + extents;
00078   
00081     gluOrtho2D(lower.x, upper.x, lower.y, upper.y);
00082   }
00083   
00084   
00085   void callbacks_t::keyboard_cb(unsigned char key, int x, int y)
00086   {
00088     B2_NOT_USED(x);
00089     B2_NOT_USED(y);
00090     
00091     switch (key)
00092     {
00093     case 27:
00094       exit(0);
00095       break;
00096       
00098     case 'z':
00099       view_zoom = b2Min(1.1f * view_zoom, 20.0f);
00100       resize_cb(width, height);
00101       break;
00102       
00104     case 'x':
00105       view_zoom = b2Max(0.9f * view_zoom, 0.02f);
00106       resize_cb(width, height);
00107       break;
00108       
00110     case 'r':
00111       delete test;
00112       test = entry->create_fcn();
00113       break;
00114       
00116     case 'p':
00117       settings.pause = !settings.pause;
00118       break;
00119       
00121     default:
00122       if (test)
00123     {
00124       test->keyboard(key);
00125     }
00126     }
00127   }
00128   
00129   
00130   void callbacks_t::keyboard_special_cb(int key, int x, int y)
00131   {
00132     B2_NOT_USED(x);
00133     B2_NOT_USED(y);
00134     
00135     switch (key)
00136     {
00137     case GLUT_ACTIVE_SHIFT:
00138       
00140     case GLUT_KEY_LEFT:
00141       settings.view_center.x -= 0.5f;
00142       resize_cb(width, height);
00143       break;
00144       
00146     case GLUT_KEY_RIGHT:
00147       settings.view_center.x += 0.5f;
00148       resize_cb(width, height);
00149       break;
00150       
00152     case GLUT_KEY_DOWN:
00153       settings.view_center.y -= 0.5f;
00154       resize_cb(width, height);
00155       break;
00156       
00158     case GLUT_KEY_UP:
00159       settings.view_center.y += 0.5f;
00160       resize_cb(width, height);
00161       break;
00162       
00164     case GLUT_KEY_HOME:
00165       view_zoom = 1.0f;
00166       settings.view_center.Set(0.0f, 20.0f);
00167       callbacks_t::resize_cb(width, height);
00168       break;
00169     }
00170   }
00171 
00172   void callbacks_t::keyboard_up_cb(unsigned char key, int x, int y)
00173   {
00174     B2_NOT_USED(x);
00175     B2_NOT_USED(y);
00176     
00177     if (test)
00178       {
00179     test->keyboard_up(key);
00180       }
00181   }
00182   
00183   void callbacks_t::mouse_cb(int32 button, int32 state, int32 x, int32 y)
00184   {
00186     if (button == GLUT_LEFT_BUTTON)
00187       {
00188     int mod = glutGetModifiers();
00189     b2Vec2 p = convert_screen_to_world(x, y);
00190     if (state == GLUT_DOWN)
00191       {
00192         b2Vec2 p = convert_screen_to_world(x, y);
00193         if (mod == GLUT_ACTIVE_SHIFT)
00194           {
00195         test->shift_mouse_down(p);
00196           }
00197         else
00198           {
00199         test->mouse_down(p);
00200           }
00201       }
00202     
00203     if (state == GLUT_UP)
00204       {
00205         test->mouse_up(p);
00206       }
00207       }
00208     else if (button == GLUT_RIGHT_BUTTON)
00209       {
00210     if (state == GLUT_DOWN)
00211       { 
00212         lastp = convert_screen_to_world(x, y);
00213         r_mouse_down = true;
00214       }
00215     
00216     if (state == GLUT_UP)
00217       {
00218       r_mouse_down = false;
00219       }
00220       }
00221   }
00222   
00223   
00224   void callbacks_t::mouse_motion_cb(int32 x, int32 y)
00225   {
00226     b2Vec2 p = convert_screen_to_world(x, y);
00227     test->mouse_move(p);
00228     
00229     if (r_mouse_down)
00230       {
00231     b2Vec2 diff = p - lastp;
00232     settings.view_center.x -= diff.x;
00233     settings.view_center.y -= diff.y;
00234     resize_cb(width, height);
00235     lastp = convert_screen_to_world(x, y);
00236       }
00237   }
00238   
00239   void callbacks_t::timer_cb(int)
00240   {
00241     glutSetWindow(main_window);
00242     glutPostRedisplay();
00243     glutTimerFunc(frame_period, timer_cb, 0);
00244   }
00245   
00246   void callbacks_t::display_cb(void)
00247   {
00248     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00249     
00250     glMatrixMode(GL_MODELVIEW);
00251     glLoadIdentity();
00252     
00253     test->set_text_line(30);
00254     b2Vec2 old_center = settings.view_center;
00255     settings.hz = settings_hz;
00256     
00257     test->step(&settings);
00258     
00259     if (old_center.x != settings.view_center.x || old_center.y != settings.view_center.y)
00260       {
00261     resize_cb(width, height);
00262       }
00263     
00264     test->draw_title(5, 15, entry->name);
00265     
00266     glutSwapBuffers();
00267     
00268     if (test_selection != test_index)
00269       {
00270     test_index = test_selection;
00271     delete test;
00272     entry = cs296::sim;
00273     test = entry->create_fcn();
00274     view_zoom = 1.0f;
00275     settings.view_center.Set(0.0f, 20.0f);
00276       resize_cb(width, height);
00277       }
00278   }
00279   
00280   
00281   
00282   void callbacks_t::restart_cb(int)
00283   {
00284     delete test;
00285     entry = cs296::sim;
00286     test = entry->create_fcn();
00287     resize_cb(width, height);
00288   }
00289   
00290   void callbacks_t::pause_cb(int)
00291   {
00292     settings.pause = !settings.pause;
00293   }
00294   
00295   void callbacks_t::exit_cb(int code)
00296   {
00297     exit(code);
00298   }
00299   
00300   void callbacks_t::single_step_cb(int)
00301   {
00302     settings.pause = 1;
00303     settings.single_step = 1;
00304   }
00305 
00306 };
 All Classes Namespaces Files Functions Variables Typedefs Friends Defines