Use FPSLocker on actual hardware or uncap framerate emulator and/or limit game speed to 200% to achieve the same result as this guide. No Ghidra or guide required now.
This is a basic guide to create an .ips that patches 'nvnWindowBuilderSetPresentInterval' and/or 'nvnWindowSetPresentInterval' for a game in order to make the game run at 60FPS. Some games need additional patches specific to that game for 60FPS and not only this method.
If you want to follow along the game I am using is Story of Seasons: A Wonderful Life v1.1 (JP) which I have made a patch for https://gameparadise.org/threads/story-of-seasons-a-wonderful-life-60fps-ips-patch.2930/
Thanks @systemdev for helping me with this game and indirectly this guide.
Instructions
1. Obtain the main of the game - you want to dump the one from the latest update of the game. For this I dump the exeFS of the game using nxdumptool after I've installed the game on my system although there are other ways. https://github.com/DarkMatterCore/nxdumptool/releases
2. Install https://github.com/NationalSecurityAgency/ghidra and https://github.com/Adubbz/Ghidra-Switch-Loader
3. Make a new project, put the main into Ghidra and analyze it (this will take a while)
4. On Switch two variables usually control the framerate target which are
'nvnWindowBuilderSetPresentInterval'
'nvnWindowSetPresentInterval'
Click Search->Search Memory (Search Program Text is an alternate option) and search for one or both of these - in my case I searched for 'nvnWindowSetPresentInterval'
Click on the search result that should come up and you should have found it!
5. Double click on the function circled in red - Ghidra should now analyze the function on the right side of the screen in a window. This might take a little bit.
6. Find nvnWindowSetPresentInterval and its corresponding DAT
7. Click on DAT_71010cb520 and you'll be taken a screen that looks this
You'll have to click on each function and examine if you can find the right ASM block. For me, it was the second one which is highlighted which looks like this when clicked on
8. Look at the highlight block above. We are going to edit the w1, #0x2. Right click on it and then click 'Patch Instruction'. Change the #0x2 to #0x1. For other games that #0x2 may be a w20 or another value, however in that case still change it to a #0x1.
9. IPS patch time! We are first going to make the .pchtxt file which will be turned into the IPS patch which are formatted like this
The NSOBID part contains the BID of the game. I use Tinfoil to easily find the full BID (Build ID) of a game. https://tinfoil.io/Title/0100936018EB4000
Include the flag offset_shift 0x100 so the patch is applied to the right place
Under @enabled your modified ASM will go. The left part is the address and the right part are the values you have modified at that address. Make sure you get rid of the first two digits '71' from the Ghidra address. Save this file as a .pchtxt file.
10. Install IPSwitch on your Switch. Copy the .pchtxt to sdmc:/switch/ipswitch/{patch_description}/{whatever_name}.pchtxt
Run IPSwitch and select the patch located into the folder and turn it into a .ips file which will be located at atmosphere/exefs_patches/{patch_description}/{BID of Patch}.ips
11. Run the game and see if its at 60FPS. Make sure you overclock using sys-clk (some games when modded to 60FPS, if they can't run at 60FPS they will drop to 30FPS, and need the extra performance from overclocking) or another program and check the FPS using Status Monitor. Congratulations, hopefully your game is at a silky smooth 60FPS like the example below!
This is a basic guide to create an .ips that patches 'nvnWindowBuilderSetPresentInterval' and/or 'nvnWindowSetPresentInterval' for a game in order to make the game run at 60FPS. Some games need additional patches specific to that game for 60FPS and not only this method.
If you want to follow along the game I am using is Story of Seasons: A Wonderful Life v1.1 (JP) which I have made a patch for https://gameparadise.org/threads/story-of-seasons-a-wonderful-life-60fps-ips-patch.2930/
Thanks @systemdev for helping me with this game and indirectly this guide.
Instructions
1. Obtain the main of the game - you want to dump the one from the latest update of the game. For this I dump the exeFS of the game using nxdumptool after I've installed the game on my system although there are other ways. https://github.com/DarkMatterCore/nxdumptool/releases
2. Install https://github.com/NationalSecurityAgency/ghidra and https://github.com/Adubbz/Ghidra-Switch-Loader
3. Make a new project, put the main into Ghidra and analyze it (this will take a while)
4. On Switch two variables usually control the framerate target which are
'nvnWindowBuilderSetPresentInterval'
'nvnWindowSetPresentInterval'
Click Search->Search Memory (Search Program Text is an alternate option) and search for one or both of these - in my case I searched for 'nvnWindowSetPresentInterval'
Click on the search result that should come up and you should have found it!
5. Double click on the function circled in red - Ghidra should now analyze the function on the right side of the screen in a window. This might take a little bit.
6. Find nvnWindowSetPresentInterval and its corresponding DAT
7. Click on DAT_71010cb520 and you'll be taken a screen that looks this
You'll have to click on each function and examine if you can find the right ASM block. For me, it was the second one which is highlighted which looks like this when clicked on
8. Look at the highlight block above. We are going to edit the w1, #0x2. Right click on it and then click 'Patch Instruction'. Change the #0x2 to #0x1. For other games that #0x2 may be a w20 or another value, however in that case still change it to a #0x1.
9. IPS patch time! We are first going to make the .pchtxt file which will be turned into the IPS patch which are formatted like this
The NSOBID part contains the BID of the game. I use Tinfoil to easily find the full BID (Build ID) of a game. https://tinfoil.io/Title/0100936018EB4000
Include the flag offset_shift 0x100 so the patch is applied to the right place
Under @enabled your modified ASM will go. The left part is the address and the right part are the values you have modified at that address. Make sure you get rid of the first two digits '71' from the Ghidra address. Save this file as a .pchtxt file.
10. Install IPSwitch on your Switch. Copy the .pchtxt to sdmc:/switch/ipswitch/{patch_description}/{whatever_name}.pchtxt
Run IPSwitch and select the patch located into the folder and turn it into a .ips file which will be located at atmosphere/exefs_patches/{patch_description}/{BID of Patch}.ips
11. Run the game and see if its at 60FPS. Make sure you overclock using sys-clk (some games when modded to 60FPS, if they can't run at 60FPS they will drop to 30FPS, and need the extra performance from overclocking) or another program and check the FPS using Status Monitor. Congratulations, hopefully your game is at a silky smooth 60FPS like the example below!