From db0afed3fd2156f50df68a65fa4877effd864797 Mon Sep 17 00:00:00 2001 From: minenice55 Date: Sun, 1 Mar 2026 00:24:55 -0500 Subject: [PATCH] implement BT_SHAKE and code cleanup --- src/d_ticcmd.h | 5 ++- src/deh_tables.c | 1 + src/g_game.c | 105 ++++++++++++++++++-------------------------- src/g_game.h | 9 ++-- src/g_input.c | 9 ++-- src/p_mobj.c | 18 ++++++++ src/sdl/i_gamepad.c | 4 ++ 7 files changed, 78 insertions(+), 73 deletions(-) diff --git a/src/d_ticcmd.h b/src/d_ticcmd.h index 59a3422e7..404356995 100644 --- a/src/d_ticcmd.h +++ b/src/d_ticcmd.h @@ -34,8 +34,9 @@ typedef enum BT_BACKWARD = 1<<6, // Aim Item Backward BT_LOOKBACK = 1<<7, // Look Backward BT_HORN = 1<<8, // Honk your (follower's) horn + BT_SHAKE = 1<<9, // Shake controller (if using IMU) - // free: 1<<9 to 1<<12 + // free: 1<<10 to 1<<12 // Lua garbage BT_CUSTOM1 = 1<<13, @@ -58,7 +59,7 @@ typedef enum #define TICCMD_RECEIVED (0x01) /* Actual tic recieved from client */ #define TICCMD_TYPING (0x02) /* chat window or console open */ #define TICCMD_KEYSTROKE (0x04) /* chat character input */ -#define TICCMD_EXCESSTILT (0x08) /* player tilting controller too far */ +#define TICCMD_USINGTILT (0x08) /* player is using tilt control */ struct ticcmd_t { diff --git a/src/deh_tables.c b/src/deh_tables.c index 72c259f3c..7783f9466 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -1383,6 +1383,7 @@ struct int_const_s const INT_CONST[] = { {"BT_BACKWARD",BT_BACKWARD}, {"BT_LOOKBACK",BT_LOOKBACK}, {"BT_HORN",BT_HORN}, + {"BT_SHAKE",BT_SHAKE}, {"BT_CUSTOM1",BT_CUSTOM1}, // Lua customizable {"BT_CUSTOM2",BT_CUSTOM2}, // Lua customizable {"BT_CUSTOM3",BT_CUSTOM3}, // Lua customizable diff --git a/src/g_game.c b/src/g_game.c index 9265dcd06..0d7ddb1f3 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1421,22 +1421,7 @@ static void G_HandleAxisDeadZone(UINT8 splitnum, joystickvector2_t *joystickvect } // copy/pasted from the lua version of these routines -static vector4_t *QuaternionMul(vector4_t *out, vector4_t *a, vector4_t *b) -{ - fixed_t ax = a->x, ay = a->y, az = a->z, aw = a->a; - fixed_t bx = b->x, by = b->y, bz = b->z, bw = b->a; - - FV4_NormalizeEx(out, FV4_Load(out, - FixedMul(aw, bx) + FixedMul(ax, bw) + FixedMul(ay, bz) - FixedMul(az, by), - FixedMul(aw, by) - FixedMul(ax, bz) + FixedMul(ay, bw) + FixedMul(az, bx), - FixedMul(aw, bz) + FixedMul(ax, by) - FixedMul(ay, bx) + FixedMul(az, bw), - FixedMul(aw, bw) - FixedMul(ax, bx) - FixedMul(ay, by) - FixedMul(az, bz) - )); - - return out; -} - -static vector3_t *QuaternionMulVec3(vector3_t *out, vector3_t *a, vector4_t *b) +inline static vector3_t *QuaternionMulVec3(vector3_t *out, vector3_t *a, vector4_t *b) { fixed_t ax = a->x, ay = a->y, az = a->z, aw = 0; fixed_t bx = b->x, by = b->y, bz = b->z, bw = b->a; @@ -1450,28 +1435,16 @@ static vector3_t *QuaternionMulVec3(vector3_t *out, vector3_t *a, vector4_t *b) return out; } -static fixed_t FV3_LengthSquared(const vector3_t *vec) +inline static fixed_t FV3_LengthSquared(const vector3_t *vec) { return FixedMul(vec->x, vec->x) + FixedMul(vec->y, vec->y) + FixedMul(vec->z, vec->z); } -static fixed_t FV3_Length(const vector3_t *vec) +inline static fixed_t FV3_Length(const vector3_t *vec) { return FixedSqrt(FV3_LengthSquared(vec)); } -static vector4_t *QuaternionInvert(vector4_t *out) -{ - FV4_Load(out, - -out->x, - -out->y, - -out->z, - out->a - ); - - return out; -} - inline static vector4_t AngleAxis(fixed_t angle, fixed_t x, fixed_t y, fixed_t z) { fixed_t sinangle = FINESINE(FixedAngle(angle/2) >> ANGLETOFINESHIFT); @@ -1531,6 +1504,8 @@ void G_UpdateGamepadGravity(INT32 p, vector3_t gyro, vector3_t accel) vector3_t gravityToAccelDirection = {0}; vector3_t correction = {0}; + if (!G_GetGamepadCanUseTilt(p)) return; + // rotate gravity vector QuaternionMulVec3(&localgravityvectors[p], &localgravityvectors[p], &invRotation); QuaternionMulVec3(&localsmoothedaccel[p], &localsmoothedaccel[p], &invRotation); @@ -1594,20 +1569,12 @@ void G_UpdateGamepadGravity(INT32 p, vector3_t gyro, vector3_t accel) } } -#define TILTRANGE (45*FRACUNIT/100) -fixed_t G_GetGamepadTilt(INT32 p) +INT32 G_GetGamepadTilt(INT32 p) { fixed_t tilt; fixed_t curve; - if (p >= MAXSPLITSCREENPLAYERS) - { -#ifdef PARANOIA - CONS_Debug(DBG_GAMELOGIC, "G_PlayerInputAnalog: Invalid player ID %d\n", p); -#endif - return 0; - } - - tilt = CLAMP(FixedDiv(G_GetGamepadGravity(p).x + TILTRANGE, (TILTRANGE + TILTRANGE)), 0, FRACUNIT); + if (!G_GetGamepadCanUseTilt(p)) return 0; + tilt = CLAMP(FixedDiv(G_GetGamepadGravity(p).x + MAXGAMEPADTILT, 2*MAXGAMEPADTILT), 0, FRACUNIT); CONS_Debug(DBG_IMU, "Tilt: %4.2f\n", FixedToFloat(tilt)); curve = FINESINE(FixedAngle(180*(tilt-FRACUNIT/2))>>ANGLETOFINESHIFT); @@ -1615,39 +1582,35 @@ fixed_t G_GetGamepadTilt(INT32 p) return (JOYAXISRANGE * curve)/FRACUNIT; } -#undef TILTRANGE vector3_t G_GetGamepadGravity(INT32 p) { - const vector3_t zero = {0}; - - if (p >= MAXSPLITSCREENPLAYERS) - { -#ifdef PARANOIA - CONS_Debug(DBG_GAMELOGIC, "G_PlayerInputAnalog: Invalid player ID %d\n", p); -#endif - return zero; - } - + const vector3_t zero = {0, -ACCELEROMETERGRAVITY, 0}; + if (!G_GetGamepadCanUseTilt(p)) return zero; return localgravityvectors[p]; } vector3_t G_GetGamepadShake(INT32 p) { - const vector3_t zero = {0}; - vector3_t accel; - + vector3_t accel = {0}; + if (!G_GetGamepadCanUseTilt(p)) return accel; + accel = G_PlayerInputSensor(p, ACCELEROMETER); + FV3_Add(&accel, &localgravityvectors[p]); + + return accel; +} + +boolean G_GetGamepadCanUseTilt(INT32 p) +{ if (p >= MAXSPLITSCREENPLAYERS) { #ifdef PARANOIA - CONS_Debug(DBG_GAMELOGIC, "G_PlayerInputAnalog: Invalid player ID %d\n", p); + CONS_Debug(DBG_GAMELOGIC, "G_GetGamepadCanUseTilt: Invalid player ID %d\n", p); #endif - return zero; + return false; } - accel = G_PlayerInputSensor(p, ACCELEROMETER); - FV3_Add(&accel, &localgravityvectors[p]); - return accel; + return (I_ControllerSupportsSensorAccelerometer(p) && I_ControllerSupportsSensorGyro(p)); } #undef Interpolator @@ -1696,7 +1659,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) INT32 forward, side, tspeed; joystickvector2_t joystickvector; - INT16 accelerometertilt; + INT32 accelerometertilt; // you'd BETTER not touch the player while freecamming... player_t *player = &players[g_localplayers[forplayer]]; @@ -1723,7 +1686,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) // update our gamepad gravity when applicable // this should always execute so we have an accurate state - if (true) //todo: check if gamepad supports accel or accel and gyro + if (G_GetGamepadCanUseTilt(forplayer)) { vector3_t accel = G_PlayerInputSensor(forplayer, ACCELEROMETER); vector3_t gyro = G_PlayerInputSensor(forplayer, GYROSCOPE); @@ -1753,7 +1716,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) accelerometertilt = 0; } - if (!cv_tiltcontrol[forplayer].value) + if (cv_tiltcontrol[forplayer].value != 1) { accelerometertilt = 0; } @@ -1920,6 +1883,17 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) cmd->buttons |= BT_HORN; } + // shaking controller shakes + if (G_GetGamepadCanUseTilt(forplayer) && cv_tiltcontrol[forplayer].value > 0) + { + vector3_t shake = G_GetGamepadShake(forplayer); + CONS_Debug(DBG_IMU, "Shake: %4.2f\n", FixedToFloat(FV3_Length(&shake))); + if (FV3_Length(&shake) >= FRACUNIT) + { + cmd->buttons |= BT_SHAKE; + } + } + // Lua scriptable buttons if (G_PlayerInputDown(forplayer, gc_custom1, false, DEADZONE_BUTTON)) cmd->buttons |= BT_CUSTOM1; @@ -1972,6 +1946,11 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) } } + if (G_GetGamepadCanUseTilt(forplayer) && (cv_tiltcontrol[forplayer].value == 1)) + { + cmd->flags |= TICCMD_USINGTILT; + } + /* Lua: Allow this hook to overwrite ticcmd. We check if we're actually in a level because for some reason this Hook would run in menus and on the titlescreen otherwise. Be aware that within this hook, nothing but this player's cmd can be edited (otherwise we'd run in some pretty bad synching problems since this is clientsided, or something) diff --git a/src/g_game.h b/src/g_game.h index bddde7852..f07ac3dfd 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -141,12 +141,13 @@ typedef enum GYROSCOPE, } motionsensortype_e; -#define MAXGAMEPADTILT (ANG30) -#define ACCEL_GRAVITY (FLOAT_TO_FIXED(9.80665f)) +#define MAXGAMEPADTILT (45*FRACUNIT/100) +#define ACCELEROMETERGRAVITY FLOAT_TO_FIXED(9.80665f) +boolean G_GetGamepadCanUseTilt(INT32 p); void G_UpdateGamepadGravity(INT32 p, vector3_t gyro, vector3_t accel); -vector3_t G_GetGamepadGravity(INT32 p); +INT32 G_GetGamepadTilt(INT32 p); vector3_t G_GetGamepadShake(INT32 p); -fixed_t G_GetGamepadTilt(INT32 p); +vector3_t G_GetGamepadGravity(INT32 p); vector3_t G_PlayerInputSensor(UINT8 p, motionsensortype_e sensor); fixed_t G_GetDeadZoneType(INT32 p, SINT8 type); diff --git a/src/g_input.c b/src/g_input.c index a1548e2ae..e23f3615a 100644 --- a/src/g_input.c +++ b/src/g_input.c @@ -90,11 +90,12 @@ consvar_t cv_controllerled[MAXSPLITSCREENPLAYERS] = { CVAR_INIT ("gamepadled4", "Skincolor", CV_SAVE|CV_CALL|CV_NOINIT, controllerled_cons_t, led_off_handle4) }; +static CV_PossibleValue_t tiltcontrol_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Shakes Only"}, {0, NULL}}; consvar_t cv_tiltcontrol[MAXSPLITSCREENPLAYERS] = { - CVAR_INIT ("tiltcontrol", "Off", CV_SAVE, CV_OnOff, NULL), - CVAR_INIT ("tiltcontrol2", "Off", CV_SAVE, CV_OnOff, NULL), - CVAR_INIT ("tiltcontrol3", "Off", CV_SAVE, CV_OnOff, NULL), - CVAR_INIT ("tiltcontrol4", "Off", CV_SAVE, CV_OnOff, NULL) + CVAR_INIT ("tiltcontrol", "Off", CV_SAVE, tiltcontrol_cons_t, NULL), + CVAR_INIT ("tiltcontrol2", "Off", CV_SAVE, tiltcontrol_cons_t, NULL), + CVAR_INIT ("tiltcontrol3", "Off", CV_SAVE, tiltcontrol_cons_t, NULL), + CVAR_INIT ("tiltcontrol4", "Off", CV_SAVE, tiltcontrol_cons_t, NULL) }; static void rumble_off_handle(void) diff --git a/src/p_mobj.c b/src/p_mobj.c index f55f8f95b..8f79e6009 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10036,6 +10036,24 @@ static boolean P_MobjRegularThink(mobj_t *mobj) mobj->lastlook = player->cmd.turning; } + if (player->cmd.buttons & BT_SHAKE) + { + if (mobj->extravalue3 == 0) mobj->extravalue3 = 1; + + if (mobj->extravalue2 == 0) + { + mobj->movecount += (TICRATE/2); + mobj->threshold = 16*mobj->extravalue3; + S_StartSound(mobj, sfx_s1ab); + } + mobj->extravalue2 = 1; + mobj->extravalue3 *= -1; + } + else + { + mobj->extravalue2 = 0; + } + mobj->movecount++; } else if (mobj->extravalue1) // lost your player somehow, DIE diff --git a/src/sdl/i_gamepad.c b/src/sdl/i_gamepad.c index b2b43b472..fa46597c1 100644 --- a/src/sdl/i_gamepad.c +++ b/src/sdl/i_gamepad.c @@ -172,6 +172,10 @@ void I_InitController(UINT8 playernum) if (M_CheckParm("-nolibusb")) SDL_SetHintWithPriority("SDL_HIDAPI_LIBUSB", "0", SDL_HINT_OVERRIDE); + + // need to figure out how to get it to recognize Motion Plus + // if (!M_CheckParm("-nohidapiwii")) + // SDL_SetHintWithPriority("SDL_JOYSTICK_HIDAPI_WII", "1", SDL_HINT_OVERRIDE); if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0) {