Skip to content

Commit

Permalink
feat: auto hdr
Browse files Browse the repository at this point in the history
  • Loading branch information
moesnow committed Mar 2, 2024
1 parent 4cd0d71 commit aa42d97
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 2 deletions.
4 changes: 2 additions & 2 deletions app/setting_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -505,8 +505,8 @@ def __initCard(self):
)
self.autoSetResolutionEnableCard = SwitchSettingCard1(
FIF.FULL_SCREEN,
self.tr('启用自动修改分辨率'),
"通过软件启动游戏会自动修改 1920x1080 分辨率,不影响手动启动游戏(未测试国际服)",
self.tr('启用自动修改分辨率并关闭自动 HDR'),
"通过软件启动游戏会自动修改 1920x1080 分辨率并关闭自动 HDR,不影响手动启动游戏(未测试国际服)",
"auto_set_resolution_enable"
)
self.autoSetGamePathEnableCard = SwitchSettingCard1(
Expand Down
26 changes: 26 additions & 0 deletions tasks/game/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from utils.date import Date
from utils.gamecontroller import GameController
from utils.registry.star_rail_resolution import get_game_resolution, set_game_resolution
from utils.registry.game_auto_hdr import get_game_auto_hdr, set_game_auto_hdr
from typing import Literal, Optional
import time
import logging
Expand All @@ -22,6 +23,7 @@ class StarRailController(GameController):
def __init__(self, game_path: str, process_name: str, window_name: str, window_class: Optional[str], logger: Optional[logging.Logger] = None) -> None:
super().__init__(game_path, process_name, window_name, window_class, logger)
self.game_resolution = None
self.game_auto_hdr = None
self.screen_resolution = pyautogui.size()

def change_resolution(self, width: int, height: int):
Expand All @@ -46,6 +48,27 @@ def restore_resolution(self):
self.log_debug(f"恢复游戏分辨率: {self.game_resolution[0]}x{self.game_resolution[1]} ({'全屏' if self.game_resolution[2] else '窗口'})")
except Exception as e:
self.log_error("写入注册表值时发生错误:", e)

def change_auto_hdr(self, status: Literal["enable", "disable", "unset"] = "unset"):
"""通过注册表修改游戏自动 HDR 设置"""
status_map = {"enable": "启用", "disable": "禁用", "unset": "未设置"}
try:
self.game_auto_hdr = get_game_auto_hdr(self.game_path)
set_game_auto_hdr(self.game_path, status)
self.log_debug(f"修改游戏自动 HDR: {status_map.get(self.game_auto_hdr)} --> {status_map.get(status)}")
except Exception as e:
self.log_debug(f"修改游戏自动 HDR 设置时发生错误:{e}")

def restore_auto_hdr(self):
"""通过注册表恢复游戏自动 HDR 设置"""
status_map = {"enable": "启用", "disable": "禁用", "unset": "未设置"}
try:
if self.game_auto_hdr:
set_game_auto_hdr(self.game_path, self.game_auto_hdr)
self.log_debug(f"恢复游戏自动 HDR: {status_map.get(self.game_auto_hdr)}")
except Exception as e:
self.log_debug(f"恢复游戏自动 HDR 设置时发生错误:{e}")

def check_resolution(self, target_width: int, target_height: int) -> None:
"""
检查游戏窗口的分辨率是否匹配目标分辨率。
Expand Down Expand Up @@ -151,17 +174,20 @@ def get_process_path(name):
if not game.switch_to_game():
if config.auto_set_resolution_enable:
game.change_resolution(1920, 1080)
game.change_auto_hdr("disable")

if not game.start_game():
raise Exception("启动游戏失败")
time.sleep(10)

if not wait_until(lambda: game.switch_to_game(), 60):
game.restore_resolution()
game.restore_auto_hdr()
raise TimeoutError("切换到游戏超时")

time.sleep(10)
game.restore_resolution()
game.restore_auto_hdr()
game.check_resolution_ratio(1920, 1080)

if not wait_until(lambda: check_and_click_enter(), 600):
Expand Down
85 changes: 85 additions & 0 deletions utils/registry/game_auto_hdr.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
from typing import Literal
import winreg
import os


def get_game_auto_hdr(game_path: str) -> Literal["enable", "disable", "unset"]:
"""
Get the Auto HDR setting for a specific game via Windows Registry.
Parameters:
- game_path: The file path to the game executable, ensuring Windows path conventions.
Returns:
- A Literal indicating the status of Auto HDR for the game: "enable", "disable", or "unset".
"""
if not os.path.isabs(game_path):
raise ValueError(f"'{game_path}' is not an absolute path.")

game_path = os.path.normpath(game_path)
reg_path = r"Software\Microsoft\DirectX\UserGpuPreferences"
reg_key = game_path

try:
with winreg.OpenKey(winreg.HKEY_CURRENT_USER, reg_path) as key:
existing_value, _ = winreg.QueryValueEx(key, reg_key)
settings = dict(item.split("=") for item in existing_value.split(";") if item)
hdr_status = settings.get("AutoHDREnable", None)
if hdr_status == "2097":
return "enable"
elif hdr_status == "2096":
return "disable"
else:
return "unset"
except FileNotFoundError:
return "unset"
except Exception as e:
raise Exception(f"Error getting Auto HDR status for '{game_path}': {e}")


def set_game_auto_hdr(game_path: str, status: Literal["enable", "disable", "unset"] = "unset"):
"""
Set, update, or unset the Auto HDR setting for a specific game via Windows Registry,
without affecting other settings. Ensures the game path is an absolute path
and raises exceptions on errors instead of printing.
Parameters:
- game_path: The file path to the game executable, ensuring Windows path conventions.
- status: Literal indicating the desired status for Auto HDR. One of "enable", "disable", or "unset".
"""
if not os.path.isabs(game_path):
raise ValueError(f"'{game_path}' is not an absolute path.")

game_path = os.path.normpath(game_path)
reg_path = r"Software\Microsoft\DirectX\UserGpuPreferences"
reg_key = game_path

hdr_value = {"enable": "2097", "disable": "2096"}.get(status, None)

try:
with winreg.CreateKey(winreg.HKEY_CURRENT_USER, reg_path) as key:
if status == "unset":
try:
existing_value, _ = winreg.QueryValueEx(key, reg_key)
settings = dict(item.split("=") for item in existing_value.split(";") if item)
if "AutoHDREnable" in settings:
del settings["AutoHDREnable"]
updated_value = ";".join([f"{k}={v}" for k, v in settings.items()]) + ";"
if settings:
winreg.SetValueEx(key, reg_key, 0, winreg.REG_SZ, updated_value)
else:
winreg.DeleteValue(key, reg_key)
except FileNotFoundError:
pass
else:
try:
existing_value, _ = winreg.QueryValueEx(key, reg_key)
except FileNotFoundError:
existing_value = ""
settings = dict(item.split("=") for item in existing_value.split(";") if item)
if hdr_value is not None:
settings["AutoHDREnable"] = hdr_value
updated_value = ";".join([f"{k}={v}" for k, v in settings.items()]) + ";"
winreg.SetValueEx(key, reg_key, 0, winreg.REG_SZ, updated_value)
except Exception as e:
raise Exception(f"Error setting Auto HDR for '{game_path}' with status '{status}': {e}")

0 comments on commit aa42d97

Please sign in to comment.