From ce343decd0e9a58e2b18c7ffcca677f7ab17be29 Mon Sep 17 00:00:00 2001 From: MasaGratoR Date: Tue, 5 Nov 2024 19:01:35 +0100 Subject: [PATCH] Support SaltyNX 1.0.3 refresh rate, small code refactor (#87) --- Makefile | 4 +- source/Utils.hpp | 85 ++++++++++++++++++++---------------- source/modes/FPS_Graph.hpp | 23 ++++++---- source/modes/Full.hpp | 21 +++++---- source/modes/Mini.hpp | 14 +++--- source/modes/Resolutions.hpp | 14 +++--- 6 files changed, 87 insertions(+), 74 deletions(-) diff --git a/Makefile b/Makefile index 01e08c17..46a99a8d 100755 --- a/Makefile +++ b/Makefile @@ -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 @@ -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)\"" diff --git a/source/Utils.hpp b/source/Utils.hpp index 929405db..a0b0b538 100644 --- a/source/Utils.hpp +++ b/source/Utils.hpp @@ -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; @@ -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; @@ -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 @@ -247,10 +263,10 @@ 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; } @@ -258,18 +274,11 @@ void CheckIfGameRunning(void*) { } 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; } @@ -488,8 +497,8 @@ void Misc(void*) { //FPS if (GameRunning) { if (SharedMemoryUsed) { - FPS = *FPS_shared; - FPSavg = 19'200'000.f / (std::accumulate(FPSticks_shared, FPSticks_shared+10, 0) / 10); + FPS = (NxFps -> FPS); + FPSavg = 19'200'000.f / (std::accumulate(&(NxFps -> FPSticks[0]), &(NxFps -> FPSticks[10]), 0) / 10); } } else FPSavg = 254; @@ -623,8 +632,8 @@ void FPSCounter(void*) { while (!threadexit) { if (GameRunning) { if (SharedMemoryUsed) { - FPS = *FPS_shared; - FPSavg = 19'200'000.f / (std::accumulate(FPSticks_shared, FPSticks_shared+10, 0) / 10); + FPS = (NxFps -> FPS); + FPSavg = 19'200'000.f / (std::accumulate(&(NxFps -> FPSticks[0]), &(NxFps -> FPSticks[10]), 0) / 10); } } else FPSavg = 254; diff --git a/source/modes/FPS_Graph.hpp b/source/modes/FPS_Graph.hpp index 3db7db98..d35e77fe 100644 --- a/source/modes/FPS_Graph.hpp +++ b/source/modes/FPS_Graph.hpp @@ -186,17 +186,23 @@ 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) { @@ -204,7 +210,6 @@ class com_FPSGraph : public tsl::Gui { if (!isDocked && R_SUCCEEDED(SaltySD_Connect())) { if (R_FAILED(SaltySD_GetDisplayRefreshRate(&refreshRate))) refreshRate = 0; - svcSleepThread(100'000); SaltySD_Term(); isStarted = true; } diff --git a/source/modes/Full.hpp b/source/modes/Full.hpp index 98c9881d..77f18710 100644 --- a/source/modes/Full.hpp +++ b/source/modes/Full.hpp @@ -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); @@ -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() { @@ -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)); }); @@ -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)); diff --git a/source/modes/Mini.hpp b/source/modes/Mini.hpp index 1e22ef86..50c9acaa 100644 --- a/source/modes/Mini.hpp +++ b/source/modes/Mini.hpp @@ -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)); @@ -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); diff --git a/source/modes/Resolutions.hpp b/source/modes/Resolutions.hpp index 98901ad5..0150e515 100644 --- a/source/modes/Resolutions.hpp +++ b/source/modes/Resolutions.hpp @@ -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)); @@ -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)); } @@ -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,