diff --git a/src/Makefile.am b/src/Makefile.am index 11abaff3..75dc7f01 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -101,7 +101,7 @@ liblol_core_sources = \ \ audio/audio.cpp audio/sample.cpp \ \ - ui/input.cpp ui/input.h ui/input_internal.h ui/keys.inc \ + ui/input.cpp ui/input.h ui/keys.inc \ ui/controller.cpp ui/controller.h \ ui/gui.cpp ui/gui.h \ \ diff --git a/src/application/android-app.cpp b/src/application/android-app.cpp index e34d4c1c..4294734f 100644 --- a/src/application/android-app.cpp +++ b/src/application/android-app.cpp @@ -28,7 +28,7 @@ extern "C" { } #include "application/android-app.h" -#include "ui/input_internal.h" +#include "ui/input.h" using namespace lol; @@ -84,7 +84,7 @@ public: /* FIXME: we need proper unproject or at least screen space events!! */ ivec2 m_wanted_resolution; - InputDeviceInternal* m_mouse; + InputDevice* m_mouse; SavedState m_state; @@ -344,7 +344,7 @@ lol::AndroidApp::AndroidApp(char const *title, ivec2 res, float fps) Ticker::Setup(fps); m_data->m_wanted_resolution = res; - m_data->m_mouse = InputDeviceInternal::CreateStandardMouse(); + m_data->m_mouse = InputDevice::CreateStandardMouse(); } void lol::AndroidApp::ShowPointer(bool show) diff --git a/src/lol-core.vcxproj b/src/lol-core.vcxproj index ce8f5a2d..9ffe1715 100644 --- a/src/lol-core.vcxproj +++ b/src/lol-core.vcxproj @@ -291,7 +291,6 @@ - true diff --git a/src/lol-core.vcxproj.filter b/src/lol-core.vcxproj.filter index 9e368cb1..60672514 100644 --- a/src/lol-core.vcxproj.filter +++ b/src/lol-core.vcxproj.filter @@ -683,9 +683,6 @@ ui - - ui - ... diff --git a/src/ui/d3d9-input.cpp b/src/ui/d3d9-input.cpp index 22cd4f1f..67d9986d 100644 --- a/src/ui/d3d9-input.cpp +++ b/src/ui/d3d9-input.cpp @@ -21,7 +21,7 @@ #include #include "ui/d3d9-input.h" -#include "ui/input_internal.h" +#include "ui/input.h" namespace lol { @@ -57,7 +57,7 @@ class D3d9InputData private: #if defined LOL_USE_XINPUT - array m_joysticks; + array m_joysticks; #endif // LOL_USE_XINPUT }; @@ -75,7 +75,7 @@ D3d9Input::D3d9Input() if (XInputGetState(i, &state) != ERROR_SUCCESS) continue; // TODO: we can put more friendly name here, such as LeftAxisX, ButtonX... - InputDeviceInternal* stick = new InputDeviceInternal(g_name_joystick(i + 1)); + InputDevice* stick = new InputDevice(g_name_joystick(i + 1)); stick->AddAxis(g_name_xbox_axis_left_x.c_str()); stick->AddAxis(g_name_xbox_axis_left_y.c_str()); diff --git a/src/ui/input.cpp b/src/ui/input.cpp index efda2996..b05d230c 100644 --- a/src/ui/input.cpp +++ b/src/ui/input.cpp @@ -15,12 +15,20 @@ #include #include +#include -#include "ui/input_internal.h" +#include "ui/input.h" namespace lol { +std::shared_ptr input::get() +{ + static auto instance = new input(); + static auto shared_instance = std::shared_ptr(instance); + return shared_instance; +} + // Lookup tables for scancode and key name lookups static std::vector g_all_keys { @@ -47,8 +55,9 @@ std::vector const &input::all_keys() std::string const &input::key_to_name(input::key k) { + static std::string unknown("Unknown"); auto it = g_key_to_name.find(k); - return it == g_key_to_name.end() ? "Unknown" : it->second; + return it == g_key_to_name.end() ? unknown : it->second; } input::key input::name_to_key(std::string const &name) @@ -58,8 +67,6 @@ input::key input::name_to_key(std::string const &name) } array InputDevice::devices; -int InputDevice::joystick_count = 0; -bool InputDevice::m_capturemouse; array InputDevice::GetAvailableDevices() { @@ -86,7 +93,7 @@ void InputDevice::SetTextInputActive(bool status) m_input_active = status; } -void InputDeviceInternal::AddKey(int index, const char* name) +void InputDevice::AddKey(int index, const char* name) { if (index == -1) index = (int)m_key_names.size(); @@ -100,7 +107,7 @@ void InputDeviceInternal::AddKey(int index, const char* name) m_key_names[index] = name; } -void InputDeviceInternal::AddAxis(int index, const char* name, float sensitivity) +void InputDevice::AddAxis(int index, const char* name, float sensitivity) { if (index == -1) index = (int)m_axis_names.size(); @@ -116,7 +123,7 @@ void InputDeviceInternal::AddAxis(int index, const char* name, float sensitivity m_axis[index].m2 = sensitivity; } -void InputDeviceInternal::AddCursor(int index, const char* name) +void InputDevice::AddCursor(int index, const char* name) { if (index == -1) index = (int)m_cursor_names.size(); @@ -130,9 +137,9 @@ void InputDeviceInternal::AddCursor(int index, const char* name) m_cursor_names[index] = name; } -InputDeviceInternal* InputDeviceInternal::CreateStandardKeyboard() +InputDevice* InputDevice::CreateStandardKeyboard() { - InputDeviceInternal* keyboard = new InputDeviceInternal(g_name_keyboard.c_str()); + InputDevice* keyboard = new InputDevice(g_name_keyboard.c_str()); /* Register all scancodes known to SDL (from the USB standard) */ # define _SC(id, str, name) keyboard->AddKey(id, #name); @@ -141,9 +148,9 @@ InputDeviceInternal* InputDeviceInternal::CreateStandardKeyboard() return keyboard; } -InputDeviceInternal* InputDeviceInternal::CreateStandardMouse() +InputDevice* InputDevice::CreateStandardMouse() { - InputDeviceInternal* mouse = new InputDeviceInternal(g_name_mouse.c_str()); + InputDevice* mouse = new InputDevice(g_name_mouse.c_str()); mouse->AddKey(g_name_mouse_key_left.c_str()); mouse->AddKey(g_name_mouse_key_middle.c_str()); mouse->AddKey(g_name_mouse_key_right.c_str()); diff --git a/src/ui/input.h b/src/ui/input.h index 13ac67dc..d4bee918 100644 --- a/src/ui/input.h +++ b/src/ui/input.h @@ -15,6 +15,7 @@ #include #include +#include namespace lol { @@ -22,6 +23,10 @@ namespace lol class input { public: + static std::shared_ptr get(); + + // Keyboard API + enum class key : uint16_t { #define _SC(id, str, name) SC_##name = id, @@ -31,6 +36,24 @@ public: static std::vector const &all_keys(); static std::string const &key_to_name(key k); static key name_to_key(std::string const &name); + + // Internal keyboard API (TODO: move to input device class?) + + void internal_set_key(key k, bool state); + void internal_add_text(std::string const &text); + + // Mouse API + + /** Gets and sets whether the mouse cursor should be captured. */ + void mouse_capture(bool value) { m_mouse_capture = value; } + bool mouse_capture() const { return m_mouse_capture; } + + // Joystick API + +private: + input() = default; + + bool m_mouse_capture = false; }; const std::string g_name_mouse("Mouse"); @@ -57,6 +80,25 @@ const std::string g_name_mouse_cursor("Cursor"); class InputDevice { public: + InputDevice(std::string const &name) + : m_name(name), + m_input_active(false) + { + devices.push_unique(this); + } + + ~InputDevice() + { + for (int i = 0; i < devices.count(); ++i) + { + if (devices[i] == this) + { + devices.remove(i); + return; + } + } + } + /** Gets the name of this input device */ const std::string& GetName() const { @@ -162,21 +204,66 @@ public: { return GetDevice(g_name_mouse); } - static int GetJoystickCount() - { - return joystick_count; - } static InputDevice* GetJoystick(const uint64_t num) { return GetDevice(g_name_joystick(num)); } - /** Sets whether the mouse cursor should be captured. */ - static void CaptureMouse(bool activated) +public: + /** Internal functions that allow to construct an InputDevice + * dynamically, when the keys, axis and cursors are not known at + * compile time. */ + void AddKey(int id, char const * name); + + inline void AddKey(char const * name) + { + AddKey(-1, name); + } + + void AddAxis(int id, char const * name, float sensitivity = 1.0f); + + inline void AddAxis(char const * name, float sensitivity = 1.0f) + { + AddAxis(-1, name, sensitivity); + } + + void AddCursor(int id, char const * name); + + inline void AddCursor(char const * name) + { + AddCursor(-1, name); + } + + void SetCursor(int id, vec2 const & position, ivec2 const & pixel) + { + m_cursors[id].m1 = position; + m_cursors[id].m2 = pixel; + } + + ivec2 GetCursorPixelPos(int id) + { + return m_cursors[id].m2; + } + + /* Internal functions for the platform-specific drivers. */ + void internal_set_key(int id, bool state) + { + m_keys[id] = state; + } + + void internal_add_text(std::string const &text) + { + m_text += text; + } + + void internal_set_axis(int id, float value) { - m_capturemouse = activated; + m_axis[id].m1 = value; } + static InputDevice* CreateStandardKeyboard(); + static InputDevice* CreateStandardMouse(); + protected: // TODO: hide all of this in a InputDeviceData? @@ -199,30 +286,8 @@ protected: /** Cursor position */ array m_cursors; - static bool m_capturemouse; - - InputDevice(std::string const &name) - : m_name(name), - m_input_active(false) - { - devices.push_unique(this); - } - - ~InputDevice() - { - for (int i = 0; i < devices.count(); ++i) - { - if (devices[i] == this) - { - devices.remove(i); - return; - } - } - } - private: static array devices; - static int joystick_count; template size_t GetItemIndex(std::string const &name, std::vector const& a) const @@ -235,10 +300,6 @@ private: static InputDevice* GetDevice(std::string const &name) { - //Count the device types. TODO: Multi mouse/keyboard - if (name.find(g_name_joystick()) != std::string::npos) - ++joystick_count; - for (int i = 0; i < devices.count(); ++i) { if (devices[i]->m_name == name) diff --git a/src/ui/input_internal.h b/src/ui/input_internal.h deleted file mode 100644 index d641ed7d..00000000 --- a/src/ui/input_internal.h +++ /dev/null @@ -1,87 +0,0 @@ -// -// Lol Engine -// -// Copyright © 2017—2019 Sam Hocevar -// © 2010—2015 Benjamin Litzelmann -// -// Lol Engine is free software. It comes without any warranty, to -// the extent permitted by applicable law. You can redistribute it -// and/or modify it under the terms of the Do What the Fuck You Want -// to Public License, Version 2, as published by the WTFPL Task Force. -// See http://www.wtfpl.net/ for more details. -// - -#pragma once - -#include - -namespace lol -{ - -/** Internal class (not public) that allows to construct an InputDevice - * dynamically, when the keys, axis and cursors are not known at - * compile time. */ -class InputDeviceInternal : public InputDevice -{ -public: - inline InputDeviceInternal(std::string const& name) : InputDevice(name) { } - - void AddKey(int id, char const * name); - - inline void AddKey(char const * name) - { - AddKey(-1, name); - } - - void AddAxis(int id, char const * name, float sensitivity = 1.0f); - - inline void AddAxis(char const * name, float sensitivity = 1.0f) - { - AddAxis(-1, name, sensitivity); - } - - void AddCursor(int id, char const * name); - - inline void AddCursor(char const * name) - { - AddCursor(-1, name); - } - - void SetCursor(int id, vec2 const & position, ivec2 const & pixel) - { - m_cursors[id].m1 = position; - m_cursors[id].m2 = pixel; - } - - ivec2 GetCursorPixelPos(int id) - { - return m_cursors[id].m2; - } - - /* Internal functions for the platform-specific drivers. */ - void internal_set_key(int id, bool state) - { - m_keys[id] = state; - } - - void internal_add_text(std::string const &text) - { - m_text += text; - } - - void internal_set_axis(int id, float value) - { - m_axis[id].m1 = value; - } - - static bool GetMouseCapture() - { - return m_capturemouse; - } - - static InputDeviceInternal* CreateStandardKeyboard(); - static InputDeviceInternal* CreateStandardMouse(); -}; - -} /* namespace lol */ - diff --git a/src/ui/sdl-input.cpp b/src/ui/sdl-input.cpp index 290d628c..c4e84f52 100644 --- a/src/ui/sdl-input.cpp +++ b/src/ui/sdl-input.cpp @@ -23,8 +23,8 @@ # include #endif -#include "ui/input_internal.h" #include "ui/sdl-input.h" +#include "ui/input.h" /* We force joystick polling because no events are received when * there is no SDL display (eg. on the Raspberry Pi). */ @@ -89,8 +89,8 @@ SdlInput::SdlInput(int app_w, int app_h, int screen_w, int screen_h) SDL_Init(SDL_INIT_TIMER | SDL_INIT_JOYSTICK); #endif - m_keyboard = InputDeviceInternal::CreateStandardKeyboard(); - m_mouse = InputDeviceInternal::CreateStandardMouse(); + m_keyboard = InputDevice::CreateStandardKeyboard(); + m_mouse = InputDevice::CreateStandardMouse(); // XXX: another option for emscripten is to properly support gamepads #if LOL_USE_SDL && !__EMSCRIPTEN__ @@ -118,7 +118,7 @@ SdlInput::SdlInput(int app_w, int app_h, int screen_w, int screen_h) } //format("Joystick%d", i + 1).c_str() - InputDeviceInternal* stick = new InputDeviceInternal(g_name_joystick(i + 1)); + InputDevice* stick = new InputDevice(g_name_joystick(i + 1)); for (int j = 0; j < SDL_JoystickNumAxes(sdlstick); ++j) stick->AddAxis(format("Axis%d", j + 1).c_str()); for (int j = 0; j < SDL_JoystickNumButtons(sdlstick); ++j) @@ -283,9 +283,9 @@ void SdlInput::tick(float seconds) SDL_GetMouseState(&mouse.x, &mouse.y); mouse.y = Video::GetSize().y - 1 - mouse.y; - if (InputDeviceInternal::GetMouseCapture() != m_mousecapture) + if (input::get()->mouse_capture() != m_mousecapture) { - m_mousecapture = InputDeviceInternal::GetMouseCapture(); + m_mousecapture = input::get()->mouse_capture(); SDL_SetRelativeMouseMode(m_mousecapture ? SDL_TRUE : SDL_FALSE); mouse = ivec2(m_app * .5f); diff --git a/src/ui/sdl-input.h b/src/ui/sdl-input.h index f532bf87..ede04158 100644 --- a/src/ui/sdl-input.h +++ b/src/ui/sdl-input.h @@ -46,9 +46,9 @@ protected: private: void tick(float seconds); - array m_joysticks; - InputDeviceInternal *m_mouse = nullptr; - InputDeviceInternal *m_keyboard = nullptr; + array m_joysticks; + InputDevice *m_mouse = nullptr; + InputDevice *m_keyboard = nullptr; ivec2 m_prevmouse = ivec2::zero; vec2 m_app;