mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2024-11-10 07:12:07 +00:00
Controller Rumble / force feedback
Replaces classic "haptic" implementation, no longer available for game controllers as of SDL 2.0.14.
This commit is contained in:
parent
5c560039d8
commit
5a22720735
4 changed files with 155 additions and 313 deletions
|
@ -285,10 +285,8 @@ void Key_ReadConsoleHistory();
|
|||
void Key_WriteConsoleHistory();
|
||||
void Key_SetBinding(int keynum, char *binding);
|
||||
void Key_MarkAllUp(void);
|
||||
void Haptic_Feedback(char *name, int effect_volume, int effect_duration,
|
||||
int effect_begin, int effect_end,
|
||||
int effect_attack, int effect_fade,
|
||||
int effect_x, int effect_y, int effect_z);
|
||||
void Controller_Rumble(const char *name, vec3_t source, qboolean from_player,
|
||||
unsigned int duration, unsigned short int volume);
|
||||
int Key_GetMenuKey(int key);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -108,31 +108,10 @@ static cvar_t *windowed_mouse;
|
|||
|
||||
// ----
|
||||
|
||||
struct hapric_effects_cache {
|
||||
int effect_volume;
|
||||
int effect_duration;
|
||||
int effect_begin;
|
||||
int effect_end;
|
||||
int effect_attack;
|
||||
int effect_fade;
|
||||
int effect_id;
|
||||
int effect_x;
|
||||
int effect_y;
|
||||
int effect_z;
|
||||
};
|
||||
qboolean show_haptic = false;
|
||||
|
||||
qboolean show_haptic;
|
||||
|
||||
static SDL_Haptic *joystick_haptic = NULL;
|
||||
static SDL_GameController *controller = NULL;
|
||||
|
||||
#define HAPTIC_EFFECT_LIST_SIZE 16
|
||||
|
||||
static int last_haptic_volume = 0;
|
||||
static int last_haptic_efffect_size = HAPTIC_EFFECT_LIST_SIZE;
|
||||
static int last_haptic_efffect_pos = 0;
|
||||
static struct hapric_effects_cache last_haptic_efffect[HAPTIC_EFFECT_LIST_SIZE];
|
||||
|
||||
// Joystick sensitivity
|
||||
static cvar_t *joy_yawsensitivity;
|
||||
static cvar_t *joy_pitchsensitivity;
|
||||
|
@ -1386,232 +1365,138 @@ In_FlushQueue(void)
|
|||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
static void IN_Haptic_Shutdown(void);
|
||||
|
||||
/*
|
||||
* Init haptic effects
|
||||
*/
|
||||
static int
|
||||
IN_Haptic_Effect_Init(int effect_x, int effect_y, int effect_z,
|
||||
int period, int magnitude,
|
||||
int delay, int attack, int fade)
|
||||
{
|
||||
static SDL_HapticEffect haptic_effect;
|
||||
|
||||
/* limit magnitude */
|
||||
if (magnitude > SHRT_MAX)
|
||||
{
|
||||
magnitude = SHRT_MAX;
|
||||
}
|
||||
else if (magnitude < 0)
|
||||
{
|
||||
magnitude = 0;
|
||||
}
|
||||
|
||||
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_CARTESIAN; // Cartesian/3d coordinates
|
||||
haptic_effect.periodic.direction.dir[0] = effect_x;
|
||||
haptic_effect.periodic.direction.dir[1] = effect_y;
|
||||
haptic_effect.periodic.direction.dir[2] = effect_z;
|
||||
haptic_effect.periodic.period = period;
|
||||
haptic_effect.periodic.magnitude = magnitude;
|
||||
haptic_effect.periodic.length = period;
|
||||
haptic_effect.periodic.delay = delay;
|
||||
haptic_effect.periodic.attack_length = attack;
|
||||
haptic_effect.periodic.fade_length = fade;
|
||||
|
||||
int effect_id = SDL_HapticNewEffect(joystick_haptic, &haptic_effect);
|
||||
|
||||
if (effect_id < 0)
|
||||
{
|
||||
Com_Printf ("SDL_HapticNewEffect failed: %s\n", SDL_GetError());
|
||||
Com_Printf ("Please try to rerun game. Effects will be disabled for now.\n");
|
||||
|
||||
IN_Haptic_Shutdown();
|
||||
}
|
||||
|
||||
return effect_id;
|
||||
}
|
||||
|
||||
static void
|
||||
IN_Haptic_Effects_Info(void)
|
||||
{
|
||||
show_haptic = true;
|
||||
|
||||
Com_Printf ("Joystick/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_LIST_SIZE)
|
||||
{
|
||||
last_haptic_efffect_size = HAPTIC_EFFECT_LIST_SIZE;
|
||||
}
|
||||
|
||||
for (int i=0; i<HAPTIC_EFFECT_LIST_SIZE; i++)
|
||||
{
|
||||
last_haptic_efffect[i].effect_id = -1;
|
||||
last_haptic_efffect[i].effect_volume = 0;
|
||||
last_haptic_efffect[i].effect_duration = 0;
|
||||
last_haptic_efffect[i].effect_begin = 0;
|
||||
last_haptic_efffect[i].effect_end = 0;
|
||||
last_haptic_efffect[i].effect_attack = 0;
|
||||
last_haptic_efffect[i].effect_fade = 0;
|
||||
last_haptic_efffect[i].effect_x = 0;
|
||||
last_haptic_efffect[i].effect_y = 0;
|
||||
last_haptic_efffect[i].effect_z = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 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_Shutdown(void)
|
||||
{
|
||||
for (int i=0; i<HAPTIC_EFFECT_LIST_SIZE; i++)
|
||||
{
|
||||
last_haptic_efffect[i].effect_volume = 0;
|
||||
last_haptic_efffect[i].effect_duration = 0;
|
||||
last_haptic_efffect[i].effect_begin = 0;
|
||||
last_haptic_efffect[i].effect_end = 0;
|
||||
last_haptic_efffect[i].effect_attack = 0;
|
||||
last_haptic_efffect[i].effect_fade = 0;
|
||||
last_haptic_efffect[i].effect_x = 0;
|
||||
last_haptic_efffect[i].effect_y = 0;
|
||||
last_haptic_efffect[i].effect_z = 0;
|
||||
|
||||
IN_Haptic_Effect_Shutdown(&last_haptic_efffect[i].effect_id);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Haptic Feedback:
|
||||
* effect_volume=0..SHRT_MAX
|
||||
* effect{x,y,z} - effect direction
|
||||
* name - sound file name
|
||||
* Controller_Rumble:
|
||||
* name = sound file name
|
||||
* effect_volume = 0..USHRT_MAX
|
||||
* effect_duration is in ms
|
||||
* source = origin of audio
|
||||
* from_player = if source is the client (player)
|
||||
*/
|
||||
void
|
||||
Haptic_Feedback(char *name, int effect_volume, int effect_duration,
|
||||
int effect_begin, int effect_end,
|
||||
int effect_attack, int effect_fade,
|
||||
int effect_x, int effect_y, int effect_z)
|
||||
Controller_Rumble(const char *name, vec3_t source, qboolean from_player,
|
||||
unsigned int duration, unsigned short int volume)
|
||||
{
|
||||
if (!joystick_haptic)
|
||||
vec_t intens = 0.0f, low_freq = 1.0f, hi_freq = 1.0f, dist_prop;
|
||||
unsigned short int max_distance = 4;
|
||||
unsigned int effect_volume;
|
||||
|
||||
if (!show_haptic || !controller || joy_haptic_magnitude->value <= 0
|
||||
|| volume == 0 || duration == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (joy_haptic_magnitude->value <= 0)
|
||||
if (strstr(name, "weapons/"))
|
||||
{
|
||||
intens = 1.75f;
|
||||
|
||||
if (strstr(name, "/blastf") || strstr(name, "/hyprbf") || strstr(name, "/nail"))
|
||||
{
|
||||
intens = 0.125f; // dampen blasters and nailgun's fire
|
||||
low_freq = 0.7f;
|
||||
hi_freq = 1.2f;
|
||||
}
|
||||
else if (strstr(name, "/shotgf") || strstr(name, "/rocklf"))
|
||||
{
|
||||
low_freq = 1.1f; // shotgun & RL shouldn't feel so weak
|
||||
duration *= 0.7;
|
||||
}
|
||||
else if (strstr(name, "/sshotf"))
|
||||
{
|
||||
duration *= 0.6; // the opposite for super shotgun
|
||||
}
|
||||
else if (strstr(name, "/machgf") || strstr(name, "/disint"))
|
||||
{
|
||||
intens = 1.125f; // machine gun & disruptor fire
|
||||
}
|
||||
else if (strstr(name, "/grenlb") || strstr(name, "/hgrenb") // bouncing grenades
|
||||
|| strstr(name, "open") || strstr(name, "warn")) // rogue's items
|
||||
{
|
||||
return; // ... don't have feedback
|
||||
}
|
||||
else if (strstr(name, "/plasshot")) // phalanx cannon
|
||||
{
|
||||
intens = 1.0f;
|
||||
hi_freq = 0.3f;
|
||||
duration *= 0.5;
|
||||
}
|
||||
else if (strstr(name, "x")) // explosions...
|
||||
{
|
||||
low_freq = 1.1f;
|
||||
hi_freq = 0.9f;
|
||||
max_distance = 550; // can be felt far away
|
||||
}
|
||||
else if (strstr(name, "r")) // reloads & ion ripper fire
|
||||
{
|
||||
low_freq = 0.1f;
|
||||
hi_freq = 0.6f;
|
||||
}
|
||||
}
|
||||
else if ( (strstr(name, "player/") || strstr(name, "players/")) &&
|
||||
(strstr(name, "/death") || strstr(name, "/fall") || strstr(name, "/pain")) )
|
||||
{
|
||||
intens = 3.5f; // exaggerate player damage
|
||||
low_freq = 1.1f;
|
||||
}
|
||||
else if (strstr(name, "player/land"))
|
||||
{
|
||||
intens = 2.5f; // fall without injury
|
||||
}
|
||||
else if (strstr(name, "doors/"))
|
||||
{
|
||||
intens = 0.125f;
|
||||
low_freq = 0.4f;
|
||||
max_distance = 280;
|
||||
}
|
||||
else if (strstr(name, "plats/"))
|
||||
{
|
||||
intens = 1.0f; // platforms rumble...
|
||||
max_distance = 200; // when player near them
|
||||
}
|
||||
else if (strstr(name, "world/"))
|
||||
{
|
||||
max_distance = 3000; // ambient events
|
||||
if (strstr(name, "/dish") || strstr(name, "/drill2a") || strstr(name, "/dr_")
|
||||
|| strstr(name, "/explod1") || strstr(name, "/rocks") || strstr(name, "/rumble"))
|
||||
{
|
||||
intens = 0.25f;
|
||||
low_freq = 0.7f;
|
||||
}
|
||||
else if (strstr(name, "/quake"))
|
||||
{
|
||||
intens = 0.625f; // (earth)quakes are more evident
|
||||
low_freq = 1.2f;
|
||||
}
|
||||
}
|
||||
|
||||
if (intens == 0.0f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (effect_volume <= 0)
|
||||
if (from_player)
|
||||
{
|
||||
dist_prop = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
dist_prop = VectorLength(source);
|
||||
if (dist_prop > max_distance)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (effect_duration <= 0)
|
||||
{
|
||||
return;
|
||||
dist_prop = (max_distance - dist_prop) / max_distance;
|
||||
}
|
||||
|
||||
if (last_haptic_volume != (int)(joy_haptic_magnitude->value * 255))
|
||||
{
|
||||
IN_Haptic_Effects_Shutdown();
|
||||
IN_Haptic_Effects_Init();
|
||||
}
|
||||
effect_volume = joy_haptic_magnitude->value * intens * dist_prop * volume;
|
||||
low_freq = min(effect_volume * low_freq, USHRT_MAX);
|
||||
hi_freq = min(effect_volume * hi_freq, USHRT_MAX);
|
||||
|
||||
last_haptic_volume = joy_haptic_magnitude->value * 255;
|
||||
// Com_Printf("%s: vol %d | %d ms | prop:%.3f | l:%.0f h:%.0f\n",
|
||||
// name, effect_volume, duration, dist_prop, low_freq, hi_freq);
|
||||
|
||||
if (
|
||||
strstr(name, "misc/menu") ||
|
||||
strstr(name, "weapons/") ||
|
||||
/* detect pain for any player model */
|
||||
((
|
||||
strstr(name, "player/") ||
|
||||
strstr(name, "players/")
|
||||
) && (
|
||||
strstr(name, "/pain")
|
||||
)) ||
|
||||
strstr(name, "player/step") ||
|
||||
strstr(name, "player/land")
|
||||
)
|
||||
{
|
||||
// check last effect for reuse
|
||||
if (
|
||||
last_haptic_efffect[last_haptic_efffect_pos].effect_volume != effect_volume ||
|
||||
last_haptic_efffect[last_haptic_efffect_pos].effect_duration != effect_duration ||
|
||||
last_haptic_efffect[last_haptic_efffect_pos].effect_begin != effect_begin ||
|
||||
last_haptic_efffect[last_haptic_efffect_pos].effect_end != effect_end ||
|
||||
last_haptic_efffect[last_haptic_efffect_pos].effect_attack != effect_attack ||
|
||||
last_haptic_efffect[last_haptic_efffect_pos].effect_fade != effect_fade ||
|
||||
last_haptic_efffect[last_haptic_efffect_pos].effect_x != effect_x ||
|
||||
last_haptic_efffect[last_haptic_efffect_pos].effect_y != effect_y ||
|
||||
last_haptic_efffect[last_haptic_efffect_pos].effect_z != effect_z)
|
||||
{
|
||||
if ((SDL_HapticQuery(joystick_haptic) & SDL_HAPTIC_SINE)==0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int hapric_volume = joy_haptic_magnitude->value * effect_volume; // 32767 max strength;
|
||||
|
||||
if (effect_duration <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
Com_Printf("%s: volume %d: %d ms %d:%d:%d ms speed: %.2f\n",
|
||||
name, effect_volume, effect_duration - effect_end,
|
||||
effect_begin, effect_attack, effect_fade,
|
||||
(float)effect_volume / effect_fade);
|
||||
*/
|
||||
|
||||
// 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_volume = effect_volume;
|
||||
last_haptic_efffect[last_haptic_efffect_pos].effect_duration = effect_duration;
|
||||
last_haptic_efffect[last_haptic_efffect_pos].effect_attack = effect_attack;
|
||||
last_haptic_efffect[last_haptic_efffect_pos].effect_fade = effect_fade;
|
||||
last_haptic_efffect[last_haptic_efffect_pos].effect_x = effect_x;
|
||||
last_haptic_efffect[last_haptic_efffect_pos].effect_y = effect_y;
|
||||
last_haptic_efffect[last_haptic_efffect_pos].effect_z = effect_z;
|
||||
last_haptic_efffect[last_haptic_efffect_pos].effect_id = IN_Haptic_Effect_Init(
|
||||
effect_x, effect_y, effect_z,
|
||||
effect_duration - effect_end, hapric_volume,
|
||||
effect_begin, effect_attack, effect_fade);
|
||||
}
|
||||
|
||||
SDL_HapticRunEffect(joystick_haptic, last_haptic_efffect[last_haptic_efffect_pos].effect_id, 1);
|
||||
}
|
||||
SDL_GameControllerRumble(controller, low_freq, hi_freq, duration);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1673,7 +1558,7 @@ IN_Controller_Init(qboolean notify_user)
|
|||
Com_Printf("- Game Controller init attempt -\n");
|
||||
}
|
||||
|
||||
if (!SDL_WasInit(SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC))
|
||||
if (!SDL_WasInit(SDL_INIT_GAMECONTROLLER))
|
||||
{
|
||||
|
||||
#ifdef SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE // extended input reports on PS controllers (enables gyro thru bluetooth)
|
||||
|
@ -1683,7 +1568,7 @@ IN_Controller_Init(qboolean notify_user)
|
|||
SDL_SetHint( SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, "1" );
|
||||
#endif
|
||||
|
||||
if (SDL_Init(SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC) == -1)
|
||||
if (SDL_Init(SDL_INIT_GAMECONTROLLER) == -1)
|
||||
{
|
||||
Com_Printf ("Couldn't init SDL joystick: %s.\n", SDL_GetError ());
|
||||
return;
|
||||
|
@ -1694,17 +1579,6 @@ IN_Controller_Init(qboolean notify_user)
|
|||
|
||||
if (!SDL_NumJoysticks())
|
||||
{
|
||||
joystick_haptic = SDL_HapticOpenFromMouse();
|
||||
|
||||
if (joystick_haptic == NULL)
|
||||
{
|
||||
Com_Printf("Most likely mouse isn't haptic.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
IN_Haptic_Effects_Info();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1770,17 +1644,6 @@ IN_Controller_Init(qboolean notify_user)
|
|||
Com_Printf (" * snap-to-axis ratio = %.3f\n", joy_right_snapaxis->value);
|
||||
Com_Printf (" * inner deadzone = %.3f\n", joy_right_deadzone->value);
|
||||
|
||||
joystick_haptic = SDL_HapticOpenFromJoystick(SDL_GameControllerGetJoystick(controller));
|
||||
|
||||
if (joystick_haptic == NULL)
|
||||
{
|
||||
Com_Printf("Most likely controller isn't haptic.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
IN_Haptic_Effects_Info();
|
||||
}
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 16) // support for controller sensors
|
||||
|
||||
if ( SDL_GameControllerHasSensor(controller, SDL_SENSOR_GYRO)
|
||||
|
@ -1810,6 +1673,22 @@ IN_Controller_Init(qboolean notify_user)
|
|||
|
||||
#endif // SDL_VERSION_ATLEAST(2, 0, 16)
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 18) // support for query on features from controller
|
||||
if (SDL_GameControllerHasRumble(controller))
|
||||
{
|
||||
show_haptic = true;
|
||||
Com_Printf("Rumble support available.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
show_haptic = false;
|
||||
Com_Printf("Controller doesn't support rumble.\n");
|
||||
}
|
||||
#else
|
||||
show_haptic = true; // when in doubt, say yes
|
||||
Com_Printf("Controller might support rumble.\n");
|
||||
#endif // SDL_VERSION_ATLEAST(2, 0, 18)
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1887,21 +1766,6 @@ IN_Init(void)
|
|||
Com_Printf("------------------------------------\n\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Shuts the backend down
|
||||
*/
|
||||
static void
|
||||
IN_Haptic_Shutdown(void)
|
||||
{
|
||||
if (joystick_haptic)
|
||||
{
|
||||
IN_Haptic_Effects_Shutdown();
|
||||
|
||||
SDL_HapticClose(joystick_haptic);
|
||||
joystick_haptic = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
IN_Controller_Shutdown(qboolean notify_user)
|
||||
{
|
||||
|
@ -1910,8 +1774,6 @@ IN_Controller_Shutdown(qboolean notify_user)
|
|||
Com_Printf("- Game Controller disconnected -\n");
|
||||
}
|
||||
|
||||
IN_Haptic_Shutdown();
|
||||
|
||||
if (controller)
|
||||
{
|
||||
SDL_GameControllerClose(controller);
|
||||
|
@ -1923,6 +1785,9 @@ IN_Controller_Shutdown(qboolean notify_user)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Shuts the backend down
|
||||
*/
|
||||
void
|
||||
IN_Shutdown(void)
|
||||
{
|
||||
|
@ -1939,7 +1804,7 @@ IN_Shutdown(void)
|
|||
|
||||
IN_Controller_Shutdown(false);
|
||||
|
||||
const Uint32 subsystems = SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC;
|
||||
const Uint32 subsystems = SDL_INIT_GAMECONTROLLER;
|
||||
if (SDL_WasInit(subsystems) == subsystems)
|
||||
SDL_QuitSubSystem(subsystems);
|
||||
}
|
||||
|
|
|
@ -1942,10 +1942,10 @@ Joy_MenuInit(void)
|
|||
s_joy_haptic_slider.generic.x = 0;
|
||||
s_joy_haptic_slider.generic.y = y;
|
||||
y += 10;
|
||||
s_joy_haptic_slider.generic.name = "haptic magnitude";
|
||||
s_joy_haptic_slider.generic.name = "rumble intensity";
|
||||
s_joy_haptic_slider.cvar = "joy_haptic_magnitude";
|
||||
s_joy_haptic_slider.minvalue = 0.0f;
|
||||
s_joy_haptic_slider.maxvalue = 2.2f;
|
||||
s_joy_haptic_slider.maxvalue = 2.0f;
|
||||
Menu_AddItem(&s_joy_menu, (void *)&s_joy_haptic_slider);
|
||||
}
|
||||
|
||||
|
|
|
@ -1109,34 +1109,18 @@ S_StartSound(vec3_t origin, int entnum, int entchannel, sfx_t *sfx,
|
|||
|
||||
if (sfx->name[0])
|
||||
{
|
||||
vec3_t orientation, direction;
|
||||
vec_t distance_direction;
|
||||
int dir_x, dir_y, dir_z;
|
||||
int effect_duration = 0;
|
||||
int effect_volume = -1;
|
||||
vec3_t direction = {0};
|
||||
unsigned int effect_duration = 0;
|
||||
unsigned short int effect_volume = 0;
|
||||
|
||||
VectorSubtract(listener_forward, listener_up, orientation);
|
||||
|
||||
// with !fixed we have all sounds related directly to player,
|
||||
// with !ps->fixed we have all sounds related directly to player,
|
||||
// e.g. players fire, pain, menu
|
||||
if (!ps->fixed_origin)
|
||||
{
|
||||
VectorCopy(orientation, direction);
|
||||
distance_direction = 0;
|
||||
}
|
||||
else
|
||||
// else, they come from the environment
|
||||
if (ps->fixed_origin)
|
||||
{
|
||||
VectorSubtract(listener_origin, ps->origin, direction);
|
||||
distance_direction = VectorLength(direction);
|
||||
}
|
||||
|
||||
VectorNormalize(direction);
|
||||
VectorNormalize(orientation);
|
||||
|
||||
dir_x = 16 * orientation[0] * direction[0];
|
||||
dir_y = 16 * orientation[1] * direction[1];
|
||||
dir_z = 16 * orientation[2] * direction[2];
|
||||
|
||||
if (sfx->cache)
|
||||
{
|
||||
effect_duration = sfx->cache->length;
|
||||
|
@ -1146,16 +1130,11 @@ S_StartSound(vec3_t origin, int entnum, int entchannel, sfx_t *sfx,
|
|||
effect_duration /= 2;
|
||||
}
|
||||
|
||||
/* sound near player has 16 points */
|
||||
effect_volume = sfx->cache->volume / 16;
|
||||
effect_volume = sfx->cache->volume;
|
||||
}
|
||||
|
||||
Haptic_Feedback(
|
||||
sfx->name, (16 - distance_direction / 32) * effect_volume,
|
||||
effect_duration,
|
||||
sfx->cache->begin, sfx->cache->end,
|
||||
sfx->cache->attack, sfx->cache->fade,
|
||||
dir_x, dir_y, dir_z);
|
||||
Controller_Rumble(sfx->name, direction, !ps->fixed_origin,
|
||||
effect_duration, effect_volume);
|
||||
}
|
||||
|
||||
ps->entnum = entnum;
|
||||
|
|
Loading…
Reference in a new issue