Improve Analog Deadzone

This commit is contained in:
LRFLEW 2021-03-18 17:59:32 -05:00
parent 43cab27a55
commit befb234653
5 changed files with 13 additions and 15 deletions

View File

@ -488,8 +488,6 @@ INT_PTR CALLBACK GbaSlotAnalog(HWND dialog, UINT msg, WPARAM wparam, LPARAM lpar
SendDlgItemMessage(dialog, IDC_ANALOG_DEADZONE_SLIDER, TBM_SETPOS, TRUE, tmp_Analog.Deadzone); SendDlgItemMessage(dialog, IDC_ANALOG_DEADZONE_SLIDER, TBM_SETPOS, TRUE, tmp_Analog.Deadzone);
CheckDlgButton(dialog, IDC_ANALOG_JOINED, tmp_Analog.Joined); CheckDlgButton(dialog, IDC_ANALOG_JOINED, tmp_Analog.Joined);
CheckDlgButton(dialog, IDC_ANALOG_CIRCLE, tmp_Analog.Circle);
EnableWindow(GetDlgItem(dialog, IDC_ANALOG_CIRCLE), tmp_Analog.Joined);
return TRUE; return TRUE;
} }
@ -536,10 +534,7 @@ INT_PTR CALLBACK GbaSlotAnalog(HWND dialog, UINT msg, WPARAM wparam, LPARAM lpar
return TRUE; return TRUE;
} }
case MAKELONG(IDC_ANALOG_JOINED, BN_CLICKED): case MAKELONG(IDC_ANALOG_JOINED, BN_CLICKED):
case MAKELONG(IDC_ANALOG_CIRCLE, BN_CLICKED):
tmp_Analog.Joined = IsDlgCheckboxChecked(dialog, IDC_ANALOG_JOINED); tmp_Analog.Joined = IsDlgCheckboxChecked(dialog, IDC_ANALOG_JOINED);
tmp_Analog.Circle = IsDlgCheckboxChecked(dialog, IDC_ANALOG_CIRCLE);
EnableWindow(GetDlgItem(dialog, IDC_ANALOG_CIRCLE), tmp_Analog.Joined);
return TRUE; return TRUE;
} }
return FALSE; return FALSE;
@ -732,7 +727,6 @@ void GBAslotDialog(HWND hwnd)
WritePrivateProfileInt("Slot2.Analog", "Y", Analog.Y, IniName); WritePrivateProfileInt("Slot2.Analog", "Y", Analog.Y, IniName);
WritePrivateProfileInt("Slot2.Analog", "Deadzone", Analog.Deadzone, IniName); WritePrivateProfileInt("Slot2.Analog", "Deadzone", Analog.Deadzone, IniName);
WritePrivateProfileBool("Slot2.Analog", "Joined", Analog.Joined, IniName); WritePrivateProfileBool("Slot2.Analog", "Joined", Analog.Joined, IniName);
WritePrivateProfileBool("Slot2.Analog", "Circle", Analog.Circle, IniName);
break; break;
default: default:
return; return;

View File

@ -263,7 +263,7 @@ SPaddle Paddle;
SPaddle DefaultPaddle = { false, 'K', 'L' }; SPaddle DefaultPaddle = { false, 'K', 'L' };
SAnalog Analog; SAnalog Analog;
SAnalog DefaultAnalog = { false, 1, 2, 15, true, true }; SAnalog DefaultAnalog = { false, 1, 2, 15, true };
bool killStylusTopScreen = false; bool killStylusTopScreen = false;
bool killStylusOffScreen = false; bool killStylusOffScreen = false;
@ -485,7 +485,6 @@ static void LoadAnalogConfig()
ReadAnalogControl("Y", Analog.Y); ReadAnalogControl("Y", Analog.Y);
ReadAnalogControl("Deadzone", Analog.Deadzone); ReadAnalogControl("Deadzone", Analog.Deadzone);
ReadAnalogBool("Joined", Analog.Joined); ReadAnalogBool("Joined", Analog.Joined);
ReadAnalogBool("Circle", Analog.Circle);
} }
@ -2714,6 +2713,12 @@ static float get_analog_float(WORD axis)
return (float) val / 10000.0f; return (float) val / 10000.0f;
} }
static float apply_deadzone(float value, float mag, float deadzone) {
if (mag <= deadzone) return 0.0f;
float cmag = std::min(mag, 1.0f); // clamp mag to 1.0f just in case
return value * (cmag - deadzone) / (1.0f - deadzone) / mag;
}
//void S9xOldAutofireAndStuff () //void S9xOldAutofireAndStuff ()
//{ //{
// // stuff ripped out of Snes9x that's no longer functional, at least for now // // stuff ripped out of Snes9x that's no longer functional, at least for now
@ -3058,11 +3063,13 @@ void input_acquire()
float y = get_analog_float(Analog.Y); float y = get_analog_float(Analog.Y);
if (Analog.Joined) { if (Analog.Joined) {
float value = Analog.Circle ? std::hypot(x, y) : (std::max)(std::abs(x), std::abs(y)); float mag = std::hypot(x, y);
if (value < deadzone) x = y = 0.0f; x = apply_deadzone(x, mag, deadzone);
y = apply_deadzone(y, mag, deadzone);
} else { } else {
if (x < deadzone && x > -deadzone) x = 0.0f; // Faster approximation that prioritizes cardinal directions
if (y < deadzone && y > -deadzone) y = 0.0f; x = apply_deadzone(x, x, deadzone);
y = apply_deadzone(y, y, deadzone);
} }
analog_setValue(x, y); analog_setValue(x, y);

View File

@ -167,7 +167,6 @@ struct SAnalog {
WORD Deadzone; WORD Deadzone;
BOOL Joined; BOOL Joined;
BOOL Circle;
}; };
extern SGuitar Guitar; extern SGuitar Guitar;

View File

@ -527,7 +527,6 @@
#define IDC_CHECK1 1074 #define IDC_CHECK1 1074
#define IDC_CHECK2 1075 #define IDC_CHECK2 1075
#define IDC_CAP0_SRC 1075 #define IDC_CAP0_SRC 1075
#define IDC_ANALOG_CIRCLE 1075
#define IDC_CHECK3 1076 #define IDC_CHECK3 1076
#define IDC_CAP0_ONESHOT 1076 #define IDC_CAP0_ONESHOT 1076
#define IDC_CHECK4 1077 #define IDC_CHECK4 1077

View File

@ -1602,7 +1602,6 @@ BEGIN
EDITTEXT IDC_ANALOG_DEADZONE,105,41,40,14,ES_AUTOHSCROLL | ES_NUMBER EDITTEXT IDC_ANALOG_DEADZONE,105,41,40,14,ES_AUTOHSCROLL | ES_NUMBER
RTEXT "Deadzone",-1,61,41,38,14,SS_CENTERIMAGE RTEXT "Deadzone",-1,61,41,38,14,SS_CENTERIMAGE
CONTROL "Joined Deadzone",IDC_ANALOG_JOINED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,66,63,71,10 CONTROL "Joined Deadzone",IDC_ANALOG_JOINED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,66,63,71,10
CONTROL "Circular Deadzone",IDC_ANALOG_CIRCLE,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,74,77,74,10
END END