4 #include "client/camera.h"
5 #include "client/client.h"
6 #include "client/client_player.h"
7 #include "client/debug_menu.h"
8 #include "client/game.h"
9 #include "client/gui.h"
10 #include "client/input.h"
11 #include "client/window.h"
24 GUIElement *pause_menu;
25 GUIElement *status_message;
27 KeyListener pause_listener;
28 KeyListener fullscreen_listener;
29 KeyListener fly_listener;
30 KeyListener collision_listener;
31 KeyListener timelapse_listener;
32 KeyListener debug_menu_listener;
33 KeyListener screenshot_listener;
36 void input_on_cursor_pos(double current_x, double current_y)
41 static double last_x, last_y = 0.0;
43 double delta_x = current_x - last_x;
44 double delta_y = current_y - last_y;
48 client_player.yaw += (f32) delta_x * M_PI / 180.0f / 8.0f;
49 client_player.pitch -= (f32) delta_y * M_PI / 180.0f / 8.0f;
51 client_player.yaw = fmod(client_player.yaw + M_PI * 2.0f, M_PI * 2.0f);
52 client_player.pitch = fmax(fmin(client_player.pitch, M_PI / 2.0f - 0.01f), -M_PI / 2.0f + 0.01f);
54 camera_set_angle(client_player.yaw, client_player.pitch);
56 debug_menu_update_yaw();
57 debug_menu_update_pitch();
60 static bool move(int forward, int backward, vec3 dir)
63 f64 speed = client_player.fly ? 25.0f : 4.317f;
65 if (glfwGetKey(window.handle, forward) == GLFW_PRESS)
67 else if (glfwGetKey(window.handle, backward) == GLFW_PRESS)
72 client_player.velocity.x += dir[0] * speed * sign;
73 client_player.velocity.y += dir[1] * speed * sign;
74 client_player.velocity.z += dir[2] * speed * sign;
79 static void enter_game()
81 glfwSetInputMode(window.handle, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
82 input.pause_menu->visible = false;
85 static void do_key_listener(KeyListener *listener)
87 bool is_pressed = glfwGetKey(window.handle, listener->key) == GLFW_PRESS;
88 listener->fired = listener->was_pressed && ! is_pressed;
89 listener->was_pressed = is_pressed;
92 static KeyListener create_key_listener(int key)
94 return (KeyListener) {
101 static void set_status_message(char *message)
103 gui_set_text(input.status_message, message);
104 input.status_message->def.text_color.w = 1.01f;
107 void input_tick(f64 dtime)
109 if (input.status_message->def.text_color.w > 1.0f)
110 input.status_message->def.text_color.w = 1.0f;
111 else if (input.status_message->def.text_color.w > 0.0f)
112 input.status_message->def.text_color.w -= dtime * 1.0f;
114 do_key_listener(&input.pause_listener);
115 do_key_listener(&input.fullscreen_listener);
117 if (input.pause_listener.fired) {
118 input.paused = ! input.paused;
121 glfwSetInputMode(window.handle, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
122 input.pause_menu->visible = true;
128 if (input.fullscreen_listener.fired) {
129 if (window.fullscreen)
130 window_exit_fullscreen();
132 window_enter_fullscreen();
135 if (! input.paused) {
136 do_key_listener(&input.fly_listener);
137 do_key_listener(&input.collision_listener);
138 do_key_listener(&input.timelapse_listener);
139 do_key_listener(&input.debug_menu_listener);
140 do_key_listener(&input.screenshot_listener);
142 if (input.fly_listener.fired) {
143 client_player.fly = ! client_player.fly;
144 debug_menu_update_flight();
145 set_status_message(format_string("Flight %s", client_player.fly ? "Enabled" : "Disabled"));
148 if (input.collision_listener.fired) {
149 client_player.collision = ! client_player.collision;
150 debug_menu_update_collision();
151 set_status_message(format_string("Collision %s", client_player.collision ? "Enabled" : "Disabled"));
154 if (input.timelapse_listener.fired) {
155 f64 current_time = get_time_of_day();
156 timelapse = ! timelapse;
157 set_time_of_day(current_time);
158 debug_menu_update_timelapse();
159 set_status_message(format_string("Timelapse %s", timelapse ? "Enabled" : "Disabled"));
162 if (input.debug_menu_listener.fired)
165 if (input.screenshot_listener.fired) {
166 char *screenshot_filename = take_screenshot();
167 set_status_message(format_string("Screenshot saved to %s", screenshot_filename));
168 free(screenshot_filename);
172 client_player.velocity.x = 0.0f;
173 client_player.velocity.z = 0.0f;
175 if (client_player.fly)
176 client_player.velocity.y = 0.0f;
178 if (! input.paused) {
179 move(GLFW_KEY_W, GLFW_KEY_S, camera.movement_dirs.front);
180 move(GLFW_KEY_D, GLFW_KEY_A, camera.movement_dirs.right);
182 if (client_player.fly)
183 move(GLFW_KEY_SPACE, GLFW_KEY_LEFT_SHIFT, camera.movement_dirs.up);
184 else if (glfwGetKey(window.handle, GLFW_KEY_SPACE) == GLFW_PRESS)
185 client_player_jump();
191 input.paused = false;
193 input.pause_listener = create_key_listener(GLFW_KEY_ESCAPE);
194 input.fullscreen_listener = create_key_listener(GLFW_KEY_F11);
195 input.fly_listener = create_key_listener(GLFW_KEY_F);
196 input.collision_listener = create_key_listener(GLFW_KEY_C);
197 input.timelapse_listener = create_key_listener(GLFW_KEY_T);
198 input.debug_menu_listener = create_key_listener(GLFW_KEY_F3);
199 input.screenshot_listener = create_key_listener(GLFW_KEY_F2);
201 input.pause_menu = gui_add(&gui_root, (GUIElementDefinition) {
206 .align = {0.0f, 0.0f},
207 .scale = {1.0f, 1.0f},
208 .scale_type = GST_PARENT,
209 .affect_parent_scale = false,
212 .text_color = {0.0f, 0.0f, 0.0f, 0.0f},
213 .bg_color = {0.0f, 0.0f, 0.0f, 0.4f},
216 input.status_message = gui_add(&gui_root, (GUIElementDefinition) {
217 .pos = {0.5f, 0.25f},
221 .align = {0.5f, 0.5f},
222 .scale = {1.0f, 1.0f},
223 .scale_type = GST_TEXT,
224 .affect_parent_scale = false,
227 .text_color = {1.0f, 0.91f, 0.13f, 0.0f},
228 .bg_color = {0.0f, 0.0f, 0.0f, 0.0f},
231 glfwSetInputMode(window.handle, GLFW_STICKY_KEYS, GL_TRUE);