#include "debug_vars.h" #include "event.h" #include "game.h" #include "gui.h" #include "../system/platform.h" #include "texture.h" #include static void debug_vars_clear(struct Debug_Vars* debug_vars); void debug_vars_init(struct Debug_Vars* debug_vars) { debug_vars->visible = false; debug_vars->location = DVL_TOP_RIGHT; debug_vars->window_width = 350; debug_vars->window_height = 500; debug_vars->row_height = 14; debug_vars->row_height_color = 16; debug_vars->row_height_texture = 200; for(int i = 0; i < MAX_DEBUG_VARS_PER_FRAME_NUMERIC; i++) { memset(&debug_vars->numeric_vars[i].name[0], '\0', MAX_DEBUG_VAR_NAME); variant_init_empty(&debug_vars->numeric_vars[i]); } for(int i = 0; i < MAX_DEBUG_VARS_PER_FRAME_TEXTURES; i++) { memset(&debug_vars->texture_vars[i].name[0], '\0', MAX_DEBUG_VAR_NAME); variant_init_empty(&debug_vars->texture_vars[i]); } } void debug_vars_cleanup(struct Debug_Vars* debug_vars) { debug_vars->visible = false; debug_vars_clear(debug_vars); } void debug_vars_location_set(struct Debug_Vars* debug_vars, int location) { if(location < 0 || location >= DVL_MAX) { log_error("debug_vars:location_set", "Invalid location. Valid values are from 0-4"); return; } debug_vars->location = location; } void debug_vars_post_update(struct Debug_Vars* debug_vars) { if(!debug_vars->visible) return; int window_x = 0; int window_y = 0; int display_width = 0; int display_height = 0; struct Game_State* game_state = game_state_get(); struct Gui* gui = game_state->gui; struct nk_context* context = &gui->context; window_get_drawable_size(game_state->window, &display_width, &display_height); int window_flags = NK_WINDOW_BACKGROUND | NK_WINDOW_NO_SCROLLBAR; switch(debug_vars->location) { case DVL_TOP_RIGHT: window_x = display_width - debug_vars->window_width; window_y = 0; break; case DVL_BOTTOM_RIGHT: window_x = display_width - debug_vars->window_width; window_y = display_height - debug_vars->window_height; break; case DVL_BOTTOM_LEFT: window_x = 0; window_y = display_height - debug_vars->window_height; break; case DVL_TOP_LEFT: window_x = 0; window_y = 0; break; case DVL_FREE: window_x = (display_width / 2) - (debug_vars->window_width / 2); window_y = (display_height / 2) - (debug_vars->window_height / 2); window_flags &= ~(NK_WINDOW_BACKGROUND & NK_WINDOW_NO_INPUT); break; } nk_byte previous_opacity = context->style.window.background.a; context->style.window.fixed_background.data.color.a = 100; if(nk_begin(context, "Debug Variables", nk_recti(window_x, window_y, debug_vars->window_width, debug_vars->window_height), window_flags)) { nk_layout_row_dynamic(context, debug_vars->row_height, 2); int name_flags = NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_CENTERED; int value_flags = NK_TEXT_ALIGN_RIGHT | NK_TEXT_ALIGN_CENTERED; for(int i = 0; i < MAX_DEBUG_VARS_PER_FRAME_NUMERIC; i++) { struct Debug_Variable* variable = &debug_vars->numeric_vars[i]; if(variable->value.type == VT_NONE) continue; switch(variable->value.type) { case VT_INT: nk_label(context, &variable->name[0], name_flags); nk_labelf(context, value_flags, "%d", variable->value.val_int); break; case VT_BOOL: nk_label(context, &variable->name[0], name_flags); nk_labelf(context, value_flags, "%s", variable->value.val_bool ? "True" : "False"); break; case VT_FLOAT: nk_label(context, &variable->name[0], name_flags); nk_labelf(context, value_flags, "%.3f", variable->value.val_float); break; case VT_VEC2: nk_label(context, &variable->name[0], name_flags); nk_labelf(context, value_flags, "%.3f %.3f", variable->value.val_vec2.x, variable->value.val_vec2.y); break; case VT_VEC3: nk_label(context, &variable->name[0], name_flags); nk_labelf(context, value_flags, "%.3f %.3f %.3f", variable->value.val_vec3.x, variable->value.val_vec3.y, variable->value.val_vec3.z); break; case VT_VEC4: nk_label(context, &variable->name[0], name_flags); nk_labelf(context, value_flags, "%.3f %.3f %.3f %.3f", variable->value.val_vec4.x, variable->value.val_vec4.y, variable->value.val_vec4.z, variable->value.val_vec4.w); break; default: nk_label(context, &variable->name[0], name_flags); nk_label(context, "Unsupported Type", value_flags); break; } } for(int i = 0; i < MAX_DEBUG_VARS_PER_FRAME_TEXTURES; i++) { struct Debug_Variable* variable = &debug_vars->texture_vars[i]; if(variable->value.type == VT_NONE) continue; switch(variable->value.type) { case VT_INT: // Texture nk_layout_row_dynamic(context, debug_vars->row_height_texture, 2); nk_label(context, &variable->name[0], name_flags); //nk_image_color(context, nk_image_id(texture_get_texture_handle(variable->value.val_int)), nk_rgb_f(1.f, 1.f, 1.f)); nk_image_color(context, nk_image_id(variable->value.val_int), nk_rgb_f(1.f, 1.f, 1.f)); break; case VT_VEC3: // Color RGB nk_layout_row_dynamic(context, debug_vars->row_height_color, 2); nk_label(context, &variable->name[0], name_flags); nk_button_color(context, nk_rgb_fv(&variable->value.val_vec3)); break; case VT_VEC4: // Color RGBA nk_layout_row_dynamic(context, debug_vars->row_height_color, 2); nk_label(context, &variable->name[0], name_flags); nk_button_color(context, nk_rgba_fv(&variable->value.val_vec4)); break; default: nk_layout_row_dynamic(context, debug_vars->row_height, 2); nk_label(context, &variable->name[0], name_flags); nk_label(context, "Unsupported Type", value_flags); break; } } nk_end(context); } context->style.window.fixed_background.data.color.a = 255; debug_vars_clear(debug_vars); } void debug_vars_clear(struct Debug_Vars* debug_vars) { for(int i = 0; i < MAX_DEBUG_VARS_PER_FRAME_NUMERIC; i++) { memset(&debug_vars->numeric_vars[i].name[0], '\0', MAX_DEBUG_VAR_NAME); variant_free(&debug_vars->numeric_vars[i].value); } for(int i = 0; i < MAX_DEBUG_VARS_PER_FRAME_TEXTURES; i++) { memset(&debug_vars->texture_vars[i].name[0], '\0', MAX_DEBUG_VAR_NAME); variant_free(&debug_vars->texture_vars[i].value); } } void debug_vars_show(const char* name, const struct Variant* value, bool is_numeric) { struct Debug_Vars* debug_vars = game_state_get()->debug_vars; if(!debug_vars->visible) return; struct Debug_Variable* vars_array = is_numeric ? &debug_vars->numeric_vars[0] : &debug_vars->texture_vars[0]; int array_length = is_numeric ? MAX_DEBUG_VARS_PER_FRAME_NUMERIC : MAX_DEBUG_VARS_PER_FRAME_TEXTURES; for(int i = 0; i < array_length; i++) { struct Debug_Variable* variable = &vars_array[i]; if(variable->value.type == VT_NONE) { strncpy(&variable->name[0], name, MAX_DEBUG_VAR_NAME); variant_copy(&variable->value, value); return; } } log_warning("%s Debug Vars Full", is_numeric ? "Numeric" : "Texture"); } void debug_vars_show_int(const char* name, int value) { struct Variant temp_var; variant_assign_int(&temp_var, value); debug_vars_show(name, &temp_var, true); } void debug_vars_show_bool(const char* name, bool value) { struct Variant temp_var; variant_assign_bool(&temp_var, value); debug_vars_show(name, &temp_var, true); } void debug_vars_show_float(const char* name, float value) { struct Variant temp_var; variant_assign_float(&temp_var, value); debug_vars_show(name, &temp_var, true); } void debug_vars_show_texture(const char* name, int texture_index) { struct Variant temp_var; variant_assign_int(&temp_var, texture_index); debug_vars_show(name, &temp_var, false); } void debug_vars_show_vec3(const char* name, const vec3* value) { struct Variant temp_var; variant_assign_vec3(&temp_var, value); debug_vars_show(name, &temp_var, true); } void debug_vars_show_vec2(const char* name, const vec3* value) { struct Variant temp_var; variant_assign_vec2(&temp_var, value); debug_vars_show(name, &temp_var, true); } void debug_vars_show_vec4(const char* name, const vec3* value) { struct Variant temp_var; variant_assign_vec4(&temp_var, value); debug_vars_show(name, &temp_var, true); } void debug_vars_show_color_rgb(const char* name, const vec3* value) { struct Variant temp_var; variant_assign_vec3(&temp_var, value); debug_vars_show(name, &temp_var, false); } void debug_vars_show_color_rgba(const char* name, const vec4* value) { struct Variant temp_var; variant_assign_vec4(&temp_var, value); debug_vars_show(name, &temp_var, false); } void debug_vars_cycle_location(struct Debug_Vars* debug_vars) { if(++debug_vars->location >= DVL_MAX) debug_vars->location = 0; }