diff --git a/doc/tutorial/07_input.cpp b/doc/tutorial/07_input.cpp index a791069d..e30f62db 100644 --- a/doc/tutorial/07_input.cpp +++ b/doc/tutorial/07_input.cpp @@ -76,7 +76,7 @@ public: m_autorot = !m_autorot; /* Handle joystick */ - auto joystick = InputDevice::Get(g_name_joystick(1).c_str()); + auto joystick = input::joystick(0); if ((bool)joystick) { if (lol::abs(joystick->axis(input::axis::LeftY)) > 0.2f) @@ -91,8 +91,8 @@ public: if (mouse->button(input::button::BTN_Left)) { mouse->capture(true); - m_pitch_angle -= mouse->axis(input::axis::MoveX) * seconds * 0.1f; - m_yaw_angle += mouse->axis(input::axis::MoveY) * seconds * 0.1f; + m_pitch_angle += mouse->axis(input::axis::MoveY) * seconds * 0.1f; + m_yaw_angle += mouse->axis(input::axis::MoveX) * seconds * 0.1f; } else { diff --git a/src/ui/d3d9-input.cpp b/src/ui/d3d9-input.cpp index 237197f9..9bb50e33 100644 --- a/src/ui/d3d9-input.cpp +++ b/src/ui/d3d9-input.cpp @@ -18,6 +18,8 @@ # include #endif +#include + #include #include "ui/d3d9-input.h" @@ -36,7 +38,7 @@ class D3d9InputData private: #if defined LOL_USE_XINPUT - array m_joysticks; + array> m_joysticks; #endif // LOL_USE_XINPUT }; @@ -53,8 +55,8 @@ D3d9Input::D3d9Input() XINPUT_STATE state; if (XInputGetState(i, &state) != ERROR_SUCCESS) continue; - // TODO: we can put more friendly name here, such as LeftAxisX, ButtonX... - InputDevice* stick = new InputDevice(g_name_joystick(i + 1)); + + auto stick = input::joystick(i); stick->internal_add_axis(input::axis::LeftX, "LeftX"); stick->internal_add_axis(input::axis::LeftY, "LeftY"); @@ -76,12 +78,9 @@ D3d9Input::D3d9Input() D3d9Input::~D3d9Input() { #if defined LOL_USE_XINPUT - /* Unregister all the joysticks we added */ + /* Unregister all the joysticks we added (FIXME: this code seems unnecessary) */ while (m_data->m_joysticks.count()) - { - delete m_data->m_joysticks[0].m2; m_data->m_joysticks.remove(0); - } #endif delete m_data; } diff --git a/src/ui/input.cpp b/src/ui/input.cpp index 5c3457ab..fa31f6a0 100644 --- a/src/ui/input.cpp +++ b/src/ui/input.cpp @@ -22,14 +22,6 @@ namespace lol { -const std::string g_name_mouse("mouse"); -const std::string g_name_keyboard("keyboard"); - -std::string g_name_joystick(const uint64_t num) -{ - return format("joystick%d", (int)num); -} - std::shared_ptr input::get() { static auto instance = new input(); @@ -40,13 +32,13 @@ std::shared_ptr input::get() input::input() { // Create default keyboard device - m_keyboard = std::make_shared(g_name_keyboard.c_str()); + m_keyboard = std::make_shared("default keyboard"); /* Register all scancodes known to SDL (from the USB standard) */ #define _SC(id, str, name) m_keyboard->internal_add_key(input::key::SC_##name, #name); #include "ui/keys.inc" // Create default mouse device - m_mouse = std::make_shared(g_name_mouse.c_str()); + m_mouse = std::make_shared("default mouse"); #define _BTN(id, name) m_mouse->internal_add_button(input::button::BTN_##name, #name); #include "ui/buttons.inc" // FIXME: this will also add joystick buttons! m_mouse->internal_add_axis(input::axis::X, "X"); @@ -58,6 +50,8 @@ input::input() m_mouse->internal_add_axis(input::axis::ScreenMoveX, "ScreenMoveX"); m_mouse->internal_add_axis(input::axis::ScreenMoveY, "ScreenMoveY"); m_mouse->internal_add_axis(input::axis::Wheel, "Wheel"); + + // FIXME: there are no default joysticks and they will all have zero axes by default } // Lookup tables for scancode and key name lookups @@ -97,26 +91,38 @@ input::key input::name_to_key(std::string const &name) return it == g_name_to_key.end() ? key::SC_Unknown : it->second; } -array InputDevice::devices; +std::shared_ptr input::joystick(int n) +{ + auto &joysticks = get()->m_joysticks; + + if (joysticks.find(n) == joysticks.end()) + joysticks[n] = std::make_shared(format("joystick %d", n)); + + return joysticks[n]; +} + +// +// input::device +// -std::string InputDevice::text() +std::string input::device::text() { std::string ret = m_text; m_text = ""; return ret; } -bool InputDevice::capture_text() +bool input::device::capture_text() { return m_input_active; } -void InputDevice::capture_text(bool status) +void input::device::capture_text(bool status) { m_input_active = status; } -void InputDevice::internal_add_key(input::key key, const char* name) +void input::device::internal_add_key(input::key key, const char* name) { while ((int)key >= (int)m_key_names.size()) { @@ -127,7 +133,7 @@ void InputDevice::internal_add_key(input::key key, const char* name) m_key_names[(int)key] = name; } -void InputDevice::internal_add_button(input::button button, const char* name) +void input::device::internal_add_button(input::button button, const char* name) { while ((int)button >= (int)m_button_names.size()) { @@ -138,7 +144,7 @@ void InputDevice::internal_add_button(input::button button, const char* name) m_button_names[(int)button] = name; } -void InputDevice::internal_add_axis(input::axis axis, const char* name) +void input::device::internal_add_axis(input::axis axis, const char* name) { while ((int)axis >= (int)m_axis_names.size()) { diff --git a/src/ui/input.h b/src/ui/input.h index efd147b0..5f5237ee 100644 --- a/src/ui/input.h +++ b/src/ui/input.h @@ -21,22 +21,9 @@ namespace lol { -extern const std::string g_name_mouse; -extern const std::string g_name_keyboard; -extern std::string g_name_joystick(const uint64_t num); - class input { public: - static std::shared_ptr get(); - - // Default devices - - static std::shared_ptr keyboard() { return get()->m_keyboard; } - static std::shared_ptr mouse() { return get()->m_mouse; } - - // Keyboard API - enum class key : uint16_t { #define _SC(id, str, name) SC_##name = id, @@ -70,226 +57,210 @@ public: RightShoulder, }; - static std::vector const &all_keys(); - static std::string const &key_to_name(key k); - static key name_to_key(std::string const &name); - - // Joystick API - -private: - input(); - - std::shared_ptr m_keyboard; - std::shared_ptr m_mouse; -}; - -class InputDevice -{ -public: - InputDevice(std::string const &name) - : m_name(name), - m_input_active(false) + class device { - devices.push_unique(this); - } + public: + device(std::string const &name) : m_name(name) {} - ~InputDevice() - { - for (int i = 0; i < devices.count(); ++i) + class mouse; + class keyboard; + class joystick; + + /** Gets the name of this input device */ + const std::string& GetName() const { - if (devices[i] == this) - { - devices.remove(i); - return; - } + return m_name; } - } - /** Gets the name of this input device */ - const std::string& GetName() const - { - return m_name; - } + // + // Bindings section + // - /** Gets the index of the corresponding key, needed to call GetKey */ - int GetKeyIndex(std::string const &name) const - { - return GetItemIndex(name, m_key_names); - } + void bind(input::key key, uint16_t event); + void unbind(input::key key, uint16_t event); - /** Gets the index of the corresponding axis, needed to call GetAxis */ - int GetAxisIndex(std::string const &name) const - { - return GetItemIndex(name, m_axis_names); - } + void bind(input::button button, uint16_t event); + void unbind(input::button button, uint16_t event); - // - // Bindings section - // + void bind(input::axis axis, uint16_t event); + void unbind(input::axis axis, uint16_t event); - void bind(input::key key, uint16_t event); - void unbind(input::key key, uint16_t event); + // + // Key, button etc. state + // - void bind(input::button button, uint16_t event); - void unbind(input::button button, uint16_t event); + // Get the current state of the given key + bool key(input::key key) const + { + return (size_t)key >= m_keys.size() ? false : m_keys[(int)key]; + } - void bind(input::axis axis, uint16_t event); - void unbind(input::axis axis, uint16_t event); + bool key_released(input::key key) const + { + return m_released_keys.find(key) != m_released_keys.end(); + } - // - // Key, button etc. state - // + bool key_pressed(input::key key) const + { + return m_pressed_keys.find(key) != m_pressed_keys.end(); + } - // Get the current state of the given key - bool key(input::key key) const { return m_keys[(int)key]; } + // Get the current state of the given button + bool button(input::button button) const + { + return (size_t)button >= m_buttons.size() ? false : m_buttons[(int)button]; + } - bool key_released(input::key key) const - { - return m_released_keys.find(key) != m_released_keys.end(); - } + bool button_released(input::button button) const + { + return m_released_buttons.find(button) != m_released_buttons.end(); + } - bool key_pressed(input::key key) const - { - return m_pressed_keys.find(key) != m_pressed_keys.end(); - } + bool button_pressed(input::button button) const + { + return m_pressed_buttons.find(button) != m_pressed_buttons.end(); + } - // Get the current state of the given button - bool button(input::button button) const { return m_buttons[(int)button]; } + // Get the current state of the given axis + float axis(input::axis axis) const + { + return (size_t)axis >= m_axes.size() ? 0.0f : m_axes[(int)axis]; + } - bool button_released(input::button button) const - { - return m_released_buttons.find(button) != m_released_buttons.end(); - } + bool axis_changed(input::axis axis) const + { + return m_changed_axes.find(axis) != m_changed_axes.end(); + } - bool button_pressed(input::button button) const - { - return m_pressed_buttons.find(button) != m_pressed_buttons.end(); - } + // TODO: axis sensitivity was removed - // Get the current state of the given axis - float axis(input::axis axis) const { return m_axes[(int)axis]; } + // + // Keyboard-specific section + // - bool axis_changed(input::axis axis) const - { - return m_changed_axes.find(axis) != m_changed_axes.end(); - } + /** Get the names of all available keys on this device */ + std::vector const& key_names() const { return m_key_names; } - // TODO: axis sensitivity was removed + /** Get the current state of all keys */ + std::vector const &keys() const { return m_keys; } - // - // Keyboard-specific section - // + /** Gets the latest contents of text input. */ + std::string text(); - /** Get the names of all available keys on this device */ - std::vector const& key_names() const { return m_key_names; } + bool capture_text(); + void capture_text(bool status); - /** Get the current state of all keys */ - std::vector const &keys() const { return m_keys; } + // + // Mouse-specific section + // - /** Gets the latest contents of text input. */ - std::string text(); + // Gets and sets whether the mouse cursor should be captured. + void capture(bool value) { m_capture = value; } + bool capture() const { return m_capture; } - bool capture_text(); - void capture_text(bool status); + public: + /** Internal functions that allow to construct an input device + * dynamically, when the keys, axis and cursors are not known at + * compile time. */ + void internal_add_key(input::key, char const *name); + void internal_add_button(input::button, char const *name); + void internal_add_axis(input::axis, char const *name); - // - // Mouse-specific section - // + /* Internal functions for the platform-specific drivers. */ + void internal_begin_frame() + { + m_pressed_keys.clear(); + m_released_keys.clear(); + m_pressed_buttons.clear(); + m_released_buttons.clear(); + m_changed_axes.clear(); + } - // Gets and sets whether the mouse cursor should be captured. - void capture(bool value) { m_capture = value; } - bool capture() const { return m_capture; } + void internal_set_key(input::key key, bool state) + { + if (m_keys[(int)key] != state) + (state ? m_pressed_keys : m_released_keys).insert(key); + m_keys[(int)key] = state; + } - /** Gets an input device by its name */ - static InputDevice* Get(std::string const &name) - { - for (int i = 0; i < devices.count(); ++i) + void internal_set_button(input::button button, bool state) { - if (devices[i]->m_name == name) - return devices[i]; + if (m_buttons[(int)button] != state) + (state ? m_pressed_buttons : m_released_buttons).insert(button); + m_buttons[(int)button] = state; } - return nullptr; - } -public: - /** Internal functions that allow to construct an InputDevice - * dynamically, when the keys, axis and cursors are not known at - * compile time. */ - void internal_add_key(input::key, char const *name); - void internal_add_button(input::button, char const *name); - void internal_add_axis(input::axis, char const *name); - - /* Internal functions for the platform-specific drivers. */ - void internal_begin_frame() - { - m_pressed_keys.clear(); - m_released_keys.clear(); - m_pressed_buttons.clear(); - m_released_buttons.clear(); - m_changed_axes.clear(); - } - - void internal_set_key(input::key key, bool state) - { - if (m_keys[(int)key] != state) - (state ? m_pressed_keys : m_released_keys).insert(key); - m_keys[(int)key] = state; - } + void internal_set_axis(input::axis axis, float value) + { + if (m_axes[(int)axis] != value) + m_changed_axes.insert(axis); + m_axes[(int)axis] = value; + } - void internal_set_button(input::button button, bool state) - { - if (m_buttons[(int)button] != state) - (state ? m_pressed_buttons : m_released_buttons).insert(button); - m_buttons[(int)button] = state; - } + void internal_add_text(std::string const &text) + { + m_text += text; + } - void internal_set_axis(input::axis axis, float value) - { - if (m_axes[(int)axis] != value) - m_changed_axes.insert(axis); - m_axes[(int)axis] = value; - } + protected: + std::string m_name; - void internal_add_text(std::string const &text) - { - m_text += text; - } + std::vector m_key_names; + std::vector m_button_names; + std::vector m_axis_names; -protected: - // TODO: hide all of this in a InputDeviceData? + /** Key and button states (pressed/released) */ + std::vector m_keys; + std::unordered_set m_pressed_keys, m_released_keys; + std::vector m_buttons; + std::unordered_set m_pressed_buttons, m_released_buttons; + std::vector m_axes; + std::unordered_set m_changed_axes; - std::string m_name; + // Text input state + std::string m_text; + bool m_input_active = false; - std::vector m_key_names; - std::vector m_button_names; - std::vector m_axis_names; + // Capture (for mouse devices) + bool m_capture = false; + }; - /** Key and button states (pressed/released) */ - std::vector m_keys; - std::unordered_set m_pressed_keys, m_released_keys; - std::vector m_buttons; - std::unordered_set m_pressed_buttons, m_released_buttons; - std::vector m_axes; - std::unordered_set m_changed_axes; + // Default devices - // Text input state - std::string m_text; - bool m_input_active; + static std::shared_ptr keyboard() { return get()->m_keyboard; } + static std::shared_ptr mouse() { return get()->m_mouse; } + static std::shared_ptr joystick(int n); - // Capture (for mouse devices) - bool m_capture = false; + static std::vector const &all_keys(); + static std::string const &key_to_name(key k); + static key name_to_key(std::string const &name); private: - static array devices; + input(); - template - int GetItemIndex(std::string const &name, std::vector const& a) const - { - for (size_t i = 0; i < a.size(); ++i) - if (a[i] == name) - return (int)i; - return -1; - } + static std::shared_ptr get(); + + std::shared_ptr m_keyboard; + std::shared_ptr m_mouse; + std::map> m_joysticks; +}; + +class input::device::mouse : public input::device +{ +public: + mouse(std::string const &name) : input::device(name) {} +}; + +class input::device::keyboard : public input::device +{ +public: + keyboard(std::string const &name) : input::device(name) {} +}; + +class input::device::joystick : public input::device +{ +public: + joystick(std::string const &name) : input::device(name) {} }; } /* namespace lol */ diff --git a/src/ui/sdl-input.cpp b/src/ui/sdl-input.cpp index 0cd9e6d4..9f52608f 100644 --- a/src/ui/sdl-input.cpp +++ b/src/ui/sdl-input.cpp @@ -83,7 +83,7 @@ SdlInput::SdlInput(int app_w, int app_h, int screen_w, int screen_h) continue; } - InputDevice* stick = new InputDevice(g_name_joystick(i + 1)); + auto stick = input::joystick(i); for (int j = 0; j < SDL_JoystickNumAxes(sdlstick); ++j) stick->internal_add_axis((input::axis)(j + 1), format("Axis%d", j + 1).c_str()); for (int j = 0; j < SDL_JoystickNumButtons(sdlstick); ++j) @@ -103,7 +103,6 @@ SdlInput::~SdlInput() while (m_joysticks.count()) { SDL_JoystickClose(m_joysticks[0].m1); - delete m_joysticks[0].m2; m_joysticks.remove(0); } #endif diff --git a/src/ui/sdl-input.h b/src/ui/sdl-input.h index bb08de19..8bd72740 100644 --- a/src/ui/sdl-input.h +++ b/src/ui/sdl-input.h @@ -27,6 +27,8 @@ # endif #endif +#include + namespace lol { @@ -46,7 +48,7 @@ protected: private: void tick(float seconds); - array m_joysticks; + array> m_joysticks; vec2 m_app; vec2 m_screen;