mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-09-07 05:03:35 +02:00
Merge pull request #14823 from hrydgard/storage-fixes
Android: Disallow using the folder selection on older system versions
This commit is contained in:
@@ -356,7 +356,6 @@ void DrawBuffer::DrawImageRotatedStretch(ImageID atlas_image, const Bounds &boun
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: add arc support
|
||||
void DrawBuffer::Circle(float xc, float yc, float radius, float thickness, int segments, float startAngle, uint32_t color, float u_mul) {
|
||||
float angleDelta = PI * 2 / segments;
|
||||
float uDelta = 1.0f / segments;
|
||||
@@ -372,12 +371,31 @@ void DrawBuffer::Circle(float xc, float yc, float radius, float thickness, int s
|
||||
float c1 = cosf(angle1), s1 = sinf(angle1), c2 = cosf(angle2), s2 = sinf(angle2);
|
||||
const float x[4] = {c1 * r1 + xc, c2 * r1 + xc, c1 * r2 + xc, c2 * r2 + xc};
|
||||
const float y[4] = {s1 * r1 + yc, s2 * r1 + yc, s1 * r2 + yc, s2 * r2 + yc};
|
||||
V(x[0], y[0], color, u1, 0);
|
||||
V(x[1], y[1], color, u2, 0);
|
||||
V(x[2], y[2], color, u1, 1);
|
||||
V(x[1], y[1], color, u2, 0);
|
||||
V(x[3], y[3], color, u2, 1);
|
||||
V(x[2], y[2], color, u1, 1);
|
||||
V(x[0], y[0], color, u1, 0.0f);
|
||||
V(x[1], y[1], color, u2, 0.0f);
|
||||
V(x[2], y[2], color, u1, 1.0f);
|
||||
V(x[1], y[1], color, u2, 0.0f);
|
||||
V(x[3], y[3], color, u2, 1.0f);
|
||||
V(x[2], y[2], color, u1, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawBuffer::FillCircle(float xc, float yc, float radius, int segments, uint32_t color) {
|
||||
float angleDelta = PI * 2 / segments;
|
||||
float uDelta = 1.0f / segments;
|
||||
float r1 = radius;
|
||||
for (int i = 0; i < segments + 1; i++) {
|
||||
float angle1 = i * angleDelta;
|
||||
float angle2 = (i + 1) * angleDelta;
|
||||
float u1 = i * uDelta;
|
||||
float u2 = (i + 1) * uDelta;
|
||||
// TODO: get rid of one pair of cos/sin per loop, can reuse from last iteration
|
||||
float c1 = cosf(angle1), s1 = sinf(angle1), c2 = cosf(angle2), s2 = sinf(angle2);
|
||||
const float x[2] = { c1 * r1 + xc, c2 * r1 + xc };
|
||||
const float y[2] = { s1 * r1 + yc, s2 * r1 + yc };
|
||||
V(xc, yc, color, 0.0f, 0.0f);
|
||||
V(x[0], y[0], color, u1, 0.0f);
|
||||
V(x[1], y[1], color, u2, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -101,6 +101,7 @@ public:
|
||||
}
|
||||
|
||||
void Circle(float x, float y, float radius, float thickness, int segments, float startAngle, uint32_t color, float u_mul);
|
||||
void FillCircle(float x, float y, float radius, int segments, uint32_t color);
|
||||
|
||||
// New drawing APIs
|
||||
|
||||
|
||||
@@ -221,6 +221,9 @@ void TextDrawerAndroid::DrawStringBitmap(std::vector<uint8_t> &bitmapData, TextS
|
||||
|
||||
void TextDrawerAndroid::DrawString(DrawBuffer &target, const char *str, float x, float y, uint32_t color, int align) {
|
||||
using namespace Draw;
|
||||
if (!str)
|
||||
return;
|
||||
|
||||
std::string text(NormalizeString(std::string(str)));
|
||||
if (text.empty())
|
||||
return;
|
||||
|
||||
+6
-4
@@ -848,10 +848,12 @@ void TextView::Draw(UIContext &dc) {
|
||||
Bounds textBounds = bounds_;
|
||||
|
||||
if (bullet_) {
|
||||
// Possible alternatives: •●■
|
||||
// TODO: Maybe draw an actual circle if we don't have real unicode fonts. So far this is only
|
||||
// used on Android.
|
||||
dc.DrawTextRect("●", textBounds, textColor, ALIGN_LEFT);
|
||||
float radius = 7.0f;
|
||||
dc.Flush();
|
||||
dc.BeginNoTex();
|
||||
dc.Draw()->FillCircle(textBounds.x + radius, textBounds.centerY(), radius, 20, textColor);
|
||||
dc.Flush();
|
||||
dc.Begin();
|
||||
textBounds.x += bulletOffset;
|
||||
textBounds.w -= bulletOffset;
|
||||
}
|
||||
|
||||
+61
-9
@@ -147,10 +147,20 @@ void MemStickScreen::CreateViews() {
|
||||
}
|
||||
#endif
|
||||
|
||||
leftColumn->Add(new Choice(iz->T("Create or Choose a PSP folder")))->OnClick.Handle(this, &MemStickScreen::OnBrowse);
|
||||
leftColumn->Add(new TextView(iz->T("DataWillStay", "Data will stay even if you uninstall PPSSPP.")))->SetBullet(true);
|
||||
leftColumn->Add(new TextView(iz->T("DataCanBeShared", "Data can be shared between PPSSPP regular/Gold.")))->SetBullet(true);
|
||||
leftColumn->Add(new TextView(iz->T("EasyUSBAccess", "Easy USB access")))->SetBullet(true);
|
||||
// Let's only offer the browse-for-folder choice on Android 10 or later.
|
||||
// Earlier versions often don't really have working folder browsers.
|
||||
bool storageBrowserWorking = System_GetPropertyInt(SYSPROP_SYSTEMVERSION) >= 29;
|
||||
|
||||
if (storageBrowserWorking) {
|
||||
leftColumn->Add(new Choice(iz->T("Create or Choose a PSP folder")))->OnClick.Handle(this, &MemStickScreen::OnBrowse);
|
||||
leftColumn->Add(new TextView(iz->T("DataWillStay", "Data will stay even if you uninstall PPSSPP.")))->SetBullet(true);
|
||||
leftColumn->Add(new TextView(iz->T("DataCanBeShared", "Data can be shared between PPSSPP regular/Gold.")))->SetBullet(true);
|
||||
leftColumn->Add(new TextView(iz->T("EasyUSBAccess", "Easy USB access")))->SetBullet(true);
|
||||
} else {
|
||||
leftColumn->Add(new Choice(iz->T("Manually specify PSP folder")))->OnClick.Handle(this, &MemStickScreen::OnSetFolderManually);
|
||||
leftColumn->Add(new TextView(iz->T("DataWillStay", "Data will stay even if you uninstall PPSSPP.")))->SetBullet(true);
|
||||
leftColumn->Add(new TextView(iz->T("DataCanBeShared", "Data can be shared between PPSSPP regular/Gold.")))->SetBullet(true);
|
||||
}
|
||||
|
||||
leftColumn->Add(new Choice(iz->T("Use App Private Directory")))->OnClick.Handle(this, &MemStickScreen::OnUseInternalStorage);
|
||||
// Consider https://www.compart.com/en/unicode/U+26A0 (unicode warning sign?)? or a graphic?
|
||||
@@ -171,6 +181,45 @@ void MemStickScreen::CreateViews() {
|
||||
INFO_LOG(SYSTEM, "MemStickScreen: initialSetup=%d", (int)initialSetup_);
|
||||
}
|
||||
|
||||
UI::EventReturn MemStickScreen::OnSetFolderManually(UI::EventParams ¶ms) {
|
||||
// The old way, from before scoped storage.
|
||||
#if PPSSPP_PLATFORM(ANDROID)
|
||||
auto sy = GetI18NCategory("System");
|
||||
System_InputBoxGetString(sy->T("Memory Stick Folder"), g_Config.memStickDirectory.ToString(), [&](bool result, const std::string &value) {
|
||||
auto sy = GetI18NCategory("System");
|
||||
auto di = GetI18NCategory("Dialog");
|
||||
|
||||
if (result) {
|
||||
std::string newPath = value;
|
||||
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);
|
||||
}
|
||||
|
||||
Path pendingMemStickFolder(newPath);
|
||||
if (pendingMemStickFolder == g_Config.memStickDirectory) {
|
||||
// Same directory as before - all good.
|
||||
TriggerFinish(DialogResult::DR_OK);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!File::Exists(pendingMemStickFolder)) {
|
||||
SystemToast(sy->T("Path does not exist!"));
|
||||
return;
|
||||
}
|
||||
|
||||
screenManager()->push(new ConfirmMemstickMoveScreen(pendingMemStickFolder, false));
|
||||
}
|
||||
});
|
||||
#endif
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
|
||||
UI::EventReturn MemStickScreen::OnUseInternalStorage(UI::EventParams ¶ms) {
|
||||
Path pendingMemStickFolder = Path(g_extFilesDir);
|
||||
|
||||
@@ -182,9 +231,12 @@ UI::EventReturn MemStickScreen::OnUseInternalStorage(UI::EventParams ¶ms) {
|
||||
} else {
|
||||
// This can't really happen?? Not worth making an error message.
|
||||
}
|
||||
} else {
|
||||
} else if (pendingMemStickFolder != g_Config.memStickDirectory) {
|
||||
// Always ask for confirmation when called from the UI. Likely there's already some data.
|
||||
screenManager()->push(new ConfirmMemstickMoveScreen(pendingMemStickFolder, false));
|
||||
} else {
|
||||
// User chose the same directory it's already in. Let's just bail.
|
||||
TriggerFinish(DialogResult::DR_OK);
|
||||
}
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
@@ -200,9 +252,12 @@ UI::EventReturn MemStickScreen::OnUseStorageRoot(UI::EventParams ¶ms) {
|
||||
} else {
|
||||
// This can't really happen?? Not worth making an error message.
|
||||
}
|
||||
} else {
|
||||
} else if (pendingMemStickFolder != g_Config.memStickDirectory) {
|
||||
// Always ask for confirmation when called from the UI. Likely there's already some data.
|
||||
screenManager()->push(new ConfirmMemstickMoveScreen(pendingMemStickFolder, false));
|
||||
} else {
|
||||
// User chose the same directory it's already in. Let's just bail.
|
||||
TriggerFinish(DialogResult::DR_OK);
|
||||
}
|
||||
return UI::EVENT_DONE;
|
||||
}
|
||||
@@ -227,9 +282,6 @@ void MemStickScreen::sendMessage(const char *message, const char *value) {
|
||||
|
||||
if (pendingMemStickFolder == g_Config.memStickDirectory) {
|
||||
auto iz = GetI18NCategory("MemStick");
|
||||
#if PPSSPP_PLATFORM(ANDROID)
|
||||
SystemToast(iz->T("That's the folder being used!"));
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -59,6 +59,7 @@ private:
|
||||
UI::EventReturn OnBrowse(UI::EventParams &e);
|
||||
UI::EventReturn OnUseInternalStorage(UI::EventParams ¶ms);
|
||||
UI::EventReturn OnUseStorageRoot(UI::EventParams ¶ms);
|
||||
UI::EventReturn OnSetFolderManually(UI::EventParams ¶ms);
|
||||
|
||||
SettingInfoMessage *settingInfo_ = nullptr;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user