From 780900af61ada7dec4f63d810208b1c5e6e14db4 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 16 Apr 2026 10:37:13 +0200 Subject: [PATCH] Add render FPS and perf HUD settings --- assets/root/prototype.py | 16 +++ assets/root/uisystemoption.py | 76 +++++++++++ .../uiscript/uiscript/systemoptiondialog.py | 127 +++++++++++++++++- 3 files changed, 217 insertions(+), 2 deletions(-) diff --git a/assets/root/prototype.py b/assets/root/prototype.py index dc02243e..00b1da10 100644 --- a/assets/root/prototype.py +++ b/assets/root/prototype.py @@ -43,6 +43,21 @@ def _GetHeadlessInt(name, default): return default +def _ApplyRenderFPSOverride(): + rawValue = os.environ.get("M2_RENDER_FPS", "").strip() + if not rawValue: + return + + try: + fps = int(rawValue) + except (TypeError, ValueError): + _WriteHeadlessTrace("Invalid M2_RENDER_FPS=%s" % rawValue) + return + + app.SetFPS(fps) + _WriteHeadlessTrace("Render FPS override=%d" % fps) + + def _SetInitialPhase(mainStream): scenario = _GetHeadlessScenario() if scenario == "map_load": @@ -83,6 +98,7 @@ def RunApp(): return app.SetCamera(1500.0, 30.0, 0.0, 180.0) + _ApplyRenderFPSOverride() #Gets and sets the floating-point control word #app.SetControlFP() diff --git a/assets/root/uisystemoption.py b/assets/root/uisystemoption.py index 8050ba3a..64311e55 100644 --- a/assets/root/uisystemoption.py +++ b/assets/root/uisystemoption.py @@ -41,6 +41,9 @@ class OptionDialog(ui.ScriptWindow): self.cameraModeButtonList = [] self.fogModeButtonList = [] self.tilingModeButtonList = [] + self.renderFPSButtonList = [] + self.renderFPSValues = [60, 120, 144, 240, 0] + self.performanceHUDButtonList = [] self.ctrlShadowQuality = 0 def Destroy(self): @@ -72,6 +75,13 @@ class OptionDialog(ui.ScriptWindow): self.fogModeButtonList.append(GetObject("fog_level2")) self.tilingModeButtonList.append(GetObject("tiling_cpu")) self.tilingModeButtonList.append(GetObject("tiling_gpu")) + self.renderFPSButtonList.append(GetObject("render_fps_60")) + self.renderFPSButtonList.append(GetObject("render_fps_120")) + self.renderFPSButtonList.append(GetObject("render_fps_144")) + self.renderFPSButtonList.append(GetObject("render_fps_240")) + self.renderFPSButtonList.append(GetObject("render_fps_max")) + self.performanceHUDButtonList.append(GetObject("performance_hud_off")) + self.performanceHUDButtonList.append(GetObject("performance_hud_on")) self.tilingApplyButton=GetObject("tiling_apply") #self.ctrlShadowQuality = GetObject("shadow_bar") except: @@ -106,6 +116,13 @@ class OptionDialog(ui.ScriptWindow): self.tilingModeButtonList[0].SAFE_SetEvent(self.__OnClickTilingModeCPUButton) self.tilingModeButtonList[1].SAFE_SetEvent(self.__OnClickTilingModeGPUButton) + self.renderFPSButtonList[0].SAFE_SetEvent(self.__OnClickRenderFPS60Button) + self.renderFPSButtonList[1].SAFE_SetEvent(self.__OnClickRenderFPS120Button) + self.renderFPSButtonList[2].SAFE_SetEvent(self.__OnClickRenderFPS144Button) + self.renderFPSButtonList[3].SAFE_SetEvent(self.__OnClickRenderFPS240Button) + self.renderFPSButtonList[4].SAFE_SetEvent(self.__OnClickRenderFPSMaxButton) + self.performanceHUDButtonList[0].SAFE_SetEvent(self.__OnClickPerformanceHUDOffButton) + self.performanceHUDButtonList[1].SAFE_SetEvent(self.__OnClickPerformanceHUDOnButton) self.tilingApplyButton.SAFE_SetEvent(self.__OnClickTilingApplyButton) @@ -115,6 +132,7 @@ class OptionDialog(ui.ScriptWindow): self.__ClickRadioButton(self.fogModeButtonList, systemSetting.GetFogLevel()) # MR-14: -- END OF -- Fog update by Alaric self.__ClickRadioButton(self.cameraModeButtonList, constInfo.GET_CAMERA_MAX_DISTANCE_INDEX()) + self.RefreshRenderSettings() if musicInfo.fieldMusic==musicInfo.METIN2THEMA: self.selectMusicFile.SetText(uiSelectMusic.DEFAULT_THEMA) @@ -179,6 +197,41 @@ class OptionDialog(ui.ScriptWindow): self.__ClickRadioButton(self.fogModeButtonList, index) + def __ApplyAndSaveConfig(self): + systemSetting.ApplyConfig() + systemSetting.SaveConfig() + + def __GetRenderFPSButtonIndex(self): + renderFPS = systemSetting.GetRenderFPS() + if renderFPS <= 0: + return len(self.renderFPSValues) - 1 + + try: + return self.renderFPSValues.index(renderFPS) + except ValueError: + bestIndex = 0 + bestDistance = abs(self.renderFPSValues[0] - renderFPS) + for index in xrange(len(self.renderFPSValues) - 1): + distance = abs(self.renderFPSValues[index] - renderFPS) + if distance < bestDistance: + bestIndex = index + bestDistance = distance + return bestIndex + + def RefreshRenderSettings(self): + self.__ClickRadioButton(self.renderFPSButtonList, self.__GetRenderFPSButtonIndex()) + self.__ClickRadioButton(self.performanceHUDButtonList, 1 if systemSetting.IsShowPerformanceHUD() else 0) + + def __SetRenderFPS(self, fps): + systemSetting.SetRenderFPS(fps) + self.__ApplyAndSaveConfig() + self.RefreshRenderSettings() + + def __SetPerformanceHUD(self, isVisible): + systemSetting.SetShowPerformanceHUDFlag(1 if isVisible else 0) + self.__ApplyAndSaveConfig() + self.RefreshRenderSettings() + def __OnClickCameraModeShortButton(self): self.__SetCameraMode(0) @@ -194,6 +247,27 @@ class OptionDialog(ui.ScriptWindow): def __OnClickFogModeLevel2Button(self): self.__SetFogLevel(2) + def __OnClickRenderFPS60Button(self): + self.__SetRenderFPS(60) + + def __OnClickRenderFPS120Button(self): + self.__SetRenderFPS(120) + + def __OnClickRenderFPS144Button(self): + self.__SetRenderFPS(144) + + def __OnClickRenderFPS240Button(self): + self.__SetRenderFPS(240) + + def __OnClickRenderFPSMaxButton(self): + self.__SetRenderFPS(0) + + def __OnClickPerformanceHUDOffButton(self): + self.__SetPerformanceHUD(False) + + def __OnClickPerformanceHUDOnButton(self): + self.__SetPerformanceHUD(True) + def __OnChangeMusic(self, fileName): self.selectMusicFile.SetText(fileName[:MUSIC_FILENAME_MAX_LEN]) @@ -239,6 +313,8 @@ class OptionDialog(ui.ScriptWindow): return True def Show(self): + self.RefreshRenderSettings() + self.__SetCurTilingMode() ui.ScriptWindow.Show(self) def Close(self): diff --git a/assets/uiscript/uiscript/systemoptiondialog.py b/assets/uiscript/uiscript/systemoptiondialog.py index 9a714efb..29fb2685 100644 --- a/assets/uiscript/uiscript/systemoptiondialog.py +++ b/assets/uiscript/uiscript/systemoptiondialog.py @@ -1,6 +1,11 @@ import uiScriptLocale ROOT_PATH = "d:/ymir work/ui/public/" +OPTION_RENDER_FPS = getattr(uiScriptLocale, "OPTION_RENDER_FPS", "Render FPS") +OPTION_RENDER_FPS_MAX = getattr(uiScriptLocale, "OPTION_RENDER_FPS_MAX", "MAX") +OPTION_PERFORMANCE_HUD = getattr(uiScriptLocale, "OPTION_PERFORMANCE_HUD", "Perf HUD") +OPTION_ON = getattr(uiScriptLocale, "OPTION_ON", "On") +OPTION_OFF = getattr(uiScriptLocale, "OPTION_OFF", "Off") TEMPORARY_X = +13 TEXT_TEMPORARY_X = -10 @@ -15,7 +20,7 @@ window = { "y" : 0, "width" : 305, - "height" : 255, + "height" : 295, "children" : ( @@ -27,7 +32,7 @@ window = { "y" : 0, "width" : 305, - "height" : 255, + "height" : 295, "children" : ( @@ -261,6 +266,124 @@ window = { "down_image" : ROOT_PATH + "middle_Button_03.sub", }, + { + "name" : "render_fps_mode", + "type" : "text", + + "x" : 18, + "y" : 210 + 2, + + "text" : OPTION_RENDER_FPS, + }, + + { + "name" : "render_fps_60", + "type" : "radio_button", + + "x" : 82, + "y" : 210, + + "text" : "60", + + "default_image" : ROOT_PATH + "small_Button_01.sub", + "over_image" : ROOT_PATH + "small_Button_02.sub", + "down_image" : ROOT_PATH + "small_Button_03.sub", + }, + + { + "name" : "render_fps_120", + "type" : "radio_button", + + "x" : 124, + "y" : 210, + + "text" : "120", + + "default_image" : ROOT_PATH + "small_Button_01.sub", + "over_image" : ROOT_PATH + "small_Button_02.sub", + "down_image" : ROOT_PATH + "small_Button_03.sub", + }, + + { + "name" : "render_fps_144", + "type" : "radio_button", + + "x" : 166, + "y" : 210, + + "text" : "144", + + "default_image" : ROOT_PATH + "small_Button_01.sub", + "over_image" : ROOT_PATH + "small_Button_02.sub", + "down_image" : ROOT_PATH + "small_Button_03.sub", + }, + + { + "name" : "render_fps_240", + "type" : "radio_button", + + "x" : 208, + "y" : 210, + + "text" : "240", + + "default_image" : ROOT_PATH + "small_Button_01.sub", + "over_image" : ROOT_PATH + "small_Button_02.sub", + "down_image" : ROOT_PATH + "small_Button_03.sub", + }, + + { + "name" : "render_fps_max", + "type" : "radio_button", + + "x" : 250, + "y" : 210, + + "text" : OPTION_RENDER_FPS_MAX, + + "default_image" : ROOT_PATH + "small_Button_01.sub", + "over_image" : ROOT_PATH + "small_Button_02.sub", + "down_image" : ROOT_PATH + "small_Button_03.sub", + }, + + { + "name" : "performance_hud_mode", + "type" : "text", + + "x" : 18, + "y" : 235 + 2, + + "text" : OPTION_PERFORMANCE_HUD, + }, + + { + "name" : "performance_hud_off", + "type" : "radio_button", + + "x" : 110, + "y" : 235, + + "text" : OPTION_OFF, + + "default_image" : ROOT_PATH + "small_Button_01.sub", + "over_image" : ROOT_PATH + "small_Button_02.sub", + "down_image" : ROOT_PATH + "small_Button_03.sub", + }, + + { + "name" : "performance_hud_on", + "type" : "radio_button", + + "x" : 160, + "y" : 235, + + "text" : OPTION_ON, + + "default_image" : ROOT_PATH + "small_Button_01.sub", + "over_image" : ROOT_PATH + "small_Button_02.sub", + "down_image" : ROOT_PATH + "small_Button_03.sub", + }, + ## 그림자 # {