[retro-gtk/wip/aplazas/c-port: 20/25] Port Core to C



commit caa55dd3afe9375c74927d989f2862550d799495
Author: Adrien Plazas <kekun plazas laposte net>
Date:   Mon Sep 25 13:52:36 2017 +0200

    Port Core to C

 retro-gtk/Makefile.am           |    2 +-
 retro-gtk/core.vala             |  200 -------
 retro-gtk/retro-cairo-display.c |    2 +-
 retro-gtk/retro-cairo-display.h |    4 +-
 retro-gtk/retro-core-private.h  |   29 +-
 retro-gtk/retro-core-view.h     |    4 +-
 retro-gtk/retro-core.c          | 1220 +++++++++++++++++++++++++++++++--------
 retro-gtk/retro-core.h          |   88 +++
 retro-gtk/retro-environment.c   |   81 +--
 retro-gtk/retro-gtk.h           |    1 +
 retro-gtk/retro-log.c           |    2 +-
 retro-gtk/retro-log.h           |    4 +-
 retro-gtk/retro-main-loop.h     |    5 +-
 retro-gtk/retro-module.h        |    3 +-
 retro-gtk/retro-rumble-effect.h |    2 +-
 15 files changed, 1113 insertions(+), 534 deletions(-)
---
diff --git a/retro-gtk/Makefile.am b/retro-gtk/Makefile.am
index 063066f..4658523 100644
--- a/retro-gtk/Makefile.am
+++ b/retro-gtk/Makefile.am
@@ -34,6 +34,7 @@ retro_gtk_public_h_sources = \
        retro-analog-index.h \
        retro-controller-iterator.h \
        retro-core-descriptor.h \
+       retro-core.h \
        retro-core-view.h \
        retro-device-type.h \
        retro-gtk.h \
@@ -76,7 +77,6 @@ retro_gtk_private_h_sources = \
 libretro_gtk_la_SOURCES = \
        input/retro-keyboard-key.c \
        \
-       core.vala \
        retro.vala \
        retro-analog-id.c \
        retro-analog-index.c \
diff --git a/retro-gtk/retro-cairo-display.c b/retro-gtk/retro-cairo-display.c
index 3a14662..951e0f1 100644
--- a/retro-gtk/retro-cairo-display.c
+++ b/retro-gtk/retro-cairo-display.c
@@ -261,7 +261,7 @@ retro_cairo_display_init (RetroCairoDisplay *self)
 static void
 retro_cairo_display_on_video_output (RetroCore        *sender,
                                      guint8           *data,
-                                     int               data_length1,
+                                     gsize             length,
                                      guint             width,
                                      guint             height,
                                      gsize             pitch,
diff --git a/retro-gtk/retro-cairo-display.h b/retro-gtk/retro-cairo-display.h
index 1a54c28..efa03c2 100644
--- a/retro-gtk/retro-cairo-display.h
+++ b/retro-gtk/retro-cairo-display.h
@@ -8,13 +8,11 @@
 #endif
 
 #include <gtk/gtk.h>
+#include "retro-core.h"
 #include "retro-video-filter.h"
 
 G_BEGIN_DECLS
 
-// FIXME Remove as soon as possible.
-typedef struct _RetroCore RetroCore;
-
 #define RETRO_TYPE_CAIRO_DISPLAY (retro_cairo_display_get_type())
 
 G_DECLARE_FINAL_TYPE (RetroCairoDisplay, retro_cairo_display, RETRO, CAIRO_DISPLAY, GtkDrawingArea)
diff --git a/retro-gtk/retro-core-private.h b/retro-gtk/retro-core-private.h
index 31d260b..9fffbed 100644
--- a/retro-gtk/retro-core-private.h
+++ b/retro-gtk/retro-core-private.h
@@ -7,8 +7,10 @@
 # error "Only <retro-gtk.h> can be included directly."
 #endif
 
+#include "retro-core.h"
 #include "retro-disk-control-callback.h"
 #include "retro-gtk-internal.h"
+#include "retro-input-descriptor.h"
 #include "retro-module.h"
 #include "retro-options.h"
 #include "retro-pixel-format.h"
@@ -20,11 +22,19 @@ typedef struct {
   void (*callback) (guchar down, guint keycode, guint32 character, guint16 key_modifiers);
 } RetroKeyboardCallback;
 
-#define RETRO_CORE_ENVIRONMENT_INTERNAL(core) ((RetroCoreEnvironmentInternal *) 
((core)->environment_internal))
+struct _RetroCore
+{
+  GObject parent_instance;
+  gchar *filename;
+  gchar *system_directory;
+  gchar *libretro_path;
+  gchar *content_directory;
+  gchar *save_directory;
+  gboolean is_initiated;
+  gboolean game_loaded;
+  gboolean support_no_game;
+  gdouble frames_per_second;
 
-typedef struct _RetroCoreEnvironmentInternal RetroCoreEnvironmentInternal;
-
-struct _RetroCoreEnvironmentInternal {
   RetroModule *module;
   RetroDiskControlCallback *disk_control_callback;
   gchar **media_uris;
@@ -37,15 +47,26 @@ struct _RetroCoreEnvironmentInternal {
 
   RetroKeyboardCallback keyboard_callback;
   GHashTable *controllers;
+  GtkWidget *keyboard_widget;
+  gulong key_press_event_id;
+  gulong key_release_event_id;
   RetroOptions *options;
 };
 
+void retro_core_push_cb_data (RetroCore *self);
+void retro_core_pop_cb_data (void);
+RetroCore *retro_core_get_cb_data (void);
+void retro_core_set_support_no_game (RetroCore *self,
+                                     gboolean   support_no_game);
 gchar *retro_core_get_name (RetroCore *self);
 void retro_core_set_system_av_info (RetroCore         *self,
                                     RetroSystemAvInfo *system_av_info);
 void retro_core_set_controller_port_device (RetroCore       *self,
                                             guint            port,
                                             RetroDeviceType  device);
+void retro_core_set_controller_descriptors (RetroCore            *self,
+                                            RetroInputDescriptor *input_descriptors,
+                                            gsize                 length);
 
 G_END_DECLS
 
diff --git a/retro-gtk/retro-core-view.h b/retro-gtk/retro-core-view.h
index 6636442..4b9551e 100644
--- a/retro-gtk/retro-core-view.h
+++ b/retro-gtk/retro-core-view.h
@@ -6,15 +6,13 @@
 #endif
 
 #include <gtk/gtk.h>
+#include "retro-core.h"
 #include "retro-device-type.h"
 #include "retro-input-device.h"
 #include "retro-video-filter.h"
 
 G_BEGIN_DECLS
 
-// FIXME Remove as soon as possible.
-typedef struct _RetroCore RetroCore;
-
 #define RETRO_TYPE_CORE_VIEW (retro_core_view_get_type())
 
 G_DECLARE_FINAL_TYPE (RetroCoreView, retro_core_view, RETRO, CORE_VIEW, GtkEventBox)
diff --git a/retro-gtk/retro-core.c b/retro-gtk/retro-core.c
index 350f09c..a567bb2 100644
--- a/retro-gtk/retro-core.c
+++ b/retro-gtk/retro-core.c
@@ -2,8 +2,8 @@
 
 #include "retro-core-private.h"
 
+#include <string.h>
 #include "retro-controller-iterator-private.h"
-#include "retro-gtk-internal.h"
 #include "input/retro-keyboard-key.h"
 
 #define RETRO_CORE_ERROR (retro_core_error_quark ())
@@ -15,7 +15,35 @@ enum {
   RETRO_CORE_ERROR_NO_CALLBACK,
 };
 
-/* Private */
+G_DEFINE_TYPE (RetroCore, retro_core, G_TYPE_OBJECT)
+
+enum {
+  PROP_0,
+  PROP_API_VERSION,
+  PROP_FILENAME,
+  PROP_SYSTEM_DIRECTORY,
+  PROP_LIBRETRO_PATH,
+  PROP_CONTENT_DIRECTORY,
+  PROP_SAVE_DIRECTORY,
+  PROP_IS_INITIATED,
+  PROP_GAME_LOADED,
+  PROP_SUPPORT_NO_GAME,
+  PROP_FRAMES_PER_SECOND,
+  N_PROPS,
+};
+
+static GParamSpec *properties [N_PROPS];
+
+enum {
+  SIG_VIDEO_OUTPUT_SIGNAL,
+  SIG_AUDIO_OUTPUT_SIGNAL,
+  SIG_LOG_SIGNAL,
+  SIG_SHUTDOWN_SIGNAL,
+  SIG_MESSAGE_SIGNAL,
+  N_SIGNALS,
+};
+
+static guint signals[N_SIGNALS];
 
 #define RETRO_CORE_OBJECTS_LENGTH 32
 
@@ -24,17 +52,25 @@ static GRecMutex retro_core_w_mutex = { 0 };
 static RetroCore *retro_core_objects[32];
 static gint retro_core_i = 0;
 
+static void retro_core_set_filename (RetroCore   *self,
+                                     const gchar *filename);
+static void retro_core_set_is_initiated (RetroCore *self,
+                                         gboolean   is_initiated);
+static void retro_core_set_game_loaded (RetroCore *self,
+                                        gboolean   game_loaded);
+
+/* Private */
+
 static GQuark
 retro_core_error_quark (void)
 {
   return g_quark_from_static_string ("retro-core-error-quark");
 }
 
-// FIXME Make static as soon as possible.
 void
 retro_core_push_cb_data (RetroCore *self)
 {
-  g_return_if_fail (self != NULL);
+  g_return_if_fail (RETRO_IS_CORE (self));
 
   g_rec_mutex_lock (&retro_core_w_mutex);
   g_rec_mutex_lock (&retro_core_r_mutex);
@@ -52,7 +88,6 @@ retro_core_push_cb_data (RetroCore *self)
   g_rec_mutex_unlock (&retro_core_r_mutex);
 }
 
-// FIXME Make static as soon as possible.
 void
 retro_core_pop_cb_data (void)
 {
@@ -73,7 +108,6 @@ retro_core_pop_cb_data (void)
   g_rec_mutex_unlock (&retro_core_w_mutex);
 }
 
-// FIXME Make static as soon as possible.
 RetroCore *
 retro_core_get_cb_data (void)
 {
@@ -94,6 +128,458 @@ retro_core_get_cb_data (void)
   return result;
 }
 
+static void
+retro_core_finalize (GObject *object)
+{
+  RetroCore *self = RETRO_CORE (object);
+  RetroUnloadGame unload_game;
+  RetroDeinit deinit;
+
+  g_return_if_fail (RETRO_IS_CORE (self));
+
+  retro_core_push_cb_data (self);
+  if (retro_core_get_game_loaded (self)) {
+    unload_game = retro_module_get_unload_game (self->module);
+    unload_game ();
+  }
+  deinit = retro_module_get_deinit (self->module);
+  deinit ();
+  retro_core_pop_cb_data ();
+
+  if (self->media_uris != NULL)
+    g_strfreev (self->media_uris);
+
+  g_object_unref (self->module);
+  g_hash_table_unref (self->controllers);
+  g_object_unref (self->options);
+
+  g_free (self->filename);
+  g_free (self->system_directory);
+  g_free (self->libretro_path);
+  g_free (self->content_directory);
+  g_free (self->save_directory);
+  g_object_unref (self->keyboard_widget);
+
+  G_OBJECT_CLASS (retro_core_parent_class)->finalize (object);
+}
+
+static void
+retro_core_get_property (GObject    *object,
+                         guint       prop_id,
+                         GValue     *value,
+                         GParamSpec *pspec)
+{
+  RetroCore *self = RETRO_CORE (object);
+
+  switch (prop_id) {
+  case PROP_API_VERSION:
+    g_value_set_uint (value, retro_core_get_api_version (self));
+
+    break;
+  case PROP_FILENAME:
+    g_value_set_string (value, retro_core_get_filename (self));
+
+    break;
+  case PROP_SYSTEM_DIRECTORY:
+    g_value_set_string (value, retro_core_get_system_directory (self));
+
+    break;
+  case PROP_LIBRETRO_PATH:
+    g_value_set_string (value, retro_core_get_libretro_path (self));
+
+    break;
+  case PROP_CONTENT_DIRECTORY:
+    g_value_set_string (value, retro_core_get_content_directory (self));
+
+    break;
+  case PROP_SAVE_DIRECTORY:
+    g_value_set_string (value, retro_core_get_save_directory (self));
+
+    break;
+  case PROP_IS_INITIATED:
+    g_value_set_boolean (value, retro_core_get_is_initiated (self));
+
+    break;
+  case PROP_GAME_LOADED:
+    g_value_set_boolean (value, retro_core_get_game_loaded (self));
+
+    break;
+  case PROP_SUPPORT_NO_GAME:
+    g_value_set_boolean (value, retro_core_get_support_no_game (self));
+
+    break;
+  case PROP_FRAMES_PER_SECOND:
+    g_value_set_double (value, retro_core_get_frames_per_second (self));
+
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+
+    break;
+  }
+}
+
+static void
+retro_core_set_property (GObject      *object,
+                         guint         prop_id,
+                         const GValue *value,
+                         GParamSpec   *pspec)
+{
+  RetroCore *self = RETRO_CORE (object);
+
+  switch (prop_id) {
+  case PROP_FILENAME:
+    retro_core_set_filename (self, g_value_get_string (value));
+
+    break;
+  case PROP_SYSTEM_DIRECTORY:
+    retro_core_set_system_directory (self, g_value_get_string (value));
+
+    break;
+  case PROP_LIBRETRO_PATH:
+    retro_core_set_libretro_path (self, g_value_get_string (value));
+
+    break;
+  case PROP_CONTENT_DIRECTORY:
+    retro_core_set_content_directory (self, g_value_get_string (value));
+
+    break;
+  case PROP_SAVE_DIRECTORY:
+    retro_core_set_save_directory (self, g_value_get_string (value));
+
+    break;
+  case PROP_IS_INITIATED:
+    retro_core_set_is_initiated (self, g_value_get_boolean (value));
+
+    break;
+  case PROP_GAME_LOADED:
+    retro_core_set_game_loaded (self, g_value_get_boolean (value));
+
+    break;
+  case PROP_SUPPORT_NO_GAME:
+    retro_core_set_support_no_game (self, g_value_get_boolean (value));
+
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+
+    break;
+  }
+}
+
+static void
+retro_core_class_init (RetroCoreClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = retro_core_finalize;
+  object_class->get_property = retro_core_get_property;
+  object_class->set_property = retro_core_set_property;
+
+  /**
+   * RetroCore:api-version:
+   *
+   * The Libretro API version implement by the core.
+   */
+  properties[PROP_API_VERSION] =
+    g_param_spec_uint ("api-version",
+                       "API version",
+                       "The API version",
+                       0,
+                       G_MAXUINT,
+                       0U,
+                       G_PARAM_READABLE |
+                       G_PARAM_STATIC_NAME |
+                       G_PARAM_STATIC_NICK |
+                       G_PARAM_STATIC_BLURB);
+
+  /**
+   * RetroCore:filename:
+   *
+   * The filename of the core.
+   */
+  properties[PROP_FILENAME] =
+    g_param_spec_string ("filename",
+                         "Filename",
+                         "The module filename",
+                         NULL,
+                         G_PARAM_READWRITE |
+                         G_PARAM_STATIC_NAME |
+                         G_PARAM_STATIC_NICK |
+                         G_PARAM_STATIC_BLURB);
+
+  /**
+   * RetroCore:system-directory:
+   *
+   * The system directory of the core.
+   *
+   * The core will look here for additional data, such as firmware ROMs or
+   * configuration files.
+   */
+  properties[PROP_SYSTEM_DIRECTORY] =
+    g_param_spec_string ("system-directory",
+                         "System directory",
+                         "The system directory",
+                         NULL,
+                         G_PARAM_READWRITE |
+                         G_PARAM_STATIC_NAME |
+                         G_PARAM_STATIC_NICK |
+                         G_PARAM_STATIC_BLURB);
+
+  // FIXME This should be removed as it is useful only to the core and it is
+  // computable from the filename.
+  properties[PROP_LIBRETRO_PATH] =
+    g_param_spec_string ("libretro-path",
+                         "Libretro path",
+                         "The Libretro path",
+                         NULL,
+                         G_PARAM_READWRITE |
+                         G_PARAM_STATIC_NAME |
+                         G_PARAM_STATIC_NICK |
+                         G_PARAM_STATIC_BLURB);
+
+  // FIXME This should be removed as it is deprecated by Libretro.
+  properties[PROP_CONTENT_DIRECTORY] =
+    g_param_spec_string ("content-directory",
+                         "Content directory",
+                         "The content directory",
+                         NULL,
+                         G_PARAM_READWRITE |
+                         G_PARAM_STATIC_NAME |
+                         G_PARAM_STATIC_NICK |
+                         G_PARAM_STATIC_BLURB);
+
+  /**
+   * RetroCore:save-directory:
+   *
+   * The save directory of the core.
+   *
+   * The core will save some data here.
+   */
+  properties[PROP_SAVE_DIRECTORY] =
+    g_param_spec_string ("save-directory",
+                         "Save directory",
+                         "The save directory",
+                         NULL,
+                         G_PARAM_READWRITE |
+                         G_PARAM_STATIC_NAME |
+                         G_PARAM_STATIC_NICK |
+                         G_PARAM_STATIC_BLURB);
+
+  /**
+   * RetroCore:is-initiated:
+   *
+   * Whether the core has been initiated.
+   */
+  properties[PROP_IS_INITIATED] =
+    g_param_spec_boolean ("is-initiated",
+                          "Is initiated",
+                          "Whether the core has been initiated",
+                          FALSE,
+                          G_PARAM_READWRITE |
+                          G_PARAM_STATIC_NAME |
+                          G_PARAM_STATIC_NICK |
+                          G_PARAM_STATIC_BLURB);
+
+  /**
+   * RetroCore:game-loaded:
+   *
+   * Whether a game has been loaded.
+   */
+  properties[PROP_GAME_LOADED] =
+    g_param_spec_boolean ("game-loaded",
+                          "Game loaded",
+                          "Whether a game has been loaded",
+                          FALSE,
+                          G_PARAM_READWRITE |
+                          G_PARAM_STATIC_NAME |
+                          G_PARAM_STATIC_NICK |
+                          G_PARAM_STATIC_BLURB);
+
+  /**
+   * RetroCore:support-no-game:
+   *
+   * Whether the core supports running with no game.
+   */
+  properties[PROP_SUPPORT_NO_GAME] =
+    g_param_spec_boolean ("support-no-game",
+                          "Support no game",
+                          "Whether the core supports running with no game",
+                          FALSE,
+                          G_PARAM_READWRITE |
+                          G_PARAM_STATIC_NAME |
+                          G_PARAM_STATIC_NICK |
+                          G_PARAM_STATIC_BLURB);
+
+  /**
+   * RetroCore:frames-per-second:
+   *
+   * The FPS rate for the core's video output.
+   */
+  properties[PROP_FRAMES_PER_SECOND] =
+    g_param_spec_double ("frames-per-second",
+                         "Frames per second",
+                         "The FPS rate for the core's video output",
+                         -G_MAXDOUBLE,
+                         G_MAXDOUBLE,
+                         0.0,
+                         G_PARAM_READABLE |
+                         G_PARAM_STATIC_NAME |
+                         G_PARAM_STATIC_NICK |
+                         G_PARAM_STATIC_BLURB);
+
+  g_object_class_install_properties (G_OBJECT_CLASS (klass), N_PROPS, properties);
+
+  /**
+   * RetroCore::video-output:
+   * @self: the #RetroCore
+   * @data: (array length=length) (element-type guint8): the video frame data
+   * @length: the lentgh of @data
+   * @width: the width of the video frame
+   * @height: the height of the video frame
+   * @pitch: the distance in bytes between rows
+   * @pixel_format: the pixel format
+   * @aspect_ratio: the aspect ratio to render the frame
+   *
+   * The ::video-output signal is emitted each time a new video frame is emitted
+   * by the core.
+   */
+  signals[SIG_VIDEO_OUTPUT_SIGNAL] =
+    g_signal_new ("video-output", RETRO_TYPE_CORE, G_SIGNAL_RUN_LAST,
+                  0, NULL, NULL,
+                  NULL,
+                  G_TYPE_NONE,
+                  7,
+                  G_TYPE_POINTER,
+                  G_TYPE_ULONG,
+                  G_TYPE_UINT,
+                  G_TYPE_UINT,
+                  G_TYPE_ULONG,
+                  RETRO_TYPE_PIXEL_FORMAT,
+                  G_TYPE_FLOAT);
+
+  /**
+   * RetroCore::audio-output:
+   * @self: the #RetroCore
+   * @data: (array length=length) (element-type guint8): the audio frame data
+   * @length: the lentgh of @data
+   * @sample_rate: the sample rate to play the frame
+   *
+   * The ::audio-output signal is emitted each time a new audio frame is emitted
+   * by the core.
+   */
+  signals[SIG_AUDIO_OUTPUT_SIGNAL] =
+    g_signal_new ("audio-output", RETRO_TYPE_CORE, G_SIGNAL_RUN_LAST,
+                  0, NULL, NULL,
+                  NULL,
+                  G_TYPE_NONE,
+                  3,
+                  G_TYPE_POINTER,
+                  G_TYPE_ULONG,
+                  G_TYPE_DOUBLE);
+
+  /**
+   * RetroCore::log:
+   * @self: the #RetroCore
+   * @log_domain: the log domain
+   * @log_level: (type GLogLevelFlags): the log level
+   * @message: the message
+   *
+   * The ::log signal is emitted each time the core emits a message to log.
+   */
+  signals[SIG_LOG_SIGNAL] =
+    g_signal_new ("log", RETRO_TYPE_CORE, G_SIGNAL_RUN_LAST,
+                  0, NULL, NULL,
+                  NULL,
+                  G_TYPE_NONE,
+                  3,
+                  G_TYPE_STRING,
+                  G_TYPE_UINT,
+                  G_TYPE_STRING);
+
+  /**
+   * RetroCore::shutdown:
+   * @self: the #RetroCore
+   *
+   * The ::shutdown signal is emitted when the core shut down.
+   *
+   * The core must be released or re-started in order to function anew.
+   *
+   * Returns: whether the request got fulfilled
+   */
+  signals[SIG_SHUTDOWN_SIGNAL] =
+    g_signal_new ("shutdown", RETRO_TYPE_CORE, G_SIGNAL_RUN_LAST,
+                  0, NULL, NULL,
+                  NULL,
+                  G_TYPE_BOOLEAN,
+                  0);
+
+  /**
+   * RetroCore::message:
+   * @self: the #RetroCore
+   * @message: the message
+   * @frames: the number of frames the message should be displayed
+   *
+   * The ::message signal is emitted each time the core emits a message to
+   * display during a given amount of frames.
+   *
+   * Returns: whether the request got fulfilled
+   */
+  signals[SIG_MESSAGE_SIGNAL] =
+    g_signal_new ("message", RETRO_TYPE_CORE, G_SIGNAL_RUN_LAST,
+                  0, NULL, NULL,
+                  NULL,
+                  G_TYPE_BOOLEAN,
+                  2,
+                  G_TYPE_STRING,
+                  G_TYPE_UINT);
+}
+
+static void
+retro_core_init (RetroCore *self)
+{
+}
+
+static void
+retro_core_set_filename (RetroCore   *self,
+                         const gchar *filename)
+{
+  g_return_if_fail (RETRO_IS_CORE (self));
+
+  if (g_strcmp0 (filename, retro_core_get_filename (self)) == 0)
+    return;
+
+  g_free (self->filename);
+  self->filename = g_strdup (filename);
+  g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FILENAME]);
+}
+
+static void
+retro_core_set_is_initiated (RetroCore *self,
+                             gboolean   is_initiated)
+{
+  g_return_if_fail (RETRO_IS_CORE (self));
+
+  if (retro_core_get_is_initiated (self) == is_initiated)
+    return;
+
+  self->is_initiated = is_initiated;
+  g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_IS_INITIATED]);
+}
+
+static void
+retro_core_set_game_loaded (RetroCore *self,
+                            gboolean   game_loaded)
+{
+  g_return_if_fail (RETRO_IS_CORE (self));
+
+  if (retro_core_get_game_loaded (self) == game_loaded)
+    return;
+
+  self->game_loaded = game_loaded;
+  g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_GAME_LOADED]);
+}
+
 /**
  * retro_core_get_system_info:
  * @self: A #RetroCore
@@ -105,16 +591,13 @@ static void
 retro_core_get_system_info (RetroCore       *self,
                             RetroSystemInfo *system_info)
 {
-  RetroCoreEnvironmentInternal *internal;
   RetroGetSystemInfo get_system_info;
 
-  g_return_if_fail (self != NULL);
+  g_return_if_fail (RETRO_IS_CORE (self));
   g_return_if_fail (system_info != NULL);
 
-  internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
-
   retro_core_push_cb_data (self);
-  get_system_info = retro_module_get_get_system_info (internal->module);
+  get_system_info = retro_module_get_get_system_info (self->module);
   get_system_info (system_info);
   retro_core_pop_cb_data ();
 }
@@ -129,12 +612,13 @@ retro_core_get_needs_full_path (RetroCore *self)
   return system_info.need_fullpath;
 }
 
-// FIXME Make static as soon as possible.
 /**
  * retro_core_get_name:
- * @self: A #RetroCore
+ * @self: a #RetroCore
+ *
+ * Gets the name of @self.
  *
- * Returns: (transfer none): The name of the Libretro core.
+ * Returns: (transfer none): the name of @self
  */
 gchar *
 retro_core_get_name (RetroCore *self)
@@ -146,15 +630,14 @@ retro_core_get_name (RetroCore *self)
   return system_info.library_name;
 }
 
-// FIXME Make static as soon as possible.
-void
+static void
 retro_core_controller_connected (RetroCore        *self,
                                  guint             port,
                                  RetroInputDevice *device)
 {
   RetroDeviceType device_type;
 
-  g_return_if_fail (self != NULL);
+  g_return_if_fail (RETRO_IS_CORE (self));
   g_return_if_fail (device != NULL);
 
   if (!retro_core_get_is_initiated (self))
@@ -164,12 +647,11 @@ retro_core_controller_connected (RetroCore        *self,
   retro_core_set_controller_port_device (self, port, device_type);
 }
 
-// FIXME Make static as soon as possible.
-void
+static void
 retro_core_controller_disconnected (RetroCore *self,
                                     guint      port)
 {
-  g_return_if_fail (self != NULL);
+  g_return_if_fail (RETRO_IS_CORE (self));
 
   if (!retro_core_get_is_initiated (self))
     return;
@@ -184,20 +666,15 @@ retro_core_send_input_key_event (RetroCore                *self,
                                  guint32                   character,
                                  RetroKeyboardModifierKey  key_modifiers)
 {
-  RetroCoreEnvironmentInternal *environment_internal;
-
-  g_return_if_fail (self != NULL);
-
-  environment_internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
+  g_return_if_fail (RETRO_IS_CORE (self));
 
-  if (environment_internal->keyboard_callback.callback == NULL)
+  if (self->keyboard_callback.callback == NULL)
     return;
 
-  environment_internal->keyboard_callback.callback (down, keycode, character, key_modifiers);
+  self->keyboard_callback.callback (down, keycode, character, key_modifiers);
 }
 
-// FIXME Make static as soon as possible.
-gboolean
+static gboolean
 retro_core_key_event (RetroCore   *self,
                       GdkEventKey *event)
 {
@@ -206,7 +683,7 @@ retro_core_key_event (RetroCore   *self,
   RetroKeyboardModifierKey retro_modifier_key;
   guint32 character;
 
-  g_return_val_if_fail (self != NULL, FALSE);
+  g_return_val_if_fail (RETRO_IS_CORE (self), FALSE);
   g_return_val_if_fail (event != NULL, FALSE);
 
   if (!retro_core_get_is_initiated (self))
@@ -233,15 +710,12 @@ retro_core_set_disk_ejected (RetroCore  *self,
                              gboolean    ejected,
                              GError    **error)
 {
-  RetroCoreEnvironmentInternal *internal;
   RetroDiskControlCallbackSetEjectState set_eject_state;
   gboolean result;
 
-  g_return_val_if_fail (self != NULL, FALSE);
-
-  internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
+  g_return_val_if_fail (RETRO_IS_CORE (self), FALSE);
 
-  set_eject_state = internal->disk_control_callback->set_eject_state;
+  set_eject_state = self->disk_control_callback->set_eject_state;
 
   if (set_eject_state == NULL) {
     g_set_error_literal (error,
@@ -264,15 +738,12 @@ retro_core_set_disk_image_index (RetroCore  *self,
                                  guint       index,
                                  GError    **error)
 {
-  RetroCoreEnvironmentInternal *internal;
   RetroDiskControlCallbackSetImageIndex set_image_index;
   gboolean result;
 
-  g_return_val_if_fail (self != NULL, FALSE);
-
-  internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
+  g_return_val_if_fail (RETRO_IS_CORE (self), FALSE);
 
-  set_image_index = internal->disk_control_callback->set_image_index;
+  set_image_index = self->disk_control_callback->set_image_index;
 
   if (set_image_index == NULL) {
     g_set_error_literal (error,
@@ -294,15 +765,12 @@ static guint
 retro_core_get_disk_images_number (RetroCore  *self,
                                    GError    **error)
 {
-  RetroCoreEnvironmentInternal *internal;
   RetroDiskControlCallbackGetNumImages get_num_images;
   guint result;
 
-  g_return_val_if_fail (self != NULL, FALSE);
-
-  internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
+  g_return_val_if_fail (RETRO_IS_CORE (self), FALSE);
 
-  get_num_images = internal->disk_control_callback->get_num_images;
+  get_num_images = self->disk_control_callback->get_num_images;
 
   if (get_num_images == NULL) {
     g_set_error_literal (error,
@@ -326,15 +794,12 @@ retro_core_replace_disk_image_index (RetroCore     *self,
                                      RetroGameInfo *info,
                                      GError        **error)
 {
-  RetroCoreEnvironmentInternal *internal;
   RetroDiskControlCallbackReplaceImageIndex replace_image_index;
   gboolean result;
 
-  g_return_val_if_fail (self != NULL, FALSE);
-
-  internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
+  g_return_val_if_fail (RETRO_IS_CORE (self), FALSE);
 
-  replace_image_index = internal->disk_control_callback->replace_image_index;
+  replace_image_index = self->disk_control_callback->replace_image_index;
 
   if (replace_image_index == NULL) {
     g_set_error_literal (error,
@@ -356,15 +821,12 @@ static gboolean
 retro_core_add_disk_image_index (RetroCore  *self,
                                  GError    **error)
 {
-  RetroCoreEnvironmentInternal *internal;
   RetroDiskControlCallbackAddImageIndex add_image_index;
   gboolean result;
 
-  g_return_val_if_fail (self != NULL, FALSE);
-
-  internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
+  g_return_val_if_fail (RETRO_IS_CORE (self), FALSE);
 
-  add_image_index = internal->disk_control_callback->add_image_index;
+  add_image_index = self->disk_control_callback->add_image_index;
 
   if (add_image_index == NULL) {
     g_set_error_literal (error,
@@ -386,7 +848,6 @@ static void
 retro_core_load_discs (RetroCore  *self,
                        GError    **error)
 {
-  RetroCoreEnvironmentInternal *internal;
   guint length;
   gboolean fullpath;
   GFile *file;
@@ -395,9 +856,7 @@ retro_core_load_discs (RetroCore  *self,
   RetroGameInfo *game_info = NULL;
   GError *tmp_error = NULL;
 
-  g_return_if_fail (self != NULL);
-
-  internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
+  g_return_if_fail (RETRO_IS_CORE (self));
 
   retro_core_set_disk_ejected (self, TRUE, &tmp_error);
   if (G_UNLIKELY (tmp_error != NULL)) {
@@ -406,7 +865,7 @@ retro_core_load_discs (RetroCore  *self,
     return;
   }
 
-  length = g_strv_length (internal->media_uris);
+  length = g_strv_length (self->media_uris);
   while (retro_core_get_disk_images_number (self, &tmp_error) < length &&
          (tmp_error != NULL)) {
     retro_core_add_disk_image_index (self, &tmp_error);
@@ -425,7 +884,7 @@ retro_core_load_discs (RetroCore  *self,
 
   fullpath = retro_core_get_needs_full_path (self);
   for (index = 0; index < length; index++) {
-    file = g_file_new_for_uri (internal->media_uris[index]);
+    file = g_file_new_for_uri (self->media_uris[index]);
     path = g_file_get_path (file);
 
     if (fullpath) {
@@ -473,30 +932,27 @@ static gboolean
 retro_core_load_game (RetroCore     *self,
                       RetroGameInfo *game)
 {
-  RetroCoreEnvironmentInternal *internal;
   RetroUnloadGame unload_game;
   RetroLoadGame load_game;
   RetroGetSystemAvInfo get_system_av_info;
   gboolean game_loaded;
   RetroSystemAvInfo info = {{ 0 }};
 
-  g_return_val_if_fail (self != NULL, FALSE);
+  g_return_val_if_fail (RETRO_IS_CORE (self), FALSE);
   g_return_val_if_fail (game != NULL, FALSE);
 
-  internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
-
   if (retro_core_get_game_loaded (self)) {
     retro_core_push_cb_data (self);
-    unload_game = retro_module_get_unload_game (internal->module);
+    unload_game = retro_module_get_unload_game (self->module);
     unload_game ();
     retro_core_pop_cb_data ();
   }
 
   retro_core_push_cb_data (self);
-  load_game = retro_module_get_load_game (internal->module);
+  load_game = retro_module_get_load_game (self->module);
   game_loaded = load_game (game);
   retro_core_set_game_loaded (self, game_loaded);
-  get_system_av_info = retro_module_get_get_system_av_info (internal->module);
+  get_system_av_info = retro_module_get_get_system_av_info (self->module);
   get_system_av_info (&info);
   retro_core_set_system_av_info (self, &info);
   retro_core_pop_cb_data ();
@@ -505,22 +961,19 @@ retro_core_load_game (RetroCore     *self,
 }
 
 static gboolean
-retro_core_prepare (RetroCore* self) {
-  RetroCoreEnvironmentInternal *internal;
+retro_core_prepare (RetroCore *self) {
   RetroLoadGame load_game;
   RetroGetSystemAvInfo get_system_av_info;
   gboolean game_loaded;
   RetroSystemAvInfo info = {{ 0 }};
 
-  g_return_val_if_fail (self != NULL, FALSE);
-
-  internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
+  g_return_val_if_fail (RETRO_IS_CORE (self), FALSE);
 
   retro_core_push_cb_data (self);
-  load_game = retro_module_get_load_game (internal->module);
+  load_game = retro_module_get_load_game (self->module);
   game_loaded = load_game (NULL);
   retro_core_set_game_loaded (self, game_loaded);
-  get_system_av_info = retro_module_get_get_system_av_info (internal->module);
+  get_system_av_info = retro_module_get_get_system_av_info (self->module);
   get_system_av_info (&info);
   retro_core_set_system_av_info (self, &info);
   retro_core_pop_cb_data ();
@@ -529,10 +982,9 @@ retro_core_prepare (RetroCore* self) {
 }
 
 static void
-retro_core_load_medias (RetroCore* self,
+retro_core_load_medias (RetroCore *self,
                         GError** error)
 {
-  RetroCoreEnvironmentInternal *internal;
   guint length;
   gchar *uri;
   GFile *file;
@@ -541,10 +993,8 @@ retro_core_load_medias (RetroCore* self,
   RetroGameInfo *game_info = NULL;
   GError *tmp_error = NULL;
 
-  g_return_if_fail (self != NULL);
-
-  internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
-  length = g_strv_length (internal->media_uris);
+  g_return_if_fail (RETRO_IS_CORE (self));
+  length = g_strv_length (self->media_uris);
 
   if (length == 0) {
     retro_core_prepare (self);
@@ -552,7 +1002,7 @@ retro_core_load_medias (RetroCore* self,
     return;
   }
 
-  uri = g_strdup (internal->media_uris[0]);
+  uri = g_strdup (self->media_uris[0]);
   file = g_file_new_for_uri (uri);
   path = g_file_get_path (file);
   fullpath = retro_core_get_needs_full_path (self);
@@ -579,7 +1029,7 @@ retro_core_load_medias (RetroCore* self,
 
     return;
   }
-  if (internal->disk_control_callback != NULL) {
+  if (self->disk_control_callback != NULL) {
     retro_core_load_discs (self, &tmp_error);
     if (G_UNLIKELY (tmp_error != NULL)) {
       g_propagate_error (error, tmp_error);
@@ -597,110 +1047,280 @@ retro_core_load_medias (RetroCore* self,
   g_free (uri);
 }
 
-// FIXME Make static as soon as possible.
+void retro_core_set_environment_interface (RetroCore *self);
+void retro_core_set_callbacks (RetroCore *self);
+
+static gboolean
+on_key_event (GtkWidget   *widget,
+              GdkEventKey *event,
+              gpointer     self)
+{
+  g_return_val_if_fail (RETRO_IS_CORE (self), FALSE);
+  g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  return retro_core_key_event (RETRO_CORE (self), event);
+}
+
+/* Public */
+
+/**
+ * retro_core_get_api_version:
+ * @self: a #RetroCore
+ *
+ * Gets the Libretro API version implement by the core.
+ *
+ * Returns: the API version
+ */
 guint
-retro_core_get_api_version_real (RetroCore *self)
+retro_core_get_api_version (RetroCore *self)
 {
-  RetroCoreEnvironmentInternal *internal;
   guint result;
   RetroApiVersion api_version;
 
-  g_return_val_if_fail (self != NULL, 0U);
-
-  internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
+  g_return_val_if_fail (RETRO_IS_CORE (self), 0U);
 
   retro_core_push_cb_data (self);
-  api_version = retro_module_get_api_version (internal->module);
+  api_version = retro_module_get_api_version (self->module);
   result = api_version ();
   retro_core_pop_cb_data ();
 
   return result;
 }
 
-void retro_core_set_environment_interface (RetroCore *self);
-void retro_core_set_callbacks (RetroCore *self);
+/**
+ * retro_core_get_filename:
+ * @self: a #RetroCore
+ *
+ * Gets the filename of the core.
+ *
+ * Returns: the filename of the core
+ */
+const gchar *
+retro_core_get_filename (RetroCore *self)
+{
+  g_return_val_if_fail (RETRO_IS_CORE (self), NULL);
+
+  return self->filename;
+}
 
-// FIXME Make static as soon as possible.
+/**
+ * retro_core_get_system_directory:
+ * @self: a #RetroCore
+ *
+ * Gets the system directory of the core.
+ *
+ * The core will look here for additional data, such as firmware ROMs or
+ * configuration files.
+ *
+ * Returns: the system directory of the core
+ */
+const gchar *
+retro_core_get_system_directory (RetroCore *self)
+{
+  g_return_val_if_fail (RETRO_IS_CORE (self), NULL);
+
+  return self->system_directory;
+}
+
+/**
+ * retro_core_set_system_directory:
+ * @self: a #RetroCore
+ * @system_directory: the system directory
+ *
+ * Sets the system directory of the core.
+ *
+ * The core will look here for additional data, such as firmware ROMs or
+ * configuration files.
+ */
 void
-retro_core_constructor (RetroCore   *self,
-                        const gchar *file_name)
+retro_core_set_system_directory (RetroCore   *self,
+                                 const gchar *system_directory)
 {
-  RetroCoreEnvironmentInternal *internal;
-  GFile *file;
-  GFile *relative_path_file;
-  gchar *libretro_path;
+  g_return_if_fail (RETRO_IS_CORE (self));
 
-  g_return_if_fail (file_name != NULL);
+  if (g_strcmp0 (system_directory, retro_core_get_system_directory (self)) == 0)
+    return;
 
-  retro_core_set_file_name (self, file_name);
+  g_free (self->system_directory);
+  self->system_directory = g_strdup (system_directory);
+  g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SYSTEM_DIRECTORY]);
+}
 
-  internal = g_new0 (RetroCoreEnvironmentInternal, 1);
-  self->environment_internal = internal;
+// FIXME This should be removed as it is useful only to the core and it is
+// computable from the filename.
+const gchar *
+retro_core_get_libretro_path (RetroCore *self)
+{
+  g_return_val_if_fail (RETRO_IS_CORE (self), NULL);
 
-  file = g_file_new_for_path (file_name);
-  relative_path_file = g_file_resolve_relative_path (file, "");
+  return self->libretro_path;
+}
 
-  g_object_unref (file);
+// FIXME This should be removed as it is useful only to the core and it is
+// computable from the filename.
+void
+retro_core_set_libretro_path (RetroCore   *self,
+                              const gchar *libretro_path)
+{
+  g_return_if_fail (RETRO_IS_CORE (self));
 
-  libretro_path = g_file_get_path (relative_path_file);
+  if (g_strcmp0 (libretro_path, retro_core_get_libretro_path (self)) == 0)
+    return;
 
-  g_object_unref (relative_path_file);
+  g_free (self->libretro_path);
+  self->libretro_path = g_strdup (libretro_path);
+  g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_LIBRETRO_PATH]);
+}
 
-  retro_core_set_libretro_path (self, libretro_path);
-  internal->module = retro_module_new (libretro_path);
+// FIXME This should be removed as it is deprecated by Libretro.
+const gchar *
+retro_core_get_content_directory (RetroCore *self)
+{
+  g_return_val_if_fail (RETRO_IS_CORE (self), NULL);
 
-  g_free (libretro_path);
+  return self->content_directory;
+}
 
-  retro_core_set_callbacks (self);
-  internal->controllers = g_hash_table_new_full (g_int_hash, g_int_equal,
-                                                        g_free, g_object_unref);
-  internal->options = retro_options_new ();
+// FIXME This should be removed as it is deprecated by Libretro.
+void
+retro_core_set_content_directory (RetroCore   *self,
+                                  const gchar *content_directory)
+{
+  g_return_if_fail (RETRO_IS_CORE (self));
+
+  if (g_strcmp0 (content_directory, retro_core_get_content_directory (self)) == 0)
+    return;
+
+  g_free (self->content_directory);
+  self->content_directory = g_strdup (content_directory);
+  g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_CONTENT_DIRECTORY]);
+}
+
+/**
+ * retro_core_get_save_directory:
+ * @self: a #RetroCore
+ *
+ * Gets the save directory of the core.
+ *
+ * The core will save some data here.
+ *
+ * Returns: the save directory of the core
+ */
+const gchar *
+retro_core_get_save_directory (RetroCore *self)
+{
+  g_return_val_if_fail (RETRO_IS_CORE (self), NULL);
+
+  return self->save_directory;
 }
 
-// FIXME Make static as soon as possible.
+/**
+ * retro_core_set_save_directory:
+ * @self: a #RetroCore
+ * @save_directory: the save directory
+ *
+ * Sets the save directory of the core.
+ *
+ * The core will save some data here.
+ */
 void
-retro_core_destructor (RetroCore *self)
+retro_core_set_save_directory (RetroCore   *self,
+                               const gchar *save_directory)
 {
-  RetroCoreEnvironmentInternal *internal;
-  RetroUnloadGame unload_game;
-  RetroDeinit deinit;
+  g_return_if_fail (RETRO_IS_CORE (self));
 
-  g_return_if_fail (self != NULL);
+  if (g_strcmp0 (save_directory, retro_core_get_save_directory (self)) == 0)
+    return;
 
-  internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
+  g_free (self->save_directory);
+  self->save_directory = g_strdup (save_directory);
+  g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SAVE_DIRECTORY]);
+}
 
-  retro_core_push_cb_data (self);
-  if (retro_core_get_game_loaded (self)) {
-    unload_game = retro_module_get_unload_game (internal->module);
-    unload_game ();
-  }
-  deinit = retro_module_get_deinit (internal->module);
-  deinit ();
-  retro_core_pop_cb_data ();
+/**
+ * retro_core_get_is_initiated:
+ * @self: a #RetroCore
+ *
+ * Gets whether the core has been initiated.
+ *
+ * Returns: whether the core has been initiated
+ */
+gboolean
+retro_core_get_is_initiated (RetroCore *self)
+{
+  g_return_val_if_fail (RETRO_IS_CORE (self), FALSE);
 
-  if (internal->media_uris != NULL)
-    g_strfreev (internal->media_uris);
+  return self->is_initiated;
+}
 
-  g_object_unref (internal->module);
-  g_hash_table_unref (internal->controllers);
-  g_object_unref (internal->options);
+/**
+ * retro_core_get_game_loaded:
+ * @self: a #RetroCore
+ *
+ * Gets whether a game has been loaded.
+ *
+ * Returns: whether a game has been loaded
+ */
+gboolean
+retro_core_get_game_loaded (RetroCore *self)
+{
+  g_return_val_if_fail (RETRO_IS_CORE (self), FALSE);
 
-  g_free (self->environment_internal);
+  return self->game_loaded;
 }
 
-static gboolean
-on_key_event (GtkWidget   *widget,
-              GdkEventKey *event,
-              gpointer     self)
+/**
+ * retro_core_get_support_no_game:
+ * @self: a #RetroCore
+ *
+ * Gets whether the core supports running with no game.
+ *
+ * Returns: whether the core supports running with no game
+ */
+gboolean
+retro_core_get_support_no_game (RetroCore *self)
 {
   g_return_val_if_fail (RETRO_IS_CORE (self), FALSE);
-  g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
-  g_return_val_if_fail (event != NULL, FALSE);
 
-  return retro_core_key_event (RETRO_CORE (self), event);
+  return self->support_no_game;
 }
 
-/* Public */
+/**
+ * retro_core_set_support_no_game:
+ * @self: a #RetroCore
+ * @support_no_game: the save directory
+ *
+ * Sets whether the core supports running with no game.
+ */
+void
+retro_core_set_support_no_game (RetroCore *self,
+                                gboolean   support_no_game)
+{
+  g_return_if_fail (RETRO_IS_CORE (self));
+
+  if (retro_core_get_support_no_game (self) == support_no_game)
+    return;
+
+  self->support_no_game = support_no_game;
+  g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SUPPORT_NO_GAME]);
+}
+
+/**
+ * retro_core_get_frames_per_second:
+ * @self: a #RetroCore
+ *
+ * Gets the FPS rate for the core's video output.
+ *
+ * Returns: the FPS rate for the core's video output
+ */
+gdouble
+retro_core_get_frames_per_second (RetroCore *self)
+{
+  g_return_val_if_fail (RETRO_IS_CORE (self), 0.0);
+
+  return self->frames_per_second;
+}
 
 /**
  * retro_core_boot:
@@ -714,7 +1334,6 @@ void
 retro_core_boot (RetroCore  *self,
                  GError    **error)
 {
-  RetroCoreEnvironmentInternal *internal;
   RetroInit init;
   RetroControllerIterator *controller_iterator;
   guint *port;
@@ -722,14 +1341,12 @@ retro_core_boot (RetroCore  *self,
   RetroDeviceType device_type;
   GError *tmp_error = NULL;
 
-  g_return_if_fail (self != NULL);
-
-  internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
+  g_return_if_fail (RETRO_IS_CORE (self));
 
   retro_core_set_environment_interface (self);
 
   retro_core_push_cb_data (self);
-  init = retro_module_get_init (internal->module);
+  init = retro_module_get_init (self->module);
   init ();
   retro_core_pop_cb_data ();
 
@@ -752,40 +1369,54 @@ retro_core_boot (RetroCore  *self,
   }
 }
 
+/**
+ * retro_core_set_medias:
+ * @self: a #RetroCore
+ * @uris: (array zero-terminated=1) (element-type utf8)
+ * (transfer none): the URIs
+ *
+ * Sets the medias to load into the core.
+ *
+ * You can use this before booting the core.
+ */
 void
-retro_core_set_medias (RetroCore  *self,
-                       gchar     **uris)
+retro_core_set_medias (RetroCore    *self,
+                       const gchar **uris)
 {
-  RetroCoreEnvironmentInternal *internal;
 
-  g_return_if_fail (self != NULL);
+  g_return_if_fail (RETRO_IS_CORE (self));
   g_return_if_fail (!retro_core_get_is_initiated (self));
 
-  internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
-
-  if (internal->media_uris != NULL)
-    g_strfreev (internal->media_uris);
+  if (self->media_uris != NULL)
+    g_strfreev (self->media_uris);
 
-  internal->media_uris = g_strdupv (uris);
+  self->media_uris = g_strdupv ((gchar **) uris);
 }
 
+/**
+ * retro_core_set_current_media:
+ * @self: a #RetroCore
+ * @media_index: the media index
+ * @error: return location for a #GError, or %NULL
+ *
+ * Sets the current media index.
+ *
+ * You can use this after booting the core.
+ */
 void
 retro_core_set_current_media (RetroCore  *self,
                               guint       media_index,
                               GError    **error)
 {
-  RetroCoreEnvironmentInternal *internal;
   guint length;
   GError *tmp_error = NULL;
 
-  g_return_if_fail (self != NULL);
-
-  internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
-  length = g_strv_length (internal->media_uris);
+  g_return_if_fail (RETRO_IS_CORE (self));
+  length = g_strv_length (self->media_uris);
 
   g_return_if_fail (media_index < length);
 
-  if (internal->disk_control_callback == NULL)
+  if (self->disk_control_callback == NULL)
     return;
 
   retro_core_set_disk_ejected (self, TRUE, &tmp_error);
@@ -810,93 +1441,109 @@ retro_core_set_current_media (RetroCore  *self,
   }
 }
 
+// FIXME Merge this into retro_core_set_controller().
 void
 retro_core_set_controller_port_device (RetroCore       *self,
                                        guint            port,
                                        RetroDeviceType  device)
 {
-  RetroCoreEnvironmentInternal *internal;
   RetroSetControllerPortDevice set_controller_port_device;
 
-  g_return_if_fail (self != NULL);
-
-  internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
+  g_return_if_fail (RETRO_IS_CORE (self));
 
   retro_core_push_cb_data (self);
-  set_controller_port_device = retro_module_get_set_controller_port_device (internal->module);
+  set_controller_port_device = retro_module_get_set_controller_port_device (self->module);
   set_controller_port_device (port, device);
   retro_core_pop_cb_data ();
 }
 
+/**
+ * retro_core_reset:
+ * @self: a #RetroCore
+ *
+ * Resets @self.
+ */
 void
-retro_core_reset (RetroCore* self)
+retro_core_reset (RetroCore *self)
 {
-  RetroCoreEnvironmentInternal *internal;
   RetroReset reset;
 
-  g_return_if_fail (self != NULL);
-
-  internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
+  g_return_if_fail (RETRO_IS_CORE (self));
 
   retro_core_push_cb_data (self);
-  reset = retro_module_get_reset (internal->module);
+  reset = retro_module_get_reset (self->module);
   reset ();
   retro_core_pop_cb_data ();
 }
 
+/**
+ * retro_core_run:
+ * @self: a #RetroCore
+ *
+ * Iterate @self for a frame.
+ */
 void
-retro_core_run (RetroCore* self)
+retro_core_run (RetroCore *self)
 {
-  RetroCoreEnvironmentInternal *internal;
   RetroRun run;
 
-  g_return_if_fail (self != NULL);
-
-  internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
+  g_return_if_fail (RETRO_IS_CORE (self));
 
   retro_core_push_cb_data (self);
-  run = retro_module_get_run (internal->module);
+  run = retro_module_get_run (self->module);
   run ();
   retro_core_pop_cb_data ();
 }
 
+/**
+ * retro_core_supports_serialization:
+ * @self: a #RetroCore
+ *
+ * Gets whether the state of @self can be accessed.
+ *
+ * Returns: whether the state of @self can be accessed
+ */
 gboolean
 retro_core_supports_serialization (RetroCore *self)
 {
-  RetroCoreEnvironmentInternal *internal;
   RetroSerializeSize serialize_size = NULL;
   gsize size;
 
-  g_return_val_if_fail (self != NULL, FALSE);
-
-  internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
+  g_return_val_if_fail (RETRO_IS_CORE (self), FALSE);
 
   retro_core_push_cb_data (self);
-  serialize_size = retro_module_get_serialize_size (internal->module);
+  serialize_size = retro_module_get_serialize_size (self->module);
   size = serialize_size ();
   retro_core_pop_cb_data ();
 
   return size > 0;
 }
 
+/**
+ * retro_core_get_state:
+ * @self: a #RetroCore
+ * @length: return location for the length of the returned data
+ * @error: return location for a #GError, or %NULL
+ *
+ * Gets the state of @self.
+ *
+ * Returns: (array length=length): the content of the memory region
+ */
 guint8 *
-retro_core_serialize_state (RetroCore  *self,
-                            gsize      *length,
-                            GError    **error)
+retro_core_get_state (RetroCore  *self,
+                      gsize      *length,
+                      GError    **error)
 {
-  RetroCoreEnvironmentInternal *internal;
   RetroSerializeSize serialize_size = NULL;
   RetroSerialize serialize = NULL;
   guint8 *data;
   gsize size;
   gboolean success;
 
-  g_return_val_if_fail (self != NULL, NULL);
+  g_return_val_if_fail (RETRO_IS_CORE (self), NULL);
   g_return_val_if_fail (length != NULL, NULL);
 
-  internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
-
-  serialize_size = retro_module_get_serialize_size (internal->module);
+  serialize_size = retro_module_get_serialize_size (self->module);
 
   retro_core_push_cb_data (self);
   size = serialize_size ();
@@ -911,7 +1558,7 @@ retro_core_serialize_state (RetroCore  *self,
     return NULL;
   }
 
-  serialize = retro_module_get_serialize (internal->module);
+  serialize = retro_module_get_serialize (self->module);
   data = g_new0 (guint8, size);
 
   retro_core_push_cb_data (self);
@@ -933,24 +1580,30 @@ retro_core_serialize_state (RetroCore  *self,
   return data;
 }
 
+/**
+ * retro_core_set_state:
+ * @self: a #RetroCore
+ * @data: (array length=length): the data to set
+ * @length: the length of @data
+ * @error: return location for a #GError, or %NULL
+ *
+ * Sets the state of the @self.
+ */
 void
-retro_core_deserialize_state (RetroCore  *self,
-                              guint8     *data,
-                              gsize       length,
-                              GError    **error)
+retro_core_set_state (RetroCore     *self,
+                      const guint8  *data,
+                      gsize          length,
+                      GError       **error)
 {
-  RetroCoreEnvironmentInternal *internal;
   RetroSerializeSize serialize_size = NULL;
   RetroUnserialize unserialize = NULL;
   gsize size;
   gboolean success;
 
-  g_return_if_fail (self != NULL);
+  g_return_if_fail (RETRO_IS_CORE (self));
   g_return_if_fail (data != NULL);
 
-  internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
-
-  serialize_size = retro_module_get_serialize_size (internal->module);
+  serialize_size = retro_module_get_serialize_size (self->module);
 
   retro_core_push_cb_data (self);
   size = serialize_size ();
@@ -969,15 +1622,18 @@ retro_core_deserialize_state (RetroCore  *self,
     g_set_error (error,
                  RETRO_CORE_ERROR,
                  RETRO_CORE_ERROR_COULDNT_DESERIALIZE,
-                 "Couldn't deserialize the internal state: expected at most %"G_GSIZE_FORMAT" bytes, got 
%"G_GSIZE_FORMAT".", size, length);
+                 "Couldn't deserialize the internal state: expected at most %"
+                 G_GSIZE_FORMAT" bytes, got %"G_GSIZE_FORMAT".",
+                 size,
+                 length);
 
     return;
   }
 
-  unserialize = retro_module_get_unserialize (internal->module);
+  unserialize = retro_module_get_unserialize (self->module);
 
   retro_core_push_cb_data (self);
-  success = unserialize (data, length);
+  success = unserialize ((guint8 *) data, length);
   retro_core_pop_cb_data ();
 
   if (!success) {
@@ -988,48 +1644,61 @@ retro_core_deserialize_state (RetroCore  *self,
   }
 }
 
+/**
+ * retro_core_get_memory_size:
+ * @self: a #RetroCore
+ * @memory_type: the type of memory
+ *
+ * Gets the size of a memory region of @self.
+ *
+ * Returns: the size of a memory region
+ */
 gsize
 retro_core_get_memory_size (RetroCore       *self,
-                            RetroMemoryType  id)
+                            RetroMemoryType  memory_type)
 {
-  RetroCoreEnvironmentInternal *internal;
   gsize size;
   RetroGetMemorySize get_memory_size;
 
-  g_return_val_if_fail (self != NULL, 0UL);
-
-  internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
+  g_return_val_if_fail (RETRO_IS_CORE (self), 0UL);
 
   retro_core_push_cb_data (self);
-  get_memory_size = retro_module_get_get_memory_size (internal->module);
-  size = get_memory_size (id);
+  get_memory_size = retro_module_get_get_memory_size (self->module);
+  size = get_memory_size (memory_type);
   retro_core_pop_cb_data ();
 
   return size;
 }
 
+/**
+ * retro_core_get_memory:
+ * @self: a #RetroCore
+ * @memory_type: the type of memory
+ * @length: return location for the length of the returned data
+ *
+ * Gets a memory region of @self.
+ *
+ * Returns: (array length=length): the content of the memory region
+ */
 guint8 *
 retro_core_get_memory (RetroCore       *self,
-                       RetroMemoryType  id,
-                       gint            *length)
+                       RetroMemoryType  memory_type,
+                       gsize           *length)
 {
-  RetroCoreEnvironmentInternal *internal;
   RetroGetMemoryData get_mem_data;
   RetroGetMemorySize get_mem_size;
   guint8 *data;
   gsize size;
 
-  g_return_val_if_fail (self != NULL, NULL);
+  g_return_val_if_fail (RETRO_IS_CORE (self), NULL);
   g_return_val_if_fail (length != NULL, NULL);
 
-  internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
-
-  get_mem_data = retro_module_get_get_memory_data (internal->module);
-  get_mem_size = retro_module_get_get_memory_size (internal->module);
+  get_mem_data = retro_module_get_get_memory_data (self->module);
+  get_mem_size = retro_module_get_get_memory_size (self->module);
 
   retro_core_push_cb_data (self);
-  data = get_mem_data (id);
-  size = get_mem_size (id);
+  data = get_mem_data (memory_type);
+  size = get_mem_size (memory_type);
   retro_core_pop_cb_data ();
 
   data = g_memdup (data, size);
@@ -1038,41 +1707,48 @@ retro_core_get_memory (RetroCore       *self,
   return data;
 }
 
+/**
+ * retro_core_set_memory:
+ * @self: a #RetroCore
+ * @memory_type: the type of memory
+ * @data: (array length=length): the data to set
+ * @length: the length of @data
+ *
+ * Sets a memory region of @self.
+ */
 void
 retro_core_set_memory (RetroCore       *self,
-                       RetroMemoryType  id,
+                       RetroMemoryType  memory_type,
                        guint8          *data,
-                       gint             length)
+                       gsize            length)
 {
-  RetroCoreEnvironmentInternal *internal;
   RetroGetMemoryData get_mem_region;
   RetroGetMemorySize get_mem_region_size;
   guint8 *memory_region;
   gsize memory_region_size;
 
-  g_return_if_fail (self != NULL);
+  g_return_if_fail (RETRO_IS_CORE (self));
   g_return_if_fail (data != NULL);
   g_return_if_fail (length > 0);
 
-  internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
-
-  get_mem_region = retro_module_get_get_memory_data (internal->module);
-  get_mem_region_size = retro_module_get_get_memory_size (internal->module);
+  get_mem_region = retro_module_get_get_memory_data (self->module);
+  get_mem_region_size = retro_module_get_get_memory_size (self->module);
 
   retro_core_push_cb_data (self);
-  memory_region = get_mem_region (id);
-  memory_region_size = get_mem_region_size (id);
+  memory_region = get_mem_region (memory_type);
+  memory_region_size = get_mem_region_size (memory_type);
   retro_core_pop_cb_data ();
 
   g_return_if_fail (memory_region != NULL);
   g_return_if_fail (memory_region_size >= length);
 
   if (memory_region_size != length)
-    g_debug ("%s expects %"G_GSIZE_FORMAT" bytes for memory region %d: %d bytes"
-             " were passed. The excess will be filled with zeros.",
+    g_debug ("%s expects %"G_GSIZE_FORMAT" bytes for memory region %d: %"
+             G_GSIZE_FORMAT" bytes were passed. The excess will be filled with"
+             "zeros.",
              retro_core_get_name (self),
              memory_region_size,
-             id,
+             memory_type,
              length);
 
   memcpy (memory_region, data, length);
@@ -1121,17 +1797,14 @@ retro_core_get_controller_input_state (RetroCore       *self,
                                        guint            index,
                                        guint            id)
 {
-  RetroCoreEnvironmentInternal *internal;
   RetroInputDevice *controller;
 
   g_return_val_if_fail (RETRO_IS_CORE (self), 0);
 
-  internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
-
-  if (!g_hash_table_contains (internal->controllers, &port))
+  if (!g_hash_table_contains (self->controllers, &port))
     return 0;
 
-  controller = g_hash_table_lookup (internal->controllers, &port);
+  controller = g_hash_table_lookup (self->controllers, &port);
 
   if (controller == NULL)
     return 0;
@@ -1145,16 +1818,18 @@ retro_core_get_controller_input_state (RetroCore       *self,
                                              id);
 }
 
+// FIXME documentation
 void
 retro_core_set_controller_descriptors (RetroCore            *self,
                                        RetroInputDescriptor *input_descriptors,
-                                       gsize                 input_descriptors_length)
+                                       gsize                 length)
 {
   g_return_if_fail (RETRO_IS_CORE (self));
 
   // TODO
 }
 
+// FIXME documentation
 guint64
 retro_core_get_controller_capabilities (RetroCore *self)
 {
@@ -1178,17 +1853,14 @@ retro_core_set_controller (RetroCore        *self,
                            guint             port,
                            RetroInputDevice *controller)
 {
-  RetroCoreEnvironmentInternal *internal;
   guint *port_copy;
 
   g_return_if_fail (RETRO_IS_CORE (self));
   g_return_if_fail (RETRO_IS_INPUT_DEVICE (controller));
 
-  internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
-
   port_copy = g_new (guint, 1);
   *port_copy = port;
-  g_hash_table_insert (internal->controllers,
+  g_hash_table_insert (self->controllers,
                        port_copy,
                        g_object_ref (controller));
   retro_core_controller_connected (self, port, controller);
@@ -1205,7 +1877,7 @@ void
 retro_core_set_keyboard (RetroCore *self,
                          GtkWidget *widget)
 {
-  g_return_if_fail (self != NULL);
+  g_return_if_fail (RETRO_IS_CORE (self));
 
   if (self->keyboard_widget != NULL) {
     g_signal_handler_disconnect (G_OBJECT (self->keyboard_widget), self->key_press_event_id);
@@ -1241,14 +1913,11 @@ void
 retro_core_remove_controller (RetroCore *self,
                               guint      port)
 {
-  RetroCoreEnvironmentInternal *internal;
 
   g_return_if_fail (RETRO_IS_CORE (self));
 
-  internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
-
   // FIXME Do that only if a controller is plugged into that port.
-  g_hash_table_remove (internal->controllers, &port);
+  g_hash_table_remove (self->controllers, &port);
   retro_core_controller_disconnected (self, port);
 }
 
@@ -1264,11 +1933,52 @@ retro_core_remove_controller (RetroCore *self,
 RetroControllerIterator *
 retro_core_iterate_controllers (RetroCore *self)
 {
-  RetroCoreEnvironmentInternal *internal;
 
   g_return_val_if_fail (RETRO_IS_CORE (self), NULL);
 
-  internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
+  return retro_controller_iterator_new (self->controllers);
+}
+
+/**
+ * retro_core_new:
+ * @filename: the filename of a Libretro core
+ *
+ * Creates a new #RetroCore.
+ *
+ * Returns: (transfer full): a new #RetroCore
+ */
+RetroCore *
+retro_core_new (const gchar *filename)
+{
+  RetroCore *self;
+  GFile *file;
+  GFile *relative_path_file;
+  gchar *libretro_path;
+
+  g_return_val_if_fail (filename != NULL, NULL);
+
+  self = g_object_new (RETRO_TYPE_CORE, NULL);
+
+  retro_core_set_filename (self, filename);
+
+  file = g_file_new_for_path (filename);
+  relative_path_file = g_file_resolve_relative_path (file, "");
+
+  g_object_unref (file);
+
+  libretro_path = g_file_get_path (relative_path_file);
+
+  g_object_unref (relative_path_file);
+
+  retro_core_set_libretro_path (self, libretro_path);
+  self->module = retro_module_new (libretro_path);
+
+  g_free (libretro_path);
+
+  retro_core_set_callbacks (self);
+  self->controllers = g_hash_table_new_full (g_int_hash, g_int_equal,
+                                             g_free, g_object_unref);
+  self->options = retro_options_new ();
 
-  return retro_controller_iterator_new (internal->controllers);
+  return self;
 }
diff --git a/retro-gtk/retro-core.h b/retro-gtk/retro-core.h
new file mode 100644
index 0000000..4898478
--- /dev/null
+++ b/retro-gtk/retro-core.h
@@ -0,0 +1,88 @@
+// This file is part of retro-gtk. License: GPL-3.0+.
+
+#ifndef RETRO_CORE_H
+#define RETRO_CORE_H
+
+#if !defined(__RETRO_GTK_INSIDE__) && !defined(RETRO_GTK_COMPILATION)
+# error "Only <retro-gtk.h> can be included directly."
+#endif
+
+#include <gtk/gtk.h>
+#include "retro-controller-iterator.h"
+#include "retro-device-type.h"
+#include "retro-input-device.h"
+#include "retro-memory-type.h"
+
+G_BEGIN_DECLS
+
+#define RETRO_TYPE_CORE (retro_core_get_type())
+
+G_DECLARE_FINAL_TYPE (RetroCore, retro_core, RETRO, CORE, GObject)
+
+RetroCore *retro_core_new (const gchar *filename);
+guint retro_core_get_api_version (RetroCore *self);
+const gchar *retro_core_get_filename (RetroCore *self);
+const gchar *retro_core_get_system_directory (RetroCore *self);
+void retro_core_set_system_directory (RetroCore   *self,
+                                      const gchar *system_directory);
+const gchar *retro_core_get_libretro_path (RetroCore *self);
+void retro_core_set_libretro_path (RetroCore   *self,
+                                   const gchar *libretro_path);
+const gchar *retro_core_get_content_directory (RetroCore *self);
+void retro_core_set_content_directory (RetroCore   *self,
+                                       const gchar *content_directory);
+const gchar *retro_core_get_save_directory (RetroCore *self);
+void retro_core_set_save_directory (RetroCore   *self,
+                                    const gchar *save_directory);
+gboolean retro_core_get_is_initiated (RetroCore *self);
+gboolean retro_core_get_game_loaded (RetroCore *self);
+gboolean retro_core_get_support_no_game (RetroCore *self);
+gdouble retro_core_get_frames_per_second (RetroCore *self);
+void retro_core_boot (RetroCore  *self,
+                      GError    **error);
+void retro_core_set_medias (RetroCore    *self,
+                            const gchar **uris);
+void retro_core_set_current_media (RetroCore  *self,
+                                   guint       media_index,
+                                   GError    **error);
+void retro_core_set_controller_port_device (RetroCore       *self,
+                                            guint            port,
+                                            RetroDeviceType  controller);
+void retro_core_reset (RetroCore *self);
+void retro_core_run (RetroCore *self);
+gboolean retro_core_supports_serialization (RetroCore *self);
+guint8 *retro_core_get_state (RetroCore  *self,
+                              gsize      *length,
+                              GError    **error);
+void retro_core_set_state (RetroCore     *self,
+                           const guint8  *data,
+                           gsize          length,
+                           GError       **error);
+gsize retro_core_get_memory_size (RetroCore       *self,
+                                  RetroMemoryType  memory_type);
+guint8 *retro_core_get_memory (RetroCore       *self,
+                              RetroMemoryType  memory_type,
+                              gsize           *length);
+void retro_core_set_memory (RetroCore       *self,
+                            RetroMemoryType  memory_type,
+                            guint8          *data,
+                            gsize            length);
+void retro_core_poll_controllers (RetroCore *self);
+gint16 retro_core_get_controller_input_state (RetroCore       *self,
+                                              uint             port,
+                                              RetroDeviceType  controller_type,
+                                              guint            index,
+                                              guint            id);
+guint64 retro_core_get_controller_capabilities (RetroCore *self);
+void retro_core_set_controller (RetroCore        *self,
+                                guint             port,
+                                RetroInputDevice *controller);
+void retro_core_set_keyboard (RetroCore *self,
+                              GtkWidget *widget);
+void retro_core_remove_controller (RetroCore *self,
+                                   guint      port);
+RetroControllerIterator *retro_core_iterate_controllers (RetroCore *self);
+
+G_END_DECLS
+
+#endif /* RETRO_CORE_H */
diff --git a/retro-gtk/retro-environment.c b/retro-gtk/retro-environment.c
index 0cf5a98..4ff59c0 100644
--- a/retro-gtk/retro-environment.c
+++ b/retro-gtk/retro-environment.c
@@ -33,19 +33,16 @@ rumble_callback_set_rumble_state (guint             port,
                                   guint16           strength)
 {
   RetroCore *self;
-  RetroCoreEnvironmentInternal *internal;
   RetroInputDevice *controller;
 
   self = retro_core_get_cb_data ();
 
   g_return_val_if_fail (RETRO_IS_CORE (self), FALSE);
 
-  internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
-
-  if (!g_hash_table_contains (internal->controllers, &port))
+  if (!g_hash_table_contains (self->controllers, &port))
     return FALSE;
 
-  controller = g_hash_table_lookup (internal->controllers, &port);
+  controller = g_hash_table_lookup (self->controllers, &port);
 
   if (controller == NULL)
     return FALSE;
@@ -64,7 +61,6 @@ on_log (guint level, const gchar *format, ...)
   gchar *message;
   va_list args;
 
-
   self = retro_core_get_cb_data ();
   if (!self)
     g_return_if_reached ();
@@ -154,7 +150,7 @@ static gboolean
 get_overscan (RetroCore *self,
               gboolean  *overscan)
 {
-  *overscan = RETRO_CORE_ENVIRONMENT_INTERNAL (self)->overscan;
+  *overscan = self->overscan;
 
   return TRUE;
 }
@@ -190,15 +186,12 @@ static gboolean
 get_variable (RetroCore     *self,
               RetroVariable *variable)
 {
-  RetroCoreEnvironmentInternal *internal;
   const gchar *value;
 
-  internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
-
-  if (!retro_options_contains (internal->options, variable->key))
+  if (!retro_options_contains (self->options, variable->key))
     return FALSE;
 
-  value = retro_options_get_option_value (internal->options, variable->key);
+  value = retro_options_get_option_value (self->options, variable->key);
   variable->value = g_strdup (value); // FIXME Is that a memory leak?
 
   return TRUE;
@@ -208,11 +201,7 @@ static gboolean
 get_variable_update (RetroCore *self,
                      gboolean  *update)
 {
-  RetroCoreEnvironmentInternal *internal;
-
-  internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
-
-  *update = retro_options_get_variable_update (internal->options);
+  *update = retro_options_get_variable_update (self->options);
 
   return TRUE;
 }
@@ -221,7 +210,7 @@ static gboolean
 set_disk_control_interface (RetroCore                *self,
                             RetroDiskControlCallback *callback)
 {
-  RETRO_CORE_ENVIRONMENT_INTERNAL (self)->disk_control_callback = callback;
+  self->disk_control_callback = callback;
 
   return TRUE;
 }
@@ -242,7 +231,7 @@ static gboolean
 set_keyboard_callback (RetroCore             *self,
                        RetroKeyboardCallback *callback)
 {
-  RETRO_CORE_ENVIRONMENT_INTERNAL (self)->keyboard_callback = *callback;
+  self->keyboard_callback = *callback;
 
   return TRUE;
 }
@@ -261,7 +250,7 @@ static gboolean
 set_pixel_format (RetroCore              *self,
                   const RetroPixelFormat *pixel_format)
 {
-  RETRO_CORE_ENVIRONMENT_INTERNAL (self)->pixel_format = *pixel_format;
+  self->pixel_format = *pixel_format;
 
   return TRUE;
 }
@@ -270,7 +259,7 @@ static gboolean
 set_rotation (RetroCore           *self,
               const RetroRotation *rotation)
 {
-  RETRO_CORE_ENVIRONMENT_INTERNAL (self)->rotation = *rotation;
+  self->rotation = *rotation;
 
   return TRUE;
 }
@@ -297,13 +286,10 @@ static gboolean
 set_variables (RetroCore     *self,
                RetroVariable *variable_array)
 {
-  RetroCoreEnvironmentInternal *internal;
   int i;
 
-  internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
-
   for (i = 0 ; variable_array[i].key && variable_array[i].value ; i++)
-    retro_options_insert_variable (internal->options, &variable_array[i]);
+    retro_options_insert_variable (self->options, &variable_array[i]);
 
   return TRUE;
 }
@@ -432,7 +418,6 @@ on_video_refresh (guint8 *data,
                   gsize   pitch)
 {
   RetroCore *self;
-  RetroCoreEnvironmentInternal *internal;
 
   if (data == NULL)
     return;
@@ -442,11 +427,9 @@ on_video_refresh (guint8 *data,
   if (self == NULL)
     g_return_if_reached ();
 
-  internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
-
   g_signal_emit_by_name (self, "video_output", data, pitch * height,
-                         width, height, pitch, internal->pixel_format,
-                         internal->aspect_ratio);
+                         width, height, pitch, self->pixel_format,
+                         self->aspect_ratio);
 }
 
 // TODO This is internal, make it private as soon as possible.
@@ -461,7 +444,6 @@ on_audio_sample (gint16 left,
                  gint16 right)
 {
   RetroCore *self;
-  RetroCoreEnvironmentInternal *internal;
   gint16 samples[] = { left, right };
 
   self = retro_core_get_cb_data ();
@@ -469,12 +451,10 @@ on_audio_sample (gint16 left,
   if (self == NULL)
     g_return_if_reached ();
 
-  internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
-
-  if (internal->sample_rate <= 0.0)
+  if (self->sample_rate <= 0.0)
     return;
 
-  g_signal_emit_by_name (self, "audio_output", samples, 2, internal->sample_rate);
+  g_signal_emit_by_name (self, "audio_output", samples, 2, self->sample_rate);
 }
 
 static gsize
@@ -482,19 +462,16 @@ on_audio_sample_batch (gint16 *data,
                        int     frames)
 {
   RetroCore *self;
-  RetroCoreEnvironmentInternal *internal;
 
   self = retro_core_get_cb_data ();
 
   if (self == NULL)
     g_return_val_if_reached (0);
 
-  internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
-
-  if (internal->sample_rate <= 0.0)
+  if (self->sample_rate <= 0.0)
     return 0;
 
-  g_signal_emit_by_name (self, "audio_output", data, frames * 2, internal->sample_rate);
+  g_signal_emit_by_name (self, "audio_output", data, frames * 2, self->sample_rate);
 
   // FIXME What should be returned?
   return 0;
@@ -533,13 +510,10 @@ on_input_state (guint port,
 void
 retro_core_set_environment_interface (RetroCore *self)
 {
-  RetroCoreEnvironmentInternal *internal;
   RetroModule *module;
   RetroCallbackSetter set_environment;
 
-  internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
-
-  module = internal->module;
+  module = self->module;
   set_environment = retro_module_get_set_environment (module);
 
   retro_core_push_cb_data (self);
@@ -551,7 +525,6 @@ retro_core_set_environment_interface (RetroCore *self)
 void
 retro_core_set_callbacks (RetroCore *self)
 {
-  RetroCoreEnvironmentInternal *internal;
   RetroModule *module;
   RetroCallbackSetter set_video_refresh;
   RetroCallbackSetter set_audio_sample;
@@ -559,9 +532,7 @@ retro_core_set_callbacks (RetroCore *self)
   RetroCallbackSetter set_input_poll;
   RetroCallbackSetter set_input_state;
 
-  internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
-
-  module = internal->module;
+  module = self->module;
   set_video_refresh = retro_module_get_set_video_refresh (module);
   set_audio_sample = retro_module_get_set_audio_sample (module);
   set_audio_sample_batch = retro_module_get_set_audio_sample_batch (module);
@@ -582,18 +553,14 @@ void
 retro_core_set_system_av_info (RetroCore         *self,
                                RetroSystemAvInfo *system_av_info)
 {
-  RetroCoreEnvironmentInternal *internal;
-
-  internal = RETRO_CORE_ENVIRONMENT_INTERNAL (self);
-
-  if (self->_frames_per_second != system_av_info->timing.fps) {
-    self->_frames_per_second = system_av_info->timing.fps;
+  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");
   }
   if (system_av_info->geometry.aspect_ratio > 0.f)
-    internal->aspect_ratio = system_av_info->geometry.aspect_ratio;
+    self->aspect_ratio = system_av_info->geometry.aspect_ratio;
   else
-    internal->aspect_ratio = (float) system_av_info->geometry.base_width /
+    self->aspect_ratio = (float) system_av_info->geometry.base_width /
                              (float) system_av_info->geometry.base_height;
-  internal->sample_rate = system_av_info->timing.sample_rate;
+  self->sample_rate = system_av_info->timing.sample_rate;
 }
diff --git a/retro-gtk/retro-gtk.h b/retro-gtk/retro-gtk.h
index 4f0affb..828b5b8 100644
--- a/retro-gtk/retro-gtk.h
+++ b/retro-gtk/retro-gtk.h
@@ -11,6 +11,7 @@
 
 #include "retro-analog-id.h"
 #include "retro-analog-index.h"
+#include "retro-core.h"
 #include "retro-core-descriptor.h"
 #include "retro-core-view.h"
 #include "retro-device-type.h"
diff --git a/retro-gtk/retro-log.c b/retro-gtk/retro-log.c
index 27340b5..d8219a3 100644
--- a/retro-gtk/retro-log.c
+++ b/retro-gtk/retro-log.c
@@ -1,6 +1,6 @@
 // This file is part of retro-gtk. License: GPL-3.0+.
 
-#include "retro-gtk-internal.h"
+#include "retro-core.h"
 
 /**
  * retro_g_log:
diff --git a/retro-gtk/retro-log.h b/retro-gtk/retro-log.h
index 69b2377..d96465d 100644
--- a/retro-gtk/retro-log.h
+++ b/retro-gtk/retro-log.h
@@ -8,12 +8,10 @@
 #endif
 
 #include <glib-object.h>
+#include "retro-core.h"
 
 G_BEGIN_DECLS
 
-// FIXME Remove as soon as possible.
-typedef struct _RetroCore RetroCore;
-
 void retro_g_log (RetroCore      *self,
                   const gchar    *log_domain,
                   GLogLevelFlags  log_level,
diff --git a/retro-gtk/retro-main-loop.h b/retro-gtk/retro-main-loop.h
index a105d4f..bf2052f 100644
--- a/retro-gtk/retro-main-loop.h
+++ b/retro-gtk/retro-main-loop.h
@@ -7,13 +7,10 @@
 # error "Only <retro-gtk.h> can be included directly."
 #endif
 
-#include <glib-object.h>
+#include "retro-core.h"
 
 G_BEGIN_DECLS
 
-// FIXME Remove as soon as possible.
-typedef struct _RetroCore RetroCore;
-
 #define RETRO_TYPE_MAIN_LOOP (retro_main_loop_get_type())
 
 G_DECLARE_FINAL_TYPE (RetroMainLoop, retro_main_loop, RETRO, MAIN_LOOP, GObject)
diff --git a/retro-gtk/retro-module.h b/retro-gtk/retro-module.h
index e148890..8c9ba26 100644
--- a/retro-gtk/retro-module.h
+++ b/retro-gtk/retro-module.h
@@ -8,8 +8,9 @@
 #endif
 
 #include <glib-object.h>
-#include "retro-gtk-internal.h"
+#include "retro-device-type.h"
 #include "retro-game-info.h"
+#include "retro-memory-type.h"
 #include "retro-system-av-info.h"
 #include "retro-system-info.h"
 
diff --git a/retro-gtk/retro-rumble-effect.h b/retro-gtk/retro-rumble-effect.h
index 93e314d..d846c78 100644
--- a/retro-gtk/retro-rumble-effect.h
+++ b/retro-gtk/retro-rumble-effect.h
@@ -7,7 +7,7 @@
 # error "Only <retro-gtk.h> can be included directly."
 #endif
 
-#include <glib.h>
+#include <glib-object.h>
 
 G_BEGIN_DECLS
 


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