Changed the way deadzone is handled to provide better precision access on the low end of the range. Changed the ConvertToByte function to divide the end result of the conversion by 1.5 to ensure the output is [-85,85] rather than [-127,128]. This should better match a real N64 controller thumbstick's behavior. This results in better, smoother control when using thumbsticks. This change affects both SDL and XInput controllers.

This commit is contained in:
Fred Hallock 2022-07-24 18:11:39 -04:00 committed by Blake Warner
parent 92e127cb28
commit 1d3aabe643
5 changed files with 76 additions and 31 deletions

View File

@ -1535,7 +1535,7 @@ s16 Camera_CalcControllerPitch(Camera* camera, s16 cur, s16 target, s16 arg3)
f32 pitchUpdRate;
const oot::hid::Controller& controller = oot::player(0).controller();
s16 rStickY = (s16)controller.state().r_stick_y * (s16)-100;
s16 rStickY = (s16)controller.state().r_stick_y * (s16)-150;
if(rStickY != 0)
{
@ -1555,7 +1555,7 @@ s16 Camera_CalcControllerYaw(Camera* camera, s16 cur, s16 target, f32 arg3, f32
f32 yawUpdRate;
const oot::hid::Controller& controller = oot::player(0).controller();
s16 rStickX = (s16)controller.state().r_stick_x * (s16)-250;
s16 rStickX = (s16)controller.state().r_stick_x * (s16)-375;
if(rStickX != 0)
{
camera->startControlTimer = 250; // 10s

View File

@ -376,7 +376,7 @@ namespace oot::hid
if(isFirstPerson() && !config().camera().useClassicCamera())
{
if(this->r_stickMag > oot::config().controls().stickRightDeadzone())
if(this->r_stickMag > 0)
{
this->stickMag = this->r_stickMag;
this->stickX = this->r_stickX;

View File

@ -163,11 +163,13 @@ namespace oot::hid
{
if(value > 0)
{
return value * 0x7F / max;
//printf("value: %d, byte: %d\n", value, value * 0x7F / (max * 1.5));
return value * 0x7F / (max * 1.5);
}
else
{
return value * 0x80 / (max+1);
//printf("value: %d, byte: %d\n", value, value * 0x80 / (max + 1));
return value * 0x80 / (1.5 * (max+1));
}
}

View File

@ -228,7 +228,7 @@ namespace oot::hid
static inline int8_t convertToByte(int value, int max)
{
int8_t result = value * 0x7F / max;
int8_t result = value * 0x7F / (max * 1.5);
return result;
}
@ -240,7 +240,14 @@ namespace oot::hid
inline int8_t stickLeftX()
{
auto value = readAxis(SDL_CONTROLLER_AXIS_LEFTX);
int deadzone = oot::config().controls().stickLeftDeadzone() * 0x7f;
int value = readAxis(SDL_CONTROLLER_AXIS_LEFTX);
if(value < -deadzone)
value += deadzone;
else if(value > deadzone)
value -= deadzone;
else
value = 0;
if(abs(value) > g_lstickX_peak)
{
@ -252,7 +259,14 @@ namespace oot::hid
inline int8_t stickLeftY()
{
int deadzone = oot::config().controls().stickLeftDeadzone() * 0x7f;
auto value = -readAxis(SDL_CONTROLLER_AXIS_LEFTY);
if(value < -deadzone)
value += deadzone;
else if(value > deadzone)
value -= deadzone;
else
value = 0;
if(abs(value) > g_lstickY_peak)
{
@ -264,7 +278,14 @@ namespace oot::hid
inline int8_t stickRightX()
{
auto value = readAxis(SDL_CONTROLLER_AXIS_RIGHTX);
int deadzone = oot::config().controls().stickRightDeadzone() * 0x7f;
int value = readAxis(SDL_CONTROLLER_AXIS_RIGHTX);
if(value < -deadzone)
value += deadzone;
else if(value > deadzone)
value -= deadzone;
else
value = 0;
if(abs(value) > g_rstickX_peak)
{
@ -276,7 +297,14 @@ namespace oot::hid
inline int8_t stickRightY()
{
auto value = -readAxis(SDL_CONTROLLER_AXIS_RIGHTY);
int deadzone = oot::config().controls().stickRightDeadzone() * 0x7f;
int value = -readAxis(SDL_CONTROLLER_AXIS_RIGHTY);
if(value < -deadzone)
value += deadzone;
else if(value > deadzone)
value -= deadzone;
else
value = 0;
if(abs(value) > g_rstickY_peak)
{
@ -446,22 +474,6 @@ namespace oot::hid
m_state.stick_y *= 0.25f;
}
uint32_t magnitude_sq = (uint32_t)(m_state.stick_x * m_state.stick_x) + (uint32_t)(m_state.stick_y * m_state.stick_y);
if(magnitude_sq < (uint32_t)(oot::config().controls().stickLeftDeadzone() * oot::config().controls().stickLeftDeadzone()))
{
m_state.stick_x = 0;
m_state.stick_y = 0;
}
magnitude_sq = (uint32_t)(m_state.r_stick_x * m_state.r_stick_x) + (uint32_t)(m_state.r_stick_y * m_state.r_stick_y);
if(magnitude_sq < (uint32_t)(oot::config().controls().stickRightDeadzone() * oot::config().controls().stickRightDeadzone()))
{
m_state.r_stick_x = 0;
m_state.r_stick_y = 0;
}
memcpy(m_lastButtonState, m_buttonState, sizeof(m_lastButtonState));
rumble();
}

View File

@ -451,11 +451,42 @@ namespace oot::hid
if(xstate.Gamepad.bRightTrigger > 0x7F)
m_state.button |= R_TRIG;
m_state.stick_x = convertToByte(xstate.Gamepad.sThumbLX, 0x7FFF);
m_state.stick_y = convertToByte(xstate.Gamepad.sThumbLY, 0x7FFF);
int deadzone = oot::config().controls().stickLeftDeadzone() * 0x7F;
int value = xstate.Gamepad.sThumbLX;
if(value < -deadzone)
value += deadzone;
else if(value > deadzone)
value -= deadzone;
else
value = 0;
m_state.stick_x = convertToByte(value, 0x7FFF - deadzone);
m_state.r_stick_x = convertToByte(xstate.Gamepad.sThumbRX, 0x7FFF);
m_state.r_stick_y = convertToByte(xstate.Gamepad.sThumbRY, 0x7FFF);
value = xstate.Gamepad.sThumbLY;
if(value < -deadzone)
value += deadzone;
else if(value > deadzone)
value -= deadzone;
else
value = 0;
m_state.stick_y = convertToByte(value, 0x7FFF - deadzone);
value = xstate.Gamepad.sThumbRX;
if(value < -deadzone)
value += deadzone;
else if(value > deadzone)
value -= deadzone;
else
value = 0;
m_state.r_stick_x = convertToByte(value, 0x7FFF - deadzone);
value = xstate.Gamepad.sThumbRY;
if(value < -deadzone)
value += deadzone;
else if(value > deadzone)
value -= deadzone;
else
value = 0;
m_state.r_stick_y = convertToByte(value, 0x7FFF - deadzone);
u8 state[MAX_BUTTONS];
expandButtonBits(xstate.Gamepad.wButtons, state);
@ -480,7 +511,7 @@ namespace oot::hid
}
}
uint32_t magnitude_sq = (uint32_t)(m_state.stick_x * m_state.stick_x) + (uint32_t)(m_state.stick_y * m_state.stick_y);
/*uint32_t magnitude_sq = (uint32_t)(m_state.stick_x * m_state.stick_x) + (uint32_t)(m_state.stick_y * m_state.stick_y);
if(magnitude_sq < (uint32_t)(oot::config().controls().stickLeftDeadzone() * oot::config().controls().stickLeftDeadzone()))
{
@ -494,7 +525,7 @@ namespace oot::hid
{
m_state.r_stick_x = 0;
m_state.r_stick_y = 0;
}
}*/
memcpy(m_lastKeyState, state, MAX_BUTTONS);
rumble();