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

cellPad: scale emulated skateboard IR input down #16049

Merged
merged 2 commits into from
Sep 6, 2024
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 116 additions & 7 deletions rpcs3/Emu/Cell/Modules/cellPad.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "Emu/Cell/lv2/sys_process.h"
#include "Emu/Cell/lv2/sys_sync.h"
#include "Emu/Io/pad_types.h"
#include "Emu/RSX/Overlays/overlay_debug_overlay.h"
#include "Input/pad_thread.h"
#include "Input/product_info.h"
#include "cellPad.h"
Expand Down Expand Up @@ -73,6 +74,96 @@ void pad_info::save(utils::serial& ar)
sys_io_serialize(ar);
}

void show_debug_overlay(const CellPadData& data, const Pad& pad, const pad_info& config)
{
const u32 setting = config.port_setting[pad.m_player_id];
const u16 d1 = data.button[CELL_PAD_BTN_OFFSET_DIGITAL1];
const u16 d2 = data.button[CELL_PAD_BTN_OFFSET_DIGITAL2];

std::string text = fmt::format(
"> Name: Raw Value Pressure\n"
">\n"
"> Len: %13d\n"
"> Digital: %5s %5s\n"
"> Press: %5s %5s\n"
"> Sensor: %5s %5s\n"
">\n"
"> Digital 1: 0x%04x 0x%04x\n"
"> Digital 2: 0x%04x 0x%04x\n"
">\n"
"> D-Pad Up: %5d %5d %5d\n"
"> D-Pad Down: %5d %5d %5d\n"
"> D-Pad Left: %5d %5d %5d\n"
"> D-Pad Right: %5d %5d %5d\n"
"> Cross: %5d %5d %5d\n"
"> Square: %5d %5d %5d\n"
"> Circle: %5d %5d %5d\n"
"> Triangle: %5d %5d %5d\n"
"> Start: %5d %5d\n"
"> Select: %5d %5d\n"
"> PS: %5d %5d\n"
"> L1: %5d %5d %5d\n"
"> L2: %5d %5d %5d\n"
"> L3: %5d %5d\n"
"> R1: %5d %5d %5d\n"
"> R2: %5d %5d %5d\n"
"> R3: %5d %5d\n"
"> LS X: %5d %5d\n"
"> LS Y: %5d %5d\n"
"> RS X: %5d %5d\n"
"> RS Y: %5d %5d\n"
">\n"
"> Sensor X: %5d %5d\n"
"> Sensor Y: %5d %5d\n"
"> Sensor Z: %5d %5d\n"
"> Sensor G: %5d %5d\n"
">\n"
"> PID: 0x%04x\n"
"> VID: 0x%04x\n"
"> Device Type: 0x%08x\n"
"> Class Type: 0x%08x\n"
,
data.len,
"on", data.len >= CELL_PAD_LEN_CHANGE_DEFAULT ? "on" : "off",
(setting & CELL_PAD_SETTING_PRESS_ON) ? "on" : "off", data.len >= CELL_PAD_LEN_CHANGE_PRESS_ON ? "on" : "off",
(setting & CELL_PAD_SETTING_SENSOR_ON) ? "on" : "off", data.len >= CELL_PAD_LEN_CHANGE_SENSOR_ON ? "on" : "off",
pad.m_digital_1, d1,
pad.m_digital_2, d2,
pad.m_press_up, !!(d1 & CELL_PAD_CTRL_UP), data.button[CELL_PAD_BTN_OFFSET_PRESS_UP],
pad.m_press_down, !!(d1 & CELL_PAD_CTRL_DOWN), data.button[CELL_PAD_BTN_OFFSET_PRESS_DOWN],
pad.m_press_left, !!(d1 & CELL_PAD_CTRL_LEFT), data.button[CELL_PAD_BTN_OFFSET_PRESS_LEFT],
pad.m_press_right, !!(d1 & CELL_PAD_CTRL_RIGHT), data.button[CELL_PAD_BTN_OFFSET_PRESS_RIGHT],
pad.m_press_cross, !!(d2 & CELL_PAD_CTRL_CROSS), data.button[CELL_PAD_BTN_OFFSET_PRESS_CROSS],
pad.m_press_square, !!(d2 & CELL_PAD_CTRL_SQUARE), data.button[CELL_PAD_BTN_OFFSET_PRESS_SQUARE],
pad.m_press_circle, !!(d2 & CELL_PAD_CTRL_CIRCLE), data.button[CELL_PAD_BTN_OFFSET_PRESS_CIRCLE],
pad.m_press_triangle, !!(d2 & CELL_PAD_CTRL_TRIANGLE), data.button[CELL_PAD_BTN_OFFSET_PRESS_TRIANGLE],
!!(pad.m_digital_1 & CELL_PAD_CTRL_START), !!(d1 & CELL_PAD_CTRL_START),
!!(pad.m_digital_1 & CELL_PAD_CTRL_SELECT), !!(d1 & CELL_PAD_CTRL_SELECT),
!!(pad.m_digital_1 & CELL_PAD_CTRL_PS), !!(d1 & CELL_PAD_CTRL_PS),
pad.m_press_L1, !!(d2 & CELL_PAD_CTRL_L1), data.button[CELL_PAD_BTN_OFFSET_PRESS_L1],
pad.m_press_L2, !!(d2 & CELL_PAD_CTRL_L2), data.button[CELL_PAD_BTN_OFFSET_PRESS_L2],
!!(pad.m_digital_1 & CELL_PAD_CTRL_L3), !!(d1 & CELL_PAD_CTRL_L3),
pad.m_press_R1, !!(d2 & CELL_PAD_CTRL_R1), data.button[CELL_PAD_BTN_OFFSET_PRESS_R1],
pad.m_press_R2, !!(d2 & CELL_PAD_CTRL_R2), data.button[CELL_PAD_BTN_OFFSET_PRESS_R2],
!!(pad.m_digital_1 & CELL_PAD_CTRL_R3), !!(d1 & CELL_PAD_CTRL_R3),
pad.m_analog_left_x, data.button[CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X],
pad.m_analog_left_y, data.button[CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y],
pad.m_analog_right_x, data.button[CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X],
pad.m_analog_right_y, data.button[CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y],
pad.m_sensor_x, data.button[CELL_PAD_BTN_OFFSET_SENSOR_X],
pad.m_sensor_y, data.button[CELL_PAD_BTN_OFFSET_SENSOR_Y],
pad.m_sensor_z, data.button[CELL_PAD_BTN_OFFSET_SENSOR_Z],
pad.m_sensor_g, data.button[CELL_PAD_BTN_OFFSET_SENSOR_G],
pad.m_product_id,
pad.m_vendor_id,
pad.m_device_type,
pad.m_class_type
);

//CELL_PAD_SETTING_LDD = 0x00000001, // Speculative
rsx::overlays::set_debug_overlay_text(std::move(text));
}

extern void send_sys_io_connect_event(usz index, u32 state);

bool cellPad_NotifyStateChange(usz index, u64 /*state*/, bool locked, bool is_blocking = true)
Expand Down Expand Up @@ -297,10 +388,22 @@ void pad_get_data(u32 port_no, CellPadData* data, bool get_periph_data = false)
// Curiously it maps infrared on the press value of the face buttons for some reason.
const bool use_piggyback = pad->m_class_type == CELL_PAD_PCLASS_TYPE_SKATEBOARD;

const auto set_value = [&btnChanged, use_piggyback](u16& value, u16 new_value, bool is_piggyback = false)
const auto set_value = [&btnChanged, use_piggyback, &pad](u16& value, u16 new_value, bool force_processing = false, u16 old_max_value = 255, u16 new_max_value = 255)
{
if (use_piggyback && !is_piggyback)
return;
if (use_piggyback)
{
if (!force_processing)
return;

// Some piggyback values need to be scaled down on emulated devices
if (old_max_value != new_max_value)
{
if (pad->m_class_type == CELL_PAD_PCLASS_TYPE_SKATEBOARD && pad->m_pad_handler != pad_handler::skateboard)
{
new_value = static_cast<u16>(new_max_value * std::clamp(new_value / static_cast<f32>(old_max_value), 0.0f, 1.0f));
}
}
}

if (value != new_value)
{
Expand Down Expand Up @@ -367,10 +470,10 @@ void pad_get_data(u32 port_no, CellPadData* data, bool get_periph_data = false)
case CELL_PAD_CTRL_PRESS_LEFT: set_value(pad->m_press_left, button.m_value, true); break;
case CELL_PAD_CTRL_PRESS_UP: set_value(pad->m_press_up, button.m_value, true); break;
case CELL_PAD_CTRL_PRESS_DOWN: set_value(pad->m_press_down, button.m_value, true); break;
case CELL_PAD_CTRL_PRESS_TRIANGLE: set_value(pad->m_press_triangle, button.m_value, true); break;
case CELL_PAD_CTRL_PRESS_CIRCLE: set_value(pad->m_press_circle, button.m_value, true); break;
case CELL_PAD_CTRL_PRESS_CROSS: set_value(pad->m_press_cross, button.m_value, true); break;
case CELL_PAD_CTRL_PRESS_SQUARE: set_value(pad->m_press_square, button.m_value, true); break;
case CELL_PAD_CTRL_PRESS_TRIANGLE: set_value(pad->m_press_triangle, button.m_value, true, 255, 63); break; // Infrared on RIDE Skateboard
case CELL_PAD_CTRL_PRESS_CIRCLE: set_value(pad->m_press_circle, button.m_value, true, 255, 63); break; // Infrared on RIDE Skateboard
case CELL_PAD_CTRL_PRESS_CROSS: set_value(pad->m_press_cross, button.m_value, true, 255, 63); break; // Infrared on RIDE Skateboard
case CELL_PAD_CTRL_PRESS_SQUARE: set_value(pad->m_press_square, button.m_value, true, 255, 63); break; // Infrared on RIDE Skateboard
case CELL_PAD_CTRL_PRESS_L1: set_value(pad->m_press_L1, button.m_value, true); break;
case CELL_PAD_CTRL_PRESS_R1: set_value(pad->m_press_R1, button.m_value, true); break;
case CELL_PAD_CTRL_PRESS_L2: set_value(pad->m_press_L2, button.m_value, true); break;
Expand Down Expand Up @@ -614,6 +717,12 @@ error_code cellPadGetData(u32 port_no, vm::ptr<CellPadData> data)
return not_an_error(CELL_PAD_ERROR_NO_DEVICE);

pad_get_data(port_no, data.get_ptr());

if (g_cfg.io.debug_overlay && !g_cfg.video.overlay && port_no == 0)
{
show_debug_overlay(*data, *pad, config);
}

return CELL_OK;
}

Expand Down
4 changes: 2 additions & 2 deletions rpcs3/Emu/RSX/Overlays/overlay_debug_overlay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ namespace rsx
{
auto overlay = manager->get<rsx::overlays::debug_overlay>();

if (g_cfg.video.overlay)
if (g_cfg.video.overlay || g_cfg.io.debug_overlay)
{
if (!overlay)
{
Expand All @@ -66,7 +66,7 @@ namespace rsx

extern void set_debug_overlay_text(std::string&& text)
{
if (!g_cfg.misc.use_native_interface || !g_cfg.video.overlay)
if (!g_cfg.misc.use_native_interface || (!g_cfg.video.overlay && !g_cfg.io.debug_overlay))
return;

if (auto manager = g_fxo->try_get<rsx::overlays::display_manager>())
Expand Down
1 change: 1 addition & 0 deletions rpcs3/Emu/system_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ struct cfg_root : cfg::node
cfg::_bool lock_overlay_input_to_player_one{this, "Lock overlay input to player one", false, true};
cfg::string midi_devices{this, "Emulated Midi devices", "ßßß@@@ßßß@@@ßßß@@@"};
cfg::_bool load_sdl_mappings{ this, "Load SDL GameController Mappings", true };
cfg::_bool debug_overlay{ this, "IO Debug overlay", false, true };

} io{ this };

Expand Down
2 changes: 2 additions & 0 deletions rpcs3/rpcs3qt/emu_settings_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ enum class emu_settings_type
GHLtar,
MidiDevices,
SDLMappings,
IoDebugOverlay,

// Misc
ExitRPCS3OnFinish,
Expand Down Expand Up @@ -354,6 +355,7 @@ inline static const QMap<emu_settings_type, cfg_location> settings_location =
{ emu_settings_type::GHLtar, { "Input/Output", "GHLtar emulated controller" }},
{ emu_settings_type::MidiDevices, { "Input/Output", "Emulated Midi devices" }},
{ emu_settings_type::SDLMappings, { "Input/Output", "Load SDL GameController Mappings" }},
{ emu_settings_type::IoDebugOverlay, { "Input/Output", "IO Debug overlay" }},

// Misc
{ emu_settings_type::ExitRPCS3OnFinish, { "Miscellaneous", "Exit RPCS3 when process finishes" }},
Expand Down
4 changes: 4 additions & 0 deletions rpcs3/rpcs3qt/settings_dialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2437,6 +2437,10 @@ settings_dialog::settings_dialog(std::shared_ptr<gui_settings> gui_settings, std
m_emu_settings->EnhanceCheckBox(ui->perfReport, emu_settings_type::PerformanceReport);
SubscribeTooltip(ui->perfReport, tooltips.settings.enable_performance_report);

// Checkboxes: IO debug options
m_emu_settings->EnhanceCheckBox(ui->debugOverlayIO, emu_settings_type::IoDebugOverlay);
SubscribeTooltip(ui->debugOverlayIO, tooltips.settings.debug_overlay_io);

// Comboboxes

m_emu_settings->EnhanceComboBox(ui->combo_accurate_ppu_128, emu_settings_type::AccuratePPU128Loop, true);
Expand Down
34 changes: 33 additions & 1 deletion rpcs3/rpcs3qt/settings_dialog.ui
Original file line number Diff line number Diff line change
Expand Up @@ -4364,7 +4364,7 @@
</item>
<item>
<widget class="QWidget" name="debug_more_stuff" native="true">
<layout class="QVBoxLayout" name="debug_more_stuff_layout">
<layout class="QVBoxLayout" name="debug_more_stuff_layout" stretch="0,0,0,0,1">
<property name="leftMargin">
<number>0</number>
</property>
Expand Down Expand Up @@ -4424,6 +4424,38 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="gb_debug_io">
<property name="title">
<string>I/O</string>
</property>
<layout class="QVBoxLayout" name="gb_debug_io_layout">
<item>
<widget class="QCheckBox" name="debugOverlayIO">
<property name="text">
<string>Debug Overlay For Pad Input</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacerDebugMore">
<property name="orientation">
Expand Down
1 change: 1 addition & 0 deletions rpcs3/rpcs3qt/tooltips.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ class Tooltips : public QObject
const QString force_high_pz = tr("Only useful when debugging differences in GPU hardware.\nNot necessary for average users.\nIf unsure, don't use this option.");
const QString debug_output = tr("Enables the selected API's inbuilt debugging functionality.\nWill cause severe performance degradation especially with Vulkan.\nOnly useful to developers.\nIf unsure, don't use this option.");
const QString debug_overlay = tr("Provides a graphical overlay of various debugging information.\nIf unsure, don't use this option.");
const QString debug_overlay_io = tr("Provides a graphical overlay with pad input values for player 1.\nThis is only shown if the other debug overlay is disabled.\nIf unsure, don't use this option.");
const QString log_shader_programs = tr("Dump game shaders to file. Only useful to developers.\nIf unsure, don't use this option.");
const QString disable_occlusion_queries = tr("Disables running occlusion queries. Minor to moderate performance boost.\nMight introduce issues with broken occlusion e.g missing geometry and extreme pop-in.");
const QString disable_video_output = tr("Disables all video output and PS3 graphical rendering.\nIts only use case is to evaluate performance on CELL for development.");
Expand Down