@@ -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; | |||