diff --git a/Source/Core/Core/HW/Triforce/MarioKartGP.cpp b/Source/Core/Core/HW/Triforce/MarioKartGP.cpp index 63203b4403..9b7d2cb0ef 100644 --- a/Source/Core/Core/HW/Triforce/MarioKartGP.cpp +++ b/Source/Core/Core/HW/Triforce/MarioKartGP.cpp @@ -14,6 +14,13 @@ #include "InputCommon/GCPadStatus.h" +namespace +{ +constexpr std::array ACK_NO_ERROR{'E', '0', '0'}; +constexpr std::array ACK_POWER_ON{'C', '0', '1'}; +constexpr std::array ACK_POWER_OFF{'C', '0', '6'}; +} // namespace + namespace Triforce { @@ -94,10 +101,10 @@ void MarioKartGPSteeringWheel::ProcessRequest(std::span request) { DEBUG_LOG_FMT(SERIALINTERFACE_AMBB, "SteeringWheel: Request: {:02x}", fmt::join(request, " ")); - const u8 cmd = request[3]; - if (cmd != 0x01) + const u32 cmd = Common::swap32(request.data()); + if (cmd != 0xffffff01) { - WARN_LOG_FMT(SERIALINTERFACE_AMBB, "SteeringWheel: Unknown command: {:02x}", cmd); + WARN_LOG_FMT(SERIALINTERFACE_AMBB, "SteeringWheel: Unknown command: {:08x}", cmd); return; } @@ -111,15 +118,27 @@ void MarioKartGPSteeringWheel::ProcessRequest(std::span request) switch (m_init_state) { case 0: - WriteTxBytes(std::array{'E', '0', '0'}); // Error - ++m_init_state; - break; - case 1: - WriteTxBytes(std::array{'C', '0', '6'}); // Power Off + // The game seems to expect this on power up. + WriteTxBytes(ACK_NO_ERROR); ++m_init_state; break; + default: - WriteTxBytes(std::array{'C', '0', '1'}); // Power On + // The game won't send non-zero forces unless the "POWER_ON" response is observed. + // After a race, the game gradually lowers the force to 0 and expects a "POWER_OFF" response. + // The meaning of these responses is not really understood. + // Cycling between "POWER_OFF" and "POWER_ON" seems to make the game happy for now.. + + if (m_init_state == 1) + { + WriteTxBytes(ACK_POWER_OFF); + ++m_init_state; + } + else + { + WriteTxBytes(ACK_POWER_ON); + m_init_state = 1; + } break; } }