diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java
index c320106f2f5..2f4e465c11a 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java
@@ -187,16 +187,11 @@ public final class EmulationActivity extends AppCompatActivity
{
new AfterDirectoryInitializationRunner().runWithLifecycle(activity, true, () ->
{
- if (FileBrowserHelper.isPathEmptyOrValid(StringSetting.MAIN_DEFAULT_ISO) &&
- FileBrowserHelper.isPathEmptyOrValid(StringSetting.MAIN_FS_PATH) &&
- FileBrowserHelper.isPathEmptyOrValid(StringSetting.MAIN_DUMP_PATH) &&
- FileBrowserHelper.isPathEmptyOrValid(StringSetting.MAIN_LOAD_PATH) &&
- FileBrowserHelper.isPathEmptyOrValid(StringSetting.MAIN_RESOURCEPACK_PATH) &&
- FileBrowserHelper.isPathEmptyOrValid(StringSetting.MAIN_SD_PATH))
- {
- continueCallback.run();
- }
- else
+ if (!FileBrowserHelper.isPathEmptyOrValid(StringSetting.MAIN_DEFAULT_ISO) ||
+ !FileBrowserHelper.isPathEmptyOrValid(StringSetting.MAIN_FS_PATH) ||
+ !FileBrowserHelper.isPathEmptyOrValid(StringSetting.MAIN_DUMP_PATH) ||
+ !FileBrowserHelper.isPathEmptyOrValid(StringSetting.MAIN_LOAD_PATH) ||
+ !FileBrowserHelper.isPathEmptyOrValid(StringSetting.MAIN_RESOURCEPACK_PATH))
{
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setMessage(R.string.unavailable_paths);
@@ -206,10 +201,25 @@ public final class EmulationActivity extends AppCompatActivity
continueCallback.run());
builder.show();
}
+ else if (!FileBrowserHelper.isPathEmptyOrValid(StringSetting.MAIN_WII_SD_CARD_IMAGE_PATH) ||
+ !FileBrowserHelper.isPathEmptyOrValid(
+ StringSetting.MAIN_WII_SD_CARD_SYNC_FOLDER_PATH))
+ {
+ AlertDialog.Builder builder = new AlertDialog.Builder(activity);
+ builder.setMessage(R.string.unavailable_paths);
+ builder.setPositiveButton(R.string.yes, (dialogInterface, i) ->
+ SettingsActivity.launch(activity, MenuTag.CONFIG_WII));
+ builder.setNeutralButton(R.string.continue_anyway, (dialogInterface, i) ->
+ continueCallback.run());
+ builder.show();
+ }
+ else
+ {
+ continueCallback.run();
+ }
});
}
-
public static void launchSystemMenu(FragmentActivity activity)
{
if (sIgnoreLaunchRequests)
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.java
index b6e63895a3e..b16bd40f250 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.java
@@ -27,6 +27,8 @@ public enum BooleanSetting implements AbstractBooleanSetting
MAIN_SIMULATE_KONGA_2(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "SimulateKonga2", false),
MAIN_SIMULATE_KONGA_3(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "SimulateKonga3", false),
MAIN_WII_SD_CARD(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "WiiSDCard", true),
+ MAIN_WII_SD_CARD_ENABLE_FOLDER_SYNC(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE,
+ "WiiSDCardEnableFolderSync", false),
MAIN_WIIMOTE_CONTINUOUS_SCANNING(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE,
"WiimoteContinuousScanning", false),
MAIN_WIIMOTE_ENABLE_SPEAKER(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE,
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/StringSetting.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/StringSetting.java
index 5cb9127a585..0fac3fee031 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/StringSetting.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/StringSetting.java
@@ -21,7 +21,10 @@ public enum StringSetting implements AbstractStringSetting
MAIN_RESOURCEPACK_PATH(Settings.FILE_DOLPHIN, Settings.SECTION_INI_GENERAL, "ResourcePackPath",
""),
MAIN_FS_PATH(Settings.FILE_DOLPHIN, Settings.SECTION_INI_GENERAL, "NANDRootPath", ""),
- MAIN_SD_PATH(Settings.FILE_DOLPHIN, Settings.SECTION_INI_GENERAL, "WiiSDCardPath", ""),
+ MAIN_WII_SD_CARD_IMAGE_PATH(Settings.FILE_DOLPHIN, Settings.SECTION_INI_GENERAL, "WiiSDCardPath",
+ ""),
+ MAIN_WII_SD_CARD_SYNC_FOLDER_PATH(Settings.FILE_DOLPHIN, Settings.SECTION_INI_GENERAL,
+ "WiiSDCardSyncFolder", ""),
MAIN_WFS_PATH(Settings.FILE_DOLPHIN, Settings.SECTION_INI_GENERAL, "WFSPath", ""),
GFX_ENHANCE_POST_SHADER(Settings.FILE_GFX, Settings.SECTION_GFX_ENHANCEMENTS,
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.java
index 83ae49b2d46..234b0a8e341 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.java
@@ -39,7 +39,10 @@ import org.dolphinemu.dolphinemu.features.settings.model.view.StringSingleChoice
import org.dolphinemu.dolphinemu.features.settings.model.view.SubmenuSetting;
import org.dolphinemu.dolphinemu.features.settings.utils.SettingsFile;
import org.dolphinemu.dolphinemu.ui.main.MainPresenter;
+import org.dolphinemu.dolphinemu.utils.BooleanSupplier;
import org.dolphinemu.dolphinemu.utils.EGLHelper;
+import org.dolphinemu.dolphinemu.utils.ThreadUtil;
+import org.dolphinemu.dolphinemu.utils.WiiUtils;
import java.util.ArrayList;
import java.util.LinkedHashMap;
@@ -411,8 +414,6 @@ public final class SettingsFragmentPresenter
MainPresenter.REQUEST_DIRECTORY, "/Load"));
sl.add(new FilePicker(mContext, StringSetting.MAIN_RESOURCEPACK_PATH,
R.string.resource_pack_path, 0, MainPresenter.REQUEST_DIRECTORY, "/ResourcePacks"));
- sl.add(new FilePicker(mContext, StringSetting.MAIN_SD_PATH, R.string.SD_card_path, 0,
- MainPresenter.REQUEST_SD_FILE, "/Wii/sd.raw"));
sl.add(new FilePicker(mContext, StringSetting.MAIN_WFS_PATH, R.string.wfs_path, 0,
MainPresenter.REQUEST_DIRECTORY, "/WFS"));
}
@@ -446,6 +447,21 @@ public final class SettingsFragmentPresenter
R.string.insert_sd_card_description));
sl.add(new CheckBoxSetting(mContext, BooleanSetting.MAIN_ALLOW_SD_WRITES,
R.string.wii_sd_card_allow_writes, 0));
+ sl.add(new CheckBoxSetting(mContext, BooleanSetting.MAIN_WII_SD_CARD_ENABLE_FOLDER_SYNC,
+ R.string.wii_sd_card_sync, R.string.wii_sd_card_sync_description));
+ // TODO: Hardcoding "Load" here is wrong, because the user may have changed the Load path.
+ // The code structure makes this hard to fix, and with scoped storage active the Load path
+ // can't be changed anyway
+ sl.add(new FilePicker(mContext, StringSetting.MAIN_WII_SD_CARD_IMAGE_PATH,
+ R.string.wii_sd_card_path, 0, MainPresenter.REQUEST_SD_FILE, "/Load/WiiSD.raw"));
+ sl.add(new FilePicker(mContext, StringSetting.MAIN_WII_SD_CARD_SYNC_FOLDER_PATH,
+ R.string.wii_sd_sync_folder, 0, MainPresenter.REQUEST_DIRECTORY, "/Load/WiiSDSync/"));
+ sl.add(new RunRunnable(mContext, R.string.wii_sd_card_folder_to_file, 0,
+ R.string.wii_sd_card_folder_to_file_confirmation, 0,
+ () -> convertOnThread(WiiUtils::syncSdFolderToSdImage)));
+ sl.add(new RunRunnable(mContext, R.string.wii_sd_card_file_to_folder, 0,
+ R.string.wii_sd_card_file_to_folder_confirmation, 0,
+ () -> convertOnThread(WiiUtils::syncSdImageToSdFolder)));
sl.add(new HeaderSetting(mContext, R.string.wii_wiimote_settings, 0));
sl.add(new CheckBoxSetting(mContext, BooleanSetting.SYSCONF_WIIMOTE_MOTOR,
@@ -1358,4 +1374,11 @@ public final class SettingsFragmentPresenter
mView.getAdapter().notifyAllSettingsChanged();
}
+
+ private void convertOnThread(BooleanSupplier f)
+ {
+ ThreadUtil.runOnThreadAndShowResult(mView.getActivity(), R.string.wii_converting, 0, () ->
+ mContext.getResources().getString(
+ f.get() ? R.string.wii_convert_success : R.string.wii_convert_failure));
+ }
}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/WiiUtils.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/WiiUtils.java
index 44103f7483d..fb1d7e90cb8 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/WiiUtils.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/WiiUtils.java
@@ -33,4 +33,8 @@ public final class WiiUtils
public static native boolean isSystemMenuInstalled();
public static native String getSystemMenuVersion();
+
+ public static native boolean syncSdFolderToSdImage();
+
+ public static native boolean syncSdImageToSdFolder();
}
diff --git a/Source/Android/app/src/main/res/values/strings.xml b/Source/Android/app/src/main/res/values/strings.xml
index 17e8d1a5e19..3d52eb8c8db 100644
--- a/Source/Android/app/src/main/res/values/strings.xml
+++ b/Source/Android/app/src/main/res/values/strings.xml
@@ -145,6 +145,17 @@
Insert SD Card
Supports SD and SDHC. Default size is 128 MB.
Allow Writes to SD Card
+ Automatically Sync with Folder
+ Synchronizes the SD Card with the SD Sync Folder when starting and ending emulation.
+ SD Card Path
+ SD Sync Folder
+ Convert Folder to File Now
+ You are about to convert the content of the SD sync folder into the SD card file. All current content of the file will be deleted. Are you sure you want to continue?
+ Convert File to Folder Now
+ You are about to convert the content of the SD card file into the SD sync folder. All current content of the folder will be deleted. Are you sure you want to continue?
+ Converting...
+ Conversion done.
+ Conversion failed.
Wii Remote Rumble
Wii Remote Speaker Volume
Sensor Bar Sensitivity
@@ -212,7 +223,6 @@
Dump Path
Load Path
Resource Pack Path
- SD Card Path
WFS Path
diff --git a/Source/Android/jni/WiiUtils.cpp b/Source/Android/jni/WiiUtils.cpp
index 08e93897e20..e26ac485e91 100644
--- a/Source/Android/jni/WiiUtils.cpp
+++ b/Source/Android/jni/WiiUtils.cpp
@@ -8,12 +8,15 @@
#include "jni/AndroidCommon/AndroidCommon.h"
#include "jni/AndroidCommon/IDCache.h"
+#include "Common/FatFsUtil.h"
#include "Common/ScopeGuard.h"
+
#include "Core/CommonTitles.h"
#include "Core/HW/WiiSave.h"
#include "Core/IOS/ES/ES.h"
#include "Core/IOS/IOS.h"
#include "Core/WiiUtils.h"
+
#include "DiscIO/NANDImporter.h"
// The hardcoded values here must match WiiUtils.java
@@ -175,4 +178,16 @@ Java_org_dolphinemu_dolphinemu_utils_WiiUtils_getSystemMenuVersion(JNIEnv* env,
return ToJString(env, DiscIO::GetSysMenuVersionString(tmd.GetTitleVersion()));
}
+
+JNIEXPORT jboolean JNICALL
+Java_org_dolphinemu_dolphinemu_utils_WiiUtils_syncSdFolderToSdImage(JNIEnv* env, jclass)
+{
+ return static_cast(Common::SyncSDFolderToSDImage(false));
+}
+
+JNIEXPORT jboolean JNICALL
+Java_org_dolphinemu_dolphinemu_utils_WiiUtils_syncSdImageToSdFolder(JNIEnv* env, jclass)
+{
+ return static_cast(Common::SyncSDImageToSDFolder());
+}
}