Posted by JibbSmartJibbSmart on 09 Mar 2019 08:59

JoyShockMapper (JSM) converts input from PlayStation 4 controllers (DualShock 4) and Switch controllers (JoyCons and Pro Controller) to keyboard and mouse inputs. If you prefer playing games with a controller, but the games you want to play don't have all the configuration options you want, this may help. If you want to explore flick stick and gyro as a mouse, JSM provides everything you need for the most intuitive and precise aiming and cursor control possible with a modern console controller.

The goal of this post is to help you get using JSM quickly, without having to know everything about how it works. If you're in a real hurry, here's the two minute version:

For a comprehensive list of all of JSM's features, check out its README.

This article is split up into four sections, starting with what everyone needs and ending with what only advanced users will need:

  1. Installing JSM
  2. Using an already-made configuration file
  3. Using calibration info from GyroWiki to make your own configuration file
  4. Calibrating JSM (and sharing on GyroWiki)

Every step will rely on the steps before it, but if all you want is to use an already-made configuration file (for example), you'll only need to follow a small portion of this How-to. You can find a bunch of already-made community configs in the GyroWiki games database.

A comprehensive explanation of all of JSM's features can be found in its README, but a new user will find that more useful after experimenting with JSM's features covered in the next few sections. Using an already-made config is easier than creating one from scratch and is a good way to get familiar with how JSM works. JSM comes with a simple config you can use for basic interaction with Windows and simple Windows applications (such as Minesweeper and Solitaire) called 'Windows.txt', and it'll be used as an example below.

Installing JSM

JoyShockMapper doesn't come with an installer. Just download the latest release from here, extract it to a folder, and run JoyShockMapper.exe. It should look something like this:

5WI5oF3.png

Notice it says "0 devices connected". I forgot to connect my controllers before starting the application. But I can fix that by plugging in my DualShock 4 or connecting my JoyCons or Pro Controller by Bluetooth, and then entering the command "RECONNECT_CONTROLLERS" like so:

wGbzKFK.png

One of the goals of JSM is to make configuration files shareable between different users on different systems, as well as between different games. By necessity, this requires some unique configuration on a per-game basis.

When your mouse sends a movement to the game, it can get changed in a bunch of ways:

  1. it may be modified by your mouse settings in Windows,
  2. it may be modified by your mouse settings in the game you're playing,
  3. it may be multiplied by another number to convert the movement into the appropriate angle or cursor movement.

If your mouse settings are relatively simple (you don't have "enhance pointer precision" enabled in Windows or mouse acceleration enabled in game), JSM can account for all three steps so that you can use the same settings between different users and games:

  1. if necessary, it can be told to detect and counter Windows' mouse settings,
  2. it can be given your in-game mouse settings and counter those,
  3. it uses a real-world calibration number to know how much to move the mouse to produce the desired in-game change.

Number 2 will likely be different from user to user. So if your configuration does anything with the mouse (whether with the sticks or the gyro), you should always set IN_GAME_SENS to your in-game mouse speed. If your game doesn't have that option, just set it to 1.

Numbers 1 and 3 vary depending on the game. For 1, some games ignore Windows' mouse settings (often called "raw input"), so JSM's command to detect and counter Windows' settings is optional. For number 3, it can be some work to actually figure out an appropriate REAL_WORLD_CALIBRATION value (explained below).

The games database is a growing collection of calibration settings for games so that you don't have to figure out those settings yourself. Many of those games have community configs — complete configurations that'll work right away once you've set your IN_GAME_SENS.

Using an already-made configuration file

JSM comes with a folder called 'GyroConfigs', which is where I like to keep config files for different games handy. Your folder should already contain a couple of files to help with calibrating (covered later), a couple of templates for creating new configs, and a file called 'Windows.txt'. Let's use it as an example of how to use someone else's config file, but you can always use configs you've found elsewhere, such as community configs in the games database.

Open the file in Notepad, and you should see something like this:

# Windows interaction using gyro
# Clear previous settings
RESET_MAPPINGS

# Calibration
REAL_WORLD_CALIBRATION = 5.3333
IN_GAME_SENS = 1
COUNTER_OS_MOUSE_SPEED

# Button mappings
GYRO_OFF = E
LLEFT = LEFT
LRIGHT = RIGHT
LUP = UP
LDOWN = DOWN
R = LMOUSE
L = RMOUSE
+ = ESC
ZL = LSHIFT
S = SPACE
N = ESC

# Include mouse settings
GyroConfigs/_2Dmouse.txt

Every line you see in this config file is a line you can manually enter into JSM to change your settings. But it'd be tedious to have to copy out every command each time you start JSM or change game, so you can group these commands into text files and load them in JSM.

But before we use Windows.txt for the first time, we must check a couple of things:

  1. Is "enhance pointer precision" disabled? "Enhance pointer precision" is an option in Windows' pointer speed settings that makes the mouse behave in ways that JSM can't account for. If you want to have the same experience as whoever created this config file, you should disable "enhance pointer precision".
  2. Has IN_GAME_SENS been set correctly? Every time you try a new config file, the very first thing you should do is change IN_GAME_SENS to match your in game mouse speed setting. This is how JSM accounts for different people having different game settings while still being able to have the same gyro- or stick- mouse for different users. Windows.txt sets it to 1, which is the default, and is actually what we want in this case, since Windows doesn't have a separate in-game mouse speed to account for, and your Windows pointer speed is already accounted for by the command COUNTER_OS_MOUSE_SPEED. In fact, Windows.txt doesn't actually need to set IN_GAME_SENS to 1 because RESET_MAPPINGS already did that. I've just put it in there as a reminder: always set IN_GAME_SENS to your in-game mouse speed.

Note: Sometimes games won't have a number next to their mouse speed setting. Sometimes the number can be found in a config file the game uses, but sometimes there's nothing that can be done, and users should just try to pick something appropriate (like using the game's default mouse speed and assuming it's '1').

Now that we've disabled "enhance pointer precision" and checked IN_GAME_SENS, let's load the config file into JSM: run JSM, then either drag the config file you want to use into JSM or just type in the path relative to the program's location (in this case, GyroConfigs/Windows.txt) before hitting Enter:

And that's all it takes! You should be able to move the mouse around just by moving the gyro or using the right stick.

If your configuration uses gyro for mouse, you may need to calibrate your gyro. If you put your controller down and the mouse is still moving across the screen, it's a good idea to calibrate your gyro — this just means telling the controller what "not moving" looks like.

One way to do this is to put your controller down on a steady surface, then tap the Calibrate button — this is the PS button, the Home button, or the Capture button, depending on what controller it is. If you're using a pair of JoyCons, the default behaviour is for the left gyro to be ignored, so unless you change this, don't bother with the left JoyCon.

When you tap the Calibrate button, JoyShockMapper will either say "Enabled continuous calibration" or "Disabled continuous calibration". If it says "Disabled", tap it again to enable continuous calibration. This just means it's gathering gyro data from the controller and finding the average. After a second or longer, tap the Calibrate button again so JoyShockMapper says "Disabled continuous calibration". This means it'll stop gathering gyro data for calibration, but it'll continue using the data it previously gathered. Once that's done, you should be all set:

A quicker way to do this can be to just press and hold the Calibrate button for a while and then release it (either on a steady surface or holding the controller very still). While holding the button it'll gather gyro data, accumulating an average. When released, it'll stop. However, pressing the Home or Capture button can interfere with the gyro on JoyCons, causing it to calibrate incorrectly, so I don't recommend using this method there.

Finally, to calibrate all connected controllers at the same time without having to touch any of the controllers, enter the command RESTART_GYRO_CALIBRATION to begin calibration, then enter FINISH_GYRO_CALIBRATION to finish calibration. Of course, leave the controllers still on a steady surface while doing this for best results.

As the gyro's temperature changes over time, it may need to be calibrated again, but depending on how high your sensitivity settings are, you shouldn't need to recalibrate very often. With the DualShock 4 I almost never have to calibrate it. With the Nintendo controllers I normally do it once at the beginning of a play session and maybe once again after I've warmed up a bit.

Using calibration info from GyroWiki to make your own configuration file

To explore what it takes to make your own config file using calibration info from GyroWiki, let's compare the GyroWiki page for Windows to the contents of Windows.txt. We won't look at every possible command. For a comprehensive list of all JSM commands and how to use them, check out the Commands section of the JoyShockMapper README.

As we go through Windows.txt it'll be helpful to have the Windows page open from the GyroWiki games database as we step through the related config file:

# Windows interaction using gyro

Any line entered into JSM that begins with '#' will be ignored. Such lines are referred to as "comments". Lines that aren't commands won't change any settings, but JSM will complain about them unless they begin with '#'. Or, even worse, if your comment is also a JSM command, it may be executed without you intending it. Therefore it's best to put '#' at the beginning of comments.

By the way, if you ever want to temporarily remove a command that you might want later, you can just put a '#' at the beginning of the command. That way, the text is still there for you to restore later, but it'll be ignored by JSM. In programming this is often called "commenting out a line".

# Clear previous settings
RESET_MAPPINGS

I like to use comments and empty lines to separate different related sections of configuration files. All my files begin with RESET_MAPPINGS, which is a JSM command to restore all default settings. This means unmapping all button inputs, for example. This means after this I only have to set the settings that matter for this game.

After this, the file is divided into 3 sections:

  1. Calibration - using the info from GyroWiki or calculated elsewhere to tell JSM how to translate actions into the appropriately sized mouse movement;
  2. Buttons - mapping buttons and sticks to different keys or mouse buttons;
  3. Mouse - mapping sticks and/or gyro to mouse movements.

Calibration

Let's look at the first section.

# Calibration
REAL_WORLD_CALIBRATION = 5.3333
IN_GAME_SENS = 1
COUNTER_OS_MOUSE_SPEED

This is where the GyroWiki game info comes into play. All GyroWiki game entries boil down to 3 pieces of info, apart from some optional notes. Here's the info from GyroWiki's entry for Windows:

  • Real World Calibration: 5.3333
  • Mouse Control Mode: Cursor
  • Raw Input: No

The page also has explanations of what you need to do in JSM to calibrate it correctly. See how they correspond to the commands in this section of Windows.txt? It says to set REAL_WORLD_CALIBRATION to 5.3333. This will be explained in detail in the calibration section later, for those interested, but for now just know that having the right REAL_WORLD_CALIBRATION setting makes it easier to keep all your other settings the same between different games.

It also says to use COUNTER_OS_MOUSE_SPEED. If the game in question uses raw input (that is, it isn't affected by Windows' mouse settings), you would have nothing in its place, since the default behaviour is to ignore Windows' mouse settings, and RESET_MAPPINGS (from earlier) already restored default behaviour.

Finally, the page reminds users to always set IN_GAME_SENS to your in game mouse speed setting, if there is one. If not, just set it to 1.

Button Mapping

Now to the buttons. Let's have a look at what Windows.txt has:

# Button mappings
GYRO_OFF = E
LLEFT = LEFT
LRIGHT = RIGHT
LUP = UP
LDOWN = DOWN
R = LMOUSE
L = RMOUSE
+ = ESC
ZL = LSHIFT
S = SPACE
N = ESC

This section is where we'll handle button inputs. This can include stick inputs if you want to use the stick that way, which we'll get to in just a bit. But first, GYRO_OFF is a special command here. Most of your inputs will be set up something like [controller input] = [keyboard or mouse input], and so each controller input has one function. Enabling or disabling gyro input is special and can overlap with other input (for example, you might enable gyro while pressing the same button you use to aim down sights).

The line GYRO_OFF = E means pressing the East face button disables the gyro. If instead you want the gyro to be enabled while pressing a button, use GYRO_ON instead. If you use GYRO_ON, the gyro will be disabled whenever that button is not pressed. This can be undone by setting GYRO_OFF again. If you want neither, but want the gyro to always be enabled, try GYRO_OFF = NONE.

The next four lines are for the left stick. They make pressing the left stick left, right, up, or down send a keyboard key press for the left, right, up, or down arrow, respectively. After that you can see mappings for clicking the mouse (left-click, right-click), escape, left shift, spacebar, and another button for escape. You can map any number of controller inputs to the same keyboard or mouse input.

The face button controller inputs are named after the directions on a compass, since the supported controllers don't all have the same button names. N, S, E, W for North, South, East, West, respectively. Most other buttons are named after Switch controllers, since a pair of JoyCons has more buttons than a DualShock 4. However, since the stick clicks only have short, well-known names on DualShock 4, they're L3 and R3 (for left click and right click, respectively).

Once calibrated, the same mouse settings can usually be used between games of similar genre. While you might want to refine these more later, this means that once you have your calibration settings correct, you can focus on figuring out a good button mapping for the game you're configuring. Feel free to make little changes at a time, testing them out to see if you like them, rather than trying to create the perfect config file in one go.

In Windows.txt I have the left stick mapped to the arrow keys on the keyboard. But many games use the WASD keys for character movement, so that's often a good place to start when creating your own config file:

LLEFT = A
LUP = W
LRIGHT = D
LDOWN = S

If you make these changes to Windows.txt and reload it, or put them directly into JSM, you can see this in action. Create a new file in Notepad and move the stick around, and you should see that it's responding as if those keys are being pressed:

It's up to you what inputs you map to what. These will usually change a lot between different games. Here are some considerations I normally have:

  • A lot of shooters have their primary and secondary fire mapped to ZR (R2) and ZL (L2), respectively, which will usually correspond to LMOUSE (left click) and RMOUSE (right click), respectively. But I prefer to use R (R1) and L (L1), because I find it easier to press them without accidentally moving the controller at the same time.
  • A lot of thought goes into designing good controller controls. If the game you're configuring is available on a console, look up those controls and use them as a starting point. Or, if the game on PC natively supports a controller, use those controls as a starting point. If neither of those is the case, perhaps there are similar games that you can draw inspiration from.
  • Because there are a lot more keys on a keyboard than buttons on a controller, many games that appear on both PC and consoles will combine multiple keyboard actions into fewer controller buttons. For example, you might tap the crouch button to crouch or hold it to go prone on the ground. JSM lets you map taps and holds to different inputs by putting two keyboard/mouse inputs (separated by a space) after the =. Eg: "UP = SCROLLUP Q" means tapping up on the d-pad will scroll the mouse wheel up, holding it will press and hold the Q key.
  • Prioritise core gameplay actions. Maybe it's not feasible to fit all the core gameplay as well as a help shortcut, chat key, show score key, and shortcuts for different emotes. That's okay. It's important that you can access your core gameplay actions easily.
  • Think about what combinations of actions you'll want to do at the same time. If you want to jump while aiming with the right stick, perhaps it's best your jump button is not mapped to a face button, as it's hard to press face buttons while using the right stick. How about ZL (L2) or ZR (R2) instead?
  • Practice. Many games have on-screen prompts telling you what key to press. The game doesn't know the configuration you've set up through JSM, so sometimes it might tell you to press F to perform a certain action and you'll forget what controller button you mapped to the F key. But with a little extra practice, these actions will become second nature to you.

Mouse Movement Mapping

Finally, let's look at how we've set up mouse controls in Windows.txt:

# Include mouse settings
GyroConfigs/_2Dmouse.txt

Remember how JSM accepts individual commands typed into the console or file names for files containing commands for it to use? Those files can also contain links to other files. This file name, though, must either be an absolute path, or a path relative to JoyShockMapper.exe. Because JoyShockMapper comes with a folder called GyroConfigs, it's a good place to put config files that you might reference from other config files.

Because most 2D games have the same needs and most 3D games have the same needs (2D meaning the mouse controls a cursor on a 2D plane; 3D meaning the mouse moves a camera in a 3D space), I like to simplify my configs by having most 2D games share the same mouse settings and most 3D games share the same mouse settings. JoyShockMapper includes examples called '_2Dmouse.txt' and '_3Dmouse.txt', which you can use however you like. So as I experiment with gyro controls and find that there are changes I want to make to how I play 2D games, I can make those changes in one place and enjoy them in every game that uses the same config file.

Let's look inside _2Dmouse.txt and see what's happening here:

# Gyro mouse setup
MIN_GYRO_SENS = 8
MAX_GYRO_SENS = 16
GYRO_CUTOFF_RECOVERY = 5
MIN_GYRO_THRESHOLD = 5
MAX_GYRO_THRESHOLD = 75
GYRO_SMOOTH_THRESHOLD = 5

# In case you want to use the right stick instead
RIGHT_STICK_MODE = AIM
STICK_SENS = 360
STICK_POWER = 1
STICK_ACCELERATION_RATE = 2
STICK_ACCELERATION_CAP = 4

There's a lot to unpack here. It's split into two sections: gyro and stick. Let's start with the gyro stuff at the top.

The first two lines are MIN_GYRO_SENS and MAX_GYRO_SENS, but the simplest way to set your gyro sensitivity is with GYRO_SENS, so I'll explain that first. GYRO_SENS is a multiplier to your gyro input when it's being converted to mouse input. This has different implications for 3D games and 2D games, both of which depend on REAL_WORLD_CALIBRATION and IN_GAME_SENS being set correctly:

  • 3D games: GYRO_SENS is a multiplier from real world rotation to in-game rotation. That means if you set GYRO_SENS to 1 and turn your controller 37° to the left, your in-game camera will turn 37° to the left. Set it to 2 and the same movement will turn your in-game camera 74° to the left. Simple, right? Any game that uses gyro aiming should use this scale.
  • 2D games: The reason 3D games don't all use the same sensitivity scale when converting from a 2D mouse movement to a 3D rotation is that there's no obvious conversion. The same applies when converting a 3D gyro rotation to a 2D mouse movement. By convention, JSM configs should be calibrated such that GYRO_SENS sets what fraction of a full turn the controller must make to move the mouse all the way from one side of the screen to the other, horizontally. For 2D games, this will often depend on screen resolution (it does with Windows, for example), so for consistency's sake, it's best to calculate it for a screen that's 1920 pixels wide. When you set GYRO_SENS to 8 for a 2D game, you're saying you want to be able to cover the whole screen within 1/8 of a full rotation (360° / 8 = 45°). If you set GYRO_SENS to 16, it'll take 1/16 of a full rotation (360° / 16 = 22.5°) to cover the whole screen.

By the way, if you're wondering how you choose between 2D game settings and 3D game settings, you don't. All you need to do is set the right REAL_WORLD_CALIBRATION for the game and it should work fine.

Just as with a regular mouse, choosing the right sensitivity is a balancing act between two goals that are at odds with each other. A high sensitivity (small movements translate to big movements) means that you can more easily make fast turns or move the cursor great distances, and you'll be able to do more without turning an uncomfortable angle and having to recentre yourself (or with a real mouse, lifting the mouse off the mousepad and moving it somewhere more comfortable). But this makes it hard to make small, precise movements.

With gyro, since there's no mousepad to rest on, a high sensitivity can make shaky hands mess up difficult shots. A low sensitivity (big movements translate to small movements) makes it easy to steadily track slow moving targets or to move the cursor over a small element on-screen, but difficult to make big movements quickly, and you'll quickly encounter an uncomfortable turn, making play awkward.

JSM attempts to give you the best of both worlds by letting you set a sensitivity to use when turning the gyro slowly (MIN_GYRO_SENS) and a sensitivity to use when turning the gyro quickly (MAX_GYRO_SENS). Any turns between "slowly" and "quickly" will linearly interpolate between the two. So, if in the current instant you're turning halfway between "slowly" and "quickly", JSM will use a gyro sensitivity halfway between MIN_GYRO_SENS and MAX_GYRO_SENS.

So what's "slowly" and what's "quickly"? They're determined by MIN_GYRO_THRESHOLD and MAX_GYRO_THRESHOLD, in degrees per second. In the example above, MIN_GYRO_THRESHOLD is 5, so if you're moving slower than 5° over a second (which is pretty slow!), JSM will consider it a "slow" turn and use MIN_GYRO_SENS. MAX_GYRO_THRESHOLD is 75, which means it'll use MAX_GYRO_SENS if you're turning the gyro at least fast enough to cover 75° in a second. Of course, JSM is using your instantaneous velocity to do these calculations. You don't have to actually turn your controller 75° over the course of a second; it just needs to be fast enough that if you maintained this speed for a whole second, it'd turn at least that far.

75° per second isn't super fast, but it doesn't need to be. It's good to set MAX_GYRO_THRESHOLD to something reasonably fast, but slow enough that you can consistently move that quickly without worrying too much about it. It's easier to make quick movements more consistent if the sensitivity is constant, so setting the max threshold to something you'll regularly encounter anyway means you'll usually have a constant sensitivity during quick movements without having to think about it.

GYRO_CUTOFF_RECOVERY is a threshold below which JSM will start to push your sensitivity towards zero. Like MIN_GYRO_THRESHOLD and MAX_GYRO_THRESHOLD, this is in degrees per second. This helps the cursor stay almost completely still despite shaky hands when you try to keep it still. I usually don't use GYRO_CUTOFF_RECOVERY, especially in 3D games, but it's demonstrated here. Some games will actually have a cutoff below which the gyro turn speed is considered zero. This is the worst. They shouldn't do it. You shouldn't do it, especially in 3D games.

The last gyro setting in the example is GYRO_SMOOTH_THRESHOLD. Another way to combat shaky hands is to average out the gyro input over a small period of time. Of course, that makes the resulting movement feel laggy, so it should never be applied to big, intentional movements. GYRO_SMOOTH_THRESHOLD is a real-life turn speed at and above which no smoothing will be applied. Its default is 0 (no smoothing), and I normally leave it at 0, especially in 3D games, but a small smoothing threshold can help cover up some shakiness, especially in combination with GYRO_CUTOFF_RECOVERY.

JSM has other commands not described here. You can find descriptions of those in the Gyro Mouse Inputs section of the JoyShockMapper README.

Finally, let's have a brief look at the right stick.

RIGHT_STICK_MODE determines what the right stick will be used for. LEFT_STICK_MODE does the same for the left stick. By default, it'll just be set to keyboard and mouse inputs as described earlier. But by setting RIGHT_STICK_MODE to AIM, you're saying that the right stick should be used to move the mouse. Alternatively, you can set it to FLICK, but that's only used for 3D games.

The commands after that only apply when using the AIM stick mode.

STICK_SENS says how fast you want the cursor to move per second when it's fully tilted. These settings are designed around 3D games, since stick-cursor generally isn't that useful in 2D games. So in 3D games, STICK_SENS = 360 means that a full tilt of the stick will turn the camera 360° per second. Properly calibrated 2D games treat the width of an HD screen as a full turn, so STICK_SENS = 360 means that a full tilt of the stick to the left or the right will take one second to cover the full width of the screen.

This will be affected by the other settings, like STICK_ACCELERATION_RATE, so it's worth looking them up in the Stick Mouse Inputs section of the JoyShockMapper README.

If you look at _3Dmouse.txt you'll see I do things a little differently for 3D games:

  • I like to use flick stick in every game where the mouse turns the camera. If you don't, comment out the FLICK line (put a # at the beginning) and add a new line: RIGHT_STICK_MODE = AIM. _3Dmouse.txt still includes some useful defaults for AIM mode, but you'll likely want to experiment with these and find something that works well for you.
  • All the options you saw in _2Dmouse.txt work in 3D games as well, but since responsiveness and precision are often even more valuable in 3D games, I don't do any smoothing.
  • You don't have to use these mouse files for every config. Some games have different needs. It's okay to have multiple different mouse configuration files, or even to all of your mouse configuration for a particular game in the same file that has its button mappings.

Calibrating JSM (and sharing on GyroWiki)

Lastly, if you want to set up a config for a game that doesn't already have calibration info on GyroWiki, you can figure out the calibration info yourself. It doesn't have to be exact, but the method described here should get you fairly precise fairly easily.

The goal here is to figure out:

  1. Does the game us raw input?
  2. What is a good REAL_WORLD_CALIBRATION value to make this game behave the same as other similar games?

Raw input is when a game reads the mouse input without interference from Windows' mouse settings. You can often find info online regarding whether a game uses raw input. Alternatively, some games have the option to enable raw input in the settings menu. If the option is there, it's often best to enable it, but if you don't want to mess with your mouse settings for this particular game, it's fine not to.

If this information isn't available online, you'll have to figure out if the game uses raw input by trial and error. This is a simple matter of playing the game with a real mouse, getting an idea of how fast the mouse moves. Then change your Windows mouse setting drastically (to the lowest or highest setting will be the most obvious, but you might want to first make a note of where the setting was before in case you want to return to it), and then return to the game. Move the mouse again. Is it moving roughly the same speed as before? Raw input. Is it drastically slower or faster (depending on whether you changed your Windows settings to be slower or faster)? No raw input.

For games that use raw input, there's nothing you need to do as long as your config file starts with RESET_MAPPINGS. Otherwise, you can restore default behaviour of ignoring Windows' mouse settings with the command IGNORE_OS_MOUSE_SPEED. But for games that don't use raw input, you'll want to have the command COUNTER_OS_MOUSE_SPEED in your config file.

Calculating Real World Calibration

Now we need to figure out a good REAL_WORLD_CALIBRATION value. We can do this mathematically if we know enough info about how the game works, or we find the value experimentally. Usually it'll be experimental, but let's quickly touch on mathematical calculation.

When the mouse reports the mouse speed, it's reporting the number of pixels across the screen the on-screen cursor should move if your Windows' mouse sensitivity is set to 1. Since JSM's gyro reports in degrees, a 360 degree turn will tell the on-screen cursor to move 360 pixels unless your REAL_WORLD_CALIBRATION is something other than 1. For 2D applications, REAL_WORLD_CALIBRATION is supposed to convert a full rotation into a 1920 pixel horizontal movement (the horizontal resolution of an HD monitor), so we can calculate our REAL_WORLD_CALIBRATION for Windows as 1920 / 360, which gives us 5 and 1/3.

Most 2D games will have this REAL_WORLD_CALIBRATION, but sometimes they'll have an internal multiplier for the mouse sensitivity for other reasons — maybe it's because the cursor moves in a plane in the 3D world. Maybe it's because it moves the camera and cursor at the same time. Maybe it's because the developer had a different idea for what a nice scale would be for the mouse settings. These are all reasons you might need a different REAL_WORLD_CALIBRATION for a 2D game.

So let's get into how to find a game's REAL_WORLD_CALIBRATION experimentally.

The GyroConfigs folder contains two calibration helpers: '_2Dcalibrate.txt' and '_3Dcalibrate.txt'. They're both very similar, but the 2D one assumes most 2D games don't use raw input (this isn't always the case), and the 3D one assumes most 3D games do use raw input (this isn't always the case). But these files all contain your simplest setup for calculating your REAL_WORLD_CALIBRATION.

RESET_MAPPINGS
# Use flick stick 
RIGHT_STICK_MODE = FLICK
REAL_WORLD_CALIBRATION = 1
COUNTER_OS_MOUSE_SPEED
# Change this to whatever mouse sensitivity you have in the game you're playing
IN_GAME_SENS = 1

First it resets all settings to their default so that nothing else interferes with this calculation. Then set the right stick to FLICK mode. FLICK isn't normally used in 2D games, but it's still the easiest way to calibrate them, because flick stick creates an isolated horizontal movement that JSM can easily keep track of. Set REAL_WORLD_CALIBRATION to something small, like 1. If the game you're calibrating for does not use raw input, counter Windows' mouse settings. And finally, don't forget to set IN_GAME_SENS to whatever your in-game mouse sensitivity is, or 1 if there isn't one.

JSM has a command CALCULATE_REAL_WORLD_CALIBRATION that uses the last flick stick rotation and assumes that it produced a 360° turn in your 3D game or a complete cursor movement from one side of the screen to the other in a 2D game. It'll then tell you what your REAL_WORLD_CALIBRATION value should be to be correctly calibrated.

For a 2D game, move the cursor all the way to the left side of the screen, then tilt the right stick forward but slightly to the right (don't want to accidentally move left when there's nowhere left to go), and rotate the stick until the cursor has just barely touched the right edge of the screen. Then release the stick. If it takes less than a full rotation, you should try again with a lower initial REAL_WORLD_CALIBRATION value to get a more precise result.

Then type CALCULATE_REAL_WORLD_CALIBRATION into JSM and you should get a reasonably precise recommended REAL_WORLD_CALIBRATION.

Notice that although we calculated earlier that the best REAL_WORLD_CALIBRATION value should be 5.3333, the number we got from JSM was 5.3536. This is less than a 0.4% error, which is fine. The difference can be due to an accumulation of tiny rounding errors in JSM as it adds up the angle and calculates the result, or it could be that the stick moved a little as I released it. It's OK. Whether you're playing a 2D or 3D game, this is accurate enough.

For a 3D game, find a safe space and line up your aimer or the edge of the screen with a static part of the environment. Try and line it up in a way that you can be sure you're lining it up exactly after completing a full turn. Then, tilt your flick stick roughly forward, and start rotating it. You may have to rotate it a lot depending on what the game's actual REAL_WORLD_CALIBRATION is, but eventually you should complete a full turn, be facing exactly the same way you were before, and release the stick.

As before, if it takes less than a full rotation of the stick to complete a full rotation in-game, change REAL_WORLD_CALIBRATION to something even smaller and try again, as it's difficult to do this precisely when a tiny movement of the stick results in a big movement in-game.

Once you've managed to complete exactly one rotation with the flick stick (within reason), release it and type into JSM: CALCULATE_REAL_WORLD_CALIBRATION. This process looks something like this:

That's the REAL_WORLD_CALIBRATION value you should use for this game.

Once you've done all this, why not save someone else the trouble of having to calibrate this game? I'd love for you to contribute your findings to the GyroWiki games database!

If you're not a member of GyroWiki, please consider creating an account. Once you've done that, go to the games list and look for the "Add game" button near the bottom of the page. Type in the name of your game you're adding, click the button, and there you'll be able to create a new game entry for the database!

All you'll have to do is enter the Real World Calibration value, indicate whether the mouse controls the camera or a 2D cursor, whether the game uses raw input, and then you can optionally add some notes. For example, you might say in the notes that the game's native support for DualShock 4 interferes with JSM, but it can be disabled in the game settings (if that's the case).

Members can also edit already-created entries. If someone else made a mistake with their entry and you're sure you can correct it (please double check that it actually should be changed), then go ahead and do it! Or maybe the basic details are correct, but more notes would be helpful. You can go ahead and add those helpful notes yourself.

The more games are added to the GyroWiki games database, the less often JoyShockMapper users will have to calculate these calibration values themselves. This makes it much more accessible to more people who may find it difficult or not have the time to do this calibration.


My goal with this blog post was to get users up and running with JSM without having to learn more than they really need to. As such, there's plenty more to learn about JSM for advanced users. Everything there is to know about all the commands in JoyShockMapper should be covered in its README, which you can find online here. Thanks for reading, and I look forward to seeing what you can do with JoyShockMapper!