+++ /dev/null
-/* Copyright (C) 2021-2022 Harry Godden (hgn) - All Rights Reserved */
-#ifndef VG_INPUT_H
-#define VG_INPUT_H
-
-#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
-{
- k_button_state_down = 1,
- k_button_state_up = 3,
- k_button_state_pressed = 2,
- k_button_state_none = 0
-};
-
-VG_STATIC struct input_binding
-{
- const char *name;
-
- enum input_type
- {
- k_input_type_button,
- k_input_type_axis,
- k_input_type_axis_norm,
-
- k_input_type_unknown,
- k_input_type_keyboard_key,
- k_input_type_mouse_button, /* ? TODO */
- k_input_type_gamepad_axis,
- k_input_type_gamepad_button
- }
- type;
-
- union
- {
- struct input_axis
- {
- u32 gamepad_axis,
- keyboard_positive,
- keyboard_negative;
-
- int gamepad_inverted;
- float value;
- }
- axis;
-
- struct
- {
- u32 gamepad_id, keyboard_id;
- int value, prev;
- }
- button;
- };
-
- int save_this;
-}
-vg_named_inputs[ 32 ];
-VG_STATIC u32 vg_named_input_count = 0;
-
-VG_STATIC void vg_create_unnamed_input( struct input_binding *bind,
- enum input_type type )
-{
- memset( bind, 0, sizeof(struct input_binding) );
-
- bind->name = "API DEFINED";
- bind->save_this = 0;
- bind->type = type;
-
- bind->axis.gamepad_axis = -1;
- bind->axis.keyboard_positive = -1;
- bind->axis.keyboard_negative = -1;
- bind->button.gamepad_id = -1;
- bind->button.keyboard_id = -1;
-}
-
-VG_STATIC struct input_binding *vg_create_named_input( const char *name,
- enum input_type type )
-{
- struct input_binding *bind = &vg_named_inputs[ vg_named_input_count ++ ];
- memset( bind, 0, sizeof(struct input_binding) );
-
- bind->name = name;
- bind->save_this = 0;
- bind->type = type;
-
- bind->axis.gamepad_axis = -1;
- bind->axis.keyboard_positive = -1;
- bind->axis.keyboard_negative = -1;
- bind->button.gamepad_id = -1;
- bind->button.keyboard_id = -1;
-
- return bind;
-}
-
-VG_STATIC struct input_binding *vg_get_named_input( const char *name )
-{
- if( name[0] == '+' || name[0] == '-' )
- name ++;
-
- for( u32 i=0; i<vg_named_input_count; i++ )
- {
- struct input_binding *bind = &vg_named_inputs[i];
- if( !strcmp( bind->name, name ) )
- return bind;
- }
-
- return NULL;
-}
-
-struct input_en
-{
- enum input_type type;
-
- const char *alias;
- int id;
-}
-vg_all_bindable_inputs[] =
-{
- {k_input_type_keyboard_key, "space", GLFW_KEY_SPACE},
- {k_input_type_keyboard_key, ";", GLFW_KEY_SEMICOLON},
- {k_input_type_keyboard_key, "-", GLFW_KEY_MINUS},
- {k_input_type_keyboard_key, ".", GLFW_KEY_PERIOD},
- {k_input_type_keyboard_key, ",", GLFW_KEY_COMMA},
- {k_input_type_keyboard_key, "=", GLFW_KEY_EQUAL},
- {k_input_type_keyboard_key, "[", GLFW_KEY_LEFT_BRACKET},
- {k_input_type_keyboard_key, "]", GLFW_KEY_RIGHT_BRACKET},
- {k_input_type_keyboard_key, "left", GLFW_KEY_LEFT},
- {k_input_type_keyboard_key, "right", GLFW_KEY_RIGHT},
- {k_input_type_keyboard_key, "up", GLFW_KEY_UP},
- {k_input_type_keyboard_key, "down", GLFW_KEY_DOWN},
- {k_input_type_keyboard_key, "shift", GLFW_KEY_LEFT_SHIFT},
- {k_input_type_keyboard_key, "control", GLFW_KEY_LEFT_CONTROL},
- {k_input_type_keyboard_key, "\2enter", GLFW_KEY_ENTER},
- {k_input_type_keyboard_key, "\2escape", GLFW_KEY_ESCAPE },
-
- {k_input_type_gamepad_axis, "gp-lt", GLFW_GAMEPAD_AXIS_LEFT_TRIGGER},
- {k_input_type_gamepad_axis, "gp-rt", GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER},
- {k_input_type_gamepad_axis, "gp-ls-h", GLFW_GAMEPAD_AXIS_LEFT_X},
- {k_input_type_gamepad_axis, "gp-ls-v", GLFW_GAMEPAD_AXIS_LEFT_Y},
- {k_input_type_gamepad_axis, "gp-rs-h", GLFW_GAMEPAD_AXIS_RIGHT_X},
- {k_input_type_gamepad_axis, "gp-rs-v", GLFW_GAMEPAD_AXIS_RIGHT_Y},
-
- {k_input_type_gamepad_button, "gp-a", GLFW_GAMEPAD_BUTTON_A},
- {k_input_type_gamepad_button, "gp-b", GLFW_GAMEPAD_BUTTON_B},
- {k_input_type_gamepad_button, "gp-x", GLFW_GAMEPAD_BUTTON_X},
- {k_input_type_gamepad_button, "gp-y", GLFW_GAMEPAD_BUTTON_Y},
- {k_input_type_gamepad_button, "gp-rb", GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER},
- {k_input_type_gamepad_button, "gp-lb", GLFW_GAMEPAD_BUTTON_LEFT_BUMPER},
- {k_input_type_gamepad_button, "gp-rs", GLFW_GAMEPAD_BUTTON_RIGHT_THUMB},
- {k_input_type_gamepad_button, "gp-ls", GLFW_GAMEPAD_BUTTON_LEFT_THUMB},
- {k_input_type_gamepad_button, "gp-dpad-down", GLFW_GAMEPAD_BUTTON_DPAD_DOWN},
- {k_input_type_gamepad_button, "gp-dpad-left", GLFW_GAMEPAD_BUTTON_DPAD_LEFT},
- {k_input_type_gamepad_button, "gp-dpad-right", GLFW_GAMEPAD_BUTTON_DPAD_RIGHT},
- {k_input_type_gamepad_button, "gp-dpad-up", GLFW_GAMEPAD_BUTTON_DPAD_UP},
- {k_input_type_gamepad_button, "\2gp-menu", GLFW_GAMEPAD_BUTTON_BACK}
-};
-
-VG_STATIC const char *vg_input_to_str( u32 input, enum input_type input_type )
-{
- if( input == -1 )
- return NULL;
-
- if( input_type == k_input_type_keyboard_key )
- {
- if( (input >= GLFW_KEY_A) && (input <= GLFW_KEY_Z) )
- {
- return &"a\0b\0c\0d\0e\0f\0g\0h\0i\0j\0k\0l\0m\0n\0o\0p\0"
- "q\0r\0s\0t\0u\0v\0w\0x\0y\0z\0"[(input-GLFW_KEY_A)*2];
- }
-
- if( (input >= GLFW_KEY_0) && (input <= GLFW_KEY_9) )
- {
- return &"0\0" "1\0" "2\0" "3\0" "4\0"
- "5\0" "6\0" "7\0" "8\0" "9\0"[(input-GLFW_KEY_0)*2];
- }
- }
-
- for( int i=0; i<vg_list_size(vg_all_bindable_inputs); i++ )
- {
- struct input_en *desc = &vg_all_bindable_inputs[i];
-
- if( (desc->type == input_type) && (desc->id == input) )
- return desc->alias;
- }
-
- return NULL;
-}
-
-VG_STATIC enum input_type vg_str_to_input( const char *str, u32 *input )
-{
- if( !str )
- {
- *input = -1;
- return k_input_type_unknown;
- }
-
- u32 len = strlen(str);
-
- if( len == 0 )
- {
- *input = -1;
- return k_input_type_unknown;
- }
-
- if( len == 1 )
- {
- u8 uch = str[0];
-
- if( (uch >= (u8)'a') && (uch <= (u8)'z') )
- {
- *input = GLFW_KEY_A + (uch-(u8)'a');
- return k_input_type_keyboard_key;
- }
-
- if( (uch >= (u8)'0') && (uch <= (u8)'9') )
- {
- *input = GLFW_KEY_0 + (uch-(u8)'0');
- return k_input_type_keyboard_key;
- }
- }
-
- for( int i=0; i<vg_list_size(vg_all_bindable_inputs); i++ )
- {
- struct input_en *desc = &vg_all_bindable_inputs[i];
-
- if( !strcmp( desc->alias, str ) )
- {
- *input = desc->id;
- return desc->type;
- }
- }
-
- *input = -1;
- return k_input_type_unknown;
-}
-
-VG_STATIC void vg_print_binding_info( struct input_binding *bind )
-{
- vg_info( " name: %s\n", bind->name );
- vg_info( " type: %s\n", (const char *[]){"button","axis","axis[0-1]"}
- [ bind->type ] );
- vg_info( " save this? %d\n", bind->save_this );
-
- if( (bind->type == k_input_type_axis) ||
- (bind->type == k_input_type_axis_norm) )
- {
- vg_info( " gamepad_axis: %s\n",
- vg_input_to_str(bind->axis.gamepad_axis, k_input_type_gamepad_axis));
-
- vg_info( " keyboard_positive: %s\n",
- vg_input_to_str(bind->axis.keyboard_positive,
- k_input_type_keyboard_key ));
-
- vg_info( " keyboard_negative: %s\n",
- vg_input_to_str(bind->axis.keyboard_negative,
- k_input_type_keyboard_key ));
- }
- else
- {
- vg_info( " gamepad_id: %s\n",
- vg_input_to_str(bind->button.gamepad_id, k_input_type_gamepad_button));
- vg_info( " keyboard_id: %s\n",
- vg_input_to_str(bind->button.keyboard_id,
- k_input_type_keyboard_key));
- }
-}
-
-VG_STATIC void vg_apply_bind_str( struct input_binding *bind,
- const char *mod,
- const char *str )
-{
- int axis_mod = 0;
- char modch = ' ';
- if( (mod[0] == '-') || (mod[0] == '+') )
- {
- axis_mod = 1;
- modch = mod[0];
- mod ++;
- }
-
- int invert = 0;
- if( (str[0] == '-' ) )
- {
- invert = 1;
- str ++;
- }
-
- u32 id;
- enum input_type type = vg_str_to_input( str, &id );
-
- if( bind->type == k_input_type_button )
- {
- if( axis_mod )
- {
- vg_error( "Cannot use axis modifiers on button input!\n" );
- return;
- }
-
- if( invert )
- {
- vg_error( "Cannot invert button input!\n" );
- return;
- }
-
- if( type == k_input_type_keyboard_key )
- bind->button.keyboard_id = id;
- else if( type == k_input_type_gamepad_button )
- bind->button.gamepad_id = id;
- else
- {
- vg_error( "Unknown button or key '%s'\n", str );
- return;
- }
- }
- else if( (bind->type == k_input_type_axis ) ||
- (bind->type == k_input_type_axis_norm))
- {
- if( axis_mod )
- {
- if( type == k_input_type_keyboard_key )
- {
- if( invert )
- {
- vg_error( "Cannot invert a keyboard key!\n" );
- return;
- }
-
- if( modch == '+' )
- bind->axis.keyboard_positive = id;
- else
- bind->axis.keyboard_negative = id;
- }
- else
- {
- vg_error( "You can only bind keyboard keys to +- axises\n" );
- return;
- }
- }
- else
- {
- if( type == k_input_type_gamepad_axis )
- {
- bind->axis.gamepad_inverted = invert;
- bind->axis.gamepad_axis = id;
- }
- else
- {
- vg_error( "You can only bind gamepad axises to this\n" );
- return;
- }
- }
- }
-}
-
-/*
- * bind x jump
- * bind a -horizontal
- * bind d +horizontal
- * bind -gp-ls-h horizontal
- */
-
-VG_STATIC int vg_rebind_input_cmd( int argc, const char *argv[] )
-{
- if( argc == 0 )
- {
- vg_info( "Usage: bind jump x\n" );
- vg_info( " bind -steerh j\n" );
- vg_info( " bind steerh gp-ls-h\n" );
- return 0;
- }
-
- const char *str_bind_name = argv[0];
- struct input_binding *bind = vg_get_named_input( str_bind_name );
-
- if( !bind )
- {
- vg_error( "There is no bind with that name '%s'\n", str_bind_name );
- return 0;
- }
-
- if( argc == 1 )
- {
- vg_print_binding_info( bind );
- return 0;
- }
-
- if( argc == 2 )
- {
- const char *str_input_id = argv[1];
-
- vg_apply_bind_str( bind, str_bind_name, str_input_id );
- return 0;
- }
-
- return 0;
-}
-
-VG_STATIC void vg_input_update( u32 num, struct input_binding *binds )
-{
- if( vg_console.enabled )
- {
- for( i32 i=0; i<num; i++ )
- {
- struct input_binding *bind = &binds[i];
-
- if( bind->type == k_input_type_button )
- {
- bind->button.prev = bind->button.value;
- bind->button.value = 0;
- }
- }
-
- return;
- }
-
- for( i32 i=0; i<num; i++ )
- {
- struct input_binding *bind = &binds[i];
-
- if( bind->type == k_input_type_button )
- {
- bind->button.prev = bind->button.value;
- bind->button.value = 0;
-
- if( bind->button.gamepad_id != -1 )
- bind->button.value |= vg.gamepad.buttons[ bind->button.gamepad_id ];
-
- if( bind->button.keyboard_id != -1 )
- bind->button.value |= glfwGetKey( vg.window,
- bind->button.keyboard_id );
- }
- else if( bind->type == k_input_type_axis )
- {
- float keyboard_value = 0.0f,
- gamepad_value = 0.0f;
-
- if( bind->axis.keyboard_positive != -1 )
- if( glfwGetKey( vg.window, bind->axis.keyboard_positive ) )
- keyboard_value += 1.0f;
-
- if( bind->axis.keyboard_negative != -1 )
- if( glfwGetKey( vg.window, bind->axis.keyboard_negative ) )
- keyboard_value -= 1.0f;
-
- if( bind->axis.gamepad_axis != -1 )
- {
- gamepad_value = vg.gamepad.axes[ bind->axis.gamepad_axis ];
- if( bind->axis.gamepad_inverted )
- gamepad_value *= -1.0f;
- }
-
- if( fabsf(gamepad_value) <= 0.01f )
- gamepad_value = 0.0f;
-
- if( fabsf(keyboard_value) > fabsf(gamepad_value) )
- bind->axis.value = keyboard_value;
- else
- bind->axis.value = gamepad_value;
- }
- else if( bind->type == k_input_type_axis_norm )
- {
- float value = -1.0f;
- if( bind->axis.keyboard_positive != -1 )
- if( glfwGetKey( vg.window, bind->axis.keyboard_positive ))
- value = 1.0f;
-
- if( bind->axis.gamepad_axis != -1 )
- value = vg_maxf( value, vg.gamepad.axes[bind->axis.gamepad_axis] );
-
- bind->axis.value = value * 0.5f + 0.5f;
- }
- }
-}
-
-VG_STATIC int vg_console_enabled(void);
-VG_STATIC int vg_input_button_down( struct input_binding *bind )
-{
- if( bind->button.value && !bind->button.prev )
- return 1;
- return 0;
-}
-#if 0
-
-VG_STATIC float vg_get_axis( const char *axis )
-{
- return 0.0f;
-}
-
-
-VG_STATIC void vg_get_button_states( const char *name, int *cur, int *prev )
-{
-}
-
-VG_STATIC int vg_get_button( const char *button )
-{
- return 0;
-}
-
-VG_STATIC int vg_get_button_down( const char *button )
-{
- return 0;
-}
-
-VG_STATIC int vg_get_button_up( const char *button )
-{
- return 0;
-}
-
-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;
- return k_button_state_none;
-}
-#endif
-
-void vg_update_inputs(void)
-{
- if( !glfwGetGamepadState( GLFW_JOYSTICK_1, &vg.gamepad) )
- {
- vg.gamepad_ready = 0;
- vg.gamepad.axes[ GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER ] = -1.0f;
- vg.gamepad.axes[ GLFW_GAMEPAD_AXIS_LEFT_TRIGGER ] = -1.0f;
- }
-
- /* update all inputs */
- vg_input_update( vg_named_input_count, vg_named_inputs );
-}
-
-VG_STATIC void vg_gamepad_init(void)
-{
- vg_acquire_thread_sync();
-
- vg_function_push( (struct vg_cmd)
- {
- .name = "bind",
- .function = vg_rebind_input_cmd
- });
-
- 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 );
-
- /* This path usually only gets chosen when starting outside of steam */
- if( !strcmp(vg.gamepad_name, "Steam Controller") )
- vg.gamepad_use_trackpad_look = 1;
-
- 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