Initial commit

This commit is contained in:
2024-10-11 22:21:32 +02:00
commit 1bdd01e9b2
38 changed files with 11363 additions and 0 deletions

389
input/input.jai Normal file
View File

@@ -0,0 +1,389 @@
#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);
}

260
input/sdl_input.jai Normal file
View File

@@ -0,0 +1,260 @@
key_mappings : Table(SDL_Keycode, Key_Code);
sdl_button_map : [SDL_CONTROLLER_BUTTON_MAX] Gamepad_Button;
init_sdl_input :: () {
table_add(*key_mappings, SDLK_a, .A);//[SDLK_a] = .A;
table_add(*key_mappings, SDLK_b, .B);
table_add(*key_mappings, SDLK_c, .C);
table_add(*key_mappings, SDLK_d, .D);
table_add(*key_mappings, SDLK_e, .E);
table_add(*key_mappings, SDLK_f, .F);
table_add(*key_mappings, SDLK_g, .G);
table_add(*key_mappings, SDLK_h, .H);
table_add(*key_mappings, SDLK_i, .I);
table_add(*key_mappings, SDLK_j, .J);
table_add(*key_mappings, SDLK_k, .K);
table_add(*key_mappings, SDLK_l, .L);
table_add(*key_mappings, SDLK_m, .M);
table_add(*key_mappings, SDLK_n, .N);
table_add(*key_mappings, SDLK_o, .O);
table_add(*key_mappings, SDLK_p, .P);
table_add(*key_mappings, SDLK_q, .Q);
table_add(*key_mappings, SDLK_r, .R);
table_add(*key_mappings, SDLK_s, .S);
table_add(*key_mappings, SDLK_t, .T);
table_add(*key_mappings, SDLK_u, .U);
table_add(*key_mappings, SDLK_v, .V);
table_add(*key_mappings, SDLK_w, .W);
table_add(*key_mappings, SDLK_x, .X);
table_add(*key_mappings, SDLK_y, .Y);
table_add(*key_mappings, SDLK_z, .Z);
table_add(*key_mappings, SDLK_0, .ZERO);
table_add(*key_mappings, SDLK_1, .ONE);
table_add(*key_mappings, SDLK_2, .TWO);
table_add(*key_mappings, SDLK_3, .THREE);
table_add(*key_mappings, SDLK_4, .FOUR);
table_add(*key_mappings, SDLK_5, .FIVE);
table_add(*key_mappings, SDLK_6, .SIX);
table_add(*key_mappings, SDLK_7, .SEVEN);
table_add(*key_mappings, SDLK_8, .EIGHT);
table_add(*key_mappings, SDLK_9, .NINE);
table_add(*key_mappings, SDLK_F1, .F1);
table_add(*key_mappings, SDLK_F1, .F2);
table_add(*key_mappings, SDLK_F2, .F3);
table_add(*key_mappings, SDLK_F3, .F3);
table_add(*key_mappings, SDLK_F4, .F4);
table_add(*key_mappings, SDLK_F5, .F5);
table_add(*key_mappings, SDLK_F6, .F6);
table_add(*key_mappings, SDLK_F7, .F7);
table_add(*key_mappings, SDLK_F8, .F8);
table_add(*key_mappings, SDLK_F9, .F9);
table_add(*key_mappings, SDLK_F10, .F10);
table_add(*key_mappings, SDLK_F11, .F11);
table_add(*key_mappings, SDLK_F12, .F12);
table_add(*key_mappings, SDLK_SPACE, .SPACE);
table_add(*key_mappings, SDLK_BACKSPACE, .BACKSPACE);
table_add(*key_mappings, SDLK_ESCAPE, .ESCAPE);
table_add(*key_mappings, SDLK_RETURN, .RETURN);
table_add(*key_mappings, SDLK_TAB, .TAB);
table_add(*key_mappings, SDLK_LSHIFT, .SHIFT); // @Incomplete
table_add(*key_mappings, SDLK_LCTRL, .CTRL); // @Incomplete
table_add(*key_mappings, SDLK_LALT, .ALT); // @Incomplete
table_add(*key_mappings, SDLK_DELETE, .DELETE);
table_add(*key_mappings, SDLK_BACKQUOTE, .TILDE);
table_add(*key_mappings, SDLK_LEFT, .LEFT);
table_add(*key_mappings, SDLK_RIGHT, .RIGHT);
table_add(*key_mappings, SDLK_UP, .UP);
table_add(*key_mappings, SDLK_DOWN, .DOWN);
//glfw_key_map[GLFW_MOUSE_BUTTON_LEFT] = .MOUSE_LEFT;
//glfw_key_map[GLFW_MOUSE_BUTTON_RIGHT] = .MOUSE_RIGHT;
}
update_sdl_input :: () {
event : SDL_Event;
while SDL_PollEvent(*event) {
if event.type == {
case SDL_QUIT; {
input.exit = true;
}
case SDL_KEYDOWN; {
keycode, success := table_find(*key_mappings, event.key.keysym.sym);
if success {
update_key_state(keycode, true);
}
}
case SDL_KEYUP; {
keycode, success := table_find(*key_mappings, event.key.keysym.sym);
if success {
update_key_state(keycode, false);
}
}
case SDL_TEXTINPUT; {
input.current_char = event.text.text[0];
input.has_char = true;
}
case .SDL_MOUSEMOTION; {
input.mouse.delta_x += xx event.motion.xrel;
input.mouse.delta_y += xx event.motion.yrel;
input.mouse.x = xx event.motion.x;
input.mouse.y = xx event.motion.y;
}
case .SDL_MOUSEWHEEL; {
input.mouse.wheel += event.wheel.y;
}
case .SDL_CONTROLLERAXISMOTION; {
sdl_gamepad_axis_update(event.caxis);
}
case .SDL_MOUSEBUTTONDOWN; {
button := event.button.button;
if button == SDL_BUTTON_LEFT {
update_key_state(.MOUSE_LEFT, true);
} else if button == SDL_BUTTON_RIGHT {
update_key_state(.MOUSE_RIGHT, true);
}
}
case .SDL_MOUSEBUTTONUP; {
button := event.button.button;
if button == SDL_BUTTON_LEFT {
update_key_state(.MOUSE_LEFT, false);
} else if button == SDL_BUTTON_RIGHT {
update_key_state(.MOUSE_RIGHT, false);
}
}
case SDL_CONTROLLERBUTTONDOWN; #through;
case SDL_CONTROLLERBUTTONUP; {
sdl_gamepad_button_update(event.cbutton);
}
case SDL_CONTROLLERDEVICEADDED; #through;
case SDL_CONTROLLERDEVICEREMOVED; {
sdl_gamepad_device_event(event.cdevice);
}
case SDL_CONTROLLERDEVICEREMAPPED; {
}
}
}
//mouse_x, mouse_y : s32;
//SDL_GetRelativeMouseState(*mouse_x, *mouse_y);
//input.mouse.delta_x = xx mouse_x;
//input.mouse.delta_y = xx mouse_y;
}
sdl_connect_gamepad :: (input : *Input_State, id : SDL_JoystickID) {
if !SDL_IsGameController(id) {
return;
} else if input.num_gamepads >= MAX_GAMEPADS {
return;
}
// @Incomplete: Is this necessary?
//if input.gamepads[id].controller != null {
// print("Already connected gamepad with id %\n", id);
// return;
//}
gamepad : Gamepad;
controller := xx SDL_GameControllerOpen(id);
input.gamepads[id] = gamepad;
input.num_gamepads += 1;
}
sdl_disconnect_gamepad :: (input : *Input_State, id : SDL_JoystickID) {
if !SDL_IsGameController(id) {
return;
}
gamepad := input.gamepads[id];
//if !gamepad.controller {
// return;
//}
//input.gamepads[id].controller = null;
}
update_gamepad_input :: () {
// Deadzone checks
for 0..input.num_gamepads-1 {
gamepad := *input.gamepads[it];
if abs(gamepad.left_stick_x) + abs(gamepad.left_stick_y) < LEFT_STICK_DEADZONE {
gamepad.left_stick_x = 0.0;
gamepad.left_stick_y = 0.0;
}
if abs(gamepad.right_stick_x) + abs(gamepad.right_stick_y) < RIGHT_STICK_DEADZONE {
gamepad.right_stick_x = 0.0;
gamepad.right_stick_y = 0.0;
}
}
}
sdl_gamepad_axis_update :: (using event : SDL_ControllerAxisEvent) {
if which < 0 || which >= input.num_gamepads {
return;
}
gamepad := *input.gamepads[which];
if cast(SDL_GameControllerAxis) axis == {
case SDL_CONTROLLER_AXIS_LEFTX; {
gamepad.left_stick_x = cast(float)value / 32767.0;
//update_gamepad_state(gamepad, .LEFT_STICK_LEFT, gamepad.left_stick_x < -0.1);
//update_gamepad_state(gamepad, .LEFT_STICK_RIGHT, gamepad.left_stick_x > 0.1);
}
case SDL_CONTROLLER_AXIS_LEFTY; {
gamepad.left_stick_y = cast(float)value / 32767.0;
//update_gamepad_state(gamepad, .LEFT_STICK_UP, gamepad.left_stick_y > 0.1);
//update_gamepad_state(gamepad, .LEFT_STICK_DOWN, gamepad.left_stick_y < -0.1);
}
case SDL_CONTROLLER_AXIS_RIGHTX; {
gamepad.right_stick_x = cast(float)value / 32767.0;
//update_gamepad_state(gamepad, .RIGHT_STICK_LEFT, gamepad.right_stick_x < -0.1);
//update_gamepad_state(gamepad, .RIGHT_STICK_RIGHT, gamepad.right_stick_x > 0.1);
}
case SDL_CONTROLLER_AXIS_RIGHTY; {
gamepad.right_stick_y = cast(float)value / 32767.0;
///update_gamepad_state(gamepad, .RIGHT_STICK_UP, gamepad.right_stick_y > 0.1);
///update_gamepad_state(gamepad, .RIGHT_STICK_DOWN, gamepad.right_stick_y < -0.1);
}
case SDL_CONTROLLER_AXIS_TRIGGERLEFT; {
//gamepad.trigger_left = cast(float)value;
}
case SDL_CONTROLLER_AXIS_TRIGGERRIGHT; {
//gamepad.trigger_right = cast(float)value;
}
}
}
sdl_gamepad_button_update :: (using event : SDL_ControllerButtonEvent) {
if which < 0 || which >= input.num_gamepads {
return;
}
down := state == SDL_PRESSED;
gamepad_button := sdl_button_map[button];
gamepad := *input.gamepads[which];
update_gamepad_state(gamepad, gamepad_button, down);
}
sdl_gamepad_device_event :: (using event : SDL_ControllerDeviceEvent) {
if which < 0 || which >= MAX_GAMEPADS {
return;
}
if type == {
case SDL_CONTROLLERDEVICEADDED; {
sdl_connect_gamepad(*input, which);
}
case SDL_CONTROLLERDEVICEREMOVED; {
sdl_disconnect_gamepad(*input, which);
}
}
}