• This repository has been archived on 08/Dec/2023
  • Stars
    star
    180
  • Rank 213,097 (Top 5 %)
  • Language
    C
  • License
    MIT License
  • Created over 4 years ago
  • Updated about 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

SaltyNX Plugin collecting FPS data

NX-FPS

SaltyNX plugin that collects FPS data in Nintendo Switch games. You need my fork of SaltyNX 0.5.0+ installed. https://github.com/masagrator/SaltyNX/releases

Put NX-FPS.elf to /SaltySD/plugins

Currently supported graphics APIs:

  • NVN
  • EGL
  • Vulkan

To read FPS from plugin you can use Status Monitor Overlay 0.8.1+ or write your own code.

I am providing instructions based on Status Monitor Overlay code how to read it from your own homebrew:

  • You need to include old ipc.h (here) and SaltyNX.h (here).
  • We need to connect to SaltyNX SharedMemory by connecting to SaltyNX, retrieving SharedMemory handle, terminating connection with SaltyNX and assigning SharedMemory to homebrew.

Helper:

Handle remoteSharedMemory = 1;
SharedMemory _sharedmemory = {};
bool SharedMemoryUsed = false;

//Function pinging SaltyNX InjectServ port to check if it's alive.
bool CheckPort () {
	Handle saltysd;
	for (int i = 0; i < 67; i++) {
		if (R_SUCCEEDED(svcConnectToNamedPort(&saltysd, "InjectServ"))) {
			svcCloseHandle(saltysd);
			break;
		}
		else {
			if (i == 66) return false;
			svcSleepThread(1'000'000);
		}
	}
	for (int i = 0; i < 67; i++) {
		if (R_SUCCEEDED(svcConnectToNamedPort(&saltysd, "InjectServ"))) {
			svcCloseHandle(saltysd);
			return true;
		}
		else svcSleepThread(1'000'000);
	}
	return false;
}

bool LoadSharedMemory() {
    //Connect to main SaltyNX port. On failed attempt return false
    if (SaltySD_Connect())
      return false;
    //Retrieve handle necessary to get access to SaltyNX SharedMemory
    SaltySD_GetSharedMemoryHandle(&remoteSharedMemory);
    //Terminate SaltyNX main port connection
    SaltySD_Term();
    
    //Prepare struct that will be passed to shmemMap to get access to SaltyNX SharedMemory
    shmemLoadRemote(&_sharedmemory, remoteSharedMemory, 0x1000, Perm_Rw);
    //Try to get access to SaltyNX SharedMemory
    if (!shmemMap(&_sharedmemory)) {
      //On success change bool of SharedMemoryUsed to true and return true
      SharedMemoryUsed = true;
      return true;
    }
    //On failed attemp return false
    return false;
}

//By connecting to InjectServ port we can check if SaltyNX is alive and is not stuck anywhere.
bool SaltyNX = CheckPort();
//Check if SaltyNX signaled anything, if yes then use LoadSharedMemory() to get access to SaltyNX SharedMemory
if (SaltyNX) LoadSharedMemory();
  • Next we need to find where our plugin is inside SharedMemory. For this our plugin stores magic 0x465053 as uint32_t. We need to find magic and based on that we know where our plugin is.
uint32_t* MAGIC_shared = 0;
uint8_t* FPS_shared = 0;
float* FPSavg_shared = 0;
bool* pluginActive = 0;

//Function searching for NX-FPS magic through SharedMemory.
//SaltyNX is page aligning any SharedMemory reservation request to 4, that's why we check every 4th byte for MAGIC.
ptrdiff_t searchSharedMemoryBlock(uintptr_t base) {
	ptrdiff_t search_offset = 0;
	while(search_offset < 0x1000) {
		MAGIC_shared = (uint32_t*)(base + search_offset);
		if (*MAGIC_shared == 0x465053) {
			return search_offset;
		}
		else search_offset += 4;
	}
	return -1;
}

//Get virtual address of SaltyNX SharedMemory
uintptr_t base = (uintptr_t)shmemGetAddr(&_sharedmemory);
//Pass retrieved virtual address of SaltyNX SharedMemory to function that will search for NX-FPS magic
ptrdiff_t rel_offset = searchSharedMemoryBlock(base);
//If magic will be found, you will get offset that starts before magic. It cannot be lower than 0.
if (rel_offset > -1) {
  //Pass correct addresses inside SharedMemory to our pointers
  //It shows how many frames passed in one second
  FPS_shared = (uint8_t*)(base + rel_offset + 4);
  //It calculates average FPS based on last 10 readings
  FPSavg_shared = (float*)(base + rel_offset + 5);
  //Pointer where plugin writes true for every frame.
  pluginActive = (bool*)(base + rel_offset + 9);
  ///By passing false to *pluginActive and checking later if it has changed to true we can be sure plugin is working.
  *pluginActive = false;
}

WARNING

Plugin brings some instability to boot process for some games. It is recommended to not close game before ~10 seconds have passed from showing Nintendo logo, otherwise you risk Kernel panic, which results in crashing OS.


Not working games with this plugin (You can find games not compatible with SaltyNX here)

Title Version(s) Why?
Final Fantasy VIII Remastered all Framework stuff is included in NROs which SaltyNX doesn't support
Final Fantasy X/X-2 all Framework stuff is included in NROs which SaltyNX doesn't support
LEGO Harry Potter Collection all Framework stuff is included in NROs which SaltyNX doesn't support

Troubleshooting

Q: Why I got constantly 255?

A: 255 is default value before plugin starts counting frames. This may be a sign that:

  • Game is using different API or function than what is currently supported
  • Plugin missed symbol when initializing (for whatever reason)

Try first to run game again few times. If it's still 255, make an issue and state name of game. Next updates will include support for other graphics APIs.

Thanks to:

  • RetroNX channel for help with coding stuff,
  • CTCaer for providing many useful informations and convincing me to the end that I should target high precision,
  • Herbaciarz for providing video footage.

More Repositories

1

Status-Monitor-Overlay

Monitor many stats of Nintendo Switch hardware
C++
482
star
2

NXGraphicsPatches

Graphics Patches for Nintendo Switch games
338
star
3

ReverseNX-RT

Alternative version of ReverseNX that can switch between handheld and docked mode in Real Time.
C
202
star
4

FPSLocker

Set custom FPS in Nintendo Switch games
C++
201
star
5

ReverseNX-Tool

Tool for easier management of ReverseNX patches
C++
151
star
6

FPSLocker-Warehouse

FPSLocker patches and methodology how to update them
Python
140
star
7

ReverseNX

SaltyNX plugin forcing docked or handheld graphics settings
C
80
star
8

HigurashiENX

Higurashi no Naku Koro ni English Translation Mod for Nintendo Switch
Python
55
star
9

NXGameScripts

Various scripts dedicated to Nintendo Switch games
Python
39
star
10

SaltyNX-Tool

To manage SaltyNX functions
Makefile
36
star
11

Xenoblade2DynFPS

Plugin adjusting dynamically game speed to framerate
C++
25
star
12

PortalNXSideLoader

Portal Collection File Sideloader for Nintendo Switch
C
22
star
13

UnityGraphics

SaltyNX plugin & Tesla overlay dedicated to changing graphics settings in Unity games
C
15
star
14

ToCS1-ENX

English Translation Mod for The Legend of Heroes: Trails of Cold Steel Kai Nintendo Switch version
C++
12
star
15

AIR-ENX

English Translation Mod for Air Nintendo Switch version
C
11
star
16

MonHunRiseResPlugin

Skyline plugin for Monster Hunter Rise to override resolution
C
10
star
17

ToCS2-ENX

English Translation Mod for The Legend of Heroes: Trails of Cold Steel 2 Kai Nintendo Switch version
C++
9
star
18

SPRB-ENX

Summer Pockets Reflection Blue English translation mod for Nintendo Switch
C
8
star
19

UE4cfgdumper

Tool that finds automatically RAM offsets for graphics settings in Unreal Engine 4 & 5 Nintendo Switch games
C++
7
star
20

UnityGraphicsWarehouse

Storage for offsets files
6
star
21

SymphonicRain-ENX

English translation mod for Nintendo Switch version of Symphonic Rain
Python
4
star
22

HigurashiENX-texts

2
star
23

NVNpointersLabels

Files for ghidra to name all nvn pointers for games
Python
2
star
24

AIR-texts

2
star
25

BatteryChargeInfoNX

Test overlay to RE BatteryChargeInfoFields struct
C++
2
star
26

Yahari

C++
2
star
27

NX-FidDb

FunctionID database of Nintendo Switch executables to use with Ghidra
2
star
28

UnrealOodleWrapper

Visual Studio Project linking Unreal Oodle plugin with command tool
C++
2
star
29

DiesIraeNXEN

1
star
30

LANoireNX

LA Noire scripts used for repacking files from Switch version
Roff
1
star
31

HigurashiENX-OyashiroShock

C++
1
star
32

UE4CMDNX

Use commands in Unreal Engine 4 games for Nintendo Switch
C
1
star
33

NXResolutionDB

Resolution used in games
C
1
star
34

DiesIraeScenario

Nintendo Switch
MAXScript
1
star
35

ToCS3Configurator

C++
1
star
36

FLiNSGM

Force Language in Nintendo Switch Games Methodology repo
1
star
37

HigurashiENX-images

1
star
38

GetNetworkPass

Simple app to get password from connected network on Nintendo Switch
Makefile
1
star
39

ShinPlugin

C++
1
star
40

SaltyNX-Patches

Some useful asm64 patches for SaltyNX
1
star