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:
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;
+        }
     }
 }