[retro-gtk] retro-main-loop: Merge into RetroCore
- From: Adrien Plazas <aplazas src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [retro-gtk] retro-main-loop: Merge into RetroCore
- Date: Mon, 20 Jan 2020 10:18:44 +0000 (UTC)
commit 56d981adbb8e9a1ce115aff1af41e23b6dbdf523
Author: Alexander Mikhaylenko <alexm gnome org>
Date: Tue Jan 7 03:31:30 2020 +0500
retro-main-loop: Merge into RetroCore
There's no point in separating these 2 classes, as one core cannot have
two main loops anyway. Additionally, RetroMainLoop contains very little
amount of logic, and having just one object will simplify things later
with subprocess.
demos/retro-demo.c | 7 +-
retro-gtk/meson.build | 2 -
retro-gtk/retro-core-private.h | 2 +
retro-gtk/retro-core.c | 137 ++++++++++++++++
retro-gtk/retro-core.h | 5 +
retro-gtk/retro-gtk.h | 1 -
retro-gtk/retro-main-loop.c | 351 -----------------------------------------
retro-gtk/retro-main-loop.h | 28 ----
8 files changed, 145 insertions(+), 388 deletions(-)
---
diff --git a/demos/retro-demo.c b/demos/retro-demo.c
index 16372cd..abf5774 100644
--- a/demos/retro-demo.c
+++ b/demos/retro-demo.c
@@ -11,7 +11,6 @@ struct _RetroDemoApplication
GtkApplication parent_instance;
RetroCore *core;
- RetroMainLoop *loop;
};
G_DEFINE_TYPE (RetroDemoApplication, retro_demo_application, GTK_TYPE_APPLICATION)
@@ -79,9 +78,6 @@ retro_demo_application_finalize (GObject *object)
if (self->core != NULL)
g_object_unref (self->core);
- if (self->loop != NULL)
- g_object_unref (self->loop);
-
G_OBJECT_CLASS (retro_demo_application_parent_class)->finalize (object);
}
@@ -110,8 +106,7 @@ retro_demo_activate (GApplication *application)
gtk_application_add_window (GTK_APPLICATION (application),
GTK_WINDOW (window));
- self->loop = retro_main_loop_new (self->core);
- retro_main_loop_start (self->loop);
+ retro_core_start (self->core);
}
static void
diff --git a/retro-gtk/meson.build b/retro-gtk/meson.build
index d4321b7..28229f8 100644
--- a/retro-gtk/meson.build
+++ b/retro-gtk/meson.build
@@ -25,7 +25,6 @@ retro_gtk_sources = [
'retro-keyboard.c',
'retro-key-joypad-mapping.c',
'retro-log.c',
- 'retro-main-loop.c',
'retro-memory-type.c',
'retro-module.c',
'retro-module-iterator.c',
@@ -54,7 +53,6 @@ retro_gtk_headers = [
'retro-input.h',
'retro-key-joypad-mapping.h',
'retro-log.h',
- 'retro-main-loop.h',
'retro-memory-type.h',
'retro-module-iterator.h',
'retro-module-query.h',
diff --git a/retro-gtk/retro-core-private.h b/retro-gtk/retro-core-private.h
index 8e92eed..8f357c5 100644
--- a/retro-gtk/retro-core-private.h
+++ b/retro-gtk/retro-core-private.h
@@ -55,6 +55,8 @@ struct _RetroCore
gboolean variable_updated;
guint runahead;
gssize run_remaining;
+ gdouble speed_rate;
+ glong main_loop;
gint16 *audio_samples;
gulong audio_samples_length;
};
diff --git a/retro-gtk/retro-core.c b/retro-gtk/retro-core.c
index e1ece22..49081b1 100644
--- a/retro-gtk/retro-core.c
+++ b/retro-gtk/retro-core.c
@@ -37,6 +37,7 @@ enum {
PROP_SUPPORT_NO_GAME,
PROP_FRAMES_PER_SECOND,
PROP_RUNAHEAD,
+ PROP_SPEED_RATE,
N_PROPS,
};
@@ -159,6 +160,8 @@ retro_core_finalize (GObject *object)
g_return_if_fail (RETRO_IS_CORE (self));
+ retro_core_stop (self);
+
retro_core_push_cb_data (self);
if (retro_core_get_game_loaded (self)) {
unload_game = retro_module_get_unload_game (self->module);
@@ -226,6 +229,10 @@ retro_core_get_property (GObject *object,
case PROP_RUNAHEAD:
g_value_set_uint (value, retro_core_get_runahead (self));
+ break;
+ case PROP_SPEED_RATE:
+ g_value_set_double (value, retro_core_get_speed_rate (self));
+
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -262,6 +269,10 @@ retro_core_set_property (GObject *object,
case PROP_RUNAHEAD:
retro_core_set_runahead (self, g_value_get_uint (value));
+ break;
+ case PROP_SPEED_RATE:
+ retro_core_set_speed_rate (self, g_value_get_double (value));
+
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -438,6 +449,21 @@ retro_core_class_init (RetroCoreClass *klass)
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB);
+ /**
+ * RetroCore:speed-rate:
+ *
+ * The speed ratio at wich the core will run.
+ */
+ properties[PROP_SPEED_RATE] =
+ g_param_spec_double ("speed-rate",
+ "Speed rate",
+ "The speed ratio at wich the core will run",
+ -G_MAXDOUBLE, G_MAXDOUBLE, 1.0,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_NAME |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB);
+
g_object_class_install_properties (G_OBJECT_CLASS (klass), N_PROPS, properties);
/**
@@ -544,6 +570,9 @@ retro_core_init (RetroCore *self)
self->controllers = g_hash_table_new_full (g_int_hash, g_int_equal,
g_free, g_object_unref);
+
+ self->main_loop = -1;
+ self->speed_rate = 1;
}
static void
@@ -618,6 +647,16 @@ retro_core_get_needs_full_path (RetroCore *self)
return system_info.need_fullpath;
}
+static void
+restart (RetroCore *self)
+{
+ if (self->main_loop < 0)
+ return;
+
+ retro_core_stop (self);
+ retro_core_start (self);
+}
+
void
retro_core_set_system_av_info (RetroCore *self,
RetroSystemAvInfo *system_av_info)
@@ -625,6 +664,7 @@ retro_core_set_system_av_info (RetroCore *self,
if (self->frames_per_second != system_av_info->timing.fps) {
self->frames_per_second = system_av_info->timing.fps;
g_object_notify (G_OBJECT (self), "frames-per-second");
+ restart (self);
}
retro_core_set_geometry (self, &system_av_info->geometry);
self->sample_rate = system_av_info->timing.sample_rate;
@@ -1501,6 +1541,65 @@ retro_core_set_controller_port_device (RetroCore *self,
retro_core_pop_cb_data ();
}
+static gboolean
+run_main_loop (RetroCore *self)
+{
+ if (self->main_loop < 0)
+ return FALSE;
+
+ retro_core_run (self);
+
+ return TRUE;
+}
+
+/**
+ * retro_core_start:
+ * @self: a #RetroCore
+ *
+ * Starts running the core. If the core was stopped, it will restart from this
+ * moment.
+ */
+void
+retro_core_start (RetroCore *self)
+{
+ gdouble fps;
+
+ g_return_if_fail (RETRO_IS_CORE (self));
+
+ if (self->main_loop >= 0 || self->speed_rate <= 0)
+ return;
+
+ // TODO What if fps <= 0?
+ fps = retro_core_get_frames_per_second (self);
+ /* Do not make the timeout source hold a reference on the RetroCore, so
+ * destroying the RetroCore while it is still running will stop it instead
+ * of leaking a reference.
+ */
+ self->main_loop =
+ g_timeout_add_full (G_PRIORITY_DEFAULT_IDLE,
+ (guint) (1000 / (fps * self->speed_rate)),
+ (GSourceFunc) run_main_loop,
+ self, NULL);
+}
+
+/**
+ * retro_core_stop:
+ * @self: a #RetroCore
+ *
+ * Stops running the core.
+ */
+void
+retro_core_stop (RetroCore *self)
+{
+ g_return_if_fail (RETRO_IS_CORE (self));
+
+ if (self->main_loop < 0)
+ return;
+
+ g_source_remove (self->main_loop);
+ self->main_loop = -1;
+}
+
/**
* retro_core_reset:
* @self: a #RetroCore
@@ -2159,6 +2258,44 @@ retro_core_is_running_ahead (RetroCore *self)
return self->run_remaining > 0;
}
+/**
+ * retro_core_get_speed_rate:
+ * @self: a #RetroCore
+ *
+ * Gets the speed rate at which to run the core.
+ *
+ * Returns: the speed rate
+ */
+gdouble
+retro_core_get_speed_rate (RetroCore *self)
+{
+ g_return_val_if_fail (RETRO_IS_CORE (self), 1.0);
+
+ return self->speed_rate;
+}
+
+/**
+ * retro_core_set_speed_rate:
+ * @self: a #RetroCore
+ * @speed_rate: a speed rate
+ *
+ * Sets the speed rate at which to run the core.
+ */
+void
+retro_core_set_speed_rate (RetroCore *self,
+ gdouble speed_rate)
+{
+ g_return_if_fail (RETRO_IS_CORE (self));
+
+ if (self->speed_rate == speed_rate)
+ return;
+
+ self->speed_rate = speed_rate;
+ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SPEED_RATE]);
+
+ restart (self);
+}
+
/**
* retro_core_has_option:
* @self: a #RetroCore
diff --git a/retro-gtk/retro-core.h b/retro-gtk/retro-core.h
index a00b719..460d86f 100644
--- a/retro-gtk/retro-core.h
+++ b/retro-gtk/retro-core.h
@@ -40,6 +40,8 @@ void retro_core_set_medias (RetroCore *self,
void retro_core_set_current_media (RetroCore *self,
guint media_index,
GError **error);
+void retro_core_start (RetroCore *self);
+void retro_core_stop (RetroCore *self);
void retro_core_reset (RetroCore *self);
void retro_core_run (RetroCore *self);
gboolean retro_core_get_can_access_state (RetroCore *self);
@@ -71,6 +73,9 @@ RetroControllerIterator *retro_core_iterate_controllers (RetroCore *self);
guint retro_core_get_runahead (RetroCore *self);
void retro_core_set_runahead (RetroCore *self,
guint runahead);
+gdouble retro_core_get_speed_rate (RetroCore *self);
+void retro_core_set_speed_rate (RetroCore *self,
+ gdouble speed_rate);
gboolean retro_core_has_option (RetroCore *self,
const gchar *key);
RetroOption *retro_core_get_option (RetroCore *self,
diff --git a/retro-gtk/retro-gtk.h b/retro-gtk/retro-gtk.h
index 94ae6d2..e5ef793 100644
--- a/retro-gtk/retro-gtk.h
+++ b/retro-gtk/retro-gtk.h
@@ -19,7 +19,6 @@
#include "retro-input.h"
#include "retro-key-joypad-mapping.h"
#include "retro-log.h"
-#include "retro-main-loop.h"
#include "retro-memory-type.h"
#include "retro-module-iterator.h"
#include "retro-module-query.h"
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]