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