Gamepad stuff (forgot to commit this file before)

This commit is contained in:
Charlie Malmqvist 2024-08-19 14:08:50 +02:00
parent f8ef5dd8b3
commit a8ded88dca

View file

@ -2,31 +2,68 @@
Main input juice:
bool is_key_down(Input_Key_Code code);
bool is_key_up(Input_Key_Code code);
bool is_key_just_pressed(Input_Key_Code code);
bool is_key_just_released(Input_Key_Code code);
bool consume_key_down(Input_Key_Code code);
bool consume_key_just_pressed(Input_Key_Code code);
bool consume_key_just_released(Input_Key_Code code);
// To loop through events this frame
for (u64 i = 0; i < input_frame.number_of_events; i++) {
Input_Event e = input_frame.events[i];
bool is_key_down(Input_Key_Code code)
bool is_key_up(Input_Key_Code code)
bool is_key_just_pressed(Input_Key_Code code)
bool is_key_just_released(Input_Key_Code code)
switch (e.kind) {
case INPUT_EVENT_KEY: ...; break;
case INPUT_EVENT_SCROLL: ...; break;
case INPUT_EVENT_TEXT: ...; break;
bool consume_key_down(Input_Key_Code code)
bool consume_key_just_pressed(Input_Key_Code code)
bool consume_key_just_released(Input_Key_Code code)
To loop through events this frame:
for (u64 i = 0; i < input_frame.number_of_events; i++) {
Input_Event e = input_frame.events[i];
switch (e.kind) {
case INPUT_EVENT_KEY: ...; break;
case INPUT_EVENT_SCROLL: ...; break;
case INPUT_EVENT_TEXT: ...; break;
case INPUT_EVENT_GAMEPAD_AXIS: ...; break;
}
}
}
Gamepad input:
Vector2 input_frame.left_stick
Vector2 input_frame.right_stick
float32 input_frame.left_trigger
float32 input_frame.right_trigger
Gamepad buttons are treated as regular keys.
Example:
is_key_just_pressed(GAMEPAD_A);
is_key_down(GAMEPAD_DPAD_LEFT);
To handle multiple gamepads, you need to poll input events and use the event.gamepad_index.
For gamepad buttons: INPUT_EVENT_KEY
For gamepad axes: INPUT_EVENT_GAMEPAD_AXIS
Set axis deadzones with global variables:
Vector2 deadzone_left_stick
Vector2 deadzone_right_stick
float32 deadzone_left_trigger
float32 deadzone_right_trigger
Set vibration with:
set_gamepad_vibration(float32 left, float32 right)
set_specific_gamepad_vibration(int gamepad_index, float32 left, float32 right)
see input_example.c for example code in practice
*/
// #Global
forward_global const u64 MAX_NUMBER_OF_GAMEPADS; // Defined in os layer
typedef enum Input_Event_Kind {
INPUT_EVENT_KEY,
INPUT_EVENT_SCROLL,
INPUT_EVENT_TEXT,
INPUT_EVENT_GAMEPAD_AXIS,
} Input_Event_Kind;
typedef enum Input_Key_Code {
@ -83,10 +120,34 @@ typedef enum Input_Key_Code {
KEY_PRINT_SCREEN,
GAMEPAD_DPAD_UP,
GAMEPAD_DPAD_RIGHT,
GAMEPAD_DPAD_DOWN,
GAMEPAD_DPAD_LEFT,
GAMEPAD_A,
GAMEPAD_X,
GAMEPAD_Y,
GAMEPAD_B,
GAMEPAD_START,
GAMEPAD_BACK,
GAMEPAD_LEFT_STICK,
GAMEPAD_RIGHT_STICK,
GAMEPAD_LEFT_BUMPER,
GAMEPAD_RIGHT_BUMPER,
GAMEPAD_LEFT_TRIGGER,
GAMEPAD_RIGHT_TRIGGER,
MOUSE_BUTTON_LEFT,
MOUSE_BUTTON_MIDDLE,
MOUSE_BUTTON_RIGHT,
GAMEPAD_FIRST = GAMEPAD_START,
GAMEPAD_LAST = GAMEPAD_RIGHT_TRIGGER,
MOUSE_FIRST = MOUSE_BUTTON_LEFT,
MOUSE_LAST = MOUSE_BUTTON_RIGHT,
@ -100,12 +161,21 @@ typedef enum Input_State_Flags {
INPUT_STATE_REPEAT = 1<<3,
} Input_State_Flags;
typedef enum Input_Axis_Flags {
INPUT_AXIS_LEFT_STICK = 1<<0,
INPUT_AXIS_RIGHT_STICK = 1<<1,
INPUT_AXIS_LEFT_TRIGGER = 1<<2,
INPUT_AXIS_RIGHT_TRIGGER = 1<<3,
} Input_Axis_Flags;
typedef struct Input_Event {
Input_Event_Kind kind;
// For INPUT_EVENT_KEY
Input_Key_Code key_code;
Input_State_Flags key_state;
// Also for INPUT_EVENT_GAMEPAD_AXIS
s64 gamepad_index; // -1 if key is not from a gamepad
// For INPUT_EVENT_SCROLL
float64 xscroll;
@ -114,6 +184,14 @@ typedef struct Input_Event {
// For INPUT_EVENT_TEXT_INPUT
union { u32 utf32; char ascii; };
// For INPUT_EVENT_GAMEPAD_AXIS
// Only the changed axes have valid values
Input_Axis_Flags axes_changed;
Vector2 left_stick;
Vector2 right_stick;
float32 left_trigger;
float32 right_trigger;
} Input_Event;
Input_Key_Code os_key_to_key_code(void* os_key);
@ -127,17 +205,36 @@ typedef struct Input_Frame {
float32 mouse_x;
float32 mouse_y;
// Gamepad
// If you need to deal with more than 1 gamepad, use INPUT_EVENT_GAMEPAD_AXIS
Vector2 left_stick;
Vector2 right_stick;
float32 left_trigger;
float32 right_trigger;
Input_State_Flags key_states[INPUT_KEY_CODE_COUNT];
} Input_Frame;
// #Global
ogb_instance Input_Frame input_frame;
ogb_instance Vector2 deadzone_left_stick;
ogb_instance Vector2 deadzone_right_stick;
ogb_instance float32 deadzone_left_trigger;
ogb_instance float32 deadzone_right_trigger;
#if !OOGABOOGA_LINK_EXTERNAL_INSTANCE
Input_Frame input_frame = ZERO(Input_Frame);
Vector2 deadzone_left_stick = {0.2, 0.2};
Vector2 deadzone_right_stick = {0.2, 0.2};
float32 deadzone_left_trigger = {0.07};
float32 deadzone_right_trigger = {0.07};
#endif
// 0.0 for no vibration, 1.0 for max vibration
void set_gamepad_vibration(float32 left, float32 right);
void set_specific_gamepad_vibration(u64 gamepad_index, float32 left, float32 right);
bool has_key_state(Input_Key_Code code, Input_State_Flags flags) {
assert(code > 0 && code < INPUT_KEY_CODE_COUNT, "Invalid key code %d!", code);
Input_State_Flags state = input_frame.key_states[code];