a-game

2D platformer written from scratch.
git clone git://git.amin.space/a-game.git
Log | Files | Refs | README | LICENSE

commit df5aadc9e21983da65064fc5db5d2d8eaf5b9fce
parent 73a03d9d40cdd393a8d70d493de5869ccf43da6e
Author: amin <dev@aminmesbah.com>
Date:   Mon,  1 Jul 2019 00:43:04 +0000

Store more information about button inputs

FossilOrigin-Name: 714ed8a50df25d27e7588969eb6a0f0c0ab98572583192a8311acfe58e272a74
Diffstat:
Msrc/game.c | 28++++++++++++++++++++++------
Msrc/platform.h | 25++++++++++++++++---------
Msrc/platform_linux.c | 79++++++++++++++++++++++++++++++++++++-------------------------------------------
3 files changed, 74 insertions(+), 58 deletions(-)

diff --git a/src/game.c b/src/game.c @@ -6,6 +6,13 @@ #include "render.c" #include "world.c" +internal bool btn_is_down(u32 button_states, enum GameButton b) +{ + assert(b < NUM_GAME_BUTTONS); + bool result = button_states & (1 << b); + return result; +} + internal void move_state_print(enum MoveState s) { switch(s) @@ -228,11 +235,20 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga assert(current_room); assert(math_v2i_eq(current_room_i, current_room->index)); + // game_update_input + { + u32 button_changes = game_input->prev_button_states ^ game_input->button_states; + game_input->button_ups = button_changes & (~game_input->button_states); + game_input->button_downs = button_changes & game_input->button_states; + game_input->prev_button_states = game_input->button_states; + } + // game_update_player { struct Entity *player = &game_state->player; move_state_print(player->move_state); f32 dt = game_input->dt; + u32 button_states = game_input->button_states; if (dt >= 0.5f) { // NOTE(amin): If our dt is 0.5 seconds, we've probably been @@ -247,12 +263,12 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga f32 friction = 0.7f; enum Direction previous_facing_dir = player->facing; - if (game_input->key_left) + if (btn_is_down(button_states, BTN_LEFT)) { player->facing = DIR_LEFT; player->acceleration.x = -acceleration_rate; } - else if (game_input->key_right) + else if (btn_is_down(button_states, BTN_RIGHT)) { player->facing = DIR_RIGHT; player->acceleration.x = acceleration_rate; @@ -275,7 +291,7 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga if(entity_is_adjacent_to_solid_tiles(game_state->world, player->pos, player_rect, DIR_DOWN)) { player->acceleration.y = 0.0f; - if (game_input->key_jump) + if (btn_is_down(button_states, BTN_JUMP)) { player->acceleration.y = acceleration_rate; player->move_state = MOVE_STATE_JUMPING; @@ -290,11 +306,11 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga if (player->facing == previous_facing_dir && entity_is_adjacent_to_solid_tiles(game_state->world, player->pos, player_rect, player->facing)) { - if (game_input->key_up) + if (btn_is_down(button_states, BTN_UP)) { player->acceleration.y = acceleration_rate; } - else if (game_input->key_down) + else if (btn_is_down(button_states, BTN_DOWN)) { player->acceleration.y = -acceleration_rate; } @@ -312,7 +328,7 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga { // TODO: give this a real timer bool jump_timed_out = false; - if (!jump_timed_out && game_input->key_jump) + if (!jump_timed_out && btn_is_down(button_states, BTN_JUMP)) { player->acceleration.y = acceleration_rate; player->move_state = MOVE_STATE_JUMPING; diff --git a/src/platform.h b/src/platform.h @@ -7,21 +7,28 @@ #define KIBIBYTES(n) (n) * 1024LL #define MEBIBYTES(n) KIBIBYTES((n) * 1024LL) -enum InputKeyAction +enum GameButton { - KEY_RELEASE, - KEY_PRESS, - KEY_REPEAT, + BTN_LEFT, + BTN_RIGHT, + BTN_UP, + BTN_DOWN, + BTN_JUMP, + + NUM_GAME_BUTTONS, + NULL_GAME_BUTTON, }; +// TODO: define static assert without string arg +static_assert(NUM_GAME_BUTTONS <= 32, ""); + struct GameInput { f32 dt; - enum InputKeyAction key_left; - enum InputKeyAction key_right; - enum InputKeyAction key_up; - enum InputKeyAction key_down; - enum InputKeyAction key_jump; + u32 button_states; + u32 prev_button_states; + u32 button_ups; + u32 button_downs; }; #define PLATFORM_READ_ENTIRE_FILE(name) char *(name)(char *file_path) diff --git a/src/platform_linux.c b/src/platform_linux.c @@ -10,6 +10,15 @@ #include "platform.h" #include "platform_linux.h" +// TODO: map this in a nicer way +global_variable int platform_input_map[NUM_GAME_BUTTONS] = { + [BTN_LEFT] = GLFW_KEY_LEFT, + [BTN_RIGHT] = GLFW_KEY_RIGHT, + [BTN_UP] = GLFW_KEY_UP, + [BTN_DOWN] = GLFW_KEY_DOWN, + [BTN_JUMP] = GLFW_KEY_S, +}; + int main(void) { glfwSetErrorCallback(error_callback); @@ -132,62 +141,46 @@ int main(void) return 0; } -internal void error_callback(int error, const char* description) +internal void error_callback(int error, const char *description) { fprintf(stderr, "Error: %s\n", description); } -internal void framebuffer_size_callback(GLFWwindow* window, int width, int height) +internal void framebuffer_size_callback(GLFWwindow *window, int width, int height) { glViewport(0, 0, width, height); } -internal void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +internal void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods) { - struct GameInput *game_input = (struct GameInput*)glfwGetWindowUserPointer(window); + struct GameInput *game_input = (struct GameInput *)glfwGetWindowUserPointer(window); - enum InputKeyAction game_input_key_action = 0; - switch (action) + enum GameButton game_button = NULL_GAME_BUTTON; + // TODO: Determine the button in a nicer way + for (enum GameButton b = 0; b < NUM_GAME_BUTTONS; b++) { - case GLFW_PRESS: - game_input_key_action = KEY_PRESS; - break; - case GLFW_RELEASE: - game_input_key_action = KEY_RELEASE; - break; - case GLFW_REPEAT: - game_input_key_action = KEY_REPEAT; - break; - default: - exit(1); - break; - } - - enum InputKeyAction* game_key = NULL; - switch (key) - { - case GLFW_KEY_LEFT: - game_key = &(game_input->key_left); - break; - case GLFW_KEY_RIGHT: - game_key = &(game_input->key_right); - break; - case GLFW_KEY_UP: - game_key = &(game_input->key_up); - break; - case GLFW_KEY_DOWN: - game_key = &(game_input->key_down); - break; - case GLFW_KEY_S: - game_key = &(game_input->key_jump); - break; - default: - break; + if (platform_input_map[b] == key) + { + game_button = b; + } } - - if (game_key) + if (game_button != NULL_GAME_BUTTON) { - *game_key = game_input_key_action; + switch (action) + { + case GLFW_PRESS: + game_input->button_states |= (1 << game_button); + break; + case GLFW_RELEASE: + game_input->button_states &= ~(1 << game_button); + break; + case GLFW_REPEAT: + // Do nothing + break; + default: + exit(1); + break; + } } }