Merge pull request #22716 from hrydgard/vsh-mount-iso

Allow --mount in the app, and make VSH UMD autoboot a setting
This commit is contained in:
Henrik Rydgård authored and GitHub committed 2026-10-21 20:57:42 +02:00
commit 03457d559b
11 files changed
+30 -11

No files matched your search

+1 -1
View File
@@ -226,7 +226,7 @@ static const CommandLineParam g_autoParams[] = {
{POFF(timeoutWall), CmdParamType::Double, "timeout", '\0', "Alias for --timeout-wall", CmdLineMode::Headless},
{POFF(frameStats), CmdParamType::Bool, "frame-stats", '\0', "Print flips per emulated second at the end of the run, counted from --state's load", CmdLineMode::Headless},
{POFF(maxScreenshotError), CmdParamType::Double, "max-mse", '\0', "Maximum allowed MSE error for screenshot comparison", CmdLineMode::Headless},
{POFF(mountIso), CmdParamType::String, "mount", 'm', "Mount ISO/CSO on umd1:", CmdLineMode::Headless},
{POFF(mountIso), CmdParamType::String, "mount", 'm', "Mount ISO/CSO on umd1: when booting an ELF/PBP or --vsh"},
{POFF(unpackUpdater), CmdParamType::String, "unpack-updater", '\0', "Unpack the firmware in an updater EBOOT.PBP into DIR and exit", CmdLineMode::Headless},
{POFF(unpackUpdaterModel), CmdParamType::String, "unpack-updater-model", '\0', "PSP model to unpack for (01g..12g, default any)", CmdLineMode::Headless},
{POFF(unpackUpdaterFilter), CmdParamType::String, "unpack-updater-filter", '\0', "Only unpack entries under this path, e.g. flash0:/font/", CmdLineMode::Headless},
+1 -1
View File
@@ -215,7 +215,7 @@ struct CommandLineOptions {
// Headless: preserve the alpha channel when saving PNG screenshots.
std::optional<bool> screenshotSaveKeepAlpha;
// Headless: mount an ISO/CSO on umd1:.
// Mount an ISO/CSO on umd1: when booting an ELF/PBP (or the VSH).
std::optional<std::string> mountIso;
// Headless: also log through OutputDebugString (Windows).
std::optional<bool> odsLog;
+1
View File
@@ -1121,6 +1121,7 @@ static const ConfigSetting systemParamSettings[] = {
ConfigSetting("BypassOSKWithKeyboard", SETTING(g_Config, bBypassOSKWithKeyboard), false, CfgFlag::PER_GAME),
ConfigSetting("WlanPowerSave", SETTING(g_Config, bWlanPowerSave), (bool) PSP_SYSTEMPARAM_WLAN_POWERSAVE_OFF, CfgFlag::PER_GAME),
ConfigSetting("EncryptSave", SETTING(g_Config, bEncryptSave), true, CfgFlag::PER_GAME | CfgFlag::REPORT),
ConfigSetting("VshUmdAutoboot", SETTING(g_Config, bVshUmdAutoboot), false, CfgFlag::DEFAULT),
ConfigSetting("MemStickSize", SETTING(g_Config, iMemStickSizeGB), 16, CfgFlag::DEFAULT),
ConfigSetting("FuseID", SETTING(g_Config, sFuseID), "", CfgFlag::DEFAULT),
};
+2
View File
@@ -594,6 +594,8 @@ public:
int iButtonPreference;
int iLockParentalLevel;
bool bEncryptSave;
// /CONFIG/SYSTEM/umd_autoboot: whether the VSH starts an inserted disc by itself.
bool bVshUmdAutoboot;
// Networking
bool bEnableAdhocServer;
+11 -1
View File
@@ -8,6 +8,7 @@
#include "Common/Serialize/Serializer.h"
#include "Common/Serialize/SerializeMap.h"
#include "Common/StringUtils.h"
#include "Core/Config.h"
#define SYSTEM_REGISTRY "/system"
#define REG_KEYNAME_SIZE 27
@@ -58,6 +59,9 @@ struct KeyValue {
const char *strValue; // also can be used for bin. Note: can't be std::string/string_view, will cut off the length.
int intValue;
const KeyValue *dirContents; // intValue is the count.
// If set, an INT key reads this setting (as 0 or 1), even after the guest writes it: the VSH
// rewrites every key with its default at each boot, since category_version is below its schema.
const bool *boolSetting = nullptr;
};
// Guest-written registry values (sceRegCreateKey / sceRegSetKeyValue), keyed by category path
@@ -764,7 +768,7 @@ static const KeyValue tree_CONFIG_SYSTEM_CHARACTER_SET[] = {
static const KeyValue tree_CONFIG_SYSTEM[] = {
{ "owner_name", ValueType::STR, "P939", 5 },
{ "backlight_brightness", ValueType::INT, "", (int)0x3 }, // decimal: 3
{ "umd_autoboot", ValueType::INT, "", (int)0x1 }, // decimal: 1
{ "umd_autoboot", ValueType::INT, "", (int)0x1, nullptr, &g_Config.bVshUmdAutoboot }, // decimal: 1
{ "usb_charge", ValueType::INT, "", (int)0x1 }, // decimal: 1
{ "umd_cache", ValueType::INT, "", (int)0x1 }, // decimal: 1
{ "usb_auto_connect", ValueType::INT, "", (int)0x1 }, // decimal: 1
@@ -1090,6 +1094,12 @@ static const MergedCategory &GetMergedCategory(const std::string &path) {
}
}
for (auto &kv : merged.keyvals) {
if (kv.boolSetting) {
kv.intValue = *kv.boolSetting ? 1 : 0;
}
}
return merged;
}
+1 -1
View File
@@ -529,7 +529,7 @@ static Path NormalizePath(const Path &path) {
}
bool Load_PSP_ELF_PBP(FileLoader *fileLoader, std::string_view discId, bool loadGameConfigs, std::string *error_string) {
// This is really just for headless, might need tweaking later.
// Set by --mount, which also lets the VSH boot with a disc in the drive.
if (PSP_CoreParameter().mountIsoLoader != nullptr) {
std::shared_ptr<BlockDevice> bd(ConstructBlockDevice(PSP_CoreParameter().mountIsoLoader, error_string));
if (bd) {
+1
View File
@@ -6,6 +6,7 @@
class UIContext;
extern Path boot_filename;
extern Path boot_mountIso;
void UIBackgroundInit(UIContext &dc);
void UIBackgroundShutdown();
+4 -3
View File
@@ -161,8 +161,8 @@ void EmuScreen::SetPSPAnalog(int iInternalScreenRotation, int stick, float x, fl
__CtrlSetAnalogXY(stick, x, y);
}
EmuScreen::EmuScreen(const Path &filename)
: gamePath_(filename) {
EmuScreen::EmuScreen(const Path &filename, const Path &mountIso)
: gamePath_(filename), mountIso_(mountIso) {
saveStateSlot_ = SaveState::GetCurrentSlot();
g_controlMapper.AddListener(this);
@@ -321,7 +321,7 @@ void EmuScreen::ProcessGameBoot(const Path &filename) {
coreParam.graphicsContext = PSP_CoreParameter().graphicsContext;
coreParam.enableSound = g_Config.bEnableSound;
coreParam.fileToStart = filename;
coreParam.mountIso.clear();
coreParam.mountIso = mountIso_;
coreParam.mountRoot = g_Config.mountRoot;
coreParam.startBreak = !g_Config.bAutoRun;
coreParam.headLess = false;
@@ -619,6 +619,7 @@ void EmuScreen::sendMessage(UIMessage message, const char *value) {
bootPending_ = true;
bootIsReset_ = false;
gamePath_ = newGamePath;
mountIso_.clear();
}
} else if (message == UIMessage::CONFIG_LOADED) {
// In case we need to position touch controls differently.
+3 -1
View File
@@ -40,7 +40,8 @@ struct ImGuiContext;
class EmuScreen : public UIScreen, protected ControlListener {
public:
EmuScreen(const Path &filename);
// mountIso, if set, is mounted on umd1: when filename is an ELF/PBP (like the VSH).
EmuScreen(const Path &filename, const Path &mountIso = Path());
~EmuScreen();
const char *tag() const override { return "Emu"; }
@@ -101,6 +102,7 @@ private:
bool bootPending_ = true;
bool bootIsReset_ = false;
Path gamePath_;
Path mountIso_;
bool quit_ = false;
std::string errorMessage_;
+2 -2
View File
@@ -367,7 +367,7 @@ void LogoScreen::Next() {
switch (afterLogoScreen_) {
case AfterLogoScreen::TO_GAME_SETTINGS:
if (!gamePath.empty()) {
screenManager()->switchScreen(new EmuScreen(gamePath));
screenManager()->switchScreen(new EmuScreen(gamePath, boot_mountIso));
} else {
screenManager()->switchScreen(new MainScreen());
}
@@ -379,7 +379,7 @@ void LogoScreen::Next() {
case AfterLogoScreen::DEFAULT:
default:
if (boot_filename.size()) {
screenManager()->switchScreen(new EmuScreen(gamePath));
screenManager()->switchScreen(new EmuScreen(gamePath, boot_mountIso));
} else {
screenManager()->switchScreen(new MainScreen());
}
+3 -1
View File
@@ -411,6 +411,7 @@ std::thread *graphicsLoadThread;
// globals
Path boot_filename;
Path boot_mountIso;
// This is called before NativeInit so we do a little bit of initialization here.
void NativeGetAppInfo(std::string *app_dir_name, std::string *app_nice_name, bool *landscape, std::string *version) {
@@ -701,6 +702,7 @@ void NativeInit(int argc, const char *argv[], const CommandLineOptions &cmdLineO
if (boot_filename.empty() && cmdLineOptions.bootVSH.value_or(false)) {
boot_filename = g_Config.nandRootDirectory / "flash0/vsh/module/vshmain.prx";
}
boot_mountIso = cmdLineOptions.mountIso.has_value() ? Path(cmdLineOptions.mountIso.value()) : Path();
if (cmdLineOptions.appendConfig.has_value()) {
g_Config.SetAppendedConfigIni(Path(cmdLineOptions.appendConfig.value()));
@@ -833,7 +835,7 @@ void NativeInit(int argc, const char *argv[], const CommandLineOptions &cmdLineO
}
} else if (skipLogo && !boot_filename.empty()) {
INFO_LOG(Log::System, "Launching EmuScreen with boot filename '%s'", boot_filename.c_str());
g_screenManager->switchScreen(new EmuScreen(boot_filename));
g_screenManager->switchScreen(new EmuScreen(boot_filename, boot_mountIso));
} else {
g_screenManager->switchScreen(new LogoScreen(AfterLogoScreen::DEFAULT));
}