diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java index d8b1b6c112..c9efb0c790 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java @@ -274,6 +274,12 @@ public final class NativeLibrary }); } + public static void endEmulationActivity() + { + Log.v("DolphinEmu", "Ending EmulationActivity."); + mEmulationActivity.finish(); + } + public static void setEmulationActivity(EmulationActivity emulationActivity) { Log.v("DolphinEmu", "Registering EmulationActivity."); diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java index cb6b17c3d5..b569785d35 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java @@ -150,7 +150,11 @@ public final class EmulationActivity extends AppCompatActivity else { // Let the system handle it; i.e. quit the activity TODO or show "are you sure?" dialog. - super.onBackPressed(); + EmulationFragment fragment = (EmulationFragment) getFragmentManager() + .findFragmentByTag(EmulationFragment.FRAGMENT_TAG); + fragment.notifyEmulationStopped(); + + NativeLibrary.StopEmulation(); } } diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/MainActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/MainActivity.java index 7812e6ead5..09ec145ebf 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/MainActivity.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/MainActivity.java @@ -127,6 +127,13 @@ public final class MainActivity extends AppCompatActivity implements LoaderManag } } + @Override + protected void onResume() + { + super.onResume(); + mAdapter.notifyDataSetChanged(); + } + @Override public boolean onCreateOptionsMenu(Menu menu) { diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java index 70dff7237e..9d23736cb6 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java @@ -119,7 +119,7 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C public void onDestroyView() { super.onDestroyView(); - if (getActivity().isFinishing()) + if (getActivity().isFinishing() && mEmulationStarted) { NativeLibrary.StopEmulation(); } @@ -195,6 +195,16 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C mEmulationRunning = false; } + /** + * Called by containing activity to tell the Fragment emulation is already stopping, + * so it doesn't try to stop emulation on its way to the garbage collector. + */ + public void notifyEmulationStopped() + { + mEmulationStarted = false; + mEmulationRunning = false; + } + private Runnable mEmulationRunner = new Runnable() { @Override diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/Game.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/Game.java index ae52261b45..f3ef6f7514 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/Game.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/Game.java @@ -113,21 +113,7 @@ public final class Game { ContentValues values = new ContentValues(); - // TODO Come up with a way of finding the most recent screenshot that doesn't involve counting files - String screenshotFolderPath = PATH_SCREENSHOT_FOLDER + gameId + "/"; - - // Count how many screenshots are available, so we can use the most recent one. - File screenshotFolder = new File(screenshotFolderPath.substring(screenshotFolderPath.indexOf('s') - 1)); - int screenCount = 0; - - if (screenshotFolder.isDirectory()) - { - screenCount = screenshotFolder.list().length; - } - - String screenPath = screenshotFolderPath - + gameId + "-" - + screenCount + ".png"; + String screenPath = PATH_SCREENSHOT_FOLDER + gameId + "/thumb.png"; values.put(GameDatabase.KEY_GAME_PLATFORM, platform); values.put(GameDatabase.KEY_GAME_TITLE, title); diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp index 0de8605719..ff69f3d591 100644 --- a/Source/Core/Core/Core.cpp +++ b/Source/Core/Core/Core.cpp @@ -671,6 +671,22 @@ void SaveScreenShot() SetState(CORE_RUN); } +void SaveScreenShot(std::string name) +{ + const bool bPaused = (GetState() == CORE_PAUSE); + + SetState(CORE_PAUSE); + + const std::string& gameId = SConfig::GetInstance().GetUniqueID(); + std::string path = File::GetUserPath(D_SCREENSHOTS_IDX) + gameId + DIR_SEP_CHR; + + name = StringFromFormat("%s%s.png", path.c_str(), name.c_str()); + g_video_backend->Video_Screenshot(name); + + if (!bPaused) + SetState(CORE_RUN); +} + void RequestRefreshInfo() { s_request_refresh_info = true; diff --git a/Source/Core/Core/Core.h b/Source/Core/Core/Core.h index 1eea2be226..dafa35d5f3 100644 --- a/Source/Core/Core/Core.h +++ b/Source/Core/Core/Core.h @@ -52,6 +52,7 @@ void SetState(EState _State); EState GetState(); void SaveScreenShot(); +void SaveScreenShot(std::string name); void Callback_WiimoteInterruptChannel(int _number, u16 _channelID, const void* _pData, u32 _Size); diff --git a/Source/Core/DolphinWX/MainAndroid.cpp b/Source/Core/DolphinWX/MainAndroid.cpp index cca694c251..3788f42928 100644 --- a/Source/Core/DolphinWX/MainAndroid.cpp +++ b/Source/Core/DolphinWX/MainAndroid.cpp @@ -31,6 +31,7 @@ #include "UICommon/UICommon.h" #include "VideoCommon/OnScreenDisplay.h" +#include "VideoCommon/RenderBase.h" #include "VideoCommon/VideoBackendBase.h" ANativeWindow* surf; @@ -40,6 +41,7 @@ std::string g_set_userpath = ""; JavaVM* g_java_vm; jclass g_jni_class; jmethodID g_jni_method_alert; +jmethodID g_jni_method_end; #define DOLPHIN_TAG "DolphinEmuNative" @@ -394,6 +396,8 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_PauseEmulati JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_StopEmulation(JNIEnv *env, jobject obj) { + Core::SaveScreenShot("thumb"); + Renderer::s_screenshotCompleted.Wait(); Core::Stop(); updateMainFrameEvent.Set(); // Kick the waiting event } @@ -591,6 +595,7 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_CacheClasses // Method signature taken from javap -s Source/Android/app/build/intermediates/classes/arm/debug/org/dolphinemu/dolphinemu/NativeLibrary.class g_jni_method_alert = env->GetStaticMethodID(g_jni_class, "displayAlertMsg", "(Ljava/lang/String;)V"); + g_jni_method_end = env->GetStaticMethodID(g_jni_class, "endEmulationActivity", "()V"); } JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_Run(JNIEnv *env, jobject obj, jobject _surf) @@ -624,6 +629,9 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_Run(JNIEnv * UICommon::Shutdown(); ANativeWindow_release(surf); + + // Execute the Java method. + env->CallStaticVoidMethod(g_jni_class, g_jni_method_end); } diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp index 6efdd7fd40..2b2a88da33 100644 --- a/Source/Core/VideoBackends/OGL/Render.cpp +++ b/Source/Core/VideoBackends/OGL/Render.cpp @@ -1510,6 +1510,7 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co // Reset settings s_sScreenshotName.clear(); s_bScreenshot = false; + s_screenshotCompleted.Set(); } // Frame dumps are handled a little differently in Windows diff --git a/Source/Core/VideoCommon/RenderBase.cpp b/Source/Core/VideoCommon/RenderBase.cpp index d8222888f7..a688c86792 100644 --- a/Source/Core/VideoCommon/RenderBase.cpp +++ b/Source/Core/VideoCommon/RenderBase.cpp @@ -17,6 +17,7 @@ #include #include "Common/Atomic.h" +#include "Common/Event.h" #include "Common/Profiler.h" #include "Common/StringUtil.h" #include "Common/Timer.h" @@ -53,6 +54,8 @@ Renderer *g_renderer = nullptr; std::mutex Renderer::s_criticalScreenshot; std::string Renderer::s_sScreenshotName; +Common::Event Renderer::s_screenshotCompleted; + volatile bool Renderer::s_bScreenshot; // The framebuffer size diff --git a/Source/Core/VideoCommon/RenderBase.h b/Source/Core/VideoCommon/RenderBase.h index 8e3e830d3f..a17525ca2e 100644 --- a/Source/Core/VideoCommon/RenderBase.h +++ b/Source/Core/VideoCommon/RenderBase.h @@ -17,6 +17,7 @@ #include #include +#include "Common/Event.h" #include "Common/MathUtil.h" #include "Common/Thread.h" #include "VideoCommon/BPMemory.h" @@ -133,6 +134,8 @@ public: // Max height/width virtual int GetMaxTextureSize() = 0; + static Common::Event s_screenshotCompleted; + protected: static void CalculateTargetScale(int x, int y, int* scaledX, int* scaledY);