1 #include <asprintf/asprintf.h>
8 #include "client/client_config.h"
9 #include "client/client_node.h"
10 #include "client/client_player.h"
11 #include "client/client_terrain.h"
12 #include "client/debug_menu.h"
13 #include "client/game.h"
14 #include "client/gl_debug.h"
15 #include "client/gui.h"
16 #include "client/interact.h"
17 #include "client/window.h"
19 #include "environment.h"
23 static GUIElement *gui_elements[COUNT_ENTRY] = {NULL};
24 static bool changed_elements[COUNT_ENTRY] = {false};
25 static pthread_mutex_t changed_elements_mtx = PTHREAD_MUTEX_INITIALIZER;
27 static bool debug_menu_enabled = true;
28 static DebugMenuEntry last_always_visible = ENTRY_POINTED;
30 static char *get_entry_text(DebugMenuEntry entry)
33 bool collision = false;
36 v3f64 pos = {0.0f, 0.0f, 0.0f};
37 v3f32 rot = {0.0f, 0.0f, 0.0f};
38 char *pnt_name = NULL;
41 static struct InteractPointed *pnt = &interact_pointed;
48 case ENTRY_TEMPERATURE: {
49 ClientEntity *entity = client_player_entity_local();
53 pthread_rwlock_rdlock(&entity->lock_pos_rot);
54 pos = entity->data.pos;
55 rot = entity->data.rot;
56 pthread_rwlock_unlock(&entity->lock_pos_rot);
57 refcount_drp(&entity->rc);
65 pnt_name = client_node_defs[pnt->node].name;
70 pthread_rwlock_rdlock(&client_player.lock_movement);
71 flight = client_player.movement.flight;
72 collision = client_player.movement.collision;
73 pthread_rwlock_unlock(&client_player.lock_movement);
76 case ENTRY_ANTIALIASING:
77 if (!client_config.antialiasing)
78 return strdup("antialiasing: disabled");
82 split_time_of_day(&hours, &minutes);
91 case ENTRY_VERSION: asprintf(&str, "Dragonblocks Alpha %s", VERSION ); break;
92 case ENTRY_FPS: asprintf(&str, "%d FPS", game_fps ); break;
93 case ENTRY_POS: asprintf(&str, "(%.1f %.1f %.1f)", pos.x, pos.y, pos.z ); break;
94 case ENTRY_POINTED: asprintf(&str, "%s (%d, %d, %d)", pnt_name, pnt->pos.x, pnt->pos.y, pnt->pos.z ); break;
95 case ENTRY_YAW: asprintf(&str, "yaw = %.1f", 360.0 - rot.y / M_PI * 180.0 ); break;
96 case ENTRY_PITCH: asprintf(&str, "pitch = %.1f", -rot.x / M_PI * 180.0 ); break;
97 case ENTRY_TIME: asprintf(&str, "%02d:%02d", hours, minutes ); break;
98 case ENTRY_DAYLIGHT: asprintf(&str, "daylight = %.2f", get_daylight() ); break;
99 case ENTRY_SUN_ANGLE: asprintf(&str, "sun angle = %.1f", fmod(get_sun_angle() / M_PI * 180.0, 360.0) ); break;
100 case ENTRY_HUMIDITY: asprintf(&str, "humidity = %.2f", get_humidity((v3s32) {pos.x, pos.y, pos.z}) ); break;
101 case ENTRY_TEMPERATURE: asprintf(&str, "temperature = %.2f", get_temperature((v3s32) {pos.x, pos.y, pos.z})); break;
102 case ENTRY_SEED: asprintf(&str, "seed = %d", seed ); break;
103 case ENTRY_FLIGHT: asprintf(&str, "flight: %s", flight ? "enabled" : "disabled" ); break;
104 case ENTRY_COLLISION: asprintf(&str, "collision: %s", collision ? "enabled" : "disabled" ); break;
105 case ENTRY_TIMELAPSE: asprintf(&str, "timelapse: %s", timelapse ? "enabled" : "disabled" ); break;
106 case ENTRY_FULLSCREEN: asprintf(&str, "fullscreen: %s", window.fullscreen ? "enabled" : "disabled" ); break;
107 case ENTRY_OPENGL: asprintf(&str, "OpenGL %s", glGetString(GL_VERSION) ); GL_DEBUG break;
108 case ENTRY_GPU: asprintf(&str, "%s", glGetString(GL_RENDERER) ); GL_DEBUG break;
109 case ENTRY_ANTIALIASING: asprintf(&str, "antialiasing: %u samples", client_config.antialiasing ); break;
110 case ENTRY_MIPMAP: asprintf(&str, "mipmap: %s", client_config.mipmap ? "enabled" : "disabled" ); break;
111 case ENTRY_VIEW_DISTANCE: asprintf(&str, "view distance: %.1lf", client_config.view_distance ); break;
112 case ENTRY_LOAD_DISTANCE: asprintf(&str, "load distance: %u", client_terrain_get_load_distance() ); break;
118 void debug_menu_init()
122 for (DebugMenuEntry i = 0; i < COUNT_ENTRY; i++) {
123 gui_elements[i] = gui_add(NULL, (GUIElementDef) {
126 .offset = {2, offset += 18},
128 .align = {0.0f, 0.0f},
129 .scale = {1.0f, 1.0f},
130 .scale_type = SCALE_TEXT,
131 .affect_parent_scale = false,
134 .text_color = (v4f32) {1.0f, 1.0f, 1.0f, 1.0f},
135 .bg_color = (v4f32) {0.0f, 0.0f, 0.0f, 0.0f},
141 debug_menu_changed(ENTRY_VERSION);
142 debug_menu_changed(ENTRY_SEED);
143 debug_menu_changed(ENTRY_TIMELAPSE);
144 debug_menu_changed(ENTRY_FULLSCREEN);
145 debug_menu_changed(ENTRY_OPENGL);
146 debug_menu_changed(ENTRY_GPU);
147 debug_menu_changed(ENTRY_ANTIALIASING);
148 debug_menu_changed(ENTRY_MIPMAP);
149 debug_menu_changed(ENTRY_VIEW_DISTANCE);
152 void debug_menu_toggle()
154 debug_menu_enabled = !debug_menu_enabled;
156 for (DebugMenuEntry i = 0; i < COUNT_ENTRY; i++) {
157 gui_elements[i]->visible = debug_menu_enabled || i <= last_always_visible;
158 gui_elements[i]->def.bg_color.w = debug_menu_enabled ? 0.5f : 0.0f;
162 void debug_menu_update()
164 bool changed_elements_cpy[COUNT_ENTRY];
166 pthread_mutex_lock(&changed_elements_mtx);
167 memcpy(changed_elements_cpy, changed_elements, COUNT_ENTRY * sizeof(bool));
168 memset(changed_elements, 0, COUNT_ENTRY * sizeof(bool));
169 pthread_mutex_unlock(&changed_elements_mtx);
171 for (DebugMenuEntry i = 0; i < COUNT_ENTRY; i++)
172 if (changed_elements_cpy[i]) {
173 char *str = get_entry_text(i);
174 gui_text(gui_elements[i], str);
179 void debug_menu_changed(DebugMenuEntry entry)
181 pthread_mutex_lock(&changed_elements_mtx);
182 changed_elements[entry] = true;
183 pthread_mutex_unlock(&changed_elements_mtx);