port: changes to the video settings PR:

- change FPS calculation to use average FPS, use real time instead of render time for interval timing

- remove Maximize Window (you already have a maximize button and it's saved to the INI)

- remove Display FPS Interval from settings (the average user won't care and whoever cares can change it in the INI)

- remove the tickrate override flag and implicit tickrate adjustment in the framerate limit option, instead add one checkbox to uncap tickrate (mostly because I'd like the game to default to the og 60 FPS cap since high FPS is still unstable)

- rearrange some options a bit
This commit is contained in:
fgsfds committed 2025-02-22 13:22:00 +01:00
1 parent e3104b7043
commit ac4f317879
6 files changed
+73 -161

No files matched your search

+3 -3
View File
@@ -21,7 +21,6 @@ void videoStartFrame(void);
void videoSubmitCommands(Gfx *cmds); void videoSubmitCommands(Gfx *cmds);
void videoClearScreen(void); void videoClearScreen(void);
void videoEndFrame(void); void videoEndFrame(void);
f64 videoGetDiffTime(void);
void *videoGetWindowHandle(void); void *videoGetWindowHandle(void);
@@ -47,9 +46,11 @@ s32 videoGetNumDisplayModes(void);
s32 videoGetVsync(void); s32 videoGetVsync(void);
s32 videoGetFramerateLimit(void); s32 videoGetFramerateLimit(void);
s32 videoGetDisplayFPS(void); s32 videoGetDisplayFPS(void);
s32 videoGetDisplayFPSDivisor(void);
s32 videoGetMSAA(void); s32 videoGetMSAA(void);
f32 videoGetAverageFPS(void);
f64 videoGetLastRenderTime(void);
void videoSetWindowOffset(s32 x, s32 y); void videoSetWindowOffset(s32 x, s32 y);
void videoSetFullscreen(s32 fs); void videoSetFullscreen(s32 fs);
void videoSetFullscreenMode(s32 mode); void videoSetFullscreenMode(s32 mode);
@@ -60,7 +61,6 @@ void videoSetDisplayMode(const s32 index);
void videoSetVsync(const s32 vsync); void videoSetVsync(const s32 vsync);
void videoSetFramerateLimit(const s32 limit); void videoSetFramerateLimit(const s32 limit);
void videoSetDisplayFPS(const s32 displayfps); void videoSetDisplayFPS(const s32 displayfps);
void videoSetDisplayFPSDivisor(const s32 divisor);
void videoSetMSAA(const s32 msaa); void videoSetMSAA(const s32 msaa);
s32 videoCreateFramebuffer(u32 w, u32 h, s32 upscale, s32 autoresize); s32 videoCreateFramebuffer(u32 w, u32 h, s32 upscale, s32 autoresize);
-2
View File
@@ -36,7 +36,6 @@ u32 g_VmNumPageReplaces = 0;
u8 g_VmShowStats = 0; u8 g_VmShowStats = 0;
s32 g_TickRateDiv = 1; s32 g_TickRateDiv = 1;
s32 g_TickRateDivOverride = 0;
s32 g_TickExtraSleep = true; s32 g_TickExtraSleep = true;
s32 g_SkipIntro = false; s32 g_SkipIntro = false;
@@ -166,7 +165,6 @@ PD_CONSTRUCTOR static void gameConfigInit(void)
configRegisterInt("Game.MenuMouseControl", &g_MenuMouseControl, 0, 1); configRegisterInt("Game.MenuMouseControl", &g_MenuMouseControl, 0, 1);
configRegisterFloat("Game.ScreenShakeIntensity", &g_ViShakeIntensityMult, 0.f, 10.f); configRegisterFloat("Game.ScreenShakeIntensity", &g_ViShakeIntensityMult, 0.f, 10.f);
configRegisterInt("Game.TickRateDivisor", &g_TickRateDiv, 0, 10); configRegisterInt("Game.TickRateDivisor", &g_TickRateDiv, 0, 10);
configRegisterInt("Game.TickRateDivisorOverride", &g_TickRateDivOverride, 0, 1);
configRegisterInt("Game.ExtraSleep", &g_TickExtraSleep, 0, 1); configRegisterInt("Game.ExtraSleep", &g_TickExtraSleep, 0, 1);
configRegisterInt("Game.SkipIntro", &g_SkipIntro, 0, 1); configRegisterInt("Game.SkipIntro", &g_SkipIntro, 0, 1);
configRegisterInt("Game.DisableMpDeathMusic", &g_MusicDisableMpDeath, 0, 1); configRegisterInt("Game.DisableMpDeathMusic", &g_MusicDisableMpDeath, 0, 1);
+24 -123
View File
@@ -721,19 +721,6 @@ static MenuItemHandlerResult menuhandlerFullScreenMode(s32 operation, struct men
return 0; return 0;
} }
static MenuItemHandlerResult menuhandlerMaximizeWindow(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
case MENUOP_GET:
return videoGetMaximizeWindow();
case MENUOP_SET:
videoSetMaximizeWindow(data->checkbox.value);
break;
}
return 0;
}
static MenuItemHandlerResult menuhandlerCenterWindow(s32 operation, struct menuitem *item, union handlerdata *data) static MenuItemHandlerResult menuhandlerCenterWindow(s32 operation, struct menuitem *item, union handlerdata *data)
{ {
switch (operation) { switch (operation) {
@@ -786,9 +773,6 @@ static MenuItemHandlerResult menuhandlerFramerateLimit(s32 operation, struct men
data->slider.value = videoGetFramerateLimit(); data->slider.value = videoGetFramerateLimit();
break; break;
case MENUOP_SET: case MENUOP_SET:
if (!g_TickRateDivOverride) {
g_TickRateDiv = (data->slider.value == 0 || data->slider.value > 60) ? 0 : 1;
}
videoSetFramerateLimit(data->slider.value); videoSetFramerateLimit(data->slider.value);
break; break;
case MENUOP_GETSLIDERLABEL: case MENUOP_GETSLIDERLABEL:
@@ -937,27 +921,6 @@ static MenuItemHandlerResult menuhandlerDisplayFPS(s32 operation, struct menuite
return 0; return 0;
} }
static MenuItemHandlerResult menuhandlerDisplayFPSInterval(s32 operation, struct menuitem *item, union handlerdata *data)
{
switch (operation) {
case MENUOP_GETSLIDER:
data->slider.value = videoGetDisplayFPSDivisor() - 1;
break;
case MENUOP_SET:
videoSetDisplayFPSDivisor(data->dropdown.value + 1);
break;
case MENUOP_GETSLIDERLABEL:
// NOTE: data->slider.label length must not exceed 15.
if (data->slider.value == 0) {
strcpy(data->slider.label, "1 Sec");
} else {
sprintf(data->slider.label, "1/%d Secs", data->slider.value + 1);
}
}
return 0;
}
static MenuItemHandlerResult menuhandlerGeMuzzleFlashes(s32 operation, struct menuitem *item, union handlerdata *data) static MenuItemHandlerResult menuhandlerGeMuzzleFlashes(s32 operation, struct menuitem *item, union handlerdata *data)
{ {
switch (operation) { switch (operation) {
@@ -971,44 +934,14 @@ static MenuItemHandlerResult menuhandlerGeMuzzleFlashes(s32 operation, struct me
return 0; return 0;
} }
static MenuItemHandlerResult menuhandlerTickrateDivisorOverride(s32 operation, struct menuitem *item, union handlerdata *data) static MenuItemHandlerResult menuhandlerUncapTickrate(s32 operation, struct menuitem *item, union handlerdata *data)
{ {
s32 framerateLimit;
switch (operation) { switch (operation) {
case MENUOP_GET: case MENUOP_GET:
return g_TickRateDivOverride; return (g_TickRateDiv == 0);
case MENUOP_SET: case MENUOP_SET:
g_TickRateDivOverride = data->checkbox.value; g_TickRateDiv = !data->checkbox.value;
if (!g_TickRateDivOverride) {
framerateLimit = videoGetFramerateLimit();
g_TickRateDiv = (framerateLimit == 0 || framerateLimit > 60) ? 0 : 1;
}
}
return 0;
}
static MenuItemHandlerResult menuhandlerTickrateDivisor(s32 operation, struct menuitem *item, union handlerdata *data)
{
s32 framerateLimit;
switch (operation) {
case MENUOP_CHECKHIDDEN:
if (!g_TickRateDivOverride) {
return true;
}
break; break;
case MENUOP_GETSLIDER:
data->slider.value = g_TickRateDiv;
break;
case MENUOP_SET:
if (g_TickRateDivOverride) {
g_TickRateDiv = data->slider.value;
} else {
framerateLimit = videoGetFramerateLimit();
g_TickRateDiv = (framerateLimit == 0 || framerateLimit > 60) ? 0 : 1;
}
} }
return 0; return 0;
@@ -1087,14 +1020,6 @@ struct menuitem g_ExtendedVideoMenuItems[] = {
0, 0,
menuhandlerResolution, menuhandlerResolution,
}, },
{
MENUITEMTYPE_CHECKBOX,
0,
MENUITEMFLAG_LITERAL_TEXT,
(uintptr_t)"Maximize Window",
0,
menuhandlerMaximizeWindow,
},
{ {
MENUITEMTYPE_CHECKBOX, MENUITEMTYPE_CHECKBOX,
0, 0,
@@ -1107,9 +1032,9 @@ struct menuitem g_ExtendedVideoMenuItems[] = {
MENUITEMTYPE_DROPDOWN, MENUITEMTYPE_DROPDOWN,
0, 0,
MENUITEMFLAG_LITERAL_TEXT, MENUITEMFLAG_LITERAL_TEXT,
(uintptr_t)"HUD Centering", (uintptr_t)"Anti-aliasing",
0, 0,
menuhandlerCenterHUD, menuhandlerMSAA,
}, },
{ {
MENUITEMTYPE_SEPARATOR, MENUITEMTYPE_SEPARATOR,
@@ -1135,6 +1060,14 @@ struct menuitem g_ExtendedVideoMenuItems[] = {
VIDEO_MAX_FPS, VIDEO_MAX_FPS,
menuhandlerFramerateLimit, menuhandlerFramerateLimit,
}, },
{
MENUITEMTYPE_CHECKBOX,
0,
MENUITEMFLAG_LITERAL_TEXT,
(uintptr_t)"Uncap Tickrate",
0,
menuhandlerUncapTickrate,
},
{ {
MENUITEMTYPE_CHECKBOX, MENUITEMTYPE_CHECKBOX,
0, 0,
@@ -1143,14 +1076,6 @@ struct menuitem g_ExtendedVideoMenuItems[] = {
0, 0,
menuhandlerDisplayFPS, menuhandlerDisplayFPS,
}, },
{
MENUITEMTYPE_SLIDER,
0,
MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_WIDE,
(uintptr_t)"Display FPS Interval",
31,
menuhandlerDisplayFPSInterval,
},
{ {
MENUITEMTYPE_SEPARATOR, MENUITEMTYPE_SEPARATOR,
0, 0,
@@ -1159,14 +1084,6 @@ struct menuitem g_ExtendedVideoMenuItems[] = {
0, 0,
NULL, NULL,
}, },
{
MENUITEMTYPE_DROPDOWN,
0,
MENUITEMFLAG_LITERAL_TEXT,
(uintptr_t)"Anti-aliasing",
0,
menuhandlerMSAA,
},
{ {
MENUITEMTYPE_DROPDOWN, MENUITEMTYPE_DROPDOWN,
0, 0,
@@ -1183,6 +1100,14 @@ struct menuitem g_ExtendedVideoMenuItems[] = {
0, 0,
menuhandlerTexFilter2D, menuhandlerTexFilter2D,
}, },
{
MENUITEMTYPE_CHECKBOX,
0,
MENUITEMFLAG_LITERAL_TEXT,
(uintptr_t)"Detail Textures",
0,
menuhandlerTexDetail,
},
{ {
MENUITEMTYPE_SEPARATOR, MENUITEMTYPE_SEPARATOR,
0, 0,
@@ -1192,12 +1117,12 @@ struct menuitem g_ExtendedVideoMenuItems[] = {
NULL, NULL,
}, },
{ {
MENUITEMTYPE_CHECKBOX, MENUITEMTYPE_DROPDOWN,
0, 0,
MENUITEMFLAG_LITERAL_TEXT, MENUITEMFLAG_LITERAL_TEXT,
(uintptr_t)"Detail Textures", (uintptr_t)"HUD Centering",
0, 0,
menuhandlerTexDetail, menuhandlerCenterHUD,
}, },
{ {
MENUITEMTYPE_CHECKBOX, MENUITEMTYPE_CHECKBOX,
@@ -1223,30 +1148,6 @@ struct menuitem g_ExtendedVideoMenuItems[] = {
0, 0,
NULL, NULL,
}, },
{
MENUITEMTYPE_CHECKBOX,
0,
MENUITEMFLAG_LITERAL_TEXT,
(uintptr_t)"Override Tickrate Divisor",
0,
menuhandlerTickrateDivisorOverride,
},
{
MENUITEMTYPE_SLIDER,
0,
MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_WIDE,
(uintptr_t)"Tickrate Divisor",
10,
menuhandlerTickrateDivisor,
},
{
MENUITEMTYPE_SEPARATOR,
0,
0,
0,
0,
NULL,
},
{ {
MENUITEMTYPE_SELECTABLE, MENUITEMTYPE_SELECTABLE,
0, 0,
+29 -25
View File
@@ -41,20 +41,26 @@ static s32 vidAllowHiDpi = false;
static s32 vidVsync = 1; static s32 vidVsync = 1;
static s32 vidMSAA = 1; static s32 vidMSAA = 1;
static s32 vidFramerateLimit = 0; static s32 vidFramerateLimit = 0;
static s32 vidDisplayFPS = 0; static s32 vidDisplayFPS = 0;
static s32 vidDisplayFPSDivisor = 16; static f32 vidDisplayFPSInterval = 1.f;
static displaymode vidModeDefault; static f32 vidAvgFPS = 0;
static f64 vidLastRenderTime;
static s32 vidNumModes = 1; static s32 vidNumModes = 1;
static displaymode vidModeDefault;
static displaymode *vidModes = &vidModeDefault; static displaymode *vidModes = &vidModeDefault;
static f64 vidDiffTime;
static s32 texFilter = FILTER_LINEAR; static s32 texFilter = FILTER_LINEAR;
static s32 texFilter2D = true; static s32 texFilter2D = true;
static s32 texDetail = true; static s32 texDetail = false;
static u32 dlcount = 0; static u32 dlcount = 0;
static u32 frames = 0; static u32 frames = 0;
static f64 startTime, endTime; static f64 startTime, endTime;
static f64 accumDelta = 0.0;
static f64 fpsTime = 0.0;
static s32 fpsNumFrames = 0;
static s32 videoInitDisplayModes(void); static s32 videoInitDisplayModes(void);
@@ -121,8 +127,6 @@ void videoSubmitCommands(Gfx *cmds)
void videoEndFrame(void) void videoEndFrame(void)
{ {
static f64 accumTime = 0.0;
if (!initDone) { if (!initDone) {
return; return;
} }
@@ -130,22 +134,32 @@ void videoEndFrame(void)
gfx_end_frame(); gfx_end_frame();
++frames; ++frames;
++fpsNumFrames;
endTime = wmAPI->get_time(); const f64 flipTime = wmAPI->get_time();
accumTime += endTime - startTime; accumDelta += flipTime - endTime;
endTime = flipTime;
vidLastRenderTime = endTime - startTime;
if (accumTime >= 1.0 / (f64)vidDisplayFPSDivisor) { if (endTime >= fpsTime) {
char tmp[128]; char tmp[128];
vidDiffTime = endTime - startTime; vidAvgFPS = fpsNumFrames ? ((f64)fpsNumFrames / accumDelta) : 0.f;
accumTime = 0.0; fpsNumFrames = 0;
snprintf(tmp, sizeof(tmp), "fps %3u frt %lf frm %u", (u32)(1.0 / vidDiffTime), vidDiffTime, frames); accumDelta = 0.0;
snprintf(tmp, sizeof(tmp), "fps %4.1f frt %lf frm %u", vidAvgFPS, vidLastRenderTime, frames);
wmAPI->set_window_title(tmp); wmAPI->set_window_title(tmp);
fpsTime = endTime + vidDisplayFPSInterval;
} }
} }
f64 videoGetDiffTime(void) f64 videoGetLastRenderTime(void)
{ {
return vidDiffTime; return vidLastRenderTime;
}
f32 videoGetAverageFPS(void)
{
return vidAvgFPS;
} }
void videoClearScreen(void) void videoClearScreen(void)
@@ -253,11 +267,6 @@ s32 videoGetDisplayFPS(void)
return vidDisplayFPS; return vidDisplayFPS;
} }
s32 videoGetDisplayFPSDivisor(void)
{
return vidDisplayFPSDivisor;
}
static s32 videoInitDisplayModes(void) static s32 videoInitDisplayModes(void)
{ {
if (!wmAPI->get_current_display_mode(&vidModeDefault.width, &vidModeDefault.height)) { if (!wmAPI->get_current_display_mode(&vidModeDefault.width, &vidModeDefault.height)) {
@@ -470,11 +479,6 @@ void videoSetDisplayFPS(const s32 displayfps)
vidDisplayFPS = displayfps; vidDisplayFPS = displayfps;
} }
void videoSetDisplayFPSDivisor(const s32 divisor)
{
vidDisplayFPSDivisor = divisor;
}
void videoSetFramebuffer(s32 target) void videoSetFramebuffer(s32 target)
{ {
return gfx_set_framebuffer(target, 1.f); return gfx_set_framebuffer(target, 1.f);
@@ -529,7 +533,7 @@ PD_CONSTRUCTOR static void videoConfigInit(void)
configRegisterInt("Video.FramebufferEffects", &vidFramebuffers, 0, 1); configRegisterInt("Video.FramebufferEffects", &vidFramebuffers, 0, 1);
configRegisterInt("Video.FramerateLimit", &vidFramerateLimit, 0, VIDEO_MAX_FPS); configRegisterInt("Video.FramerateLimit", &vidFramerateLimit, 0, VIDEO_MAX_FPS);
configRegisterInt("Video.DisplayFPS", &vidDisplayFPS, 0, 1); configRegisterInt("Video.DisplayFPS", &vidDisplayFPS, 0, 1);
configRegisterInt("Video.DisplayFPSDivisor", &vidDisplayFPSDivisor, 1, 32); configRegisterFloat("Video.DisplayFPSInterval", &vidDisplayFPSInterval, 0.01f, 32.f);
configRegisterInt("Video.MSAA", &vidMSAA, 1, 16); configRegisterInt("Video.MSAA", &vidMSAA, 1, 16);
configRegisterInt("Video.TextureFilter", &texFilter, 0, 2); configRegisterInt("Video.TextureFilter", &texFilter, 0, 2);
configRegisterInt("Video.TextureFilter2D", &texFilter2D, 0, 1); configRegisterInt("Video.TextureFilter2D", &texFilter2D, 0, 1);
+17 -7
View File
@@ -957,16 +957,26 @@ void lvFindThreats(void)
#ifndef PLATFORM_N64 #ifndef PLATFORM_N64
Gfx *lvRenderFPS(Gfx *gdl) Gfx *lvRenderFPS(Gfx *gdl)
{ {
const f32 fps = videoGetAverageFPS();
const u8 a = 160;
s32 x = 27, y = 13; s32 x = 27, y = 13;
f32 fps = 1.0f / videoGetDiffTime(); u32 color;
s32 ifps = (s32)fps;
u8 r = (ifps <= 30) ? 255 : (ifps <= 60) ? roundf(255 * (1.0f - (ifps - 30.0f) / 30.0f)) : 0;
u8 g = (ifps <= 30) ? roundf(255 * (ifps - 1.0f) / 29.0f) : 255;
u8 b = (ifps > 60 && ifps <= 90) ? roundf(255 * (ifps - 60.0f) / 30.0f) : (ifps > 90) ? 255 : 0;
u8 a = 160;
u32 color = r << 24 | g << 16 | b << 8 | a;
char buffer[16]; char buffer[16];
if (fps <= 30.f) {
// red -> yellow
color = 0xff000000 | a | ((u32)((fps / 30.f) * 255.f) << 16);
} else if (fps <= 60.f) {
// yellow -> green
color = 0x00ff0000 | a | ((u32)((1.f - (fps - 30.f) / 30.f) * 255.f) << 24);
} else if (fps <= 90.f) {
// green -> cyan
color = 0x00ff0000 | a | ((u32)(((fps - 60.f) / 30.f) * 255.f) << 8);
} else {
// cyan
color = 0x00ffff00 | a;
}
if (g_CharsNumeric && g_FontNumeric) { if (g_CharsNumeric && g_FontNumeric) {
snprintf(buffer, sizeof buffer, "%.2f", fps); snprintf(buffer, sizeof buffer, "%.2f", fps);
-1
View File
@@ -551,7 +551,6 @@ extern s32 g_BlurFb;
extern s32 g_BlurFbCapTimer; extern s32 g_BlurFbCapTimer;
extern bool g_BlurFbDirty; extern bool g_BlurFbDirty;
extern s32 g_TickRateDiv; extern s32 g_TickRateDiv;
extern s32 g_TickRateDivOverride;
extern s32 g_TickExtraSleep; extern s32 g_TickExtraSleep;
extern s32 g_MusicDisableMpDeath; extern s32 g_MusicDisableMpDeath;
extern s32 g_BgunGeMuzzleFlashes; extern s32 g_BgunGeMuzzleFlashes;