Homebrew  Updated

FPSLocker - set custom FPS target in retail games

An overlay that with SaltyNX 1.2.0+ allows to set custom refresh rate in both handheld and docked mode + FPS in Nintendo Switch retail games.

Disclaimer: Tool is utilizing detection of graphics API to manipulate FPS. It supports special patches that are helping with going above 30 FPS in games using proprietary FPS locks.

You can see here how it works (I was utilizing Witcher 3 dynamic resolution config mod to make anything above 30 FPS available):


More in README (I recommend to read it + also SaltyNX readme if you don't know how it works)
Repo: https://github.com/masagrator/FPSLocker
Releases: https://github.com/masagrator/FPSLocker/releases
Patches: https://github.com/masagrator/FPSLocker-Warehouse
 
Last edited by masagrator,
2.2.0
2.2.0 prerelease now available that adds support for 70-120 Hz in docked mode. Requires SaltyNX 1.3.0 that is also in prerelease
https://github.com/masagrator/FPSLocker/releases/tag/2.2.0
https://github.com/masagrator/SaltyNX/releases/tag/1.3.0

1748626202811.png2025053119303500.jpg
 
THPS 3+4 attempt to reach target 60 FPS on v1.

Needs more tuning maybe some else know how to get better results, game is pretty demanding so it gets fairly hot. I would target 50 FPS and make sure you are in handheld mode if you are gonna play long term.

CPU 1683
GPU 921
RAM unchanged

 
  • Like
Reactions: czerwinski76
It requires FPSLocker patch tweaking engine to properly support higher framerates without so big gpu demand. But you won't see anything from me for next 2 weeks unless someone will send me log file created by ue4cfgdumper.
 
It requires FPSLocker patch tweaking engine to properly support higher framerates without so big gpu demand. But you won't see anything from me for next 2 weeks unless someone will send me log file created by ue4cfgdumper.
yeah I thought it might do! Don’t stress my friend. There is no rush ❤️🙏
 
  • Like
Reactions: czerwinski76
2.2.0
2.2.0 is now in full release.
Requires SaltyNX 1.3.0+ to work properly.

Changelog:
  • Add support for 720p/1080p docked mode refresh rates: `70, 72, 75, 80, 90, 95, 100, 110, 120 Hz`
    • Add wizard for testing refresh rates from 70 up to 120 Hz for 1080p (for 720p it automatically unlocks all refresh rates supported by your display)
    • Not all displays supporting 1080p signal with refresh rates higher than 75 Hz can be set to those higher refresh rates, more in README.
  • Add support for changing refresh rates for Switch OLED and Retro Remake OLED displays.
    • For Switch OLED it comes with auto gamma curve adjustments on hardware level that are trying to reproduce original colors as close as possible, but because of nature of such approach it's not possible to do it perfectly (the worst case is at ~60% brightness using 45 Hz). With that also comes another issue, the lower the refresh rate the lower max brightness.
    • For Retro Remake SUPER5 first revision users, you must enable Retro Remake Mode in Display Settings. That is because we can't differentiate between first SUPER5 and already existing InnoLux display. That option won't show up for other users.
  • Load game titles in background, resulting in faster boot times when game is not running
  • Add support for languages: German, French, Russian, Brazilian Portuguese, Chinese Simplified (UI was redesigned to give them more space for text), it's set based on system language. You can force back English if you prefer.

Read README for more informations.

SaltyNX 1.3.0 changelog
  • Add support for overclocking compatible external display's refresh rate up to 120 Hz
  • Add support for downclocking OLED internal display refresh rate down to 45 Hz
  • Add support for downclocking Retro Remake SUPER5 refresh rate down to 40 Hz (with initial support for other Retro Remake displays)
  • Fix an issue with not clearing shared memory after application is closed, resulting in tools such as Status Monitor and FPSLocker reporting false values
 
Last edited by masagrator,
120hz output a very welcomed feature! The wizard was unable to detect 120hz, although I suspect it just wasn't given enough time to handshake; you may want to extend each test by a few seconds. I'm Feeding it into an Avermedia 4k card and manually enabling it worked.
Interestingly I did have it lose sync when opening up the pause menu in Metroid Dread like the age old problem of resolution switching in older games. After a re-dock/re-enable it seemed to work, perhaps a fluke. I wish Switch 2 had this option instead of only in supported titles. Great update!

edit: Can't seem to set an FPS target in docked for some reason. I see the numbers blip open for a split second and close up before I can select one. Something I need to update besides Salty/Locker?

edit2: Works perfectly now with 2.3.0
 
Last edited by BobsYurUncle,
  • Like
Reactions: czerwinski76
2.3.0
2.3.0 was released. Before it was 2.2.1 that got separate display sync for docked and handheld.

Requires SaltyNX 1.4.0+ to work properly

  • Removed save settings option, now every change is automatically saved
  • Fixed bugged Display Sync Docked functionality
  • Fix issue with both Wizards, being initiated, not returning to 60 Hz after pressing B
  • Separate display overclocking settings for docked 720p
  • Separate FPS targets saved for docked and handheld
  • Hide Docked Settings options that were blocked (because of not being in docked mode or not using 720p/1080p modes)
  • FPSLocker now is closed faster when game is running

SaltyNX 1.4.0 changelog
  • Separate display sync for handheld and docked
  • Fix memory leak related to reading external display's config (it was crashing system)
  • Read separately FPS targets for docked and handheld from FPSLocker save
  • Add SaltyNX version to logs of sysmodule and Cores
  • Fix an issue with sysmodule not injecting Core anymore to next games if Core initialization failed which resulted in game crash before Core had a chance to close connection
  • Improve NX-FPS's PFPS stat reporting
  • Read separate docked overclocking settings for 720p
  • Now game read speed in Core is opt-out instead of opt-in (to get game read speed use Status Monitor Overlay 1.2.0+)
  • Fix some FPSLocker patches not working with 32-bit games
 
Last edited by masagrator,
Hello! Can you Tell me if there is a way to disable dynamic permission in FPSlocker patches? :З

I'm playing Zelda BOTW on 40FPS and tried to bind the UltraCam modification to FPSlocker, but with the same fps restriction (in both config files) the game starts to lag, please tell me what I'm doing wrong?

Maybe I should use one thing and they can't be combined?

I'm a beginner :D
 
Last edited by Bnbalsohide,
Dunno what is "dynamic permission". And yes, you can't use both Ultracam and FPSLocker patch at the same time, they are not intercompatible.
 
  • Like
Reactions: Bnbalsohide
3.0.0
3.0.0 version was released
  • Add support for next generation of FPSLocker configs called "v4"
    • Allows putting code caves and new variables inside SaltyNX Core, which allows easier updating of more complex configs + helps avoiding conflicts with cheats using caves
    • More functionality when using branches in assembly
    • "v3" branch in FPSLocker Warehouse is now removed, and "v3.1" branch will be removed in next week.
  • User is now informed in main menu when currently running game should use FPSLocker patch with red text "Patch file was not found".

Updating SaltyNX to 1.5.0+ version is required!​

SaltyNX 1.5.0 changelog:
  • Add support for next generation of FPSLocker patches introduced in FPSLocker 3.0.0 release
  • Fix compatibility with Unity 6 games (Hollow Knight Silksong, Disney Dreamlight Valley 1.18.0)
  • NX-FPS: report resolutions only with width higher than 160 px
  • FPSLocker patch is now applied every frame in handheld instead of every second. This can cause crashes with some old patches on game's boot, it can be solved by removing patch in FPSLocker, downloading new config with FPSLocker 3.0.0+ and creating from it new patch
  • With each new release "Debug_files.zip" will be included for easier debugging of specific release version
 
Fantastic! Can't wait to try out the new version and what new configs can bring.

Question: where are patch files created on your Switch actually saved? What kind of files are it?
 
where are patch files created on your Switch actually saved?
1757336852775.png

What kind of files are it?
Fully custom binary files. Designed my own format based on what I have learned from reverse engineering visual novels to get something that is lightweight and fast to process. FPSLocker creates intermediary patch that you can find on sdcard which is converted by SaltyNX Core to final patch that matches exactly your chosen fps target and refresh rate, is stored in Core's cache as long as you don't change fps target or refresh rate.

Code used to convert config to intermediary patch:
https://github.com/masagrator/FPSLocker/blob/main/source/Lock.cpp
Code used to convert intermediary patch to final patch + how to interpret them:
https://github.com/masagrator/SaltyNX/blob/master/saltysd_core/source/lock.hpp
 
Last edited by masagrator,
  • Love
Reactions: jelbo
SaltyNX 1.5.1-beta1
Released SaltyNX 1.5.1-beta1 which focuses on fixing compatibility with games having heap issues since forever, it changes how one of crucial functions work so there is a chance that some games which were working before won't work, but without making this public chances of getting such report are very low. Tested it with all games I had and no issues were found.

Games that didn't work with SaltyNX up to 1.5.0 but in this beta are working correctly:
  • Death Road to Canada
  • Donkey Kong Country: Tropical Freeze
  • Stubbs the Zombie in Rebel Without a Pulse (game has hardcoded sizes, included exefs patch to reduce 1.5GB general buffer by 2MB - added patches for versions 1.0.0 and 1.0.3)
  • Olympic Games Tokyo 2020 – The Official Video Game™ (game has hardcoded sizes, included exefs patch to reduce ~1.4GB general buffer by 2MB - added patches for versions 1.0.0 and 1.0.2 EUR + 1.0.9 Asia)
  • Splatoon 3
So they are now not blocked anymore in exceptions.

Edit: Beta 2
  • Bring back original max brightness for Switch OLED when refresh rate is set below 60 Hz
  • Change colors for Switch OLED's 50 Hz at low range of brightness to better match 60 Hz colors
 
Last edited by masagrator,
Released FPSLocker 3.0.1 beside SaltyNX 1.5.2

Now changing between double buffer, triple buffer and quadruple buffer works in real time as long as game supports it.


Is it possible to request a patch for FC26? Can I give you a link to the game? It was pre-released last night. I want to play without lag.
 
I was trying to use the available FPS unlocker patch for SMTVV but it doesn't work. Every time I download and convert it, FPSLocker asks me to restart the game, which I do, but nothing happens when I increase or decrease the frame rate after restarting.

It says "Plugin didn’t apply patch to game" for some reason.

I am using the latest Atmosphère, HOS 19.0.1 and the latest FPSLocker releases.
 
Last edited by yankii,

Site & Scene News

Popular threads in this forum