+ 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));
+ }