Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@ Reshade Shader Loader for Decky Plugin Loader for the handheld Steam Game Loader
More shaders can be added at the `~/.local/share/gamescope/reshade/Shaders` folder such that the `.fx` files are in the
root of the `Shaders` folder. Then you can pick and apply the shader using the plugin.

You can also designate shaders as a "screensaver" (one that blacks the screen out is included by default). Screensaver shaders start
with "SS_" in their name, are enabled by pushing the aptly labeled button, and will stop running if the Deck is moved, a button is pressed,
trackpad or stick activity, or the Deck is put to suspend.

![Example Screenshot](reshadeck.png)

# Caveats
Expand Down
25 changes: 0 additions & 25 deletions defaults/shaders/SS_ScreenOff.fx

This file was deleted.

28 changes: 8 additions & 20 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,33 +20,25 @@
class Plugin:
_enabled = False
_current = "0"
_current_screensaver = "SS_ScreenOff.fx"

def _get_all_shaders():
def _get_all_shaders(self):
return sorted([str(p.name) for p in Path(destination_folder).glob("*.fx")])

async def get_shader_list(self):
shaders = [s for s in Plugin._get_all_shaders() if not s.startswith("SS_")]
return shaders

async def get_screensaver_list(self):
shaders = [s for s in Plugin._get_all_shaders() if s.startswith("SS_")]
shaders = Plugin._get_all_shaders(self)
return shaders

async def get_current_shader(self):
return Plugin._current

async def get_current_screensaver(self):
return Plugin._current_screensaver

async def apply_shader(self, screensaver):
shader = Plugin._current if not screensaver else Plugin._current_screensaver
async def apply_shader(self):
shader = Plugin._current
logger.info("Applying shader " + shader)
try:
ret = subprocess.run([shaders_folder + "/set_shader.sh", shader], capture_output=True)
logger.info(ret)
except Exception:
logger.exepction("apply screensaver")
logger.exception("apply shader")

async def set_shader(self, shader_name):
logger.info("Setting and applying shader " + shader_name)
Expand All @@ -57,11 +49,7 @@ async def set_shader(self, shader_name):
decky_plugin.logger.info(ret)
Plugin._current = shader_name
except Exception:
decky_plugin.logger.exepction("setting shader")

async def set_screensaver(self, shader_name):
logger.info("Setting screensaver " + shader_name)
Plugin._current_screensaver = shader_name
decky_plugin.logger.exception("setting shader")

async def _main(self):
try:
Expand All @@ -73,6 +61,6 @@ async def _main(self):
decky_plugin.logger.debug(f"could not copy {item}")
decky_plugin.logger.info("Initialized")
decky_plugin.logger.info(str(await Plugin.get_shader_list(self)))
await Plugin.apply_shader(self, False)
await Plugin.apply_shader(self)
except Exception:
decky_plugin.logger.exepction("main")
decky_plugin.logger.exception("main")
95 changes: 0 additions & 95 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,68 +23,17 @@ import logo from "../assets/logo.png";
class ReshadeckLogic {
serverAPI: ServerAPI;
dataTakenAt: number = Date.now();
screensaverActive: boolean = false;

constructor(serverAPI: ServerAPI) {
this.serverAPI = serverAPI;
}

handleButtonInput = async (val: any[]) => {
if (!this.screensaverActive) {
return;
}
let cancel = false;
const { flSoftwareGyroDegreesPerSecondPitch,
flSoftwareGyroDegreesPerSecondYaw,
flSoftwareGyroDegreesPerSecondRoll,
ulButtons,
sLeftStickX,
sLeftStickY,
sRightStickX,
sRightStickY,
} = val[0];
if (ulButtons != 0) { cancel = true; }
if (Math.abs(sLeftStickX) > 5000 || Math.abs(sLeftStickY) > 5000 ||
Math.abs(sRightStickX) > 5000 || Math.abs(sRightStickY) > 5000) {
cancel = true;
}

if (!cancel && Date.now() - this.dataTakenAt < 1000) {
return;
}
this.dataTakenAt = Date.now();
let degrees = 10;
if (!cancel && Math.abs(flSoftwareGyroDegreesPerSecondPitch) > degrees ||
Math.abs(flSoftwareGyroDegreesPerSecondYaw) > degrees ||
Math.abs(flSoftwareGyroDegreesPerSecondRoll) > degrees) {
cancel = true;
}

if (cancel) {
await this.serverAPI.callPluginMethod("apply_shader", { "screensaver": false });
await this.serverAPI.toaster.toast({
title: "Waking Up Screen",
body: "Waking Up Screen",
duration: 100,
critical: true
});
this.screensaverActive = false;
}
}

handleSuspend = async (val: any) => {
await this.serverAPI.callPluginMethod("apply_shader", { "screensaver": false });
}
}

const Content: VFC<{ serverAPI: ServerAPI, logic: ReshadeckLogic }> = ({ serverAPI, logic }) => {
const baseShader = { data: "None", label: "No Shader" } as SingleDropdownOption;
const baseScreensaver = { data: "None", label: "No Screensaver" } as SingleDropdownOption;
const [shader_list, set_shader_list] = useState<string[]>([]);
const [selectedShader, setSelectedShader] = useState<DropdownOption>(baseShader);
const [shaderOptions, setShaderOptions] = useState<DropdownOption[]>([baseShader]);
const [selectedScreenSaver, setSelectedScreenSaver] = useState<DropdownOption>(baseShader);
const [screenSaverOptions, setScreenSaverOptions] = useState<DropdownOption[]>([baseScreensaver]);

const getShaderOptions = (le_list: string[], baseShaderOrSS: any) => {
let options: DropdownOption[] = [];
Expand All @@ -98,16 +47,11 @@ const Content: VFC<{ serverAPI: ServerAPI, logic: ReshadeckLogic }> = ({ serverA

const initState = async () => {
let shader_list = (await serverAPI.callPluginMethod("get_shader_list", {})).result as string[];
let screensaver_list = (await serverAPI.callPluginMethod("get_screensaver_list", {})).result as string[];
set_shader_list(shader_list)
setShaderOptions(getShaderOptions(shader_list, baseShader));
setScreenSaverOptions(getShaderOptions(screensaver_list, baseScreensaver));

let curr = await serverAPI.callPluginMethod("get_current_shader", {});
setSelectedShader({ data: curr.result, label: (curr.result == "0" ? "None" : curr.result) } as SingleDropdownOption);

let currSS = await serverAPI.callPluginMethod("get_current_screensaver", {});
setSelectedScreenSaver({ data: currSS.result, label: (currSS.result == "0" ? "None" : currSS.result) } as SingleDropdownOption);
}

useEffect(() => {
Expand All @@ -127,37 +71,6 @@ const Content: VFC<{ serverAPI: ServerAPI, logic: ReshadeckLogic }> = ({ serverA
}}
/>
</PanelSectionRow>
<PanelSectionRow>
<b>Select Screensaver</b>
</PanelSectionRow>
<PanelSectionRow>
<Dropdown
menuLabel="Select screensaver"
strDefaultLabel={selectedScreenSaver.label as string}
rgOptions={screenSaverOptions}
selectedOption={selectedScreenSaver}
onChange={async (newSelectedScreenSaver: DropdownOption) => {
await serverAPI.callPluginMethod("set_screensaver", { "shader_name": newSelectedScreenSaver.data });
setSelectedScreenSaver(newSelectedScreenSaver.data);
}}
/>
</PanelSectionRow>
<PanelSectionRow>
<ButtonItem onClick={async () => {
console.log(selectedScreenSaver);
let ret = await serverAPI.callPluginMethod("apply_shader", { "screensaver": true });
await serverAPI.toaster.toast({
title: "Starting Screensaver",
body: "Starting Screensaver",
duration: 100,
critical: true
});
setTimeout(() => {
(logic as any).screensaverActive = true;
}, 5000)
}
}>Start Screensaver</ButtonItem>
</PanelSectionRow>
<PanelSectionRow>
<div>Place any custom shaders in <pre>~/.local/share/gamescope</pre><pre>/reshade/Shaders</pre> so that the .fx files are in the root of the Shaders folder.</div>
</PanelSectionRow>
Expand All @@ -170,18 +83,10 @@ const Content: VFC<{ serverAPI: ServerAPI, logic: ReshadeckLogic }> = ({ serverA

export default definePlugin((serverApi: ServerAPI) => {
let logic = new ReshadeckLogic(serverApi);
let input_register = window.SteamClient.Input.RegisterForControllerStateChanges(logic.handleButtonInput);
let suspend_registers = [window.SteamClient.System.RegisterForOnSuspendRequest(logic.handleSuspend), window.SteamClient.System.RegisterForOnResumeFromSuspend(logic.handleSuspend)];

return {
title: <div className={staticClasses.Title}>Reshadeck</div>,
content: <Content serverAPI={serverApi} logic={logic} />,
icon: <MdWbShade />,
onDismount() {
input_register.unregister();
suspend_registers[0].unregister();
suspend_registers[1].unregister();
},
alwaysRender: true
};
});