SI/GCSteeringWheel: Allow simultaneous use of accelerator and brake.

This commit is contained in:
Jordan Woyak 2019-02-02 16:13:35 -06:00
parent e7bc86881d
commit f74f49383c
1 changed files with 33 additions and 7 deletions

View File

@ -4,6 +4,8 @@
#include "Core/HW/SI/SI_DeviceGCSteeringWheel.h"
#include <algorithm>
#include <cmath>
#include <cstring>
#include "Common/CommonTypes.h"
@ -57,13 +59,37 @@ bool CSIDevice_GCSteeringWheel::GetData(u32& hi, u32& low)
low = (u8)pad_status.triggerRight; // All 8 bits
low |= (u32)((u8)pad_status.triggerLeft << 8); // All 8 bits
// The GC Steering Wheel appears to have combined pedals
// (both the Accelerate and Brake pedals are mapped to a single axis)
// We use the stickY axis for the pedals.
if (pad_status.stickY < 128)
low |= (u32)((u8)(255 - ((pad_status.stickY & 0x7f) * 2)) << 16); // All 8 bits (Brake)
if (pad_status.stickY >= 128)
low |= (u32)((u8)((pad_status.stickY & 0x7f) * 2) << 24); // All 8 bits (Accelerate)
// The GC Steering Wheel has 8 bit values for both the accelerator/brake.
// Our mapping UI and GCPadEmu class weren't really designed to provide
// input data other than what the regular GC controller has.
//
// Without a big redesign we really don't have a choice but to
// use the analog stick values for accelerator/brake.
//
// Main-stick: up:accelerator / down:brake
//
// But that doesn't allow the user to press both at the same time.
// so also provide the opposite functionality on the c-stick.
//
// C-stick: up:brake / down:accelerator
// Use either the upper-half of main-stick or lower-half of c-stick for accelerator.
const int accel_value = std::max(pad_status.stickY - GCPadStatus::MAIN_STICK_CENTER_Y,
GCPadStatus::C_STICK_CENTER_Y - pad_status.substickY);
// Use either the upper-half of c-stick or lower-half of main-stick for brake.
const int brake_value = std::max(pad_status.substickY - GCPadStatus::C_STICK_CENTER_Y,
GCPadStatus::MAIN_STICK_CENTER_Y - pad_status.stickY);
// We must double these values because we are mapping half of a stick range to a 0..255 value.
// We're only getting half the precison we could potentially have,
// but we'll have to redesign our gamecube controller input to fix that.
// All 8 bits (Accelerate)
low |= u32(std::clamp(accel_value * 2, 0, 0xff)) << 24;
// All 8 bits (Brake)
low |= u32(std::clamp(brake_value * 2, 0, 0xff)) << 16;
HandleButtonCombos(pad_status);
}