Skip to content

Commit

Permalink
[gamepad] Add support for SCUF Vantage, Vantage 2 gamepads
Browse files Browse the repository at this point in the history
SCUF Vantage gamepads are designed to work with Playstation 4
consoles and behave mostly the same as genuine Sony DualShock 4
gamepads, but expose a different vendor and product ID. Both
SCUF Vantage and SCUF Vantage 2 expose the same IDs (2e95:7725).

This CL enables Dualshock4Controller to recognize the SCUF
Vantage and Vantage 2 as PS4-compatible devices and applies the
mapping functions used for DualShock 4.

BUG=1017414

Change-Id: Ic55dc5d2b36c456061eb8bb76b0d0c9f0b85a1d1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1880635
Reviewed-by: Ovidio de Jesús Ruiz-Henríquez <odejesush@chromium.org>
Commit-Queue: Matt Reynolds <mattreynolds@chromium.org>
Cr-Commit-Position: refs/heads/master@{#715153}
  • Loading branch information
Matt Reynolds authored and Commit Bot committed Nov 14, 2019
1 parent 92e2496 commit 215a5be
Show file tree
Hide file tree
Showing 11 changed files with 44 additions and 13 deletions.
24 changes: 18 additions & 6 deletions device/gamepad/dualshock4_controller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,14 @@ static float NormalizeDpad(uint8_t value) {

} // namespace

Dualshock4Controller::Dualshock4Controller(GamepadBusType bus_type,
Dualshock4Controller::Dualshock4Controller(uint16_t vendor_id,
uint16_t product_id,
GamepadBusType bus_type,
std::unique_ptr<HidWriter> writer)
: bus_type_(bus_type), writer_(std::move(writer)) {}
: vendor_id_(vendor_id),
product_id_(product_id),
bus_type_(bus_type),
writer_(std::move(writer)) {}

Dualshock4Controller::~Dualshock4Controller() = default;

Expand All @@ -133,7 +138,8 @@ bool Dualshock4Controller::IsDualshock4(uint16_t vendor_id,
uint16_t product_id) {
auto gamepad_id = GamepadIdList::Get().GetGamepadId(vendor_id, product_id);
return gamepad_id == GamepadId::kSonyProduct05c4 ||
gamepad_id == GamepadId::kSonyProduct09cc;
gamepad_id == GamepadId::kSonyProduct09cc ||
gamepad_id == GamepadId::kVendor2e95Product7725;
}

// static
Expand Down Expand Up @@ -210,10 +216,16 @@ bool Dualshock4Controller::ProcessInputReport(uint8_t report_id,

void Dualshock4Controller::SetVibration(double strong_magnitude,
double weak_magnitude) {
if (bus_type_ == GAMEPAD_BUS_BLUETOOTH)
// Genuine DualShock 4 gamepads use an alternate output report when connected
// over Bluetooth. Always send USB-mode reports to SCUF Vantage gamepads.
if (bus_type_ == GAMEPAD_BUS_BLUETOOTH &&
GamepadIdList::Get().GetGamepadId(vendor_id_, product_id_) !=
GamepadId::kVendor2e95Product7725) {
SetVibrationBluetooth(strong_magnitude, weak_magnitude);
else
SetVibrationUsb(strong_magnitude, weak_magnitude);
return;
}

SetVibrationUsb(strong_magnitude, weak_magnitude);
}

void Dualshock4Controller::SetVibrationUsb(double strong_magnitude,
Expand Down
6 changes: 5 additions & 1 deletion device/gamepad/dualshock4_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ class HidWriter;
class DEVICE_GAMEPAD_EXPORT Dualshock4Controller final
: public AbstractHapticGamepad {
public:
Dualshock4Controller(GamepadBusType bus_type,
Dualshock4Controller(uint16_t vendor_id,
uint16_t product_id,
GamepadBusType bus_type,
std::unique_ptr<HidWriter> hid_writer);
~Dualshock4Controller() override;

Expand Down Expand Up @@ -55,6 +57,8 @@ class DEVICE_GAMEPAD_EXPORT Dualshock4Controller final
// Dualshock4.
void SetVibrationBluetooth(double strong_magnitude, double weak_magnitude);

uint16_t vendor_id_;
uint16_t product_id_;
GamepadBusType bus_type_;
std::unique_ptr<HidWriter> writer_;
base::WeakPtrFactory<Dualshock4Controller> weak_factory_{this};
Expand Down
10 changes: 7 additions & 3 deletions device/gamepad/dualshock4_controller_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ namespace device {

namespace {

constexpr uint16_t kVendorIdSony = 0x054c;
constexpr uint16_t kProductIdDualShock4 = 0x05c4;
constexpr size_t kUsbReportLength = 32;
constexpr size_t kBluetoothReportLength = 78;

Expand Down Expand Up @@ -126,13 +128,15 @@ class Dualshock4ControllerTest : public testing::Test {
// for Bluetooth.
auto usb_writer = std::make_unique<FakeHidWriter>();
usb_writer_ = usb_writer.get();
ds4_usb_ = std::make_unique<Dualshock4Controller>(GAMEPAD_BUS_USB,
std::move(usb_writer));
ds4_usb_ = std::make_unique<Dualshock4Controller>(
kVendorIdSony, kProductIdDualShock4, GAMEPAD_BUS_USB,
std::move(usb_writer));

auto bluetooth_writer = std::make_unique<FakeHidWriter>();
bluetooth_writer_ = bluetooth_writer.get();
ds4_bluetooth_ = std::make_unique<Dualshock4Controller>(
GAMEPAD_BUS_BLUETOOTH, std::move(bluetooth_writer));
kVendorIdSony, kProductIdDualShock4, GAMEPAD_BUS_BLUETOOTH,
std::move(bluetooth_writer));
}

void TearDown() override {
Expand Down
3 changes: 2 additions & 1 deletion device/gamepad/gamepad_device_linux.cc
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,8 @@ void GamepadDeviceLinux::InitializeHidraw(base::ScopedFD fd) {

if (is_dualshock4 && !dualshock4_) {
dualshock4_ = std::make_unique<Dualshock4Controller>(
bus_type_, std::make_unique<HidWriterLinux>(hidraw_fd_));
vendor_id, product_id, bus_type_,
std::make_unique<HidWriterLinux>(hidraw_fd_));
}

if (is_xbox_hid && !xbox_hid_) {
Expand Down
3 changes: 2 additions & 1 deletion device/gamepad/gamepad_device_mac.mm
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ GamepadBusType QueryBusType(IOHIDDeviceRef device) {
ff_effect_ref_(nullptr) {
if (Dualshock4Controller::IsDualshock4(vendor_id, product_id)) {
dualshock4_ = std::make_unique<Dualshock4Controller>(
bus_type_, std::make_unique<HidWriterMac>(device_ref));
vendor_id, product_id, bus_type_,
std::make_unique<HidWriterMac>(device_ref));
return;
}

Expand Down
1 change: 1 addition & 0 deletions device/gamepad/gamepad_id_list.cc
Original file line number Diff line number Diff line change
Expand Up @@ -581,6 +581,7 @@ constexpr struct GamepadInfo {
{0x2dc8, 0x3820, kXInputTypeNone},
{0x2dc8, 0x9001, kXInputTypeNone},
{0x2dfa, 0x0001, kXInputTypeNone},
{0x2e95, 0x7725, kXInputTypeNone},
{0x3767, 0x0101, kXInputTypeXbox},
{0x3820, 0x0009, kXInputTypeNone},
{0x4c50, 0x5453, kXInputTypeNone},
Expand Down
1 change: 1 addition & 0 deletions device/gamepad/gamepad_id_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ enum class GamepadId : uint32_t {
kVendor2378Product1008 = 0x23781008,
kVendor2378Product100a = 0x2378100a,
kVendor2836Product0001 = 0x28360001,
kVendor2e95Product7725 = 0x2e957725,
};

class DEVICE_GAMEPAD_EXPORT GamepadIdList {
Expand Down
2 changes: 2 additions & 0 deletions device/gamepad/gamepad_standard_mappings_linux.cc
Original file line number Diff line number Diff line change
Expand Up @@ -786,6 +786,8 @@ constexpr struct MappingData {
{GamepadId::kVendor2378Product100a, MapperOnLiveWireless},
// OUYA Controller
{GamepadId::kVendor2836Product0001, MapperOUYA},
// SCUF Vantage, SCUF Vantage 2
{GamepadId::kVendor2e95Product7725, MapperDualshock4},
// boom PSX+N64 USB Converter
{GamepadId::kPrototypeVendorProduct0667, MapperBoomN64Psx},
// Stadia Controller prototype
Expand Down
2 changes: 2 additions & 0 deletions device/gamepad/gamepad_standard_mappings_mac.mm
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,8 @@ void MapperXboxAdaptiveControllerBluetooth(const Gamepad& input,
{GamepadId::kVendor2378Product100a, MapperOnLiveWireless},
// OUYA Controller
{GamepadId::kVendor2836Product0001, MapperOUYA},
// SCUF Vantage, SCUF Vantage 2
{GamepadId::kVendor2e95Product7725, MapperDualshock4},
// boom PSX+N64 USB Converter
{GamepadId::kPrototypeVendorProduct0667, MapperBoomN64Psx},
// Stadia Controller prototype
Expand Down
2 changes: 2 additions & 0 deletions device/gamepad/gamepad_standard_mappings_win.cc
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,8 @@ constexpr struct MappingData {
{GamepadId::kVendor2378Product100a, MapperOnLiveWireless},
// OUYA Controller
{GamepadId::kVendor2836Product0001, MapperOUYA},
// SCUF Vantage, SCUF Vantage 2
{GamepadId::kVendor2e95Product7725, MapperDualshock4},
// boom PSX+N64 USB Converter
{GamepadId::kPrototypeVendorProduct0667, MapperBoomN64Psx},
// Stadia Controller prototype
Expand Down
3 changes: 2 additions & 1 deletion device/gamepad/raw_input_gamepad_device_win.cc
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ RawInputGamepadDeviceWin::RawInputGamepadDeviceWin(
GamepadBusType bus_type =
Dualshock4Controller::BusTypeFromVersionNumber(version_number_);
dualshock4_ = std::make_unique<Dualshock4Controller>(
bus_type, std::make_unique<HidWriterWin>(handle_));
vendor_id_, product_id_, bus_type,
std::make_unique<HidWriterWin>(handle_));
} else if (HidHapticGamepad::IsHidHaptic(vendor_id_, product_id_)) {
hid_haptics_ = HidHapticGamepad::Create(
vendor_id_, product_id_, std::make_unique<HidWriterWin>(handle_));
Expand Down

0 comments on commit 215a5be

Please sign in to comment.