now thats a lot of damage!
[vg.git] / src / vg / vg_input.h
index 62d4690a68e2acfa2673a6af7e7992959d42ca82..ac2cce6e2cb4c7dcd8bbf85e829a43c6e67c450c 100644 (file)
@@ -1,9 +1,18 @@
-// Copyright (C) 2021 Harry Godden (hgn) - All Rights Reserved
+/* Copyright (C) 2021-2022 Harry Godden (hgn) - All Rights Reserved */
+#ifndef VG_INPUT_H
+#define VG_INPUT_H
 
-static inline float vg_get_axis( const char *axis ) __attribute__((unused));
-static inline int vg_get_button( const char *button ) __attribute__((unused));
-static inline int vg_get_button_down( const char *button ) __attribute__((unused));
-static inline int vg_get_button_up( const char *button ) __attribute__((unused));
+#include "common.h"
+#include "vg/vg_loader.h"
+
+VG_STATIC inline float vg_get_axis( const char *axis );
+VG_STATIC inline int vg_get_button( const char *button );
+
+/*
+ * Cannot be used in fixed update
+ */
+VG_STATIC inline int vg_get_button_down( const char *button );
+VG_STATIC inline int vg_get_button_up( const char *button );
 
 enum vg_button_state
 {
@@ -13,13 +22,7 @@ enum vg_button_state
        k_button_state_none = 0
 };
 
-// Input
-// ===========================================================================================================
-GLFWgamepadstate vg_gamepad;
-int                    vg_gamepad_ready = 0;
-const char *vg_gamepad_name = NULL;
-int                    vg_gamepad_id;
-
+/* TODO: Fix this... */
 enum EInputMode
 {
        k_EInputMode_pc,
@@ -27,13 +30,14 @@ enum EInputMode
 }
 vg_input_mode;
 
-static struct axis_binding
+VG_STATIC struct axis_binding
 {
        const char *name;
        union
        {
                int positive;
                int bind;
+      int axis;
        };
        int negative;
        
@@ -41,120 +45,175 @@ static struct axis_binding
 }
 vg_axis_binds[];
 
-static struct button_binding
+VG_STATIC struct button_binding
 {
        const char *name;
        int bind;
        
        int value; int prev;
 }
-vg_button_binds[];
+vg_button_binds[],
+vg_controller_binds[];
 
-#include "vg/config.h"
+#include "vg_config.h"
 
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wreturn-type"
 
-static inline float vg_get_axis( const char *axis )
+VG_STATIC float vg_get_axis( const char *axis )
 {
        for( int i = 0; i < vg_list_size( vg_axis_binds ); i ++ )
-       {
                if( !strcmp( axis, vg_axis_binds[i].name ) )
-               {
                        return vg_axis_binds[i].value;
-               }
-       }
 }
 
-static inline struct button_binding *vg_get_button_ptr( const char *button )
+VG_STATIC struct button_binding *vg_get_button_ptr( const char *button )
 {
-       for( int i = 0; i < vg_list_size( vg_button_binds ); i ++ )
-       {
-               if( !strcmp( button, vg_button_binds[i].name ) )
-               {
+       for( int i=0; i<vg_list_size(vg_button_binds); i ++ )
+               if( !strcmp(button,vg_button_binds[i].name) )
                        return vg_button_binds + i;
-               }
-       }
+   return NULL;
 }
+
+VG_STATIC struct button_binding *vg_get_button_ptr_c( const char *button )
+{
+       for( int i=0; i<vg_list_size(vg_controller_binds); i ++ )
+               if( !strcmp(button,vg_controller_binds[i].name) )
+                       return vg_controller_binds + i;
+   return NULL;
+}
+
 #pragma GCC diagnostic pop
 
-static int vg_console_enabled(void);
+VG_STATIC int vg_console_enabled(void);
 
-static inline int vg_get_button( const char *button )
+VG_STATIC void vg_get_button_states( const char *name, int *cur, int *prev )
 {
-       return vg_get_button_ptr( button )->value && !vg_console_enabled();
+       struct button_binding *bind = vg_get_button_ptr( name ),
+                        *bindc = vg_get_button_ptr_c( name );
+   
+   *cur = 0; *prev = 0;
+
+   if( bind ) 
+   {
+      *cur |= bind->value;
+      *prev |= bind->prev;
+   }
+
+   if( bindc ) 
+   {
+      *cur |= bindc->value;
+      *prev |= bindc->prev;
+   }
+}
+
+VG_STATIC int vg_get_button( const char *button )
+{
+   int cur, prev;
+   vg_get_button_states( button, &cur, &prev );
+
+       return cur && !vg_console_enabled();
 }
 
-static inline int vg_get_button_down( const char *button )
+VG_STATIC int vg_get_button_down( const char *button )
 {
-       struct button_binding *bind = vg_get_button_ptr( button );
-       return bind->value & (bind->value ^ bind->prev) && !vg_console_enabled();
+   if( vg.engine_stage == k_engine_stage_update_fixed )
+      vg_fatal_exit_loop( "Cannot use that here\n" );
+
+   int cur, prev;
+   vg_get_button_states( button, &cur, &prev );
+
+       return cur & (cur ^ prev) && !vg_console_enabled();
 }
 
-static inline int vg_get_button_up( const char *button )
+VG_STATIC int vg_get_button_up( const char *button )
 {
-       struct button_binding *bind = vg_get_button_ptr( button );
-       return bind->prev & (bind->value ^ bind->prev) && !vg_console_enabled();
+   if( vg.engine_stage == k_engine_stage_update_fixed )
+      vg_fatal_exit_loop( "Cannot use that here\n" );
+
+   int cur, prev;
+   vg_get_button_states( button, &cur, &prev );
+
+       return prev & (cur ^ prev) && !vg_console_enabled();
 }
 
-static inline enum vg_button_state vg_get_button_state( const char *button )
+VG_STATIC enum vg_button_state vg_get_button_state( const char *button )
 {
-       if( vg_get_button_down( button ) ) return k_button_state_down;
-       if( vg_get_button_up( button ) ) return k_button_state_up;
-       if( vg_get_button( button ) ) return k_button_state_pressed;
+       if(vg_get_button_down( button )) return k_button_state_down;
+       if(vg_get_button_up( button )) return k_button_state_up;
+       if(vg_get_button( button )) return k_button_state_pressed;
        return k_button_state_none;
 }
 
-static inline int key_is_keyboard( int const id )
+VG_STATIC int key_is_keyboard( int const id )
 {
-       vg_static_assert( GLFW_MOUSE_BUTTON_LAST < GLFW_KEY_SPACE, "GLFW: Mouse has too many buttons" );
+       vg_static_assert( GLFW_MOUSE_BUTTON_LAST < GLFW_KEY_SPACE, 
+         "GLFW: Mouse has too many buttons" );
        return id > GLFW_MOUSE_BUTTON_LAST;
 }
 
-// Mouse AND Keyboard get button press
 int get_button_cross_device( int const id )
 {
        if( key_is_keyboard( id ) )
-       {
-               return glfwGetKey( vg_window, id );
-       }
+               return glfwGetKey( vg.window, id );
        else
-       {
-               return glfwGetMouseButton( vg_window, id ) == GLFW_PRESS;
-       }
+               return glfwGetMouseButton( vg.window, id ) == GLFW_PRESS;
 }
 
 void vg_update_inputs(void)
 {
-       // Update button inputs
+   if( !glfwGetGamepadState( GLFW_JOYSTICK_1, &vg.gamepad) )
+      vg.gamepad_ready = 0;
+
+       /* Update button inputs */
        for( int i = 0; i < vg_list_size( vg_button_binds ); i ++ )
        {
                struct button_binding *binding = vg_button_binds + i;
                binding->prev = binding->value;
-       
-               if( vg_input_mode == k_EInputMode_pc )
-               {
-                       binding->value = get_button_cross_device( binding->bind );
-               }
-               else
-               {
-                       binding->value = vg_gamepad.buttons[ binding->bind ];
-               }
+      binding->value = get_button_cross_device( binding->bind );
        }
+
+   for( int i=0; i<vg_list_size( vg_controller_binds ); i++ )
+   {
+               struct button_binding *binding = vg_controller_binds + i;
+               binding->prev = binding->value;
+      binding->value = vg.gamepad.buttons[ binding->bind ];
+   }
        
-       // Update axis inputs
+       /* Update axis inputs */
        for( int i = 0; i < vg_list_size( vg_axis_binds ); i ++ )
        {
                struct axis_binding *binding = vg_axis_binds + i;
-               
-               if( vg_input_mode == k_EInputMode_pc )
-               {
-                       binding->value  = get_button_cross_device( binding->positive );
-                       binding->value -= get_button_cross_device( binding->negative );
-               }
-               else
-               {
-                       binding->value = vg_gamepad.axes[ binding->bind ];
-               }
+      binding->value = vg.gamepad.axes[ binding->bind ];
        }
 }
+
+VG_STATIC void vg_gamepad_init(void)
+{
+   vg_acquire_thread_sync();
+
+   for( int id=0; id<=GLFW_JOYSTICK_LAST; id ++ )
+   {
+      if( glfwJoystickPresent( id ) )
+      {
+         vg_info( "Joystick found: '%s'\n", glfwGetJoystickName(id) );
+      }
+
+      if( glfwJoystickIsGamepad( id ) )
+      {
+         vg.gamepad_name = glfwGetGamepadName( id );
+         vg_success( "Gamepad mapping registered: %s\n", vg.gamepad_name );
+         
+         vg.gamepad_ready = 1;
+         vg.gamepad_id = id;
+         break;
+      }
+   }
+
+   vg.gamepad.axes[ GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER ] = -1.0f;
+   vg.gamepad.axes[ GLFW_GAMEPAD_AXIS_LEFT_TRIGGER  ] = -1.0f;
+
+   vg_release_thread_sync();
+}
+
+#endif