From e4a358cacb1295b3f63fbcd83d32b1ae49989179 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Sat, 19 Oct 2024 16:22:59 +1000 Subject: [PATCH] Controller: Add Pop'n and Densha De Go Controllers Variants of digital controller with different buttons grounded. --- data/resources/gamedb.yaml | 14 ++++- src/core/controller.cpp | 16 ++++- src/core/digital_controller.cpp | 105 ++++++++++++++++++++++++-------- src/core/digital_controller.h | 13 ++-- src/core/types.h | 2 + 5 files changed, 113 insertions(+), 37 deletions(-) diff --git a/data/resources/gamedb.yaml b/data/resources/gamedb.yaml index a3fd76884..0a3672fb7 100644 --- a/data/resources/gamedb.yaml +++ b/data/resources/gamedb.yaml @@ -126975,6 +126975,7 @@ SCPS-45379: controllers: - AnalogController - DigitalController + - PopnController metadata: publisher: "Konami" developer: "KCE Yokohama" @@ -126994,6 +126995,7 @@ SLPM-86183: controllers: - AnalogController - DigitalController + - PopnController metadata: publisher: "Konami" developer: "KCE Yokohama" @@ -127013,6 +127015,7 @@ SLPM-86592: controllers: - AnalogController - DigitalController + - PopnController metadata: publisher: "Konami" developer: "KCE Studios" @@ -127032,6 +127035,7 @@ SLPM-86670: controllers: - AnalogController - DigitalController + - PopnController metadata: publisher: "Konami" developer: "Konami" @@ -127051,6 +127055,7 @@ SCPS-45433: controllers: - AnalogController - DigitalController + - PopnController metadata: publisher: "Konami" developer: "Konami" @@ -127070,6 +127075,7 @@ SLPM-86294: controllers: - AnalogController - DigitalController + - PopnController codes: - SLPM-86294 - SLPM-86512 @@ -127092,6 +127098,7 @@ SLPM-86415: controllers: - AnalogController - DigitalController + - PopnController metadata: publisher: "Konami" developer: "Konami" @@ -127111,6 +127118,7 @@ SLPM-86649: controllers: - AnalogController - DigitalController + - PopnController metadata: publisher: "Konami" developer: "Konami" @@ -127130,6 +127138,7 @@ SLPM-86937: controllers: - AnalogController - DigitalController + - PopnController metadata: publisher: "Konami" developer: "Konami" @@ -127149,8 +127158,7 @@ SLPM-87089: controllers: - AnalogController - DigitalController - traits: - - ForceInterlacing + - PopnController metadata: publisher: "Konami" developer: "Konami" @@ -127170,6 +127178,7 @@ SLPS-01636: controllers: - AnalogController - DigitalController + - PopnController metadata: publisher: "Taito Corporation" developer: "Taito" @@ -127192,6 +127201,7 @@ SLPM-86146: controllers: - AnalogController - DigitalController + - PopnController metadata: publisher: "Enix" developer: "Symbio / Roman-Tech" diff --git a/src/core/controller.cpp b/src/core/controller.cpp index 7640bce1d..9fb19a6d4 100644 --- a/src/core/controller.cpp +++ b/src/core/controller.cpp @@ -27,9 +27,17 @@ static const Controller::ControllerInfo s_none_info = {ControllerType::None, Controller::VibrationCapabilities::NoVibration}; static const Controller::ControllerInfo* s_controller_info[] = { - &s_none_info, &DigitalController::INFO, &AnalogController::INFO, &AnalogJoystick::INFO, - &NeGcon::INFO, &NeGconRumble::INFO, &GunCon::INFO, &PlayStationMouse::INFO, + &s_none_info, + &DigitalController::INFO, + &AnalogController::INFO, + &AnalogJoystick::INFO, + &NeGcon::INFO, + &NeGconRumble::INFO, + &GunCon::INFO, + &PlayStationMouse::INFO, &Justifier::INFO, + &DigitalController::INFO_POPN, + &DigitalController::INFO_DDGO, }; const std::array Controller::PortDisplayOrder = {{0, 2, 3, 4, 1, 5, 6, 7}}; @@ -102,7 +110,9 @@ std::unique_ptr Controller::Create(ControllerType type, u32 index) switch (type) { case ControllerType::DigitalController: - return DigitalController::Create(index); + case ControllerType::PopnController: + case ControllerType::DDGoController: + return DigitalController::Create(index, type); case ControllerType::AnalogController: return AnalogController::Create(index); diff --git a/src/core/digital_controller.cpp b/src/core/digital_controller.cpp index d0415a920..35f597047 100644 --- a/src/core/digital_controller.cpp +++ b/src/core/digital_controller.cpp @@ -12,7 +12,7 @@ #include "common/assert.h" #include "common/bitutils.h" -DigitalController::DigitalController(u32 index) : Controller(index) +DigitalController::DigitalController(u32 index, u16 button_mask) : Controller(index), m_button_mask(button_mask) { } @@ -127,13 +127,13 @@ bool DigitalController::Transfer(const u8 data_in, u8* data_out) case TransferState::ButtonsLSB: { - *data_out = Truncate8(m_button_state) & GetButtonsLSBMask(); + *data_out = Truncate8(m_button_state & m_button_mask); m_transfer_state = TransferState::ButtonsMSB; return true; } case TransferState::ButtonsMSB: - *data_out = Truncate8(m_button_state >> 8); + *data_out = Truncate8((m_button_state & m_button_mask) >> 8); m_transfer_state = TransferState::Idle; return false; @@ -142,9 +142,24 @@ bool DigitalController::Transfer(const u8 data_in, u8* data_out) } } -std::unique_ptr DigitalController::Create(u32 index) +std::unique_ptr DigitalController::Create(u32 index, ControllerType type) { - return std::make_unique(index); + // popn controller - right/down/left grounded + static constexpr u16 POPN_BUTTON_MASK = + static_cast(~((1u << static_cast(Button::Right)) | (1u << static_cast(Button::Down)) | + (1u << static_cast(Button::Left)))); + + // densha de go! controller - up/down grounded + static constexpr u16 DDGO_BUTTON_MASK = + static_cast(~((1u << static_cast(Button::Up)) | (1u << static_cast(Button::Down)))); + + u16 mask = 0xFFFFu; + if (type == ControllerType::PopnController) + mask = POPN_BUTTON_MASK; + else if (type == ControllerType::DDGoController) + mask = DDGO_BUTTON_MASK; + + return std::make_unique(index, mask); } static const Controller::ControllerBindingInfo s_binding_info[] = { @@ -173,30 +188,72 @@ static const Controller::ControllerBindingInfo s_binding_info[] = { #undef BUTTON }; -static const SettingInfo s_settings[] = { - {SettingInfo::Type::Boolean, "ForcePopnControllerMode", - TRANSLATE_NOOP("DigitalController", "Force Pop'n Controller Mode"), - TRANSLATE_NOOP("DigitalController", "Forces the Digital Controller to act as a Pop'n Controller."), "false", nullptr, - nullptr, nullptr, nullptr, nullptr, 0.0f}}; - const Controller::ControllerInfo DigitalController::INFO = {ControllerType::DigitalController, "DigitalController", TRANSLATE_NOOP("ControllerType", "Digital Controller"), ICON_PF_GAMEPAD_ALT, s_binding_info, - s_settings, + {}, Controller::VibrationCapabilities::NoVibration}; -void DigitalController::LoadSettings(SettingsInterface& si, const char* section, bool initial) -{ - Controller::LoadSettings(si, section, initial); - m_popn_controller_mode = si.GetBoolValue(section, "ForcePopnControllerMode", false); -} +static const Controller::ControllerBindingInfo s_popn_binding_info[] = { +#define BUTTON(name, display_name, icon_name, button, genb) \ + { \ + name, display_name, icon_name, static_cast(button), InputBindingInfo::Type::Button, genb \ + } -u8 DigitalController::GetButtonsLSBMask() const -{ - constexpr u8 popn_controller_mask = - static_cast(~(u8(1) << static_cast(Button::Right) | u8(1) << static_cast(Button::Down) | - u8(1) << static_cast(Button::Left))); - return m_popn_controller_mode ? popn_controller_mask : 0xFF; -} + // clang-format off + BUTTON("LeftWhite", TRANSLATE_NOOP("DigitalController", "Left White"), ICON_PF_BUTTON_TRIANGLE, DigitalController::Button::Triangle, GenericInputBinding::Triangle), + BUTTON("LeftYellow", TRANSLATE_NOOP("DigitalController", "Left Yellow"), ICON_PF_BUTTON_CIRCLE, DigitalController::Button::Circle, GenericInputBinding::Circle), + BUTTON("LeftGreen", TRANSLATE_NOOP("DigitalController", "Left Green"), ICON_PF_RIGHT_SHOULDER_R1, DigitalController::Button::R1, GenericInputBinding::R1), + BUTTON("LeftBlue", TRANSLATE_NOOP("DigitalController", "Left Blue/Sel"), ICON_PF_BUTTON_CROSS, DigitalController::Button::Cross, GenericInputBinding::Cross), + BUTTON("MiddleRed", TRANSLATE_NOOP("DigitalController", "Middle Red/Okay"), ICON_PF_LEFT_SHOULDER_L1, DigitalController::Button::L1, GenericInputBinding::L1), + BUTTON("RightBlue", TRANSLATE_NOOP("DigitalController", "Right Blue/Sel"), ICON_PF_BUTTON_SQUARE, DigitalController::Button::Square, GenericInputBinding::Square), + BUTTON("RightGreen", TRANSLATE_NOOP("DigitalController", "Right Green"), ICON_PF_RIGHT_TRIGGER_R2, DigitalController::Button::R2, GenericInputBinding::R2), + BUTTON("RightYellow", TRANSLATE_NOOP("DigitalController", "Right Yellow"), ICON_PF_DPAD_UP, DigitalController::Button::Up, GenericInputBinding::DPadUp), + BUTTON("RightWhite", TRANSLATE_NOOP("DigitalController", "Right White"), ICON_PF_LEFT_TRIGGER_L2, DigitalController::Button::L2, GenericInputBinding::L2), +// clang-format on + +#undef BUTTON +}; + +const Controller::ControllerInfo DigitalController::INFO_POPN = {ControllerType::PopnController, + "PopnController", + TRANSLATE_NOOP("ControllerType", "Pop'n Controller"), + ICON_PF_GAMEPAD_ALT, + s_popn_binding_info, + {}, + Controller::VibrationCapabilities::NoVibration}; + +static const Controller::ControllerBindingInfo s_ddgo_binding_info[] = { +#define BUTTON(name, display_name, icon_name, button, genb) \ + { \ + name, display_name, icon_name, static_cast(button), InputBindingInfo::Type::Button, genb \ + } + + // clang-format off + BUTTON("Select", TRANSLATE_NOOP("DigitalController", "Select"), ICON_PF_SELECT_SHARE, DigitalController::Button::Select, GenericInputBinding::Select), + BUTTON("Start", TRANSLATE_NOOP("DigitalController", "Start"), ICON_PF_START, DigitalController::Button::Start, GenericInputBinding::Start), + BUTTON("A", TRANSLATE_NOOP("DigitalController", "A"), ICON_PF_BUTTON_SQUARE, DigitalController::Button::Square, GenericInputBinding::Square), + BUTTON("B", TRANSLATE_NOOP("DigitalController", "B"), ICON_PF_BUTTON_CROSS, DigitalController::Button::Cross, GenericInputBinding::Cross), + BUTTON("C", TRANSLATE_NOOP("DigitalController", "C"), ICON_PF_BUTTON_CIRCLE, DigitalController::Button::Circle, GenericInputBinding::Circle), + BUTTON("Power1", TRANSLATE_NOOP("DigitalController", "Power 1"), ICON_PF_BUTTON_TRIANGLE, DigitalController::Button::Triangle, GenericInputBinding::Triangle), + BUTTON("Power2", TRANSLATE_NOOP("DigitalController", "Power 2"), ICON_PF_DPAD_LEFT, DigitalController::Button::Left, GenericInputBinding::DPadLeft), + BUTTON("Power3", TRANSLATE_NOOP("DigitalController", "Power 3"), ICON_PF_DPAD_RIGHT, DigitalController::Button::Right, GenericInputBinding::DPadRight), + BUTTON("Brake1", TRANSLATE_NOOP("DigitalController", "Brake 1"), ICON_PF_LEFT_SHOULDER_L1, DigitalController::Button::L1, GenericInputBinding::L1), + BUTTON("Brake2", TRANSLATE_NOOP("DigitalController", "Brake 3"), ICON_PF_RIGHT_SHOULDER_R1, DigitalController::Button::R1, GenericInputBinding::R1), + BUTTON("Brake3", TRANSLATE_NOOP("DigitalController", "Brake 2"), ICON_PF_LEFT_TRIGGER_L2, DigitalController::Button::L2, GenericInputBinding::L2), + BUTTON("Brake4", TRANSLATE_NOOP("DigitalController", "Brake 4"), ICON_PF_RIGHT_TRIGGER_R2, DigitalController::Button::R2, GenericInputBinding::R2), +// clang-format on + +#undef BUTTON +}; + +const Controller::ControllerInfo DigitalController::INFO_DDGO = { + ControllerType::DDGoController, + "DDGoController", + TRANSLATE_NOOP("ControllerType", "Densha de Go! Controller"), + ICON_PF_GAMEPAD_ALT, + s_ddgo_binding_info, + {}, + Controller::VibrationCapabilities::NoVibration}; diff --git a/src/core/digital_controller.h b/src/core/digital_controller.h index 4c23bcdb1..b1c173b9e 100644 --- a/src/core/digital_controller.h +++ b/src/core/digital_controller.h @@ -32,11 +32,13 @@ public: }; static const Controller::ControllerInfo INFO; + static const Controller::ControllerInfo INFO_POPN; + static const Controller::ControllerInfo INFO_DDGO; - DigitalController(u32 index); + DigitalController(u32 index, u16 button_mask); ~DigitalController() override; - static std::unique_ptr Create(u32 index); + static std::unique_ptr Create(u32 index, ControllerType type); ControllerType GetType() const override; @@ -50,8 +52,6 @@ public: void ResetTransferState() override; bool Transfer(const u8 data_in, u8* data_out) override; - void LoadSettings(SettingsInterface& si, const char* section, bool initial) override; - private: enum class TransferState : u8 { @@ -64,10 +64,7 @@ private: // buttons are active low u16 m_button_state = UINT16_C(0xFFFF); + u16 m_button_mask = UINT16_C(0xFFFF); TransferState m_transfer_state = TransferState::Idle; - - bool m_popn_controller_mode = false; - - u8 GetButtonsLSBMask() const; }; diff --git a/src/core/types.h b/src/core/types.h index 828720739..bcf3cd30c 100644 --- a/src/core/types.h +++ b/src/core/types.h @@ -209,6 +209,8 @@ enum class ControllerType : u8 NeGcon, NeGconRumble, Justifier, + PopnController, + DDGoController, Count };