Skip to content

Commit

Permalink
Android: Allow using custom storage paths.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
unknownbrackets committed Feb 18, 2019
1 parent a29fe3f commit 1e94354
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 3 deletions.
80 changes: 78 additions & 2 deletions UI/GameSettingsScreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -736,7 +736,11 @@ void GameSettingsScreen::CreateViews() {
#if defined(USING_WIN_UI)
systemSettings->Add(new CheckBox(&g_Config.bBypassOSKWithKeyboard, sy->T("Enable Windows native keyboard", "Enable Windows native keyboard")));
#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->OnClick.Handle(this, &GameSettingsScreen::OnSavePathMydoc);
SavePathInOtherChoice = systemSettings->Add(new CheckBox(&otherinstalled_, sy->T("Save path in installed.txt", "Save path in installed.txt")));
Expand Down Expand Up @@ -905,7 +909,15 @@ UI::EventReturn GameSettingsScreen::OnJitAffectingSetting(UI::EventParams &e) {
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) {
const std::string PPSSPPpath = File::GetExeDirectory();
Expand Down Expand Up @@ -1067,6 +1079,70 @@ void GameSettingsScreen::onFinish(DialogResult result) {
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) {
// 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.
Expand Down
13 changes: 12 additions & 1 deletion UI/GameSettingsScreen.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#pragma once

#include "ppsspp_config.h"
#include "ui/ui_screen.h"
#include "UI/MiscScreens.h"

Expand All @@ -30,6 +31,7 @@ class GameSettingsScreen : public UIDialogScreenWithGameBackground {

void update() override;
void onFinish(DialogResult result) override;
void sendMessage(const char *message, const char *value) override;
std::string tag() const override { return "settings"; }

UI::Event OnRecentChanged;
Expand All @@ -39,6 +41,9 @@ class GameSettingsScreen : public UIDialogScreenWithGameBackground {
void CallbackRestoreDefaults(bool yes);
void CallbackRenderingBackend(bool yes);
void CallbackRenderingDevice(bool yes);
#if PPSSPP_PLATFORM(ANDROID)
void CallbackMemstickFolder(bool yes);
#endif
bool UseVerticalLayout() const;

private:
Expand Down Expand Up @@ -90,7 +95,9 @@ class GameSettingsScreen : public UIDialogScreenWithGameBackground {
UI::EventReturn OnRenderingBackend(UI::EventParams &e);
UI::EventReturn OnRenderingDevice(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 OnSavePathOther(UI::EventParams &e);
#endif
Expand Down Expand Up @@ -120,6 +127,10 @@ class GameSettingsScreen : public UIDialogScreenWithGameBackground {
bool resolutionEnable_;
bool bloomHackEnable_;
bool tessHWEnable_;

#if PPSSPP_PLATFORM(ANDROID)
std::string pendingMemstickFolder_;
#endif
};

class SettingInfoMessage : public UI::LinearLayout {
Expand Down
9 changes: 9 additions & 0 deletions UI/NativeApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,15 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch
// most sense.
g_Config.memStickDirectory = std::string(external_dir) + "/";
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)
g_Config.memStickDirectory = user_data_path;
g_Config.flash0Directory = std::string(external_dir) + "/flash0/";
Expand Down

3 comments on commit 1e94354

@Toff-kun
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This or possibly another File Explorer related commit between February 09 and 21 made made the Load menu option disappear from the UWP ARM version of PPSSPP.

@hrydgard
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it's very likely that this particular commit did it. Please file an issue though.

@Toff-kun
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. #11855

Please sign in to comment.