Gyro Mouse Inputs - AL2009man/JoyShockMapper GitHub Wiki

The first thing you need to know about gyro mouse inputs is that a controller's gyro will often need calibrating. This just means telling the application where "zero" is. Just like a scale, the gyro needs a point of reference to compare against in order to accurately give a result. This is done by leaving the controller still, or holding it very still in your hands, and finding the average velocity over a short time of staying still. It needs to be averaged over some time because the gyro will pick up a little bit of "noise" -- tiny variations that aren't caused by any real movement -- but this noise is negligible compared to the shakiness of human hands trying to hold a controller still.

If you have gyro mouse enabled and the gyro moves across the screen (even slowly) when the controller is lying still on a solid surface, your device needs calibrating. That's okay -- I do it at the beginning of most play sessions, especially with Nintendo devices, which seem to need it more often.

If you set AUTO_CALIBRATE_GYRO to ON, JoyShockMapper will try to detect when your controller is being held still or left on a steady surface and calibrate the gyro automatically. This is imperfect, though -- every automatic calibration solution will sometimes interpret slow and steady movement as the controller being held still. This can interrupt you making small adjustments to your aim or tracking slow/distant targets. It's also only a new feature, and we try not to change default behaviour. Also, it doesn't yet give you any settings to tweak its thresholds. For all of these reasons this setting is OFF by default, and it's recommended that you calibrate your gyro manually instead.

To manually calibrate your gyro, place your controller on steady surface so that it's not moving at all, and then use the following commands:

  • RESTART_GYRO_CALIBRATION - All connected gyro devices will begin collecting gyro data, remembering the average collected so far and treating it as "zero".
  • FINISH_GYRO_CALIBRATION - Stop collecting gyro data for calibration. JoyShockMapper will use whatever it has already collected from that controller as the "zero" reference point for input from that controller.

It should only take a second or so to get a good calibration for your devices. You can also calibrate each controller separately with buttons mapped to CALIBRATE. This is how you using them assuming you use the built-in mappings:

  • Tap the PS, Touchpad-click, Home, or Capture button on your controller to restart calibration, or to finish calibration if that controller is already calibrating.
  • Hold the PS, Touchpad-click, Home, or Capture button to restart calibration, and it'll finish calibration once you release the controller. Warning: I've found that touching the Home button interferes with the gyro input on one of my JoyCons, so if I hold the button to calibrate it, it'll be incorrectly calibrated when I release the button. If you encounter this, it's better to rely on the tapping toggle shortcuts above for each controller, or calibrate all controllers at the same time using the commands above.

The reason gyros need calibrating is that their physical properties (such as temperature) can affect their sense of "zero". Calibrating at the beginning of a play session will usually be enough for the rest of the play session, but it's possible that after the controller warms up it could use calibrating again. You'll be able to tell it needs calibrating if it appears that the gyro's "zero" is incorrect -- when the controller isn't moving, the mouse moves steadily in one direction anyway.

The second thing you need to know about gyro mouse inputs is how to choose the sensitivity of the gyro inputs:

  • GYRO_SENS (default 0.0) - How does turning the controller turn the in-game camera? A value of 1 means turning the controller will turn the in-game camera the same angle (within the limits of two axes). A value of 2 means turning the controller will turn double the angle in-game. Increasing the GYRO_SENS gives you more freedom to move around before turning uncomfortably and having to disable the gyro and reposition the controller, but decreasing it will give you more stability to hit small targets.
    For games where you don't turn the camera directly, but instead use the mouse to control an on-screen cursor, a GYRO_SENS of 1 would mean the controller needs to turn around completely to get from one side of the screen to the other. For games like these, you'll be better off with a GYRO_SENS of 8 or more, meaning you only need to turn the controller 360/8 = 45 degrees to move from one side of the screen to the other.

A single GYRO_SENS setting may not be enough to get both the precision you need for small targets and the range you need to comfortably navigate the game without regularly having to disable the gyro and reposition the controller.

JoyShockMapper allows you to say, "When turning slowly, I want this sensitivity. When turning quickly, I want that sensitivity." You can do this by setting two real life speed thresholds and a sensitivity for each of those thresholds. Everything in-between will be linearly interpolated. To do this, use MIN_GYRO_THRESHOLD, MAX_GYRO_THRESHOLD, MIN_GYRO_SENS, and MAX_GYRO_SENS:

  • MIN_GYRO_THRESHOLD and MAX_GYRO_THRESHOLD (default 0.0 degrees per second); MIN_GYRO_SENS and MAX_GYRO_SENS (default 0.0) - MIN_GYRO_SENS and MAX_GYRO_SENS work just like GYRO_SENS, but MIN_GYRO_SENS applies when the controller is turning at or below the speed defined by MIN_GYRO_THRESHOLD, and MAX_GYRO_SENS applies when the controller is turning at or above the speed defined by MAX_GYRO_THRESHOLD. When the controller is turning at a speed between those two thresholds, the gyro sensitivity is interpolated accordingly. The thresholds are in real life degrees per second. For example, if you think about how fast you need to turn the controller for it to turn a quarter circle in one second, that's 90 degrees per second. Setting GYRO_SENS overrides MIN_GYRO_SENS and MAX_GYRO_SENS to be the same value. You can set a different vertical sensitivity by giving two values to the command separated by a space, instead of just one.

Finally, there are a bunch more settings you can tweak if you so desire:

  • GYRO_SPACE (default LOCAL) - Simple gyro aiming solutions will map one of your controller's gyro axes to your camera/cursor's horizontal axis and one to the vertical axis. That's the behaviour you'll get with JoyShockMapper when GYRO_SPACE is set to "LOCAL". This is simple to implement and leaves no room for misinterpretation, but aiming can feel off as you tilt your controller more and more. If you'd prefer a more advanced reading of the gyro combined with the accelerometer to more naturally handle different controller positions, PLAYER_TURN is the way to go. Or, if you prefer to lean your controller side to side to turn your camera, try PLAYER_LEAN. Finally, WORLD_TURN and WORLD_LEAN account for gravity more strictly than the PLAYER_* options.
  • GYRO_AXIS_X and GYRO_AXIS_Y (default STANDARD) - This allows you to invert the gyro directions if you wish. Want a left- gyro turn to translate to a right- in-game turn? Set GYRO_AXIS_X to INVERTED. For normal behaviour, set it to STANDARD.
  • MOUSE_X_FROM_GYRO_AXIS and MOUSE_Y_FROM_GYRO_AXIS (default Y and X, respectively) - Maybe you want to turn the camera left and right by rolling your controller about its local Z axis instead of turning it about its local Y axis. Or maybe you want to play with a single JoyCon sideways. This is how you do that. Your options are X, Y, Z, and NONE, if you want an axis of mouse movement unaffected by the gyro. These settings only apply when GYRO_SPACE is set to LOCAL.
  • GYRO_CUTOFF_SPEED (default 0.0 degrees per second) - Some games attempt to cover up small unintentional movements by setting a minimum speed below which gyro input will be ignored. This is that setting. It's never good. Don't use it. Some games won't even let you change or disable this "feature". I implemented it to see if it could be made good. I left it in there only so you can see for yourself that it's not good, or for you to perhaps show me how it can be.
    It might be mostly harmless for interacting with a simple UI with big-ish buttons, but it's useless if the player will ever intentionally turn the controller slowly (such as to track a slow-moving target), because they may unintentionally fall below the cutoff speed. Even a very small cutoff speed might be so high that it's impossible to move the aimer at the same speed as a very slow-moving target.
    One might argue that such a cutoff is too high, and it just needs to be set lower. But if the cutoff speed is small enough that it doesn't make the player's experience worse, it's probably also small enough that it's actually not doing anything.
  • GYRO_CUTOFF_RECOVERY (default 0.0 degrees per second) - In order to avoid the problem that GYRO_CUTOFF_SPEED makes it impossible to move the cursor at the same speed as a very slow-moving target, JoyShockMapper smooths over the transition between the cutoff speed and a threshold determined by GYRO_CUTOFF_RECOVERY. Originally intended to make GYRO_CUTOFF_SPEED not awful, it ends up doing a good job of reducing shakiness even when GYRO_CUTOFF_SPEED is set to 0.0, but I only use it (possibly in combination with smoothing, below) as a last resort.
  • GYRO_SMOOTH_THRESHOLD (default 0.0 degrees per second) - Optionally, JoyShockMapper will apply smoothing to the gyro input to cover up shaky hands at high sensitivities. The problem with smoothing is that it unavoidably introduces latency, so a game should never have any smoothing apply to any input faster than a very small threshold. Any gyro movement at or above this threshold will not be smoothed. Anything below this threshold will be smoothed according to the GYRO_SMOOTH_TIME setting, with a gradual transition from full smoothing at half GYRO_SMOOTH_THRESHOLD to no smoothing at GYRO_SMOOTH_THRESHOLD.
  • GYRO_SMOOTH_TIME (default 0.125s) - If any smoothing is applied to gyro input (as determined by GYRO_SMOOTH_THRESHOLD), GYRO_SMOOTH_TIME is the length of time over which it is smoothed. Larger values mean smoother movement, but also make it feel sluggish and unresponsive. Set the smooth time too small, and it won't actually cover up unintentional movements.