feat: Implemented emulator versions and updating

This commit is contained in:
Simeon Radivoev 2026-04-03 23:02:22 +03:00
parent a69147a4f7
commit 34db717ec5
Signed by: simeonradivoev
GPG key ID: 7611A451D2A5D37A
22 changed files with 434 additions and 212 deletions

View file

@ -11,7 +11,12 @@ export default class DOLPHINIntegration implements PluginType
ctx.hooks.games.emulatorLaunchSupport.tap(desc.name, (ctx) =>
{
if (ctx.emulator === 'DOLPHIN')
return { id: desc.name, possible: !!ctx.source };
return { id: desc.name, supportLevel: "full", capabilities: ["batch", "config", "fullscreen", "resolution", "saves", "states"] };
});
ctx.hooks.emulators.emulatorPostInstall.tapPromise(desc.name, async (ctx) =>
{
await Bun.write(path.join(ctx.path, "portable.txt"), "");
});
ctx.hooks.games.emulatorLaunch.tapPromise(desc.name, async (ctx) =>

View file

@ -15,13 +15,26 @@ export default class PCSX2Integration implements PluginType
{
if (ctx.emulator === 'PCSX2')
{
return { id: desc.name, possible: ctx.source?.type === 'store' };
const baseCapabilities: EmulatorCapabilities[] = ["batch", "fullscreen", "saves", "states"];
if (ctx.source?.type === 'store')
{
return {
id: desc.name,
supportLevel: "full",
capabilities: [...baseCapabilities, "resolution", "config"]
};
}
else
{
return { id: desc.name, supportLevel: "partial", capabilities: [...baseCapabilities] };
}
}
});
ctx.hooks.games.emulatorLaunch.tapPromise(desc.name, async (ctx) =>
{
if (ctx.autoValidCommand.emulator === 'PCSX2' && ctx.autoValidCommand.emulatorSource === 'store' && ctx.autoValidCommand.metadata.emulatorDir)
if (ctx.autoValidCommand.emulator === 'PCSX2' && ctx.autoValidCommand.metadata.emulatorDir)
{
const args = ["-batch"];
if (config.get('launchInFullscreen'))
@ -30,32 +43,35 @@ export default class PCSX2Integration implements PluginType
}
args.push(...["-bigpicture", "-portable", "--", ctx.autoValidCommand.metadata.romPath]);
const configFileContents = await Bun.file(configFile).text();
if (ctx.autoValidCommand.emulatorSource === 'store' && !ctx.dryRun)
{
const configFileContents = await Bun.file(configFile).text();
const biosFolder = path.join(config.get('downloadPath'), "bios", 'PCSX2');
const storageFolder = path.join(config.get('downloadPath'), "storage", 'PCSX2');
const savesFolder = path.join(config.get('downloadPath'), "saves", 'PCSX2');
const biosFolder = path.join(config.get('downloadPath'), "bios", 'PCSX2');
const storageFolder = path.join(config.get('downloadPath'), "storage", 'PCSX2');
const savesFolder = path.join(config.get('downloadPath'), "saves", 'PCSX2');
const view = {
BIOS_PATH: biosFolder,
SNAPSHOTS_PATH: path.join(storageFolder, 'snaps'),
SAVE_STATES_PATH: path.join(savesFolder, 'states'),
MEMORY_CARDS_PATH: path.join(savesFolder, 'saves'),
CACHE_PATH: path.join(storageFolder, 'cache'),
COVERS_PATH: path.join(storageFolder, 'covers'),
TEXTURES_PATH: path.join(storageFolder, 'textures'),
RECURSIVE_PATHS: path.join(config.get('downloadPath'), 'roms', 'PS2'),
};
const view = {
BIOS_PATH: biosFolder,
SNAPSHOTS_PATH: path.join(storageFolder, 'snaps'),
SAVE_STATES_PATH: path.join(savesFolder, 'states'),
MEMORY_CARDS_PATH: path.join(savesFolder, 'saves'),
CACHE_PATH: path.join(storageFolder, 'cache'),
COVERS_PATH: path.join(storageFolder, 'covers'),
TEXTURES_PATH: path.join(storageFolder, 'textures'),
RECURSIVE_PATHS: path.join(config.get('downloadPath'), 'roms', 'PS2'),
};
await Promise.all(Object.values(view).map(p => ensureDir(p)));
await Promise.all(Object.values(view).map(p => ensureDir(p)));
let pscx2Path = '';
if (process.platform === 'win32')
pscx2Path = path.join(ctx.autoValidCommand.metadata.emulatorDir, 'inis');
else
pscx2Path = path.join(ctx.autoValidCommand.metadata.emulatorDir, "PCSX2", 'inis');
let pscx2Path = '';
if (process.platform === 'win32')
pscx2Path = path.join(ctx.autoValidCommand.metadata.emulatorDir, 'inis');
else
pscx2Path = path.join(ctx.autoValidCommand.metadata.emulatorDir, "PCSX2", 'inis');
await Bun.write(path.join(pscx2Path, 'PCSX2.ini'), Mustache.render(configFileContents, view));
await Bun.write(path.join(pscx2Path, 'PCSX2.ini'), Mustache.render(configFileContents, view));
}
return args;
}

View file

@ -14,18 +14,31 @@ export default class PCSX2Integration implements PluginType
{
load (ctx: PluginContextType)
{
ctx.hooks.games.emulatorLaunchSupport.tap(desc.name, (ctx) =>
{
if (ctx.emulator === 'PPSSPP')
{
return { id: desc.name, possible: ctx.source?.type === 'store' };
const baseCapabilities: EmulatorCapabilities[] = ["batch", "fullscreen", "saves", "states"];
if (ctx.source?.type === 'store')
{
return {
id: desc.name,
supportLevel: "full",
capabilities: [...baseCapabilities, "resolution", "config"]
};
}
else
{
return { id: desc.name, supportLevel: "partial", capabilities: [...baseCapabilities] };
}
}
});
ctx.hooks.games.emulatorLaunch.tapPromise(desc.name, async (ctx) =>
{
if (ctx.autoValidCommand.emulator === 'PPSSPP' && ctx.autoValidCommand.emulatorSource === 'store' && ctx.autoValidCommand.metadata.emulatorDir)
if (ctx.autoValidCommand.emulator === 'PPSSPP' && ctx.autoValidCommand.metadata.emulatorDir)
{
const args = [ctx.autoValidCommand.metadata.romPath, "--escape-exit", "--pause-menu-exit"];
if (config.get('launchInFullscreen'))
@ -33,44 +46,47 @@ export default class PCSX2Integration implements PluginType
args.push("--fullscreen");
}
let confPath: string | undefined = undefined;
let controlsPath: string | undefined = undefined;
switch (process.platform)
if (ctx.autoValidCommand.emulatorSource === 'store' && !ctx.dryRun)
{
case "win32":
confPath = configFilePathWin32;
controlsPath = configControlsFilePathWin32;
break;
case 'linux':
confPath = configFilePathLinux;
controlsPath = configControlsFilePathLinux;
break;
}
let confPath: string | undefined = undefined;
let controlsPath: string | undefined = undefined;
let ppssppPath = '';
if (process.platform === 'win32')
{
ppssppPath = path.join(ctx.autoValidCommand.metadata.emulatorDir, 'memstick', 'PSP', 'SYSTEM');
} else
{
//TODO: Use way to set custom memstick path when they support it
ensureDir(path.join(homedir(), '.config', 'ppsspp'));
ppssppPath = path.join(homedir(), '.config', 'ppsspp', 'PSP', 'SYSTEM');
}
switch (process.platform)
{
case "win32":
confPath = configFilePathWin32;
controlsPath = configControlsFilePathWin32;
break;
case 'linux':
confPath = configFilePathLinux;
controlsPath = configControlsFilePathLinux;
break;
}
ensureDir(ppssppPath);
let ppssppPath = '';
if (process.platform === 'win32')
{
ppssppPath = path.join(ctx.autoValidCommand.metadata.emulatorDir, 'memstick', 'PSP', 'SYSTEM');
} else
{
//TODO: Use way to set custom memstick path when they support it
ensureDir(path.join(homedir(), '.config', 'ppsspp'));
ppssppPath = path.join(homedir(), '.config', 'ppsspp', 'PSP', 'SYSTEM');
}
if (confPath)
{
const configFileContents = await Bun.file(confPath).text();
await Bun.write(path.join(ppssppPath, 'ppsspp.ini'), Mustache.render(configFileContents, {}));
}
ensureDir(ppssppPath);
if (controlsPath)
{
const controlsFileContents = await Bun.file(controlsPath).text();
await Bun.write(path.join(ppssppPath, 'controls.ini'), Mustache.render(controlsFileContents, {}));
if (confPath)
{
const configFileContents = await Bun.file(confPath).text();
await Bun.write(path.join(ppssppPath, 'ppsspp.ini'), Mustache.render(configFileContents, {}));
}
if (controlsPath)
{
const controlsFileContents = await Bun.file(controlsPath).text();
await Bun.write(path.join(ppssppPath, 'controls.ini'), Mustache.render(controlsFileContents, {}));
}
}
return args;