Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Buzz! emulated controller #9504

Merged
merged 3 commits into from
Dec 31, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 4 additions & 4 deletions Utilities/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,15 +82,15 @@ bool cfg::try_to_int64(s64* out, const std::string& value, s64 min, s64 max)

if (ret.ec != std::errc() || ret.ptr != end || (start[0] == '-' && sign < 0))
{
if (out) cfg_log.error("cfg::try_to_int('%s'): invalid integer", value);
if (out) cfg_log.error("cfg::try_to_int64('%s'): invalid integer", value);
return false;
}

result *= sign;

if (result < min || result > max)
{
if (out) cfg_log.error("cfg::try_to_int('%s'): out of bounds (%d..%d)", value, min, max);
if (out) cfg_log.error("cfg::try_to_int64('%s'): out of bounds (%d..%d)", value, min, max);
return false;
}

Expand Down Expand Up @@ -121,13 +121,13 @@ bool cfg::try_to_uint64(u64* out, const std::string& value, u64 min, u64 max)

if (ret.ec != std::errc() || ret.ptr != end)
{
if (out) cfg_log.error("cfg::try_to_int('%s'): invalid integer", value);
if (out) cfg_log.error("cfg::try_to_uint64('%s'): invalid integer", value);
return false;
}

if (result < min || result > max)
{
if (out) cfg_log.error("cfg::try_to_int('%s'): out of bounds (%u..%u)", value, min, max);
if (out) cfg_log.error("cfg::try_to_uint64('%s'): out of bounds (%u..%u)", value, min, max);
return false;
}

Expand Down
1 change: 1 addition & 0 deletions rpcs3/Emu/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,7 @@ target_sources(rpcs3_emu PRIVATE
Io/usb_device.cpp
Io/Skylander.cpp
Io/GHLtar.cpp
Io/Buzz.cpp
)

# Np
Expand Down
23 changes: 19 additions & 4 deletions rpcs3/Emu/Cell/lv2/sys_usbd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "Emu/Io/usb_device.h"
#include "Emu/Io/Skylander.h"
#include "Emu/Io/GHLtar.h"
#include "Emu/Io/Buzz.h"

#include <libusb.h>

Expand Down Expand Up @@ -144,6 +145,7 @@ usb_handler_thread::usb_handler_thread()

bool found_skylander = false;
bool found_ghltar = false;
bool found_buzz = false;

for (ssize_t index = 0; index < ndev; index++)
{
Expand Down Expand Up @@ -197,10 +199,14 @@ usb_handler_thread::usb_handler_thread()
check_device(0x044F, 0xB660, 0xB660, "Thrustmaster T500 RS Gear Shift");

// Buzz controllers
check_device(0x054C, 0x1000, 0x1040, "buzzer0");
check_device(0x054C, 0x0001, 0x0041, "buzzer1");
check_device(0x054C, 0x0042, 0x0042, "buzzer2");
check_device(0x046D, 0xC220, 0xC220, "buzzer9");
if (check_device(0x054C, 0x1000, 0x1040, "buzzer0"))
found_buzz = true;
if (check_device(0x054C, 0x0001, 0x0041, "buzzer1"))
AniLeo marked this conversation as resolved.
Show resolved Hide resolved
found_buzz = true;
if (check_device(0x054C, 0x0042, 0x0042, "buzzer2"))
AniLeo marked this conversation as resolved.
Show resolved Hide resolved
found_buzz = true;
if (check_device(0x046D, 0xC220, 0xC220, "buzzer9"))
found_buzz = true;

// GCon3 Gun
check_device(0x0B9A, 0x0800, 0x0800, "guncon3");
Expand All @@ -223,6 +229,15 @@ usb_handler_thread::usb_handler_thread()
usb_devices.push_back(std::make_shared<usb_device_ghltar>());
}

if (!found_buzz)
{
sys_usbd.notice("Adding emulated Buzz! buzzer");
usb_devices.push_back(std::make_shared<usb_device_buzz>(0, 3));
// The current buzz emulation piggybacks on the pad input.
// Since there can only be 7 pads connected on a PS3 the 8th player is currently not supported
usb_devices.push_back(std::make_shared<usb_device_buzz>(4, 6));
}

for (u32 index = 0; index < MAX_SYS_USBD_TRANSFERS; index++)
{
transfers[index].transfer = libusb_alloc_transfer(8);
Expand Down
104 changes: 104 additions & 0 deletions rpcs3/Emu/Io/Buzz.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// Buzz! buzzer emulator

#include "stdafx.h"
#include "Buzz.h"
#include "Emu/Cell/lv2/sys_usbd.h"
#include "Input/pad_thread.h"

LOG_CHANNEL(buzz_log);

usb_device_buzz::usb_device_buzz(int first_controller, int last_controller)
{
this->first_controller = first_controller;
this->last_controller = last_controller;

device = UsbDescriptorNode(USB_DESCRIPTOR_DEVICE, UsbDeviceDescriptor{0x0200, 0x00, 0x00, 0x00, 0x08, 0x054c, 0x0002, 0x05a1, 0x03, 0x01, 0x00, 0x01});
auto& config0 = device.add_node(UsbDescriptorNode(USB_DESCRIPTOR_CONFIG, UsbDeviceConfiguration{0x0022, 0x01, 0x01, 0x00, 0x80, 0x32}));
config0.add_node(UsbDescriptorNode(USB_DESCRIPTOR_INTERFACE, UsbDeviceInterface{0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00}));
config0.add_node(UsbDescriptorNode(USB_DESCRIPTOR_HID, UsbDeviceHID{0x0111, 0x33, 0x01, 0x22, 0x004e}));
config0.add_node(UsbDescriptorNode(USB_DESCRIPTOR_ENDPOINT, UsbDeviceEndpoint{0x81, 0x03, 0x0008, 0x0A}));
}

usb_device_buzz::~usb_device_buzz()
{
}

void usb_device_buzz::control_transfer(u8 bmRequestType, u8 bRequest, u16 wValue, u16 wIndex, u16 wLength, u32 buf_size, u8* buf, UsbTransfer* transfer)
{
transfer->fake = true;

// Control transfers are nearly instant
switch (bmRequestType)
{
case 0x01:
case 0x21:
case 0x80:
buzz_log.error("Unhandled Query Len: 0x%02X", buf_size);
buzz_log.error("Unhandled Query Type: 0x%02X", (buf_size > 0) ? buf[0] : -1);
break;
default:
usb_device_emulated::control_transfer(bmRequestType, bRequest, wValue, wIndex, wLength, buf_size, buf, transfer);
break;
}
}

void usb_device_buzz::interrupt_transfer(u32 buf_size, u8* buf, u32 endpoint, UsbTransfer* transfer)
{
transfer->fake = true;
transfer->expected_count = 5;
transfer->expected_result = HC_CC_NOERR;
// Interrupt transfers are slow (6ms, TODO accurate measurement)
transfer->expected_time = get_timestamp() + 6000;

memset(buf, 0, buf_size);

// https://gist.github.com/Lewiscowles1986/eef220dac6f0549e4702393a7b9351f6
buf[0] = 0x7f;
buf[1] = 0x7f;
buf[2] = 0x00;
buf[3] = 0x00;
buf[4] = 0xf0;

const auto handler = pad::get_current_handler();
const auto& pads = handler->GetPads();

for (int index = 0; index <= (last_controller - first_controller); index++)
{
const auto pad = pads[first_controller + index];

if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
continue;

for (Button& button : pad->m_buttons)
{
if (button.m_offset == CELL_PAD_BTN_OFFSET_DIGITAL2)
{
switch (button.m_outKeyCode)
{
case CELL_PAD_CTRL_R1:
if (button.m_pressed)
buf[2 + (0 + 5 * index) / 8] |= 1 << ((0 + 5 * index) % 8); // Red
break;
case CELL_PAD_CTRL_TRIANGLE:
if (button.m_pressed)
buf[2 + (4 + 5 * index) / 8] |= 1 << ((4 + 5 * index) % 8); // Blue
break;
case CELL_PAD_CTRL_SQUARE:
if (button.m_pressed)
buf[2 + (3 + 5 * index) / 8] |= 1 << ((3 + 5 * index) % 8); // Orange
break;
case CELL_PAD_CTRL_CIRCLE:
if (button.m_pressed)
buf[2 + (2 + 5 * index) / 8] |= 1 << ((2 + 5 * index) % 8); // Green
break;
case CELL_PAD_CTRL_CROSS:
if (button.m_pressed)
buf[2 + (1 + 5 * index) / 8] |= 1 << ((1 + 5 * index) % 8); // Yellow
break;
default:
break;
}
}
}
}
}
16 changes: 16 additions & 0 deletions rpcs3/Emu/Io/Buzz.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#pragma once

#include "Emu/Io/usb_device.h"

class usb_device_buzz : public usb_device_emulated
{
int first_controller;
int last_controller;

public:
usb_device_buzz(int first_controller, int last_controller);
~usb_device_buzz();

void control_transfer(u8 bmRequestType, u8 bRequest, u16 wValue, u16 wIndex, u16 wLength, u32 buf_size, u8* buf, UsbTransfer* transfer) override;
Florin9doi marked this conversation as resolved.
Show resolved Hide resolved
void interrupt_transfer(u32 buf_size, u8* buf, u32 endpoint, UsbTransfer* transfer) override;
};
2 changes: 2 additions & 0 deletions rpcs3/emucore.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="Emu\Io\GHLtar.cpp" />
<ClCompile Include="Emu\Io\Buzz.cpp" />
<ClCompile Include="Emu\Audio\AudioBackend.cpp" />
<ClCompile Include="Emu\Io\interception.cpp" />
<ClCompile Include="Emu\Io\KeyboardHandler.cpp" />
Expand Down Expand Up @@ -445,6 +446,7 @@
<ClInclude Include="Emu\Cell\Modules\cellSsl.h" />
<ClInclude Include="Emu\Cell\Modules\cellStorage.h" />
<ClInclude Include="Emu\Io\GHLtar.h" />
<ClInclude Include="Emu\Io\Buzz.h" />
<ClInclude Include="Emu\Io\interception.h" />
<ClInclude Include="Emu\Io\pad_types.h" />
<ClInclude Include="Emu\Io\Keyboard.h" />
Expand Down
6 changes: 6 additions & 0 deletions rpcs3/emucore.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -896,6 +896,9 @@
<ClCompile Include="Emu\Io\GHLtar.cpp">
<Filter>Emu\Io</Filter>
</ClCompile>
<ClCompile Include="Emu\Io\Buzz.cpp">
<Filter>Emu\Io</Filter>
</ClCompile>
<ClCompile Include="Emu\Cell\lv2\sys_crypto_engine.cpp">
<Filter>Emu\Cell\lv2</Filter>
</ClCompile>
Expand Down Expand Up @@ -1807,6 +1810,9 @@
<ClInclude Include="Emu\Io\GHLtar.h">
<Filter>Emu\Io</Filter>
</ClInclude>
<ClInclude Include="Emu\Io\Buzz.h">
<Filter>Emu\Io</Filter>
</ClInclude>
<ClInclude Include="Emu\NP\np_handler.h">
<Filter>Emu\NP</Filter>
</ClInclude>
Expand Down