Merge pull request #9452 from JosJuice/android-wii-saves
Android: Add "Import Wii Save"
This commit is contained in:
commit
96e3360f05
|
@ -444,8 +444,6 @@ public final class NativeLibrary
|
|||
|
||||
public static native void ReloadLoggerConfig();
|
||||
|
||||
public static native boolean InstallWAD(String file);
|
||||
|
||||
public static native boolean ConvertDiscImage(String inPath, String outPath, int platform,
|
||||
int format, int blockSize, int compression, int compressionLevel, boolean scrub,
|
||||
CompressCallback callback);
|
||||
|
|
|
@ -175,21 +175,12 @@ public final class MainActivity extends AppCompatActivity implements MainView
|
|||
}
|
||||
|
||||
@Override
|
||||
public void launchOpenFileActivity()
|
||||
public void launchOpenFileActivity(int requestCode)
|
||||
{
|
||||
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
intent.setType("*/*");
|
||||
startActivityForResult(intent, MainPresenter.REQUEST_GAME_FILE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void launchInstallWAD()
|
||||
{
|
||||
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
intent.setType("*/*");
|
||||
startActivityForResult(intent, MainPresenter.REQUEST_WAD_FILE);
|
||||
startActivityForResult(intent, requestCode);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -229,6 +220,11 @@ public final class MainActivity extends AppCompatActivity implements MainView
|
|||
FileBrowserHelper.runAfterExtensionCheck(this, uri, FileBrowserHelper.WAD_EXTENSION,
|
||||
() -> mPresenter.installWAD(result.getData().toString()));
|
||||
break;
|
||||
|
||||
case MainPresenter.REQUEST_WII_SAVE_FILE:
|
||||
FileBrowserHelper.runAfterExtensionCheck(this, uri, FileBrowserHelper.BIN_EXTENSION,
|
||||
() -> mPresenter.importWiiSave(result.getData().toString()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -7,24 +7,26 @@ import android.content.Context;
|
|||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.net.Uri;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
|
||||
import org.dolphinemu.dolphinemu.BuildConfig;
|
||||
import org.dolphinemu.dolphinemu.NativeLibrary;
|
||||
import org.dolphinemu.dolphinemu.R;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.BooleanSetting;
|
||||
import org.dolphinemu.dolphinemu.features.settings.ui.MenuTag;
|
||||
import org.dolphinemu.dolphinemu.model.GameFileCache;
|
||||
import org.dolphinemu.dolphinemu.services.GameFileCacheService;
|
||||
import org.dolphinemu.dolphinemu.utils.AfterDirectoryInitializationRunner;
|
||||
import org.dolphinemu.dolphinemu.utils.BooleanSupplier;
|
||||
import org.dolphinemu.dolphinemu.utils.CompletableFuture;
|
||||
import org.dolphinemu.dolphinemu.utils.ContentHandler;
|
||||
import org.dolphinemu.dolphinemu.utils.FileBrowserHelper;
|
||||
import org.dolphinemu.dolphinemu.utils.WiiUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public final class MainPresenter
|
||||
{
|
||||
|
@ -32,6 +34,7 @@ public final class MainPresenter
|
|||
public static final int REQUEST_GAME_FILE = 2;
|
||||
public static final int REQUEST_SD_FILE = 3;
|
||||
public static final int REQUEST_WAD_FILE = 4;
|
||||
public static final int REQUEST_WII_SAVE_FILE = 5;
|
||||
|
||||
private final MainView mView;
|
||||
private final Context mContext;
|
||||
|
@ -92,11 +95,17 @@ public final class MainPresenter
|
|||
return true;
|
||||
|
||||
case R.id.menu_open_file:
|
||||
mView.launchOpenFileActivity();
|
||||
mView.launchOpenFileActivity(REQUEST_GAME_FILE);
|
||||
return true;
|
||||
|
||||
case R.id.menu_install_wad:
|
||||
new AfterDirectoryInitializationRunner().run(context, true, mView::launchInstallWAD);
|
||||
new AfterDirectoryInitializationRunner().run(context, true,
|
||||
() -> mView.launchOpenFileActivity(REQUEST_WAD_FILE));
|
||||
return true;
|
||||
|
||||
case R.id.menu_import_wii_save:
|
||||
new AfterDirectoryInitializationRunner().run(context, true,
|
||||
() -> mView.launchOpenFileActivity(REQUEST_WII_SAVE_FILE));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -150,32 +159,98 @@ public final class MainPresenter
|
|||
mDirToAdd = uri.toString();
|
||||
}
|
||||
|
||||
public void installWAD(String file)
|
||||
public void installWAD(String path)
|
||||
{
|
||||
runOnThreadAndShowResult(R.string.import_in_progress, () ->
|
||||
{
|
||||
boolean success = WiiUtils.installWAD(path);
|
||||
int message = success ? R.string.wad_install_success : R.string.wad_install_failure;
|
||||
return mContext.getResources().getString(message);
|
||||
});
|
||||
}
|
||||
|
||||
public void importWiiSave(String path)
|
||||
{
|
||||
final Activity mainPresenterActivity = (Activity) mContext;
|
||||
|
||||
AlertDialog dialog = new AlertDialog.Builder(mContext, R.style.DolphinDialogBase).create();
|
||||
dialog.setTitle("Installing WAD");
|
||||
dialog.setMessage("Installing...");
|
||||
dialog.setCancelable(false);
|
||||
dialog.show();
|
||||
CompletableFuture<Boolean> canOverwriteFuture = new CompletableFuture<>();
|
||||
|
||||
Thread installWADThread = new Thread(() ->
|
||||
runOnThreadAndShowResult(R.string.import_in_progress, () ->
|
||||
{
|
||||
if (NativeLibrary.InstallWAD(file))
|
||||
BooleanSupplier canOverwrite = () ->
|
||||
{
|
||||
mainPresenterActivity.runOnUiThread(
|
||||
() -> Toast.makeText(mContext, R.string.wad_install_success, Toast.LENGTH_SHORT)
|
||||
.show());
|
||||
}
|
||||
else
|
||||
mainPresenterActivity.runOnUiThread(() ->
|
||||
{
|
||||
mainPresenterActivity.runOnUiThread(
|
||||
() -> Toast.makeText(mContext, R.string.wad_install_failure, Toast.LENGTH_SHORT)
|
||||
.show());
|
||||
AlertDialog.Builder builder =
|
||||
new AlertDialog.Builder(mContext, R.style.DolphinDialogBase);
|
||||
builder.setMessage(R.string.wii_save_exists);
|
||||
builder.setCancelable(false);
|
||||
builder.setPositiveButton(R.string.yes, (dialog, i) -> canOverwriteFuture.complete(true));
|
||||
builder.setNegativeButton(R.string.no, (dialog, i) -> canOverwriteFuture.complete(false));
|
||||
builder.show();
|
||||
});
|
||||
|
||||
try
|
||||
{
|
||||
return canOverwriteFuture.get();
|
||||
}
|
||||
mainPresenterActivity.runOnUiThread(dialog::dismiss);
|
||||
}, "InstallWAD");
|
||||
installWADThread.start();
|
||||
catch (ExecutionException | InterruptedException e)
|
||||
{
|
||||
// Shouldn't happen
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
};
|
||||
|
||||
int result = WiiUtils.importWiiSave(path, canOverwrite);
|
||||
|
||||
int message;
|
||||
switch (result)
|
||||
{
|
||||
case WiiUtils.RESULT_SUCCESS:
|
||||
message = R.string.wii_save_import_success;
|
||||
break;
|
||||
case WiiUtils.RESULT_CORRUPTED_SOURCE:
|
||||
message = R.string.wii_save_import_corruped_source;
|
||||
break;
|
||||
case WiiUtils.RESULT_TITLE_MISSING:
|
||||
message = R.string.wii_save_import_title_missing;
|
||||
break;
|
||||
case WiiUtils.RESULT_CANCELLED:
|
||||
return null;
|
||||
default:
|
||||
message = R.string.wii_save_import_error;
|
||||
break;
|
||||
}
|
||||
return mContext.getResources().getString(message);
|
||||
});
|
||||
}
|
||||
|
||||
private void runOnThreadAndShowResult(int progressMessage, Supplier<String> f)
|
||||
{
|
||||
final Activity mainPresenterActivity = (Activity) mContext;
|
||||
|
||||
AlertDialog progressDialog = new AlertDialog.Builder(mContext, R.style.DolphinDialogBase)
|
||||
.create();
|
||||
progressDialog.setTitle(progressMessage);
|
||||
progressDialog.setCancelable(false);
|
||||
progressDialog.show();
|
||||
|
||||
new Thread(() ->
|
||||
{
|
||||
String result = f.get();
|
||||
mainPresenterActivity.runOnUiThread(() ->
|
||||
{
|
||||
progressDialog.dismiss();
|
||||
|
||||
if (result != null)
|
||||
{
|
||||
AlertDialog.Builder builder =
|
||||
new AlertDialog.Builder(mContext, R.style.DolphinDialogBase);
|
||||
builder.setMessage(result);
|
||||
builder.setPositiveButton(R.string.ok, (dialog, i) -> dialog.dismiss());
|
||||
builder.show();
|
||||
}
|
||||
});
|
||||
}, mContext.getResources().getString(progressMessage)).start();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,9 +21,7 @@ public interface MainView
|
|||
|
||||
void launchFileListActivity();
|
||||
|
||||
void launchOpenFileActivity();
|
||||
|
||||
void launchInstallWAD();
|
||||
void launchOpenFileActivity(int requestCode);
|
||||
|
||||
/**
|
||||
* To be called when the game file cache is updated.
|
||||
|
|
|
@ -180,21 +180,12 @@ public final class TvMainActivity extends FragmentActivity implements MainView
|
|||
}
|
||||
|
||||
@Override
|
||||
public void launchOpenFileActivity()
|
||||
public void launchOpenFileActivity(int requestCode)
|
||||
{
|
||||
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
intent.setType("*/*");
|
||||
startActivityForResult(intent, MainPresenter.REQUEST_GAME_FILE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void launchInstallWAD()
|
||||
{
|
||||
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
intent.setType("*/*");
|
||||
startActivityForResult(intent, MainPresenter.REQUEST_WAD_FILE);
|
||||
startActivityForResult(intent, requestCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -253,6 +244,11 @@ public final class TvMainActivity extends FragmentActivity implements MainView
|
|||
FileBrowserHelper.runAfterExtensionCheck(this, uri, FileBrowserHelper.WAD_EXTENSION,
|
||||
() -> mPresenter.installWAD(result.getData().toString()));
|
||||
break;
|
||||
|
||||
case MainPresenter.REQUEST_WII_SAVE_FILE:
|
||||
FileBrowserHelper.runAfterExtensionCheck(this, uri, FileBrowserHelper.BIN_EXTENSION,
|
||||
() -> mPresenter.importWiiSave(result.getData().toString()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -353,6 +349,10 @@ public final class TvMainActivity extends FragmentActivity implements MainView
|
|||
R.drawable.ic_folder,
|
||||
R.string.grid_menu_install_wad));
|
||||
|
||||
rowItems.add(new TvSettingsItem(R.id.menu_import_wii_save,
|
||||
R.drawable.ic_folder,
|
||||
R.string.grid_menu_import_wii_save));
|
||||
|
||||
// Create a header for this row.
|
||||
HeaderItem header =
|
||||
new HeaderItem(R.string.preferences_settings, getString(R.string.preferences_settings));
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
package org.dolphinemu.dolphinemu.utils;
|
||||
|
||||
public interface BooleanSupplier
|
||||
{
|
||||
boolean get();
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
package org.dolphinemu.dolphinemu.utils;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.locks.Condition;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
/**
|
||||
* Simplified re-implementation of a subset of {@link java.util.concurrent.CompletableFuture}.
|
||||
* Replace this class with that class once we have full Java 8 support (once we require API 24).
|
||||
*/
|
||||
public class CompletableFuture<T> implements Future<T>
|
||||
{
|
||||
private final Lock lock = new ReentrantLock();
|
||||
private final Condition done = lock.newCondition();
|
||||
|
||||
private boolean isDone = false;
|
||||
private T result = null;
|
||||
|
||||
@Override
|
||||
public boolean cancel(boolean mayInterruptIfRunning)
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDone()
|
||||
{
|
||||
return isDone;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T get() throws ExecutionException, InterruptedException
|
||||
{
|
||||
lock.lock();
|
||||
try
|
||||
{
|
||||
while (!isDone)
|
||||
done.await();
|
||||
|
||||
return result;
|
||||
}
|
||||
finally
|
||||
{
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public T get(long timeout, TimeUnit unit)
|
||||
throws ExecutionException, InterruptedException, TimeoutException
|
||||
{
|
||||
lock.lock();
|
||||
try
|
||||
{
|
||||
while (!isDone)
|
||||
{
|
||||
if (!done.await(timeout, unit))
|
||||
throw new TimeoutException();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
finally
|
||||
{
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean complete(T value)
|
||||
{
|
||||
lock.lock();
|
||||
try
|
||||
{
|
||||
boolean wasDone = isDone;
|
||||
result = value;
|
||||
isDone = true;
|
||||
done.signalAll();
|
||||
return !wasDone;
|
||||
}
|
||||
finally
|
||||
{
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -37,6 +37,9 @@ public final class FileBrowserHelper
|
|||
GAME_LIKE_EXTENSIONS.add("dff");
|
||||
}
|
||||
|
||||
public static final HashSet<String> BIN_EXTENSION = new HashSet<>(Collections.singletonList(
|
||||
"bin"));
|
||||
|
||||
public static final HashSet<String> RAW_EXTENSION = new HashSet<>(Collections.singletonList(
|
||||
"raw"));
|
||||
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
package org.dolphinemu.dolphinemu.utils;
|
||||
|
||||
public final class WiiUtils
|
||||
{
|
||||
public static final int RESULT_SUCCESS = 0;
|
||||
public static final int RESULT_ERROR = 1;
|
||||
public static final int RESULT_CANCELLED = 2;
|
||||
public static final int RESULT_CORRUPTED_SOURCE = 3;
|
||||
public static final int RESULT_TITLE_MISSING = 4;
|
||||
|
||||
public static native boolean installWAD(String file);
|
||||
|
||||
public static native int importWiiSave(String file, BooleanSupplier canOverwrite);
|
||||
}
|
|
@ -25,4 +25,9 @@
|
|||
android:title="@string/grid_menu_install_wad"
|
||||
app:showAsAction="never"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_import_wii_save"
|
||||
android:title="@string/grid_menu_import_wii_save"
|
||||
app:showAsAction="never"/>
|
||||
|
||||
</menu>
|
||||
|
|
|
@ -329,8 +329,15 @@
|
|||
<string name="grid_menu_refresh">Refresh Library</string>
|
||||
<string name="grid_menu_open_file">Open File</string>
|
||||
<string name="grid_menu_install_wad">Install WAD</string>
|
||||
<string name="grid_menu_import_wii_save">Import Wii Save</string>
|
||||
<string name="import_in_progress">Importing...</string>
|
||||
<string name="wad_install_success">Successfully installed this title to the NAND.</string>
|
||||
<string name="wad_install_failure">Failed to install this title to the NAND.</string>
|
||||
<string name="wii_save_exists">Save data for this title already exists in the NAND. Consider backing up the current data before overwriting.\nOverwrite now?</string>
|
||||
<string name="wii_save_import_success">Successfully imported save file.</string>
|
||||
<string name="wii_save_import_error">Failed to import save file. Your NAND may be corrupt, or something is preventing access to files within it.</string>
|
||||
<string name="wii_save_import_corruped_source">Failed to import save file. The given file appears to be corrupted or is not a valid Wii save.</string>
|
||||
<string name="wii_save_import_title_missing">Failed to import save file. Please launch the game once, then try again.</string>
|
||||
|
||||
<!-- Game Properties Screen -->
|
||||
<string name="properties_details">Details</string>
|
||||
|
|
|
@ -56,6 +56,9 @@ static jmethodID s_network_helper_get_network_ip_address;
|
|||
static jmethodID s_network_helper_get_network_prefix_length;
|
||||
static jmethodID s_network_helper_get_network_gateway;
|
||||
|
||||
static jclass s_boolean_supplier_class;
|
||||
static jmethodID s_boolean_supplier_get;
|
||||
|
||||
namespace IDCache
|
||||
{
|
||||
JNIEnv* GetEnvForThread()
|
||||
|
@ -261,6 +264,11 @@ jmethodID GetNetworkHelperGetNetworkGateway()
|
|||
return s_network_helper_get_network_gateway;
|
||||
}
|
||||
|
||||
jmethodID GetBooleanSupplierGet()
|
||||
{
|
||||
return s_boolean_supplier_get;
|
||||
}
|
||||
|
||||
} // namespace IDCache
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -361,6 +369,11 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved)
|
|||
s_network_helper_get_network_gateway =
|
||||
env->GetStaticMethodID(s_network_helper_class, "GetNetworkGateway", "()I");
|
||||
|
||||
const jclass boolean_supplier_class =
|
||||
env->FindClass("org/dolphinemu/dolphinemu/utils/BooleanSupplier");
|
||||
s_boolean_supplier_class = reinterpret_cast<jclass>(env->NewGlobalRef(boolean_supplier_class));
|
||||
s_boolean_supplier_get = env->GetMethodID(s_boolean_supplier_class, "get", "()Z");
|
||||
|
||||
return JNI_VERSION;
|
||||
}
|
||||
|
||||
|
|
|
@ -56,4 +56,6 @@ jmethodID GetNetworkHelperGetNetworkIpAddress();
|
|||
jmethodID GetNetworkHelperGetNetworkPrefixLength();
|
||||
jmethodID GetNetworkHelperGetNetworkGateway();
|
||||
|
||||
jmethodID GetBooleanSupplierGet();
|
||||
|
||||
} // namespace IDCache
|
||||
|
|
|
@ -5,6 +5,7 @@ add_library(main SHARED
|
|||
IniFile.cpp
|
||||
MainAndroid.cpp
|
||||
NativeConfig.cpp
|
||||
WiiUtils.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(main
|
||||
|
|
|
@ -45,7 +45,6 @@
|
|||
#include "Core/PowerPC/PowerPC.h"
|
||||
#include "Core/PowerPC/Profiler.h"
|
||||
#include "Core/State.h"
|
||||
#include "Core/WiiUtils.h"
|
||||
|
||||
#include "DiscIO/Blob.h"
|
||||
#include "DiscIO/Enums.h"
|
||||
|
@ -596,14 +595,6 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_ReloadLogger
|
|||
Common::Log::LogManager::Init();
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_InstallWAD(JNIEnv* env,
|
||||
jclass,
|
||||
jstring jFile)
|
||||
{
|
||||
const std::string path = GetJString(env, jFile);
|
||||
return static_cast<jboolean>(WiiUtils::InstallWAD(path));
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_ConvertDiscImage(
|
||||
JNIEnv* env, jclass, jstring jInPath, jstring jOutPath, jint jPlatform, jint jFormat,
|
||||
jint jBlockSize, jint jCompression, jint jCompressionLevel, jboolean jScrub, jobject jCallback)
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
// Copyright 2021 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#include "jni/AndroidCommon/AndroidCommon.h"
|
||||
#include "jni/AndroidCommon/IDCache.h"
|
||||
|
||||
#include "Core/HW/WiiSave.h"
|
||||
#include "Core/WiiUtils.h"
|
||||
|
||||
// The hardcoded values here must match WiiUtils.java
|
||||
static jint ConvertCopyResult(WiiSave::CopyResult result)
|
||||
{
|
||||
switch (result)
|
||||
{
|
||||
case WiiSave::CopyResult::Success:
|
||||
return 0;
|
||||
case WiiSave::CopyResult::Error:
|
||||
return 1;
|
||||
case WiiSave::CopyResult::Cancelled:
|
||||
return 2;
|
||||
case WiiSave::CopyResult::CorruptedSource:
|
||||
return 3;
|
||||
case WiiSave::CopyResult::TitleMissing:
|
||||
return 4;
|
||||
default:
|
||||
ASSERT(false);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static_assert(static_cast<int>(WiiSave::CopyResult::NumberOfEntries) == 5);
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_utils_WiiUtils_installWAD(JNIEnv* env,
|
||||
jclass,
|
||||
jstring jFile)
|
||||
{
|
||||
const std::string path = GetJString(env, jFile);
|
||||
return static_cast<jboolean>(WiiUtils::InstallWAD(path));
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_dolphinemu_dolphinemu_utils_WiiUtils_importWiiSave(
|
||||
JNIEnv* env, jclass, jstring jFile, jobject jCanOverwrite)
|
||||
{
|
||||
const std::string path = GetJString(env, jFile);
|
||||
const auto can_overwrite = [&] {
|
||||
const jmethodID get = IDCache::GetBooleanSupplierGet();
|
||||
return static_cast<bool>(env->CallBooleanMethod(jCanOverwrite, get));
|
||||
};
|
||||
|
||||
return ConvertCopyResult(WiiSave::Import(path, can_overwrite));
|
||||
}
|
||||
}
|
|
@ -39,6 +39,7 @@ enum class CopyResult
|
|||
Cancelled,
|
||||
CorruptedSource,
|
||||
TitleMissing,
|
||||
NumberOfEntries
|
||||
};
|
||||
|
||||
CopyResult Copy(Storage* source, Storage* destination);
|
||||
|
|
Loading…
Reference in New Issue