A 3D game engine from scratch.
at main 273 lines 6.1 kB view raw
1// (c) 2020 Vlad-Stefan Harbuz <vlad@vladh.net> 2 3#include "../src_external/pstr.h" 4#include "logs.hpp" 5#include "input.hpp" 6 7 8input::State *input::state = nullptr; 9 10 11char * 12input::get_text_input() 13{ 14 return input::state->text_input; 15} 16 17 18bool 19input::is_cursor_enabled() 20{ 21 return input::state->is_cursor_enabled; 22} 23 24 25void 26input::set_is_cursor_enabled(bool val) 27{ 28 input::state->is_cursor_enabled = val; 29} 30 31 32bool 33input::is_text_input_enabled() 34{ 35 return input::state->is_text_input_enabled; 36} 37 38 39v2 40input::get_mouse_offset() 41{ 42 return input::state->mouse_offset; 43} 44 45 46v2 47input::get_mouse_3d_offset() 48{ 49 return input::state->mouse_3d_offset; 50} 51 52 53void 54input::update_mouse_button(int button, int action, int mods) 55{ 56 bool new_state = (action == GLFW_PRESS); 57 if (new_state != input::state->mouse_button_states[button]) { 58 input::state->mouse_button_states[button] = new_state; 59 input::state->n_mouse_button_state_changes_this_frame[button]++; 60 } 61} 62 63 64bool 65input::is_mouse_button_down(int button) 66{ 67 return input::state->mouse_button_states[button]; 68} 69 70 71bool 72input::is_mouse_button_up(int button) 73{ 74 return !is_mouse_button_down(button); 75} 76 77 78bool 79input::is_mouse_button_now_down(int button) 80{ 81 return is_mouse_button_down(button) && 82 input::state->n_mouse_button_state_changes_this_frame[button] > 0; 83} 84 85 86bool 87input::is_mouse_button_now_up(int button) 88{ 89 return is_mouse_button_up(button) && 90 input::state->n_mouse_button_state_changes_this_frame[button] > 0; 91} 92 93 94void 95input::update_mouse(v2 new_mouse_pos) 96{ 97 if (!input::state->have_ever_gotten_mouse_pos) { 98 input::state->mouse_pos = new_mouse_pos; 99 input::state->have_ever_gotten_mouse_pos = true; 100 } 101 102 input::state->mouse_offset = new_mouse_pos - input::state->mouse_pos; 103 input::state->mouse_3d_offset = 104 input::state->mouse_offset * (f32)input::state->mouse_3d_sensitivity; 105 input::state->mouse_pos = new_mouse_pos; 106} 107 108 109void 110input::clear_text_input() 111{ 112 pstr_clear(input::state->text_input); 113} 114 115 116void 117input::enable_text_input() 118{ 119 input::state->is_text_input_enabled = true; 120 clear_text_input(); 121} 122 123 124void 125input::disable_text_input() 126{ 127 input::state->is_text_input_enabled = false; 128 clear_text_input(); 129} 130 131 132void 133input::do_text_input_backspace() 134{ 135 size_t text_input_length = strlen(input::state->text_input); 136 if (text_input_length == 0) { 137 return; 138 } 139 input::state->text_input[text_input_length - 1] = '\0'; 140} 141 142 143void 144input::update_text_input(u32 codepoint) 145{ 146 if (!input::state->is_text_input_enabled) { 147 return; 148 } 149 char poor_smashed_ascii_character = (char)codepoint; 150 size_t text_input_length = strlen(input::state->text_input); 151 152 if (text_input_length + 1 >= MAX_TEXT_INPUT_LENGTH - 1) { 153 logs::error("Can't add another character to text_input, it's full."); 154 return; 155 } 156 157 input::state->text_input[text_input_length] = poor_smashed_ascii_character; 158 input::state->text_input[text_input_length + 1] = '\0'; 159} 160 161 162void 163input::update_keys(int key, int scancode, int action, int mods) 164{ 165 bool new_state = (action == GLFW_PRESS || action == GLFW_REPEAT); 166 if (new_state != input::state->key_states[key]) { 167 input::state->key_states[key] = new_state; 168 input::state->n_key_state_changes_this_frame[key]++; 169 } 170} 171 172 173bool 174input::is_key_down(int key) 175{ 176 return input::state->key_states[key]; 177} 178 179 180bool 181input::is_key_up(int key) 182{ 183 return !is_key_down(key); 184} 185 186 187bool 188input::is_key_now_down(int key) 189{ 190 return is_key_down(key) && input::state->n_key_state_changes_this_frame[key] > 0; 191} 192 193 194bool 195input::is_key_now_up(int key) 196{ 197 return is_key_up(key) && input::state->n_key_state_changes_this_frame[key] > 0; 198} 199 200 201bool 202input::is_mouse_in_bb(v2 topleft, v2 bottomright) 203{ 204 return input::state->mouse_pos.x > topleft.x && 205 input::state->mouse_pos.x < bottomright.x && 206 input::state->mouse_pos.y > topleft.y && 207 input::state->mouse_pos.y < bottomright.y; 208} 209 210 211void 212input::set_cursor(GLFWcursor *new_cursor) 213{ 214 if (input::state->current_cursor == new_cursor) { 215 return; 216 } 217 input::state->current_cursor = new_cursor; 218 glfwSetCursor(input::state->window, new_cursor); 219} 220 221 222void 223input::set_cursor(CursorType type) 224{ 225 if (type == input::CursorType::none) { 226 return; 227 } else if (type == input::CursorType::arrow) { 228 set_cursor(input::state->arrow_cursor); 229 } else if (type == input::CursorType::ibeam) { 230 set_cursor(input::state->ibeam_cursor); 231 } else if (type == input::CursorType::crosshair) { 232 set_cursor(input::state->crosshair_cursor); 233 } else if (type == input::CursorType::hand) { 234 set_cursor(input::state->hand_cursor); 235 } else if (type == input::CursorType::hresize) { 236 set_cursor(input::state->hresize_cursor); 237 } else if (type == input::CursorType::vresize) { 238 set_cursor(input::state->vresize_cursor); 239 } else { 240 logs::fatal("Unknown cursor type"); 241 } 242} 243 244 245void 246input::reset_n_mouse_button_state_changes_this_frame() 247{ 248 memset(input::state->n_mouse_button_state_changes_this_frame, 249 0, sizeof(input::state->n_mouse_button_state_changes_this_frame)); 250} 251 252 253void 254input::reset_n_key_state_changes_this_frame() 255{ 256 memset(input::state->n_key_state_changes_this_frame, 257 0, sizeof(input::state->n_key_state_changes_this_frame)); 258} 259 260 261void 262input::init(input::State *input_state, GLFWwindow *window) 263{ 264 input::state = input_state; 265 input::state->window = window; 266 input::state->mouse_3d_sensitivity = 0.1f; 267 input::state->arrow_cursor = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); 268 input::state->ibeam_cursor = glfwCreateStandardCursor(GLFW_IBEAM_CURSOR); 269 input::state->crosshair_cursor = glfwCreateStandardCursor(GLFW_CROSSHAIR_CURSOR); 270 input::state->hand_cursor = glfwCreateStandardCursor(GLFW_HAND_CURSOR); 271 input::state->hresize_cursor = glfwCreateStandardCursor(GLFW_HRESIZE_CURSOR); 272 input::state->vresize_cursor = glfwCreateStandardCursor(GLFW_VRESIZE_CURSOR); 273}