1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-22 10:42:36 +01:00

input: add turntable config file

No sticks yet
This commit is contained in:
Megamouse 2023-05-20 13:45:22 +02:00
parent 7b9a36be7d
commit 8b5f7a0770
6 changed files with 270 additions and 115 deletions

View File

@ -5,9 +5,9 @@
#include "Emu/Cell/lv2/sys_usbd.h"
#include "Input/pad_thread.h"
LOG_CHANNEL(turntable_log);
LOG_CHANNEL(turntable_log, "TURN");
usb_device_turntable::usb_device_turntable(int controller_index, const std::array<u8, 7>& location)
usb_device_turntable::usb_device_turntable(u32 controller_index, const std::array<u8, 7>& location)
: usb_device_emulated(location), m_controller_index(controller_index)
{
device = UsbDescriptorNode(USB_DESCRIPTOR_DEVICE, UsbDeviceDescriptor{0x0100, 0x00, 0x00, 0x00, 0x40, 0x12BA, 0x0140, 0x0005, 0x01, 0x02, 0x00, 0x01});
@ -16,6 +16,11 @@ usb_device_turntable::usb_device_turntable(int controller_index, const std::arra
config0.add_node(UsbDescriptorNode(USB_DESCRIPTOR_HID, UsbDeviceHID{0x0110, 0x00, 0x01, 0x22, 0x0089}));
config0.add_node(UsbDescriptorNode(USB_DESCRIPTOR_ENDPOINT, UsbDeviceEndpoint{0x81, 0x03, 0x0040, 0x0a}));
config0.add_node(UsbDescriptorNode(USB_DESCRIPTOR_ENDPOINT, UsbDeviceEndpoint{0x02, 0x03, 0x0040, 0x0a}));
if (!m_cfg.load())
{
turntable_log.notice("Could not load turntable config. Using defaults.");
}
}
usb_device_turntable::~usb_device_turntable()
@ -121,59 +126,54 @@ void usb_device_turntable::interrupt_transfer(u32 buf_size, u8* buf, u32 /*endpo
std::lock_guard lock(pad::g_pad_mutex);
const auto handler = pad::get_current_handler();
const auto& pad = handler->GetPads()[m_controller_index];
const auto& pads = handler->GetPads();
const auto& pad = ::at32(pads, m_controller_index);
const auto& cfg = ::at32(m_cfg.players, m_controller_index);
if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
return;
for (const Button& button : pad->m_buttons)
{
if (button.m_pressed)
if (!button.m_pressed)
continue;
if (const auto btn = cfg->find_button(button.m_offset, button.m_outKeyCode))
{
if (button.m_offset == CELL_PAD_BTN_OFFSET_DIGITAL2)
switch (btn.value())
{
switch (button.m_outKeyCode)
{
case CELL_PAD_CTRL_SQUARE:
case turntable_btn::blue:
buf[0] |= 0x01; // Square Button
buf[7] = ~buf[7]; // Square Button
buf[23] |= 0x04; // Right Platter Blue
break;
case CELL_PAD_CTRL_CROSS:
case turntable_btn::green:
buf[0] |= 0x02; // Cross Button
buf[9] = ~buf[9]; // Cross Button
buf[23] |= 0x01; // Right Platter Green
break;
case CELL_PAD_CTRL_CIRCLE:
case turntable_btn::red:
buf[0] |= 0x04; // Circle Button
buf[12] = ~buf[12]; // Circle Button
buf[23] |= 0x02; // Right Platter Red
break;
case CELL_PAD_CTRL_TRIANGLE:
case turntable_btn::triangle:
buf[0] |= 0x08; // Triangle Button / Euphoria
buf[11] = ~buf[11]; // Triangle Button / Euphoria
break;
case CELL_PAD_CTRL_R1:
case turntable_btn::cross:
buf[0] |= 0x02; // Cross Button Only
buf[9] = ~buf[9]; // Cross Button Only
break;
case CELL_PAD_CTRL_L1:
case turntable_btn::circle:
buf[0] |= 0x04; // Circle Button Only
buf[12] = ~buf[12]; // Circle Button Only
break;
case CELL_PAD_CTRL_R2:
case turntable_btn::square:
buf[0] |= 0x01; // Square Button Only
buf[7] = ~buf[7]; // Square Button Only
break;
default:
break;
}
}
else if (button.m_offset == CELL_PAD_BTN_OFFSET_DIGITAL1)
{
switch (button.m_outKeyCode)
{
case CELL_PAD_CTRL_DOWN:
case turntable_btn::dpad_down:
if (buf[2] == 0x02) // Right D-Pad
{
buf[2] = 0x03; // Right-Down D-Pad
@ -188,7 +188,7 @@ void usb_device_turntable::interrupt_transfer(u32 buf_size, u8* buf, u32 /*endpo
}
buf[10] = ~buf[10]; // Down D-Pad;
break;
case CELL_PAD_CTRL_UP:
case turntable_btn::dpad_up:
if (buf[2] == 0x02) // Right D-Pad
{
buf[2] = 0x01; // Right-Up D-Pad
@ -203,7 +203,7 @@ void usb_device_turntable::interrupt_transfer(u32 buf_size, u8* buf, u32 /*endpo
}
buf[9] = ~buf[9]; // Up D-Pad;
break;
case CELL_PAD_CTRL_LEFT:
case turntable_btn::dpad_left:
if (buf[2] == 0x00) // Up D-Pad
{
buf[2] = 0x07; // Left-Up D-Pad
@ -218,7 +218,7 @@ void usb_device_turntable::interrupt_transfer(u32 buf_size, u8* buf, u32 /*endpo
}
buf[8] = ~buf[8]; // Left D-Pad;
break;
case CELL_PAD_CTRL_RIGHT:
case turntable_btn::dpad_right:
if (buf[2] == 0x00) // Up D-Pad
{
buf[2] = 0x01; // Right-Up D-Pad
@ -233,18 +233,16 @@ void usb_device_turntable::interrupt_transfer(u32 buf_size, u8* buf, u32 /*endpo
}
buf[7] = ~buf[7]; // Right D-Pad
break;
case CELL_PAD_CTRL_START:
case turntable_btn::start:
buf[1] |= 0x02; // Start
break;
case CELL_PAD_CTRL_SELECT:
case turntable_btn::select:
buf[1] |= 0x01; // Select
break;
default:
break;
}
}
}
}
for (const AnalogStick& stick : pad->m_sticks)
{
switch (stick.m_offset)

View File

@ -1,16 +1,18 @@
#pragma once
#include "Emu/Io/usb_device.h"
#include "Emu/Io/turntable_config.h"
class usb_device_turntable : public usb_device_emulated
{
private:
int m_controller_index;
public:
usb_device_turntable(int controller_index, const std::array<u8, 7>& location);
usb_device_turntable(u32 controller_index, const std::array<u8, 7>& location);
~usb_device_turntable();
void control_transfer(u8 bmRequestType, u8 bRequest, u16 wValue, u16 wIndex, u16 wLength, u32 buf_size, u8* buf, UsbTransfer* transfer) override;
void interrupt_transfer(u32 buf_size, u8* buf, u32 endpoint, UsbTransfer* transfer) override;
private:
u32 m_controller_index;
cfg_turntables m_cfg;
};

View File

@ -0,0 +1,86 @@
#include "stdafx.h"
#include "turntable_config.h"
LOG_CHANNEL(turntable_log, "TURN");
std::optional<turntable_btn> cfg_turntable::find_button(u32 offset, u32 keycode) const
{
if (const auto it = buttons.find(offset); it != buttons.cend())
{
if (const auto it2 = it->second.find(keycode); it2 != it->second.cend())
{
return it2->second;
}
}
return std::nullopt;
}
bool cfg_turntables::load()
{
bool result = false;
const std::string cfg_name = fs::get_config_dir() + "config/turntable.yml";
turntable_log.notice("Loading turntable config: %s", cfg_name);
from_default();
for (cfg_turntable* player : players)
{
player->buttons.clear();
}
if (fs::file cfg_file{ cfg_name, fs::read })
{
if (std::string content = cfg_file.to_string(); !content.empty())
{
result = from_string(content);
}
}
else
{
save();
}
for (cfg_turntable* player : players)
{
const auto set_button = [&player](pad_button pbtn, turntable_btn bbtn)
{
const u32 offset = pad_button_offset(pbtn);
const u32 keycode = pad_button_keycode(pbtn);
player->buttons[(offset >> 8) & 0xFF][keycode & 0xFF] = bbtn;
};
set_button(player->red, turntable_btn::red);
set_button(player->green, turntable_btn::green);
set_button(player->blue, turntable_btn::blue);
set_button(player->dpad_up, turntable_btn::dpad_up);
set_button(player->dpad_down, turntable_btn::dpad_down);
set_button(player->dpad_left, turntable_btn::dpad_left);
set_button(player->dpad_right, turntable_btn::dpad_right);
set_button(player->start, turntable_btn::start);
set_button(player->select, turntable_btn::select);
set_button(player->square, turntable_btn::square);
set_button(player->circle, turntable_btn::circle);
set_button(player->cross, turntable_btn::cross);
set_button(player->triangle, turntable_btn::triangle);
}
return result;
}
void cfg_turntables::save() const
{
const std::string cfg_name = fs::get_config_dir() + "config/turntable.yml";
turntable_log.notice("Saving turntable config to '%s'", cfg_name);
if (!fs::create_path(fs::get_parent_dir(cfg_name)))
{
turntable_log.fatal("Failed to create path: %s (%s)", cfg_name, fs::g_tls_error);
}
fs::pending_file cfg_file(cfg_name);
if (!cfg_file.file || (cfg_file.file.write(to_string()), !cfg_file.commit()))
{
turntable_log.error("Failed to save turntable config to '%s' (error=%s)", cfg_name, fs::g_tls_error);
}
}

View File

@ -0,0 +1,61 @@
#pragma once
#include "Utilities/Config.h"
#include "pad_types.h"
#include <array>
enum class turntable_btn
{
red,
green,
blue,
dpad_up,
dpad_down,
dpad_left,
dpad_right,
start,
select,
square,
circle,
cross,
triangle
};
struct cfg_turntable final : cfg::node
{
cfg_turntable(node* owner, const std::string& name) : cfg::node(owner, name) {}
cfg::_enum<pad_button> blue{ this, "Blue", pad_button::square };
cfg::_enum<pad_button> green{ this, "Green", pad_button::cross };
cfg::_enum<pad_button> red{ this, "Red", pad_button::circle };
cfg::_enum<pad_button> dpad_up{ this, "D-Pad Up", pad_button::dpad_up };
cfg::_enum<pad_button> dpad_down{ this, "D-Pad Down", pad_button::dpad_down };
cfg::_enum<pad_button> dpad_left{ this, "D-Pad Left", pad_button::dpad_left };
cfg::_enum<pad_button> dpad_right{ this, "D-Pad Right", pad_button::dpad_right };
cfg::_enum<pad_button> start{ this, "Start", pad_button::start };
cfg::_enum<pad_button> select{ this, "Select", pad_button::select };
cfg::_enum<pad_button> square{ this, "Square", pad_button::R2 };
cfg::_enum<pad_button> circle{ this, "Circle", pad_button::L1 };
cfg::_enum<pad_button> cross{ this, "Cross", pad_button::R1 };
cfg::_enum<pad_button> triangle{ this, "Triangle", pad_button::triangle };
std::map<u32, std::map<u32, turntable_btn>> buttons;
std::optional<turntable_btn> find_button(u32 offset, u32 keycode) const;
};
struct cfg_turntables final : cfg::node
{
cfg_turntable player1{ this, "Player 1" };
cfg_turntable player2{ this, "Player 2" };
cfg_turntable player3{ this, "Player 3" };
cfg_turntable player4{ this, "Player 4" };
cfg_turntable player5{ this, "Player 5" };
cfg_turntable player6{ this, "Player 6" };
cfg_turntable player7{ this, "Player 7" };
std::array<cfg_turntable*, 7> players{ &player1, &player2, &player3, &player4, &player5, &player6, &player7 }; // Thanks gcc!
bool load();
void save() const;
};

View File

@ -78,6 +78,7 @@
<ClCompile Include="Emu\Io\Turntable.cpp" />
<ClCompile Include="Emu\Io\GHLtar.cpp" />
<ClCompile Include="Emu\Io\Buzz.cpp" />
<ClCompile Include="Emu\Io\turntable_config.cpp" />
<ClCompile Include="Emu\Io\usio.cpp" />
<ClCompile Include="Emu\Audio\AudioBackend.cpp" />
<ClCompile Include="Emu\Io\interception.cpp" />
@ -519,6 +520,7 @@
<ClInclude Include="Emu\Io\Turntable.h" />
<ClInclude Include="Emu\Io\GHLtar.h" />
<ClInclude Include="Emu\Io\Buzz.h" />
<ClInclude Include="Emu\Io\turntable_config.h" />
<ClInclude Include="Emu\Io\usio.h" />
<ClInclude Include="Emu\Io\interception.h" />
<ClInclude Include="Emu\Io\pad_types.h" />

View File

@ -1168,6 +1168,9 @@
<ClCompile Include="Emu\Io\pad_types.cpp">
<Filter>Emu\Io</Filter>
</ClCompile>
<ClCompile Include="Emu\Io\turntable_config.cpp">
<Filter>Emu\Io</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Crypto\aes.h">
@ -2353,6 +2356,9 @@
<ClInclude Include="Emu\Io\buzz_config.h">
<Filter>Emu\Io</Filter>
</ClInclude>
<ClInclude Include="Emu\Io\turntable_config.h">
<Filter>Emu\Io</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="Emu\RSX\Program\GLSLSnippets\GPUDeswizzle.glsl">