summaryrefslogtreecommitdiff
path: root/main.py
diff options
context:
space:
mode:
authorxXJSONDeruloXx <danielhimebauch@gmail.com>2026-06-22 21:14:25 -0400
committerxXJSONDeruloXx <danielhimebauch@gmail.com>2026-06-22 21:14:25 -0400
commitd6bddf23bdd3874da4d255732a5132d20fda5ede (patch)
tree97414baeb33cfffa07be7276b2a0a3452e728b6f /main.py
parentdc4610dabb0a70783d4b9e9832578ddde757a850 (diff)
downloadDecky-Framegen-feat/opti-pre10-variant.tar.gz
Decky-Framegen-feat/opti-pre10-variant.zip
feat: add RDNA2 pre10 FSR4 variantv0.16.0-pre1feat/opti-pre10-variant
Diffstat (limited to 'main.py')
-rw-r--r--main.py162
1 files changed, 159 insertions, 3 deletions
diff --git a/main.py b/main.py
index 70f1359..f657cfe 100644
--- a/main.py
+++ b/main.py
@@ -27,6 +27,18 @@ FSR4_OFFICIAL_411_ASSET = {
"version": "4.1.1-official",
}
+FSR4_VALVE_411_ASSET = {
+ "name": "amdxcffx64_valve_2.3.0.2913.dll",
+ "sha256": "4e7dc37aebea3a90e3d3cc43e24cb2b54176b2535315f20dbe63b3b7cfc56b1e",
+ "version": "4.1.1-valve-2.3.0.2913",
+}
+
+OPTISCALER_PRE10_ASSET = {
+ "name": "OptiScaler_0.10.0-pre1.20260622_135940.dll",
+ "sha256": "b374b19081cc066365d0c6da4808d768e16469b0cbdfc478b6e95999947d5364",
+ "version": "0.10.0-pre1.20260622_135940",
+}
+
OPTIPATCHER_ASSET = {
"name": "OptiPatcher_rolling.asi",
"sha256": "88b9e1be3559737cd205fdf5f2c8550cf1923fb1def4c603e5bf03c3e84131b1",
@@ -73,6 +85,32 @@ FSR4_VARIANTS = {
"source_version": FSR4_OFFICIAL_411_ASSET["version"],
}
],
+ "config_overrides": {},
+ },
+ "rdna2-valve-411-pre10": {
+ "label": "4.1.1 Valve RDNA2 compatibility",
+ "dir_name": "fsr4-rdna2-valve-411-pre10",
+ "sha256": "ec7ed3ca674e288240e6f04b986342aece47454c41d9b0959449e82e22bd7f6d",
+ "source_asset_name": OPTISCALER_ARCHIVE_ASSET["name"],
+ "source_version": OPTISCALER_ARCHIVE_ASSET["version"],
+ "uses_archive_native": True,
+ "injector": {
+ "name": "OptiScaler.dll",
+ "sha256": OPTISCALER_PRE10_ASSET["sha256"],
+ "source_asset_name": OPTISCALER_PRE10_ASSET["name"],
+ "source_version": OPTISCALER_PRE10_ASSET["version"],
+ },
+ "extra_files": [
+ {
+ "name": FSR4_DRIVER_OVERRIDE_FILENAME,
+ "sha256": FSR4_VALVE_411_ASSET["sha256"],
+ "source_asset_name": FSR4_VALVE_411_ASSET["name"],
+ "source_version": FSR4_VALVE_411_ASSET["version"],
+ }
+ ],
+ "config_overrides": {
+ "Fsr4ForceModel": "2",
+ },
},
}
VARIANT_EXTRA_FILENAMES = sorted(
@@ -375,6 +413,51 @@ class Plugin:
def _fsr4_variant_extra_file_path(self, fgmod_path: Path, fsr4_variant: str | None, filename: str) -> Path:
return self._fsr4_variant_dir(fgmod_path, fsr4_variant) / filename
+ def _fsr4_variant_injector_info(self, fsr4_variant: str | None) -> dict | None:
+ variant = self._fsr4_variant_info(fsr4_variant)
+ injector = variant.get("injector")
+ return injector if isinstance(injector, dict) else None
+
+ def _fsr4_variant_injector_path(self, fgmod_path: Path, fsr4_variant: str | None) -> Path | None:
+ injector = self._fsr4_variant_injector_info(fsr4_variant)
+ if not injector:
+ return None
+ return self._fsr4_variant_dir(fgmod_path, fsr4_variant) / injector.get("name", "OptiScaler.dll")
+
+ def _fsr4_variant_renamed_proxy_path(self, fgmod_path: Path, fsr4_variant: str | None, dll_name: str) -> Path | None:
+ if not self._fsr4_variant_injector_info(fsr4_variant):
+ return None
+ return self._fsr4_variant_dir(fgmod_path, fsr4_variant) / "renames" / dll_name
+
+ def _fsr4_variant_config_overrides(self, fsr4_variant: str | None) -> dict:
+ variant = self._fsr4_variant_info(fsr4_variant)
+ overrides = variant.get("config_overrides") or {}
+ return dict(overrides) if isinstance(overrides, dict) else {}
+
+ def _apply_optiscaler_ini_overrides(self, ini_file: Path, overrides: dict) -> bool:
+ if not overrides:
+ return True
+ try:
+ content = ini_file.read_text(encoding="utf-8", errors="replace")
+ for key, value in overrides.items():
+ key = str(key).strip()
+ value = str(value).strip()
+ if not key:
+ continue
+ pattern = re.compile(rf"^{re.escape(key)}\s*=.*$", re.MULTILINE)
+ replacement = f"{key}={value}"
+ if pattern.search(content):
+ content = pattern.sub(replacement, content)
+ else:
+ if content and not content.endswith("\n"):
+ content += "\n"
+ content += f"{replacement}\n"
+ ini_file.write_text(content, encoding="utf-8")
+ return True
+ except Exception as exc:
+ decky.logger.error(f"Failed to apply OptiScaler.ini overrides to {ini_file}: {exc}")
+ return False
+
def _sync_variant_root_extra_files(self, fgmod_path: Path, fsr4_variant: str | None) -> None:
selected_extra_files = {extra_file["name"]: extra_file for extra_file in self._fsr4_variant_extra_files(fsr4_variant)}
for filename in VARIANT_EXTRA_FILENAMES:
@@ -580,11 +663,15 @@ class Plugin:
optiscaler_archive = bin_path / OPTISCALER_ARCHIVE_ASSET["name"]
fsr4_int8_src = bin_path / FSR4_INT8_ASSET["name"]
fsr4_official_411_src = bin_path / FSR4_OFFICIAL_411_ASSET["name"]
+ fsr4_valve_411_src = bin_path / FSR4_VALVE_411_ASSET["name"]
+ optiscaler_pre10_src = bin_path / OPTISCALER_PRE10_ASSET["name"]
optipatcher_src = bin_path / OPTIPATCHER_ASSET["name"]
for required_path, asset in [
(optiscaler_archive, OPTISCALER_ARCHIVE_ASSET),
(fsr4_int8_src, FSR4_INT8_ASSET),
(fsr4_official_411_src, FSR4_OFFICIAL_411_ASSET),
+ (fsr4_valve_411_src, FSR4_VALVE_411_ASSET),
+ (optiscaler_pre10_src, OPTISCALER_PRE10_ASSET),
(optipatcher_src, OPTIPATCHER_ASSET),
]:
if not required_path.exists():
@@ -660,6 +747,42 @@ class Plugin:
"Prepared rdna34-official-411 driver override",
)
+ rdna2_valve_dir = extract_path / FSR4_VARIANTS["rdna2-valve-411-pre10"]["dir_name"]
+ rdna2_valve_dir.mkdir(parents=True, exist_ok=True)
+ rdna2_valve_upscaler = rdna2_valve_dir / FSR4_UPSCALER_FILENAME
+ shutil.copy2(native_upscaler_root, rdna2_valve_upscaler)
+ self._verify_bundled_asset(
+ rdna2_valve_upscaler,
+ FSR4_VARIANTS["rdna2-valve-411-pre10"]["sha256"],
+ "Prepared rdna2-valve-411-pre10 FSR4 upscaler",
+ )
+ self._verify_bundled_asset(
+ fsr4_valve_411_src,
+ FSR4_VALVE_411_ASSET["sha256"],
+ "Bundled rdna2-valve-411-pre10 driver override",
+ )
+ rdna2_valve_driver = rdna2_valve_dir / FSR4_DRIVER_OVERRIDE_FILENAME
+ shutil.copy2(fsr4_valve_411_src, rdna2_valve_driver)
+ self._verify_bundled_asset(
+ rdna2_valve_driver,
+ FSR4_VALVE_411_ASSET["sha256"],
+ "Prepared rdna2-valve-411-pre10 driver override",
+ )
+ self._verify_bundled_asset(
+ optiscaler_pre10_src,
+ OPTISCALER_PRE10_ASSET["sha256"],
+ "Bundled rdna2-valve-411-pre10 OptiScaler injector",
+ )
+ rdna2_valve_injector = rdna2_valve_dir / "OptiScaler.dll"
+ shutil.copy2(optiscaler_pre10_src, rdna2_valve_injector)
+ self._verify_bundled_asset(
+ rdna2_valve_injector,
+ OPTISCALER_PRE10_ASSET["sha256"],
+ "Prepared rdna2-valve-411-pre10 OptiScaler injector",
+ )
+ if not self._create_renamed_copies(rdna2_valve_injector, rdna2_valve_dir / "renames"):
+ return {"status": "error", "message": "Failed to prepare renamed pre10 OptiScaler proxies."}
+
rdna23_dir = extract_path / FSR4_VARIANTS["rdna23-int8"]["dir_name"]
rdna23_dir.mkdir(parents=True, exist_ok=True)
self._verify_bundled_asset(
@@ -704,6 +827,18 @@ class Plugin:
"source_asset_name": variant["source_asset_name"],
"source_version": variant["source_version"],
"uses_archive_native": bool(variant["uses_archive_native"]),
+ "injector": (
+ {
+ "name": variant["injector"]["name"],
+ "sha256": variant["injector"]["sha256"],
+ "source_asset_name": variant["injector"]["source_asset_name"],
+ "source_version": variant["injector"]["source_version"],
+ "path": str((Path(variant["dir_name"]) / variant["injector"]["name"]).as_posix()),
+ }
+ if isinstance(variant.get("injector"), dict)
+ else None
+ ),
+ "config_overrides": dict(variant.get("config_overrides") or {}),
"extra_files": [
{
"name": extra_file["name"],
@@ -864,11 +999,17 @@ class Plugin:
if not plugins_dir.exists() or not (plugins_dir / "OptiPatcher.asi").exists():
return {"exists": False}
- for variant in FSR4_VARIANTS.values():
+ for variant_id, variant in FSR4_VARIANTS.items():
variant_dir = path / variant["dir_name"]
variant_path = variant_dir / FSR4_UPSCALER_FILENAME
if not variant_path.exists():
return {"exists": False}
+ injector = variant.get("injector")
+ if isinstance(injector, dict):
+ if not (variant_dir / injector.get("name", "OptiScaler.dll")).exists():
+ return {"exists": False}
+ if not (variant_dir / "renames" / "dxgi.dll").exists():
+ return {"exists": False}
for extra_file in variant.get("extra_files", []):
if not (variant_dir / extra_file["name"]).exists():
return {"exists": False}
@@ -917,8 +1058,13 @@ class Plugin:
}
preserve_ini = True
+ previous_marker_metadata = self._read_marker(directory / MARKER_FILENAME)
+ previous_variant = str(previous_marker_metadata.get("fsr4_variant") or "").strip()
selected_variant = self._selected_fsr4_variant(fgmod_path, fsr4_variant)
selected_variant_info = FSR4_VARIANTS[selected_variant]
+ selected_config_overrides = self._fsr4_variant_config_overrides(selected_variant)
+ if previous_variant == "rdna2-valve-411-pre10" and selected_variant != previous_variant:
+ selected_config_overrides.setdefault("Fsr4ForceModel", "auto")
selected_upscaler_src = self._fsr4_variant_path(fgmod_path, selected_variant)
if not selected_upscaler_src.exists():
selected_upscaler_src = fgmod_path / FSR4_UPSCALER_FILENAME
@@ -976,9 +1122,18 @@ class Plugin:
else "No original game DLLs required backup"
)
- renamed = fgmod_path / "renames" / dll_name
+ variant_renamed = self._fsr4_variant_renamed_proxy_path(fgmod_path, selected_variant, dll_name)
+ variant_injector = self._fsr4_variant_injector_path(fgmod_path, selected_variant)
+ root_renamed = fgmod_path / "renames" / dll_name
destination_dll = directory / dll_name
- source_for_copy = renamed if renamed.exists() else optiscaler_dll
+ if variant_renamed and variant_renamed.exists():
+ source_for_copy = variant_renamed
+ elif variant_injector and variant_injector.exists():
+ source_for_copy = variant_injector
+ elif root_renamed.exists():
+ source_for_copy = root_renamed
+ else:
+ source_for_copy = optiscaler_dll
shutil.copy2(source_for_copy, destination_dll)
decky.logger.info(f"Copied injector DLL from {source_for_copy} to {destination_dll}")
@@ -995,6 +1150,7 @@ class Plugin:
if target_ini.exists():
self._migrate_optiscaler_ini(target_ini)
self._disable_hq_font_auto(target_ini)
+ self._apply_optiscaler_ini_overrides(target_ini, selected_config_overrides)
plugins_src = fgmod_path / "plugins"
plugins_dest = directory / "plugins"