diff --git a/src/doomdef.h b/src/doomdef.h index 714f743df..ff98a7d6a 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -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, diff --git a/src/g_game.c b/src/g_game.c index e20c5ba00..4484dbd07 100644 --- a/src/g_game.c +++ b/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" @@ -1334,12 +1335,14 @@ vector3_t G_PlayerInputSensor(UINT8 p, motionsensortype_e sensor) 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; } @@ -1417,20 +1420,61 @@ static void G_HandleAxisDeadZone(UINT8 splitnum, joystickvector2_t *joystickvect } } -// copy/pasted from the lua version of this routine -inline static vector4_t AngleAxis(angle_t angle, vector3_t *axis) +// copy/pasted from the lua version of these routines +static vector4_t *QuaternionMul(vector4_t *out, vector4_t *a, vector4_t *b) { - fixed_t cosangle = FINECOSINE(((angle / 2) >> ANGLETOFINESHIFT) & FINEMASK); - fixed_t sinangle = FINESINE(((angle / 2) >> ANGLETOFINESHIFT) & FINEMASK); - vector4_t result; - vector3_t normaxis; + 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; - FV3_NormalizeEx(axis, &normaxis); + 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) +{ + 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; +} + +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); + fixed_t cosangle = FINECOSINE(FixedAngle(angle/2) >> ANGLETOFINESHIFT); + vector3_t axis = {x, y, z}; + vector4_t result; + + FV3_Normalize(&axis); FV4_Load(&result, - FixedMul(normaxis.x, sinangle), - FixedMul(normaxis.y, sinangle), - FixedMul(normaxis.z, sinangle), + FixedMul(axis.x, sinangle), + FixedMul(axis.y, sinangle), + FixedMul(axis.z, sinangle), cosangle ); @@ -1439,32 +1483,177 @@ inline static vector4_t AngleAxis(angle_t angle, vector3_t *axis) // math sourced from this article // http://gyrowiki.jibbsmart.com/blog:finding-gravity-with-sensor-fusion +#define Interpolator (FRACUNIT/4) +// thresholds of trust for accel shakiness. less shakiness = more trust +#define ShakinessMaxThreshold (4*FRACUNIT/10) +#define ShakinessMinThreshold (FRACUNIT/10) +// 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/10) +// 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/10) +// thresholds for what's considered "close enough" +#define CorrectionGyroMinThreshold (5*FRACUNIT/100) +#define CorrectionGyroMaxThreshold (FRACUNIT/4) +// no matter what, always apply a minimum of this much correction to our gravity vector +#define CorrectionMinimumSpeed (FRACUNIT/10) + +// state +fixed_t localshakinessfac[MAXSPLITSCREENPLAYERS]; +vector3_t localsmoothedaccel[MAXSPLITSCREENPLAYERS]; vector3_t localgravityvectors[MAXSPLITSCREENPLAYERS]; -vector3_t G_UpdateGamepadGravity(INT32 p, vector3_t gyro, vector3_t accel) +void G_UpdateGamepadGravity(INT32 p, vector3_t gyro, vector3_t accel) { - const vector3_t invGyro = {-gyro.x, -gyro.y, -gyro.z}; - const vector3_t newGravity = {-accel.x, -accel.y, -accel.z}; - const vector4_t invRotation = AngleAxis(FixedMul(FV3_Magnitude(&gyro), FRACUNIT/TICRATE), &invGyro); - const fixed_t correctionRate = FRACUNIT/8; - vector3_t gravityDelta; - - FV3_Mul(&localgravityvectors[p], &invRotation); - FV3_SubEx(&gravityDelta, &newGravity, &localgravityvectors[p]); - FV3_Load(&localgravityvectors[p], - FixedMul(gravityDelta.x, correctionRate), - FixedMul(gravityDelta.y, correctionRate), - FixedMul(gravityDelta.z, correctionRate) + // convert gyro input to reverse rotation + const vector3_t invAccel = {-accel.x, -accel.y, -accel.z}; + fixed_t correctionRate = CorrectionMinimumSpeed; + fixed_t correctionMagnitude, gravityDeltaMagnitude, angleRate, correctionLimit; + vector4_t invRotation = AngleAxis( + -gyro.x, + -gyro.y, + -gyro.z, + FixedMul(FV3_Magnitude(&gyro), FRACUNIT/TICRATE) ); + vector3_t gravityDelta = {0}; + vector3_t gravityDeltaDirection = {0}; + vector3_t fv3_temp = {0}; + + // rotate gravity vector + QuaternionMulVec3(&localgravityvectors[p], &localgravityvectors[p], &invRotation); + QuaternionMulVec3(&localsmoothedaccel[p], &localsmoothedaccel[p], &invRotation); + FV3_SubEx(&accel, &localsmoothedaccel[p], &fv3_temp); + localshakinessfac[p] = max( + FixedMul(localshakinessfac[p], Interpolator), + FV3_Magnitude(&fv3_temp) + ); + FV3_Load(&localsmoothedaccel[p], + Easing_Linear(Interpolator, accel.x, localsmoothedaccel[p].x), + Easing_Linear(Interpolator, accel.y, localsmoothedaccel[p].y), + Easing_Linear(Interpolator, accel.z, localsmoothedaccel[p].z) + ); + + FV3_SubEx(&invAccel, &localgravityvectors[p], &gravityDelta); + FV3_NormalizeEx(&gravityDelta, &gravityDeltaDirection); + + if (ShakinessMaxThreshold > ShakinessMinThreshold) + { + fixed_t stillness = CLAMP(FixedDiv((localshakinessfac[p] - ShakinessMinThreshold), (ShakinessMaxThreshold - ShakinessMinThreshold)), 0, FRACUNIT); + correctionRate = CorrectionStillRate + FixedMul(stillness, (CorrectionShakyRate - CorrectionStillRate)); + } + else if (localshakinessfac[p] > ShakinessMaxThreshold) + { + correctionRate = CorrectionShakyRate; + } + else + { + correctionRate = CorrectionStillRate; + } + + // limit in proportion to rotation rate + angleRate = FixedMul(FV3_Magnitude(&gyro), M_PI_FIXED)/180; + correctionLimit = FixedMul(FixedMul(angleRate, FV3_Magnitude(&localgravityvectors[p])), CorrectionGyroFactor); + if (correctionRate > correctionLimit) { + fixed_t closeEnoughFactor; + if (CorrectionGyroMaxThreshold > CorrectionGyroMinThreshold) + { + closeEnoughFactor = CLAMP(FixedDiv((FV3_Magnitude(&gravityDelta) - CorrectionGyroMinThreshold), (CorrectionGyroMaxThreshold - CorrectionGyroMinThreshold)), 0, FRACUNIT); + } + else if (FV3_Magnitude(&gravityDelta) > CorrectionGyroMaxThreshold) + { + closeEnoughFactor = FRACUNIT; + } + else + { + closeEnoughFactor = 0; + } + correctionRate = correctionRate + FixedMul((correctionLimit - correctionRate), closeEnoughFactor); + } + + // finally, let's always allow a little bit of correction + correctionRate = max(correctionRate, CorrectionMinimumSpeed); + + FV3_Load(&gravityDeltaDirection, + FixedMul(FixedMul(correctionRate, FRACUNIT/TICRATE), gravityDeltaDirection.x), + FixedMul(FixedMul(correctionRate, FRACUNIT/TICRATE), gravityDeltaDirection.y), + FixedMul(FixedMul(correctionRate, FRACUNIT/TICRATE), gravityDeltaDirection.z) + ); + + correctionMagnitude = FV3_Magnitude(&gravityDeltaDirection); + gravityDeltaMagnitude = FV3_Magnitude(&gravityDelta); + if (FixedMul(correctionMagnitude, correctionMagnitude) > FixedMul(gravityDeltaMagnitude, gravityDeltaMagnitude)) + { + FV3_Add(&localgravityvectors[p], &gravityDeltaDirection); + } + else + { + FV3_Add(&localgravityvectors[p], &gravityDelta); + } +} + +#define TILTRANGE 35*FRACUNIT +fixed_t G_GetGamepadTilt(INT32 p) +{ + fixed_t tilt; + fixed_t axis; + if (p >= MAXSPLITSCREENPLAYERS) + { +#ifdef PARANOIA + CONS_Debug(DBG_GAMELOGIC, "G_PlayerInputAnalog: Invalid player ID %d\n", p); +#endif + return 0; + } + + tilt = CLAMP(G_GetGamepadGravity(p).x, -TILTRANGE, TILTRANGE); + //TODO: this is really dumb, pinch towards 0 and towards the farthest we can tilt comfortably + axis = Easing_Linear(FixedDiv(tilt + TILTRANGE, (2*TILTRANGE)), -32768, 32767); + return axis; +} +#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; + } return localgravityvectors[p]; } -vector3_t G_GetGamepadTilt(INT32 p, vector3_t gravity) +vector3_t G_GetGamepadShake(INT32 p) { - vector3_t out; - return out; + const vector3_t zero = {0}; + vector3_t accel; + + if (p >= MAXSPLITSCREENPLAYERS) + { +#ifdef PARANOIA + CONS_Debug(DBG_GAMELOGIC, "G_PlayerInputAnalog: Invalid player ID %d\n", p); +#endif + return zero; + } + + accel = G_PlayerInputSensor(p, ACCELEROMETER); + FV3_Add(&accel, &localgravityvectors[p]); + return accel; } +#undef Interpolator +#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 @@ -1501,8 +1690,6 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) INT32 forward, side, tspeed; joystickvector2_t joystickvector; - - vector3_t gravity = {0}; INT16 accelerometertilt; // you'd BETTER not touch the player while freecamming... @@ -1528,19 +1715,13 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) break; } - if (K_PlayerUsesBotMovement(player)) - { - // Bot ticcmd is generated by K_BuildBotTiccmd - return; - } - // 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 { vector3_t accel = G_PlayerInputSensor(forplayer, ACCELEROMETER); vector3_t gyro = G_PlayerInputSensor(forplayer, GYROSCOPE); - gravity = G_UpdateGamepadGravity(forplayer, gyro, accel); + G_UpdateGamepadGravity(forplayer, gyro, accel); } // why build a ticcmd if we're paused? @@ -1550,6 +1731,12 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) return; } + if (K_PlayerUsesBotMovement(player)) + { + // Bot ticcmd is generated by K_BuildBotTiccmd + return; + } + joystickvector.xaxis = G_PlayerInputAnalog(forplayer, gc_turnright, false, DEADZONE_X) - G_PlayerInputAnalog(forplayer, gc_turnleft, false, DEADZONE_X); joystickvector.yaxis = 0; G_HandleAxisDeadZone(forplayer, &joystickvector); @@ -1557,10 +1744,11 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) if (joystickvector.xaxis != 0) { joystickactive[forplayer] = true; + accelerometertilt = 0; } else if (!joystickactive[forplayer]) { - + accelerometertilt = G_GetGamepadTilt(forplayer); } // For kart, I've turned the aim axis into a digital axis because we only @@ -1576,7 +1764,14 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) } forward = side = 0; - tspeed = joystickvector.xaxis; + if (joystickactive[forplayer]) + { + tspeed = joystickvector.xaxis; + } + else + { + tspeed = accelerometertilt; + } // use two stage accelerative turning // on the keyboard and (NOT!) joystick @@ -1609,6 +1804,12 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) cmd->angle -= (tspeed * KART_FULLTURN) / JOYAXISRANGE; side += (joystickvector.xaxis * 4) / JOYAXISRANGE; } + else if (accelerometertilt != 0) + { + cmd->turning -= (tspeed * KART_FULLTURN) / JOYAXISRANGE; + cmd->angle -= (tspeed * KART_FULLTURN) / JOYAXISRANGE; + side += (accelerometertilt * 4) / JOYAXISRANGE; + } // Specator mouse turning if (spectating) diff --git a/src/g_game.h b/src/g_game.h index 8ef08e215..bddde7852 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -143,8 +143,11 @@ typedef enum #define MAXGAMEPADTILT (ANG30) #define ACCEL_GRAVITY (FLOAT_TO_FIXED(9.80665f)) -vector3_t G_UpdateGamepadGravity(INT32 p, vector3_t gyro, vector3_t accel); -vector3_t G_GetGamepadTilt(INT32 p, vector3_t gravity); +void G_UpdateGamepadGravity(INT32 p, vector3_t gyro, vector3_t accel); +vector3_t G_GetGamepadGravity(INT32 p); +vector3_t G_GetGamepadShake(INT32 p); +fixed_t G_GetGamepadTilt(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); diff --git a/src/g_input.c b/src/g_input.c index 805417e52..8ed61c255 100644 --- a/src/g_input.c +++ b/src/g_input.c @@ -491,19 +491,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] = diff --git a/src/g_input.h b/src/g_input.h index e34e1c251..02bd76b7e 100644 --- a/src/g_input.h +++ b/src/g_input.h @@ -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, diff --git a/src/m_cheat.c b/src/m_cheat.c index 308356218..c22dac95e 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -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 diff --git a/src/sdl/i_gamepad.c b/src/sdl/i_gamepad.c index cad61b0ee..b2b43b472 100644 --- a/src/sdl/i_gamepad.c +++ b/src/sdl/i_gamepad.c @@ -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); } @@ -250,6 +250,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) diff --git a/src/sdl/i_video.cpp b/src/sdl/i_video.cpp index bf089779e..5ce00126b 100644 --- a/src/sdl/i_video.cpp +++ b/src/sdl/i_video.cpp @@ -1057,6 +1057,7 @@ static void Impl_HandleControllerSensorEvent(SDL_GamepadSensorEvent evt) // 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] / SDL_STANDARD_GRAVITY); event.data2 = FLOAT_TO_FIXED(evt.data[1] / SDL_STANDARD_GRAVITY); @@ -1070,10 +1071,11 @@ static void Impl_HandleControllerSensorEvent(SDL_GamepadSensorEvent evt) // we convert to degrees per second before passing it to the event case SDL_SENSOR_GYRO: #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; diff --git a/src/st_stuff.c b/src/st_stuff.c index feb3b859e..eda5e70c5 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -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);