]> git.lizzy.rs Git - dragonblocks_alpha.git/blob - src/client/input.c
c2964c27e22937941c5e891aea73d11404de054e
[dragonblocks_alpha.git] / src / client / input.c
1 #include <math.h>
2 #include "client/camera.h"
3 #include "client/client.h"
4 #include "client/client_player.h"
5 #include "client/debug_menu.h"
6 #include "client/gui.h"
7 #include "client/input.h"
8 #include "client/window.h"
9
10 typedef struct
11 {
12         int key;
13         bool was_pressed;
14         bool fired;
15 } KeyListener;
16
17 static struct
18 {
19         GUIElement *pause_menu;
20         bool paused;
21         KeyListener pause_listener;
22         KeyListener fullscreen_listener;
23         KeyListener fly_listener;
24         KeyListener collision_listener;
25         KeyListener debug_menu_listener;
26 } input;
27
28 void input_on_cursor_pos(double current_x, double current_y)
29 {
30         if (input.paused)
31                 return;
32
33         static double last_x, last_y = 0.0;
34
35         double delta_x = current_x - last_x;
36         double delta_y = current_y - last_y;
37         last_x = current_x;
38         last_y = current_y;
39
40         client_player.yaw += (f32) delta_x * M_PI / 180.0f / 8.0f;
41         client_player.pitch -= (f32) delta_y * M_PI / 180.0f / 8.0f;
42
43         client_player.yaw = fmod(client_player.yaw + M_PI * 2.0f, M_PI * 2.0f);
44         client_player.pitch = fmax(fmin(client_player.pitch, M_PI / 2.0f - 0.01f), -M_PI / 2.0f + 0.01f);
45
46         camera_set_angle(client_player.yaw, client_player.pitch);
47
48         debug_menu_update_yaw();
49         debug_menu_update_pitch();
50 }
51
52 static bool move(int forward, int backward, vec3 dir)
53 {
54         f64 sign;
55         f64 speed = client_player.fly ? 25.0f : 4.317f;
56
57         if (glfwGetKey(window.handle, forward) == GLFW_PRESS)
58                 sign = +1.0f;
59         else if (glfwGetKey(window.handle, backward) == GLFW_PRESS)
60                 sign = -1.0f;
61         else
62                 return false;
63
64         client_player.velocity.x += dir[0] * speed * sign;
65         client_player.velocity.y += dir[1] * speed * sign;
66         client_player.velocity.z += dir[2] * speed * sign;
67
68         return true;
69 }
70
71 static void enter_game()
72 {
73         glfwSetInputMode(window.handle, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
74         input.pause_menu->visible = false;
75 }
76
77 static void do_key_listener(KeyListener *listener)
78 {
79         bool is_pressed = glfwGetKey(window.handle, listener->key) == GLFW_PRESS;
80         listener->fired = listener->was_pressed && ! is_pressed;
81         listener->was_pressed = is_pressed;
82 }
83
84 static KeyListener create_key_listener(int key)
85 {
86         return (KeyListener) {
87                 .key = key,
88                 .was_pressed = false,
89                 .fired = false,
90         };
91 }
92
93 void input_tick()
94 {
95         do_key_listener(&input.pause_listener);
96         do_key_listener(&input.fullscreen_listener);
97
98         if (input.pause_listener.fired) {
99                 input.paused = ! input.paused;
100
101                 if (input.paused) {
102                         glfwSetInputMode(window.handle, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
103                         input.pause_menu->visible = true;
104                 } else {
105                         enter_game();
106                 }
107         }
108
109         if (input.fullscreen_listener.fired) {
110                 if (window.fullscreen)
111                         window_exit_fullscreen();
112                 else
113                         window_enter_fullscreen();
114         }
115
116         if (! input.paused) {
117                 do_key_listener(&input.fly_listener);
118                 do_key_listener(&input.collision_listener);
119                 do_key_listener(&input.debug_menu_listener);
120
121                 if (input.fly_listener.fired) {
122                         client_player.fly = ! client_player.fly;
123                         debug_menu_update_flight();
124                 }
125
126                 if (input.collision_listener.fired) {
127                         client_player.collision = ! client_player.collision;
128                         debug_menu_update_collision();
129                 }
130
131                 if (input.debug_menu_listener.fired)
132                         debug_menu_toggle();
133         }
134
135         client_player.velocity.x = 0.0f;
136         client_player.velocity.z = 0.0f;
137
138         if (client_player.fly)
139                 client_player.velocity.y = 0.0f;
140
141         if (! input.paused) {
142                 move(GLFW_KEY_W, GLFW_KEY_S, camera.movement_dirs.front);
143                 move(GLFW_KEY_D, GLFW_KEY_A, camera.movement_dirs.right);
144
145                 if (client_player.fly)
146                         move(GLFW_KEY_SPACE, GLFW_KEY_LEFT_SHIFT, camera.movement_dirs.up);
147                 else if (glfwGetKey(window.handle, GLFW_KEY_SPACE) == GLFW_PRESS)
148                         client_player_jump();
149         }
150 }
151
152 void input_init()
153 {
154         input.paused = false;
155
156         input.pause_listener = create_key_listener(GLFW_KEY_ESCAPE);
157         input.fullscreen_listener = create_key_listener(GLFW_KEY_F11);
158         input.fly_listener = create_key_listener(GLFW_KEY_F);
159         input.collision_listener = create_key_listener(GLFW_KEY_C);
160         input.debug_menu_listener = create_key_listener(GLFW_KEY_F3);
161
162         input.pause_menu = gui_add(&gui_root, (GUIElementDefinition) {
163                 .pos = {0.0f, 0.0f},
164                 .z_index = 0.5f,
165                 .offset = {0, 0},
166                 .margin = {0, 0},
167                 .align = {0.0f, 0.0f},
168                 .scale = {1.0f, 1.0f},
169                 .scale_type = GST_PARENT,
170                 .affect_parent_scale = false,
171                 .text = NULL,
172                 .image = NULL,
173                 .text_color = {0.0f, 0.0f, 0.0f, 0.0f},
174                 .bg_color = {0.0f, 0.0f, 0.0f, 0.4f},
175         });
176
177         glfwSetInputMode(window.handle, GLFW_STICKY_KEYS, GL_TRUE);
178
179         enter_game();
180 }