mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-09-20 03:18:04 +02:00
Name both versions in the firmware overwrite warning
"Firmware 6.20 is installed. It will be erased and replaced with 6.60." is the thing worth double-checking before wiping a firmware - installing off whatever disc is to hand makes going backwards easy to do by accident. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
86fcfdc60a
commit
e4d940604e
@@ -908,7 +908,7 @@ static const char *UPDATE_PSAR_SUFFIX = "PSP_GAME/SYSDIR/UPDATE/DATA.BIN";
|
||||
static const char *UPDATE_SFO_SUFFIX = "PSP_GAME/SYSDIR/UPDATE/PARAM.SFO";
|
||||
|
||||
// A disc updater's PARAM.SFO titles itself "PSP(tm) Update ver 3.95"; we want the number.
|
||||
static std::string VersionFromUpdaterTitle(std::string_view title) {
|
||||
std::string VersionFromUpdaterTitle(std::string_view title) {
|
||||
const size_t space = title.rfind(' ');
|
||||
if (space != std::string_view::npos) {
|
||||
return std::string(title.substr(space + 1));
|
||||
@@ -1068,6 +1068,13 @@ static bool ScanDirRecursive(const Path &dir, int *fileCount, u64 *totalSize) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Whether a directory holds anything at all, without walking into it. flash0's contents are always
|
||||
// in subdirectories (font/, kd/, vsh/, ...), so one listing settles "is anything installed".
|
||||
static bool DirHasEntries(const Path &dir) {
|
||||
std::vector<File::FileInfo> files;
|
||||
return File::GetFilesInDir(dir, &files) && !files.empty();
|
||||
}
|
||||
|
||||
static int CountFilesInDir(const Path &dir) {
|
||||
std::vector<File::FileInfo> files;
|
||||
if (!File::GetFilesInDir(dir, &files)) {
|
||||
@@ -1122,14 +1129,19 @@ static void ParseVersionTxt(std::string_view contents, InstalledFirmwareInfo *in
|
||||
}
|
||||
}
|
||||
|
||||
void ReadInstalledFirmwareInfo(const Path &nandRoot, InstalledFirmwareInfo *info) {
|
||||
void ReadInstalledFirmwareInfo(const Path &nandRoot, InstalledFirmwareInfo *info, bool countFiles) {
|
||||
*info = InstalledFirmwareInfo{};
|
||||
|
||||
const Path flash0 = nandRoot / "flash0";
|
||||
for (const char *dir : { "flash0", "flash1", "ipl" }) {
|
||||
ScanDirRecursive(nandRoot / dir, &info->fileCount, &info->totalSize);
|
||||
if (countFiles) {
|
||||
for (const char *dir : { "flash0", "flash1", "ipl" }) {
|
||||
ScanDirRecursive(nandRoot / dir, &info->fileCount, &info->totalSize);
|
||||
}
|
||||
info->anythingInstalled = info->fileCount > 0;
|
||||
} else {
|
||||
// Cheap equivalent: an install always has files under flash0, so one listing settles it.
|
||||
info->anythingInstalled = DirHasEntries(flash0);
|
||||
}
|
||||
info->anythingInstalled = info->fileCount > 0;
|
||||
if (!info->anythingInstalled) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -141,6 +141,9 @@ bool ReadBundledUpdateInfo(IFileSystem *fs, std::string_view pathPrefix, Bundled
|
||||
// decryption needed, so it's cheap enough to check every disc with. Empty if there's no updater.
|
||||
std::string ReadUpdaterVersion(const Path &filename);
|
||||
|
||||
// Pulls the version out of an updater's SFO title: "PSP(tm) Update ver 3.95" -> "3.95".
|
||||
std::string VersionFromUpdaterTitle(std::string_view title);
|
||||
|
||||
// What's actually in the NAND directory right now. That can be anything from a handful of fonts
|
||||
// we pulled off a game disc to a full firmware unpacked from an updater, so this reports what's
|
||||
// there rather than assuming one or the other.
|
||||
@@ -158,9 +161,10 @@ struct InstalledFirmwareInfo {
|
||||
u64 totalSize = 0;
|
||||
};
|
||||
|
||||
// Walks the NAND directory (the one holding flash0/flash1). A full firmware is only a few
|
||||
// hundred files, so this is cheap, but it does read the whole tree.
|
||||
void ReadInstalledFirmwareInfo(const Path &nandRoot, InstalledFirmwareInfo *info);
|
||||
// Walks the NAND directory (the one holding flash0/flash1). Pass countFiles = false when
|
||||
// fileCount and totalSize aren't wanted: those are the only fields that need the whole tree read,
|
||||
// and a full firmware is a few hundred files, which isn't free on a phone's storage.
|
||||
void ReadInstalledFirmwareInfo(const Path &nandRoot, InstalledFirmwareInfo *info, bool countFiles = true);
|
||||
|
||||
// Wipes what's in the NAND directory: flash0, flash1 and ipl. Two firmwares can't be merged -
|
||||
// files a newer one dropped would linger and still get loaded - so an install starts from empty.
|
||||
|
||||
@@ -46,7 +46,8 @@ InstallUpdateScreen::InstallUpdateScreen(const Path &path, std::string_view titl
|
||||
fileSize_ = fileInfo.size;
|
||||
}
|
||||
// There's no practical way to merge two firmwares, so an install replaces whatever is there.
|
||||
overwrites_ = File::Exists(destination_ / "flash0");
|
||||
ReadInstalledFirmwareInfo(destination_, &installed_, false);
|
||||
overwrites_ = installed_.anythingInstalled;
|
||||
}
|
||||
|
||||
std::string_view InstallUpdateScreen::GetTitle() const {
|
||||
@@ -81,8 +82,18 @@ void InstallUpdateScreen::CreateDialogViews(UI::ViewGroup *parent) {
|
||||
container->Add(new TextView(GetFriendlyPath(destination_)))->SetAlign(FLAG_WRAP_TEXT);
|
||||
|
||||
if (overwrites_) {
|
||||
// The title is whatever the updater's SFO says, so only trust the tail of it if it came
|
||||
// out looking like a version number rather than the last word of some other sentence.
|
||||
std::string newVersion = VersionFromUpdaterTitle(title_);
|
||||
if (newVersion.find('.') == std::string::npos || newVersion[0] < '0' || newVersion[0] > '9') {
|
||||
newVersion.clear();
|
||||
}
|
||||
const std::string_view unknown = "N/A";
|
||||
container->Add(new NoticeView(NoticeLevel::WARN, di->T("Confirm Overwrite"),
|
||||
iz->T("The firmware already installed will be erased first")));
|
||||
ApplySafeSubstitutions(
|
||||
iz->T("ReplaceFirmware", "Firmware %1 is installed. It will be erased and replaced with %2."),
|
||||
installed_.version.empty() ? unknown : std::string_view(installed_.version),
|
||||
newVersion.empty() ? unknown : std::string_view(newVersion))));
|
||||
}
|
||||
|
||||
container->Add(new Spacer(12.0f));
|
||||
|
||||
@@ -77,6 +77,8 @@ private:
|
||||
u64 fileSize_ = 0;
|
||||
bool overwrites_ = false;
|
||||
bool allowRun_ = false;
|
||||
// What's in the NAND right now, for overwrite warnings.
|
||||
InstalledFirmwareInfo installed_;
|
||||
|
||||
std::shared_ptr<InstallState> state_;
|
||||
bool reportedDone_ = false;
|
||||
|
||||
Reference in New Issue
Block a user