android: threading fix. stop vibrator thread. allow screen saver
If the android activity is destroyed and the game unloaded, the gui's game state wasn't updated, leading to a crash if resuming. Same for the android game state if pausing, destroying then resuming. tentative fix for MINIDUMP-27, MINIDUMP-25, MINIDUMP-23 Wait until emu is stopped in single-threaded. Stop vibrator thread when view is detached Allow the screen saver when a game isn't running.
This commit is contained in:
parent
5fa98da17e
commit
673fb26d6e
|
@ -88,8 +88,11 @@ static void emuEventCallback(Event event, void *)
|
|||
game_started = true;
|
||||
break;
|
||||
case Event::Start:
|
||||
GamepadDevice::load_system_mappings();
|
||||
break;
|
||||
case Event::Terminate:
|
||||
GamepadDevice::load_system_mappings();
|
||||
game_started = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -490,7 +493,6 @@ void gui_stop_game(const std::string& message)
|
|||
// Exit to main menu
|
||||
emu.unloadGame();
|
||||
gui_state = GuiState::Main;
|
||||
game_started = false;
|
||||
reset_vmus();
|
||||
if (!message.empty())
|
||||
gui_error("Flycast has stopped.\n\n" + message);
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||
|
||||
|
|
|
@ -79,7 +79,6 @@ public abstract class BaseGLActivity extends Activity implements ActivityCompat.
|
|||
getWindow().getAttributes().layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
|
||||
}
|
||||
|
||||
|
||||
if (!getFilesDir().exists()) {
|
||||
getFilesDir().mkdir();
|
||||
}
|
||||
|
@ -406,5 +405,17 @@ public abstract class BaseGLActivity extends Activity implements ActivityCompat.
|
|||
}
|
||||
}
|
||||
|
||||
// Called from native code
|
||||
public void onGameStateChange(boolean started) {
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
if (started)
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
else
|
||||
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static native void register(BaseGLActivity activity);
|
||||
}
|
||||
|
|
|
@ -35,7 +35,6 @@ public class NativeGLView extends SurfaceView implements SurfaceHolder.Callback
|
|||
public NativeGLView(final Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
getHolder().addCallback(this);
|
||||
setKeepScreenOn(true);
|
||||
setFocusable(true);
|
||||
setFocusableInTouchMode(true);
|
||||
requestFocus();
|
||||
|
@ -53,13 +52,24 @@ public class NativeGLView extends SurfaceView implements SurfaceHolder.Callback
|
|||
}
|
||||
});
|
||||
}
|
||||
vjoyDelegate = new VirtualJoystickDelegate(this);
|
||||
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
|
||||
this.setLayerType(LAYER_TYPE_HARDWARE, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
vjoyDelegate = new VirtualJoystickDelegate(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
vjoyDelegate.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom)
|
||||
{
|
||||
|
|
|
@ -46,6 +46,14 @@ public class VirtualJoystickDelegate {
|
|||
scaleGestureDetector = new ScaleGestureDetector(context, new OscOnScaleGestureListener());
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
vibratorThread.stopVibrator();
|
||||
try {
|
||||
vibratorThread.join();
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
|
||||
public void readCustomVjoyValues() {
|
||||
vjoy_d_custom = VJoy.readCustomVjoyValues(context);
|
||||
}
|
||||
|
@ -58,7 +66,6 @@ public class VirtualJoystickDelegate {
|
|||
view.requestLayout();
|
||||
}
|
||||
|
||||
|
||||
private void reset_analog()
|
||||
{
|
||||
|
||||
|
|
|
@ -102,15 +102,29 @@ jobject g_emulator;
|
|||
jmethodID saveAndroidSettingsMid;
|
||||
static ANativeWindow *g_window = 0;
|
||||
|
||||
// Activity
|
||||
static jobject g_activity;
|
||||
static jmethodID VJoyStartEditingMID;
|
||||
static jmethodID VJoyStopEditingMID;
|
||||
static jmethodID VJoyResetEditingMID;
|
||||
static jmethodID showTextInputMid;
|
||||
static jmethodID hideTextInputMid;
|
||||
static jmethodID isScreenKeyboardShownMid;
|
||||
static jmethodID onGameStateChangeMid;
|
||||
|
||||
static void emuEventCallback(Event event, void *)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case Event::Pause:
|
||||
game_started = false;
|
||||
if (g_activity != nullptr)
|
||||
jvm_attacher.getEnv()->CallVoidMethod(g_activity, onGameStateChangeMid, false);
|
||||
break;
|
||||
case Event::Resume:
|
||||
game_started = true;
|
||||
if (g_activity != nullptr)
|
||||
jvm_attacher.getEnv()->CallVoidMethod(g_activity, onGameStateChangeMid, true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -302,15 +316,6 @@ jmethodID audioInitMid;
|
|||
jmethodID audioTermMid;
|
||||
static jobject g_audioBackend;
|
||||
|
||||
// Activity
|
||||
static jobject g_activity;
|
||||
static jmethodID VJoyStartEditingMID;
|
||||
static jmethodID VJoyStopEditingMID;
|
||||
static jmethodID VJoyResetEditingMID;
|
||||
static jmethodID showTextInputMid;
|
||||
static jmethodID hideTextInputMid;
|
||||
static jmethodID isScreenKeyboardShownMid;
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_setupMic(JNIEnv *env,jobject obj,jobject sip)
|
||||
{
|
||||
sipemu = env->NewGlobalRef(sip);
|
||||
|
@ -319,11 +324,22 @@ extern "C" JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_setupMic(J
|
|||
stopRecordingMid = env->GetMethodID(env->GetObjectClass(sipemu),"stopRecording","()V");
|
||||
}
|
||||
|
||||
static void stopEmu()
|
||||
{
|
||||
if (!emu.running())
|
||||
game_started = false;
|
||||
else
|
||||
emu.stop();
|
||||
// in single-threaded mode, stopping is delayed
|
||||
while (game_started)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_pause(JNIEnv *env,jobject obj)
|
||||
{
|
||||
if (game_started)
|
||||
if (emu.running())
|
||||
{
|
||||
emu.stop();
|
||||
stopEmu();
|
||||
game_started = true; // restart when resumed
|
||||
if (config::AutoSaveState)
|
||||
dc_savestate(config::SavestateSlot);
|
||||
|
@ -339,14 +355,10 @@ extern "C" JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_resume(JNI
|
|||
|
||||
extern "C" JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_stop(JNIEnv *env,jobject obj)
|
||||
{
|
||||
if (emu.running()) {
|
||||
emu.stop();
|
||||
if (config::AutoSaveState)
|
||||
dc_savestate(config::SavestateSlot);
|
||||
}
|
||||
stopEmu();
|
||||
emu.unloadGame();
|
||||
gui_state = GuiState::Main;
|
||||
settings.content.path.clear();
|
||||
game_started = false;
|
||||
}
|
||||
|
||||
static void *render_thread_func(void *)
|
||||
|
@ -652,6 +664,7 @@ extern "C" JNIEXPORT void JNICALL Java_com_reicast_emulator_BaseGLActivity_regis
|
|||
showTextInputMid = env->GetMethodID(env->GetObjectClass(activity), "showTextInput", "(IIII)V");
|
||||
hideTextInputMid = env->GetMethodID(env->GetObjectClass(activity), "hideTextInput", "()V");
|
||||
isScreenKeyboardShownMid = env->GetMethodID(env->GetObjectClass(activity), "isScreenKeyboardShown", "()Z");
|
||||
onGameStateChangeMid = env->GetMethodID(env->GetObjectClass(activity), "onGameStateChange", "(Z)V");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue