From GameBrew - a wiki dedicated to Video Game Homebrew.
I originally started looking into swapping buttons when I got the MHGen hunting grip. I've always thought Nintendo's placement of the L/R and ZL/ZR is backwards from everyone else, and I don't like it. While searching for something to swap the two, I looked at the source for InputRedirection from @Stary2001. If you don't know how it works, it hooks into the HID process (which is responsible for user input), and redirects where the values for user input are read from in memory through Arm assembly.
His patch was pretty easy for me to read to see what was going on, and I thought, "What if we could get the values from what buttons were pressed, then modify the values before the value gets written to this redirected memory?" After some experimentation, it worked!
I've put quite a bit of work to make this as user-friendly as possible, but be aware of a few things:
- This code works at almost the lowest level possible-assembly code; it is really hard to debug. As long as you don't touch the other functions (.single, .combo, .touch, .cpad), the worst that can happen is your console will get bad input data and be uncontrollable. Just reboot and try a different configuration.
- You cannot reconfigure this on the 3DS! Every time you want to change your button mappings, you need to edit the injected file and recompile the program. Hopefully I can change that in the future - I'm open to help for this.
- The C-stick and ZL/ZR are not mappable right now. I'm looking into hooking the IR process to achieve this.
- The Home button and Power button are not remappable. These buttons use a separate part of the hardware, and there are no plans to make this possible.
- While based on InputRedirection, it is not compatible. This program would overwrite any data sent by the InputRedirection desktop programs.
- It can still be a bit buggy. It is designed to un-press any buttons that were pressed if you use touchscreen or C-pad mappings, but I noticed that it doesn't always work when used with combos. YMMV.
- I've just merged with Stary's latest changes, but I haven't tested the Mode3 version, as I don't have an O3DS.
Spoiler: Old "How To Use" and technical info
Code is located at my repo: https://github.com/MikahJC/ButtonSwap3DS
Spoiler: Build Environment
You will need a working setup of the devkitARM toolchain for 3DS, follow this guide if you need help: https://www.3dbrew.org/wiki/Setting_up_Development_Environment.
You will also need this library by @Stary2001: https://github.com/Stary2001/ScenicRoute. Clone it, then run make install in the ScenicRoute directory.
Finally, clone the repository at https://github.com/MikahJC/ButtonSwap3DS.
The instructions for each type of mapping are provided in the source/injected.s file. I've provided a Java program to generate the correct button masks and coordinate values. When you have saved your mappings into this file, you will need to compile it. To build, change to the ButtonSwap3DS directory in a terminal, then run make.
Spoiler: Each data field, and how to get it
Spoiler: Button Masks
This is the data that defines which buttons will activate the remapping and which buttons will be pressed as a result. Either use the provided program, or manually calculate the mask using this table. For example, this code would swap A and B:
ldr r4, =0x1 ldr r5, =0x2 bl .button ldr r4, =0x2 ldr r5, =0x1 bl .button
The next two data fields are six-digit numbers. The first 3 digits are the Y coordinate data, and the last 3 digits are the X coordinate data.
Spoiler: Touchscreen Data
The data that will be sent as the touchscreen. Use the provided tool to generate this data.
Spoiler: C-pad Data
Data that will be sent as the c-pad. This data is a bit harder to calculate. The default value for the C-pad is 0x800800. To calculate this value, you will need to use the developer mode on your calculator. Xor 0x800800 by the value you want the C-pad to have. For example, if you want to have the C-pad pushed to the right, you would xor 0x800800 by 0x800FFF, giving you 0x7FF. Pad this with 3 zeroes in front (0x0007FF), and you have your data!
2020 Update: I know I've been absent from this thread for a long time, so I want to thank @AmberLoss for putting together an FAQ here and helping others get mappings built. As of yesterday, I finished a project that should make this a lot easier to use. ButtonSwap3DS Builder is a web application that lets you configure what mappings you want and download a CIA with those mappings. This eliminates the need to set up a build environment or use tools to calculate mappings. I'm on my phone right now but I'll try to add some more info to the FAQ once I get to a real computer.
I've attached a basic version that swaps A and B for demonstration purposes.
Thanks and credit to @Stary2001. He wrote all of the injection code and almost all of the setup code. I just figured out how to mess with the values in-between. :)
2/15/2017: Uploaded a new zip with the mode3 version as well.
3/28/2017: @Vague Rant pointed out an error with the combo swap documentation. Thanks!
4/15/2017: Changed how button pressing and un-pressing works. As @Vague Rant and @rolim91 pointed out, multiple mappings had the possibility of affecting each other, resulting in undesirable results when multiple buttons were pressed. The new system maintains a record of which buttons need to be pressed and unpressed, then applies all changes at the end of the mapping process. My initial testing shows that it is working much better, but I appreciate any feedback if there are still bugs.
TL;DR: New tool for building ButtonSwap3DS, homebrew that lets you remap 3DS buttons. Back in 2017, I figured out how to remap buttons based on the Input Redirection codebase. I posted it to GBATemp and I'm surprised the thread is still somewhat active. There are a number of problems with it though:
- In order to configure it, tools had to be made to calculate the data for you easily.
- You had to set up a small development environment to build the CIA.
- You can't reconfigure it on the 3DS. You want a new mapping, you need to rebuild it.
ButtonSwap3DS Builder solves the first two points, and provides a workaround for the third. It's a web based tool that provides an easy way to write remaps and get the CIA for it. Under the main configuration panel, you can change the unique ID of the generated CIA so you can have multiple versions installed. It's currently hosted on a free tier Heroku instance, so if it's not responding you may need to wait for traffic to die down. If it's down too often, I'll look into hosting it somewhere else. Enjoy!