mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-15 05:47:56 -07:00
7aa305ea35
This global belongs in the JitOptions structure, as it's a conditional setting (A.K.A. option) that changes the behavior of what the JIT does. Plus it keeps the scope of the variable constrained to the general area it's intended to be used and nothing further.
630 lines
24 KiB
C++
630 lines
24 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/AndroidAnalytics.h"
|
|
#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/Analytics.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;
|
|
}
|
|
|
|
static void ReportSend(std::string endpoint, std::string report)
|
|
{
|
|
// Associate the current Thread with the Java VM.
|
|
JNIEnv* env;
|
|
IDCache::GetJavaVM()->AttachCurrentThread(&env, nullptr);
|
|
|
|
jbyteArray output_array = env->NewByteArray(report.size());
|
|
jbyte* output = env->GetByteArrayElements(output_array, nullptr);
|
|
memcpy(output, report.data(), report.size());
|
|
env->ReleaseByteArrayElements(output_array, output, 0);
|
|
env->CallStaticVoidMethod(IDCache::GetAnalyticsClass(), IDCache::GetSendAnalyticsReport(),
|
|
ToJString(env, endpoint), output_array);
|
|
|
|
IDCache::GetJavaVM()->DetachCurrentThread();
|
|
}
|
|
|
|
static std::string GetAnalyticValue(std::string key)
|
|
{
|
|
// Associate the current Thread with the Java VM.
|
|
JNIEnv* env;
|
|
bool attached = false;
|
|
int getEnvStat =
|
|
IDCache::GetJavaVM()->GetEnv(reinterpret_cast<void**>(&env), IDCache::JNI_VERSION);
|
|
if (getEnvStat == JNI_EDETACHED)
|
|
{
|
|
IDCache::GetJavaVM()->AttachCurrentThread(&env, nullptr);
|
|
attached = true;
|
|
}
|
|
|
|
jstring value = reinterpret_cast<jstring>(env->CallStaticObjectMethod(
|
|
IDCache::GetAnalyticsClass(), IDCache::GetAnalyticsValue(), ToJString(env, key)));
|
|
|
|
std::string stdvalue = GetJString(env, value);
|
|
|
|
// Only detach the thread if it wasn't already attached
|
|
if (attached)
|
|
IDCache::GetJavaVM()->DetachCurrentThread();
|
|
|
|
return stdvalue;
|
|
}
|
|
|
|
#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_2Z(
|
|
JNIEnv* env, jobject obj, jstring jFile, jboolean jfirstOpen);
|
|
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();
|
|
JitInterface::SetProfilingState(enable ? JitInterface::ProfilingState::Enabled :
|
|
JitInterface::ProfilingState::Disabled);
|
|
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, bool first_open,
|
|
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);
|
|
Common::AndroidSetReportHandler(&ReportSend);
|
|
DolphinAnalytics::AndroidSetGetValFunc(&GetAnalyticValue);
|
|
|
|
std::unique_lock<std::mutex> guard(s_host_identity_lock);
|
|
UICommon::Init();
|
|
|
|
if (first_open)
|
|
{
|
|
DolphinAnalytics::Instance()->ReportDolphinStart(GetAnalyticValue("DEVICE_TYPE"));
|
|
}
|
|
|
|
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_2Z(
|
|
JNIEnv* env, jobject obj, jstring jFile, jboolean jfirstOpen)
|
|
{
|
|
Run(GetJString(env, jFile), jfirstOpen);
|
|
}
|
|
|
|
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), false, 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
|