From f4f4aad8899c2c3c9fad64e5e27d61a043add0fa Mon Sep 17 00:00:00 2001 From: cypress Date: Sun, 30 Jun 2024 19:15:38 -0700 Subject: [PATCH] NX/VITA: Add support for nzp_rumble builtin --- source/cl_input.c | 13 +++++++++++ source/cl_parse.c | 4 ++++ source/in_sdl.c | 55 +++++++++++++++++++++++++++++++++++++++++------ source/input.h | 4 ++-- source/main_sdl.c | 2 -- source/pr_cmds.c | 54 ++++++++++++++++++++++++++++++---------------- source/protocol.h | 2 ++ 7 files changed, 105 insertions(+), 29 deletions(-) diff --git a/source/cl_input.c b/source/cl_input.c index 44cba63..43f61f1 100644 --- a/source/cl_input.c +++ b/source/cl_input.c @@ -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 @@ -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 } diff --git a/source/cl_parse.c b/source/cl_parse.c index 0a62bfd..2cc35f4 100644 --- a/source/cl_parse.c +++ b/source/cl_parse.c @@ -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(); diff --git a/source/in_sdl.c b/source/in_sdl.c index 5943e47..0d919cb 100644 --- a/source/in_sdl.c +++ b/source/in_sdl.c @@ -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) @@ -58,7 +57,51 @@ void IN_StopRumble (void) rumble_tick = 0; } } -#endif +#else + +#include +#include + +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; diff --git a/source/input.h b/source/input.h index 3fa260a..df76af9 100644 --- a/source/input.h +++ b/source/input.h @@ -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 diff --git a/source/main_sdl.c b/source/main_sdl.c index 9b726dd..ec9c4d4 100644 --- a/source/main_sdl.c +++ b/source/main_sdl.c @@ -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); diff --git a/source/pr_cmds.c b/source/pr_cmds.c index 7df8c18..83953be 100644 --- a/source/pr_cmds.c +++ b/source/pr_cmds.c @@ -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 @@ -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, @@ -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 @@ -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; diff --git a/source/protocol.h b/source/protocol.h index 03bde61..85b2a25 100644 --- a/source/protocol.h +++ b/source/protocol.h @@ -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