diff --git a/src/client/component/console.cpp b/src/client/component/console.cpp index 9b75ceff..0840553d 100644 --- a/src/client/component/console.cpp +++ b/src/client/component/console.cpp @@ -31,6 +31,7 @@ namespace console HANDLE kill_event; char buffer[512]{}; int cursor; + std::deque history; std::int32_t history_index = -1; } con{}; @@ -180,18 +181,16 @@ namespace console { case VK_UP: { - const auto& history = game_console::get_history(); - - if (++con.history_index >= history.size()) + if (++con.history_index >= con.history.size()) { - con.history_index = static_cast(history.size()) - 1; + con.history_index = static_cast(con.history.size()) - 1; } clear(); if (con.history_index != -1) { - strncpy_s(con.buffer, history.at(con.history_index).data(), sizeof(con.buffer)); + strncpy_s(con.buffer, con.history.at(con.history_index).data(), sizeof(con.buffer)); con.cursor = static_cast(strlen(con.buffer)); } @@ -200,8 +199,6 @@ namespace console } case VK_DOWN: { - const auto& history = game_console::get_history(); - if (--con.history_index < -1) { con.history_index = -1; @@ -211,7 +208,7 @@ namespace console if (con.history_index != -1) { - strncpy_s(con.buffer, history.at(con.history_index).data(), sizeof(con.buffer)); + strncpy_s(con.buffer, con.history.at(con.history_index).data(), sizeof(con.buffer)); con.cursor = static_cast(strlen(con.buffer)); } @@ -240,26 +237,24 @@ namespace console } case VK_RETURN: { - auto& history = game_console::get_history(); - if (con.history_index != -1) { - const auto itr = history.begin() + con.history_index; + const auto itr = con.history.begin() + con.history_index; if (*itr == con.buffer) { - history.erase(history.begin() + con.history_index); + con.history.erase(con.history.begin() + con.history_index); } } if (con.buffer[0]) { - history.push_front(con.buffer); + con.history.push_front(con.buffer); } - if (history.size() > 10) + if (con.history.size() > 10) { - history.erase(history.begin() + 10); + con.history.erase(con.history.begin() + 10); } con.history_index = -1; diff --git a/src/client/component/game_console.cpp b/src/client/component/game_console.cpp index 4d2e62b0..a3bf435d 100644 --- a/src/client/component/game_console.cpp +++ b/src/client/component/game_console.cpp @@ -14,6 +14,7 @@ #include #include +#include #define console_font game::R_RegisterFont("fonts/fira_mono_regular.ttf", 18) #define material_white game::Material_RegisterHandle("white") @@ -33,6 +34,8 @@ namespace game_console int info_line_count; }; + using output_queue = std::deque; + struct ingame_console { char buffer[256]; @@ -46,7 +49,7 @@ namespace game_console bool output_visible; int display_line_offset; int line_count; - std::deque output; + utils::concurrency::container output{}; }; ingame_console con; @@ -71,17 +74,20 @@ namespace game_console void print(const std::string& data) { - if (con.visible_line_count > 0 && con.display_line_offset == (con.output.size() - con.visible_line_count)) + con.output.access([&](output_queue& output) { - con.display_line_offset++; - } + if (con.visible_line_count > 0 + && con.display_line_offset == (output.size() - con.visible_line_count)) + { + con.display_line_offset++; + } - con.output.push_back(data); - - if (con.output.size() > 1024) - { - con.output.pop_front(); - } + output.push_back(data); + if (output.size() > 512) + { + output.pop_front(); + } + }); } void toggle_console() @@ -298,19 +304,19 @@ namespace game_console } } - void draw_output_scrollbar(const float x, float y, const float width, const float height) + void draw_output_scrollbar(const float x, float y, const float width, const float height, output_queue& output) { const auto _x = (x + width) - 10.0f; draw_box(_x, y, 10.0f, height, dvars::con_outputBarColor->current.vector); auto _height = height; - if (con.output.size() > con.visible_line_count) + if (output.size() > con.visible_line_count) { - const auto percentage = static_cast(con.visible_line_count) / con.output.size(); + const auto percentage = static_cast(con.visible_line_count) / output.size(); _height *= percentage; const auto remainingSpace = height - _height; - const auto percentageAbove = static_cast(con.display_line_offset) / (con.output.size() - con. + const auto percentageAbove = static_cast(con.display_line_offset) / (output.size() - con. visible_line_count); y = y + (remainingSpace * percentageAbove); @@ -319,42 +325,45 @@ namespace game_console draw_box(_x, y, 10.0f, _height, dvars::con_outputSliderColor->current.vector); } - void draw_output_text(const float x, float y) + void draw_output_text(const float x, float y, output_queue& output) { - const auto offset = con.output.size() >= con.visible_line_count + const auto offset = output.size() >= con.visible_line_count ? 0.0f - : (con.font_height * (con.visible_line_count - con.output.size())); + : (con.font_height * (con.visible_line_count - output.size())); for (auto i = 0; i < con.visible_line_count; i++) { y = console_font->pixelHeight + y; const auto index = i + con.display_line_offset; - if (index >= con.output.size()) + if (index >= output.size()) { break; } - game::R_AddCmdDrawText(con.output.at(index).data(), 0x7FFF, console_font, x, y + offset, 1.0f, 1.0f, + game::R_AddCmdDrawText(output.at(index).data(), 0x7FFF, console_font, x, y + offset, 1.0f, 1.0f, 0.0f, color_white, 0); } } void draw_output_window() { - draw_box(con.screen_min[0], con.screen_min[1] + 32.0f, con.screen_max[0] - con.screen_min[0], - (con.screen_max[1] - con.screen_min[1]) - 32.0f, dvars::con_outputWindowColor->current.vector); + con.output.access([](output_queue& output) + { + draw_box(con.screen_min[0], con.screen_min[1] + 32.0f, con.screen_max[0] - con.screen_min[0], + (con.screen_max[1] - con.screen_min[1]) - 32.0f, dvars::con_outputWindowColor->current.vector); - const auto x = con.screen_min[0] + 6.0f; - const auto y = (con.screen_min[1] + 32.0f) + 6.0f; - const auto width = (con.screen_max[0] - con.screen_min[0]) - 12.0f; - const auto height = ((con.screen_max[1] - con.screen_min[1]) - 32.0f) - 12.0f; + const auto x = con.screen_min[0] + 6.0f; + const auto y = (con.screen_min[1] + 32.0f) + 6.0f; + const auto width = (con.screen_max[0] - con.screen_min[0]) - 12.0f; + const auto height = ((con.screen_max[1] - con.screen_min[1]) - 32.0f) - 12.0f; - game::R_AddCmdDrawText("h2-mod", 0x7FFFFFFF, console_font, x, - ((height - 16.0f) + y) + console_font->pixelHeight, 1.0f, 1.0f, 0.0f, color_h2, 0); + game::R_AddCmdDrawText("h2-mod", 0x7FFFFFFF, console_font, x, + ((height - 16.0f) + y) + console_font->pixelHeight, 1.0f, 1.0f, 0.0f, color_h2, 0); - draw_output_scrollbar(x, y, width, height); - draw_output_text(x, y); + draw_output_scrollbar(x, y, width, height, output); + draw_output_text(x, y, output); + }); } void draw_console() @@ -478,7 +487,10 @@ namespace game_console { clear(); con.line_count = 0; - con.output.clear(); + con.output.access([](output_queue& output) + { + output.clear(); + }); history_index = -1; history.clear(); @@ -628,19 +640,24 @@ namespace game_console //scroll through output if (key == game::keyNum_t::K_MWHEELUP || key == game::keyNum_t::K_PGUP) { - if (con.output.size() > con.visible_line_count && con.display_line_offset > 0) + con.output.access([](output_queue& output) { - con.display_line_offset--; - } + if (output.size() > con.visible_line_count && con.display_line_offset > 0) + { + con.display_line_offset--; + } + }); } else if (key == game::keyNum_t::K_MWHEELDOWN || key == game::keyNum_t::K_PGDN) { - if (con.output.size() > con.visible_line_count && con.display_line_offset < (con.output.size() - - con. - visible_line_count)) + con.output.access([](output_queue& output) { - con.display_line_offset++; - } + if (output.size() > con.visible_line_count + && con.display_line_offset < (output.size() - con.visible_line_count)) + { + con.display_line_offset++; + } + }); } if (key == game::keyNum_t::K_ENTER) @@ -708,7 +725,7 @@ namespace game_console if (match_compare(input, name, exact)) { - suggestions.push_back({ cmd->name, "" }); + suggestions.push_back({cmd->name, ""}); } if (exact && suggestions.size() > 1) @@ -721,21 +738,14 @@ namespace game_console } } - std::deque& get_output() - { - return con.output; - } - - std::deque& get_history() - { - return history; - } - void clear_console() { clear(); con.line_count = 0; - con.output.clear(); + con.output.access([](output_queue& output) + { + output.clear(); + }); history_index = -1; history.clear(); } @@ -786,7 +796,7 @@ namespace game_console ); dvars::con_outputSliderColor = dvars::register_vec4( "con_outputSliderColor", - 0.3f, 0.7f, 0.3f, 1.0f, 0.0f, 1.0f, + 0.9f, 0.9f, 0.5f, 1.0f, 0.0f, 1.0f, game::DVAR_FLAG_SAVED, "color of console output slider" ); diff --git a/src/client/component/game_console.hpp b/src/client/component/game_console.hpp index 93cfed50..41e3e75e 100644 --- a/src/client/component/game_console.hpp +++ b/src/client/component/game_console.hpp @@ -13,7 +13,4 @@ namespace game_console void execute(const char* cmd); void clear_console(); void add(const std::string& cmd); - - std::deque& get_output(); - std::deque& get_history(); } \ No newline at end of file diff --git a/src/client/component/gui_console.cpp b/src/client/component/gui_console.cpp deleted file mode 100644 index 1cf45274..00000000 --- a/src/client/component/gui_console.cpp +++ /dev/null @@ -1,213 +0,0 @@ -#include -#include "loader/component_loader.hpp" - -#include "game/game.hpp" -#include "game/dvars.hpp" - -#include "scheduler.hpp" -#include "command.hpp" -#include "game_console.hpp" -#include "gui.hpp" - -#include -#include -#include - -namespace gui::console -{ - namespace - { - bool auto_scroll = true; - int history_index = -1; - std::string input; - std::string filter; - std::vector matches; - - int input_text_edit(ImGuiInputTextCallbackData* data) - { - switch (data->EventFlag) - { - case ImGuiInputTextFlags_CallbackCompletion: - { - matches.clear(); - const std::string text = data->Buf; - - if (text.find(" ") != std::string::npos) - { - game_console::find_matches(text.substr(0, text.find(" ")), matches, true); - } - else - { - game_console::find_matches(text, matches, false); - } - - if (matches.size() < 24 && matches.size() > 0) - { - const auto match = matches.begin()->name.data(); - data->DeleteChars(0, data->BufTextLen); - data->InsertChars(0, match, match + strlen(match)); - } - - break; - } - case ImGuiInputTextFlags_CallbackHistory: - { - const auto& history = game_console::get_history(); - - if (data->EventKey == ImGuiKey_UpArrow) - { - if (++history_index >= history.size()) - { - history_index = static_cast(history.size()) - 1; - } - - data->DeleteChars(0, data->BufTextLen); - - if (history_index != -1) - { - const auto text = history.at(history_index).data(); - data->InsertChars(0, text, text + strlen(text)); - } - } - else if (data->EventKey == ImGuiKey_DownArrow) - { - if (--history_index < -1) - { - history_index = -1; - } - - data->DeleteChars(0, data->BufTextLen); - - if (history_index != -1) - { - const auto text = history.at(history_index).data(); - data->InsertChars(0, text, text + strlen(text)); - } - } - - break; - } - } - - return 0; - } - - std::string get_filtered_text() - { - std::string text{}; - - const auto& output = game_console::get_output(); - for (const auto& line : output) - { - if (utils::string::find_lower(line, filter)) - { - text.append(line.data()); - text.append("\n"); - } - } - - if (!text.empty() && text[text.size() - 1] == '\n') - { - text.pop_back(); - } - - return text; - } - - void on_frame() - { - static auto* enabled = &gui::enabled_menus["console"]; - if (!*enabled) - { - return; - } - - const auto filtered_text = get_filtered_text(); - const float footer_height_to_reserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing(); - static const auto input_text_flags = ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CallbackCompletion | - ImGuiInputTextFlags_CallbackHistory; - - ImGui::Begin("Console", enabled); - - if (ImGui::BeginPopup("Options")) - { - ImGui::Checkbox("Auto-scroll", &auto_scroll); - ImGui::EndPopup(); - } - - if (ImGui::Button("Clear")) - { - game_console::clear_console(); - } - - ImGui::SameLine(); - - if (ImGui::Button("Copy")) - { - utils::string::set_clipboard_data(filtered_text); - gui::notification("Console", "Text copied to clipboard"); - } - - ImGui::Separator(); - - if (ImGui::Button("Options")) - { - ImGui::OpenPopup("Options"); - } - - ImGui::SameLine(); - ImGui::InputText("Filter", &filter); - - ImGui::BeginChild("console_scroll", ImVec2(0, -footer_height_to_reserve), false); - - const auto& output = game_console::get_output(); - for (const auto& line : output) - { - if (utils::string::find_lower(line, filter)) - { - ImGui::Text(line.data(), ImVec2(-1, -1)); - } - } - - if (auto_scroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY()) - { - ImGui::SetScrollHereY(1.0f); - } - - ImGui::EndChild(); - - if (ImGui::InputText("Input", &input, input_text_flags, input_text_edit)) - { - auto& history = game_console::get_history(); - - if (history_index != -1) - { - const auto itr = history.begin() + history_index; - - if (*itr == input) - { - history.erase(history.begin() + history_index); - } - } - - ImGui::SetKeyboardFocusHere(-1); - game_console::add(input.data()); - history_index = -1; - input.clear(); - } - - ImGui::End(); - } - } - - class component final : public component_interface - { - public: - void post_unpack() override - { - gui::on_frame(on_frame); - } - }; -} - -REGISTER_COMPONENT(gui::console::component) diff --git a/src/client/component/gui_script_console.cpp b/src/client/component/gui_script_console.cpp index 360fd96d..2c036934 100644 --- a/src/client/component/gui_script_console.cpp +++ b/src/client/component/gui_script_console.cpp @@ -202,9 +202,9 @@ namespace gui::script_console } history.push_front(input); - if (history.size() > 10) + if (history.size() > 50) { - history.erase(history.begin() + 10); + history.erase(history.begin() + 50); } ImGui::SetKeyboardFocusHere(-1);