@PixieCatSupreme Hi, I’m back with maybe a solution for you (sorry for the delay).
Can you try the following and see if this resolves for you?
1. Create Custom Mapping Loader
The first step is to create a helper class you can use to load custom mappings. Add a new class to your project (for the purposes of example, i called it CustomControllerMapping
but you can call it whatever you want)
(also replace YourNameSpace
in the code below with your project’s namespace)
using System.Runtime.InteropServices;
namespace YourNamespace;
public static class CustomControllerMapping
{
[DllImport("SDL2.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int SDL_GameControllerAddMapping(string mappingString);
}
Next, in your Game1
constructor, add the following code (we’ll replace the string parameter in just a moment)
CustomControllerMapping.SDL_GameControllerAddMapping("");
2. Create Controller Mapping
Next you’ll need to create a full SDL controller mapping for your controller. To do this, you can use the SDL2 Gamepad Tool program found at https://www.generalarcade.com/gamepadtool/.
Download this tool, unzip it and run it. Then click the **Create A New Mapping" button
Follow all of the steps to create the mapping for each input button. If there is a button that your controller doesn’t have a 1:1 mapping for in the image, you can press the Skip button. Once you have completed all buttons mappings, click the Copy Mapping String button
Now go back to your game Game1
constructor and paste the mapping string you just copied as the parameter for the method we added. It should be something similar to this (your mapping string will be different than my example obviously)
CustomControllerMapping.SDL_GameControllerAddMapping("030000006f0e00008401000000010000,Faceoff Deluxe+ Audio Wired Controller for Nintendo Switch,platform:Mac OS X,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b13,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,-leftx:a0,+leftx:a1,lefty:+a1,-rightx:a2,+rightx:a3,righty:+a3,lefttrigger:b6,righttrigger:b7,");
3. Run The Game
Now run the game and see if the buttons are all correctly mapped.
4. Caveat and Gotchas
-
First, this code will only work for Monogame Crossplatform Desktop (DesktopGL aka OpenGL) projects, as they are the only ones that use SDL for the controller mapping.
-
Second, the [DllImport]
attribute that is part of the SDL_GameControllerAddMapping
method will only work on Windows. This is because on Windows, OpenGL projects use the SDL2.dll
where Mac uses libSDL2.dylib
and Linux uses libSDL2-2.0.so.0
. So if you want this as a single solution for all platforms you export to you’ll need to make use of #if
preprocessor directives to specify the platform and which of those to import based on the operating system as well as ensuring those preprocessor values are set for your project. For example:
#if WINDOWS
[DllImport("SDL2.dll", CallingConvention = CallingConvention.Cdecl)]
#elif MAC
[DllImport("libSDL2.dylib", CallingConvention = CallingConvention.Cdecl)]
#else // Linux presumed if not windows or mac
[DllImport("libSDL2-2.0.so.0", CallingConvention = CallingConvention.Cdecl)]
#endif
public static extern int SDL_GameControllerAddMapping(string mappingString);
- Hardcoding the mapping string like in the example is not a great solution, especially if you want your players to be able to add their own mappings for their controller’s if needed. So I would recommend a solution where you add the mappings to a file and read them from the file to the game. Alternatively, you can just download the most current
gamecontrollerdb.txt
file from the SDL_GameControllerDB Github and read in all the mappings and add them manually (atleast until the next MonoGame release where the mappings will be updated).