@@ -31,23 +31,22 @@ public: | |||||
# ifdef OLD_SCHOOL | # ifdef OLD_SCHOOL | ||||
m_controller->SetInputCount(KEY_MAX, AXIS_MAX); | m_controller->SetInputCount(KEY_MAX, AXIS_MAX); | ||||
m_keyboard = InputDevice::Get("Keyboard"); | |||||
if (m_keyboard) | |||||
m_controller->GetKey(KEY_MANUAL_ROTATION).Bind("Keyboard", "Space"); | |||||
auto keyboard = input::get()->keyboard(); | |||||
m_controller->GetKey(KEY_MANUAL_ROTATION).Bind(g_name_keyboard, "Space"); | |||||
m_mouse = InputDevice::Get("Mouse"); | |||||
if (m_mouse) | |||||
auto mouse = input::get()->mouse(); | |||||
if (mouse) | |||||
{ | { | ||||
m_controller->GetKey(KEY_DRAG_MESH).Bind("Mouse", "Left"); | |||||
m_controller->GetAxis(AXIS_DRAG_PITCH).Bind("Mouse", "Y"); | |||||
m_controller->GetAxis(AXIS_DRAG_YAW).Bind("Mouse", "X"); | |||||
m_controller->GetKey(KEY_DRAG_MESH).Bind(g_name_mouse, "Left"); | |||||
m_controller->GetAxis(AXIS_DRAG_PITCH).Bind(g_name_mouse, "Y"); | |||||
m_controller->GetAxis(AXIS_DRAG_YAW).Bind(g_name_mouse, "X"); | |||||
} | } | ||||
m_joystick = InputDevice::Get("Joystick1"); | |||||
m_joystick = InputDevice::Get(g_name_joystick(1)); | |||||
if (m_joystick) | if (m_joystick) | ||||
{ | { | ||||
m_controller->GetAxis(AXIS_PITCH).Bind("Joystick1", "Axis2"); | |||||
m_controller->GetAxis(AXIS_YAW).Bind("Joystick1", "Axis1"); | |||||
m_controller->GetAxis(AXIS_PITCH).Bind(g_name_joystick(1), "Axis2"); | |||||
m_controller->GetAxis(AXIS_YAW).Bind(g_name_joystick(1), "Axis1"); | |||||
} | } | ||||
# else | # else | ||||
m_profile | m_profile | ||||
@@ -59,8 +58,6 @@ public: | |||||
<< InputProfile::MouseAxis(AXIS_DRAG_YAW, "X"); | << InputProfile::MouseAxis(AXIS_DRAG_YAW, "X"); | ||||
m_controller->Init(m_profile); | m_controller->Init(m_profile); | ||||
m_keyboard = InputDevice::GetKeyboard(); | |||||
m_mouse = InputDevice::GetMouse(); | |||||
m_joystick = InputDevice::GetJoystick(1); | m_joystick = InputDevice::GetJoystick(1); | ||||
# endif //OLD_SCHOOL | # endif //OLD_SCHOOL | ||||
@@ -107,11 +104,8 @@ public: | |||||
WorldEntity::tick_game(seconds); | WorldEntity::tick_game(seconds); | ||||
/* Handle keyboard */ | /* Handle keyboard */ | ||||
if (m_keyboard) | |||||
{ | |||||
if (m_controller->WasKeyPressedThisFrame(KEY_MANUAL_ROTATION)) | |||||
m_autorot = !m_autorot; | |||||
} | |||||
if (m_controller->WasKeyPressedThisFrame(KEY_MANUAL_ROTATION)) | |||||
m_autorot = !m_autorot; | |||||
/* Handle joystick */ | /* Handle joystick */ | ||||
if (m_joystick) | if (m_joystick) | ||||
@@ -123,7 +117,7 @@ public: | |||||
} | } | ||||
/* Handle mouse */ | /* Handle mouse */ | ||||
if (m_mouse) | |||||
if (true) | |||||
{ | { | ||||
if (m_controller->IsKeyPressed(KEY_DRAG_MESH)) | if (m_controller->IsKeyPressed(KEY_DRAG_MESH)) | ||||
{ | { | ||||
@@ -138,10 +132,11 @@ public: | |||||
m_yaw_angle += seconds * 0.2f; | m_yaw_angle += seconds * 0.2f; | ||||
} | } | ||||
auto mouse = input::get()->mouse(); | |||||
m_text->SetText(lol::format( | m_text->SetText(lol::format( | ||||
"cursor: (%0.3f, %0.3f) - pixel (%d, %d)", | "cursor: (%0.3f, %0.3f) - pixel (%d, %d)", | ||||
m_mouse->GetCursor(0).x, m_mouse->GetCursor(0).y, | |||||
m_mouse->GetCursorPixel(0).x, m_mouse->GetCursorPixel(0).y)); | |||||
mouse->GetCursor(0).x, mouse->GetCursor(0).y, | |||||
mouse->GetCursorPixel(0).x, mouse->GetCursorPixel(0).y)); | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
@@ -227,7 +222,7 @@ private: | |||||
AXIS_MAX | AXIS_MAX | ||||
}; | }; | ||||
InputDevice *m_keyboard, *m_mouse, *m_joystick; | |||||
InputDevice *m_joystick; | |||||
Controller *m_controller; | Controller *m_controller; | ||||
InputProfile m_profile; | InputProfile m_profile; | ||||
@@ -32,7 +32,6 @@ public: | |||||
m_profile << InputProfile::KeyboardKey(0, "Space") | m_profile << InputProfile::KeyboardKey(0, "Space") | ||||
<< InputProfile::MouseKey(1, "Left"); | << InputProfile::MouseKey(1, "Left"); | ||||
m_controller->Init(m_profile); | m_controller->Init(m_profile); | ||||
m_mouse = InputDevice::GetMouse(); | |||||
m_text = new Text("SPACE for sine wave, Left Click for white noise", | m_text = new Text("SPACE for sine wave, Left Click for white noise", | ||||
"data/font/ascii.png"); | "data/font/ascii.png"); | ||||
@@ -94,7 +93,6 @@ public: | |||||
private: | private: | ||||
int m_streams[2]; | int m_streams[2]; | ||||
InputDevice *m_mouse; | |||||
Controller *m_controller; | Controller *m_controller; | ||||
InputProfile m_profile; | InputProfile m_profile; | ||||
@@ -48,7 +48,6 @@ public: | |||||
<< InputProfile::MouseKey(2, "Middle") | << InputProfile::MouseKey(2, "Middle") | ||||
<< InputProfile::KeyboardKey(3, "Space"); | << InputProfile::KeyboardKey(3, "Space"); | ||||
m_controller->Init(m_profile); | m_controller->Init(m_profile); | ||||
m_mouse = InputDevice::GetMouse(); | |||||
/* Window size decides the world aspect ratio. For instance, 640×480 | /* Window size decides the world aspect ratio. For instance, 640×480 | ||||
* will be mapped to (-0.66,-0.5) - (0.66,0.5). */ | * will be mapped to (-0.66,-0.5) - (0.66,0.5). */ | ||||
@@ -158,7 +157,7 @@ public: | |||||
{ | { | ||||
WorldEntity::tick_game(seconds); | WorldEntity::tick_game(seconds); | ||||
ivec2 mousepos = m_mouse->GetCursorPixel(0); | |||||
ivec2 mousepos = input::get()->mouse()->GetCursorPixel(0); | |||||
int prev_frame = (m_frame + 4) % 4; | int prev_frame = (m_frame + 4) % 4; | ||||
m_frame = (m_frame + 1) % 4; | m_frame = (m_frame + 1) % 4; | ||||
@@ -566,7 +565,6 @@ private: | |||||
mat4 m_zoom_settings; | mat4 m_zoom_settings; | ||||
// Input support | // Input support | ||||
InputDevice *m_mouse; | |||||
Controller *m_controller; | Controller *m_controller; | ||||
InputProfile m_profile; | InputProfile m_profile; | ||||
@@ -84,8 +84,6 @@ public: | |||||
/* FIXME: we need proper unproject or at least screen space events!! */ | /* FIXME: we need proper unproject or at least screen space events!! */ | ||||
ivec2 m_wanted_resolution; | ivec2 m_wanted_resolution; | ||||
InputDevice* m_mouse; | |||||
SavedState m_state; | SavedState m_state; | ||||
bool m_video_ready; | bool m_video_ready; | ||||
@@ -195,6 +193,8 @@ void lol::AndroidAppData::DestroyDisplay() | |||||
*/ | */ | ||||
int32_t lol::AndroidAppData::HandleInput(AInputEvent* event) | int32_t lol::AndroidAppData::HandleInput(AInputEvent* event) | ||||
{ | { | ||||
auto mouse = input::get()->mouse(); | |||||
switch (AInputEvent_getType(event)) | switch (AInputEvent_getType(event)) | ||||
{ | { | ||||
case AINPUT_EVENT_TYPE_MOTION: | case AINPUT_EVENT_TYPE_MOTION: | ||||
@@ -206,19 +206,19 @@ int32_t lol::AndroidAppData::HandleInput(AInputEvent* event) | |||||
AMotionEvent_getY(event, 0)); | AMotionEvent_getY(event, 0)); | ||||
pos *= m_wanted_resolution / Video::GetSize(); | pos *= m_wanted_resolution / Video::GetSize(); | ||||
pos.y = m_wanted_resolution.y - 1 - pos.y; | pos.y = m_wanted_resolution.y - 1 - pos.y; | ||||
m_mouse->SetCursor(0, vec2(pos) / vec2(m_wanted_resolution), pos); | |||||
mouse->SetCursor(0, vec2(pos) / vec2(m_wanted_resolution), pos); | |||||
// Note: 100.0f is an arbitrary value that makes it feel about the same than an xbox controller joystick | // Note: 100.0f is an arbitrary value that makes it feel about the same than an xbox controller joystick | ||||
m_mouse->internal_set_axis(0, (pos.x - m_prev_pos.x) / max_screen_size * 100.f); | |||||
mouse->internal_set_axis(0, (pos.x - m_prev_pos.x) / max_screen_size * 100.f); | |||||
// Unlike SDL, no need to negate Y axis | // Unlike SDL, no need to negate Y axis | ||||
m_mouse->internal_set_axis(1, (pos.y - m_prev_pos.y) / max_screen_size * -100.f); | |||||
mouse->internal_set_axis(1, (pos.y - m_prev_pos.y) / max_screen_size * -100.f); | |||||
m_prev_pos = pos; | m_prev_pos = pos; | ||||
switch (AKeyEvent_getAction(event) & AMOTION_EVENT_ACTION_MASK) | switch (AKeyEvent_getAction(event) & AMOTION_EVENT_ACTION_MASK) | ||||
{ | { | ||||
case AMOTION_EVENT_ACTION_DOWN: | case AMOTION_EVENT_ACTION_DOWN: | ||||
m_mouse->internal_set_key(0, true); | |||||
mouse->internal_set_key(0, true); | |||||
break; | break; | ||||
case AMOTION_EVENT_ACTION_UP: | case AMOTION_EVENT_ACTION_UP: | ||||
m_mouse->internal_set_key(0, false); | |||||
mouse->internal_set_key(0, false); | |||||
break; | break; | ||||
} | } | ||||
return 1; | return 1; | ||||
@@ -344,7 +344,6 @@ lol::AndroidApp::AndroidApp(char const *title, ivec2 res, float fps) | |||||
Ticker::Setup(fps); | Ticker::Setup(fps); | ||||
m_data->m_wanted_resolution = res; | m_data->m_wanted_resolution = res; | ||||
m_data->m_mouse = InputDevice::CreateStandardMouse(); | |||||
} | } | ||||
void lol::AndroidApp::ShowPointer(bool show) | void lol::AndroidApp::ShowPointer(bool show) | ||||
@@ -354,7 +353,6 @@ void lol::AndroidApp::ShowPointer(bool show) | |||||
lol::AndroidApp::~AndroidApp() | lol::AndroidApp::~AndroidApp() | ||||
{ | { | ||||
m_data->DestroyDisplay(); | m_data->DestroyDisplay(); | ||||
/* FIXME: handle m_data->m_mouse */ | |||||
delete m_data; | delete m_data; | ||||
} | } | ||||
@@ -371,7 +371,7 @@ void Controller::BindProfile(InputProfile const& setup) | |||||
m_profile = setup; | m_profile = setup; | ||||
// Keyboard | // Keyboard | ||||
m_keyboard = InputDevice::GetKeyboard(); | |||||
m_keyboard = input::get()->keyboard(); | |||||
if (m_keyboard) | if (m_keyboard) | ||||
{ | { | ||||
for (InputProfile::KeyboardKey& key : m_profile.m_keys) | for (InputProfile::KeyboardKey& key : m_profile.m_keys) | ||||
@@ -379,7 +379,7 @@ void Controller::BindProfile(InputProfile const& setup) | |||||
} | } | ||||
// Mouse | // Mouse | ||||
m_mouse = InputDevice::GetMouse(); | |||||
m_mouse = input::get()->mouse(); | |||||
if (m_mouse) | if (m_mouse) | ||||
{ | { | ||||
for (InputProfile::MouseKey& key : m_profile.m_mouse_keys) | for (InputProfile::MouseKey& key : m_profile.m_mouse_keys) | ||||
@@ -356,8 +356,8 @@ private: | |||||
//Input profile stuff | //Input profile stuff | ||||
mutex m_mutex; | mutex m_mutex; | ||||
class InputProfile m_profile; | class InputProfile m_profile; | ||||
class InputDevice* m_keyboard = nullptr; | |||||
class InputDevice* m_mouse = nullptr; | |||||
std::shared_ptr<InputDevice> m_keyboard; | |||||
std::shared_ptr<InputDevice> m_mouse; | |||||
array<class InputDevice*> m_joysticks; | array<class InputDevice*> m_joysticks; | ||||
array<uint64_t> m_joystick_idx; | array<uint64_t> m_joystick_idx; | ||||
}; | }; | ||||
@@ -101,8 +101,6 @@ gui::gui(ImFontAtlas *shared_font_atlas) | |||||
Ticker::Ref(m_controller = new Controller("ImGui_Controller")); | Ticker::Ref(m_controller = new Controller("ImGui_Controller")); | ||||
m_controller->Init(m_profile); | m_controller->Init(m_profile); | ||||
m_mouse = InputDevice::GetMouse(); | |||||
m_keyboard = InputDevice::GetKeyboard(); | |||||
} | } | ||||
gui::~gui() | gui::~gui() | ||||
@@ -209,6 +207,9 @@ void gui::tick_game(float seconds) | |||||
{ | { | ||||
super::tick_game(seconds); | super::tick_game(seconds); | ||||
auto keyboard = input::get()->keyboard(); | |||||
auto mouse = input::get()->mouse(); | |||||
ImGuiIO& io = ImGui::GetIO(); | ImGuiIO& io = ImGui::GetIO(); | ||||
// Init Texture | // Init Texture | ||||
@@ -240,29 +241,26 @@ void gui::tick_game(float seconds) | |||||
for (input::key k : input::all_keys()) | for (input::key k : input::all_keys()) | ||||
io.KeysDown[(int)k] = m_controller->IsKeyPressed((int)k); | io.KeysDown[(int)k] = m_controller->IsKeyPressed((int)k); | ||||
m_keyboard->SetTextInputActive(io.WantTextInput); | |||||
keyboard->SetTextInputActive(io.WantTextInput); | |||||
//Update text input | //Update text input | ||||
std::string text = m_keyboard->GetText(); | |||||
std::string text = keyboard->GetText(); | |||||
//text.case_change(io.KeyShift); | //text.case_change(io.KeyShift); | ||||
for (auto ch : text) | for (auto ch : text) | ||||
io.AddInputCharacter(ch); | io.AddInputCharacter(ch); | ||||
// Update mouse | // Update mouse | ||||
if (m_mouse) | |||||
{ | |||||
vec2 cursor = m_mouse->GetCursor(0); | |||||
cursor.y = 1.f - cursor.y; | |||||
vec2 cursor = mouse->GetCursor(0); | |||||
cursor.y = 1.f - cursor.y; | |||||
io.MousePos = cursor * video_size; | |||||
//msg::debug("%.2f/%.2f\n", io.MousePos.x, io.MousePos.y); | |||||
io.MouseWheel = m_controller->GetAxisValue(axis_enum::Scroll); | |||||
io.MousePos = cursor * video_size; | |||||
//msg::debug("%.2f/%.2f\n", io.MousePos.x, io.MousePos.y); | |||||
io.MouseWheel = m_controller->GetAxisValue(axis_enum::Scroll); | |||||
io.MouseDown[0] = m_controller->IsKeyPressed(key_enum::LeftClick); | |||||
io.MouseDown[1] = m_controller->IsKeyPressed(key_enum::RightClick); | |||||
io.MouseDown[2] = m_controller->IsKeyPressed(key_enum::MiddleClick); | |||||
// FIXME: handle key_enum::Focus? | |||||
} | |||||
io.MouseDown[0] = m_controller->IsKeyPressed(key_enum::LeftClick); | |||||
io.MouseDown[1] = m_controller->IsKeyPressed(key_enum::RightClick); | |||||
io.MouseDown[2] = m_controller->IsKeyPressed(key_enum::MiddleClick); | |||||
// FIXME: handle key_enum::Focus? | |||||
// Start the frame | // Start the frame | ||||
ImGui::NewFrame(); | ImGui::NewFrame(); | ||||
@@ -86,8 +86,6 @@ protected: | |||||
array<ShaderAttrib> m_attribs; | array<ShaderAttrib> m_attribs; | ||||
std::shared_ptr<VertexDeclaration> m_vdecl; | std::shared_ptr<VertexDeclaration> m_vdecl; | ||||
Controller* m_controller = nullptr; | Controller* m_controller = nullptr; | ||||
InputDevice* m_mouse = nullptr; | |||||
InputDevice* m_keyboard = nullptr; | |||||
InputProfile m_profile; | InputProfile m_profile; | ||||
std::string m_clipboard; | std::string m_clipboard; | ||||
@@ -29,6 +29,29 @@ std::shared_ptr<input> input::get() | |||||
return shared_instance; | return shared_instance; | ||||
} | } | ||||
input::input() | |||||
{ | |||||
// Create default keyboard device | |||||
m_keyboard = std::make_shared<InputDevice>(g_name_keyboard.c_str()); | |||||
/* Register all scancodes known to SDL (from the USB standard) */ | |||||
# define _SC(id, str, name) m_keyboard->AddKey(id, #name); | |||||
# include "ui/keys.inc" | |||||
// Create default mouse device | |||||
m_mouse = std::make_shared<InputDevice>(g_name_mouse.c_str()); | |||||
m_mouse->AddKey(g_name_mouse_key_left.c_str()); | |||||
m_mouse->AddKey(g_name_mouse_key_middle.c_str()); | |||||
m_mouse->AddKey(g_name_mouse_key_right.c_str()); | |||||
// Added to manage if mouse is in the screen or not. | |||||
m_mouse->AddKey(g_name_mouse_key_in_screen.c_str()); | |||||
m_mouse->AddAxis(g_name_mouse_axis_x.c_str()); | |||||
m_mouse->AddAxis(g_name_mouse_axis_y.c_str()); | |||||
m_mouse->AddAxis(g_name_mouse_axis_xpixel.c_str()); | |||||
m_mouse->AddAxis(g_name_mouse_axis_ypixel.c_str()); | |||||
m_mouse->AddAxis(g_name_mouse_axis_scroll.c_str(), .0000001f); | |||||
m_mouse->AddCursor(g_name_mouse_cursor.c_str()); | |||||
} | |||||
// Lookup tables for scancode and key name lookups | // Lookup tables for scancode and key name lookups | ||||
static std::vector<input::key> g_all_keys | static std::vector<input::key> g_all_keys | ||||
{ | { | ||||
@@ -137,36 +160,4 @@ void InputDevice::AddCursor(int index, const char* name) | |||||
m_cursor_names[index] = name; | m_cursor_names[index] = name; | ||||
} | } | ||||
InputDevice* InputDevice::CreateStandardKeyboard() | |||||
{ | |||||
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); | |||||
# include "ui/keys.inc" | |||||
return keyboard; | |||||
} | |||||
InputDevice* InputDevice::CreateStandardMouse() | |||||
{ | |||||
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()); | |||||
//Added to manage if mouse is in the screen or not. | |||||
mouse->AddKey(g_name_mouse_key_in_screen.c_str()); | |||||
mouse->AddAxis(g_name_mouse_axis_x.c_str()); | |||||
mouse->AddAxis(g_name_mouse_axis_y.c_str()); | |||||
mouse->AddAxis(g_name_mouse_axis_xpixel.c_str()); | |||||
mouse->AddAxis(g_name_mouse_axis_ypixel.c_str()); | |||||
mouse->AddAxis(g_name_mouse_axis_scroll.c_str(), .0000001f); | |||||
mouse->AddCursor(g_name_mouse_cursor.c_str()); | |||||
// TODO: extended button, and wheel (as axis or as buttons? or both?) | |||||
return mouse; | |||||
} | |||||
} /* namespace lol */ | } /* namespace lol */ |
@@ -20,42 +20,6 @@ | |||||
namespace lol | 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, | |||||
#include "ui/keys.inc" | |||||
}; | |||||
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"); | const std::string g_name_mouse("Mouse"); | ||||
const std::string g_name_keyboard("Keyboard"); | const std::string g_name_keyboard("Keyboard"); | ||||
@@ -195,14 +159,6 @@ public: | |||||
} | } | ||||
/** Default helpers */ | /** Default helpers */ | ||||
static InputDevice* GetKeyboard() | |||||
{ | |||||
return GetDevice(g_name_keyboard); | |||||
} | |||||
static InputDevice* GetMouse() | |||||
{ | |||||
return GetDevice(g_name_mouse); | |||||
} | |||||
static InputDevice* GetJoystick(const uint64_t num) | static InputDevice* GetJoystick(const uint64_t num) | ||||
{ | { | ||||
return GetDevice(g_name_joystick(num)); | return GetDevice(g_name_joystick(num)); | ||||
@@ -260,9 +216,6 @@ public: | |||||
m_axis[id].m1 = value; | m_axis[id].m1 = value; | ||||
} | } | ||||
static InputDevice* CreateStandardKeyboard(); | |||||
static InputDevice* CreateStandardMouse(); | |||||
protected: | protected: | ||||
// TODO: hide all of this in a InputDeviceData? | // TODO: hide all of this in a InputDeviceData? | ||||
@@ -308,5 +261,49 @@ private: | |||||
} | } | ||||
}; | }; | ||||
class input | |||||
{ | |||||
public: | |||||
static std::shared_ptr<input> get(); | |||||
// Default devices | |||||
std::shared_ptr<InputDevice> keyboard() { return m_keyboard; } | |||||
std::shared_ptr<InputDevice> mouse() { return m_mouse; } | |||||
// Keyboard API | |||||
enum class key : uint16_t | |||||
{ | |||||
#define _SC(id, str, name) SC_##name = id, | |||||
#include "ui/keys.inc" | |||||
}; | |||||
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(); | |||||
std::shared_ptr<InputDevice> m_keyboard; | |||||
std::shared_ptr<InputDevice> m_mouse; | |||||
bool m_mouse_capture = false; | |||||
}; | |||||
} /* namespace lol */ | } /* namespace lol */ | ||||
@@ -89,9 +89,6 @@ SdlInput::SdlInput(int app_w, int app_h, int screen_w, int screen_h) | |||||
SDL_Init(SDL_INIT_TIMER | SDL_INIT_JOYSTICK); | SDL_Init(SDL_INIT_TIMER | SDL_INIT_JOYSTICK); | ||||
#endif | #endif | ||||
m_keyboard = InputDevice::CreateStandardKeyboard(); | |||||
m_mouse = InputDevice::CreateStandardMouse(); | |||||
// XXX: another option for emscripten is to properly support gamepads | // XXX: another option for emscripten is to properly support gamepads | ||||
#if LOL_USE_SDL && !__EMSCRIPTEN__ | #if LOL_USE_SDL && !__EMSCRIPTEN__ | ||||
SDL_JoystickEventState(SDL_FORCE_POLL_JOYSTICK ? SDL_QUERY : SDL_ENABLE); | SDL_JoystickEventState(SDL_FORCE_POLL_JOYSTICK ? SDL_QUERY : SDL_ENABLE); | ||||
@@ -117,7 +114,6 @@ SdlInput::SdlInput(int app_w, int app_h, int screen_w, int screen_h) | |||||
continue; | continue; | ||||
} | } | ||||
//format("Joystick%d", i + 1).c_str() | |||||
InputDevice* stick = new InputDevice(g_name_joystick(i + 1)); | InputDevice* stick = new InputDevice(g_name_joystick(i + 1)); | ||||
for (int j = 0; j < SDL_JoystickNumAxes(sdlstick); ++j) | for (int j = 0; j < SDL_JoystickNumAxes(sdlstick); ++j) | ||||
stick->AddAxis(format("Axis%d", j + 1).c_str()); | stick->AddAxis(format("Axis%d", j + 1).c_str()); | ||||
@@ -166,6 +162,9 @@ void SdlInput::tick(float seconds) | |||||
/* FIXME: maybe we should make use of this? */ | /* FIXME: maybe we should make use of this? */ | ||||
UNUSED(seconds); | UNUSED(seconds); | ||||
auto keyboard = input::get()->keyboard(); | |||||
auto mouse = input::get()->mouse(); | |||||
/* Pump all joystick events because no event is coming to us. */ | /* Pump all joystick events because no event is coming to us. */ | ||||
# if SDL_FORCE_POLL_JOYSTICK && !__EMSCRIPTEN__ | # if SDL_FORCE_POLL_JOYSTICK && !__EMSCRIPTEN__ | ||||
SDL_JoystickUpdate(); | SDL_JoystickUpdate(); | ||||
@@ -178,9 +177,9 @@ void SdlInput::tick(float seconds) | |||||
} | } | ||||
# endif | # endif | ||||
m_mouse->internal_set_axis(4, 0); | |||||
mouse->internal_set_axis(4, 0); | |||||
if (m_keyboard->IsTextInputActive()) | |||||
if (keyboard->IsTextInputActive()) | |||||
SDL_StartTextInput(); | SDL_StartTextInput(); | ||||
else | else | ||||
SDL_StopTextInput(); | SDL_StopTextInput(); | ||||
@@ -219,32 +218,32 @@ void SdlInput::tick(float seconds) | |||||
sc2 = (int)input::key::SC_NumLockClearStatus; | sc2 = (int)input::key::SC_NumLockClearStatus; | ||||
break; | break; | ||||
} | } | ||||
m_keyboard->internal_set_key(sc2, !m_keyboard->key((int)sc2)); | |||||
keyboard->internal_set_key(sc2, !keyboard->key((int)sc2)); | |||||
/* DEBUG STUFF | /* DEBUG STUFF | ||||
msg::debug("Repeat: 0x%02x : %s/%s/%s/%i\n", | msg::debug("Repeat: 0x%02x : %s/%s/%s/%i\n", | ||||
(int)m_keyboard, ScanCodeToText(sc2).C(), ScanCodeToName(sc2).C(), | |||||
m_keyboard->GetKey(sc2) ? "up" : "down", event.key.repeat); | |||||
(int)keyboard, ScanCodeToText(sc2).C(), ScanCodeToName(sc2).C(), | |||||
keyboard->GetKey(sc2) ? "up" : "down", event.key.repeat); | |||||
*/ | */ | ||||
} | } | ||||
default: | default: | ||||
// Set key updates the corresponding key | // Set key updates the corresponding key | ||||
m_keyboard->internal_set_key(sc, event.type == SDL_KEYDOWN); | |||||
keyboard->internal_set_key(sc, event.type == SDL_KEYDOWN); | |||||
break; | break; | ||||
} | } | ||||
break; | break; | ||||
//case SDL_TEXTEDITING: //TODO: handle that? | //case SDL_TEXTEDITING: //TODO: handle that? | ||||
case SDL_TEXTINPUT: | case SDL_TEXTINPUT: | ||||
m_keyboard->internal_add_text(event.text.text); | |||||
keyboard->internal_add_text(event.text.text); | |||||
break; | break; | ||||
case SDL_MOUSEBUTTONDOWN: | case SDL_MOUSEBUTTONDOWN: | ||||
case SDL_MOUSEBUTTONUP: | case SDL_MOUSEBUTTONUP: | ||||
//event.button.which | //event.button.which | ||||
m_mouse->internal_set_key(event.button.button - 1, event.type == SDL_MOUSEBUTTONDOWN); | |||||
mouse->internal_set_key(event.button.button - 1, event.type == SDL_MOUSEBUTTONDOWN); | |||||
break; | break; | ||||
case SDL_MOUSEWHEEL: | case SDL_MOUSEWHEEL: | ||||
m_mouse->internal_set_axis(4, (float)event.button.y); | |||||
mouse->internal_set_axis(4, (float)event.button.y); | |||||
break; | break; | ||||
case SDL_WINDOWEVENT: | case SDL_WINDOWEVENT: | ||||
{ | { | ||||
@@ -252,11 +251,11 @@ void SdlInput::tick(float seconds) | |||||
{ | { | ||||
case SDL_WINDOWEVENT_ENTER: | case SDL_WINDOWEVENT_ENTER: | ||||
case SDL_WINDOWEVENT_FOCUS_GAINED: | case SDL_WINDOWEVENT_FOCUS_GAINED: | ||||
m_mouse->internal_set_key(3, true); | |||||
mouse->internal_set_key(3, true); | |||||
break; | break; | ||||
case SDL_WINDOWEVENT_LEAVE: | case SDL_WINDOWEVENT_LEAVE: | ||||
case SDL_WINDOWEVENT_FOCUS_LOST: | case SDL_WINDOWEVENT_FOCUS_LOST: | ||||
m_mouse->internal_set_key(3, false); | |||||
mouse->internal_set_key(3, false); | |||||
break; | break; | ||||
case SDL_WINDOWEVENT_RESIZED: | case SDL_WINDOWEVENT_RESIZED: | ||||
Video::Resize(ivec2(event.window.data1, event.window.data2)); | Video::Resize(ivec2(event.window.data1, event.window.data2)); | ||||
@@ -279,44 +278,44 @@ void SdlInput::tick(float seconds) | |||||
} | } | ||||
/* Handle mouse input */ | /* Handle mouse input */ | ||||
ivec2 mouse(-1, -1); | |||||
SDL_GetMouseState(&mouse.x, &mouse.y); | |||||
mouse.y = Video::GetSize().y - 1 - mouse.y; | |||||
ivec2 mouse_pos(-1, -1); | |||||
SDL_GetMouseState(&mouse_pos.x, &mouse_pos.y); | |||||
mouse_pos.y = Video::GetSize().y - 1 - mouse_pos.y; | |||||
if (input::get()->mouse_capture() != m_mousecapture) | if (input::get()->mouse_capture() != m_mousecapture) | ||||
{ | { | ||||
m_mousecapture = input::get()->mouse_capture(); | m_mousecapture = input::get()->mouse_capture(); | ||||
SDL_SetRelativeMouseMode(m_mousecapture ? SDL_TRUE : SDL_FALSE); | SDL_SetRelativeMouseMode(m_mousecapture ? SDL_TRUE : SDL_FALSE); | ||||
mouse = ivec2(m_app * .5f); | |||||
mouse_pos = ivec2(m_app * .5f); | |||||
// FIXME: how do I warped mouse? | // FIXME: how do I warped mouse? | ||||
//SDL_WarpMouse((uint16_t)mouse.x, (uint16_t)mouse.y); | |||||
//SDL_WarpMouse((uint16_t)mouse_pos.x, (uint16_t)mouse_pos.y); | |||||
//SDL_ShowCursor(m_mousecapture ? SDL_DISABLE : SDL_ENABLE); | //SDL_ShowCursor(m_mousecapture ? SDL_DISABLE : SDL_ENABLE); | ||||
} | } | ||||
if (mouse.x >= 0 && mouse.x < m_app.x && mouse.y >= 0 && mouse.y < m_app.y) | |||||
if (mouse_pos.x >= 0 && mouse_pos.x < m_app.x && mouse_pos.y >= 0 && mouse_pos.y < m_app.y) | |||||
{ | { | ||||
//We need the max if we want coherent mouse speed between axis | //We need the max if we want coherent mouse speed between axis | ||||
float max_screen_size = lol::max(m_screen.x, m_screen.y); | float max_screen_size = lol::max(m_screen.x, m_screen.y); | ||||
vec2 vmouse = vec2(mouse); | |||||
vec2 vmouse = vec2(mouse_pos); | |||||
vec2 vprevmouse = vec2(m_prevmouse); | vec2 vprevmouse = vec2(m_prevmouse); | ||||
m_mouse->SetCursor(0, vmouse / m_app, mouse); | |||||
mouse->SetCursor(0, vmouse / m_app, mouse_pos); | |||||
// Note: 100.0f is an arbitrary value that makes it feel about the same than an xbox controller joystick | // Note: 100.0f is an arbitrary value that makes it feel about the same than an xbox controller joystick | ||||
m_mouse->internal_set_axis(0, (mouse.x - vprevmouse.x) * MOUSE_SPEED_MOD / max_screen_size); | |||||
mouse->internal_set_axis(0, (mouse_pos.x - vprevmouse.x) * MOUSE_SPEED_MOD / max_screen_size); | |||||
// Y Axis is also negated to match the usual joystick Y axis (negatives values are for the upper direction) | // Y Axis is also negated to match the usual joystick Y axis (negatives values are for the upper direction) | ||||
m_mouse->internal_set_axis(1,-(mouse.y - vprevmouse.y) * MOUSE_SPEED_MOD / max_screen_size); | |||||
mouse->internal_set_axis(1,-(mouse_pos.y - vprevmouse.y) * MOUSE_SPEED_MOD / max_screen_size); | |||||
//Pixel movement | //Pixel movement | ||||
m_mouse->internal_set_axis(2, (mouse.x - vprevmouse.x)); | |||||
m_mouse->internal_set_axis(3,-(mouse.y - vprevmouse.y)); | |||||
mouse->internal_set_axis(2, (mouse_pos.x - vprevmouse.x)); | |||||
mouse->internal_set_axis(3,-(mouse_pos.y - vprevmouse.y)); | |||||
} | } | ||||
if (m_mousecapture) | if (m_mousecapture) | ||||
{ | { | ||||
mouse = ivec2(m_app * .5f); | |||||
//SDL_WarpMouse((uint16_t)mouse.x, (uint16_t)mouse.y); | |||||
mouse_pos = ivec2(m_app * .5f); | |||||
//SDL_WarpMouse((uint16_t)mouse_pos.x, (uint16_t)mouse_pos.y); | |||||
} | } | ||||
m_prevmouse = mouse; | |||||
m_prevmouse = mouse_pos; | |||||
#else | #else | ||||
UNUSED(seconds); | UNUSED(seconds); | ||||
@@ -47,8 +47,6 @@ private: | |||||
void tick(float seconds); | void tick(float seconds); | ||||
array<SDL_Joystick *, class InputDevice *> m_joysticks; | array<SDL_Joystick *, class InputDevice *> m_joysticks; | ||||
InputDevice *m_mouse = nullptr; | |||||
InputDevice *m_keyboard = nullptr; | |||||
ivec2 m_prevmouse = ivec2::zero; | ivec2 m_prevmouse = ivec2::zero; | ||||
vec2 m_app; | vec2 m_app; | ||||