390 lines
7.5 KiB
Plaintext
390 lines
7.5 KiB
Plaintext
#load "sdl_input.jai";
|
|
|
|
LEFT_STICK_DEADZONE :: 0.239;
|
|
RIGHT_STICK_DEADZONE :: 0.265;
|
|
|
|
Key_Flags :: enum_flags u8 {
|
|
NONE :: 0;
|
|
DOWN :: 1;
|
|
START :: 2;
|
|
END :: 4;
|
|
EATEN :: 8;
|
|
}
|
|
|
|
Key_Code :: enum {
|
|
INVALID :: 0;
|
|
|
|
A;
|
|
B;
|
|
C;
|
|
D;
|
|
E;
|
|
F;
|
|
G;
|
|
H;
|
|
I;
|
|
J;
|
|
K;
|
|
L;
|
|
M;
|
|
N;
|
|
O;
|
|
P;
|
|
Q;
|
|
R;
|
|
S;
|
|
T;
|
|
U;
|
|
V;
|
|
W;
|
|
X;
|
|
Y;
|
|
Z;
|
|
|
|
ZERO;
|
|
ONE;
|
|
TWO;
|
|
THREE;
|
|
FOUR;
|
|
FIVE;
|
|
SIX;
|
|
SEVEN;
|
|
EIGHT;
|
|
NINE;
|
|
|
|
F1;
|
|
F2;
|
|
F3;
|
|
F4;
|
|
F5;
|
|
F6;
|
|
F7;
|
|
F8;
|
|
F9;
|
|
F10;
|
|
F11;
|
|
F12;
|
|
|
|
SPACE;
|
|
BACKSPACE;
|
|
RETURN;
|
|
TAB;
|
|
SHIFT;
|
|
CTRL;
|
|
ALT;
|
|
DELETE;
|
|
TILDE;
|
|
ESCAPE;
|
|
|
|
LEFT;
|
|
RIGHT;
|
|
UP;
|
|
DOWN;
|
|
|
|
MOUSE_LEFT;
|
|
MOUSE_RIGHT;
|
|
|
|
KEYS_MAX;
|
|
}
|
|
|
|
Gamepad_Button :: enum {
|
|
SPECIAL_BOTTOM;
|
|
SPECIAL_TOP;
|
|
SPECIAL_LEFT;
|
|
SPECIAL_RIGHT;
|
|
|
|
LEFT_STICK_LEFT;
|
|
LEFT_STICK_RIGHT;
|
|
LEFT_STICK_UP;
|
|
LEFT_STICK_DOWN;
|
|
|
|
LEFT_STICK_BUTTON;
|
|
RIGHT_STICK_BUTTON;
|
|
|
|
DPAD_LEFT;
|
|
DPAD_RIGHT;
|
|
DPAD_UP;
|
|
DPAD_DOWN;
|
|
|
|
LEFT_BUMPER;
|
|
RIGHT_BUMPER;
|
|
|
|
LEFT_TRIGGER;
|
|
RIGHT_TRIGGER;
|
|
|
|
GAMEPAD_MAX;
|
|
}
|
|
|
|
Gamepad :: struct {
|
|
id : s32;
|
|
left_stick_x : float;
|
|
left_stick_y : float;
|
|
right_stick_x : float;
|
|
right_stick_y : float;
|
|
|
|
buttons : [Gamepad_Button.GAMEPAD_MAX] Key_Flags;
|
|
}
|
|
|
|
MAX_GAMEPADS :: 4;
|
|
MAX_MAPPINGS :: 4;
|
|
|
|
Action :: enum {}
|
|
|
|
Action_Mapping :: struct {
|
|
gamepad_buttons: [MAX_MAPPINGS] Gamepad_Button;
|
|
keys: [MAX_MAPPINGS] Key_Code;
|
|
gamepad_mapping_count: s32;
|
|
key_mapping_count: s32;
|
|
}
|
|
|
|
Last_Touched_State :: enum {
|
|
KEYBOARD_AND_MOUSE;
|
|
GAMEPAD;
|
|
}
|
|
|
|
Input_State :: struct {
|
|
exit : bool;
|
|
action_mappings: [..] Action_Mapping;
|
|
|
|
keys: [Key_Code.KEYS_MAX] Key_Flags;
|
|
|
|
mouse : struct {
|
|
x : float;
|
|
y : float;
|
|
delta_x : float;
|
|
delta_y : float;
|
|
first: bool = true;
|
|
wheel: float;
|
|
}
|
|
|
|
gamepads: [MAX_GAMEPADS] Gamepad;
|
|
num_gamepads: s32;
|
|
|
|
has_char : bool;
|
|
current_char: s8;
|
|
|
|
last_touched: Last_Touched_State;
|
|
}
|
|
|
|
input : Input_State;
|
|
|
|
init_input :: () {
|
|
input = .{};
|
|
input.has_char = false;
|
|
|
|
init_sdl_input();
|
|
}
|
|
|
|
update_key_state :: (key: Key_Code, down: bool) {
|
|
using input;
|
|
flags := keys[key];
|
|
|
|
if down {
|
|
if !(flags & Key_Flags.DOWN) {
|
|
flags = Key_Flags.DOWN | Key_Flags.START;
|
|
}
|
|
} else {
|
|
flags = Key_Flags.END;
|
|
}
|
|
|
|
keys[key] = flags;
|
|
|
|
input.last_touched = .KEYBOARD_AND_MOUSE;
|
|
}
|
|
|
|
update_gamepad_state :: (gamepad: *Gamepad, button: Gamepad_Button, down: bool) {
|
|
flags := gamepad.buttons[button];
|
|
|
|
if down {
|
|
if !(flags & Key_Flags.DOWN) {
|
|
flags = Key_Flags.DOWN | Key_Flags.START;
|
|
input.last_touched = .GAMEPAD;
|
|
}
|
|
} else if flags & Key_Flags.DOWN {
|
|
flags = Key_Flags.END;
|
|
}
|
|
|
|
gamepad.buttons[button] = flags;
|
|
|
|
}
|
|
|
|
update_input :: () {
|
|
input.mouse.delta_x = 0.0;
|
|
input.mouse.delta_y = 0.0;
|
|
input.mouse.wheel = 0.0;
|
|
input.has_char = false;
|
|
remove_all_temp_key_flags(*input);
|
|
|
|
update_sdl_input();
|
|
|
|
update_gamepad_input();
|
|
}
|
|
|
|
remove_all_temp_key_flags :: (using input_state: *Input_State) {
|
|
for 0..Key_Code.KEYS_MAX - 1 {
|
|
keys[it] &= ~Key_Flags.START;
|
|
keys[it] &= ~Key_Flags.END;
|
|
keys[it] &= ~Key_Flags.EATEN;
|
|
}
|
|
|
|
for g: 0..num_gamepads-1 {
|
|
for 0..Gamepad_Button.GAMEPAD_MAX-1 {
|
|
gamepads[g].buttons[it] &= ~Key_Flags.START;
|
|
gamepads[g].buttons[it] &= ~Key_Flags.END;
|
|
}
|
|
}
|
|
}
|
|
|
|
eat_all_input :: (using input_state: *Input_State) {
|
|
for 0..Key_Code.KEYS_MAX - 1 {
|
|
eat_key(cast(Key_Code)it);
|
|
}
|
|
}
|
|
|
|
eat_mouse_input :: (using input_state: *Input_State) {
|
|
eat_key(.MOUSE_LEFT);
|
|
eat_key(.MOUSE_RIGHT);
|
|
}
|
|
|
|
eat_key :: (key: Key_Code) {
|
|
input.keys[key] |= Key_Flags.EATEN;
|
|
}
|
|
|
|
action_down :: (action: Action) -> bool {
|
|
mapping := input.action_mappings[action];
|
|
for 0..mapping.key_mapping_count-1 {
|
|
if key_down(mapping.keys[it]) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
for 0..mapping.gamepad_mapping_count-1 {
|
|
if gamepad_down(0, mapping.gamepad_buttons[it]) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
action_pressed :: (action: Action) -> bool {
|
|
mapping := input.action_mappings[action];
|
|
for 0..mapping.key_mapping_count-1 {
|
|
if key_pressed(mapping.keys[it]) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
for 0..mapping.gamepad_mapping_count-1 {
|
|
if gamepad_pressed(0, mapping.gamepad_buttons[it]) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
action_up :: (action: Action) -> bool {
|
|
mapping := input.action_mappings[action];
|
|
for 0..mapping.key_mapping_count-1 {
|
|
if key_up(mapping.keys[it]) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
for 0..mapping.gamepad_mapping_count-1 {
|
|
if gamepad_up(0, mapping.gamepad_buttons[it]) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
get_mouse_delta_x :: inline () -> float {
|
|
return input.mouse.delta_x;
|
|
}
|
|
|
|
get_mouse_delta_y :: inline () -> float {
|
|
return input.mouse.delta_y;
|
|
}
|
|
|
|
get_mouse_delta :: () -> float, float {
|
|
return get_mouse_delta_x(), get_mouse_delta_y();
|
|
}
|
|
|
|
get_mouse_wheel_input :: () -> float {
|
|
return input.mouse.wheel;
|
|
}
|
|
|
|
get_horizontal_axis :: () -> float {
|
|
if #complete input.last_touched == {
|
|
case .KEYBOARD_AND_MOUSE;
|
|
if key_pressed(.A) || key_pressed(.LEFT) return -1.0;
|
|
else if key_pressed(.D) || key_pressed(.RIGHT) return 1.0;
|
|
else return 0.0;
|
|
case .GAMEPAD;
|
|
if gamepad_pressed(0, .DPAD_LEFT) return -1.0;
|
|
else if gamepad_pressed(0, .DPAD_RIGHT) return 1.0;
|
|
return input.gamepads[0].left_stick_x;
|
|
}
|
|
}
|
|
|
|
get_vertical_axis :: () -> float {
|
|
if #complete input.last_touched == {
|
|
case .KEYBOARD_AND_MOUSE;
|
|
if key_pressed(.S) || key_pressed(.DOWN) return -1.0;
|
|
else if key_pressed(.W) || key_pressed(.UP) return 1.0;
|
|
else return 0.0;
|
|
case .GAMEPAD;
|
|
if gamepad_pressed(0, .DPAD_DOWN) return -1.0;
|
|
else if gamepad_pressed(0, .DPAD_UP) return 1.0;
|
|
return -input.gamepads[0].left_stick_y;
|
|
}
|
|
}
|
|
|
|
get_right_horizontal_axis :: () -> float {
|
|
if #complete input.last_touched == {
|
|
case .KEYBOARD_AND_MOUSE;
|
|
return input.mouse.delta_x;
|
|
case .GAMEPAD;
|
|
return input.gamepads[0].right_stick_x;
|
|
}
|
|
}
|
|
|
|
get_right_vertical_axis :: () -> float {
|
|
if #complete input.last_touched == {
|
|
case .KEYBOARD_AND_MOUSE;
|
|
return input.mouse.delta_y;
|
|
case .GAMEPAD;
|
|
return -input.gamepads[0].right_stick_y;
|
|
}
|
|
}
|
|
|
|
key_down :: (key: Key_Code) -> bool {
|
|
flags := input.keys[key];
|
|
return flags & .START && !(flags & .EATEN);
|
|
}
|
|
|
|
key_pressed :: (key: Key_Code) -> bool {
|
|
flags := input.keys[key];
|
|
return flags & .DOWN && !(flags & .EATEN);
|
|
}
|
|
|
|
key_up :: (key: Key_Code) -> bool {
|
|
flags := input.keys[key];
|
|
return flags & .END && !(flags & .EATEN);
|
|
}
|
|
|
|
gamepad_down :: (index: s32, button: Gamepad_Button) -> bool {
|
|
return cast(bool)(input.gamepads[index].buttons[button] & .START);
|
|
}
|
|
|
|
gamepad_pressed :: (index: s32, button: Gamepad_Button) -> bool {
|
|
return cast(bool)(input.gamepads[index].buttons[button] & .DOWN);
|
|
}
|
|
|
|
gamepad_up :: (index: s32, button: Gamepad_Button) -> bool {
|
|
return cast(bool)(input.gamepads[index].buttons[button] & .END);
|
|
}
|