implement BT_SHAKE and code cleanup

This commit is contained in:
minenice55 2026-03-01 00:24:55 -05:00
parent d5fc5ab7f0
commit db0afed3fd
7 changed files with 78 additions and 73 deletions

View file

@ -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
{

View file

@ -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

View file

@ -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)

View file

@ -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);

View file

@ -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)

View file

@ -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

View file

@ -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)
{