summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--py_modules/lsfg_vk/config_schema.py24
-rw-r--r--py_modules/lsfg_vk/configuration.py82
-rw-r--r--py_modules/lsfg_vk/installation.py18
-rw-r--r--py_modules/lsfg_vk/plugin.py8
-rw-r--r--src/api/lsfgApi.ts4
-rw-r--r--src/components/ConfigurationSection.tsx34
-rw-r--r--src/config/configSchema.ts16
-rw-r--r--tests/test_configuration.py65
8 files changed, 216 insertions, 35 deletions
diff --git a/py_modules/lsfg_vk/config_schema.py b/py_modules/lsfg_vk/config_schema.py
index ed82d97..460b0a0 100644
--- a/py_modules/lsfg_vk/config_schema.py
+++ b/py_modules/lsfg_vk/config_schema.py
@@ -92,6 +92,20 @@ CONFIG_SCHEMA: Dict[str, ConfigField] = {
field_type=ConfigFieldType.INTEGER,
default=0,
description="experimental: base framerate cap for dxvk games, before frame multiplier (0 = disabled)"
+ ),
+
+ "enable_wow64": ConfigField(
+ name="enable_wow64",
+ field_type=ConfigFieldType.BOOLEAN,
+ default=False,
+ description="enable PROTON_USE_WOW64=1 for 32-bit games (use with ProtonGE to fix crashing)"
+ ),
+
+ "disable_steamdeck_mode": ConfigField(
+ name="disable_steamdeck_mode",
+ field_type=ConfigFieldType.BOOLEAN,
+ default=False,
+ description="disable Steam Deck mode (unlocks hidden settings in some games)"
)
}
@@ -106,6 +120,8 @@ class ConfigurationData(TypedDict):
hdr_mode: bool
experimental_present_mode: str
experimental_fps_limit: int
+ enable_wow64: bool
+ disable_steamdeck_mode: bool
class ConfigurationManager:
@@ -314,7 +330,9 @@ class ConfigurationManager:
def create_config_from_args(enable: bool, dll: str, multiplier: int, flow_scale: float,
performance_mode: bool, hdr_mode: bool,
experimental_present_mode: str = "",
- experimental_fps_limit: int = 0) -> ConfigurationData:
+ experimental_fps_limit: int = 0,
+ enable_wow64: bool = False,
+ disable_steamdeck_mode: bool = False) -> ConfigurationData:
"""Create configuration from individual arguments"""
return cast(ConfigurationData, {
"enable": enable,
@@ -324,5 +342,7 @@ class ConfigurationManager:
"performance_mode": performance_mode,
"hdr_mode": hdr_mode,
"experimental_present_mode": experimental_present_mode,
- "experimental_fps_limit": experimental_fps_limit
+ "experimental_fps_limit": experimental_fps_limit,
+ "enable_wow64": enable_wow64,
+ "disable_steamdeck_mode": disable_steamdeck_mode
})
diff --git a/py_modules/lsfg_vk/configuration.py b/py_modules/lsfg_vk/configuration.py
index 255092a..ae0194b 100644
--- a/py_modules/lsfg_vk/configuration.py
+++ b/py_modules/lsfg_vk/configuration.py
@@ -68,7 +68,9 @@ class ConfigurationService(BaseService):
def update_config(self, enable: bool, dll: str, multiplier: int, flow_scale: float,
performance_mode: bool, hdr_mode: bool,
experimental_present_mode: str = "",
- experimental_fps_limit: int = 0) -> ConfigurationResponse:
+ experimental_fps_limit: int = 0,
+ enable_wow64: bool = False,
+ disable_steamdeck_mode: bool = False) -> ConfigurationResponse:
"""Update TOML configuration
Args:
@@ -80,6 +82,8 @@ class ConfigurationService(BaseService):
hdr_mode: Whether to enable HDR mode
experimental_present_mode: Experimental Vulkan present mode override
experimental_fps_limit: Experimental FPS limit for DXVK games
+ enable_wow64: Whether to enable PROTON_USE_WOW64=1 for 32-bit games
+ disable_steamdeck_mode: Whether to disable Steam Deck mode
Returns:
ConfigurationResponse with success status
@@ -88,23 +92,29 @@ class ConfigurationService(BaseService):
# Create configuration from individual arguments
config = ConfigurationManager.create_config_from_args(
enable, dll, multiplier, flow_scale, performance_mode, hdr_mode,
- experimental_present_mode, experimental_fps_limit
+ experimental_present_mode, experimental_fps_limit, enable_wow64, disable_steamdeck_mode
)
# Generate TOML content using centralized manager
toml_content = ConfigurationManager.generate_toml_content(config)
- # Ensure config directory exists
+ # Ensure config directory exists
self.config_dir.mkdir(parents=True, exist_ok=True)
# Write the updated config directly to preserve inode for file watchers
self._write_file(self.config_file_path, toml_content, 0o644)
+ # Update the launch script with the new configuration
+ script_result = self.update_lsfg_script(config)
+ if not script_result["success"]:
+ self.log.warning(f"Failed to update launch script: {script_result['error']}")
+
self.log.info(f"Updated lsfg TOML configuration: enable={enable}, "
f"dll='{dll}', multiplier={multiplier}, flow_scale={flow_scale}, "
f"performance_mode={performance_mode}, hdr_mode={hdr_mode}, "
f"experimental_present_mode='{experimental_present_mode}', "
- f"experimental_fps_limit={experimental_fps_limit}")
+ f"experimental_fps_limit={experimental_fps_limit}, "
+ f"enable_wow64={enable_wow64}, disable_steamdeck_mode={disable_steamdeck_mode}")
return {
"success": True,
@@ -182,3 +192,67 @@ class ConfigurationService(BaseService):
"message": None,
"error": str(e)
}
+
+ def update_lsfg_script(self, config: ConfigurationData) -> ConfigurationResponse:
+ """Update the ~/lsfg launch script with current configuration
+
+ Args:
+ config: Configuration data to apply to the script
+
+ Returns:
+ ConfigurationResponse indicating success or failure
+ """
+ try:
+ script_content = self._generate_script_content(config)
+
+ # Write the script file
+ self._write_file(self.lsfg_script_path, script_content, 0o755)
+
+ self.log.info(f"Updated lsfg launch script at {self.lsfg_script_path}")
+
+ return {
+ "success": True,
+ "config": config,
+ "message": "Launch script updated successfully",
+ "error": None
+ }
+
+ except Exception as e:
+ error_msg = f"Error updating launch script: {str(e)}"
+ self.log.error(error_msg)
+ return {
+ "success": False,
+ "config": None,
+ "message": None,
+ "error": str(e)
+ }
+
+ def _generate_script_content(self, config: ConfigurationData) -> str:
+ """Generate the content for the ~/lsfg launch script
+
+ Args:
+ config: Configuration data to apply to the script
+
+ Returns:
+ The complete script content as a string
+ """
+ lines = [
+ "#!/bin/bash",
+ "# lsfg-vk launch script generated by decky-lossless-scaling-vk plugin",
+ "# This script sets up the environment for lsfg-vk to work with the plugin configuration"
+ ]
+
+ # Add optional export statements based on configuration
+ if config.get("enable_wow64", False):
+ lines.append("export PROTON_USE_WOW64=1")
+
+ if config.get("disable_steamdeck_mode", False):
+ lines.append("export SteamDeck=0")
+
+ # Always add the LSFG_PROCESS export
+ lines.append("export LSFG_PROCESS=decky-lsfg-vk")
+
+ # Add the execution line
+ lines.append('exec "$@"')
+
+ return "\n".join(lines) + "\n"
diff --git a/py_modules/lsfg_vk/installation.py b/py_modules/lsfg_vk/installation.py
index d193219..5bfc88b 100644
--- a/py_modules/lsfg_vk/installation.py
+++ b/py_modules/lsfg_vk/installation.py
@@ -127,12 +127,18 @@ class InstallationService(BaseService):
def _create_lsfg_launch_script(self) -> None:
"""Create the ~/lsfg launch script for easier game setup"""
- script_content = """#!/bin/bash
-# lsfg-vk launch script generated by decky-lossless-scaling-vk plugin
-# This script sets up the environment for lsfg-vk to work with the plugin configuration
-export LSFG_PROCESS=decky-lsfg-vk
-exec "$@"
-"""
+ # Use the default configuration for the initial script
+ from .config_schema import ConfigurationManager
+ default_config = ConfigurationManager.get_defaults()
+
+ # Create configuration service to generate the script
+ from .configuration import ConfigurationService
+ config_service = ConfigurationService(logger=self.log)
+ config_service.user_home = self.user_home
+ config_service.lsfg_script_path = self.lsfg_launch_script_path
+
+ # Generate script content with default configuration
+ script_content = config_service._generate_script_content(default_config)
# Write the script file
self._write_file(self.lsfg_launch_script_path, script_content, 0o755)
diff --git a/py_modules/lsfg_vk/plugin.py b/py_modules/lsfg_vk/plugin.py
index 101542c..a44840d 100644
--- a/py_modules/lsfg_vk/plugin.py
+++ b/py_modules/lsfg_vk/plugin.py
@@ -125,7 +125,9 @@ class Plugin:
async def update_lsfg_config(self, enable: bool, dll: str, multiplier: int, flow_scale: float,
performance_mode: bool, hdr_mode: bool,
experimental_present_mode: str = "",
- experimental_fps_limit: int = 0) -> Dict[str, Any]:
+ experimental_fps_limit: int = 0,
+ enable_wow64: bool = False,
+ disable_steamdeck_mode: bool = False) -> Dict[str, Any]:
"""Update lsfg TOML configuration
Args:
@@ -137,13 +139,15 @@ class Plugin:
hdr_mode: Whether to enable HDR mode
experimental_present_mode: Experimental Vulkan present mode override
experimental_fps_limit: Experimental FPS limit for DXVK games
+ enable_wow64: Whether to enable PROTON_USE_WOW64=1 for 32-bit games
+ disable_steamdeck_mode: Whether to disable Steam Deck mode
Returns:
ConfigurationResponse dict with success status
"""
return self.configuration_service.update_config(
enable, dll, multiplier, flow_scale, performance_mode, hdr_mode,
- experimental_present_mode, experimental_fps_limit
+ experimental_present_mode, experimental_fps_limit, enable_wow64, disable_steamdeck_mode
)
async def update_dll_path(self, dll_path: str) -> Dict[str, Any]:
diff --git a/src/api/lsfgApi.ts b/src/api/lsfgApi.ts
index 5d866ef..5770c43 100644
--- a/src/api/lsfgApi.ts
+++ b/src/api/lsfgApi.ts
@@ -83,14 +83,14 @@ export const getLaunchOption = callable<[], LaunchOptionResult>("get_launch_opti
// Updated config function using centralized configuration
export const updateLsfgConfig = callable<
- [boolean, string, number, number, boolean, boolean, string, number],
+ [boolean, string, number, number, boolean, boolean, string, number, boolean, boolean],
ConfigUpdateResult
>("update_lsfg_config");
// Helper function to create config update from configuration object
export const updateLsfgConfigFromObject = async (config: ConfigurationData): Promise<ConfigUpdateResult> => {
const args = ConfigurationManager.createArgsFromConfig(config);
- return updateLsfgConfig(...args as [boolean, string, number, number, boolean, boolean, string, number]);
+ return updateLsfgConfig(...args as [boolean, string, number, number, boolean, boolean, string, number, boolean, boolean]);
};
// Self-updater API functions
diff --git a/src/components/ConfigurationSection.tsx b/src/components/ConfigurationSection.tsx
index dc8da89..1748839 100644
--- a/src/components/ConfigurationSection.tsx
+++ b/src/components/ConfigurationSection.tsx
@@ -106,6 +106,40 @@ export function ConfigurationSection({
color: "white"
}}
>
+ Environment Variables
+ </div>
+ </PanelSectionRow>
+
+ <PanelSectionRow>
+ <ToggleField
+ label="Enable WOW64 for 32-bit games"
+ description="Enables PROTON_USE_WOW64=1 for 32-bit games (use with ProtonGE to fix crashing)"
+ checked={config.enable_wow64}
+ onChange={(value) => onConfigChange('enable_wow64', value)}
+ />
+ </PanelSectionRow>
+
+ <PanelSectionRow>
+ <ToggleField
+ label="Disable Steam Deck Mode"
+ description="Disables Steam Deck mode (unlocks hidden settings in some games)"
+ checked={config.disable_steamdeck_mode}
+ onChange={(value) => onConfigChange('disable_steamdeck_mode', value)}
+ />
+ </PanelSectionRow>
+
+ <PanelSectionRow>
+ <div
+ style={{
+ fontSize: "14px",
+ fontWeight: "bold",
+ marginTop: "16px",
+ marginBottom: "8px",
+ borderBottom: "1px solid rgba(255, 255, 255, 0.2)",
+ paddingBottom: "4px",
+ color: "white"
+ }}
+ >
Experimental Features
</div>
</PanelSectionRow>
diff --git a/src/config/configSchema.ts b/src/config/configSchema.ts
index 9b6fc41..8715057 100644
--- a/src/config/configSchema.ts
+++ b/src/config/configSchema.ts
@@ -77,6 +77,20 @@ export const CONFIG_SCHEMA: Record<string, ConfigField> = {
fieldType: ConfigFieldType.INTEGER,
default: 0,
description: "experimental: base framerate cap for dxvk games, before frame multiplier (0 = disabled)"
+ },
+
+ enable_wow64: {
+ name: "enable_wow64",
+ fieldType: ConfigFieldType.BOOLEAN,
+ default: false,
+ description: "enable PROTON_USE_WOW64=1 for 32-bit games (use with ProtonGE to fix crashing)"
+ },
+
+ disable_steamdeck_mode: {
+ name: "disable_steamdeck_mode",
+ fieldType: ConfigFieldType.BOOLEAN,
+ default: false,
+ description: "disable Steam Deck mode (unlocks hidden settings in some games)"
}
};
@@ -90,6 +104,8 @@ export interface ConfigurationData {
hdr_mode: boolean;
experimental_present_mode: string;
experimental_fps_limit: number;
+ enable_wow64: boolean;
+ disable_steamdeck_mode: boolean;
}
// Centralized configuration manager
diff --git a/tests/test_configuration.py b/tests/test_configuration.py
index a7f80b4..f3fdcbe 100644
--- a/tests/test_configuration.py
+++ b/tests/test_configuration.py
@@ -88,21 +88,31 @@ def test_generate_script_content():
service.user_home = temp_home
service.lsfg_script_path = temp_home / "lsfg"
- content = service._generate_script_content(
- enable_lsfg=True,
- multiplier=4,
- flow_scale=2.0,
- hdr=False,
- perf_mode=True,
- immediate_mode=False
- )
-
- assert "export ENABLE_LSFG=1" in content
- assert "export LSFG_MULTIPLIER=4" in content
- assert "export LSFG_FLOW_SCALE=2.0" in content
- assert "# export LSFG_HDR=1" in content
- assert "export LSFG_PERF_MODE=1" in content
- assert "# export MESA_VK_WSI_PRESENT_MODE=immediate" in content
+ # Test with no toggles enabled
+ config = {
+ "enable_wow64": False,
+ "disable_steamdeck_mode": False
+ }
+ content = service._generate_script_content(config)
+
+ assert "#!/bin/bash" in content
+ assert "export LSFG_PROCESS=decky-lsfg-vk" in content
+ assert "export PROTON_USE_WOW64=1" not in content
+ assert "export SteamDeck=0" not in content
+ assert 'exec "$@"' in content
+
+ # Test with both toggles enabled
+ config = {
+ "enable_wow64": True,
+ "disable_steamdeck_mode": True
+ }
+ content = service._generate_script_content(config)
+
+ assert "#!/bin/bash" in content
+ assert "export PROTON_USE_WOW64=1" in content
+ assert "export SteamDeck=0" in content
+ assert "export LSFG_PROCESS=decky-lsfg-vk" in content
+ assert 'exec "$@"' in content
def test_config_roundtrip():
@@ -118,12 +128,16 @@ def test_config_roundtrip():
# Update config
result = service.update_config(
- enable_lsfg=True,
+ enable=True,
+ dll="/path/to/dll",
multiplier=3,
flow_scale=1.5,
- hdr=True,
- perf_mode=False,
- immediate_mode=True
+ performance_mode=False,
+ hdr_mode=True,
+ experimental_present_mode="immediate",
+ experimental_fps_limit=30,
+ enable_wow64=True,
+ disable_steamdeck_mode=False
)
assert result["success"] is True
@@ -133,6 +147,19 @@ def test_config_roundtrip():
assert read_result["success"] is True
config = read_result["config"]
+ assert config["enable"] is True
+ assert config["dll"] == "/path/to/dll"
+ assert config["multiplier"] == 3
+ assert config["flow_scale"] == 1.5
+ assert config["performance_mode"] is False
+ assert config["hdr_mode"] is True
+ assert config["experimental_present_mode"] == "immediate"
+ assert config["experimental_fps_limit"] == 30
+ assert config["enable_wow64"] is True
+ assert config["disable_steamdeck_mode"] is False
+
+ assert read_result["success"] is True
+ config = read_result["config"]
assert config["enable_lsfg"] is True
assert config["multiplier"] == 3