From c53b32d1545e4b94bfe4ffbcb8f7d26dae7d9b91 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Tue, 26 Nov 2013 14:04:29 +0100 Subject: [PATCH] Show a dismissable notification if PPSSPP is behind the latest official release --- CMakeLists.txt | 2 + Core/Config.cpp | 89 ++++++++++++++++++++++++++++++++++++-- Core/Config.h | 16 +++++++ Qt/Native.pro | 6 ++- UI/MainScreen.cpp | 44 +++++++++++++++++++ UI/MainScreen.h | 4 ++ UI/NativeApp.cpp | 10 +++-- Windows/PPSSPP.sln | 4 ++ native | 2 +- unittest/UnitTests.vcxproj | 3 ++ 10 files changed, 169 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b600fde43e..cfce950a01 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -640,6 +640,8 @@ add_library(native STATIC native/util/random/rng.h native/util/text/utf8.h native/util/text/utf8.cpp + native/util/text/parsers.h + native/util/text/parsers.cpp native/util/const_map.h native/ext/jpge/jpgd.cpp native/ext/jpge/jpgd.h diff --git a/Core/Config.cpp b/Core/Config.cpp index 8a4a63fd8b..e710c3f36f 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -17,15 +17,24 @@ #include "base/display.h" #include "base/NativeApp.h" +#include "ext/vjson/json.h" +#include "file/ini_file.h" +#include "i18n/i18n.h" +#include "gfx_es2/gpu_features.h" +#include "net/http_client.h" +#include "util/text/parsers.h" + +#include "Common/CPUDetect.h" #include "Common/KeyMap.h" #include "Common/FileUtil.h" #include "Common/StringUtils.h" #include "Config.h" -#include "file/ini_file.h" -#include "i18n/i18n.h" -#include "gfx_es2/gpu_features.h" #include "HLE/sceUtility.h" -#include "Common/CPUDetect.h" + +extern const char *PPSSPP_GIT_VERSION; + +// TODO: Find a better place for this. +http::Downloader g_DownloadManager; Config g_Config; @@ -325,6 +334,24 @@ void Config::Load(const char *iniFileName, const char *controllerIniFilename) { IniFile::Section *jitConfig = iniFile.GetOrCreateSection("JIT"); jitConfig->Get("DiscardRegsOnJRRA", &bDiscardRegsOnJRRA, false); + IniFile::Section *upgrade = iniFile.GetOrCreateSection("Upgrade"); + upgrade->Get("UpgradeMessage", &upgradeMessage, ""); + upgrade->Get("UpgradeVersion", &upgradeVersion, ""); + upgrade->Get("DismissedVersion", &dismissedVersion, ""); + + if (dismissedVersion == upgradeVersion) { + upgradeMessage = ""; + } + + // Check for new version on every 5 runs. + // Sometimes the download may not be finished when the main screen shows (if the user dismisses the + // splash screen quickly), but then we'll just show the notification next time instead, we store the + // upgrade number in the ini. + if (iRunCount % 5 == 0) { + g_DownloadManager.StartDownloadWithCallback( + "http://www.ppsspp.org/version.json", "", &DownloadCompletedCallback); + } + INFO_LOG(LOADER, "Loading controller config: %s", controllerIniFilename_.c_str()); bSaveSettings = true; @@ -528,6 +555,12 @@ void Config::Save() { speedhacks->Set("PrescaleUV", bPrescaleUV); speedhacks->Set("DisableAlphaTest", bDisableAlphaTest); + // Save upgrade check state + IniFile::Section *upgrade = iniFile.GetOrCreateSection("Upgrade"); + upgrade->Set("UpgradeMessage", upgradeMessage); + upgrade->Set("UpgradeVersion", upgradeVersion); + upgrade->Set("DismissedVersion", dismissedVersion); + if (!iniFile.Save(iniFilename_.c_str())) { ERROR_LOG(LOADER, "Error saving config - can't write ini %s", iniFilename_.c_str()); return; @@ -551,6 +584,54 @@ void Config::Save() { } } +// Use for debugging the version check without messing with the server +#if 0 +#define PPSSPP_GIT_VERSION "v0.0.1-gaaaaaaaaa" +#endif + +void Config::DownloadCompletedCallback(http::Download &download) { + if (download.ResultCode() != 200) { + ERROR_LOG(LOADER, "Failed to download version.json"); + } + std::string data; + download.buffer().TakeAll(&data); + JsonReader reader(data.c_str(), data.size()); + const json_value *root = reader.root(); + std::string version = root->getString("version", ""); + + const char *gitVer = PPSSPP_GIT_VERSION; + Version installed(gitVer); + Version upgrade(version); + Version dismissed(g_Config.dismissedVersion); + + if (!installed.IsValid()) { + ERROR_LOG(LOADER, "Version check: Local version string invalid. Build problems? %s", PPSSPP_GIT_VERSION); + return; + } + if (!upgrade.IsValid()) { + ERROR_LOG(LOADER, "Version check: Invalid server version: %s", version.c_str()); + return; + } + + if (installed >= upgrade) { + INFO_LOG(LOADER, "Version check: Already up to date, erasing any upgrade message"); + g_Config.upgradeMessage = ""; + g_Config.upgradeVersion = upgrade.ToString(); + g_Config.dismissedVersion = ""; + return; + } + + if (installed < upgrade && dismissed != upgrade) { + g_Config.upgradeMessage = "New version of PPSSPP available!"; + g_Config.upgradeVersion = upgrade.ToString(); + g_Config.dismissedVersion = ""; + } +} + +void Config::DismissUpgrade() { + g_Config.dismissedVersion = g_Config.upgradeVersion; +} + void Config::AddRecent(const std::string &file) { for (auto str = recentIsos.begin(); str != recentIsos.end(); ++str) { #ifdef _WIN32 diff --git a/Core/Config.h b/Core/Config.h index f0130e9e64..1ede569d58 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -28,6 +28,11 @@ extern const char *PPSSPP_GIT_VERSION; const int MAX_CONFIG_VOLUME = 8; +namespace http { + class Download; + class Downloader; +} + struct Config { public: Config(); @@ -238,6 +243,11 @@ public: std::string flash0Directory; std::string internalDataDirectory; + // Data for upgrade prompt + std::string upgradeMessage; // The actual message from the server is currently not used, need a translation mechanism. So this just acts as a flag. + std::string upgradeVersion; + std::string dismissedVersion; + void Load(const char *iniFileName = "ppsspp.ini", const char *controllerIniFilename = "controls.ini"); void Save(); void RestoreDefaults(); @@ -252,6 +262,9 @@ public: void AddRecent(const std::string &file); void CleanRecent(); + static void DownloadCompletedCallback(http::Download &download); + void DismissUpgrade(); + private: std::string iniFilename_; std::string controllerIniFilename_; @@ -259,4 +272,7 @@ private: std::string defaultPath_; }; +// TODO: Find a better place for this. +extern http::Downloader g_DownloadManager; extern Config g_Config; + diff --git a/Qt/Native.pro b/Qt/Native.pro index fcc1a056c0..b46b7a5f20 100755 --- a/Qt/Native.pro +++ b/Qt/Native.pro @@ -90,7 +90,8 @@ SOURCES += $$P/native/audio/*.cpp \ $$P/native/util/bits/*.cpp \ $$P/native/util/hash/hash.cpp \ $$P/native/util/random/perlin.cpp \ - $$P/native/util/text/utf8.cpp + $$P/native/util/text/utf8.cpp \ + $$P/native/util/text/parsers.cpp HEADERS += $$P/native/audio/*.h \ $$P/native/base/basictypes.h \ @@ -123,6 +124,7 @@ HEADERS += $$P/native/audio/*.h \ $$P/native/util/bits/*.h \ $$P/native/util/hash/hash.h \ $$P/native/util/random/*.h \ - $$P/native/util/text/utf8.h + $$P/native/util/text/utf8.h \ + $$P/native/util/text/parsers.h INCLUDEPATH += $$P/native diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index 299f5836ab..5806a646a5 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -480,6 +480,7 @@ void MainScreen::CreateViews() { gold->SetIcon(I_ICONGOLD); #endif rightColumnItems->Add(new Choice(m->T("Exit")))->OnClick.Handle(this, &MainScreen::OnExit); + if (vertical) { root_ = new LinearLayout(ORIENT_VERTICAL); rightColumn->ReplaceLayoutParams(new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)); @@ -493,6 +494,49 @@ void MainScreen::CreateViews() { root_->Add(leftColumn); root_->Add(rightColumn); } + + I18NCategory *u = GetI18NCategory("Upgrade"); + + upgradeBar_ = 0; + if (!g_Config.upgradeMessage.empty()) { + upgradeBar_ = new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)); + + UI::Margins textMargins(10, 5); + UI::Margins buttonMargins(0, 0); + UI::Drawable solid(0xFFbd9939); + upgradeBar_->SetBG(solid); + upgradeBar_->Add(new TextView(u->T("New version of PPSSPP available") + std::string(": ") + g_Config.upgradeVersion, new LinearLayoutParams(1.0f, textMargins))); + upgradeBar_->Add(new Button(u->T("Download"), new LinearLayoutParams(buttonMargins)))->OnClick.Handle(this, &MainScreen::OnDownloadUpgrade); + upgradeBar_->Add(new Button(u->T("Dismiss"), new LinearLayoutParams(buttonMargins)))->OnClick.Handle(this, &MainScreen::OnDismissUpgrade); + + // Slip in under root_ + LinearLayout *newRoot = new LinearLayout(ORIENT_VERTICAL); + newRoot->Add(root_); + newRoot->Add(upgradeBar_); + root_->ReplaceLayoutParams(new LinearLayoutParams(1.0)); + root_ = newRoot; + } +} + +UI::EventReturn MainScreen::OnDownloadUpgrade(UI::EventParams &e) { +#ifdef ANDROID + // Go to app store +#ifdef GOLD + LaunchBrowser("market://details?id=org.ppsspp.ppssppgold"); +#else + LaunchBrowser("market://details?id=org.ppsspp.ppsspp"); +#endif +#else + // Go directly to ppsspp.org and let the user sort it out + LaunchBrowser("http://www.ppsspp.org/downloads.html"); +#endif + return EVENT_DONE; +} + +UI::EventReturn MainScreen::OnDismissUpgrade(UI::EventParams &e) { + g_Config.DismissUpgrade(); + upgradeBar_->SetVisibility(V_GONE); + return EVENT_DONE; } void MainScreen::sendMessage(const char *message, const char *value) { diff --git a/UI/MainScreen.h b/UI/MainScreen.h index 49de1b45b0..308f86473c 100644 --- a/UI/MainScreen.h +++ b/UI/MainScreen.h @@ -49,6 +49,10 @@ private: UI::EventReturn OnPPSSPPOrg(UI::EventParams &e); UI::EventReturn OnForums(UI::EventParams &e); UI::EventReturn OnExit(UI::EventParams &e); + UI::EventReturn OnDownloadUpgrade(UI::EventParams &e); + UI::EventReturn OnDismissUpgrade(UI::EventParams &e); + + UI::LinearLayout *upgradeBar_; }; class GamePauseScreen : public UIDialogScreen { diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 436825376b..f1b31ee9c5 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -34,10 +34,10 @@ #include "base/NativeApp.h" #include "file/vfs.h" #include "file/zip_read.h" -#include "native/ext/stb_image_write/stb_image_writer.h" -#include "native/ext/jpge/jpge.h" -#include "native/util/text/utf8.h" -#include "native/thread/thread.h" +#include "ext/stb_image_write/stb_image_writer.h" +#include "ext/jpge/jpge.h" +#include "thread/thread.h" +#include "net/http_client.h" #include "gfx_es2/gl_state.h" #include "gfx_es2/draw_text.h" #include "gfx_es2/draw_buffer.h" @@ -51,6 +51,7 @@ #include "ui/screen.h" #include "ui/ui_context.h" #include "ui/view.h" +#include "util/text/utf8.h" #include "Common/FileUtil.h" #include "Common/LogManager.h" @@ -598,6 +599,7 @@ void NativeUpdate(InputState &input) { } } + g_DownloadManager.Update(); screenManager->update(input); } diff --git a/Windows/PPSSPP.sln b/Windows/PPSSPP.sln index cd12576b10..d589d3d501 100644 --- a/Windows/PPSSPP.sln +++ b/Windows/PPSSPP.sln @@ -32,6 +32,9 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Core", "..\Core\Core.vcxpro EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "native", "..\native\native.vcxproj", "{C4DF647E-80EA-4111-A0A8-218B1B711E18}" + ProjectSection(ProjectDependencies) = postProject + {F761046E-6C38-4428-A5F1-38391A37BB34} = {F761046E-6C38-4428-A5F1-38391A37BB34} + EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PPSSPPHeadless", "..\headless\Headless.vcxproj", "{EE9BD869-CAA3-447D-8328-294D90DE2C1F}" ProjectSection(ProjectDependencies) = postProject @@ -46,6 +49,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libkirk", "..\ext\libkirk\l EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnitTest", "..\unittest\UnitTests.vcxproj", "{37CBC214-7CE7-4655-B619-F7CEE16E3313}" ProjectSection(ProjectDependencies) = postProject + {F761046E-6C38-4428-A5F1-38391A37BB34} = {F761046E-6C38-4428-A5F1-38391A37BB34} {C4DF647E-80EA-4111-A0A8-218B1B711E18} = {C4DF647E-80EA-4111-A0A8-218B1B711E18} EndProjectSection EndProject diff --git a/native b/native index 3bb995319b..d2e70ce06f 160000 --- a/native +++ b/native @@ -1 +1 @@ -Subproject commit 3bb995319bc6142e93a066edb0d864033b51e0cc +Subproject commit d2e70ce06fd54e0c884afe8d8b876ae28ce16df0 diff --git a/unittest/UnitTests.vcxproj b/unittest/UnitTests.vcxproj index 0ef1bb9656..0f30f866e9 100644 --- a/unittest/UnitTests.vcxproj +++ b/unittest/UnitTests.vcxproj @@ -170,6 +170,9 @@ {533f1d30-d04d-47cc-ad71-20f658907e36} + + {f761046e-6c38-4428-a5f1-38391a37bb34} + {c4df647e-80ea-4111-a0a8-218b1b711e18}