Android: Allow using custom storage paths.
This allows a user to keep their save data on an insertable card, or otherwise. Currently, the UI isn't great - errors are easy to miss, and the path must be typed manually.
This commit is contained in:
parent
a29fe3f46e
commit
1e943549c2
3 changed files with 99 additions and 3 deletions
|
@ -736,7 +736,11 @@ void GameSettingsScreen::CreateViews() {
|
||||||
#if defined(USING_WIN_UI)
|
#if defined(USING_WIN_UI)
|
||||||
systemSettings->Add(new CheckBox(&g_Config.bBypassOSKWithKeyboard, sy->T("Enable Windows native keyboard", "Enable Windows native keyboard")));
|
systemSettings->Add(new CheckBox(&g_Config.bBypassOSKWithKeyboard, sy->T("Enable Windows native keyboard", "Enable Windows native keyboard")));
|
||||||
#endif
|
#endif
|
||||||
#if defined(_WIN32) && !PPSSPP_PLATFORM(UWP)
|
#if PPSSPP_PLATFORM(ANDROID)
|
||||||
|
auto memstickPath = systemSettings->Add(new ChoiceWithValueDisplay(&g_Config.memStickDirectory, sy->T("Change Memory Stick folder"), (const char *)nullptr));
|
||||||
|
memstickPath->SetEnabled(!PSP_IsInited());
|
||||||
|
memstickPath->OnClick.Handle(this, &GameSettingsScreen::OnChangeMemStickDir);
|
||||||
|
#elif defined(_WIN32) && !PPSSPP_PLATFORM(UWP)
|
||||||
SavePathInMyDocumentChoice = systemSettings->Add(new CheckBox(&installed_, sy->T("Save path in My Documents", "Save path in My Documents")));
|
SavePathInMyDocumentChoice = systemSettings->Add(new CheckBox(&installed_, sy->T("Save path in My Documents", "Save path in My Documents")));
|
||||||
SavePathInMyDocumentChoice->OnClick.Handle(this, &GameSettingsScreen::OnSavePathMydoc);
|
SavePathInMyDocumentChoice->OnClick.Handle(this, &GameSettingsScreen::OnSavePathMydoc);
|
||||||
SavePathInOtherChoice = systemSettings->Add(new CheckBox(&otherinstalled_, sy->T("Save path in installed.txt", "Save path in installed.txt")));
|
SavePathInOtherChoice = systemSettings->Add(new CheckBox(&otherinstalled_, sy->T("Save path in installed.txt", "Save path in installed.txt")));
|
||||||
|
@ -905,7 +909,15 @@ UI::EventReturn GameSettingsScreen::OnJitAffectingSetting(UI::EventParams &e) {
|
||||||
return UI::EVENT_DONE;
|
return UI::EVENT_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(_WIN32) && !PPSSPP_PLATFORM(UWP)
|
#if PPSSPP_PLATFORM(ANDROID)
|
||||||
|
|
||||||
|
UI::EventReturn GameSettingsScreen::OnChangeMemStickDir(UI::EventParams &e) {
|
||||||
|
I18NCategory *sy = GetI18NCategory("System");
|
||||||
|
System_SendMessage("inputbox", (std::string(sy->T("Memory Stick Folder")) + ":" + g_Config.memStickDirectory).c_str());
|
||||||
|
return UI::EVENT_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(_WIN32) && !PPSSPP_PLATFORM(UWP)
|
||||||
|
|
||||||
UI::EventReturn GameSettingsScreen::OnSavePathMydoc(UI::EventParams &e) {
|
UI::EventReturn GameSettingsScreen::OnSavePathMydoc(UI::EventParams &e) {
|
||||||
const std::string PPSSPPpath = File::GetExeDirectory();
|
const std::string PPSSPPpath = File::GetExeDirectory();
|
||||||
|
@ -1067,6 +1079,70 @@ void GameSettingsScreen::onFinish(DialogResult result) {
|
||||||
NativeMessageReceived("gpu_clearCache", "");
|
NativeMessageReceived("gpu_clearCache", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GameSettingsScreen::sendMessage(const char *message, const char *value) {
|
||||||
|
UIDialogScreenWithGameBackground::sendMessage(message, value);
|
||||||
|
|
||||||
|
I18NCategory *sy = GetI18NCategory("System");
|
||||||
|
I18NCategory *di = GetI18NCategory("Dialog");
|
||||||
|
|
||||||
|
if (!strcmp(message, "inputbox_completed")) {
|
||||||
|
std::vector<std::string> inputboxValue;
|
||||||
|
SplitString(value, ':', inputboxValue);
|
||||||
|
|
||||||
|
#if PPSSPP_PLATFORM(ANDROID)
|
||||||
|
if (inputboxValue.size() >= 2 && inputboxValue[0] == sy->T("Memory Stick Folder")) {
|
||||||
|
// Allow colons in the path.
|
||||||
|
std::string newPath = std::string(value).substr(inputboxValue[0].size() + 1);
|
||||||
|
size_t pos = newPath.find_last_not_of("/");
|
||||||
|
// Gotta have at least something but a /, and also needs to start with a /.
|
||||||
|
if (newPath.empty() || pos == newPath.npos || newPath[0] != '/') {
|
||||||
|
settingInfo_->Show(sy->T("ChangingMemstickPathInvalid", "That path couldn't be used to save Memory Stick files."), nullptr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (pos != newPath.size() - 1) {
|
||||||
|
newPath = newPath.substr(0, pos + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
pendingMemstickFolder_ = newPath;
|
||||||
|
std::string promptMessage = sy->T("ChangingMemstickPath", "Save games, save states, and other data will not be copied to this folder.\n\nChange the Memory Stick folder?");
|
||||||
|
if (!File::Exists(newPath)) {
|
||||||
|
promptMessage = sy->T("ChangingMemstickPathNotExists", "That folder doesn't exist yet.\n\nSave games, save states, and other data will not be copied to this folder.\n\nCreate a new Memory Stick folder?");
|
||||||
|
}
|
||||||
|
// Add the path for clarity and proper confirmation.
|
||||||
|
promptMessage += "\n\n" + newPath + "/";
|
||||||
|
screenManager()->push(new PromptScreen(promptMessage, di->T("Yes"), di->T("No"), std::bind(&GameSettingsScreen::CallbackMemstickFolder, this, std::placeholders::_1)));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if PPSSPP_PLATFORM(ANDROID)
|
||||||
|
void GameSettingsScreen::CallbackMemstickFolder(bool yes) {
|
||||||
|
I18NCategory *sy = GetI18NCategory("System");
|
||||||
|
|
||||||
|
if (yes) {
|
||||||
|
std::string memstickDirFile = g_Config.internalDataDirectory + "/memstick_dir.txt";
|
||||||
|
std::string testWriteFile = pendingMemstickFolder_ + "/.write_verify_file";
|
||||||
|
|
||||||
|
// Already, create away.
|
||||||
|
if (!File::Exists(pendingMemstickFolder_)) {
|
||||||
|
File::CreateFullPath(pendingMemstickFolder_);
|
||||||
|
}
|
||||||
|
if (!writeDataToFile(true, "1", 1, testWriteFile.c_str())) {
|
||||||
|
settingInfo_->Show(sy->T("ChangingMemstickPathInvalid", "That path couldn't be used to save Memory Stick files."), nullptr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
File::Delete(testWriteFile);
|
||||||
|
|
||||||
|
writeDataToFile(true, pendingMemstickFolder_.c_str(), pendingMemstickFolder_.size(), memstickDirFile.c_str());
|
||||||
|
// Save so the settings, at least, are transferred.
|
||||||
|
g_Config.memStickDirectory = pendingMemstickFolder_ + "/";
|
||||||
|
g_Config.Save();
|
||||||
|
screenManager()->RecreateAllViews();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void GameSettingsScreen::CallbackRenderingBackend(bool yes) {
|
void GameSettingsScreen::CallbackRenderingBackend(bool yes) {
|
||||||
// If the user ends up deciding not to restart, set the config back to the current backend
|
// If the user ends up deciding not to restart, set the config back to the current backend
|
||||||
// so it doesn't get switched by accident.
|
// so it doesn't get switched by accident.
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "ppsspp_config.h"
|
||||||
#include "ui/ui_screen.h"
|
#include "ui/ui_screen.h"
|
||||||
#include "UI/MiscScreens.h"
|
#include "UI/MiscScreens.h"
|
||||||
|
|
||||||
|
@ -30,6 +31,7 @@ public:
|
||||||
|
|
||||||
void update() override;
|
void update() override;
|
||||||
void onFinish(DialogResult result) override;
|
void onFinish(DialogResult result) override;
|
||||||
|
void sendMessage(const char *message, const char *value) override;
|
||||||
std::string tag() const override { return "settings"; }
|
std::string tag() const override { return "settings"; }
|
||||||
|
|
||||||
UI::Event OnRecentChanged;
|
UI::Event OnRecentChanged;
|
||||||
|
@ -39,6 +41,9 @@ protected:
|
||||||
void CallbackRestoreDefaults(bool yes);
|
void CallbackRestoreDefaults(bool yes);
|
||||||
void CallbackRenderingBackend(bool yes);
|
void CallbackRenderingBackend(bool yes);
|
||||||
void CallbackRenderingDevice(bool yes);
|
void CallbackRenderingDevice(bool yes);
|
||||||
|
#if PPSSPP_PLATFORM(ANDROID)
|
||||||
|
void CallbackMemstickFolder(bool yes);
|
||||||
|
#endif
|
||||||
bool UseVerticalLayout() const;
|
bool UseVerticalLayout() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -90,7 +95,9 @@ private:
|
||||||
UI::EventReturn OnRenderingBackend(UI::EventParams &e);
|
UI::EventReturn OnRenderingBackend(UI::EventParams &e);
|
||||||
UI::EventReturn OnRenderingDevice(UI::EventParams &e);
|
UI::EventReturn OnRenderingDevice(UI::EventParams &e);
|
||||||
UI::EventReturn OnJitAffectingSetting(UI::EventParams &e);
|
UI::EventReturn OnJitAffectingSetting(UI::EventParams &e);
|
||||||
#ifdef _WIN32
|
#if PPSSPP_PLATFORM(ANDROID)
|
||||||
|
UI::EventReturn OnChangeMemStickDir(UI::EventParams &e);
|
||||||
|
#elif defined(_WIN32) && !PPSSPP_PLATFORM(UWP)
|
||||||
UI::EventReturn OnSavePathMydoc(UI::EventParams &e);
|
UI::EventReturn OnSavePathMydoc(UI::EventParams &e);
|
||||||
UI::EventReturn OnSavePathOther(UI::EventParams &e);
|
UI::EventReturn OnSavePathOther(UI::EventParams &e);
|
||||||
#endif
|
#endif
|
||||||
|
@ -120,6 +127,10 @@ private:
|
||||||
bool resolutionEnable_;
|
bool resolutionEnable_;
|
||||||
bool bloomHackEnable_;
|
bool bloomHackEnable_;
|
||||||
bool tessHWEnable_;
|
bool tessHWEnable_;
|
||||||
|
|
||||||
|
#if PPSSPP_PLATFORM(ANDROID)
|
||||||
|
std::string pendingMemstickFolder_;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
class SettingInfoMessage : public UI::LinearLayout {
|
class SettingInfoMessage : public UI::LinearLayout {
|
||||||
|
|
|
@ -466,6 +466,15 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch
|
||||||
// most sense.
|
// most sense.
|
||||||
g_Config.memStickDirectory = std::string(external_dir) + "/";
|
g_Config.memStickDirectory = std::string(external_dir) + "/";
|
||||||
g_Config.flash0Directory = std::string(external_dir) + "/flash0/";
|
g_Config.flash0Directory = std::string(external_dir) + "/flash0/";
|
||||||
|
|
||||||
|
std::string memstickDirFile = g_Config.internalDataDirectory + "/memstick_dir.txt";
|
||||||
|
if (File::Exists(memstickDirFile)) {
|
||||||
|
std::string memstickDir;
|
||||||
|
readFileToString(true, memstickDirFile.c_str(), memstickDir);
|
||||||
|
if (!memstickDir.empty() && File::Exists(memstickDir)) {
|
||||||
|
g_Config.memStickDirectory = memstickDir + "/";
|
||||||
|
}
|
||||||
|
}
|
||||||
#elif defined(IOS)
|
#elif defined(IOS)
|
||||||
g_Config.memStickDirectory = user_data_path;
|
g_Config.memStickDirectory = user_data_path;
|
||||||
g_Config.flash0Directory = std::string(external_dir) + "/flash0/";
|
g_Config.flash0Directory = std::string(external_dir) + "/flash0/";
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue