Skip to content

Commit

Permalink
NX/VITA: Add support for nzp_rumble builtin
Browse files Browse the repository at this point in the history
  • Loading branch information
MotoLegacy committed Jul 1, 2024
1 parent 242147e commit f4f4aad
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 29 deletions.
13 changes: 13 additions & 0 deletions source/cl_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ SceMotionState motionstate;
#endif
#ifdef __SWITCH__
PadState gyropad;
HidVibrationValue VibrationValue;
HidVibrationValue VibrationValue_stop;
HidVibrationValue VibrationValues[2];
HidVibrationDeviceHandle VibrationDeviceHandles[2][2];
HidSixAxisSensorHandle handles[4];
#endif

Expand Down Expand Up @@ -794,6 +798,15 @@ void CL_InitInput (void)
hidStartSixAxisSensor(handles[1]);
hidStartSixAxisSensor(handles[2]);
hidStartSixAxisSensor(handles[3]);

hidInitializeVibrationDevices(VibrationDeviceHandles[0], 2, HidNpadIdType_Handheld, HidNpadStyleTag_NpadHandheld);
memset(VibrationValues, 0, sizeof(VibrationValues));
memset(&VibrationValue_stop, 0, sizeof(HidVibrationValue));

// Switch like stop behavior with muted band channels and frequencies set to default.
VibrationValue_stop.freq_low = 160.0f;
VibrationValue_stop.freq_high = 320.0f;

#endif // VITA
}

4 changes: 4 additions & 0 deletions source/cl_parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -1617,6 +1617,10 @@ void CL_ParseServerMessage (void)
MSG_ReadByte();
break;

case svc_rumble:
IN_StartRumble((int)MSG_ReadShort(), (int)MSG_ReadShort(), (int)MSG_ReadShort());
break;

case svc_screenflash:
screenflash_color = MSG_ReadByte();
screenflash_duration = sv.time + MSG_ReadByte();
Expand Down
55 changes: 49 additions & 6 deletions source/in_sdl.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

int rumble_tick = 0;
int rumble_duration;

void IN_StartRumble (float intensity_small, float intensity_large, float duration)
void IN_StartRumble(int low_frequency, int high_frequency, int duration)
{
SceCtrlActuator handle;
handle.small = (int)(intensity_small * 100.0f);
handle.large = (int)(intensity_large * 100.0f);
handle.small = high_frequency / 256;
handle.large = low_frequency / 256;
sceCtrlSetActuator(1, &handle);
rumble_tick = sceKernelGetProcessTimeWide();
rumble_duration = (int)(duration * 1000000.0f);
rumble_duration = (int)(duration * 1000.0f);
}

void IN_StopRumble (void)
Expand All @@ -58,7 +57,51 @@ void IN_StopRumble (void)
rumble_tick = 0;
}
}
#endif
#else

#include <switch.h>
#include <switch/runtime/pad.h>

float rumble_tick = 0;
float rumble_duration;
u32 target_device;

extern PadState gyropad;
extern HidVibrationValue VibrationValue;
extern HidVibrationValue VibrationValue_stop;
extern HidVibrationValue VibrationValues[2];
extern HidVibrationDeviceHandle VibrationDeviceHandles[2][2];
void IN_StartRumble(int low_frequency, int high_frequency, int duration)
{
target_device = padIsHandheld(&gyropad) ? 0 : 1;

VibrationValue.amp_low = VibrationValue.amp_high = low_frequency == 0 ? 0.0f : 320.0f;
VibrationValue.freq_low = low_frequency == 0 ? 160.0f : (float) low_frequency / 204;
VibrationValue.freq_high = high_frequency == 0 ? 320.0f : (float) high_frequency / 204;

memcpy(&VibrationValues[0], &VibrationValue, sizeof(HidVibrationValue));
memcpy(&VibrationValues[1], &VibrationValue, sizeof(HidVibrationValue));

hidSendVibrationValues(VibrationDeviceHandles[target_device], VibrationValues, 2);

rumble_tick = cl.time;
rumble_duration = ((float)duration)/1000;
}

void IN_StopRumble (void)
{
if (rumble_tick && (cl.time - rumble_tick > rumble_duration)) {
memcpy(&VibrationValues[0], &VibrationValue_stop, sizeof(HidVibrationValue));
memcpy(&VibrationValues[1], &VibrationValue_stop, sizeof(HidVibrationValue));

hidSendVibrationValues(VibrationDeviceHandles[target_device], VibrationValues, 2);
//Could also do this with 1 hidSendVibrationValues() call + a larger VibrationValues array.
hidSendVibrationValues(VibrationDeviceHandles[1-target_device], VibrationValues, 2);
rumble_tick = 0;
}
}

#endif // VITA

static qboolean textmode;

Expand Down
4 changes: 2 additions & 2 deletions source/input.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ void IN_Activate ();
// called when the app becomes inactive
void IN_Deactivate (qboolean free_cursor);

#ifdef VITA
qboolean IN_SwitchKeyboard(char *out, int out_len);
void IN_StartRumble (float intensity_small, float intensity_large, float duration);
#ifdef VITA
void IN_StartRumble(int low_frequency, int high_frequency, int duration);
void IN_StopRumble (void);
#endif

Expand Down
2 changes: 0 additions & 2 deletions source/main_sdl.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,9 +195,7 @@ int main(int argc, char *argv[])
while (1)
{
/* If we have no input focus at all, sleep a bit */
#ifdef VITA
IN_StopRumble();
#else
if (!VID_HasMouseOrInputFocus() || cl.paused)
{
SDL_Delay(16);
Expand Down
54 changes: 35 additions & 19 deletions source/pr_cmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -1395,6 +1395,39 @@ void PF_LockViewmodel(void)
MSG_WriteByte (&client->message, state);
}

/*
=================
PF_Rumble
Server tells client to rumble their
GamePad.
nzp_rumble()
=================
*/
void PF_Rumble(void)
{
client_t *client;
int entnum;
int low_frequency;
int high_frequency;
int duration;

entnum = G_EDICTNUM(OFS_PARM0);
low_frequency = G_FLOAT(OFS_PARM1);
high_frequency = G_FLOAT(OFS_PARM2);
duration = G_FLOAT(OFS_PARM3);

if (entnum < 1 || entnum > svs.maxclients)
return;

client = &svs.clients[entnum-1];
MSG_WriteByte (&client->message, svc_rumble);
MSG_WriteShort (&client->message, low_frequency);
MSG_WriteShort (&client->message, high_frequency);
MSG_WriteShort (&client->message, duration);
}

/*
=================
PF_BettyPrompt
Expand Down Expand Up @@ -3504,24 +3537,6 @@ void PF_ArgV (void)
G_INT(OFS_RETURN) = PR_SetEngineString(s);
}

/*
=================
PF_rumble
void rumble (float,float)
=================
*/
void PF_rumble (void)
{
// writes to file, like bprint
float intensity_small = G_FLOAT(OFS_PARM0);
float intensity_large = G_FLOAT(OFS_PARM1);
float duration = G_FLOAT(OFS_PARM2);
#ifdef VITA
IN_StartRumble(intensity_small, intensity_large, duration);
#endif // VITA
}

static builtin_t pr_builtin[] =
{
PF_Fixme,
Expand Down Expand Up @@ -3656,7 +3671,7 @@ static builtin_t pr_builtin[] =
NULL, // #129
NULL, // #130
NULL, // #131
PF_rumble, // #132
NULL, // #132
NULL, // #133
NULL, // #134
NULL, // #135
Expand Down Expand Up @@ -4033,6 +4048,7 @@ static builtin_t pr_builtin[] =
PF_SetDoubleTapVersion, // #506
PF_ScreenFlash, // #507
PF_LockViewmodel, // #508
PF_Rumble, // #509
};

builtin_t *pr_builtins = pr_builtin;
Expand Down
2 changes: 2 additions & 0 deletions source/protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

#define svc_screenflash 54 // [byte] color [byte] duration [byte] type
#define svc_lockviewmodel 55
#define svc_rumble 56 // [short] low frequency [short] high frequency [short] duration (ms)


//
// client to server
Expand Down

0 comments on commit f4f4aad

Please sign in to comment.