From 8431cddb1470343cf19ce932df6bcd8b2351b781 Mon Sep 17 00:00:00 2001 From: Kenix3 Date: Tue, 2 Aug 2022 23:32:37 -0400 Subject: [PATCH] LUS Cleanup: GameOverlay and moves various GUI related files to it's own filter. --- libultraship/libultraship/GameOverlay.cpp | 403 +++++++++--------- libultraship/libultraship/GameOverlay.h | 24 +- .../libultraship/libultraship.vcxproj.filters | 42 +- 3 files changed, 238 insertions(+), 231 deletions(-) diff --git a/libultraship/libultraship/GameOverlay.cpp b/libultraship/libultraship/GameOverlay.cpp index ccbdc142c..01d889dd6 100644 --- a/libultraship/libultraship/GameOverlay.cpp +++ b/libultraship/libultraship/GameOverlay.cpp @@ -10,219 +10,226 @@ #include "Lib/ImGui/imgui_internal.h" #include "Utils/StringHelper.h" -void Ship::GameOverlay::LoadFont(const std::string& name, const std::string& path, float fontSize) { - ImGuiIO& io = ImGui::GetIO(); - std::shared_ptr base = GlobalCtx2::GetInstance()->GetResourceManager()->GetArchive(); - std::shared_ptr font = std::make_shared(); - base->LoadFile(path, false, font); - if (font->bIsLoaded) { - char* font_data = new char[font->dwBufferSize]; - memcpy(font_data, font->buffer.get(), font->dwBufferSize); - Fonts[name] = io.Fonts->AddFontFromMemoryTTF(font_data, font->dwBufferSize, fontSize); +namespace Ship { + void GameOverlay::LoadFont(const std::string& name, const std::string& path, float fontSize) { + ImGuiIO& io = ImGui::GetIO(); + std::shared_ptr base = GlobalCtx2::GetInstance()->GetResourceManager()->GetArchive(); + std::shared_ptr font = std::make_shared(); + base->LoadFile(path, false, font); + if (font->bIsLoaded) { + char* font_data = new char[font->dwBufferSize]; + memcpy(font_data, font->buffer.get(), font->dwBufferSize); + Fonts[name] = io.Fonts->AddFontFromMemoryTTF(font_data, font->dwBufferSize, fontSize); + } } -} -void Ship::GameOverlay::TextDraw(float x, float y, bool shadow, ImVec4 color, const char* fmt, ...) { - char buf[1024]; - va_list args; - va_start(args, fmt); - vsnprintf(buf, IM_ARRAYSIZE(buf), fmt, args); - buf[IM_ARRAYSIZE(buf) - 1] = 0; - va_end(args); + void GameOverlay::TextDraw(float x, float y, bool shadow, ImVec4 color, const char* fmt, ...) { + char buf[1024]; + va_list args; + va_start(args, fmt); + vsnprintf(buf, IM_ARRAYSIZE(buf), fmt, args); + buf[IM_ARRAYSIZE(buf) - 1] = 0; + va_end(args); - ImGui::PushStyleColor(ImGuiCol_Text, color); - ImGui::PushFont(Fonts[this->CurrentFont]); - if (shadow) { - ImGui::SetCursorPos(ImVec2(x + 1, y + 1)); - ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(.0f, .0f, .0f, color.w)); + ImGui::PushStyleColor(ImGuiCol_Text, color); + ImGui::PushFont(Fonts[this->CurrentFont]); + if (shadow) { + ImGui::SetCursorPos(ImVec2(x + 1, y + 1)); + ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(.0f, .0f, .0f, color.w)); + ImGui::Text(buf, args); + } + ImGui::PopStyleColor(); + ImGui::SetCursorPos(ImVec2(x, y)); ImGui::Text(buf, args); + ImGui::PopFont(); + ImGui::PopStyleColor(); } - ImGui::PopStyleColor(); - ImGui::SetCursorPos(ImVec2(x, y)); - ImGui::Text(buf, args); - ImGui::PopFont(); - ImGui::PopStyleColor(); -} -void Ship::GameOverlay::TextDrawNotification(float duration, bool shadow, const char* fmt, ...) { - char buf[1024]; - va_list args; - va_start(args, fmt); - vsnprintf(buf, IM_ARRAYSIZE(buf), fmt, args); - buf[IM_ARRAYSIZE(buf) - 1] = 0; - va_end(args); - this->RegisteredOverlays[StringHelper::Sprintf("NotificationID:%d%d", rand(), this->RegisteredOverlays.size())] = new Overlay({ OverlayType::NOTIFICATION, ImStrdup(buf), duration, duration }); - NeedsCleanup = true; -} - -void Ship::GameOverlay::CleanupNotifications() { - if(!NeedsCleanup) return; - for (auto it = this->RegisteredOverlays.begin(); it != this->RegisteredOverlays.end(); ) { - if (it->second->type == OverlayType::NOTIFICATION && it->second->duration <= 0.0f) { - it = this->RegisteredOverlays.erase(it); - } else { - ++it; - } + void GameOverlay::TextDrawNotification(float duration, bool shadow, const char* fmt, ...) { + char buf[1024]; + va_list args; + va_start(args, fmt); + vsnprintf(buf, IM_ARRAYSIZE(buf), fmt, args); + buf[IM_ARRAYSIZE(buf) - 1] = 0; + va_end(args); + this->RegisteredOverlays[StringHelper::Sprintf("NotificationID:%d%d", rand(), this->RegisteredOverlays.size())] = new Overlay({ OverlayType::NOTIFICATION, ImStrdup(buf), duration, duration }); + NeedsCleanup = true; } - NeedsCleanup = false; -} -float Ship::GameOverlay::GetScreenWidth() { - const ImGuiViewport* viewport = ImGui::GetMainViewport(); - return viewport->Size.x; -} - -float Ship::GameOverlay::GetScreenHeight() { - const ImGuiViewport* viewport = ImGui::GetMainViewport(); - return viewport->Size.y; -} - -float Ship::GameOverlay::GetStringWidth(const char* text) { - return CalculateTextSize(text).x; -} - -ImVec2 Ship::GameOverlay::CalculateTextSize(const char* text, const char* text_end, bool hide_text_after_double_hash, float wrap_width) { - ImGuiContext& g = *GImGui; - - const char* text_display_end; - if (hide_text_after_double_hash) - text_display_end = ImGui::FindRenderedTextEnd(text, text_end); // Hide anything after a '##' string - else - text_display_end = text_end; - - GameOverlay* overlay = SohImGui::overlay; - - ImFont* font = overlay->CurrentFont == "Default" ? g.Font : overlay->Fonts[overlay->CurrentFont]; - const float font_size = font->FontSize; - if (text == text_display_end) - return ImVec2(0.0f, font_size); - ImVec2 text_size = font->CalcTextSizeA(font_size, FLT_MAX, wrap_width, text, text_display_end, NULL); - - // Round - // FIXME: This has been here since Dec 2015 (7b0bf230) but down the line we want this out. - // FIXME: Investigate using ceilf or e.g. - // - https://git.musl-libc.org/cgit/musl/tree/src/math/ceilf.c - // - https://embarkstudios.github.io/rust-gpu/api/src/libm/math/ceilf.rs.html - text_size.x = IM_FLOOR(text_size.x + 0.99999f); - - return text_size; -} - -void Ship::GameOverlay::Init() { - this->LoadFont("Press Start 2P", "assets/ship_of_harkinian/fonts/PressStart2P-Regular.ttf", 12.0f); - this->LoadFont("Fipps", "assets/ship_of_harkinian/fonts/Fipps-Regular.otf", 32.0f); - const std::string DefaultFont = this->Fonts.begin()->first; - if(!this->Fonts.empty()) { - const std::string font = CVar_GetString("gOverlayFont", ImStrdup(DefaultFont.c_str())); - for (auto& [name, _] : this->Fonts) { - if (font.starts_with(name)) { - this->CurrentFont = name; - break; + void GameOverlay::CleanupNotifications() { + if (!NeedsCleanup) return; + for (auto it = this->RegisteredOverlays.begin(); it != this->RegisteredOverlays.end(); ) { + if (it->second->type == OverlayType::NOTIFICATION && it->second->duration <= 0.0f) { + it = this->RegisteredOverlays.erase(it); } - this->CurrentFont = DefaultFont; - } - } - SohImGui::console->Commands["overlay"] = { OverlayCommand, "Draw an overlay using a cvar value" }; -} - -void Ship::GameOverlay::DrawSettings() { - ImGui::Text("Overlays Text Font"); - if (ImGui::BeginCombo("##TextFont", this->CurrentFont.c_str())) { - for (auto& [name, font] : this->Fonts) { - if (ImGui::Selectable(name.c_str(), name == this->CurrentFont)) { - this->CurrentFont = name; - CVar_SetString("gOverlayFont", ImStrdup(name.c_str())); - SohImGui::needs_save = true; + else { + ++it; } - - } - ImGui::EndCombo(); - } -} - - -void Ship::GameOverlay::Draw() { - const ImGuiViewport* viewport = ImGui::GetMainViewport(); - - ImGui::SetNextWindowPos(viewport->Pos, ImGuiCond_Always); - ImGui::SetNextWindowSize(viewport->Size, ImGuiCond_Always); - ImGui::Begin("SoHOverlay", nullptr, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoBackground | - ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoInputs); - - this->CleanupNotifications(); - - float textY = 50; - float notY = 0; - - for (auto &[key, overlay] : this->RegisteredOverlays) { - - if (overlay->type == OverlayType::TEXT) { - const char* text = ImStrdup(overlay->value); - const CVar* var = CVar_Get(text); - ImVec4 color = ImVec4(1.0f, 1.0f, 1.0f, 1.0f); - - switch (var->type) { - case CVarType::Float: - this->TextDraw(30, textY, true, color, "%s %.2f", text, var->value.valueFloat); - break; - case CVarType::S32: - this->TextDraw(30, textY, true, color, "%s %d", text, var->value.valueS32); - break; - case CVarType::String: - this->TextDraw(30, textY, true, color, "%s %s", text, var->value.valueStr); - break; - case CVarType::RGBA: - this->TextDraw(30, textY, true, color, "#%08X", text, var->value.valueRGBA); - break; - } - - free((void*) text); - textY += 30; - } - - if (overlay->type == OverlayType::NOTIFICATION && overlay->duration > 0) { - const char* text = overlay->value; - const float duration = overlay->duration / overlay->fadeTime; - - const ImVec4 color = ImVec4(1.0f, 1.0f, 1.0f, duration); - const float textWidth = this->GetStringWidth(overlay->value); - - this->TextDraw(GetScreenWidth() - textWidth - 40, GetScreenHeight() - 40 - notY, true, color, text); - notY += 30; - overlay->duration -= .05f; } + NeedsCleanup = false; } - ImGui::End(); -} - - -bool Ship::OverlayCommand(const std::vector& args) { - if (args.size() < 3) { - return CMD_FAILED; + float GameOverlay::GetScreenWidth() { + const ImGuiViewport* viewport = ImGui::GetMainViewport(); + return viewport->Size.x; } - if (CVar_Get(args[2].c_str()) != nullptr) { - const char* key = args[2].c_str(); + float GameOverlay::GetScreenHeight() { + const ImGuiViewport* viewport = ImGui::GetMainViewport(); + return viewport->Size.y; + } + + float GameOverlay::GetStringWidth(const char* text) { + return CalculateTextSize(text).x; + } + + ImVec2 GameOverlay::CalculateTextSize(const char* text, const char* text_end, bool hide_text_after_double_hash, float wrap_width) { + ImGuiContext& g = *GImGui; + + const char* text_display_end; + if (hide_text_after_double_hash) + text_display_end = ImGui::FindRenderedTextEnd(text, text_end); // Hide anything after a '##' string + else + text_display_end = text_end; + GameOverlay* overlay = SohImGui::overlay; - if (args[1] == "add") { - if (!overlay->RegisteredOverlays.contains(key)) { - overlay->RegisteredOverlays[key] = new Overlay({ OverlayType::TEXT, ImStrdup(key), -1.0f }); - INFO("Added overlay: %s ", key); - } else { - ERROR("Overlay already exists: %s", key); - } - } else if (args[1] == "remove") { - if (overlay->RegisteredOverlays.contains(key)) { - overlay->RegisteredOverlays.erase(key); - INFO("Removed overlay: %s ", key); - } else { - ERROR("Overlay not found: %s ", key); - } - } - } else { - ERROR("CVar %s does not exist", args[2].c_str()); + + ImFont* font = overlay->CurrentFont == "Default" ? g.Font : overlay->Fonts[overlay->CurrentFont]; + const float font_size = font->FontSize; + if (text == text_display_end) + return ImVec2(0.0f, font_size); + ImVec2 text_size = font->CalcTextSizeA(font_size, FLT_MAX, wrap_width, text, text_display_end, NULL); + + // Round + // FIXME: This has been here since Dec 2015 (7b0bf230) but down the line we want this out. + // FIXME: Investigate using ceilf or e.g. + // - https://git.musl-libc.org/cgit/musl/tree/src/math/ceilf.c + // - https://embarkstudios.github.io/rust-gpu/api/src/libm/math/ceilf.rs.html + text_size.x = IM_FLOOR(text_size.x + 0.99999f); + + return text_size; } - return CMD_SUCCESS; -} \ No newline at end of file + void GameOverlay::Init() { + this->LoadFont("Press Start 2P", "assets/ship_of_harkinian/fonts/PressStart2P-Regular.ttf", 12.0f); + this->LoadFont("Fipps", "assets/ship_of_harkinian/fonts/Fipps-Regular.otf", 32.0f); + const std::string DefaultFont = this->Fonts.begin()->first; + if (!this->Fonts.empty()) { + const std::string font = CVar_GetString("gOverlayFont", ImStrdup(DefaultFont.c_str())); + for (auto& [name, _] : this->Fonts) { + if (font.starts_with(name)) { + this->CurrentFont = name; + break; + } + this->CurrentFont = DefaultFont; + } + } + SohImGui::console->Commands["overlay"] = { OverlayCommand, "Draw an overlay using a cvar value" }; + } + + void GameOverlay::DrawSettings() { + ImGui::Text("Overlays Text Font"); + if (ImGui::BeginCombo("##TextFont", this->CurrentFont.c_str())) { + for (auto& [name, font] : this->Fonts) { + if (ImGui::Selectable(name.c_str(), name == this->CurrentFont)) { + this->CurrentFont = name; + CVar_SetString("gOverlayFont", ImStrdup(name.c_str())); + SohImGui::needs_save = true; + } + + } + ImGui::EndCombo(); + } + } + + + void GameOverlay::Draw() { + const ImGuiViewport* viewport = ImGui::GetMainViewport(); + + ImGui::SetNextWindowPos(viewport->Pos, ImGuiCond_Always); + ImGui::SetNextWindowSize(viewport->Size, ImGuiCond_Always); + ImGui::Begin("SoHOverlay", nullptr, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoBackground | + ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoInputs); + + this->CleanupNotifications(); + + float textY = 50; + float notY = 0; + + for (auto& [key, overlay] : this->RegisteredOverlays) { + + if (overlay->type == OverlayType::TEXT) { + const char* text = ImStrdup(overlay->value); + const CVar* var = CVar_Get(text); + ImVec4 color = ImVec4(1.0f, 1.0f, 1.0f, 1.0f); + + switch (var->type) { + case CVarType::Float: + this->TextDraw(30, textY, true, color, "%s %.2f", text, var->value.valueFloat); + break; + case CVarType::S32: + this->TextDraw(30, textY, true, color, "%s %d", text, var->value.valueS32); + break; + case CVarType::String: + this->TextDraw(30, textY, true, color, "%s %s", text, var->value.valueStr); + break; + case CVarType::RGBA: + this->TextDraw(30, textY, true, color, "#%08X", text, var->value.valueRGBA); + break; + } + + free((void*)text); + textY += 30; + } + + if (overlay->type == OverlayType::NOTIFICATION && overlay->duration > 0) { + const char* text = overlay->value; + const float duration = overlay->duration / overlay->fadeTime; + + const ImVec4 color = ImVec4(1.0f, 1.0f, 1.0f, duration); + const float textWidth = this->GetStringWidth(overlay->value); + + this->TextDraw(GetScreenWidth() - textWidth - 40, GetScreenHeight() - 40 - notY, true, color, text); + notY += 30; + overlay->duration -= .05f; + } + } + + ImGui::End(); + } + + + bool OverlayCommand(const std::vector& args) { + if (args.size() < 3) { + return CMD_FAILED; + } + + if (CVar_Get(args[2].c_str()) != nullptr) { + const char* key = args[2].c_str(); + GameOverlay* overlay = SohImGui::overlay; + if (args[1] == "add") { + if (!overlay->RegisteredOverlays.contains(key)) { + overlay->RegisteredOverlays[key] = new Overlay({ OverlayType::TEXT, ImStrdup(key), -1.0f }); + INFO("Added overlay: %s ", key); + } + else { + ERROR("Overlay already exists: %s", key); + } + } + else if (args[1] == "remove") { + if (overlay->RegisteredOverlays.contains(key)) { + overlay->RegisteredOverlays.erase(key); + INFO("Removed overlay: %s ", key); + } + else { + ERROR("Overlay not found: %s ", key); + } + } + } + else { + ERROR("CVar %s does not exist", args[2].c_str()); + } + + return CMD_SUCCESS; + } +} diff --git a/libultraship/libultraship/GameOverlay.h b/libultraship/libultraship/GameOverlay.h index c9290390e..061d259ba 100644 --- a/libultraship/libultraship/GameOverlay.h +++ b/libultraship/libultraship/GameOverlay.h @@ -3,21 +3,21 @@ #include #include "Lib/ImGui/imgui.h" -#include #include -enum class OverlayType { - TEXT, IMAGE, NOTIFICATION -}; - -struct Overlay { - OverlayType type; - const char* value; - float fadeTime; - float duration; -}; - namespace Ship { + + enum class OverlayType { + TEXT, IMAGE, NOTIFICATION + }; + + struct Overlay { + OverlayType type; + const char* value; + float fadeTime; + float duration; + }; + class GameOverlay { public: std::unordered_map RegisteredOverlays; diff --git a/libultraship/libultraship/libultraship.vcxproj.filters b/libultraship/libultraship/libultraship.vcxproj.filters index f84250c29..d807349a2 100644 --- a/libultraship/libultraship/libultraship.vcxproj.filters +++ b/libultraship/libultraship/libultraship.vcxproj.filters @@ -82,9 +82,6 @@ {bd6557f1-9480-413b-b0cd-843f8efc1939} - - {3285ab8a-06d8-4dac-9af9-efb2a9723ab1} - {db6e02cc-fc4c-4138-8219-1d281ad93ec2} @@ -97,6 +94,9 @@ {010dc29b-d1f6-4793-a4e7-4156aa4fcdd6} + + {5d68254f-662d-4e8c-a57f-de0d8e1d4a58} + @@ -300,12 +300,6 @@ Source Files\Lib\ImGui - - Source Files\CustomImpl - - - Source Files\CustomImpl - Source Files\Lib\ImGui @@ -342,9 +336,6 @@ Source Files\CustomImpl - - Source Files\CustomImpl\Overlay - Source Files\Resources\Files @@ -360,6 +351,15 @@ Source Files\Lib\Mercury + + Source Files\GUI + + + Source Files\GUI + + + Source Files\GUI + @@ -587,12 +587,6 @@ Source Files\Lib\ImGui - - Source Files\CustomImpl - - - Source Files\CustomImpl - Source Files\Lib\ImGui @@ -647,9 +641,6 @@ Header Files - - Source Files\CustomImpl\Overlay - Header Files\Resources\Files @@ -677,5 +668,14 @@ Source Files\Controller + + Source Files\GUI + + + Source Files\GUI + + + Source Files\GUI + \ No newline at end of file