How to make 60FPS .ips Patch for Nintendo Switch Game Ghidra Tutorial

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://gbatemp.net/threads/story-of-seasons-a-wonderful-life-60fps-ips-patch.625672/

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!
1675544037305.png


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.
1675544179425.png


6. Find nvnWindowSetPresentInterval and its corresponding DAT
1675544286652.png

7. Click on DAT_71010cb520 and you'll be taken a screen that looks this
1675545732259.png

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
1675545867720.png

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.
1675546086229.png

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.
1675546158433.png


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!

1675546728064.png
 

Attachments

  • 1675545793968.png
    1675545793968.png
    11 KB · Views: 127
Last edited by ChanseyIsTheBest,

StevensND

Well-Known Member
Member
Joined
Dec 26, 2017
Messages
128
Trophies
0
Age
27
XP
458
Country
Spain
@StevensND this is because if analyze fails in finding references to those strings or it won't recognize them as strings, instead of search results showing normal strings they show only first byte of that string or other shit. But if there are no results at all (which OP is suggesting), it means that nvn is not used.

Ok. Thanks for the info. I'm still trying to adapt to IDA too. The analysis is faster and so far I have had no problems yet.
 

RichardTheKing

Honestly XC2>XC3...
Member
Joined
Mar 18, 2020
Messages
1,045
Trophies
1
Age
26
XP
3,203
Country
Australia
This won't help since that method works on binary level.

If they didn't screw up, answer is pretty simple - game doesn't use NVN. Tutorial lacks answers to question what if game turns out to be using EGL (so eglInterval must be patched) or Vulkan (API doesn't support setting intervals ).

In case of EGL matter complicates fact that games are using two approaches to link to subsdk functions: by implementing weak symbol, or like NVN's LoadCProcs it calls other function to get address of eglInterval and stores it somewhere.
The game I'm trying to create an IPS patch for is Fire Emblem Engage; I probably should've mentioned that before. My apologies.
I'm guessing FEE uses EGL, then; how do I patch eglInterval?
 

masagrator

The patches guy
Developer
Joined
Oct 14, 2018
Messages
6,278
Trophies
3
XP
12,043
Country
Poland
The game I'm trying to create an IPS patch for is Fire Emblem Engage; I probably should've mentioned that before. My apologies.
I'm guessing FEE uses EGL, then; how do I patch eglInterval?
Nope, it uses NVN - like all Unity games. So you are doing something wrong.

Btw. this game gets broken at some points if you unlock 60 FPS. There is already 60 FPS mod that fixes many of those issues.
 

Maq47

Lord of Pyro
Member
Joined
Jan 7, 2012
Messages
1,242
Trophies
1
Location
Your basement
Website
idont.have.one
XP
3,291
Country
United States
Okay, I'm trying to create a Main NSO cheat for a game, and know how the game likely does the calculation that I want to modify, but I cannot figure out how to unlock searching for 'matching instructions', as all options under that menu are grayed out. I'm on Ghidra 10.4, and using the latest SwitchLoader extension.
 

ChanseyIsTheBest

Well-Known Member
OP
Member
Joined
Aug 26, 2022
Messages
390
Trophies
0
Location
Australia
XP
1,052
Country
Australia
Okay, I'm trying to create a Main NSO cheat for a game, and know how the game likely does the calculation that I want to modify, but I cannot figure out how to unlock searching for 'matching instructions', as all options under that menu are grayed out. I'm on Ghidra 10.4, and using the latest SwitchLoader extension.
I'll put a big banner on the first post but you don't need this guide anymore. Use FPSLocker homebrew for actual hardware as it can change the value to make games 60FPS and it works for everything excluding 32 bit games which are rare. The same thing happens when you uncap framerate in emulator or limit game speed to 200%.
 

Maq47

Lord of Pyro
Member
Joined
Jan 7, 2012
Messages
1,242
Trophies
1
Location
Your basement
Website
idont.have.one
XP
3,291
Country
United States
I'll put a big banner on the first post but you don't need this guide anymore. Use FPSLocker homebrew for actual hardware as it can change the value to make games 60FPS and it works for everything excluding 32 bit games which are rare. The same thing happens when you uncap framerate in emulator or limit game speed to 200%.
Uhhhh, I'm trying to make a general ASM cheat code, not a 60FPS cheat.
Post automatically merged:

Also, I'm using Ryujinx.
 

NicholasFlamy

New Member
Newbie
Joined
Jan 5, 2024
Messages
1
Trophies
0
Age
34
XP
13
Country
United States
I'll put a big banner on the first post but you don't need this guide anymore. Use FPSLocker homebrew for actual hardware as it can change the value to make games 60FPS and it works for everything excluding 32 bit games which are rare. The same thing happens when you uncap framerate in emulator or limit game speed to 200%.
Limiting to 50% speed in yuzu on Android does limit games (like Splatoon 2) to 30 FPS but the game speed is not set to be normal at 30 FPS. A proper 30 FPS mod does make the game run at the correct speed at 30 FPS, but it reintroduces the squid bouncing out of the ink and not submerging issue. So something is strange about that. (It could just be an Android Yuzu problem as I haven't gotten around to testing desktop Yuzu.)
Post automatically merged:

Limiting to 50% speed in yuzu on Android does limit games (like Splatoon 2) to 30 FPS but the game speed is not set to be normal at 30 FPS. A proper 30 FPS mod does make the game run at the correct speed at 30 FPS, but it reintroduces the squid bouncing out of the ink and not submerging issue. So something is strange about that. (It could just be an Android Yuzu problem as I haven't gotten around to testing desktop Yuzu.)
That must be a game engine thing because the limit makes game speed norma; at whatever limit I set (50%, 200%, etc.) with The LEGO Movie 2 Videogame.
 
Last edited by NicholasFlamy,

Nigo

Member
Newcomer
Joined
Jan 28, 2024
Messages
5
Trophies
0
Age
23
XP
12
Country
Spain
Hi guys, im in the 5th step of the tutorial, when I search the variables, the function is missing, this happens in "nvnWindowSetPresentInterval" and in "nvnWindowBuilderSetPresentInterval" (and in other variables as well) is there a way to move forward from here?
 

StevensND

Well-Known Member
Member
Joined
Dec 26, 2017
Messages
128
Trophies
0
Age
27
XP
458
Country
Spain
Hi guys, im in the 5th step of the tutorial, when I search the variables, the function is missing, this happens in "nvnWindowSetPresentInterval" and in "nvnWindowBuilderSetPresentInterval" (and in other variables as well) is there a way to move forward from here?

Use FPSLocker on actual hardware or uncap framerate emulator and/or limit game speed to 200% to achieve the same result as this guide.
 

Nigo

Member
Newcomer
Joined
Jan 28, 2024
Messages
5
Trophies
0
Age
23
XP
12
Country
Spain
Use FPSLocker on actual hardware or uncap framerate emulator and/or limit game speed to 200% to achieve the same result as this guide.
The thing is that the game I want to patch doesn't achieve more fps when I uncap the framerate in the emulator. This means that I can't achieve more fps in that game?
 

Nigo

Member
Newcomer
Joined
Jan 28, 2024
Messages
5
Trophies
0
Age
23
XP
12
Country
Spain
So ... if you uncap the fps is still 30?. If that's the case the game might be using a internal fps lock.
Exactly, there's a 60 fps patch on switch, but it's a .bin and a .yaml files, not an ips patch, so I understand that there is a way to remove that 30 fps lock, but I don't have any idea how.
 

PeaceHacker

Member
Newcomer
Joined
Jan 24, 2021
Messages
16
Trophies
0
XP
139
Country
United States
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://gbatemp.net/threads/story-of-seasons-a-wonderful-life-60fps-ips-patch.625672/

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!
View attachment 351146

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.
View attachment 351147

6. Find nvnWindowSetPresentInterval and its corresponding DAT
View attachment 351148
7. Click on DAT_71010cb520 and you'll be taken a screen that looks this
View attachment 351151
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
View attachment 351155
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.
View attachment 351157
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.
View attachment 351158

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!

View attachment 351164
I will have to try this out for myself later
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
  • No one is chatting at the moment.
    OctoAori20 @ OctoAori20: Nice nice-