]> git.lizzy.rs Git - dragonblocks_alpha.git/blobdiff - src/client/input.c
refactoring
[dragonblocks_alpha.git] / src / client / input.c
index a862017d801b33c2aab1550c3e9701319006ffde..e9b154c32808fb39b10b5bd75353e82f4e4365ea 100644 (file)
@@ -1,3 +1,4 @@
+#include <asprintf/asprintf.h>
 #include <math.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include "client/input.h"
 #include "client/window.h"
 #include "day.h"
-#include "util.h"
 
-typedef struct
-{
+typedef struct {
        int key;
-       bool was_pressed;
-       bool fired;
+       bool state;
 } KeyListener;
 
-static struct
-{
-       GUIElement *pause_menu;
-       GUIElement *status_message;
-       bool paused;
-       KeyListener pause_listener;
-       KeyListener fullscreen_listener;
-       KeyListener fly_listener;
-       KeyListener collision_listener;
-       KeyListener timelapse_listener;
-       KeyListener debug_menu_listener;
-       KeyListener screenshot_listener;
-} input;
-
-void input_on_cursor_pos(double current_x, double current_y)
-{
-       if (input.paused)
-               return;
-
-       static double last_x, last_y = 0.0;
+static bool paused = false;
 
-       double delta_x = current_x - last_x;
-       double delta_y = current_y - last_y;
-       last_x = current_x;
-       last_y = current_y;
+static GUIElement *pause_menu;
+static GUIElement *status_message;
 
-       client_player.yaw += (f32) delta_x * M_PI / 180.0f / 8.0f;
-       client_player.pitch -= (f32) delta_y * M_PI / 180.0f / 8.0f;
+static KeyListener listener_pause      = {GLFW_KEY_ESCAPE, false};
+static KeyListener listener_fullscreen = {GLFW_KEY_F11,    false};
+static KeyListener listener_fly        = {GLFW_KEY_F,      false};
+static KeyListener listener_collision  = {GLFW_KEY_C,      false};
+static KeyListener listener_timelapse  = {GLFW_KEY_T,      false};
+static KeyListener listener_debug_menu = {GLFW_KEY_F3,     false};
+static KeyListener listener_screenshot = {GLFW_KEY_F2,     false};
 
-       client_player.yaw = fmod(client_player.yaw + M_PI * 2.0f, M_PI * 2.0f);
-       client_player.pitch = f32_clamp(client_player.pitch, -M_PI / 2.0f + 0.01f, M_PI / 2.0f - 0.01f);
-
-       camera_set_angle(client_player.yaw, client_player.pitch);
-
-       debug_menu_update_yaw();
-       debug_menu_update_pitch();
-}
+static double cursor_last_x = 0.0;
+static double cursor_last_y = 0.0;
 
+// movement mutex needs to be locked
 static bool move(int forward, int backward, vec3 dir)
 {
-       f64 sign;
-       f64 speed = client_player.fly ? 25.0f : 4.317f;
+       // 25.0f; 4.317f
+       f32 sign;
 
        if (glfwGetKey(window.handle, forward) == GLFW_PRESS)
                sign = +1.0f;
@@ -69,9 +46,9 @@ static bool move(int forward, int backward, vec3 dir)
        else
                return false;
 
-       client_player.velocity.x += dir[0] * speed * sign;
-       client_player.velocity.y += dir[1] * speed * sign;
-       client_player.velocity.z += dir[2] * speed * sign;
+       client_player.velocity.x += dir[0] * client_player.movement.speed * sign;
+       client_player.velocity.y += dir[1] * client_player.movement.speed * sign;
+       client_player.velocity.z += dir[2] * client_player.movement.speed * sign;
 
        return true;
 }
@@ -79,156 +56,174 @@ static bool move(int forward, int backward, vec3 dir)
 static void enter_game()
 {
        glfwSetInputMode(window.handle, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
-       input.pause_menu->visible = false;
+       pause_menu->visible = false;
 }
 
-static void do_key_listener(KeyListener *listener)
+static bool key_listener(KeyListener *listener)
 {
-       bool is_pressed = glfwGetKey(window.handle, listener->key) == GLFW_PRESS;
-       listener->fired = listener->was_pressed && ! is_pressed;
-       listener->was_pressed = is_pressed;
+       bool was = listener->state;
+       return !(listener->state = (glfwGetKey(window.handle, listener->key) == GLFW_PRESS)) && was;
 }
 
-static KeyListener create_key_listener(int key)
+static void set_status_message(char *message)
 {
-       return (KeyListener) {
-               .key = key,
-               .was_pressed = false,
-               .fired = false,
-       };
+       gui_text(status_message, message);
+       status_message->def.text_color.w = 1.01f;
 }
 
-static void set_status_message(char *message)
+void input_init()
 {
-       gui_set_text(input.status_message, message);
-       input.status_message->def.text_color.w = 1.01f;
+       pause_menu = gui_add(NULL, (GUIElementDefinition) {
+               .pos = {0.0f, 0.0f},
+               .z_index = 0.5f,
+               .offset = {0, 0},
+               .margin = {0, 0},
+               .align = {0.0f, 0.0f},
+               .scale = {1.0f, 1.0f},
+               .scale_type = SCALE_PARENT,
+               .affect_parent_scale = false,
+               .text = NULL,
+               .image = NULL,
+               .text_color = {0.0f, 0.0f, 0.0f, 0.0f},
+               .bg_color = {0.0f, 0.0f, 0.0f, 0.4f},
+       });
+
+       status_message = gui_add(NULL, (GUIElementDefinition) {
+               .pos = {0.5f, 0.25f},
+               .z_index = 0.1f,
+               .offset = {0, 0},
+               .margin = {0, 0},
+               .align = {0.5f, 0.5f},
+               .scale = {1.0f, 1.0f},
+               .scale_type = SCALE_TEXT,
+               .affect_parent_scale = false,
+               .text = strdup(""),
+               .image = NULL,
+               .text_color = {1.0f, 0.91f, 0.13f, 0.0f},
+               .bg_color = {0.0f, 0.0f, 0.0f, 0.0f},
+       });
+
+       glfwSetInputMode(window.handle, GLFW_STICKY_KEYS, GL_TRUE);
+       enter_game();
 }
 
 void input_tick(f64 dtime)
 {
-       if (input.status_message->def.text_color.w > 1.0f)
-               input.status_message->def.text_color.w = 1.0f;
-       else if (input.status_message->def.text_color.w > 0.0f)
-               input.status_message->def.text_color.w -= dtime * 1.0f;
+       if (status_message->def.text_color.w > 1.0f)
+               status_message->def.text_color.w = 1.0f;
+       else if (status_message->def.text_color.w > 0.0f)
+               status_message->def.text_color.w -= dtime * 1.0f;
 
-       do_key_listener(&input.pause_listener);
-       do_key_listener(&input.fullscreen_listener);
+       if (key_listener(&listener_pause)) {
+               paused = !paused;
 
-       if (input.pause_listener.fired) {
-               input.paused = ! input.paused;
-
-               if (input.paused) {
+               if (paused) {
                        glfwSetInputMode(window.handle, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
-                       input.pause_menu->visible = true;
+                       pause_menu->visible = true;
                } else {
                        enter_game();
                }
        }
 
-       if (input.fullscreen_listener.fired) {
+       if (key_listener(&listener_fullscreen)) {
                if (window.fullscreen)
                        window_exit_fullscreen();
                else
                        window_enter_fullscreen();
        }
 
-       if (! input.paused) {
-               do_key_listener(&input.fly_listener);
-               do_key_listener(&input.collision_listener);
-               do_key_listener(&input.timelapse_listener);
-               do_key_listener(&input.debug_menu_listener);
-               do_key_listener(&input.screenshot_listener);
-
-               if (input.fly_listener.fired) {
-                       client_player.fly = ! client_player.fly;
-                       debug_menu_update_flight();
-                       set_status_message(format_string("Flight %s", client_player.fly ? "Enabled" : "Disabled"));
+       if (!paused) {
+               if (key_listener(&listener_fly)) {
+                       pthread_rwlock_wrlock(&client_player.lock_movement);
+                       client_player.movement.flight = !client_player.movement.flight;
+
+                       char *msg;
+                       asprintf(&msg, "Flight %s", client_player.movement.flight ? "Enabled" : "Disabled");
+                       set_status_message(msg);
+                       debug_menu_changed(ENTRY_FLIGHT);
+
+                       pthread_rwlock_unlock(&client_player.lock_movement);
                }
 
-               if (input.collision_listener.fired) {
-                       client_player.collision = ! client_player.collision;
-                       debug_menu_update_collision();
-                       set_status_message(format_string("Collision %s", client_player.collision ? "Enabled" : "Disabled"));
+               if (key_listener(&listener_collision)) {
+                       pthread_rwlock_wrlock(&client_player.lock_movement);
+                       client_player.movement.collision = !client_player.movement.collision;
+
+                       char *msg;
+                       asprintf(&msg, "Collision %s", client_player.movement.collision ? "Enabled" : "Disabled");
+                       set_status_message(msg);
+                       debug_menu_changed(ENTRY_COLLISION);
+
+                       pthread_rwlock_unlock(&client_player.lock_movement);
                }
 
-               if (input.timelapse_listener.fired) {
+               if (key_listener(&listener_timelapse)) {
                        f64 current_time = get_time_of_day();
-                       timelapse = ! timelapse;
+                       timelapse = !timelapse;
                        set_time_of_day(current_time);
-                       debug_menu_update_timelapse();
-                       set_status_message(format_string("Timelapse %s", timelapse ? "Enabled" : "Disabled"));
+
+                       char *msg;
+                       asprintf(&msg, "Timelapse %s", timelapse ? "Enabled" : "Disabled");
+                       set_status_message(msg);
+                       debug_menu_changed(ENTRY_TIMELAPSE);
                }
 
-               if (input.debug_menu_listener.fired)
+               if (key_listener(&listener_debug_menu))
                        debug_menu_toggle();
 
-               if (input.screenshot_listener.fired) {
-                       char *screenshot_filename = take_screenshot();
-                       set_status_message(format_string("Screenshot saved to %s", screenshot_filename));
+               if (key_listener(&listener_screenshot)) {
+                       char *screenshot_filename = game_take_screenshot();
+                       char *msg;
+                       asprintf(&msg, "Screenshot saved to %s", screenshot_filename);
+                       set_status_message(msg);
                        free(screenshot_filename);
                }
        }
 
+       pthread_rwlock_rdlock(&client_player.lock_movement);
+
        client_player.velocity.x = 0.0f;
        client_player.velocity.z = 0.0f;
 
-       if (client_player.fly)
+       if (client_player.movement.flight)
                client_player.velocity.y = 0.0f;
 
-       if (! input.paused) {
+       if (!paused) {
                move(GLFW_KEY_W, GLFW_KEY_S, camera.movement_dirs.front);
                move(GLFW_KEY_D, GLFW_KEY_A, camera.movement_dirs.right);
 
-               if (client_player.fly)
+               if (client_player.movement.flight)
                        move(GLFW_KEY_SPACE, GLFW_KEY_LEFT_SHIFT, camera.movement_dirs.up);
                else if (glfwGetKey(window.handle, GLFW_KEY_SPACE) == GLFW_PRESS)
                        client_player_jump();
        }
+
+       pthread_rwlock_unlock(&client_player.lock_movement);
 }
 
-void input_init()
+void input_cursor(double current_x, double current_y)
 {
-       input.paused = false;
+       if (paused)
+               return;
 
-       input.pause_listener = create_key_listener(GLFW_KEY_ESCAPE);
-       input.fullscreen_listener = create_key_listener(GLFW_KEY_F11);
-       input.fly_listener = create_key_listener(GLFW_KEY_F);
-       input.collision_listener = create_key_listener(GLFW_KEY_C);
-       input.timelapse_listener = create_key_listener(GLFW_KEY_T);
-       input.debug_menu_listener = create_key_listener(GLFW_KEY_F3);
-       input.screenshot_listener = create_key_listener(GLFW_KEY_F2);
+       double delta_x = current_x - cursor_last_x;
+       double delta_y = current_y - cursor_last_y;
+       cursor_last_x = current_x;
+       cursor_last_y = current_y;
 
-       input.pause_menu = gui_add(&gui_root, (GUIElementDefinition) {
-               .pos = {0.0f, 0.0f},
-               .z_index = 0.5f,
-               .offset = {0, 0},
-               .margin = {0, 0},
-               .align = {0.0f, 0.0f},
-               .scale = {1.0f, 1.0f},
-               .scale_type = GST_PARENT,
-               .affect_parent_scale = false,
-               .text = NULL,
-               .image = NULL,
-               .text_color = {0.0f, 0.0f, 0.0f, 0.0f},
-               .bg_color = {0.0f, 0.0f, 0.0f, 0.4f},
-       });
+       ClientEntity *entity = client_player_entity();
+       if (!entity)
+               return;
 
-       input.status_message = gui_add(&gui_root, (GUIElementDefinition) {
-               .pos = {0.5f, 0.25f},
-               .z_index = 0.1f,
-               .offset = {0, 0},
-               .margin = {0, 0},
-               .align = {0.5f, 0.5f},
-               .scale = {1.0f, 1.0f},
-               .scale_type = GST_TEXT,
-               .affect_parent_scale = false,
-               .text = strdup(""),
-               .image = NULL,
-               .text_color = {1.0f, 0.91f, 0.13f, 0.0f},
-               .bg_color = {0.0f, 0.0f, 0.0f, 0.0f},
-       });
+       pthread_rwlock_wrlock(&entity->lock_pos_rot);
 
-       glfwSetInputMode(window.handle, GLFW_STICKY_KEYS, GL_TRUE);
+       entity->data.rot.x += (f32) delta_x * M_PI / 180.0f / 8.0f;
+       entity->data.rot.y -= (f32) delta_y * M_PI / 180.0f / 8.0f;
 
-       enter_game();
+       entity->data.rot.x = fmod(entity->data.rot.x + M_PI * 2.0f, M_PI * 2.0f);
+       entity->data.rot.y = f32_clamp(entity->data.rot.y, -M_PI / 2.0f + 0.01f, M_PI / 2.0f - 0.01f);
+
+       client_player_update_rot(entity);
+       pthread_rwlock_unlock(&entity->lock_pos_rot);
+       refcount_drp(&entity->rc);
 }