Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 1 commit into from May 11, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
40 changes: 33 additions & 7 deletions Source/Core/Core/HW/SI/SI_DeviceGCSteeringWheel.cpp
Expand Up @@ -4,6 +4,8 @@

#include "Core/HW/SI/SI_DeviceGCSteeringWheel.h"

#include <algorithm>
#include <cmath>
#include <cstring>

#include "Common/CommonTypes.h"
Expand Down Expand Up @@ -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);
}
Expand Down