[retro-gtk] retro-core: Run a frame when loading state the first time



commit 2e13a24a7335f9d8fbba46ef4e9801eef6552bfe
Author: Alexander Mikhaylenko <alexm gnome org>
Date:   Sat Feb 1 02:38:04 2020 +0500

    retro-core: Run a frame when loading state the first time
    
    Some cores, such as MAME and ParaLLEl N64, can only properly restore the
    state after at least one frame has been run, so do it automatically.

 retro-runner/ipc-runner-impl.c    |  8 +++-----
 retro-runner/retro-core-private.h |  3 +++
 retro-runner/retro-core.c         | 16 ++++++++++++++++
 retro-runner/retro-environment.c  |  3 ++-
 4 files changed, 24 insertions(+), 6 deletions(-)
---
diff --git a/retro-runner/ipc-runner-impl.c b/retro-runner/ipc-runner-impl.c
index 005f81b..9ff413b 100644
--- a/retro-runner/ipc-runner-impl.c
+++ b/retro-runner/ipc-runner-impl.c
@@ -21,7 +21,6 @@ struct _IpcRunnerImpl
 #endif
 
   GVariant *variables;
-  gboolean block_video_signal;
 };
 
 static void ipc_runner_iface_init (IpcRunnerIface *iface);
@@ -212,9 +211,9 @@ ipc_runner_impl_handle_iteration (IpcRunner             *runner,
   /* For this call UI process will do the video handling itself
    * to ensure it's synchronous, no signal emission needed.
    * See retro_core_iteration() in retro-core/retro-core.c */
-  self->block_video_signal = TRUE;
+  self->core->block_video_signal = TRUE;
   retro_core_iteration (self->core);
-  self->block_video_signal = FALSE;
+  self->core->block_video_signal = FALSE;
 
   ipc_runner_complete_iteration (runner, invocation);
 
@@ -522,8 +521,7 @@ static void
 video_output_cb (RetroCore     *core,
                  IpcRunnerImpl *self)
 {
-  if (!self->block_video_signal)
-    ipc_runner_emit_video_output (IPC_RUNNER (self));
+  ipc_runner_emit_video_output (IPC_RUNNER (self));
 }
 
 static void
diff --git a/retro-runner/retro-core-private.h b/retro-runner/retro-core-private.h
index 8838bb6..435010b 100644
--- a/retro-runner/retro-core-private.h
+++ b/retro-runner/retro-core-private.h
@@ -57,6 +57,9 @@ struct _RetroCore
   gssize run_remaining;
   gdouble speed_rate;
   glong main_loop;
+
+  gboolean has_run;
+  gboolean block_video_signal;
 };
 
 RetroCore *retro_core_get_instance (void);
diff --git a/retro-runner/retro-core.c b/retro-runner/retro-core.c
index f695e88..18891e4 100644
--- a/retro-runner/retro-core.c
+++ b/retro-runner/retro-core.c
@@ -1599,6 +1599,8 @@ retro_core_iteration (RetroCore *self)
 
   g_return_if_fail (RETRO_IS_CORE (self));
 
+  self->has_run = TRUE;
+
   iterated = self;
   run = retro_module_get_run (self->module);
 
@@ -1810,6 +1812,20 @@ retro_core_load_state (RetroCore    *self,
                 expected_size,
                 data_size);
 
+  /* Some cores, such as MAME and ParaLLEl N64, can only properly restore the
+   * state after at least one frame has been run. */
+  if (!self->has_run) {
+    RetroRun run = retro_module_get_run (self->module);
+
+    /* Ignore the video output here to avoid briefly showing the previous state
+     * in case user is showing a screenshot of the state to restore here. */
+    self->block_video_signal = TRUE;
+    run ();
+    self->block_video_signal = FALSE;
+
+    self->has_run = TRUE;
+  }
+
   unserialize = retro_module_get_unserialize (self->module);
   success = unserialize ((guint8 *) data, data_size);
 
diff --git a/retro-runner/retro-environment.c b/retro-runner/retro-environment.c
index 60a61d6..8ae8844 100644
--- a/retro-runner/retro-environment.c
+++ b/retro-runner/retro-environment.c
@@ -540,7 +540,8 @@ on_video_refresh (guint8 *data,
                               width, height, self->aspect_ratio, data);
   retro_framebuffer_unlock (self->framebuffer);
 
-  g_signal_emit_by_name (self, "video-output");
+  if (!self->block_video_signal)
+    g_signal_emit_by_name (self, "video-output");
 }
 
 // TODO This is internal, make it private as soon as possible.


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]