|
|
|
@ -18,66 +18,166 @@
|
|
|
|
|
|
|
|
|
|
namespace InputCommon {
|
|
|
|
|
|
|
|
|
|
static std::shared_ptr<Keyboard> keyboard;
|
|
|
|
|
static std::shared_ptr<MotionEmu> motion_emu;
|
|
|
|
|
#ifdef HAVE_SDL2
|
|
|
|
|
static std::unique_ptr<SDL::State> sdl;
|
|
|
|
|
#endif
|
|
|
|
|
static std::unique_ptr<CemuhookUDP::State> udp;
|
|
|
|
|
static std::shared_ptr<GCButtonFactory> gcbuttons;
|
|
|
|
|
static std::shared_ptr<GCAnalogFactory> gcanalog;
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
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
|
|
|
|
|
sdl = SDL::Init();
|
|
|
|
|
sdl = SDL::Init();
|
|
|
|
|
#endif
|
|
|
|
|
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();
|
|
|
|
|
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.reset();
|
|
|
|
|
sdl.reset();
|
|
|
|
|
#endif
|
|
|
|
|
udp.reset();
|
|
|
|
|
Input::UnregisterFactory<Input::ButtonDevice>("gcpad");
|
|
|
|
|
Input::UnregisterFactory<Input::AnalogDevice>("gcpad");
|
|
|
|
|
udp.reset();
|
|
|
|
|
Input::UnregisterFactory<Input::ButtonDevice>("gcpad");
|
|
|
|
|
Input::UnregisterFactory<Input::AnalogDevice>("gcpad");
|
|
|
|
|
|
|
|
|
|
gcbuttons.reset();
|
|
|
|
|
gcanalog.reset();
|
|
|
|
|
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 {};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::shared_ptr<Keyboard> keyboard;
|
|
|
|
|
std::shared_ptr<MotionEmu> motion_emu;
|
|
|
|
|
#ifdef HAVE_SDL2
|
|
|
|
|
std::unique_ptr<SDL::State> sdl;
|
|
|
|
|
#endif
|
|
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Keyboard* GetKeyboard() {
|
|
|
|
|
return keyboard.get();
|
|
|
|
|
void InputSubsystem::Shutdown() {
|
|
|
|
|
impl->Shutdown();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MotionEmu* GetMotionEmu() {
|
|
|
|
|
return motion_emu.get();
|
|
|
|
|
Keyboard* InputSubsystem::GetKeyboard() {
|
|
|
|
|
return impl->keyboard.get();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GCButtonFactory* GetGCButtons() {
|
|
|
|
|
return gcbuttons.get();
|
|
|
|
|
const Keyboard* InputSubsystem::GetKeyboard() const {
|
|
|
|
|
return impl->keyboard.get();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GCAnalogFactory* GetGCAnalogs() {
|
|
|
|
|
return gcanalog.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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ButtonMapping InputSubsystem::GetButtonMappingForDevice(const Common::ParamPackage& device) const {
|
|
|
|
|
return impl->GetButtonMappingForDevice(device);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GCAnalogFactory* InputSubsystem::GetGCAnalogs() {
|
|
|
|
|
return impl->gcanalog.get();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const GCAnalogFactory* InputSubsystem::GetGCAnalogs() const {
|
|
|
|
|
return impl->gcanalog.get();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GCButtonFactory* InputSubsystem::GetGCButtons() {
|
|
|
|
|
return impl->gcbuttons.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
|
|
|
|
|