internal static string OnFindControlLayoutForDevice(int deviceId, ref InputDeviceDescription description, string matchedTemplate, IInputRuntime runtime) { if (description.interfaceName != "Android" || string.IsNullOrEmpty(description.capabilities)) { return(null); } ////TODO: these should just be Controller and Sensor; the interface is already Android switch (description.deviceClass) { case "AndroidGameController": { var caps = AndroidDeviceCapabilities.FromJson(description.capabilities); if ((caps.inputSources & AndroidInputSource.Gamepad) == AndroidInputSource.Gamepad) { if (caps.motionAxes != null) { if (caps.motionAxes.Contains(AndroidAxis.HatX) && caps.motionAxes.Contains(AndroidAxis.HatY)) { return("AndroidGamepadWithDpadAxes"); } } return("AndroidGamepadWithDpadButtons"); } return("AndroidJoystick"); } default: return(null); } }
internal static string OnFindLayoutForDevice(int deviceId, ref InputDeviceDescription description, string matchedTemplate, IInputRuntime runtime) { if (description.interfaceName != "Android" || string.IsNullOrEmpty(description.capabilities)) { return(null); } ////TODO: these should just be Controller and Sensor; the interface is already Android switch (description.deviceClass) { case "AndroidGameController": { var caps = AndroidDeviceCapabilities.FromJson(description.capabilities); // Note: Gamepads have both AndroidInputSource.Gamepad and AndroidInputSource.Joystick in input source, while // Joysticks don't have AndroidInputSource.Gamepad in their input source if ((caps.inputSources & AndroidInputSource.Gamepad) != AndroidInputSource.Gamepad) { return("AndroidJoystick"); } if (caps.motionAxes == null) { return("AndroidGamepadWithDpadButtons"); } // Vendor Ids, Product Ids can be found here http://www.linux-usb.org/usb.ids const int kVendorMicrosoft = 0x045e; if (caps.vendorId == kVendorMicrosoft && caps.motionAxes != null && caps.motionAxes.Contains(AndroidAxis.Rx) && caps.motionAxes.Contains(AndroidAxis.Ry) && caps.motionAxes.Contains(AndroidAxis.HatX) && caps.motionAxes.Contains(AndroidAxis.HatY)) { return("AndroidGamepadXboxController"); } // Fallback to generic gamepads if (caps.motionAxes.Contains(AndroidAxis.HatX) && caps.motionAxes.Contains(AndroidAxis.HatY)) { return("AndroidGamepadWithDpadAxes"); } return("AndroidGamepadWithDpadButtons"); } default: return(null); } }
internal static string OnFindLayoutForDevice(int deviceId, ref InputDeviceDescription description, string matchedTemplate, IInputRuntime runtime) { if (description.interfaceName != "Android" || string.IsNullOrEmpty(description.capabilities)) { return(null); } ////TODO: these should just be Controller and Sensor; the interface is already Android switch (description.deviceClass) { case "AndroidGameController": { var caps = AndroidDeviceCapabilities.FromJson(description.capabilities); // Note: Gamepads have both AndroidInputSource.Gamepad and AndroidInputSource.Joystick in input source, while // Joysticks don't have AndroidInputSource.Gamepad in their input source if ((caps.inputSources & AndroidInputSource.Gamepad) != AndroidInputSource.Gamepad) { return("AndroidJoystick"); } // Most of the gamepads: // - NVIDIA Controller v01.03/v01.04 // - ELAN PLAYSTATION(R)3 Controller // - My-Power CO.,LTD. PS(R) Controller Adaptor // - (Add more) // map buttons in the following way: // Left Stick -> AXIS_X(0) / AXIS_Y(1) // Right Stick -> AXIS_Z (11) / AXIS_RZ(14) // Right Thumb -> KEYCODE_BUTTON_THUMBR(107) // Left Thumb -> KEYCODE_BUTTON_THUMBL(106) // L1 (Left shoulder) -> KEYCODE_BUTTON_L1(102) // R1 (Right shoulder) -> KEYCODE_BUTTON_R1(103) // L2 (Left trigger) -> AXIS_BRAKE(23) // R2 (Right trigger) -> AXIS_GAS(22) // X -> KEYCODE_BUTTON_X(99) // Y -> KEYCODE_BUTTON_Y(100) // B -> KEYCODE_BUTTON_B(97) // A -> KEYCODE_BUTTON_A(96) // DPAD -> AXIS_HAT_X(15),AXIS_HAT_Y(16) or KEYCODE_DPAD_LEFT(21), KEYCODE_DPAD_RIGHT(22), KEYCODE_DPAD_UP(19), KEYCODE_DPAD_DOWN(20), // Note: On Nvidia Shield Console, L2/R2 additionally invoke key events for AXIS_LTRIGGER, AXIS_RTRIGGER (in addition to AXIS_BRAKE, AXIS_GAS) // If you connect gamepad to a phone for L2/R2 only AXIS_BRAKE/AXIS_GAS come. AXIS_LTRIGGER, AXIS_RTRIGGER are not invoked. // That's why we map triggers only to AXIS_BRAKE/AXIS_GAS // Other exotic gamepads have different mappings // Xbox Gamepad (for ex., Microsoft X-Box One pad (Firmware 2015)) mapping (Note mapping: L2/R2/Right Stick) // Left Stick -> AXIS_X(0) / AXIS_Y(1) // Right Stick -> AXIS_RX (12) / AXIS_RY(13) // Right Thumb -> KEYCODE_BUTTON_THUMBR(107) // Left Thumb -> KEYCODE_BUTTON_THUMBL(106) // L1 (Left shoulder) -> KEYCODE_BUTTON_L1(102) // R1 (Right shoulder) -> KEYCODE_BUTTON_R1(103) // L2 (Left trigger) -> AXIS_Z(11) // R2 (Right trigger) -> AXIS_RZ(14) // X -> KEYCODE_BUTTON_X(99) // Y -> KEYCODE_BUTTON_Y(100) // B -> KEYCODE_BUTTON_B(97) // A -> KEYCODE_BUTTON_A(96) // DPAD -> AXIS_HAT_X(15),AXIS_HAT_Y(16) // Sony's Dualshock // Left Stick -> AXIS_X(0) / AXIS_Y(1) // Right Stick -> AXIS_Z(11) / AXIS_RZ(14) // Right Thumb -> KEYCODE_BUTTON_START(108) // Left Thumb -> KEYCODE_BUTTON_SELECT(109) // X -> KEYCODE_BUTTON_A(96), // Y -> KEYCODE_BUTTON_X(99) // B -> KEYCODE_BUTTON_C(98), // A -> KEYCODE_BUTTON_B(97) // L1 -> KEYCODE_BUTTON_Y(100) // R1 -> KEYCODE_BUTTON_Z(101) // L2 -> KEYCODE_BUTTON_L1(102), AXIS_RX(12), // R2 -> KEYCODE_BUTTON_R1(103), AXIS_RY(13), // DPAD -> AXIS_HAT_X(15),AXIS_HAT_Y(16), // Share -> KEYCODE_BUTTON_L2(104) // Options -> KEYCODE_BUTTON_R2(105), // Click on Touchpad -> KEYCODE_BUTTON_THUMBL(106) if (caps.motionAxes == null) { return("AndroidGamepadWithDpadButtons"); } // Vendor Ids, Product Ids can be found here http://www.linux-usb.org/usb.ids const int kVendorMicrosoft = 0x045e; const int kVendorSonyCorp = 0x54c; const int kDualShock4CUHZCT1x = 0x05c4; const int kDualShock4CUHZCT2x = 0x09cc; if (caps.vendorId == kVendorMicrosoft && caps.motionAxes != null && caps.motionAxes.Contains(AndroidAxis.Rx) && caps.motionAxes.Contains(AndroidAxis.Ry) && caps.motionAxes.Contains(AndroidAxis.HatX) && caps.motionAxes.Contains(AndroidAxis.HatY)) { return("AndroidGamepadXboxController"); } if (caps.vendorId == kVendorSonyCorp && (caps.productId == kDualShock4CUHZCT1x || caps.productId == kDualShock4CUHZCT2x)) { return("AndroidGamepadDualShock"); } // Fallback to generic gamepads if (caps.motionAxes.Contains(AndroidAxis.HatX) && caps.motionAxes.Contains(AndroidAxis.HatY)) { return("AndroidGamepadWithDpadAxes"); } return("AndroidGamepadWithDpadButtons"); } default: return(null); } }
internal static string OnFindLayoutForDevice(ref InputDeviceDescription description, string matchedLayout, InputDeviceExecuteCommandDelegate executeCommandDelegate) { // If we already have a matching layout, someone registered a better match. // We only want to act as a fallback. if (!string.IsNullOrEmpty(matchedLayout) && matchedLayout != "AndroidGamepad" && matchedLayout != "AndroidJoystick") { return(null); } if (description.interfaceName != "Android" || string.IsNullOrEmpty(description.capabilities)) { return(null); } ////TODO: these should just be Controller and Sensor; the interface is already Android switch (description.deviceClass) { case "AndroidGameController": { var caps = AndroidDeviceCapabilities.FromJson(description.capabilities); // Note: Gamepads have both AndroidInputSource.Gamepad and AndroidInputSource.Joystick in input source, while // Joysticks don't have AndroidInputSource.Gamepad in their input source if ((caps.inputSources & AndroidInputSource.Gamepad) != AndroidInputSource.Gamepad) { return("AndroidJoystick"); } if (caps.motionAxes == null) { return("AndroidGamepadWithDpadButtons"); } // Vendor Ids, Product Ids can be found here http://www.linux-usb.org/usb.ids const int kVendorMicrosoft = 0x045e; const int kVendorSony = 0x054c; // Tested with controllers: PS4 DualShock; XboxOne; Nvidia Shield // Tested on devices: Shield console Android 9; Galaxy s9+ Android 10 if (caps.motionAxes.Contains(AndroidAxis.Z) && caps.motionAxes.Contains(AndroidAxis.Rz) && caps.motionAxes.Contains(AndroidAxis.HatX) && caps.motionAxes.Contains(AndroidAxis.HatY)) { if (caps.vendorId == kVendorMicrosoft) { return("XboxOneGamepadAndroid"); } if (caps.vendorId == kVendorSony) { return("DualShock4GamepadAndroid"); } } // Fallback to generic gamepads if (caps.motionAxes.Contains(AndroidAxis.HatX) && caps.motionAxes.Contains(AndroidAxis.HatY)) { return("AndroidGamepadWithDpadAxes"); } return("AndroidGamepadWithDpadButtons"); } default: return(null); } }