mirror of
https://github.com/WinampDesktop/winamp.git
synced 2025-05-02 06:35:42 -04:00
Android: Hook up settings interface
This commit is contained in:
parent
79841d13e2
commit
f9cbc3acfb
12
android/.idea/gradle.xml
generated
12
android/.idea/gradle.xml
generated
@ -1,15 +1,19 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
|
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||||
<component name="GradleSettings">
|
<component name="GradleSettings">
|
||||||
<option name="linkedExternalProjectsSettings">
|
<option name="linkedExternalProjectsSettings">
|
||||||
<GradleProjectSettings>
|
<GradleProjectSettings>
|
||||||
<compositeConfiguration>
|
<option name="testRunner" value="PLATFORM" />
|
||||||
<compositeBuild compositeDefinitionSource="SCRIPT" />
|
|
||||||
</compositeConfiguration>
|
|
||||||
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||||
|
<option name="modules">
|
||||||
|
<set>
|
||||||
|
<option value="$PROJECT_DIR$" />
|
||||||
|
<option value="$PROJECT_DIR$/app" />
|
||||||
|
</set>
|
||||||
|
</option>
|
||||||
<option name="resolveModulePerSourceSet" value="false" />
|
<option name="resolveModulePerSourceSet" value="false" />
|
||||||
<option name="testRunner" value="PLATFORM" />
|
|
||||||
</GradleProjectSettings>
|
</GradleProjectSettings>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
|
25
android/.idea/jarRepositories.xml
generated
Normal file
25
android/.idea/jarRepositories.xml
generated
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="RemoteRepositoriesConfiguration">
|
||||||
|
<remote-repository>
|
||||||
|
<option name="id" value="central" />
|
||||||
|
<option name="name" value="Maven Central repository" />
|
||||||
|
<option name="url" value="https://repo1.maven.org/maven2" />
|
||||||
|
</remote-repository>
|
||||||
|
<remote-repository>
|
||||||
|
<option name="id" value="jboss.community" />
|
||||||
|
<option name="name" value="JBoss Community repository" />
|
||||||
|
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
|
||||||
|
</remote-repository>
|
||||||
|
<remote-repository>
|
||||||
|
<option name="id" value="BintrayJCenter" />
|
||||||
|
<option name="name" value="BintrayJCenter" />
|
||||||
|
<option name="url" value="https://jcenter.bintray.com/" />
|
||||||
|
</remote-repository>
|
||||||
|
<remote-repository>
|
||||||
|
<option name="id" value="Google" />
|
||||||
|
<option name="name" value="Google" />
|
||||||
|
<option name="url" value="https://dl.google.com/dl/android/maven2/" />
|
||||||
|
</remote-repository>
|
||||||
|
</component>
|
||||||
|
</project>
|
@ -28,6 +28,7 @@ android {
|
|||||||
externalNativeBuild {
|
externalNativeBuild {
|
||||||
cmake {
|
cmake {
|
||||||
arguments "-DCMAKE_BUILD_TYPE=RelWithDebInfo"
|
arguments "-DCMAKE_BUILD_TYPE=RelWithDebInfo"
|
||||||
|
abiFilters "arm64-v8a"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
set(SRCS
|
set(SRCS
|
||||||
android_host_interface.cpp
|
android_host_interface.cpp
|
||||||
android_host_interface.h
|
android_host_interface.h
|
||||||
|
android_settings_interface.cpp
|
||||||
|
android_settings_interface.h
|
||||||
main.cpp
|
main.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -21,8 +21,9 @@ static jclass s_AndroidHostInterface_class;
|
|||||||
static jmethodID s_AndroidHostInterface_constructor;
|
static jmethodID s_AndroidHostInterface_constructor;
|
||||||
static jfieldID s_AndroidHostInterface_field_nativePointer;
|
static jfieldID s_AndroidHostInterface_field_nativePointer;
|
||||||
|
|
||||||
|
namespace AndroidHelpers {
|
||||||
// helper for retrieving the current per-thread jni environment
|
// helper for retrieving the current per-thread jni environment
|
||||||
static JNIEnv* GetJNIEnv()
|
JNIEnv* GetJNIEnv()
|
||||||
{
|
{
|
||||||
JNIEnv* env;
|
JNIEnv* env;
|
||||||
if (s_jvm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK)
|
if (s_jvm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK)
|
||||||
@ -31,13 +32,13 @@ static JNIEnv* GetJNIEnv()
|
|||||||
return env;
|
return env;
|
||||||
}
|
}
|
||||||
|
|
||||||
static AndroidHostInterface* GetNativeClass(JNIEnv* env, jobject obj)
|
AndroidHostInterface* GetNativeClass(JNIEnv* env, jobject obj)
|
||||||
{
|
{
|
||||||
return reinterpret_cast<AndroidHostInterface*>(
|
return reinterpret_cast<AndroidHostInterface*>(
|
||||||
static_cast<uintptr_t>(env->GetLongField(obj, s_AndroidHostInterface_field_nativePointer)));
|
static_cast<uintptr_t>(env->GetLongField(obj, s_AndroidHostInterface_field_nativePointer)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string JStringToString(JNIEnv* env, jstring str)
|
std::string JStringToString(JNIEnv* env, jstring str)
|
||||||
{
|
{
|
||||||
if (str == nullptr)
|
if (str == nullptr)
|
||||||
return {};
|
return {};
|
||||||
@ -54,13 +55,17 @@ static std::string JStringToString(JNIEnv* env, jstring str)
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
} // namespace AndroidHelpers
|
||||||
|
|
||||||
AndroidHostInterface::AndroidHostInterface(jobject java_object) : m_java_object(java_object) {}
|
AndroidHostInterface::AndroidHostInterface(jobject java_object, jobject context_object)
|
||||||
|
: m_java_object(java_object), m_settings_interface(context_object)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
AndroidHostInterface::~AndroidHostInterface()
|
AndroidHostInterface::~AndroidHostInterface()
|
||||||
{
|
{
|
||||||
ImGui::DestroyContext();
|
ImGui::DestroyContext();
|
||||||
GetJNIEnv()->DeleteGlobalRef(m_java_object);
|
AndroidHelpers::GetJNIEnv()->DeleteGlobalRef(m_java_object);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AndroidHostInterface::Initialize()
|
bool AndroidHostInterface::Initialize()
|
||||||
@ -98,7 +103,7 @@ void AndroidHostInterface::ReportMessage(const char* message)
|
|||||||
|
|
||||||
std::string AndroidHostInterface::GetSettingValue(const char* section, const char* key, const char* default_value)
|
std::string AndroidHostInterface::GetSettingValue(const char* section, const char* key, const char* default_value)
|
||||||
{
|
{
|
||||||
return m_settings_interface->GetStringValue(section, key, default_value);
|
return m_settings_interface.GetStringValue(section, key, default_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidHostInterface::SetUserDirectory()
|
void AndroidHostInterface::SetUserDirectory()
|
||||||
@ -109,13 +114,12 @@ void AndroidHostInterface::SetUserDirectory()
|
|||||||
|
|
||||||
void AndroidHostInterface::LoadSettings()
|
void AndroidHostInterface::LoadSettings()
|
||||||
{
|
{
|
||||||
m_settings_interface = std::make_unique<INISettingsInterface>(GetSettingsFileName());
|
CommonHostInterface::LoadSettings(m_settings_interface);
|
||||||
CommonHostInterface::LoadSettings(*m_settings_interface);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidHostInterface::UpdateInputMap()
|
void AndroidHostInterface::UpdateInputMap()
|
||||||
{
|
{
|
||||||
CommonHostInterface::UpdateInputMap(*m_settings_interface);
|
CommonHostInterface::UpdateInputMap(m_settings_interface);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AndroidHostInterface::StartEmulationThread(ANativeWindow* initial_surface, SystemBootParameters boot_params)
|
bool AndroidHostInterface::StartEmulationThread(ANativeWindow* initial_surface, SystemBootParameters boot_params)
|
||||||
@ -382,7 +386,7 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)
|
|||||||
Log::SetDebugOutputParams(true, nullptr, LOGLEVEL_DEV);
|
Log::SetDebugOutputParams(true, nullptr, LOGLEVEL_DEV);
|
||||||
s_jvm = vm;
|
s_jvm = vm;
|
||||||
|
|
||||||
JNIEnv* env = GetJNIEnv();
|
JNIEnv* env = AndroidHelpers::GetJNIEnv();
|
||||||
if ((s_AndroidHostInterface_class = env->FindClass("com/github/stenzek/duckstation/AndroidHostInterface")) == nullptr)
|
if ((s_AndroidHostInterface_class = env->FindClass("com/github/stenzek/duckstation/AndroidHostInterface")) == nullptr)
|
||||||
{
|
{
|
||||||
Log_ErrorPrint("AndroidHostInterface class lookup failed");
|
Log_ErrorPrint("AndroidHostInterface class lookup failed");
|
||||||
@ -415,7 +419,7 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)
|
|||||||
#define DEFINE_JNI_ARGS_METHOD(return_type, name, ...) \
|
#define DEFINE_JNI_ARGS_METHOD(return_type, name, ...) \
|
||||||
extern "C" JNIEXPORT return_type JNICALL Java_com_github_stenzek_duckstation_##name(JNIEnv* env, __VA_ARGS__)
|
extern "C" JNIEXPORT return_type JNICALL Java_com_github_stenzek_duckstation_##name(JNIEnv* env, __VA_ARGS__)
|
||||||
|
|
||||||
DEFINE_JNI_ARGS_METHOD(jobject, AndroidHostInterface_create, jobject unused)
|
DEFINE_JNI_ARGS_METHOD(jobject, AndroidHostInterface_create, jobject unused, jobject context_object)
|
||||||
{
|
{
|
||||||
Log::SetDebugOutputParams(true, nullptr, LOGLEVEL_DEBUG);
|
Log::SetDebugOutputParams(true, nullptr, LOGLEVEL_DEBUG);
|
||||||
|
|
||||||
@ -431,7 +435,7 @@ DEFINE_JNI_ARGS_METHOD(jobject, AndroidHostInterface_create, jobject unused)
|
|||||||
Assert(java_obj_ref != nullptr);
|
Assert(java_obj_ref != nullptr);
|
||||||
|
|
||||||
// initialize the C++ side
|
// initialize the C++ side
|
||||||
AndroidHostInterface* cpp_obj = new AndroidHostInterface(java_obj_ref);
|
AndroidHostInterface* cpp_obj = new AndroidHostInterface(java_obj_ref, context_object);
|
||||||
if (!cpp_obj->Initialize())
|
if (!cpp_obj->Initialize())
|
||||||
{
|
{
|
||||||
// TODO: Do we need to release the original java object reference?
|
// TODO: Do we need to release the original java object reference?
|
||||||
@ -448,7 +452,7 @@ DEFINE_JNI_ARGS_METHOD(jobject, AndroidHostInterface_create, jobject unused)
|
|||||||
|
|
||||||
DEFINE_JNI_ARGS_METHOD(jboolean, AndroidHostInterface_isEmulationThreadRunning, jobject obj)
|
DEFINE_JNI_ARGS_METHOD(jboolean, AndroidHostInterface_isEmulationThreadRunning, jobject obj)
|
||||||
{
|
{
|
||||||
return GetNativeClass(env, obj)->IsEmulationThreadRunning();
|
return AndroidHelpers::GetNativeClass(env, obj)->IsEmulationThreadRunning();
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_JNI_ARGS_METHOD(jboolean, AndroidHostInterface_startEmulationThread, jobject obj, jobject surface,
|
DEFINE_JNI_ARGS_METHOD(jboolean, AndroidHostInterface_startEmulationThread, jobject obj, jobject surface,
|
||||||
@ -461,17 +465,17 @@ DEFINE_JNI_ARGS_METHOD(jboolean, AndroidHostInterface_startEmulationThread, jobj
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string state_filename_str = JStringToString(env, state_filename);
|
std::string state_filename_str = AndroidHelpers::JStringToString(env, state_filename);
|
||||||
|
|
||||||
SystemBootParameters boot_params;
|
SystemBootParameters boot_params;
|
||||||
boot_params.filename = JStringToString(env, filename);
|
boot_params.filename = AndroidHelpers::JStringToString(env, filename);
|
||||||
|
|
||||||
return GetNativeClass(env, obj)->StartEmulationThread(native_surface, std::move(boot_params));
|
return AndroidHelpers::GetNativeClass(env, obj)->StartEmulationThread(native_surface, std::move(boot_params));
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_JNI_ARGS_METHOD(void, AndroidHostInterface_stopEmulationThread, jobject obj)
|
DEFINE_JNI_ARGS_METHOD(void, AndroidHostInterface_stopEmulationThread, jobject obj)
|
||||||
{
|
{
|
||||||
GetNativeClass(env, obj)->StopEmulationThread();
|
AndroidHelpers::GetNativeClass(env, obj)->StopEmulationThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_JNI_ARGS_METHOD(void, AndroidHostInterface_surfaceChanged, jobject obj, jobject surface, jint format, jint width,
|
DEFINE_JNI_ARGS_METHOD(void, AndroidHostInterface_surfaceChanged, jobject obj, jobject surface, jint format, jint width,
|
||||||
@ -481,38 +485,41 @@ DEFINE_JNI_ARGS_METHOD(void, AndroidHostInterface_surfaceChanged, jobject obj, j
|
|||||||
if (!native_surface)
|
if (!native_surface)
|
||||||
Log_ErrorPrint("ANativeWindow_fromSurface() returned null");
|
Log_ErrorPrint("ANativeWindow_fromSurface() returned null");
|
||||||
|
|
||||||
AndroidHostInterface* hi = GetNativeClass(env, obj);
|
AndroidHostInterface* hi = AndroidHelpers::GetNativeClass(env, obj);
|
||||||
hi->RunOnEmulationThread(
|
hi->RunOnEmulationThread(
|
||||||
[hi, native_surface, format, width, height]() { hi->SurfaceChanged(native_surface, format, width, height); }, true);
|
[hi, native_surface, format, width, height]() { hi->SurfaceChanged(native_surface, format, width, height); }, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_JNI_ARGS_METHOD(void, AndroidHostInterface_setControllerType, jobject obj, jint index, jstring controller_type)
|
DEFINE_JNI_ARGS_METHOD(void, AndroidHostInterface_setControllerType, jobject obj, jint index, jstring controller_type)
|
||||||
{
|
{
|
||||||
GetNativeClass(env, obj)->SetControllerType(index, JStringToString(env, controller_type));
|
AndroidHelpers::GetNativeClass(env, obj)->SetControllerType(index,
|
||||||
|
AndroidHelpers::JStringToString(env, controller_type));
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_JNI_ARGS_METHOD(void, AndroidHostInterface_setControllerButtonState, jobject obj, jint index, jint button_code,
|
DEFINE_JNI_ARGS_METHOD(void, AndroidHostInterface_setControllerButtonState, jobject obj, jint index, jint button_code,
|
||||||
jboolean pressed)
|
jboolean pressed)
|
||||||
{
|
{
|
||||||
GetNativeClass(env, obj)->SetControllerButtonState(index, button_code, pressed);
|
AndroidHelpers::GetNativeClass(env, obj)->SetControllerButtonState(index, button_code, pressed);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_JNI_ARGS_METHOD(jint, AndroidHostInterface_getControllerButtonCode, jobject unused, jstring controller_type,
|
DEFINE_JNI_ARGS_METHOD(jint, AndroidHostInterface_getControllerButtonCode, jobject unused, jstring controller_type,
|
||||||
jstring button_name)
|
jstring button_name)
|
||||||
{
|
{
|
||||||
std::optional<ControllerType> type = Settings::ParseControllerTypeName(JStringToString(env, controller_type).c_str());
|
std::optional<ControllerType> type =
|
||||||
|
Settings::ParseControllerTypeName(AndroidHelpers::JStringToString(env, controller_type).c_str());
|
||||||
if (!type)
|
if (!type)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
std::optional<s32> code = Controller::GetButtonCodeByName(type.value(), JStringToString(env, button_name));
|
std::optional<s32> code =
|
||||||
|
Controller::GetButtonCodeByName(type.value(), AndroidHelpers::JStringToString(env, button_name));
|
||||||
return code.value_or(-1);
|
return code.value_or(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_JNI_ARGS_METHOD(jarray, GameList_getEntries, jobject unused, jstring j_cache_path, jstring j_redump_dat_path,
|
DEFINE_JNI_ARGS_METHOD(jarray, GameList_getEntries, jobject unused, jstring j_cache_path, jstring j_redump_dat_path,
|
||||||
jarray j_search_directories, jboolean search_recursively)
|
jarray j_search_directories, jboolean search_recursively)
|
||||||
{
|
{
|
||||||
// const std::string cache_path = JStringToString(env, j_cache_path);
|
// const std::string cache_path = AndroidHelpers::JStringToString(env, j_cache_path);
|
||||||
std::string redump_dat_path = JStringToString(env, j_redump_dat_path);
|
std::string redump_dat_path = AndroidHelpers::JStringToString(env, j_redump_dat_path);
|
||||||
|
|
||||||
// TODO: This should use the base HostInterface.
|
// TODO: This should use the base HostInterface.
|
||||||
GameList gl;
|
GameList gl;
|
||||||
@ -523,7 +530,7 @@ DEFINE_JNI_ARGS_METHOD(jarray, GameList_getEntries, jobject unused, jstring j_ca
|
|||||||
for (jsize i = 0; i < search_directories_size; i++)
|
for (jsize i = 0; i < search_directories_size; i++)
|
||||||
{
|
{
|
||||||
jobject search_dir_obj = env->GetObjectArrayElement(reinterpret_cast<jobjectArray>(j_search_directories), i);
|
jobject search_dir_obj = env->GetObjectArrayElement(reinterpret_cast<jobjectArray>(j_search_directories), i);
|
||||||
const std::string search_dir = JStringToString(env, reinterpret_cast<jstring>(search_dir_obj));
|
const std::string search_dir = AndroidHelpers::JStringToString(env, reinterpret_cast<jstring>(search_dir_obj));
|
||||||
if (!search_dir.empty())
|
if (!search_dir.empty())
|
||||||
gl.AddDirectory(search_dir.c_str(), search_recursively);
|
gl.AddDirectory(search_dir.c_str(), search_recursively);
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "android_settings_interface.h"
|
||||||
#include "common/event.h"
|
#include "common/event.h"
|
||||||
#include "frontend-common/common_host_interface.h"
|
#include "frontend-common/common_host_interface.h"
|
||||||
#include "frontend-common/ini_settings_interface.h"
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
struct ANativeWindow;
|
struct ANativeWindow;
|
||||||
@ -16,7 +17,7 @@ class Controller;
|
|||||||
class AndroidHostInterface final : public CommonHostInterface
|
class AndroidHostInterface final : public CommonHostInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AndroidHostInterface(jobject java_object);
|
AndroidHostInterface(jobject java_object, jobject context_object);
|
||||||
~AndroidHostInterface() override;
|
~AndroidHostInterface() override;
|
||||||
|
|
||||||
bool Initialize() override;
|
bool Initialize() override;
|
||||||
@ -57,7 +58,7 @@ private:
|
|||||||
|
|
||||||
jobject m_java_object = {};
|
jobject m_java_object = {};
|
||||||
|
|
||||||
std::unique_ptr<INISettingsInterface> m_settings_interface;
|
AndroidSettingsInterface m_settings_interface;
|
||||||
|
|
||||||
ANativeWindow* m_surface = nullptr;
|
ANativeWindow* m_surface = nullptr;
|
||||||
|
|
||||||
@ -69,3 +70,9 @@ private:
|
|||||||
std::atomic_bool m_emulation_thread_start_result{false};
|
std::atomic_bool m_emulation_thread_start_result{false};
|
||||||
Common::Event m_emulation_thread_started;
|
Common::Event m_emulation_thread_started;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace AndroidHelpers {
|
||||||
|
JNIEnv* GetJNIEnv();
|
||||||
|
AndroidHostInterface* GetNativeClass(JNIEnv* env, jobject obj);
|
||||||
|
std::string JStringToString(JNIEnv* env, jstring str);
|
||||||
|
} // namespace AndroidHelpers
|
||||||
|
178
android/app/src/cpp/android_settings_interface.cpp
Normal file
178
android/app/src/cpp/android_settings_interface.cpp
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
#include "android_settings_interface.h"
|
||||||
|
#include "android_host_interface.h"
|
||||||
|
#include "common/assert.h"
|
||||||
|
#include "common/log.h"
|
||||||
|
#include "common/string.h"
|
||||||
|
#include "common/string_util.h"
|
||||||
|
#include <algorithm>
|
||||||
|
Log_SetChannel(AndroidSettingsInterface);
|
||||||
|
|
||||||
|
ALWAYS_INLINE TinyString GetSettingKey(const char* section, const char* key)
|
||||||
|
{
|
||||||
|
return TinyString::FromFormat("%s/%s", section, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
AndroidSettingsInterface::AndroidSettingsInterface(jobject java_context)
|
||||||
|
{
|
||||||
|
JNIEnv* env = AndroidHelpers::GetJNIEnv();
|
||||||
|
jclass c_preference_manager = env->FindClass("androidx/preference/PreferenceManager");
|
||||||
|
jclass c_set = env->FindClass("java/util/Set");
|
||||||
|
jmethodID m_get_default_shared_preferences =
|
||||||
|
env->GetStaticMethodID(c_preference_manager, "getDefaultSharedPreferences",
|
||||||
|
"(Landroid/content/Context;)Landroid/content/SharedPreferences;");
|
||||||
|
Assert(c_preference_manager && c_set && m_get_default_shared_preferences);
|
||||||
|
|
||||||
|
m_java_shared_preferences =
|
||||||
|
env->CallStaticObjectMethod(c_preference_manager, m_get_default_shared_preferences, java_context);
|
||||||
|
Assert(m_java_shared_preferences);
|
||||||
|
m_java_shared_preferences = env->NewGlobalRef(m_java_shared_preferences);
|
||||||
|
jclass c_shared_preferences = env->GetObjectClass(m_java_shared_preferences);
|
||||||
|
|
||||||
|
m_get_boolean = env->GetMethodID(c_shared_preferences, "getBoolean", "(Ljava/lang/String;Z)Z");
|
||||||
|
m_get_int = env->GetMethodID(c_shared_preferences, "getInt", "(Ljava/lang/String;I)I");
|
||||||
|
m_get_float = env->GetMethodID(c_shared_preferences, "getFloat", "(Ljava/lang/String;F)F");
|
||||||
|
m_get_string =
|
||||||
|
env->GetMethodID(c_shared_preferences, "getString", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
|
||||||
|
m_get_string_set =
|
||||||
|
env->GetMethodID(c_shared_preferences, "getStringSet", "(Ljava/lang/String;Ljava/util/Set;)Ljava/util/Set;");
|
||||||
|
m_set_to_array = env->GetMethodID(c_set, "toArray", "()[Ljava/lang/Object;");
|
||||||
|
Assert(m_get_boolean && m_get_int && m_get_float && m_get_string && m_get_string_set && m_set_to_array);
|
||||||
|
}
|
||||||
|
|
||||||
|
AndroidSettingsInterface::~AndroidSettingsInterface()
|
||||||
|
{
|
||||||
|
if (m_java_shared_preferences)
|
||||||
|
AndroidHelpers::GetJNIEnv()->DeleteGlobalRef(m_java_shared_preferences);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AndroidSettingsInterface::Clear()
|
||||||
|
{
|
||||||
|
Log_ErrorPrint("Not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
int AndroidSettingsInterface::GetIntValue(const char* section, const char* key, int default_value /*= 0*/)
|
||||||
|
{
|
||||||
|
JNIEnv* env = AndroidHelpers::GetJNIEnv();
|
||||||
|
#if 0
|
||||||
|
return static_cast<int>(env->CallIntMethod(m_java_shared_preferences, m_get_int,
|
||||||
|
env->NewStringUTF(GetSettingKey(section, key)), default_value));
|
||||||
|
#else
|
||||||
|
// Some of these settings are string lists...
|
||||||
|
jstring string_object = reinterpret_cast<jstring>(
|
||||||
|
env->CallObjectMethod(m_java_shared_preferences, m_get_string, env->NewStringUTF(GetSettingKey(section, key)),
|
||||||
|
env->NewStringUTF(TinyString::FromFormat("%d", default_value))));
|
||||||
|
if (!string_object)
|
||||||
|
return default_value;
|
||||||
|
|
||||||
|
const char* data = env->GetStringUTFChars(string_object, nullptr);
|
||||||
|
Assert(data != nullptr);
|
||||||
|
|
||||||
|
std::optional<int> value = StringUtil::FromChars<int>(data);
|
||||||
|
env->ReleaseStringUTFChars(string_object, data);
|
||||||
|
return value.value_or(default_value);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
float AndroidSettingsInterface::GetFloatValue(const char* section, const char* key, float default_value /*= 0.0f*/)
|
||||||
|
{
|
||||||
|
JNIEnv* env = AndroidHelpers::GetJNIEnv();
|
||||||
|
#if 0
|
||||||
|
return static_cast<float>(env->CallFloatMethod(m_java_shared_preferences, m_get_float,
|
||||||
|
env->NewStringUTF(GetSettingKey(section, key)), default_value));
|
||||||
|
#else
|
||||||
|
// Some of these settings are string lists...
|
||||||
|
jstring string_object = reinterpret_cast<jstring>(
|
||||||
|
env->CallObjectMethod(m_java_shared_preferences, m_get_string, env->NewStringUTF(GetSettingKey(section, key)),
|
||||||
|
env->NewStringUTF(TinyString::FromFormat("%f", default_value))));
|
||||||
|
if (!string_object)
|
||||||
|
return default_value;
|
||||||
|
|
||||||
|
const char* data = env->GetStringUTFChars(string_object, nullptr);
|
||||||
|
Assert(data != nullptr);
|
||||||
|
|
||||||
|
std::optional<float> value = StringUtil::FromChars<float>(data);
|
||||||
|
env->ReleaseStringUTFChars(string_object, data);
|
||||||
|
return value.value_or(default_value);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AndroidSettingsInterface::GetBoolValue(const char* section, const char* key, bool default_value /*= false*/)
|
||||||
|
{
|
||||||
|
JNIEnv* env = AndroidHelpers::GetJNIEnv();
|
||||||
|
return static_cast<bool>(env->CallBooleanMethod(m_java_shared_preferences, m_get_boolean,
|
||||||
|
env->NewStringUTF(GetSettingKey(section, key)), default_value));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string AndroidSettingsInterface::GetStringValue(const char* section, const char* key,
|
||||||
|
const char* default_value /*= ""*/)
|
||||||
|
{
|
||||||
|
JNIEnv* env = AndroidHelpers::GetJNIEnv();
|
||||||
|
jobject string_object =
|
||||||
|
env->CallObjectMethod(m_java_shared_preferences, m_get_string, env->NewStringUTF(GetSettingKey(section, key)),
|
||||||
|
env->NewStringUTF(default_value));
|
||||||
|
return AndroidHelpers::JStringToString(env, reinterpret_cast<jstring>(string_object));
|
||||||
|
}
|
||||||
|
|
||||||
|
void AndroidSettingsInterface::SetIntValue(const char* section, const char* key, int value)
|
||||||
|
{
|
||||||
|
Log_ErrorPrintf("SetIntValue(\"%s\", \"%s\", %d) not implemented", section, key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AndroidSettingsInterface::SetFloatValue(const char* section, const char* key, float value)
|
||||||
|
{
|
||||||
|
Log_ErrorPrintf("SetFloatValue(\"%s\", \"%s\", %f) not implemented", section, key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AndroidSettingsInterface::SetBoolValue(const char* section, const char* key, bool value)
|
||||||
|
{
|
||||||
|
Log_ErrorPrintf("SetBoolValue(\"%s\", \"%s\", %u) not implemented", section, key, static_cast<unsigned>(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
void AndroidSettingsInterface::SetStringValue(const char* section, const char* key, const char* value)
|
||||||
|
{
|
||||||
|
Log_ErrorPrintf("SetStringValue(\"%s\", \"%s\", \"%s\") not implemented", section, key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AndroidSettingsInterface::DeleteValue(const char* section, const char* key)
|
||||||
|
{
|
||||||
|
Log_ErrorPrintf("DeleteValue(\"%s\", \"%s\") not implemented", section, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> AndroidSettingsInterface::GetStringList(const char* section, const char* key)
|
||||||
|
{
|
||||||
|
JNIEnv* env = AndroidHelpers::GetJNIEnv();
|
||||||
|
jobject values_set = env->CallObjectMethod(m_java_shared_preferences, m_get_string_set, nullptr);
|
||||||
|
if (!values_set)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
jobjectArray values_array = reinterpret_cast<jobjectArray>(env->CallObjectMethod(values_set, m_set_to_array));
|
||||||
|
if (!values_array)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
jsize size = env->GetArrayLength(values_array);
|
||||||
|
std::vector<std::string> values;
|
||||||
|
values.reserve(size);
|
||||||
|
for (jsize i = 0; i < size; i++)
|
||||||
|
values.push_back(
|
||||||
|
AndroidHelpers::JStringToString(env, reinterpret_cast<jstring>(env->GetObjectArrayElement(values_array, i))));
|
||||||
|
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AndroidSettingsInterface::SetStringList(const char* section, const char* key,
|
||||||
|
const std::vector<std::string_view>& items)
|
||||||
|
{
|
||||||
|
Log_ErrorPrintf("SetStringList(\"%s\", \"%s\") not implemented", section, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AndroidSettingsInterface::RemoveFromStringList(const char* section, const char* key, const char* item)
|
||||||
|
{
|
||||||
|
Log_ErrorPrintf("RemoveFromStringList(\"%s\", \"%s\", \"%s\") not implemented", section, key, item);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AndroidSettingsInterface::AddToStringList(const char* section, const char* key, const char* item)
|
||||||
|
{
|
||||||
|
Log_ErrorPrintf("AddToStringList(\"%s\", \"%s\", \"%s\") not implemented", section, key, item);
|
||||||
|
return false;
|
||||||
|
}
|
37
android/app/src/cpp/android_settings_interface.h
Normal file
37
android/app/src/cpp/android_settings_interface.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "core/settings.h"
|
||||||
|
#include <jni.h>
|
||||||
|
|
||||||
|
class AndroidSettingsInterface : public SettingsInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AndroidSettingsInterface(jobject java_context);
|
||||||
|
~AndroidSettingsInterface();
|
||||||
|
|
||||||
|
void Clear() override;
|
||||||
|
|
||||||
|
int GetIntValue(const char* section, const char* key, int default_value = 0) override;
|
||||||
|
float GetFloatValue(const char* section, const char* key, float default_value = 0.0f) override;
|
||||||
|
bool GetBoolValue(const char* section, const char* key, bool default_value = false) override;
|
||||||
|
std::string GetStringValue(const char* section, const char* key, const char* default_value = "") override;
|
||||||
|
|
||||||
|
void SetIntValue(const char* section, const char* key, int value) override;
|
||||||
|
void SetFloatValue(const char* section, const char* key, float value) override;
|
||||||
|
void SetBoolValue(const char* section, const char* key, bool value) override;
|
||||||
|
void SetStringValue(const char* section, const char* key, const char* value) override;
|
||||||
|
void DeleteValue(const char* section, const char* key) override;
|
||||||
|
|
||||||
|
std::vector<std::string> GetStringList(const char* section, const char* key) override;
|
||||||
|
void SetStringList(const char* section, const char* key, const std::vector<std::string_view>& items) override;
|
||||||
|
bool RemoveFromStringList(const char* section, const char* key, const char* item) override;
|
||||||
|
bool AddToStringList(const char* section, const char* key, const char* item) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
jobject m_java_shared_preferences{};
|
||||||
|
jmethodID m_get_boolean{};
|
||||||
|
jmethodID m_get_int{};
|
||||||
|
jmethodID m_get_float{};
|
||||||
|
jmethodID m_get_string{};
|
||||||
|
jmethodID m_get_string_set{};
|
||||||
|
jmethodID m_set_to_array{};
|
||||||
|
};
|
@ -1,5 +1,6 @@
|
|||||||
package com.github.stenzek.duckstation;
|
package com.github.stenzek.duckstation;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
import android.view.Surface;
|
import android.view.Surface;
|
||||||
|
|
||||||
public class AndroidHostInterface
|
public class AndroidHostInterface
|
||||||
@ -10,7 +11,7 @@ public class AndroidHostInterface
|
|||||||
System.loadLibrary("duckstation-native");
|
System.loadLibrary("duckstation-native");
|
||||||
}
|
}
|
||||||
|
|
||||||
static public native AndroidHostInterface create();
|
static public native AndroidHostInterface create(Context context);
|
||||||
|
|
||||||
public AndroidHostInterface(long nativePointer)
|
public AndroidHostInterface(long nativePointer)
|
||||||
{
|
{
|
||||||
|
@ -142,7 +142,7 @@ public class EmulationActivity extends AppCompatActivity implements SurfaceHolde
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
mHostInterface = AndroidHostInterface.create();
|
mHostInterface = AndroidHostInterface.create(this);
|
||||||
if (mHostInterface == null)
|
if (mHostInterface == null)
|
||||||
throw new InstantiationError("Failed to create host interface");
|
throw new InstantiationError("Failed to create host interface");
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<!-- Preference Titles -->
|
<!-- Preference Titles -->
|
||||||
<string name="settings_console_header">Console</string>
|
<string name="settings_console_header">Console</string>
|
||||||
<string name="settings_behavior_header">Behavior</string>
|
<string name="settings_behavior_header">Behavior</string>
|
||||||
<string name="settings_host_synchronization_header">Host Synchronization</string>
|
<string name="settings_osd_header">On-Screen Display</string>
|
||||||
<string name="settings_cpu_header">CPU</string>
|
<string name="settings_cpu_header">CPU</string>
|
||||||
<string name="settings_gpu_header">GPU</string>
|
<string name="settings_gpu_header">GPU</string>
|
||||||
|
|
||||||
@ -20,18 +20,21 @@
|
|||||||
<!-- Behavior Preferences -->
|
<!-- Behavior Preferences -->
|
||||||
<string name="settings_behavior_enable_speed_limiter">Enable Speed Limiter</string>
|
<string name="settings_behavior_enable_speed_limiter">Enable Speed Limiter</string>
|
||||||
<string name="settings_behavior_pause_on_start">Pause On Start</string>
|
<string name="settings_behavior_pause_on_start">Pause On Start</string>
|
||||||
|
|
||||||
<!-- Host Synchronization Preferences -->
|
|
||||||
<string name="settings_host_synchronization_sync_to_audio">Sync To Audio</string>
|
<string name="settings_host_synchronization_sync_to_audio">Sync To Audio</string>
|
||||||
<string name="settings_host_synchronization_sync_to_video">Sync To Video</string>
|
<string name="settings_host_synchronization_sync_to_video">Sync To Video</string>
|
||||||
|
|
||||||
|
<!-- OSD Preferences -->
|
||||||
|
<string name="settings_osd_show_messages">Show Messages</string>
|
||||||
|
<string name="settings_osd_show_speed">Show Emulation Speed</string>
|
||||||
|
<string name="settings_osd_show_show_fps">Show FPS</string>
|
||||||
|
<string name="settings_osd_show_show_vps">Show VPS</string>
|
||||||
|
|
||||||
<!-- CPU Preferences -->
|
<!-- CPU Preferences -->
|
||||||
<string name="settings_cpu_execution_mode">Execution Mode</string>
|
<string name="settings_cpu_execution_mode">Execution Mode</string>
|
||||||
<string name="settings_cpu_execution_mode_default">Interpreter</string>
|
<string name="settings_cpu_execution_mode_default">Interpreter</string>
|
||||||
|
|
||||||
<!-- GPU Preferences -->
|
<!-- GPU Preferences -->
|
||||||
<string name="settings_gpu_renderer">Renderer</string>
|
<string name="settings_gpu_renderer">Renderer</string>
|
||||||
<string name="settings_gpu_renderer_default">OpenGL</string>
|
|
||||||
<string name="settings_gpu_display_linear_filtering">Display Linear Filtering</string>
|
<string name="settings_gpu_display_linear_filtering">Display Linear Filtering</string>
|
||||||
<string name="settings_gpu_resolution_scale">Resolution Scale</string>
|
<string name="settings_gpu_resolution_scale">Resolution Scale</string>
|
||||||
<string name="settings_gpu_true_color">True 24-Bit Color (Disables Dithering)</string>
|
<string name="settings_gpu_true_color">True 24-Bit Color (Disables Dithering)</string>
|
||||||
|
@ -49,11 +49,13 @@
|
|||||||
<SwitchPreferenceCompat
|
<SwitchPreferenceCompat
|
||||||
app:key="BIOS/PatchTTYEnable"
|
app:key="BIOS/PatchTTYEnable"
|
||||||
app:title="@string/settings_console_tty_output"
|
app:title="@string/settings_console_tty_output"
|
||||||
|
app:defaultValue="false"
|
||||||
app:useSimpleSummaryProvider="true" />
|
app:useSimpleSummaryProvider="true" />
|
||||||
|
|
||||||
<SwitchPreferenceCompat
|
<SwitchPreferenceCompat
|
||||||
app:key="BIOS/PatchFastBoot"
|
app:key="BIOS/PatchFastBoot"
|
||||||
app:title="@string/settings_console_fast_boot"
|
app:title="@string/settings_console_fast_boot"
|
||||||
|
app:defaultValue="false"
|
||||||
app:useSimpleSummaryProvider="true" />
|
app:useSimpleSummaryProvider="true" />
|
||||||
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
@ -62,6 +64,7 @@
|
|||||||
<SwitchPreferenceCompat
|
<SwitchPreferenceCompat
|
||||||
app:key="General/SpeedLimiterEnabled"
|
app:key="General/SpeedLimiterEnabled"
|
||||||
app:title="@string/settings_behavior_enable_speed_limiter"
|
app:title="@string/settings_behavior_enable_speed_limiter"
|
||||||
|
app:defaultValue="true"
|
||||||
app:useSimpleSummaryProvider="true" />
|
app:useSimpleSummaryProvider="true" />
|
||||||
<SwitchPreferenceCompat
|
<SwitchPreferenceCompat
|
||||||
app:key="General/StartPaused"
|
app:key="General/StartPaused"
|
||||||
@ -79,13 +82,36 @@
|
|||||||
app:useSimpleSummaryProvider="true" />
|
app:useSimpleSummaryProvider="true" />
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
|
<PreferenceCategory app:title="@string/settings_osd_header">
|
||||||
|
<SwitchPreferenceCompat
|
||||||
|
app:key="Display/ShowOSDMessages"
|
||||||
|
app:title="@string/settings_osd_show_messages"
|
||||||
|
app:defaultValue="true"
|
||||||
|
app:useSimpleSummaryProvider="true" />
|
||||||
|
<SwitchPreferenceCompat
|
||||||
|
app:key="Display/ShowSpeed"
|
||||||
|
app:title="@string/settings_osd_show_speed"
|
||||||
|
app:defaultValue="false"
|
||||||
|
app:useSimpleSummaryProvider="true" />
|
||||||
|
<SwitchPreferenceCompat
|
||||||
|
app:key="Display/ShowFPS"
|
||||||
|
app:title="@string/settings_osd_show_show_fps"
|
||||||
|
app:defaultValue="false"
|
||||||
|
app:useSimpleSummaryProvider="true" />
|
||||||
|
<SwitchPreferenceCompat
|
||||||
|
app:key="Display/ShowVPS"
|
||||||
|
app:title="@string/settings_osd_show_show_vps"
|
||||||
|
app:defaultValue="false"
|
||||||
|
app:useSimpleSummaryProvider="true" />
|
||||||
|
</PreferenceCategory>
|
||||||
|
|
||||||
<PreferenceCategory app:title="@string/settings_cpu_header">
|
<PreferenceCategory app:title="@string/settings_cpu_header">
|
||||||
<ListPreference
|
<ListPreference
|
||||||
app:key="CPU/ExecutionMode"
|
app:key="CPU/ExecutionMode"
|
||||||
app:title="@string/settings_cpu_execution_mode"
|
app:title="@string/settings_cpu_execution_mode"
|
||||||
app:entries="@array/settings_cpu_execution_mode_entries"
|
app:entries="@array/settings_cpu_execution_mode_entries"
|
||||||
app:entryValues="@array/settings_cpu_execution_mode_values"
|
app:entryValues="@array/settings_cpu_execution_mode_values"
|
||||||
app:defaultValue="@string/settings_cpu_execution_mode_default"
|
app:defaultValue="Recompiler"
|
||||||
app:useSimpleSummaryProvider="true" />
|
app:useSimpleSummaryProvider="true" />
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
<PreferenceCategory app:title="@string/settings_gpu_header">
|
<PreferenceCategory app:title="@string/settings_gpu_header">
|
||||||
@ -95,7 +121,7 @@
|
|||||||
app:title="@string/settings_gpu_renderer"
|
app:title="@string/settings_gpu_renderer"
|
||||||
app:entries="@array/gpu_renderer_entries"
|
app:entries="@array/gpu_renderer_entries"
|
||||||
app:entryValues="@array/gpu_renderer_values"
|
app:entryValues="@array/gpu_renderer_values"
|
||||||
app:defaultValue="@string/settings_gpu_renderer_default"
|
app:defaultValue="OpenGL"
|
||||||
app:useSimpleSummaryProvider="true" />
|
app:useSimpleSummaryProvider="true" />
|
||||||
|
|
||||||
<ListPreference
|
<ListPreference
|
||||||
@ -103,12 +129,13 @@
|
|||||||
app:title="@string/settings_gpu_resolution_scale"
|
app:title="@string/settings_gpu_resolution_scale"
|
||||||
app:entries="@array/settings_gpu_resolution_scale_entries"
|
app:entries="@array/settings_gpu_resolution_scale_entries"
|
||||||
app:entryValues="@array/settings_gpu_resolution_scale_values"
|
app:entryValues="@array/settings_gpu_resolution_scale_values"
|
||||||
app:defaultValue="@string/settings_gpu_renderer_default"
|
app:defaultValue="1"
|
||||||
app:useSimpleSummaryProvider="true" />
|
app:useSimpleSummaryProvider="true" />
|
||||||
|
|
||||||
<SwitchPreferenceCompat
|
<SwitchPreferenceCompat
|
||||||
app:key="GPU/TrueColor"
|
app:key="GPU/TrueColor"
|
||||||
app:title="@string/settings_gpu_true_color"
|
app:title="@string/settings_gpu_true_color"
|
||||||
app:defaultValue="true"/>
|
app:defaultValue="false"/>
|
||||||
|
|
||||||
<SwitchPreferenceCompat
|
<SwitchPreferenceCompat
|
||||||
app:key="Display/LinearFiltering"
|
app:key="Display/LinearFiltering"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user