| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180 |
- // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
- // SPDX-License-Identifier: GPL-2.0-or-later
- #include "common/common_types.h"
- #include "common/input.h"
- #include "input_common/input_engine.h"
- #include "input_common/input_poller.h"
- namespace InputCommon {
- class DummyInput final : public Common::Input::InputDevice {
- public:
- explicit DummyInput() = default;
- };
- class InputFromButton final : public Common::Input::InputDevice {
- public:
- explicit InputFromButton(PadIdentifier identifier_, int button_, bool turbo_, bool toggle_,
- bool inverted_, InputEngine* input_engine_)
- : identifier(identifier_), button(button_), turbo(turbo_), toggle(toggle_),
- inverted(inverted_), input_engine(input_engine_) {
- UpdateCallback engine_callback{[this]() { OnChange(); }};
- const InputIdentifier input_identifier{
- .identifier = identifier,
- .type = EngineInputType::Button,
- .index = button,
- .callback = engine_callback,
- };
- last_button_value = false;
- callback_key = input_engine->SetCallback(input_identifier);
- }
- ~InputFromButton() override {
- input_engine->DeleteCallback(callback_key);
- }
- Common::Input::ButtonStatus GetStatus() const {
- return {
- .value = input_engine->GetButton(identifier, button),
- .inverted = inverted,
- .toggle = toggle,
- .turbo = turbo,
- };
- }
- void ForceUpdate() override {
- const Common::Input::CallbackStatus status{
- .type = Common::Input::InputType::Button,
- .button_status = GetStatus(),
- };
- last_button_value = status.button_status.value;
- TriggerOnChange(status);
- }
- void OnChange() {
- const Common::Input::CallbackStatus status{
- .type = Common::Input::InputType::Button,
- .button_status = GetStatus(),
- };
- if (status.button_status.value != last_button_value) {
- last_button_value = status.button_status.value;
- TriggerOnChange(status);
- }
- }
- private:
- const PadIdentifier identifier;
- const int button;
- const bool turbo;
- const bool toggle;
- const bool inverted;
- int callback_key;
- bool last_button_value;
- InputEngine* input_engine;
- };
- class InputFromHatButton final : public Common::Input::InputDevice {
- public:
- explicit InputFromHatButton(PadIdentifier identifier_, int button_, u8 direction_, bool turbo_,
- bool toggle_, bool inverted_, InputEngine* input_engine_)
- : identifier(identifier_), button(button_), direction(direction_), turbo(turbo_),
- toggle(toggle_), inverted(inverted_), input_engine(input_engine_) {
- UpdateCallback engine_callback{[this]() { OnChange(); }};
- const InputIdentifier input_identifier{
- .identifier = identifier,
- .type = EngineInputType::HatButton,
- .index = button,
- .callback = engine_callback,
- };
- last_button_value = false;
- callback_key = input_engine->SetCallback(input_identifier);
- }
- ~InputFromHatButton() override {
- input_engine->DeleteCallback(callback_key);
- }
- Common::Input::ButtonStatus GetStatus() const {
- return {
- .value = input_engine->GetHatButton(identifier, button, direction),
- .inverted = inverted,
- .toggle = toggle,
- .turbo = turbo,
- };
- }
- void ForceUpdate() override {
- const Common::Input::CallbackStatus status{
- .type = Common::Input::InputType::Button,
- .button_status = GetStatus(),
- };
- last_button_value = status.button_status.value;
- TriggerOnChange(status);
- }
- void OnChange() {
- const Common::Input::CallbackStatus status{
- .type = Common::Input::InputType::Button,
- .button_status = GetStatus(),
- };
- if (status.button_status.value != last_button_value) {
- last_button_value = status.button_status.value;
- TriggerOnChange(status);
- }
- }
- private:
- const PadIdentifier identifier;
- const int button;
- const u8 direction;
- const bool turbo;
- const bool toggle;
- const bool inverted;
- int callback_key;
- bool last_button_value;
- InputEngine* input_engine;
- };
- class InputFromStick final : public Common::Input::InputDevice {
- public:
- explicit InputFromStick(PadIdentifier identifier_, int axis_x_, int axis_y_,
- Common::Input::AnalogProperties properties_x_,
- Common::Input::AnalogProperties properties_y_,
- InputEngine* input_engine_)
- : identifier(identifier_), axis_x(axis_x_), axis_y(axis_y_), properties_x(properties_x_),
- properties_y(properties_y_),
- input_engine(input_engine_), invert_axis_y{input_engine_->GetEngineName() == "sdl"} {
- UpdateCallback engine_callback{[this]() { OnChange(); }};
- const InputIdentifier x_input_identifier{
- .identifier = identifier,
- .type = EngineInputType::Analog,
- .index = axis_x,
- .callback = engine_callback,
- };
- const InputIdentifier y_input_identifier{
- .identifier = identifier,
- .type = EngineInputType::Analog,
- .index = axis_y,
- .callback = engine_callback,
- };
- last_axis_x_value = 0.0f;
- last_axis_y_value = 0.0f;
- callback_key_x = input_engine->SetCallback(x_input_identifier);
- callback_key_y = input_engine->SetCallback(y_input_identifier);
- }
- ~InputFromStick() override {
- input_engine->DeleteCallback(callback_key_x);
- input_engine->DeleteCallback(callback_key_y);
- }
- Common::Input::StickStatus GetStatus() const {
- Common::Input::StickStatus status;
- status.x = {
- .raw_value = input_engine->GetAxis(identifier, axis_x),
- .properties = properties_x,
- };
- status.y = {
- .raw_value = input_engine->GetAxis(identifier, axis_y),
- .properties = properties_y,
- };
- // This is a workaround to keep compatibility with old yuzu versions. Vertical axis is
- // inverted on SDL compared to Nintendo
- if (invert_axis_y) {
- status.y.raw_value = -status.y.raw_value;
- }
- return status;
- }
- void ForceUpdate() override {
- const Common::Input::CallbackStatus status{
- .type = Common::Input::InputType::Stick,
- .stick_status = GetStatus(),
- };
- last_axis_x_value = status.stick_status.x.raw_value;
- last_axis_y_value = status.stick_status.y.raw_value;
- TriggerOnChange(status);
- }
- void OnChange() {
- const Common::Input::CallbackStatus status{
- .type = Common::Input::InputType::Stick,
- .stick_status = GetStatus(),
- };
- if (status.stick_status.x.raw_value != last_axis_x_value ||
- status.stick_status.y.raw_value != last_axis_y_value) {
- last_axis_x_value = status.stick_status.x.raw_value;
- last_axis_y_value = status.stick_status.y.raw_value;
- TriggerOnChange(status);
- }
- }
- private:
- const PadIdentifier identifier;
- const int axis_x;
- const int axis_y;
- const Common::Input::AnalogProperties properties_x;
- const Common::Input::AnalogProperties properties_y;
- int callback_key_x;
- int callback_key_y;
- float last_axis_x_value;
- float last_axis_y_value;
- InputEngine* input_engine;
- const bool invert_axis_y;
- };
- class InputFromTouch final : public Common::Input::InputDevice {
- public:
- explicit InputFromTouch(PadIdentifier identifier_, int button_, bool toggle_, bool inverted_,
- int axis_x_, int axis_y_, Common::Input::AnalogProperties properties_x_,
- Common::Input::AnalogProperties properties_y_,
- InputEngine* input_engine_)
- : identifier(identifier_), button(button_), toggle(toggle_), inverted(inverted_),
- axis_x(axis_x_), axis_y(axis_y_), properties_x(properties_x_),
- properties_y(properties_y_), input_engine(input_engine_) {
- UpdateCallback engine_callback{[this]() { OnChange(); }};
- const InputIdentifier button_input_identifier{
- .identifier = identifier,
- .type = EngineInputType::Button,
- .index = button,
- .callback = engine_callback,
- };
- const InputIdentifier x_input_identifier{
- .identifier = identifier,
- .type = EngineInputType::Analog,
- .index = axis_x,
- .callback = engine_callback,
- };
- const InputIdentifier y_input_identifier{
- .identifier = identifier,
- .type = EngineInputType::Analog,
- .index = axis_y,
- .callback = engine_callback,
- };
- last_axis_x_value = 0.0f;
- last_axis_y_value = 0.0f;
- last_button_value = false;
- callback_key_button = input_engine->SetCallback(button_input_identifier);
- callback_key_x = input_engine->SetCallback(x_input_identifier);
- callback_key_y = input_engine->SetCallback(y_input_identifier);
- }
- ~InputFromTouch() override {
- input_engine->DeleteCallback(callback_key_button);
- input_engine->DeleteCallback(callback_key_x);
- input_engine->DeleteCallback(callback_key_y);
- }
- Common::Input::TouchStatus GetStatus() const {
- Common::Input::TouchStatus status{};
- status.pressed = {
- .value = input_engine->GetButton(identifier, button),
- .inverted = inverted,
- .toggle = toggle,
- };
- status.x = {
- .raw_value = input_engine->GetAxis(identifier, axis_x),
- .properties = properties_x,
- };
- status.y = {
- .raw_value = input_engine->GetAxis(identifier, axis_y),
- .properties = properties_y,
- };
- return status;
- }
- void OnChange() {
- const Common::Input::CallbackStatus status{
- .type = Common::Input::InputType::Touch,
- .touch_status = GetStatus(),
- };
- if (status.touch_status.x.raw_value != last_axis_x_value ||
- status.touch_status.y.raw_value != last_axis_y_value ||
- status.touch_status.pressed.value != last_button_value) {
- last_axis_x_value = status.touch_status.x.raw_value;
- last_axis_y_value = status.touch_status.y.raw_value;
- last_button_value = status.touch_status.pressed.value;
- TriggerOnChange(status);
- }
- }
- private:
- const PadIdentifier identifier;
- const int button;
- const bool toggle;
- const bool inverted;
- const int axis_x;
- const int axis_y;
- const Common::Input::AnalogProperties properties_x;
- const Common::Input::AnalogProperties properties_y;
- int callback_key_button;
- int callback_key_x;
- int callback_key_y;
- bool last_button_value;
- float last_axis_x_value;
- float last_axis_y_value;
- InputEngine* input_engine;
- };
- class InputFromTrigger final : public Common::Input::InputDevice {
- public:
- explicit InputFromTrigger(PadIdentifier identifier_, int button_, bool toggle_, bool inverted_,
- int axis_, Common::Input::AnalogProperties properties_,
- InputEngine* input_engine_)
- : identifier(identifier_), button(button_), toggle(toggle_), inverted(inverted_),
- axis(axis_), properties(properties_), input_engine(input_engine_) {
- UpdateCallback engine_callback{[this]() { OnChange(); }};
- const InputIdentifier button_input_identifier{
- .identifier = identifier,
- .type = EngineInputType::Button,
- .index = button,
- .callback = engine_callback,
- };
- const InputIdentifier axis_input_identifier{
- .identifier = identifier,
- .type = EngineInputType::Analog,
- .index = axis,
- .callback = engine_callback,
- };
- last_axis_value = 0.0f;
- last_button_value = false;
- callback_key_button = input_engine->SetCallback(button_input_identifier);
- axis_callback_key = input_engine->SetCallback(axis_input_identifier);
- }
- ~InputFromTrigger() override {
- input_engine->DeleteCallback(callback_key_button);
- input_engine->DeleteCallback(axis_callback_key);
- }
- Common::Input::TriggerStatus GetStatus() const {
- const Common::Input::AnalogStatus analog_status{
- .raw_value = input_engine->GetAxis(identifier, axis),
- .properties = properties,
- };
- const Common::Input::ButtonStatus button_status{
- .value = input_engine->GetButton(identifier, button),
- .inverted = inverted,
- .toggle = toggle,
- };
- return {
- .analog = analog_status,
- .pressed = button_status,
- };
- }
- void OnChange() {
- const Common::Input::CallbackStatus status{
- .type = Common::Input::InputType::Trigger,
- .trigger_status = GetStatus(),
- };
- if (status.trigger_status.analog.raw_value != last_axis_value ||
- status.trigger_status.pressed.value != last_button_value) {
- last_axis_value = status.trigger_status.analog.raw_value;
- last_button_value = status.trigger_status.pressed.value;
- TriggerOnChange(status);
- }
- }
- private:
- const PadIdentifier identifier;
- const int button;
- const bool toggle;
- const bool inverted;
- const int axis;
- const Common::Input::AnalogProperties properties;
- int callback_key_button;
- int axis_callback_key;
- bool last_button_value;
- float last_axis_value;
- InputEngine* input_engine;
- };
- class InputFromAnalog final : public Common::Input::InputDevice {
- public:
- explicit InputFromAnalog(PadIdentifier identifier_, int axis_,
- Common::Input::AnalogProperties properties_,
- InputEngine* input_engine_)
- : identifier(identifier_), axis(axis_), properties(properties_),
- input_engine(input_engine_) {
- UpdateCallback engine_callback{[this]() { OnChange(); }};
- const InputIdentifier input_identifier{
- .identifier = identifier,
- .type = EngineInputType::Analog,
- .index = axis,
- .callback = engine_callback,
- };
- last_axis_value = 0.0f;
- callback_key = input_engine->SetCallback(input_identifier);
- }
- ~InputFromAnalog() override {
- input_engine->DeleteCallback(callback_key);
- }
- Common::Input::AnalogStatus GetStatus() const {
- return {
- .raw_value = input_engine->GetAxis(identifier, axis),
- .properties = properties,
- };
- }
- void OnChange() {
- const Common::Input::CallbackStatus status{
- .type = Common::Input::InputType::Analog,
- .analog_status = GetStatus(),
- };
- if (status.analog_status.raw_value != last_axis_value) {
- last_axis_value = status.analog_status.raw_value;
- TriggerOnChange(status);
- }
- }
- private:
- const PadIdentifier identifier;
- const int axis;
- const Common::Input::AnalogProperties properties;
- int callback_key;
- float last_axis_value;
- InputEngine* input_engine;
- };
- class InputFromBattery final : public Common::Input::InputDevice {
- public:
- explicit InputFromBattery(PadIdentifier identifier_, InputEngine* input_engine_)
- : identifier(identifier_), input_engine(input_engine_) {
- UpdateCallback engine_callback{[this]() { OnChange(); }};
- const InputIdentifier input_identifier{
- .identifier = identifier,
- .type = EngineInputType::Battery,
- .index = 0,
- .callback = engine_callback,
- };
- last_battery_value = Common::Input::BatteryStatus::Charging;
- callback_key = input_engine->SetCallback(input_identifier);
- }
- ~InputFromBattery() override {
- input_engine->DeleteCallback(callback_key);
- }
- Common::Input::BatteryStatus GetStatus() const {
- return input_engine->GetBattery(identifier);
- }
- void ForceUpdate() override {
- const Common::Input::CallbackStatus status{
- .type = Common::Input::InputType::Battery,
- .battery_status = GetStatus(),
- };
- last_battery_value = status.battery_status;
- TriggerOnChange(status);
- }
- void OnChange() {
- const Common::Input::CallbackStatus status{
- .type = Common::Input::InputType::Battery,
- .battery_status = GetStatus(),
- };
- if (status.battery_status != last_battery_value) {
- last_battery_value = status.battery_status;
- TriggerOnChange(status);
- }
- }
- private:
- const PadIdentifier identifier;
- int callback_key;
- Common::Input::BatteryStatus last_battery_value;
- InputEngine* input_engine;
- };
- class InputFromColor final : public Common::Input::InputDevice {
- public:
- explicit InputFromColor(PadIdentifier identifier_, InputEngine* input_engine_)
- : identifier(identifier_), input_engine(input_engine_) {
- UpdateCallback engine_callback{[this]() { OnChange(); }};
- const InputIdentifier input_identifier{
- .identifier = identifier,
- .type = EngineInputType::Color,
- .index = 0,
- .callback = engine_callback,
- };
- last_color_value = {};
- callback_key = input_engine->SetCallback(input_identifier);
- }
- ~InputFromColor() override {
- input_engine->DeleteCallback(callback_key);
- }
- Common::Input::BodyColorStatus GetStatus() const {
- return input_engine->GetColor(identifier);
- }
- void ForceUpdate() override {
- const Common::Input::CallbackStatus status{
- .type = Common::Input::InputType::Color,
- .color_status = GetStatus(),
- };
- last_color_value = status.color_status;
- TriggerOnChange(status);
- }
- void OnChange() {
- const Common::Input::CallbackStatus status{
- .type = Common::Input::InputType::Color,
- .color_status = GetStatus(),
- };
- if (status.color_status.body != last_color_value.body) {
- last_color_value = status.color_status;
- TriggerOnChange(status);
- }
- }
- private:
- const PadIdentifier identifier;
- int callback_key;
- Common::Input::BodyColorStatus last_color_value;
- InputEngine* input_engine;
- };
- class InputFromMotion final : public Common::Input::InputDevice {
- public:
- explicit InputFromMotion(PadIdentifier identifier_, int motion_sensor_, float gyro_threshold_,
- InputEngine* input_engine_)
- : identifier(identifier_), motion_sensor(motion_sensor_), gyro_threshold(gyro_threshold_),
- input_engine(input_engine_) {
- UpdateCallback engine_callback{[this]() { OnChange(); }};
- const InputIdentifier input_identifier{
- .identifier = identifier,
- .type = EngineInputType::Motion,
- .index = motion_sensor,
- .callback = engine_callback,
- };
- callback_key = input_engine->SetCallback(input_identifier);
- }
- ~InputFromMotion() override {
- input_engine->DeleteCallback(callback_key);
- }
- Common::Input::MotionStatus GetStatus() const {
- const auto basic_motion = input_engine->GetMotion(identifier, motion_sensor);
- Common::Input::MotionStatus status{};
- const Common::Input::AnalogProperties properties = {
- .deadzone = 0.0f,
- .range = 1.0f,
- .threshold = gyro_threshold,
- .offset = 0.0f,
- };
- status.accel.x = {.raw_value = basic_motion.accel_x, .properties = properties};
- status.accel.y = {.raw_value = basic_motion.accel_y, .properties = properties};
- status.accel.z = {.raw_value = basic_motion.accel_z, .properties = properties};
- status.gyro.x = {.raw_value = basic_motion.gyro_x, .properties = properties};
- status.gyro.y = {.raw_value = basic_motion.gyro_y, .properties = properties};
- status.gyro.z = {.raw_value = basic_motion.gyro_z, .properties = properties};
- status.delta_timestamp = basic_motion.delta_timestamp;
- return status;
- }
- void OnChange() {
- const Common::Input::CallbackStatus status{
- .type = Common::Input::InputType::Motion,
- .motion_status = GetStatus(),
- };
- TriggerOnChange(status);
- }
- private:
- const PadIdentifier identifier;
- const int motion_sensor;
- const float gyro_threshold;
- int callback_key;
- InputEngine* input_engine;
- };
- class InputFromAxisMotion final : public Common::Input::InputDevice {
- public:
- explicit InputFromAxisMotion(PadIdentifier identifier_, int axis_x_, int axis_y_, int axis_z_,
- Common::Input::AnalogProperties properties_x_,
- Common::Input::AnalogProperties properties_y_,
- Common::Input::AnalogProperties properties_z_,
- InputEngine* input_engine_)
- : identifier(identifier_), axis_x(axis_x_), axis_y(axis_y_), axis_z(axis_z_),
- properties_x(properties_x_), properties_y(properties_y_), properties_z(properties_z_),
- input_engine(input_engine_) {
- UpdateCallback engine_callback{[this]() { OnChange(); }};
- const InputIdentifier x_input_identifier{
- .identifier = identifier,
- .type = EngineInputType::Analog,
- .index = axis_x,
- .callback = engine_callback,
- };
- const InputIdentifier y_input_identifier{
- .identifier = identifier,
- .type = EngineInputType::Analog,
- .index = axis_y,
- .callback = engine_callback,
- };
- const InputIdentifier z_input_identifier{
- .identifier = identifier,
- .type = EngineInputType::Analog,
- .index = axis_z,
- .callback = engine_callback,
- };
- last_axis_x_value = 0.0f;
- last_axis_y_value = 0.0f;
- last_axis_z_value = 0.0f;
- callback_key_x = input_engine->SetCallback(x_input_identifier);
- callback_key_y = input_engine->SetCallback(y_input_identifier);
- callback_key_z = input_engine->SetCallback(z_input_identifier);
- }
- ~InputFromAxisMotion() override {
- input_engine->DeleteCallback(callback_key_x);
- input_engine->DeleteCallback(callback_key_y);
- input_engine->DeleteCallback(callback_key_z);
- }
- Common::Input::MotionStatus GetStatus() const {
- Common::Input::MotionStatus status{};
- status.gyro.x = {
- .raw_value = input_engine->GetAxis(identifier, axis_x),
- .properties = properties_x,
- };
- status.gyro.y = {
- .raw_value = input_engine->GetAxis(identifier, axis_y),
- .properties = properties_y,
- };
- status.gyro.z = {
- .raw_value = input_engine->GetAxis(identifier, axis_z),
- .properties = properties_z,
- };
- status.delta_timestamp = 1000;
- status.force_update = true;
- return status;
- }
- void ForceUpdate() override {
- const Common::Input::CallbackStatus status{
- .type = Common::Input::InputType::Motion,
- .motion_status = GetStatus(),
- };
- last_axis_x_value = status.motion_status.gyro.x.raw_value;
- last_axis_y_value = status.motion_status.gyro.y.raw_value;
- last_axis_z_value = status.motion_status.gyro.z.raw_value;
- TriggerOnChange(status);
- }
- void OnChange() {
- const Common::Input::CallbackStatus status{
- .type = Common::Input::InputType::Motion,
- .motion_status = GetStatus(),
- };
- if (status.motion_status.gyro.x.raw_value != last_axis_x_value ||
- status.motion_status.gyro.y.raw_value != last_axis_y_value ||
- status.motion_status.gyro.z.raw_value != last_axis_z_value) {
- last_axis_x_value = status.motion_status.gyro.x.raw_value;
- last_axis_y_value = status.motion_status.gyro.y.raw_value;
- last_axis_z_value = status.motion_status.gyro.z.raw_value;
- TriggerOnChange(status);
- }
- }
- private:
- const PadIdentifier identifier;
- const int axis_x;
- const int axis_y;
- const int axis_z;
- const Common::Input::AnalogProperties properties_x;
- const Common::Input::AnalogProperties properties_y;
- const Common::Input::AnalogProperties properties_z;
- int callback_key_x;
- int callback_key_y;
- int callback_key_z;
- float last_axis_x_value;
- float last_axis_y_value;
- float last_axis_z_value;
- InputEngine* input_engine;
- };
- class InputFromCamera final : public Common::Input::InputDevice {
- public:
- explicit InputFromCamera(PadIdentifier identifier_, InputEngine* input_engine_)
- : identifier(identifier_), input_engine(input_engine_) {
- UpdateCallback engine_callback{[this]() { OnChange(); }};
- const InputIdentifier input_identifier{
- .identifier = identifier,
- .type = EngineInputType::Camera,
- .index = 0,
- .callback = engine_callback,
- };
- callback_key = input_engine->SetCallback(input_identifier);
- }
- ~InputFromCamera() override {
- input_engine->DeleteCallback(callback_key);
- }
- Common::Input::CameraStatus GetStatus() const {
- return input_engine->GetCamera(identifier);
- }
- void ForceUpdate() override {
- OnChange();
- }
- void OnChange() {
- const auto camera_status = GetStatus();
- const Common::Input::CallbackStatus status{
- .type = Common::Input::InputType::IrSensor,
- .camera_status = camera_status.format,
- .raw_data = camera_status.data,
- };
- TriggerOnChange(status);
- }
- private:
- const PadIdentifier identifier;
- int callback_key;
- InputEngine* input_engine;
- };
- class InputFromNfc final : public Common::Input::InputDevice {
- public:
- explicit InputFromNfc(PadIdentifier identifier_, InputEngine* input_engine_)
- : identifier(identifier_), input_engine(input_engine_) {
- UpdateCallback engine_callback{[this]() { OnChange(); }};
- const InputIdentifier input_identifier{
- .identifier = identifier,
- .type = EngineInputType::Nfc,
- .index = 0,
- .callback = engine_callback,
- };
- callback_key = input_engine->SetCallback(input_identifier);
- }
- ~InputFromNfc() override {
- input_engine->DeleteCallback(callback_key);
- }
- Common::Input::NfcStatus GetStatus() const {
- return input_engine->GetNfc(identifier);
- }
- void ForceUpdate() override {
- OnChange();
- }
- void OnChange() {
- const auto nfc_status = GetStatus();
- const Common::Input::CallbackStatus status{
- .type = Common::Input::InputType::Nfc,
- .nfc_status = nfc_status.state,
- .raw_data = nfc_status.data,
- };
- TriggerOnChange(status);
- }
- private:
- const PadIdentifier identifier;
- int callback_key;
- InputEngine* input_engine;
- };
- class OutputFromIdentifier final : public Common::Input::OutputDevice {
- public:
- explicit OutputFromIdentifier(PadIdentifier identifier_, InputEngine* input_engine_)
- : identifier(identifier_), input_engine(input_engine_) {}
- Common::Input::DriverResult SetLED(const Common::Input::LedStatus& led_status) override {
- return input_engine->SetLeds(identifier, led_status);
- }
- Common::Input::DriverResult SetVibration(
- const Common::Input::VibrationStatus& vibration_status) override {
- return input_engine->SetVibration(identifier, vibration_status);
- }
- bool IsVibrationEnabled() override {
- return input_engine->IsVibrationEnabled(identifier);
- }
- Common::Input::DriverResult SetPollingMode(Common::Input::PollingMode polling_mode) override {
- return input_engine->SetPollingMode(identifier, polling_mode);
- }
- Common::Input::DriverResult SetCameraFormat(
- Common::Input::CameraFormat camera_format) override {
- return input_engine->SetCameraFormat(identifier, camera_format);
- }
- Common::Input::NfcState SupportsNfc() const override {
- return input_engine->SupportsNfc(identifier);
- }
- Common::Input::NfcState WriteNfcData(const std::vector<u8>& data) override {
- return input_engine->WriteNfcData(identifier, data);
- }
- private:
- const PadIdentifier identifier;
- InputEngine* input_engine;
- };
- std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateButtonDevice(
- const Common::ParamPackage& params) {
- const PadIdentifier identifier = {
- .guid = Common::UUID{params.Get("guid", "")},
- .port = static_cast<std::size_t>(params.Get("port", 0)),
- .pad = static_cast<std::size_t>(params.Get("pad", 0)),
- };
- const auto button_id = params.Get("button", 0);
- const auto keyboard_key = params.Get("code", 0);
- const auto toggle = params.Get("toggle", false) != 0;
- const auto inverted = params.Get("inverted", false) != 0;
- const auto turbo = params.Get("turbo", false) != 0;
- input_engine->PreSetController(identifier);
- input_engine->PreSetButton(identifier, button_id);
- input_engine->PreSetButton(identifier, keyboard_key);
- if (keyboard_key != 0) {
- return std::make_unique<InputFromButton>(identifier, keyboard_key, turbo, toggle, inverted,
- input_engine.get());
- }
- return std::make_unique<InputFromButton>(identifier, button_id, turbo, toggle, inverted,
- input_engine.get());
- }
- std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateHatButtonDevice(
- const Common::ParamPackage& params) {
- const PadIdentifier identifier = {
- .guid = Common::UUID{params.Get("guid", "")},
- .port = static_cast<std::size_t>(params.Get("port", 0)),
- .pad = static_cast<std::size_t>(params.Get("pad", 0)),
- };
- const auto button_id = params.Get("hat", 0);
- const auto direction = input_engine->GetHatButtonId(params.Get("direction", ""));
- const auto toggle = params.Get("toggle", false) != 0;
- const auto inverted = params.Get("inverted", false) != 0;
- const auto turbo = params.Get("turbo", false) != 0;
- input_engine->PreSetController(identifier);
- input_engine->PreSetHatButton(identifier, button_id);
- return std::make_unique<InputFromHatButton>(identifier, button_id, direction, turbo, toggle,
- inverted, input_engine.get());
- }
- std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateStickDevice(
- const Common::ParamPackage& params) {
- const auto deadzone = std::clamp(params.Get("deadzone", 0.15f), 0.0f, 1.0f);
- const auto range = std::clamp(params.Get("range", 0.95f), 0.25f, 1.50f);
- const auto threshold = std::clamp(params.Get("threshold", 0.5f), 0.0f, 1.0f);
- const PadIdentifier identifier = {
- .guid = Common::UUID{params.Get("guid", "")},
- .port = static_cast<std::size_t>(params.Get("port", 0)),
- .pad = static_cast<std::size_t>(params.Get("pad", 0)),
- };
- const auto axis_x = params.Get("axis_x", 0);
- const Common::Input::AnalogProperties properties_x = {
- .deadzone = deadzone,
- .range = range,
- .threshold = threshold,
- .offset = std::clamp(params.Get("offset_x", 0.0f), -1.0f, 1.0f),
- .inverted = params.Get("invert_x", "+") == "-",
- };
- const auto axis_y = params.Get("axis_y", 1);
- const Common::Input::AnalogProperties properties_y = {
- .deadzone = deadzone,
- .range = range,
- .threshold = threshold,
- .offset = std::clamp(params.Get("offset_y", 0.0f), -1.0f, 1.0f),
- .inverted = params.Get("invert_y", "+") != "+",
- };
- input_engine->PreSetController(identifier);
- input_engine->PreSetAxis(identifier, axis_x);
- input_engine->PreSetAxis(identifier, axis_y);
- return std::make_unique<InputFromStick>(identifier, axis_x, axis_y, properties_x, properties_y,
- input_engine.get());
- }
- std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateAnalogDevice(
- const Common::ParamPackage& params) {
- const PadIdentifier identifier = {
- .guid = Common::UUID{params.Get("guid", "")},
- .port = static_cast<std::size_t>(params.Get("port", 0)),
- .pad = static_cast<std::size_t>(params.Get("pad", 0)),
- };
- const auto axis = params.Get("axis", 0);
- const Common::Input::AnalogProperties properties = {
- .deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, 1.0f),
- .range = std::clamp(params.Get("range", 1.0f), 0.25f, 1.50f),
- .threshold = std::clamp(params.Get("threshold", 0.5f), 0.0f, 1.0f),
- .offset = std::clamp(params.Get("offset", 0.0f), -1.0f, 1.0f),
- .inverted = params.Get("invert", "+") == "-",
- .inverted_button = params.Get("inverted", false) != 0,
- .toggle = params.Get("toggle", false) != 0,
- };
- input_engine->PreSetController(identifier);
- input_engine->PreSetAxis(identifier, axis);
- return std::make_unique<InputFromAnalog>(identifier, axis, properties, input_engine.get());
- }
- std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateTriggerDevice(
- const Common::ParamPackage& params) {
- const PadIdentifier identifier = {
- .guid = Common::UUID{params.Get("guid", "")},
- .port = static_cast<std::size_t>(params.Get("port", 0)),
- .pad = static_cast<std::size_t>(params.Get("pad", 0)),
- };
- const auto button = params.Get("button", 0);
- const auto toggle = params.Get("toggle", false) != 0;
- const auto inverted = params.Get("inverted", false) != 0;
- const auto axis = params.Get("axis", 0);
- const Common::Input::AnalogProperties properties = {
- .deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, 1.0f),
- .range = std::clamp(params.Get("range", 1.0f), 0.25f, 2.50f),
- .threshold = std::clamp(params.Get("threshold", 0.5f), 0.0f, 1.0f),
- .offset = std::clamp(params.Get("offset", 0.0f), -1.0f, 1.0f),
- .inverted = params.Get("invert", false) != 0,
- };
- input_engine->PreSetController(identifier);
- input_engine->PreSetAxis(identifier, axis);
- input_engine->PreSetButton(identifier, button);
- return std::make_unique<InputFromTrigger>(identifier, button, toggle, inverted, axis,
- properties, input_engine.get());
- }
- std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateTouchDevice(
- const Common::ParamPackage& params) {
- const auto deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, 1.0f);
- const auto range = std::clamp(params.Get("range", 1.0f), 0.25f, 1.50f);
- const auto threshold = std::clamp(params.Get("threshold", 0.5f), 0.0f, 1.0f);
- const PadIdentifier identifier = {
- .guid = Common::UUID{params.Get("guid", "")},
- .port = static_cast<std::size_t>(params.Get("port", 0)),
- .pad = static_cast<std::size_t>(params.Get("pad", 0)),
- };
- const auto button = params.Get("button", 0);
- const auto toggle = params.Get("toggle", false) != 0;
- const auto inverted = params.Get("inverted", false) != 0;
- const auto axis_x = params.Get("axis_x", 0);
- const Common::Input::AnalogProperties properties_x = {
- .deadzone = deadzone,
- .range = range,
- .threshold = threshold,
- .offset = std::clamp(params.Get("offset_x", 0.0f), -1.0f, 1.0f),
- .inverted = params.Get("invert_x", "+") == "-",
- };
- const auto axis_y = params.Get("axis_y", 1);
- const Common::Input::AnalogProperties properties_y = {
- .deadzone = deadzone,
- .range = range,
- .threshold = threshold,
- .offset = std::clamp(params.Get("offset_y", 0.0f), -1.0f, 1.0f),
- .inverted = params.Get("invert_y", false) != 0,
- };
- input_engine->PreSetController(identifier);
- input_engine->PreSetAxis(identifier, axis_x);
- input_engine->PreSetAxis(identifier, axis_y);
- input_engine->PreSetButton(identifier, button);
- return std::make_unique<InputFromTouch>(identifier, button, toggle, inverted, axis_x, axis_y,
- properties_x, properties_y, input_engine.get());
- }
- std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateBatteryDevice(
- const Common::ParamPackage& params) {
- const PadIdentifier identifier = {
- .guid = Common::UUID{params.Get("guid", "")},
- .port = static_cast<std::size_t>(params.Get("port", 0)),
- .pad = static_cast<std::size_t>(params.Get("pad", 0)),
- };
- input_engine->PreSetController(identifier);
- return std::make_unique<InputFromBattery>(identifier, input_engine.get());
- }
- std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateColorDevice(
- const Common::ParamPackage& params) {
- const PadIdentifier identifier = {
- .guid = Common::UUID{params.Get("guid", "")},
- .port = static_cast<std::size_t>(params.Get("port", 0)),
- .pad = static_cast<std::size_t>(params.Get("pad", 0)),
- };
- input_engine->PreSetController(identifier);
- return std::make_unique<InputFromColor>(identifier, input_engine.get());
- }
- std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateMotionDevice(
- Common::ParamPackage params) {
- const PadIdentifier identifier = {
- .guid = Common::UUID{params.Get("guid", "")},
- .port = static_cast<std::size_t>(params.Get("port", 0)),
- .pad = static_cast<std::size_t>(params.Get("pad", 0)),
- };
- if (params.Has("motion")) {
- const auto motion_sensor = params.Get("motion", 0);
- const auto gyro_threshold = params.Get("threshold", 0.007f);
- input_engine->PreSetController(identifier);
- input_engine->PreSetMotion(identifier, motion_sensor);
- return std::make_unique<InputFromMotion>(identifier, motion_sensor, gyro_threshold,
- input_engine.get());
- }
- const auto deadzone = std::clamp(params.Get("deadzone", 0.15f), 0.0f, 1.0f);
- const auto range = std::clamp(params.Get("range", 1.0f), 0.25f, 1.50f);
- const auto threshold = std::clamp(params.Get("threshold", 0.5f), 0.0f, 1.0f);
- const auto axis_x = params.Get("axis_x", 0);
- const Common::Input::AnalogProperties properties_x = {
- .deadzone = deadzone,
- .range = range,
- .threshold = threshold,
- .offset = std::clamp(params.Get("offset_x", 0.0f), -1.0f, 1.0f),
- .inverted = params.Get("invert_x", "+") == "-",
- };
- const auto axis_y = params.Get("axis_y", 1);
- const Common::Input::AnalogProperties properties_y = {
- .deadzone = deadzone,
- .range = range,
- .threshold = threshold,
- .offset = std::clamp(params.Get("offset_y", 0.0f), -1.0f, 1.0f),
- .inverted = params.Get("invert_y", "+") != "+",
- };
- const auto axis_z = params.Get("axis_z", 1);
- const Common::Input::AnalogProperties properties_z = {
- .deadzone = deadzone,
- .range = range,
- .threshold = threshold,
- .offset = std::clamp(params.Get("offset_z", 0.0f), -1.0f, 1.0f),
- .inverted = params.Get("invert_z", "+") != "+",
- };
- input_engine->PreSetController(identifier);
- input_engine->PreSetAxis(identifier, axis_x);
- input_engine->PreSetAxis(identifier, axis_y);
- input_engine->PreSetAxis(identifier, axis_z);
- return std::make_unique<InputFromAxisMotion>(identifier, axis_x, axis_y, axis_z, properties_x,
- properties_y, properties_z, input_engine.get());
- }
- std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateCameraDevice(
- const Common::ParamPackage& params) {
- const PadIdentifier identifier = {
- .guid = Common::UUID{params.Get("guid", "")},
- .port = static_cast<std::size_t>(params.Get("port", 0)),
- .pad = static_cast<std::size_t>(params.Get("pad", 0)),
- };
- input_engine->PreSetController(identifier);
- return std::make_unique<InputFromCamera>(identifier, input_engine.get());
- }
- std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateNfcDevice(
- const Common::ParamPackage& params) {
- const PadIdentifier identifier = {
- .guid = Common::UUID{params.Get("guid", "")},
- .port = static_cast<std::size_t>(params.Get("port", 0)),
- .pad = static_cast<std::size_t>(params.Get("pad", 0)),
- };
- input_engine->PreSetController(identifier);
- return std::make_unique<InputFromNfc>(identifier, input_engine.get());
- }
- InputFactory::InputFactory(std::shared_ptr<InputEngine> input_engine_)
- : input_engine(std::move(input_engine_)) {}
- std::unique_ptr<Common::Input::InputDevice> InputFactory::Create(
- const Common::ParamPackage& params) {
- if (params.Has("battery")) {
- return CreateBatteryDevice(params);
- }
- if (params.Has("color")) {
- return CreateColorDevice(params);
- }
- if (params.Has("camera")) {
- return CreateCameraDevice(params);
- }
- if (params.Has("nfc")) {
- return CreateNfcDevice(params);
- }
- if (params.Has("button") && params.Has("axis")) {
- return CreateTriggerDevice(params);
- }
- if (params.Has("button") && params.Has("axis_x") && params.Has("axis_y")) {
- return CreateTouchDevice(params);
- }
- if (params.Has("button") || params.Has("code")) {
- return CreateButtonDevice(params);
- }
- if (params.Has("hat")) {
- return CreateHatButtonDevice(params);
- }
- if (params.Has("axis_x") && params.Has("axis_y") && params.Has("axis_z")) {
- return CreateMotionDevice(params);
- }
- if (params.Has("motion")) {
- return CreateMotionDevice(params);
- }
- if (params.Has("axis_x") && params.Has("axis_y")) {
- return CreateStickDevice(params);
- }
- if (params.Has("axis")) {
- return CreateAnalogDevice(params);
- }
- LOG_ERROR(Input, "Invalid parameters given");
- return std::make_unique<DummyInput>();
- }
- OutputFactory::OutputFactory(std::shared_ptr<InputEngine> input_engine_)
- : input_engine(std::move(input_engine_)) {}
- std::unique_ptr<Common::Input::OutputDevice> OutputFactory::Create(
- const Common::ParamPackage& params) {
- const PadIdentifier identifier = {
- .guid = Common::UUID{params.Get("guid", "")},
- .port = static_cast<std::size_t>(params.Get("port", 0)),
- .pad = static_cast<std::size_t>(params.Get("pad", 0)),
- };
- input_engine->PreSetController(identifier);
- return std::make_unique<OutputFromIdentifier>(identifier, input_engine.get());
- }
- } // namespace InputCommon
|