]> git.lizzy.rs Git - dragonblocks_alpha.git/blob - src/client/debug_menu.c
ddf36c41c2ebf5d13f12071b24a410b1f03f70e6
[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_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"
18 #include "day.h"
19 #include "environment.h"
20 #include "perlin.h"
21 #include "version.h"
22
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;
26
27 static bool debug_menu_enabled = true;
28 static DebugMenuEntry last_always_visible = ENTRY_POINTED;
29
30 static char *get_entry_text(DebugMenuEntry entry)
31 {
32         bool flight = false;
33         bool collision = false;
34         int hours = 0;
35         int minutes = 0;
36         v3f64 pos = {0.0f, 0.0f, 0.0f};
37         v3f32 rot = {0.0f, 0.0f, 0.0f};
38         char *pnt_name = NULL;
39
40         // shortcut
41         static struct InteractPointed *pnt = &interact_pointed;
42
43         switch (entry) {
44                 case ENTRY_POS:
45                 case ENTRY_YAW:
46                 case ENTRY_PITCH:
47                 case ENTRY_HUMIDITY:
48                 case ENTRY_TEMPERATURE: {
49                         ClientEntity *entity = client_player_entity_local();
50                         if (!entity)
51                                 return strdup("");
52
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);
58                         break;
59                 }
60
61                 case ENTRY_POINTED:
62                         if (!pnt->exists)
63                                 return strdup("");
64
65                         pnt_name = client_node_def[pnt->node].name;
66                         break;
67
68                 case ENTRY_FLIGHT:
69                 case ENTRY_COLLISION:
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);
74                         break;
75
76                 case ENTRY_ANTIALIASING:
77                         if (!client_config.antialiasing)
78                                 return strdup("antialiasing: disabled");
79                         break;
80
81                 case ENTRY_TIME:
82                         split_time_of_day(&hours, &minutes);
83                         break;
84
85                 default:
86                         break;
87         }
88
89         char *str;
90         switch (entry) {
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;
113                 default: break;
114         }
115         return str;
116 }
117
118 void debug_menu_init()
119 {
120         s32 offset = -16;
121
122         for (DebugMenuEntry i = 0; i < COUNT_ENTRY; i++) {
123                 gui_elements[i] = gui_add(NULL, (GUIElementDef) {
124                         .pos = {0.0f, 0.0f},
125                         .z_index = 0.1f,
126                         .offset = {2, offset += 18},
127                         .margin = {2, 2},
128                         .align = {0.0f, 0.0f},
129                         .scale = {1.0f, 1.0f},
130                         .scale_type = SCALE_TEXT,
131                         .affect_parent_scale = false,
132                         .text = "",
133                         .image = NULL,
134                         .text_color = (v4f32) {1.0f, 1.0f, 1.0f, 1.0f},
135                         .bg_color = (v4f32) {0.0f, 0.0f, 0.0f, 0.0f},
136                 });
137         }
138
139         debug_menu_toggle();
140
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);
150 }
151
152 void debug_menu_toggle()
153 {
154         debug_menu_enabled = !debug_menu_enabled;
155
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;
159         }
160 }
161
162 void debug_menu_update()
163 {
164         bool changed_elements_cpy[COUNT_ENTRY];
165
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);
170
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);
175                         free(str);
176                 }
177 }
178
179 void debug_menu_changed(DebugMenuEntry entry)
180 {
181         pthread_mutex_lock(&changed_elements_mtx);
182         changed_elements[entry] = true;
183         pthread_mutex_unlock(&changed_elements_mtx);
184 }