diff --git a/rpcs3/Emu/Io/GHLtar.cpp b/rpcs3/Emu/Io/GHLtar.cpp index 8b9a047c66..281376711d 100644 --- a/rpcs3/Emu/Io/GHLtar.cpp +++ b/rpcs3/Emu/Io/GHLtar.cpp @@ -5,9 +5,9 @@ #include "Emu/Cell/lv2/sys_usbd.h" #include "Input/pad_thread.h" -LOG_CHANNEL(ghltar_log); +LOG_CHANNEL(ghltar_log, "GHLTAR"); -usb_device_ghltar::usb_device_ghltar(int controller_index, const std::array& location) +usb_device_ghltar::usb_device_ghltar(u32 controller_index, const std::array& location) : usb_device_emulated(location), m_controller_index(controller_index) { device = UsbDescriptorNode(USB_DESCRIPTOR_DEVICE, UsbDeviceDescriptor{0x0200, 0x00, 0x00, 0x00, 0x20, 0x12BA, 0x074B, 0x0100, 0x01, 0x02, 0x00, 0x01}); @@ -16,6 +16,11 @@ usb_device_ghltar::usb_device_ghltar(int controller_index, const std::arrayGetPads(), m_controller_index); + const auto& cfg = ::at32(m_cfg.players, m_controller_index); if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED)) { @@ -123,62 +129,53 @@ void usb_device_ghltar::interrupt_transfer(u32 buf_size, u8* buf, u32 /*endpoint continue; } - if (button.m_offset == CELL_PAD_BTN_OFFSET_DIGITAL2) + if (const auto btn = cfg->find_button(button.m_offset, button.m_outKeyCode)) { - switch (button.m_outKeyCode) + switch (btn.value()) { - case CELL_PAD_CTRL_SQUARE: + case ghltar_btn::w1: buf[0] += 0x01; // W1 break; - case CELL_PAD_CTRL_CROSS: + case ghltar_btn::b1: buf[0] += 0x02; // B1 break; - case CELL_PAD_CTRL_CIRCLE: + case ghltar_btn::b2: buf[0] += 0x04; // B2 break; - case CELL_PAD_CTRL_TRIANGLE: + case ghltar_btn::b3: buf[0] += 0x08; // B3 break; - case CELL_PAD_CTRL_R1: + case ghltar_btn::w3: buf[0] += 0x20; // W3 break; - case CELL_PAD_CTRL_L1: + case ghltar_btn::w2: buf[0] += 0x10; // W2 break; - default: - break; - } - } - else if (button.m_offset == CELL_PAD_BTN_OFFSET_DIGITAL1) - { - switch (button.m_outKeyCode) - { - case CELL_PAD_CTRL_DOWN: + case ghltar_btn::strum_down: buf[4] = 0xFF; // Strum Down break; - case CELL_PAD_CTRL_UP: + case ghltar_btn::strum_up: buf[4] = 0x00; // Strum Up break; - case CELL_PAD_CTRL_LEFT: + case ghltar_btn::dpad_left: buf[2] = 0x02; // Left D-Pad (Unused) break; - case CELL_PAD_CTRL_RIGHT: + case ghltar_btn::dpad_right: buf[2] = 0x06; // Right D-Pad (Unused) break; - case CELL_PAD_CTRL_START: + case ghltar_btn::start: buf[1] += 0x02; // Pause break; - case CELL_PAD_CTRL_SELECT: + case ghltar_btn::hero_power: buf[1] += 0x01; // Hero Power break; - case CELL_PAD_CTRL_L3: + case ghltar_btn::ghtv: buf[1] += 0x04; // GHTV Button break; - default: - break; } } } + for (const AnalogStick& stick : pad->m_sticks) { switch (stick.m_offset) diff --git a/rpcs3/Emu/Io/GHLtar.h b/rpcs3/Emu/Io/GHLtar.h index 52c9fd58a5..e09e3d08bf 100644 --- a/rpcs3/Emu/Io/GHLtar.h +++ b/rpcs3/Emu/Io/GHLtar.h @@ -1,16 +1,18 @@ #pragma once #include "Emu/Io/usb_device.h" +#include "Emu/Io/ghltar_config.h" class usb_device_ghltar : public usb_device_emulated { -private: - int m_controller_index; - public: - usb_device_ghltar(int controller_index, const std::array& location); + usb_device_ghltar(u32 controller_index, const std::array& location); ~usb_device_ghltar(); 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_ghltars m_cfg; }; diff --git a/rpcs3/Emu/Io/ghltar_config.cpp b/rpcs3/Emu/Io/ghltar_config.cpp new file mode 100644 index 0000000000..ee437589b7 --- /dev/null +++ b/rpcs3/Emu/Io/ghltar_config.cpp @@ -0,0 +1,86 @@ +#include "stdafx.h" +#include "ghltar_config.h" + +LOG_CHANNEL(ghltar_log, "GHLTAR"); + +std::optional cfg_ghltar::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_ghltars::load() +{ + bool result = false; + const std::string cfg_name = fs::get_config_dir() + "config/ghltar.yml"; + ghltar_log.notice("Loading ghltar config: %s", cfg_name); + + from_default(); + + for (cfg_ghltar* 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_ghltar* player : players) + { + const auto set_button = [&player](pad_button pbtn, ghltar_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->w1, ghltar_btn::w1); + set_button(player->w2, ghltar_btn::w2); + set_button(player->w3, ghltar_btn::w3); + set_button(player->b1, ghltar_btn::b1); + set_button(player->b2, ghltar_btn::b2); + set_button(player->b3, ghltar_btn::b3); + set_button(player->start, ghltar_btn::start); + set_button(player->hero_power, ghltar_btn::hero_power); + set_button(player->ghtv, ghltar_btn::ghtv); + set_button(player->strum_down, ghltar_btn::strum_down); + set_button(player->strum_up, ghltar_btn::strum_up); + set_button(player->dpad_left, ghltar_btn::dpad_left); + set_button(player->dpad_right, ghltar_btn::dpad_right); + } + + return result; +} + +void cfg_ghltars::save() const +{ + const std::string cfg_name = fs::get_config_dir() + "config/ghltar.yml"; + ghltar_log.notice("Saving ghltar config to '%s'", cfg_name); + + if (!fs::create_path(fs::get_parent_dir(cfg_name))) + { + ghltar_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())) + { + ghltar_log.error("Failed to save ghltar config to '%s' (error=%s)", cfg_name, fs::g_tls_error); + } +} diff --git a/rpcs3/Emu/Io/ghltar_config.h b/rpcs3/Emu/Io/ghltar_config.h new file mode 100644 index 0000000000..a14dc66992 --- /dev/null +++ b/rpcs3/Emu/Io/ghltar_config.h @@ -0,0 +1,61 @@ +#pragma once + +#include "Utilities/Config.h" +#include "pad_types.h" + +#include + +enum class ghltar_btn +{ + w1, + w2, + w3, + b1, + b2, + b3, + start, + hero_power, + ghtv, + strum_down, + strum_up, + dpad_left, + dpad_right +}; + +struct cfg_ghltar final : cfg::node +{ + cfg_ghltar(node* owner, const std::string& name) : cfg::node(owner, name) {} + + cfg::_enum w1{ this, "W1", pad_button::square }; + cfg::_enum w2{ this, "W2", pad_button::L1 }; + cfg::_enum w3{ this, "W3", pad_button::R1 }; + cfg::_enum b1{ this, "B1", pad_button::cross }; + cfg::_enum b2{ this, "B2", pad_button::circle }; + cfg::_enum b3{ this, "B3", pad_button::triangle }; + cfg::_enum start{ this, "Start", pad_button::start }; + cfg::_enum hero_power{ this, "Hero Power", pad_button::select }; + cfg::_enum ghtv{ this, "GHTV", pad_button::L3 }; + cfg::_enum strum_down{ this, "Strum Down", pad_button::dpad_down }; + cfg::_enum strum_up{ this, "Strum Up", pad_button::dpad_up }; + cfg::_enum dpad_left{ this, "D-Pad Left", pad_button::dpad_left }; + cfg::_enum dpad_right{ this, "D-Pad Right", pad_button::dpad_right }; + + std::map> buttons; + std::optional find_button(u32 offset, u32 keycode) const; +}; + +struct cfg_ghltars final : cfg::node +{ + cfg_ghltar player1{ this, "Player 1" }; + cfg_ghltar player2{ this, "Player 2" }; + cfg_ghltar player3{ this, "Player 3" }; + cfg_ghltar player4{ this, "Player 4" }; + cfg_ghltar player5{ this, "Player 5" }; + cfg_ghltar player6{ this, "Player 6" }; + cfg_ghltar 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 6829db4764..c5d7400543 100644 --- a/rpcs3/emucore.vcxproj +++ b/rpcs3/emucore.vcxproj @@ -70,6 +70,7 @@ + @@ -510,6 +511,7 @@ + diff --git a/rpcs3/emucore.vcxproj.filters b/rpcs3/emucore.vcxproj.filters index 738a423942..c4fb9bcde7 100644 --- a/rpcs3/emucore.vcxproj.filters +++ b/rpcs3/emucore.vcxproj.filters @@ -1171,6 +1171,9 @@ Emu\Io + + Emu\Io + @@ -2359,6 +2362,9 @@ Emu\Io + + Emu\Io +