From e7c0df4eac1720ffe5f1a9c5ae57b5a49d6819a2 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Sat, 20 May 2023 14:34:35 +0200 Subject: [PATCH] input: add usio config file No sticks yet --- rpcs3/Emu/Io/usio.cpp | 149 ++++++++++++++++------------------ rpcs3/Emu/Io/usio.h | 2 + rpcs3/Emu/Io/usio_config.cpp | 87 ++++++++++++++++++++ rpcs3/Emu/Io/usio_config.h | 63 ++++++++++++++ rpcs3/emucore.vcxproj | 2 + rpcs3/emucore.vcxproj.filters | 6 ++ 6 files changed, 231 insertions(+), 78 deletions(-) create mode 100644 rpcs3/Emu/Io/usio_config.cpp create mode 100644 rpcs3/Emu/Io/usio_config.h diff --git a/rpcs3/Emu/Io/usio.cpp b/rpcs3/Emu/Io/usio.cpp index 4c5ee572e3..700620a0de 100644 --- a/rpcs3/Emu/Io/usio.cpp +++ b/rpcs3/Emu/Io/usio.cpp @@ -6,7 +6,7 @@ #include "Input/pad_thread.h" #include "Emu/IdManager.h" -LOG_CHANNEL(usio_log); +LOG_CHANNEL(usio_log, "USIO"); struct usio_memory { @@ -81,6 +81,11 @@ usb_device_usio::usb_device_usio(const std::array& location) g_fxo->get().last_game_status.clear(); g_fxo->get().last_game_status.resize(0x28); load_backup(); + + if (!m_cfg.load()) + { + usio_log.notice("Could not load usio config. Using defaults."); + } } usb_device_usio::~usb_device_usio() @@ -161,102 +166,90 @@ void usb_device_usio::translate_input() return; } - const auto& pad = handler->GetPads()[pad_number]; + const auto& pad = ::at32(handler->GetPads(), pad_number); if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED)) { return; } - const std::size_t offset = (player * 8); + const auto& cfg = ::at32(m_cfg.players, pad_number); + const std::size_t offset = (player * 8ULL); for (const Button& button : pad->m_buttons) { - switch (button.m_offset) + if (const auto btn = cfg->find_button(button.m_offset, button.m_outKeyCode)) { - case CELL_PAD_BTN_OFFSET_DIGITAL1: - if (player == 0) + switch (btn.value()) { - switch (button.m_outKeyCode) - { - case CELL_PAD_CTRL_SELECT: - if (button.m_pressed && !test_key_pressed) // Solve the need to hold the Test key - test_on = !test_on; - test_key_pressed = button.m_pressed; - break; - case CELL_PAD_CTRL_LEFT: - if (button.m_pressed && !coin_key_pressed) // Ensure only one coin is inserted each time the Coin key is pressed - coin_counter++; - coin_key_pressed = button.m_pressed; - break; - default: - if (button.m_pressed) - { - switch (button.m_outKeyCode) - { - case CELL_PAD_CTRL_START: - test_keys |= 0x200; // Enter - break; - case CELL_PAD_CTRL_UP: - test_keys |= 0x2000; // Up - break; - case CELL_PAD_CTRL_DOWN: - test_keys |= 0x1000; // Down - break; - case CELL_PAD_CTRL_RIGHT: - test_keys |= 0x4000; // Service - break; - default: - break; - } - } - break; - } - } - break; - case CELL_PAD_BTN_OFFSET_DIGITAL2: - if (button.m_pressed) - { - switch (button.m_outKeyCode) - { - case CELL_PAD_CTRL_SQUARE: - // Strong hit side left + case usio_btn::test: + if (player != 0) break; + if (button.m_pressed && !test_key_pressed) // Solve the need to hold the Test key + test_on = !test_on; + test_key_pressed = button.m_pressed; + break; + case usio_btn::coin: + if (player != 0) break; + if (button.m_pressed && !coin_key_pressed) // Ensure only one coin is inserted each time the Coin key is pressed + coin_counter++; + coin_key_pressed = button.m_pressed; + break; + case usio_btn::enter: + if (player == 0 && button.m_pressed) + test_keys |= 0x200; // Enter + break; + case usio_btn::up: + if (player == 0 && button.m_pressed) + test_keys |= 0x2000; // Up + break; + case usio_btn::down: + if (player == 0 && button.m_pressed) + test_keys |= 0x1000; // Down + break; + case usio_btn::service: + if (player == 0 && button.m_pressed) + test_keys |= 0x4000; // Service + break; + case usio_btn::strong_hit_side_left: + // Strong hit side left + if (button.m_pressed) std::memcpy(input_buf.data() + 32 + offset, &c_big_hit, sizeof(u16)); - break; - case CELL_PAD_CTRL_CROSS: - // Strong hit center right + break; + case usio_btn::strong_hit_center_right: + // Strong hit center right + if (button.m_pressed) std::memcpy(input_buf.data() + 36 + offset, &c_big_hit, sizeof(u16)); - break; - case CELL_PAD_CTRL_CIRCLE: - // Strong hit side right + break; + case usio_btn::strong_hit_side_right: + // Strong hit side right + if (button.m_pressed) std::memcpy(input_buf.data() + 38 + offset, &c_big_hit, sizeof(u16)); - break; - case CELL_PAD_CTRL_TRIANGLE: - // Strong hit center left + break; + case usio_btn::strong_hit_center_left: + // Strong hit center left + if (button.m_pressed) std::memcpy(input_buf.data() + 34 + offset, &c_big_hit, sizeof(u16)); - break; - case CELL_PAD_CTRL_L1: - // Small hit center left + break; + case usio_btn::small_hit_center_left: + // Small hit center left + if (button.m_pressed) std::memcpy(input_buf.data() + 34 + offset, &c_small_hit, sizeof(u16)); - break; - case CELL_PAD_CTRL_R1: - // Small hit center right + break; + case usio_btn::small_hit_center_right: + // Small hit center right + if (button.m_pressed) std::memcpy(input_buf.data() + 36 + offset, &c_small_hit, sizeof(u16)); - break; - case CELL_PAD_CTRL_L2: - // Small hit side left + break; + case usio_btn::small_hit_side_left: + // Small hit side left + if (button.m_pressed) std::memcpy(input_buf.data() + 32 + offset, &c_small_hit, sizeof(u16)); - break; - case CELL_PAD_CTRL_R2: - // Small hit side right + break; + case usio_btn::small_hit_side_right: + // Small hit side right + if (button.m_pressed) std::memcpy(input_buf.data() + 38 + offset, &c_small_hit, sizeof(u16)); - break; - default: - break; - } + break; } - break; - default: - break; } } }; diff --git a/rpcs3/Emu/Io/usio.h b/rpcs3/Emu/Io/usio.h index 310c00d692..4008c12b2a 100644 --- a/rpcs3/Emu/Io/usio.h +++ b/rpcs3/Emu/Io/usio.h @@ -2,6 +2,7 @@ #include "Emu/system_utils.hpp" #include "Emu/Io/usb_device.h" +#include "Emu/Io/usio_config.h" class usb_device_usio : public usb_device_emulated { @@ -28,4 +29,5 @@ private: le_t coin_counter = 0; const std::string usio_backup_path = rpcs3::utils::get_hdd1_dir() + "/caches/usiobackup.bin"; std::vector response; + cfg_usios m_cfg; }; diff --git a/rpcs3/Emu/Io/usio_config.cpp b/rpcs3/Emu/Io/usio_config.cpp new file mode 100644 index 0000000000..f5ef3b9850 --- /dev/null +++ b/rpcs3/Emu/Io/usio_config.cpp @@ -0,0 +1,87 @@ +#include "stdafx.h" +#include "usio_config.h" + +LOG_CHANNEL(usio_log, "USIO"); + +std::optional cfg_usio::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_usios::load() +{ + bool result = false; + const std::string cfg_name = fs::get_config_dir() + "config/usio.yml"; + usio_log.notice("Loading usio config: %s", cfg_name); + + from_default(); + + for (cfg_usio* 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_usio* player : players) + { + const auto set_button = [&player](pad_button pbtn, usio_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->test, usio_btn::test); + set_button(player->coin, usio_btn::coin); + set_button(player->enter, usio_btn::enter); + set_button(player->up, usio_btn::up); + set_button(player->down, usio_btn::down); + set_button(player->service, usio_btn::service); + set_button(player->strong_hit_side_left, usio_btn::strong_hit_side_left); + set_button(player->strong_hit_side_right, usio_btn::strong_hit_side_right); + set_button(player->strong_hit_center_left, usio_btn::strong_hit_center_left); + set_button(player->strong_hit_center_right, usio_btn::strong_hit_center_right); + set_button(player->small_hit_side_left, usio_btn::small_hit_side_left); + set_button(player->small_hit_side_right, usio_btn::small_hit_side_right); + set_button(player->small_hit_center_left, usio_btn::small_hit_center_left); + set_button(player->small_hit_center_right, usio_btn::small_hit_center_right); + } + + return result; +} + +void cfg_usios::save() const +{ + const std::string cfg_name = fs::get_config_dir() + "config/usio.yml"; + usio_log.notice("Saving usio config to '%s'", cfg_name); + + if (!fs::create_path(fs::get_parent_dir(cfg_name))) + { + usio_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())) + { + usio_log.error("Failed to save usio config to '%s' (error=%s)", cfg_name, fs::g_tls_error); + } +} diff --git a/rpcs3/Emu/Io/usio_config.h b/rpcs3/Emu/Io/usio_config.h new file mode 100644 index 0000000000..378be4aa38 --- /dev/null +++ b/rpcs3/Emu/Io/usio_config.h @@ -0,0 +1,63 @@ +#pragma once + +#include "Utilities/Config.h" +#include "pad_types.h" + +#include + +enum class usio_btn +{ + test, + coin, + enter, + up, + down, + service, + strong_hit_side_left, + strong_hit_side_right, + strong_hit_center_left, + strong_hit_center_right, + small_hit_side_left, + small_hit_side_right, + small_hit_center_left, + small_hit_center_right +}; + +struct cfg_usio final : cfg::node +{ + cfg_usio(node* owner, const std::string& name) : cfg::node(owner, name) {} + + cfg::_enum test{ this, "Test", pad_button::select }; + cfg::_enum coin{ this, "Coin", pad_button::dpad_left }; + cfg::_enum enter{ this, "Enter", pad_button::start }; + cfg::_enum up{ this, "Up", pad_button::dpad_up }; + cfg::_enum down{ this, "Down", pad_button::dpad_down }; + cfg::_enum service{ this, "Service", pad_button::dpad_right }; + cfg::_enum strong_hit_side_left{ this, "Strong Hit Side Left", pad_button::square }; + cfg::_enum strong_hit_side_right{ this, "Strong Hit Side Right", pad_button::circle }; + cfg::_enum strong_hit_center_left{ this, "Strong Hit Center Left", pad_button::triangle }; + cfg::_enum strong_hit_center_right{ this, "Strong Hit Center Right", pad_button::cross }; + cfg::_enum small_hit_side_left{ this, "Small Hit Side Left", pad_button::L2 }; + cfg::_enum small_hit_side_right{ this, "Small Hit Side Right", pad_button::R2 }; + cfg::_enum small_hit_center_left{ this, "Small Hit Center Left", pad_button::L1 }; + cfg::_enum small_hit_center_right{ this, "Small Hit Center Right", pad_button::R1 }; + + std::map> buttons; + std::optional find_button(u32 offset, u32 keycode) const; +}; + +struct cfg_usios final : cfg::node +{ + cfg_usio player1{ this, "Player 1" }; + cfg_usio player2{ this, "Player 2" }; + cfg_usio player3{ this, "Player 3" }; + cfg_usio player4{ this, "Player 4" }; + cfg_usio player5{ this, "Player 5" }; + cfg_usio player6{ this, "Player 6" }; + cfg_usio player7{ this, "Player 7" }; + + std::array players{ &player1, &player2, &player3, &player4, &player5, &player6, &player7 }; // Thanks gcc! + + bool load(); + void save() const; +}; diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj index c5d7400543..59adbf87dd 100644 --- a/rpcs3/emucore.vcxproj +++ b/rpcs3/emucore.vcxproj @@ -86,6 +86,7 @@ + @@ -529,6 +530,7 @@ + diff --git a/rpcs3/emucore.vcxproj.filters b/rpcs3/emucore.vcxproj.filters index c4fb9bcde7..487b849253 100644 --- a/rpcs3/emucore.vcxproj.filters +++ b/rpcs3/emucore.vcxproj.filters @@ -1174,6 +1174,9 @@ Emu\Io + + Emu\Io + @@ -2365,6 +2368,9 @@ Emu\Io + + Emu\Io +