summaryrefslogtreecommitdiffstats
path: root/game/client/config
diff options
context:
space:
mode:
Diffstat (limited to 'game/client/config')
-rw-r--r--game/client/config/CMakeLists.txt7
-rw-r--r--game/client/config/gamepad_axis.cc114
-rw-r--r--game/client/config/gamepad_axis.hh42
-rw-r--r--game/client/config/gamepad_button.cc90
-rw-r--r--game/client/config/gamepad_button.hh32
-rw-r--r--game/client/config/keybind.cc200
-rw-r--r--game/client/config/keybind.hh29
7 files changed, 514 insertions, 0 deletions
diff --git a/game/client/config/CMakeLists.txt b/game/client/config/CMakeLists.txt
new file mode 100644
index 0000000..0536160
--- /dev/null
+++ b/game/client/config/CMakeLists.txt
@@ -0,0 +1,7 @@
+target_sources(vclient PRIVATE
+ "${CMAKE_CURRENT_LIST_DIR}/gamepad_axis.cc"
+ "${CMAKE_CURRENT_LIST_DIR}/gamepad_axis.hh"
+ "${CMAKE_CURRENT_LIST_DIR}/gamepad_button.cc"
+ "${CMAKE_CURRENT_LIST_DIR}/gamepad_button.hh"
+ "${CMAKE_CURRENT_LIST_DIR}/keybind.cc"
+ "${CMAKE_CURRENT_LIST_DIR}/keybind.hh")
diff --git a/game/client/config/gamepad_axis.cc b/game/client/config/gamepad_axis.cc
new file mode 100644
index 0000000..a82de81
--- /dev/null
+++ b/game/client/config/gamepad_axis.cc
@@ -0,0 +1,114 @@
+#include "client/pch.hh"
+
+#include "client/config/gamepad_axis.hh"
+
+#include "core/math/constexpr.hh"
+
+#include "client/io/gamepad.hh"
+
+constexpr static const char* UNKNOWN_AXIS_NAME = "UNKNOWN";
+
+static const std::pair<int, const char*> axis_names[] = {
+ { GLFW_GAMEPAD_AXIS_LEFT_X, "LEFT_X" },
+ { GLFW_GAMEPAD_AXIS_LEFT_Y, "LEFT_Y" },
+ { GLFW_GAMEPAD_AXIS_RIGHT_X, "RIGHT_X" },
+ { GLFW_GAMEPAD_AXIS_RIGHT_Y, "RIGHT_Y" },
+ { GLFW_GAMEPAD_AXIS_LEFT_TRIGGER, "LEFT_TRIG" },
+ { GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER, "RIGHT_TRIG" },
+};
+
+static const char* get_axis_name(int axis)
+{
+ for(const auto& it : axis_names) {
+ if(it.first != axis) {
+ continue;
+ }
+
+ return it.second;
+ }
+
+ return UNKNOWN_AXIS_NAME;
+}
+
+config::GamepadAxis::GamepadAxis(void) : GamepadAxis(io::INVALID_GAMEPAD_AXIS, false)
+{
+}
+
+config::GamepadAxis::GamepadAxis(int axis, bool inverted)
+{
+ m_inverted = inverted;
+ m_gamepad_axis = axis;
+ m_name = get_axis_name(axis);
+ m_full_string = std::format("{}:{}", m_name, m_inverted ? 1U : 0U);
+}
+
+const char* config::GamepadAxis::get(void) const
+{
+ return m_full_string.c_str();
+}
+
+void config::GamepadAxis::set(const char* value)
+{
+ char new_name[64];
+ unsigned int new_invert;
+
+ if(2 == std::sscanf(value, "%63[^:]:%u", new_name, &new_invert)) {
+ for(const auto& it : axis_names) {
+ if(!std::strcmp(it.second, new_name)) {
+ m_inverted = new_invert;
+ m_gamepad_axis = it.first;
+ m_name = get_axis_name(m_gamepad_axis);
+ m_full_string = std::format("{}:{}", m_name, m_inverted ? 1U : 0U);
+ return;
+ }
+ }
+ }
+
+ m_inverted = false;
+ m_gamepad_axis = io::INVALID_GAMEPAD_AXIS;
+ m_name = UNKNOWN_AXIS_NAME;
+ m_full_string = std::format("{}:{}", m_name, m_inverted ? 1U : 0U);
+}
+
+int config::GamepadAxis::get_axis(void) const
+{
+ return m_gamepad_axis;
+}
+
+void config::GamepadAxis::set_axis(int axis)
+{
+ m_gamepad_axis = axis;
+ m_name = get_axis_name(axis);
+ m_full_string = std::format("{}:{}", m_name, m_inverted ? 1U : 0U);
+}
+
+bool config::GamepadAxis::is_inverted(void) const
+{
+ return m_inverted;
+}
+
+void config::GamepadAxis::set_inverted(bool inverted)
+{
+ m_inverted = inverted;
+ m_full_string = std::format("{}:{}", m_name, m_inverted ? 1U : 0U);
+}
+
+float config::GamepadAxis::get_value(const GLFWgamepadstate& state, float deadzone) const
+{
+ if(m_gamepad_axis <= math::array_size(state.axes)) {
+ auto value = state.axes[m_gamepad_axis];
+
+ if(math::abs(value) > deadzone) {
+ return m_inverted ? -value : value;
+ }
+
+ return 0.0f;
+ }
+
+ return 0.0f;
+}
+
+const char* config::GamepadAxis::get_name(void) const
+{
+ return m_name;
+}
diff --git a/game/client/config/gamepad_axis.hh b/game/client/config/gamepad_axis.hh
new file mode 100644
index 0000000..0308ce6
--- /dev/null
+++ b/game/client/config/gamepad_axis.hh
@@ -0,0 +1,42 @@
+#ifndef CLIENT_GAMEPAD_AXIS_HH
+#define CLIENT_GAMEPAD_AXIS_HH 1
+#pragma once
+
+#include "core/config/ivalue.hh"
+
+struct GLFWgamepadstate;
+
+namespace config
+{
+class GamepadAxis final : public IValue {
+public:
+ explicit GamepadAxis(void);
+ explicit GamepadAxis(int axis, bool inverted);
+ virtual ~GamepadAxis(void) = default;
+
+ virtual const char* get(void) const override;
+ virtual void set(const char* value) override;
+
+ int get_axis(void) const;
+ void set_axis(int axis);
+
+ bool is_inverted(void) const;
+ void set_inverted(bool inverted);
+
+ float get_value(const GLFWgamepadstate& state, float deadzone = 0.0f) const;
+
+ // Conventional get/set methods implemented by
+ // this configuration value actually contain the
+ // inversion flag. Since we're updating that flag
+ // in the UI by means of a separate checkbox, we only need the name here
+ const char* get_name(void) const;
+
+private:
+ bool m_inverted;
+ int m_gamepad_axis;
+ std::string m_full_string;
+ const char* m_name;
+};
+} // namespace config
+
+#endif // CLIENT_GAMEPAD_AXIS_HH
diff --git a/game/client/config/gamepad_button.cc b/game/client/config/gamepad_button.cc
new file mode 100644
index 0000000..b983baa
--- /dev/null
+++ b/game/client/config/gamepad_button.cc
@@ -0,0 +1,90 @@
+#include "client/pch.hh"
+
+#include "client/config/gamepad_button.hh"
+
+#include "core/math/constexpr.hh"
+
+#include "client/io/gamepad.hh"
+
+constexpr static const char* UNKNOWN_BUTTON_NAME = "UNKNOWN";
+
+static const std::pair<int, const char*> button_names[] = {
+ { GLFW_GAMEPAD_BUTTON_A, "A" },
+ { GLFW_GAMEPAD_BUTTON_B, "B" },
+ { GLFW_GAMEPAD_BUTTON_X, "X" },
+ { GLFW_GAMEPAD_BUTTON_Y, "Y" },
+ { GLFW_GAMEPAD_BUTTON_LEFT_BUMPER, "L_BUMP" },
+ { GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER, "R_BUMP" },
+ { GLFW_GAMEPAD_BUTTON_BACK, "BACK" },
+ { GLFW_GAMEPAD_BUTTON_START, "START" },
+ { GLFW_GAMEPAD_BUTTON_GUIDE, "GUIDE" },
+ { GLFW_GAMEPAD_BUTTON_LEFT_THUMB, "L_THUMB" },
+ { GLFW_GAMEPAD_BUTTON_RIGHT_THUMB, "R_THUMB" },
+ { GLFW_GAMEPAD_BUTTON_DPAD_UP, "DPAD_UP" },
+ { GLFW_GAMEPAD_BUTTON_DPAD_RIGHT, "DPAD_RIGHT" },
+ { GLFW_GAMEPAD_BUTTON_DPAD_DOWN, "DPAD_DOWN" },
+ { GLFW_GAMEPAD_BUTTON_DPAD_LEFT, "DPAD_LEFT" },
+};
+
+static const char* get_button_name(int button)
+{
+ for(const auto& it : button_names) {
+ if(it.first == button) {
+ return it.second;
+ }
+ }
+
+ return UNKNOWN_BUTTON_NAME;
+}
+
+config::GamepadButton::GamepadButton(void)
+{
+ m_gamepad_button = io::INVALID_GAMEPAD_BUTTON;
+ m_name = UNKNOWN_BUTTON_NAME;
+}
+
+config::GamepadButton::GamepadButton(int button)
+{
+ m_gamepad_button = button;
+ m_name = get_button_name(button);
+}
+
+const char* config::GamepadButton::get(void) const
+{
+ return m_name;
+}
+
+void config::GamepadButton::set(const char* value)
+{
+ for(const auto& it : button_names) {
+ if(!std::strcmp(it.second, value)) {
+ m_gamepad_button = it.first;
+ m_name = it.second;
+ return;
+ }
+ }
+
+ m_gamepad_button = io::INVALID_GAMEPAD_BUTTON;
+ m_name = UNKNOWN_BUTTON_NAME;
+}
+
+int config::GamepadButton::get_button(void) const
+{
+ return m_gamepad_button;
+}
+
+void config::GamepadButton::set_button(int button)
+{
+ m_gamepad_button = button;
+ m_name = get_button_name(button);
+}
+
+bool config::GamepadButton::equals(int button) const
+{
+ return m_gamepad_button == button;
+}
+
+bool config::GamepadButton::is_pressed(const GLFWgamepadstate& state) const
+{
+ return m_gamepad_button < math::array_size(state.buttons) && state.buttons[m_gamepad_button] == GLFW_PRESS;
+}
diff --git a/game/client/config/gamepad_button.hh b/game/client/config/gamepad_button.hh
new file mode 100644
index 0000000..11566c1
--- /dev/null
+++ b/game/client/config/gamepad_button.hh
@@ -0,0 +1,32 @@
+#ifndef CLIENT_GAMEPAD_BUTTON_HH
+#define CLIENT_GAMEPAD_BUTTON_HH 1
+#pragma once
+
+#include "core/config/ivalue.hh"
+
+struct GLFWgamepadstate;
+
+namespace config
+{
+class GamepadButton final : public IValue {
+public:
+ explicit GamepadButton(void);
+ explicit GamepadButton(int button);
+ virtual ~GamepadButton(void) = default;
+
+ virtual const char* get(void) const override;
+ virtual void set(const char* value) override;
+
+ int get_button(void) const;
+ void set_button(int button);
+
+ bool equals(int button) const;
+ bool is_pressed(const GLFWgamepadstate& state) const;
+
+private:
+ int m_gamepad_button;
+ const char* m_name;
+};
+} // namespace config
+
+#endif // CLIENT_GAMEPAD_BUTTON_HH
diff --git a/game/client/config/keybind.cc b/game/client/config/keybind.cc
new file mode 100644
index 0000000..1cf896c
--- /dev/null
+++ b/game/client/config/keybind.cc
@@ -0,0 +1,200 @@
+#include "client/pch.hh"
+
+#include "client/config/keybind.hh"
+
+#include "core/math/constexpr.hh"
+
+#include "client/const.hh"
+
+constexpr static const char* UNKNOWN_KEY_NAME = "UNKNOWN";
+
+static const std::pair<int, const char*> key_names[] = {
+ { GLFW_KEY_SPACE, "SPACE" },
+ { GLFW_KEY_APOSTROPHE, "'" },
+ { GLFW_KEY_COMMA, "," },
+ { GLFW_KEY_MINUS, "-" },
+ { GLFW_KEY_PERIOD, "." },
+ { GLFW_KEY_SLASH, "/" },
+ { GLFW_KEY_0, "0" },
+ { GLFW_KEY_1, "1" },
+ { GLFW_KEY_2, "2" },
+ { GLFW_KEY_3, "3" },
+ { GLFW_KEY_4, "4" },
+ { GLFW_KEY_5, "5" },
+ { GLFW_KEY_6, "6" },
+ { GLFW_KEY_7, "7" },
+ { GLFW_KEY_8, "8" },
+ { GLFW_KEY_9, "9" },
+ { GLFW_KEY_SEMICOLON, ";" },
+ { GLFW_KEY_EQUAL, "=" },
+ { GLFW_KEY_A, "A" },
+ { GLFW_KEY_B, "B" },
+ { GLFW_KEY_C, "C" },
+ { GLFW_KEY_D, "D" },
+ { GLFW_KEY_E, "E" },
+ { GLFW_KEY_F, "F" },
+ { GLFW_KEY_G, "G" },
+ { GLFW_KEY_H, "H" },
+ { GLFW_KEY_I, "I" },
+ { GLFW_KEY_J, "J" },
+ { GLFW_KEY_K, "K" },
+ { GLFW_KEY_L, "L" },
+ { GLFW_KEY_M, "M" },
+ { GLFW_KEY_N, "N" },
+ { GLFW_KEY_O, "O" },
+ { GLFW_KEY_P, "P" },
+ { GLFW_KEY_Q, "Q" },
+ { GLFW_KEY_R, "R" },
+ { GLFW_KEY_S, "S" },
+ { GLFW_KEY_T, "T" },
+ { GLFW_KEY_U, "U" },
+ { GLFW_KEY_V, "V" },
+ { GLFW_KEY_W, "W" },
+ { GLFW_KEY_X, "X" },
+ { GLFW_KEY_Y, "Y" },
+ { GLFW_KEY_Z, "Z" },
+ { GLFW_KEY_LEFT_BRACKET, "[" },
+ { GLFW_KEY_BACKSLASH, "\\" },
+ { GLFW_KEY_RIGHT_BRACKET, "]" },
+ { GLFW_KEY_GRAVE_ACCENT, "`" },
+ { GLFW_KEY_WORLD_1, "WORLD_1" },
+ { GLFW_KEY_WORLD_2, "WORLD_2" },
+ { GLFW_KEY_ESCAPE, "ESCAPE" },
+ { GLFW_KEY_ENTER, "ENTER" },
+ { GLFW_KEY_TAB, "TAB" },
+ { GLFW_KEY_BACKSPACE, "BACKSPACE" },
+ { GLFW_KEY_INSERT, "INSERT" },
+ { GLFW_KEY_DELETE, "DELETE" },
+ { GLFW_KEY_RIGHT, "RIGHT" },
+ { GLFW_KEY_LEFT, "LEFT" },
+ { GLFW_KEY_DOWN, "DOWN" },
+ { GLFW_KEY_UP, "UP" },
+ { GLFW_KEY_PAGE_UP, "PAGE_UP" },
+ { GLFW_KEY_PAGE_DOWN, "PAGE_DOWN" },
+ { GLFW_KEY_HOME, "HOME" },
+ { GLFW_KEY_END, "END" },
+ { GLFW_KEY_CAPS_LOCK, "CAPS_LOCK" },
+ { GLFW_KEY_SCROLL_LOCK, "SCROLL_LOCK" },
+ { GLFW_KEY_NUM_LOCK, "NUM_LOCK" },
+ { GLFW_KEY_PRINT_SCREEN, "PRINT_SCREEN" },
+ { GLFW_KEY_PAUSE, "PAUSE" },
+ { GLFW_KEY_F1, "F1" },
+ { GLFW_KEY_F2, "F2" },
+ { GLFW_KEY_F3, "F3" },
+ { GLFW_KEY_F4, "F4" },
+ { GLFW_KEY_F5, "F5" },
+ { GLFW_KEY_F6, "F6" },
+ { GLFW_KEY_F7, "F7" },
+ { GLFW_KEY_F8, "F8" },
+ { GLFW_KEY_F9, "F9" },
+ { GLFW_KEY_F10, "F10" },
+ { GLFW_KEY_F11, "F11" },
+ { GLFW_KEY_F12, "F12" },
+ { GLFW_KEY_F13, "F13" },
+ { GLFW_KEY_F14, "F14" },
+ { GLFW_KEY_F15, "F15" },
+ { GLFW_KEY_F16, "F16" },
+ { GLFW_KEY_F17, "F17" },
+ { GLFW_KEY_F18, "F18" },
+ { GLFW_KEY_F19, "F19" },
+ { GLFW_KEY_F20, "F20" },
+ { GLFW_KEY_F21, "F21" },
+ { GLFW_KEY_F22, "F22" },
+ { GLFW_KEY_F23, "F23" },
+ { GLFW_KEY_F24, "F24" },
+ { GLFW_KEY_F25, "F25" },
+ { GLFW_KEY_KP_0, "KEYPAD_0" },
+ { GLFW_KEY_KP_1, "KEYPAD_1" },
+ { GLFW_KEY_KP_2, "KEYPAD_2" },
+ { GLFW_KEY_KP_3, "KEYPAD_3" },
+ { GLFW_KEY_KP_4, "KEYPAD_4" },
+ { GLFW_KEY_KP_5, "KEYPAD_5" },
+ { GLFW_KEY_KP_6, "KEYPAD_6" },
+ { GLFW_KEY_KP_7, "KEYPAD_7" },
+ { GLFW_KEY_KP_8, "KEYPAD_8" },
+ { GLFW_KEY_KP_9, "KEYPAD_9" },
+ { GLFW_KEY_KP_DECIMAL, "KEYPAD_POINT" },
+ { GLFW_KEY_KP_DIVIDE, "KEYPAD_DIV" },
+ { GLFW_KEY_KP_MULTIPLY, "KEYPAD_MUL" },
+ { GLFW_KEY_KP_SUBTRACT, "KEYPAD_MINUS" },
+ { GLFW_KEY_KP_ADD, "KEYPAD_PLUS" },
+ { GLFW_KEY_KP_ENTER, "KEYPAD_ENTER" },
+ { GLFW_KEY_KP_EQUAL, "KEYPAD_EQUAL" },
+ { GLFW_KEY_LEFT_SHIFT, "LEFT_SHIFT" },
+ { GLFW_KEY_LEFT_CONTROL, "LEFT_CTRL" },
+ { GLFW_KEY_LEFT_ALT, "LEFT_ALT" },
+ { GLFW_KEY_LEFT_SUPER, "LEFT_SUPER" },
+ { GLFW_KEY_RIGHT_SHIFT, "RIGHT_SHIFT" },
+ { GLFW_KEY_RIGHT_CONTROL, "RIGHT_CTRL" },
+ { GLFW_KEY_RIGHT_ALT, "RIGHT_ALT" },
+ { GLFW_KEY_RIGHT_SUPER, "RIGHT_SUPER" },
+ { GLFW_KEY_MENU, "MENU" },
+};
+
+static const char* get_key_name(int keycode)
+{
+ for(const auto& it : key_names) {
+ if(it.first == keycode) {
+ return it.second;
+ }
+ }
+
+ return UNKNOWN_KEY_NAME;
+}
+
+config::KeyBind::KeyBind(void)
+{
+ m_glfw_keycode = GLFW_KEY_UNKNOWN;
+ m_name = UNKNOWN_KEY_NAME;
+}
+
+config::KeyBind::KeyBind(int default_value)
+{
+ if(default_value == DEBUG_KEY) {
+ m_glfw_keycode = GLFW_KEY_UNKNOWN;
+ m_name = UNKNOWN_KEY_NAME;
+ } else {
+ m_glfw_keycode = default_value;
+ m_name = get_key_name(default_value);
+ }
+}
+
+void config::KeyBind::set(const char* value)
+{
+ for(const auto& it : key_names) {
+ if((it.first != DEBUG_KEY) && !std::strcmp(it.second, value)) {
+ m_glfw_keycode = it.first;
+ m_name = it.second;
+ return;
+ }
+ }
+
+ m_glfw_keycode = GLFW_KEY_UNKNOWN;
+ m_name = UNKNOWN_KEY_NAME;
+}
+
+const char* config::KeyBind::get(void) const
+{
+ return m_name;
+}
+
+void config::KeyBind::set_key(int keycode)
+{
+ if(keycode == DEBUG_KEY) {
+ m_glfw_keycode = GLFW_KEY_UNKNOWN;
+ m_name = UNKNOWN_KEY_NAME;
+ } else {
+ m_glfw_keycode = keycode;
+ m_name = get_key_name(keycode);
+ }
+}
+
+int config::KeyBind::get_key(void) const
+{
+ return m_glfw_keycode;
+}
+
+bool config::KeyBind::equals(int keycode) const
+{
+ return m_glfw_keycode == keycode;
+}
diff --git a/game/client/config/keybind.hh b/game/client/config/keybind.hh
new file mode 100644
index 0000000..abfb97a
--- /dev/null
+++ b/game/client/config/keybind.hh
@@ -0,0 +1,29 @@
+#ifndef CLIENT_KEYBIND_HH
+#define CLIENT_KEYBIND_HH 1
+#pragma once
+
+#include "core/config/ivalue.hh"
+
+namespace config
+{
+class KeyBind final : public IValue {
+public:
+ explicit KeyBind(void);
+ explicit KeyBind(int default_value);
+ virtual ~KeyBind(void) = default;
+
+ virtual void set(const char* value) override;
+ virtual const char* get(void) const override;
+
+ void set_key(int keycode);
+ int get_key(void) const;
+
+ bool equals(int keycode) const;
+
+private:
+ const char* m_name;
+ int m_glfw_keycode;
+};
+} // namespace config
+
+#endif // CLIENT_KEYBIND_HH