Merge pull request #215 from 0lvin/joystick

Add joystick support
This commit is contained in:
Yamagi 2017-09-25 19:41:15 +02:00 committed by GitHub
commit b1e3c90a51
9 changed files with 920 additions and 121 deletions

View file

@ -101,6 +101,14 @@ vidmode_t vid_modes[] = {
{"Mode 21: 1920x1080", 1920, 1080, 21},
{"Mode 22: 1920x1200", 1920, 1200, 22},
{"Mode 23: 2048x1536", 2048, 1536, 23},
{"Mode 24: 2560x1080", 2560, 1080, 24},
{"Mode 25: 2560x1440", 2560, 1440, 25},
{"Mode 26: 2560x1600", 2560, 1600, 26},
{"Mode 27: 3440x1440", 3440, 1440, 27},
{"Mode 28: 3840x1600", 3840, 1600, 28},
{"Mode 29: 3840x2160", 3840, 2160, 29},
{"Mode 30: 4096x2160", 4096, 2160, 30},
{"Mode 31: 5120x2880", 5120, 2880, 31},
};
/* Console variables that we need to access from this module */

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 2010 Yamagi Burmeister
* Copyright (C) 1997-2001 Id Software, Inc.
* Copyright (C) 1997-2005 Id Software, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -23,6 +23,8 @@
* This is the Quake II input system backend, implemented with SDL.
*
* =======================================================================
*
* Joystick threshold code is partially based on http://ioquake3.org code.
*/
#include "../../client/header/keyboard.h"
@ -61,16 +63,64 @@
#define MOUSE_MAX 3000
#define MOUSE_MIN 40
/* Globals */
static int mouse_x, mouse_y;
static int old_mouse_x, old_mouse_y;
static qboolean mlooking;
#if SDL_VERSION_ATLEAST(2, 0, 0)
static int joystick_yaw, joystick_pitch;
static int joystick_forwardmove, joystick_sidemove;
static int joystick_up;
static char last_hat = SDL_HAT_CENTERED;
static qboolean left_trigger = false;
static qboolean right_trigger = false;
qboolean show_haptic = false;
/* Haptic feedback types */
enum QHARPICTYPES {
HAPTIC_EFFECT_UNKNOWN = -1,
HAPTIC_EFFECT_BLASTER = 0,
HAPTIC_EFFECT_MENY,
HAPTIC_EFFECT_HYPER_BLASTER,
HAPTIC_EFFECT_MACHINEGUN,
HAPTIC_EFFECT_SHOTGUN,
HAPTIC_EFFECT_SSHOTGUN,
HAPTIC_EFFECT_RAILGUN,
HAPTIC_EFFECT_ROCKETGUN,
HAPTIC_EFFECT_GRENADE,
HAPTIC_EFFECT_BFG,
HAPTIC_EFFECT_PALANX,
HAPTIC_EFFECT_IONRIPPER,
HAPTIC_EFFECT_ETFRIFLE,
HAPTIC_EFFECT_SHOTGUN2,
HAPTIC_EFFECT_TRACKER,
HAPTIC_EFFECT_PAIN,
HAPTIC_EFFECT_STEP,
HAPTIC_EFFECT_TRAPCOCK,
HAPTIC_EFFECT_LAST
};
struct hapric_effects_cache {
int effect_type;
int effect_id;
};
static int last_haptic_volume = 0;
static struct hapric_effects_cache last_haptic_efffect[HAPTIC_EFFECT_LAST];
static int last_haptic_efffect_size = HAPTIC_EFFECT_LAST;
static int last_haptic_efffect_pos = 0;
/* Joystick */
static SDL_Haptic *joystick_haptic = NULL;
static SDL_Joystick *joystick = NULL;
static SDL_GameController *controller = NULL;
#endif
/* CVars */
cvar_t *vid_fullscreen;
static cvar_t *in_grab;
static cvar_t *in_mouse;
static cvar_t *exponential_speedup;
cvar_t *freelook;
cvar_t *lookstrafe;
@ -78,10 +128,35 @@ cvar_t *m_forward;
static cvar_t *m_filter;
cvar_t *m_pitch;
cvar_t *m_side;
cvar_t *m_up;
cvar_t *m_yaw;
cvar_t *sensitivity;
static cvar_t *windowed_mouse;
#if SDL_VERSION_ATLEAST(2, 0, 0)
/* Joystick sensitivity */
static cvar_t *joy_yawsensitivity;
static cvar_t *joy_pitchsensitivity;
static cvar_t *joy_forwardsensitivity;
static cvar_t *joy_sidesensitivity;
static cvar_t *joy_upsensitivity;
/* Joystick direction settings */
static cvar_t *joy_axis_leftx;
static cvar_t *joy_axis_lefty;
static cvar_t *joy_axis_rightx;
static cvar_t *joy_axis_righty;
static cvar_t *joy_axis_triggerleft;
static cvar_t *joy_axis_triggerright;
/* Joystick threshold settings */
static cvar_t *joy_axis_leftx_threshold;
static cvar_t *joy_axis_lefty_threshold;
static cvar_t *joy_axis_rightx_threshold;
static cvar_t *joy_axis_righty_threshold;
static cvar_t *joy_axis_triggerleft_threshold;
static cvar_t *joy_axis_triggerright_threshold;
/* Joystick haptic */
static cvar_t *joy_haptic_magnitude;
#endif
extern void GLimp_GrabInput(qboolean grab);
@ -447,10 +522,149 @@ IN_Update(void)
}
#endif
break;
#if SDL_VERSION_ATLEAST(2, 0, 0)
case SDL_CONTROLLERAXISMOTION: /* Handle Controller Motion */
{
char* direction_type;
float threshold = 0;
float fix_value = 0;
int axis_value = event.caxis.value;
switch (event.caxis.axis)
{
/* left/right */
case SDL_CONTROLLER_AXIS_LEFTX:
direction_type = joy_axis_leftx->string;
threshold = joy_axis_leftx_threshold->value;
break;
/* top/bottom */
case SDL_CONTROLLER_AXIS_LEFTY:
direction_type = joy_axis_lefty->string;
threshold = joy_axis_lefty_threshold->value;
break;
/* second left/right */
case SDL_CONTROLLER_AXIS_RIGHTX:
direction_type = joy_axis_rightx->string;
threshold = joy_axis_rightx_threshold->value;
break;
/* second top/bottom */
case SDL_CONTROLLER_AXIS_RIGHTY:
direction_type = joy_axis_righty->string;
threshold = joy_axis_righty_threshold->value;
break;
case SDL_CONTROLLER_AXIS_TRIGGERLEFT:
direction_type = joy_axis_triggerleft->string;
threshold = joy_axis_triggerleft_threshold->value;
break;
case SDL_CONTROLLER_AXIS_TRIGGERRIGHT:
direction_type = joy_axis_triggerright->string;
threshold = joy_axis_triggerright_threshold->value;
break;
default:
direction_type = "none";
}
if (threshold > 0.9)
threshold = 0.9;
if (axis_value < 0 && (axis_value > (32768 * threshold)))
axis_value = 0;
else if (axis_value > 0 && (axis_value < (32768 * threshold)))
axis_value = 0;
// Smoothly ramp from dead zone to maximum value (from ioquake)
// https://github.com/ioquake/ioq3/blob/master/code/sdl/sdl_input.c
fix_value = ((float)abs(axis_value) / 32767.0f - threshold) / (1.0f - threshold);
if (fix_value < 0.0f)
fix_value = 0.0f;
axis_value = (int)(32767 * ((axis_value < 0) ? -fix_value : fix_value));
if (cls.key_dest == key_game && (int)cl_paused->value == 0)
{
if (strcmp(direction_type, "sidemove") == 0)
{
joystick_sidemove = axis_value * joy_sidesensitivity->value;
joystick_sidemove *= cl_sidespeed->value;
}
else if (strcmp(direction_type, "forwardmove") == 0)
{
joystick_forwardmove = axis_value * joy_forwardsensitivity->value;
// We need to be twice faster because with joystic we run...
joystick_forwardmove *= cl_forwardspeed->value * 2;
}
else if (strcmp(direction_type, "yaw") == 0)
{
joystick_yaw = axis_value * joy_yawsensitivity->value;
joystick_yaw *= cl_yawspeed->value;
}
else if (strcmp(direction_type, "pitch") == 0)
{
joystick_pitch = axis_value * joy_pitchsensitivity->value;
joystick_pitch *= cl_pitchspeed->value;
}
else if (strcmp(direction_type, "updown") == 0)
{
joystick_up = axis_value * joy_upsensitivity->value;
joystick_up *= cl_upspeed->value;
}
}
if (strcmp(direction_type, "triggerleft") == 0)
{
qboolean new_left_trigger = abs(axis_value) > (32767 / 4);
if (new_left_trigger != left_trigger)
{
left_trigger = new_left_trigger;
Key_Event(K_TRIG_LEFT, left_trigger, true);
}
}
else if (strcmp(direction_type, "triggerright") == 0)
{
qboolean new_right_trigger = abs(axis_value) > (32767 / 4);
if (new_right_trigger != right_trigger)
{
right_trigger = new_right_trigger;
Key_Event(K_TRIG_RIGHT, right_trigger, true);
}
}
}
break;
/* Joystick can have more buttons than on general game controller
* so try to map not free buttons */
case SDL_JOYBUTTONUP:
case SDL_JOYBUTTONDOWN:
{
qboolean down = (event.type == SDL_JOYBUTTONDOWN);
if(event.jbutton.button <= (K_JOY32 - K_JOY1)) {
Key_Event(event.jbutton.button + K_JOY1, down, true);
}
}
break;
case SDL_JOYHATMOTION:
{
if (last_hat != event.jhat.value)
{
char diff = last_hat ^ event.jhat.value;
int i;
for (i=0; i < 4; i++) {
if (diff & (1 << i)) {
/* check that we have button up for some bit */
if (last_hat & (1 << i))
Key_Event(i + K_HAT_UP, false, true);
/* check that we have button down for some bit */
if (event.jhat.value & (1 << i))
Key_Event(i + K_HAT_UP, true, true);
}
}
last_hat = event.jhat.value;
}
}
break;
#endif
case SDL_QUIT:
Com_Quit();
break;
}
}
@ -480,7 +694,7 @@ In_FlushQueue(void)
Key_MarkAllUp();
}
/*
* Move handling
*/
@ -559,8 +773,35 @@ IN_Move(usercmd_t *cmd)
mouse_x = mouse_y = 0;
}
#if SDL_VERSION_ATLEAST(2, 0, 0)
if (joystick_yaw)
{
cl.viewangles[YAW] -= (m_yaw->value * joystick_yaw) / 32768;
}
if(joystick_pitch)
{
cl.viewangles[PITCH] += (m_pitch->value * joystick_pitch) / 32768;
}
if (joystick_forwardmove)
{
cmd->forwardmove -= (m_forward->value * joystick_forwardmove) / 32768;
}
if (joystick_sidemove)
{
cmd->sidemove += (m_side->value * joystick_sidemove) / 32768;
}
if (joystick_up)
{
cmd->upmove -= (m_up->value * joystick_up) / 32768;
}
#endif
}
/* ------------------------------------------------------------------ */
/*
@ -582,7 +823,310 @@ IN_MLookUp(void)
IN_CenterView();
}
#if SDL_VERSION_ATLEAST(2, 0, 0)
/* ------------------------------------------------------------------ */
/*
* Init haptic effects
*/
static int
IN_Haptic_Effect_Init(int dir, int period, int magnitude, int length, int attack, int fade)
{
/*
* Direction:
* North - 0
* East - 9000
* South - 18000
* West - 27000
*/
int effect_id;
static SDL_HapticEffect haptic_effect;
SDL_memset(&haptic_effect, 0, sizeof(SDL_HapticEffect)); // 0 is safe default
haptic_effect.type = SDL_HAPTIC_SINE;
haptic_effect.periodic.direction.type = SDL_HAPTIC_POLAR; // Polar coordinates
haptic_effect.periodic.direction.dir[0] = dir;
haptic_effect.periodic.period = period;
haptic_effect.periodic.magnitude = magnitude;
haptic_effect.periodic.length = length;
haptic_effect.periodic.attack_length = attack;
haptic_effect.periodic.fade_length = fade;
effect_id = SDL_HapticNewEffect(joystick_haptic, &haptic_effect);
if (effect_id < 0)
{
Com_Printf ("SDL_HapticNewEffect failed: %s", SDL_GetError());
}
return effect_id;
}
static int
IN_Haptic_Effects_To_Id(int haptic_effect)
{
if ((SDL_HapticQuery(joystick_haptic) & SDL_HAPTIC_SINE)==0)
return -1;
int hapric_volume = joy_haptic_magnitude->value * 255; // * 128 = 32767 max strength;
if (hapric_volume > 255)
hapric_volume = 255;
else if (hapric_volume < 0)
hapric_volume = 0;
switch(haptic_effect) {
case HAPTIC_EFFECT_MENY:
case HAPTIC_EFFECT_TRAPCOCK:
case HAPTIC_EFFECT_STEP:
/* North */
return IN_Haptic_Effect_Init(
0/* Force comes from N*/, 500/* 500 ms*/, hapric_volume * 48,
200/* 0.2 seconds long */, 100/* Takes 0.1 second to get max strength */,
100/* Takes 0.1 second to fade away */);
case HAPTIC_EFFECT_PAIN:
return IN_Haptic_Effect_Init(
0/* Force comes from N*/, 700/* 700 ms*/, hapric_volume * 196,
300/* 0.3 seconds long */, 200/* Takes 0.2 second to get max strength */,
200/* Takes 0.2 second to fade away */);
case HAPTIC_EFFECT_BLASTER:
/* 30 degrees */
return IN_Haptic_Effect_Init(
2000/* Force comes from NNE*/, 500/* 500 ms*/, hapric_volume * 64,
200/* 0.2 seconds long */, 100/* Takes 0.1 second to get max strength */,
100/* Takes 0.1 second to fade away */);
case HAPTIC_EFFECT_HYPER_BLASTER:
return IN_Haptic_Effect_Init(
4000/* Force comes from NNE*/, 500/* 500 ms*/, hapric_volume * 64,
200/* 0.2 seconds long */, 100/* Takes 0.1 second to get max strength */,
100/* Takes 0.1 second to fade away */);
case HAPTIC_EFFECT_ETFRIFLE:
/* 60 degrees */
return IN_Haptic_Effect_Init(
5000/* Force comes from NEE*/, 500/* 500 ms*/, hapric_volume * 64,
200/* 0.2 seconds long */, 100/* Takes 0.1 second to get max strength */,
100/* Takes 0.1 second to fade away */);
case HAPTIC_EFFECT_TRACKER:
return IN_Haptic_Effect_Init(
7000/* Force comes from NEE*/, 500/* 500 ms*/, hapric_volume * 64,
200/* 0.2 seconds long */, 100/* Takes 0.1 second to get max strength */,
100/* Takes 0.1 second to fade away */);
case HAPTIC_EFFECT_MACHINEGUN:
/* 90 degrees */
return IN_Haptic_Effect_Init(
9000/* Force comes from E*/, 800/* 800 ms*/, hapric_volume * 88,
600/* 0.6 seconds long */, 200/* Takes 0.2 second to get max strength */,
400/* Takes 0.4 second to fade away */);
case HAPTIC_EFFECT_SHOTGUN:
/* 120 degrees */
return IN_Haptic_Effect_Init(
12000/* Force comes from EES*/, 700/* 700 ms*/, hapric_volume * 100,
500/* 0.5 seconds long */, 100/* Takes 0.1 second to get max strength */,
200/* Takes 0.2 second to fade away */);
case HAPTIC_EFFECT_SHOTGUN2:
/* 150 degrees */
return IN_Haptic_Effect_Init(
14000/* Force comes from ESS*/, 700/* 700 ms*/, hapric_volume * 96,
500/* 0.5 seconds long */, 100/* Takes 0.1 second to get max strength */,
100/* Takes 0.1 second to fade away */);
case HAPTIC_EFFECT_SSHOTGUN:
return IN_Haptic_Effect_Init(
16000/* Force comes from ESS*/, 700/* 700 ms*/, hapric_volume * 96,
500/* 0.5 seconds long */, 100/* Takes 0.1 second to get max strength */,
100/* Takes 0.1 second to fade away */);
case HAPTIC_EFFECT_RAILGUN:
/* 180 degrees */
return IN_Haptic_Effect_Init(
18000/* Force comes from S*/, 700/* 700 ms*/, hapric_volume * 64,
400/* 0.4 seconds long */, 100/* Takes 0.1 second to get max strength */,
100/* Takes 0.1 second to fade away */);
case HAPTIC_EFFECT_ROCKETGUN:
/* 210 degrees */
return IN_Haptic_Effect_Init(
21000/* Force comes from SSW*/, 700/* 700 ms*/, hapric_volume * 128,
400/* 0.4 seconds long */, 300/* Takes 0.3 second to get max strength */,
100/* Takes 0.1 second to fade away */);
case HAPTIC_EFFECT_GRENADE:
/* 240 degrees */
return IN_Haptic_Effect_Init(
24000/* Force comes from SWW*/, 500/* 500 ms*/, hapric_volume * 64,
200/* 0.2 seconds long */, 100/* Takes 0.1 second to get max strength */,
100/* Takes 0.1 second to fade away */);
case HAPTIC_EFFECT_BFG:
/* 270 degrees */
return IN_Haptic_Effect_Init(
27000/* Force comes from W*/, 800/* 800 ms*/, hapric_volume * 100,
600/* 0.2 seconds long */, 100/* Takes 0.1 second to get max strength */,
100/* Takes 0.1 second to fade away */);
case HAPTIC_EFFECT_PALANX:
/* 300 degrees */
return IN_Haptic_Effect_Init(
30000/* Force comes from WWN*/, 500/* 500 ms*/, hapric_volume * 64,
200/* 0.2 seconds long */, 100/* Takes 0.1 second to get max strength */,
100/* Takes 0.1 second to fade away */);
case HAPTIC_EFFECT_IONRIPPER:
/* 330 degrees */
return IN_Haptic_Effect_Init(
33000/* Force comes from WNN*/, 500/* 500 ms*/, hapric_volume * 64,
200/* 0.2 seconds long */, 100/* Takes 0.1 second to get max strength */,
100/* Takes 0.1 second to fade away */);
default:
return -1;
}
}
static void
IN_Haptic_Effects_Info(void)
{
show_haptic = true;
Com_Printf ("Joystic/Mouse haptic:\n");
Com_Printf (" * %d effects\n", SDL_HapticNumEffects(joystick_haptic));
Com_Printf (" * %d effects in same time\n", SDL_HapticNumEffectsPlaying(joystick_haptic));
Com_Printf (" * %d haptic axis\n", SDL_HapticNumAxes(joystick_haptic));
}
static void
IN_Haptic_Effects_Init(void)
{
last_haptic_efffect_size = SDL_HapticNumEffectsPlaying(joystick_haptic);
if (last_haptic_efffect_size > HAPTIC_EFFECT_LAST)
last_haptic_efffect_size = HAPTIC_EFFECT_LAST;
for (int i=0; i<HAPTIC_EFFECT_LAST; i++)
{
last_haptic_efffect[i].effect_type = HAPTIC_EFFECT_UNKNOWN;
last_haptic_efffect[i].effect_id = -1;
}
}
/*
* Shuts the backend down
*/
static void
IN_Haptic_Effect_Shutdown(int * effect_id)
{
if (!effect_id)
return;
if (*effect_id >= 0)
SDL_HapticDestroyEffect(joystick_haptic, *effect_id);
*effect_id = -1;
}
static void
IN_Haptic_Effects_Shotdown(void)
{
for (int i=0; i<HAPTIC_EFFECT_LAST; i++)
{
last_haptic_efffect[i].effect_type = HAPTIC_EFFECT_UNKNOWN;
IN_Haptic_Effect_Shutdown(&last_haptic_efffect[i].effect_id);
}
}
#endif
void
Haptic_Feedback(char *name)
{
#if SDL_VERSION_ATLEAST(2, 0, 0)
int effect_type = HAPTIC_EFFECT_UNKNOWN;
if (joy_haptic_magnitude->value <= 0)
return;
if (!joystick_haptic)
return;
if (last_haptic_volume != (int)(joy_haptic_magnitude->value * 255))
{
IN_Haptic_Effects_Shotdown();
IN_Haptic_Effects_Init();
}
last_haptic_volume = joy_haptic_magnitude->value * 255;
if (strstr(name, "misc/menu"))
{
effect_type = HAPTIC_EFFECT_MENY;
}
else if (strstr(name, "weapons/blastf1a"))
{
effect_type = HAPTIC_EFFECT_BLASTER;
}
else if (strstr(name, "weapons/hyprbf1a"))
{
effect_type = HAPTIC_EFFECT_HYPER_BLASTER;
}
else if (strstr(name, "weapons/machgf"))
{
effect_type = HAPTIC_EFFECT_MACHINEGUN;
}
else if (strstr(name, "weapons/shotgf1b"))
{
effect_type = HAPTIC_EFFECT_SHOTGUN;
}
else if (strstr(name, "weapons/sshotf1b"))
{
effect_type = HAPTIC_EFFECT_SSHOTGUN;
}
else if (strstr(name, "weapons/railgf1a"))
{
effect_type = HAPTIC_EFFECT_RAILGUN;
}
else if (strstr(name, "weapons/rocklf1a"))
{
effect_type = HAPTIC_EFFECT_ROCKETGUN;
}
else if (strstr(name, "weapons/grenlf1a") || strstr(name, "weapons/hgrent1a"))
{
effect_type = HAPTIC_EFFECT_GRENADE;
}
else if (strstr(name, "weapons/bfg__f1y"))
{
effect_type = HAPTIC_EFFECT_BFG;
}
else if (strstr(name, "weapons/plasshot"))
{
effect_type = HAPTIC_EFFECT_PALANX;
}
else if (strstr(name, "weapons/rippfire"))
{
effect_type = HAPTIC_EFFECT_IONRIPPER;
}
else if (strstr(name, "weapons/nail1"))
{
effect_type = HAPTIC_EFFECT_ETFRIFLE;
}
else if (strstr(name, "weapons/shotg2"))
{
effect_type = HAPTIC_EFFECT_SHOTGUN2;
}
else if (strstr(name, "weapons/disint2"))
{
effect_type = HAPTIC_EFFECT_TRACKER;
}
else if (strstr(name, "player/male/pain") ||
strstr(name, "player/female/pain") ||
strstr(name, "players/male/pain") ||
strstr(name, "players/female/pain"))
{
effect_type = HAPTIC_EFFECT_PAIN;
}
else if (strstr(name, "player/step") ||
strstr(name, "player/land"))
{
effect_type = HAPTIC_EFFECT_STEP;
}
else if (strstr(name, "weapons/trapcock"))
{
effect_type = HAPTIC_EFFECT_TRAPCOCK;
}
if (effect_type != HAPTIC_EFFECT_UNKNOWN)
{
// check last effect for reuse
if (last_haptic_efffect[last_haptic_efffect_pos].effect_type != effect_type)
{
// FIFO for effects
last_haptic_efffect_pos = (last_haptic_efffect_pos+1) % last_haptic_efffect_size;
IN_Haptic_Effect_Shutdown(&last_haptic_efffect[last_haptic_efffect_pos].effect_id);
last_haptic_efffect[last_haptic_efffect_pos].effect_type = effect_type;
last_haptic_efffect[last_haptic_efffect_pos].effect_id = IN_Haptic_Effects_To_Id(effect_type);
}
SDL_HapticRunEffect(joystick_haptic, last_haptic_efffect[last_haptic_efffect_pos].effect_id, 1);
}
#endif
}
/*
* Initializes the backend
@ -594,17 +1138,46 @@ IN_Init(void)
mouse_x = mouse_y = 0;
#if SDL_VERSION_ATLEAST(2, 0, 0)
joystick_yaw = joystick_pitch = joystick_forwardmove = joystick_sidemove = 0;
#endif
exponential_speedup = Cvar_Get("exponential_speedup", "0", CVAR_ARCHIVE);
freelook = Cvar_Get("freelook", "1", 0);
in_grab = Cvar_Get("in_grab", "2", CVAR_ARCHIVE);
in_mouse = Cvar_Get("in_mouse", "0", CVAR_ARCHIVE);
lookstrafe = Cvar_Get("lookstrafe", "0", 0);
m_filter = Cvar_Get("m_filter", "0", CVAR_ARCHIVE);
m_up = Cvar_Get("m_up", "1", 0);
m_forward = Cvar_Get("m_forward", "1", 0);
m_pitch = Cvar_Get("m_pitch", "0.022", 0);
m_side = Cvar_Get("m_side", "0.8", 0);
m_yaw = Cvar_Get("m_yaw", "0.022", 0);
sensitivity = Cvar_Get("sensitivity", "3", 0);
#if SDL_VERSION_ATLEAST(2, 0, 0)
joy_haptic_magnitude = Cvar_Get("joy_haptic_magnitude", "0.0", CVAR_ARCHIVE);
joy_yawsensitivity = Cvar_Get("joy_yawsensitivity", "1.0", CVAR_ARCHIVE);
joy_pitchsensitivity = Cvar_Get("joy_pitchsensitivity", "1.0", CVAR_ARCHIVE);
joy_forwardsensitivity = Cvar_Get("joy_forwardsensitivity", "1.0", CVAR_ARCHIVE);
joy_sidesensitivity = Cvar_Get("joy_sidesensitivity", "1.0", CVAR_ARCHIVE);
joy_upsensitivity = Cvar_Get("joy_upsensitivity", "1.0", CVAR_ARCHIVE);
joy_axis_leftx = Cvar_Get("joy_axis_leftx", "sidemove", CVAR_ARCHIVE);
joy_axis_lefty = Cvar_Get("joy_axis_lefty", "forwardmove", CVAR_ARCHIVE);
joy_axis_rightx = Cvar_Get("joy_axis_rightx", "yaw", CVAR_ARCHIVE);
joy_axis_righty = Cvar_Get("joy_axis_righty", "pitch", CVAR_ARCHIVE);
joy_axis_triggerleft = Cvar_Get("joy_axis_triggerleft", "triggerleft", CVAR_ARCHIVE);
joy_axis_triggerright = Cvar_Get("joy_axis_triggerright", "triggerright", CVAR_ARCHIVE);
joy_axis_leftx_threshold = Cvar_Get("joy_axis_leftx_threshold", "0.15", CVAR_ARCHIVE);
joy_axis_lefty_threshold = Cvar_Get("joy_axis_lefty_threshold", "0.15", CVAR_ARCHIVE);
joy_axis_rightx_threshold = Cvar_Get("joy_axis_rightx_threshold", "0.15", CVAR_ARCHIVE);
joy_axis_righty_threshold = Cvar_Get("joy_axis_righty_threshold", "0.15", CVAR_ARCHIVE);
joy_axis_triggerleft_threshold = Cvar_Get("joy_axis_triggerleft_threshold", "0.15", CVAR_ARCHIVE);
joy_axis_triggerright_threshold = Cvar_Get("joy_axis_triggerright_threshold", "0.15", CVAR_ARCHIVE);
#endif
vid_fullscreen = Cvar_Get("vid_fullscreen", "0", CVAR_ARCHIVE);
windowed_mouse = Cvar_Get("windowed_mouse", "1", CVAR_USERINFO | CVAR_ARCHIVE);
@ -617,6 +1190,76 @@ IN_Init(void)
SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
#endif
#if SDL_VERSION_ATLEAST(2, 0, 0)
/* joystik init */
if (!SDL_WasInit(SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC))
{
if (SDL_Init(SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC) == -1)
{
Com_Printf ("Couldn't init SDL joystick: %s.\n", SDL_GetError ());
} else {
Com_Printf ("%i joysticks were found.\n", SDL_NumJoysticks());
if (SDL_NumJoysticks() > 0) {
int i;
for (i=0; i<SDL_NumJoysticks(); i ++) {
joystick = SDL_JoystickOpen(i);
Com_Printf ("The name of the joystick is '%s'\n", SDL_JoystickName(joystick));
Com_Printf ("Number of Axes: %d\n", SDL_JoystickNumAxes(joystick));
Com_Printf ("Number of Buttons: %d\n", SDL_JoystickNumButtons(joystick));
Com_Printf ("Number of Balls: %d\n", SDL_JoystickNumBalls(joystick));
Com_Printf ("Number of Hats: %d\n", SDL_JoystickNumHats(joystick));
joystick_haptic = SDL_HapticOpenFromJoystick(joystick);
if (joystick_haptic == NULL)
Com_Printf ("Most likely joystick isn't haptic\n");
else
IN_Haptic_Effects_Info();
if(SDL_IsGameController(i))
{
controller = SDL_GameControllerOpen(i);
Com_Printf ("Controller settings: %s\n", SDL_GameControllerMapping(controller));
Com_Printf ("Controller axis: \n");
Com_Printf (" * leftx = %s\n", joy_axis_leftx->string);
Com_Printf (" * lefty = %s\n", joy_axis_lefty->string);
Com_Printf (" * rightx = %s\n", joy_axis_rightx->string);
Com_Printf (" * righty = %s\n", joy_axis_righty->string);
Com_Printf (" * triggerleft = %s\n", joy_axis_triggerleft->string);
Com_Printf (" * triggerright = %s\n", joy_axis_triggerright->string);
Com_Printf ("Controller thresholds: \n");
Com_Printf (" * leftx = %f\n", joy_axis_leftx_threshold->value);
Com_Printf (" * lefty = %f\n", joy_axis_lefty_threshold->value);
Com_Printf (" * rightx = %f\n", joy_axis_rightx_threshold->value);
Com_Printf (" * righty = %f\n", joy_axis_righty_threshold->value);
Com_Printf (" * triggerleft = %f\n", joy_axis_triggerleft_threshold->value);
Com_Printf (" * triggerright = %f\n", joy_axis_triggerright_threshold->value);
break;
}
else
{
char joystick_guid[256] = {0};
SDL_JoystickGUID guid;
guid = SDL_JoystickGetDeviceGUID(i);
SDL_JoystickGetGUIDString(guid, joystick_guid, 255);
Com_Printf ("For use joystic as game contoller please set SDL_GAMECONTROLLERCONFIG:\n");
Com_Printf ("e.g.: SDL_GAMECONTROLLERCONFIG='%s,%s,leftx:a0,lefty:a1,rightx:a2,righty:a3,...\n", joystick_guid, SDL_JoystickName(joystick));
}
}
}
else
{
joystick_haptic = SDL_HapticOpenFromMouse();
if (joystick_haptic == NULL)
Com_Printf ("Most likely mouse isn't haptic\n");
else
IN_Haptic_Effects_Info();
}
}
}
#endif
Com_Printf("------------------------------------\n\n");
}
@ -630,7 +1273,29 @@ IN_Shutdown(void)
Cmd_RemoveCommand("+mlook");
Cmd_RemoveCommand("-mlook");
Com_Printf("Shutting down input.\n");
Com_Printf("Shutting down input.\n");
#if SDL_VERSION_ATLEAST(2, 0, 0)
if (joystick_haptic)
{
IN_Haptic_Effects_Shotdown();
SDL_HapticClose(joystick_haptic);
joystick_haptic = NULL;
}
if (controller)
{
SDL_GameControllerClose(controller);
controller = NULL;
}
if (joystick)
{
SDL_JoystickClose(joystick);
joystick = NULL;
}
#endif
}
/* ------------------------------------------------------------------ */

View file

@ -106,6 +106,47 @@ keyname_t keynames[] = {
{"MOUSE4", K_MOUSE4},
{"MOUSE5", K_MOUSE5},
{"JOY1", K_JOY1},
{"JOY2", K_JOY2},
{"JOY3", K_JOY3},
{"JOY4", K_JOY4},
{"JOY5", K_JOY5},
{"JOY6", K_JOY6},
{"JOY7", K_JOY7},
{"JOY8", K_JOY8},
{"JOY9", K_JOY9},
{"JOY10", K_JOY10},
{"JOY11", K_JOY11},
{"JOY12", K_JOY12},
{"JOY13", K_JOY13},
{"JOY14", K_JOY14},
{"JOY15", K_JOY15},
{"JOY16", K_JOY16},
{"JOY17", K_JOY17},
{"JOY18", K_JOY18},
{"JOY19", K_JOY19},
{"JOY20", K_JOY20},
{"JOY21", K_JOY21},
{"JOY22", K_JOY22},
{"JOY23", K_JOY23},
{"JOY24", K_JOY24},
{"JOY25", K_JOY25},
{"JOY26", K_JOY26},
{"JOY27", K_JOY27},
{"JOY28", K_JOY28},
{"JOY29", K_JOY29},
{"JOY30", K_JOY30},
{"JOY31", K_JOY31},
{"JOY32", K_JOY32},
{"HAT_UP", K_HAT_UP},
{"HAT_RIGHT", K_HAT_RIGHT},
{"HAT_DOWN", K_HAT_DOWN},
{"HAT_LEFT", K_HAT_LEFT},
{"TRIG_LEFT", K_TRIG_LEFT},
{"TRIG_RIGHT", K_TRIG_RIGHT},
{"AUX1", K_AUX1},
{"AUX2", K_AUX2},
{"AUX3", K_AUX3},
@ -562,7 +603,7 @@ Key_Message(int key)
}
/*
* Returns a key number to be used to index
* Returns a key number to be used to index
* keybindings[] by looking at the given string.
* Single ascii characters return themselves, while
* the K_* names are matched up.
@ -773,7 +814,7 @@ Key_WriteBindings(FILE *f)
{
if (keybindings[i] && keybindings[i][0])
{
fprintf(f, "bind %s \"%s\"\n",
fprintf(f, "bind %s \"%s\"\n",
Key_KeynumToString(i), keybindings[i]);
}
}
@ -1061,7 +1102,7 @@ Key_Event(int key, qboolean down, qboolean special)
}
/* Key is unbound */
if ((key >= 200) && !keybindings[key] && (cls.key_dest != key_console))
if ((key >= K_MOUSE1) && !keybindings[key] && (cls.key_dest != key_console))
{
Com_Printf("%s is unbound, hit F4 to set.\n", Key_KeynumToString(key));
}

View file

@ -57,7 +57,6 @@ cvar_t *cl_showclamp;
cvar_t *cl_paused;
cvar_t *lookspring;
cvar_t *lookstrafe;
cvar_t *sensitivity;
@ -490,7 +489,6 @@ CL_InitLocal(void)
cl_run = Cvar_Get("cl_run", "0", CVAR_ARCHIVE);
freelook = Cvar_Get("freelook", "1", CVAR_ARCHIVE);
lookspring = Cvar_Get("lookspring", "0", CVAR_ARCHIVE);
lookstrafe = Cvar_Get("lookstrafe", "0", CVAR_ARCHIVE);
sensitivity = Cvar_Get("sensitivity", "3", CVAR_ARCHIVE);

View file

@ -271,7 +271,6 @@ extern cvar_t *cl_anglespeedkey;
extern cvar_t *cl_shownet;
extern cvar_t *cl_showmiss;
extern cvar_t *cl_showclamp;
extern cvar_t *lookspring;
extern cvar_t *lookstrafe;
extern cvar_t *sensitivity;
extern cvar_t *m_pitch;

View file

@ -144,6 +144,14 @@ enum QKEYS {
K_JOY31,
K_JOY32,
K_HAT_UP,
K_HAT_RIGHT,
K_HAT_DOWN,
K_HAT_LEFT,
K_TRIG_LEFT,
K_TRIG_RIGHT,
K_AUX1,
K_AUX2,
K_AUX3,
@ -305,6 +313,7 @@ void Key_ReadConsoleHistory();
void Key_WriteConsoleHistory();
void Key_SetBinding(int keynum, char *binding);
void Key_MarkAllUp(void);
int Key_GetKey(void);
void Haptic_Feedback(char *name);
int Key_GetMenuKey(int key);
#endif

View file

@ -215,11 +215,118 @@ M_PushMenu(void (*draw)(void), const char *(*key)(int))
cls.key_dest = key_menu;
}
int
Key_GetMenuKey(int key)
{
switch (key)
{
case K_KP_UPARROW:
case K_UPARROW:
case K_HAT_UP:
return K_UPARROW;
case K_TAB:
case K_KP_DOWNARROW:
case K_DOWNARROW:
case K_HAT_DOWN:
return K_DOWNARROW;
case K_KP_LEFTARROW:
case K_LEFTARROW:
case K_HAT_LEFT:
case K_TRIG_LEFT:
return K_LEFTARROW;
case K_KP_RIGHTARROW:
case K_RIGHTARROW:
case K_HAT_RIGHT:
case K_TRIG_RIGHT:
return K_RIGHTARROW;
case K_MOUSE1:
case K_MOUSE2:
case K_MOUSE3:
case K_MOUSE4:
case K_MOUSE5:
case K_JOY1:
case K_JOY2:
case K_JOY3:
case K_JOY4:
case K_JOY5:
case K_JOY6:
case K_JOY7:
case K_JOY8:
case K_JOY9:
case K_JOY10:
case K_JOY11:
case K_JOY12:
case K_JOY13:
case K_JOY14:
case K_JOY15:
case K_JOY16:
case K_JOY17:
case K_JOY18:
case K_JOY19:
case K_JOY20:
case K_JOY21:
case K_JOY22:
case K_JOY23:
case K_JOY24:
case K_JOY25:
case K_JOY26:
case K_JOY27:
case K_JOY28:
case K_JOY29:
case K_JOY30:
case K_JOY31:
case K_AUX1:
case K_AUX2:
case K_AUX3:
case K_AUX4:
case K_AUX5:
case K_AUX6:
case K_AUX7:
case K_AUX8:
case K_AUX9:
case K_AUX10:
case K_AUX11:
case K_AUX12:
case K_AUX13:
case K_AUX14:
case K_AUX15:
case K_AUX16:
case K_AUX17:
case K_AUX18:
case K_AUX19:
case K_AUX20:
case K_AUX21:
case K_AUX22:
case K_AUX23:
case K_AUX24:
case K_AUX25:
case K_AUX26:
case K_AUX27:
case K_AUX28:
case K_AUX29:
case K_AUX30:
case K_AUX31:
case K_AUX32:
case K_KP_ENTER:
case K_ENTER:
return K_ENTER;
}
return key;
}
const char *
Default_MenuKey(menuframework_s *m, int key)
{
const char *sound = NULL;
menucommon_s *item;
int menu_key = Key_GetMenuKey(key);
if (m)
{
@ -235,110 +342,51 @@ Default_MenuKey(menuframework_s *m, int key)
}
}
switch (key)
switch (menu_key)
{
case K_ESCAPE:
M_PopMenu();
return menu_out_sound;
case K_KP_UPARROW:
case K_UPARROW:
case K_UPARROW:
if (m)
{
m->cursor--;
Menu_AdjustCursor(m, -1);
sound = menu_move_sound;
}
break;
case K_TAB:
if (m)
{
m->cursor++;
Menu_AdjustCursor(m, 1);
sound = menu_move_sound;
}
break;
case K_KP_DOWNARROW:
case K_DOWNARROW:
if (m)
{
m->cursor++;
Menu_AdjustCursor(m, 1);
sound = menu_move_sound;
}
break;
case K_KP_LEFTARROW:
case K_LEFTARROW:
case K_LEFTARROW:
if (m)
{
Menu_SlideItem(m, -1);
sound = menu_move_sound;
}
break;
case K_KP_RIGHTARROW:
case K_RIGHTARROW:
case K_RIGHTARROW:
if (m)
{
Menu_SlideItem(m, 1);
sound = menu_move_sound;
}
break;
case K_MOUSE1:
case K_MOUSE2:
case K_MOUSE3:
case K_MOUSE4:
case K_MOUSE5:
case K_AUX1:
case K_AUX2:
case K_AUX3:
case K_AUX4:
case K_AUX5:
case K_AUX6:
case K_AUX7:
case K_AUX8:
case K_AUX9:
case K_AUX10:
case K_AUX11:
case K_AUX12:
case K_AUX13:
case K_AUX14:
case K_AUX15:
case K_AUX16:
case K_AUX17:
case K_AUX18:
case K_AUX19:
case K_AUX20:
case K_AUX21:
case K_AUX22:
case K_AUX23:
case K_AUX24:
case K_AUX25:
case K_AUX26:
case K_AUX27:
case K_AUX28:
case K_AUX29:
case K_AUX30:
case K_AUX31:
case K_AUX32:
case K_KP_ENTER:
case K_ENTER:
if (m)
{
Menu_SelectItem(m);
}
sound = menu_move_sound;
break;
}
@ -593,35 +641,29 @@ M_Main_Draw(void)
const char *
M_Main_Key(int key)
{
const char *sound = menu_move_sound;
const char *sound = menu_move_sound;
int menu_key = Key_GetMenuKey(key);
switch (key)
switch (menu_key)
{
case K_ESCAPE:
M_PopMenu();
break;
case K_KP_DOWNARROW:
case K_DOWNARROW:
if (++m_main_cursor >= MAIN_ITEMS)
{
m_main_cursor = 0;
}
return sound;
case K_KP_UPARROW:
case K_UPARROW:
if (--m_main_cursor < 0)
{
m_main_cursor = MAIN_ITEMS - 1;
}
return sound;
case K_KP_ENTER:
case K_ENTER:
m_entersound = true;
@ -1003,10 +1045,12 @@ static menuslider_s s_options_sensitivity_slider;
static menulist_s s_options_freelook_box;
static menulist_s s_options_alwaysrun_box;
static menulist_s s_options_invertmouse_box;
static menulist_s s_options_lookspring_box;
static menulist_s s_options_lookstrafe_box;
static menulist_s s_options_crosshair_box;
static menuslider_s s_options_sfxvolume_slider;
#ifdef SDL2
static menuslider_s s_options_haptic_slider;
#endif
#if defined(OGG) || defined(CDA)
static menulist_s s_options_cdshuffle_box;
#endif
@ -1023,6 +1067,14 @@ CrosshairFunc(void *unused)
Cvar_SetValue("crosshair", (float)s_options_crosshair_box.curvalue);
}
#ifdef SDL2
static void
HapticMagnitudeFunc(void *unused)
{
Cvar_SetValue("joy_haptic_magnitude", s_options_haptic_slider.curvalue / 10.0F);
}
#endif
static void
CustomizeControlsFunc(void *unused)
{
@ -1097,13 +1149,15 @@ ControlsSetMenuItemValues(void)
s_options_invertmouse_box.curvalue = (m_pitch->value < 0);
s_options_lookspring_box.curvalue = (lookspring->value != 0);
s_options_lookstrafe_box.curvalue = (lookstrafe->value != 0);
s_options_freelook_box.curvalue = (freelook->value != 0);
s_options_crosshair_box.curvalue = ClampCvar(0, 3, crosshair->value);
#ifdef SDL2
s_options_haptic_slider.curvalue = Cvar_VariableValue("joy_haptic_magnitude") * 10.0F;
#endif
}
static void
@ -1122,12 +1176,6 @@ InvertMouseFunc(void *unused)
Cvar_SetValue("m_pitch", -m_pitch->value);
}
static void
LookspringFunc(void *unused)
{
Cvar_SetValue("lookspring", (float)!lookspring->value);
}
static void
LookstrafeFunc(void *unused)
{
@ -1319,7 +1367,11 @@ Options_MenuInit(void)
0
};
float scale = SCR_GetMenuScale();
float scale = SCR_GetMenuScale();
#ifdef SDL2
extern qboolean show_haptic;
#endif
/* configure controls menu and menu items */
s_options_menu.x = viddef.width / 2;
@ -1389,34 +1441,37 @@ Options_MenuInit(void)
s_options_invertmouse_box.generic.callback = InvertMouseFunc;
s_options_invertmouse_box.itemnames = yesno_names;
s_options_lookspring_box.generic.type = MTYPE_SPINCONTROL;
s_options_lookspring_box.generic.x = 0;
s_options_lookspring_box.generic.y = 90;
s_options_lookspring_box.generic.name = "lookspring";
s_options_lookspring_box.generic.callback = LookspringFunc;
s_options_lookspring_box.itemnames = yesno_names;
s_options_lookstrafe_box.generic.type = MTYPE_SPINCONTROL;
s_options_lookstrafe_box.generic.x = 0;
s_options_lookstrafe_box.generic.y = 100;
s_options_lookstrafe_box.generic.y = 90;
s_options_lookstrafe_box.generic.name = "lookstrafe";
s_options_lookstrafe_box.generic.callback = LookstrafeFunc;
s_options_lookstrafe_box.itemnames = yesno_names;
s_options_freelook_box.generic.type = MTYPE_SPINCONTROL;
s_options_freelook_box.generic.x = 0;
s_options_freelook_box.generic.y = 110;
s_options_freelook_box.generic.y = 100;
s_options_freelook_box.generic.name = "free look";
s_options_freelook_box.generic.callback = FreeLookFunc;
s_options_freelook_box.itemnames = yesno_names;
s_options_crosshair_box.generic.type = MTYPE_SPINCONTROL;
s_options_crosshair_box.generic.x = 0;
s_options_crosshair_box.generic.y = 120;
s_options_crosshair_box.generic.y = 110;
s_options_crosshair_box.generic.name = "crosshair";
s_options_crosshair_box.generic.callback = CrosshairFunc;
s_options_crosshair_box.itemnames = crosshair_names;
#ifdef SDL2
s_options_haptic_slider.generic.type = MTYPE_SLIDER;
s_options_haptic_slider.generic.x = 0;
s_options_haptic_slider.generic.y = 120;
s_options_haptic_slider.generic.name = "haptic magnitude";
s_options_haptic_slider.generic.callback = HapticMagnitudeFunc;
s_options_haptic_slider.minvalue = 0;
s_options_haptic_slider.maxvalue = 22;
#endif
s_options_customize_options_action.generic.type = MTYPE_ACTION;
s_options_customize_options_action.generic.x = 0;
s_options_customize_options_action.generic.y = 140;
@ -1450,10 +1505,15 @@ Options_MenuInit(void)
Menu_AddItem(&s_options_menu, (void *)&s_options_sensitivity_slider);
Menu_AddItem(&s_options_menu, (void *)&s_options_alwaysrun_box);
Menu_AddItem(&s_options_menu, (void *)&s_options_invertmouse_box);
Menu_AddItem(&s_options_menu, (void *)&s_options_lookspring_box);
Menu_AddItem(&s_options_menu, (void *)&s_options_lookstrafe_box);
Menu_AddItem(&s_options_menu, (void *)&s_options_freelook_box);
Menu_AddItem(&s_options_menu, (void *)&s_options_crosshair_box);
#ifdef SDL2
if (show_haptic)
Menu_AddItem(&s_options_menu, (void *)&s_options_haptic_slider);
#endif
Menu_AddItem(&s_options_menu, (void *)&s_options_customize_options_action);
Menu_AddItem(&s_options_menu, (void *)&s_options_defaults_action);
Menu_AddItem(&s_options_menu, (void *)&s_options_console_action);
@ -2305,10 +2365,10 @@ static const char *
LoadGame_MenuKey(int key)
{
static menuframework_s *m = &s_loadgame_menu;
int menu_key = Key_GetMenuKey(key);
switch (key)
switch (menu_key)
{
case K_KP_UPARROW:
case K_UPARROW:
if (m->cursor == 0)
{
@ -2316,8 +2376,7 @@ LoadGame_MenuKey(int key)
LoadGame_MenuInit();
}
break;
case K_TAB:
case K_KP_DOWNARROW:
case K_DOWNARROW:
if (m->cursor == m->nitems - 1)
{
@ -2325,16 +2384,17 @@ LoadGame_MenuKey(int key)
LoadGame_MenuInit();
}
break;
case K_KP_LEFTARROW:
case K_LEFTARROW:
LoadSave_AdjustPage(-1);
LoadGame_MenuInit();
return menu_move_sound;
case K_KP_RIGHTARROW:
case K_RIGHTARROW:
LoadSave_AdjustPage(1);
LoadGame_MenuInit();
return menu_move_sound;
default:
s_savegame_menu.cursor = s_loadgame_menu.cursor;
break;
@ -2416,6 +2476,7 @@ static const char *
SaveGame_MenuKey(int key)
{
static menuframework_s *m = &s_savegame_menu;
int menu_key = Key_GetMenuKey(key);
if (m_popup_string)
{
@ -2423,9 +2484,8 @@ SaveGame_MenuKey(int key)
return NULL;
}
switch (key)
switch (menu_key)
{
case K_KP_UPARROW:
case K_UPARROW:
if (m->cursor == 0)
{
@ -2433,8 +2493,7 @@ SaveGame_MenuKey(int key)
SaveGame_MenuInit();
}
break;
case K_TAB:
case K_KP_DOWNARROW:
case K_DOWNARROW:
if (m->cursor == m->nitems - 1)
{
@ -2442,16 +2501,17 @@ SaveGame_MenuKey(int key)
SaveGame_MenuInit();
}
break;
case K_KP_LEFTARROW:
case K_LEFTARROW:
LoadSave_AdjustPage(-1);
SaveGame_MenuInit();
return menu_move_sound;
case K_KP_RIGHTARROW:
case K_RIGHTARROW:
LoadSave_AdjustPage(1);
SaveGame_MenuInit();
return menu_move_sound;
default:
s_loadgame_menu.cursor = s_savegame_menu.cursor;
break;

View file

@ -261,6 +261,14 @@ VID_MenuInit(void)
"[1920 1080 ]",
"[1920 1200 ]",
"[2048 1536 ]",
"[2560x1080 ]",
"[2560x1440 ]",
"[2560x1600 ]",
"[3440x1440 ]",
"[3840x1600 ]",
"[3840x2160 ]",
"[4096x2160 ]",
"[5120x2880 ]",
"[custom ]",
0
};
@ -522,8 +530,9 @@ VID_MenuKey(int key)
menuframework_s *m = &s_opengl_menu;
static const char *sound = "misc/menu1.wav";
int menu_key = Key_GetMenuKey(key);
switch (key)
switch (menu_key)
{
case K_ESCAPE:
M_PopMenu();

View file

@ -669,6 +669,16 @@ S_StartSound(vec3_t origin, int entnum, int entchannel, sfx_t *sfx,
ps->fixed_origin = false;
}
if (sfx->name)
{
// with !fixed we have all sounds related directly to player,
// e.g. players fire, pain, menu
if (!ps->fixed_origin)
{
Haptic_Feedback(sfx->name);
}
}
ps->entnum = entnum;
ps->entchannel = entchannel;
ps->attenuation = attenuation;