|
|
|
@ -18,66 +18,166 @@ |
|
|
|
|
|
|
|
namespace InputCommon { |
|
|
|
|
|
|
|
static std::shared_ptr<Keyboard> keyboard; |
|
|
|
static std::shared_ptr<MotionEmu> motion_emu; |
|
|
|
struct InputSubsystem::Impl { |
|
|
|
void Initialize() { |
|
|
|
auto gcadapter = std::make_shared<GCAdapter::Adapter>(); |
|
|
|
gcbuttons = std::make_shared<GCButtonFactory>(gcadapter); |
|
|
|
Input::RegisterFactory<Input::ButtonDevice>("gcpad", gcbuttons); |
|
|
|
gcanalog = std::make_shared<GCAnalogFactory>(gcadapter); |
|
|
|
Input::RegisterFactory<Input::AnalogDevice>("gcpad", gcanalog); |
|
|
|
|
|
|
|
keyboard = std::make_shared<Keyboard>(); |
|
|
|
Input::RegisterFactory<Input::ButtonDevice>("keyboard", keyboard); |
|
|
|
Input::RegisterFactory<Input::AnalogDevice>("analog_from_button", |
|
|
|
std::make_shared<AnalogFromButton>()); |
|
|
|
motion_emu = std::make_shared<MotionEmu>(); |
|
|
|
Input::RegisterFactory<Input::MotionDevice>("motion_emu", motion_emu); |
|
|
|
|
|
|
|
#ifdef HAVE_SDL2
|
|
|
|
static std::unique_ptr<SDL::State> sdl; |
|
|
|
sdl = SDL::Init(); |
|
|
|
#endif
|
|
|
|
static std::unique_ptr<CemuhookUDP::State> udp; |
|
|
|
static std::shared_ptr<GCButtonFactory> gcbuttons; |
|
|
|
static std::shared_ptr<GCAnalogFactory> gcanalog; |
|
|
|
|
|
|
|
void Init() { |
|
|
|
auto gcadapter = std::make_shared<GCAdapter::Adapter>(); |
|
|
|
gcbuttons = std::make_shared<GCButtonFactory>(gcadapter); |
|
|
|
Input::RegisterFactory<Input::ButtonDevice>("gcpad", gcbuttons); |
|
|
|
gcanalog = std::make_shared<GCAnalogFactory>(gcadapter); |
|
|
|
Input::RegisterFactory<Input::AnalogDevice>("gcpad", gcanalog); |
|
|
|
|
|
|
|
keyboard = std::make_shared<Keyboard>(); |
|
|
|
Input::RegisterFactory<Input::ButtonDevice>("keyboard", keyboard); |
|
|
|
Input::RegisterFactory<Input::AnalogDevice>("analog_from_button", |
|
|
|
std::make_shared<AnalogFromButton>()); |
|
|
|
motion_emu = std::make_shared<MotionEmu>(); |
|
|
|
Input::RegisterFactory<Input::MotionDevice>("motion_emu", motion_emu); |
|
|
|
|
|
|
|
udp = CemuhookUDP::Init(); |
|
|
|
} |
|
|
|
|
|
|
|
void Shutdown() { |
|
|
|
Input::UnregisterFactory<Input::ButtonDevice>("keyboard"); |
|
|
|
keyboard.reset(); |
|
|
|
Input::UnregisterFactory<Input::AnalogDevice>("analog_from_button"); |
|
|
|
Input::UnregisterFactory<Input::MotionDevice>("motion_emu"); |
|
|
|
motion_emu.reset(); |
|
|
|
#ifdef HAVE_SDL2
|
|
|
|
sdl = SDL::Init(); |
|
|
|
sdl.reset(); |
|
|
|
#endif
|
|
|
|
udp = CemuhookUDP::Init(); |
|
|
|
} |
|
|
|
udp.reset(); |
|
|
|
Input::UnregisterFactory<Input::ButtonDevice>("gcpad"); |
|
|
|
Input::UnregisterFactory<Input::AnalogDevice>("gcpad"); |
|
|
|
|
|
|
|
gcbuttons.reset(); |
|
|
|
gcanalog.reset(); |
|
|
|
} |
|
|
|
|
|
|
|
[[nodiscard]] std::vector<Common::ParamPackage> GetInputDevices() const { |
|
|
|
std::vector<Common::ParamPackage> devices = { |
|
|
|
Common::ParamPackage{{"display", "Any"}, {"class", "any"}}, |
|
|
|
Common::ParamPackage{{"display", "Keyboard/Mouse"}, {"class", "key"}}, |
|
|
|
}; |
|
|
|
#ifdef HAVE_SDL2
|
|
|
|
auto sdl_devices = sdl->GetInputDevices(); |
|
|
|
devices.insert(devices.end(), sdl_devices.begin(), sdl_devices.end()); |
|
|
|
#endif
|
|
|
|
auto udp_devices = udp->GetInputDevices(); |
|
|
|
devices.insert(devices.end(), udp_devices.begin(), udp_devices.end()); |
|
|
|
return devices; |
|
|
|
} |
|
|
|
|
|
|
|
[[nodiscard]] AnalogMapping GetAnalogMappingForDevice( |
|
|
|
const Common::ParamPackage& params) const { |
|
|
|
if (!params.Has("class") || params.Get("class", "") == "any") { |
|
|
|
return {}; |
|
|
|
} |
|
|
|
if (params.Get("class", "") == "key") { |
|
|
|
// TODO consider returning the SDL key codes for the default keybindings
|
|
|
|
return {}; |
|
|
|
} |
|
|
|
#ifdef HAVE_SDL2
|
|
|
|
if (params.Get("class", "") == "sdl") { |
|
|
|
return sdl->GetAnalogMappingForDevice(params); |
|
|
|
} |
|
|
|
#endif
|
|
|
|
return {}; |
|
|
|
} |
|
|
|
|
|
|
|
[[nodiscard]] ButtonMapping GetButtonMappingForDevice( |
|
|
|
const Common::ParamPackage& params) const { |
|
|
|
if (!params.Has("class") || params.Get("class", "") == "any") { |
|
|
|
return {}; |
|
|
|
} |
|
|
|
if (params.Get("class", "") == "key") { |
|
|
|
// TODO consider returning the SDL key codes for the default keybindings
|
|
|
|
return {}; |
|
|
|
} |
|
|
|
#ifdef HAVE_SDL2
|
|
|
|
if (params.Get("class", "") == "sdl") { |
|
|
|
return sdl->GetButtonMappingForDevice(params); |
|
|
|
} |
|
|
|
#endif
|
|
|
|
return {}; |
|
|
|
} |
|
|
|
|
|
|
|
void Shutdown() { |
|
|
|
Input::UnregisterFactory<Input::ButtonDevice>("keyboard"); |
|
|
|
keyboard.reset(); |
|
|
|
Input::UnregisterFactory<Input::AnalogDevice>("analog_from_button"); |
|
|
|
Input::UnregisterFactory<Input::MotionDevice>("motion_emu"); |
|
|
|
motion_emu.reset(); |
|
|
|
std::shared_ptr<Keyboard> keyboard; |
|
|
|
std::shared_ptr<MotionEmu> motion_emu; |
|
|
|
#ifdef HAVE_SDL2
|
|
|
|
sdl.reset(); |
|
|
|
std::unique_ptr<SDL::State> sdl; |
|
|
|
#endif
|
|
|
|
udp.reset(); |
|
|
|
Input::UnregisterFactory<Input::ButtonDevice>("gcpad"); |
|
|
|
Input::UnregisterFactory<Input::AnalogDevice>("gcpad"); |
|
|
|
std::unique_ptr<CemuhookUDP::State> udp; |
|
|
|
std::shared_ptr<GCButtonFactory> gcbuttons; |
|
|
|
std::shared_ptr<GCAnalogFactory> gcanalog; |
|
|
|
}; |
|
|
|
|
|
|
|
InputSubsystem::InputSubsystem() : impl{std::make_unique<Impl>()} {} |
|
|
|
|
|
|
|
InputSubsystem::~InputSubsystem() = default; |
|
|
|
|
|
|
|
void InputSubsystem::Initialize() { |
|
|
|
impl->Initialize(); |
|
|
|
} |
|
|
|
|
|
|
|
void InputSubsystem::Shutdown() { |
|
|
|
impl->Shutdown(); |
|
|
|
} |
|
|
|
|
|
|
|
Keyboard* InputSubsystem::GetKeyboard() { |
|
|
|
return impl->keyboard.get(); |
|
|
|
} |
|
|
|
|
|
|
|
const Keyboard* InputSubsystem::GetKeyboard() const { |
|
|
|
return impl->keyboard.get(); |
|
|
|
} |
|
|
|
|
|
|
|
MotionEmu* InputSubsystem::GetMotionEmu() { |
|
|
|
return impl->motion_emu.get(); |
|
|
|
} |
|
|
|
|
|
|
|
const MotionEmu* InputSubsystem::GetMotionEmu() const { |
|
|
|
return impl->motion_emu.get(); |
|
|
|
} |
|
|
|
|
|
|
|
std::vector<Common::ParamPackage> InputSubsystem::GetInputDevices() const { |
|
|
|
return impl->GetInputDevices(); |
|
|
|
} |
|
|
|
|
|
|
|
AnalogMapping InputSubsystem::GetAnalogMappingForDevice(const Common::ParamPackage& device) const { |
|
|
|
return impl->GetAnalogMappingForDevice(device); |
|
|
|
} |
|
|
|
|
|
|
|
gcbuttons.reset(); |
|
|
|
gcanalog.reset(); |
|
|
|
ButtonMapping InputSubsystem::GetButtonMappingForDevice(const Common::ParamPackage& device) const { |
|
|
|
return impl->GetButtonMappingForDevice(device); |
|
|
|
} |
|
|
|
|
|
|
|
Keyboard* GetKeyboard() { |
|
|
|
return keyboard.get(); |
|
|
|
GCAnalogFactory* InputSubsystem::GetGCAnalogs() { |
|
|
|
return impl->gcanalog.get(); |
|
|
|
} |
|
|
|
|
|
|
|
MotionEmu* GetMotionEmu() { |
|
|
|
return motion_emu.get(); |
|
|
|
const GCAnalogFactory* InputSubsystem::GetGCAnalogs() const { |
|
|
|
return impl->gcanalog.get(); |
|
|
|
} |
|
|
|
|
|
|
|
GCButtonFactory* GetGCButtons() { |
|
|
|
return gcbuttons.get(); |
|
|
|
GCButtonFactory* InputSubsystem::GetGCButtons() { |
|
|
|
return impl->gcbuttons.get(); |
|
|
|
} |
|
|
|
|
|
|
|
GCAnalogFactory* GetGCAnalogs() { |
|
|
|
return gcanalog.get(); |
|
|
|
const GCButtonFactory* InputSubsystem::GetGCButtons() const { |
|
|
|
return impl->gcbuttons.get(); |
|
|
|
} |
|
|
|
|
|
|
|
std::vector<std::unique_ptr<Polling::DevicePoller>> InputSubsystem::GetPollers( |
|
|
|
Polling::DeviceType type) const { |
|
|
|
#ifdef HAVE_SDL2
|
|
|
|
return impl->sdl->GetPollers(type); |
|
|
|
#else
|
|
|
|
return {}; |
|
|
|
#endif
|
|
|
|
} |
|
|
|
|
|
|
|
std::string GenerateKeyboardParam(int key_code) { |
|
|
|
@ -101,68 +201,4 @@ std::string GenerateAnalogParamFromKeys(int key_up, int key_down, int key_left, |
|
|
|
}; |
|
|
|
return circle_pad_param.Serialize(); |
|
|
|
} |
|
|
|
|
|
|
|
std::vector<Common::ParamPackage> GetInputDevices() { |
|
|
|
std::vector<Common::ParamPackage> devices = { |
|
|
|
Common::ParamPackage{{"display", "Any"}, {"class", "any"}}, |
|
|
|
Common::ParamPackage{{"display", "Keyboard/Mouse"}, {"class", "key"}}, |
|
|
|
}; |
|
|
|
#ifdef HAVE_SDL2
|
|
|
|
auto sdl_devices = sdl->GetInputDevices(); |
|
|
|
devices.insert(devices.end(), sdl_devices.begin(), sdl_devices.end()); |
|
|
|
#endif
|
|
|
|
auto udp_devices = udp->GetInputDevices(); |
|
|
|
devices.insert(devices.end(), udp_devices.begin(), udp_devices.end()); |
|
|
|
return devices; |
|
|
|
} |
|
|
|
|
|
|
|
std::unordered_map<Settings::NativeButton::Values, Common::ParamPackage> GetButtonMappingForDevice( |
|
|
|
const Common::ParamPackage& params) { |
|
|
|
std::unordered_map<Settings::NativeButton::Values, Common::ParamPackage> mappings; |
|
|
|
if (!params.Has("class") || params.Get("class", "") == "any") { |
|
|
|
return {}; |
|
|
|
} |
|
|
|
if (params.Get("class", "") == "key") { |
|
|
|
// TODO consider returning the SDL key codes for the default keybindings
|
|
|
|
return {}; |
|
|
|
} |
|
|
|
#ifdef HAVE_SDL2
|
|
|
|
if (params.Get("class", "") == "sdl") { |
|
|
|
return sdl->GetButtonMappingForDevice(params); |
|
|
|
} |
|
|
|
#endif
|
|
|
|
return {}; |
|
|
|
} |
|
|
|
|
|
|
|
std::unordered_map<Settings::NativeAnalog::Values, Common::ParamPackage> GetAnalogMappingForDevice( |
|
|
|
const Common::ParamPackage& params) { |
|
|
|
std::unordered_map<Settings::NativeAnalog::Values, Common::ParamPackage> mappings; |
|
|
|
if (!params.Has("class") || params.Get("class", "") == "any") { |
|
|
|
return {}; |
|
|
|
} |
|
|
|
if (params.Get("class", "") == "key") { |
|
|
|
// TODO consider returning the SDL key codes for the default keybindings
|
|
|
|
return {}; |
|
|
|
} |
|
|
|
#ifdef HAVE_SDL2
|
|
|
|
if (params.Get("class", "") == "sdl") { |
|
|
|
return sdl->GetAnalogMappingForDevice(params); |
|
|
|
} |
|
|
|
#endif
|
|
|
|
return {}; |
|
|
|
} |
|
|
|
|
|
|
|
namespace Polling { |
|
|
|
|
|
|
|
std::vector<std::unique_ptr<DevicePoller>> GetPollers(DeviceType type) { |
|
|
|
std::vector<std::unique_ptr<DevicePoller>> pollers; |
|
|
|
|
|
|
|
#ifdef HAVE_SDL2
|
|
|
|
pollers = sdl->GetPollers(type); |
|
|
|
#endif
|
|
|
|
|
|
|
|
return pollers; |
|
|
|
} |
|
|
|
|
|
|
|
} // namespace Polling
|
|
|
|
} // namespace InputCommon
|