From 5409cbb92fb41ccf5f9545e22c97cb51ef024d15 Mon Sep 17 00:00:00 2001 From: edemirkan <462667+edemirkan@users.noreply.github.com> Date: Tue, 10 Mar 2026 03:28:51 -0400 Subject: [PATCH] ppsspp-sa: bump to v1.20.1 (#2390) --- .../emulators/standalone/ppsspp-sa/package.mk | 4 +- .../ppsspp-sa/patches/001-do-not-mute.patch | 14 +-- .../patches/002-fullscreen-drm.patch | 99 +++++++++++++++++++ .../patches/002-fullscreen_drm.patch | 54 ---------- .../ppsspp-sa/patches/003-disable-mouse.patch | 14 +-- .../ppsspp-sa/patches/004-set-paths.patch | 61 ++++++------ .../packages/rocknix/sources/post-update | 6 ++ 7 files changed, 151 insertions(+), 101 deletions(-) create mode 100644 projects/ROCKNIX/packages/emulators/standalone/ppsspp-sa/patches/002-fullscreen-drm.patch delete mode 100644 projects/ROCKNIX/packages/emulators/standalone/ppsspp-sa/patches/002-fullscreen_drm.patch diff --git a/projects/ROCKNIX/packages/emulators/standalone/ppsspp-sa/package.mk b/projects/ROCKNIX/packages/emulators/standalone/ppsspp-sa/package.mk index 5f93f0fa4f..f62b81a0e1 100644 --- a/projects/ROCKNIX/packages/emulators/standalone/ppsspp-sa/package.mk +++ b/projects/ROCKNIX/packages/emulators/standalone/ppsspp-sa/package.mk @@ -5,8 +5,8 @@ PKG_NAME="ppsspp-sa" PKG_SITE="https://github.com/hrydgard/ppsspp" PKG_URL="${PKG_SITE}.git" -PKG_VERSION="e49c0bd8836a8a8f678565357773386f1174d3f5" # v1.19.3 -CHEAT_DB_VERSION="c7a24d8c80c4db773f3ac14b3ef7bb9cd1782d95" # Update cheat.db (11/04/2025) +PKG_VERSION="eb859735feddf88dbe651763f366a7705612113a" # v1.20.1 +CHEAT_DB_VERSION="7c9fe1ae71155626cea767aed53f968de9f4051f" # Update cheat.db (17/01/2026) PKG_LICENSE="GPLv2" PKG_DEPENDS_TARGET="toolchain libzip SDL2 zlib zip" PKG_LONGDESC="PPSSPPDL" diff --git a/projects/ROCKNIX/packages/emulators/standalone/ppsspp-sa/patches/001-do-not-mute.patch b/projects/ROCKNIX/packages/emulators/standalone/ppsspp-sa/patches/001-do-not-mute.patch index da0c60199c..8a0700bcde 100644 --- a/projects/ROCKNIX/packages/emulators/standalone/ppsspp-sa/patches/001-do-not-mute.patch +++ b/projects/ROCKNIX/packages/emulators/standalone/ppsspp-sa/patches/001-do-not-mute.patch @@ -1,17 +1,17 @@ diff --git a/Core/Config.cpp b/Core/Config.cpp -index 6b8c868d1..6ca8f49b3 100644 +index 4f6ee43dce..e61e3eda4c 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp -@@ -1473,9 +1473,9 @@ void Config::PostLoadCleanup(bool gameSpecific) { +@@ -1616,12 +1616,6 @@ void Config::PostLoadCleanup() { + g_Config.bSkipBufferEffects = false; } - // Automatically silence secondary instances. Could be an option I guess, but meh. +- // Automatically silence secondary instances. Could be an option I guess, but meh. - if (PPSSPP_ID > 1) { +- NOTICE_LOG(Log::Audio, "Secondary instance %d - silencing audio", (int)PPSSPP_ID); - g_Config.iGameVolume = 0; - } -+ //if (PPSSPP_ID > 1) { -+ // g_Config.iGameVolume = 0; -+ //} - +- // Automatically switch away from deprecated setting value. if (iTexScalingLevel <= 0) { + iTexScalingLevel = 1; diff --git a/projects/ROCKNIX/packages/emulators/standalone/ppsspp-sa/patches/002-fullscreen-drm.patch b/projects/ROCKNIX/packages/emulators/standalone/ppsspp-sa/patches/002-fullscreen-drm.patch new file mode 100644 index 0000000000..e4be2a1120 --- /dev/null +++ b/projects/ROCKNIX/packages/emulators/standalone/ppsspp-sa/patches/002-fullscreen-drm.patch @@ -0,0 +1,99 @@ +diff --git a/SDL/SDLMain.cpp b/SDL/SDLMain.cpp +index 04c16ca7a0..cecc4b7f0f 100644 +--- a/SDL/SDLMain.cpp ++++ b/SDL/SDLMain.cpp +@@ -824,9 +824,9 @@ void UpdateWindowState(SDL_Window *window) { + + Uint32 window_flags = SDL_GetWindowFlags(window); + if (g_Config.bFullScreen) { +- window_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; ++ window_flags |= SDL_WINDOW_FULLSCREEN; + } else { +- window_flags &= ~SDL_WINDOW_FULLSCREEN_DESKTOP; ++ window_flags &= ~SDL_WINDOW_FULLSCREEN; + } + SDL_SetWindowFullscreen(window, window_flags); + } +@@ -956,7 +956,7 @@ static void ProcessSDLEvent(SDL_Window *window, const SDL_Event &event, InputSta + Native_NotifyWindowHidden(false); + + Uint32 window_flags = SDL_GetWindowFlags(window); +- bool fullscreen = (window_flags & (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_FULLSCREEN_DESKTOP)); ++ bool fullscreen = (window_flags & (SDL_WINDOW_FULLSCREEN)); + + // This one calls NativeResized if the size changed. + Native_UpdateScreenScale(new_width_px, new_height_px, UIScaleFactorToMultiplier(g_Config.iUIScaleFactor)); +@@ -986,7 +986,7 @@ static void ProcessSDLEvent(SDL_Window *window, const SDL_Event &event, InputSta + case SDL_WINDOWEVENT_MOVED: + { + Uint32 window_flags = SDL_GetWindowFlags(window); +- bool fullscreen = (window_flags & (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_FULLSCREEN_DESKTOP)); ++ bool fullscreen = (window_flags & (SDL_WINDOW_FULLSCREEN)); + if (!fullscreen) { + g_Config.iWindowX = (int)event.window.data1; + g_Config.iWindowY = (int)event.window.data2; +@@ -1466,7 +1466,7 @@ int main(int argc, char *argv[]) { + Uint32 mode = 0; + for (int i = 1; i < argc; i++) { + if (!strcmp(argv[i], "--fullscreen")) { +- mode |= SDL_WINDOW_FULLSCREEN_DESKTOP; ++ mode |= SDL_WINDOW_FULLSCREEN; + g_Config.DoNotSaveSetting(&g_Config.bFullScreen); + } else if (set_xres == -2) + set_xres = parseInt(argv[i]); +@@ -1559,19 +1559,19 @@ int main(int argc, char *argv[]) { + + // Force fullscreen if the resolution is too low to run windowed. + if (g_DesktopWidth < 480 * 2 && g_DesktopHeight < 272 * 2) { +- mode |= SDL_WINDOW_FULLSCREEN_DESKTOP; ++ mode |= SDL_WINDOW_FULLSCREEN; + } + + // If we're on mobile, don't try for windowed either. + #if defined(MOBILE_DEVICE) && !PPSSPP_PLATFORM(SWITCH) + mode |= SDL_WINDOW_FULLSCREEN; + #elif defined(USING_FBDEV) || PPSSPP_PLATFORM(SWITCH) +- mode |= SDL_WINDOW_FULLSCREEN_DESKTOP; ++ mode |= SDL_WINDOW_FULLSCREEN; + #else + mode |= SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI; + #endif + +- if (mode & SDL_WINDOW_FULLSCREEN_DESKTOP) { ++ if (mode & SDL_WINDOW_FULLSCREEN) { + g_display.pixel_xres = g_DesktopWidth; + g_display.pixel_yres = g_DesktopHeight; + g_Config.bFullScreen = true; +@@ -1634,7 +1634,7 @@ int main(int argc, char *argv[]) { + + // Use the setting from the config when initing the window. + if (g_Config.bFullScreen) { +- mode |= SDL_WINDOW_FULLSCREEN_DESKTOP; ++ mode |= SDL_WINDOW_FULLSCREEN; + g_display.pixel_xres = g_DesktopWidth; + g_display.pixel_yres = g_DesktopHeight; + } +diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp +index d7a97347b1..531997fba0 100644 +--- a/UI/MainScreen.cpp ++++ b/UI/MainScreen.cpp +@@ -1454,19 +1454,6 @@ void MainScreen::CreateViews() { + LinearLayout *rightColumnItems = new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)); + rightColumnItems->SetSpacing(0.0f); + ViewGroup *logo = new LogoView(false, new LinearLayoutParams(FILL_PARENT, 80.0f)); +-#if !defined(MOBILE_DEVICE) +- auto gr = GetI18NCategory(I18NCat::GRAPHICS); +- ImageID icon(g_Config.bFullScreen ? "I_RESTORE" : "I_FULLSCREEN"); +- UI::Button *fullscreenButton = logo->Add(new Button("", icon, new AnchorLayoutParams(48, 48, NONE, 0, 0, NONE, Centering::None))); +- fullscreenButton->SetIgnoreText(true); +- fullscreenButton->OnClick.Add([fullscreenButton](UI::EventParams &e) { +- if (fullscreenButton) { +- fullscreenButton->SetImageID(ImageID(!g_Config.bFullScreen ? "I_RESTORE" : "I_FULLSCREEN")); +- } +- g_Config.bFullScreen = !g_Config.bFullScreen; +- System_ApplyFullscreenState(); +- }); +-#endif + rightColumnItems->Add(logo); + + LinearLayout *rightColumnChoices = rightColumnItems; diff --git a/projects/ROCKNIX/packages/emulators/standalone/ppsspp-sa/patches/002-fullscreen_drm.patch b/projects/ROCKNIX/packages/emulators/standalone/ppsspp-sa/patches/002-fullscreen_drm.patch deleted file mode 100644 index b9043f5edb..0000000000 --- a/projects/ROCKNIX/packages/emulators/standalone/ppsspp-sa/patches/002-fullscreen_drm.patch +++ /dev/null @@ -1,54 +0,0 @@ -diff --git a/SDL/SDLMain.cpp b/SDL/SDLMain.cpp -index 92537c9bd..a697ff157 100644 ---- a/SDL/SDLMain.cpp -+++ b/SDL/SDLMain.cpp -@@ -603,11 +603,11 @@ void UpdateWindowState(SDL_Window *window) { - - Uint32 window_flags = SDL_GetWindowFlags(window); - if (g_windowState.toggleFullScreenType == -1) { -- window_flags ^= SDL_WINDOW_FULLSCREEN_DESKTOP; -+ window_flags ^= SDL_WINDOW_FULLSCREEN; - } else if (g_windowState.toggleFullScreenType == 1) { -- window_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; -+ window_flags |= SDL_WINDOW_FULLSCREEN; - } else { -- window_flags &= ~SDL_WINDOW_FULLSCREEN_DESKTOP; -+ window_flags &= ~SDL_WINDOW_FULLSCREEN; - } - SDL_SetWindowFullscreen(window, window_flags); - } -@@ -718,7 +718,7 @@ int main(int argc, char *argv[]) { - Uint32 mode = 0; - for (int i = 1; i < argc; i++) { - if (!strcmp(argv[i],"--fullscreen")) { -- mode |= SDL_WINDOW_FULLSCREEN_DESKTOP; -+ mode |= SDL_WINDOW_FULLSCREEN; - g_Config.iForceFullScreen = 1; - } else if (set_xres == -2) - set_xres = parseInt(argv[i]); -@@ -791,14 +791,14 @@ int main(int argc, char *argv[]) { - - // Force fullscreen if the resolution is too low to run windowed. - if (g_DesktopWidth < 480 * 2 && g_DesktopHeight < 272 * 2) { -- mode |= SDL_WINDOW_FULLSCREEN_DESKTOP; -+ mode |= SDL_WINDOW_FULLSCREEN; - } - - // If we're on mobile, don't try for windowed either. - #if defined(MOBILE_DEVICE) && !PPSSPP_PLATFORM(SWITCH) - mode |= SDL_WINDOW_FULLSCREEN; - #elif defined(USING_FBDEV) || PPSSPP_PLATFORM(SWITCH) -- mode |= SDL_WINDOW_FULLSCREEN_DESKTOP; -+ mode |= SDL_WINDOW_FULLSCREEN; - #else - mode |= SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI; - #endif -@@ -868,7 +868,7 @@ int main(int argc, char *argv[]) { - - // Use the setting from the config when initing the window. - if (g_Config.UseFullScreen()) -- mode |= SDL_WINDOW_FULLSCREEN_DESKTOP; -+ mode |= SDL_WINDOW_FULLSCREEN; - - int x = SDL_WINDOWPOS_UNDEFINED_DISPLAY(getDisplayNumber()); - int y = SDL_WINDOWPOS_UNDEFINED; diff --git a/projects/ROCKNIX/packages/emulators/standalone/ppsspp-sa/patches/003-disable-mouse.patch b/projects/ROCKNIX/packages/emulators/standalone/ppsspp-sa/patches/003-disable-mouse.patch index af7f2cf12f..8bb2544ed3 100644 --- a/projects/ROCKNIX/packages/emulators/standalone/ppsspp-sa/patches/003-disable-mouse.patch +++ b/projects/ROCKNIX/packages/emulators/standalone/ppsspp-sa/patches/003-disable-mouse.patch @@ -1,8 +1,8 @@ diff --git a/SDL/SDLMain.cpp b/SDL/SDLMain.cpp -index dae1b6934..ea2230533 100644 +index 04c16ca7a0..f2ae555923 100644 --- a/SDL/SDLMain.cpp +++ b/SDL/SDLMain.cpp -@@ -817,12 +817,7 @@ static void ProcessSDLEvent(SDL_Window *window, const SDL_Event &event, InputSta +@@ -974,12 +974,7 @@ static void ProcessSDLEvent(SDL_Window *window, const SDL_Event &event, InputSta g_Config.iWindowWidth = new_width; g_Config.iWindowHeight = new_height; } @@ -16,13 +16,13 @@ index dae1b6934..ea2230533 100644 break; } -@@ -1435,9 +1430,7 @@ int main(int argc, char *argv[]) { - printf("Init from thread error: '%s'\n", error_message.c_str()); - } +@@ -1746,9 +1741,7 @@ int main(int argc, char *argv[]) { + // OK, we have a valid graphics backend selected. Let's clear the failures. + g_Config.sFailedGPUBackends.clear(); -#ifdef MOBILE_DEVICE SDL_ShowCursor(SDL_DISABLE); -#endif - // Ensure that the swap interval is set after context creation (needed for kmsdrm) - SDL_GL_SetSwapInterval(1); + // Avoid the IME popup when holding keys. This doesn't affect all versions of SDL. + // Note: We re-enable it in text input fields! This is necessary otherwise we don't receive diff --git a/projects/ROCKNIX/packages/emulators/standalone/ppsspp-sa/patches/004-set-paths.patch b/projects/ROCKNIX/packages/emulators/standalone/ppsspp-sa/patches/004-set-paths.patch index fcd1d66df9..d31dce81b5 100644 --- a/projects/ROCKNIX/packages/emulators/standalone/ppsspp-sa/patches/004-set-paths.patch +++ b/projects/ROCKNIX/packages/emulators/standalone/ppsspp-sa/patches/004-set-paths.patch @@ -1,34 +1,21 @@ diff --git a/Core/Config.cpp b/Core/Config.cpp -index 6b8c868d1..2d81b2376 100644 +index 4f6ee43dce..188bbca207 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp -@@ -1151,7 +1151,7 @@ void Config::UpdateIniLocation(const char *iniFileName, const char *controllerIn +@@ -1271,7 +1271,7 @@ void Config::UpdateIniLocation(const char *iniFileName, const char *controllerIn const bool useIniFilename = iniFileName != nullptr && strlen(iniFileName) > 0; const char *ppssppIniFilename = IsVREnabled() ? "ppssppvr.ini" : "ppsspp.ini"; bool exists; -- iniFilename_ = FindConfigFile(useIniFilename ? iniFileName : ppssppIniFilename, &exists); +- iniFilename_ = FindConfigFile(searchPath_, useIniFilename ? iniFileName : ppssppIniFilename, &exists); + iniFilename_ = Path("/storage/.config/ppsspp/PSP/SYSTEM") / ppssppIniFilename; const bool useControllerIniFilename = controllerIniFilename != nullptr && strlen(controllerIniFilename) > 0; const char *controlsIniFilename = IsVREnabled() ? "controlsvr.ini" : "controls.ini"; - controllerIniFilename_ = FindConfigFile(useControllerIniFilename ? controllerIniFilename : controlsIniFilename, &exists); -diff --git a/Core/SaveState.cpp b/Core/SaveState.cpp -index f70098d4d..c9b5a13ca 100644 ---- a/Core/SaveState.cpp -+++ b/Core/SaveState.cpp -@@ -542,7 +542,7 @@ double g_lastSaveTime = -1.0; - - Path GenerateSaveSlotFilename(const Path &gameFilename, int slot, const char *extension) - { -- std::string filename = StringFromFormat("%s_%d.%s", GenerateFullDiscId(gameFilename).c_str(), slot, extension); -+ std::string filename = StringFromFormat("%s_%d.%s", gameFilename.WithReplacedExtension("").GetFilename().c_str(), slot, extension); - return GetSysDirectory(DIRECTORY_SAVESTATE) / filename; - } - -diff --git a/Core/System.cpp b/Core/System.cpp -index fdc439e38..8d0923788 100644 ---- a/Core/System.cpp -+++ b/Core/System.cpp -@@ -766,14 +766,8 @@ void PSP_RunLoopFor(int cycles) { + controllerIniFilename_ = FindConfigFile(searchPath_, useControllerIniFilename ? controllerIniFilename : controlsIniFilename, &exists); +diff --git a/Core/Util/PathUtil.cpp b/Core/Util/PathUtil.cpp +index a82bc95fe6..4c1a926cd8 100644 +--- a/Core/Util/PathUtil.cpp ++++ b/Core/Util/PathUtil.cpp +@@ -42,14 +42,8 @@ Path FindConfigFile(const Path &searchPath, std::string_view baseFilename, bool } Path GetSysDirectory(PSPDirectories directoryType) { @@ -41,11 +28,11 @@ index fdc439e38..8d0923788 100644 - pspDirectory = memStickDirectory / "PSP"; - } + Path memStickDirectory = Path("/storage/roms/psp/"); -+ Path pspDirectory = Path("/storage/.config/ppsspp/PSP/"); ++ Path pspDirectory = Path("/storage/.config/ppsspp/PSP/"); switch (directoryType) { case DIRECTORY_PSP: -@@ -783,9 +777,9 @@ Path GetSysDirectory(PSPDirectories directoryType) { +@@ -59,9 +53,9 @@ Path GetSysDirectory(PSPDirectories directoryType) { case DIRECTORY_GAME: return pspDirectory / "GAME"; case DIRECTORY_SAVEDATA: @@ -57,7 +44,7 @@ index fdc439e38..8d0923788 100644 case DIRECTORY_SYSTEM: return pspDirectory / "SYSTEM"; case DIRECTORY_PAUTH: -@@ -795,7 +789,7 @@ Path GetSysDirectory(PSPDirectories directoryType) { +@@ -71,7 +65,7 @@ Path GetSysDirectory(PSPDirectories directoryType) { case DIRECTORY_DUMP: return pspDirectory / "SYSTEM/DUMP"; case DIRECTORY_SAVESTATE: @@ -66,13 +53,13 @@ index fdc439e38..8d0923788 100644 case DIRECTORY_CACHE: return pspDirectory / "SYSTEM/CACHE"; case DIRECTORY_TEXTURES: -@@ -817,11 +811,11 @@ Path GetSysDirectory(PSPDirectories directoryType) { +@@ -93,11 +87,11 @@ Path GetSysDirectory(PSPDirectories directoryType) { return pspDirectory / "themes"; case DIRECTORY_MEMSTICK_ROOT: - return g_Config.memStickDirectory; + return memStickDirectory; - // Just return the memory stick root if we run into some sort of problem. + // Just return the memory stick root if we run into some sort of problem. default: ERROR_LOG(Log::FileSystem, "Unknown directory type."); - return g_Config.memStickDirectory; @@ -81,7 +68,7 @@ index fdc439e38..8d0923788 100644 } diff --git a/SDL/SDLJoystick.cpp b/SDL/SDLJoystick.cpp -index 94a6f481b..2ab655f14 100644 +index 290cf57ce1..5d2e13da4d 100644 --- a/SDL/SDLJoystick.cpp +++ b/SDL/SDLJoystick.cpp @@ -24,7 +24,7 @@ SDLJoystick::SDLJoystick(bool init_SDL ) : registeredAsEventHandler(false) { @@ -103,10 +90,10 @@ index 94a6f481b..2ab655f14 100644 delete[] mappingData; } else { diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp -index e99cfc4ca..2a8aa85ec 100644 +index 84596b04ec..8e89a7bb13 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp -@@ -385,7 +385,7 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch +@@ -367,7 +367,7 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch #if !defined(MOBILE_DEVICE) && !defined(_WIN32) && !PPSSPP_PLATFORM(SWITCH) g_VFS.Register("", new DirectoryReader(File::GetExeDirectory() / "assets")); g_VFS.Register("", new DirectoryReader(File::GetExeDirectory())); @@ -115,7 +102,7 @@ index e99cfc4ca..2a8aa85ec 100644 g_VFS.Register("", new DirectoryReader(Path("/usr/local/share/games/ppsspp/assets"))); g_VFS.Register("", new DirectoryReader(Path("/usr/share/ppsspp/assets"))); g_VFS.Register("", new DirectoryReader(Path("/usr/share/games/ppsspp/assets"))); -@@ -492,7 +492,7 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch +@@ -474,7 +474,7 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch else // Just in case config = "./config"; @@ -124,3 +111,15 @@ index e99cfc4ca..2a8aa85ec 100644 g_Config.flash0Directory = File::GetExeDirectory() / "assets/flash0"; if (getenv("HOME") != nullptr) { g_Config.defaultCurrentDirectory = Path(getenv("HOME")); +index a8300543d..37c12caa4 100644 +--- a/Core/SaveState.cpp ++++ b/Core/SaveState.cpp +@@ -333,7 +333,7 @@ int g_screenshotFailures; + } + + std::string GetGamePrefix(const ParamSFOData ¶mSFO) { +- return GenerateFullDiscId(paramSFO); ++ return PSP_CoreParameter().fileToStart.WithReplacedExtension("").GetFilename(); + } + + // The prefix is always based on GenerateFullDiscId. So we can find these by scanning, too. diff --git a/projects/ROCKNIX/packages/rocknix/sources/post-update b/projects/ROCKNIX/packages/rocknix/sources/post-update index 33f94490b2..0203f58aca 100644 --- a/projects/ROCKNIX/packages/rocknix/sources/post-update +++ b/projects/ROCKNIX/packages/rocknix/sources/post-update @@ -97,6 +97,12 @@ rsync -a --delete /usr/config/locale/* /storage/.config/locale/ >>/var/log/confi rm -rf /storage/.config/emulationstation/locale >>/var/log/configure.log 2>&1 ||: ln -sf /usr/share/locale /storage/.config/emulationstation/locale >>/var/log/configure.log 2>&1 ||: +### Handle assets folder for ppsspp v1.20+ upgrade +if [ ! -d "/storage/.config/ppsspp/assets/ui_images" ] +then + rsync -a --delete /usr/config/ppsspp/assets/* /storage/.config/ppsspp/assets/ +fi + ### Fix Japanese language bug if [ ! -e "/storage/.config/ppsspp/assets/NotoSansJP-Regular.ttf" ] then