CRT lightguns: 50 ms offscreen grace period (#599)
When a CRT lightgun starts reporting out-of-screen coordinates, the last good on-screen coordinates are retained and passed through for 50 ms. This improves GunCon 2 performance on NES, and generally makes CRT-based guns a bit more reliable in games with a lot of dark areas.
This commit is contained in:
58
input.cpp
58
input.cpp
@@ -1586,6 +1586,8 @@ static uint32_t autofire[NUMPLAYERS] = {};
|
||||
static uint32_t autofirecodes[NUMPLAYERS][BTN_NUM] = {};
|
||||
static int af_delay[NUMPLAYERS] = {};
|
||||
|
||||
static uint32_t crtgun_timeout[NUMDEV] = {};
|
||||
|
||||
static unsigned char mouse_btn = 0; //emulated mouse
|
||||
static unsigned char mice_btn = 0;
|
||||
static int mouse_req = 0;
|
||||
@@ -4865,7 +4867,7 @@ int input_test(int getchar)
|
||||
}
|
||||
}
|
||||
|
||||
if (ev.type == EV_ABS && (input[i].quirk == QUIRK_LIGHTGUN_CRT || input[i].quirk == QUIRK_LIGHTGUN))
|
||||
if (ev.type == EV_ABS && input[i].quirk == QUIRK_LIGHTGUN)
|
||||
{
|
||||
menu_lightgun_cb(i, ev.type, ev.code, ev.value);
|
||||
|
||||
@@ -4881,6 +4883,60 @@ int input_test(int getchar)
|
||||
}
|
||||
}
|
||||
|
||||
if (ev.type == EV_ABS && input[i].quirk == QUIRK_LIGHTGUN_CRT)
|
||||
{
|
||||
menu_lightgun_cb(i, ev.type, ev.code, ev.value);
|
||||
|
||||
if (ev.code == ABS_X)
|
||||
{
|
||||
absinfo.minimum = input[i].guncal[2];
|
||||
absinfo.maximum = input[i].guncal[3];
|
||||
|
||||
// When the gun loses tracking, give it a short grace period
|
||||
// before passing through the off-screen coordinates.
|
||||
// The GunCon 1 and 2 both report out-of-screen x values
|
||||
// more reliably than Y values, so X is used here.
|
||||
if (ev.value < absinfo.minimum || ev.value > absinfo.maximum)
|
||||
{
|
||||
// Grace period of 50 ms. Longer times here make guns a bit
|
||||
// more reliable on dark screens, but introduce lag to any mechanics
|
||||
// where you want to shoot offscreen (e.g., to reload.)
|
||||
if (!crtgun_timeout[i]) crtgun_timeout[i] = GetTimer(50);
|
||||
}
|
||||
else
|
||||
{
|
||||
crtgun_timeout[i] = 0;
|
||||
input[i].lastx = ev.value;
|
||||
}
|
||||
// For the window between losing the gun signal and the timer
|
||||
// running out, report the last on-screen coordinate
|
||||
if (crtgun_timeout[i] && !CheckTimer(crtgun_timeout[i]))
|
||||
{
|
||||
ev.value = input[i].lastx;
|
||||
}
|
||||
}
|
||||
else if (ev.code == ABS_Y)
|
||||
{
|
||||
absinfo.minimum = input[i].guncal[0];
|
||||
absinfo.maximum = input[i].guncal[1];
|
||||
|
||||
// Handle gun going off-screen
|
||||
if (crtgun_timeout[i])
|
||||
{
|
||||
// For the window between losing the gun signal and the timer
|
||||
// running out, report the last on-screen coordinate
|
||||
if (!CheckTimer(crtgun_timeout[i]))
|
||||
{
|
||||
ev.value = input[i].lasty;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
input[i].lasty = ev.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ev.type == EV_KEY && user_io_osd_is_visible())
|
||||
{
|
||||
if (input[i].quirk == QUIRK_WIIMOTE || input[i].quirk == QUIRK_LIGHTGUN_CRT || input[i].quirk == QUIRK_LIGHTGUN)
|
||||
|
||||
Reference in New Issue
Block a user