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;
+};