mirror of
https://github.com/DrBeef/JKXR.git
synced 2024-11-21 19:51:33 +00:00
HAPTICS!!!
Controller only so far - still needs some things implemented, but mostly there
This commit is contained in:
parent
85f642e9e7
commit
077cfe159e
14 changed files with 163 additions and 45 deletions
|
@ -848,16 +848,23 @@ JKVR_Vibrate
|
|||
float vibration_channel_duration[2] = {0.0f, 0.0f};
|
||||
float vibration_channel_intensity[2] = {0.0f, 0.0f};
|
||||
|
||||
void JKVR_Vibrate( int duration, int channel, float intensity )
|
||||
void JKVR_Vibrate( int duration, int chan, float intensity )
|
||||
{
|
||||
if (vibration_channel_duration[channel] > 0.0f)
|
||||
return;
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
int channel = (i + 1) & chan;
|
||||
if (channel)
|
||||
{
|
||||
if (vibration_channel_duration[channel-1] > 0.0f)
|
||||
return;
|
||||
|
||||
if (vibration_channel_duration[channel] == -1.0f && duration != 0.0f)
|
||||
return;
|
||||
if (vibration_channel_duration[channel-1] == -1.0f && duration != 0.0f)
|
||||
return;
|
||||
|
||||
vibration_channel_duration[channel] = duration;
|
||||
vibration_channel_intensity[channel] = intensity;
|
||||
vibration_channel_duration[channel-1] = duration;
|
||||
vibration_channel_intensity[channel-1] = intensity * vr_haptic_intensity->value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JKVR_GetMove(float *forward, float *side, float *pos_forward, float *pos_side, float *up,
|
||||
|
@ -1337,6 +1344,7 @@ void JKVR_Init()
|
|||
vr_irl_crouch_enabled = Cvar_Get ("vr_irl_crouch_enabled", "0", CVAR_ARCHIVE);
|
||||
vr_irl_crouch_to_stand_ratio = Cvar_Get ("vr_irl_crouch_to_stand_ratio", "0.65", CVAR_ARCHIVE);
|
||||
vr_saber_block_debounce_time = Cvar_Get ("vr_saber_block_debounce_time", "200", CVAR_ARCHIVE);
|
||||
vr_haptic_intensity = Cvar_Get ("vr_haptic_intensity", "1.0", CVAR_ARCHIVE);
|
||||
|
||||
cvar_t *expanded_menu_enabled = Cvar_Get ("expanded_menu_enabled", "0", CVAR_ARCHIVE);
|
||||
if (FS_FileExists("expanded_menu.pk3")) {
|
||||
|
@ -1636,7 +1644,7 @@ void JKVR_processHaptics() {
|
|||
for (int i = 0; i < 2; ++i) {
|
||||
if (vibration_channel_duration[i] > 0.0f ||
|
||||
vibration_channel_duration[i] == -1.0f) {
|
||||
vrapi_SetHapticVibrationSimple(gAppState.Ovr, controllerIDs[i],
|
||||
vrapi_SetHapticVibrationSimple(gAppState.Ovr, controllerIDs[1 - i],
|
||||
vibration_channel_intensity[i]);
|
||||
|
||||
if (vibration_channel_duration[i] != -1.0f) {
|
||||
|
@ -1648,11 +1656,73 @@ void JKVR_processHaptics() {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
vrapi_SetHapticVibrationSimple(gAppState.Ovr, controllerIDs[i], 0.0f);
|
||||
vrapi_SetHapticVibrationSimple(gAppState.Ovr, controllerIDs[1 - i], 0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JKVR_HapticEvent(const char* event, int position, int flags, int intensity, float angle, float yHeight )
|
||||
{
|
||||
if (vr_haptic_intensity->value == 0.0f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// engine_t* engine = VR_GetEngine();
|
||||
// jstring StringArg1 = (*(engine->java.Env))->NewStringUTF(engine->java.Env, event);
|
||||
// (*(engine->java.Env))->CallVoidMethod(engine->java.Env, engine->java.ActivityObject, android_haptic_event, StringArg1, position, flags, (int)(intensity * vr_hapticIntensity->value), angle, yHeight);
|
||||
|
||||
//Controller Haptic Support
|
||||
int weaponFireChannel = vr.weapon_stabilised ? 3 : (vr_control_scheme->integer ? 2 : 1);
|
||||
if (flags != 0)
|
||||
{
|
||||
weaponFireChannel = flags;
|
||||
}
|
||||
if (strcmp(event, "pickup_shield") == 0 ||
|
||||
strcmp(event, "pickup_weapon") == 0 ||
|
||||
strstr(event, "pickup_item") != NULL)
|
||||
{
|
||||
JKVR_Vibrate(100, 3, 1.0);
|
||||
}
|
||||
else if (strcmp(event, "weapon_switch") == 0)
|
||||
{
|
||||
JKVR_Vibrate(250, vr_control_scheme->integer ? 2 : 1, 0.8);
|
||||
}
|
||||
else if (strcmp(event, "shotgun") == 0 || strcmp(event, "fireball") == 0)
|
||||
{
|
||||
JKVR_Vibrate(400, 3, 1.0);
|
||||
}
|
||||
else if (strcmp(event, "bullet") == 0)
|
||||
{
|
||||
JKVR_Vibrate(150, 3, 1.0);
|
||||
}
|
||||
else if (strcmp(event, "chainsaw_fire") == 0 ||
|
||||
strcmp(event, "RTCWQuest:fire_tesla") == 0)
|
||||
{
|
||||
JKVR_Vibrate(500, weaponFireChannel, 1.0);
|
||||
}
|
||||
else if (strcmp(event, "machinegun_fire") == 0 || strcmp(event, "plasmagun_fire") == 0)
|
||||
{
|
||||
JKVR_Vibrate(90, weaponFireChannel, 0.8);
|
||||
}
|
||||
else if (strcmp(event, "shotgun_fire") == 0)
|
||||
{
|
||||
JKVR_Vibrate(250, weaponFireChannel, 1.0);
|
||||
}
|
||||
else if (strcmp(event, "rocket_fire") == 0 ||
|
||||
strcmp(event, "RTCWQuest:fire_sniper") == 0 ||
|
||||
strcmp(event, "bfg_fire") == 0 ||
|
||||
strcmp(event, "handgrenade_fire") == 0 )
|
||||
{
|
||||
JKVR_Vibrate(400, weaponFireChannel, 1.0);
|
||||
}
|
||||
else if (strcmp(event, "selector_icon") == 0)
|
||||
{
|
||||
//Quick blip
|
||||
JKVR_Vibrate(50, flags, 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
void showLoadingIcon()
|
||||
{
|
||||
int frameFlags = 0;
|
||||
|
|
|
@ -17,4 +17,5 @@ extern cvar_t *vr_crouch_toggle;
|
|||
extern cvar_t *vr_irl_crouch_enabled;
|
||||
extern cvar_t *vr_irl_crouch_to_stand_ratio;
|
||||
extern cvar_t *vr_saber_block_debounce_time;
|
||||
extern cvar_t *vr_haptic_intensity;
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ cvar_t *vr_crouch_toggle;
|
|||
cvar_t *vr_irl_crouch_enabled;
|
||||
cvar_t *vr_irl_crouch_to_stand_ratio;
|
||||
cvar_t *vr_saber_block_debounce_time;
|
||||
cvar_t *vr_haptic_intensity;
|
||||
|
||||
ovrInputStateTrackedRemote leftTrackedRemoteState_old;
|
||||
ovrInputStateTrackedRemote leftTrackedRemoteState_new;
|
||||
|
|
|
@ -221,7 +221,8 @@ Ghoul2 Insert End
|
|||
|
||||
CG_OPENJK_MENU_PAINT,
|
||||
CG_OPENJK_GETMENU_BYNAME,
|
||||
CG_CVAR_GET
|
||||
CG_CVAR_GET,
|
||||
CG_HAPTICEVENT
|
||||
} cgameImport_t;
|
||||
|
||||
#ifdef JK2_MODE
|
||||
|
@ -348,6 +349,7 @@ Ghoul2 Insert End
|
|||
CG_OPENJK_MENU_PAINT_JK2,
|
||||
CG_OPENJK_GETMENU_BYNAME_JK2,
|
||||
CG_CVAR_GET_JK2,
|
||||
CG_HAPTICEVENT_JK2
|
||||
} cgameJK2Import_t;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -467,6 +467,9 @@ cgameImport_t CL_ConvertJK2SysCall( cgameJK2Import_t import )
|
|||
case CG_CVAR_GET_JK2:
|
||||
return CG_CVAR_GET;
|
||||
break;
|
||||
case CG_HAPTICEVENT_JK2:
|
||||
return CG_HAPTICEVENT;
|
||||
break;
|
||||
case CG_ARGC_JK2:
|
||||
return CG_ARGC;
|
||||
break;
|
||||
|
@ -1378,6 +1381,9 @@ Ghoul2 Insert End
|
|||
return strlen(text);
|
||||
#endif
|
||||
|
||||
case CG_HAPTICEVENT:
|
||||
JKVR_HapticEvent( (const char*)VMA(1), args[2], args[3], args[4], VMF(5), VMF(6) );
|
||||
return 0;
|
||||
default:
|
||||
Com_Error( ERR_DROP, "Bad cgame system trap: %ld", (long int) args[0] );
|
||||
}
|
||||
|
|
|
@ -841,6 +841,8 @@ void CL_Frame ( int msec,float fractionMsec ) {
|
|||
|
||||
JKVR_processHaptics();
|
||||
|
||||
//trigger frame tick for haptics
|
||||
JKVR_HapticEvent("frame_tick", 0, 0, 0, 0, 0);
|
||||
|
||||
// see if we need to update any userinfo
|
||||
CL_CheckUserinfo();
|
||||
|
|
|
@ -41,6 +41,10 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
#include "qcommon/stringed_ingame.h"
|
||||
|
||||
#include <JKVR/VrClientInfo.h>
|
||||
|
||||
extern vr_client_info_t vr;
|
||||
|
||||
void UI_LoadMenus(const char *menuFile, qboolean reset);
|
||||
|
||||
extern vmCvar_t ui_char_color_red;
|
||||
|
@ -9159,7 +9163,7 @@ void Item_MouseEnter(itemDef_t *item, float x, float y)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void JKVR_HapticEvent(const char* event, int position, int flags, int intensity, float angle, float yHeight );
|
||||
|
||||
/*
|
||||
=================
|
||||
|
@ -9244,6 +9248,7 @@ qboolean Item_SetFocus(itemDef_t *item, float x, float y)
|
|||
if (playSound && sfx)
|
||||
{
|
||||
DC->startLocalSound( *sfx, CHAN_LOCAL_SOUND );
|
||||
JKVR_HapticEvent("selector_icon", 0, vr.right_handed ? 1 : 2, 60, 0, 0);
|
||||
}
|
||||
|
||||
for (i = 0; i < parent->itemCount; i++)
|
||||
|
|
|
@ -478,6 +478,7 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
|
|||
// show icon and name on status bar
|
||||
if ( es->number == cg.snap->ps.clientNum ) {
|
||||
CG_ItemPickup( index, bHadItem );
|
||||
cgi_HapticEvent("pickup_weapon", 0, 0, 80, 0, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -511,6 +512,8 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
|
|||
}
|
||||
}
|
||||
|
||||
cgi_HapticEvent("weapon_switch", 0, 0, 100, 0, 0);
|
||||
|
||||
// FIXME: if it happens that you don't want the saber to play the switch sounds, feel free to modify this bit.
|
||||
if ( weaponData[cg.weaponSelect].selectSnd[0] )
|
||||
{
|
||||
|
@ -564,7 +567,11 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
|
|||
cg.powerupActive = PW_BATTLESUIT;
|
||||
cg.powerupTime = cg.time;
|
||||
}
|
||||
//cgi_S_StartSound (NULL, es->number, CHAN_ITEM, cgs.media.invulnoProtectSound );
|
||||
if ( clientNum == cg.snap->ps.clientNum ) {
|
||||
cgi_HapticEvent("decontaminate", 0, 0, 100, 0, 0);
|
||||
}
|
||||
|
||||
//cgi_S_StartSound (NULL, es->number, CHAN_ITEM, cgs.media.invulnoProtectSound );
|
||||
break;
|
||||
|
||||
//=================================================================
|
||||
|
@ -766,6 +773,9 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
|
|||
return;
|
||||
}
|
||||
*/
|
||||
if ( clientNum == cg.snap->ps.clientNum ) {
|
||||
cgi_HapticEvent("fireball", 0, 0, 100, 0, 0);
|
||||
}
|
||||
CG_TryPlayCustomSound( NULL, es->number, CHAN_VOICE, va("*death%i.wav", event - EV_DEATH1 + 1), CS_BASIC );
|
||||
break;
|
||||
|
||||
|
|
|
@ -972,6 +972,9 @@ void cgi_Cvar_Set( const char *var_name, const char *value );
|
|||
char* cgi_Cvar_Get( const char *var_name );
|
||||
|
||||
|
||||
//Haptics
|
||||
int cgi_HapticEvent( char *description, int position, int channel, int intensity, float yaw, float height);
|
||||
|
||||
// ServerCommand and ConsoleCommand parameter access
|
||||
int cgi_Argc( void );
|
||||
void cgi_Argv( int n, char *buffer, int bufferLength );
|
||||
|
|
|
@ -204,6 +204,13 @@ void CG_DamageFeedback( int yawByte, int pitchByte, int damage ) {
|
|||
cg.damageValue = kick;
|
||||
cg.v_dmg_time = cg.time + DAMAGE_TIME;
|
||||
cg.damageTime = cg.snap->serverTime;
|
||||
|
||||
if (damage > 30)
|
||||
{
|
||||
cgi_HapticEvent("shotgun", 0, 0, 100, yaw, 0);
|
||||
} else {
|
||||
cgi_HapticEvent("bullet", 0, 0, 100, yaw, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -198,7 +198,8 @@ Ghoul2 Insert End
|
|||
|
||||
CG_OPENJK_MENU_PAINT,
|
||||
CG_OPENJK_GETMENU_BYNAME,
|
||||
CG_CVAR_GET
|
||||
CG_CVAR_GET,
|
||||
CG_HAPTICEVENT
|
||||
} cgameImport_t;
|
||||
|
||||
//----------------------------------------------
|
||||
|
|
|
@ -421,6 +421,10 @@ void cgi_R_WorldEffectCommand( const char *command )
|
|||
Q_syscall( CG_R_WORLD_EFFECT_COMMAND, command );
|
||||
}
|
||||
|
||||
int cgi_HapticEvent( char *description, int position, int channel, int intensity, float yaw, float height) {
|
||||
return Q_syscall( CG_HAPTICEVENT, description, position, channel, intensity, PASSFLOAT(yaw), PASSFLOAT(height));
|
||||
}
|
||||
|
||||
// this returns a handle. arg0 is the name in the format "idlogo.roq", set arg1 to NULL, alteredstates to qfalse (do not alter gamestate)
|
||||
int trap_CIN_PlayCinematic( const char *arg0, int xpos, int ypos, int width, int height, int bits, const char *psAudioFile /* = NULL */) {
|
||||
return Q_syscall(CG_CIN_PLAYCINEMATIC, arg0, xpos, ypos, width, height, bits, psAudioFile);
|
||||
|
|
|
@ -3040,7 +3040,9 @@ void CG_DrawItemSelector( void )
|
|||
selectable) {
|
||||
if (cg.itemSelectorSelection != itemId) {
|
||||
cg.itemSelectorSelection = itemId;
|
||||
//trap_HapticEvent("selector_icon", 0, 0, 100, 0, 0);
|
||||
|
||||
cgi_HapticEvent("selector_icon", 0, vr->right_handed ?
|
||||
((cg.itemSelectorType == 3) ? 2 : 1) : ((cg.itemSelectorType == 3) ? 1 : 2), 100, 0, 0);
|
||||
}
|
||||
|
||||
selected = qtrue;
|
||||
|
@ -3231,51 +3233,46 @@ void CG_FireWeapon( centity_t *cent, qboolean alt_fire )
|
|||
}
|
||||
}
|
||||
|
||||
// Do overcharge sound that get's added to the top
|
||||
/* if (( ent->powerups & ( 1<<PW_WEAPON_OVERCHARGE )))
|
||||
//Are we the player?
|
||||
if (cent->gent->client->ps.clientNum == 0)
|
||||
{
|
||||
if ( alt_fire )
|
||||
{
|
||||
switch( ent->weapon )
|
||||
{
|
||||
case WP_THERMAL:
|
||||
case WP_DET_PACK:
|
||||
case WP_TRIP_MINE:
|
||||
case WP_ROCKET_LAUNCHER:
|
||||
case WP_FLECHETTE:
|
||||
// these weapon fires don't overcharge
|
||||
break;
|
||||
int position = vr->weapon_stabilised ? 4 : (vr->right_handed ? 1 : 2);
|
||||
|
||||
//Haptics
|
||||
switch (ent->weapon) {
|
||||
case WP_SABER:
|
||||
cgi_HapticEvent("chainsaw_fire", position, 0, 50, 0, 0);
|
||||
break;
|
||||
case WP_BRYAR_PISTOL:
|
||||
case WP_BOWCASTER:
|
||||
case WP_BLASTER:
|
||||
cgi_S_StartSound( NULL, ent->number, CHAN_AUTO, cgs.media.overchargeFastSound );
|
||||
cgi_HapticEvent("machinegun_fire", position, 0, 100, 0, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
cgi_S_StartSound( NULL, ent->number, CHAN_AUTO, cgs.media.overchargeSlowSound );
|
||||
case WP_BLASTER_PISTOL:
|
||||
cgi_HapticEvent("shotgun_fire", position, 0, 100, 0, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch( ent->weapon )
|
||||
{
|
||||
case WP_THERMAL:
|
||||
case WP_DET_PACK:
|
||||
case WP_TRIP_MINE:
|
||||
cgi_HapticEvent("handgrenade_fire", position, 0, 80, 0, 0);
|
||||
break;
|
||||
case WP_ROCKET_LAUNCHER:
|
||||
// these weapon fires don't overcharge
|
||||
cgi_HapticEvent("rocket_fire", position, 0, 100, 0, 0);
|
||||
break;
|
||||
|
||||
case WP_DISRUPTOR:
|
||||
cgi_HapticEvent("RTCWQuest:fire_sniper", position, 0, 100, 0, 0);
|
||||
break;
|
||||
case WP_FLECHETTE:
|
||||
case WP_REPEATER:
|
||||
cgi_S_StartSound( NULL, ent->number, CHAN_AUTO, cgs.media.overchargeFastSound );
|
||||
cgi_HapticEvent("plasmagun_fire", position, 0, 100, 0, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
cgi_S_StartSound( NULL, ent->number, CHAN_AUTO, cgs.media.overchargeSlowSound );
|
||||
case WP_DEMP2:
|
||||
case WP_EMPLACED_GUN:
|
||||
cgi_HapticEvent("bfg_fire", position, 0, 100, 0, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -5716,6 +5716,11 @@ void ForceThrowEx( gentity_t *self, qboolean pull, qboolean aimByViewAngles )
|
|||
parts = SETANIM_BOTH;
|
||||
}
|
||||
}
|
||||
|
||||
//Handle this here so it is refreshed on every frame, not just when the lightning gun is first fired
|
||||
cgi_HapticEvent("RTCWQuest:fire_tesla", 0, (vr->right_handed ? 2 : 1), 100, 0, 0);
|
||||
|
||||
|
||||
NPC_SetAnim( self, parts, anim, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD|SETANIM_FLAG_RESTART );
|
||||
self->client->ps.saberMove = self->client->ps.saberBounceMove = LS_READY;//don't finish whatever saber anim you may have been in
|
||||
self->client->ps.saberBlocked = BLOCKED_NONE;
|
||||
|
@ -7326,6 +7331,10 @@ void ForceShootLightning( gentity_t *self )
|
|||
|
||||
VectorNormalize( forward );
|
||||
|
||||
//Handle this here so it is refreshed on every frame, not just when the lightning gun is first fired
|
||||
cgi_HapticEvent("RTCWQuest:fire_tesla", 0, (vr->right_handed ? 2 : 1), 100, 0, 0);
|
||||
|
||||
|
||||
//FIXME: if lightning hits water, do water-only-flagged radius damage from that point
|
||||
if ( self->client->ps.forcePowerLevel[FP_LIGHTNING] > FORCE_LEVEL_2 )
|
||||
{//arc
|
||||
|
|
Loading…
Reference in a new issue