From c421b7a13a98b2a30bf115aa2031acc0dd64f9ed Mon Sep 17 00:00:00 2001 From: fallenoak Date: Wed, 19 Nov 2025 22:16:53 -0600 Subject: [PATCH] feat(ui): implement Script_GetRefreshRates --- src/ui/game/CGVideoOptionsScript.cpp | 69 +++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) diff --git a/src/ui/game/CGVideoOptionsScript.cpp b/src/ui/game/CGVideoOptionsScript.cpp index 2c45b1a..bea2483 100644 --- a/src/ui/game/CGVideoOptionsScript.cpp +++ b/src/ui/game/CGVideoOptionsScript.cpp @@ -12,6 +12,17 @@ static TSGrowableArray s_multisampleFormats; static TSGrowableArray s_screenResolutions; +int32_t SortRefreshRates(const void* a, const void* b) { + auto rateA = static_cast(a); + auto rateB = static_cast(b); + + if (*rateA >= *rateB) { + return *rateB < *rateA; + } + + return -1; +} + void SetupFormats() { if (s_multisampleFormats.Count()) { return; @@ -147,7 +158,63 @@ int32_t Script_SetScreenResolution(lua_State* L) { } int32_t Script_GetRefreshRates(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + // Load available resolutions + + SetupResolutions(); + + // Find matching resolution + + uint32_t resolutionIndex = 0; + + if (lua_isnumber(L, 1)) { + if (lua_tonumber(L, 1) - 1 < s_screenResolutions.Count()) { + resolutionIndex = static_cast(lua_tonumber(L, 1)) - 1; + } else { + resolutionIndex = s_screenResolutions.Count(); + } + } + + if (resolutionIndex >= s_screenResolutions.Count()) { + return 0; + } + + auto& screenResolution = s_screenResolutions[resolutionIndex]; + + // Load available monitor modes + + TSGrowableArray monitorModes; + GxAdapterMonitorModes(monitorModes); + + // Find refresh rates matching desired resolution + + uint32_t rateCount = 0; + auto refreshRates = static_cast(alloca(sizeof(uint32_t) * monitorModes.Count())); + + for (uint32_t i = 0; i < monitorModes.Count(); i++) { + auto& monitorMode = monitorModes[i]; + + if (monitorMode.size.x == screenResolution.x && monitorMode.size.y == screenResolution.y) { + refreshRates[rateCount++] = monitorModes[i].refreshRate; + } + } + + // Sort refresh rates + + if (rateCount > 0) { + qsort(refreshRates, rateCount, sizeof(uint32_t), &SortRefreshRates); + } + + // Return sorted refresh rates + + int32_t nargs = 0; + for (uint32_t i = 0; i < rateCount; i++) { + if (i == 0 || refreshRates[i] != refreshRates[i - 1]) { + lua_pushnumber(L, refreshRates[i]); + nargs++; + } + } + + return nargs; } int32_t Script_SetupFullscreenScale(lua_State* L) {