Added dead zone configuration (#857)
User can define dead zone by device identifier and a radius.
This commit is contained in:
23
MiSTer.ini
23
MiSTer.ini
@@ -175,6 +175,29 @@ jamma2_pid=0x2222
|
||||
;no_merge_vidpid=0x12345678
|
||||
;no_merge_vidpid=0x11112222
|
||||
|
||||
; Dead zone radius definitions.
|
||||
; Joystick movements smaller than a defined radius will be neglected.
|
||||
; This is good for worn or poorly made joysticks and converters.
|
||||
; Devices that match the identifier part of the string will be affected.
|
||||
; You can add multiple devices (one entry per identifier).
|
||||
; The identifier part is case-insensitive, and the radius can be up to 64 units.
|
||||
; Identifier and radius are separated by a whitespace (' ') and/or a comma (',').
|
||||
; Accepted formats are:
|
||||
;
|
||||
; - VIDPID as an eight digit hex number ("0x" can be omitted), then the radius (not hex).
|
||||
;deadzone=0x1E8F1603, 25
|
||||
;
|
||||
; - vid:VID as a four digit hex, then the radius.
|
||||
;deadzone=vid:0x1e8f, 25
|
||||
;
|
||||
; - pid:PID as a four digit hex, then the radius.
|
||||
;deadzone=PID:1603 25
|
||||
;
|
||||
; - The following formats are explained a bit further down:
|
||||
;deadzone=usb-1.2/, 10
|
||||
;deadzone=7c:10:c9:15:22:33/df:47:3a:12:44:55, 8
|
||||
;deadzone=1e8f_1603_55c4dd0c, 5
|
||||
|
||||
; Permanently assign specific controller to specific player.
|
||||
; Normally you don't need to use this option, but if you use arcade cabinet with integrated controllers then
|
||||
; you may want to use it for specific player regardless which controller is used first.
|
||||
|
||||
45
cfg.cpp
45
cfg.cpp
@@ -64,6 +64,7 @@ static const ini_var_t ini_vars[] =
|
||||
{ "OSD_TIMEOUT", (void*)(&(cfg.osd_timeout)), INT16, 0, 3600 },
|
||||
{ "DIRECT_VIDEO", (void*)(&(cfg.direct_video)), UINT8, 0, 1 },
|
||||
{ "OSD_ROTATE", (void*)(&(cfg.osd_rotate)), UINT8, 0, 2 },
|
||||
{ "DEADZONE", (void*)(&(cfg.controller_deadzone)), STRINGARR, sizeof(cfg.controller_deadzone) / sizeof(*cfg.controller_deadzone), sizeof(*cfg.controller_deadzone) },
|
||||
{ "GAMEPAD_DEFAULTS", (void*)(&(cfg.gamepad_defaults)), UINT8, 0, 1 },
|
||||
{ "RECENTS", (void*)(&(cfg.recents)), UINT8, 0, 1 },
|
||||
{ "CONTROLLER_INFO", (void*)(&(cfg.controller_info)), UINT8, 0, 10 },
|
||||
@@ -97,35 +98,35 @@ static const ini_var_t ini_vars[] =
|
||||
{ "BT_AUTO_DISCONNECT", (void*)(&(cfg.bt_auto_disconnect)), UINT32, 0, 180 },
|
||||
{ "BT_RESET_BEFORE_PAIR", (void*)(&(cfg.bt_reset_before_pair)), UINT8, 0, 1 },
|
||||
{ "WAITMOUNT", (void*)(&(cfg.waitmount)), STRING, 0, sizeof(cfg.waitmount) - 1 },
|
||||
{ "RUMBLE", (void *)(&(cfg.rumble)), UINT8, 0, 1},
|
||||
{ "RUMBLE", (void *)(&(cfg.rumble)), UINT8, 0, 1 },
|
||||
{ "WHEEL_FORCE", (void*)(&(cfg.wheel_force)), UINT8, 0, 100 },
|
||||
{ "WHEEL_RANGE", (void*)(&(cfg.wheel_range)), UINT16, 0, 1000 },
|
||||
{ "HDMI_GAME_MODE", (void *)(&(cfg.hdmi_game_mode)), UINT8, 0, 1},
|
||||
{ "VRR_MODE", (void *)(&(cfg.vrr_mode)), UINT8, 0, 3},
|
||||
{ "VRR_MIN_FRAMERATE", (void *)(&(cfg.vrr_min_framerate)), UINT8, 0, 255},
|
||||
{ "VRR_MAX_FRAMERATE", (void *)(&(cfg.vrr_max_framerate)), UINT8, 0, 255},
|
||||
{ "VRR_VESA_FRAMERATE", (void *)(&(cfg.vrr_vesa_framerate)), UINT8, 0, 255},
|
||||
{ "HDMI_GAME_MODE", (void *)(&(cfg.hdmi_game_mode)), UINT8, 0, 1 },
|
||||
{ "VRR_MODE", (void *)(&(cfg.vrr_mode)), UINT8, 0, 3 },
|
||||
{ "VRR_MIN_FRAMERATE", (void *)(&(cfg.vrr_min_framerate)), UINT8, 0, 255 },
|
||||
{ "VRR_MAX_FRAMERATE", (void *)(&(cfg.vrr_max_framerate)), UINT8, 0, 255 },
|
||||
{ "VRR_VESA_FRAMERATE", (void *)(&(cfg.vrr_vesa_framerate)), UINT8, 0, 255 },
|
||||
{ "VIDEO_OFF", (void*)(&(cfg.video_off)), INT16, 0, 3600 },
|
||||
{ "PLAYER_1_CONTROLLER", (void*)(&(cfg.player_controller[0])), STRINGARR, sizeof(cfg.player_controller[0]) / sizeof(cfg.player_controller[0][0]), sizeof(cfg.player_controller[0][0])},
|
||||
{ "PLAYER_2_CONTROLLER", (void*)(&(cfg.player_controller[1])), STRINGARR, sizeof(cfg.player_controller[0]) / sizeof(cfg.player_controller[0][0]), sizeof(cfg.player_controller[0][0])},
|
||||
{ "PLAYER_3_CONTROLLER", (void*)(&(cfg.player_controller[2])), STRINGARR, sizeof(cfg.player_controller[0]) / sizeof(cfg.player_controller[0][0]), sizeof(cfg.player_controller[0][0])},
|
||||
{ "PLAYER_4_CONTROLLER", (void*)(&(cfg.player_controller[3])), STRINGARR, sizeof(cfg.player_controller[0]) / sizeof(cfg.player_controller[0][0]), sizeof(cfg.player_controller[0][0])},
|
||||
{ "PLAYER_5_CONTROLLER", (void*)(&(cfg.player_controller[4])), STRINGARR, sizeof(cfg.player_controller[0]) / sizeof(cfg.player_controller[0][0]), sizeof(cfg.player_controller[0][0])},
|
||||
{ "PLAYER_6_CONTROLLER", (void*)(&(cfg.player_controller[5])), STRINGARR, sizeof(cfg.player_controller[0]) / sizeof(cfg.player_controller[0][0]), sizeof(cfg.player_controller[0][0])},
|
||||
{ "DISABLE_AUTOFIRE", (void *)(&(cfg.disable_autofire)), UINT8, 0, 1},
|
||||
{ "VIDEO_BRIGHTNESS", (void *)(&(cfg.video_brightness)), UINT8, 0, 100},
|
||||
{ "VIDEO_CONTRAST", (void *)(&(cfg.video_contrast)), UINT8, 0, 100},
|
||||
{ "VIDEO_SATURATION", (void *)(&(cfg.video_saturation)), UINT8, 0, 100},
|
||||
{ "VIDEO_HUE", (void *)(&(cfg.video_hue)), UINT16, 0, 360},
|
||||
{ "VIDEO_GAIN_OFFSET", (void *)(&(cfg.video_gain_offset)), STRING, 0, sizeof(cfg.video_gain_offset)},
|
||||
{ "PLAYER_1_CONTROLLER", (void*)(&(cfg.player_controller[0])), STRINGARR, sizeof(cfg.player_controller[0]) / sizeof(cfg.player_controller[0][0]), sizeof(cfg.player_controller[0][0]) },
|
||||
{ "PLAYER_2_CONTROLLER", (void*)(&(cfg.player_controller[1])), STRINGARR, sizeof(cfg.player_controller[0]) / sizeof(cfg.player_controller[0][0]), sizeof(cfg.player_controller[0][0]) },
|
||||
{ "PLAYER_3_CONTROLLER", (void*)(&(cfg.player_controller[2])), STRINGARR, sizeof(cfg.player_controller[0]) / sizeof(cfg.player_controller[0][0]), sizeof(cfg.player_controller[0][0]) },
|
||||
{ "PLAYER_4_CONTROLLER", (void*)(&(cfg.player_controller[3])), STRINGARR, sizeof(cfg.player_controller[0]) / sizeof(cfg.player_controller[0][0]), sizeof(cfg.player_controller[0][0]) },
|
||||
{ "PLAYER_5_CONTROLLER", (void*)(&(cfg.player_controller[4])), STRINGARR, sizeof(cfg.player_controller[0]) / sizeof(cfg.player_controller[0][0]), sizeof(cfg.player_controller[0][0]) },
|
||||
{ "PLAYER_6_CONTROLLER", (void*)(&(cfg.player_controller[5])), STRINGARR, sizeof(cfg.player_controller[0]) / sizeof(cfg.player_controller[0][0]), sizeof(cfg.player_controller[0][0]) },
|
||||
{ "DISABLE_AUTOFIRE", (void *)(&(cfg.disable_autofire)), UINT8, 0, 1 },
|
||||
{ "VIDEO_BRIGHTNESS", (void *)(&(cfg.video_brightness)), UINT8, 0, 100 },
|
||||
{ "VIDEO_CONTRAST", (void *)(&(cfg.video_contrast)), UINT8, 0, 100 },
|
||||
{ "VIDEO_SATURATION", (void *)(&(cfg.video_saturation)), UINT8, 0, 100 },
|
||||
{ "VIDEO_HUE", (void *)(&(cfg.video_hue)), UINT16, 0, 360 },
|
||||
{ "VIDEO_GAIN_OFFSET", (void *)(&(cfg.video_gain_offset)), STRING, 0, sizeof(cfg.video_gain_offset) },
|
||||
{ "HDR", (void*)(&cfg.hdr), UINT8, 0, 2 },
|
||||
{ "HDR_MAX_NITS", (void*)(&(cfg.hdr_max_nits)), UINT16, 100, 10000},
|
||||
{ "HDR_AVG_NITS", (void*)(&(cfg.hdr_avg_nits)), UINT16, 100, 10000},
|
||||
{ "HDR_MAX_NITS", (void*)(&(cfg.hdr_max_nits)), UINT16, 100, 10000 },
|
||||
{ "HDR_AVG_NITS", (void*)(&(cfg.hdr_avg_nits)), UINT16, 100, 10000 },
|
||||
{ "VGA_MODE", (void*)(&(cfg.vga_mode)), STRING, 0, sizeof(cfg.vga_mode) - 1 },
|
||||
{ "NTSC_MODE", (void *)(&(cfg.ntsc_mode)), UINT8, 0, 2},
|
||||
{ "NTSC_MODE", (void *)(&(cfg.ntsc_mode)), UINT8, 0, 2 },
|
||||
{ "CONTROLLER_UNIQUE_MAPPING", (void *)(cfg.controller_unique_mapping), UINT32ARR, 0, 0xFFFFFFFF },
|
||||
{ "OSD_LOCK", (void*)(&(cfg.osd_lock)), STRING, 0, sizeof(cfg.osd_lock) - 1 },
|
||||
{ "OSD_LOCK_TIME", (void*)(&(cfg.osd_lock_time)), UINT16, 0, 60},
|
||||
{ "OSD_LOCK_TIME", (void*)(&(cfg.osd_lock_time)), UINT16, 0, 60 },
|
||||
};
|
||||
|
||||
static const int nvars = (int)(sizeof(ini_vars) / sizeof(ini_var_t));
|
||||
|
||||
1
cfg.h
1
cfg.h
@@ -72,6 +72,7 @@ typedef struct {
|
||||
char shmask_default[1023];
|
||||
char preset_default[1023];
|
||||
char player_controller[6][8][256];
|
||||
char controller_deadzone[8][256];
|
||||
uint8_t rumble;
|
||||
uint8_t wheel_force;
|
||||
uint16_t wheel_range;
|
||||
|
||||
229
input.cpp
229
input.cpp
@@ -37,7 +37,6 @@
|
||||
#define NUMPLAYERS 6
|
||||
#define UINPUT_NAME "MiSTer virtual input"
|
||||
|
||||
|
||||
char joy_bnames[NUMBUTTONS][32] = {};
|
||||
int joy_bcount = 0;
|
||||
static struct pollfd pool[NUMDEV + 3];
|
||||
@@ -1199,9 +1198,12 @@ typedef struct
|
||||
char id[80];
|
||||
char name[128];
|
||||
char sysfs[512];
|
||||
|
||||
int ss_range[2];
|
||||
int max_cardinal[2];
|
||||
float max_range[2];
|
||||
|
||||
uint32_t deadzone;
|
||||
} devInput;
|
||||
|
||||
static devInput input[NUMDEV] = {};
|
||||
@@ -1778,6 +1780,65 @@ static void mouse_btn_req()
|
||||
if (grabbed) mouse_req |= 2;
|
||||
}
|
||||
|
||||
static inline void joy_clamp(int* value, const int min, const int max)
|
||||
{
|
||||
if (*value < min) {
|
||||
*value = min;
|
||||
}
|
||||
else if (*value > max) {
|
||||
*value = max;
|
||||
}
|
||||
}
|
||||
|
||||
static inline float boxradf(const float angle)
|
||||
{
|
||||
return 1.0f / fmaxf(fabsf(sinf(angle)), fabsf(cosf(angle)));
|
||||
}
|
||||
|
||||
static void joy_apply_deadzone(int* x, int* y, const devInput* dev, const int stick) {
|
||||
// Don't be fancy with such a small deadzone.
|
||||
if (dev->deadzone <= 2)
|
||||
{
|
||||
if (dev->deadzone && (abs((*x > *y) == (*x > -*y) ? *x : *y) <= dev->deadzone))
|
||||
*x = *y = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
const float radius = hypotf(*x, *y);
|
||||
if (radius <= (float)dev->deadzone)
|
||||
{
|
||||
*x = *y = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
const float angle = atan2f(*y, *x);
|
||||
const float box_radius = boxradf(angle);
|
||||
|
||||
/* A measure of how "cardinal" the angle is,
|
||||
i.e closeness to [0, 90, 180, 270] degrees (0.0 - 1.0). */
|
||||
const float cardinality = (1.4142136f - box_radius) * 2.4142136f;
|
||||
|
||||
// Expected range for the given angle.
|
||||
const float max_cardinal = dev->max_cardinal[stick] > (2.0f * dev->deadzone) ? dev->max_cardinal[stick] : 127.0f;
|
||||
const float max_diagonal = dev->max_range[stick] > (2.0f * dev->deadzone) ? dev->max_range[stick] : 127.0f;
|
||||
const float range = cardinality * max_cardinal + (1.0f - cardinality) * max_diagonal;
|
||||
|
||||
const float weight = 1.0f - fmaxf(range - radius, .0f) / (range - dev->deadzone);
|
||||
const float adjusted_radius = fminf(weight * range, max_cardinal * box_radius);
|
||||
|
||||
/* Don't ever return a larger magnitude than that was given.
|
||||
The whole point of this function is to subtract some magnitude, not add. */
|
||||
if (adjusted_radius > radius) return;
|
||||
|
||||
*x = nearbyintf(adjusted_radius * cosf(angle));
|
||||
*y = nearbyintf(adjusted_radius * sinf(angle));
|
||||
|
||||
// Just to be sure.
|
||||
const int min_range = is_psx() ? -128 : -127;
|
||||
joy_clamp(x, min_range, INT8_MAX);
|
||||
joy_clamp(y, min_range, INT8_MAX);
|
||||
}
|
||||
|
||||
static uint32_t osdbtn = 0;
|
||||
static void joy_digital(int jnum, uint32_t mask, uint32_t code, char press, int bnum, int dont_save = 0)
|
||||
{
|
||||
@@ -2078,42 +2139,62 @@ static void joy_digital(int jnum, uint32_t mask, uint32_t code, char press, int
|
||||
}
|
||||
}
|
||||
|
||||
static bool joy_dir_is_diagonal(const int x, const int y)
|
||||
{
|
||||
static const float JOY_DIAG_THRESHOLD = .85f;
|
||||
|
||||
return
|
||||
((x == 0) || (y == 0)) ? false :
|
||||
((x == y) || (x == -y)) ? true :
|
||||
abs((x > y) == (x > -y) ? (float)y / x : (float)x / y) >= JOY_DIAG_THRESHOLD;
|
||||
}
|
||||
|
||||
static void joy_analog(int dev, int axis, int offset, int stick = 0)
|
||||
{
|
||||
int num = input[dev].num;
|
||||
static int pos[2][NUMPLAYERS][2] = {};
|
||||
|
||||
if (grabbed && num > 0 && num < NUMPLAYERS+1)
|
||||
if (grabbed && num > 0 && --num < NUMPLAYERS)
|
||||
{
|
||||
num--;
|
||||
pos[stick][num][axis] = offset;
|
||||
int x = pos[stick][num][0];
|
||||
int y = pos[stick][num][1];
|
||||
if (is_n64())
|
||||
int x = pos[stick][num][0], y = pos[stick][num][1];
|
||||
|
||||
if (joy_dir_is_diagonal(x, y))
|
||||
{
|
||||
// Update maximum observed cardinal distance
|
||||
const int abs_x = abs(x);
|
||||
const int abs_y = abs(y);
|
||||
|
||||
if (abs_x > input[dev].max_cardinal[stick]) input[dev].max_cardinal[stick] = abs_x;
|
||||
if (abs_y > input[dev].max_cardinal[stick]) input[dev].max_cardinal[stick] = abs_y;
|
||||
|
||||
// Update maximum observed diag
|
||||
// Use sum of squares and only calc sqrt() when necessary
|
||||
const int ss_range_curr = x*x + y*y;
|
||||
// compare to max ss_range and update if larger
|
||||
if ((ss_range_curr > input[dev].ss_range[stick]) & (abs(abs_x - abs_y) <= 3))
|
||||
const int ss_range_curr = x * x + y * y;
|
||||
if ((ss_range_curr > input[dev].ss_range[stick]))
|
||||
{
|
||||
input[dev].ss_range[stick] = ss_range_curr;
|
||||
input[dev].max_range[stick] = sqrt(ss_range_curr);
|
||||
input[dev].max_range[stick] = sqrtf(ss_range_curr);
|
||||
}
|
||||
|
||||
// emulate n64 joystick range and shape for regular -127-+127 controllers
|
||||
n64_joy_emu(x, y, &x, &y, input[dev].max_cardinal[stick], input[dev].max_range[stick]);
|
||||
stick_swap(num,stick,&num,&stick);
|
||||
}
|
||||
if(stick) user_io_r_analog_joystick(num, (char)x, (char)y);
|
||||
else user_io_l_analog_joystick(num, (char)x, (char)y);
|
||||
|
||||
// Update maximum observed cardinal distance
|
||||
const int c_dist = abs((x > y) == (x > -y) ? x : y);
|
||||
if (c_dist > input[dev].max_cardinal[stick])
|
||||
{
|
||||
input[dev].max_cardinal[stick] = c_dist;
|
||||
}
|
||||
|
||||
joy_apply_deadzone(&x, &y, &input[dev], stick);
|
||||
|
||||
if (is_n64())
|
||||
{
|
||||
// Emulate N64 joystick range and shape for regular -127-+127 controllers
|
||||
n64_joy_emu(x, y, &x, &y, input[dev].max_cardinal[stick], input[dev].max_range[stick]);
|
||||
stick_swap(num, stick, &num, &stick);
|
||||
}
|
||||
|
||||
if (stick)
|
||||
{
|
||||
user_io_r_analog_joystick(num, (char)x, (char)y);
|
||||
}
|
||||
else
|
||||
{
|
||||
user_io_l_analog_joystick(num, (char)x, (char)y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2573,6 +2654,81 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
|
||||
map_joystick_show(input[dev].map, input[dev].mmap, input[dev].num);
|
||||
}
|
||||
}
|
||||
|
||||
// Analog joystick dead zone
|
||||
{
|
||||
// Lightgun/wheel has no dead zone
|
||||
if (ev->type != EV_ABS || (ev->code <= 1 && (input[dev].lightgun || input[dev].quirk == QUIRK_WHEEL)))
|
||||
{
|
||||
input[dev].deadzone = 0U;
|
||||
}
|
||||
// Dual Shock 3/4
|
||||
else if (input[dev].quirk == QUIRK_DS3 || input[dev].quirk == QUIRK_DS4)
|
||||
{
|
||||
input[dev].deadzone = 10U;
|
||||
}
|
||||
// Default dead zone
|
||||
else
|
||||
{
|
||||
input[dev].deadzone = 2U;
|
||||
}
|
||||
|
||||
char cfg_format[32];
|
||||
char cfg_uid[sizeof(*cfg.controller_deadzone)];
|
||||
|
||||
snprintf(cfg_format, sizeof(cfg_format), "%%%u[^ \t,]%%*[ \t,]%%u%%n", (size_t)(sizeof(cfg_uid) - 1));
|
||||
|
||||
const char* dev_uid = get_unique_mapping(dev, 1);
|
||||
|
||||
for (size_t i = 0; i < sizeof(cfg.controller_deadzone) / sizeof(*cfg.controller_deadzone); i++)
|
||||
{
|
||||
const char* cfg_line = cfg.controller_deadzone[i];
|
||||
if (!cfg_line || !strlen(cfg_line)) break;
|
||||
|
||||
uint32_t cfg_vidpid, cfg_deadzone;
|
||||
size_t scan_pos;
|
||||
char vp;
|
||||
|
||||
if ((sscanf(cfg_line, cfg_format, cfg_uid, &cfg_deadzone, &scan_pos) < 2) ||
|
||||
(scan_pos != strlen(cfg_line))) continue;
|
||||
|
||||
if ((
|
||||
sscanf(cfg_uid, "0%*[Xx]%08x%n", &cfg_vidpid, &scan_pos) ||
|
||||
sscanf(cfg_uid, "%08x%n", &cfg_vidpid, &scan_pos)) &&
|
||||
(scan_pos == strlen(cfg_uid)))
|
||||
{
|
||||
const uint32_t vidpid = (input[dev].vid << 16) | input[dev].pid;
|
||||
if (vidpid != cfg_vidpid) continue;
|
||||
}
|
||||
else if ((
|
||||
(sscanf(cfg_uid, "%[VvPp]%*[Ii]%*[Dd]:0%*[Xx]%04x%n", &vp, &cfg_vidpid, &scan_pos) == 2) ||
|
||||
(sscanf(cfg_uid, "%[VvPp]%*[Ii]%*[Dd]:%04x%n", &vp, &cfg_vidpid, &scan_pos) == 2)) &&
|
||||
(scan_pos == strlen(cfg_uid)))
|
||||
{
|
||||
if (vp == 'V' || vp == 'v')
|
||||
{
|
||||
if (input[dev].vid != cfg_vidpid) continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (input[dev].pid != cfg_vidpid) continue;
|
||||
}
|
||||
}
|
||||
else if (
|
||||
!strcasestr(input[dev].id, cfg_uid) &&
|
||||
!strcasestr(input[dev].sysfs, cfg_uid) &&
|
||||
!strcasestr(dev_uid, cfg_uid))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cfg_deadzone > 64) cfg_deadzone = 64;
|
||||
|
||||
printf("Analog device %s was given a dead zone of %u\n", input[dev].id, cfg_deadzone);
|
||||
input[dev].deadzone = cfg_deadzone;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int old_combo = input[dev].osd_combo;
|
||||
@@ -3294,29 +3450,14 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
|
||||
}
|
||||
|
||||
int hrange = (absinfo->maximum - absinfo->minimum) / 2;
|
||||
int dead = hrange/63;
|
||||
|
||||
if (input[sub_dev].quirk == QUIRK_DS3 || input[sub_dev].quirk == QUIRK_DS4)
|
||||
{
|
||||
dead = 10;
|
||||
}
|
||||
|
||||
// normalize to -range/2...+range/2
|
||||
value = value - (absinfo->minimum + absinfo->maximum) / 2;
|
||||
|
||||
if (ev->code > 1 || (!input[dev].lightgun && input[dev].quirk != QUIRK_WHEEL)) //lightgun/wheel has no dead zone
|
||||
{
|
||||
// check the dead-zone and remove it from the range
|
||||
hrange -= dead;
|
||||
if (value < -dead) value += dead;
|
||||
else if (value > dead) value -= dead;
|
||||
else value = 0;
|
||||
}
|
||||
value -= (absinfo->minimum + absinfo->maximum) / 2;
|
||||
|
||||
int range = is_psx() ? 128 : 127;
|
||||
value = (value * range) / hrange;
|
||||
|
||||
//final check to eliminate additive error
|
||||
// final check to eliminate additive error
|
||||
if (value < -range) value = -range;
|
||||
else if (value > 127) value = 127;
|
||||
|
||||
@@ -3326,14 +3467,14 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
|
||||
if (ev->code == (input[dev].mmap[SYS_AXIS_MX] & 0xFFFF) && mouse_emu)
|
||||
{
|
||||
mouse_emu_x = 0;
|
||||
if (value < -1 || value>1) mouse_emu_x = value;
|
||||
if (value < -1 || value > 1) mouse_emu_x = value;
|
||||
mouse_emu_x /= 12;
|
||||
return;
|
||||
}
|
||||
else if (ev->code == (input[dev].mmap[SYS_AXIS_MY] & 0xFFFF) && mouse_emu)
|
||||
{
|
||||
mouse_emu_y = 0;
|
||||
if (value < -1 || value>1) mouse_emu_y = value;
|
||||
if (value < -1 || value > 1) mouse_emu_y = value;
|
||||
mouse_emu_y /= 12;
|
||||
return;
|
||||
}
|
||||
@@ -3389,7 +3530,7 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int
|
||||
}
|
||||
else
|
||||
{
|
||||
int offset = (value < -1 || value>1) ? value : 0;
|
||||
int offset = (value < -1 || value > 1) ? value : 0;
|
||||
if (input[dev].stick_l[0] && ev->code == (uint16_t)input[dev].mmap[input[dev].stick_l[0]])
|
||||
{
|
||||
joy_analog(dev, 0, offset, 0);
|
||||
@@ -5300,7 +5441,7 @@ int input_test(int getchar)
|
||||
|
||||
if (!noabs) input_cb(&ev, &absinfo, i);
|
||||
|
||||
//sumulate digital directions from analog
|
||||
// simulate digital directions from analog
|
||||
if (ev.type == EV_ABS && !(mapping && mapping_type <= 1 && mapping_button < -4) && !(ev.code <= 1 && input[dev].lightgun) && input[dev].quirk != QUIRK_PDSP && input[dev].quirk != QUIRK_MSSP)
|
||||
{
|
||||
input_absinfo *pai = 0;
|
||||
|
||||
Reference in New Issue
Block a user