2020-12-31 19:02:03 +01:00
|
|
|
// Buzz! buzzer emulator
|
|
|
|
|
|
|
|
|
|
#include "stdafx.h"
|
|
|
|
|
#include "Buzz.h"
|
|
|
|
|
#include "Emu/Cell/lv2/sys_usbd.h"
|
2023-05-21 13:26:32 +02:00
|
|
|
#include "Emu/Io/buzz_config.h"
|
2020-12-31 19:02:03 +01:00
|
|
|
#include "Input/pad_thread.h"
|
|
|
|
|
|
2023-05-20 12:31:33 +02:00
|
|
|
LOG_CHANNEL(buzz_log, "BUZZ");
|
2020-12-31 19:02:03 +01:00
|
|
|
|
2023-05-21 15:57:57 +02:00
|
|
|
template <>
|
|
|
|
|
void fmt_class_string<buzz_btn>::format(std::string& out, u64 arg)
|
|
|
|
|
{
|
|
|
|
|
format_enum(out, arg, [](buzz_btn value)
|
|
|
|
|
{
|
|
|
|
|
switch (value)
|
|
|
|
|
{
|
|
|
|
|
case buzz_btn::red: return "Red";
|
|
|
|
|
case buzz_btn::yellow: return "Yellow";
|
|
|
|
|
case buzz_btn::green: return "Green";
|
|
|
|
|
case buzz_btn::orange: return "Orange";
|
|
|
|
|
case buzz_btn::blue: return "Blue";
|
|
|
|
|
case buzz_btn::count: return "Count";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return unknown;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-20 10:54:20 +02:00
|
|
|
usb_device_buzz::usb_device_buzz(u32 first_controller, u32 last_controller, const std::array<u8, 7>& location)
|
2021-11-23 15:52:41 +01:00
|
|
|
: usb_device_emulated(location)
|
2023-05-20 10:54:20 +02:00
|
|
|
, m_first_controller(first_controller)
|
|
|
|
|
, m_last_controller(last_controller)
|
2020-12-31 19:02:03 +01:00
|
|
|
{
|
|
|
|
|
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)
|
|
|
|
|
{
|
2022-07-05 22:49:20 +02:00
|
|
|
case 0x01:
|
|
|
|
|
case 0x21:
|
|
|
|
|
case 0x80:
|
2023-05-20 10:54:20 +02:00
|
|
|
buzz_log.error("Unhandled Query: buf_size=0x%02X, Type=0x%02X, bmRequestType=0x%02X", buf_size, (buf_size > 0) ? buf[0] : -1, bmRequestType);
|
2022-07-05 22:49:20 +02:00
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
usb_device_emulated::control_transfer(bmRequestType, bRequest, wValue, wIndex, wLength, buf_size, buf, transfer);
|
|
|
|
|
break;
|
2020-12-31 19:02:03 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-05 21:47:05 +02:00
|
|
|
extern bool is_input_allowed();
|
|
|
|
|
|
2021-03-05 20:05:37 +01:00
|
|
|
void usb_device_buzz::interrupt_transfer(u32 buf_size, u8* buf, u32 /*endpoint*/, UsbTransfer* transfer)
|
2020-12-31 19:02:03 +01:00
|
|
|
{
|
2023-05-20 10:54:20 +02:00
|
|
|
const u8 max_index = 2 + (4 + 5 * m_last_controller) / 8;
|
|
|
|
|
ensure(buf_size > max_index);
|
|
|
|
|
|
2020-12-31 19:02:03 +01:00
|
|
|
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;
|
|
|
|
|
|
2022-07-05 21:47:05 +02:00
|
|
|
if (!is_input_allowed())
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-08 18:50:37 +02:00
|
|
|
std::lock_guard lock(pad::g_pad_mutex);
|
2020-12-31 19:02:03 +01:00
|
|
|
const auto handler = pad::get_current_handler();
|
|
|
|
|
const auto& pads = handler->GetPads();
|
2023-05-20 10:54:20 +02:00
|
|
|
ensure(pads.size() > m_last_controller);
|
2023-05-21 13:26:32 +02:00
|
|
|
ensure(g_cfg_buzz.players.size() > m_last_controller);
|
2020-12-31 19:02:03 +01:00
|
|
|
|
2023-05-20 10:54:20 +02:00
|
|
|
for (u32 i = m_first_controller, index = 0; i <= m_last_controller; i++, index++)
|
2020-12-31 19:02:03 +01:00
|
|
|
{
|
2023-05-20 10:54:20 +02:00
|
|
|
const auto& pad = pads[i];
|
2020-12-31 19:02:03 +01:00
|
|
|
|
|
|
|
|
if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
|
2022-07-05 22:49:20 +02:00
|
|
|
{
|
2020-12-31 19:02:03 +01:00
|
|
|
continue;
|
2022-07-05 22:49:20 +02:00
|
|
|
}
|
2020-12-31 19:02:03 +01:00
|
|
|
|
2023-05-22 23:10:13 +02:00
|
|
|
const auto& cfg = g_cfg_buzz.players[i];
|
2023-05-30 19:47:35 +02:00
|
|
|
cfg->handle_input(pad, true, [&buf, &index](buzz_btn btn, u16 /*value*/, bool pressed)
|
2020-12-31 19:02:03 +01:00
|
|
|
{
|
2023-05-30 19:47:35 +02:00
|
|
|
if (!pressed)
|
|
|
|
|
return;
|
|
|
|
|
|
2023-05-22 23:10:13 +02:00
|
|
|
switch (btn)
|
2020-12-31 19:02:03 +01:00
|
|
|
{
|
2023-05-20 12:31:33 +02:00
|
|
|
case buzz_btn::red:
|
2022-07-05 22:49:20 +02:00
|
|
|
buf[2 + (0 + 5 * index) / 8] |= 1 << ((0 + 5 * index) % 8); // Red
|
|
|
|
|
break;
|
2023-05-20 12:31:33 +02:00
|
|
|
case buzz_btn::yellow:
|
|
|
|
|
buf[2 + (1 + 5 * index) / 8] |= 1 << ((1 + 5 * index) % 8); // Yellow
|
2022-07-05 22:49:20 +02:00
|
|
|
break;
|
2023-05-20 12:31:33 +02:00
|
|
|
case buzz_btn::green:
|
2022-07-05 22:49:20 +02:00
|
|
|
buf[2 + (2 + 5 * index) / 8] |= 1 << ((2 + 5 * index) % 8); // Green
|
|
|
|
|
break;
|
2023-05-20 12:31:33 +02:00
|
|
|
case buzz_btn::orange:
|
|
|
|
|
buf[2 + (3 + 5 * index) / 8] |= 1 << ((3 + 5 * index) % 8); // Orange
|
2022-07-05 22:49:20 +02:00
|
|
|
break;
|
2023-05-20 12:31:33 +02:00
|
|
|
case buzz_btn::blue:
|
|
|
|
|
buf[2 + (4 + 5 * index) / 8] |= 1 << ((4 + 5 * index) % 8); // Blue
|
2022-07-05 22:49:20 +02:00
|
|
|
break;
|
2023-05-21 13:43:27 +02:00
|
|
|
case buzz_btn::count:
|
|
|
|
|
break;
|
2020-12-31 19:02:03 +01:00
|
|
|
}
|
2023-05-22 23:10:13 +02:00
|
|
|
});
|
2020-12-31 19:02:03 +01:00
|
|
|
}
|
|
|
|
|
}
|