diff --git a/Source/Core/Core/HW/GBAPadEmu.h b/Source/Core/Core/HW/GBAPadEmu.h index c9c38f1e5a..3cb23b9b98 100644 --- a/Source/Core/Core/HW/GBAPadEmu.h +++ b/Source/Core/Core/HW/GBAPadEmu.h @@ -17,7 +17,8 @@ class Buttons; enum class GBAPadGroup { DPad, - Buttons + Buttons, + Triforce }; class GBAPad : public ControllerEmu::EmulatedController diff --git a/Source/Core/Core/HW/GCPadEmu.cpp b/Source/Core/Core/HW/GCPadEmu.cpp index 0058bc74e4..f66318cb46 100644 --- a/Source/Core/Core/HW/GCPadEmu.cpp +++ b/Source/Core/Core/HW/GCPadEmu.cpp @@ -34,6 +34,7 @@ static const u16 trigger_bitmasks[] = { static const u16 dpad_bitmasks[] = {PAD_BUTTON_UP, PAD_BUTTON_DOWN, PAD_BUTTON_LEFT, PAD_BUTTON_RIGHT}; +static const u8 triforce_bitmask[] = { PAD_SWITCH_TEST, PAD_SWITCH_SERVICE, PAD_SWITCH_COIN }; GCPad::GCPad(const unsigned int index) : m_index(index) { @@ -68,6 +69,13 @@ GCPad::GCPad(const unsigned int index) : m_index(index) m_dpad->AddInput(Translatability::Translate, named_direction); } + // triforce + groups.emplace_back(m_triforce = new ControllerEmu::Buttons(TRIFORCE_GROUP)); + for (const char* named_button : { TEST_BUTTON, SERVICE_BUTTON, COIN_BUTTON }) + { + m_triforce->AddInput(Translatability::DoNotTranslate, named_button); + } + // Microphone groups.emplace_back(m_mic = new ControllerEmu::Buttons(MIC_GROUP)); m_mic->AddInput(Translatability::Translate, _trans("Button")); @@ -119,6 +127,8 @@ ControllerEmu::ControlGroup* GCPad::GetGroup(PadGroup group) return m_mic; case PadGroup::Options: return m_options; + case PadGroup::Triforce: + return m_triforce; default: return nullptr; } @@ -150,6 +160,9 @@ GCPadStatus GCPad::GetInput() const // dpad m_dpad->GetState(&pad.button, dpad_bitmasks, m_input_override_function); + // triforce + m_triforce->GetState(&pad.switches, triforce_bitmask, m_input_override_function); + // sticks const auto main_stick_state = m_main_stick->GetState(m_input_override_function); pad.stickX = MapFloat(main_stick_state.x, GCPadStatus::MAIN_STICK_CENTER_X, 1); @@ -202,6 +215,11 @@ void GCPad::LoadDefaults(const ControllerInterface& ciface) m_dpad->SetControlExpression(2, "`F`"); // Left m_dpad->SetControlExpression(3, "`H`"); // Right + // Triforce + m_dpad->SetControlExpression(0, "`1`"); // Test + m_dpad->SetControlExpression(1, "`2`"); // Service + m_dpad->SetControlExpression(2, "`3`"); // Coin + // C Stick m_c_stick->SetControlExpression(0, "`I`"); // Up m_c_stick->SetControlExpression(1, "`K`"); // Down diff --git a/Source/Core/Core/HW/GCPadEmu.h b/Source/Core/Core/HW/GCPadEmu.h index 2555ee05b1..1918b34659 100644 --- a/Source/Core/Core/HW/GCPadEmu.h +++ b/Source/Core/Core/HW/GCPadEmu.h @@ -29,7 +29,8 @@ enum class PadGroup Triggers, Rumble, Mic, - Options + Options, + Triforce }; class GCPad : public ControllerEmu::EmulatedController @@ -61,6 +62,7 @@ public: static constexpr const char* RUMBLE_GROUP = _trans("Rumble"); static constexpr const char* MIC_GROUP = _trans("Microphone"); static constexpr const char* OPTIONS_GROUP = _trans("Options"); + static constexpr const char* TRIFORCE_GROUP = _trans("Triforce"); static constexpr const char* A_BUTTON = "A"; static constexpr const char* B_BUTTON = "B"; @@ -69,6 +71,11 @@ public: static constexpr const char* Z_BUTTON = "Z"; static constexpr const char* START_BUTTON = "Start"; + // Special Triforce buttons + static constexpr const char* TEST_BUTTON = "Test"; + static constexpr const char* SERVICE_BUTTON = "Service"; + static constexpr const char* COIN_BUTTON = "Coin"; + // i18n: The left trigger button (labeled L on real controllers) static constexpr const char* L_DIGITAL = _trans("L"); // i18n: The right trigger button (labeled R on real controllers) @@ -87,6 +94,7 @@ private: ControllerEmu::ControlGroup* m_rumble; ControllerEmu::Buttons* m_mic; ControllerEmu::ControlGroup* m_options; + ControllerEmu::Buttons* m_triforce; ControllerEmu::SettingValue m_always_connected_setting; diff --git a/Source/Core/Core/HW/SI/SI_DeviceAMBaseboard.cpp b/Source/Core/Core/HW/SI/SI_DeviceAMBaseboard.cpp index f30f01dcc1..93abb824b6 100644 --- a/Source/Core/Core/HW/SI/SI_DeviceAMBaseboard.cpp +++ b/Source/Core/Core/HW/SI/SI_DeviceAMBaseboard.cpp @@ -1546,7 +1546,7 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length) PadStatus = Pad::GetStatus(0); // Test button - if (PadStatus.button & PAD_TRIGGER_Z) + if (PadStatus.switches&PAD_SWITCH_TEST) { // Trying to access the test menu without SegaBoot present will cause a crash if (AMMediaboard::GetTestMenu()) @@ -1581,7 +1581,7 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length) if (PadStatus.button & PAD_BUTTON_START) player_data[0] |= 0x80; // Service button - if (PadStatus.button & PAD_BUTTON_X) + if (PadStatus.switches&PAD_SWITCH_SERVICE) player_data[0] |= 0x40; // Boost if (PadStatus.button & PAD_BUTTON_Y) @@ -1639,7 +1639,7 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length) if (PadStatus.button & PAD_BUTTON_START) player_data[0] |= 0x80; // Service button - if (PadStatus.button & PAD_BUTTON_X) + if (PadStatus.switches&PAD_SWITCH_SERVICE) player_data[0] |= 0x40; // Boost if (PadStatus.button & PAD_BUTTON_Y) @@ -1689,7 +1689,7 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length) if (PadStatus.button & PAD_BUTTON_START) player_data[0] |= 0x80; // Service button - if (PadStatus.button & PAD_BUTTON_X) + if (PadStatus.switches&PAD_SWITCH_SERVICE) player_data[0] |= 0x40; // Long Pass if (PadStatus.button & PAD_TRIGGER_L) @@ -1721,7 +1721,7 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length) if (PadStatus.button & PAD_BUTTON_START) player_data[0] |= 0x80; // Service button - if (PadStatus.button & PAD_BUTTON_X) + if (PadStatus.switches&PAD_SWITCH_SERVICE) player_data[0] |= 0x40; // Long Pass if (PadStatus.button & PAD_TRIGGER_L) @@ -1762,7 +1762,7 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length) if (PadStatus.button & PAD_BUTTON_START) player_data[0] |= 0x80; // Service button - if (PadStatus.button & PAD_BUTTON_X) + if (PadStatus.switches&PAD_SWITCH_SERVICE) player_data[0] |= 0x40; // A if (PadStatus.button & PAD_BUTTON_B) @@ -1813,7 +1813,7 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length) if (PadStatus.button & PAD_BUTTON_START) player_data[0] |= 0x80; // Service button - if (PadStatus.button & PAD_BUTTON_X) + if (PadStatus.switches&PAD_SWITCH_SERVICE) player_data[0] |= 0x40; // Switch 1 if (PadStatus.button & PAD_BUTTON_A) @@ -1843,11 +1843,11 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* buffer, int request_length) { GCPadStatus PadStatus; PadStatus = Pad::GetStatus(i); - if ((PadStatus.button & PAD_BUTTON_X) && !m_coin_pressed[i]) + if ((PadStatus.switches&PAD_SWITCH_COIN) && !m_coin_pressed[i]) { m_coin[i]++; } - m_coin_pressed[i] = PadStatus.button & PAD_BUTTON_X; + m_coin_pressed[i] = PadStatus.switches & PAD_SWITCH_COIN; message.addData((m_coin[i] >> 8) & 0x3f); message.addData(m_coin[i] & 0xff); } diff --git a/Source/Core/DolphinQt/Config/Mapping/GCPadEmu.cpp b/Source/Core/DolphinQt/Config/Mapping/GCPadEmu.cpp index d3c9f8ccfc..94ebbaeeef 100644 --- a/Source/Core/DolphinQt/Config/Mapping/GCPadEmu.cpp +++ b/Source/Core/DolphinQt/Config/Mapping/GCPadEmu.cpp @@ -8,6 +8,10 @@ #include "Core/HW/GCPad.h" #include "Core/HW/GCPadEmu.h" +#include "Core/HW/SI/SI.h" +#include "Core/HW/SI/SI_DeviceAMBaseboard.h" + +#include "Core/Config/MainSettings.h" #include "InputCommon/ControllerEmu/Setting/NumericSetting.h" #include "InputCommon/InputConfig.h" @@ -23,8 +27,13 @@ void GCPadEmu::CreateMainLayout() layout->addWidget(CreateGroupBox(tr("Buttons"), Pad::GetGroup(GetPort(), PadGroup::Buttons)), 0, 0); - layout->addWidget(CreateGroupBox(tr("D-Pad"), Pad::GetGroup(GetPort(), PadGroup::DPad)), 1, 0, -1, - 1); + layout->addWidget(CreateGroupBox(tr("D-Pad"), Pad::GetGroup(GetPort(), PadGroup::DPad)), 1, 0 ); + + if (Config::Get(Config::GetInfoForSIDevice(0)) == SerialInterface::SIDevices::SIDEVICE_AM_BASEBOARD) + { + layout->addWidget(CreateGroupBox(tr("Triforce"), Pad::GetGroup(GetPort(), PadGroup::Triforce)), 2, 0); + } + layout->addWidget( CreateGroupBox(tr("Control Stick"), Pad::GetGroup(GetPort(), PadGroup::MainStick)), 0, 1, -1, 1); diff --git a/Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp b/Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp index e134902115..1d1a5ffa83 100644 --- a/Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp +++ b/Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp @@ -24,6 +24,9 @@ #include "Common/IniFile.h" #include "Common/StringUtil.h" +#include "Core/HW/SI/SI.h" +#include "Core/HW/SI/SI_DeviceAMBaseboard.h" + #include "DolphinQt/Config/Mapping/FreeLookGeneral.h" #include "DolphinQt/Config/Mapping/FreeLookRotation.h" #include "DolphinQt/Config/Mapping/GBAPadEmu.h" @@ -437,8 +440,16 @@ void MappingWindow::SetMappingType(MappingWindow::Type type) case Type::MAPPING_GC_DANCEMAT: case Type::MAPPING_GCPAD: widget = new GCPadEmu(this); - setWindowTitle(tr("GameCube Controller at Port %1").arg(GetPort() + 1)); - AddWidget(tr("GameCube Controller"), widget); + if (Config::Get(Config::GetInfoForSIDevice(GetPort())) == SerialInterface::SIDevices::SIDEVICE_AM_BASEBOARD) + { + setWindowTitle(tr("Triforce Baseboard at Port %1").arg(GetPort() + 1)); + AddWidget(tr("Triforce Baseboard"), widget); + } + else + { + setWindowTitle(tr("GameCube Controller at Port %1").arg(GetPort() + 1)); + AddWidget(tr("GameCube Controller"), widget); + } break; case Type::MAPPING_GC_MICROPHONE: widget = new GCMicrophone(this); diff --git a/Source/Core/InputCommon/GCPadStatus.h b/Source/Core/InputCommon/GCPadStatus.h index 74849e5594..6f7353ce34 100644 --- a/Source/Core/InputCommon/GCPadStatus.h +++ b/Source/Core/InputCommon/GCPadStatus.h @@ -28,6 +28,13 @@ enum PadButton PAD_BUTTON_START = 0x1000, }; +enum SwitchButton +{ + PAD_SWITCH_TEST = 0x0001, + PAD_SWITCH_SERVICE = 0x0002, + PAD_SWITCH_COIN = 0x0004, +}; + struct GCPadStatus { u16 button = 0; // Or-ed PAD_BUTTON_* and PAD_TRIGGER_* bits @@ -39,6 +46,8 @@ struct GCPadStatus u8 triggerRight = 0; // 0 <= triggerRight <= 255 u8 analogA = 0; // 0 <= analogA <= 255 u8 analogB = 0; // 0 <= analogB <= 255 + //Triforce + u8 switches = 0; bool isConnected = true; static const u8 MAIN_STICK_CENTER_X = 0x80; diff --git a/Source/dolphin-emu.sln b/Source/dolphin-emu.sln index f1183c287f..36f9c87c3a 100644 --- a/Source/dolphin-emu.sln +++ b/Source/dolphin-emu.sln @@ -25,7 +25,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Languages", "..\Languages\L EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LZO", "..\Externals\LZO\LZO.vcxproj", "{AB993F38-C31D-4897-B139-A620C42BC565}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lz4", "..\Externals\LZ4\LZ4.vcxproj", "{9092C5CC-3E71-41B3-BF68-4A7BDD8A5476}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LZ4", "..\Externals\lz4\LZ4.vcxproj", "{9092C5CC-3E71-41B3-BF68-4A7BDD8A5476}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniupnpc", "..\Externals\miniupnpc\miniupnpc.vcxproj", "{31643FDB-1BB8-4965-9DE7-000FC88D35AE}" EndProject @@ -186,7 +186,6 @@ Global {31643FDB-1BB8-4965-9DE7-000FC88D35AE}.Debug|ARM64.ActiveCfg = Debug|ARM64 {31643FDB-1BB8-4965-9DE7-000FC88D35AE}.Debug|ARM64.Build.0 = Debug|ARM64 {31643FDB-1BB8-4965-9DE7-000FC88D35AE}.Debug|x64.ActiveCfg = Debug|x64 - {31643FDB-1BB8-4965-9DE7-000FC88D35AE}.Debug|x64.Build.0 = Debug|x64 {31643FDB-1BB8-4965-9DE7-000FC88D35AE}.Release|ARM64.ActiveCfg = Release|ARM64 {31643FDB-1BB8-4965-9DE7-000FC88D35AE}.Release|ARM64.Build.0 = Release|ARM64 {31643FDB-1BB8-4965-9DE7-000FC88D35AE}.Release|x64.ActiveCfg = Release|x64