]> git.lizzy.rs Git - dragonblocks_alpha.git/blob - src/client/debug_menu.c
You can now see other players
[dragonblocks_alpha.git] / src / client / debug_menu.c
1 #include <asprintf/asprintf.h>
2 #include <GL/glew.h>
3 #include <GL/gl.h>
4 #include <stdbool.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <pthread.h>
8 #include "client/client_config.h"
9 #include "client/client_player.h"
10 #include "client/client_terrain.h"
11 #include "client/debug_menu.h"
12 #include "client/game.h"
13 #include "client/gl_debug.h"
14 #include "client/gui.h"
15 #include "client/window.h"
16 #include "day.h"
17 #include "environment.h"
18 #include "perlin.h"
19 #include "version.h"
20
21 static GUIElement *gui_elements[COUNT_ENTRY] = {NULL};
22 static bool changed_elements[COUNT_ENTRY] = {false};
23 static pthread_mutex_t changed_elements_mtx = PTHREAD_MUTEX_INITIALIZER;
24
25 static bool debug_menu_enabled = true;
26 static DebugMenuEntry last_always_visible = ENTRY_POS;
27
28 static char *get_entry_text(DebugMenuEntry entry)
29 {
30         bool flight = false;
31         bool collision = false;
32         int hours = 0;
33         int minutes = 0;
34         v3f64 pos = {0.0f, 0.0f, 0.0f};
35         v3f32 rot = {0.0f, 0.0f, 0.0f};
36
37         switch (entry) {
38                 case ENTRY_POS:
39                 case ENTRY_YAW:
40                 case ENTRY_PITCH:
41                 case ENTRY_HUMIDITY:
42                 case ENTRY_TEMPERATURE: {
43                         ClientEntity *entity = client_player_entity();
44                         if (!entity)
45                                 return strdup("");
46
47                         pthread_rwlock_rdlock(&entity->lock_pos_rot);
48                         pos = entity->data.pos;
49                         rot = entity->data.rot;
50                         pthread_rwlock_unlock(&entity->lock_pos_rot);
51                         refcount_drp(&entity->rc);
52                         break;
53                 }
54
55                 case ENTRY_FLIGHT:
56                 case ENTRY_COLLISION:
57                         pthread_rwlock_rdlock(&client_player.lock_movement);
58                         flight = client_player.movement.flight;
59                         collision = client_player.movement.collision;
60                         pthread_rwlock_unlock(&client_player.lock_movement);
61                         break;
62
63                 case ENTRY_ANTIALIASING:
64                         if (!client_config.antialiasing)
65                                 return strdup("antialiasing: disabled");
66                         break;
67
68                 case ENTRY_TIME:
69                         split_time_of_day(&hours, &minutes);
70                         break;
71
72                 default:
73                         break;
74         }
75
76         char *str;
77         switch (entry) {
78                 case ENTRY_VERSION:       asprintf(&str, "Dragonblocks Alpha %s", VERSION                                    );          break;
79                 case ENTRY_FPS:           asprintf(&str, "%d FPS", game_fps                                                  );          break;
80                 case ENTRY_POS:           asprintf(&str, "(%.1f %.1f %.1f)", pos.x, pos.y, pos.z                             );          break;
81                 case ENTRY_YAW:           asprintf(&str, "yaw = %.1f", 360.0 - rot.y / M_PI * 180.0                          );          break;
82                 case ENTRY_PITCH:         asprintf(&str, "pitch = %.1f", -rot.x / M_PI * 180.0                               );          break;
83                 case ENTRY_TIME:          asprintf(&str, "%02d:%02d", hours, minutes                                         );          break;
84                 case ENTRY_DAYLIGHT:      asprintf(&str, "daylight = %.2f", get_daylight()                                   );          break;
85                 case ENTRY_SUN_ANGLE:     asprintf(&str, "sun angle = %.1f", fmod(get_sun_angle() / M_PI * 180.0, 360.0)     );          break;
86                 case ENTRY_HUMIDITY:      asprintf(&str, "humidity = %.2f", get_humidity((v3s32) {pos.x, pos.y, pos.z})      );          break;
87                 case ENTRY_TEMPERATURE:   asprintf(&str, "temperature = %.2f", get_temperature((v3s32) {pos.x, pos.y, pos.z}));          break;
88                 case ENTRY_SEED:          asprintf(&str, "seed = %d", seed                                                   );          break;
89                 case ENTRY_FLIGHT:        asprintf(&str, "flight: %s", flight ? "enabled" : "disabled"                       );          break;
90                 case ENTRY_COLLISION:     asprintf(&str, "collision: %s", collision ? "enabled" : "disabled"                 );          break;
91                 case ENTRY_TIMELAPSE:     asprintf(&str, "timelapse: %s", timelapse ? "enabled" : "disabled"                 );          break;
92                 case ENTRY_FULLSCREEN:    asprintf(&str, "fullscreen: %s", window.fullscreen ? "enabled" : "disabled"        );          break;
93                 case ENTRY_OPENGL:        asprintf(&str, "OpenGL %s", glGetString(GL_VERSION)                                ); GL_DEBUG break;
94                 case ENTRY_GPU:           asprintf(&str, "%s", glGetString(GL_RENDERER)                                      ); GL_DEBUG break;
95                 case ENTRY_ANTIALIASING:  asprintf(&str, "antialiasing: %u samples", client_config.antialiasing              );          break;
96                 case ENTRY_MIPMAP:        asprintf(&str, "mipmap: %s", client_config.mipmap ? "enabled" : "disabled"         );          break;
97                 case ENTRY_VIEW_DISTANCE: asprintf(&str, "view distance: %.1lf", client_config.view_distance                 );          break;
98                 case ENTRY_LOAD_DISTANCE: asprintf(&str, "load distance: %u", client_terrain_get_load_distance()             );          break;
99                 default: break;
100         }
101         return str;
102 }
103
104 void debug_menu_init()
105 {
106         s32 offset = -16;
107
108         for (DebugMenuEntry i = 0; i < COUNT_ENTRY; i++) {
109                 gui_elements[i] = gui_add(NULL, (GUIElementDefinition) {
110                         .pos = {0.0f, 0.0f},
111                         .z_index = 0.1f,
112                         .offset = {2, offset += 18},
113                         .margin = {2, 2},
114                         .align = {0.0f, 0.0f},
115                         .scale = {1.0f, 1.0f},
116                         .scale_type = SCALE_TEXT,
117                         .affect_parent_scale = false,
118                         .text = "",
119                         .image = NULL,
120                         .text_color = (v4f32) {1.0f, 1.0f, 1.0f, 1.0f},
121                         .bg_color = (v4f32) {0.0f, 0.0f, 0.0f, 0.0f},
122                 });
123         }
124
125         debug_menu_toggle();
126
127         debug_menu_changed(ENTRY_VERSION);
128         debug_menu_changed(ENTRY_SEED);
129         debug_menu_changed(ENTRY_TIMELAPSE);
130         debug_menu_changed(ENTRY_FULLSCREEN);
131         debug_menu_changed(ENTRY_OPENGL);
132         debug_menu_changed(ENTRY_GPU);
133         debug_menu_changed(ENTRY_ANTIALIASING);
134         debug_menu_changed(ENTRY_MIPMAP);
135         debug_menu_changed(ENTRY_VIEW_DISTANCE);
136 }
137
138 void debug_menu_toggle()
139 {
140         debug_menu_enabled = !debug_menu_enabled;
141
142         for (DebugMenuEntry i = 0; i < COUNT_ENTRY; i++) {
143                 gui_elements[i]->visible = debug_menu_enabled || i <= last_always_visible;
144                 gui_elements[i]->def.bg_color.w = debug_menu_enabled ? 0.5f : 0.0f;
145         }
146 }
147
148 void debug_menu_update()
149 {
150         bool changed_elements_cpy[COUNT_ENTRY];
151
152         pthread_mutex_lock(&changed_elements_mtx);
153         memcpy(changed_elements_cpy, changed_elements, COUNT_ENTRY * sizeof(bool));
154         memset(changed_elements, 0,                    COUNT_ENTRY * sizeof(bool));
155         pthread_mutex_unlock(&changed_elements_mtx);
156
157         for (DebugMenuEntry i = 0; i < COUNT_ENTRY; i++)
158                 if (changed_elements_cpy[i]) {
159                         char *str = get_entry_text(i);
160                         gui_text(gui_elements[i], str);
161                         free(str);
162                 }
163 }
164
165 void debug_menu_changed(DebugMenuEntry entry)
166 {
167         pthread_mutex_lock(&changed_elements_mtx);
168         changed_elements[entry] = true;
169         pthread_mutex_unlock(&changed_elements_mtx);
170 }