X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=vg_input.h;h=0122c92e5043f26ccbb9141fb1ad688f3dd366f4;hb=3fe47be51b12f62735fd1cb062e71a98ebb3d14a;hp=1052c42937f1c61ce535b8199d8857494b08e57d;hpb=bc9d0792623d0839920fc09bbffe339e6dc104ee;p=vg.git diff --git a/vg_input.h b/vg_input.h index 1052c42..0122c92 100644 --- a/vg_input.h +++ b/vg_input.h @@ -2,656 +2,634 @@ #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 ); +#define VG_MAX_CONTROLLERS 4 -/* - * 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 ); +static float controller_deadzone = 0.05f; +typedef u32 vg_input_op; +typedef vg_input_op *vg_input_program; -VG_STATIC float g_controller_deadzone = 0.05f; - -enum vg_button_state -{ - k_button_state_down = 1, - k_button_state_up = 3, - k_button_state_pressed = 2, - k_button_state_none = 0 +enum vg_input_type { + k_vg_input_type_button_u8, + k_vg_input_type_axis_f32, + k_vg_input_type_joy_v2f }; -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 - { - SDL_GameControllerAxis gamepad_axis; - SDL_Keycode keyboard_positive, - keyboard_negative; - - int gamepad_inverted; - float value; - } - axis; - - struct - { - SDL_GameControllerButton gamepad_id; - SDL_Keycode keyboard_id; - int value, prev; - } - button; - }; - - int save_this; +enum vg_input_op { + /* data source */ + vg_keyboard, + vg_mouse, + vg_joy_button, + vg_joy_axis, + vg_joy_ls, + vg_joy_rs, + + /* modes */ + vg_mode_mul, + vg_mode_sub, + vg_mode_add, + vg_mode_absmax, + vg_mode_max, + + /* control */ + vg_index, + vg_end, + vg_gui_visible, + + /* math */ + vg_normalize }; -struct -{ - const u8 *sdl_keys; - struct input_binding named_inputs[ 32 ]; - u32 named_input_count; - - const char *controller_name; - SDL_GameController *controller_handle; /* null if unplugged */ - SDL_JoystickID controller_joystick_id; - int controller_should_use_trackpad_look; +struct{ + const u8 *sdl_keys; + u32 sdl_mouse; - float controller_axises[ SDL_CONTROLLER_AXIS_MAX ]; - int controller_buttons[ SDL_CONTROLLER_BUTTON_MAX ]; -} -VG_STATIC vg_input; + struct vg_controller{ + SDL_GameController *handle; /* handle for controller. NULL if unused */ + SDL_JoystickID instance_id; /* uid used in events */ -VG_STATIC void vg_create_unnamed_input( struct input_binding *bind, - enum input_type type ) -{ - memset( bind, 0, sizeof(struct input_binding) ); + float axises[ SDL_CONTROLLER_AXIS_MAX ]; + u32 buttons[ SDL_CONTROLLER_BUTTON_MAX ]; + } + controllers[4]; - bind->name = "API DEFINED"; - bind->save_this = 0; - bind->type = type; + int active_controller_index; /* most recent controller (by button press) + will be -1 if no controllers active */ - 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; + /* what the user is currently using. the keyboard and controller are still + * active simultaneously, but this reflects what the UI should show */ + enum input_method{ + k_input_method_kbm, + k_input_method_controller + } + display_input_method; + SDL_GameControllerType display_input_type; } +static vg_input = { .active_controller_index = -2 }; -VG_STATIC struct input_binding *vg_create_named_input( const char *name, - enum input_type type ) +static u8 vg_getkey( SDL_Keycode kc ) { - struct input_binding *bind = - &vg_input.named_inputs[ vg_input.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; + SDL_Scancode sc = SDL_GetScancodeFromKey( kc ); + return vg_input.sdl_keys[sc]; } -VG_STATIC struct input_binding *vg_get_named_input( const char *name ) +/* + * takes SDL device index, and tries to open that on any free channel + */ +static int vg_open_gamecontroller( Sint32 index ) { - if( name[0] == '+' || name[0] == '-' ) - name ++; - - for( u32 i=0; iname, name ) ) - return bind; + struct vg_controller *controller = NULL; + int vg_id = 0; + const char *name = SDL_GameControllerNameForIndex( index ); + SDL_JoystickID instance_id = SDL_JoystickGetDeviceInstanceID( index ); + + if( instance_id == -1 ){ + vg_error( ". Invalid device index (vg_open_gamecontroller)\n" ); + return -1; } - return NULL; -} - -struct input_en -{ - enum input_type type; + for( int j=0; j= SDLK_a) && (input <= SDLK_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-SDLK_a)*2]; + if( esta->handle ){ + if( esta->instance_id == instance_id ){ + vg_warn( " . SDL_JoystickID[%d] is already in open at index #%d\n", + esta->instance_id, j ); + return -1; + } } - - if( (input >= SDLK_0) && (input <= SDLK_9) ) - { - return &"0\0" "1\0" "2\0" "3\0" "4\0" - "5\0" "6\0" "7\0" "8\0" "9\0"[(input-SDLK_0)*2]; + else{ + if( !controller ){ + controller = &vg_input.controllers[j]; + vg_id = j; + } } } - for( int i=0; itype == 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( controller ){ + controller->handle = SDL_GameControllerOpen( index ); + controller->instance_id = instance_id; - if( len == 0 ) - { - *input = -1; - return k_input_type_unknown; - } - - if( len == 1 ) - { - u8 uch = str[0]; + if( controller->handle ){ + vg_success( + " . opened SDL_JoystickID[%d] as controller '%s' at index #%d\n", + instance_id, name, vg_id ); + + for( u32 i=0; i< SDL_CONTROLLER_BUTTON_MAX; i++ ) + controller->buttons[i] = 0; + + for( u32 i=0; i< SDL_CONTROLLER_AXIS_MAX; i++ ) + controller->axises[i] = 0.0f; + + if( vg_input.active_controller_index == -2 ){ + vg_input.active_controller_index = vg_id; + vg_input.display_input_method = k_input_method_controller; + vg_input.display_input_type = + SDL_GameControllerGetType( controller->handle ); + } - if( (uch >= (u8)'a') && (uch <= (u8)'z') ) - { - *input = SDLK_a + (uch-(u8)'a'); - return k_input_type_keyboard_key; + return vg_id; } - - if( (uch >= (u8)'0') && (uch <= (u8)'9') ) - { - *input = SDLK_0 + (uch-(u8)'0'); - return k_input_type_keyboard_key; + else{ + vg_error( ". Failed to attach game controller '%s'. Reason: %s\n", + name, SDL_GetError() ); + return -1; } } - - for( int i=0; ialias, str ) ) - { - *input = desc->id; - return desc->type; - } + else{ + vg_error( ". Too many controllers open! ignoring '%s'\n", name ); + return -1; } - - *input = -1; - return k_input_type_unknown; } -VG_STATIC void vg_print_binding_info( struct input_binding *bind ) +static void vg_input_device_event( SDL_Event *ev ) { - 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)); + if( ev->type == SDL_CONTROLLERDEVICEADDED ){ + int is_controller = SDL_IsGameController( ev->cdevice.which ); + const char *name = SDL_JoystickNameForIndex( ev->cdevice.which ); - vg_info( " keyboard_positive: %s\n", - vg_input_to_str(bind->axis.keyboard_positive, - k_input_type_keyboard_key )); + Sint32 index = ev->cdevice.which; + SDL_JoystickID instance_id = SDL_JoystickGetDeviceInstanceID( index ); + vg_info( "SDL_CONTROLLERDEVICEADDED | device index: %d, name: '%s'\n", + index, name ); - vg_info( " keyboard_negative: %s\n", - vg_input_to_str(bind->axis.keyboard_negative, - k_input_type_keyboard_key )); + if( is_controller ){ + vg_open_gamecontroller( index ); + } } - 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)); + else if( ev->type == SDL_CONTROLLERDEVICEREMOVED ){ + vg_info( "SDL_CONTROLLERDEVICEREMOVED | instance_id: %d\n", + ev->cdevice.which ); + + for( int i=0; ihandle ){ + if( controller->instance_id == ev->cdevice.which ){ + vg_info( " . closing controller at index #%d\n", i ); + SDL_GameControllerClose( controller->handle ); + controller->handle = NULL; + controller->instance_id = -1; + + if( vg_input.active_controller_index == i ){ + vg_input.active_controller_index = -1; + vg_input.display_input_method = k_input_method_kbm; + vg_info( "display_input: k_input_method_kbm\n" ); + } + break; + } + } + } } } -VG_STATIC void vg_apply_bind_str( struct input_binding *bind, - const char *mod, - const char *str ) +static void vg_input_controller_event( SDL_Event *ev ) { - 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 ++; - } + if( ev->type == SDL_CONTROLLERAXISMOTION ){ + for( int i=0; icaxis.which == esta->instance_id ){ + float value = (float)ev->caxis.value / 32767.0f; - 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( ev->caxis.axis == SDL_CONTROLLER_AXIS_LEFTX || + ev->caxis.axis == SDL_CONTROLLER_AXIS_LEFTY || + ev->caxis.axis == SDL_CONTROLLER_AXIS_RIGHTX || + ev->caxis.axis == SDL_CONTROLLER_AXIS_RIGHTY ) + { + float deadz = vg_clampf( controller_deadzone, 0.0f, 0.999f ), + high = vg_maxf( 0.0f, fabsf(value) - deadz ); + + value = vg_signf(value) * (high / (1.0f-deadz)); + } - 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; + esta->axises[ ev->caxis.axis ] = value; + break; + } } } - 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; + else if( ev->type == SDL_CONTROLLERBUTTONDOWN ){ + struct vg_controller *active = NULL; + + if( vg_input.active_controller_index >= 0 ) + active = &vg_input.controllers[vg_input.active_controller_index]; + + if( !active || (ev->cbutton.which != active->instance_id) ){ + active = NULL; + vg_input.active_controller_index = -1; + vg_input.display_input_method = k_input_method_kbm; + + for( int i=0; icbutton.which ){ + active = &vg_input.controllers[i]; + vg_input.active_controller_index = i; + vg_input.display_input_type = + SDL_GameControllerGetType(active->handle); + break; } - - 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; + + if( active ){ + vg_info( "Switching active controller index to #%d\n", + vg_input.active_controller_index ); + } + else{ + vg_error( "Input out of range (SDL_JoystickID#%d)\n", + ev->cbutton.which ); } } - else - { - if( type == k_input_type_gamepad_axis ) - { - bind->axis.gamepad_inverted = invert; - bind->axis.gamepad_axis = id; + + if( active ){ + if( vg_input.display_input_method != k_input_method_controller ){ + vg_input.display_input_method = k_input_method_controller; + vg_info( "display_input: k_input_method_controller\n" ); } - else - { - vg_error( "You can only bind gamepad axises to this\n" ); - return; + active->buttons[ ev->cbutton.button ] = 1; + } + } + else if( ev->type == SDL_CONTROLLERBUTTONUP ){ + for( int i=0; icbutton.which == esta->instance_id ){ + esta->buttons[ ev->cbutton.button ] = 0; + break; } } } } -/* - * 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[] ) +static void vg_process_inputs(void) { - 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]; + int count; + vg_input.sdl_keys = SDL_GetKeyboardState( &count ); + vg_input.sdl_mouse = SDL_GetMouseState(NULL,NULL); + + if( vg_input.display_input_method != k_input_method_kbm ){ + /* check for giving keyboard priority */ + for( int i=0; iname, argv[argc-1], 0 ); - } - } + vg_info( "%d: %s [controller: %d]\n", i, name, is_controller ); - else if( argc == 2 ) - { - for( int i=0; ialias, argv[argc-1], 0 ); + if( is_controller ){ + vg_open_gamecontroller( i ); } } } -VG_STATIC u8 vg_getkey( SDL_Keycode kc ) +static void vg_input_init(void) { - SDL_Scancode sc = SDL_GetScancodeFromKey( kc ); - return vg_input.sdl_keys[sc]; + vg_async_call( async_vg_input_init, NULL, 0 ); } -VG_STATIC void vg_input_update( u32 num, struct input_binding *binds ) +static void vg_input_free(void) { - if( vg_console.enabled ) - { - for( i32 i=0; itype == k_input_type_button ) - { - bind->button.prev = bind->button.value; - bind->button.value = 0; - } + if( controller->handle ){ + SDL_GameControllerClose( controller->handle ); + controller->handle = NULL; } - - return; } +} - for( i32 i=0; itype == k_input_type_button ) - { - bind->button.prev = bind->button.value; - bind->button.value = 0; +struct vg_controller *vg_active_controller(void){ + if( vg_input.active_controller_index >= 0 ) + return &vg_input.controllers[vg_input.active_controller_index]; + else + return NULL; +} - if( bind->button.gamepad_id != -1 ) - bind->button.value |= - vg_input.controller_buttons[ bind->button.gamepad_id ]; +static u8 vg_controller_button( SDL_GameControllerButton button ){ + struct vg_controller *c = vg_active_controller(); + if( c ) return c->buttons[ button ]; + else return 0; +} - if( bind->button.keyboard_id != -1 ) - bind->button.value |= vg_getkey( bind->button.keyboard_id ); - } - else if( bind->type == k_input_type_axis ) - { - float keyboard_value = 0.0f, - gamepad_value = 0.0f; +static f32 vg_controller_axis( SDL_GameControllerAxis axis ){ + struct vg_controller *c = vg_active_controller(); + if( c ) return c->axises[ axis ]; + else return 0; +} - if( bind->axis.keyboard_positive != -1 ) - if( vg_getkey( bind->axis.keyboard_positive ) ) - keyboard_value += 1.0f; +static void vg_input_apply_to_u8( vg_input_op mode, u8 data, u8 *inout_result ){ + if ( mode == vg_mode_absmax ) *inout_result |= data; + else if( mode == vg_mode_mul ) *inout_result &= data; + else vg_fatal_error( "mode not supported for destination type (%d)", mode ); +} - if( bind->axis.keyboard_negative != -1 ) - if( vg_getkey( bind->axis.keyboard_negative ) ) - keyboard_value -= 1.0f; +static void vg_input_apply_to_f32( vg_input_op mode, f32 data, + f32 *inout_result ){ + if ( mode == vg_mode_absmax ){ + if( fabsf(data) > fabsf(*inout_result) ) + *inout_result = data; + } + else if( mode == vg_mode_max ) *inout_result = vg_maxf(*inout_result,data); + else if( mode == vg_mode_mul ) *inout_result *= (f32)data; + else if( mode == vg_mode_sub ) *inout_result -= (f32)data; + else if( mode == vg_mode_add ) *inout_result += (f32)data; + else vg_fatal_error( "mode not supported for destination type (%d)", mode ); +} - if( bind->axis.gamepad_axis != -1 ) - { - gamepad_value = - vg_input.controller_axises[ bind->axis.gamepad_axis ]; +/* + * Run an input program. out_result must point to memory with sufficient + * storage respective to the size set by type. + */ +static void vg_exec_input_program( enum vg_input_type type, vg_input_op *ops, + void *out_result ){ + u8 *out_button = NULL; + f32 *out_joy = NULL; + + if( type == k_vg_input_type_button_u8 ){ + out_button = out_result; + *out_button = 0; + } + else if( type == k_vg_input_type_axis_f32 ){ + out_joy = out_result; + out_joy[0] = 0.0f; + } + else if( type == k_vg_input_type_joy_v2f ){ + out_joy = out_result; + out_joy[0] = 0.0f; + out_joy[1] = 0.0f; + } - if( bind->axis.gamepad_inverted ) - gamepad_value *= -1.0f; - } + /* computer state */ + vg_input_op mode = vg_mode_absmax; + u32 pc = 0, index = 0; - 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); +next_code:; + vg_input_op op = ops[ pc ++ ]; - gamepad_value = vg_signf( gamepad_value ) * norm; + if( (op >= vg_mode_mul) && (op <= vg_mode_max) ) + mode = op; + else if( (op == vg_keyboard) || (op == vg_mouse) || (op == vg_joy_button) ){ + u8 state = 0; - 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 = 0.0f; - if( bind->axis.keyboard_positive != -1 ) - if( vg_getkey( bind->axis.keyboard_positive )) - value = 1.0f; - - if( bind->axis.gamepad_axis != -1 ) - value = vg_maxf( value, - vg_input.controller_axises[bind->axis.gamepad_axis] ); + if( op == vg_keyboard ) + state = vg_getkey(ops[pc ++]); + else if( op == vg_mouse ) + state = (vg_input.sdl_mouse & SDL_BUTTON(ops[pc ++]))?1:0; + else + state = vg_controller_button(ops[pc ++]); - bind->axis.value = value; + if( type == k_vg_input_type_button_u8 ) + vg_input_apply_to_u8( mode, state, out_button ); + else + vg_input_apply_to_f32( mode, (f32)state, &out_joy[index] ); + } + else if( op == vg_joy_axis ){ + f32 state = vg_controller_axis( ops[pc ++] ); + if( type == k_vg_input_type_button_u8 ) + vg_input_apply_to_u8( mode, state>0.5f?1:0, out_button ); + else + vg_input_apply_to_f32( mode, state, &out_joy[index] ); + } + else if( (op == vg_joy_ls) || (op == vg_joy_rs) ){ + if( type == k_vg_input_type_joy_v2f ){ + vg_input_apply_to_f32( mode, + vg_controller_axis( op==vg_joy_ls? SDL_CONTROLLER_AXIS_LEFTX: + SDL_CONTROLLER_AXIS_RIGHTX), + &out_joy[0] ); + vg_input_apply_to_f32( mode, + vg_controller_axis( op==vg_joy_ls? SDL_CONTROLLER_AXIS_LEFTY: + SDL_CONTROLLER_AXIS_RIGHTY), + &out_joy[1] ); } } + else if( op == vg_index ) + index = ops[pc ++]; + else if( op == vg_end ) + return; + else if( op == vg_normalize ) + v2_normalize( out_joy ); + else if( op == vg_gui_visible ) + pc ++; + else + vg_fatal_error( "unknown op\n" ); + + goto next_code; } -VG_STATIC void vg_input_controller_event( SDL_Event *ev ) -{ - if( ev->type == SDL_CONTROLLERAXISMOTION ) - { - if( ev->caxis.which == vg_input.controller_joystick_id ) - { - vg_input.controller_axises[ ev->caxis.axis ] = - (float)ev->caxis.value / 32767.0f; - } - } - else if( ev->type == SDL_CONTROLLERBUTTONDOWN ) +/* + * Get vendor specific button glyphs based on SDL button ID + */ +static const char *controller_button_str( SDL_GameControllerButton button ){ + static const char *controller_glyphs[ SDL_CONTROLLER_BUTTON_MAX ][2] = { + /* xbox/generic playstation */ + [ SDL_CONTROLLER_BUTTON_A ] = { "\x1e\x85","\x1e\x82" }, + [ SDL_CONTROLLER_BUTTON_B ] = { "\x1e\x86","\x1e\x81" }, + [ SDL_CONTROLLER_BUTTON_X ] = { "\x1e\x83","\x1e\x7f" }, + [ SDL_CONTROLLER_BUTTON_Y ] = { "\x1e\x84","\x1e\x80" }, + [ SDL_CONTROLLER_BUTTON_LEFTSTICK ] = { "\x87", "\x87" }, + [ SDL_CONTROLLER_BUTTON_RIGHTSTICK ] = { "\x8b", "\x8b" }, + [ SDL_CONTROLLER_BUTTON_LEFTSHOULDER ] = { "\x91", "\x91" }, + [ SDL_CONTROLLER_BUTTON_RIGHTSHOULDER ]= { "\x92", "\x92" }, + [ SDL_CONTROLLER_BUTTON_DPAD_LEFT ] = { "\x1e\x93","\x1e\x93" }, + [ SDL_CONTROLLER_BUTTON_DPAD_UP ] = { "\x1e\x94","\x1e\x94" }, + [ SDL_CONTROLLER_BUTTON_DPAD_RIGHT ] = { "\x1e\x95","\x1e\x95" }, + [ SDL_CONTROLLER_BUTTON_DPAD_DOWN ] = { "\x1e\x96","\x1e\x96" }, + [ SDL_CONTROLLER_BUTTON_GUIDE ] = { "\x91", "\x91" }, + }; + + if( vg_input.display_input_type == SDL_CONTROLLER_TYPE_PS3 || + vg_input.display_input_type == SDL_CONTROLLER_TYPE_PS4 || + vg_input.display_input_type == SDL_CONTROLLER_TYPE_PS5 ) { - if( ev->cbutton.which == vg_input.controller_joystick_id ) - vg_input.controller_buttons[ ev->cbutton.button ] = 1; + return controller_glyphs[ button ][ 1 ]; } - else if( ev->type == SDL_CONTROLLERBUTTONUP ) + else if( vg_input.display_input_type == + SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO || + vg_input.display_input_type == + SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_LEFT || + vg_input.display_input_type == + SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_PAIR || + vg_input.display_input_type == + SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT ) { - if( ev->cbutton.which == vg_input.controller_joystick_id ) - vg_input.controller_buttons[ ev->cbutton.button ] = 0; + return NULL; } + else + return controller_glyphs[ button ][ 0 ]; } -VG_STATIC void vg_try_attach_controller(void) -{ - int joy_count = SDL_NumJoysticks(); - for( int i=0; i= SDLK_a) && (key <= SDLK_z) ){ + key = (key-SDLK_a)+(u32)'A'; + + if( special_glyphs ){ + vg_strcatch( str, '\x1f' ); + vg_strcatch( str, key ); + vg_strcatch( str, ' ' ); } + else + vg_strcatch( str, key ); + } + else if( (key == SDLK_LSHIFT) || (key == SDLK_RSHIFT) ) + vg_strcat( str, special_glyphs? "\x9e": "shift" ); + else if( (key == SDLK_LCTRL) || (key == SDLK_RCTRL) ) + vg_strcat( str, special_glyphs? "\x9f": "ctrl" ); + else if( (key == SDLK_LALT) || (key == SDLK_RALT) ) + vg_strcat( str, special_glyphs? "\xa0": "alt" ); + else if( key == SDLK_SPACE ) + vg_strcat( str, special_glyphs? "\xa1": "space" ); + else if( (key == SDLK_RETURN) || (key == SDLK_RETURN2) ) + vg_strcat( str, special_glyphs? "\xa2": "return" ); + else if( key == SDLK_ESCAPE ) + vg_strcat( str, special_glyphs? "\xa3": "escape" ); + else if( key == SDLK_RIGHT ) + vg_strcat( str, special_glyphs? "\x1f\x95 ": "right" ); + else if( key == SDLK_LEFT ) + vg_strcat( str, special_glyphs? "\x1f\x93 ": "left" ); + else if( key == SDLK_UP ) + vg_strcat( str, special_glyphs? "\x1f\x94 ": "up" ); + else if( key == SDLK_DOWN ) + vg_strcat( str, special_glyphs? "\x1f\x96 ": "down" ); + else { + vg_strcat( str, "keyboard key #" ); + vg_strcati32( str, key ); } } - -VG_STATIC void vg_update_inputs(void) -{ - vg_input.sdl_keys = SDL_GetKeyboardState(NULL); - - if( vg_input.controller_handle ) - { - if( !SDL_GameControllerGetAttached( vg_input.controller_handle ) ) - { - SDL_GameControllerClose( vg_input.controller_handle ); - vg_input.controller_handle = NULL; - } +/* + * Cat mouse button string. special_glyphs include SR glyphs + */ +static void vg_mouse_button_string( vg_str *str, u32 button, + int special_glyphs ){ + if ( button == SDL_BUTTON_LEFT ) + vg_strcat( str, special_glyphs? "\x99": "left mouse" ); + else if( button == SDL_BUTTON_RIGHT ) + vg_strcat( str, special_glyphs? "\x9a": "right mouse" ); + else if( button == SDL_BUTTON_MIDDLE ) + vg_strcat( str, special_glyphs? "\x9c": "middle mouse" ); + else{ + vg_strcat( str, "mouse button #" ); + vg_strcati32( str, button ); } +} - if( !vg_input.controller_handle ) - { - vg_input.controller_axises[ SDL_CONTROLLER_AXIS_TRIGGERLEFT ] = -1.0f; - vg_input.controller_axises[ SDL_CONTROLLER_AXIS_TRIGGERRIGHT ] = -1.0f; - vg_try_attach_controller(); +/* + * Cat string represeinting single axis + */ +static void vg_joy_axis_string( vg_str *str, + SDL_GameControllerAxis axis, int special_glyphs ){ + if( axis == SDL_CONTROLLER_AXIS_TRIGGERLEFT ) + vg_strcat( str, special_glyphs?"\x8f":"left trigger" ); + else if( axis == SDL_CONTROLLER_AXIS_TRIGGERRIGHT ) + vg_strcat( str, special_glyphs?"\x90":"right trigger" ); + else if( axis == SDL_CONTROLLER_AXIS_LEFTX ) + vg_strcat( str, special_glyphs?"\x88":"left stick horizontal" ); + else if( axis == SDL_CONTROLLER_AXIS_LEFTY ) + vg_strcat( str, special_glyphs?"\x89":"left stick vertical" ); + else if( axis == SDL_CONTROLLER_AXIS_RIGHTX ) + vg_strcat( str, special_glyphs?"\x8c":"right stick horizontal" ); + else if( axis == SDL_CONTROLLER_AXIS_RIGHTY ) + vg_strcat( str, special_glyphs?"\x8d":"right stick vertical" ); + else{ + vg_strcat( str, "axis " ); + vg_strcati32( str, axis ); } - - /* update all inputs */ - vg_input_update( vg_input.named_input_count, vg_input.named_inputs ); } -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; +/* + * Cat string represeinting whole joystick + */ +static void vg_joy_string( vg_str *str, vg_input_op op, int special_glyphs ){ + if( op == vg_joy_ls ) + vg_strcat( str, special_glyphs? "\x87": "left stick" ); + else + vg_strcat( str, special_glyphs? "\x8b": "right stick" ); } -VG_STATIC void vg_input_init(void) -{ - vg_acquire_thread_sync(); - - vg_function_push( (struct vg_cmd) - { - .name = "bind", - .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" ); - SDL_GameControllerAddMappingsFromFile( "gamecontrollerdb.txt" ); - - int joy_count = SDL_NumJoysticks(); - for( int i=0; i