From 90071fd8684571a5f111a74552449eb9b425deef Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= <hrydgard@gmail.com>
Date: Sun, 17 May 2020 14:44:11 +0200
Subject: [PATCH 1/3] Fix a crash bug in homebrew store

---
 UI/Store.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/UI/Store.cpp b/UI/Store.cpp
index 23f02fd42f..780a7f4c99 100644
--- a/UI/Store.cpp
+++ b/UI/Store.cpp
@@ -244,6 +244,7 @@ void ProductView::CreateViews() {
 	auto di = GetI18NCategory("Dialog");
 	wasInstalled_ = IsGameInstalled();
 	if (!wasInstalled_) {
+		launchButton_ = nullptr;
 		installButton_ = Add(new Button(st->T("Install")));
 		installButton_->OnClick.Handle(this, &ProductView::OnInstall);
 	} else {

From 7c8bcb2ee46e2a76f284f129f3ec94e1528fafe4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= <hrydgard@gmail.com>
Date: Sun, 17 May 2020 14:57:12 +0200
Subject: [PATCH 2/3] Fix homebrew store button to work even after changing
 grid layouts (it lost its click handler)

---
 UI/MainScreen.cpp | 23 +++++++----------------
 UI/MainScreen.h   | 19 ++++++++-----------
 2 files changed, 15 insertions(+), 27 deletions(-)

diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp
index b5d26b1547..dad5f7cd3c 100644
--- a/UI/MainScreen.cpp
+++ b/UI/MainScreen.cpp
@@ -628,7 +628,6 @@ void GameBrowser::Refresh() {
 	lastScale_ = g_Config.fGameGridScale;
 	lastLayoutWasGrid_ = *gridStyle_;
 
-	homebrewStoreButton_ = nullptr;
 	// Kill all the contents
 	Clear();
 
@@ -785,9 +784,7 @@ void GameBrowser::Refresh() {
 
 	if (browseFlags_ & BrowseFlags::HOMEBREW_STORE) {
 		Add(new Spacer());
-		homebrewStoreButton_ = Add(new Choice(mm->T("DownloadFromStore", "Download from the PPSSPP Homebrew Store"), new UI::LinearLayoutParams(UI::WRAP_CONTENT, UI::WRAP_CONTENT)));
-	} else {
-		homebrewStoreButton_ = nullptr;
+		Add(new Choice(mm->T("DownloadFromStore", "Download from the PPSSPP Homebrew Store"), new UI::LinearLayoutParams(UI::WRAP_CONTENT, UI::WRAP_CONTENT)))->OnClick.Handle(this, &GameBrowser::OnHomebrewStore);
 	}
 
 	if (!lastText_.empty() && gameButtons.empty()) {
@@ -908,7 +905,12 @@ UI::EventReturn GameBrowser::OnRecentClear(UI::EventParams &e) {
 	return UI::EVENT_DONE;
 }
 
-MainScreen::MainScreen() : highlightProgress_(0.0f), prevHighlightProgress_(0.0f), backFromStore_(false), lockBackgroundAudio_(false) {
+UI::EventReturn GameBrowser::OnHomebrewStore(UI::EventParams &e) {
+	screenManager_->push(new StoreScreen());
+	return UI::EVENT_DONE;
+}
+
+MainScreen::MainScreen() {
 	System_SendMessage("event", "mainscreen");
 	SetBackgroundAudioGame("");
 	lastVertical_ = UseVerticalLayout();
@@ -918,7 +920,6 @@ MainScreen::~MainScreen() {
 	SetBackgroundAudioGame("");
 }
 
-
 void MainScreen::CreateViews() {
 	// Information in the top left.
 	// Back button to the bottom left.
@@ -974,11 +975,6 @@ void MainScreen::CreateViews() {
 			mm->T("How to get homebrew & demos", "How to get homebrew && demos"), "https://www.ppsspp.org/gethomebrew.html",
 			new LinearLayoutParams(FILL_PARENT, FILL_PARENT));
 
-		Choice *hbStore = tabHomebrew->HomebrewStoreButton();
-		if (hbStore) {
-			hbStore->OnClick.Handle(this, &MainScreen::OnHomebrewStore);
-		}
-
 		scrollAllGames->Add(tabAllGames);
 		gameBrowsers_.push_back(tabAllGames);
 		scrollHomebrew->Add(tabHomebrew);
@@ -1323,11 +1319,6 @@ UI::EventReturn MainScreen::OnCredits(UI::EventParams &e) {
 	return UI::EVENT_DONE;
 }
 
-UI::EventReturn MainScreen::OnHomebrewStore(UI::EventParams &e) {
-	screenManager()->push(new StoreScreen());
-	return UI::EVENT_DONE;
-}
-
 UI::EventReturn MainScreen::OnSupport(UI::EventParams &e) {
 #ifdef __ANDROID__
 	LaunchBrowser("market://details?id=org.ppsspp.ppssppgold");
diff --git a/UI/MainScreen.h b/UI/MainScreen.h
index b2052d3474..832d104043 100644
--- a/UI/MainScreen.h
+++ b/UI/MainScreen.h
@@ -53,8 +53,6 @@ public:
 	UI::Event OnHoldChoice;
 	UI::Event OnHighlight;
 
-	UI::Choice *HomebrewStoreButton() { return homebrewStoreButton_; }
-
 	void FocusGame(const std::string &gamePath);
 	void SetPath(const std::string &path);
 	void Draw(UIContext &dc) override;
@@ -81,14 +79,14 @@ private:
 	UI::EventReturn PinToggleClick(UI::EventParams &e);
 	UI::EventReturn GridSettingsClick(UI::EventParams &e);
 	UI::EventReturn OnRecentClear(UI::EventParams &e);
+	UI::EventReturn OnHomebrewStore(UI::EventParams &e);
 
 	UI::ViewGroup *gameList_ = nullptr;
 	PathBrowser path_;
-	bool *gridStyle_;
+	bool *gridStyle_ = nullptr;
 	BrowseFlags browseFlags_;
 	std::string lastText_;
 	std::string lastLink_;
-	UI::Choice *homebrewStoreButton_ = nullptr;
 	std::string focusGamePath_;
 	bool listingPending_ = false;
 	float lastScale_ = 1.0f;
@@ -131,21 +129,20 @@ protected:
 	UI::EventReturn OnExit(UI::EventParams &e);
 	UI::EventReturn OnDownloadUpgrade(UI::EventParams &e);
 	UI::EventReturn OnDismissUpgrade(UI::EventParams &e);
-	UI::EventReturn OnHomebrewStore(UI::EventParams &e);
 	UI::EventReturn OnAllowStorage(UI::EventParams &e);
 
-	UI::LinearLayout *upgradeBar_;
-	UI::TabHolder *tabHolder_;
+	UI::LinearLayout *upgradeBar_ = nullptr;
+	UI::TabHolder *tabHolder_ = nullptr;
 
 	std::string restoreFocusGamePath_;
 	std::vector<GameBrowser *> gameBrowsers_;
 
 	std::string highlightedGamePath_;
 	std::string prevHighlightedGamePath_;
-	float highlightProgress_;
-	float prevHighlightProgress_;
-	bool backFromStore_;
-	bool lockBackgroundAudio_;
+	float highlightProgress_ = 0.0f;
+	float prevHighlightProgress_ = 0.0f;
+	bool backFromStore_ = false;
+	bool lockBackgroundAudio_ = false;
 	bool lastVertical_;
 	bool confirmedTemporary_ = false;
 

From 9ed9468d7225941f6b1fccb0d63bb391631fff1a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= <hrydgard@gmail.com>
Date: Sun, 17 May 2020 15:12:38 +0200
Subject: [PATCH 3/3] Make the IsValidPBP DISC_ID check a bit more lenient.
 Fixes an issue where some homebrew would no longer show in the list.

---
 UI/MainScreen.cpp             | 6 +++---
 ext/native/file/file_util.cpp | 1 +
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp
index dad5f7cd3c..43535913d7 100644
--- a/UI/MainScreen.cpp
+++ b/UI/MainScreen.cpp
@@ -601,7 +601,7 @@ void GameBrowser::Draw(UIContext &dc) {
 	}
 }
 
-static bool IsValidPBP(const std::string &path) {
+static bool IsValidPBP(const std::string &path, bool allowHomebrew) {
 	if (!File::Exists(path))
 		return false;
 
@@ -613,7 +613,7 @@ static bool IsValidPBP(const std::string &path) {
 
 	ParamSFOData sfo;
 	sfo.ReadSFO(sfoData);
-	if (sfo.GetValueString("DISC_ID").empty())
+	if (!allowHomebrew && sfo.GetValueString("DISC_ID").empty())
 		return false;
 
 	if (sfo.GetValueString("CATEGORY") == "ME")
@@ -705,7 +705,7 @@ void GameBrowser::Refresh() {
 			bool isGame = !fileInfo[i].isDirectory;
 			bool isSaveData = false;
 			// Check if eboot directory
-			if (!isGame && path_.GetPath().size() >= 4 && IsValidPBP(path_.GetPath() + fileInfo[i].name + "/EBOOT.PBP"))
+			if (!isGame && path_.GetPath().size() >= 4 && IsValidPBP(path_.GetPath() + fileInfo[i].name + "/EBOOT.PBP", true))
 				isGame = true;
 			else if (!isGame && File::Exists(path_.GetPath() + fileInfo[i].name + "/PSP_GAME/SYSDIR"))
 				isGame = true;
diff --git a/ext/native/file/file_util.cpp b/ext/native/file/file_util.cpp
index 57fd61926e..5b1087b425 100644
--- a/ext/native/file/file_util.cpp
+++ b/ext/native/file/file_util.cpp
@@ -287,6 +287,7 @@ size_t getFilesInDir(const char *directory, std::vector<FileInfo> *files, const
 		info.isDirectory = isDirectory(info.fullName);
 		info.exists = true;
 		info.size = 0;
+		info.isWritable = false;  // TODO - implement some kind of check
 		if (!info.isDirectory) {
 			std::string ext = getFileExtension(info.fullName);
 			if (filter) {