mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-29 07:02:12 +00:00
Joystick support fixes.
I did this because I wanted to fly around maps using a Spaceball 4000FLX, or any other 6DOF controller. These fixes help it work. Various fixes to joystick support: - joyaxiscallback() used strtol() to check to see if the supplied string was an integer, then didn't assign the parsed integer to the cvar. - Wrong multiplier for left/turnleft values. - Delete `axismap[]` from J_JoystickAxis(). It was causing problems, and smells like it was trying to do what the cvars joyadvaxis[xyzruv] are doing now. - Fix compiler error by adding case statements for: SDL_SENSOR_ACCEL_L SDL_SENSOR_ACCEL_R SDL_SENSOR_GYRO_L SDL_SENSOR_GYRO_R New cvar: "joyonly". "Joystick" axes are typically return-to-center affairs; their deflection values are therefore reported as -MAX - MAX, with zero in the center. "Game controllers" are similar, but also often have analog left and right "triggers" which are reported as 0 - MAX, with zero at one end (fully released to fully depressed). Unfortunately, SDL will try its darndest to make a joystick look like a "game controller." It does this by reinterpreting certain of the axes to report the range 0 - MAX, as if they were triggers. This is not a thing to do with 6DOF controllers, where all axes are return-to-center. While it may be remotely possible to put together an SDL2 controller mapping that reports -MAX - MAX on all axes, for me it was simpler to hack on FTEQW. Coupled with that is FTEQW's giving preference to "game controllers," i.e. if SDL_IsGameController() returns true, FTEQW will treat it as one. "joyonly" is a boolean cvar. If true, FTE will ignore "game controllers" and treat everything as a joystick. The default is false. "joyonly" must be set at startup to be effective, when the controllers are being enumerated by SDL.
This commit is contained in:
parent
ebbc6c0930
commit
1fda671b9a
2 changed files with 34 additions and 8 deletions
|
@ -31,9 +31,15 @@ void QDECL joyaxiscallback(cvar_t *var, char *oldvalue)
|
||||||
{
|
{
|
||||||
int sign;
|
int sign;
|
||||||
char *end;
|
char *end;
|
||||||
strtol(var->string, &end, 0);
|
sign = strtol(var->string, &end, 0);
|
||||||
if (!*end) //okay, its missing or an actual number.
|
if (!*end)
|
||||||
|
{
|
||||||
|
//okay, its missing or an actual number.
|
||||||
|
if (sign >= -6 && sign <= 6) {
|
||||||
|
var->ival = sign;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
end = var->string;
|
end = var->string;
|
||||||
if (*end == '-')
|
if (*end == '-')
|
||||||
|
@ -63,7 +69,7 @@ void QDECL joyaxiscallback(cvar_t *var, char *oldvalue)
|
||||||
else if (!Q_strcasecmp(end, "right") || !Q_strcasecmp(end, "turnright"))
|
else if (!Q_strcasecmp(end, "right") || !Q_strcasecmp(end, "turnright"))
|
||||||
var->ival = 4*sign;
|
var->ival = 4*sign;
|
||||||
else if (!Q_strcasecmp(end, "left") || !Q_strcasecmp(end, "turnleft"))
|
else if (!Q_strcasecmp(end, "left") || !Q_strcasecmp(end, "turnleft"))
|
||||||
var->ival = 4*sign*1;
|
var->ival = 4*sign*-1;
|
||||||
else if (!Q_strcasecmp(end, "up") || !Q_strcasecmp(end, "moveup"))
|
else if (!Q_strcasecmp(end, "up") || !Q_strcasecmp(end, "moveup"))
|
||||||
var->ival = 5*sign;
|
var->ival = 5*sign;
|
||||||
else if (!Q_strcasecmp(end, "down") || !Q_strcasecmp(end, "movedown"))
|
else if (!Q_strcasecmp(end, "down") || !Q_strcasecmp(end, "movedown"))
|
||||||
|
|
|
@ -95,6 +95,9 @@ static uint32_t SDL_GiveFinger(SDL_JoystickID jid, SDL_TouchID tid, SDL_FingerID
|
||||||
|
|
||||||
#if SDL_MAJOR_VERSION >= 2
|
#if SDL_MAJOR_VERSION >= 2
|
||||||
#define MAX_JOYSTICKS 16
|
#define MAX_JOYSTICKS 16
|
||||||
|
#ifndef MAXJOYAXIS
|
||||||
|
#define MAXJOYAXIS 6
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct
|
static struct
|
||||||
{
|
{
|
||||||
|
@ -154,6 +157,8 @@ static struct sdljoy_s
|
||||||
float buttonrepeat[countof(gpbuttonmap)];
|
float buttonrepeat[countof(gpbuttonmap)];
|
||||||
} sdljoy[MAX_JOYSTICKS];
|
} sdljoy[MAX_JOYSTICKS];
|
||||||
|
|
||||||
|
static cvar_t joy_only = CVARD("joyonly", "0", "If true, treats \"game controllers\" as regular joysticks.\nMust be set at startup.");
|
||||||
|
|
||||||
//the enumid is the value for the open function rather than the working id.
|
//the enumid is the value for the open function rather than the working id.
|
||||||
static void J_AllocateDevID(struct sdljoy_s *joy)
|
static void J_AllocateDevID(struct sdljoy_s *joy)
|
||||||
{
|
{
|
||||||
|
@ -184,6 +189,10 @@ static void J_ControllerAdded(int enumid)
|
||||||
{
|
{
|
||||||
const char *cname;
|
const char *cname;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (joy_only.ival)
|
||||||
|
return;
|
||||||
|
|
||||||
for (i = 0; i < MAX_JOYSTICKS; i++)
|
for (i = 0; i < MAX_JOYSTICKS; i++)
|
||||||
if (sdljoy[i].controller == NULL && sdljoy[i].joystick == NULL)
|
if (sdljoy[i].controller == NULL && sdljoy[i].joystick == NULL)
|
||||||
break;
|
break;
|
||||||
|
@ -213,7 +222,7 @@ static void J_JoystickAdded(int enumid)
|
||||||
if (i == MAX_JOYSTICKS)
|
if (i == MAX_JOYSTICKS)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (SDL_IsGameController(enumid)) //if its reported via the gamecontroller api then use that instead. don't open it twice.
|
if (!joy_only.ival && SDL_IsGameController(enumid)) //if its reported via the gamecontroller api then use that instead. don't open it twice.
|
||||||
return;
|
return;
|
||||||
|
|
||||||
sdljoy[i].joystick = SDL_JoystickOpen(enumid);
|
sdljoy[i].joystick = SDL_JoystickOpen(enumid);
|
||||||
|
@ -283,11 +292,17 @@ static void J_ControllerAxis(SDL_JoystickID jid, int axis, int value)
|
||||||
}
|
}
|
||||||
static void J_JoystickAxis(SDL_JoystickID jid, int axis, int value)
|
static void J_JoystickAxis(SDL_JoystickID jid, int axis, int value)
|
||||||
{
|
{
|
||||||
static const int axismap[] = {0,1,3,4,2,5};
|
|
||||||
|
|
||||||
struct sdljoy_s *joy = J_DevId(jid);
|
struct sdljoy_s *joy = J_DevId(jid);
|
||||||
if (joy && !joy->controller && axis < sizeof(axismap)/sizeof(axismap[0]) && joy->qdevid != DEVID_UNSET)
|
|
||||||
IN_JoystickAxisEvent(joy->qdevid, axismap[axis], value / 32767.0);
|
if (joy->qdevid == DEVID_UNSET)
|
||||||
|
{
|
||||||
|
if (abs(value) < 0x1000)
|
||||||
|
return;
|
||||||
|
J_AllocateDevID(joy);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (joy && !joy->controller && axis < MAXJOYAXIS && joy->qdevid != DEVID_UNSET)
|
||||||
|
IN_JoystickAxisEvent(joy->qdevid, axis, value / 32767.0);
|
||||||
}
|
}
|
||||||
//we don't do hats and balls and stuff.
|
//we don't do hats and balls and stuff.
|
||||||
static void J_ControllerButton(SDL_JoystickID jid, int button, qboolean pressed)
|
static void J_ControllerButton(SDL_JoystickID jid, int button, qboolean pressed)
|
||||||
|
@ -499,6 +514,10 @@ static void J_ControllerSensor(SDL_JoystickID jid, SDL_SensorType sensor, float
|
||||||
case SDL_SENSOR_GYRO:
|
case SDL_SENSOR_GYRO:
|
||||||
IN_Gyroscope(joy->qdevid, data[0], data[1], data[2]);
|
IN_Gyroscope(joy->qdevid, data[0], data[1], data[2]);
|
||||||
break;
|
break;
|
||||||
|
case SDL_SENSOR_ACCEL_L:
|
||||||
|
case SDL_SENSOR_ACCEL_R:
|
||||||
|
case SDL_SENSOR_GYRO_L:
|
||||||
|
case SDL_SENSOR_GYRO_R:
|
||||||
case SDL_SENSOR_INVALID:
|
case SDL_SENSOR_INVALID:
|
||||||
case SDL_SENSOR_UNKNOWN:
|
case SDL_SENSOR_UNKNOWN:
|
||||||
safedefault:
|
safedefault:
|
||||||
|
@ -1454,6 +1473,7 @@ void INS_Init (void)
|
||||||
#ifdef HAVE_SDL_TEXTINPUT
|
#ifdef HAVE_SDL_TEXTINPUT
|
||||||
Cvar_Register(&sys_osk, "input controls");
|
Cvar_Register(&sys_osk, "input controls");
|
||||||
#endif
|
#endif
|
||||||
|
Cvar_Register (&joy_only, "input controls");
|
||||||
|
|
||||||
#ifdef HAVE_SDL_TEXTINPUT
|
#ifdef HAVE_SDL_TEXTINPUT
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
|
|
Loading…
Reference in a new issue