mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-15 13:57:57 -07:00
6f473b96d0
Makes the enum values strongly-typed and prevents the identifiers from polluting the PowerPC namespace. This also cleans up the parameters of some functions where we were accepting an ambiguous int type and expecting the correct values to be passed in. Now those parameters accept a PowerPC::CPUCore type only, making it immediately obvious which values should be passed in. It also turns out we were storing these core types into other structures as plain ints, which have also been corrected. As this type is used directly with the configuration code, we need to provide our own overloaded insertion (<<) and extraction (>>) operators in order to make it compatible with it. These are fairly trivial to implement, so there's no issue here. A minor adjustment to TryParse() was required, as our generic function was doing the following: N tmp = 0; which is problematic, as custom types may not be able to have that assignment performed (e.g. strongly-typed enums), so we change this to: N tmp; which is sufficient, as the value is attempted to be initialized immediately under that statement.
579 lines
22 KiB
C++
579 lines
22 KiB
C++
// Copyright 2003 Dolphin Emulator Project
|
|
// Licensed under GPLv2+
|
|
// Refer to the license.txt file included.
|
|
|
|
#include <EGL/egl.h>
|
|
#include <android/log.h>
|
|
#include <android/native_window_jni.h>
|
|
#include <cinttypes>
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <jni.h>
|
|
#include <memory>
|
|
#include <mutex>
|
|
#include <optional>
|
|
#include <string>
|
|
#include <thread>
|
|
#include <utility>
|
|
|
|
#include "Common/CPUDetect.h"
|
|
#include "Common/CommonPaths.h"
|
|
#include "Common/CommonTypes.h"
|
|
#include "Common/Event.h"
|
|
#include "Common/FileUtil.h"
|
|
#include "Common/GL/GLInterfaceBase.h"
|
|
#include "Common/Logging/LogManager.h"
|
|
#include "Common/MsgHandler.h"
|
|
#include "Common/Version.h"
|
|
|
|
#include "Core/Boot/Boot.h"
|
|
#include "Core/BootManager.h"
|
|
#include "Core/ConfigLoaders/GameConfigLoader.h"
|
|
#include "Core/ConfigManager.h"
|
|
#include "Core/Core.h"
|
|
#include "Core/HW/DVD/DVDInterface.h"
|
|
#include "Core/HW/Wiimote.h"
|
|
#include "Core/HW/WiimoteReal/WiimoteReal.h"
|
|
#include "Core/Host.h"
|
|
#include "Core/PowerPC/JitInterface.h"
|
|
#include "Core/PowerPC/PowerPC.h"
|
|
#include "Core/PowerPC/Profiler.h"
|
|
#include "Core/State.h"
|
|
|
|
#include "DiscIO/Enums.h"
|
|
#include "DiscIO/Volume.h"
|
|
|
|
#include "UICommon/UICommon.h"
|
|
|
|
#include "VideoCommon/OnScreenDisplay.h"
|
|
#include "VideoCommon/RenderBase.h"
|
|
#include "VideoCommon/VideoBackendBase.h"
|
|
|
|
#include "jni/AndroidCommon/AndroidCommon.h"
|
|
#include "jni/AndroidCommon/IDCache.h"
|
|
#include "jni/ButtonManager.h"
|
|
|
|
namespace
|
|
{
|
|
static constexpr char DOLPHIN_TAG[] = "DolphinEmuNative";
|
|
|
|
ANativeWindow* s_surf;
|
|
|
|
// The Core only supports using a single Host thread.
|
|
// If multiple threads want to call host functions then they need to queue
|
|
// sequentially for access.
|
|
std::mutex s_host_identity_lock;
|
|
Common::Event s_update_main_frame_event;
|
|
bool s_have_wm_user_stop = false;
|
|
} // Anonymous namespace
|
|
|
|
void Host_NotifyMapLoaded()
|
|
{
|
|
}
|
|
void Host_RefreshDSPDebuggerWindow()
|
|
{
|
|
}
|
|
|
|
void Host_Message(HostMessageID id)
|
|
{
|
|
if (id == HostMessageID::WMUserJobDispatch)
|
|
{
|
|
s_update_main_frame_event.Set();
|
|
}
|
|
else if (id == HostMessageID::WMUserStop)
|
|
{
|
|
s_have_wm_user_stop = true;
|
|
if (Core::IsRunning())
|
|
Core::QueueHostJob(&Core::Stop);
|
|
}
|
|
}
|
|
|
|
void* Host_GetRenderHandle()
|
|
{
|
|
return s_surf;
|
|
}
|
|
|
|
void Host_UpdateTitle(const std::string& title)
|
|
{
|
|
__android_log_write(ANDROID_LOG_INFO, DOLPHIN_TAG, title.c_str());
|
|
}
|
|
|
|
void Host_UpdateDisasmDialog()
|
|
{
|
|
}
|
|
|
|
void Host_UpdateMainFrame()
|
|
{
|
|
}
|
|
|
|
void Host_RequestRenderWindowSize(int width, int height)
|
|
{
|
|
}
|
|
|
|
bool Host_UINeedsControllerState()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
bool Host_RendererHasFocus()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
bool Host_RendererIsFullscreen()
|
|
{
|
|
return false;
|
|
}
|
|
|
|
void Host_ShowVideoConfig(void*, const std::string&)
|
|
{
|
|
}
|
|
|
|
void Host_YieldToUI()
|
|
{
|
|
}
|
|
|
|
void Host_UpdateProgressDialog(const char* caption, int position, int total)
|
|
{
|
|
}
|
|
|
|
static bool MsgAlert(const char* caption, const char* text, bool yes_no, MsgType /*style*/)
|
|
{
|
|
__android_log_print(ANDROID_LOG_ERROR, DOLPHIN_TAG, "%s:%s", caption, text);
|
|
|
|
// Associate the current Thread with the Java VM.
|
|
JNIEnv* env;
|
|
IDCache::GetJavaVM()->AttachCurrentThread(&env, nullptr);
|
|
|
|
// Execute the Java method.
|
|
jboolean result = env->CallStaticBooleanMethod(
|
|
IDCache::GetNativeLibraryClass(), IDCache::GetDisplayAlertMsg(), ToJString(env, caption),
|
|
ToJString(env, text), yes_no ? JNI_TRUE : JNI_FALSE);
|
|
|
|
// Must be called before the current thread exits; might as well do it here.
|
|
IDCache::GetJavaVM()->DetachCurrentThread();
|
|
|
|
return result != JNI_FALSE;
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_UnPauseEmulation(JNIEnv* env,
|
|
jobject obj);
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_PauseEmulation(JNIEnv* env,
|
|
jobject obj);
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_StopEmulation(JNIEnv* env,
|
|
jobject obj);
|
|
JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_IsRunning(JNIEnv* env,
|
|
jobject obj);
|
|
JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_onGamePadEvent(
|
|
JNIEnv* env, jobject obj, jstring jDevice, jint Button, jint Action);
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_onGamePadMoveEvent(
|
|
JNIEnv* env, jobject obj, jstring jDevice, jint Axis, jfloat Value);
|
|
JNIEXPORT jstring JNICALL
|
|
Java_org_dolphinemu_dolphinemu_NativeLibrary_GetVersionString(JNIEnv* env, jobject obj);
|
|
JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetGitRevision(JNIEnv* env,
|
|
jobject obj);
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SaveScreenShot(JNIEnv* env,
|
|
jobject obj);
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_eglBindAPI(JNIEnv* env,
|
|
jobject obj,
|
|
jint api);
|
|
JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetConfig(
|
|
JNIEnv* env, jobject obj, jstring jFile, jstring jSection, jstring jKey, jstring jDefault);
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SetConfig(
|
|
JNIEnv* env, jobject obj, jstring jFile, jstring jSection, jstring jKey, jstring jValue);
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SetFilename(JNIEnv* env,
|
|
jobject obj,
|
|
jstring jFile);
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SaveState(JNIEnv* env,
|
|
jobject obj,
|
|
jint slot,
|
|
jboolean wait);
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SaveStateAs(JNIEnv* env,
|
|
jobject obj,
|
|
jstring path,
|
|
jboolean wait);
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_LoadState(JNIEnv* env,
|
|
jobject obj,
|
|
jint slot);
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_LoadStateAs(JNIEnv* env,
|
|
jobject obj,
|
|
jstring path);
|
|
JNIEXPORT void JNICALL
|
|
Java_org_dolphinemu_dolphinemu_services_DirectoryInitializationService_CreateUserDirectories(
|
|
JNIEnv* env, jobject obj);
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SetUserDirectory(
|
|
JNIEnv* env, jobject obj, jstring jDirectory);
|
|
JNIEXPORT jstring JNICALL
|
|
Java_org_dolphinemu_dolphinemu_NativeLibrary_GetUserDirectory(JNIEnv* env, jobject obj);
|
|
JNIEXPORT jint JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_DefaultCPUCore(JNIEnv* env,
|
|
jobject obj);
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SetProfiling(JNIEnv* env,
|
|
jobject obj,
|
|
jboolean enable);
|
|
JNIEXPORT void JNICALL
|
|
Java_org_dolphinemu_dolphinemu_NativeLibrary_WriteProfileResults(JNIEnv* env, jobject obj);
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_Run__Ljava_lang_String_2(
|
|
JNIEnv* env, jobject obj, jstring jFile);
|
|
JNIEXPORT void JNICALL
|
|
Java_org_dolphinemu_dolphinemu_NativeLibrary_Run__Ljava_lang_String_2Ljava_lang_String_2Z(
|
|
JNIEnv* env, jobject obj, jstring jFile, jstring jSavestate, jboolean jDeleteSavestate);
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SurfaceChanged(JNIEnv* env,
|
|
jobject obj,
|
|
jobject surf);
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SurfaceDestroyed(JNIEnv* env,
|
|
jobject obj);
|
|
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_UnPauseEmulation(JNIEnv* env,
|
|
jobject obj)
|
|
{
|
|
std::lock_guard<std::mutex> guard(s_host_identity_lock);
|
|
Core::SetState(Core::State::Running);
|
|
}
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_PauseEmulation(JNIEnv* env,
|
|
jobject obj)
|
|
{
|
|
std::lock_guard<std::mutex> guard(s_host_identity_lock);
|
|
Core::SetState(Core::State::Paused);
|
|
}
|
|
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_StopEmulation(JNIEnv* env,
|
|
jobject obj)
|
|
{
|
|
std::lock_guard<std::mutex> guard(s_host_identity_lock);
|
|
Core::SaveScreenShot("thumb", true);
|
|
Core::Stop();
|
|
s_update_main_frame_event.Set(); // Kick the waiting event
|
|
}
|
|
|
|
JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_IsRunning(JNIEnv* env,
|
|
jobject obj)
|
|
{
|
|
return Core::IsRunning();
|
|
}
|
|
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_ChangeDisc(JNIEnv* env,
|
|
jobject obj,
|
|
jstring jFile);
|
|
|
|
JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_onGamePadEvent(
|
|
JNIEnv* env, jobject obj, jstring jDevice, jint Button, jint Action)
|
|
{
|
|
return ButtonManager::GamepadEvent(GetJString(env, jDevice), Button, Action);
|
|
}
|
|
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_onGamePadMoveEvent(
|
|
JNIEnv* env, jobject obj, jstring jDevice, jint Axis, jfloat Value)
|
|
{
|
|
ButtonManager::GamepadAxisEvent(GetJString(env, jDevice), Axis, Value);
|
|
}
|
|
|
|
JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetVersionString(JNIEnv* env,
|
|
jobject obj)
|
|
{
|
|
return ToJString(env, Common::scm_rev_str.c_str());
|
|
}
|
|
|
|
JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetGitRevision(JNIEnv* env,
|
|
jobject obj)
|
|
{
|
|
return ToJString(env, Common::scm_rev_git_str.c_str());
|
|
}
|
|
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SaveScreenShot(JNIEnv* env,
|
|
jobject obj)
|
|
{
|
|
std::lock_guard<std::mutex> guard(s_host_identity_lock);
|
|
Core::SaveScreenShot();
|
|
}
|
|
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_eglBindAPI(JNIEnv* env,
|
|
jobject obj,
|
|
jint api)
|
|
{
|
|
eglBindAPI(api);
|
|
}
|
|
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_InitGameIni(JNIEnv* env,
|
|
jobject obj,
|
|
jstring jGameID)
|
|
{
|
|
// Initialize an empty INI file
|
|
IniFile ini;
|
|
std::string gameid = GetJString(env, jGameID);
|
|
|
|
__android_log_print(ANDROID_LOG_DEBUG, "InitGameIni", "Initializing base game config file");
|
|
ini.Save(File::GetUserPath(D_GAMESETTINGS_IDX) + gameid + ".ini");
|
|
}
|
|
|
|
JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetUserSetting(
|
|
JNIEnv* env, jobject obj, jstring jGameID, jstring jSection, jstring jKey)
|
|
{
|
|
IniFile ini;
|
|
std::string gameid = GetJString(env, jGameID);
|
|
std::string section = GetJString(env, jSection);
|
|
std::string key = GetJString(env, jKey);
|
|
|
|
ini = SConfig::GetInstance().LoadGameIni(gameid, 0);
|
|
std::string value;
|
|
|
|
ini.GetOrCreateSection(section)->Get(key, &value, "-1");
|
|
|
|
return ToJString(env, value.c_str());
|
|
}
|
|
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SetUserSetting(
|
|
JNIEnv* env, jobject obj, jstring jGameID, jstring jSection, jstring jKey, jstring jValue)
|
|
{
|
|
IniFile ini;
|
|
std::string gameid = GetJString(env, jGameID);
|
|
std::string section = GetJString(env, jSection);
|
|
std::string key = GetJString(env, jKey);
|
|
std::string val = GetJString(env, jValue);
|
|
|
|
ini.Load(File::GetUserPath(D_GAMESETTINGS_IDX) + gameid + ".ini");
|
|
|
|
if (val != "-1")
|
|
{
|
|
ini.GetOrCreateSection(section)->Set(key, val);
|
|
}
|
|
else
|
|
{
|
|
ini.GetOrCreateSection(section)->Delete(key);
|
|
}
|
|
|
|
ini.Save(File::GetUserPath(D_GAMESETTINGS_IDX) + gameid + ".ini");
|
|
}
|
|
|
|
JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetConfig(
|
|
JNIEnv* env, jobject obj, jstring jFile, jstring jSection, jstring jKey, jstring jDefault)
|
|
{
|
|
IniFile ini;
|
|
std::string file = GetJString(env, jFile);
|
|
std::string section = GetJString(env, jSection);
|
|
std::string key = GetJString(env, jKey);
|
|
std::string defaultValue = GetJString(env, jDefault);
|
|
|
|
ini.Load(File::GetUserPath(D_CONFIG_IDX) + std::string(file));
|
|
std::string value;
|
|
|
|
ini.GetOrCreateSection(section)->Get(key, &value, defaultValue);
|
|
|
|
return ToJString(env, value.c_str());
|
|
}
|
|
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SetConfig(
|
|
JNIEnv* env, jobject obj, jstring jFile, jstring jSection, jstring jKey, jstring jValue)
|
|
{
|
|
IniFile ini;
|
|
std::string file = GetJString(env, jFile);
|
|
std::string section = GetJString(env, jSection);
|
|
std::string key = GetJString(env, jKey);
|
|
std::string value = GetJString(env, jValue);
|
|
|
|
ini.Load(File::GetUserPath(D_CONFIG_IDX) + std::string(file));
|
|
|
|
ini.GetOrCreateSection(section)->Set(key, value);
|
|
ini.Save(File::GetUserPath(D_CONFIG_IDX) + std::string(file));
|
|
}
|
|
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SaveState(JNIEnv* env,
|
|
jobject obj,
|
|
jint slot,
|
|
jboolean wait)
|
|
{
|
|
std::lock_guard<std::mutex> guard(s_host_identity_lock);
|
|
State::Save(slot, wait);
|
|
}
|
|
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SaveStateAs(JNIEnv* env,
|
|
jobject obj,
|
|
jstring path,
|
|
jboolean wait)
|
|
{
|
|
std::lock_guard<std::mutex> guard(s_host_identity_lock);
|
|
State::SaveAs(GetJString(env, path), wait);
|
|
}
|
|
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_LoadState(JNIEnv* env,
|
|
jobject obj,
|
|
jint slot)
|
|
{
|
|
std::lock_guard<std::mutex> guard(s_host_identity_lock);
|
|
State::Load(slot);
|
|
}
|
|
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_LoadStateAs(JNIEnv* env,
|
|
jobject obj,
|
|
jstring path)
|
|
{
|
|
std::lock_guard<std::mutex> guard(s_host_identity_lock);
|
|
State::LoadAs(GetJString(env, path));
|
|
}
|
|
|
|
JNIEXPORT void JNICALL
|
|
Java_org_dolphinemu_dolphinemu_services_DirectoryInitializationService_SetSysDirectory(
|
|
JNIEnv* env, jobject obj, jstring jPath)
|
|
{
|
|
const std::string path = GetJString(env, jPath);
|
|
File::SetSysDirectory(path);
|
|
}
|
|
|
|
JNIEXPORT void JNICALL
|
|
Java_org_dolphinemu_dolphinemu_services_DirectoryInitializationService_CreateUserDirectories(
|
|
JNIEnv* env, jobject obj)
|
|
{
|
|
UICommon::CreateDirectories();
|
|
}
|
|
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SetUserDirectory(
|
|
JNIEnv* env, jobject obj, jstring jDirectory)
|
|
{
|
|
std::lock_guard<std::mutex> guard(s_host_identity_lock);
|
|
UICommon::SetUserDirectory(GetJString(env, jDirectory));
|
|
}
|
|
|
|
JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetUserDirectory(JNIEnv* env,
|
|
jobject obj)
|
|
{
|
|
return ToJString(env, File::GetUserPath(D_USER_IDX).c_str());
|
|
}
|
|
|
|
JNIEXPORT jint JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_DefaultCPUCore(JNIEnv* env,
|
|
jobject obj)
|
|
{
|
|
return static_cast<jint>(PowerPC::DefaultCPUCore());
|
|
}
|
|
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SetProfiling(JNIEnv* env,
|
|
jobject obj,
|
|
jboolean enable)
|
|
{
|
|
std::lock_guard<std::mutex> guard(s_host_identity_lock);
|
|
Core::SetState(Core::State::Paused);
|
|
JitInterface::ClearCache();
|
|
Profiler::g_ProfileBlocks = enable;
|
|
Core::SetState(Core::State::Running);
|
|
}
|
|
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_WriteProfileResults(JNIEnv* env,
|
|
jobject obj)
|
|
{
|
|
std::lock_guard<std::mutex> guard(s_host_identity_lock);
|
|
std::string filename = File::GetUserPath(D_DUMP_IDX) + "Debug/profiler.txt";
|
|
File::CreateFullPath(filename);
|
|
JitInterface::WriteProfileResults(filename);
|
|
}
|
|
|
|
// Surface Handling
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SurfaceChanged(JNIEnv* env,
|
|
jobject obj,
|
|
jobject surf)
|
|
{
|
|
s_surf = ANativeWindow_fromSurface(env, surf);
|
|
if (s_surf == nullptr)
|
|
__android_log_print(ANDROID_LOG_ERROR, DOLPHIN_TAG, "Error: Surface is null.");
|
|
|
|
if (g_renderer)
|
|
g_renderer->ChangeSurface(s_surf);
|
|
}
|
|
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SurfaceDestroyed(JNIEnv* env,
|
|
jobject obj)
|
|
{
|
|
if (g_renderer)
|
|
g_renderer->ChangeSurface(nullptr);
|
|
|
|
if (s_surf)
|
|
{
|
|
ANativeWindow_release(s_surf);
|
|
s_surf = nullptr;
|
|
}
|
|
}
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_RefreshWiimotes(JNIEnv* env,
|
|
jobject obj)
|
|
{
|
|
std::lock_guard<std::mutex> guard(s_host_identity_lock);
|
|
WiimoteReal::Refresh();
|
|
}
|
|
|
|
static void Run(const std::string& path, std::optional<std::string> savestate_path = {},
|
|
bool delete_savestate = false)
|
|
{
|
|
__android_log_print(ANDROID_LOG_INFO, DOLPHIN_TAG, "Running : %s", path.c_str());
|
|
|
|
// Install our callbacks
|
|
OSD::AddCallback(OSD::CallbackType::Initialization, ButtonManager::Init);
|
|
OSD::AddCallback(OSD::CallbackType::Shutdown, ButtonManager::Shutdown);
|
|
|
|
RegisterMsgAlertHandler(&MsgAlert);
|
|
|
|
std::unique_lock<std::mutex> guard(s_host_identity_lock);
|
|
UICommon::Init();
|
|
|
|
WiimoteReal::InitAdapterClass();
|
|
|
|
// No use running the loop when booting fails
|
|
s_have_wm_user_stop = false;
|
|
std::unique_ptr<BootParameters> boot = BootParameters::GenerateFromFile(path, savestate_path);
|
|
boot->delete_savestate = delete_savestate;
|
|
if (BootManager::BootCore(std::move(boot)))
|
|
{
|
|
static constexpr int TIMEOUT = 10000;
|
|
static constexpr int WAIT_STEP = 25;
|
|
int time_waited = 0;
|
|
// A Core::CORE_ERROR state would be helpful here.
|
|
while (!Core::IsRunning() && time_waited < TIMEOUT && !s_have_wm_user_stop)
|
|
{
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_STEP));
|
|
time_waited += WAIT_STEP;
|
|
}
|
|
while (Core::IsRunning())
|
|
{
|
|
guard.unlock();
|
|
s_update_main_frame_event.Wait();
|
|
guard.lock();
|
|
Core::HostDispatchJobs();
|
|
}
|
|
}
|
|
|
|
Core::Shutdown();
|
|
UICommon::Shutdown();
|
|
guard.unlock();
|
|
|
|
if (s_surf)
|
|
{
|
|
ANativeWindow_release(s_surf);
|
|
s_surf = nullptr;
|
|
}
|
|
}
|
|
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_Run__Ljava_lang_String_2(
|
|
JNIEnv* env, jobject obj, jstring jFile)
|
|
{
|
|
Run(GetJString(env, jFile));
|
|
}
|
|
|
|
JNIEXPORT void JNICALL
|
|
Java_org_dolphinemu_dolphinemu_NativeLibrary_Run__Ljava_lang_String_2Ljava_lang_String_2Z(
|
|
JNIEnv* env, jobject obj, jstring jFile, jstring jSavestate, jboolean jDeleteSavestate)
|
|
{
|
|
Run(GetJString(env, jFile), GetJString(env, jSavestate), jDeleteSavestate);
|
|
}
|
|
|
|
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_ChangeDisc(JNIEnv* env,
|
|
jobject obj,
|
|
jstring jFile)
|
|
{
|
|
const std::string path = GetJString(env, jFile);
|
|
__android_log_print(ANDROID_LOG_INFO, DOLPHIN_TAG, "Change Disc: %s", path.c_str());
|
|
Core::RunAsCPUThread([&path] { DVDInterface::ChangeDisc(path); });
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|