summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorxXJSONDeruloXx <danielhimebauch@gmail.com>2025-07-17 14:22:56 -0400
committerxXJSONDeruloXx <danielhimebauch@gmail.com>2025-07-17 14:22:56 -0400
commit6b701637ad308513b678c80baceec6c79e339ce9 (patch)
tree1d7e306ad3c93b36515f5cb0622023be7ada0560 /src
parent8a71f528ef34447c43e67db67d071e38ff084ff1 (diff)
downloaddecky-lsfg-vk-6b701637ad308513b678c80baceec6c79e339ce9.tar.gz
decky-lsfg-vk-6b701637ad308513b678c80baceec6c79e339ce9.zip
initial conf FE and BE hooks
Diffstat (limited to 'src')
-rw-r--r--src/api/lsfgApi.ts4
-rw-r--r--src/components/ConfigurationSection.tsx67
-rw-r--r--src/components/Content.tsx2
-rw-r--r--src/components/UsageInstructions.tsx130
-rw-r--r--src/config/configSchema.ts83
-rw-r--r--src/hooks/useLsfgHooks.ts2
6 files changed, 113 insertions, 175 deletions
diff --git a/src/api/lsfgApi.ts b/src/api/lsfgApi.ts
index f7363c1..8cdf6f0 100644
--- a/src/api/lsfgApi.ts
+++ b/src/api/lsfgApi.ts
@@ -76,14 +76,14 @@ export const getConfigSchema = callable<[], ConfigSchemaResult>("get_config_sche
// Updated config function using centralized configuration
export const updateLsfgConfig = callable<
- [boolean, number, number, boolean, boolean, boolean, boolean, number],
+ [boolean, string, number, 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, number, number, boolean, boolean, boolean, boolean, number]);
+ return updateLsfgConfig(...args as [boolean, string, number, number, boolean, boolean]);
};
// Self-updater API functions
diff --git a/src/components/ConfigurationSection.tsx b/src/components/ConfigurationSection.tsx
index 2545217..118b418 100644
--- a/src/components/ConfigurationSection.tsx
+++ b/src/components/ConfigurationSection.tsx
@@ -1,9 +1,9 @@
-import { PanelSectionRow, ToggleField, SliderField } from "@decky/ui";
+import { PanelSectionRow, ToggleField, SliderField, TextField } from "@decky/ui";
import { ConfigurationData } from "../config/configSchema";
interface ConfigurationSectionProps {
config: ConfigurationData;
- onConfigChange: (fieldName: keyof ConfigurationData, value: boolean | number) => Promise<void>;
+ onConfigChange: (fieldName: keyof ConfigurationData, value: boolean | number | string) => Promise<void>;
}
export function ConfigurationSection({
@@ -30,16 +30,25 @@ export function ConfigurationSection({
<PanelSectionRow>
<ToggleField
label="Enable LSFG"
- description="Enables the frame generation layer"
- checked={config.enable_lsfg}
- onChange={(value) => onConfigChange('enable_lsfg', value)}
+ description="enable/disable lsfg on every game"
+ checked={config.enable}
+ onChange={(value) => onConfigChange('enable', value)}
+ />
+ </PanelSectionRow>
+
+ <PanelSectionRow>
+ <TextField
+ label="Lossless.dll Path"
+ description="specify where Lossless.dll is stored"
+ value={config.dll}
+ onChange={(e) => onConfigChange('dll', e.target.value)}
/>
</PanelSectionRow>
<PanelSectionRow>
<SliderField
label="FPS Multiplier"
- description="Traditional FPS multiplier value"
+ description="change the fps multiplier"
value={config.multiplier}
min={2}
max={4}
@@ -57,7 +66,7 @@ export function ConfigurationSection({
<PanelSectionRow>
<SliderField
label={`Flow Scale ${Math.round(config.flow_scale * 100)}%`}
- description="Lowers the internal motion estimation resolution"
+ description="change the flow scale (lower = faster)"
value={config.flow_scale}
min={0.25}
max={1.0}
@@ -68,51 +77,21 @@ export function ConfigurationSection({
<PanelSectionRow>
<ToggleField
- label="HDR Mode"
- description="Enable HDR mode (only if Game supports HDR)"
- checked={config.hdr}
- onChange={(value) => onConfigChange('hdr', value)}
- />
- </PanelSectionRow>
-
- <PanelSectionRow>
- <ToggleField
label="Performance Mode"
- description="Use lighter model for FG"
- checked={config.perf_mode}
- onChange={(value) => onConfigChange('perf_mode', value)}
+ description="toggle performance mode (2x-8x performance increase)"
+ checked={config.performance_mode}
+ onChange={(value) => onConfigChange('performance_mode', value)}
/>
</PanelSectionRow>
<PanelSectionRow>
<ToggleField
- label="Immediate Mode"
- description="Reduce input lag (Experimental, will cause issues in many games)"
- checked={config.immediate_mode}
- onChange={(value) => onConfigChange('immediate_mode', value)}
- />
- </PanelSectionRow>
-
- <PanelSectionRow>
- <SliderField
- label={`Game Frame Cap ${config.frame_cap === 0 ? "(Disabled)" : `(${config.frame_cap} FPS)`}`}
- description="Limit base game FPS (0 = disabled)"
- value={config.frame_cap}
- min={0}
- max={60}
- step={1}
- onChange={(value) => onConfigChange('frame_cap', value)}
+ label="HDR Mode"
+ description="enable hdr mode (doesn't support scrgb)"
+ checked={config.hdr_mode}
+ onChange={(value) => onConfigChange('hdr_mode', value)}
/>
</PanelSectionRow>
-
- {/* <PanelSectionRow>
- <ToggleField
- label="Disable vkbasalt"
- description="Some plugins add vkbasalt layer, which can break lsfg. Toggling on fixes this"
- checked={config.disable_vkbasalt}
- onChange={(value) => onConfigChange('disable_vkbasalt', value)}
- />
- </PanelSectionRow> */}
</>
);
}
diff --git a/src/components/Content.tsx b/src/components/Content.tsx
index ea3f3c1..613e722 100644
--- a/src/components/Content.tsx
+++ b/src/components/Content.tsx
@@ -37,7 +37,7 @@ export function Content() {
}, [isInstalled, loadLsfgConfig]);
// Generic configuration change handler
- const handleConfigChange = async (fieldName: keyof ConfigurationData, value: boolean | number) => {
+ const handleConfigChange = async (fieldName: keyof ConfigurationData, value: boolean | number | string) => {
await updateField(fieldName, value);
};
diff --git a/src/components/UsageInstructions.tsx b/src/components/UsageInstructions.tsx
index 727a0ab..ac721c7 100644
--- a/src/components/UsageInstructions.tsx
+++ b/src/components/UsageInstructions.tsx
@@ -6,88 +6,68 @@ interface UsageInstructionsProps {
}
export function UsageInstructions({ config }: UsageInstructionsProps) {
- // Build manual environment variables string based on current config
- const buildManualEnvVars = (): string => {
- const envVars: string[] = [];
-
- if (config.enable_lsfg) {
- envVars.push("ENABLE_LSFG=1");
- }
-
- // Always include multiplier and flow_scale if LSFG is enabled, as they have defaults
- if (config.enable_lsfg) {
- envVars.push(`LSFG_MULTIPLIER=${config.multiplier}`);
- envVars.push(`LSFG_FLOW_SCALE=${config.flow_scale}`);
- }
-
- if (config.hdr) {
- envVars.push("LSFG_HDR=1");
- }
-
- if (config.perf_mode) {
- envVars.push("LSFG_PERF_MODE=1");
- }
-
- if (config.immediate_mode) {
- envVars.push("MESA_VK_WSI_PRESENT_MODE=immediate");
- }
-
- if (config.disable_vkbasalt) {
- envVars.push("DISABLE_VKBASALT=1");
- }
-
- if (config.frame_cap > 0) {
- envVars.push(`DXVK_FRAME_RATE=${config.frame_cap}`);
- }
-
- return envVars.length > 0 ? `${envVars.join(" ")} %command%` : "%command%";
- };
-
return (
<>
<PanelSectionRow>
<div
style={{
- fontSize: "13px",
- marginTop: "12px",
- padding: "8px",
- backgroundColor: "rgba(255, 255, 255, 0.05)",
- borderRadius: "4px"
+ fontSize: "14px",
+ fontWeight: "bold",
+ marginTop: "16px",
+ marginBottom: "8px",
+ borderBottom: "1px solid rgba(255, 255, 255, 0.2)",
+ paddingBottom: "4px"
+ }}
+ >
+ Usage Instructions
+ </div>
+ </PanelSectionRow>
+
+ <PanelSectionRow>
+ <div
+ style={{
+ fontSize: "12px",
+ lineHeight: "1.4",
+ opacity: "0.8",
+ whiteSpace: "pre-wrap"
+ }}
+ >
+ {config.enable
+ ? "LSFG is enabled globally. The layer will be active for all games automatically. No launch arguments needed."
+ : "LSFG is disabled. Enable it above to activate frame generation for all games."
+ }
+ </div>
+ </PanelSectionRow>
+
+ <PanelSectionRow>
+ <div
+ style={{
+ fontSize: "12px",
+ lineHeight: "1.4",
+ opacity: "0.8",
+ whiteSpace: "pre-wrap"
+ }}
+ >
+ {`Current Configuration:
+• Enable: ${config.enable ? "Yes" : "No"}
+• DLL Path: ${config.dll}
+• Multiplier: ${config.multiplier}x
+• Flow Scale: ${Math.round(config.flow_scale * 100)}%
+• Performance Mode: ${config.performance_mode ? "Yes" : "No"}
+• HDR Mode: ${config.hdr_mode ? "Yes" : "No"}`}
+ </div>
+ </PanelSectionRow>
+
+ <PanelSectionRow>
+ <div
+ style={{
+ fontSize: "11px",
+ lineHeight: "1.3",
+ opacity: "0.6",
+ marginTop: "8px"
}}
>
- <div style={{ fontWeight: "bold", marginBottom: "6px" }}>
- Usage Instructions:
- </div>
- <div style={{ marginBottom: "4px" }}>
- Option 1: Use the lsfg script (recommended):
- </div>
- <div
- style={{
- fontFamily: "monospace",
- backgroundColor: "rgba(0, 0, 0, 0.3)",
- padding: "4px",
- borderRadius: "2px",
- fontSize: "12px",
- marginBottom: "6px"
- }}
- >
- ~/lsfg %command%
- </div>
- <div style={{ marginBottom: "4px" }}>
- Option 2: Manual environment variables:
- </div>
- <div
- style={{
- fontFamily: "monospace",
- backgroundColor: "rgba(0, 0, 0, 0.3)",
- padding: "4px",
- borderRadius: "2px",
- fontSize: "12px",
- marginBottom: "6px"
- }}
- >
- {buildManualEnvVars()}
- </div>
+ The configuration is stored in ~/.config/lsfg-vk/conf.toml and applies to all games globally.
</div>
</PanelSectionRow>
</>
diff --git a/src/config/configSchema.ts b/src/config/configSchema.ts
index 6956030..83dc4aa 100644
--- a/src/config/configSchema.ts
+++ b/src/config/configSchema.ts
@@ -9,95 +9,72 @@
export enum ConfigFieldType {
BOOLEAN = "boolean",
INTEGER = "integer",
- FLOAT = "float"
+ FLOAT = "float",
+ STRING = "string"
}
// Configuration field definition
export interface ConfigField {
name: string;
fieldType: ConfigFieldType;
- default: boolean | number;
+ default: boolean | number | string;
description: string;
- scriptTemplate: string;
- scriptComment?: string;
}
// Configuration schema - must match Python CONFIG_SCHEMA
export const CONFIG_SCHEMA: Record<string, ConfigField> = {
- enable_lsfg: {
- name: "enable_lsfg",
+ enable: {
+ name: "enable",
fieldType: ConfigFieldType.BOOLEAN,
default: true,
- description: "Enables the frame generation layer",
- scriptTemplate: "export ENABLE_LSFG={value}",
- scriptComment: "# export ENABLE_LSFG=1"
+ description: "enable/disable lsfg on every game"
+ },
+
+ dll: {
+ name: "dll",
+ fieldType: ConfigFieldType.STRING,
+ default: "/games/Lossless Scaling/Lossless.dll",
+ description: "specify where Lossless.dll is stored"
},
multiplier: {
name: "multiplier",
fieldType: ConfigFieldType.INTEGER,
default: 2,
- description: "Traditional FPS multiplier value",
- scriptTemplate: "export LSFG_MULTIPLIER={value}"
+ description: "change the fps multiplier"
},
flow_scale: {
name: "flow_scale",
fieldType: ConfigFieldType.FLOAT,
default: 0.8,
- description: "Lowers the internal motion estimation resolution",
- scriptTemplate: "export LSFG_FLOW_SCALE={value}"
- },
-
- hdr: {
- name: "hdr",
- fieldType: ConfigFieldType.BOOLEAN,
- default: false,
- description: "Enable HDR mode (only if Game supports HDR)",
- scriptTemplate: "export LSFG_HDR={value}",
- scriptComment: "# export LSFG_HDR=1"
+ description: "change the flow scale (lower = faster)"
},
- perf_mode: {
- name: "perf_mode",
+ performance_mode: {
+ name: "performance_mode",
fieldType: ConfigFieldType.BOOLEAN,
default: true,
- description: "Use lighter model for FG",
- scriptTemplate: "export LSFG_PERF_MODE={value}",
- scriptComment: "# export LSFG_PERF_MODE=1"
+ description: "toggle performance mode (2x-8x performance increase)"
},
- immediate_mode: {
- name: "immediate_mode",
+ hdr_mode: {
+ name: "hdr_mode",
fieldType: ConfigFieldType.BOOLEAN,
default: false,
- description: "Reduce input lag (Experimental, will cause issues in many games)",
- scriptTemplate: "export MESA_VK_WSI_PRESENT_MODE=immediate # - disable vsync",
- scriptComment: "# export MESA_VK_WSI_PRESENT_MODE=immediate # - disable vsync"
- },
-
- disable_vkbasalt: {
- name: "disable_vkbasalt",
- fieldType: ConfigFieldType.BOOLEAN,
- default: true,
- description: "Some plugins add vkbasalt layer, which can break lsfg. Toggling on fixes this",
- scriptTemplate: "export DISABLE_VKBASALT={value}",
- scriptComment: "# export DISABLE_VKBASALT=1"
- },
-
- frame_cap: {
- name: "frame_cap",
- fieldType: ConfigFieldType.INTEGER,
- default: 0,
- description: "Limit base game FPS (0 = disabled)",
- scriptTemplate: "export DXVK_FRAME_RATE={value}",
- scriptComment: "# export DXVK_FRAME_RATE=60"
+ description: "enable hdr mode (doesn't support scrgb)"
}
};
// Type-safe configuration data structure
export interface ConfigurationData {
- enable_lsfg: boolean;
+ enable: boolean;
+ dll: string;
+ multiplier: number;
+ flow_scale: number;
+ performance_mode: boolean;
+ hdr_mode: boolean;
+}
multiplier: number;
flow_scale: number;
hdr: boolean;
@@ -140,7 +117,7 @@ export class ConfigurationManager {
/**
* Create ordered arguments array from configuration object
*/
- static createArgsFromConfig(config: ConfigurationData): (boolean | number)[] {
+ static createArgsFromConfig(config: ConfigurationData): (boolean | number | string)[] {
return this.getFieldNames().map(fieldName =>
config[fieldName as keyof ConfigurationData]
);
@@ -163,6 +140,8 @@ export class ConfigurationManager {
(validated as any)[fieldName] = parseInt(String(value), 10);
} else if (fieldDef.fieldType === ConfigFieldType.FLOAT) {
(validated as any)[fieldName] = parseFloat(String(value));
+ } else if (fieldDef.fieldType === ConfigFieldType.STRING) {
+ (validated as any)[fieldName] = String(value);
}
}
});
diff --git a/src/hooks/useLsfgHooks.ts b/src/hooks/useLsfgHooks.ts
index 8ff9061..e514d72 100644
--- a/src/hooks/useLsfgHooks.ts
+++ b/src/hooks/useLsfgHooks.ts
@@ -110,7 +110,7 @@ export function useLsfgConfig() {
}
}, []);
- const updateField = useCallback(async (fieldName: keyof ConfigurationData, value: boolean | number): Promise<ConfigUpdateResult> => {
+ const updateField = useCallback(async (fieldName: keyof ConfigurationData, value: boolean | number | string): Promise<ConfigUpdateResult> => {
const newConfig = { ...config, [fieldName]: value };
return updateConfig(newConfig);
}, [config, updateConfig]);