Index: trunk/src/gl/gl_device.cc
===================================================================
--- trunk/src/gl/gl_device.cc	(revision 183)
+++ trunk/src/gl/gl_device.cc	(revision 184)
@@ -25,5 +25,5 @@
 	m_info = NULL;
 
-	if ( SDL_Init( SDL_INIT_VIDEO ) < 0 )
+	if ( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_JOYSTICK ) < 0 )
 	{
 		NV_LOG( LOG_CRITICAL, "Video initialization failed: " << SDL_GetError( ) );
Index: trunk/src/gl/gl_window.cc
===================================================================
--- trunk/src/gl/gl_window.cc	(revision 183)
+++ trunk/src/gl/gl_window.cc	(revision 184)
@@ -132,4 +132,41 @@
 }
 
+static bool sdl_joy_button_event_to_io_event( const SDL_JoyButtonEvent& jb, io_event& jevent )
+{
+	jevent.type            = EV_JOY_BUTTON;
+	jevent.jbutton.id      = jb.which;
+	jevent.jbutton.button  = jb.button;
+	jevent.jbutton.pressed = (jb.type == SDL_PRESSED);
+	return true;
+}
+
+static bool sdl_joy_axis_event_to_io_event( const SDL_JoyAxisEvent& ja, io_event& jevent )
+{
+	jevent.type          = EV_JOY_AXIS;
+	jevent.jaxis.id      = ja.which;
+	jevent.jaxis.axis    = ja.axis;
+	jevent.jaxis.value   = ja.value;
+	return true;
+}
+
+static bool sdl_joy_hat_event_to_io_event( const SDL_JoyHatEvent& jh, io_event& jevent )
+{
+	jevent.type          = EV_JOY_HAT;
+	jevent.jhat.id       = jh.which;
+	jevent.jhat.hat      = jh.hat;
+	jevent.jhat.value    = jh.value;
+	return true;
+}
+
+static bool sdl_joy_ball_event_to_io_event( const SDL_JoyBallEvent& jb, io_event& jevent )
+{
+	jevent.type          = EV_JOY_HAT;
+	jevent.jball.id      = jb.which;
+	jevent.jball.ball    = jb.ball;
+	jevent.jball.rx      = jb.xrel;
+	jevent.jball.ry      = jb.yrel;
+	return true;
+}
+
 static bool sdl_event_to_io_event( const SDL_Event& e, io_event& ioevent )
 {
@@ -156,9 +193,9 @@
 	case SDL_SYSWMEVENT      : ioevent.type = EV_SYSTEM; return true;
 	case SDL_QUIT            : ioevent.type = EV_QUIT;   return true;
-	case SDL_JOYAXISMOTION   : return false;
-	case SDL_JOYBALLMOTION   : return false;
-	case SDL_JOYHATMOTION    : return false;
-	case SDL_JOYBUTTONDOWN   : return false;
-	case SDL_JOYBUTTONUP     : return false;
+	case SDL_JOYAXISMOTION   : return sdl_joy_axis_event_to_io_event( e.jaxis, ioevent ); 
+	case SDL_JOYBALLMOTION   : return sdl_joy_ball_event_to_io_event( e.jball, ioevent ); 
+	case SDL_JOYHATMOTION    : return sdl_joy_hat_event_to_io_event( e.jhat, ioevent ); 
+	case SDL_JOYBUTTONDOWN   : return sdl_joy_button_event_to_io_event( e.jbutton, ioevent );
+	case SDL_JOYBUTTONUP     : return sdl_joy_button_event_to_io_event( e.jbutton, ioevent );
 	default : return false;
 	}
@@ -183,4 +220,15 @@
 	}
 
+// 	NV_LOG( LOG_INFO, "Joystick count : " << SDL_NumJoysticks() );
+// 	SDL_Joystick* j = SDL_JoystickOpen(0);
+// 	if (j)
+// 	{
+// 		NV_LOG( LOG_INFO, "Joystick Name: " << SDL_JoystickNameForIndex(0) );
+// 		NV_LOG( LOG_INFO, "Joystick Number of Axes: " << SDL_JoystickNumAxes(j));
+// 		NV_LOG( LOG_INFO, "Joystick Number of Buttons: " << SDL_JoystickNumButtons(j));
+// 		NV_LOG( LOG_INFO, "Joystick Number of Balls: " << SDL_JoystickNumBalls(j));
+// 	}
+
+
 	m_context = new gl_context( m_device, m_handle );
 	m_context->set_viewport( nv::ivec4( 0, 0, m_width, m_height ) );
Index: trunk/src/io_event.cc
===================================================================
--- trunk/src/io_event.cc	(revision 183)
+++ trunk/src/io_event.cc	(revision 184)
@@ -94,4 +94,33 @@
 	db->create_type<mouse_move_event>("mouse_move_event").fields( mouse_move_fields );
 
+	type_field joy_button_fields[] = {
+		type_field( "id",      &joy_button_event::id ),
+		type_field( "button",  &joy_button_event::button ),
+		type_field( "pressed", &joy_button_event::pressed ),
+	};
+	db->create_type<joy_button_event>("joy_button_event").fields( joy_button_fields );
+
+	type_field joy_axis_fields[] = {
+		type_field( "id",      &joy_axis_event::id ),
+		type_field( "axis",    &joy_axis_event::axis ),
+		type_field( "value",   &joy_axis_event::value ),
+	};
+	db->create_type<joy_axis_event>("joy_axis_event").fields( joy_axis_fields );
+
+	type_field joy_hat_fields[] = {
+		type_field( "id",      &joy_hat_event::id ),
+		type_field( "hat",     &joy_hat_event::hat ),
+		type_field( "value",   &joy_hat_event::value ),
+	};
+	db->create_type<joy_hat_event>("joy_hat_event").fields( joy_hat_fields );
+
+	type_field joy_ball_fields[] = {
+		type_field( "id",      &joy_ball_event::id ),
+		type_field( "ball",    &joy_ball_event::ball ),
+		type_field( "rx",      &joy_ball_event::rx ),
+		type_field( "ry",      &joy_ball_event::ry ),
+	};
+	db->create_type<joy_ball_event>("joy_ball_event").fields( joy_ball_fields );
+
 	type_field system_fields[] = {
 		type_field( "sys_type", &system_event::sys_type ),
