diff --git a/rpcs3/Emu/Cell/Modules/cellPad.cpp b/rpcs3/Emu/Cell/Modules/cellPad.cpp index b7dfa25bf6..4d7d4f92ec 100644 --- a/rpcs3/Emu/Cell/Modules/cellPad.cpp +++ b/rpcs3/Emu/Cell/Modules/cellPad.cpp @@ -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" @@ -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) @@ -626,6 +717,12 @@ error_code cellPadGetData(u32 port_no, vm::ptr 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; } diff --git a/rpcs3/Emu/RSX/Overlays/overlay_debug_overlay.cpp b/rpcs3/Emu/RSX/Overlays/overlay_debug_overlay.cpp index 31fde89f29..2f6aca17a2 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_debug_overlay.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlay_debug_overlay.cpp @@ -50,7 +50,7 @@ namespace rsx { auto overlay = manager->get(); - if (g_cfg.video.overlay) + if (g_cfg.video.overlay || g_cfg.io.debug_overlay) { if (!overlay) { @@ -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()) diff --git a/rpcs3/Emu/system_config.h b/rpcs3/Emu/system_config.h index 9dc23e1f7f..236c4269d7 100644 --- a/rpcs3/Emu/system_config.h +++ b/rpcs3/Emu/system_config.h @@ -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 }; diff --git a/rpcs3/rpcs3qt/emu_settings_type.h b/rpcs3/rpcs3qt/emu_settings_type.h index 8a208c07d5..202b873f64 100644 --- a/rpcs3/rpcs3qt/emu_settings_type.h +++ b/rpcs3/rpcs3qt/emu_settings_type.h @@ -162,6 +162,7 @@ enum class emu_settings_type GHLtar, MidiDevices, SDLMappings, + IoDebugOverlay, // Misc ExitRPCS3OnFinish, @@ -354,6 +355,7 @@ inline static const QMap 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" }}, diff --git a/rpcs3/rpcs3qt/settings_dialog.cpp b/rpcs3/rpcs3qt/settings_dialog.cpp index 1a23d5d388..73563abcfd 100644 --- a/rpcs3/rpcs3qt/settings_dialog.cpp +++ b/rpcs3/rpcs3qt/settings_dialog.cpp @@ -2437,6 +2437,10 @@ settings_dialog::settings_dialog(std::shared_ptr 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); diff --git a/rpcs3/rpcs3qt/settings_dialog.ui b/rpcs3/rpcs3qt/settings_dialog.ui index ca7a5f9c87..7d3d81a88b 100644 --- a/rpcs3/rpcs3qt/settings_dialog.ui +++ b/rpcs3/rpcs3qt/settings_dialog.ui @@ -4364,7 +4364,7 @@ - + 0 @@ -4424,6 +4424,38 @@ + + + + I/O + + + + + + Debug Overlay For Pad Input + + + + + + + Qt::Vertical + + + QSizePolicy::MinimumExpanding + + + + 0 + 0 + + + + + + + diff --git a/rpcs3/rpcs3qt/tooltips.h b/rpcs3/rpcs3qt/tooltips.h index 8a5bd99c93..ecf1d340ac 100644 --- a/rpcs3/rpcs3qt/tooltips.h +++ b/rpcs3/rpcs3qt/tooltips.h @@ -110,6 +110,7 @@ public: 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.");