diff --git a/README.md b/README.md index d80ab0b..d227b07 100644 --- a/README.md +++ b/README.md @@ -155,10 +155,15 @@ - ## TODO - - Switching between editor and game mode/cameras - - In-game scrollable console/log-viewer + - Console log output + - Console coloured output + - Console commands + - Console fix bug when enabled in editor mode + - Console command history + - Console command help - Player projectiles and sounds - NPR and cross-hatching + - Move Gui_State and Editor_State into game_state and modify usage as needed - Remove model and replace all usages with static mesh - Get editor camera speed and other settings from config file - Re-Implement player logic @@ -401,4 +406,6 @@ * Completed Phase 1 of codebase refactoring * Improved editor camera handling * Re-implemented showing all the entities in the editor - * Player init, update, visual representation and movement \ No newline at end of file + * Player init, update, visual representation and movement + * Switching between editor and game mode/cameras + * In-game basis for scrollable console/log-viewer \ No newline at end of file diff --git a/src/libsymmetry/console.c b/src/libsymmetry/console.c new file mode 100644 index 0000000..698d640 --- /dev/null +++ b/src/libsymmetry/console.c @@ -0,0 +1,81 @@ +#include "console.h" +#include "gui.h" +#include "game.h" +#include "../common/log.h" +#include "../common/common.h" + +#include +#include +#include + +static struct nk_color color_normal; + +static int console_filter(const struct nk_text_edit *box, nk_rune unicode); + +void console_init(struct Console* console) +{ + assert(console); + + console->visible = false; + console->text_region_height = 22.f; + console->line_height = 20.f; + + color_normal = nk_rgb(255, 255, 255); + memset(console->console_command_text, '\0', MAX_CONSOLE_COMMAND_LEN); +} + +void console_toggle(struct Console* console) +{ + console->visible = !console->visible; +} + +void console_update(struct Console* console, struct Gui_State* gui_state, float dt) +{ + if(!console->visible) return; + + struct nk_context* context = &gui_state->context; + struct Game_State* game_state = game_state_get(); + + int win_width = 0, win_height = 0; + platform->window.get_drawable_size(game_state->window, &win_width, &win_height); + int half_height = win_height / 2; + + if(nk_begin_titled(context, "Console", "Console", nk_recti(0, 0, win_width, half_height), NK_WINDOW_SCROLL_AUTO_HIDE)) + { + nk_layout_row_dynamic(context, nk_window_get_height(context) - console->text_region_height * 2, 1); + if(nk_group_begin(context, "Log", NK_WINDOW_SCROLL_AUTO_HIDE)) + { + for(int i = 0; i < MAX_CONSOLE_LINES / 2; i++) + { + nk_layout_row_dynamic(context, console->line_height, 1); + nk_labelf_colored(context, NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE, color_normal, "This is a test log line. Do not panic!"); + } + nk_group_end(context); + } + + nk_layout_row_dynamic(context, console->text_region_height, 1); + int edit_flags = NK_EDIT_GOTO_END_ON_ACTIVATE | NK_EDIT_FIELD | NK_EDIT_SIG_ENTER; + nk_edit_focus(context, edit_flags); + int edit_state = nk_edit_string_zero_terminated(context, edit_flags, console->console_command_text, MAX_CONSOLE_COMMAND_LEN, console_filter); + if(edit_state & NK_EDIT_COMMITED) + { + log_message("New message entered : %s", console->console_command_text); + memset(console->console_command_text, '\0', MAX_CONSOLE_COMMAND_LEN); + } + } + nk_end(context); +} + +void console_destroy(struct Console* console) +{ + +} + +int console_filter(const struct nk_text_edit *box, nk_rune unicode) +{ + NK_UNUSED(box); + if(unicode > 128 || unicode == 96) // Ignore tilde or anything other than ascii + return nk_false; + else + return nk_true; +} \ No newline at end of file diff --git a/src/libsymmetry/console.h b/src/libsymmetry/console.h new file mode 100644 index 0000000..dfb4d96 --- /dev/null +++ b/src/libsymmetry/console.h @@ -0,0 +1,24 @@ +#ifndef CONSOLE_H +#define CONSOLE_H + +#include + +#define MAX_CONSOLE_COMMAND_LEN 128 +#define MAX_CONSOLE_LINES 1024 +#define MAX_CONSOLE_LINE_LEN 256 + +struct Console +{ + bool visible; + float text_region_height; + float line_height; + char console_command_text[MAX_CONSOLE_COMMAND_LEN]; +}; + +void console_init(struct Console* console); +void console_toggle(struct Console* console); +void console_update(struct Console* console, struct Gui_State* gui_state, float dt); +void console_destroy(struct Console* console); + + +#endif \ No newline at end of file diff --git a/src/libsymmetry/game.c b/src/libsymmetry/game.c index 4af570f..9a3b4aa 100644 --- a/src/libsymmetry/game.c +++ b/src/libsymmetry/game.c @@ -25,6 +25,7 @@ #include "gui.h" #include "editor.h" #include "sprite.h" +#include "console.h" #include "../common/string_utils.h" #include "../common/parser.h" #include "../common/hashmap.h" @@ -53,9 +54,6 @@ static void on_collision_test(struct Entity* this_ent, struct Entity* other_ent, static struct Game_State* game_state = NULL; struct Platform_Api* platform = NULL; - -static int suz_id = 0; - bool game_init(struct Window* window, struct Platform_Api* platform_api) { if(!platform_api) @@ -77,8 +75,9 @@ bool game_init(struct Window* window, struct Platform_Api* platform_api) game_state->window = window; game_state->is_initialized = false; game_state->game_mode = GAME_MODE_GAME; - game_state->renderer = malloc(sizeof(*game_state->renderer)); - game_state->scene = malloc(sizeof(*game_state->scene)); + game_state->renderer = calloc(1, sizeof(*game_state->renderer)); + game_state->scene = calloc(1, sizeof(*game_state->scene)); + game_state->console = calloc(1, sizeof(*game_state->console)); log_file_handle_set(platform->log.file_handle_get()); if(!gl_load_extentions()) @@ -96,6 +95,8 @@ bool game_init(struct Window* window, struct Platform_Api* platform_api) shader_init(); texture_init(); framebuffer_init(); + gui_init(); + console_init(game_state->console); geom_init(); platform->physics.init(); platform->physics.gravity_set(0.f, -9.8f, 0.f); @@ -488,6 +489,7 @@ void game_update(float dt, bool* window_should_close) if(input_is_key_pressed(KEY_ESCAPE)) *window_should_close = true; if(input_map_state_get("Window_Fullscreen", KS_RELEASED)) platform->window.fullscreen_set(game_state->window, 1); if(input_map_state_get("Window_Maximize", KS_RELEASED)) platform->window.fullscreen_set(game_state->window, 0); + if(input_map_state_get("Console_Toggle", KS_RELEASED)) console_toggle(game_state->console); if(input_map_state_get("Editor_Toggle", KS_RELEASED)) { //editor_toggle(); @@ -512,6 +514,7 @@ void game_update(float dt, bool* window_should_close) //game_debug(dt); //debug_gui(dt); + console_update(game_state->console, gui_state_get(), dt); scene_update(game_state->scene, dt); if(game_state->game_mode == GAME_MODE_GAME) { @@ -1749,11 +1752,14 @@ void game_cleanup(void) scene_destroy(game_state->scene); input_cleanup(); renderer_cleanup(game_state->renderer); + gui_cleanup(); + console_destroy(game_state->console); geom_cleanup(); framebuffer_cleanup(); texture_cleanup(); shader_cleanup(); + free(game_state->console); free(game_state->scene); free(game_state->renderer); } diff --git a/src/libsymmetry/game.h b/src/libsymmetry/game.h index bbced1e..734c766 100644 --- a/src/libsymmetry/game.h +++ b/src/libsymmetry/game.h @@ -15,6 +15,8 @@ struct Renderer; struct Scene; struct Entity; struct Player; +struct Console; +struct Gui_State; enum Game_Mode { @@ -24,11 +26,13 @@ enum Game_Mode struct Game_State { - bool is_initialized; - int game_mode; - struct Window* window; - struct Renderer* renderer; - struct Scene* scene; + bool is_initialized; + int game_mode; + struct Window* window; + struct Renderer* renderer; + struct Scene* scene; + struct Console* console; + struct Gui_State* gui; }; diff --git a/src/libsymmetry/input.c b/src/libsymmetry/input.c index 6db9b92..d7e9725 100644 --- a/src/libsymmetry/input.c +++ b/src/libsymmetry/input.c @@ -28,21 +28,22 @@ void input_init(void) key_bindings = hashmap_new(); /* Default keys for fallback */ - struct Key_Binding forward_keys = {KEY_W, KMOD_NONE, KEY_UP, KMOD_NONE, KS_INACTIVE}; - struct Key_Binding backward_keys = {KEY_S, KMOD_NONE, KEY_DOWN, KMOD_NONE, KS_INACTIVE}; - struct Key_Binding up_keys = {KEY_Q, KMOD_NONE, KEY_NONE, KMOD_NONE, KS_INACTIVE}; - struct Key_Binding down_keys = {KEY_E, KMOD_NONE, KEY_NONE, KMOD_NONE, KS_INACTIVE}; - struct Key_Binding left_keys = {KEY_A, KMOD_NONE, KEY_LEFT, KMOD_NONE, KS_INACTIVE}; - struct Key_Binding right_keys = {KEY_D, KMOD_NONE, KEY_RIGHT, KMOD_NONE, KS_INACTIVE}; - struct Key_Binding turn_right_keys = {KEY_L, KMOD_NONE, KEY_NONE, KMOD_NONE, KS_INACTIVE}; - struct Key_Binding turn_left_keys = {KEY_J, KMOD_NONE, KEY_NONE, KMOD_NONE, KS_INACTIVE}; - struct Key_Binding turn_up_keys = {KEY_I, KMOD_NONE, KEY_NONE, KMOD_NONE, KS_INACTIVE}; - struct Key_Binding turn_down_keys = {KEY_K, KMOD_NONE, KEY_NONE, KMOD_NONE, KS_INACTIVE}; - struct Key_Binding sprint_keys = {KEY_LSHIFT, KMOD_NONE, KEY_RSHIFT, KMOD_NONE, KS_INACTIVE}; - struct Key_Binding ed_toggle_keys = {KEY_F1, KMOD_NONE, KEY_NONE, KMOD_NONE, KS_INACTIVE}; - struct Key_Binding win_fullscr_keys = {KEY_F11, KMOD_NONE, KEY_NONE, KMOD_NONE, KS_INACTIVE}; - struct Key_Binding win_max_keys = {KEY_F12, KMOD_NONE, KEY_NONE, KMOD_NONE, KS_INACTIVE}; - struct Key_Binding reload_game_keys = {KEY_F5, KMOD_NONE, KEY_NONE, KMOD_NONE, KS_INACTIVE}; + struct Key_Binding forward_keys = {KEY_W, KMOD_NONE, KEY_UP, KMOD_NONE, KS_INACTIVE}; + struct Key_Binding backward_keys = {KEY_S, KMOD_NONE, KEY_DOWN, KMOD_NONE, KS_INACTIVE}; + struct Key_Binding up_keys = {KEY_Q, KMOD_NONE, KEY_NONE, KMOD_NONE, KS_INACTIVE}; + struct Key_Binding down_keys = {KEY_E, KMOD_NONE, KEY_NONE, KMOD_NONE, KS_INACTIVE}; + struct Key_Binding left_keys = {KEY_A, KMOD_NONE, KEY_LEFT, KMOD_NONE, KS_INACTIVE}; + struct Key_Binding right_keys = {KEY_D, KMOD_NONE, KEY_RIGHT, KMOD_NONE, KS_INACTIVE}; + struct Key_Binding turn_right_keys = {KEY_L, KMOD_NONE, KEY_NONE, KMOD_NONE, KS_INACTIVE}; + struct Key_Binding turn_left_keys = {KEY_J, KMOD_NONE, KEY_NONE, KMOD_NONE, KS_INACTIVE}; + struct Key_Binding turn_up_keys = {KEY_I, KMOD_NONE, KEY_NONE, KMOD_NONE, KS_INACTIVE}; + struct Key_Binding turn_down_keys = {KEY_K, KMOD_NONE, KEY_NONE, KMOD_NONE, KS_INACTIVE}; + struct Key_Binding sprint_keys = {KEY_LSHIFT, KMOD_NONE, KEY_RSHIFT, KMOD_NONE, KS_INACTIVE}; + struct Key_Binding editor_toggle_keys = {KEY_F1, KMOD_NONE, KEY_NONE, KMOD_NONE, KS_INACTIVE}; + struct Key_Binding console_toggle_keys = {KEY_TILDE, KMOD_NONE, KEY_NONE, KMOD_NONE, KS_INACTIVE}; + struct Key_Binding win_fullscr_keys = {KEY_F11, KMOD_NONE, KEY_NONE, KMOD_NONE, KS_INACTIVE}; + struct Key_Binding win_max_keys = {KEY_F12, KMOD_NONE, KEY_NONE, KMOD_NONE, KS_INACTIVE}; + struct Key_Binding reload_game_keys = {KEY_F5, KMOD_NONE, KEY_NONE, KMOD_NONE, KS_INACTIVE}; input_map_create("Move_Forward", forward_keys); input_map_create("Move_Backward", backward_keys); input_map_create("Move_Up", up_keys); @@ -54,7 +55,8 @@ void input_init(void) input_map_create("Turn_Up", turn_up_keys); input_map_create("Turn_Down", turn_down_keys); input_map_create("Sprint", sprint_keys); - input_map_create("Editor_Toggle", ed_toggle_keys); + input_map_create("Editor_Toggle", editor_toggle_keys); + input_map_create("Console_Toggle", console_toggle_keys); input_map_create("Window_Fullscreen", win_fullscr_keys); input_map_create("Window_Maximize", win_max_keys); input_map_create("Reload_Game_Lib", reload_game_keys); diff --git a/src/libsymmetry/input.h b/src/libsymmetry/input.h index a0c94dc..b1d6bec 100644 --- a/src/libsymmetry/input.h +++ b/src/libsymmetry/input.h @@ -87,6 +87,7 @@ enum Keyboard_Key KEY_8 = SDLK_8, KEY_9 = SDLK_9, KEY_BACKSPACE = SDLK_BACKSPACE, + KEY_TILDE = SDLK_BACKQUOTE, KEY_TAB = SDLK_TAB, KEY_RETURN = SDLK_RETURN, KEY_RETURN2 = SDLK_RETURN2, diff --git a/src/libsymmetry/renderer.c b/src/libsymmetry/renderer.c index caf0bc6..702977e 100644 --- a/src/libsymmetry/renderer.c +++ b/src/libsymmetry/renderer.c @@ -40,7 +40,6 @@ void renderer_init(struct Renderer* renderer) glEnable(GL_CULL_FACE); glCullFace(GL_BACK); platform->windowresize_callback_set(on_framebuffer_size_change); - gui_init(); struct Hashmap* cvars = platform->config.get(); renderer->settings.fog.mode = hashmap_int_get(cvars, "fog_mode"); @@ -441,7 +440,6 @@ void renderer_cleanup(struct Renderer* renderer) im_cleanup(); sprite_batch_remove(renderer->sprite_batch); free(renderer->sprite_batch); - gui_cleanup(); geom_remove(renderer->quad_geo); framebuffer_remove(renderer->def_fbo); texture_remove(renderer->def_albedo_tex); diff --git a/src/libsymmetry/sprite.c b/src/libsymmetry/sprite.c index 6c9f4e8..a6c2fe8 100644 --- a/src/libsymmetry/sprite.c +++ b/src/libsymmetry/sprite.c @@ -123,7 +123,8 @@ void sprite_batch_end(struct Sprite_Batch* batch) void sprite_batch_render(struct Sprite_Batch* batch) { assert(batch); - + if(batch->current_sprite_count == 0) return; + texture_bind(batch->texture); glBindVertexArray(batch->vao);