summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoruntodesu <kirill@untode.su>2026-01-05 02:20:01 +0500
committeruntodesu <kirill@untode.su>2026-01-05 02:20:01 +0500
commit915e52157208af9b41dd52892e7138c8c440e85b (patch)
tree718224dbf69a1fdf557131a648c34e60dbdca25d
parenta1c83d56f41e6f2e0ad86dcd76d1446bfc60a37c (diff)
downloadvoxelius-915e52157208af9b41dd52892e7138c8c440e85b.tar.bz2
voxelius-915e52157208af9b41dd52892e7138c8c440e85b.zip
Progress
-rw-r--r--assets/lang/lang.en_US.json11
-rw-r--r--src/game/client/entity/player_look.cc20
-rw-r--r--src/game/client/gui/chat.cc14
-rw-r--r--src/game/client/gui/direct_connection.cc8
-rw-r--r--src/game/client/gui/hotbar.cc19
-rw-r--r--src/game/client/gui/main_menu.cc9
-rw-r--r--src/game/client/gui/play_menu.cc8
-rw-r--r--src/game/client/gui/settings.cc198
-rw-r--r--src/game/client/gui/splash.cc21
-rw-r--r--src/game/client/io/CMakeLists.txt9
-rw-r--r--src/game/client/main.cc8
-rw-r--r--src/game/client/receive.cc6
-rw-r--r--src/game/client/screenshot.cc8
-rw-r--r--src/game/client/session.cc9
-rw-r--r--src/game/client/toggles.cc18
15 files changed, 268 insertions, 98 deletions
diff --git a/assets/lang/lang.en_US.json b/assets/lang/lang.en_US.json
index 3d5a402..de2d429 100644
--- a/assets/lang/lang.en_US.json
+++ b/assets/lang/lang.en_US.json
@@ -71,7 +71,6 @@
"settings.value.game.key.toggle_hide_hud": "Hide/Show HUD",
"settings.value.game.streamer_mode": "Streamer mode",
"settings.value.game.username": "Username",
- "settings.value.game.vertical_sync": "Vertical sync",
"settings.value.game.world_curvature": "World curvature",
"settings.value.gamepad.active": "Use Gamepad",
"settings.value.gamepad.deadzone": "Deadzone",
@@ -111,6 +110,8 @@
"settings.value.sound.volume_master": "Master volume",
"settings.value.sound.volume_music": "Music volume",
"settings.value.sound.volume_ui": "UI volume",
+ "settings.value.video.current_mode": "Video Mode",
+ "settings.value.video.enable_vsync": "Vertical Sync",
"settings.tooltip.camera.roll_angle": "Quake-styled view roll applied with sideways moves",
"settings.tooltip.camera.vertical_fov": "Field Of View",
@@ -123,6 +124,14 @@
"settings.tooltip.player_look.mouse.raw_input": "Disable OS-specific mouse filtering",
"settings.tooltip.player_look.mouse.sensitivity": "Specifies the rate at which cursor movement on 2D screen is reflected by the camera",
"settings.tooltip.player_move.enable_speedometer": "Display horizontal speed",
+ "settings.tooltip.video.enable_vsync": "Synchronize buffer swapping with your monitor's refresh rate; this removes screen tearing but adds a noticeable input lag",
+
+ "settings.choice.video_mode.windowed": "Windowed",
+
+ "settings.popup.video_change.title": "Change video mode",
+ "settings.popup.video_change.text": "Are you sure?",
+ "settings.popup.video_change.answer.yes": "Yes",
+ "settings.popup.video_change.answer.no": "No",
"connecting.cancel_button": "Cancel",
"connecting.connecting": "Connecting",
diff --git a/src/game/client/entity/player_look.cc b/src/game/client/entity/player_look.cc
index c3b7dbd..9788efb 100644
--- a/src/game/client/entity/player_look.cc
+++ b/src/game/client/entity/player_look.cc
@@ -25,7 +25,7 @@
#include "client/gui/settings.hh"
#include "client/io/gamepad.hh"
-#include "client/io/glfw.hh"
+#include "client/io/mouse.hh"
#include "client/const.hh"
#include "client/globals.hh"
@@ -71,32 +71,32 @@ static void add_angles(float pitch, float yaw)
}
}
-static void on_glfw_cursor_pos(const GlfwCursorPosEvent& event)
+static void on_cursor_pos(const CursorPosEvent& event)
{
if(gamepad::available && gamepad::active.get_value()) {
// The player is assumed to be using
// a gamepad instead of mouse and keyboard
- last_cursor = event.pos;
+ last_cursor = event.position();
return;
}
if(globals::gui_screen || !session::is_ingame()) {
// UI is visible or we're not in-game
- last_cursor = event.pos;
+ last_cursor = event.position();
return;
}
- auto dx = -0.01f * static_cast<float>(mouse_sensitivity.get_value()) * math::radians(event.pos.x - last_cursor.x);
- auto dy = -0.01f * static_cast<float>(mouse_sensitivity.get_value()) * math::radians(event.pos.y - last_cursor.y);
+ auto dx = -0.01f * static_cast<float>(mouse_sensitivity.get_value()) * math::radians(event.xpos() - last_cursor.x);
+ auto dy = -0.01f * static_cast<float>(mouse_sensitivity.get_value()) * math::radians(event.ypos() - last_cursor.y);
add_angles(dy, dx);
- last_cursor = event.pos;
+ last_cursor = event.position();
}
static void on_gamepad_button(const GamepadButtonEvent& event)
{
- if(button_fastlook.equals(event.button)) {
- fastlook_enabled = event.action == GLFW_PRESS;
+ if(button_fastlook.equals(event.button())) {
+ fastlook_enabled = event.is_action(GLFW_PRESS);
}
}
@@ -126,7 +126,7 @@ void player_look::init(void)
last_cursor.x = 0.5f * static_cast<float>(globals::width);
last_cursor.y = 0.5f * static_cast<float>(globals::height);
- globals::dispatcher.sink<GlfwCursorPosEvent>().connect<&on_glfw_cursor_pos>();
+ globals::dispatcher.sink<CursorPosEvent>().connect<&on_cursor_pos>();
globals::dispatcher.sink<GamepadButtonEvent>().connect<&on_gamepad_button>();
}
diff --git a/src/game/client/gui/chat.cc b/src/game/client/gui/chat.cc
index 9613aa5..a56c262 100644
--- a/src/game/client/gui/chat.cc
+++ b/src/game/client/gui/chat.cc
@@ -25,7 +25,7 @@
#include "client/gui/language.hh"
#include "client/gui/settings.hh"
-#include "client/io/glfw.hh"
+#include "client/io/keyboard.hh"
#include "client/io/sound.hh"
#include "client/resource/sound_effect.hh"
@@ -109,10 +109,10 @@ static void on_chat_message_packet(const protocol::ChatMessage& packet)
}
}
-static void on_glfw_key(const GlfwKeyEvent& event)
+static void on_key(const KeyEvent& event)
{
- if(event.action == GLFW_PRESS) {
- if((event.key == GLFW_KEY_ENTER) && (globals::gui_screen == GUI_CHAT)) {
+ if(event.is_action(GLFW_PRESS)) {
+ if(event.is_keycode(GLFW_KEY_ENTER) && globals::gui_screen == GUI_CHAT) {
if(!utils::is_whitespace(chat_input)) {
protocol::ChatMessage packet;
packet.type = protocol::ChatMessage::TEXT_MESSAGE;
@@ -129,12 +129,12 @@ static void on_glfw_key(const GlfwKeyEvent& event)
return;
}
- if((event.key == GLFW_KEY_ESCAPE) && (globals::gui_screen == GUI_CHAT)) {
+ if(event.is_keycode(GLFW_KEY_ESCAPE) && globals::gui_screen == GUI_CHAT) {
globals::gui_screen = GUI_SCREEN_NONE;
return;
}
- if(key_chat.equals(event.key) && !globals::gui_screen) {
+ if(key_chat.equals(event.keycode()) && !globals::gui_screen) {
globals::gui_screen = GUI_CHAT;
needs_focus = true;
return;
@@ -151,7 +151,7 @@ void client_chat::init(void)
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<GlfwKeyEvent>().connect<&on_glfw_key>();
+ globals::dispatcher.sink<KeyEvent>().connect<&on_key>();
sfx_chat_message = resource::load<SoundEffect>("sounds/ui/chat_message.wav");
}
diff --git a/src/game/client/gui/direct_connection.cc b/src/game/client/gui/direct_connection.cc
index 2b75a44..775140c 100644
--- a/src/game/client/gui/direct_connection.cc
+++ b/src/game/client/gui/direct_connection.cc
@@ -16,7 +16,7 @@
#include "client/gui/gui_screen.hh"
#include "client/gui/language.hh"
-#include "client/io/glfw.hh"
+#include "client/io/keyboard.hh"
#include "client/game.hh"
#include "client/globals.hh"
@@ -34,9 +34,9 @@ static std::string str_password;
static std::string direct_hostname;
static std::string direct_password;
-static void on_glfw_key(const GlfwKeyEvent& event)
+static void on_key(const KeyEvent& event)
{
- if((event.key == GLFW_KEY_ESCAPE) && (event.action == GLFW_PRESS)) {
+ if(event.is_keycode(GLFW_KEY_ESCAPE) && event.is_action(GLFW_PRESS)) {
if(globals::gui_screen == GUI_DIRECT_CONNECTION) {
globals::gui_screen = GUI_PLAY_MENU;
return;
@@ -79,7 +79,7 @@ static void connect_to_server(void)
void direct_connection::init(void)
{
- globals::dispatcher.sink<GlfwKeyEvent>().connect<&on_glfw_key>();
+ globals::dispatcher.sink<KeyEvent>().connect<&on_key>();
globals::dispatcher.sink<LanguageSetEvent>().connect<&on_language_set>();
}
diff --git a/src/game/client/gui/hotbar.cc b/src/game/client/gui/hotbar.cc
index edcf8a9..14c701c 100644
--- a/src/game/client/gui/hotbar.cc
+++ b/src/game/client/gui/hotbar.cc
@@ -18,7 +18,8 @@
#include "client/gui/settings.hh"
#include "client/gui/status_lines.hh"
-#include "client/io/glfw.hh"
+#include "client/io/keyboard.hh"
+#include "client/io/mouse.hh"
#include "client/resource/texture_gui.hh"
@@ -55,11 +56,11 @@ static void update_hotbar_item(void)
}
}
-static void on_glfw_key(const GlfwKeyEvent& event)
+static void on_key(const KeyEvent& event)
{
- if((event.action == GLFW_PRESS) && !globals::gui_screen) {
+ if(event.is_action(GLFW_PRESS) && !globals::gui_screen) {
for(unsigned int i = 0U; i < HOTBAR_SIZE; ++i) {
- if(hotbar_keys[i].equals(event.key)) {
+ if(hotbar_keys[i].equals(event.keycode())) {
hotbar::active_slot = i;
update_hotbar_item();
break;
@@ -68,15 +69,15 @@ static void on_glfw_key(const GlfwKeyEvent& event)
}
}
-static void on_glfw_scroll(const GlfwScrollEvent& event)
+static void on_scroll(const ScrollEvent& event)
{
if(!globals::gui_screen) {
- if(event.dy < 0.0) {
+ if(event.yoffset() < 0.0) {
hotbar::next_slot();
return;
}
- if(event.dy > 0.0) {
+ if(event.yoffset() > 0.0) {
hotbar::prev_slot();
return;
}
@@ -118,8 +119,8 @@ void hotbar::init(void)
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<GlfwKeyEvent>().connect<&on_glfw_key>();
- globals::dispatcher.sink<GlfwScrollEvent>().connect<&on_glfw_scroll>();
+ globals::dispatcher.sink<KeyEvent>().connect<&on_key>();
+ globals::dispatcher.sink<ScrollEvent>().connect<&on_scroll>();
}
void hotbar::shutdown(void)
diff --git a/src/game/client/gui/main_menu.cc b/src/game/client/gui/main_menu.cc
index 6fa5cc9..de96538 100644
--- a/src/game/client/gui/main_menu.cc
+++ b/src/game/client/gui/main_menu.cc
@@ -17,9 +17,8 @@
#include "client/gui/imutils_button.hh"
#include "client/gui/imutils_popup.hh"
#include "client/gui/language.hh"
-#include "client/gui/window_title.hh"
-#include "client/io/glfw.hh"
+#include "client/io/keyboard.hh"
#include "client/resource/texture_gui.hh"
@@ -36,9 +35,9 @@ static std::string str_quit_popup_title;
static std::string str_quit_popup_question;
static std::string str_quit_popup_choices[2];
-static void on_glfw_key(const GlfwKeyEvent& event)
+static void on_key(const KeyEvent& event)
{
- if(session::is_ingame() && (event.key == GLFW_KEY_ESCAPE) && (event.action == GLFW_PRESS)) {
+ if(session::is_ingame() && event.is_keycode(GLFW_KEY_ESCAPE) && event.is_action(GLFW_PRESS)) {
if(globals::gui_screen == GUI_SCREEN_NONE) {
globals::gui_screen = GUI_MAIN_MENU;
return;
@@ -67,7 +66,7 @@ static void on_language_set(const LanguageSetEvent& event)
void main_menu::init(void)
{
- globals::dispatcher.sink<GlfwKeyEvent>().connect<&on_glfw_key>();
+ globals::dispatcher.sink<KeyEvent>().connect<&on_key>();
globals::dispatcher.sink<LanguageSetEvent>().connect<&on_language_set>();
}
diff --git a/src/game/client/gui/play_menu.cc b/src/game/client/gui/play_menu.cc
index 61a99a4..62b5fce 100644
--- a/src/game/client/gui/play_menu.cc
+++ b/src/game/client/gui/play_menu.cc
@@ -23,7 +23,7 @@
#include "client/gui/gui_screen.hh"
#include "client/gui/language.hh"
-#include "client/io/glfw.hh"
+#include "client/io/keyboard.hh"
#include "client/game.hh"
#include "client/globals.hh"
@@ -170,9 +170,9 @@ static void join_selected_server(void)
}
}
-static void on_glfw_key(const GlfwKeyEvent& event)
+static void on_key(const KeyEvent& event)
{
- if((event.key == GLFW_KEY_ESCAPE) && (event.action == GLFW_PRESS)) {
+ if(event.is_keycode(GLFW_KEY_ESCAPE) && event.is_action(GLFW_PRESS)) {
if(globals::gui_screen == GUI_PLAY_MENU) {
if(editing_server) {
if(adding_server) {
@@ -517,7 +517,7 @@ void play_menu::init(void)
}
}
- globals::dispatcher.sink<GlfwKeyEvent>().connect<&on_glfw_key>();
+ globals::dispatcher.sink<KeyEvent>().connect<&on_key>();
globals::dispatcher.sink<LanguageSetEvent>().connect<&on_language_set>();
globals::dispatcher.sink<BotherResponseEvent>().connect<&on_bother_response>();
}
diff --git a/src/game/client/gui/settings.cc b/src/game/client/gui/settings.cc
index 65e91aa..60701e3 100644
--- a/src/game/client/gui/settings.cc
+++ b/src/game/client/gui/settings.cc
@@ -21,10 +21,12 @@
#include "client/gui/gui_screen.hh"
#include "client/gui/imutils_button.hh"
+#include "client/gui/imutils_popup.hh"
#include "client/gui/language.hh"
#include "client/io/gamepad.hh"
-#include "client/io/glfw.hh"
+#include "client/io/keyboard.hh"
+#include "client/io/video.hh"
#include "client/const.hh"
#include "client/globals.hh"
@@ -34,20 +36,21 @@ constexpr static unsigned int NUM_LOCATIONS = static_cast<unsigned int>(settings
constexpr static const char* TOOLTIP_TEXT = "[?]";
enum class setting_type {
- CHECKBOX, ///< config::Boolean
- INPUT_INT, ///< config::Number<int>
- INPUT_FLOAT, ///< config::Number<float>
- INPUT_UINT, ///< config::Number<unsigned int>
- INPUT_STRING, ///< config::String
- SLIDER_INT, ///< config::Number<int>
- SLIDER_FLOAT, ///< config::Number<float>
- SLIDER_UINT, ///< config::Number<unsigned int>
- STEPPER_INT, ///< config::Number<int>
- STEPPER_UINT, ///< config::Number<unsigned int>
- KEYBIND, ///< config::KeyBind
- GAMEPAD_AXIS, ///< config::GamepadAxis
- GAMEPAD_BUTTON, ///< config::GamepadButton
- LANGUAGE_SELECT, ///< config::String internally
+ CHECKBOX, ///< config::Boolean
+ INPUT_INT, ///< config::Number<int>
+ INPUT_FLOAT, ///< config::Number<float>
+ INPUT_UINT, ///< config::Number<unsigned int>
+ INPUT_STRING, ///< config::String
+ SLIDER_INT, ///< config::Number<int>
+ SLIDER_FLOAT, ///< config::Number<float>
+ SLIDER_UINT, ///< config::Number<unsigned int>
+ STEPPER_INT, ///< config::Number<int>
+ STEPPER_UINT, ///< config::Number<unsigned int>
+ KEYBIND, ///< config::KeyBind
+ GAMEPAD_AXIS, ///< config::GamepadAxis
+ GAMEPAD_BUTTON, ///< config::GamepadButton
+ LANGUAGE_SELECT, ///< config::String internally
+ VIDEO_MODE_SELECT, ///< config::String internally
};
enum class gui_location {
@@ -223,6 +226,16 @@ public:
virtual void layout(void) const override;
};
+class SettingValue_VideoMode final : public SettingValueWID {
+public:
+ virtual ~SettingValue_VideoMode(void) override = default;
+ virtual void layout(void) const override;
+ void refresh_choices(void);
+
+ std::vector<VideoMode> choices;
+ std::vector<std::string> choice_labels;
+};
+
static std::string str_label_movement;
static std::string str_label_gameplay;
static std::string str_label_miscellaneous;
@@ -242,6 +255,10 @@ static std::string str_separator_devices;
static std::string str_checkbox_false;
static std::string str_checkbox_true;
+static std::string str_popup_video_change_title;
+static std::string str_popup_video_change_text;
+static std::string str_popup_video_change_answers[2];
+
static std::vector<std::shared_ptr<SettingValue>> values_all;
static std::vector<std::shared_ptr<SettingValue>> values[NUM_LOCATIONS];
@@ -249,6 +266,8 @@ static std::string str_gamepad_axis_prefix;
static std::string str_gamepad_button_prefix;
static std::string str_gamepad_checkbox_tooltip;
+static bool should_open_video_mode_popup;
+static const VideoMode* target_video_mode;
static gui_location selected_location;
void SettingValue::layout_tooltip(void) const
@@ -542,6 +561,93 @@ void SettingValue_Language::layout(void) const
layout_tooltip();
}
+void SettingValue_VideoMode::layout(void) const
+{
+ int current_width;
+ int current_height;
+ int current_refresh_rate = GLFW_DONT_CARE;
+ bool is_fullscreen = false;
+
+ video::query_current_mode(current_width, current_height, is_fullscreen);
+
+ if(is_fullscreen) {
+ auto monitor = glfwGetWindowMonitor(globals::window);
+ auto video_mode = glfwGetVideoMode(monitor);
+ current_refresh_rate = video_mode->refreshRate;
+ }
+
+ int current_index = 0;
+
+ if(is_fullscreen) {
+ for(std::size_t i = 0; i < choices.size(); ++i) {
+ if(choices[i] == VideoMode(current_width, current_height, current_refresh_rate)) {
+ current_index = static_cast<int>(i) + 1;
+ break;
+ }
+ }
+ }
+
+ if(ImGui::BeginCombo(wid.c_str(), choice_labels[current_index].c_str())) {
+ if(ImGui::Selectable(choice_labels[0].c_str(), current_index == 0)) {
+ if(current_index != 0) {
+ should_open_video_mode_popup = true;
+ target_video_mode = nullptr;
+ }
+ }
+
+ auto current_width = INT_MIN;
+ auto current_height = INT_MIN;
+ ImVec2 dummy_size(0.0f, 0.0625f * ImGui::GetStyle().ItemSpacing.y);
+
+ for(std::size_t i = 1; i < choices.size(); ++i) {
+ const auto& mode = choices[i - 1];
+ auto mode_width = mode.wide();
+ auto mode_height = mode.tall();
+
+ if(current_width != mode_width || current_height != mode_height) {
+ ImGui::Separator();
+ ImGui::Dummy(dummy_size);
+
+ current_height = mode_height;
+ current_width = mode_width;
+ }
+
+ if(ImGui::Selectable(choice_labels[i].c_str(), current_index == static_cast<int>(i))) {
+ if(current_index != static_cast<int>(i)) {
+ should_open_video_mode_popup = true;
+ target_video_mode = &mode;
+ }
+ }
+ }
+
+ ImGui::EndCombo();
+ }
+
+ layout_label();
+ layout_tooltip();
+}
+
+void SettingValue_VideoMode::refresh_choices(void)
+{
+ auto& modes = video::query_fullscreen_modes();
+ unsigned int mode_index = 0U;
+
+ choices.clear();
+ choices.reserve(modes.size());
+
+ choice_labels.clear();
+ choice_labels.reserve(1 + modes.size());
+ choice_labels.push_back(std::string(language::resolve("settings.choice.video_mode.windowed")));
+
+ for(const auto& mode : modes) {
+ auto mode_string = std::format("{}x{} @ {}", mode.wide(), mode.tall(), mode.rate());
+ auto mode_label = std::format("{}###GUI::VideoMode[{}]", mode_string, mode_index);
+ choice_labels.emplace_back(std::move(mode_label));
+ choices.push_back(mode);
+ mode_index += 1U;
+ }
+}
+
static void refresh_input_wids(void)
{
for(auto& value : values_all) {
@@ -560,15 +666,22 @@ static void refresh_input_wids(void)
if(value->type == setting_type::GAMEPAD_BUTTON) {
auto gamepad_button = std::static_pointer_cast<SettingValue_GamepadButton>(value);
gamepad_button->refresh_wids();
+ continue;
+ }
+
+ if(value->type == setting_type::VIDEO_MODE_SELECT) {
+ auto video_mode = std::static_pointer_cast<SettingValue_VideoMode>(value);
+ video_mode->refresh_choices();
+ continue;
}
}
}
-static void on_glfw_key(const GlfwKeyEvent& event)
+static void on_key(const KeyEvent& event)
{
- if((event.action == GLFW_PRESS) && (event.key != DEBUG_KEY)) {
+ if(event.is_action(GLFW_PRESS) && !event.is_keycode(DEBUG_KEY)) {
if(globals::gui_keybind_ptr || globals::gui_gamepad_axis_ptr || globals::gui_gamepad_button_ptr) {
- if(event.key == GLFW_KEY_ESCAPE) {
+ if(event.is_keycode(GLFW_KEY_ESCAPE)) {
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
@@ -582,7 +695,7 @@ static void on_glfw_key(const GlfwKeyEvent& event)
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
- globals::gui_keybind_ptr->set_key(event.key);
+ globals::gui_keybind_ptr->set_key(event.keycode());
globals::gui_keybind_ptr = nullptr;
refresh_input_wids();
@@ -590,7 +703,7 @@ static void on_glfw_key(const GlfwKeyEvent& event)
return;
}
- if((event.key == GLFW_KEY_ESCAPE) && (globals::gui_screen == GUI_SETTINGS)) {
+ if(event.is_keycode(GLFW_KEY_ESCAPE) && globals::gui_screen == GUI_SETTINGS) {
globals::gui_screen = GUI_MAIN_MENU;
return;
}
@@ -603,7 +716,7 @@ static void on_gamepad_axis(const GamepadAxisEvent& event)
auto& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
- globals::gui_gamepad_axis_ptr->set_axis(event.axis);
+ globals::gui_gamepad_axis_ptr->set_axis(event.axis());
globals::gui_gamepad_axis_ptr = nullptr;
refresh_input_wids();
@@ -618,7 +731,7 @@ static void on_gamepad_button(const GamepadButtonEvent& event)
auto& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
- globals::gui_gamepad_button_ptr->set_button(event.button);
+ globals::gui_gamepad_button_ptr->set_button(event.button());
globals::gui_gamepad_button_ptr = nullptr;
refresh_input_wids();
@@ -648,6 +761,11 @@ static void on_language_set(const LanguageSetEvent& event)
str_checkbox_false = language::resolve("settings.checkbox.false");
str_checkbox_true = language::resolve("settings.checkbox.true");
+ str_popup_video_change_title = language::resolve_gui("settings.popup.video_change.title");
+ str_popup_video_change_text = language::resolve("settings.popup.video_change.text");
+ str_popup_video_change_answers[0] = language::resolve_gui("settings.popup.video_change.answer.yes");
+ str_popup_video_change_answers[1] = language::resolve_gui("settings.popup.video_change.answer.no");
+
str_gamepad_axis_prefix = language::resolve("settings.gamepad.axis");
str_gamepad_button_prefix = language::resolve("settings.gamepad.button");
str_gamepad_checkbox_tooltip = language::resolve("settings.gamepad.checkbox_tooltip");
@@ -696,7 +814,11 @@ static void layout_location_selectable(const std::string& label, gui_location ta
void settings::init(void)
{
- globals::dispatcher.sink<GlfwKeyEvent>().connect<&on_glfw_key>();
+ selected_location = gui_location::GENERAL;
+ should_open_video_mode_popup = false;
+ target_video_mode = nullptr;
+
+ globals::dispatcher.sink<KeyEvent>().connect<&on_key>();
globals::dispatcher.sink<GamepadAxisEvent>().connect<&on_gamepad_axis>();
globals::dispatcher.sink<GamepadButtonEvent>().connect<&on_gamepad_button>();
globals::dispatcher.sink<LanguageSetEvent>().connect<&on_language_set>();
@@ -822,9 +944,24 @@ void settings::layout(void)
ImGui::EndChild();
}
+ if(should_open_video_mode_popup) {
+ ImGui::OpenPopup(str_popup_video_change_title.c_str());
+
+ should_open_video_mode_popup = false;
+ }
+
ImGui::PopStyleVar(2);
ImGui::PopFont();
+ if(0 == imutils::popup(str_popup_video_change_title, str_popup_video_change_text, str_popup_video_change_answers, 2, 1.0f)) {
+ if(target_video_mode) {
+ video::request_fullscreen(target_video_mode->wide(), target_video_mode->tall(), target_video_mode->rate());
+ }
+ else {
+ video::request_windowed();
+ }
+ }
+
ImGui::End();
}
@@ -1044,3 +1181,18 @@ void settings::add_language_select(int priority, settings_location location, std
values[static_cast<unsigned int>(location)].push_back(setting_value);
values_all.push_back(setting_value);
}
+
+void settings::add_video_mode_select(int priority, settings_location location, std::string_view name)
+{
+ auto setting_value = std::make_shared<SettingValue_VideoMode>();
+ setting_value->type = setting_type::VIDEO_MODE_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.get()));
+ setting_value->refresh_choices();
+
+ values[static_cast<unsigned int>(location)].push_back(setting_value);
+ values_all.push_back(setting_value);
+}
diff --git a/src/game/client/gui/splash.cc b/src/game/client/gui/splash.cc
index 7d7b86c..8e4c505 100644
--- a/src/game/client/gui/splash.cc
+++ b/src/game/client/gui/splash.cc
@@ -18,7 +18,8 @@
#include "client/gui/gui_screen.hh"
#include "client/gui/language.hh"
-#include "client/io/glfw.hh"
+#include "client/io/keyboard.hh"
+#include "client/io/mouse.hh"
#include "client/resource/texture_gui.hh"
@@ -37,17 +38,17 @@ static float texture_alpha;
static std::uint64_t end_time;
static std::string current_text;
-static void on_glfw_key(const GlfwKeyEvent& event)
+static void on_key(const KeyEvent& event)
{
end_time = UINT64_C(0);
}
-static void on_glfw_mouse_button(const GlfwMouseButtonEvent& event)
+static void on_mouse_button(const MouseButtonEvent& event)
{
end_time = UINT64_C(0);
}
-static void on_glfw_scroll(const GlfwScrollEvent& event)
+static void on_scroll(const ScrollEvent& event)
{
end_time = UINT64_C(0);
}
@@ -89,9 +90,9 @@ void client_splash::init_late(void)
end_time = utils::unix_microseconds() + DELAY_MICROSECONDS;
- globals::dispatcher.sink<GlfwKeyEvent>().connect<&on_glfw_key>();
- globals::dispatcher.sink<GlfwMouseButtonEvent>().connect<&on_glfw_mouse_button>();
- globals::dispatcher.sink<GlfwScrollEvent>().connect<&on_glfw_scroll>();
+ globals::dispatcher.sink<KeyEvent>().connect<&on_key>();
+ globals::dispatcher.sink<MouseButtonEvent>().connect<&on_mouse_button>();
+ globals::dispatcher.sink<ScrollEvent>().connect<&on_scroll>();
current_text = language::resolve("splash.skip_prompt");
@@ -108,9 +109,9 @@ void client_splash::init_late(void)
client_splash::render();
}
- globals::dispatcher.sink<GlfwKeyEvent>().disconnect<&on_glfw_key>();
- globals::dispatcher.sink<GlfwMouseButtonEvent>().disconnect<&on_glfw_mouse_button>();
- globals::dispatcher.sink<GlfwScrollEvent>().disconnect<&on_glfw_scroll>();
+ globals::dispatcher.sink<KeyEvent>().disconnect<&on_key>();
+ globals::dispatcher.sink<MouseButtonEvent>().disconnect<&on_mouse_button>();
+ globals::dispatcher.sink<ScrollEvent>().disconnect<&on_scroll>();
texture = nullptr;
texture_aspect = 0.0f;
diff --git a/src/game/client/io/CMakeLists.txt b/src/game/client/io/CMakeLists.txt
index a68f137..078d265 100644
--- a/src/game/client/io/CMakeLists.txt
+++ b/src/game/client/io/CMakeLists.txt
@@ -1,6 +1,11 @@
target_sources(vclient PRIVATE
"${CMAKE_CURRENT_LIST_DIR}/gamepad.cc"
"${CMAKE_CURRENT_LIST_DIR}/gamepad.hh"
- "${CMAKE_CURRENT_LIST_DIR}/glfw.hh"
+ "${CMAKE_CURRENT_LIST_DIR}/keyboard.cc"
+ "${CMAKE_CURRENT_LIST_DIR}/keyboard.hh"
+ "${CMAKE_CURRENT_LIST_DIR}/mouse.cc"
+ "${CMAKE_CURRENT_LIST_DIR}/mouse.hh"
"${CMAKE_CURRENT_LIST_DIR}/sound.cc"
- "${CMAKE_CURRENT_LIST_DIR}/sound.hh")
+ "${CMAKE_CURRENT_LIST_DIR}/sound.hh"
+ "${CMAKE_CURRENT_LIST_DIR}/video.cc"
+ "${CMAKE_CURRENT_LIST_DIR}/video.hh")
diff --git a/src/game/client/main.cc b/src/game/client/main.cc
index b58d840..dcc78b3 100644
--- a/src/game/client/main.cc
+++ b/src/game/client/main.cc
@@ -75,6 +75,8 @@ int main(int argc, char** argv)
spdlog::info("Voxelius Client {}", version::full);
+ splash::init_client();
+
video::init();
keyboard::init();
@@ -163,8 +165,6 @@ int main(int argc, char** argv)
}
}
- splash::init_client();
-
video::update_window_title();
ImGuiIO& io = ImGui::GetIO();
@@ -205,9 +205,11 @@ int main(int argc, char** argv)
client_game::init_late();
+ is_running = true;
+
auto last_curtime = globals::curtime;
- while(!glfwWindowShouldClose(globals::window)) {
+ while(is_running) {
globals::curtime = utils::unix_microseconds();
globals::window_frametime_us = globals::curtime - last_curtime;
diff --git a/src/game/client/receive.cc b/src/game/client/receive.cc
index 5331dc5..532d462 100644
--- a/src/game/client/receive.cc
+++ b/src/game/client/receive.cc
@@ -21,9 +21,9 @@
#include "client/gui/chat.hh"
#include "client/gui/gui_screen.hh"
#include "client/gui/message_box.hh"
-#include "client/gui/window_title.hh"
#include "client/io/sound.hh"
+#include "client/io/video.hh"
#include "client/globals.hh"
#include "client/session.hh"
@@ -51,7 +51,7 @@ static bool synchronize_entity_id(Dimension* dimension, entt::entity entity)
message_box::set_subtitle("protocol.entity_id_desync");
message_box::add_button("disconnected.back", [](void) {
globals::gui_screen = GUI_PLAY_MENU;
- window_title::update();
+ video::update_window_title();
});
globals::gui_screen = GUI_MESSAGE_BOX;
@@ -156,7 +156,7 @@ static void on_spawn_player_packet(const protocol::SpawnPlayer& packet)
client_chat::refresh_timings();
- window_title::update();
+ video::update_window_title();
}
}
}
diff --git a/src/game/client/screenshot.cc b/src/game/client/screenshot.cc
index a4c043e..868a8bb 100644
--- a/src/game/client/screenshot.cc
+++ b/src/game/client/screenshot.cc
@@ -17,7 +17,7 @@
#include "client/gui/language.hh"
#include "client/gui/settings.hh"
-#include "client/io/glfw.hh"
+#include "client/io/keyboard.hh"
#include "client/globals.hh"
#include "client/toggles.hh"
@@ -29,10 +29,10 @@ static void stbi_png_physfs_callback(void* context, void* data, int size)
PHYSFS_writeBytes(reinterpret_cast<PHYSFS_File*>(context), data, size);
}
-static void on_glfw_key(const GlfwKeyEvent& event)
+static void on_key(const KeyEvent& event)
{
if(!globals::gui_keybind_ptr && !toggles::is_sequence_await) {
- if(screenshot_key.equals(event.key) && (event.action == GLFW_PRESS)) {
+ if(event.is_keycode(screenshot_key.get_key()) && event.is_action(GLFW_PRESS)) {
screenshot::take();
return;
}
@@ -45,7 +45,7 @@ void screenshot::init(void)
settings::add_keybind(0, screenshot_key, settings_location::KEYBOARD_MISC, "key.screenshot");
- globals::dispatcher.sink<GlfwKeyEvent>().connect<&on_glfw_key>();
+ globals::dispatcher.sink<KeyEvent>().connect<&on_key>();
}
void screenshot::take(void)
diff --git a/src/game/client/session.cc b/src/game/client/session.cc
index 7c38b28..6239797 100644
--- a/src/game/client/session.cc
+++ b/src/game/client/session.cc
@@ -31,7 +31,8 @@
#include "client/gui/gui_screen.hh"
#include "client/gui/message_box.hh"
#include "client/gui/progress_bar.hh"
-#include "client/gui/window_title.hh"
+
+#include "client/io/video.hh"
#include "client/world/chunk_visibility.hh"
@@ -92,7 +93,7 @@ static void on_disconnect_packet(const protocol::Disconnect& packet)
message_box::set_subtitle(packet.reason.c_str());
message_box::add_button("disconnected.back", [](void) {
globals::gui_screen = GUI_PLAY_MENU;
- window_title::update();
+ video::update_window_title();
});
globals::gui_screen = GUI_MESSAGE_BOX;
@@ -178,7 +179,7 @@ void session::invalidate(void)
message_box::set_subtitle("enet.peer_connection_timeout");
message_box::add_button("disconnected.back", [](void) {
globals::gui_screen = GUI_PLAY_MENU;
- window_title::update();
+ video::update_window_title();
});
globals::gui_screen = GUI_MESSAGE_BOX;
@@ -225,7 +226,7 @@ void session::connect(std::string_view host, std::uint16_t port, std::string_vie
message_box::set_subtitle("enet.peer_connection_failed");
message_box::add_button("disconnected.back", [](void) {
globals::gui_screen = GUI_PLAY_MENU;
- window_title::update();
+ video::update_window_title();
});
globals::gui_screen = GUI_MESSAGE_BOX;
diff --git a/src/game/client/toggles.cc b/src/game/client/toggles.cc
index 96f9dfd..1b46960 100644
--- a/src/game/client/toggles.cc
+++ b/src/game/client/toggles.cc
@@ -13,7 +13,7 @@
#include "client/gui/language.hh"
#include "client/io/gamepad.hh"
-#include "client/io/glfw.hh"
+#include "client/io/keyboard.hh"
#include "client/const.hh"
#include "client/globals.hh"
@@ -54,7 +54,7 @@ static void toggle_value(ToggleInfo& info, toggle_type type)
print_toggle_state(info);
}
-static void on_glfw_key(const GlfwKeyEvent& event)
+static void on_key(const KeyEvent& event)
{
if(globals::gui_keybind_ptr) {
// The UI keybind subsystem has the authority
@@ -62,22 +62,22 @@ static void on_glfw_key(const GlfwKeyEvent& event)
return;
}
- if(event.key == DEBUG_KEY) {
- if(event.action == GLFW_PRESS) {
+ if(event.is_keycode(DEBUG_KEY)) {
+ if(event.is_action(GLFW_PRESS)) {
toggles::is_sequence_await = true;
ImGui::GetIO().ConfigFlags &= ~ImGuiConfigFlags_NavEnableKeyboard;
return;
}
- if(event.action == GLFW_RELEASE) {
+ if(event.is_action(GLFW_RELEASE)) {
toggles::is_sequence_await = false;
ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
return;
}
}
- if((event.action == GLFW_PRESS) && toggles::is_sequence_await) {
- if(event.key == GLFW_KEY_L) {
+ if((event.is_action(GLFW_PRESS)) && toggles::is_sequence_await) {
+ if(event.is_keycode(GLFW_KEY_L)) {
// This causes the language subsystem
// to re-parse the JSON file essentially
// causing the game to soft-reload language
@@ -86,7 +86,7 @@ static void on_glfw_key(const GlfwKeyEvent& event)
}
for(toggle_type i = 0; i < TOGGLE_COUNT; ++i) {
- if(event.key == toggle_infos[i].glfw_keycode) {
+ if(event.is_keycode(toggle_infos[i].glfw_keycode)) {
toggle_value(toggle_infos[i], i);
return;
}
@@ -120,7 +120,7 @@ void toggles::init(void)
toggle_infos[TOGGLE_PM_FLIGHT].glfw_keycode = GLFW_KEY_F;
toggle_infos[TOGGLE_PM_FLIGHT].is_enabled = false;
- globals::dispatcher.sink<GlfwKeyEvent>().connect<&on_glfw_key>();
+ globals::dispatcher.sink<KeyEvent>().connect<&on_key>();
}
void toggles::init_late(void)