| @@ -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 \ | |||
| \ | |||
| @@ -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) | |||
| @@ -291,7 +291,6 @@ | |||
| <ClInclude Include="ui\d3d9-input.h" /> | |||
| <ClInclude Include="ui\gui.h" /> | |||
| <ClInclude Include="ui\input.h" /> | |||
| <ClInclude Include="ui\input_internal.h" /> | |||
| <ClInclude Include="ui\keys.inc" /> | |||
| <ClInclude Include="ui\sdl-input.h"> | |||
| <ExcludedFromBuild Condition="'$(enable_sdl)'=='no'">true</ExcludedFromBuild> | |||
| @@ -683,9 +683,6 @@ | |||
| <ClInclude Include="ui\controller.h"> | |||
| <Filter>ui</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="ui\input_internal.h"> | |||
| <Filter>ui</Filter> | |||
| </ClInclude> | |||
| <ClInclude Include="utils.h"> | |||
| <Filter>...</Filter> | |||
| </ClInclude> | |||
| @@ -21,7 +21,7 @@ | |||
| #include <lol/engine-internal.h> | |||
| #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<int, InputDeviceInternal*> m_joysticks; | |||
| array<int, InputDevice*> 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()); | |||
| @@ -15,12 +15,20 @@ | |||
| #include <string> | |||
| #include <map> | |||
| #include <memory> | |||
| #include "ui/input_internal.h" | |||
| #include "ui/input.h" | |||
| namespace lol | |||
| { | |||
| std::shared_ptr<input> input::get() | |||
| { | |||
| static auto instance = new input(); | |||
| static auto shared_instance = std::shared_ptr<input>(instance); | |||
| return shared_instance; | |||
| } | |||
| // Lookup tables for scancode and key name lookups | |||
| static std::vector<input::key> g_all_keys | |||
| { | |||
| @@ -47,8 +55,9 @@ std::vector<input::key> 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*> InputDevice::devices; | |||
| int InputDevice::joystick_count = 0; | |||
| bool InputDevice::m_capturemouse; | |||
| array<std::string> 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()); | |||
| @@ -15,6 +15,7 @@ | |||
| #include <string> | |||
| #include <vector> | |||
| #include <memory> | |||
| namespace lol | |||
| { | |||
| @@ -22,6 +23,10 @@ namespace lol | |||
| class input | |||
| { | |||
| public: | |||
| static std::shared_ptr<input> get(); | |||
| // Keyboard API | |||
| enum class key : uint16_t | |||
| { | |||
| #define _SC(id, str, name) SC_##name = id, | |||
| @@ -31,6 +36,24 @@ public: | |||
| static std::vector<key> 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<vec2, ivec2> 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<InputDevice*> devices; | |||
| static int joystick_count; | |||
| template <typename... T> | |||
| size_t GetItemIndex(std::string const &name, std::vector<std::string, T...> 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) | |||
| @@ -1,87 +0,0 @@ | |||
| // | |||
| // Lol Engine | |||
| // | |||
| // Copyright © 2017—2019 Sam Hocevar <sam@hocevar.net> | |||
| // © 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 <string> | |||
| 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 */ | |||
| @@ -23,8 +23,8 @@ | |||
| # include <emscripten/html5.h> | |||
| #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); | |||
| @@ -46,9 +46,9 @@ protected: | |||
| private: | |||
| void tick(float seconds); | |||
| array<SDL_Joystick *, class InputDeviceInternal *> m_joysticks; | |||
| InputDeviceInternal *m_mouse = nullptr; | |||
| InputDeviceInternal *m_keyboard = nullptr; | |||
| array<SDL_Joystick *, class InputDevice *> m_joysticks; | |||
| InputDevice *m_mouse = nullptr; | |||
| InputDevice *m_keyboard = nullptr; | |||
| ivec2 m_prevmouse = ivec2::zero; | |||
| vec2 m_app; | |||