diff --git a/Source/Core/Core/HW/GCPadEmu.cpp b/Source/Core/Core/HW/GCPadEmu.cpp index 223eec1743..85f0b18e03 100644 --- a/Source/Core/Core/HW/GCPadEmu.cpp +++ b/Source/Core/Core/HW/GCPadEmu.cpp @@ -126,16 +126,20 @@ GCPadStatus GCPad::GetInput() const // sticks m_main_stick->GetState(&x, &y); - pad.stickX = - static_cast(GCPadStatus::MAIN_STICK_CENTER_X + (x * GCPadStatus::MAIN_STICK_RADIUS)); - pad.stickY = - static_cast(GCPadStatus::MAIN_STICK_CENTER_Y + (y * GCPadStatus::MAIN_STICK_RADIUS)); + // immediately compute and cast the absolute offsets to u8 to avoid rounding inconsistencies + // for example, when x or y is 0.5/-0.5, the absolute offset of that axis should always be 63, never 64 + u8 stickXAbsoluteOffset = static_cast(abs(x) * GCPadStatus::MAIN_STICK_RADIUS); + u8 stickYAbsoluteOffset = static_cast(abs(y) * GCPadStatus::MAIN_STICK_RADIUS); + pad.stickX = static_cast(GCPadStatus::MAIN_STICK_CENTER_X + sign(x) * stickXAbsoluteOffset); + pad.stickY = static_cast(GCPadStatus::MAIN_STICK_CENTER_Y + sign(y) * stickYAbsoluteOffset); m_c_stick->GetState(&x, &y); - pad.substickX = - static_cast(GCPadStatus::C_STICK_CENTER_X + (x * GCPadStatus::C_STICK_RADIUS)); - pad.substickY = - static_cast(GCPadStatus::C_STICK_CENTER_Y + (y * GCPadStatus::C_STICK_RADIUS)); + // immediately compute and cast the absolute offsets to u8 to avoid rounding inconsistencies + // for example, when x or y is 0.5/-0.5, the absolute offset of that axis should always be 63, never 64 + u8 substickXAbsoluteOffset = static_cast(abs(x) * GCPadStatus::C_STICK_RADIUS); + u8 substickYAbsoluteOffset = static_cast(abs(y) * GCPadStatus::C_STICK_RADIUS); + pad.substickX = static_cast(GCPadStatus::C_STICK_CENTER_X + sign(x) * substickXAbsoluteOffset); + pad.substickY = static_cast(GCPadStatus::C_STICK_CENTER_Y + sign(y) * substickYAbsoluteOffset); // triggers m_triggers->GetState(&pad.button, trigger_bitmasks, triggers);