Skip to content

Commit

Permalink
Support SaltyNX 1.0.3 refresh rate, small code refactor (#87)
Browse files Browse the repository at this point in the history
  • Loading branch information
masagrator authored Nov 5, 2024
1 parent 13346c2 commit ce343de
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 74 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ include $(DEVKITPRO)/libnx/switch_rules
# NACP building is skipped as well.
#---------------------------------------------------------------------------------
APP_TITLE := Status Monitor
APP_VERSION := 1.1.5
APP_VERSION := 1.1.6
TARGET := $(notdir $(CURDIR))
BUILD := build
SOURCES := source
Expand All @@ -51,7 +51,7 @@ NO_ICON := 1
#---------------------------------------------------------------------------------
ARCH := -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIE

CFLAGS := -g -Wall -O2 -ffunction-sections \
CFLAGS := -g -Wall -Wno-address-of-packed-member -O2 -ffunction-sections \
$(ARCH) $(DEFINES)

CFLAGS += $(INCLUDE) -D__SWITCH__ -DAPP_VERSION="\"$(APP_VERSION)\""
Expand Down
85 changes: 47 additions & 38 deletions source/Utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,35 @@ uint32_t GPU_Load_u = 0;
bool GPULoadPerFrame = true;

//NX-FPS

struct resolutionCalls {
uint16_t width;
uint16_t height;
uint16_t calls;
};

struct NxFpsSharedBlock {
uint32_t MAGIC;
uint8_t FPS;
float FPSavg;
bool pluginActive;
uint8_t FPSlocked;
uint8_t FPSmode;
uint8_t ZeroSync;
uint8_t patchApplied;
uint8_t API;
uint32_t FPSticks[10];
uint8_t Buffers;
uint8_t SetBuffers;
uint8_t ActiveBuffers;
uint8_t SetActiveBuffers;
uint8_t displaySync;
resolutionCalls renderCalls[8];
resolutionCalls viewportCalls[8];
bool forceOriginalRefreshRate;
} NX_PACKED;

NxFpsSharedBlock* NxFps = 0;
bool GameRunning = false;
bool check = true;
bool SaltySD = false;
Expand All @@ -143,22 +172,8 @@ uint32_t FPS = 0xFE;
float FPSavg = 254;
SharedMemory _sharedmemory = {};
bool SharedMemoryUsed = false;
uint32_t* MAGIC_shared = 0;
uint8_t* FPS_shared = 0;
uint8_t* API_shared = 0;
float* FPSavg_shared = 0;
bool* pluginActive = 0;
uint32_t* FPSticks_shared = 0;
Handle remoteSharedMemory = 1;

struct resolutionCalls {
uint16_t width;
uint16_t height;
uint16_t calls;
};
resolutionCalls* renderCalls_shared = 0;
resolutionCalls* viewportCalls_shared = 0;

//Read real freqs from sys-clk sysmodule
uint32_t realCPU_Hz = 0;
uint32_t realGPU_Hz = 0;
Expand Down Expand Up @@ -207,16 +222,17 @@ void LoadSharedMemory() {
else FPS = 1234;
}

ptrdiff_t searchSharedMemoryBlock(uintptr_t base) {
void 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;
NxFps = (NxFpsSharedBlock*)(base + search_offset);
if (NxFps -> MAGIC == 0x465053) {
return;
}
else search_offset += 4;
}
return -1;
NxFps = 0;
return;
}

//Check if SaltyNX is working
Expand Down Expand Up @@ -247,29 +263,22 @@ void CheckIfGameRunning(void*) {
if (!check && R_FAILED(pmdmntGetApplicationProcessId(&PID))) {
GameRunning = false;
if (SharedMemoryUsed) {
*MAGIC_shared = 0;
*pluginActive = false;
*FPS_shared = 0;
*FPSavg_shared = 0.0;
(NxFps -> MAGIC) = 0;
(NxFps -> pluginActive) = false;
(NxFps -> FPS) = 0;
(NxFps -> FPSavg) = 0.0;
FPS = 254;
FPSavg = 254.0;
}
check = true;
}
else if (!GameRunning && SharedMemoryUsed) {
uintptr_t base = (uintptr_t)shmemGetAddr(&_sharedmemory);
ptrdiff_t rel_offset = searchSharedMemoryBlock(base);
if (rel_offset > -1) {
FPS_shared = (uint8_t*)(base + rel_offset + 4);
FPSavg_shared = (float*)(base + rel_offset + 5);
pluginActive = (bool*)(base + rel_offset + 9);
API_shared = (uint8_t*)(base + rel_offset + 14);
FPSticks_shared = (uint32_t*)(base + rel_offset + 15);
renderCalls_shared = (resolutionCalls*)(base + rel_offset + 60);
viewportCalls_shared = (resolutionCalls*)(base + rel_offset + 60 + (sizeof(resolutionCalls) * 8));
*pluginActive = false;
searchSharedMemoryBlock(base);
if (NxFps) {
(NxFps -> pluginActive) = false;
svcSleepThread(100'000'000);
if (*pluginActive) {
if ((NxFps -> pluginActive)) {
GameRunning = true;
check = false;
}
Expand Down Expand Up @@ -488,8 +497,8 @@ void Misc(void*) {
//FPS
if (GameRunning) {
if (SharedMemoryUsed) {
FPS = *FPS_shared;
FPSavg = 19'200'000.f / (std::accumulate<uint32_t*, float>(FPSticks_shared, FPSticks_shared+10, 0) / 10);
FPS = (NxFps -> FPS);
FPSavg = 19'200'000.f / (std::accumulate<uint32_t*, float>(&(NxFps -> FPSticks[0]), &(NxFps -> FPSticks[10]), 0) / 10);
}
}
else FPSavg = 254;
Expand Down Expand Up @@ -623,8 +632,8 @@ void FPSCounter(void*) {
while (!threadexit) {
if (GameRunning) {
if (SharedMemoryUsed) {
FPS = *FPS_shared;
FPSavg = 19'200'000.f / (std::accumulate<uint32_t*, float>(FPSticks_shared, FPSticks_shared+10, 0) / 10);
FPS = (NxFps -> FPS);
FPSavg = 19'200'000.f / (std::accumulate<uint32_t*, float>(&(NxFps -> FPSticks[0]), &(NxFps -> FPSticks[10]), 0) / 10);
}
}
else FPSavg = 254;
Expand Down
23 changes: 14 additions & 9 deletions source/modes/FPS_Graph.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,25 +186,30 @@ class com_FPSGraph : public tsl::Gui {
else if (performanceMode == ApmPerformanceMode_Normal) {
isDocked = false;
}

if (!isDocked && isStarted && FPSavg_old != 0 && FPSavg_old == FPSavg) {
if (R_SUCCEEDED(SaltySD_Connect())) {
if (R_FAILED(SaltySD_GetDisplayRefreshRate(&refreshRate)))
refreshRate = 0;
svcSleepThread(100'000'000);
SaltySD_Term();
}

if (!isDocked && isStarted && FPSavg_old != 0) {
uint8_t SaltySharedDisplayRefreshRate = *(uint8_t*)((uintptr_t)shmemGetAddr(&_sharedmemory) + 1);
if (SaltySharedDisplayRefreshRate) refreshRate = SaltySharedDisplayRefreshRate;
else if (FPSavg_old == FPSavg) {
if (R_SUCCEEDED(SaltySD_Connect())) {
if (R_FAILED(SaltySD_GetDisplayRefreshRate(&refreshRate)))
refreshRate = 0;
svcSleepThread(100'000'000);
SaltySD_Term();
}
}
}

if (FPSavg_old == FPSavg)
return;

FPSavg_old = FPSavg;
snprintf(FPSavg_c, sizeof FPSavg_c, "%2.1f", FPSavg);
if (FPSavg < 254) {
if (!isStarted) {
if (!isDocked && R_SUCCEEDED(SaltySD_Connect())) {
if (R_FAILED(SaltySD_GetDisplayRefreshRate(&refreshRate)))
refreshRate = 0;
svcSleepThread(100'000);
SaltySD_Term();
isStarted = true;
}
Expand Down
21 changes: 10 additions & 11 deletions source/modes/Full.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ class FullOverlay : public tsl::Gui {
uint8_t COMMON_MARGIN = 20;
FullSettings settings;
uint64_t systemtickfrequency_impl = systemtickfrequency;
std::string formattedKeyCombo = keyCombo;
std::string message = "Hold to Exit";
public:
FullOverlay() {
GetConfigSettings(&settings);
Expand All @@ -37,6 +39,8 @@ class FullOverlay : public tsl::Gui {
tsl::gfx::Renderer::getRenderer().setLayerPos(1248, 0);
}
deactivateOriginalFooter = true;
formatButtonCombination(formattedKeyCombo);
message = "Hold " + formattedKeyCombo + " to Exit";
StartThreads();
}
~FullOverlay() {
Expand Down Expand Up @@ -178,18 +182,13 @@ class FullOverlay : public tsl::Gui {
uint32_t offset = COMMON_MARGIN + width_offset + dimensions.first;
renderer->drawString(FPS_var_compressed_c, false, offset, 120, 20, renderer->a(0xFFFF));
}
if ((settings.showRES == true) && *API_shared == 1) {
if ((settings.showRES == true) && (NxFps -> API) == 1) {
width_offset = 170;
renderer->drawString("Resolution:", false, COMMON_MARGIN + width_offset, 185, 20, renderer->a(0xFFFF));
renderer->drawString(Resolutions_c, false, COMMON_MARGIN + width_offset, 205, 20, renderer->a(0xFFFF));
}
}

std::string formattedKeyCombo = keyCombo;
formatButtonCombination(formattedKeyCombo);

std::string message = "Hold " + formattedKeyCombo + " to Exit";

renderer->drawString(message.c_str(), false, COMMON_MARGIN, 693, 23, renderer->a(0xFFFF));

});
Expand Down Expand Up @@ -269,17 +268,17 @@ class FullOverlay : public tsl::Gui {
snprintf(FPS_var_compressed_c, sizeof FPS_var_compressed_c, "%u\n%2.1f", FPS, FPSavg);

//Resolutions
if ((settings.showRES == true) && GameRunning && renderCalls_shared) {
if ((settings.showRES == true) && GameRunning && NxFps) {
if (!resolutionLookup) {
renderCalls_shared[0].calls = 0xFFFF;
(NxFps -> renderCalls[0].calls) = 0xFFFF;
resolutionLookup = 1;
}
else if (resolutionLookup == 1) {
if (renderCalls_shared[0].calls != 0xFFFF) resolutionLookup = 2;
if ((NxFps -> renderCalls[0].calls) != 0xFFFF) resolutionLookup = 2;
}
else {
memcpy(&m_resolutionRenderCalls, renderCalls_shared, sizeof(m_resolutionRenderCalls));
memcpy(&m_resolutionViewportCalls, viewportCalls_shared, sizeof(m_resolutionViewportCalls));
memcpy(&m_resolutionRenderCalls, &(NxFps -> renderCalls), sizeof(m_resolutionRenderCalls));
memcpy(&m_resolutionViewportCalls, &(NxFps -> viewportCalls), sizeof(m_resolutionViewportCalls));
qsort(m_resolutionRenderCalls, 8, sizeof(resolutionCalls), compare);
qsort(m_resolutionViewportCalls, 8, sizeof(resolutionCalls), compare);
memset(&m_resolutionOutput, 0, sizeof(m_resolutionOutput));
Expand Down
14 changes: 7 additions & 7 deletions source/modes/Mini.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -329,17 +329,17 @@ class MiniOverlay : public tsl::Gui {
skin_temperaturemiliC / 1000, (skin_temperaturemiliC / 100) % 10);
snprintf(Rotation_SpeedLevel_c, sizeof Rotation_SpeedLevel_c, "%2.1f%%", Rotation_Duty);

if (GameRunning && renderCalls_shared && resolutionShow) {
if (GameRunning && NxFps && resolutionShow) {
if (!resolutionLookup) {
renderCalls_shared[0].calls = 0xFFFF;
(NxFps -> renderCalls[0].calls) = 0xFFFF;
resolutionLookup = 1;
}
else if (resolutionLookup == 1) {
if (renderCalls_shared[0].calls != 0xFFFF) resolutionLookup = 2;
if ((NxFps -> renderCalls[0].calls) != 0xFFFF) resolutionLookup = 2;
}
else {
memcpy(&m_resolutionRenderCalls, renderCalls_shared, sizeof(m_resolutionRenderCalls));
memcpy(&m_resolutionViewportCalls, viewportCalls_shared, sizeof(m_resolutionViewportCalls));
memcpy(&m_resolutionRenderCalls, &(NxFps -> renderCalls), sizeof(m_resolutionRenderCalls));
memcpy(&m_resolutionViewportCalls, &(NxFps -> viewportCalls), sizeof(m_resolutionViewportCalls));
qsort(m_resolutionRenderCalls, 8, sizeof(resolutionCalls), compare);
qsort(m_resolutionViewportCalls, 8, sizeof(resolutionCalls), compare);
memset(&m_resolutionOutput, 0, sizeof(m_resolutionOutput));
Expand Down Expand Up @@ -458,10 +458,10 @@ class MiniOverlay : public tsl::Gui {
strcat(Temp, "\n");
}
char Temp_s[32] = "";
if (*API_shared == 2) {
if (NxFps -> API == 2) {
snprintf(Temp_s, sizeof(Temp_s), "EGL");
}
else if (*API_shared == 3) {
else if (NxFps -> API == 3) {
snprintf(Temp_s, sizeof(Temp_s), "Vulkan");
}
else snprintf(Temp_s, sizeof(Temp_s), "%dx%d || %dx%d", m_resolutionOutput[0].width, m_resolutionOutput[0].height, m_resolutionOutput[1].width, m_resolutionOutput[1].height);
Expand Down
14 changes: 7 additions & 7 deletions source/modes/Resolutions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ class ResolutionsOverlay : public tsl::Gui {
break;
}

if (gameStart && *API_shared == 1) {
if (gameStart && NxFps -> API == 1) {
renderer->drawRect(base_x, base_y, 360, 200, a(settings.backgroundColor));

renderer->drawString("Depth:", false, base_x+20, base_y+20, 20, renderer->a(settings.catColor));
Expand All @@ -96,7 +96,7 @@ class ResolutionsOverlay : public tsl::Gui {
base_y = 692;
break;
}
if (gameStart && *API_shared > 1) {
if (gameStart && NxFps -> API > 1) {
renderer->drawRect(base_x, base_y, 360, 28, a(settings.backgroundColor));
renderer->drawString("Game doesn't use NVN, it's incompatible.", false, base_x, base_y+20, 18, renderer->a(0xF00F));
}
Expand All @@ -114,17 +114,17 @@ class ResolutionsOverlay : public tsl::Gui {

virtual void update() override {

if (gameStart && renderCalls_shared) {
if (gameStart && NxFps) {
if (!resolutionLookup) {
renderCalls_shared[0].calls = 0xFFFF;
NxFps -> renderCalls[0].calls = 0xFFFF;
resolutionLookup = 1;
}
else if (resolutionLookup == 1) {
if (renderCalls_shared[0].calls != 0xFFFF) resolutionLookup = 2;
if ((NxFps -> renderCalls[0].calls) != 0xFFFF) resolutionLookup = 2;
else return;
}
memcpy(&m_resolutionRenderCalls, renderCalls_shared, sizeof(m_resolutionRenderCalls));
memcpy(&m_resolutionViewportCalls, viewportCalls_shared, sizeof(m_resolutionViewportCalls));
memcpy(&m_resolutionRenderCalls, &(NxFps -> renderCalls), sizeof(m_resolutionRenderCalls));
memcpy(&m_resolutionViewportCalls, &(NxFps -> viewportCalls), sizeof(m_resolutionViewportCalls));
qsort(m_resolutionRenderCalls, 8, sizeof(resolutionCalls), compare);
qsort(m_resolutionViewportCalls, 8, sizeof(resolutionCalls), compare);
snprintf(Resolutions_c, sizeof Resolutions_c,
Expand Down

0 comments on commit ce343de

Please sign in to comment.