Merge pull request '[FEAT] Tilt Steering, GamepadMotion Sensor Access' (#222) from accelerometer into next
Reviewed-on: https://codeberg.org/NepDisk/blankart/pulls/222
This commit is contained in:
commit
2c6605440d
19 changed files with 554 additions and 69 deletions
|
|
@ -93,7 +93,7 @@
|
|||
#define ASSET_HASH_TEXTURES_KART 0xb4211b2f32b6a291
|
||||
#define ASSET_HASH_CHARS_KART 0x1e68a3e01aa5c68b
|
||||
#define ASSET_HASH_MAPS_KART 0x38558ed00da41ce9
|
||||
#define ASSET_HASH_MAIN_PK3 0x348af552ccc104d2
|
||||
#define ASSET_HASH_MAIN_PK3 0x9a54c263d9f325cd
|
||||
#define ASSET_HASH_MAPPATCH_PK3 0x1745690024efbaf8
|
||||
#define ASSET_HASH_BONUSCHARS_KART 0x60e6f13d822a7461
|
||||
#ifdef USE_PATCH_FILE
|
||||
|
|
@ -220,6 +220,16 @@ void D_ProcessEvents(void)
|
|||
// i have to reset this somewhere or else your camera just glides away!
|
||||
for (size_t i = 0; i < 4; i++)
|
||||
gamekeydown[0][KEY_MOUSEMOVE + i] = 0;
|
||||
|
||||
for (size_t dev = 0; dev < MAXDEVICES; dev++)
|
||||
{
|
||||
gamekeydown[dev][KEY_ACCELEROMETER1+0] = 0;
|
||||
gamekeydown[dev][KEY_ACCELEROMETER1+1] = 0;
|
||||
gamekeydown[dev][KEY_ACCELEROMETER1+2] = 0;
|
||||
gamekeydown[dev][KEY_GYROSCOPE1+0] = 0;
|
||||
gamekeydown[dev][KEY_GYROSCOPE1+1] = 0;
|
||||
gamekeydown[dev][KEY_GYROSCOPE1+2] = 0;
|
||||
}
|
||||
|
||||
for (; eventtail != eventhead; eventtail = (eventtail+1) & (MAXEVENTS-1))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1405,6 +1405,7 @@ void D_RegisterClientCommands(void)
|
|||
CV_RegisterVar(&cv_controllerrumble[i]);
|
||||
CV_RegisterVar(&cv_rumblestrength[i]);
|
||||
CV_RegisterVar(&cv_controllerled[i]);
|
||||
CV_RegisterVar(&cv_tiltcontrol[i]);
|
||||
}
|
||||
|
||||
// filesrch.c
|
||||
|
|
|
|||
|
|
@ -58,7 +58,10 @@ 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_USINGTILT (0x08) /* player is using tilt control instead of the stick/buttons to turn */
|
||||
#define TICCMD_EXCESSTILT (0x10) /* player is tilting gamepad farther than the max range */
|
||||
|
||||
// 16 bytes long now!
|
||||
struct ticcmd_t
|
||||
{
|
||||
SINT8 forwardmove; // -MAXPLMOVE to MAXPLMOVE (50)
|
||||
|
|
@ -70,6 +73,8 @@ struct ticcmd_t
|
|||
UINT16 buttons;
|
||||
UINT8 latency; // Netgames: how many tics ago was this ticcmd generated from this player's end?
|
||||
UINT8 flags;
|
||||
SINT8 tilt;
|
||||
UINT8 shake;
|
||||
} ATTRPACK;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
|
|
@ -1851,6 +1851,17 @@ struct int_const_s const INT_CONST[] = {
|
|||
{"TIMER_PINK", TIMER_PINK},
|
||||
{"TIMER_BROWN", TIMER_BROWN},
|
||||
{"TIMER_TAN", TIMER_TAN},
|
||||
|
||||
// motion sensor related constants
|
||||
{"MAXGAMEPADTILT", MAXGAMEPADTILT},
|
||||
{"GAMEPADSHAKETHRESHOLD", GAMEPADSHAKETHRESHOLD},
|
||||
{"ACCELEROMETERGRAVITY", ACCELEROMETERGRAVITY},
|
||||
|
||||
//ticcmd constants
|
||||
{"TICCMD_TYPING", TICCMD_TYPING},
|
||||
{"TICCMD_KEYSTROKE", TICCMD_KEYSTROKE},
|
||||
{"TICCMD_USINGTILT", TICCMD_USINGTILT},
|
||||
{"TICCMD_EXCESSTILT", TICCMD_EXCESSTILT},
|
||||
|
||||
{NULL,0}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -370,7 +370,7 @@ typedef enum
|
|||
DBG_PLAYER = 0x00000004,
|
||||
DBG_RENDER = 0x00000008,
|
||||
DBG_MUSIC = 0x00000010,
|
||||
//DBG_NIGHTS = 0x00000020, // free
|
||||
DBG_IMU = 0x00000020,
|
||||
DBG_POLYOBJ = 0x00000040,
|
||||
DBG_GAMELOGIC = 0x00000080,
|
||||
DBG_NETPLAY = 0x00000100,
|
||||
|
|
|
|||
20
src/g_demo.c
20
src/g_demo.c
|
|
@ -144,6 +144,8 @@ demoghost *ghosts = NULL;
|
|||
#define ZT_AIMING 0x0040
|
||||
#define ZT_LATENCY 0x0080
|
||||
#define ZT_FLAGS 0x0100
|
||||
#define ZT_IMUTILT 0x0200
|
||||
#define ZT_IMUSHAKE 0x0400
|
||||
// Ziptics are UINT16 now, go nuts
|
||||
|
||||
#define DEMOMARKER 0x80 // demobuf.end
|
||||
|
|
@ -400,6 +402,10 @@ static UINT8 *G_ReadZipTic(ticcmd_t *cmd, UINT8 *dp, UINT16 version)
|
|||
cmd->latency = READUINT8(dp);
|
||||
if (ziptic & ZT_FLAGS)
|
||||
cmd->flags = READUINT8(dp);
|
||||
if (ziptic & ZT_IMUTILT)
|
||||
cmd->tilt = READSINT8(dp);
|
||||
if (ziptic & ZT_IMUSHAKE)
|
||||
cmd->shake = READUINT8(dp);
|
||||
|
||||
if (version < 0x000a && ziptic & 0x8000) // ZT_BOT
|
||||
{
|
||||
|
|
@ -1583,6 +1589,20 @@ void G_WriteDemoTiccmd(ticcmd_t *cmd, INT32 playernum)
|
|||
ziptic |= ZT_FLAGS;
|
||||
}
|
||||
|
||||
if (cmd->tilt != oldcmd[playernum].tilt)
|
||||
{
|
||||
WRITESINT8(demobuf.p,cmd->tilt);
|
||||
oldcmd[playernum].tilt = cmd->tilt;
|
||||
ziptic |= ZT_IMUTILT;
|
||||
}
|
||||
|
||||
if (cmd->shake != oldcmd[playernum].shake)
|
||||
{
|
||||
WRITESINT8(demobuf.p,cmd->shake);
|
||||
oldcmd[playernum].shake = cmd->shake;
|
||||
ziptic |= ZT_IMUSHAKE;
|
||||
}
|
||||
|
||||
WRITEUINT16(ziptic_p, ziptic);
|
||||
|
||||
// attention here for the ticcmd size!
|
||||
|
|
|
|||
304
src/g_game.c
304
src/g_game.c
|
|
@ -51,6 +51,7 @@
|
|||
#include "m_cond.h" // condition sets
|
||||
#include "r_fps.h" // frame interpolation/uncapped
|
||||
#include "lua_hud.h"
|
||||
#include "m_easing.h"
|
||||
|
||||
// SRB2kart
|
||||
#include "k_kart.h"
|
||||
|
|
@ -1306,6 +1307,46 @@ retrygetcontrol:
|
|||
return 0;
|
||||
}
|
||||
|
||||
vector3_t G_PlayerInputSensor(UINT8 p, motionsensortype_e sensor)
|
||||
{
|
||||
vector3_t out = {0};
|
||||
INT32 deviceID;
|
||||
|
||||
if (p >= MAXSPLITSCREENPLAYERS)
|
||||
{
|
||||
#ifdef PARANOIA
|
||||
CONS_Debug(DBG_GAMELOGIC, "G_PlayerInputAnalog: Invalid player ID %d\n", p);
|
||||
#endif
|
||||
return out;
|
||||
}
|
||||
|
||||
deviceID = I_GetControllerSlotfromID(I_GetControllerIDForPlayer(p));
|
||||
if (deviceID >= MAXDEVICES)
|
||||
return out;
|
||||
|
||||
if (deviceID == INVALID_DEVICE || deviceID == KEYBOARD_MOUSE_DEVICE)
|
||||
return out;
|
||||
|
||||
switch (sensor)
|
||||
{
|
||||
case ACCELEROMETER:
|
||||
FV3_Load(&out,
|
||||
gamekeydown[deviceID][KEY_ACCELEROMETER1+0],
|
||||
gamekeydown[deviceID][KEY_ACCELEROMETER1+1],
|
||||
gamekeydown[deviceID][KEY_ACCELEROMETER1+2]
|
||||
);
|
||||
break;
|
||||
case GYROSCOPE:
|
||||
FV3_Load(&out,
|
||||
gamekeydown[deviceID][KEY_GYROSCOPE1+0],
|
||||
gamekeydown[deviceID][KEY_GYROSCOPE1+1],
|
||||
gamekeydown[deviceID][KEY_GYROSCOPE1+2]
|
||||
);
|
||||
break;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
boolean G_PlayerInputDown(UINT8 p, INT32 gc, boolean digital, SINT8 type)
|
||||
{
|
||||
return (G_PlayerInputAnalog(p, gc, digital, type) != 0);
|
||||
|
|
@ -1379,6 +1420,207 @@ static void G_HandleAxisDeadZone(UINT8 splitnum, joystickvector2_t *joystickvect
|
|||
}
|
||||
}
|
||||
|
||||
// copy/pasted from the lua version of these routines
|
||||
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;
|
||||
|
||||
FV3_NormalizeEx(out, FV3_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)
|
||||
));
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
inline static fixed_t FV3_Length(const vector3_t *vec)
|
||||
{
|
||||
return FixedSqrt(FV3_LengthSquared(vec));
|
||||
}
|
||||
|
||||
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);
|
||||
fixed_t cosangle = FINECOSINE(FixedAngle(angle/2) >> ANGLETOFINESHIFT);
|
||||
vector3_t axis = {x, y, z};
|
||||
vector4_t result;
|
||||
|
||||
FV3_Normalize(&axis);
|
||||
|
||||
FV4_Load(&result,
|
||||
FixedMul(axis.x, sinangle),
|
||||
FixedMul(axis.y, sinangle),
|
||||
FixedMul(axis.z, sinangle),
|
||||
cosangle
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// math sourced from this article
|
||||
// http://gyrowiki.jibbsmart.com/blog:finding-gravity-with-sensor-fusion
|
||||
// state
|
||||
fixed_t localshakinessfac[MAXSPLITSCREENPLAYERS];
|
||||
vector3_t localsmoothedaccel[MAXSPLITSCREENPLAYERS];
|
||||
vector3_t localgravityvectors[MAXSPLITSCREENPLAYERS];
|
||||
|
||||
// thresholds of trust for accel shakiness. less shakiness = more trust
|
||||
#define ShakinessMaxThreshold (80*FRACUNIT/100)
|
||||
#define ShakinessMinThreshold (32*FRACUNIT/100)
|
||||
// when we trust the accel a lot (the controller is "still"), how quickly do we correct our gravity vector?
|
||||
#define CorrectionStillRate (FRACUNIT)
|
||||
// when we don't trust the accel (the controller is "shaky"), how quickly do we correct our gravity vector?
|
||||
#define CorrectionShakyRate (FRACUNIT/8)
|
||||
// if our old gravity vector is close enough to our new one, limit further corrections to this proportion of the rotation speed
|
||||
#define CorrectionGyroFactor (FRACUNIT/5)
|
||||
// thresholds for what's considered "close enough"
|
||||
#define CorrectionGyroMinThreshold (2*FRACUNIT/100)
|
||||
#define CorrectionGyroMaxThreshold (FRACUNIT/4)
|
||||
// no matter what, always apply a minimum of this much correction to our gravity vector
|
||||
#define CorrectionMinimumSpeed (9*FRACUNIT/100)
|
||||
|
||||
void G_UpdateGamepadGravity(INT32 p, vector3_t gyro, vector3_t accel)
|
||||
{
|
||||
// convert gyro input to reverse rotation
|
||||
const fixed_t smoothFactor = 800*FRACUNIT/1000;
|
||||
vector3_t invAccel = {-accel.x, -accel.y, -accel.z};
|
||||
fixed_t gravCorrectionRate = 0;
|
||||
fixed_t angleRate;
|
||||
fixed_t correctionLimit;
|
||||
vector4_t invRotation = AngleAxis(
|
||||
FixedMul(FV3_Length(&gyro), FRACUNIT/TICRATE),
|
||||
-gyro.x,
|
||||
-gyro.y,
|
||||
-gyro.z
|
||||
);
|
||||
vector3_t gravityToAccel = {0};
|
||||
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);
|
||||
localshakinessfac[p] = FixedMul(localshakinessfac[p], smoothFactor),
|
||||
FV3_SubEx(&accel, &localsmoothedaccel[p], &correction);
|
||||
localshakinessfac[p] = max(localshakinessfac[p], FV3_Length(&correction));
|
||||
FV3_Load(&localsmoothedaccel[p],
|
||||
Easing_Linear(smoothFactor, accel.x, localsmoothedaccel[p].x),
|
||||
Easing_Linear(smoothFactor, accel.y, localsmoothedaccel[p].y),
|
||||
Easing_Linear(smoothFactor, accel.z, localsmoothedaccel[p].z)
|
||||
);
|
||||
|
||||
CONS_Debug(DBG_IMU, "Shakiness: %4.2f\n", FixedToFloat(localshakinessfac[p]));
|
||||
|
||||
FV3_SubEx(&invAccel, &localgravityvectors[p], &gravityToAccel);
|
||||
FV3_NormalizeEx(&gravityToAccel, &gravityToAccelDirection);
|
||||
|
||||
if (ShakinessMaxThreshold > ShakinessMinThreshold)
|
||||
{
|
||||
fixed_t stillness = CLAMP(FixedDiv((localshakinessfac[p] - ShakinessMinThreshold), (ShakinessMaxThreshold - ShakinessMinThreshold)), 0, FRACUNIT);
|
||||
gravCorrectionRate = CorrectionStillRate + FixedMul((CorrectionShakyRate - CorrectionStillRate), stillness);
|
||||
}
|
||||
else
|
||||
{
|
||||
gravCorrectionRate = localshakinessfac[p] < ShakinessMaxThreshold ? CorrectionStillRate : CorrectionShakyRate;
|
||||
}
|
||||
|
||||
// limit in proportion to rotation rate
|
||||
angleRate = FixedMul(FV3_Length(&gyro), M_PI_FIXED)/180;
|
||||
correctionLimit = FixedMul(FixedMul(angleRate, FV3_Length(&localgravityvectors[p])), CorrectionGyroFactor);
|
||||
if (gravCorrectionRate > correctionLimit) {
|
||||
fixed_t closeEnoughFactor;
|
||||
if (CorrectionGyroMaxThreshold > CorrectionGyroMinThreshold)
|
||||
{
|
||||
closeEnoughFactor = CLAMP(FixedDiv((FV3_Length(&gravityToAccel) - CorrectionGyroMinThreshold), (CorrectionGyroMaxThreshold - CorrectionGyroMinThreshold)), 0, FRACUNIT);
|
||||
}
|
||||
else
|
||||
{
|
||||
closeEnoughFactor = FV3_Length(&gravityToAccel) < CorrectionGyroMaxThreshold ? 0 : FRACUNIT;
|
||||
}
|
||||
gravCorrectionRate = correctionLimit + FixedMul((gravCorrectionRate - correctionLimit), closeEnoughFactor);
|
||||
}
|
||||
|
||||
// finally, let's always allow a little bit of correction
|
||||
gravCorrectionRate = max(gravCorrectionRate, CorrectionMinimumSpeed);
|
||||
|
||||
CONS_Debug(DBG_IMU, "Correction Rate: %4.2f\n", FixedToFloat(gravCorrectionRate));
|
||||
|
||||
FV3_Load(&correction,
|
||||
FixedMul(gravityToAccel.x, gravCorrectionRate/TICRATE),
|
||||
FixedMul(gravityToAccel.y, gravCorrectionRate/TICRATE),
|
||||
FixedMul(gravityToAccel.z, gravCorrectionRate/TICRATE)
|
||||
);
|
||||
if (FV3_LengthSquared(&correction) < FV3_LengthSquared(&gravityToAccel))
|
||||
{
|
||||
FV3_Add(&localgravityvectors[p], &correction);
|
||||
}
|
||||
else
|
||||
{
|
||||
FV3_Add(&localgravityvectors[p], &gravityToAccel);
|
||||
}
|
||||
}
|
||||
|
||||
INT32 G_GetGamepadTilt(INT32 p)
|
||||
{
|
||||
fixed_t tilt;
|
||||
fixed_t curve;
|
||||
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);
|
||||
CONS_Debug(DBG_IMU, "Pinched Tilt: %4.2f\n", FixedToFloat(curve));
|
||||
|
||||
return (JOYAXISRANGE * curve)/FRACUNIT;
|
||||
}
|
||||
|
||||
vector3_t G_GetGamepadGravity(INT32 p)
|
||||
{
|
||||
const vector3_t zero = {0, -ACCELEROMETERGRAVITY, 0};
|
||||
if (!G_GetGamepadCanUseTilt(p)) return zero;
|
||||
return localgravityvectors[p];
|
||||
}
|
||||
|
||||
vector3_t G_GetGamepadShake(INT32 p)
|
||||
{
|
||||
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_GetGamepadCanUseTilt: Invalid player ID %d\n", p);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
return (I_ControllerSupportsSensorAccelerometer(p) && I_ControllerSupportsSensorGyro(p));
|
||||
}
|
||||
#undef ShakinessMaxThreshold
|
||||
#undef ShakinessMinThreshold
|
||||
#undef CorrectionStillRate
|
||||
#undef CorrectionShakyRate
|
||||
#undef CorrectionGyroFactor
|
||||
#undef CorrectionGyroMinThreshold
|
||||
#undef CorrectionGyroMaxThreshold
|
||||
#undef CorrectionMinimumSpeed
|
||||
|
||||
//
|
||||
// G_BuildTiccmd
|
||||
// Builds a ticcmd from all of the available inputs
|
||||
|
|
@ -1414,6 +1656,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
|||
INT32 forward, side, tspeed;
|
||||
|
||||
joystickvector2_t joystickvector;
|
||||
INT32 accelerometertilt;
|
||||
|
||||
// you'd BETTER not touch the player while freecamming...
|
||||
player_t *player = &players[g_localplayers[forplayer]];
|
||||
|
|
@ -1438,6 +1681,15 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
|||
break;
|
||||
}
|
||||
|
||||
// update our gamepad gravity when applicable
|
||||
// this should always execute so we have an accurate state
|
||||
if (G_GetGamepadCanUseTilt(forplayer))
|
||||
{
|
||||
vector3_t accel = G_PlayerInputSensor(forplayer, ACCELEROMETER);
|
||||
vector3_t gyro = G_PlayerInputSensor(forplayer, GYROSCOPE);
|
||||
G_UpdateGamepadGravity(forplayer, gyro, accel);
|
||||
}
|
||||
|
||||
// why build a ticcmd if we're paused?
|
||||
// Or, for that matter, if we're being reborn.
|
||||
if (!thiscam->freecam && (paused || P_AutoPause() || (gamestate == GS_LEVEL && player->playerstate == PST_REBORN)))
|
||||
|
|
@ -1455,6 +1707,16 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
|||
joystickvector.yaxis = 0;
|
||||
G_HandleAxisDeadZone(forplayer, &joystickvector);
|
||||
|
||||
// tilt control never has deadzone
|
||||
// if stick input is used gradually cancel out tilt based on stick intensity
|
||||
if (cv_tiltcontrol[forplayer].value == 1)
|
||||
{
|
||||
fixed_t rate = FixedDiv(abs(joystickvector.xaxis), JOYAXISRANGE);
|
||||
accelerometertilt =
|
||||
(FixedMul(rate, joystickvector.xaxis*FRACUNIT)/FRACUNIT) +
|
||||
(FixedMul(FRACUNIT-rate, G_GetGamepadTilt(forplayer)*FRACUNIT)/FRACUNIT);
|
||||
}
|
||||
|
||||
// For kart, I've turned the aim axis into a digital axis because we only
|
||||
// use it for aiming to throw items forward/backward and the vote screen
|
||||
// This mean that the turn axis will still be gradient but up/down will be 0
|
||||
|
|
@ -1465,10 +1727,18 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
|||
if (encoremode)
|
||||
{
|
||||
joystickvector.xaxis = -joystickvector.xaxis;
|
||||
accelerometertilt = -accelerometertilt;
|
||||
}
|
||||
|
||||
forward = side = 0;
|
||||
tspeed = joystickvector.xaxis;
|
||||
if (cv_tiltcontrol[forplayer].value == 1)
|
||||
{
|
||||
tspeed = accelerometertilt;
|
||||
}
|
||||
else
|
||||
{
|
||||
tspeed = joystickvector.xaxis;
|
||||
}
|
||||
|
||||
// use two stage accelerative turning
|
||||
// on the keyboard and (NOT!) joystick
|
||||
|
|
@ -1488,11 +1758,19 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
|||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
turnheld[forplayer] = 0;
|
||||
}
|
||||
|
||||
cmd->turning = 0;
|
||||
|
||||
if (joystickvector.xaxis != 0)
|
||||
if (cv_tiltcontrol[forplayer].value == 1)
|
||||
{
|
||||
cmd->turning -= (tspeed * KART_FULLTURN) / JOYAXISRANGE;
|
||||
cmd->angle -= (tspeed * KART_FULLTURN) / JOYAXISRANGE;
|
||||
side += (accelerometertilt * 4) / JOYAXISRANGE;
|
||||
}
|
||||
else if (joystickvector.xaxis != 0)
|
||||
{
|
||||
cmd->turning -= (tspeed * KART_FULLTURN) / JOYAXISRANGE;
|
||||
cmd->angle -= (tspeed * KART_FULLTURN) / JOYAXISRANGE;
|
||||
|
|
@ -1693,6 +1971,26 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
|||
else if (cmd->throwdir < -KART_FULLTURN)
|
||||
cmd->throwdir = -KART_FULLTURN;
|
||||
|
||||
if (G_GetGamepadCanUseTilt(forplayer) && cv_tiltcontrol[forplayer].value)
|
||||
{
|
||||
fixed_t tilt = G_GetGamepadGravity(forplayer).x;
|
||||
vector3_t shake = G_GetGamepadShake(forplayer);
|
||||
|
||||
if (cv_tiltcontrol[forplayer].value == 1)
|
||||
{
|
||||
cmd->tilt = INT8_MAX*tilt/FRACUNIT;
|
||||
|
||||
cmd->flags |= TICCMD_USINGTILT;
|
||||
if (abs(tilt) > MAXGAMEPADTILT)
|
||||
cmd->flags |= TICCMD_EXCESSTILT;
|
||||
}
|
||||
|
||||
CONS_Debug(DBG_IMU, "Shake: %4.2f\n", FixedToFloat(FV3_Length(&shake)));
|
||||
cmd->shake = CLAMP((GAMEPADSHAKETHRESHOLD*FV3_Length(&shake))/FRACUNIT, 0, UINT8_MAX);
|
||||
|
||||
CONS_Debug(DBG_IMU, "CMD Tilt: %d, Shake: %d\n", cmd->tilt, cmd->shake);
|
||||
}
|
||||
|
||||
G_DoCameraTurn(cmd, realtics, ssplayer, player);
|
||||
|
||||
// Reset away view if a command is given.
|
||||
|
|
@ -1725,6 +2023,8 @@ ticcmd_t *G_MoveTiccmd(ticcmd_t* dest, const ticcmd_t* src, const size_t n)
|
|||
dest[i].buttons = (UINT16)SHORT(src[i].buttons);
|
||||
dest[i].latency = src[i].latency;
|
||||
dest[i].flags = src[i].flags;
|
||||
dest[i].tilt = src[i].tilt;
|
||||
dest[i].shake = src[i].shake;
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
|
|
|||
17
src/g_game.h
17
src/g_game.h
|
|
@ -135,6 +135,23 @@ typedef enum
|
|||
DEADZONE_BUTTON,
|
||||
} analogdeadzone_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ACCELEROMETER,
|
||||
GYROSCOPE,
|
||||
} motionsensortype_e;
|
||||
|
||||
#define MAXGAMEPADTILT (50*FRACUNIT/100)
|
||||
#define ACCELEROMETERGRAVITY ((fixed_t)(9.80665f * ((float)FRACUNIT)))
|
||||
#define GAMEPADSHAKETHRESHOLD (UINT8_MAX/2)
|
||||
#define TILTTOSTICKEASE 6
|
||||
boolean G_GetGamepadCanUseTilt(INT32 p);
|
||||
void G_UpdateGamepadGravity(INT32 p, vector3_t gyro, vector3_t accel);
|
||||
INT32 G_GetGamepadTilt(INT32 p);
|
||||
vector3_t G_GetGamepadShake(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);
|
||||
INT32 G_PlayerInputAnalog(UINT8 p, INT32 gc, boolean digital, SINT8 type);
|
||||
boolean G_PlayerInputDown(UINT8 p, INT32 gc, boolean digital, SINT8 type);
|
||||
|
|
|
|||
|
|
@ -90,6 +90,14 @@ 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, 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)
|
||||
{
|
||||
if (cv_controllerrumble[0].value == 0)
|
||||
|
|
@ -333,6 +341,20 @@ void G_MapEventsToControls(event_t *ev)
|
|||
gamekeydown[device][i] = max(0, ev->data2);
|
||||
|
||||
break;
|
||||
|
||||
case ev_accelerometer:
|
||||
// average out accel events recieved for this tick (favouring the newer data)
|
||||
gamekeydown[device][KEY_ACCELEROMETER1+0] = (gamekeydown[device][KEY_ACCELEROMETER1+0] + (3*ev->data1))/4;
|
||||
gamekeydown[device][KEY_ACCELEROMETER1+1] = (gamekeydown[device][KEY_ACCELEROMETER1+1] + (3*ev->data2))/4;
|
||||
gamekeydown[device][KEY_ACCELEROMETER1+2] = (gamekeydown[device][KEY_ACCELEROMETER1+2] + (3*ev->data3))/4;
|
||||
break;
|
||||
|
||||
case ev_gyroscope:
|
||||
// average out gyro events recieved for this tick
|
||||
gamekeydown[device][KEY_GYROSCOPE1+0] = (gamekeydown[device][KEY_GYROSCOPE1+0] + ev->data1)/2;
|
||||
gamekeydown[device][KEY_GYROSCOPE1+1] = (gamekeydown[device][KEY_GYROSCOPE1+1] + ev->data2)/2;
|
||||
gamekeydown[device][KEY_GYROSCOPE1+2] = (gamekeydown[device][KEY_GYROSCOPE1+2] + ev->data3)/2;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
|
|
@ -472,19 +494,13 @@ static keyname_t keynames[] =
|
|||
{KEY_AXIS1+8, "L TRIGGER"},
|
||||
{KEY_AXIS1+9, "R TRIGGER"},
|
||||
|
||||
{KEY_ACCELEROMETER1+0, "TILT -X"},
|
||||
{KEY_ACCELEROMETER1+1, "TILT +X"},
|
||||
{KEY_ACCELEROMETER1+2, "TILT -Y"},
|
||||
{KEY_ACCELEROMETER1+3, "TILT +Y"},
|
||||
{KEY_ACCELEROMETER1+4, "TILT -Z"},
|
||||
{KEY_ACCELEROMETER1+5, "TILT +Z"},
|
||||
{KEY_ACCELEROMETER1+0, "TILT X"},
|
||||
{KEY_ACCELEROMETER1+1, "TILT Y"},
|
||||
{KEY_ACCELEROMETER1+2, "TILT Z"},
|
||||
|
||||
{KEY_GYROSCOPE1+0, "ROTATE -X"},
|
||||
{KEY_GYROSCOPE1+1, "ROTATE +X"},
|
||||
{KEY_GYROSCOPE1+2, "ROTATE -Y"},
|
||||
{KEY_GYROSCOPE1+3, "ROTATE +Y"},
|
||||
{KEY_GYROSCOPE1+4, "ROTATE -Z"},
|
||||
{KEY_GYROSCOPE1+5, "ROTATE +Z"},
|
||||
{KEY_GYROSCOPE1+0, "ROTATE X"},
|
||||
{KEY_GYROSCOPE1+1, "ROTATE Y"},
|
||||
{KEY_GYROSCOPE1+2, "ROTATE Z"},
|
||||
};
|
||||
|
||||
static const char *gamecontrolname[num_gamecontrols] =
|
||||
|
|
|
|||
|
|
@ -35,8 +35,9 @@ extern "C" {
|
|||
#define JOYANALOGS 4 // 4 analog stick axes (2 sticks * 2 axes)
|
||||
#define JOYTRIGGERS 2 // 2 trigger axes, positive only
|
||||
#define JOYIMUAXISES 6 // 3 accelerometer, 3 gyroscope axes (x, y, z)
|
||||
#define JOYAXISES (JOYANALOGS + JOYTRIGGERS + JOYIMUAXISES)
|
||||
#define JOYAXISKEYS ((2 * JOYANALOGS) + JOYTRIGGERS + (2 * JOYIMUAXISES))
|
||||
#define JOYAXISES (JOYANALOGS + JOYTRIGGERS + JOYIMUAXISES)
|
||||
#define JOYAXISKEYS (2 * JOYANALOGS) + JOYTRIGGERS
|
||||
#define JOYSTATEKEYS JOYAXISKEYS + JOYIMUAXISES
|
||||
|
||||
#define MAXINPUTMAPPING 4
|
||||
|
||||
|
|
@ -48,9 +49,9 @@ typedef enum
|
|||
KEY_JOY1 = NUMKEYS,
|
||||
KEY_HAT1 = KEY_JOY1 + JOY_DPAD_UP,
|
||||
KEY_AXIS1 = KEY_JOY1 + JOYBUTTONS,
|
||||
KEY_ACCELEROMETER1 = KEY_AXIS1 + JOYANALOGS + JOYTRIGGERS,
|
||||
KEY_GYROSCOPE1 = KEY_ACCELEROMETER1 + 6,
|
||||
JOYINPUTEND = KEY_AXIS1 + JOYAXISKEYS,
|
||||
KEY_ACCELEROMETER1 = KEY_AXIS1 + JOYAXISKEYS,
|
||||
KEY_GYROSCOPE1 = KEY_ACCELEROMETER1 + 3,
|
||||
JOYINPUTEND = KEY_AXIS1 + JOYSTATEKEYS,
|
||||
|
||||
KEY_MOUSE1 = JOYINPUTEND,
|
||||
KEY_MOUSEMOVE = KEY_MOUSE1 + MOUSEBUTTONS,
|
||||
|
|
@ -106,6 +107,7 @@ extern consvar_t cv_turnsmooth[MAXSPLITSCREENPLAYERS];
|
|||
extern consvar_t cv_controllerrumble[MAXSPLITSCREENPLAYERS];
|
||||
extern consvar_t cv_rumblestrength[MAXSPLITSCREENPLAYERS];
|
||||
extern consvar_t cv_controllerled[MAXSPLITSCREENPLAYERS];
|
||||
extern consvar_t cv_tiltcontrol[MAXSPLITSCREENPLAYERS];
|
||||
|
||||
// current state of the keys: JOYAXISRANGE or 0 when boolean.
|
||||
// Or anything inbetween for analog values
|
||||
|
|
|
|||
87
src/k_hud.c
87
src/k_hud.c
|
|
@ -189,7 +189,8 @@ static patch_t *kp_check[11];
|
|||
static patch_t *kp_eggnum[4];
|
||||
|
||||
static patch_t *kp_fpview[3];
|
||||
static patch_t *kp_inputwheel[5];
|
||||
static patch_t *kp_inputwheel;
|
||||
static patch_t *kp_inputwheel_shadow;
|
||||
|
||||
static patch_t *kp_challenger[25];
|
||||
|
||||
|
|
@ -600,12 +601,21 @@ void K_LoadKartHUDGraphics(void)
|
|||
HU_UpdatePatch(&joyshadow, "JOYSHD");
|
||||
|
||||
// Input UI Wheel
|
||||
sprintf(buffer, "K_WHEELx");
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
buffer[7] = '0'+i;
|
||||
HU_UpdatePatch(&kp_inputwheel[i], "%s", buffer);
|
||||
}
|
||||
HU_UpdatePatch(&kp_inputwheel, "K_WHEEL0");
|
||||
kp_inputwheel->pivot.x =
|
||||
(kp_inputwheel->width / 2) + kp_inputwheel->leftoffset;
|
||||
kp_inputwheel->pivot.y =
|
||||
(kp_inputwheel->height / 2) + kp_inputwheel->topoffset;
|
||||
kp_inputwheel->alignflags |=
|
||||
(PATCHALIGN_AUTOCENTER | PATCHALIGN_USEPIVOTS);
|
||||
|
||||
HU_UpdatePatch(&kp_inputwheel_shadow, "K_WHEEL1");
|
||||
kp_inputwheel_shadow->pivot.x =
|
||||
(kp_inputwheel_shadow->width / 2) + kp_inputwheel_shadow->leftoffset;
|
||||
kp_inputwheel_shadow->pivot.y =
|
||||
(kp_inputwheel_shadow->height / 2) + kp_inputwheel_shadow->topoffset;
|
||||
kp_inputwheel_shadow->alignflags |=
|
||||
(PATCHALIGN_AUTOCENTER | PATCHALIGN_USEPIVOTS);
|
||||
|
||||
// HERE COMES A NEW CHALLENGER
|
||||
sprintf(buffer, "K_CHALxx");
|
||||
|
|
@ -5439,44 +5449,43 @@ static void K_drawInput(void)
|
|||
}
|
||||
else if (cv_showinput.value == 1)
|
||||
{
|
||||
if (!stplyr->cmd.turning) // no turn
|
||||
target = 0;
|
||||
else // turning of multiple strengths!
|
||||
{
|
||||
target = ((abs(stplyr->cmd.turning) - 1)/200)+1; // was 125, do we need another toggle for this? Zzz...
|
||||
if (target > 4)
|
||||
target = 4;
|
||||
if (stplyr->cmd.turning < 0)
|
||||
target = -target;
|
||||
}
|
||||
patch_t *workingPic = kp_inputwheel;
|
||||
patch_t *shadowPic = kp_inputwheel_shadow;
|
||||
|
||||
if (pn != target)
|
||||
{
|
||||
if (abs(pn - target) == 1)
|
||||
pn = target;
|
||||
else if (pn < target)
|
||||
pn += 2;
|
||||
else //if (pn > target)
|
||||
pn -= 2;
|
||||
}
|
||||
|
||||
if (pn < 0)
|
||||
{
|
||||
splitflags |= V_FLIP; // right turn
|
||||
x -= FRACUNIT;
|
||||
}
|
||||
|
||||
target = abs(pn);
|
||||
if (target > 4)
|
||||
target = 4;
|
||||
INT16 turning = encoremode ? -stplyr->cmd.turning : stplyr->cmd.turning;
|
||||
SINT8 tilt = encoremode ? -stplyr->cmd.tilt : stplyr->cmd.tilt;
|
||||
angle_t rotate = FixedAngle(60 * FixedDiv(abs(turning), 1024) * intsign(turning));
|
||||
UINT8 *colormap;
|
||||
|
||||
if (!K_GetHudColor())
|
||||
V_DrawFixedPatch(x, y, FRACUNIT, splitflags, kp_inputwheel[target], NULL);
|
||||
{
|
||||
V_DrawRotatedPatch(x-(17*FRACUNIT), y-(38*FRACUNIT)+(FRACUNIT*2), rotate, FRACUNIT, FRACUNIT, splitflags|V_SUBTRACT|V_10TRANS, shadowPic, NULL);
|
||||
V_DrawRotatedPatch(x-(17*FRACUNIT), y-(38*FRACUNIT), rotate, FRACUNIT, FRACUNIT, splitflags, workingPic, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT8 *colormap;
|
||||
colormap = R_GetTranslationColormap(0, K_GetHudColor(), GTC_CACHE);
|
||||
V_DrawFixedPatch(x, y, FRACUNIT, splitflags, kp_inputwheel[target], colormap);
|
||||
V_DrawRotatedPatch(x-(17*FRACUNIT), y-(38*FRACUNIT)+(FRACUNIT*2), rotate, FRACUNIT, FRACUNIT, splitflags|V_SUBTRACT|V_10TRANS, shadowPic, colormap);
|
||||
V_DrawRotatedPatch(x-(17*FRACUNIT), y-(38*FRACUNIT), rotate, FRACUNIT, FRACUNIT, splitflags, workingPic, colormap);
|
||||
}
|
||||
|
||||
// a la GT7
|
||||
if (stplyr->cmd.flags & TICCMD_USINGTILT)
|
||||
{
|
||||
rotate = FixedAngle(60 * ((tilt < 0) ? FixedDiv(-tilt, -(50*INT8_MIN/100)) : FixedDiv(tilt, (50*INT8_MAX/100))));
|
||||
x += 17*FINESINE(rotate>>ANGLETOFINESHIFT) * intsign(tilt);
|
||||
y -= 17*FINECOSINE(rotate>>ANGLETOFINESHIFT);
|
||||
splitflags |= (((leveltime % 3 == 0) && (stplyr->cmd.flags & TICCMD_EXCESSTILT)) ? V_ADD|V_20TRANS : 0);
|
||||
|
||||
if (!K_GetHudColor())
|
||||
{
|
||||
V_DrawFixedPatch(x-(2*FRACUNIT)-(FRACUNIT/2), y-(23*FRACUNIT), FRACUNIT, splitflags, kp_minimapdot, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
colormap = R_GetTranslationColormap(0, K_GetHudColor(), GTC_CACHE);
|
||||
V_DrawFixedPatch(x-(2*FRACUNIT)-(FRACUNIT/2), y-(23*FRACUNIT), FRACUNIT, splitflags, kp_minimapdot, colormap);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1813,7 +1813,7 @@ void K_KartMoveAnimation(player_t *player)
|
|||
const boolean lookback = ((buttons & BT_LOOKBACK) == BT_LOOKBACK);
|
||||
const boolean skincompat = wadfiles[((skin_t *)player->mo->skin)->wadnum]->compatmode;
|
||||
|
||||
SINT8 turndir = intsign(player->cmd.turning);
|
||||
SINT8 turndir = 0;
|
||||
SINT8 destGlanceDir = 0;
|
||||
SINT8 drift = player->drift;
|
||||
UINT8 spr2, glanceofs;
|
||||
|
|
@ -1823,6 +1823,11 @@ void K_KartMoveAnimation(player_t *player)
|
|||
|
||||
if (!lookback)
|
||||
player->pflags &= ~PF_GAINAX;
|
||||
|
||||
if (drift || (abs(player->cmd.turning) > (10*KART_FULLTURN/100)))
|
||||
{
|
||||
turndir = intsign(player->cmd.turning);
|
||||
}
|
||||
|
||||
// Sliptides: drift -> lookback frames
|
||||
if (abs(player->aizdriftturn) >= ANGLE_90 && !skincompat)
|
||||
|
|
|
|||
|
|
@ -2678,6 +2678,8 @@ enum ticcmd_e
|
|||
ticcmd_buttons,
|
||||
ticcmd_latency,
|
||||
ticcmd_flags,
|
||||
ticcmd_tilt,
|
||||
ticcmd_shake,
|
||||
};
|
||||
|
||||
static const char *const ticcmd_opt[] = {
|
||||
|
|
@ -2692,6 +2694,8 @@ static const char *const ticcmd_opt[] = {
|
|||
"buttons",
|
||||
"latency",
|
||||
"flags",
|
||||
"tilt",
|
||||
"shake",
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
|
@ -2736,6 +2740,12 @@ static int ticcmd_get(lua_State *L)
|
|||
case ticcmd_flags:
|
||||
lua_pushinteger(L, cmd->flags);
|
||||
break;
|
||||
case ticcmd_tilt:
|
||||
lua_pushinteger(L, cmd->tilt);
|
||||
break;
|
||||
case ticcmd_shake:
|
||||
lua_pushinteger(L, cmd->shake);
|
||||
break;
|
||||
default:
|
||||
return NOFIELD;
|
||||
}
|
||||
|
|
@ -2782,6 +2792,10 @@ static int ticcmd_set(lua_State *L)
|
|||
return NOSET;
|
||||
case ticcmd_flags:
|
||||
return NOSET;
|
||||
case ticcmd_tilt:
|
||||
cmd->tilt = (SINT8)luaL_checkinteger(L, 3);
|
||||
case ticcmd_shake:
|
||||
cmd->shake = (UINT8)luaL_checkinteger(L, 3);
|
||||
default:
|
||||
return NOFIELD;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -723,6 +723,11 @@ struct debugFlagNames_s const debug_flag_names[] =
|
|||
{"Player", DBG_PLAYER},
|
||||
{"Render", DBG_RENDER},
|
||||
{"Renderer", DBG_RENDER}, // alt name
|
||||
{"Music", DBG_MUSIC},
|
||||
{"IMU", DBG_IMU},
|
||||
{"Accelerometer", DBG_IMU}, // alt name
|
||||
{"Gyro", DBG_IMU}, // alt name
|
||||
{"Sensors", DBG_IMU}, // alt name
|
||||
{"Polyobj", DBG_POLYOBJ},
|
||||
{"GameLogic", DBG_GAMELOGIC},
|
||||
{"Game", DBG_GAMELOGIC}, // alt name
|
||||
|
|
|
|||
|
|
@ -8592,6 +8592,7 @@ INT32 MR_SetupControlsMenu(INT32 arg)
|
|||
M_SetItemCvar(MN_OP_CHANGECONTROLS, "LEDCOLOR", &cv_controllerled[arg]);
|
||||
M_SetItemCvar(MN_OP_CHANGECONTROLS, "RUMBLE", &cv_controllerrumble[arg]);
|
||||
M_SetItemCvar(MN_OP_CHANGECONTROLS, "RUMBLESTR", &cv_rumblestrength[arg]);
|
||||
M_SetItemCvar(MN_OP_CHANGECONTROLS, "TILTCONTROL", &cv_tiltcontrol[arg]);
|
||||
|
||||
M_SetItemVisible(MN_OP_CHANGECONTROLS, "TALK", player1); // Chat
|
||||
//M_SetItemVisible(MN_OP_CHANGECONTROLS, "TEAM", player1); // Team-chat
|
||||
|
|
|
|||
18
src/p_mobj.c
18
src/p_mobj.c
|
|
@ -10000,6 +10000,24 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
mobj->lastlook = player->cmd.turning;
|
||||
}
|
||||
|
||||
if (player->cmd.shake > GAMEPADSHAKETHRESHOLD)
|
||||
{
|
||||
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
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ void I_ShutdownController(UINT8 index)
|
|||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
event.data1 = 0;
|
||||
event.data2 = 0;
|
||||
event.data2 = FLOAT_TO_FIXED(9.80665f);
|
||||
event.data3 = 0;
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
|
|
@ -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)
|
||||
{
|
||||
|
|
@ -250,6 +254,18 @@ void I_InitController(UINT8 playernum)
|
|||
controller->flipbuttons = SDL_GetGamepadButtonLabel(newcontroller, SDL_GAMEPAD_BUTTON_SOUTH) == SDL_GAMEPAD_BUTTON_LABEL_B;
|
||||
controller->flipgc = SDL_GetGamepadButtonLabel(newcontroller, SDL_GAMEPAD_BUTTON_WEST) == SDL_GAMEPAD_BUTTON_LABEL_B
|
||||
&& SDL_GetGamepadButtonLabel(newcontroller, SDL_GAMEPAD_BUTTON_EAST) == SDL_GAMEPAD_BUTTON_LABEL_X;
|
||||
|
||||
if (controller->hasaccelerometer)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "Enabling accelerometer for controller %d\n", joystick_id);
|
||||
SDL_SetGamepadSensorEnabled(controller->dev, SDL_SENSOR_ACCEL, true);
|
||||
}
|
||||
|
||||
if (controller->hasgyro)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "Enabling gyro for controller %d\n", joystick_id);
|
||||
SDL_SetGamepadSensorEnabled(controller->dev, SDL_SENSOR_GYRO, true);
|
||||
}
|
||||
}
|
||||
|
||||
void I_InitController1(void)
|
||||
|
|
|
|||
|
|
@ -1055,23 +1055,27 @@ static void Impl_HandleControllerSensorEvent(SDL_GamepadSensorEvent evt)
|
|||
// data[0]: x acceleration in m/s
|
||||
// data[1]: y acceleration in m/s
|
||||
// data[2]: z acceleration in m/s
|
||||
// we convert to gs before passing it to the event
|
||||
case SDL_SENSOR_ACCEL:
|
||||
// CONS_Debug(DBG_IMU, "Got Accelerometer event %4.2f %4.2f %4.2f\n", evt.data[0]/SDL_STANDARD_GRAVITY, evt.data[1]/SDL_STANDARD_GRAVITY, evt.data[2]/SDL_STANDARD_GRAVITY);
|
||||
event.type = ev_accelerometer;
|
||||
event.data1 = FLOAT_TO_FIXED(evt.data[0]);
|
||||
event.data2 = FLOAT_TO_FIXED(evt.data[1]);
|
||||
event.data3 = FLOAT_TO_FIXED(evt.data[2]);
|
||||
event.data1 = FLOAT_TO_FIXED(evt.data[0] / SDL_STANDARD_GRAVITY);
|
||||
event.data2 = FLOAT_TO_FIXED(evt.data[1] / SDL_STANDARD_GRAVITY);
|
||||
event.data3 = FLOAT_TO_FIXED(evt.data[2] / SDL_STANDARD_GRAVITY);
|
||||
D_PostEvent(&event);
|
||||
return;
|
||||
|
||||
// data[0]: delta pitch in rad/s
|
||||
// data[1]: delta yaw in rad/s
|
||||
// data[2]: delta roll in rad/s
|
||||
// we convert to degrees per second before passing it to the event
|
||||
case SDL_SENSOR_GYRO:
|
||||
#define RAD2DEG 57.295779513f
|
||||
#define RAD2DEG -57.295779513f
|
||||
// CONS_Debug(DBG_IMU, "Got Gyro event %4.2f %4.2f %4.2f\n", RAD2DEG * evt.data[0], RAD2DEG * evt.data[1], RAD2DEG * evt.data[2]);
|
||||
event.type = ev_gyroscope;
|
||||
event.data1 = FixedAngle(FLOAT_TO_FIXED(RAD2DEG * evt.data[0]));
|
||||
event.data2 = FixedAngle(FLOAT_TO_FIXED(RAD2DEG * evt.data[1]));
|
||||
event.data3 = FixedAngle(FLOAT_TO_FIXED(RAD2DEG * evt.data[2]));
|
||||
event.data1 = FLOAT_TO_FIXED(RAD2DEG * evt.data[0]);
|
||||
event.data2 = FLOAT_TO_FIXED(RAD2DEG * evt.data[1]);
|
||||
event.data3 = FLOAT_TO_FIXED(RAD2DEG * evt.data[2]);
|
||||
#undef RAD2DEG
|
||||
D_PostEvent(&event);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -474,6 +474,32 @@ static void ST_drawMusicDebug(INT32 *height)
|
|||
ST_pushDebugString(height, va(" Song: %8s", mname));
|
||||
}
|
||||
|
||||
static INT32 ST_getFixedFrac(fixed_t val)
|
||||
{
|
||||
return ((abs(val) * 100)>>FRACBITS) % 100;
|
||||
}
|
||||
|
||||
static void ST_drawImuDebug(INT32 *height)
|
||||
{
|
||||
INT32 pnum = stplyrnum;
|
||||
vector3_t accel, gyro, grav, shake;
|
||||
if (demo.playback || (!P_IsMachineLocalPlayer(stplyr)))
|
||||
{
|
||||
ST_pushDebugString(height, va("Only for local player!!"));
|
||||
return;
|
||||
}
|
||||
|
||||
accel = G_PlayerInputSensor(pnum, ACCELEROMETER);
|
||||
gyro = G_PlayerInputSensor(pnum, GYROSCOPE);
|
||||
grav = G_GetGamepadGravity(pnum);
|
||||
shake = G_GetGamepadShake(pnum);
|
||||
|
||||
ST_pushDebugString(height, va(" Gyro :%4.2f, %4.2f,%4.2f", FixedToFloat(gyro.x), FixedToFloat(gyro.y), FixedToFloat(gyro.z)));
|
||||
ST_pushDebugString(height, va("Accel :%4.2f, %4.2f,%4.2f", FixedToFloat(accel.x), FixedToFloat(accel.y), FixedToFloat(accel.z)));
|
||||
ST_pushDebugString(height, va("Shake :%4.2f, %4.2f,%4.2f", FixedToFloat(shake.x), FixedToFloat(shake.y), FixedToFloat(shake.z)));
|
||||
ST_pushDebugString(height, va(" Grav :%4.2f, %4.2f,%4.2f", FixedToFloat(grav.x), FixedToFloat(grav.y), FixedToFloat(grav.z)));
|
||||
}
|
||||
|
||||
static void ST_drawRenderDebug(INT32 *height)
|
||||
{
|
||||
const struct RenderStats *i = &g_renderstats;
|
||||
|
|
@ -569,6 +595,11 @@ static void ST_drawDebugInfo(void)
|
|||
height -= 32;
|
||||
}
|
||||
|
||||
if (cht_debug & DBG_IMU)
|
||||
{
|
||||
ST_drawImuDebug(&height);
|
||||
}
|
||||
|
||||
if (cht_debug & DBG_MUSIC)
|
||||
{
|
||||
ST_drawMusicDebug(&height);
|
||||
|
|
|
|||
Loading…
Reference in a new issue