summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/android/app/src/main/jni/native.cpp122
1 files changed, 64 insertions, 58 deletions
diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp
index 6a499b97d..d0794e8b1 100644
--- a/src/android/app/src/main/jni/native.cpp
+++ b/src/android/app/src/main/jni/native.cpp
@@ -61,7 +61,7 @@ public:
61 } 61 }
62 62
63 bool IsRunning() const { 63 bool IsRunning() const {
64 return system.IsPoweredOn(); 64 return is_running.load(std::memory_order_relaxed);
65 } 65 }
66 66
67 const Core::PerfStatsResults& PerfStats() const { 67 const Core::PerfStatsResults& PerfStats() const {
@@ -95,7 +95,8 @@ public:
95 system.GetFileSystemController().CreateFactories(*system.GetFilesystem()); 95 system.GetFileSystemController().CreateFactories(*system.GetFilesystem());
96 96
97 // Load the ROM. 97 // Load the ROM.
98 const Core::SystemResultStatus load_result{system.Load(EmulationSession::GetInstance().Window(), filepath)}; 98 const Core::SystemResultStatus load_result{
99 system.Load(EmulationSession::GetInstance().Window(), filepath)};
99 if (load_result != Core::SystemResultStatus::Success) { 100 if (load_result != Core::SystemResultStatus::Success) {
100 return load_result; 101 return load_result;
101 } 102 }
@@ -124,19 +125,23 @@ public:
124 } 125 }
125 126
126 void HaltEmulation() { 127 void HaltEmulation() {
128 is_running.store(false, std::memory_order_relaxed);
127 cv.notify_one(); 129 cv.notify_one();
128 } 130 }
129 131
130 void RunEmulation() { 132 void RunEmulation() {
131 std::unique_lock lock(mutex); 133 std::unique_lock lock(mutex);
132 134
135 is_running.store(true, std::memory_order_relaxed);
136
133 void(system.Run()); 137 void(system.Run());
134 138
135 if (system.DebuggerEnabled()) { 139 if (system.DebuggerEnabled()) {
136 system.InitializeDebugger(); 140 system.InitializeDebugger();
137 } 141 }
138 142
139 while (cv.wait_for(lock, std::chrono::seconds (1)) == std::cv_status::timeout) { 143 while (!cv.wait_for(lock, std::chrono::seconds(1),
144 [&]() { return !is_running.load(std::memory_order_relaxed); })) {
140 std::scoped_lock perf_stats_lock(perf_stats_mutex); 145 std::scoped_lock perf_stats_lock(perf_stats_mutex);
141 perf_stats = system.GetAndResetPerfStats(); 146 perf_stats = system.GetAndResetPerfStats();
142 } 147 }
@@ -157,6 +162,7 @@ private:
157 std::unique_ptr<EmuWindow_Android> window; 162 std::unique_ptr<EmuWindow_Android> window;
158 std::mutex mutex; 163 std::mutex mutex;
159 std::condition_variable_any cv; 164 std::condition_variable_any cv;
165 std::atomic_bool is_running{};
160}; 166};
161 167
162/*static*/ EmulationSession EmulationSession::s_instance; 168/*static*/ EmulationSession EmulationSession::s_instance;
@@ -211,14 +217,14 @@ static Core::SystemResultStatus RunEmulation(const std::string& filepath) {
211extern "C" { 217extern "C" {
212 218
213void Java_org_yuzu_yuzu_1emu_NativeLibrary_SurfaceChanged(JNIEnv* env, 219void Java_org_yuzu_yuzu_1emu_NativeLibrary_SurfaceChanged(JNIEnv* env,
214 [[maybe_unused]] jclass clazz, 220 [[maybe_unused]] jclass clazz,
215 jobject surf) { 221 jobject surf) {
216 EmulationSession::GetInstance().SetNativeWindow(ANativeWindow_fromSurface(env, surf)); 222 EmulationSession::GetInstance().SetNativeWindow(ANativeWindow_fromSurface(env, surf));
217 EmulationSession::GetInstance().SurfaceChanged(); 223 EmulationSession::GetInstance().SurfaceChanged();
218} 224}
219 225
220void Java_org_yuzu_yuzu_1emu_NativeLibrary_SurfaceDestroyed(JNIEnv* env, 226void Java_org_yuzu_yuzu_1emu_NativeLibrary_SurfaceDestroyed(JNIEnv* env,
221 [[maybe_unused]] jclass clazz) { 227 [[maybe_unused]] jclass clazz) {
222 ANativeWindow_release(EmulationSession::GetInstance().NativeWindow()); 228 ANativeWindow_release(EmulationSession::GetInstance().NativeWindow());
223 EmulationSession::GetInstance().SetNativeWindow(nullptr); 229 EmulationSession::GetInstance().SetNativeWindow(nullptr);
224 EmulationSession::GetInstance().SurfaceChanged(); 230 EmulationSession::GetInstance().SurfaceChanged();
@@ -227,34 +233,34 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_SurfaceDestroyed(JNIEnv* env,
227void Java_org_yuzu_yuzu_1emu_NativeLibrary_DoFrame(JNIEnv* env, [[maybe_unused]] jclass clazz) {} 233void Java_org_yuzu_yuzu_1emu_NativeLibrary_DoFrame(JNIEnv* env, [[maybe_unused]] jclass clazz) {}
228 234
229void Java_org_yuzu_yuzu_1emu_NativeLibrary_NotifyOrientationChange(JNIEnv* env, 235void Java_org_yuzu_yuzu_1emu_NativeLibrary_NotifyOrientationChange(JNIEnv* env,
230 [[maybe_unused]] jclass clazz, 236 [[maybe_unused]] jclass clazz,
231 jint layout_option, 237 jint layout_option,
232 jint rotation) {} 238 jint rotation) {}
233 239
234void Java_org_yuzu_yuzu_1emu_NativeLibrary_SetUserDirectory( 240void Java_org_yuzu_yuzu_1emu_NativeLibrary_SetUserDirectory([[maybe_unused]] JNIEnv* env,
235 [[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, 241 [[maybe_unused]] jclass clazz,
236 [[maybe_unused]] jstring j_directory) {} 242 [[maybe_unused]] jstring j_directory) {}
237 243
238void Java_org_yuzu_yuzu_1emu_NativeLibrary_UnPauseEmulation([[maybe_unused]] JNIEnv* env, 244void Java_org_yuzu_yuzu_1emu_NativeLibrary_UnPauseEmulation([[maybe_unused]] JNIEnv* env,
239 [[maybe_unused]] jclass clazz) {} 245 [[maybe_unused]] jclass clazz) {}
240 246
241void Java_org_yuzu_yuzu_1emu_NativeLibrary_PauseEmulation([[maybe_unused]] JNIEnv* env, 247void Java_org_yuzu_yuzu_1emu_NativeLibrary_PauseEmulation([[maybe_unused]] JNIEnv* env,
242 [[maybe_unused]] jclass clazz) {} 248 [[maybe_unused]] jclass clazz) {}
243 249
244void Java_org_yuzu_yuzu_1emu_NativeLibrary_StopEmulation([[maybe_unused]] JNIEnv* env, 250void Java_org_yuzu_yuzu_1emu_NativeLibrary_StopEmulation([[maybe_unused]] JNIEnv* env,
245 [[maybe_unused]] jclass clazz) { 251 [[maybe_unused]] jclass clazz) {
246 EmulationSession::GetInstance().HaltEmulation(); 252 EmulationSession::GetInstance().HaltEmulation();
247} 253}
248 254
249jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_IsRunning([[maybe_unused]] JNIEnv* env, 255jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_IsRunning([[maybe_unused]] JNIEnv* env,
250 [[maybe_unused]] jclass clazz) { 256 [[maybe_unused]] jclass clazz) {
251 return static_cast<jboolean>(EmulationSession::GetInstance().IsRunning()); 257 return static_cast<jboolean>(EmulationSession::GetInstance().IsRunning());
252} 258}
253 259
254jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_onGamePadEvent([[maybe_unused]] JNIEnv* env, 260jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_onGamePadEvent([[maybe_unused]] JNIEnv* env,
255 [[maybe_unused]] jclass clazz, 261 [[maybe_unused]] jclass clazz,
256 [[maybe_unused]] jstring j_device, 262 [[maybe_unused]] jstring j_device,
257 jint j_button, jint action) { 263 jint j_button, jint action) {
258 if (EmulationSession::GetInstance().IsRunning()) { 264 if (EmulationSession::GetInstance().IsRunning()) {
259 EmulationSession::GetInstance().Window().OnGamepadEvent(j_button, action != 0); 265 EmulationSession::GetInstance().Window().OnGamepadEvent(j_button, action != 0);
260 } 266 }
@@ -262,9 +268,9 @@ jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_onGamePadEvent([[maybe_unused]] J
262} 268}
263 269
264jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_onGamePadMoveEvent([[maybe_unused]] JNIEnv* env, 270jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_onGamePadMoveEvent([[maybe_unused]] JNIEnv* env,
265 [[maybe_unused]] jclass clazz, 271 [[maybe_unused]] jclass clazz,
266 jstring j_device, jint axis, 272 jstring j_device, jint axis,
267 jfloat x, jfloat y) { 273 jfloat x, jfloat y) {
268 // Clamp joystick movement to supported minimum and maximum. 274 // Clamp joystick movement to supported minimum and maximum.
269 x = std::clamp(x, -1.f, 1.f); 275 x = std::clamp(x, -1.f, 1.f);
270 y = std::clamp(-y, -1.f, 1.f); 276 y = std::clamp(-y, -1.f, 1.f);
@@ -284,68 +290,68 @@ jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_onGamePadMoveEvent([[maybe_unused
284} 290}
285 291
286jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_onGamePadAxisEvent([[maybe_unused]] JNIEnv* env, 292jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_onGamePadAxisEvent([[maybe_unused]] JNIEnv* env,
287 [[maybe_unused]] jclass clazz, 293 [[maybe_unused]] jclass clazz,
288 jstring j_device, jint axis_id, 294 jstring j_device, jint axis_id,
289 jfloat axis_val) { 295 jfloat axis_val) {
290 return {}; 296 return {};
291} 297}
292 298
293jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_onTouchEvent([[maybe_unused]] JNIEnv* env, 299jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_onTouchEvent([[maybe_unused]] JNIEnv* env,
294 [[maybe_unused]] jclass clazz, 300 [[maybe_unused]] jclass clazz, jfloat x,
295 jfloat x, jfloat y, 301 jfloat y, jboolean pressed) {
296 jboolean pressed) {
297 if (EmulationSession::GetInstance().IsRunning()) { 302 if (EmulationSession::GetInstance().IsRunning()) {
298 return static_cast<jboolean>(EmulationSession::GetInstance().Window().OnTouchEvent(x, y, pressed)); 303 return static_cast<jboolean>(
304 EmulationSession::GetInstance().Window().OnTouchEvent(x, y, pressed));
299 } 305 }
300 return static_cast<jboolean>(false); 306 return static_cast<jboolean>(false);
301} 307}
302 308
303void Java_org_yuzu_yuzu_1emu_NativeLibrary_onTouchMoved([[maybe_unused]] JNIEnv* env, 309void Java_org_yuzu_yuzu_1emu_NativeLibrary_onTouchMoved([[maybe_unused]] JNIEnv* env,
304 [[maybe_unused]] jclass clazz, jfloat x, 310 [[maybe_unused]] jclass clazz, jfloat x,
305 jfloat y) { 311 jfloat y) {
306 if (EmulationSession::GetInstance().IsRunning()) { 312 if (EmulationSession::GetInstance().IsRunning()) {
307 EmulationSession::GetInstance().Window().OnTouchMoved(x, y); 313 EmulationSession::GetInstance().Window().OnTouchMoved(x, y);
308 } 314 }
309} 315}
310 316
311jintArray Java_org_yuzu_yuzu_1emu_NativeLibrary_GetIcon([[maybe_unused]] JNIEnv* env, 317jintArray Java_org_yuzu_yuzu_1emu_NativeLibrary_GetIcon([[maybe_unused]] JNIEnv* env,
312 [[maybe_unused]] jclass clazz, 318 [[maybe_unused]] jclass clazz,
313 [[maybe_unused]] jstring j_file) { 319 [[maybe_unused]] jstring j_file) {
314 return {}; 320 return {};
315} 321}
316 322
317jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_GetTitle([[maybe_unused]] JNIEnv* env, 323jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_GetTitle([[maybe_unused]] JNIEnv* env,
318 [[maybe_unused]] jclass clazz, 324 [[maybe_unused]] jclass clazz,
319 [[maybe_unused]] jstring j_filename) { 325 [[maybe_unused]] jstring j_filename) {
320 return env->NewStringUTF(""); 326 return env->NewStringUTF("");
321} 327}
322 328
323jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_GetDescription([[maybe_unused]] JNIEnv* env, 329jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_GetDescription([[maybe_unused]] JNIEnv* env,
324 [[maybe_unused]] jclass clazz, 330 [[maybe_unused]] jclass clazz,
325 jstring j_filename) { 331 jstring j_filename) {
326 return j_filename; 332 return j_filename;
327} 333}
328 334
329jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_GetGameId([[maybe_unused]] JNIEnv* env, 335jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_GetGameId([[maybe_unused]] JNIEnv* env,
330 [[maybe_unused]] jclass clazz, 336 [[maybe_unused]] jclass clazz,
331 jstring j_filename) { 337 jstring j_filename) {
332 return j_filename; 338 return j_filename;
333} 339}
334 340
335jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_GetRegions([[maybe_unused]] JNIEnv* env, 341jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_GetRegions([[maybe_unused]] JNIEnv* env,
336 [[maybe_unused]] jclass clazz, 342 [[maybe_unused]] jclass clazz,
337 [[maybe_unused]] jstring j_filename) { 343 [[maybe_unused]] jstring j_filename) {
338 return env->NewStringUTF(""); 344 return env->NewStringUTF("");
339} 345}
340 346
341jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_GetCompany([[maybe_unused]] JNIEnv* env, 347jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_GetCompany([[maybe_unused]] JNIEnv* env,
342 [[maybe_unused]] jclass clazz, 348 [[maybe_unused]] jclass clazz,
343 [[maybe_unused]] jstring j_filename) { 349 [[maybe_unused]] jstring j_filename) {
344 return env->NewStringUTF(""); 350 return env->NewStringUTF("");
345} 351}
346 352
347jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_GetGitRevision([[maybe_unused]] JNIEnv* env, 353jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_GetGitRevision([[maybe_unused]] JNIEnv* env,
348 [[maybe_unused]] jclass clazz) { 354 [[maybe_unused]] jclass clazz) {
349 return {}; 355 return {};
350} 356}
351 357
@@ -355,7 +361,7 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_CreateConfigFile
355} 361}
356 362
357jint Java_org_yuzu_yuzu_1emu_NativeLibrary_DefaultCPUCore([[maybe_unused]] JNIEnv* env, 363jint Java_org_yuzu_yuzu_1emu_NativeLibrary_DefaultCPUCore([[maybe_unused]] JNIEnv* env,
358 [[maybe_unused]] jclass clazz) { 364 [[maybe_unused]] jclass clazz) {
359 return {}; 365 return {};
360} 366}
361 367
@@ -364,14 +370,14 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_Run__Ljava_lang_String_2Ljava_lang_St
364 [[maybe_unused]] jstring j_savestate, [[maybe_unused]] jboolean j_delete_savestate) {} 370 [[maybe_unused]] jstring j_savestate, [[maybe_unused]] jboolean j_delete_savestate) {}
365 371
366void Java_org_yuzu_yuzu_1emu_NativeLibrary_ReloadSettings([[maybe_unused]] JNIEnv* env, 372void Java_org_yuzu_yuzu_1emu_NativeLibrary_ReloadSettings([[maybe_unused]] JNIEnv* env,
367 [[maybe_unused]] jclass clazz) { 373 [[maybe_unused]] jclass clazz) {
368 Config{}; 374 Config{};
369} 375}
370 376
371jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_GetUserSetting([[maybe_unused]] JNIEnv* env, 377jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_GetUserSetting([[maybe_unused]] JNIEnv* env,
372 [[maybe_unused]] jclass clazz, 378 [[maybe_unused]] jclass clazz,
373 jstring j_game_id, jstring j_section, 379 jstring j_game_id, jstring j_section,
374 jstring j_key) { 380 jstring j_key) {
375 std::string_view game_id = env->GetStringUTFChars(j_game_id, 0); 381 std::string_view game_id = env->GetStringUTFChars(j_game_id, 0);
376 std::string_view section = env->GetStringUTFChars(j_section, 0); 382 std::string_view section = env->GetStringUTFChars(j_section, 0);
377 std::string_view key = env->GetStringUTFChars(j_key, 0); 383 std::string_view key = env->GetStringUTFChars(j_key, 0);
@@ -384,9 +390,9 @@ jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_GetUserSetting([[maybe_unused]] JN
384} 390}
385 391
386void Java_org_yuzu_yuzu_1emu_NativeLibrary_SetUserSetting([[maybe_unused]] JNIEnv* env, 392void Java_org_yuzu_yuzu_1emu_NativeLibrary_SetUserSetting([[maybe_unused]] JNIEnv* env,
387 [[maybe_unused]] jclass clazz, 393 [[maybe_unused]] jclass clazz,
388 jstring j_game_id, jstring j_section, 394 jstring j_game_id, jstring j_section,
389 jstring j_key, jstring j_value) { 395 jstring j_key, jstring j_value) {
390 std::string_view game_id = env->GetStringUTFChars(j_game_id, 0); 396 std::string_view game_id = env->GetStringUTFChars(j_game_id, 0);
391 std::string_view section = env->GetStringUTFChars(j_section, 0); 397 std::string_view section = env->GetStringUTFChars(j_section, 0);
392 std::string_view key = env->GetStringUTFChars(j_key, 0); 398 std::string_view key = env->GetStringUTFChars(j_key, 0);
@@ -399,15 +405,15 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_SetUserSetting([[maybe_unused]] JNIEn
399} 405}
400 406
401void Java_org_yuzu_yuzu_1emu_NativeLibrary_InitGameIni([[maybe_unused]] JNIEnv* env, 407void Java_org_yuzu_yuzu_1emu_NativeLibrary_InitGameIni([[maybe_unused]] JNIEnv* env,
402 [[maybe_unused]] jclass clazz, 408 [[maybe_unused]] jclass clazz,
403 jstring j_game_id) { 409 jstring j_game_id) {
404 std::string_view game_id = env->GetStringUTFChars(j_game_id, 0); 410 std::string_view game_id = env->GetStringUTFChars(j_game_id, 0);
405 411
406 env->ReleaseStringUTFChars(j_game_id, game_id.data()); 412 env->ReleaseStringUTFChars(j_game_id, game_id.data());
407} 413}
408 414
409jdoubleArray Java_org_yuzu_yuzu_1emu_NativeLibrary_GetPerfStats([[maybe_unused]] JNIEnv* env, 415jdoubleArray Java_org_yuzu_yuzu_1emu_NativeLibrary_GetPerfStats([[maybe_unused]] JNIEnv* env,
410 [[maybe_unused]] jclass clazz) { 416 [[maybe_unused]] jclass clazz) {
411 jdoubleArray j_stats = env->NewDoubleArray(4); 417 jdoubleArray j_stats = env->NewDoubleArray(4);
412 418
413 if (EmulationSession::GetInstance().IsRunning()) { 419 if (EmulationSession::GetInstance().IsRunning()) {
@@ -427,8 +433,8 @@ void Java_org_yuzu_yuzu_1emu_utils_DirectoryInitialization_SetSysDirectory(
427 [[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jstring j_path) {} 433 [[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jstring j_path) {}
428 434
429void Java_org_yuzu_yuzu_1emu_NativeLibrary_Run__Ljava_lang_String_2([[maybe_unused]] JNIEnv* env, 435void Java_org_yuzu_yuzu_1emu_NativeLibrary_Run__Ljava_lang_String_2([[maybe_unused]] JNIEnv* env,
430 [[maybe_unused]] jclass clazz, 436 [[maybe_unused]] jclass clazz,
431 jstring j_path) { 437 jstring j_path) {
432 const std::string path = GetJString(env, j_path); 438 const std::string path = GetJString(env, j_path);
433 439
434 const Core::SystemResultStatus result{RunEmulation(path)}; 440 const Core::SystemResultStatus result{RunEmulation(path)};
@@ -439,7 +445,7 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_Run__Ljava_lang_String_2([[maybe_unus
439} 445}
440 446
441void Java_org_yuzu_yuzu_1emu_NativeLibrary_LogDeviceInfo([[maybe_unused]] JNIEnv* env, 447void Java_org_yuzu_yuzu_1emu_NativeLibrary_LogDeviceInfo([[maybe_unused]] JNIEnv* env,
442 [[maybe_unused]] jclass clazz) { 448 [[maybe_unused]] jclass clazz) {
443 LOG_INFO(Frontend, "yuzu Version: {}-{}", Common::g_scm_branch, Common::g_scm_desc); 449 LOG_INFO(Frontend, "yuzu Version: {}-{}", Common::g_scm_branch, Common::g_scm_desc);
444 LOG_INFO(Frontend, "Host OS: Android API level {}", android_get_device_api_level()); 450 LOG_INFO(Frontend, "Host OS: Android API level {}", android_get_device_api_level());
445} 451}