heebie
[vg.git] / vg_input.h
index f97a41af28d161fbf95687319ed57931ac5bf862..af0ac6882d9ff285cdbe6e95ba91d71a930553a8 100644 (file)
@@ -14,6 +14,8 @@ VG_STATIC inline int vg_get_button( const char *button );
 VG_STATIC inline int vg_get_button_down( const char *button );
 VG_STATIC inline int vg_get_button_up( const char *button );
 
+VG_STATIC float g_controller_deadzone = 0.05f;
+
 enum vg_button_state
 {
        k_button_state_down = 1,
@@ -57,6 +59,7 @@ struct input_binding
       {
          SDL_GameControllerButton gamepad_id;
          SDL_Keycode              keyboard_id;
+         int                      mouse_id;
          int value, prev;
       }
       button;
@@ -95,6 +98,7 @@ VG_STATIC void vg_create_unnamed_input( struct input_binding *bind,
    bind->axis.keyboard_negative = -1;
    bind->button.gamepad_id = -1;
    bind->button.keyboard_id = -1;
+   bind->button.mouse_id = -1;
 }
 
 VG_STATIC struct input_binding *vg_create_named_input( const char *name,
@@ -113,6 +117,7 @@ VG_STATIC struct input_binding *vg_create_named_input( const char *name,
    bind->axis.keyboard_negative = -1;
    bind->button.gamepad_id = -1;
    bind->button.keyboard_id = -1;
+   bind->button.mouse_id = -1;
 
    return bind;
 }
@@ -177,7 +182,10 @@ vg_all_bindable_inputs[] =
  {k_input_type_gamepad_button, "gp-dpad-left", SDL_CONTROLLER_BUTTON_DPAD_LEFT},
  {k_input_type_gamepad_button,"gp-dpad-right",SDL_CONTROLLER_BUTTON_DPAD_RIGHT},
  {k_input_type_gamepad_button, "gp-dpad-up", SDL_CONTROLLER_BUTTON_DPAD_UP},
- {k_input_type_gamepad_button, "\2gp-menu", SDL_CONTROLLER_BUTTON_BACK}
+ {k_input_type_gamepad_button, "\2gp-menu", SDL_CONTROLLER_BUTTON_BACK},
+
+ {k_input_type_mouse_button,   "mouse1", SDL_BUTTON_LEFT },
+ {k_input_type_mouse_button,   "mouse2", SDL_BUTTON_RIGHT }
 };
 
 VG_STATIC const char *vg_input_to_str( u32 input, enum input_type input_type )
@@ -287,6 +295,9 @@ VG_STATIC void vg_print_binding_info( struct input_binding *bind )
       vg_info( "      keyboard_id: %s\n",
          vg_input_to_str(bind->button.keyboard_id,
                          k_input_type_keyboard_key));
+      vg_info( "      mouse_id: %s\n",
+         vg_input_to_str(bind->button.mouse_id,
+                         k_input_type_mouse_button));
    }
 }
 
@@ -329,6 +340,8 @@ VG_STATIC void vg_apply_bind_str( struct input_binding *bind,
 
       if( type == k_input_type_keyboard_key )
          bind->button.keyboard_id = id;
+      else if( type == k_input_type_mouse_button )
+         bind->button.mouse_id = id;
       else if( type == k_input_type_gamepad_button )
          bind->button.gamepad_id = id;
       else
@@ -378,10 +391,10 @@ VG_STATIC void vg_apply_bind_str( struct input_binding *bind,
 }
 
 /* 
- * bind x jump 
- * bind a -horizontal
- * bind d +horizontal
- * bind -gp-ls-h horizontal
+ * bind  jump        x
+ * bind -horizontal  a
+ * bind +horizontal  d
+ * bind  horizontal -gp-ls-h 
  */
 
 VG_STATIC int vg_rebind_input_cmd( int argc, const char *argv[] )
@@ -420,6 +433,32 @@ VG_STATIC int vg_rebind_input_cmd( int argc, const char *argv[] )
    return 0;
 }
 
+VG_STATIC void vg_rebind_input_cmd_poll( int argc, const char *argv[] )
+{
+   if( argc == 0 )
+      return;
+
+   const char *str_bind_name = argv[0];
+
+   if( argc == 1 )
+   {
+      for( u32 i=0; i<vg_input.named_input_count; i++ )
+      {
+         struct input_binding *bind = &vg_input.named_inputs[i];
+         console_suggest_score_text( bind->name, argv[argc-1], 0 );
+      }
+   }
+
+   else if( argc == 2 )
+   {
+      for( int i=0; i<vg_list_size(vg_all_bindable_inputs); i++ )
+      {
+         struct input_en *desc = &vg_all_bindable_inputs[i];
+         console_suggest_score_text( desc->alias, argv[argc-1], 0 );
+      }
+   }
+}
+
 VG_STATIC u8 vg_getkey( SDL_Keycode kc )
 {
    SDL_Scancode sc = SDL_GetScancodeFromKey( kc );
@@ -458,7 +497,16 @@ VG_STATIC void vg_input_update( u32 num, struct input_binding *binds )
                vg_input.controller_buttons[ bind->button.gamepad_id ];
 
          if( bind->button.keyboard_id != -1 )
+         {
             bind->button.value |= vg_getkey( bind->button.keyboard_id );
+         }
+
+         if( bind->button.mouse_id != -1 )
+         {
+            if( SDL_GetMouseState(NULL, NULL) & 
+                                    SDL_BUTTON( bind->button.mouse_id ) )
+               bind->button.value |= 1;
+         }
       }
       else if( bind->type == k_input_type_axis )
       {
@@ -482,8 +530,11 @@ VG_STATIC void vg_input_update( u32 num, struct input_binding *binds )
                gamepad_value *= -1.0f;
          }
 
-         if( fabsf(gamepad_value) <= 0.01f )
-            gamepad_value = 0.0f;
+         float deadz   = vg_clampf( g_controller_deadzone, 0.0f, 0.999f ),
+               high    = vg_maxf( 0.0f, fabsf(gamepad_value) - deadz ),
+               norm    = high / (1.0f-deadz);
+
+         gamepad_value = vg_signf( gamepad_value ) * norm;
 
          if( fabsf(keyboard_value) > fabsf(gamepad_value) )
             bind->axis.value = keyboard_value;
@@ -583,7 +634,16 @@ VG_STATIC void vg_input_init(void)
    vg_function_push( (struct vg_cmd)
    {
       .name = "bind",
-      .function = vg_rebind_input_cmd
+      .function = vg_rebind_input_cmd,
+      .poll_suggest = vg_rebind_input_cmd_poll
+   });
+
+   vg_var_push( (struct vg_var){
+      .name = "controller_deadzone",
+      .data = &g_controller_deadzone,
+      .data_type = k_var_dtype_f32,
+      .opt_f32 = { .clamp = 0 },
+      .persistent = 1
    });
 
    vg_info( "Checking for controller\n" );
@@ -605,7 +665,7 @@ VG_STATIC void vg_input_init(void)
    vg_release_thread_sync();
 }
 
-VG_STATIC void vg_input_free(void *_)
+VG_STATIC void vg_input_free(void)
 {
    if( vg_input.controller_handle )
    {