[Android] Add support for rotation and minimizing the application

This commit is contained in:
Ryan Houdek 2016-01-10 12:31:49 -06:00
parent 6448e5e5ee
commit 5a549ef663
7 changed files with 78 additions and 29 deletions

View File

@ -333,10 +333,12 @@ public final class NativeLibrary
/**
* Begins emulation.
*
* @param surf The surface to render to.
*/
public static native void Run(Surface surf);
public static native void Run();
// Surface Handling
public static native void SurfaceChanged(Surface surf);
public static native void SurfaceDestroyed();
/** Unpauses emulation from a paused state. */
public static native void UnPauseEmulation();

View File

@ -177,13 +177,16 @@ public final class EmulationActivity extends AppCompatActivity
}
});
// Instantiate an EmulationFragment.
EmulationFragment emulationFragment = EmulationFragment.newInstance(path);
if (savedInstanceState == null)
{
// Instantiate an EmulationFragment.
EmulationFragment emulationFragment = EmulationFragment.newInstance(path);
// Add fragment to the activity - this triggers all its lifecycle callbacks.
getFragmentManager().beginTransaction()
.add(R.id.frame_emulation_fragment, emulationFragment, EmulationFragment.FRAGMENT_TAG)
.commit();
// Add fragment to the activity - this triggers all its lifecycle callbacks.
getFragmentManager().beginTransaction()
.add(R.id.frame_emulation_fragment, emulationFragment, EmulationFragment.FRAGMENT_TAG)
.commit();
}
if (mDeviceHasTouchScreen)
{

View File

@ -115,7 +115,6 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C
public void onStop()
{
super.onStop();
pauseEmulation();
}
@Override
@ -160,12 +159,14 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C
{
Log.d("DolphinEmu", "Surface changed. Resolution: " + width + "x" + height);
mSurface = holder.getSurface();
NativeLibrary.SurfaceChanged(mSurface);
}
@Override
public void surfaceDestroyed(SurfaceHolder holder)
{
Log.d("DolphinEmu", "Surface destroyed.");
NativeLibrary.SurfaceDestroyed();
if (mEmulationRunning)
{
@ -216,20 +217,14 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C
mEmulationRunning = true;
mEmulationStarted = true;
// Loop until onSurfaceCreated succeeds
while (mSurface == null)
{
if (!mEmulationRunning)
{
// So that if the user quits before this gets a surface, we don't loop infinitely.
return;
}
}
Log.i("DolphinEmu", "Starting emulation: " + mSurface);
// Start emulation using the provided Surface.
NativeLibrary.Run(mSurface);
NativeLibrary.Run();
}
};
}

View File

@ -18,6 +18,7 @@
#include "Common/CPUDetect.h"
#include "Common/Event.h"
#include "Common/FileUtil.h"
#include "Common/GL/GLInterfaceBase.h"
#include "Common/Logging/LogManager.h"
#include "Core/BootManager.h"
@ -380,8 +381,9 @@ JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetUserDi
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_CacheClassesAndMethods(JNIEnv *env, jobject obj);
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_Run(JNIEnv *env, jobject obj, jobject _surf);
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_Run(JNIEnv *env, jobject obj);
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)
{
@ -596,18 +598,45 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_CacheClasses
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)
// Surface Handling
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SurfaceChanged(JNIEnv *env, jobject obj, jobject _surf)
{
surf = ANativeWindow_fromSurface(env, _surf);
if (surf == nullptr)
__android_log_print(ANDROID_LOG_ERROR, DOLPHIN_TAG, "Error: Surface is null.");
// If GLInterface isn't a thing yet then we don't need to let it know that the surface has changed
if (GLInterface)
{
GLInterface->UpdateHandle(surf);
Renderer::s_ChangedSurface.Reset();
Renderer::s_SurfaceNeedsChanged.Set();
Renderer::s_ChangedSurface.Wait();
}
}
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SurfaceDestroyed(JNIEnv *env, jobject obj)
{
if (surf)
{
ANativeWindow_release(surf);
surf = nullptr;
}
// If GLInterface isn't a thing yet then we don't need to let it know that the surface has changed
if (GLInterface)
{
GLInterface->UpdateHandle(nullptr);
Renderer::s_ChangedSurface.Reset();
Renderer::s_SurfaceNeedsChanged.Set();
Renderer::s_ChangedSurface.Wait();
}
}
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_Run(JNIEnv *env, jobject obj)
{
__android_log_print(ANDROID_LOG_INFO, DOLPHIN_TAG, "Running : %s", g_filename.c_str());
surf = ANativeWindow_fromSurface(env, _surf);
if (surf == nullptr)
{
__android_log_print(ANDROID_LOG_ERROR, DOLPHIN_TAG, "Error: Surface is null.");
return;
}
// Install our callbacks
OSD::AddCallback(OSD::CallbackType::Initialization, ButtonManager::Init);
OSD::AddCallback(OSD::CallbackType::Shutdown, ButtonManager::Shutdown);
@ -627,7 +656,12 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_Run(JNIEnv *
Core::Shutdown();
UICommon::Shutdown();
ANativeWindow_release(surf);
if (surf)
{
ANativeWindow_release(surf);
surf = nullptr;
}
// Execute the Java method.
env->CallStaticVoidMethod(g_jni_class, g_jni_method_end);

View File

@ -1467,6 +1467,13 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co
OSD::DoCallbacks(OSD::CallbackType::OnFrame);
OSD::DrawMessages();
if (s_SurfaceNeedsChanged.IsSet())
{
GLInterface->UpdateSurface();
s_SurfaceNeedsChanged.Clear();
s_ChangedSurface.Set();
}
// Copy the rendered frame to the real window
GLInterface->Swap();

View File

@ -58,6 +58,10 @@ Common::Event Renderer::s_screenshotCompleted;
volatile bool Renderer::s_bScreenshot;
// Final surface changing
Common::Flag Renderer::s_SurfaceNeedsChanged;
Common::Event Renderer::s_ChangedSurface;
// The framebuffer size
int Renderer::s_target_width;
int Renderer::s_target_height;

View File

@ -138,6 +138,10 @@ public:
static Common::Event s_screenshotCompleted;
// Final surface changing
static Common::Flag s_SurfaceNeedsChanged;
static Common::Event s_ChangedSurface;
protected:
static void CalculateTargetScale(int x, int y, int* scaledX, int* scaledY);