Merge pull request #275 from 0lvin/3dhaptic

Use  SDL_HAPTIC_CARTESIAN as effect direction.
This commit is contained in:
Yamagi 2018-02-15 07:35:58 +01:00 committed by GitHub
commit c68aade396
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 99 additions and 166 deletions

View file

@ -105,8 +105,12 @@ enum QHARPICTYPES {
};
struct hapric_effects_cache {
int effect_type;
int effect_id;
int effect_type;
int effect_volume;
int effect_id;
int effect_x;
int effect_y;
int effect_z;
};
static int last_haptic_volume = 0;
@ -871,7 +875,7 @@ static void IN_Haptic_Shutdown(void);
* Init haptic effects
*/
static int
IN_Haptic_Effect_Init(int dir, int period, int magnitude, int length, int attack, int fade)
IN_Haptic_Effect_Init(int effect_x, int effect_y, int effect_z, int period, int magnitude, int length, int attack, int fade)
{
/*
* Direction:
@ -884,8 +888,10 @@ IN_Haptic_Effect_Init(int dir, int period, int magnitude, int length, int attack
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.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 = length;
@ -902,12 +908,12 @@ IN_Haptic_Effect_Init(int dir, int period, int magnitude, int length, int attack
}
static int
IN_Haptic_Effects_To_Id(int haptic_effect)
IN_Haptic_Effects_To_Id(int haptic_effect, int effect_volume, int effect_x, int effect_y, int effect_z)
{
if ((SDL_HapticQuery(joystick_haptic) & SDL_HAPTIC_SINE)==0)
return -1;
int hapric_volume = joy_haptic_magnitude->value * 255; // * 128 = 32767 max strength;
int hapric_volume = joy_haptic_magnitude->value * effect_volume * 16; // * 128 = 32767 max strength;
if (hapric_volume > 255)
hapric_volume = 255;
else if (hapric_volume < 0)
@ -919,93 +925,93 @@ IN_Haptic_Effects_To_Id(int haptic_effect)
case HAPTIC_EFFECT_STEP:
/* North */
return IN_Haptic_Effect_Init(
0/* Force comes from N*/, 500/* 500 ms*/, hapric_volume * 48,
effect_x, effect_y, effect_z, 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,
effect_x, effect_y, effect_z, 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,
effect_x, effect_y, effect_z, 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,
effect_x, effect_y, effect_z, 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,
effect_x, effect_y, effect_z, 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,
effect_x, effect_y, effect_z, 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,
effect_x, effect_y, effect_z, 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,
effect_x, effect_y, effect_z, 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,
effect_x, effect_y, effect_z, 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,
effect_x, effect_y, effect_z, 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,
effect_x, effect_y, effect_z, 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,
effect_x, effect_y, effect_z, 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,
effect_x, effect_y, effect_z, 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,
effect_x, effect_y, effect_z, 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,
effect_x, effect_y, effect_z, 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,
effect_x, effect_y, effect_z, 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:
@ -1033,6 +1039,10 @@ IN_Haptic_Effects_Init(void)
{
last_haptic_efffect[i].effect_type = HAPTIC_EFFECT_UNKNOWN;
last_haptic_efffect[i].effect_id = -1;
last_haptic_efffect[i].effect_volume = 0;
last_haptic_efffect[i].effect_x = 0;
last_haptic_efffect[i].effect_y = 0;
last_haptic_efffect[i].effect_z = 0;
}
}
@ -1055,13 +1065,23 @@ IN_Haptic_Effects_Shutdown(void)
for (int i=0; i<HAPTIC_EFFECT_LAST; i++)
{
last_haptic_efffect[i].effect_type = HAPTIC_EFFECT_UNKNOWN;
last_haptic_efffect[i].effect_volume = 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);
}
}
#endif
/*
* Haptic Feedback:
* effect_volume=0..16
* effect{x,y,z} - effect direction
* name - sound file name
*/
void
Haptic_Feedback(char *name)
Haptic_Feedback(char *name, int effect_volume, int effect_x, int effect_y, int effect_z)
{
#if SDL_VERSION_ATLEAST(2, 0, 0)
int effect_type = HAPTIC_EFFECT_UNKNOWN;
@ -1069,6 +1089,9 @@ Haptic_Feedback(char *name)
if (joy_haptic_magnitude->value <= 0)
return;
if (effect_volume <= 0)
return;
if (!joystick_haptic)
return;
@ -1107,11 +1130,14 @@ Haptic_Feedback(char *name)
{
effect_type = HAPTIC_EFFECT_RAILGUN;
}
else if (strstr(name, "weapons/rocklf1a"))
else if (strstr(name, "weapons/rocklf1a") ||
strstr(name, "weapons/rocklx1a"))
{
effect_type = HAPTIC_EFFECT_ROCKETGUN;
}
else if (strstr(name, "weapons/grenlf1a") || strstr(name, "weapons/hgrent1a"))
else if (strstr(name, "weapons/grenlf1a") ||
strstr(name, "weapons/grenlx1a") ||
strstr(name, "weapons/hgrent1a"))
{
effect_type = HAPTIC_EFFECT_GRENADE;
}
@ -1159,13 +1185,22 @@ Haptic_Feedback(char *name)
if (effect_type != HAPTIC_EFFECT_UNKNOWN)
{
// check last effect for reuse
if (last_haptic_efffect[last_haptic_efffect_pos].effect_type != effect_type)
if (last_haptic_efffect[last_haptic_efffect_pos].effect_type != effect_type ||
last_haptic_efffect[last_haptic_efffect_pos].effect_volume != effect_volume ||
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)
{
// 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_type = effect_type;
last_haptic_efffect[last_haptic_efffect_pos].effect_id = IN_Haptic_Effects_To_Id(effect_type);
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_Effects_To_Id(
effect_type, effect_volume, effect_x, effect_y, effect_z);
}
SDL_HapticRunEffect(joystick_haptic, last_haptic_efffect[last_haptic_efffect_pos].effect_id, 1);
}

View file

@ -188,103 +188,6 @@ enum QKEYS {
K_AUX31,
K_AUX32,
K_WORLD_0,
K_WORLD_1,
K_WORLD_2,
K_WORLD_3,
K_WORLD_4,
K_WORLD_5,
K_WORLD_6,
K_WORLD_7,
K_WORLD_8,
K_WORLD_9,
K_WORLD_10,
K_WORLD_11,
K_WORLD_12,
K_WORLD_13,
K_WORLD_14,
K_WORLD_15,
K_WORLD_16,
K_WORLD_17,
K_WORLD_18,
K_WORLD_19,
K_WORLD_20,
K_WORLD_21,
K_WORLD_22,
K_WORLD_23,
K_WORLD_24,
K_WORLD_25,
K_WORLD_26,
K_WORLD_27,
K_WORLD_28,
K_WORLD_29,
K_WORLD_30,
K_WORLD_31,
K_WORLD_32,
K_WORLD_33,
K_WORLD_34,
K_WORLD_35,
K_WORLD_36,
K_WORLD_37,
K_WORLD_38,
K_WORLD_39,
K_WORLD_40,
K_WORLD_41,
K_WORLD_42,
K_WORLD_43,
K_WORLD_44,
K_WORLD_45,
K_WORLD_46,
K_WORLD_47,
K_WORLD_48,
K_WORLD_49,
K_WORLD_50,
K_WORLD_51,
K_WORLD_52,
K_WORLD_53,
K_WORLD_54,
K_WORLD_55,
K_WORLD_56,
K_WORLD_57,
K_WORLD_58,
K_WORLD_59,
K_WORLD_60,
K_WORLD_61,
K_WORLD_62,
K_WORLD_63,
K_WORLD_64,
K_WORLD_65,
K_WORLD_66,
K_WORLD_67,
K_WORLD_68,
K_WORLD_69,
K_WORLD_70,
K_WORLD_71,
K_WORLD_72,
K_WORLD_73,
K_WORLD_74,
K_WORLD_75,
K_WORLD_76,
K_WORLD_77,
K_WORLD_78,
K_WORLD_79,
K_WORLD_80,
K_WORLD_81,
K_WORLD_82,
K_WORLD_83,
K_WORLD_84,
K_WORLD_85,
K_WORLD_86,
K_WORLD_87,
K_WORLD_88,
K_WORLD_89,
K_WORLD_90,
K_WORLD_91,
K_WORLD_92,
K_WORLD_93,
K_WORLD_94,
K_WORLD_95,
K_SUPER,
K_COMPOSE,
K_MODE,
@ -292,9 +195,7 @@ enum QKEYS {
K_PRINT,
K_SYSREQ,
K_SCROLLOCK,
K_BREAK,
K_MENU,
K_EURO,
K_UNDO,
K_LAST
@ -316,7 +217,7 @@ void Key_ReadConsoleHistory();
void Key_WriteConsoleHistory();
void Key_SetBinding(int keynum, char *binding);
void Key_MarkAllUp(void);
void Haptic_Feedback(char *name);
void Haptic_Feedback(char *name, int effect_volume, int effect_x, int effect_y, int effect_z);
int Key_GetMenuKey(int key);
#endif

View file

@ -38,6 +38,10 @@ Draw_InitLocal(void)
{
/* load console characters */
draw_chars = R_FindImage("pics/conchars.pcx", it_pic);
if (!draw_chars)
{
ri.Sys_Error(ERR_FATAL, "Couldn't load pics/conchars.pcx");
}
}
/*

View file

@ -38,6 +38,10 @@ GL3_Draw_InitLocal(void)
{
/* load console characters */
draw_chars = GL3_FindImage("pics/conchars.pcx", it_pic);
if (!draw_chars)
{
ri.Sys_Error(ERR_FATAL, "Couldn't load pics/conchars.pcx");
}
// set up attribute layout for 2D textured rendering
glGenVertexArrays(1, &vao2D);

View file

@ -59,6 +59,10 @@ Draw_InitLocal
void Draw_InitLocal (void)
{
draw_chars = RE_Draw_FindPic ("conchars");
if (!draw_chars)
{
ri.Sys_Error(ERR_FATAL, "Couldn't load pics/conchars.pcx");
}
}

View file

@ -309,7 +309,6 @@ R_UnRegister (void)
ri.Cmd_RemoveCommand( "imagelist" );
}
static int SWimp_Init(void);
static void SWimp_Shutdown(void );
/*
@ -339,7 +338,7 @@ RE_Init(void)
R_Register ();
Draw_GetPalette ();
if (SWimp_Init() == false)
if (!ri.GLimp_Init())
return false;
// create the window
@ -1470,41 +1469,6 @@ static SDL_Surface* window = NULL;
#endif
static qboolean X11_active = false;
/*
** SWimp_Init
**
** This routine is responsible for initializing the implementation
** specific stuff in a software rendering subsystem.
*/
static int
SWimp_Init(void)
{
if (!SDL_WasInit(SDL_INIT_VIDEO))
{
if (SDL_Init(SDL_INIT_VIDEO) == -1)
{
Com_Printf("Couldn't init SDL video: %s.\n", SDL_GetError());
return false;
}
SDL_version version;
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_GetVersion(&version);
const char* driverName = SDL_GetCurrentVideoDriver();
#else
char driverName[64];
SDL_VideoDriverName(driverName, sizeof(driverName));
version = *SDL_Linked_Version();
#endif
Com_Printf("SDL version is: %i.%i.%i\n", (int)version.major, (int)version.minor, (int)version.patch);
Com_Printf("SDL video driver is \"%s\".\n", driverName);
}
return true;
}
/*
* Sets the window icon
*/

View file

@ -672,12 +672,33 @@ 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;
VectorSubtract(listener_forward, listener_up, orientation);
// with !fixed we have all sounds related directly to player,
// e.g. players fire, pain, menu
if (!ps->fixed_origin)
{
Haptic_Feedback(sfx->name);
VectorCopy(orientation, direction);
distance_direction = 0;
}
else
{
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];
Haptic_Feedback(sfx->name, 16 - distance_direction / 32, dir_x, dir_y, dir_z);
}
ps->entnum = entnum;