Skip to content

Commit

Permalink
main, refresh_rate.h: add support for passing decimal refresh rates t…
Browse files Browse the repository at this point in the history
…o gamescope thru the command line (-r, -o)
  • Loading branch information
sharkautarch committed Aug 12, 2024
1 parent e31b8de commit f2a1282
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 2 deletions.
27 changes: 25 additions & 2 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,29 @@ static bool IsInDebugSession()
return nTracePid != 0;
}
#endif
namespace gamescope {
static int32_t ConvertHztomHz( char* refreshHz ) {
std::vector svParts = Split(refreshHz, ".,");

size_t ulWholeNumLen = svParts[0].size();
if (svParts.size() > 1)
refreshHz[ulWholeNumLen] = '\0'; //replace the decimal separator with null terminator, so that atol can be used
uint64_t ulWholeNum = (uint64_t) atol(refreshHz);

std::array<uint64_t, 2> decimalParts = [svParts]() -> std::array<uint64_t, 2> {
if (svParts.size()>1)
return {(uint64_t)atol(svParts[1].data()), (uint64_t)svParts[1].size()};
return {0ul, 1ul};
}();
const uint64_t ulDec = decimalParts[0], ulDecLen = decimalParts[1];

uint64_t ulDecDenom = (uint64_t)lrintf(powf(10.0f, (int32_t)ulDecLen));
uint64_t ulMultiplied = ulWholeNum * 1'000lu * ulDecDenom + ulDec * 1'000lu; //don't divide the decimal part by its denominator(/number of decimal places) first, instead multiply the wholeNum by the number of decimal places, and then divide the result of adding the multiplied wholeNum & decimal parts.

//This, along with doing all intermediate calculations w/ 64-bit unsigned ints, ensures there's no precision loss.
return (int32_t)(ulMultiplied/ulDecDenom);
}
}

bool steamMode = false;
bool g_bLaunchMangoapp = false;
Expand Down Expand Up @@ -684,7 +707,7 @@ int main(int argc, char **argv)
g_nNestedHeight = atoi( optarg );
break;
case 'r':
g_nNestedRefresh = gamescope::ConvertHztomHz( atoi( optarg ) );
g_nNestedRefresh = gamescope::ConvertHztomHz( optarg );
break;
case 'W':
g_nPreferredOutputWidth = atoi( optarg );
Expand All @@ -693,7 +716,7 @@ int main(int argc, char **argv)
g_nPreferredOutputHeight = atoi( optarg );
break;
case 'o':
g_nNestedUnfocusedRefresh = gamescope::ConvertHztomHz( atoi( optarg ) );
g_nNestedUnfocusedRefresh = gamescope::ConvertHztomHz( optarg );
break;
case 'm':
g_flMaxWindowScale = atof( optarg );
Expand Down
3 changes: 3 additions & 0 deletions src/refresh_rate.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

namespace gamescope
{
int32_t ConvertHztomHz( const char* refreshHz ); //function definition in main.cpp
//function definition not included here, because having the function definition here gave me linker errors - sharkautarch

constexpr int32_t ConvertHztomHz( int32_t nRefreshHz )
{
return nRefreshHz * 1'000;
Expand Down

0 comments on commit f2a1282

Please sign in to comment.