diff --git a/Source/Core/Core/HW/GBAPadEmu.cpp b/Source/Core/Core/HW/GBAPadEmu.cpp index c25763b6d8..274c042c2e 100644 --- a/Source/Core/Core/HW/GBAPadEmu.cpp +++ b/Source/Core/Core/HW/GBAPadEmu.cpp @@ -15,24 +15,21 @@ static const u16 dpad_bitmasks[] = {PAD_BUTTON_UP, PAD_BUTTON_DOWN, PAD_BUTTON_L static const u16 button_bitmasks[] = {PAD_BUTTON_B, PAD_BUTTON_A, PAD_TRIGGER_L, PAD_TRIGGER_R, PAD_TRIGGER_Z, PAD_BUTTON_START}; -static const char* const named_buttons[] = {"B", "A", "L", "R", _trans("SELECT"), _trans("START")}; - GBAPad::GBAPad(const unsigned int index) : m_reset_pending(false), m_index(index) { // Buttons - groups.emplace_back(m_buttons = new ControllerEmu::Buttons(_trans("Buttons"))); - for (const char* named_button : named_buttons) + groups.emplace_back(m_buttons = new ControllerEmu::Buttons(BUTTONS_GROUP)); + for (const char* named_button : {B_BUTTON, A_BUTTON, L_BUTTON, R_BUTTON}) { - const ControllerEmu::Translatability translate = - (named_button == std::string(_trans("SELECT")) || - named_button == std::string(_trans("START"))) ? - ControllerEmu::Translate : - ControllerEmu::DoNotTranslate; - m_buttons->AddInput(translate, named_button); + m_buttons->AddInput(ControllerEmu::DoNotTranslate, named_button); + } + for (const char* named_button : {SELECT_BUTTON, START_BUTTON}) + { + m_buttons->AddInput(ControllerEmu::Translate, named_button); } // DPad - groups.emplace_back(m_dpad = new ControllerEmu::Buttons(_trans("D-Pad"))); + groups.emplace_back(m_dpad = new ControllerEmu::Buttons(DPAD_GROUP)); for (const char* named_direction : named_directions) { m_dpad->AddInput(ControllerEmu::Translate, named_direction); @@ -63,10 +60,10 @@ GCPadStatus GBAPad::GetInput() GCPadStatus pad = {}; // Buttons - m_buttons->GetState(&pad.button, button_bitmasks); + m_buttons->GetState(&pad.button, button_bitmasks, m_input_override_function); // DPad - m_dpad->GetState(&pad.button, dpad_bitmasks); + m_dpad->GetState(&pad.button, dpad_bitmasks, m_input_override_function); // Use X button as a reset signal if (m_reset_pending) diff --git a/Source/Core/Core/HW/GBAPadEmu.h b/Source/Core/Core/HW/GBAPadEmu.h index 8dc8f24457..ca42666b48 100644 --- a/Source/Core/Core/HW/GBAPadEmu.h +++ b/Source/Core/Core/HW/GBAPadEmu.h @@ -3,6 +3,8 @@ #pragma once +#include "Common/Common.h" + #include "InputCommon/ControllerEmu/ControllerEmu.h" struct GCPadStatus; @@ -31,6 +33,16 @@ public: void LoadDefaults(const ControllerInterface& ciface) override; + static constexpr const char* BUTTONS_GROUP = _trans("Buttons"); + static constexpr const char* DPAD_GROUP = _trans("D-Pad"); + + static constexpr const char* B_BUTTON = "B"; + static constexpr const char* A_BUTTON = "A"; + static constexpr const char* L_BUTTON = "L"; + static constexpr const char* R_BUTTON = "R"; + static constexpr const char* SELECT_BUTTON = _trans("SELECT"); + static constexpr const char* START_BUTTON = _trans("START"); + private: ControllerEmu::Buttons* m_buttons; ControllerEmu::Buttons* m_dpad; diff --git a/Source/Core/DolphinQt/CMakeLists.txt b/Source/Core/DolphinQt/CMakeLists.txt index 2455b6a03e..0307d3fc36 100644 --- a/Source/Core/DolphinQt/CMakeLists.txt +++ b/Source/Core/DolphinQt/CMakeLists.txt @@ -327,6 +327,8 @@ add_executable(dolphin-emu Settings/WiiPane.h TAS/GCTASInputWindow.cpp TAS/GCTASInputWindow.h + TAS/GBATASInputWindow.cpp + TAS/GBATASInputWindow.h TAS/IRWidget.cpp TAS/IRWidget.h TAS/StickWidget.cpp diff --git a/Source/Core/DolphinQt/DolphinQt.vcxproj b/Source/Core/DolphinQt/DolphinQt.vcxproj index 3c37f4ca1e..9519c30313 100644 --- a/Source/Core/DolphinQt/DolphinQt.vcxproj +++ b/Source/Core/DolphinQt/DolphinQt.vcxproj @@ -201,6 +201,7 @@ + @@ -379,6 +380,7 @@ + diff --git a/Source/Core/DolphinQt/MainWindow.cpp b/Source/Core/DolphinQt/MainWindow.cpp index be9f8f6db1..7e530ba237 100644 --- a/Source/Core/DolphinQt/MainWindow.cpp +++ b/Source/Core/DolphinQt/MainWindow.cpp @@ -109,6 +109,7 @@ #include "DolphinQt/RiivolutionBootWidget.h" #include "DolphinQt/SearchBar.h" #include "DolphinQt/Settings.h" +#include "DolphinQt/TAS/GBATASInputWindow.h" #include "DolphinQt/TAS/GCTASInputWindow.h" #include "DolphinQt/TAS/WiiTASInputWindow.h" #include "DolphinQt/ToolBar.h" @@ -303,6 +304,7 @@ MainWindow::~MainWindow() for (int i = 0; i < 4; i++) { delete m_gc_tas_input_windows[i]; + delete m_gba_tas_input_windows[i]; delete m_wii_tas_input_windows[i]; } @@ -402,6 +404,7 @@ void MainWindow::CreateComponents() for (int i = 0; i < 4; i++) { m_gc_tas_input_windows[i] = new GCTASInputWindow(nullptr, i); + m_gba_tas_input_windows[i] = new GBATASInputWindow(nullptr, i); m_wii_tas_input_windows[i] = new WiiTASInputWindow(nullptr, i); } @@ -1787,8 +1790,14 @@ void MainWindow::ShowTASInput() for (int i = 0; i < num_gc_controllers; i++) { const auto si_device = Config::Get(Config::GetInfoForSIDevice(i)); - if (si_device != SerialInterface::SIDEVICE_NONE && - si_device != SerialInterface::SIDEVICE_GC_GBA) + if (si_device == SerialInterface::SIDEVICE_GC_GBA_EMULATED) + { + m_gba_tas_input_windows[i]->show(); + m_gba_tas_input_windows[i]->raise(); + m_gba_tas_input_windows[i]->activateWindow(); + } + else if (si_device != SerialInterface::SIDEVICE_NONE && + si_device != SerialInterface::SIDEVICE_GC_GBA) { m_gc_tas_input_windows[i]->show(); m_gc_tas_input_windows[i]->raise(); diff --git a/Source/Core/DolphinQt/MainWindow.h b/Source/Core/DolphinQt/MainWindow.h index 60880a5275..70acfcb53a 100644 --- a/Source/Core/DolphinQt/MainWindow.h +++ b/Source/Core/DolphinQt/MainWindow.h @@ -26,6 +26,7 @@ class DragEnterEvent; class FIFOPlayerWindow; class FreeLookWindow; class GameList; +class GBATASInputWindow; class GCTASInputWindow; class GraphicsWindow; class HotkeyScheduler; @@ -228,6 +229,7 @@ private: NetPlaySetupDialog* m_netplay_setup_dialog; static constexpr int num_gc_controllers = 4; std::array m_gc_tas_input_windows{}; + std::array m_gba_tas_input_windows{}; static constexpr int num_wii_controllers = 4; std::array m_wii_tas_input_windows{}; diff --git a/Source/Core/DolphinQt/TAS/GBATASInputWindow.cpp b/Source/Core/DolphinQt/TAS/GBATASInputWindow.cpp new file mode 100644 index 0000000000..d963308ca1 --- /dev/null +++ b/Source/Core/DolphinQt/TAS/GBATASInputWindow.cpp @@ -0,0 +1,86 @@ +// Copyright 2022 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "DolphinQt/TAS/GBATASInputWindow.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "Common/CommonTypes.h" + +#include "Core/HW/GBAPad.h" +#include "Core/HW/GBAPadEmu.h" + +#include "DolphinQt/TAS/TASCheckBox.h" + +#include "InputCommon/ControllerEmu/ControllerEmu.h" +#include "InputCommon/InputConfig.h" + +GBATASInputWindow::GBATASInputWindow(QWidget* parent, int controller_id) + : TASInputWindow(parent), m_controller_id(controller_id) +{ + setWindowTitle(tr("GBA TAS Input %1").arg(controller_id + 1)); + + m_b_button = + CreateButton(QStringLiteral("&B"), GBAPad::BUTTONS_GROUP, GBAPad::B_BUTTON, &m_overrider); + m_a_button = + CreateButton(QStringLiteral("&A"), GBAPad::BUTTONS_GROUP, GBAPad::A_BUTTON, &m_overrider); + m_l_button = + CreateButton(QStringLiteral("&L"), GBAPad::BUTTONS_GROUP, GBAPad::L_BUTTON, &m_overrider); + m_r_button = + CreateButton(QStringLiteral("&R"), GBAPad::BUTTONS_GROUP, GBAPad::R_BUTTON, &m_overrider); + m_select_button = CreateButton(QStringLiteral("SELE&CT"), GBAPad::BUTTONS_GROUP, + GBAPad::SELECT_BUTTON, &m_overrider); + m_start_button = m_start_button = CreateButton(QStringLiteral("&START"), GBAPad::BUTTONS_GROUP, + GBAPad::START_BUTTON, &m_overrider); + + m_left_button = + CreateButton(QStringLiteral("L&eft"), GBAPad::DPAD_GROUP, DIRECTION_LEFT, &m_overrider); + m_up_button = CreateButton(QStringLiteral("&Up"), GBAPad::DPAD_GROUP, DIRECTION_UP, &m_overrider); + m_down_button = + CreateButton(QStringLiteral("&Down"), GBAPad::DPAD_GROUP, DIRECTION_DOWN, &m_overrider); + m_right_button = + CreateButton(QStringLiteral("R&ight"), GBAPad::DPAD_GROUP, DIRECTION_RIGHT, &m_overrider); + + auto* buttons_layout = new QGridLayout; + + buttons_layout->addWidget(m_left_button, 0, 0); + buttons_layout->addWidget(m_up_button, 0, 1); + buttons_layout->addWidget(m_down_button, 0, 2); + buttons_layout->addWidget(m_right_button, 0, 3); + + buttons_layout->addWidget(m_l_button, 1, 0); + buttons_layout->addWidget(m_r_button, 1, 1); + buttons_layout->addWidget(m_b_button, 1, 2); + buttons_layout->addWidget(m_a_button, 1, 3); + + buttons_layout->addWidget(m_select_button, 2, 0, 1, 2); + buttons_layout->addWidget(m_start_button, 2, 2, 1, 2); + + buttons_layout->addItem(new QSpacerItem(1, 1, QSizePolicy::Expanding), 0, 4); + + QGroupBox* buttons_box = new QGroupBox(tr("Buttons")); + buttons_box->setLayout(buttons_layout); + + auto* layout = new QVBoxLayout; + layout->addWidget(buttons_box); + + setLayout(layout); +} + +void GBATASInputWindow::hideEvent(QHideEvent* event) +{ + Pad::GetGBAConfig()->GetController(m_controller_id)->ClearInputOverrideFunction(); +} + +void GBATASInputWindow::showEvent(QShowEvent* event) +{ + Pad::GetGBAConfig() + ->GetController(m_controller_id) + ->SetInputOverrideFunction(m_overrider.GetInputOverrideFunction()); +} diff --git a/Source/Core/DolphinQt/TAS/GBATASInputWindow.h b/Source/Core/DolphinQt/TAS/GBATASInputWindow.h new file mode 100644 index 0000000000..6b036682a0 --- /dev/null +++ b/Source/Core/DolphinQt/TAS/GBATASInputWindow.h @@ -0,0 +1,39 @@ +// Copyright 2022 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "DolphinQt/TAS/TASInputWindow.h" + +class QGroupBox; +class QHideEvent; +class QShowEvent; +class QSpinBox; +class TASCheckBox; + +class GBATASInputWindow final : public TASInputWindow +{ + Q_OBJECT +public: + explicit GBATASInputWindow(QWidget* parent, int controller_id); + + void hideEvent(QHideEvent* event) override; + void showEvent(QShowEvent* event) override; + +private: + int m_controller_id; + + InputOverrider m_overrider; + + TASCheckBox* m_b_button; + TASCheckBox* m_a_button; + TASCheckBox* m_l_button; + TASCheckBox* m_r_button; + TASCheckBox* m_select_button; + TASCheckBox* m_start_button; + + TASCheckBox* m_left_button; + TASCheckBox* m_up_button; + TASCheckBox* m_down_button; + TASCheckBox* m_right_button; +};