mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 14:19:46 -06:00
Merge pull request #8902 from JosJuice/android-convert
Android: Add disc image conversion
This commit is contained in:
@ -11,6 +11,7 @@
|
||||
#include <jni.h>
|
||||
|
||||
#include "Common/StringUtil.h"
|
||||
#include "jni/AndroidCommon/IDCache.h"
|
||||
|
||||
std::string GetJString(JNIEnv* env, jstring jstr)
|
||||
{
|
||||
@ -40,3 +41,27 @@ std::vector<std::string> JStringArrayToVector(JNIEnv* env, jobjectArray array)
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int OpenAndroidContent(const std::string& uri, const std::string& mode)
|
||||
{
|
||||
JNIEnv* env = IDCache::GetEnvForThread();
|
||||
const jint fd = env->CallStaticIntMethod(IDCache::GetContentHandlerClass(),
|
||||
IDCache::GetContentHandlerOpenFd(), ToJString(env, uri),
|
||||
ToJString(env, mode));
|
||||
|
||||
// We can get an IllegalArgumentException when passing an invalid mode
|
||||
if (env->ExceptionCheck())
|
||||
{
|
||||
env->ExceptionDescribe();
|
||||
abort();
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
bool DeleteAndroidContent(const std::string& uri)
|
||||
{
|
||||
JNIEnv* env = IDCache::GetEnvForThread();
|
||||
return env->CallStaticBooleanMethod(IDCache::GetContentHandlerClass(),
|
||||
IDCache::GetContentHandlerDelete(), ToJString(env, uri));
|
||||
}
|
||||
|
@ -11,3 +11,6 @@
|
||||
std::string GetJString(JNIEnv* env, jstring jstr);
|
||||
jstring ToJString(JNIEnv* env, const std::string& str);
|
||||
std::vector<std::string> JStringArrayToVector(JNIEnv* env, jobjectArray array);
|
||||
|
||||
int OpenAndroidContent(const std::string& uri, const std::string& mode);
|
||||
bool DeleteAndroidContent(const std::string& uri);
|
||||
|
15
Source/Android/jni/AndroidCommon/CMakeLists.txt
Normal file
15
Source/Android/jni/AndroidCommon/CMakeLists.txt
Normal file
@ -0,0 +1,15 @@
|
||||
add_library(androidcommon STATIC
|
||||
AndroidCommon.cpp
|
||||
AndroidCommon.h
|
||||
IDCache.cpp
|
||||
IDCache.h
|
||||
)
|
||||
|
||||
target_link_libraries(androidcommon
|
||||
PRIVATE
|
||||
android
|
||||
log
|
||||
"-Wl,--no-warn-mismatch"
|
||||
"-Wl,--whole-archive"
|
||||
"-Wl,--no-whole-archive"
|
||||
)
|
@ -36,6 +36,13 @@ static jclass s_ini_file_section_class;
|
||||
static jfieldID s_ini_file_section_pointer;
|
||||
static jmethodID s_ini_file_section_constructor;
|
||||
|
||||
static jclass s_compress_cb_class;
|
||||
static jmethodID s_compress_cb_run;
|
||||
|
||||
static jclass s_content_handler_class;
|
||||
static jmethodID s_content_handler_open_fd;
|
||||
static jmethodID s_content_handler_delete;
|
||||
|
||||
namespace IDCache
|
||||
{
|
||||
JNIEnv* GetEnvForThread()
|
||||
@ -161,6 +168,31 @@ jmethodID GetIniFileSectionConstructor()
|
||||
return s_ini_file_section_constructor;
|
||||
}
|
||||
|
||||
jclass GetCompressCallbackClass()
|
||||
{
|
||||
return s_compress_cb_class;
|
||||
}
|
||||
|
||||
jmethodID GetCompressCallbackRun()
|
||||
{
|
||||
return s_compress_cb_run;
|
||||
}
|
||||
|
||||
jclass GetContentHandlerClass()
|
||||
{
|
||||
return s_content_handler_class;
|
||||
}
|
||||
|
||||
jmethodID GetContentHandlerOpenFd()
|
||||
{
|
||||
return s_content_handler_open_fd;
|
||||
}
|
||||
|
||||
jmethodID GetContentHandlerDelete()
|
||||
{
|
||||
return s_content_handler_delete;
|
||||
}
|
||||
|
||||
} // namespace IDCache
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -223,6 +255,19 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved)
|
||||
s_linked_hash_map_put = env->GetMethodID(
|
||||
s_linked_hash_map_class, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
|
||||
|
||||
const jclass compress_cb_class =
|
||||
env->FindClass("org/dolphinemu/dolphinemu/utils/CompressCallback");
|
||||
s_compress_cb_class = reinterpret_cast<jclass>(env->NewGlobalRef(compress_cb_class));
|
||||
s_compress_cb_run = env->GetMethodID(s_compress_cb_class, "run", "(Ljava/lang/String;F)Z");
|
||||
|
||||
const jclass content_handler_class =
|
||||
env->FindClass("org/dolphinemu/dolphinemu/utils/ContentHandler");
|
||||
s_content_handler_class = reinterpret_cast<jclass>(env->NewGlobalRef(content_handler_class));
|
||||
s_content_handler_open_fd = env->GetStaticMethodID(s_content_handler_class, "openFd",
|
||||
"(Ljava/lang/String;Ljava/lang/String;)I");
|
||||
s_content_handler_delete =
|
||||
env->GetStaticMethodID(s_content_handler_class, "delete", "(Ljava/lang/String;)Z");
|
||||
|
||||
return JNI_VERSION;
|
||||
}
|
||||
|
||||
@ -239,6 +284,8 @@ void JNI_OnUnload(JavaVM* vm, void* reserved)
|
||||
env->DeleteGlobalRef(s_linked_hash_map_class);
|
||||
env->DeleteGlobalRef(s_ini_file_class);
|
||||
env->DeleteGlobalRef(s_ini_file_section_class);
|
||||
env->DeleteGlobalRef(s_compress_cb_class);
|
||||
env->DeleteGlobalRef(s_content_handler_class);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -38,4 +38,11 @@ jclass GetIniFileSectionClass();
|
||||
jfieldID GetIniFileSectionPointer();
|
||||
jmethodID GetIniFileSectionConstructor();
|
||||
|
||||
jclass GetCompressCallbackClass();
|
||||
jmethodID GetCompressCallbackRun();
|
||||
|
||||
jclass GetContentHandlerClass();
|
||||
jmethodID GetContentHandlerOpenFd();
|
||||
jmethodID GetContentHandlerDelete();
|
||||
|
||||
} // namespace IDCache
|
||||
|
@ -1,7 +1,6 @@
|
||||
add_library(main SHARED
|
||||
AndroidCommon/AndroidCommon.cpp
|
||||
AndroidCommon/IDCache.cpp
|
||||
GameList/GameFile.cpp
|
||||
GameList/GameFile.h
|
||||
GameList/GameFileCache.cpp
|
||||
IniFile.cpp
|
||||
MainAndroid.cpp
|
||||
@ -10,6 +9,7 @@ add_library(main SHARED
|
||||
|
||||
target_link_libraries(main
|
||||
PRIVATE
|
||||
androidcommon
|
||||
core
|
||||
uicommon
|
||||
)
|
||||
@ -32,3 +32,5 @@ file(REMOVE_RECURSE ${CMAKE_SOURCE_DIR}/Source/Android/app/src/main/assets/Sys/R
|
||||
file(REMOVE_RECURSE ${CMAKE_SOURCE_DIR}/Source/Android/app/src/main/assets/Sys/Themes/)
|
||||
|
||||
set(CPACK_PACKAGE_EXECUTABLES ${CPACK_PACKAGE_EXECUTABLES} main)
|
||||
|
||||
add_subdirectory(AndroidCommon)
|
||||
|
@ -63,6 +63,8 @@ JNIEXPORT jint JNICALL Java_org_dolphinemu_dolphinemu_model_GameFile_getDiscNumb
|
||||
jobject obj);
|
||||
JNIEXPORT jint JNICALL Java_org_dolphinemu_dolphinemu_model_GameFile_getRevision(JNIEnv* env,
|
||||
jobject obj);
|
||||
JNIEXPORT jint JNICALL Java_org_dolphinemu_dolphinemu_model_GameFile_getBlobType(JNIEnv* env,
|
||||
jobject obj);
|
||||
JNIEXPORT jstring JNICALL
|
||||
Java_org_dolphinemu_dolphinemu_model_GameFile_getBlobTypeString(JNIEnv* env, jobject obj);
|
||||
JNIEXPORT jlong JNICALL Java_org_dolphinemu_dolphinemu_model_GameFile_getBlockSize(JNIEnv* env,
|
||||
@ -71,8 +73,12 @@ JNIEXPORT jstring JNICALL
|
||||
Java_org_dolphinemu_dolphinemu_model_GameFile_getCompressionMethod(JNIEnv* env, jobject obj);
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_org_dolphinemu_dolphinemu_model_GameFile_shouldShowFileFormatDetails(JNIEnv* env, jobject obj);
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_org_dolphinemu_dolphinemu_model_GameFile_shouldAllowConversion(JNIEnv* env, jobject obj);
|
||||
JNIEXPORT jlong JNICALL Java_org_dolphinemu_dolphinemu_model_GameFile_getFileSize(JNIEnv* env,
|
||||
jobject obj);
|
||||
JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_model_GameFile_isDatelDisc(JNIEnv* env,
|
||||
jobject obj);
|
||||
JNIEXPORT jintArray JNICALL Java_org_dolphinemu_dolphinemu_model_GameFile_getBanner(JNIEnv* env,
|
||||
jobject obj);
|
||||
JNIEXPORT jint JNICALL Java_org_dolphinemu_dolphinemu_model_GameFile_getBannerWidth(JNIEnv* env,
|
||||
@ -154,6 +160,12 @@ JNIEXPORT jint JNICALL Java_org_dolphinemu_dolphinemu_model_GameFile_getRevision
|
||||
return GetRef(env, obj)->GetRevision();
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_dolphinemu_dolphinemu_model_GameFile_getBlobType(JNIEnv* env,
|
||||
jobject obj)
|
||||
{
|
||||
return static_cast<jint>(GetRef(env, obj)->GetBlobType());
|
||||
}
|
||||
|
||||
JNIEXPORT jstring JNICALL
|
||||
Java_org_dolphinemu_dolphinemu_model_GameFile_getBlobTypeString(JNIEnv* env, jobject obj)
|
||||
{
|
||||
@ -175,7 +187,13 @@ Java_org_dolphinemu_dolphinemu_model_GameFile_getCompressionMethod(JNIEnv* env,
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_org_dolphinemu_dolphinemu_model_GameFile_shouldShowFileFormatDetails(JNIEnv* env, jobject obj)
|
||||
{
|
||||
return GetRef(env, obj)->ShouldShowFileFormatDetails();
|
||||
return static_cast<jboolean>(GetRef(env, obj)->ShouldShowFileFormatDetails());
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_org_dolphinemu_dolphinemu_model_GameFile_shouldAllowConversion(JNIEnv* env, jobject obj)
|
||||
{
|
||||
return static_cast<jboolean>(GetRef(env, obj)->ShouldAllowConversion());
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_org_dolphinemu_dolphinemu_model_GameFile_getFileSize(JNIEnv* env,
|
||||
@ -184,6 +202,12 @@ JNIEXPORT jlong JNICALL Java_org_dolphinemu_dolphinemu_model_GameFile_getFileSiz
|
||||
return GetRef(env, obj)->GetFileSize();
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_model_GameFile_isDatelDisc(JNIEnv* env,
|
||||
jobject obj)
|
||||
{
|
||||
return static_cast<jboolean>(GetRef(env, obj)->IsDatelDisc());
|
||||
}
|
||||
|
||||
JNIEXPORT jintArray JNICALL Java_org_dolphinemu_dolphinemu_model_GameFile_getBanner(JNIEnv* env,
|
||||
jobject obj)
|
||||
{
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <utility>
|
||||
|
||||
#include "Common/AndroidAnalytics.h"
|
||||
#include "Common/Assert.h"
|
||||
#include "Common/CPUDetect.h"
|
||||
#include "Common/CommonPaths.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
@ -26,6 +27,7 @@
|
||||
#include "Common/IniFile.h"
|
||||
#include "Common/Logging/LogManager.h"
|
||||
#include "Common/MsgHandler.h"
|
||||
#include "Common/ScopeGuard.h"
|
||||
#include "Common/Version.h"
|
||||
#include "Common/WindowSystemInfo.h"
|
||||
|
||||
@ -45,7 +47,9 @@
|
||||
#include "Core/State.h"
|
||||
#include "Core/WiiUtils.h"
|
||||
|
||||
#include "DiscIO/Blob.h"
|
||||
#include "DiscIO/Enums.h"
|
||||
#include "DiscIO/ScrubbedBlob.h"
|
||||
#include "DiscIO/Volume.h"
|
||||
|
||||
#include "InputCommon/ControllerInterface/Android/Android.h"
|
||||
@ -663,6 +667,65 @@ JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_InstallW
|
||||
return static_cast<jboolean>(WiiUtils::InstallWAD(path));
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_ConvertDiscImage(
|
||||
JNIEnv* env, jobject obj, jstring jInPath, jstring jOutPath, jint jPlatform, jint jFormat,
|
||||
jint jBlockSize, jint jCompression, jint jCompressionLevel, jboolean jScrub, jobject jCallback)
|
||||
{
|
||||
const std::string in_path = GetJString(env, jInPath);
|
||||
const std::string out_path = GetJString(env, jOutPath);
|
||||
const DiscIO::Platform platform = static_cast<DiscIO::Platform>(jPlatform);
|
||||
const DiscIO::BlobType format = static_cast<DiscIO::BlobType>(jFormat);
|
||||
const DiscIO::WIARVZCompressionType compression =
|
||||
static_cast<DiscIO::WIARVZCompressionType>(jCompression);
|
||||
const bool scrub = static_cast<bool>(jScrub);
|
||||
|
||||
std::unique_ptr<DiscIO::BlobReader> blob_reader;
|
||||
if (scrub)
|
||||
blob_reader = DiscIO::ScrubbedBlob::Create(in_path);
|
||||
else
|
||||
blob_reader = DiscIO::CreateBlobReader(in_path);
|
||||
|
||||
if (!blob_reader)
|
||||
return static_cast<jboolean>(false);
|
||||
|
||||
jobject jCallbackGlobal = env->NewGlobalRef(jCallback);
|
||||
Common::ScopeGuard scope_guard([jCallbackGlobal, env] { env->DeleteGlobalRef(jCallbackGlobal); });
|
||||
|
||||
const auto callback = [&jCallbackGlobal](const std::string& text, float completion) {
|
||||
JNIEnv* env = IDCache::GetEnvForThread();
|
||||
return static_cast<bool>(env->CallBooleanMethod(
|
||||
jCallbackGlobal, IDCache::GetCompressCallbackRun(), ToJString(env, text), completion));
|
||||
};
|
||||
|
||||
bool success = false;
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case DiscIO::BlobType::PLAIN:
|
||||
success = DiscIO::ConvertToPlain(blob_reader.get(), in_path, out_path, callback);
|
||||
break;
|
||||
|
||||
case DiscIO::BlobType::GCZ:
|
||||
success =
|
||||
DiscIO::ConvertToGCZ(blob_reader.get(), in_path, out_path,
|
||||
platform == DiscIO::Platform::WiiDisc ? 1 : 0, jBlockSize, callback);
|
||||
break;
|
||||
|
||||
case DiscIO::BlobType::WIA:
|
||||
case DiscIO::BlobType::RVZ:
|
||||
success = DiscIO::ConvertToWIAOrRVZ(blob_reader.get(), in_path, out_path,
|
||||
format == DiscIO::BlobType::RVZ, compression,
|
||||
jCompressionLevel, jBlockSize, callback);
|
||||
break;
|
||||
|
||||
default:
|
||||
ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
return static_cast<jboolean>(success);
|
||||
}
|
||||
|
||||
JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_FormatSize(JNIEnv* env,
|
||||
jobject obj,
|
||||
jlong bytes,
|
||||
|
Reference in New Issue
Block a user