summaryrefslogtreecommitdiffstats
path: root/game/client/gui
diff options
context:
space:
mode:
Diffstat (limited to 'game/client/gui')
-rw-r--r--game/client/gui/CMakeLists.txt38
-rw-r--r--game/client/gui/background.cc39
-rw-r--r--game/client/gui/background.hh8
-rw-r--r--game/client/gui/bother.cc167
-rw-r--r--game/client/gui/bother.hh24
-rw-r--r--game/client/gui/chat.cc273
-rw-r--r--game/client/gui/chat.hh17
-rw-r--r--game/client/gui/crosshair.cc43
-rw-r--r--game/client/gui/crosshair.hh8
-rw-r--r--game/client/gui/direct_connection.cc145
-rw-r--r--game/client/gui/direct_connection.hh7
-rw-r--r--game/client/gui/gui_screen.hh10
-rw-r--r--game/client/gui/hotbar.cc182
-rw-r--r--game/client/gui/hotbar.hh30
-rw-r--r--game/client/gui/imdraw_ext.cc34
-rw-r--r--game/client/gui/imdraw_ext.hh17
-rw-r--r--game/client/gui/language.cc202
-rw-r--r--game/client/gui/language.hh42
-rw-r--r--game/client/gui/main_menu.cc172
-rw-r--r--game/client/gui/main_menu.hh8
-rw-r--r--game/client/gui/message_box.cc95
-rw-r--r--game/client/gui/message_box.hh20
-rw-r--r--game/client/gui/metrics.cc103
-rw-r--r--game/client/gui/metrics.hh7
-rw-r--r--game/client/gui/play_menu.cc594
-rw-r--r--game/client/gui/play_menu.hh9
-rw-r--r--game/client/gui/progress_bar.cc111
-rw-r--r--game/client/gui/progress_bar.hh19
-rw-r--r--game/client/gui/scoreboard.cc103
-rw-r--r--game/client/gui/scoreboard.hh7
-rw-r--r--game/client/gui/settings.cc1069
-rw-r--r--game/client/gui/settings.hh90
-rw-r--r--game/client/gui/splash.cc178
-rw-r--r--game/client/gui/splash.hh8
-rw-r--r--game/client/gui/status_lines.cc84
-rw-r--r--game/client/gui/status_lines.hh21
-rw-r--r--game/client/gui/window_title.cc14
-rw-r--r--game/client/gui/window_title.hh6
38 files changed, 0 insertions, 4004 deletions
diff --git a/game/client/gui/CMakeLists.txt b/game/client/gui/CMakeLists.txt
deleted file mode 100644
index 46d64a1..0000000
--- a/game/client/gui/CMakeLists.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-target_sources(vclient PRIVATE
- "${CMAKE_CURRENT_LIST_DIR}/background.cc"
- "${CMAKE_CURRENT_LIST_DIR}/background.hh"
- "${CMAKE_CURRENT_LIST_DIR}/bother.cc"
- "${CMAKE_CURRENT_LIST_DIR}/bother.hh"
- "${CMAKE_CURRENT_LIST_DIR}/chat.cc"
- "${CMAKE_CURRENT_LIST_DIR}/chat.hh"
- "${CMAKE_CURRENT_LIST_DIR}/crosshair.cc"
- "${CMAKE_CURRENT_LIST_DIR}/crosshair.hh"
- "${CMAKE_CURRENT_LIST_DIR}/direct_connection.cc"
- "${CMAKE_CURRENT_LIST_DIR}/direct_connection.hh"
- "${CMAKE_CURRENT_LIST_DIR}/gui_screen.hh"
- "${CMAKE_CURRENT_LIST_DIR}/hotbar.cc"
- "${CMAKE_CURRENT_LIST_DIR}/hotbar.hh"
- "${CMAKE_CURRENT_LIST_DIR}/imdraw_ext.cc"
- "${CMAKE_CURRENT_LIST_DIR}/imdraw_ext.hh"
- "${CMAKE_CURRENT_LIST_DIR}/language.cc"
- "${CMAKE_CURRENT_LIST_DIR}/language.hh"
- "${CMAKE_CURRENT_LIST_DIR}/main_menu.cc"
- "${CMAKE_CURRENT_LIST_DIR}/main_menu.hh"
- "${CMAKE_CURRENT_LIST_DIR}/message_box.cc"
- "${CMAKE_CURRENT_LIST_DIR}/message_box.hh"
- "${CMAKE_CURRENT_LIST_DIR}/metrics.cc"
- "${CMAKE_CURRENT_LIST_DIR}/metrics.hh"
- "${CMAKE_CURRENT_LIST_DIR}/play_menu.cc"
- "${CMAKE_CURRENT_LIST_DIR}/play_menu.hh"
- "${CMAKE_CURRENT_LIST_DIR}/progress_bar.cc"
- "${CMAKE_CURRENT_LIST_DIR}/progress_bar.hh"
- "${CMAKE_CURRENT_LIST_DIR}/scoreboard.cc"
- "${CMAKE_CURRENT_LIST_DIR}/scoreboard.hh"
- "${CMAKE_CURRENT_LIST_DIR}/settings.cc"
- "${CMAKE_CURRENT_LIST_DIR}/settings.hh"
- "${CMAKE_CURRENT_LIST_DIR}/splash.cc"
- "${CMAKE_CURRENT_LIST_DIR}/splash.hh"
- "${CMAKE_CURRENT_LIST_DIR}/status_lines.cc"
- "${CMAKE_CURRENT_LIST_DIR}/status_lines.hh"
- "${CMAKE_CURRENT_LIST_DIR}/window_title.cc"
- "${CMAKE_CURRENT_LIST_DIR}/window_title.hh")
diff --git a/game/client/gui/background.cc b/game/client/gui/background.cc
deleted file mode 100644
index d1500bb..0000000
--- a/game/client/gui/background.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-#include "client/pch.hh"
-
-#include "client/gui/background.hh"
-
-#include "core/math/constexpr.hh"
-
-#include "core/resource/resource.hh"
-
-#include "client/resource/texture_gui.hh"
-
-#include "client/globals.hh"
-
-static resource_ptr<TextureGUI> texture;
-
-void gui::background::init(void)
-{
- texture = resource::load<TextureGUI>("textures/gui/background.png", TEXTURE_GUI_LOAD_VFLIP);
-
- if(texture == nullptr) {
- spdlog::critical("background: texture load failed");
- std::terminate();
- }
-}
-
-void gui::background::shutdown(void)
-{
- texture = nullptr;
-}
-
-void gui::background::layout(void)
-{
- auto viewport = ImGui::GetMainViewport();
- auto draw_list = ImGui::GetBackgroundDrawList();
-
- auto scaled_width = 0.75f * static_cast<float>(globals::width / globals::gui_scale);
- auto scaled_height = 0.75f * static_cast<float>(globals::height / globals::gui_scale);
- auto scale_uv = ImVec2(scaled_width / static_cast<float>(texture->size.x), scaled_height / static_cast<float>(texture->size.y));
- draw_list->AddImage(texture->handle, ImVec2(0.0f, 0.0f), viewport->Size, ImVec2(0.0f, 0.0f), scale_uv);
-}
diff --git a/game/client/gui/background.hh b/game/client/gui/background.hh
deleted file mode 100644
index 6145484..0000000
--- a/game/client/gui/background.hh
+++ /dev/null
@@ -1,8 +0,0 @@
-#pragma once
-
-namespace gui::background
-{
-void init(void);
-void shutdown(void);
-void layout(void);
-} // namespace gui::background
diff --git a/game/client/gui/bother.cc b/game/client/gui/bother.cc
deleted file mode 100644
index e87b9ff..0000000
--- a/game/client/gui/bother.cc
+++ /dev/null
@@ -1,167 +0,0 @@
-#include "client/pch.hh"
-
-#include "client/gui/bother.hh"
-
-#include "core/version.hh"
-
-#include "shared/protocol.hh"
-
-#include "client/globals.hh"
-
-// Maximum amount of peers used for bothering
-constexpr static std::size_t BOTHER_PEERS = 4;
-
-struct BotherQueueItem final {
- unsigned int identity;
- std::string hostname;
- std::uint16_t port;
-};
-
-static ENetHost* bother_host;
-static entt::dispatcher bother_dispatcher;
-static std::unordered_set<unsigned int> bother_set;
-static std::deque<BotherQueueItem> bother_queue;
-
-static void on_status_response_packet(const protocol::StatusResponse& packet)
-{
- auto identity = static_cast<unsigned int>(reinterpret_cast<std::uintptr_t>(packet.peer->data));
-
- bother_set.erase(identity);
-
- gui::BotherResponseEvent event;
- event.identity = identity;
- event.is_server_unreachable = false;
- event.num_players = packet.num_players;
- event.max_players = packet.max_players;
- event.motd = packet.motd;
- event.game_version_major = packet.game_version_major;
- event.game_version_minor = packet.game_version_minor;
- event.game_version_patch = packet.game_version_patch;
- globals::dispatcher.trigger(event);
-
- enet_peer_disconnect(packet.peer, protocol::CHANNEL);
-}
-
-void gui::bother::init(void)
-{
- bother_host = enet_host_create(nullptr, BOTHER_PEERS, 1, 0, 0);
- bother_dispatcher.clear();
- bother_set.clear();
-
- bother_dispatcher.sink<protocol::StatusResponse>().connect<&on_status_response_packet>();
-}
-
-void gui::bother::shutdown(void)
-{
- enet_host_destroy(bother_host);
- bother_dispatcher.clear();
- bother_set.clear();
-}
-
-void gui::bother::update_late(void)
-{
- unsigned int free_peers = 0U;
-
- // Figure out how much times we can call
- // enet_host_connect and reallistically succeed
- for(unsigned int i = 0U; i < bother_host->peerCount; ++i) {
- if(bother_host->peers[i].state != ENET_PEER_STATE_DISCONNECTED) {
- continue;
- }
-
- free_peers += 1U;
- }
-
- for(unsigned int i = 0U; (i < free_peers) && bother_queue.size(); ++i) {
- const auto& item = bother_queue.front();
-
- ENetAddress address;
- enet_address_set_host(&address, item.hostname.c_str());
- address.port = enet_uint16(item.port);
-
- if(auto peer = enet_host_connect(bother_host, &address, 1, 0)) {
- peer->data = reinterpret_cast<void*>(static_cast<std::uintptr_t>(item.identity));
- bother_set.insert(item.identity);
- enet_host_flush(bother_host);
- }
-
- bother_queue.pop_front();
- }
-
- ENetEvent enet_event;
-
- if(0 < enet_host_service(bother_host, &enet_event, 0)) {
- if(enet_event.type == ENET_EVENT_TYPE_CONNECT) {
- protocol::StatusRequest packet;
- packet.game_version_major = version::major;
- protocol::send(enet_event.peer, protocol::encode(packet));
- return;
- }
-
- if(enet_event.type == ENET_EVENT_TYPE_RECEIVE) {
- protocol::decode(bother_dispatcher, enet_event.packet, enet_event.peer);
- enet_packet_destroy(enet_event.packet);
- return;
- }
-
- if(enet_event.type == ENET_EVENT_TYPE_DISCONNECT) {
- auto identity = static_cast<unsigned int>(reinterpret_cast<std::uintptr_t>(enet_event.peer->data));
-
- if(bother_set.count(identity)) {
- BotherResponseEvent event;
- event.identity = identity;
- event.is_server_unreachable = true;
- globals::dispatcher.trigger(event);
- }
-
- bother_set.erase(identity);
-
- return;
- }
- }
-}
-
-void gui::bother::ping(unsigned int identity, std::string_view host, std::uint16_t port)
-{
- if(bother_set.count(identity)) {
- // Already in the process
- return;
- }
-
- for(const auto& item : bother_queue) {
- if(item.identity == identity) {
- // Already in the queue
- return;
- }
- }
-
- BotherQueueItem item;
- item.identity = identity;
- item.hostname = host;
- item.port = port;
-
- bother_queue.push_back(item);
-}
-
-void gui::bother::cancel(unsigned int identity)
-{
- bother_set.erase(identity);
-
- auto item = bother_queue.cbegin();
-
- while(item != bother_queue.cend()) {
- if(item->identity == identity) {
- item = bother_queue.erase(item);
- continue;
- }
-
- item = std::next(item);
- }
-
- for(unsigned int i = 0U; i < bother_host->peerCount; ++i) {
- if(bother_host->peers[i].data == reinterpret_cast<void*>(static_cast<std::uintptr_t>(identity))) {
- enet_peer_reset(&bother_host->peers[i]);
- break;
- }
- }
-}
diff --git a/game/client/gui/bother.hh b/game/client/gui/bother.hh
deleted file mode 100644
index 75e56d1..0000000
--- a/game/client/gui/bother.hh
+++ /dev/null
@@ -1,24 +0,0 @@
-#pragma once
-
-namespace gui
-{
-struct BotherResponseEvent final {
- unsigned int identity;
- bool is_server_unreachable;
- std::uint16_t num_players;
- std::uint16_t max_players;
- std::uint32_t game_version_major;
- std::uint32_t game_version_minor;
- std::uint32_t game_version_patch;
- std::string motd;
-};
-} // namespace gui
-
-namespace gui::bother
-{
-void init(void);
-void shutdown(void);
-void update_late(void);
-void ping(unsigned int identity, std::string_view host, std::uint16_t port);
-void cancel(unsigned int identity);
-} // namespace gui::bother
diff --git a/game/client/gui/chat.cc b/game/client/gui/chat.cc
deleted file mode 100644
index aaee8c6..0000000
--- a/game/client/gui/chat.cc
+++ /dev/null
@@ -1,273 +0,0 @@
-#include "client/pch.hh"
-
-#include "client/gui/chat.hh"
-
-#include "core/config/number.hh"
-#include "core/config/string.hh"
-
-#include "core/io/config_map.hh"
-
-#include "core/resource/resource.hh"
-
-#include "core/utils/string.hh"
-
-#include "shared/protocol.hh"
-
-#include "client/config/keybind.hh"
-
-#include "client/gui/gui_screen.hh"
-#include "client/gui/imdraw_ext.hh"
-#include "client/gui/language.hh"
-#include "client/gui/settings.hh"
-
-#include "client/io/glfw.hh"
-
-#include "client/resource/sound_effect.hh"
-
-#include "client/sound/sound.hh"
-
-#include "client/game.hh"
-#include "client/globals.hh"
-#include "client/session.hh"
-
-constexpr static ImGuiWindowFlags WINDOW_FLAGS = ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration;
-constexpr static unsigned int MAX_HISTORY_SIZE = 128U;
-
-struct GuiChatMessage final {
- std::uint64_t spawn;
- std::string text;
- ImVec4 color;
-};
-
-static config::KeyBind key_chat(GLFW_KEY_ENTER);
-static config::Unsigned history_size(32U, 0U, MAX_HISTORY_SIZE);
-
-static std::deque<GuiChatMessage> history;
-static std::string chat_input;
-static bool needs_focus;
-
-static resource_ptr<SoundEffect> sfx_chat_message;
-
-static void append_text_message(const std::string& sender, const std::string& text)
-{
- GuiChatMessage message;
- message.spawn = globals::curtime;
- message.text = std::format("<{}> {}", sender, text);
- message.color = ImGui::GetStyleColorVec4(ImGuiCol_Text);
- history.push_back(message);
-
- if(sfx_chat_message && session::is_ingame()) {
- sound::play_ui(sfx_chat_message, false, 1.0f);
- }
-}
-
-static void append_player_join(const std::string& sender)
-{
- GuiChatMessage message;
- message.spawn = globals::curtime;
- message.text = std::format("{} {}", sender, gui::language::resolve("chat.client_join"));
- message.color = ImGui::GetStyleColorVec4(ImGuiCol_DragDropTarget);
- history.push_back(message);
-
- if(sfx_chat_message && session::is_ingame()) {
- sound::play_ui(sfx_chat_message, false, 1.0f);
- }
-}
-
-static void append_player_leave(const std::string& sender, const std::string& reason)
-{
- GuiChatMessage message;
- message.spawn = globals::curtime;
- message.text = std::format("{} {} ({})", sender, gui::language::resolve("chat.client_left"), gui::language::resolve(reason.c_str()));
- message.color = ImGui::GetStyleColorVec4(ImGuiCol_DragDropTarget);
- history.push_back(message);
-
- if(sfx_chat_message && session::is_ingame()) {
- sound::play_ui(sfx_chat_message, false, 1.0f);
- }
-}
-
-static void on_chat_message_packet(const protocol::ChatMessage& packet)
-{
- if(packet.type == protocol::ChatMessage::TEXT_MESSAGE) {
- append_text_message(packet.sender, packet.message);
- return;
- }
-
- if(packet.type == protocol::ChatMessage::PLAYER_JOIN) {
- append_player_join(packet.sender);
- return;
- }
-
- if(packet.type == protocol::ChatMessage::PLAYER_LEAVE) {
- append_player_leave(packet.sender, packet.message);
- return;
- }
-}
-
-static void on_glfw_key(const io::GlfwKeyEvent& event)
-{
- if(event.action == GLFW_PRESS) {
- if((event.key == GLFW_KEY_ENTER) && (globals::gui_screen == GUI_CHAT)) {
- if(!utils::is_whitespace(chat_input)) {
- protocol::ChatMessage packet;
- packet.type = protocol::ChatMessage::TEXT_MESSAGE;
- packet.sender = client_game::username.get();
- packet.message = chat_input;
-
- protocol::send(session::peer, protocol::encode(packet));
- }
-
- globals::gui_screen = GUI_SCREEN_NONE;
-
- chat_input.clear();
-
- return;
- }
-
- if((event.key == GLFW_KEY_ESCAPE) && (globals::gui_screen == GUI_CHAT)) {
- globals::gui_screen = GUI_SCREEN_NONE;
- return;
- }
-
- if(key_chat.equals(event.key) && !globals::gui_screen) {
- globals::gui_screen = GUI_CHAT;
- needs_focus = true;
- return;
- }
- }
-}
-
-void gui::client_chat::init(void)
-{
- globals::client_config.add_value("chat.key", key_chat);
- globals::client_config.add_value("chat.history_size", history_size);
-
- settings::add_keybind(2, key_chat, settings_location::KEYBOARD_MISC, "key.chat");
- settings::add_slider(1, history_size, settings_location::VIDEO_GUI, "chat.history_size", false);
-
- globals::dispatcher.sink<protocol::ChatMessage>().connect<&on_chat_message_packet>();
- globals::dispatcher.sink<io::GlfwKeyEvent>().connect<&on_glfw_key>();
-
- sfx_chat_message = resource::load<SoundEffect>("sounds/ui/chat_message.wav");
-}
-
-void gui::client_chat::init_late(void)
-{
-}
-
-void gui::client_chat::shutdown(void)
-{
- sfx_chat_message = nullptr;
-}
-
-void gui::client_chat::update(void)
-{
- while(history.size() > history_size.get_value()) {
- history.pop_front();
- }
-}
-
-void gui::client_chat::layout(void)
-{
- auto viewport = ImGui::GetMainViewport();
- auto window_start = ImVec2(0.0f, 0.0f);
- auto window_size = ImVec2(0.75f * viewport->Size.x, viewport->Size.y);
-
- ImGui::SetNextWindowPos(window_start);
- ImGui::SetNextWindowSize(window_size);
-
- ImGui::PushFont(globals::font_unscii16, 8.0f);
-
- if(!ImGui::Begin("###chat", nullptr, WINDOW_FLAGS)) {
- ImGui::End();
- return;
- }
-
- auto& padding = ImGui::GetStyle().FramePadding;
- auto& spacing = ImGui::GetStyle().ItemSpacing;
- auto font = ImGui::GetFont();
-
- auto draw_list = ImGui::GetWindowDrawList();
-
- // The text input widget occupies the bottom part
- // of the chat window, we need to reserve some space for it
- auto ypos = window_size.y - 2.5f * ImGui::GetFontSize() - 2.0f * padding.y - 2.0f * spacing.y;
-
- if(globals::gui_screen == GUI_CHAT) {
- if(needs_focus) {
- ImGui::SetKeyboardFocusHere();
- needs_focus = false;
- }
-
- ImGui::SetNextItemWidth(window_size.x + 32.0f * padding.x);
- ImGui::SetCursorScreenPos(ImVec2(padding.x, ypos));
- ImGui::InputText("###chat.input", &chat_input);
- }
-
- if(!client_game::hide_hud && ((globals::gui_screen == GUI_SCREEN_NONE) || (globals::gui_screen == GUI_CHAT))) {
- for(auto it = history.crbegin(); it < history.crend(); ++it) {
- auto text_size = ImGui::CalcTextSize(it->text.c_str(), it->text.c_str() + it->text.size(), false, window_size.x);
- auto rect_size = ImVec2(window_size.x, text_size.y + 2.0f * padding.y);
-
- auto rect_pos = ImVec2(padding.x, ypos - text_size.y - 2.0f * padding.y);
- auto rect_end = ImVec2(rect_pos.x + rect_size.x, rect_pos.y + rect_size.y);
- auto text_pos = ImVec2(rect_pos.x + padding.x, rect_pos.y + padding.y);
-
- auto fadeout_seconds = 10.0f;
- auto fadeout = std::exp(-1.0f * std::pow(1.0e-6 * static_cast<float>(globals::curtime - it->spawn) / fadeout_seconds, 10.0f));
-
- float rect_alpha;
- float text_alpha;
-
- if(globals::gui_screen == GUI_CHAT) {
- rect_alpha = 0.75f;
- text_alpha = 1.00f;
- }
- else {
- rect_alpha = 0.50f * fadeout;
- text_alpha = 1.00f * fadeout;
- }
-
- auto rect_col = ImGui::GetColorU32(ImGuiCol_FrameBg, rect_alpha);
- auto text_col = ImGui::GetColorU32(ImVec4(it->color.x, it->color.y, it->color.z, it->color.w * text_alpha));
- auto shadow_col = ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, text_alpha));
-
- draw_list->AddRectFilled(rect_pos, rect_end, rect_col);
-
- imdraw_ext::text_shadow_w(it->text, text_pos, text_col, shadow_col, font, draw_list, 8.0f, window_size.x);
-
- ypos -= rect_size.y;
- }
- }
-
- ImGui::End();
- ImGui::PopFont();
-}
-
-void gui::client_chat::clear(void)
-{
- history.clear();
-}
-
-void gui::client_chat::refresh_timings(void)
-{
- for(auto it = history.begin(); it < history.end(); ++it) {
- // Reset the spawn time so the fadeout timer
- // is reset; SpawnPlayer handler might call this
- it->spawn = globals::curtime;
- }
-}
-
-void gui::client_chat::print(const std::string& text)
-{
- GuiChatMessage message = {};
- message.spawn = globals::curtime;
- message.text = text;
- message.color = ImGui::GetStyleColorVec4(ImGuiCol_Text);
- history.push_back(message);
-
- if(sfx_chat_message && session::is_ingame()) {
- sound::play_ui(sfx_chat_message, false, 1.0f);
- }
-}
diff --git a/game/client/gui/chat.hh b/game/client/gui/chat.hh
deleted file mode 100644
index 2fc6fb3..0000000
--- a/game/client/gui/chat.hh
+++ /dev/null
@@ -1,17 +0,0 @@
-#pragma once
-
-namespace gui::client_chat
-{
-void init(void);
-void init_late(void);
-void shutdown(void);
-void update(void);
-void layout(void);
-} // namespace gui::client_chat
-
-namespace gui::client_chat
-{
-void clear(void);
-void refresh_timings(void);
-void print(const std::string& string);
-} // namespace gui::client_chat
diff --git a/game/client/gui/crosshair.cc b/game/client/gui/crosshair.cc
deleted file mode 100644
index 2e6eeba..0000000
--- a/game/client/gui/crosshair.cc
+++ /dev/null
@@ -1,43 +0,0 @@
-#include "client/pch.hh"
-
-#include "client/gui/crosshair.hh"
-
-#include "core/math/constexpr.hh"
-
-#include "core/resource/resource.hh"
-
-#include "client/resource/texture_gui.hh"
-
-#include "client/globals.hh"
-#include "client/session.hh"
-
-static resource_ptr<TextureGUI> texture;
-
-void gui::crosshair::init(void)
-{
- texture = resource::load<TextureGUI>("textures/gui/hud_crosshair.png",
- TEXTURE_GUI_LOAD_CLAMP_S | TEXTURE_GUI_LOAD_CLAMP_T | TEXTURE_GUI_LOAD_VFLIP);
-
- if(texture == nullptr) {
- spdlog::critical("crosshair: texture load failed");
- std::terminate();
- }
-}
-
-void gui::crosshair::shutdown(void)
-{
- texture = nullptr;
-}
-
-void gui::crosshair::layout(void)
-{
- auto viewport = ImGui::GetMainViewport();
- auto draw_list = ImGui::GetForegroundDrawList();
-
- auto scaled_width = glm::max<int>(texture->size.x, globals::gui_scale * texture->size.x / 2);
- auto scaled_height = glm::max<int>(texture->size.y, globals::gui_scale * texture->size.y / 2);
- auto start = ImVec2(static_cast<int>(0.5f * viewport->Size.x) - (scaled_width / 2),
- static_cast<int>(0.5f * viewport->Size.y) - (scaled_height / 2));
- auto end = ImVec2(start.x + scaled_width, start.y + scaled_height);
- draw_list->AddImage(texture->handle, start, end);
-}
diff --git a/game/client/gui/crosshair.hh b/game/client/gui/crosshair.hh
deleted file mode 100644
index dca5725..0000000
--- a/game/client/gui/crosshair.hh
+++ /dev/null
@@ -1,8 +0,0 @@
-#pragma once
-
-namespace gui::crosshair
-{
-void init(void);
-void shutdown(void);
-void layout(void);
-} // namespace gui::crosshair
diff --git a/game/client/gui/direct_connection.cc b/game/client/gui/direct_connection.cc
deleted file mode 100644
index c521232..0000000
--- a/game/client/gui/direct_connection.cc
+++ /dev/null
@@ -1,145 +0,0 @@
-#include "client/pch.hh"
-
-#include "client/gui/direct_connection.hh"
-
-#include "core/config/boolean.hh"
-
-#include "core/utils/string.hh"
-
-#include "shared/protocol.hh"
-
-#include "client/gui/gui_screen.hh"
-#include "client/gui/language.hh"
-
-#include "client/io/glfw.hh"
-
-#include "client/game.hh"
-#include "client/globals.hh"
-#include "client/session.hh"
-
-constexpr static ImGuiWindowFlags WINDOW_FLAGS = ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration;
-
-static std::string str_title;
-static std::string str_connect;
-static std::string str_cancel;
-
-static std::string str_hostname;
-static std::string str_password;
-
-static std::string direct_hostname;
-static std::string direct_password;
-
-static void on_glfw_key(const io::GlfwKeyEvent& event)
-{
- if((event.key == GLFW_KEY_ESCAPE) && (event.action == GLFW_PRESS)) {
- if(globals::gui_screen == GUI_DIRECT_CONNECTION) {
- globals::gui_screen = GUI_PLAY_MENU;
- return;
- }
- }
-}
-
-static void on_language_set(const gui::LanguageSetEvent& event)
-{
- str_title = gui::language::resolve("direct_connection.title");
- str_connect = gui::language::resolve_gui("direct_connection.connect");
- str_cancel = gui::language::resolve_gui("direct_connection.cancel");
-
- str_hostname = gui::language::resolve("direct_connection.hostname");
- str_password = gui::language::resolve("direct_connection.password");
-}
-
-static void connect_to_server(void)
-{
- auto parts = utils::split(direct_hostname, ":");
- std::string parsed_hostname;
- std::uint16_t parsed_port;
-
- if(!parts[0].empty()) {
- parsed_hostname = parts[0];
- }
- else {
- parsed_hostname = std::string("localhost");
- }
-
- if(parts.size() >= 2) {
- parsed_port = glm::clamp<std::uint16_t>(strtoul(parts[1].c_str(), nullptr, 10), 1024, UINT16_MAX);
- }
- else {
- parsed_port = protocol::PORT;
- }
-
- session::connect(parsed_hostname.c_str(), parsed_port, direct_password.c_str());
-}
-
-void gui::direct_connection::init(void)
-{
- globals::dispatcher.sink<io::GlfwKeyEvent>().connect<&on_glfw_key>();
- globals::dispatcher.sink<LanguageSetEvent>().connect<&on_language_set>();
-}
-
-void gui::direct_connection::layout(void)
-{
- auto viewport = ImGui::GetMainViewport();
- auto window_start = ImVec2(0.25f * viewport->Size.x, 0.20f * viewport->Size.y);
- auto window_size = ImVec2(0.50f * viewport->Size.x, 0.80f * viewport->Size.y);
-
- ImGui::SetNextWindowPos(window_start);
- ImGui::SetNextWindowSize(window_size);
-
- if(ImGui::Begin("###UIDirectConnect", nullptr, WINDOW_FLAGS)) {
- const float title_width = ImGui::CalcTextSize(str_title.c_str()).x;
- ImGui::SetCursorPosX(0.5f * (window_size.x - title_width));
- ImGui::TextUnformatted(str_title.c_str());
-
- ImGui::Dummy(ImVec2(0.0f, 16.0f * globals::gui_scale));
-
- ImGuiInputTextFlags hostname_flags = ImGuiInputTextFlags_CharsNoBlank;
-
- if(client_game::streamer_mode.get_value()) {
- // Hide server hostname to avoid things like
- // followers flooding the server that is streamed online
- hostname_flags |= ImGuiInputTextFlags_Password;
- }
-
- auto avail_width = ImGui::GetContentRegionAvail().x;
-
- ImGui::PushItemWidth(avail_width);
-
- ImGui::InputText("###UIDirectConnect_hostname", &direct_hostname, hostname_flags);
-
- if(ImGui::BeginItemTooltip()) {
- ImGui::PushTextWrapPos(ImGui::GetFontSize() * 16.0f);
- ImGui::TextUnformatted(str_hostname.c_str());
- ImGui::PopTextWrapPos();
- ImGui::EndTooltip();
- }
-
- ImGui::InputText("###UIDirectConnect_password", &direct_password, ImGuiInputTextFlags_Password);
-
- if(ImGui::BeginItemTooltip()) {
- ImGui::PushTextWrapPos(ImGui::GetFontSize() * 16.0f);
- ImGui::TextUnformatted(str_password.c_str());
- ImGui::PopTextWrapPos();
- ImGui::EndTooltip();
- }
-
- ImGui::PopItemWidth();
-
- ImGui::Dummy(ImVec2(0.0f, 4.0f * globals::gui_scale));
-
- ImGui::BeginDisabled(utils::is_whitespace(direct_hostname));
-
- if(ImGui::Button(str_connect.c_str(), ImVec2(avail_width, 0.0f))) {
- connect_to_server();
- }
-
- ImGui::EndDisabled();
-
- if(ImGui::Button(str_cancel.c_str(), ImVec2(avail_width, 0.0f))) {
- globals::gui_screen = GUI_PLAY_MENU;
- }
- }
-
- ImGui::End();
-}
diff --git a/game/client/gui/direct_connection.hh b/game/client/gui/direct_connection.hh
deleted file mode 100644
index c63156b..0000000
--- a/game/client/gui/direct_connection.hh
+++ /dev/null
@@ -1,7 +0,0 @@
-#pragma once
-
-namespace gui::direct_connection
-{
-void init(void);
-void layout(void);
-} // namespace gui::direct_connection
diff --git a/game/client/gui/gui_screen.hh b/game/client/gui/gui_screen.hh
deleted file mode 100644
index c29f701..0000000
--- a/game/client/gui/gui_screen.hh
+++ /dev/null
@@ -1,10 +0,0 @@
-#pragma once
-
-constexpr static unsigned int GUI_SCREEN_NONE = 0x0000U;
-constexpr static unsigned int GUI_MAIN_MENU = 0x0001U;
-constexpr static unsigned int GUI_PLAY_MENU = 0x0002U;
-constexpr static unsigned int GUI_SETTINGS = 0x0003U;
-constexpr static unsigned int GUI_PROGRESS_BAR = 0x0004U;
-constexpr static unsigned int GUI_MESSAGE_BOX = 0x0005U;
-constexpr static unsigned int GUI_CHAT = 0x0006U;
-constexpr static unsigned int GUI_DIRECT_CONNECTION = 0x0007U;
diff --git a/game/client/gui/hotbar.cc b/game/client/gui/hotbar.cc
deleted file mode 100644
index e9458dd..0000000
--- a/game/client/gui/hotbar.cc
+++ /dev/null
@@ -1,182 +0,0 @@
-#include "client/pch.hh"
-
-#include "client/gui/hotbar.hh"
-
-#include "core/io/config_map.hh"
-
-#include "core/resource/resource.hh"
-
-#include "shared/world/item_registry.hh"
-
-#include "client/config/keybind.hh"
-
-#include "client/gui/settings.hh"
-#include "client/gui/status_lines.hh"
-
-#include "client/io/glfw.hh"
-
-#include "client/resource/texture_gui.hh"
-
-#include "client/globals.hh"
-
-constexpr static float ITEM_SIZE = 20.0f;
-constexpr static float ITEM_PADDING = 2.0f;
-constexpr static float SELECTOR_PADDING = 1.0f;
-constexpr static float HOTBAR_PADDING = 2.0f;
-
-unsigned int gui::hotbar::active_slot = 0U;
-std::array<const world::Item*, HOTBAR_SIZE> gui::hotbar::slots = {};
-
-static config::KeyBind hotbar_keys[HOTBAR_SIZE];
-
-static resource_ptr<TextureGUI> hotbar_background;
-static resource_ptr<TextureGUI> hotbar_selector;
-
-static ImU32 get_color_alpha(ImGuiCol style_color, float alpha)
-{
- const auto& color = ImGui::GetStyleColorVec4(style_color);
- return ImGui::GetColorU32(ImVec4(color.x, color.y, color.z, alpha));
-}
-
-static void update_hotbar_item(void)
-{
- auto current_item = gui::hotbar::slots[gui::hotbar::active_slot];
-
- if(current_item == nullptr) {
- gui::status_lines::unset(gui::STATUS_HOTBAR);
- }
- else {
- gui::status_lines::set(gui::STATUS_HOTBAR, current_item->get_name(), ImVec4(1.0f, 1.0f, 1.0f, 1.0f), 5.0f);
- }
-}
-
-static void on_glfw_key(const io::GlfwKeyEvent& event)
-{
- if((event.action == GLFW_PRESS) && !globals::gui_screen) {
- for(unsigned int i = 0U; i < HOTBAR_SIZE; ++i) {
- if(hotbar_keys[i].equals(event.key)) {
- gui::hotbar::active_slot = i;
- update_hotbar_item();
- break;
- }
- }
- }
-}
-
-static void on_glfw_scroll(const io::GlfwScrollEvent& event)
-{
- if(!globals::gui_screen) {
- if(event.dy < 0.0) {
- gui::hotbar::next_slot();
- return;
- }
-
- if(event.dy > 0.0) {
- gui::hotbar::prev_slot();
- return;
- }
- }
-}
-
-void gui::hotbar::init(void)
-{
- hotbar_keys[0].set_key(GLFW_KEY_1);
- hotbar_keys[1].set_key(GLFW_KEY_2);
- hotbar_keys[2].set_key(GLFW_KEY_3);
- hotbar_keys[3].set_key(GLFW_KEY_4);
- hotbar_keys[4].set_key(GLFW_KEY_5);
- hotbar_keys[5].set_key(GLFW_KEY_6);
- hotbar_keys[6].set_key(GLFW_KEY_7);
- hotbar_keys[7].set_key(GLFW_KEY_8);
- hotbar_keys[8].set_key(GLFW_KEY_9);
-
- globals::client_config.add_value("hotbar.key.0", hotbar_keys[0]);
- globals::client_config.add_value("hotbar.key.1", hotbar_keys[1]);
- globals::client_config.add_value("hotbar.key.3", hotbar_keys[2]);
- globals::client_config.add_value("hotbar.key.4", hotbar_keys[3]);
- globals::client_config.add_value("hotbar.key.5", hotbar_keys[4]);
- globals::client_config.add_value("hotbar.key.6", hotbar_keys[5]);
- globals::client_config.add_value("hotbar.key.7", hotbar_keys[6]);
- globals::client_config.add_value("hotbar.key.8", hotbar_keys[7]);
- globals::client_config.add_value("hotbar.key.9", hotbar_keys[8]);
-
- settings::add_keybind(10, hotbar_keys[0], settings_location::KEYBOARD_GAMEPLAY, "hotbar.slot.0");
- settings::add_keybind(11, hotbar_keys[1], settings_location::KEYBOARD_GAMEPLAY, "hotbar.slot.1");
- settings::add_keybind(12, hotbar_keys[2], settings_location::KEYBOARD_GAMEPLAY, "hotbar.slot.2");
- settings::add_keybind(13, hotbar_keys[3], settings_location::KEYBOARD_GAMEPLAY, "hotbar.slot.3");
- settings::add_keybind(14, hotbar_keys[4], settings_location::KEYBOARD_GAMEPLAY, "hotbar.slot.4");
- settings::add_keybind(15, hotbar_keys[5], settings_location::KEYBOARD_GAMEPLAY, "hotbar.slot.5");
- settings::add_keybind(16, hotbar_keys[6], settings_location::KEYBOARD_GAMEPLAY, "hotbar.slot.6");
- settings::add_keybind(17, hotbar_keys[7], settings_location::KEYBOARD_GAMEPLAY, "hotbar.slot.7");
- settings::add_keybind(18, hotbar_keys[8], settings_location::KEYBOARD_GAMEPLAY, "hotbar.slot.8");
-
- hotbar_background = resource::load<TextureGUI>("textures/gui/hud_hotbar.png", TEXTURE_GUI_LOAD_CLAMP_S | TEXTURE_GUI_LOAD_CLAMP_T);
- hotbar_selector = resource::load<TextureGUI>("textures/gui/hud_selector.png", TEXTURE_GUI_LOAD_CLAMP_S | TEXTURE_GUI_LOAD_CLAMP_T);
-
- globals::dispatcher.sink<io::GlfwKeyEvent>().connect<&on_glfw_key>();
- globals::dispatcher.sink<io::GlfwScrollEvent>().connect<&on_glfw_scroll>();
-}
-
-void gui::hotbar::shutdown(void)
-{
- hotbar_background = nullptr;
- hotbar_selector = nullptr;
-}
-
-void gui::hotbar::layout(void)
-{
- auto& style = ImGui::GetStyle();
-
- auto item_size = ITEM_SIZE * globals::gui_scale;
- auto hotbar_width = HOTBAR_SIZE * item_size;
- auto hotbar_padding = HOTBAR_PADDING * globals::gui_scale;
-
- auto viewport = ImGui::GetMainViewport();
- auto draw_list = ImGui::GetForegroundDrawList();
-
- // Draw the hotbar background image
- auto background_start = ImVec2(0.5f * viewport->Size.x - 0.5f * hotbar_width, viewport->Size.y - item_size - hotbar_padding);
- auto background_end = ImVec2(background_start.x + hotbar_width, background_start.y + item_size);
- draw_list->AddImage(hotbar_background->handle, background_start, background_end);
-
- // Draw the hotbar selector image
- auto selector_padding_a = SELECTOR_PADDING * globals::gui_scale;
- auto selector_padding_b = SELECTOR_PADDING * globals::gui_scale * 2.0f;
- auto selector_start = ImVec2(background_start.x + gui::hotbar::active_slot * item_size - selector_padding_a,
- background_start.y - selector_padding_a);
- auto selector_end = ImVec2(selector_start.x + item_size + selector_padding_b, selector_start.y + item_size + selector_padding_b);
- draw_list->AddImage(hotbar_selector->handle, selector_start, selector_end);
-
- // Figure out item texture padding values
- auto item_padding_a = ITEM_PADDING * globals::gui_scale;
- auto item_padding_b = ITEM_PADDING * globals::gui_scale * 2.0f;
-
- // Draw individual item textures in the hotbar
- for(std::size_t i = 0; i < HOTBAR_SIZE; ++i) {
- auto item = gui::hotbar::slots[i];
-
- if((item == nullptr) || (item->get_cached_texture() == nullptr)) {
- // There's either no item in the slot
- // or the item doesn't have a texture
- continue;
- }
-
- const auto item_start = ImVec2(background_start.x + i * item_size + item_padding_a, background_start.y + item_padding_a);
- const auto item_end = ImVec2(item_start.x + item_size - item_padding_b, item_start.y + item_size - item_padding_b);
- draw_list->AddImage(item->get_cached_texture()->handle, item_start, item_end);
- }
-}
-
-void gui::hotbar::next_slot(void)
-{
- gui::hotbar::active_slot += 1U;
- gui::hotbar::active_slot %= HOTBAR_SIZE;
- update_hotbar_item();
-}
-
-void gui::hotbar::prev_slot(void)
-{
- gui::hotbar::active_slot += HOTBAR_SIZE - 1U;
- gui::hotbar::active_slot %= HOTBAR_SIZE;
- update_hotbar_item();
-}
diff --git a/game/client/gui/hotbar.hh b/game/client/gui/hotbar.hh
deleted file mode 100644
index 223dbc9..0000000
--- a/game/client/gui/hotbar.hh
+++ /dev/null
@@ -1,30 +0,0 @@
-#pragma once
-
-// TODO: design an inventory system and an item
-// registry and integrate the hotbar into that system
-
-namespace world
-{
-class Item;
-} // namespace world
-
-constexpr static unsigned int HOTBAR_SIZE = 9U;
-
-namespace gui::hotbar
-{
-extern unsigned int active_slot;
-extern std::array<const world::Item*, HOTBAR_SIZE> slots;
-} // namespace gui::hotbar
-
-namespace gui::hotbar
-{
-void init(void);
-void shutdown(void);
-void layout(void);
-} // namespace gui::hotbar
-
-namespace gui::hotbar
-{
-void next_slot(void);
-void prev_slot(void);
-} // namespace gui::hotbar
diff --git a/game/client/gui/imdraw_ext.cc b/game/client/gui/imdraw_ext.cc
deleted file mode 100644
index c3d40c9..0000000
--- a/game/client/gui/imdraw_ext.cc
+++ /dev/null
@@ -1,34 +0,0 @@
-#include "client/pch.hh"
-
-#include "client/gui/imdraw_ext.hh"
-
-#include "client/globals.hh"
-
-void gui::imdraw_ext::text_shadow(const std::string& text, const ImVec2& position, ImU32 text_color, ImU32 shadow_color, ImFont* font,
- ImDrawList* draw_list)
-{
- imdraw_ext::text_shadow(text, position, text_color, shadow_color, font, draw_list, font->LegacySize);
-}
-
-void gui::imdraw_ext::text_shadow(const std::string& text, const ImVec2& position, ImU32 text_color, ImU32 shadow_color, ImFont* font,
- ImDrawList* draw_list, float font_size)
-{
- const auto shadow_position = ImVec2(position.x + 0.5f * globals::gui_scale, position.y + 0.5f * globals::gui_scale);
- draw_list->AddText(font, globals::gui_scale * font_size, shadow_position, shadow_color, text.c_str(), text.c_str() + text.size());
- draw_list->AddText(font, globals::gui_scale * font_size, position, text_color, text.c_str(), text.c_str() + text.size());
-}
-
-void gui::imdraw_ext::text_shadow_w(const std::string& text, const ImVec2& position, ImU32 text_color, ImU32 shadow_color, ImFont* font,
- ImDrawList* draw_list, float wrap_width)
-{
- imdraw_ext::text_shadow_w(text, position, text_color, shadow_color, font, draw_list, font->LegacySize, wrap_width);
-}
-
-void gui::imdraw_ext::text_shadow_w(const std::string& text, const ImVec2& position, ImU32 text_color, ImU32 shadow_color, ImFont* font,
- ImDrawList* draw_list, float font_size, float wrap_width)
-{
- const auto shadow_position = ImVec2(position.x + 0.5f * globals::gui_scale, position.y + 0.5f * globals::gui_scale);
- draw_list->AddText(font, globals::gui_scale * font_size, shadow_position, shadow_color, text.c_str(), text.c_str() + text.size(),
- wrap_width);
- draw_list->AddText(font, globals::gui_scale * font_size, position, text_color, text.c_str(), text.c_str() + text.size(), wrap_width);
-}
diff --git a/game/client/gui/imdraw_ext.hh b/game/client/gui/imdraw_ext.hh
deleted file mode 100644
index e1475b2..0000000
--- a/game/client/gui/imdraw_ext.hh
+++ /dev/null
@@ -1,17 +0,0 @@
-#pragma once
-
-namespace gui::imdraw_ext
-{
-void text_shadow(const std::string& text, const ImVec2& position, ImU32 text_color, ImU32 shadow_color, ImFont* font,
- ImDrawList* draw_list);
-void text_shadow(const std::string& text, const ImVec2& position, ImU32 text_color, ImU32 shadow_color, ImFont* font, ImDrawList* draw_list,
- float font_size);
-} // namespace gui::imdraw_ext
-
-namespace gui::imdraw_ext
-{
-void text_shadow_w(const std::string& text, const ImVec2& position, ImU32 text_color, ImU32 shadow_color, ImFont* font,
- ImDrawList* draw_list, float wrap_width);
-void text_shadow_w(const std::string& text, const ImVec2& position, ImU32 text_color, ImU32 shadow_color, ImFont* font,
- ImDrawList* draw_list, float font_size, float wrap_width);
-} // namespace gui::imdraw_ext
diff --git a/game/client/gui/language.cc b/game/client/gui/language.cc
deleted file mode 100644
index d10f88b..0000000
--- a/game/client/gui/language.cc
+++ /dev/null
@@ -1,202 +0,0 @@
-#include "client/pch.hh"
-
-#include "client/gui/language.hh"
-
-#include "core/config/string.hh"
-
-#include "core/io/config_map.hh"
-#include "core/io/physfs.hh"
-
-#include "client/gui/settings.hh"
-
-#include "client/globals.hh"
-
-constexpr static std::string_view DEFAULT_LANGUAGE = "en_US";
-
-// Available languages are kept in a special manifest file which
-// is essentially a key-value map of semi-IETF-compliant language tags
-// and the language's endonym; after reading the manifest, the translation
-// system knows what language it can load and will act accordingly
-constexpr static std::string_view MANIFEST_PATH = "lang/manifest.json";
-
-static gui::LanguageManifest manifest;
-static gui::LanguageIterator current_language;
-static std::unordered_map<std::string, std::string> language_map;
-static std::unordered_map<std::string, gui::LanguageIterator> ietf_map;
-static config::String config_language(DEFAULT_LANGUAGE);
-
-static void send_language_event(gui::LanguageIterator new_language)
-{
- gui::LanguageSetEvent event;
- event.new_language = new_language;
- globals::dispatcher.trigger(event);
-}
-
-void gui::language::init(void)
-{
- globals::client_config.add_value("language", config_language);
-
- settings::add_language_select(0, settings_location::GENERAL, "language");
-
- auto file = PHYSFS_openRead(std::string(MANIFEST_PATH).c_str());
-
- if(file == nullptr) {
- spdlog::critical("language: {}: {}", MANIFEST_PATH, io::physfs_error());
- std::terminate();
- }
-
- auto source = std::string(PHYSFS_fileLength(file), char(0x00));
- PHYSFS_readBytes(file, source.data(), source.size());
- PHYSFS_close(file);
-
- auto jsonv = json_parse_string(source.c_str());
- const auto json = json_value_get_object(jsonv);
- const auto count = json_object_get_count(json);
-
- if((jsonv == nullptr) || (json == nullptr) || (count == 0)) {
- spdlog::critical("language: {}: parse error", MANIFEST_PATH);
- json_value_free(jsonv);
- std::terminate();
- }
-
- for(std::size_t i = 0; i < count; ++i) {
- const auto ietf = json_object_get_name(json, i);
- const auto value = json_object_get_value_at(json, i);
- const auto endonym = json_value_get_string(value);
-
- if(ietf && endonym) {
- LanguageInfo info;
- info.ietf = std::string(ietf);
- info.endonym = std::string(endonym);
- info.display = std::format("{} ({})", endonym, ietf);
- manifest.push_back(info);
- }
- }
-
- for(auto it = manifest.cbegin(); it != manifest.cend(); ++it) {
- ietf_map.emplace(it->ietf, it);
- }
-
- json_value_free(jsonv);
-
- // This is temporary! This value will
- // be overriden in init_late after the
- // config system updates config_language
- current_language = manifest.cend();
-}
-
-void gui::language::init_late(void)
-{
- auto user_language = ietf_map.find(config_language.get_value());
-
- if(user_language != ietf_map.cend()) {
- gui::language::set(user_language->second);
- return;
- }
-
- auto fallback = ietf_map.find(std::string(DEFAULT_LANGUAGE));
-
- if(fallback != ietf_map.cend()) {
- gui::language::set(fallback->second);
- return;
- }
-
- spdlog::critical("language: we're doomed!");
- spdlog::critical("language: {} doesn't exist!", DEFAULT_LANGUAGE);
- std::terminate();
-}
-
-void gui::language::set(LanguageIterator new_language)
-{
- if(new_language != manifest.cend()) {
- auto path = std::format("lang/lang.{}.json", new_language->ietf);
-
- auto file = PHYSFS_openRead(path.c_str());
-
- if(file == nullptr) {
- spdlog::warn("language: {}: {}", path, io::physfs_error());
- send_language_event(new_language);
- return;
- }
-
- auto source = std::string(PHYSFS_fileLength(file), char(0x00));
- PHYSFS_readBytes(file, source.data(), source.size());
- PHYSFS_close(file);
-
- auto jsonv = json_parse_string(source.c_str());
- const auto json = json_value_get_object(jsonv);
- const auto count = json_object_get_count(json);
-
- if((jsonv == nullptr) || (json == nullptr) || (count == 0)) {
- spdlog::warn("language: {}: parse error", path);
- send_language_event(new_language);
- json_value_free(jsonv);
- return;
- }
-
- language_map.clear();
-
- for(size_t i = 0; i < count; ++i) {
- const auto key = json_object_get_name(json, i);
- const auto value = json_object_get_value_at(json, i);
- const auto value_str = json_value_get_string(value);
-
- if(key && value_str) {
- language_map.emplace(key, value_str);
- continue;
- }
- }
-
- json_value_free(jsonv);
-
- current_language = new_language;
- config_language.set(new_language->ietf.c_str());
- }
-
- send_language_event(new_language);
-}
-
-gui::LanguageIterator gui::language::get_current(void)
-{
- return current_language;
-}
-
-gui::LanguageIterator gui::language::find(std::string_view ietf)
-{
- const auto it = ietf_map.find(std::string(ietf));
- if(it != ietf_map.cend()) {
- return it->second;
- }
- else {
- return manifest.cend();
- }
-}
-
-gui::LanguageIterator gui::language::cbegin(void)
-{
- return manifest.cbegin();
-}
-
-gui::LanguageIterator gui::language::cend(void)
-{
- return manifest.cend();
-}
-
-std::string_view gui::language::resolve(std::string_view key)
-{
- const auto it = language_map.find(std::string(key));
-
- if(it != language_map.cend()) {
- return it->second;
- }
-
- return key;
-}
-
-std::string gui::language::resolve_gui(std::string_view key)
-{
- // We need window tags to retain their hierarchy when a language
- // dynamically changes; ImGui allows to provide hidden unique identifiers
- // to GUI primitives that have their name change dynamically, so we're using this
- return std::format("{}###{}", gui::language::resolve(key), key);
-}
diff --git a/game/client/gui/language.hh b/game/client/gui/language.hh
deleted file mode 100644
index 0628941..0000000
--- a/game/client/gui/language.hh
+++ /dev/null
@@ -1,42 +0,0 @@
-#pragma once
-
-namespace gui
-{
-struct LanguageInfo final {
- std::string endonym; // Language's self-name
- std::string display; // Display for the settings GUI
- std::string ietf; // Semi-compliant language abbreviation
-};
-
-using LanguageManifest = std::vector<LanguageInfo>;
-using LanguageIterator = LanguageManifest::const_iterator;
-
-struct LanguageSetEvent final {
- LanguageIterator new_language;
-};
-} // namespace gui
-
-namespace gui::language
-{
-void init(void);
-void init_late(void);
-} // namespace gui::language
-
-namespace gui::language
-{
-void set(LanguageIterator new_language);
-} // namespace gui::language
-
-namespace gui::language
-{
-LanguageIterator get_current(void);
-LanguageIterator find(std::string_view ietf);
-LanguageIterator cbegin(void);
-LanguageIterator cend(void);
-} // namespace gui::language
-
-namespace gui::language
-{
-std::string_view resolve(std::string_view key);
-std::string resolve_gui(std::string_view key);
-} // namespace gui::language
diff --git a/game/client/gui/main_menu.cc b/game/client/gui/main_menu.cc
deleted file mode 100644
index 6c0ee37..0000000
--- a/game/client/gui/main_menu.cc
+++ /dev/null
@@ -1,172 +0,0 @@
-#include "client/pch.hh"
-
-#include "client/gui/main_menu.hh"
-
-#include "core/math/constexpr.hh"
-
-#include "core/resource/resource.hh"
-
-#include "core/version.hh"
-
-#include "client/gui/gui_screen.hh"
-#include "client/gui/language.hh"
-#include "client/gui/window_title.hh"
-
-#include "client/io/glfw.hh"
-
-#include "client/resource/texture_gui.hh"
-
-#include "client/globals.hh"
-#include "client/session.hh"
-
-constexpr static ImGuiWindowFlags WINDOW_FLAGS = ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration;
-
-static std::string str_play;
-static std::string str_resume;
-static std::string str_settings;
-static std::string str_leave;
-static std::string str_quit;
-
-static resource_ptr<TextureGUI> title;
-static float title_aspect;
-
-static void on_glfw_key(const io::GlfwKeyEvent& event)
-{
- if(session::is_ingame() && (event.key == GLFW_KEY_ESCAPE) && (event.action == GLFW_PRESS)) {
- if(globals::gui_screen == GUI_SCREEN_NONE) {
- globals::gui_screen = GUI_MAIN_MENU;
- return;
- }
-
- if(globals::gui_screen == GUI_MAIN_MENU) {
- globals::gui_screen = GUI_SCREEN_NONE;
- return;
- }
- }
-}
-
-static void on_language_set(const gui::LanguageSetEvent& event)
-{
- str_play = gui::language::resolve_gui("main_menu.play");
- str_resume = gui::language::resolve_gui("main_menu.resume");
- str_settings = gui::language::resolve("main_menu.settings");
- str_leave = gui::language::resolve("main_menu.leave");
- str_quit = gui::language::resolve("main_menu.quit");
-}
-
-void gui::main_menu::init(void)
-{
- title = resource::load<TextureGUI>("textures/gui/menu_title.png", TEXTURE_GUI_LOAD_CLAMP_S | TEXTURE_GUI_LOAD_CLAMP_T);
-
- if(title == nullptr) {
- spdlog::critical("main_menu: texture load failed");
- std::terminate();
- }
-
- if(title->size.x > title->size.y) {
- title_aspect = static_cast<float>(title->size.x) / static_cast<float>(title->size.y);
- }
- else {
- title_aspect = static_cast<float>(title->size.y) / static_cast<float>(title->size.x);
- }
-
- globals::dispatcher.sink<io::GlfwKeyEvent>().connect<&on_glfw_key>();
- globals::dispatcher.sink<LanguageSetEvent>().connect<&on_language_set>();
-}
-
-void gui::main_menu::shutdown(void)
-{
- title = nullptr;
-}
-
-void gui::main_menu::layout(void)
-{
- const auto viewport = ImGui::GetMainViewport();
- const auto window_start = ImVec2(0.0f, viewport->Size.y * 0.15f);
- const auto window_size = ImVec2(viewport->Size.x, viewport->Size.y);
-
- ImGui::SetNextWindowPos(window_start);
- ImGui::SetNextWindowSize(window_size);
-
- if(ImGui::Begin("###main_menu", nullptr, WINDOW_FLAGS)) {
- ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 2.0f * globals::gui_scale));
-
- if(session::is_ingame()) {
- ImGui::Dummy(ImVec2(0.0f, 32.0f * globals::gui_scale));
- }
- else {
- auto reference_height = 0.225f * window_size.y;
- auto image_width = glm::min(window_size.x, reference_height * title_aspect);
- auto image_height = image_width / title_aspect;
- ImGui::SetCursorPosX(0.5f * (window_size.x - image_width));
- ImGui::Image(title->handle, ImVec2(image_width, image_height));
- }
-
- ImGui::Dummy(ImVec2(0.0f, 24.0f * globals::gui_scale));
-
- const float button_width = 240.0f * globals::gui_scale;
- const float button_xpos = 0.5f * (window_size.x - button_width);
-
- if(session::is_ingame()) {
- ImGui::SetCursorPosX(button_xpos);
-
- if(ImGui::Button(str_resume.c_str(), ImVec2(button_width, 0.0f))) {
- globals::gui_screen = GUI_SCREEN_NONE;
- }
-
- ImGui::Spacing();
- }
- else {
- ImGui::SetCursorPosX(button_xpos);
-
- if(ImGui::Button(str_play.c_str(), ImVec2(button_width, 0.0f))) {
- globals::gui_screen = GUI_PLAY_MENU;
- }
-
- ImGui::Spacing();
- }
-
- ImGui::SetCursorPosX(button_xpos);
-
- if(ImGui::Button(str_settings.c_str(), ImVec2(button_width, 0.0f))) {
- globals::gui_screen = GUI_SETTINGS;
- }
-
- ImGui::Spacing();
-
- if(session::is_ingame()) {
- ImGui::SetCursorPosX(button_xpos);
-
- if(ImGui::Button(str_leave.c_str(), ImVec2(button_width, 0.0f))) {
- session::disconnect("protocol.client_disconnect");
- globals::gui_screen = GUI_PLAY_MENU;
- gui::window_title::update();
- }
-
- ImGui::Spacing();
- }
- else {
- ImGui::SetCursorPosX(button_xpos);
-
- if(ImGui::Button(str_quit.c_str(), ImVec2(button_width, 0.0f))) {
- glfwSetWindowShouldClose(globals::window, true);
- }
-
- ImGui::Spacing();
- }
-
- if(!session::is_ingame()) {
- const auto& padding = ImGui::GetStyle().FramePadding;
- const auto& spacing = ImGui::GetStyle().ItemSpacing;
-
- ImGui::PushFont(globals::font_unscii8, 4.0f);
- ImGui::SetCursorScreenPos(ImVec2(padding.x + spacing.x, window_size.y - ImGui::GetFontSize() - padding.y - spacing.y));
- ImGui::Text("Voxelius %*s", version::semver.size(), version::semver.data()); // string_view is not always null-terminated
- ImGui::PopFont();
- }
-
- ImGui::PopStyleVar();
- }
-
- ImGui::End();
-}
diff --git a/game/client/gui/main_menu.hh b/game/client/gui/main_menu.hh
deleted file mode 100644
index 8e30e38..0000000
--- a/game/client/gui/main_menu.hh
+++ /dev/null
@@ -1,8 +0,0 @@
-#pragma once
-
-namespace gui::main_menu
-{
-void init(void);
-void shutdown(void);
-void layout(void);
-} // namespace gui::main_menu
diff --git a/game/client/gui/message_box.cc b/game/client/gui/message_box.cc
deleted file mode 100644
index b7f109a..0000000
--- a/game/client/gui/message_box.cc
+++ /dev/null
@@ -1,95 +0,0 @@
-#include "client/pch.hh"
-
-#include "client/gui/message_box.hh"
-
-#include "client/gui/gui_screen.hh"
-#include "client/gui/language.hh"
-
-#include "client/globals.hh"
-
-constexpr static ImGuiWindowFlags WINDOW_FLAGS = ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration;
-
-struct Button final {
- gui::message_box_action action;
- std::string str_title;
-};
-
-static std::string str_title;
-static std::string str_subtitle;
-static std::vector<Button> buttons;
-
-void gui::message_box::init(void)
-{
- str_title = std::string();
- str_subtitle = std::string();
- buttons.clear();
-}
-
-void gui::message_box::layout(void)
-{
- const auto viewport = ImGui::GetMainViewport();
- const auto window_start = ImVec2(0.0f, viewport->Size.y * 0.30f);
- const auto window_size = ImVec2(viewport->Size.x, viewport->Size.y * 0.70f);
-
- ImGui::SetNextWindowPos(window_start);
- ImGui::SetNextWindowSize(window_size);
-
- if(ImGui::Begin("###UIProgress", nullptr, WINDOW_FLAGS)) {
- ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 1.0f * globals::gui_scale));
-
- const float title_width = ImGui::CalcTextSize(str_title.c_str()).x;
- ImGui::SetCursorPosX(0.5f * (window_size.x - title_width));
- ImGui::TextUnformatted(str_title.c_str());
-
- ImGui::Dummy(ImVec2(0.0f, 8.0f * globals::gui_scale));
-
- if(!str_subtitle.empty()) {
- const float subtitle_width = ImGui::CalcTextSize(str_subtitle.c_str()).x;
- ImGui::SetCursorPosX(0.5f * (window_size.x - subtitle_width));
- ImGui::TextUnformatted(str_subtitle.c_str());
- }
-
- ImGui::Dummy(ImVec2(0.0f, 32.0f * globals::gui_scale));
-
- for(const auto& button : buttons) {
- const float button_width = 0.8f * ImGui::CalcItemWidth();
- ImGui::SetCursorPosX(0.5f * (window_size.x - button_width));
-
- if(ImGui::Button(button.str_title.c_str(), ImVec2(button_width, 0.0f))) {
- if(button.action) {
- button.action();
- }
- }
- }
-
- ImGui::PopStyleVar();
- }
-
- ImGui::End();
-}
-
-void gui::message_box::reset(void)
-{
- str_title.clear();
- str_subtitle.clear();
- buttons.clear();
-}
-
-void gui::message_box::set_title(std::string_view title)
-{
- str_title = gui::language::resolve(title);
-}
-
-void gui::message_box::set_subtitle(std::string_view subtitle)
-{
- str_subtitle = gui::language::resolve(subtitle);
-}
-
-void gui::message_box::add_button(std::string_view text, const message_box_action& action)
-{
- Button button = {};
- button.str_title = std::format("{}###MessageBox_Button{}", gui::language::resolve(text), buttons.size());
- button.action = action;
-
- buttons.push_back(button);
-}
diff --git a/game/client/gui/message_box.hh b/game/client/gui/message_box.hh
deleted file mode 100644
index 06a3b8b..0000000
--- a/game/client/gui/message_box.hh
+++ /dev/null
@@ -1,20 +0,0 @@
-#pragma once
-
-namespace gui
-{
-using message_box_action = void (*)(void);
-} // namespace gui
-
-namespace gui::message_box
-{
-void init(void);
-void layout(void);
-void reset(void);
-} // namespace gui::message_box
-
-namespace gui::message_box
-{
-void set_title(std::string_view title);
-void set_subtitle(std::string_view subtitle);
-void add_button(std::string_view text, const message_box_action& action);
-} // namespace gui::message_box
diff --git a/game/client/gui/metrics.cc b/game/client/gui/metrics.cc
deleted file mode 100644
index ef47880..0000000
--- a/game/client/gui/metrics.cc
+++ /dev/null
@@ -1,103 +0,0 @@
-#include "client/pch.hh"
-
-#include "client/gui/metrics.hh"
-
-#include "core/version.hh"
-
-#include "shared/entity/grounded.hh"
-#include "shared/entity/head.hh"
-#include "shared/entity/transform.hh"
-#include "shared/entity/velocity.hh"
-
-#include "shared/world/dimension.hh"
-
-#include "shared/coord.hh"
-
-#include "client/entity/camera.hh"
-
-#include "client/gui/imdraw_ext.hh"
-
-#include "client/game.hh"
-#include "client/globals.hh"
-#include "client/session.hh"
-
-constexpr static ImGuiWindowFlags WINDOW_FLAGS = ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoInputs
- | ImGuiWindowFlags_NoNav;
-
-static std::basic_string<GLubyte> r_version;
-static std::basic_string<GLubyte> r_renderer;
-
-void gui::metrics::init(void)
-{
- r_version = std::basic_string<GLubyte>(glGetString(GL_VERSION));
- r_renderer = std::basic_string<GLubyte>(glGetString(GL_RENDERER));
-}
-
-void gui::metrics::layout(void)
-{
- if(!session::is_ingame()) {
- // Sanity check; we are checking this
- // in client_game before calling layout
- // on HUD-ish GUI systems but still
- return;
- }
-
- auto draw_list = ImGui::GetForegroundDrawList();
-
- // FIXME: maybe use style colors instead of hardcoding?
- auto text_color = ImGui::GetColorU32(ImVec4(1.0f, 1.0f, 1.0f, 1.0f));
- auto shadow_color = ImGui::GetColorU32(ImVec4(0.1f, 0.1f, 0.1f, 1.0f));
-
- auto font_size = 4.0f;
- auto position = ImVec2(8.0f, 8.0f);
- auto y_step = 1.5f * globals::gui_scale * font_size;
-
- // Draw version
- auto version_line = std::format("Voxelius {} [{}]", version::semver, version::commit);
- gui::imdraw_ext::text_shadow(version_line, position, text_color, shadow_color, globals::font_unscii8, draw_list, font_size);
- position.y += 1.5f * y_step;
-
- // Draw client-side window framerate metrics
- auto window_framerate = 1.0f / globals::window_frametime_avg;
- auto window_frametime = 1000.0f * globals::window_frametime_avg;
- auto window_fps_line = std::format("{:.02f} FPS [{:.02f} ms]", window_framerate, window_frametime);
- gui::imdraw_ext::text_shadow(window_fps_line, position, text_color, shadow_color, globals::font_unscii8, draw_list, font_size);
- position.y += y_step;
-
- // Draw world rendering metrics
- auto drawcall_line = std::format("World: {} DC / {} TRI", globals::num_drawcalls, globals::num_triangles);
- gui::imdraw_ext::text_shadow(drawcall_line, position, text_color, shadow_color, globals::font_unscii8, draw_list, font_size);
- position.y += y_step;
-
- // Draw OpenGL version string
- auto r_version_line = std::format("GL_VERSION: {}", reinterpret_cast<const char*>(r_version.c_str()));
- gui::imdraw_ext::text_shadow(r_version_line, position, text_color, shadow_color, globals::font_unscii8, draw_list, font_size);
- position.y += y_step;
-
- // Draw OpenGL renderer string
- auto r_renderer_line = std::format("GL_RENDERER: {}", reinterpret_cast<const char*>(r_renderer.c_str()));
- gui::imdraw_ext::text_shadow(r_renderer_line, position, text_color, shadow_color, globals::font_unscii8, draw_list, font_size);
- position.y += 1.5f * y_step;
-
- const auto& head = globals::dimension->entities.get<entity::Head>(globals::player);
- const auto& transform = globals::dimension->entities.get<entity::Transform>(globals::player);
- const auto& velocity = globals::dimension->entities.get<entity::Velocity>(globals::player);
-
- // Draw player voxel position
- auto voxel_position = coord::to_voxel(transform.chunk, transform.local);
- auto voxel_line = std::format("voxel: [{} {} {}]", voxel_position.x, voxel_position.y, voxel_position.z);
- gui::imdraw_ext::text_shadow(voxel_line, position, text_color, shadow_color, globals::font_unscii8, draw_list, font_size);
- position.y += y_step;
-
- // Draw player world position
- auto world_line = std::format("world: [{} {} {}] [{:.03f} {:.03f} {:.03f}]", transform.chunk.x, transform.chunk.y, transform.chunk.z,
- transform.local.x, transform.local.y, transform.local.z);
- gui::imdraw_ext::text_shadow(world_line, position, text_color, shadow_color, globals::font_unscii8, draw_list, font_size);
- position.y += y_step;
-
- // Draw player look angles
- auto angles = glm::degrees(transform.angles + head.angles);
- auto angle_line = std::format("angle: [{: .03f} {: .03f} {: .03f}]", angles[0], angles[1], angles[2]);
- gui::imdraw_ext::text_shadow(angle_line, position, text_color, shadow_color, globals::font_unscii8, draw_list, font_size);
- position.y += y_step;
-}
diff --git a/game/client/gui/metrics.hh b/game/client/gui/metrics.hh
deleted file mode 100644
index 6bec5cb..0000000
--- a/game/client/gui/metrics.hh
+++ /dev/null
@@ -1,7 +0,0 @@
-#pragma once
-
-namespace gui::metrics
-{
-void init(void);
-void layout(void);
-} // namespace gui::metrics
diff --git a/game/client/gui/play_menu.cc b/game/client/gui/play_menu.cc
deleted file mode 100644
index cd7f730..0000000
--- a/game/client/gui/play_menu.cc
+++ /dev/null
@@ -1,594 +0,0 @@
-#include "client/pch.hh"
-
-#include "client/gui/play_menu.hh"
-
-#include "core/config/boolean.hh"
-
-#include "core/io/config_map.hh"
-
-#include "core/math/constexpr.hh"
-
-#include "core/utils/string.hh"
-
-#include "core/version.hh"
-
-#include "shared/protocol.hh"
-
-#include "client/gui/bother.hh"
-#include "client/gui/gui_screen.hh"
-#include "client/gui/language.hh"
-
-#include "client/io/glfw.hh"
-
-#include "client/game.hh"
-#include "client/globals.hh"
-#include "client/session.hh"
-
-constexpr static ImGuiWindowFlags WINDOW_FLAGS = ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration;
-constexpr static std::string_view DEFAULT_SERVER_NAME = "Voxelius Server";
-constexpr static std::string_view SERVERS_TXT = "servers.txt";
-
-constexpr static std::size_t MAX_SERVER_ITEM_NAME = 18;
-
-enum class item_status : unsigned int {
- UNKNOWN = 0x0000U,
- PINGING = 0x0001U,
- REACHED = 0x0002U,
- FAILURE = 0x0003U,
-};
-
-struct ServerStatusItem final {
- std::string name;
- std::string password;
- std::string hostname;
- std::uint16_t port;
-
- // Things pulled from bother events
- std::uint16_t num_players;
- std::uint16_t max_players;
- std::string motd;
- std::uint16_t game_version_major;
- std::uint16_t game_version_minor;
- std::uint16_t game_version_patch;
-
- // Unique identifier that monotonically
- // grows with each new server added and
- // doesn't reset with each server removed
- unsigned int identity;
-
- item_status status;
-};
-
-static std::string str_tab_servers;
-
-static std::string str_join;
-static std::string str_connect;
-static std::string str_add;
-static std::string str_edit;
-static std::string str_remove;
-static std::string str_refresh;
-
-static std::string str_status_init;
-static std::string str_status_ping;
-static std::string str_status_fail;
-
-static std::string input_itemname;
-static std::string input_hostname;
-static std::string input_password;
-
-static unsigned int next_identity;
-static std::deque<ServerStatusItem*> servers_deque;
-static ServerStatusItem* selected_server;
-static bool editing_server;
-static bool adding_server;
-static bool needs_focus;
-
-static void parse_hostname(ServerStatusItem* item, const std::string& hostname)
-{
- auto parts = utils::split(hostname, ":");
-
- if(!parts[0].empty()) {
- item->hostname = parts[0];
- }
- else {
- item->hostname = std::string("localhost");
- }
-
- if(parts.size() >= 2) {
- item->port = glm::clamp<std::uint16_t>(strtoul(parts[1].c_str(), nullptr, 10), 1024, UINT16_MAX);
- }
- else {
- item->port = protocol::PORT;
- }
-}
-
-static void add_new_server(void)
-{
- auto item = new ServerStatusItem();
- item->port = protocol::PORT;
- item->max_players = UINT16_MAX;
- item->num_players = UINT16_MAX;
- item->identity = next_identity;
- item->status = item_status::UNKNOWN;
- item->game_version_major = 0U;
- item->game_version_minor = 0U;
- item->game_version_patch = 0U;
-
- next_identity += 1U;
-
- input_itemname = DEFAULT_SERVER_NAME;
- input_hostname = std::string();
- input_password = std::string();
-
- servers_deque.push_back(item);
- selected_server = item;
- editing_server = true;
- adding_server = true;
- needs_focus = true;
-}
-
-static void edit_selected_server(void)
-{
- input_itemname = selected_server->name;
-
- if(selected_server->port != protocol::PORT) {
- input_hostname = std::format("{}:{}", selected_server->hostname, selected_server->port);
- }
- else {
- input_hostname = selected_server->hostname;
- }
-
- input_password = selected_server->password;
-
- editing_server = true;
- needs_focus = true;
-}
-
-static void remove_selected_server(void)
-{
- gui::bother::cancel(selected_server->identity);
-
- for(auto it = servers_deque.cbegin(); it != servers_deque.cend(); ++it) {
- if(selected_server == (*it)) {
- delete selected_server;
- selected_server = nullptr;
- servers_deque.erase(it);
- return;
- }
- }
-}
-
-static void join_selected_server(void)
-{
- if(!session::peer) {
- session::connect(selected_server->hostname.c_str(), selected_server->port, selected_server->password.c_str());
- }
-}
-
-static void on_glfw_key(const io::GlfwKeyEvent& event)
-{
- if((event.key == GLFW_KEY_ESCAPE) && (event.action == GLFW_PRESS)) {
- if(globals::gui_screen == GUI_PLAY_MENU) {
- if(editing_server) {
- if(adding_server) {
- remove_selected_server();
- }
- else {
- input_itemname.clear();
- input_hostname.clear();
- input_password.clear();
- editing_server = false;
- adding_server = false;
- return;
- }
- }
-
- globals::gui_screen = GUI_MAIN_MENU;
- selected_server = nullptr;
- return;
- }
- }
-}
-
-static void on_language_set(const gui::LanguageSetEvent& event)
-{
- str_tab_servers = gui::language::resolve_gui("play_menu.tab.servers");
-
- str_join = gui::language::resolve_gui("play_menu.join");
- str_connect = gui::language::resolve_gui("play_menu.connect");
- str_add = gui::language::resolve_gui("play_menu.add");
- str_edit = gui::language::resolve_gui("play_menu.edit");
- str_remove = gui::language::resolve_gui("play_menu.remove");
- str_refresh = gui::language::resolve_gui("play_menu.refresh");
-
- str_status_init = gui::language::resolve("play_menu.status.init");
- str_status_ping = gui::language::resolve("play_menu.status.ping");
- str_status_fail = gui::language::resolve("play_menu.status.fail");
-}
-
-static void on_bother_response(const gui::BotherResponseEvent& event)
-{
- for(auto item : servers_deque) {
- if(item->identity == event.identity) {
- if(event.is_server_unreachable) {
- item->num_players = UINT16_MAX;
- item->max_players = UINT16_MAX;
- item->motd = str_status_fail;
- item->status = item_status::FAILURE;
- item->game_version_major = 0U;
- item->game_version_minor = 0U;
- item->game_version_patch = 0U;
- }
- else {
- item->num_players = event.num_players;
- item->max_players = event.max_players;
- item->motd = event.motd;
- item->status = item_status::REACHED;
- item->game_version_major = event.game_version_major;
- item->game_version_minor = event.game_version_minor;
- item->game_version_patch = event.game_version_patch;
- }
-
- break;
- }
- }
-}
-
-static void layout_server_item(ServerStatusItem* item)
-{
- // Preserve the cursor at which we draw stuff
- const ImVec2& cursor = ImGui::GetCursorScreenPos();
- const ImVec2& padding = ImGui::GetStyle().FramePadding;
- const ImVec2& spacing = ImGui::GetStyle().ItemSpacing;
-
- const float item_width = ImGui::GetContentRegionAvail().x;
- const float line_height = ImGui::GetTextLineHeightWithSpacing();
- const std::string sid = std::format("###play_menu.servers.{}", static_cast<void*>(item));
- if(ImGui::Selectable(sid.c_str(), (item == selected_server), 0, ImVec2(0.0, 2.0f * (line_height + padding.y + spacing.y)))) {
- selected_server = item;
- editing_server = false;
- }
-
- if(ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) {
- // Double clicked - join the selected server
- join_selected_server();
- }
-
- ImDrawList* draw_list = ImGui::GetWindowDrawList();
-
- if(item == selected_server) {
- const ImVec2 start = ImVec2(cursor.x, cursor.y);
- const ImVec2 end = ImVec2(start.x + item_width, start.y + 2.0f * (line_height + padding.y + spacing.y));
- draw_list->AddRect(start, end, ImGui::GetColorU32(ImGuiCol_Text), 0.0f, 0, globals::gui_scale);
- }
-
- const ImVec2 name_pos = ImVec2(cursor.x + padding.x + 0.5f * spacing.x, cursor.y + padding.y);
- draw_list->AddText(name_pos, ImGui::GetColorU32(ImGuiCol_Text), item->name.c_str(), item->name.c_str() + item->name.size());
-
- if(item->status == item_status::REACHED) {
- auto stats = std::format("{}/{}", item->num_players, item->max_players);
- auto stats_size = ImGui::CalcTextSize(stats.c_str(), stats.c_str() + stats.size());
- auto stats_pos = ImVec2(cursor.x + item_width - stats_size.x - padding.x, cursor.y + padding.y);
- draw_list->AddText(stats_pos, ImGui::GetColorU32(ImGuiCol_TextDisabled), stats.c_str(), stats.c_str() + stats.size());
-
- auto major_version_mismatch = item->game_version_major != version::major;
- auto minor_version_mismatch = item->game_version_minor != version::minor;
- auto patch_version_mismatch = item->game_version_patch != version::patch;
-
- ImU32 version_color;
-
- if(major_version_mismatch || minor_version_mismatch || patch_version_mismatch) {
- version_color = ImGui::GetColorU32(major_version_mismatch ? ImGuiCol_PlotLinesHovered : ImGuiCol_DragDropTarget);
- }
- else {
- version_color = ImGui::GetColorU32(ImGuiCol_PlotHistogram);
- }
-
- ImGui::PushFont(globals::font_unscii8, 4.0f);
-
- std::string version_toast;
-
- if(item->game_version_major < 16U) {
- // Pre v16.x.x servers didn't send minor and patch versions
- // and also used a different versioning scheme; post v16 the
- // major version became the protocol version and the semver lost the tweak part
- version_toast = std::string("15.x.x");
- }
- else {
- version_toast = std::format("{}.{}.{}", item->game_version_major, item->game_version_minor, item->game_version_patch);
- }
-
- auto version_size = ImGui::CalcTextSize(version_toast.c_str(), version_toast.c_str() + version_toast.size());
- auto version_pos = ImVec2(stats_pos.x - version_size.x - padding.x - 4.0f * globals::gui_scale,
- cursor.y + padding.y + 0.5f * (stats_size.y - version_size.y));
- auto version_end = ImVec2(version_pos.x + version_size.x, version_pos.y + version_size.y);
-
- auto outline_pos = ImVec2(version_pos.x - 2U * globals::gui_scale, version_pos.y - 2U * globals::gui_scale);
- auto outline_end = ImVec2(version_end.x + 2U * globals::gui_scale, version_end.y + 2U * globals::gui_scale);
- auto outline_thickness = glm::max<float>(1.0f, 0.5f * static_cast<float>(globals::gui_scale));
-
- draw_list->AddRect(outline_pos, outline_end, version_color, 0.0f, 0, outline_thickness);
- draw_list->AddText(version_pos, version_color, version_toast.c_str(), version_toast.c_str() + version_toast.size());
-
- ImGui::PopFont();
- }
-
- ImU32 motd_color = {};
- const std::string* motd_text;
-
- switch(item->status) {
- case item_status::UNKNOWN:
- motd_color = ImGui::GetColorU32(ImGuiCol_TextDisabled);
- motd_text = &str_status_init;
- break;
- case item_status::PINGING:
- motd_color = ImGui::GetColorU32(ImGuiCol_TextDisabled);
- motd_text = &str_status_ping;
- break;
- case item_status::REACHED:
- motd_color = ImGui::GetColorU32(ImGuiCol_TextDisabled);
- motd_text = &item->motd;
- break;
- default:
- motd_color = ImGui::GetColorU32(ImGuiCol_PlotLinesHovered);
- motd_text = &str_status_fail;
- break;
- }
-
- const ImVec2 motd_pos = ImVec2(cursor.x + padding.x + 0.5f * spacing.x, cursor.y + padding.y + line_height);
- draw_list->AddText(motd_pos, motd_color, motd_text->c_str(), motd_text->c_str() + motd_text->size());
-}
-
-static void layout_server_edit(ServerStatusItem* item)
-{
- if(needs_focus) {
- ImGui::SetKeyboardFocusHere();
- needs_focus = false;
- }
-
- ImGui::SetNextItemWidth(-0.25f * ImGui::GetContentRegionAvail().x);
- ImGui::InputText("###play_menu.servers.edit_itemname", &input_itemname);
- ImGui::SameLine();
-
- const bool ignore_input = utils::is_whitespace(input_itemname) || input_hostname.empty();
-
- ImGui::BeginDisabled(ignore_input);
-
- if(ImGui::Button("OK###play_menu.servers.submit_input", ImVec2(-1.0f, 0.0f))
- || (!ignore_input && ImGui::IsKeyPressed(ImGuiKey_Enter))) {
- parse_hostname(item, input_hostname);
- item->password = input_password;
- item->name = input_itemname.substr(0, MAX_SERVER_ITEM_NAME);
- item->status = item_status::UNKNOWN;
- editing_server = false;
- adding_server = false;
-
- input_itemname.clear();
- input_hostname.clear();
-
- gui::bother::cancel(item->identity);
- }
-
- ImGui::EndDisabled();
-
- ImGuiInputTextFlags hostname_flags = ImGuiInputTextFlags_CharsNoBlank;
-
- if(client_game::streamer_mode.get_value()) {
- // Hide server hostname to avoid things like
- // followers flooding the server that is streamed online
- hostname_flags |= ImGuiInputTextFlags_Password;
- }
-
- ImGui::SetNextItemWidth(-0.50f * ImGui::GetContentRegionAvail().x);
- ImGui::InputText("###play_menu.servers.edit_hostname", &input_hostname, hostname_flags);
- ImGui::SameLine();
-
- ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
- ImGui::InputText("###play_menu.servers.edit_password", &input_password, ImGuiInputTextFlags_Password);
-}
-
-static void layout_servers(void)
-{
- if(ImGui::BeginListBox("###play_menu.servers.listbox", ImVec2(-1.0f, -1.0f))) {
- for(ServerStatusItem* item : servers_deque) {
- if(editing_server && item == selected_server) {
- layout_server_edit(item);
- }
- else {
- layout_server_item(item);
- }
- }
-
- ImGui::EndListBox();
- }
-}
-
-static void layout_servers_buttons(void)
-{
- auto avail_width = ImGui::GetContentRegionAvail().x;
-
- // Can only join when selected and not editing
- ImGui::BeginDisabled(!selected_server || editing_server);
-
- if(ImGui::Button(str_join.c_str(), ImVec2(-0.50f * avail_width, 0.0f))) {
- join_selected_server();
- }
-
- ImGui::EndDisabled();
- ImGui::SameLine();
-
- // Can only connect directly when not editing anything
- ImGui::BeginDisabled(editing_server);
-
- if(ImGui::Button(str_connect.c_str(), ImVec2(-1.00f, 0.0f))) {
- globals::gui_screen = GUI_DIRECT_CONNECTION;
- }
-
- ImGui::EndDisabled();
-
- // Can only add when not editing anything
- ImGui::BeginDisabled(editing_server);
-
- if(ImGui::Button(str_add.c_str(), ImVec2(-0.75f * avail_width, 0.0f))) {
- add_new_server();
- }
-
- ImGui::EndDisabled();
- ImGui::SameLine();
-
- // Can only edit when selected and not editing
- ImGui::BeginDisabled(!selected_server || editing_server);
-
- if(ImGui::Button(str_edit.c_str(), ImVec2(-0.50f * avail_width, 0.0f))) {
- edit_selected_server();
- }
-
- ImGui::EndDisabled();
- ImGui::SameLine();
-
- // Can only remove when selected and not editing
- ImGui::BeginDisabled(!selected_server || editing_server);
-
- if(ImGui::Button(str_remove.c_str(), ImVec2(-0.25f * avail_width, 0.0f))) {
- remove_selected_server();
- }
-
- ImGui::EndDisabled();
- ImGui::SameLine();
-
- if(ImGui::Button(str_refresh.c_str(), ImVec2(-1.0f, 0.0f))) {
- for(ServerStatusItem* item : servers_deque) {
- if(item->status != item_status::PINGING) {
- if(!editing_server || item != selected_server) {
- item->status = item_status::UNKNOWN;
- gui::bother::cancel(item->identity);
- }
- }
- }
- }
-}
-
-void gui::play_menu::init(void)
-{
- if(auto file = PHYSFS_openRead(std::string(SERVERS_TXT).c_str())) {
- auto source = std::string(PHYSFS_fileLength(file), char(0x00));
- PHYSFS_readBytes(file, source.data(), source.size());
- PHYSFS_close(file);
-
- auto stream = std::istringstream(source);
- auto line = std::string();
-
- while(std::getline(stream, line)) {
- auto parts = utils::split(line, "%");
-
- auto item = new ServerStatusItem();
- item->port = protocol::PORT;
- item->max_players = UINT16_MAX;
- item->num_players = UINT16_MAX;
- item->identity = next_identity;
- item->status = item_status::UNKNOWN;
- item->game_version_major = version::major;
- item->game_version_minor = version::minor;
- item->game_version_patch = version::patch;
-
- next_identity += 1U;
-
- parse_hostname(item, parts[0]);
-
- if(parts.size() >= 2) {
- item->password = parts[1];
- }
- else {
- item->password = std::string();
- }
-
- if(parts.size() >= 3) {
- item->name = parts[2].substr(0, MAX_SERVER_ITEM_NAME);
- }
- else {
- item->name = DEFAULT_SERVER_NAME;
- }
-
- servers_deque.push_back(item);
- }
- }
-
- globals::dispatcher.sink<io::GlfwKeyEvent>().connect<&on_glfw_key>();
- globals::dispatcher.sink<LanguageSetEvent>().connect<&on_language_set>();
- globals::dispatcher.sink<BotherResponseEvent>().connect<&on_bother_response>();
-}
-
-void gui::play_menu::shutdown(void)
-{
- std::ostringstream stream;
-
- for(const auto item : servers_deque) {
- stream << std::format("{}:{}%{}%{}", item->hostname, item->port, item->password, item->name) << std::endl;
- }
-
- if(auto file = PHYSFS_openWrite(std::string(SERVERS_TXT).c_str())) {
- auto source = stream.str();
- PHYSFS_writeBytes(file, source.data(), source.size());
- PHYSFS_close(file);
- }
-
- for(auto item : servers_deque)
- delete item;
- servers_deque.clear();
-}
-
-void gui::play_menu::layout(void)
-{
- const auto viewport = ImGui::GetMainViewport();
- const auto window_start = ImVec2(viewport->Size.x * 0.05f, viewport->Size.y * 0.05f);
- const auto window_size = ImVec2(viewport->Size.x * 0.90f, viewport->Size.y * 0.90f);
-
- ImGui::SetNextWindowPos(window_start);
- ImGui::SetNextWindowSize(window_size);
-
- if(ImGui::Begin("###play_menu", nullptr, WINDOW_FLAGS)) {
- ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(3.0f * globals::gui_scale, 3.0f * globals::gui_scale));
-
- if(ImGui::BeginTabBar("###play_menu.tabs", ImGuiTabBarFlags_FittingPolicyResizeDown)) {
- if(ImGui::TabItemButton("<<")) {
- globals::gui_screen = GUI_MAIN_MENU;
- selected_server = nullptr;
- editing_server = false;
- }
-
- if(ImGui::BeginTabItem(str_tab_servers.c_str())) {
- if(ImGui::BeginChild("###play_menu.servers.child", ImVec2(0.0f, -2.0f * ImGui::GetFrameHeightWithSpacing()))) {
- layout_servers();
- }
-
- ImGui::EndChild();
-
- layout_servers_buttons();
-
- ImGui::EndTabItem();
- }
-
- if(ImGui::BeginTabItem("debug###play_menu.debug.child")) {
- ImGui::ShowStyleEditor();
- ImGui::EndTabItem();
- }
-
- ImGui::EndTabBar();
- }
-
- ImGui::PopStyleVar();
- }
-
- ImGui::End();
-}
-
-void gui::play_menu::update_late(void)
-{
- for(auto item : servers_deque) {
- if(item->status == item_status::UNKNOWN) {
- gui::bother::ping(item->identity, item->hostname.c_str(), item->port);
- item->status = item_status::PINGING;
- continue;
- }
- }
-}
diff --git a/game/client/gui/play_menu.hh b/game/client/gui/play_menu.hh
deleted file mode 100644
index 15f7c89..0000000
--- a/game/client/gui/play_menu.hh
+++ /dev/null
@@ -1,9 +0,0 @@
-#pragma once
-
-namespace gui::play_menu
-{
-void init(void);
-void shutdown(void);
-void layout(void);
-void update_late(void);
-} // namespace gui::play_menu
diff --git a/game/client/gui/progress_bar.cc b/game/client/gui/progress_bar.cc
deleted file mode 100644
index 46277b5..0000000
--- a/game/client/gui/progress_bar.cc
+++ /dev/null
@@ -1,111 +0,0 @@
-#include "client/pch.hh"
-
-#include "client/gui/progress_bar.hh"
-
-#include "core/math/constexpr.hh"
-
-#include "client/gui/language.hh"
-
-#include "client/globals.hh"
-
-constexpr static ImGuiWindowFlags WINDOW_FLAGS = ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration;
-
-static std::string str_title;
-static std::string str_button;
-static gui::progress_bar_action button_action;
-
-void gui::progress_bar::init(void)
-{
- str_title = "Loading";
- str_button = std::string();
- button_action = nullptr;
-}
-
-void gui::progress_bar::layout(void)
-{
- const auto viewport = ImGui::GetMainViewport();
- const auto window_start = ImVec2(0.0f, viewport->Size.y * 0.30f);
- const auto window_size = ImVec2(viewport->Size.x, viewport->Size.y * 0.70f);
-
- ImGui::SetNextWindowPos(window_start);
- ImGui::SetNextWindowSize(window_size);
-
- if(ImGui::Begin("###UIProgress", nullptr, WINDOW_FLAGS)) {
- ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 1.0f * globals::gui_scale));
-
- const float title_width = ImGui::CalcTextSize(str_title.c_str()).x;
- ImGui::SetCursorPosX(0.5f * (window_size.x - title_width));
- ImGui::TextUnformatted(str_title.c_str());
-
- ImGui::Dummy(ImVec2(0.0f, 8.0f * globals::gui_scale));
-
- const ImVec2 cursor = ImGui::GetCursorPos();
-
- const std::size_t num_bars = 32;
- const float spinner_width = 0.8f * ImGui::CalcItemWidth();
- const float bar_width = spinner_width / static_cast<float>(num_bars);
- const float bar_height = 0.5f * ImGui::GetFrameHeight();
-
- const float base_xpos = window_start.x + 0.5f * (window_size.x - spinner_width) + 0.5f;
- const float base_ypos = window_start.y + cursor.y;
- const float phase = 2.0f * ImGui::GetTime();
-
- const ImVec4& background = ImGui::GetStyleColorVec4(ImGuiCol_Button);
- const ImVec4& foreground = ImGui::GetStyleColorVec4(ImGuiCol_PlotHistogram);
-
- for(std::size_t i = 0; i < num_bars; ++i) {
- const float sinval = std::sin(M_PI * static_cast<float>(i) / static_cast<float>(num_bars) - phase);
- const float modifier = std::exp(-8.0f * (0.5f + 0.5f * sinval));
-
- ImVec4 color = {};
- color.x = glm::mix(background.x, foreground.x, modifier);
- color.y = glm::mix(background.y, foreground.y, modifier);
- color.z = glm::mix(background.z, foreground.z, modifier);
- color.w = glm::mix(background.w, foreground.w, modifier);
-
- const ImVec2 start = ImVec2(base_xpos + bar_width * i, base_ypos);
- const ImVec2 end = ImVec2(start.x + bar_width, start.y + bar_height);
- ImGui::GetWindowDrawList()->AddRectFilled(start, end, ImGui::GetColorU32(color));
- }
-
- // The NewLine call tricks ImGui into correctly padding the
- // next widget that comes after the progress_bar spinner; this
- // is needed to ensure the button is located in the correct place
- ImGui::NewLine();
-
- if(!str_button.empty()) {
- ImGui::Dummy(ImVec2(0.0f, 32.0f * globals::gui_scale));
-
- const float button_width = 0.8f * ImGui::CalcItemWidth();
- ImGui::SetCursorPosX(0.5f * (window_size.x - button_width));
-
- if(ImGui::Button(str_button.c_str(), ImVec2(button_width, 0.0f))) {
- if(button_action) {
- button_action();
- }
- }
- }
-
- ImGui::PopStyleVar();
- }
-
- ImGui::End();
-}
-
-void gui::progress_bar::reset(void)
-{
- str_title.clear();
- str_button.clear();
- button_action = nullptr;
-}
-
-void gui::progress_bar::set_title(std::string_view title)
-{
- str_title = gui::language::resolve(title);
-}
-
-void gui::progress_bar::set_button(std::string_view text, const progress_bar_action& action)
-{
- str_button = std::format("{}###ProgressBar_Button", gui::language::resolve(text));
- button_action = action;
-}
diff --git a/game/client/gui/progress_bar.hh b/game/client/gui/progress_bar.hh
deleted file mode 100644
index 5f2e601..0000000
--- a/game/client/gui/progress_bar.hh
+++ /dev/null
@@ -1,19 +0,0 @@
-#pragma once
-
-namespace gui
-{
-using progress_bar_action = void (*)(void);
-} // namespace gui
-
-namespace gui::progress_bar
-{
-void init(void);
-void layout(void);
-} // namespace gui::progress_bar
-
-namespace gui::progress_bar
-{
-void reset(void);
-void set_title(std::string_view title);
-void set_button(std::string_view text, const progress_bar_action& action);
-} // namespace gui::progress_bar
diff --git a/game/client/gui/scoreboard.cc b/game/client/gui/scoreboard.cc
deleted file mode 100644
index 12a4f41..0000000
--- a/game/client/gui/scoreboard.cc
+++ /dev/null
@@ -1,103 +0,0 @@
-#include "client/pch.hh"
-
-#include "client/gui/scoreboard.hh"
-
-#include "core/io/config_map.hh"
-
-#include "shared/protocol.hh"
-
-#include "client/config/keybind.hh"
-
-#include "client/gui/gui_screen.hh"
-#include "client/gui/settings.hh"
-
-#include "client/globals.hh"
-#include "client/session.hh"
-
-constexpr static ImGuiWindowFlags WINDOW_FLAGS = ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoInputs
- | ImGuiWindowFlags_NoBackground;
-
-static config::KeyBind list_key(GLFW_KEY_TAB);
-
-static std::vector<std::string> usernames;
-static float max_username_size;
-
-static void on_scoreboard_update_packet(const protocol::ScoreboardUpdate& packet)
-{
- usernames = packet.names;
- max_username_size = 0.0f;
-}
-
-void gui::scoreboard::init(void)
-{
- globals::client_config.add_value("scoreboard.key", list_key);
-
- settings::add_keybind(3, list_key, settings_location::KEYBOARD_MISC, "key.scoreboard");
-
- globals::dispatcher.sink<protocol::ScoreboardUpdate>().connect<&on_scoreboard_update_packet>();
-}
-
-void gui::scoreboard::layout(void)
-{
- if(globals::gui_screen == GUI_SCREEN_NONE && session::is_ingame() && glfwGetKey(globals::window, list_key.get_key()) == GLFW_PRESS) {
- const auto viewport = ImGui::GetMainViewport();
- const auto window_start = ImVec2(0.0f, 0.0f);
- const auto window_size = ImVec2(viewport->Size.x, viewport->Size.y);
-
- ImGui::SetNextWindowPos(window_start);
- ImGui::SetNextWindowSize(window_size);
-
- if(!ImGui::Begin("###chat", nullptr, WINDOW_FLAGS)) {
- ImGui::End();
- return;
- }
-
- ImGui::PushFont(globals::font_unscii16, 8.0f);
-
- const auto& padding = ImGui::GetStyle().FramePadding;
- const auto& spacing = ImGui::GetStyle().ItemSpacing;
- auto font = globals::font_unscii8;
-
- // Figure out the maximum username size
- for(const auto& username : usernames) {
- const ImVec2 size = ImGui::CalcTextSize(username.c_str(), username.c_str() + username.size());
-
- if(size.x > max_username_size) {
- max_username_size = size.x;
- }
- }
-
- // Having a minimum size allows for
- // generally better in-game visibility
- const float true_size = glm::max<float>(0.25f * window_size.x, max_username_size);
-
- // Figure out username rect dimensions
- const float rect_start_x = 0.5f * window_size.x - 0.5f * true_size;
- const float rect_start_y = 0.15f * window_size.y;
- const float rect_size_x = 2.0f * padding.x + true_size;
- const float rect_size_y = 2.0f * padding.y + 0.5f * ImGui::GetFontSize();
-
- // const ImU32 border_col = ImGui::GetColorU32(ImGuiCol_Border, 1.00f);
- const ImU32 rect_col = ImGui::GetColorU32(ImGuiCol_FrameBg, 0.80f);
- const ImU32 text_col = ImGui::GetColorU32(ImGuiCol_Text, 1.00f);
-
- ImDrawList* draw_list = ImGui::GetWindowDrawList();
-
- // Slightly space apart individual rows
- const float row_step_y = rect_size_y + 0.5f * spacing.y;
-
- for(std::size_t i = 0; i < usernames.size(); ++i) {
- const ImVec2 rect_a = ImVec2(rect_start_x, rect_start_y + i * row_step_y);
- const ImVec2 rect_b = ImVec2(rect_a.x + rect_size_x, rect_a.y + rect_size_y);
- const ImVec2 text_pos = ImVec2(rect_a.x + padding.x, rect_a.y + padding.y);
-
- // draw_list->AddRect(rect_a, rect_b, border_col, 0.0f, ImDrawFlags_None, globals::gui_scale);
- draw_list->AddRectFilled(rect_a, rect_b, rect_col, 0.0f, ImDrawFlags_None);
- draw_list->AddText(font, 0.5f * ImGui::GetFontSize(), text_pos, text_col, usernames[i].c_str(),
- usernames[i].c_str() + usernames[i].size());
- }
-
- ImGui::PopFont();
- ImGui::End();
- }
-}
diff --git a/game/client/gui/scoreboard.hh b/game/client/gui/scoreboard.hh
deleted file mode 100644
index 5f1c59d..0000000
--- a/game/client/gui/scoreboard.hh
+++ /dev/null
@@ -1,7 +0,0 @@
-#pragma once
-
-namespace gui::scoreboard
-{
-void init(void);
-void layout(void);
-} // namespace gui::scoreboard
diff --git a/game/client/gui/settings.cc b/game/client/gui/settings.cc
deleted file mode 100644
index db26d8c..0000000
--- a/game/client/gui/settings.cc
+++ /dev/null
@@ -1,1069 +0,0 @@
-#include "client/pch.hh"
-
-#include "client/gui/settings.hh"
-
-#include "core/config/boolean.hh"
-#include "core/config/number.hh"
-#include "core/config/string.hh"
-
-#include "core/io/config_map.hh"
-
-#include "core/math/constexpr.hh"
-
-#include "client/config/gamepad_axis.hh"
-#include "client/config/gamepad_button.hh"
-#include "client/config/keybind.hh"
-
-#include "client/gui/gui_screen.hh"
-#include "client/gui/language.hh"
-
-#include "client/io/gamepad.hh"
-#include "client/io/glfw.hh"
-
-#include "client/const.hh"
-#include "client/globals.hh"
-
-constexpr static ImGuiWindowFlags WINDOW_FLAGS = ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration;
-constexpr static unsigned int NUM_LOCATIONS = static_cast<unsigned int>(settings_location::COUNT);
-
-enum class setting_type : unsigned int {
- CHECKBOX = 0x0000U, ///< config::Boolean
- INPUT_INT = 0x0001U, ///< config::Number<int>
- INPUT_FLOAT = 0x0002U, ///< config::Number<float>
- INPUT_UINT = 0x0003U, ///< config::Number<unsigned int>
- INPUT_STRING = 0x0004U, ///< config::String
- SLIDER_INT = 0x0005U, ///< config::Number<int>
- SLIDER_FLOAT = 0x0006U, ///< config::Number<float>
- SLIDER_UINT = 0x0007U, ///< config::Number<unsigned int>
- STEPPER_INT = 0x0008U, ///< config::Number<int>
- STEPPER_UINT = 0x0009U, ///< config::Number<unsigned int>
- KEYBIND = 0x000AU, ///< config::KeyBind
- GAMEPAD_AXIS = 0x000BU, ///< config::GamepadAxis
- GAMEPAD_BUTTON = 0x000CU, ///< config::GamepadButton
- LANGUAGE_SELECT = 0x000DU, ///< config::String internally
-};
-
-class SettingValue {
-public:
- virtual ~SettingValue(void) = default;
- virtual void layout(void) const = 0;
- void layout_tooltip(void) const;
- void layout_label(void) const;
-
-public:
- setting_type type;
- std::string tooltip;
- std::string title;
- std::string name;
- bool has_tooltip;
- int priority;
-};
-
-class SettingValueWID : public SettingValue {
-public:
- virtual ~SettingValueWID(void) = default;
-
-public:
- std::string wid;
-};
-
-class SettingValue_CheckBox final : public SettingValue {
-public:
- virtual ~SettingValue_CheckBox(void) = default;
- virtual void layout(void) const override;
- void refresh_wids(void);
-
-public:
- config::Boolean* value;
- std::string wids[2];
-};
-
-class SettingValue_InputInt final : public SettingValueWID {
-public:
- virtual ~SettingValue_InputInt(void) = default;
- virtual void layout(void) const override;
-
-public:
- config::Int* value;
-};
-
-class SettingValue_InputFloat final : public SettingValueWID {
-public:
- virtual ~SettingValue_InputFloat(void) = default;
- virtual void layout(void) const override;
-
-public:
- std::string format;
- config::Float* value;
-};
-
-class SettingValue_InputUnsigned final : public SettingValueWID {
-public:
- virtual ~SettingValue_InputUnsigned(void) = default;
- virtual void layout(void) const override;
-
-public:
- config::Unsigned* value;
-};
-
-class SettingValue_InputString final : public SettingValueWID {
-public:
- virtual ~SettingValue_InputString(void) = default;
- virtual void layout(void) const override;
-
-public:
- config::String* value;
- bool allow_whitespace;
-};
-
-class SettingValue_SliderInt final : public SettingValueWID {
-public:
- virtual ~SettingValue_SliderInt(void) = default;
- virtual void layout(void) const override;
-
-public:
- config::Int* value;
-};
-
-class SettingValue_SliderFloat final : public SettingValueWID {
-public:
- virtual ~SettingValue_SliderFloat(void) = default;
- virtual void layout(void) const override;
-
-public:
- std::string format;
- config::Float* value;
-};
-
-class SettingValue_SliderUnsigned final : public SettingValueWID {
-public:
- virtual ~SettingValue_SliderUnsigned(void) = default;
- virtual void layout(void) const override;
-
-public:
- config::Unsigned* value;
-};
-
-class SettingValue_StepperInt final : public SettingValue {
-public:
- virtual ~SettingValue_StepperInt(void) = default;
- virtual void layout(void) const override;
- void refresh_wids(void);
-
-public:
- std::vector<std::string> wids;
- config::Int* value;
-};
-
-class SettingValue_StepperUnsigned final : public SettingValue {
-public:
- virtual ~SettingValue_StepperUnsigned(void) = default;
- virtual void layout(void) const override;
- void refresh_wids(void);
-
-public:
- std::vector<std::string> wids;
- config::Unsigned* value;
-};
-
-class SettingValue_KeyBind final : public SettingValue {
-public:
- virtual ~SettingValue_KeyBind(void) = default;
- virtual void layout(void) const override;
- void refresh_wids(void);
-
-public:
- std::string wids[2];
- config::KeyBind* value;
-};
-
-class SettingValue_GamepadAxis final : public SettingValue {
-public:
- virtual ~SettingValue_GamepadAxis(void) = default;
- virtual void layout(void) const override;
- void refresh_wids(void);
-
-public:
- std::string wids[2];
- std::string wid_checkbox;
- config::GamepadAxis* value;
-};
-
-class SettingValue_GamepadButton final : public SettingValue {
-public:
- virtual ~SettingValue_GamepadButton(void) = default;
- virtual void layout(void) const override;
- void refresh_wids(void);
-
-public:
- std::string wids[2];
- config::GamepadButton* value;
-};
-
-class SettingValue_Language final : public SettingValueWID {
-public:
- virtual ~SettingValue_Language(void) = default;
- virtual void layout(void) const override;
-};
-
-static std::string str_checkbox_false;
-static std::string str_checkbox_true;
-
-static std::string str_tab_general;
-static std::string str_tab_input;
-static std::string str_tab_video;
-static std::string str_tab_sound;
-
-static std::string str_input_keyboard;
-static std::string str_input_gamepad;
-static std::string str_input_mouse;
-
-static std::string str_keyboard_movement;
-static std::string str_keyboard_gameplay;
-static std::string str_keyboard_misc;
-
-static std::string str_gamepad_movement;
-static std::string str_gamepad_gameplay;
-static std::string str_gamepad_misc;
-
-static std::string str_gamepad_axis_prefix;
-static std::string str_gamepad_button_prefix;
-static std::string str_gamepad_checkbox_tooltip;
-
-static std::string str_video_gui;
-
-static std::string str_sound_levels;
-
-static std::vector<SettingValue*> values_all;
-static std::vector<SettingValue*> values[NUM_LOCATIONS];
-
-void SettingValue::layout_tooltip(void) const
-{
- if(has_tooltip) {
- ImGui::SameLine();
- ImGui::TextDisabled("[?]");
-
- if(ImGui::BeginItemTooltip()) {
- ImGui::PushTextWrapPos(ImGui::GetFontSize() * 16.0f);
- ImGui::TextUnformatted(tooltip.c_str());
- ImGui::PopTextWrapPos();
- ImGui::EndTooltip();
- }
- }
-}
-
-void SettingValue::layout_label(void) const
-{
- ImGui::SameLine();
- ImGui::TextUnformatted(title.c_str());
-}
-
-void SettingValue_CheckBox::refresh_wids(void)
-{
- wids[0] = std::format("{}###{}", str_checkbox_false, static_cast<void*>(value));
- wids[1] = std::format("{}###{}", str_checkbox_true, static_cast<void*>(value));
-}
-
-void SettingValue_CheckBox::layout(void) const
-{
- const auto& wid = value->get_value() ? wids[1] : wids[0];
-
- if(ImGui::Button(wid.c_str(), ImVec2(ImGui::CalcItemWidth(), 0.0f))) {
- value->set_value(!value->get_value());
- }
-
- layout_label();
- layout_tooltip();
-}
-
-void SettingValue_InputInt::layout(void) const
-{
- auto current_value = value->get_value();
-
- if(ImGui::InputInt(wid.c_str(), &current_value)) {
- value->set_value(current_value);
- }
-
- layout_label();
- layout_tooltip();
-}
-
-void SettingValue_InputFloat::layout(void) const
-{
- auto current_value = value->get_value();
-
- if(ImGui::InputFloat(wid.c_str(), &current_value, 0.0f, 0.0f, format.c_str())) {
- value->set_value(current_value);
- }
-
- layout_label();
- layout_tooltip();
-}
-
-void SettingValue_InputUnsigned::layout(void) const
-{
- auto current_value = static_cast<std::uint32_t>(value->get_value());
-
- if(ImGui::InputScalar(wid.c_str(), ImGuiDataType_U32, &current_value)) {
- value->set_value(current_value);
- }
-
- layout_label();
- layout_tooltip();
-}
-
-void SettingValue_InputString::layout(void) const
-{
- ImGuiInputTextFlags flags;
- std::string current_value(value->get_value());
-
- if(allow_whitespace) {
- flags = ImGuiInputTextFlags_AllowTabInput;
- }
- else {
- flags = 0;
- }
-
- if(ImGui::InputText(wid.c_str(), &current_value, flags)) {
- value->set(current_value);
- }
-
- layout_label();
- layout_tooltip();
-}
-
-void SettingValue_SliderInt::layout(void) const
-{
- auto current_value = value->get_value();
-
- if(ImGui::SliderInt(wid.c_str(), &current_value, value->get_min_value(), value->get_max_value())) {
- value->set_value(current_value);
- }
-
- layout_label();
- layout_tooltip();
-}
-
-void SettingValue_SliderFloat::layout(void) const
-{
- auto current_value = value->get_value();
-
- if(ImGui::SliderFloat(wid.c_str(), &current_value, value->get_min_value(), value->get_max_value(), format.c_str())) {
- value->set_value(current_value);
- }
-
- layout_label();
- layout_tooltip();
-}
-
-void SettingValue_SliderUnsigned::layout(void) const
-{
- auto current_value = static_cast<std::uint32_t>(value->get_value());
- auto min_value = static_cast<std::uint32_t>(value->get_min_value());
- auto max_value = static_cast<std::uint32_t>(value->get_max_value());
-
- if(ImGui::SliderScalar(wid.c_str(), ImGuiDataType_U32, &current_value, &min_value, &max_value)) {
- value->set_value(current_value);
- }
-
- layout_label();
- layout_tooltip();
-}
-
-void SettingValue_StepperInt::layout(void) const
-{
- auto current_value = value->get_value();
- auto min_value = value->get_min_value();
- auto max_value = value->get_max_value();
-
- auto current_wid = current_value - min_value;
-
- if(ImGui::Button(wids[current_wid].c_str(), ImVec2(ImGui::CalcItemWidth(), 0.0f))) {
- current_value += 1;
- }
-
- if(current_value > max_value) {
- value->set_value(min_value);
- }
- else {
- value->set_value(current_value);
- }
-
- layout_label();
- layout_tooltip();
-}
-
-void SettingValue_StepperInt::refresh_wids(void)
-{
- for(std::size_t i = 0; i < wids.size(); ++i) {
- auto key = std::format("settings.value.{}.{}", name, i);
- wids[i] = std::format("{}###{}", gui::language::resolve(key.c_str()), static_cast<const void*>(value));
- }
-}
-
-void SettingValue_StepperUnsigned::layout(void) const
-{
- auto current_value = value->get_value();
- auto min_value = value->get_min_value();
- auto max_value = value->get_max_value();
-
- auto current_wid = current_value - min_value;
-
- if(ImGui::Button(wids[current_wid].c_str(), ImVec2(ImGui::CalcItemWidth(), 0.0f))) {
- current_value += 1U;
- }
-
- if(current_value > max_value) {
- value->set_value(min_value);
- }
- else {
- value->set_value(current_value);
- }
-
- layout_label();
- layout_tooltip();
-}
-
-void SettingValue_StepperUnsigned::refresh_wids(void)
-{
- for(std::size_t i = 0; i < wids.size(); ++i) {
- auto key = std::format("settings.value.{}.{}", name, i);
- wids[i] = std::format("{}###{}", gui::language::resolve(key.c_str()), static_cast<const void*>(value));
- }
-}
-
-void SettingValue_KeyBind::layout(void) const
-{
- const auto is_active = ((globals::gui_keybind_ptr == value) && !globals::gui_gamepad_axis_ptr && !globals::gui_gamepad_button_ptr);
- const auto& wid = is_active ? wids[0] : wids[1];
-
- if(ImGui::Button(wid.c_str(), ImVec2(ImGui::CalcItemWidth(), 0.0f))) {
- auto& io = ImGui::GetIO();
- io.ConfigFlags &= ~ImGuiConfigFlags_NavEnableKeyboard;
- globals::gui_keybind_ptr = value;
- }
-
- layout_label();
-}
-
-void SettingValue_KeyBind::refresh_wids(void)
-{
- wids[0] = std::format("...###{}", static_cast<const void*>(value));
- wids[1] = std::format("{}###{}", value->get(), static_cast<const void*>(value));
-}
-
-void SettingValue_GamepadAxis::layout(void) const
-{
- const auto is_active = ((globals::gui_gamepad_axis_ptr == value) && !globals::gui_keybind_ptr && !globals::gui_gamepad_button_ptr);
- const auto& wid = is_active ? wids[0] : wids[1];
- auto is_inverted = value->is_inverted();
-
- if(ImGui::Button(wid.c_str(), ImVec2(ImGui::CalcItemWidth() - ImGui::GetFrameHeight() - ImGui::GetStyle().ItemSpacing.x, 0.0f))) {
- auto& io = ImGui::GetIO();
- io.ConfigFlags &= ~ImGuiConfigFlags_NavEnableKeyboard;
- globals::gui_gamepad_axis_ptr = value;
- }
-
- ImGui::SameLine();
-
- if(ImGui::Checkbox(wid_checkbox.c_str(), &is_inverted)) {
- value->set_inverted(is_inverted);
- }
-
- if(ImGui::BeginItemTooltip()) {
- ImGui::PushTextWrapPos(ImGui::GetFontSize() * 16.0f);
- ImGui::TextUnformatted(str_gamepad_checkbox_tooltip.c_str());
- ImGui::PopTextWrapPos();
- ImGui::EndTooltip();
- }
-
- layout_label();
-}
-
-void SettingValue_GamepadAxis::refresh_wids(void)
-{
- wids[0] = std::format("...###{}", static_cast<const void*>(value));
- wids[1] = std::format("{}###{}", value->get_name(), static_cast<const void*>(value));
- wid_checkbox = std::format("###CHECKBOX_{}", static_cast<const void*>(value));
-}
-
-void SettingValue_GamepadButton::layout(void) const
-{
- const auto is_active = ((globals::gui_gamepad_button_ptr == value) && !globals::gui_keybind_ptr && !globals::gui_gamepad_axis_ptr);
- const auto& wid = is_active ? wids[0] : wids[1];
-
- if(ImGui::Button(wid.c_str(), ImVec2(ImGui::CalcItemWidth(), 0.0f))) {
- auto& io = ImGui::GetIO();
- io.ConfigFlags &= ~ImGuiConfigFlags_NavEnableKeyboard;
- globals::gui_gamepad_button_ptr = value;
- }
-
- layout_label();
-}
-
-void SettingValue_GamepadButton::refresh_wids(void)
-{
- wids[0] = std::format("...###{}", static_cast<const void*>(value));
- wids[1] = std::format("{}###{}", value->get(), static_cast<const void*>(value));
-}
-
-void SettingValue_Language::layout(void) const
-{
- auto current_language = gui::language::get_current();
-
- if(ImGui::BeginCombo(wid.c_str(), current_language->endonym.c_str())) {
- for(auto it = gui::language::cbegin(); it != gui::language::cend(); ++it) {
- if(ImGui::Selectable(it->display.c_str(), it == current_language)) {
- gui::language::set(it);
- continue;
- }
- }
-
- ImGui::EndCombo();
- }
-
- layout_label();
- layout_tooltip();
-}
-
-static void refresh_input_wids(void)
-{
- for(SettingValue* value : values_all) {
- if(value->type == setting_type::KEYBIND) {
- auto keybind = static_cast<SettingValue_KeyBind*>(value);
- keybind->refresh_wids();
- continue;
- }
-
- if(value->type == setting_type::GAMEPAD_AXIS) {
- auto gamepad_axis = static_cast<SettingValue_GamepadAxis*>(value);
- gamepad_axis->refresh_wids();
- continue;
- }
-
- if(value->type == setting_type::GAMEPAD_BUTTON) {
- auto gamepad_button = static_cast<SettingValue_GamepadButton*>(value);
- gamepad_button->refresh_wids();
- }
- }
-}
-
-static void on_glfw_key(const io::GlfwKeyEvent& event)
-{
- if((event.action == GLFW_PRESS) && (event.key != DEBUG_KEY)) {
- if(globals::gui_keybind_ptr || globals::gui_gamepad_axis_ptr || globals::gui_gamepad_button_ptr) {
- if(event.key == GLFW_KEY_ESCAPE) {
- ImGuiIO& io = ImGui::GetIO();
- io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
-
- globals::gui_keybind_ptr = nullptr;
- globals::gui_gamepad_axis_ptr = nullptr;
- globals::gui_gamepad_button_ptr = nullptr;
-
- return;
- }
-
- ImGuiIO& io = ImGui::GetIO();
- io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
-
- globals::gui_keybind_ptr->set_key(event.key);
- globals::gui_keybind_ptr = nullptr;
-
- refresh_input_wids();
-
- return;
- }
-
- if((event.key == GLFW_KEY_ESCAPE) && (globals::gui_screen == GUI_SETTINGS)) {
- globals::gui_screen = GUI_MAIN_MENU;
- return;
- }
- }
-}
-
-static void on_gamepad_axis(const io::GamepadAxisEvent& event)
-{
- if(globals::gui_gamepad_axis_ptr) {
- auto& io = ImGui::GetIO();
- io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
-
- globals::gui_gamepad_axis_ptr->set_axis(event.axis);
- globals::gui_gamepad_axis_ptr = nullptr;
-
- refresh_input_wids();
-
- return;
- }
-}
-
-static void on_gamepad_button(const io::GamepadButtonEvent& event)
-{
- if(globals::gui_gamepad_button_ptr) {
- auto& io = ImGui::GetIO();
- io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
-
- globals::gui_gamepad_button_ptr->set_button(event.button);
- globals::gui_gamepad_button_ptr = nullptr;
-
- refresh_input_wids();
-
- return;
- }
-}
-
-static void on_language_set(const gui::LanguageSetEvent& event)
-{
- str_checkbox_false = gui::language::resolve("settings.checkbox.false");
- str_checkbox_true = gui::language::resolve("settings.checkbox.true");
-
- str_tab_general = gui::language::resolve("settings.tab.general");
- str_tab_input = gui::language::resolve("settings.tab.input");
- str_tab_video = gui::language::resolve("settings.tab.video");
- str_tab_sound = gui::language::resolve("settings.tab.sound");
-
- str_input_keyboard = gui::language::resolve("settings.input.keyboard");
- str_input_gamepad = gui::language::resolve("settings.input.gamepad");
- str_input_mouse = gui::language::resolve("settings.input.mouse");
-
- str_keyboard_movement = gui::language::resolve("settings.keyboard.movement");
- str_keyboard_gameplay = gui::language::resolve("settings.keyboard.gameplay");
- str_keyboard_misc = gui::language::resolve("settings.keyboard.misc");
-
- str_gamepad_movement = gui::language::resolve("settings.gamepad.movement");
- str_gamepad_gameplay = gui::language::resolve("settings.gamepad.gameplay");
- str_gamepad_misc = gui::language::resolve("settings.gamepad.misc");
-
- str_gamepad_axis_prefix = gui::language::resolve("settings.gamepad.axis");
- str_gamepad_button_prefix = gui::language::resolve("settings.gamepad.button");
- str_gamepad_checkbox_tooltip = gui::language::resolve("settings.gamepad.checkbox_tooltip");
-
- str_video_gui = gui::language::resolve("settings.video.gui");
-
- str_sound_levels = gui::language::resolve("settings.sound.levels");
-
- for(SettingValue* value : values_all) {
- if(value->type == setting_type::CHECKBOX) {
- auto checkbox = static_cast<SettingValue_CheckBox*>(value);
- checkbox->refresh_wids();
- }
-
- if(value->type == setting_type::STEPPER_INT) {
- auto stepper = static_cast<SettingValue_StepperInt*>(value);
- stepper->refresh_wids();
- }
-
- if(value->type == setting_type::STEPPER_UINT) {
- auto stepper = static_cast<SettingValue_StepperUnsigned*>(value);
- stepper->refresh_wids();
- }
-
- value->title = gui::language::resolve(std::format("settings.value.{}", value->name).c_str());
-
- if(value->has_tooltip) {
- value->tooltip = gui::language::resolve(std::format("settings.tooltip.{}", value->name).c_str());
- }
- }
-}
-
-static void layout_values(settings_location location)
-{
- ImGui::PushItemWidth(ImGui::CalcItemWidth() * 0.70f);
-
- for(const SettingValue* value : values[static_cast<unsigned int>(location)]) {
- value->layout();
- }
-
- ImGui::PopItemWidth();
-}
-
-static void layout_general(void)
-{
- if(ImGui::BeginChild("###settings.general.child")) {
- layout_values(settings_location::GENERAL);
- }
-
- ImGui::EndChild();
-}
-
-static void layout_input_keyboard(void)
-{
- if(ImGui::BeginChild("###settings.input.keyboard.child")) {
- ImGui::SeparatorText(str_keyboard_movement.c_str());
- layout_values(settings_location::KEYBOARD_MOVEMENT);
- ImGui::SeparatorText(str_keyboard_gameplay.c_str());
- layout_values(settings_location::KEYBOARD_GAMEPLAY);
- ImGui::SeparatorText(str_keyboard_misc.c_str());
- layout_values(settings_location::KEYBOARD_MISC);
- }
-
- ImGui::EndChild();
-}
-
-static void layout_input_gamepad(void)
-{
- if(ImGui::BeginChild("###settings.input.gamepad.child")) {
- layout_values(settings_location::GAMEPAD);
- ImGui::SeparatorText(str_gamepad_movement.c_str());
- layout_values(settings_location::GAMEPAD_MOVEMENT);
- ImGui::SeparatorText(str_gamepad_gameplay.c_str());
- layout_values(settings_location::GAMEPAD_GAMEPLAY);
- ImGui::SeparatorText(str_gamepad_misc.c_str());
- layout_values(settings_location::GAMEPAD_MISC);
- }
-
- ImGui::EndChild();
-}
-
-static void layout_input_mouse(void)
-{
- if(ImGui::BeginChild("###settings.input.mouse.child")) {
- layout_values(settings_location::MOUSE);
- }
-
- ImGui::EndChild();
-}
-
-static void layout_input(void)
-{
- if(ImGui::BeginTabBar("###settings.input.tabs", ImGuiTabBarFlags_FittingPolicyResizeDown)) {
- if(ImGui::BeginTabItem(str_input_keyboard.c_str())) {
- layout_input_keyboard();
- ImGui::EndTabItem();
- }
-
- if(io::gamepad::available) {
- if(ImGui::BeginTabItem(str_input_gamepad.c_str())) {
- globals::gui_keybind_ptr = nullptr;
- layout_input_gamepad();
- ImGui::EndTabItem();
- }
- }
-
- if(ImGui::BeginTabItem(str_input_mouse.c_str())) {
- globals::gui_keybind_ptr = nullptr;
- layout_input_mouse();
- ImGui::EndTabItem();
- }
-
- ImGui::EndTabBar();
- }
-}
-
-static void layout_video(void)
-{
- if(ImGui::BeginChild("###settings.video.child")) {
- layout_values(settings_location::VIDEO);
- ImGui::SeparatorText(str_video_gui.c_str());
- layout_values(settings_location::VIDEO_GUI);
- }
-
- ImGui::EndChild();
-}
-
-static void layout_sound(void)
-{
- if(ImGui::BeginChild("###settings.sound.child")) {
- layout_values(settings_location::SOUND);
- ImGui::SeparatorText(str_sound_levels.c_str());
- layout_values(settings_location::SOUND_LEVELS);
- }
-
- ImGui::EndChild();
-}
-
-void settings::init(void)
-{
- globals::dispatcher.sink<io::GlfwKeyEvent>().connect<&on_glfw_key>();
- globals::dispatcher.sink<io::GamepadAxisEvent>().connect<&on_gamepad_axis>();
- globals::dispatcher.sink<io::GamepadButtonEvent>().connect<&on_gamepad_button>();
- globals::dispatcher.sink<gui::LanguageSetEvent>().connect<&on_language_set>();
-}
-
-void settings::init_late(void)
-{
- for(std::size_t i = 0; i < NUM_LOCATIONS; ++i) {
- std::sort(values[i].begin(), values[i].end(), [](const SettingValue* a, const SettingValue* b) {
- return a->priority < b->priority;
- });
- }
-
- refresh_input_wids();
-}
-
-void settings::shutdown(void)
-{
- for(const SettingValue* value : values_all)
- delete value;
- for(std::size_t i = 0; i < NUM_LOCATIONS; values[i++].clear())
- ;
- values_all.clear();
-}
-
-void settings::layout(void)
-{
- const ImGuiViewport* viewport = ImGui::GetMainViewport();
- const ImVec2 window_start = ImVec2(viewport->Size.x * 0.05f, viewport->Size.y * 0.05f);
- const ImVec2 window_size = ImVec2(viewport->Size.x * 0.90f, viewport->Size.y * 0.90f);
-
- ImGui::SetNextWindowPos(window_start);
- ImGui::SetNextWindowSize(window_size);
-
- if(ImGui::Begin("###settings", nullptr, WINDOW_FLAGS)) {
- ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(3.0f * globals::gui_scale, 3.0f * globals::gui_scale));
-
- if(ImGui::BeginTabBar("###settings.tabs", ImGuiTabBarFlags_FittingPolicyResizeDown)) {
- if(ImGui::TabItemButton("<<")) {
- globals::gui_screen = GUI_MAIN_MENU;
- globals::gui_keybind_ptr = nullptr;
- }
-
- if(ImGui::BeginTabItem(str_tab_general.c_str())) {
- globals::gui_keybind_ptr = nullptr;
- layout_general();
- ImGui::EndTabItem();
- }
-
- if(ImGui::BeginTabItem(str_tab_input.c_str())) {
- layout_input();
- ImGui::EndTabItem();
- }
-
- if(ImGui::BeginTabItem(str_tab_video.c_str())) {
- globals::gui_keybind_ptr = nullptr;
- layout_video();
- ImGui::EndTabItem();
- }
-
- if(globals::sound_ctx && globals::sound_dev) {
- if(ImGui::BeginTabItem(str_tab_sound.c_str())) {
- globals::gui_keybind_ptr = nullptr;
- layout_sound();
- ImGui::EndTabItem();
- }
- }
-
- ImGui::EndTabBar();
- }
-
- ImGui::PopStyleVar();
- }
-
- ImGui::End();
-}
-
-void settings::add_checkbox(int priority, config::Boolean& value, settings_location location, std::string_view name, bool tooltip)
-{
- auto setting_value = new SettingValue_CheckBox;
- setting_value->type = setting_type::CHECKBOX;
- setting_value->priority = priority;
- setting_value->has_tooltip = tooltip;
- setting_value->value = &value;
- setting_value->name = name;
-
- setting_value->refresh_wids();
-
- values[static_cast<unsigned int>(location)].push_back(setting_value);
- values_all.push_back(setting_value);
-}
-
-void settings::add_input(int priority, config::Int& value, settings_location location, std::string_view name, bool tooltip)
-{
- auto setting_value = new SettingValue_InputInt;
- setting_value->type = setting_type::INPUT_INT;
- setting_value->priority = priority;
- setting_value->has_tooltip = tooltip;
- setting_value->value = &value;
- setting_value->name = name;
-
- setting_value->wid = std::format("###{}", static_cast<const void*>(setting_value->value));
-
- values[static_cast<unsigned int>(location)].push_back(setting_value);
- values_all.push_back(setting_value);
-}
-
-void settings::add_input(int priority, config::Float& value, settings_location location, std::string_view name, bool tooltip,
- std::string_view fmt)
-{
- auto setting_value = new SettingValue_InputFloat;
- setting_value->type = setting_type::INPUT_FLOAT;
- setting_value->priority = priority;
- setting_value->has_tooltip = tooltip;
- setting_value->value = &value;
- setting_value->format = fmt;
- setting_value->name = name;
-
- setting_value->wid = std::format("###{}", static_cast<const void*>(setting_value->value));
-
- values[static_cast<unsigned int>(location)].push_back(setting_value);
- values_all.push_back(setting_value);
-}
-
-void settings::add_input(int priority, config::Unsigned& value, settings_location location, std::string_view name, bool tooltip)
-{
- auto setting_value = new SettingValue_InputUnsigned;
- setting_value->type = setting_type::INPUT_UINT;
- setting_value->priority = priority;
- setting_value->has_tooltip = tooltip;
- setting_value->value = &value;
- setting_value->name = name;
-
- setting_value->wid = std::format("###{}", static_cast<const void*>(setting_value->value));
-
- values[static_cast<unsigned int>(location)].push_back(setting_value);
- values_all.push_back(setting_value);
-}
-
-void settings::add_input(int priority, config::String& value, settings_location location, std::string_view name, bool tooltip,
- bool allow_whitespace)
-{
- auto setting_value = new SettingValue_InputString;
- setting_value->type = setting_type::INPUT_STRING;
- setting_value->priority = priority;
- setting_value->has_tooltip = tooltip;
- setting_value->value = &value;
- setting_value->name = name;
-
- setting_value->allow_whitespace = allow_whitespace;
- setting_value->wid = std::format("###{}", static_cast<const void*>(setting_value->value));
-
- values[static_cast<unsigned int>(location)].push_back(setting_value);
- values_all.push_back(setting_value);
-}
-
-void settings::add_slider(int priority, config::Int& value, settings_location location, std::string_view name, bool tooltip)
-{
- auto setting_value = new SettingValue_SliderInt;
- setting_value->type = setting_type::SLIDER_INT;
- setting_value->priority = priority;
- setting_value->has_tooltip = tooltip;
- setting_value->value = &value;
- setting_value->name = name;
-
- setting_value->wid = std::format("###{}", static_cast<const void*>(setting_value->value));
-
- values[static_cast<unsigned int>(location)].push_back(setting_value);
- values_all.push_back(setting_value);
-}
-
-void settings::add_slider(int priority, config::Float& value, settings_location location, std::string_view name, bool tooltip,
- std::string_view fmt)
-{
- auto setting_value = new SettingValue_SliderFloat;
- setting_value->type = setting_type::SLIDER_FLOAT;
- setting_value->priority = priority;
- setting_value->has_tooltip = tooltip;
- setting_value->value = &value;
- setting_value->name = name;
-
- setting_value->format = fmt;
- setting_value->wid = std::format("###{}", static_cast<const void*>(setting_value->value));
-
- values[static_cast<unsigned int>(location)].push_back(setting_value);
- values_all.push_back(setting_value);
-}
-
-void settings::add_slider(int priority, config::Unsigned& value, settings_location location, std::string_view name, bool tooltip)
-{
- auto setting_value = new SettingValue_SliderUnsigned;
- setting_value->type = setting_type::SLIDER_UINT;
- setting_value->priority = priority;
- setting_value->has_tooltip = tooltip;
- setting_value->value = &value;
- setting_value->name = name;
-
- setting_value->wid = std::format("###{}", static_cast<const void*>(setting_value->value));
-
- values[static_cast<unsigned int>(location)].push_back(setting_value);
- values_all.push_back(setting_value);
-}
-
-void settings::add_stepper(int priority, config::Int& value, settings_location location, std::string_view name, bool tooltip)
-{
- auto setting_value = new SettingValue_StepperInt;
- setting_value->type = setting_type::STEPPER_INT;
- setting_value->priority = priority;
- setting_value->has_tooltip = tooltip;
- setting_value->value = &value;
- setting_value->name = name;
-
- setting_value->wids.resize(value.get_max_value() - value.get_min_value() + 1);
- setting_value->refresh_wids();
-
- values[static_cast<unsigned int>(location)].push_back(setting_value);
- values_all.push_back(setting_value);
-}
-
-void settings::add_stepper(int priority, config::Unsigned& value, settings_location location, std::string_view name, bool tooltip)
-{
- auto setting_value = new SettingValue_StepperUnsigned;
- setting_value->type = setting_type::STEPPER_UINT;
- setting_value->priority = priority;
- setting_value->has_tooltip = tooltip;
- setting_value->value = &value;
- setting_value->name = name;
-
- setting_value->wids.resize(value.get_max_value() - value.get_min_value() + 1);
- setting_value->refresh_wids();
-
- values[static_cast<unsigned int>(location)].push_back(setting_value);
- values_all.push_back(setting_value);
-}
-
-void settings::add_keybind(int priority, config::KeyBind& value, settings_location location, std::string_view name)
-{
- auto setting_value = new SettingValue_KeyBind;
- setting_value->type = setting_type::KEYBIND;
- setting_value->priority = priority;
- setting_value->has_tooltip = false;
- setting_value->value = &value;
- setting_value->name = name;
-
- setting_value->refresh_wids();
-
- values[static_cast<unsigned int>(location)].push_back(setting_value);
- values_all.push_back(setting_value);
-}
-
-void settings::add_gamepad_axis(int priority, config::GamepadAxis& value, settings_location location, std::string_view name)
-{
- auto setting_value = new SettingValue_GamepadAxis;
- setting_value->type = setting_type::GAMEPAD_AXIS;
- setting_value->priority = priority;
- setting_value->has_tooltip = false;
- setting_value->value = &value;
- setting_value->name = name;
-
- setting_value->refresh_wids();
-
- values[static_cast<unsigned int>(location)].push_back(setting_value);
- values_all.push_back(setting_value);
-}
-
-void settings::add_gamepad_button(int priority, config::GamepadButton& value, settings_location location, std::string_view name)
-{
- auto setting_value = new SettingValue_GamepadButton;
- setting_value->type = setting_type::GAMEPAD_BUTTON;
- setting_value->priority = priority;
- setting_value->has_tooltip = false;
- setting_value->value = &value;
- setting_value->name = name;
-
- setting_value->refresh_wids();
-
- values[static_cast<unsigned int>(location)].push_back(setting_value);
- values_all.push_back(setting_value);
-}
-
-void settings::add_language_select(int priority, settings_location location, std::string_view name)
-{
- auto setting_value = new SettingValue_Language;
- setting_value->type = setting_type::LANGUAGE_SELECT;
- setting_value->priority = priority;
- setting_value->has_tooltip = false;
- setting_value->name = name;
-
- setting_value->wid = std::format("###{}", static_cast<const void*>(setting_value));
-
- values[static_cast<unsigned int>(location)].push_back(setting_value);
- values_all.push_back(setting_value);
-}
diff --git a/game/client/gui/settings.hh b/game/client/gui/settings.hh
deleted file mode 100644
index 472a61d..0000000
--- a/game/client/gui/settings.hh
+++ /dev/null
@@ -1,90 +0,0 @@
-#pragma once
-
-namespace config
-{
-class Boolean;
-class String;
-} // namespace config
-
-namespace config
-{
-class Int;
-class Float;
-class Unsigned;
-} // namespace config
-
-namespace config
-{
-class KeyBind;
-class GamepadAxis;
-class GamepadButton;
-} // namespace config
-
-enum class settings_location : unsigned int {
- GENERAL = 0x0000U,
- KEYBOARD_MOVEMENT = 0x0001U,
- KEYBOARD_GAMEPLAY = 0x0002U,
- KEYBOARD_MISC = 0x0003U,
- GAMEPAD = 0x0004U,
- GAMEPAD_MOVEMENT = 0x0005U,
- GAMEPAD_GAMEPLAY = 0x0006U,
- GAMEPAD_MISC = 0x0007U,
- MOUSE = 0x0008U,
- VIDEO = 0x0009U,
- VIDEO_GUI = 0x000AU,
- SOUND = 0x000BU,
- SOUND_LEVELS = 0x000CU,
- COUNT = 0x000DU,
-};
-
-namespace settings
-{
-void init(void);
-void init_late(void);
-void shutdown(void);
-void layout(void);
-} // namespace settings
-
-namespace settings
-{
-void add_checkbox(int priority, config::Boolean& value, settings_location location, std::string_view name, bool tooltip);
-} // namespace settings
-
-namespace settings
-{
-void add_input(int priority, config::Int& value, settings_location location, std::string_view name, bool tooltip);
-void add_input(int priority, config::Float& value, settings_location location, std::string_view name, bool tooltip,
- std::string_view fmt = "%.3f");
-void add_input(int priority, config::Unsigned& value, settings_location location, std::string_view name, bool tooltip);
-void add_input(int priority, config::String& value, settings_location location, std::string_view name, bool tooltip, bool allow_whitespace);
-} // namespace settings
-
-namespace settings
-{
-void add_slider(int priority, config::Int& value, settings_location location, std::string_view name, bool tooltip);
-void add_slider(int priority, config::Float& value, settings_location location, std::string_view name, bool tooltip,
- std::string_view format = "%.3f");
-void add_slider(int priority, config::Unsigned& value, settings_location location, std::string_view name, bool tooltip);
-} // namespace settings
-
-namespace settings
-{
-void add_stepper(int priority, config::Int& value, settings_location location, std::string_view name, bool tooltip);
-void add_stepper(int priority, config::Unsigned& value, settings_location location, std::string_view name, bool tooltip);
-} // namespace settings
-
-namespace settings
-{
-void add_keybind(int priority, config::KeyBind& value, settings_location location, std::string_view name);
-} // namespace settings
-
-namespace settings
-{
-void add_gamepad_axis(int priority, config::GamepadAxis& value, settings_location location, std::string_view name);
-void add_gamepad_button(int priority, config::GamepadButton& value, settings_location location, std::string_view name);
-} // namespace settings
-
-namespace settings
-{
-void add_language_select(int priority, settings_location location, std::string_view name);
-} // namespace settings
diff --git a/game/client/gui/splash.cc b/game/client/gui/splash.cc
deleted file mode 100644
index 5eae0f2..0000000
--- a/game/client/gui/splash.cc
+++ /dev/null
@@ -1,178 +0,0 @@
-#include "client/pch.hh"
-
-#include "client/gui/splash.hh"
-
-#include "core/io/cmdline.hh"
-
-#include "core/math/constexpr.hh"
-
-#include "core/resource/resource.hh"
-
-#include "core/utils/epoch.hh"
-
-#include "client/gui/gui_screen.hh"
-#include "client/gui/language.hh"
-
-#include "client/io/glfw.hh"
-
-#include "client/resource/texture_gui.hh"
-
-#include "client/globals.hh"
-
-constexpr static ImGuiWindowFlags WINDOW_FLAGS = ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration;
-
-constexpr static int SPLASH_COUNT = 4;
-constexpr static std::size_t DELAY_MICROSECONDS = 2000000;
-constexpr static std::string_view SPLASH_PATH = "textures/gui/client_splash.png";
-
-static resource_ptr<TextureGUI> texture;
-static float texture_aspect;
-static float texture_alpha;
-
-static std::uint64_t end_time;
-static std::string current_text;
-
-static void on_glfw_key(const io::GlfwKeyEvent& event)
-{
- end_time = UINT64_C(0);
-}
-
-static void on_glfw_mouse_button(const io::GlfwMouseButtonEvent& event)
-{
- end_time = UINT64_C(0);
-}
-
-static void on_glfw_scroll(const io::GlfwScrollEvent& event)
-{
- end_time = UINT64_C(0);
-}
-
-void gui::client_splash::init(void)
-{
- if(io::cmdline::contains("nosplash")) {
- texture = nullptr;
- texture_aspect = 0.0f;
- texture_alpha = 0.0f;
- return;
- }
-
- std::random_device randev;
- std::uniform_int_distribution<int> dist(0, SPLASH_COUNT - 1);
-
- texture = resource::load<TextureGUI>(SPLASH_PATH, TEXTURE_GUI_LOAD_CLAMP_S | TEXTURE_GUI_LOAD_CLAMP_T);
- texture_aspect = 0.0f;
- texture_alpha = 0.0f;
-
- if(texture) {
- if(texture->size.x > texture->size.y) {
- texture_aspect = static_cast<float>(texture->size.x) / static_cast<float>(texture->size.y);
- }
- else {
- texture_aspect = static_cast<float>(texture->size.y) / static_cast<float>(texture->size.x);
- }
-
- texture_alpha = 1.0f;
- }
-}
-
-void gui::client_splash::init_late(void)
-{
- if(!texture) {
- // We don't have to waste time
- // rendering the missing client_splash texture
- return;
- }
-
- end_time = utils::unix_microseconds() + DELAY_MICROSECONDS;
-
- globals::dispatcher.sink<io::GlfwKeyEvent>().connect<&on_glfw_key>();
- globals::dispatcher.sink<io::GlfwMouseButtonEvent>().connect<&on_glfw_mouse_button>();
- globals::dispatcher.sink<io::GlfwScrollEvent>().connect<&on_glfw_scroll>();
-
- current_text = gui::language::resolve("splash.skip_prompt");
-
- while(!glfwWindowShouldClose(globals::window)) {
- const std::uint64_t curtime = utils::unix_microseconds();
- const std::uint64_t remains = end_time - curtime;
-
- if(curtime >= end_time) {
- break;
- }
-
- texture_alpha = glm::smoothstep(0.25f, 0.6f, static_cast<float>(remains) / static_cast<float>(DELAY_MICROSECONDS));
-
- gui::client_splash::render();
- }
-
- globals::dispatcher.sink<io::GlfwKeyEvent>().disconnect<&on_glfw_key>();
- globals::dispatcher.sink<io::GlfwMouseButtonEvent>().disconnect<&on_glfw_mouse_button>();
- globals::dispatcher.sink<io::GlfwScrollEvent>().disconnect<&on_glfw_scroll>();
-
- texture = nullptr;
- texture_aspect = 0.0f;
- texture_alpha = 0.0f;
- end_time = UINT64_C(0);
-}
-
-void gui::client_splash::render(void)
-{
- if(!texture) {
- // We don't have to waste time
- // rendering the missing client_splash texture
- return;
- }
-
- // The client_splash is rendered outside the main
- // render loop, so we have to manually begin
- // and render both window and ImGui frames
- ImGui_ImplOpenGL3_NewFrame();
- ImGui_ImplGlfw_NewFrame();
- ImGui::NewFrame();
-
- glDisable(GL_DEPTH_TEST);
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
- glViewport(0, 0, globals::width, globals::height);
-
- glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT);
-
- auto viewport = ImGui::GetMainViewport();
- auto window_start = ImVec2(0.0f, 0.0f);
- auto window_size = ImVec2(viewport->Size.x, viewport->Size.y);
-
- ImGui::SetNextWindowPos(window_start);
- ImGui::SetNextWindowSize(window_size);
-
- if(ImGui::Begin("###client_splash", nullptr, WINDOW_FLAGS)) {
- const float image_width = 0.60f * viewport->Size.x;
- const float image_height = image_width / texture_aspect;
- const ImVec2 image_size = ImVec2(image_width, image_height);
-
- const float image_x = 0.5f * (viewport->Size.x - image_width);
- const float image_y = 0.5f * (viewport->Size.y - image_height);
- const ImVec2 image_pos = ImVec2(image_x, image_y);
-
- if(!current_text.empty()) {
- ImGui::PushFont(globals::font_unscii8, 16.0f);
- ImGui::SetCursorPos(ImVec2(16.0f, 16.0f));
- ImGui::TextDisabled("%s", current_text.c_str());
- ImGui::PopFont();
- }
-
- const ImVec2 uv_a = ImVec2(0.0f, 0.0f);
- const ImVec2 uv_b = ImVec2(1.0f, 1.0f);
- const ImVec4 tint = ImVec4(1.0f, 1.0f, 1.0f, texture_alpha);
-
- ImGui::SetCursorPos(image_pos);
- ImGui::ImageWithBg(texture->handle, image_size, uv_a, uv_b, ImVec4(0.0f, 0.0f, 0.0f, 0.0f), tint);
- }
-
- ImGui::End();
-
- ImGui::Render();
- ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
-
- glfwSwapBuffers(globals::window);
-
- glfwPollEvents();
-}
diff --git a/game/client/gui/splash.hh b/game/client/gui/splash.hh
deleted file mode 100644
index a28a9ad..0000000
--- a/game/client/gui/splash.hh
+++ /dev/null
@@ -1,8 +0,0 @@
-#pragma once
-
-namespace gui::client_splash
-{
-void init(void);
-void init_late(void);
-void render(void);
-} // namespace gui::client_splash
diff --git a/game/client/gui/status_lines.cc b/game/client/gui/status_lines.cc
deleted file mode 100644
index c146478..0000000
--- a/game/client/gui/status_lines.cc
+++ /dev/null
@@ -1,84 +0,0 @@
-#include "client/pch.hh"
-
-#include "client/gui/status_lines.hh"
-
-#include "client/gui/imdraw_ext.hh"
-
-#include "client/globals.hh"
-
-static float line_offsets[gui::STATUS_COUNT];
-static ImFont* line_fonts[gui::STATUS_COUNT];
-static float line_sizes[gui::STATUS_COUNT];
-
-static ImVec4 line_text_colors[gui::STATUS_COUNT];
-static ImVec4 line_shadow_colors[gui::STATUS_COUNT];
-static std::string line_strings[gui::STATUS_COUNT];
-static std::uint64_t line_spawns[gui::STATUS_COUNT];
-static float line_fadeouts[gui::STATUS_COUNT];
-
-void gui::status_lines::init(void)
-{
- for(unsigned int i = 0U; i < STATUS_COUNT; ++i) {
- line_text_colors[i] = ImVec4(0.0f, 0.0f, 0.0f, 0.0f);
- line_shadow_colors[i] = ImVec4(0.0f, 0.0f, 0.0f, 0.0f);
- line_strings[i] = std::string();
- line_spawns[i] = UINT64_MAX;
- line_fadeouts[i] = 0.0f;
- }
-}
-
-void gui::status_lines::init_late(void)
-{
- line_offsets[STATUS_DEBUG] = 64.0f;
- line_offsets[STATUS_HOTBAR] = 40.0f;
-}
-
-void gui::status_lines::layout(void)
-{
- line_fonts[STATUS_DEBUG] = globals::font_unscii8;
- line_sizes[STATUS_DEBUG] = 4.0f;
-
- line_fonts[STATUS_HOTBAR] = globals::font_unscii16;
- line_sizes[STATUS_HOTBAR] = 8.0f;
-
- auto viewport = ImGui::GetMainViewport();
- auto draw_list = ImGui::GetForegroundDrawList();
-
- for(unsigned int i = 0U; i < STATUS_COUNT; ++i) {
- auto offset = line_offsets[i] * globals::gui_scale;
- auto& text = line_strings[i];
- auto* font = line_fonts[i];
-
- auto size = font->CalcTextSizeA(line_sizes[i] * globals::gui_scale, FLT_MAX, 0.0f, text.c_str(), text.c_str() + text.size());
- auto pos = ImVec2(0.5f * (viewport->Size.x - size.x), viewport->Size.y - offset);
-
- auto spawn = line_spawns[i];
- auto fadeout = line_fadeouts[i];
- auto alpha = std::exp(-1.0f * std::pow(1.0e-6f * static_cast<float>(globals::curtime - spawn) / fadeout, 10.0f));
-
- auto& color = line_text_colors[i];
- auto& shadow = line_shadow_colors[i];
- auto color_U32 = ImGui::GetColorU32(ImVec4(color.x, color.y, color.z, color.w * alpha));
- auto shadow_U32 = ImGui::GetColorU32(ImVec4(shadow.x, shadow.y, shadow.z, color.w * alpha));
-
- gui::imdraw_ext::text_shadow(text, pos, color_U32, shadow_U32, font, draw_list, line_sizes[i]);
- }
-}
-
-void gui::status_lines::set(unsigned int line, std::string_view text, const ImVec4& color, float fadeout)
-{
- line_text_colors[line] = ImVec4(color.x, color.y, color.z, color.w);
- line_shadow_colors[line] = ImVec4(color.x * 0.1f, color.y * 0.1f, color.z * 0.1f, color.w);
- line_strings[line] = text;
- line_spawns[line] = globals::curtime;
- line_fadeouts[line] = fadeout;
-}
-
-void gui::status_lines::unset(unsigned int line)
-{
- line_text_colors[line] = ImVec4(0.0f, 0.0f, 0.0f, 0.0f);
- line_shadow_colors[line] = ImVec4(0.0f, 0.0f, 0.0f, 0.0f);
- line_strings[line] = std::string();
- line_spawns[line] = UINT64_C(0);
- line_fadeouts[line] = 0.0f;
-}
diff --git a/game/client/gui/status_lines.hh b/game/client/gui/status_lines.hh
deleted file mode 100644
index f694fd3..0000000
--- a/game/client/gui/status_lines.hh
+++ /dev/null
@@ -1,21 +0,0 @@
-#pragma once
-
-namespace gui
-{
-constexpr static unsigned int STATUS_DEBUG = 0x0000; // generic debug line
-constexpr static unsigned int STATUS_HOTBAR = 0x0001; // hotbar item line
-constexpr static unsigned int STATUS_COUNT = 0x0002;
-} // namespace gui
-
-namespace gui::status_lines
-{
-void init(void);
-void init_late(void);
-void layout(void);
-} // namespace gui::status_lines
-
-namespace gui::status_lines
-{
-void set(unsigned int line, std::string_view text, const ImVec4& color, float fadeout);
-void unset(unsigned int line);
-} // namespace gui::status_lines
diff --git a/game/client/gui/window_title.cc b/game/client/gui/window_title.cc
deleted file mode 100644
index 2f96205..0000000
--- a/game/client/gui/window_title.cc
+++ /dev/null
@@ -1,14 +0,0 @@
-#include "client/pch.hh"
-
-#include "client/gui/window_title.hh"
-
-#include "core/version.hh"
-
-#include "shared/splash.hh"
-
-#include "client/globals.hh"
-
-void gui::window_title::update(void)
-{
- glfwSetWindowTitle(globals::window, std::format("Voxelius {}: {}", version::semver, splash::get()).c_str());
-}
diff --git a/game/client/gui/window_title.hh b/game/client/gui/window_title.hh
deleted file mode 100644
index 86e6a86..0000000
--- a/game/client/gui/window_title.hh
+++ /dev/null
@@ -1,6 +0,0 @@
-#pragma once
-
-namespace gui::window_title
-{
-void update(void);
-} // namespace gui::window_title