mirror of
https://github.com/cemu-project/Cemu.git
synced 2024-11-29 12:34:17 +01:00
Use unordered_map for keydown to allow codes above 255 (#248)
- Adds internal support for 32bit key codes, required for proper keyboard input on Linux - Use gdk_keyval_name to get key name on Linux
This commit is contained in:
parent
5e968eff4f
commit
9f02733a0d
@ -170,16 +170,16 @@ int CemuApp::FilterEvent(wxEvent& event)
|
|||||||
{
|
{
|
||||||
const auto& key_event = (wxKeyEvent&)event;
|
const auto& key_event = (wxKeyEvent&)event;
|
||||||
wxGetKeyState(wxKeyCode::WXK_F17);
|
wxGetKeyState(wxKeyCode::WXK_F17);
|
||||||
uint32 keycode=fix_raw_keycode(key_event.GetRawKeyCode(), key_event.GetRawKeyFlags());
|
g_window_info.set_keystate(fix_raw_keycode(key_event.GetRawKeyCode(), key_event.GetRawKeyFlags()), true);
|
||||||
if(keycode<256)
|
|
||||||
g_window_info.keydown[keycode] = true;
|
|
||||||
}
|
}
|
||||||
else if(event.GetEventType() == wxEVT_KEY_UP)
|
else if(event.GetEventType() == wxEVT_KEY_UP)
|
||||||
{
|
{
|
||||||
const auto& key_event = (wxKeyEvent&)event;
|
const auto& key_event = (wxKeyEvent&)event;
|
||||||
uint32 keycode=fix_raw_keycode(key_event.GetRawKeyCode(), key_event.GetRawKeyFlags());
|
g_window_info.set_keystate(fix_raw_keycode(key_event.GetRawKeyCode(), key_event.GetRawKeyFlags()), false);
|
||||||
if(keycode<256)
|
}
|
||||||
g_window_info.keydown[keycode] = false;
|
else if(event.GetEventType() == wxEVT_KILL_FOCUS)
|
||||||
|
{
|
||||||
|
g_window_info.set_keystatesdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
return wxApp::FilterEvent(event);
|
return wxApp::FilterEvent(event);
|
||||||
|
@ -153,6 +153,15 @@ bool gui_isPadWindowOpen()
|
|||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
|
||||||
typedef void GdkDisplay;
|
typedef void GdkDisplay;
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
const char* (*gdk_keyval_name)(unsigned int keyval);
|
||||||
|
}
|
||||||
|
std::string gui_gtkRawKeyCodeToString(uint32 keyCode)
|
||||||
|
{
|
||||||
|
return gdk_keyval_name(keyCode);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void gui_initHandleContextFromWxWidgetsWindow(WindowHandleInfo& handleInfoOut, class wxWindow* wxw)
|
void gui_initHandleContextFromWxWidgetsWindow(WindowHandleInfo& handleInfoOut, class wxWindow* wxw)
|
||||||
@ -176,9 +185,11 @@ void gui_initHandleContextFromWxWidgetsWindow(WindowHandleInfo& handleInfoOut, c
|
|||||||
Window (*dyn_gdk_x11_window_get_xid)(GdkWindow *window);
|
Window (*dyn_gdk_x11_window_get_xid)(GdkWindow *window);
|
||||||
dyn_gdk_x11_window_get_xid = (Window(*)(GdkWindow *window))dlsym(RTLD_NEXT, "gdk_x11_window_get_xid");
|
dyn_gdk_x11_window_get_xid = (Window(*)(GdkWindow *window))dlsym(RTLD_NEXT, "gdk_x11_window_get_xid");
|
||||||
|
|
||||||
|
gdk_keyval_name = (const char* (*)(unsigned int))dlsym(RTLD_NEXT, "gdk_keyval_name");
|
||||||
|
|
||||||
if(!dyn_gtk_widget_realize || !dyn_gtk_widget_get_window ||
|
if(!dyn_gtk_widget_realize || !dyn_gtk_widget_get_window ||
|
||||||
!dyn_gdk_window_get_display || !dyn_gdk_x11_display_get_xdisplay ||
|
!dyn_gdk_window_get_display || !dyn_gdk_x11_display_get_xdisplay ||
|
||||||
!dyn_gdk_x11_window_get_xid)
|
!dyn_gdk_x11_window_get_xid || !gdk_keyval_name)
|
||||||
{
|
{
|
||||||
cemuLog_log(LogType::Force, "Unable to load GDK symbols");
|
cemuLog_log(LogType::Force, "Unable to load GDK symbols");
|
||||||
return;
|
return;
|
||||||
@ -206,10 +217,7 @@ void gui_initHandleContextFromWxWidgetsWindow(WindowHandleInfo& handleInfoOut, c
|
|||||||
|
|
||||||
bool gui_isKeyDown(int key)
|
bool gui_isKeyDown(int key)
|
||||||
{
|
{
|
||||||
if (key >= 256)
|
return g_window_info.get_keystate(key);
|
||||||
return false;
|
|
||||||
|
|
||||||
return g_window_info.keydown[key];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void gui_notifyGameLoaded()
|
void gui_notifyGameLoaded()
|
||||||
|
@ -41,14 +41,48 @@ struct WindowInfo
|
|||||||
std::atomic_bool has_screenshot_request;
|
std::atomic_bool has_screenshot_request;
|
||||||
std::atomic_bool is_fullscreen;
|
std::atomic_bool is_fullscreen;
|
||||||
|
|
||||||
std::atomic_bool keydown[256]{};
|
void set_keystate(uint32 keycode, bool state)
|
||||||
|
{
|
||||||
|
const std::lock_guard<std::mutex> lock(keycode_mutex);
|
||||||
|
m_keydown[keycode] = state;
|
||||||
|
};
|
||||||
|
bool get_keystate(uint32 keycode)
|
||||||
|
{
|
||||||
|
const std::lock_guard<std::mutex> lock(keycode_mutex);
|
||||||
|
auto result = m_keydown.find(keycode);
|
||||||
|
if (result == m_keydown.end())
|
||||||
|
return false;
|
||||||
|
return result->second;
|
||||||
|
}
|
||||||
|
void get_keystates(std::unordered_map<uint32, bool>& buttons_out)
|
||||||
|
{
|
||||||
|
const std::lock_guard<std::mutex> lock(keycode_mutex);
|
||||||
|
for (auto&& button : m_keydown)
|
||||||
|
{
|
||||||
|
buttons_out[button.first] = button.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void set_keystatesdown()
|
||||||
|
{
|
||||||
|
const std::lock_guard<std::mutex> lock(keycode_mutex);
|
||||||
|
std::for_each(m_keydown.begin(), m_keydown.end(), [](std::pair<const uint32, bool>& el){ el.second = false; });
|
||||||
|
}
|
||||||
|
template <typename fn>
|
||||||
|
void iter_keystates(fn f)
|
||||||
|
{
|
||||||
|
const std::lock_guard<std::mutex> lock(keycode_mutex);
|
||||||
|
std::for_each(m_keydown.cbegin(), m_keydown.cend(), f);
|
||||||
|
}
|
||||||
WindowHandleInfo window_main;
|
WindowHandleInfo window_main;
|
||||||
WindowHandleInfo window_pad;
|
WindowHandleInfo window_pad;
|
||||||
|
|
||||||
// canvas
|
// canvas
|
||||||
WindowHandleInfo canvas_main;
|
WindowHandleInfo canvas_main;
|
||||||
WindowHandleInfo canvas_pad;
|
WindowHandleInfo canvas_pad;
|
||||||
|
private:
|
||||||
|
std::mutex keycode_mutex;
|
||||||
|
// m_keydown keys must be valid ImGuiKey values
|
||||||
|
std::unordered_map<uint32, bool> m_keydown;
|
||||||
};
|
};
|
||||||
|
|
||||||
void gui_create();
|
void gui_create();
|
||||||
@ -68,6 +102,9 @@ bool gui_isFullScreen();
|
|||||||
|
|
||||||
void gui_initHandleContextFromWxWidgetsWindow(WindowHandleInfo& handleInfoOut, class wxWindow* wxw);
|
void gui_initHandleContextFromWxWidgetsWindow(WindowHandleInfo& handleInfoOut, class wxWindow* wxw);
|
||||||
|
|
||||||
|
#if BOOST_OS_LINUX
|
||||||
|
std::string gui_gtkRawKeyCodeToString(uint32 keyCode);
|
||||||
|
#endif
|
||||||
/*
|
/*
|
||||||
* Returns true if a screenshot request is queued
|
* Returns true if a screenshot request is queued
|
||||||
* Once this function has returned true, it will reset back to
|
* Once this function has returned true, it will reset back to
|
||||||
|
@ -41,7 +41,7 @@ void InputPanel::on_timer(const EmulatedControllerPtr& emulated_controller, cons
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool s_was_idle = true;
|
static bool s_was_idle = true;
|
||||||
if (state.buttons.none()) {
|
if (!std::any_of(state.buttons.begin(), state.buttons.end(), [](auto el){ return el.second; })) {
|
||||||
s_was_idle = true;
|
s_was_idle = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -49,58 +49,65 @@ void InputPanel::on_timer(const EmulatedControllerPtr& emulated_controller, cons
|
|||||||
if (!s_was_idle) {
|
if (!s_was_idle) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
auto get_button_state = [&](uint32 key_id)
|
||||||
|
{
|
||||||
|
auto result = state.buttons.find(key_id);
|
||||||
|
if (result == state.buttons.end())
|
||||||
|
return false;
|
||||||
|
return result->second;
|
||||||
|
};
|
||||||
s_was_idle = false;
|
s_was_idle = false;
|
||||||
for (size_t i = 0; i < state.buttons.size(); ++i)
|
for(auto && button : state.buttons)
|
||||||
{
|
{
|
||||||
if (state.buttons[i])
|
if (button.second)
|
||||||
{
|
{
|
||||||
|
auto id=button.first;
|
||||||
if (controller->has_axis()) {
|
if (controller->has_axis()) {
|
||||||
// test if one axis direction is pressed more than the other
|
// test if one axis direction is pressed more than the other
|
||||||
if ((i == kAxisXP || i == kAxisXN) && (state.buttons[kAxisYP] || state.buttons[kAxisYN]))
|
if ((id == kAxisXP || id == kAxisXN) && (get_button_state(kAxisYP) || get_button_state(kAxisYN)))
|
||||||
{
|
{
|
||||||
if (std::abs(state.axis.y) > std::abs(state.axis.x))
|
if (std::abs(state.axis.y) > std::abs(state.axis.x))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if ((i == kAxisYP || i == kAxisYN) && (state.buttons[kAxisXP] || state.buttons[kAxisXN]))
|
else if ((id == kAxisYP || id == kAxisYN) && (get_button_state(kAxisXP) || get_button_state(kAxisXN)))
|
||||||
{
|
{
|
||||||
if (std::abs(state.axis.x) > std::abs(state.axis.y))
|
if (std::abs(state.axis.x) > std::abs(state.axis.y))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if ((i == kRotationXP || i == kRotationXN) && (state.buttons[kRotationYP] || state.buttons[kRotationYN]))
|
else if ((id == kRotationXP || id == kRotationXN) && (get_button_state(kRotationYP) || get_button_state(kRotationYN)))
|
||||||
{
|
{
|
||||||
if (std::abs(state.rotation.y) > std::abs(state.rotation.x))
|
if (std::abs(state.rotation.y) > std::abs(state.rotation.x))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if ((i == kRotationYP || i == kRotationYN) && (state.buttons[kRotationXP] || state.buttons[kRotationXN]))
|
else if ((id == kRotationYP || id == kRotationYN) && (get_button_state(kRotationXP) || get_button_state(kRotationXN)))
|
||||||
{
|
{
|
||||||
if (std::abs(state.rotation.x) > std::abs(state.rotation.y))
|
if (std::abs(state.rotation.x) > std::abs(state.rotation.y))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if ((i == kTriggerXP || i == kTriggerXN) && (state.buttons[kTriggerYP] || state.buttons[kTriggerYN]))
|
else if ((id == kTriggerXP || id == kTriggerXN) && (get_button_state(kTriggerYP) || get_button_state(kTriggerYN)))
|
||||||
{
|
{
|
||||||
if (std::abs(state.trigger.y) > std::abs(state.trigger.x))
|
if (std::abs(state.trigger.y) > std::abs(state.trigger.x))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if ((i == kTriggerYP || i == kTriggerYN) && (state.buttons[kTriggerXP] || state.buttons[kTriggerXN]))
|
else if ((id == kTriggerYP || id == kTriggerYN) && (get_button_state(kTriggerXP) || get_button_state(kTriggerXN)))
|
||||||
{
|
{
|
||||||
if (std::abs(state.trigger.x) > std::abs(state.trigger.y))
|
if (std::abs(state.trigger.x) > std::abs(state.trigger.y))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ignore too low button values on configuration
|
// ignore too low button values on configuration
|
||||||
if (i >= kButtonAxisStart)
|
if (id >= kButtonAxisStart)
|
||||||
{
|
{
|
||||||
if (controller->get_axis_value(i) < 0.33f) {
|
if (controller->get_axis_value(id) < 0.33f) {
|
||||||
forceLogDebug_printf("skipping since value too low %f", controller->get_axis_value(i));
|
forceLogDebug_printf("skipping since value too low %f", controller->get_axis_value(id));
|
||||||
s_was_idle = true;
|
s_was_idle = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
emulated_controller->set_mapping(mapping, controller, i);
|
emulated_controller->set_mapping(mapping, controller, id);
|
||||||
element->SetValue(controller->get_button_name(i));
|
element->SetValue(controller->get_button_name(id));
|
||||||
element->SetBackgroundColour(kKeyColourNormalMode);
|
element->SetBackgroundColour(kKeyColourNormalMode);
|
||||||
m_color_backup[element->GetId()] = kKeyColourNormalMode;
|
m_color_backup[element->GetId()] = kKeyColourNormalMode;
|
||||||
break;
|
break;
|
||||||
|
@ -110,7 +110,8 @@ ImFont* ImGui_GetFont(float size)
|
|||||||
void ImGui_UpdateWindowInformation(bool mainWindow)
|
void ImGui_UpdateWindowInformation(bool mainWindow)
|
||||||
{
|
{
|
||||||
extern WindowInfo g_window_info;
|
extern WindowInfo g_window_info;
|
||||||
|
static std::map<uint32, ImGuiKey> keyboard_mapping;
|
||||||
|
static uint32 current_key = 0;
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors;
|
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors;
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;
|
||||||
@ -130,9 +131,17 @@ void ImGui_UpdateWindowInformation(bool mainWindow)
|
|||||||
bool padDown;
|
bool padDown;
|
||||||
const auto pos = instance.get_left_down_mouse_info(&padDown);
|
const auto pos = instance.get_left_down_mouse_info(&padDown);
|
||||||
io.MouseDown[0] = padDown != mainWindow && pos.has_value();
|
io.MouseDown[0] = padDown != mainWindow && pos.has_value();
|
||||||
|
auto get_mapping = [&](uint32 key_code)
|
||||||
std::fill_n(io.KeysDown, std::size(io.KeysDown), false);
|
{
|
||||||
std::copy(std::cbegin(g_window_info.keydown), std::cend(g_window_info.keydown), io.KeysDown);
|
auto key = keyboard_mapping.find(key_code);
|
||||||
|
if (key != keyboard_mapping.end())
|
||||||
|
return key->second;
|
||||||
|
ImGuiKey mapped_key = current_key + ImGuiKey_NamedKey_BEGIN;
|
||||||
|
current_key = (current_key + 1) % ImGuiKey_NamedKey_COUNT ;
|
||||||
|
keyboard_mapping[key_code] = mapped_key;
|
||||||
|
return mapped_key;
|
||||||
|
};
|
||||||
|
g_window_info.iter_keystates([&](auto&& el){ io.AddKeyEvent(get_mapping(el.first), el.second); });
|
||||||
|
|
||||||
// printf("%f %f %d\n", io.MousePos.x, io.MousePos.y, io.MouseDown[0]);
|
// printf("%f %f %d\n", io.MousePos.x, io.MousePos.y, io.MouseDown[0]);
|
||||||
|
|
||||||
|
@ -15,8 +15,10 @@ const ControllerState& ControllerBase::update_state()
|
|||||||
ControllerState result = raw_state();
|
ControllerState result = raw_state();
|
||||||
|
|
||||||
// ignore default buttons
|
// ignore default buttons
|
||||||
result.buttons &= ~m_default_state.buttons;
|
for (auto&& el : m_default_state.buttons)
|
||||||
|
{
|
||||||
|
result.buttons[el.first] = result.buttons[el.first] && !el.second;
|
||||||
|
}
|
||||||
// apply deadzone and range and ignore default axis values
|
// apply deadzone and range and ignore default axis values
|
||||||
apply_axis_setting(result.axis, m_default_state.axis, m_settings.axis);
|
apply_axis_setting(result.axis, m_default_state.axis, m_settings.axis);
|
||||||
apply_axis_setting(result.rotation, m_default_state.rotation, m_settings.rotation);
|
apply_axis_setting(result.rotation, m_default_state.rotation, m_settings.rotation);
|
||||||
@ -24,22 +26,22 @@ const ControllerState& ControllerBase::update_state()
|
|||||||
|
|
||||||
#define APPLY_AXIS_BUTTON(_axis_, _flag_) \
|
#define APPLY_AXIS_BUTTON(_axis_, _flag_) \
|
||||||
if (result._axis_.x < -ControllerState::kAxisThreshold) \
|
if (result._axis_.x < -ControllerState::kAxisThreshold) \
|
||||||
result.buttons.set((_flag_) + (kAxisXN - kAxisXP)); \
|
result.buttons[(_flag_) + (kAxisXN - kAxisXP)]=true; \
|
||||||
else if (result._axis_.x > ControllerState::kAxisThreshold) \
|
else if (result._axis_.x > ControllerState::kAxisThreshold) \
|
||||||
result.buttons.set((_flag_)); \
|
result.buttons[(_flag_)]=true; \
|
||||||
if (result._axis_.y < -ControllerState::kAxisThreshold) \
|
if (result._axis_.y < -ControllerState::kAxisThreshold) \
|
||||||
result.buttons.set((_flag_) + 1 + (kAxisXN - kAxisXP)); \
|
result.buttons[(_flag_) + 1 + (kAxisXN - kAxisXP)]=true; \
|
||||||
else if (result._axis_.y > ControllerState::kAxisThreshold) \
|
else if (result._axis_.y > ControllerState::kAxisThreshold) \
|
||||||
result.buttons.set((_flag_) + 1);
|
result.buttons[(_flag_) + 1]=true;
|
||||||
|
|
||||||
if (result.axis.x < -ControllerState::kAxisThreshold)
|
if (result.axis.x < -ControllerState::kAxisThreshold)
|
||||||
result.buttons.set((kAxisXP) + (kAxisXN - kAxisXP));
|
result.buttons[(kAxisXP) + (kAxisXN - kAxisXP)]=true;
|
||||||
else if (result.axis.x > ControllerState::kAxisThreshold)
|
else if (result.axis.x > ControllerState::kAxisThreshold)
|
||||||
result.buttons.set((kAxisXP));
|
result.buttons[(kAxisXP)]=true;
|
||||||
if (result.axis.y < -ControllerState::kAxisThreshold)
|
if (result.axis.y < -ControllerState::kAxisThreshold)
|
||||||
result.buttons.set((kAxisXP) + 1 + (kAxisXN - kAxisXP));
|
result.buttons[(kAxisXP) + 1 + (kAxisXN - kAxisXP)]=true;
|
||||||
else if (result.axis.y > ControllerState::kAxisThreshold)
|
else if (result.axis.y > ControllerState::kAxisThreshold)
|
||||||
result.buttons.set((kAxisXP) + 1);;
|
result.buttons[(kAxisXP) + 1]=true;
|
||||||
APPLY_AXIS_BUTTON(rotation, kRotationXP);
|
APPLY_AXIS_BUTTON(rotation, kRotationXP);
|
||||||
APPLY_AXIS_BUTTON(trigger, kTriggerXP);
|
APPLY_AXIS_BUTTON(trigger, kTriggerXP);
|
||||||
|
|
||||||
@ -68,7 +70,7 @@ const ControllerState& ControllerBase::update_state()
|
|||||||
|
|
||||||
#undef APPLY_AXIS_BUTTON
|
#undef APPLY_AXIS_BUTTON
|
||||||
|
|
||||||
m_last_state = result;
|
m_last_state = std::move(result);
|
||||||
return m_last_state;
|
return m_last_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,7 +129,8 @@ bool ControllerBase::operator==(const ControllerBase& c) const
|
|||||||
|
|
||||||
float ControllerBase::get_axis_value(uint64 button) const
|
float ControllerBase::get_axis_value(uint64 button) const
|
||||||
{
|
{
|
||||||
if (m_last_state.buttons.test(button))
|
auto buttonState=m_last_state.buttons.find(button);
|
||||||
|
if (buttonState!=m_last_state.buttons.end() && buttonState->second)
|
||||||
{
|
{
|
||||||
if (button <= kButtonNoneAxisMAX || !has_axis())
|
if (button <= kButtonNoneAxisMAX || !has_axis())
|
||||||
return 1.0f;
|
return 1.0f;
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <bitset>
|
|
||||||
#include <glm/vec2.hpp>
|
#include <glm/vec2.hpp>
|
||||||
|
|
||||||
struct ControllerState
|
struct ControllerState
|
||||||
@ -18,7 +17,7 @@ struct ControllerState
|
|||||||
glm::vec2 rotation{ };
|
glm::vec2 rotation{ };
|
||||||
glm::vec2 trigger{ };
|
glm::vec2 trigger{ };
|
||||||
|
|
||||||
std::bitset<256> buttons{};
|
std::unordered_map<uint32, bool> buttons{};
|
||||||
|
|
||||||
uint64 last_state = 0;
|
uint64 last_state = 0;
|
||||||
|
|
||||||
|
@ -137,7 +137,7 @@ ControllerState DSUController::raw_state()
|
|||||||
{
|
{
|
||||||
if (HAS_BIT(state.data.state1, i))
|
if (HAS_BIT(state.data.state1, i))
|
||||||
{
|
{
|
||||||
result.buttons.set(bitindex);
|
result.buttons[bitindex]=true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,12 +145,12 @@ ControllerState DSUController::raw_state()
|
|||||||
{
|
{
|
||||||
if (HAS_BIT(state.data.state2, i))
|
if (HAS_BIT(state.data.state2, i))
|
||||||
{
|
{
|
||||||
result.buttons.set(bitindex);
|
result.buttons[bitindex]=true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.data.touch)
|
if (state.data.touch)
|
||||||
result.buttons.set(kButton16);
|
result.buttons[kButton16]=true;
|
||||||
|
|
||||||
result.axis.x = (float)state.data.lx / std::numeric_limits<uint8>::max();
|
result.axis.x = (float)state.data.lx / std::numeric_limits<uint8>::max();
|
||||||
result.axis.x = (result.axis.x * 2.0f) - 1.0f;
|
result.axis.x = (result.axis.x * 2.0f) - 1.0f;
|
||||||
|
@ -278,7 +278,7 @@ ControllerState DirectInputController::raw_state()
|
|||||||
{
|
{
|
||||||
if (HAS_BIT(state.rgbButtons[i], 7))
|
if (HAS_BIT(state.rgbButtons[i], 7))
|
||||||
{
|
{
|
||||||
result.buttons.set(i);
|
result.buttons[i]=true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -316,19 +316,19 @@ ControllerState DirectInputController::raw_state()
|
|||||||
{
|
{
|
||||||
switch (pov)
|
switch (pov)
|
||||||
{
|
{
|
||||||
case 0: result.buttons.set(kButtonUp);
|
case 0: result.buttons[kButtonUp]=true;
|
||||||
break;
|
break;
|
||||||
case 4500: result.buttons.set(kButtonUp); // up + right
|
case 4500: result.buttons[kButtonUp]=true; // up + right
|
||||||
case 9000: result.buttons.set(kButtonRight);
|
case 9000: result.buttons[kButtonRight]=true;
|
||||||
break;
|
break;
|
||||||
case 13500: result.buttons.set(kButtonRight); // right + down
|
case 13500: result.buttons[kButtonRight] = true; // right + down
|
||||||
case 18000: result.buttons.set(kButtonDown);
|
case 18000: result.buttons[kButtonDown] = true;
|
||||||
break;
|
break;
|
||||||
case 22500: result.buttons.set(kButtonDown); // down + left
|
case 22500: result.buttons[kButtonDown] = true; // down + left
|
||||||
case 27000: result.buttons.set(kButtonLeft);
|
case 27000: result.buttons[kButtonLeft] = true;
|
||||||
break;
|
break;
|
||||||
case 31500: result.buttons.set(kButtonLeft);; // left + up
|
case 31500: result.buttons[kButtonLeft] = true; // left + up
|
||||||
result.buttons.set(kButtonUp); // left + up
|
result.buttons[kButtonUp] = true; // left + up
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,9 +35,13 @@ std::string KeyboardController::get_button_name(uint64 button) const
|
|||||||
char key_name[128];
|
char key_name[128];
|
||||||
if (GetKeyNameTextA(scan_code, key_name, std::size(key_name)) != 0)
|
if (GetKeyNameTextA(scan_code, key_name, std::size(key_name)) != 0)
|
||||||
return key_name;
|
return key_name;
|
||||||
#endif
|
else
|
||||||
|
|
||||||
return fmt::format("key_{}", button);
|
return fmt::format("key_{}", button);
|
||||||
|
#elif BOOST_OS_LINUX
|
||||||
|
return gui_gtkRawKeyCodeToString(button);
|
||||||
|
#else
|
||||||
|
return fmt::format("key_{}", button);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
extern WindowInfo g_window_info;
|
extern WindowInfo g_window_info;
|
||||||
@ -47,20 +51,7 @@ ControllerState KeyboardController::raw_state()
|
|||||||
ControllerState result{};
|
ControllerState result{};
|
||||||
if (g_window_info.app_active)
|
if (g_window_info.app_active)
|
||||||
{
|
{
|
||||||
static_assert(result.buttons.size() == std::size(g_window_info.keydown), "invalid size");
|
g_window_info.get_keystates(result.buttons);
|
||||||
for (uint32 i = wxKeyCode::WXK_BACK; i < result.buttons.size(); ++i)
|
|
||||||
{
|
|
||||||
if(const bool v = g_window_info.keydown[i])
|
|
||||||
{
|
|
||||||
result.buttons.set(i, v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// ignore generic key codes on Windows when there is also a left/right variant
|
|
||||||
#if BOOST_OS_WINDOWS
|
|
||||||
result.buttons.set(VK_SHIFT, false);
|
|
||||||
result.buttons.set(VK_CONTROL, false);
|
|
||||||
result.buttons.set(VK_MENU, false);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -147,7 +147,7 @@ ControllerState SDLController::raw_state()
|
|||||||
{
|
{
|
||||||
if (m_buttons[i] && SDL_GameControllerGetButton(m_controller, (SDL_GameControllerButton)i))
|
if (m_buttons[i] && SDL_GameControllerGetButton(m_controller, (SDL_GameControllerButton)i))
|
||||||
{
|
{
|
||||||
result.buttons.set(i);
|
result.buttons[i]=true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,23 +206,26 @@ ControllerState NativeWiimoteController::raw_state()
|
|||||||
return result;
|
return result;
|
||||||
|
|
||||||
const auto state = m_provider->get_state(m_index);
|
const auto state = m_provider->get_state(m_index);
|
||||||
result.buttons = state.buttons;
|
for (int i = 0; i < std::numeric_limits<uint16>::digits; i++)
|
||||||
|
result.buttons[i] = state.buttons & (1<<i);
|
||||||
|
|
||||||
if (std::holds_alternative<NunchuckData>(state.m_extension))
|
if (std::holds_alternative<NunchuckData>(state.m_extension))
|
||||||
{
|
{
|
||||||
const auto nunchuck = std::get<NunchuckData>(state.m_extension);
|
const auto nunchuck = std::get<NunchuckData>(state.m_extension);
|
||||||
if (nunchuck.c)
|
if (nunchuck.c)
|
||||||
result.buttons.set(kWiimoteButton_C);
|
result.buttons[kWiimoteButton_C]=true;
|
||||||
|
|
||||||
if (nunchuck.z)
|
if (nunchuck.z)
|
||||||
result.buttons.set(kWiimoteButton_Z);
|
result.buttons[kWiimoteButton_Z]=true;
|
||||||
|
|
||||||
result.axis = nunchuck.axis;
|
result.axis = nunchuck.axis;
|
||||||
}
|
}
|
||||||
else if (std::holds_alternative<ClassicData>(state.m_extension))
|
else if (std::holds_alternative<ClassicData>(state.m_extension))
|
||||||
{
|
{
|
||||||
const auto classic = std::get<ClassicData>(state.m_extension);
|
const auto classic = std::get<ClassicData>(state.m_extension);
|
||||||
result.buttons |= (uint64)classic.buttons << kHighestWiimote;
|
uint64 buttons = (uint64)classic.buttons << kHighestWiimote;
|
||||||
|
for (int i = 0; i < std::numeric_limits<uint64>::digits; i++)
|
||||||
|
result.buttons[i] = result.buttons[i] || (buttons & (1 << i));
|
||||||
|
|
||||||
result.axis = classic.left_axis;
|
result.axis = classic.left_axis;
|
||||||
result.rotation = classic.right_axis;
|
result.rotation = classic.right_axis;
|
||||||
|
@ -120,7 +120,8 @@ ControllerState XInputController::raw_state()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Buttons
|
// Buttons
|
||||||
result.buttons = state.Gamepad.wButtons;
|
for(int i=0;i<std::numeric_limits<WORD>::digits;i++)
|
||||||
|
result.buttons[i] = state.Gamepad.wButtons & (1<<i);
|
||||||
|
|
||||||
if (state.Gamepad.sThumbLX > 0)
|
if (state.Gamepad.sThumbLX > 0)
|
||||||
result.axis.x = (float)state.Gamepad.sThumbLX / std::numeric_limits<sint16>::max();
|
result.axis.x = (float)state.Gamepad.sThumbLX / std::numeric_limits<sint16>::max();
|
||||||
|
@ -280,7 +280,9 @@ bool EmulatedController::is_mapping_down(uint64 mapping) const
|
|||||||
if (it != m_mappings.cend())
|
if (it != m_mappings.cend())
|
||||||
{
|
{
|
||||||
if (const auto controller = it->second.controller.lock()) {
|
if (const auto controller = it->second.controller.lock()) {
|
||||||
return controller->get_state().buttons.test(it->second.button);
|
auto& buttons=controller->get_state().buttons;
|
||||||
|
auto buttonState=buttons.find(it->second.button);
|
||||||
|
return buttonState!=buttons.end() && buttonState->second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user