summaryrefslogtreecommitdiff
path: root/src/systems/input.c
blob: c3af96aa30810a83991fcfcb5f4fe1843a30eb25 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include "input.h"

#include <assert.h>
#include <glfw3.h>
#include <string.h>

#include "keys.h"
#include "log.h"

static Input_State* g_input;  // Use a global to simplify caller code

bool Input_Init(Input_State* input, GLFWwindow* window) {
  INFO("Input init");
  memset(input, 0, sizeof(Input_State));

  input->window = window;
  // Set everything to false. Could just set memory to zero but where's the fun in that
  for (int i = KEYCODE_SPACE; i < KEYCODE_MAX; i++) {
    input->depressed_keys[i] = false;
    input->just_pressed_keys[i] = false;
    input->just_released_keys[i] = false;
  }

  g_input = input;

  assert(input->mouse.x_delta == 0);
  assert(input->mouse.y_delta == 0);

  INFO("Finish input init");
  return true;
}

void Input_Shutdown(Input_State* input) {}

void Input_Update(Input_State* input) {
  glfwPollEvents();
  // --- update keyboard input

  // if we go from un-pressed -> pressed, set as "just pressed"
  // if we go from pressed -> un-pressed, set as "just released"
  for (int i = KEYCODE_SPACE; i < KEYCODE_MAX; i++) {
    bool new_state = false;
    if (glfwGetKey(input->window, i) == GLFW_PRESS) {
      new_state = true;
    } else {
      new_state = false;
    }
    if (!input->depressed_keys[i] == false && new_state) {
      input->just_pressed_keys[i] = true;
    } else {
      input->just_pressed_keys[i] = false;
    }

    if (input->depressed_keys[i] && !new_state) {
      input->just_released_keys[i] = true;
    } else {
      input->just_released_keys[i] = false;
    }

    input->depressed_keys[i] = new_state;
  }

  // --- update mouse input

  // cursor position
  f64 current_x, current_y;
  glfwGetCursorPos(input->window, &current_x, &current_y);
  i32 quantised_cur_x = (i32)current_x;
  i32 quantised_cur_y = (i32)current_y;

  mouse_state new_mouse_state = { 0 };
  new_mouse_state.x = quantised_cur_x;
  new_mouse_state.y = quantised_cur_y;
  new_mouse_state.x_delta = quantised_cur_x - input->mouse.x;
  new_mouse_state.y_delta = quantised_cur_y - input->mouse.y;

  // buttons
  int left_state = glfwGetMouseButton(input->window, GLFW_MOUSE_BUTTON_LEFT);
  int right_state = glfwGetMouseButton(input->window, GLFW_MOUSE_BUTTON_RIGHT);

  for (int i = 0; i < 3; i++) {
    new_mouse_state.prev_pressed_states[i] = input->mouse.cur_pressed_states[i];
  }
  new_mouse_state.cur_pressed_states[MOUSEBTN_LEFT] = left_state == GLFW_PRESS;
  new_mouse_state.cur_pressed_states[MOUSEBTN_RIGHT] = right_state == GLFW_PRESS;

  // this was dumb! need to also check button state changes lol
  // if (new_mouse_state.x != input->mouse.x || new_mouse_state.y != input->mouse.y)
  // TRACE("Mouse (x,y) = (%d,%d)", input->mouse.x, input->mouse.y);

  input->mouse = new_mouse_state;
}

bool key_is_pressed(keycode key) { return g_input->depressed_keys[key]; }

bool key_just_pressed(keycode key) { return g_input->just_pressed_keys[key]; }

bool key_just_released(keycode key) { return g_input->just_released_keys[key]; }

bool MouseBtn_Held(MouseBtn btn) {
  assert(btn < 3);
  return g_input->mouse.prev_pressed_states[btn] && g_input->mouse.cur_pressed_states[btn];
}

mouse_state Input_GetMouseState() { return g_input->mouse; }