Skip to content
Commits on Source (36)
=============
Version 1.0.2
=============
* RetroCoreDescriptor: Propagate an accidentally unhandled error.
* Implement mouse buttons 4 and 5.
* Fix the GLES context initialization.
* Drop the code making temporary copies of the core to avoid static
variable collisions, this isn't needed anymore as such collisions
can't happen since a single instance of a core is used per subprocess.
* Debug:
- Catch SIGSEGV, SIGABRT or any crash on the runner and print a
backtrace when the RETRO_DEBUG environement variable is set to 1.
- Print more debug info o successful Libretro environement commands
when the RETRO_DEBUG environement variable is set to 1.
* Libretro environment commands:
- Set the log domain to RetroEnvironment.
- Fix ABI issues by corretly using bool instead of gboolean for command
parameters.
- Prevent setting unknown pixel formats and rotations.
- Better log hardware rendering context support errors.
- Log a critical error when getting a variable failed.
- Log a critical error when receiving un unknown and unimplemented
commands.
* Generalize usage of auto cleanups.
* Many code style cleanups.
=============
Version 1.0.1
=============
......
......@@ -11,8 +11,7 @@ RetroGTK is a framework easing the use of Libretro cores in conjunction with
It encourages the cores to be installed in a well defined centralized place —
namely the `libretro` subdirectory of your `lib` directory — and it recommends
them to come with [Libretro core descriptors]
(https://gnome.pages.gitlab.gnome.org/retro-gtk/doc/master/libretro-core-descriptor.html).
them to come with [Libretro core descriptors](https://gnome.pages.gitlab.gnome.org/retro-gtk/doc/master/libretro-core-descriptor.html).
## Example
......
......@@ -835,15 +835,6 @@ struct retro_memory_map
};
```
## Mouse
The following mouse buttons are unimplemented:
```
#define RETRO_DEVICE_ID_MOUSE_BUTTON_4 9
#define RETRO_DEVICE_ID_MOUSE_BUTTON_5 10
```
## Overscan
Overscan is implemented by `RetroCore.overscan` but is never set and can't be
......
......@@ -22,7 +22,7 @@ retro_demo_open (GApplication *application,
const gchar *hint)
{
RetroDemoApplication *self;
char *module_path;
g_autofree char *module_path = NULL;
GError *error = NULL;
self = RETRO_DEMO_APPLICATION (application);
......@@ -35,20 +35,17 @@ retro_demo_open (GApplication *application,
module_path = g_file_get_path (files[0]);
self->core = retro_core_new (module_path);
g_free (module_path);
if (self->core == NULL)
return;
if (n_files > 1) {
gchar **medias;
gint i;
g_auto (GStrv) medias = NULL;
medias = g_new0 (gchar *, n_files);
for (i = 1; i < n_files; i++)
for (gsize i = 1; i < n_files; i++)
medias[i - 1] = g_file_get_uri (files[i]);
retro_core_set_medias (self->core, (const gchar *const *) medias);
g_strfreev (medias);
}
retro_core_boot (self->core, &error);
......@@ -73,8 +70,7 @@ retro_demo_application_finalize (GObject *object)
{
RetroDemoApplication *self = RETRO_DEMO_APPLICATION (object);
if (self->core != NULL)
g_object_unref (self->core);
g_clear_object (&self->core);
G_OBJECT_CLASS (retro_demo_application_parent_class)->finalize (object);
}
......@@ -134,7 +130,7 @@ gint
main (gint argc,
gchar *argv[])
{
RetroDemoApplication *app;
g_autoptr (RetroDemoApplication) app = NULL;
int status;
g_set_prgname ("retro-demo");
......@@ -142,7 +138,6 @@ main (gint argc,
app = retro_demo_application_new();
status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
return status;
}
......@@ -11,6 +11,7 @@ private_headers = [
'retro-controller-iterator-private.h',
'retro-controller-state-private.h',
'retro-core-view-controller-private.h',
'retro-debug-private.h',
'retro-framebuffer-private.h',
'retro-gl-display-private.h',
'retro-glsl-filter-private.h',
......
project('retro-gtk','c',
version: '1.0.1',
version: '1.0.2',
meson_version: '>= 0.50.0',
)
......
This diff is collapsed.
......@@ -24,20 +24,17 @@ retro_core_view_controller_get_input_state (RetroController *base,
RetroInput *input)
{
RetroCoreViewController *self = RETRO_CORE_VIEW_CONTROLLER (base);
gpointer view;
g_autoptr (RetroCoreView) view = NULL;
gint16 result;
if (retro_input_get_controller_type (input) != self->controller_type)
return 0;
view = g_weak_ref_get (&self->view);
if (view == NULL)
return 0;
result = retro_core_view_get_input_state (RETRO_CORE_VIEW (view), input);
g_object_unref (G_OBJECT (view));
result = retro_core_view_get_input_state (view, input);
return result;
}
......@@ -54,18 +51,14 @@ static guint64
retro_core_view_controller_get_capabilities (RetroController *base)
{
RetroCoreViewController *self = RETRO_CORE_VIEW_CONTROLLER (base);
gpointer view;
g_autoptr (GObject) view = g_weak_ref_get (&self->view);
guint64 capabilities;
view = g_weak_ref_get (&self->view);
if (view == NULL)
return 0;
capabilities = retro_core_view_get_controller_capabilities (RETRO_CORE_VIEW (view));
g_object_unref (G_OBJECT (view));
return capabilities & (1 << self->controller_type);
}
......
......@@ -129,7 +129,7 @@ grab (RetroCoreView *self,
{
GdkSeat *seat;
GdkDisplay *display;
GdkCursor *cursor;
g_autoptr (GdkCursor) cursor = NULL;
GdkScreen *screen = NULL;
GdkMonitor *monitor;
GdkRectangle monitor_geometry;
......@@ -138,13 +138,6 @@ grab (RetroCoreView *self,
g_assert (window != NULL);
g_assert (event != NULL);
if (self->grabbed_device != NULL)
g_object_unref (self->grabbed_device);
if (self->grabbed_screen != NULL)
g_object_unref (self->grabbed_screen);
self->grabbed_device = g_object_ref (device);
seat = gdk_device_get_seat (device);
display = gdk_device_get_display (device);
cursor = gdk_cursor_new_for_display (display, GDK_BLANK_CURSOR);
......@@ -153,17 +146,17 @@ grab (RetroCoreView *self,
gdk_monitor_get_geometry (monitor, &monitor_geometry);
gdk_device_get_position (device, &screen, &self->position_on_grab_x, &self->position_on_grab_y);
self->grabbed_screen = g_object_ref (screen);
self->screen_center_x = monitor_geometry.x + monitor_geometry.width / 2;
self->screen_center_y = monitor_geometry.y + monitor_geometry.height / 2;
self->mouse_x_delta = 0;
self->mouse_y_delta = 0;
g_set_object (&self->grabbed_device, device);
g_set_object (&self->grabbed_screen, screen);
recenter_pointer (self);
g_signal_emit (self, signals[SIGNAL_CONTROLLER_STATE_CHANGED], 0);
g_object_unref (cursor);
}
static void
......@@ -658,7 +651,6 @@ void
retro_core_view_set_as_default_controller (RetroCoreView *self,
RetroCore *core)
{
RetroControllerType type;
RetroController *controller;
guint64 capabilities;
......@@ -667,7 +659,7 @@ retro_core_view_set_as_default_controller (RetroCoreView *self,
capabilities = retro_core_view_get_controller_capabilities (self);
for (type = RETRO_CONTROLLER_TYPE_NONE;
for (RetroControllerType type = RETRO_CONTROLLER_TYPE_NONE;
type < RETRO_CONTROLLER_TYPE_COUNT;
type++) {
if ((capabilities & (1 << type)) == 0)
......
......@@ -167,7 +167,6 @@ static void
retro_core_finalize (GObject *object)
{
RetroCore *self = RETRO_CORE (object);
gint i;
retro_core_set_keyboard (self, NULL);
g_object_unref (self->framebuffer);
......@@ -175,7 +174,7 @@ retro_core_finalize (GObject *object)
if (self->media_uris != NULL)
g_strfreev (self->media_uris);
for (i = 0; i < RETRO_CONTROLLER_TYPE_COUNT; i++)
for (gsize i = 0; i < RETRO_CONTROLLER_TYPE_COUNT; i++)
if (self->default_controllers[i])
free_default_controller_info (self->default_controllers[i]);
g_object_unref (self->default_controller_state);
......@@ -995,15 +994,13 @@ variables_set_cb (IpcRunner *runner,
GVariant *data,
RetroCore *self)
{
GVariantIter *iter;
g_autoptr (GVariantIter) iter = NULL;
gchar *key, *value;
g_variant_get (data, "a(ss)", &iter);
while (g_variant_iter_loop (iter, "(ss)", &key, &value))
insert_variable (self, key, value);
g_variant_iter_free (iter);
}
static void
......@@ -1123,7 +1120,7 @@ retro_core_boot (RetroCore *self,
GHashTableIter iter;
RetroCoreControllerInfo *info;
g_autoptr (GPtrArray) medias_array = NULL;
gint length, i;
gint length;
GError *tmp_error = NULL;
IpcRunner *proxy;
GVariant *variables;
......@@ -1166,7 +1163,7 @@ retro_core_boot (RetroCore *self,
medias_array = g_ptr_array_new ();
if (self->media_uris) {
length = g_strv_length (self->media_uris);
for (i = 0; i < length; i++)
for (gsize i = 0; i < length; i++)
g_ptr_array_add (medias_array, self->media_uris[i]);
}
g_ptr_array_add (medias_array, NULL);
......@@ -1545,7 +1542,7 @@ sync_controller_for_type (RetroControllerState *state,
{
RetroInput input;
g_autofree gint16 *data = NULL;
gint id, index, max_id, max_index, next;
gint max_id, max_index, next;
if (!retro_controller_has_capability (controller, type))
return;
......@@ -1556,8 +1553,8 @@ sync_controller_for_type (RetroControllerState *state,
data = g_new (gint16, max_index * max_id);
next = 0;
for (index = 0; index < max_index; index++) {
for (id = 0; id < max_id; id++) {
for (gint index = 0; index < max_index; index++) {
for (gint id = 0; id < max_id; id++) {
retro_input_init (&input, type, id, index);
data[next++] = retro_controller_get_input_state (controller, &input);
}
......@@ -1579,14 +1576,13 @@ static void
controller_state_changed_cb (RetroController *controller,
RetroCoreControllerInfo *info)
{
gint type;
gboolean rumble = retro_controller_get_supports_rumble (info->controller);
retro_controller_state_lock (info->state);
retro_controller_state_set_supports_rumble (info->state, rumble);
for (type = 1; type < RETRO_CONTROLLER_TYPE_COUNT; type++)
for (gsize type = 1; type < RETRO_CONTROLLER_TYPE_COUNT; type++)
if (retro_controller_has_capability (info->controller, type))
sync_controller_for_type (info->state, info->controller, type);
else
......
......@@ -208,7 +208,7 @@ realize (RetroGLDisplay *self)
GLuint vertex_buffer_object;
GLuint vertex_array_object;
GLuint element_buffer_object;
RetroVideoFilter filter;
RetroVideoFilter current_filter;
GError *inner_error = NULL;
gtk_gl_area_make_current (GTK_GL_AREA (self));
......@@ -224,7 +224,7 @@ realize (RetroGLDisplay *self)
glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, element_buffer_object);
glBufferData (GL_ELEMENT_ARRAY_BUFFER, sizeof (elements), elements, GL_STATIC_DRAW);
for (filter = 0; filter < RETRO_VIDEO_FILTER_COUNT; filter++) {
for (RetroVideoFilter filter = 0; filter < RETRO_VIDEO_FILTER_COUNT; filter++) {
RetroGLSLShader *shader;
self->glsl_filter[filter] = retro_glsl_filter_new (filter_uris[filter], &inner_error);
......@@ -262,12 +262,12 @@ realize (RetroGLDisplay *self)
glGenTextures (1, &self->texture);
glBindTexture (GL_TEXTURE_2D, self->texture);
filter = self->filter >= RETRO_VIDEO_FILTER_COUNT ?
current_filter = self->filter >= RETRO_VIDEO_FILTER_COUNT ?
RETRO_VIDEO_FILTER_SMOOTH :
self->filter;
if (self->glsl_filter[filter] != NULL) {
RetroGLSLShader *shader = retro_glsl_filter_get_shader (self->glsl_filter[filter]);
if (self->glsl_filter[current_filter] != NULL) {
RetroGLSLShader *shader = retro_glsl_filter_get_shader (self->glsl_filter[current_filter]);
retro_glsl_shader_use_program (shader);
}
......@@ -277,13 +277,11 @@ realize (RetroGLDisplay *self)
static void
unrealize (RetroGLDisplay *self)
{
RetroVideoFilter filter;
gtk_gl_area_make_current (GTK_GL_AREA (self));
glDeleteTextures (1, &self->texture);
self->texture = 0;
for (filter = 0; filter < RETRO_VIDEO_FILTER_COUNT; filter++)
for (RetroVideoFilter filter = 0; filter < RETRO_VIDEO_FILTER_COUNT; filter++)
g_clear_object (&self->glsl_filter[filter]);
}
......@@ -314,16 +312,13 @@ static void
retro_gl_display_finalize (GObject *object)
{
RetroGLDisplay *self = (RetroGLDisplay *) object;
RetroVideoFilter filter;
glDeleteTextures (1, &self->texture);
self->texture = 0;
for (filter = 0; filter < RETRO_VIDEO_FILTER_COUNT; filter++)
for (RetroVideoFilter filter = 0; filter < RETRO_VIDEO_FILTER_COUNT; filter++)
g_clear_object (&self->glsl_filter[filter]);
if (self->core != NULL)
g_object_unref (self->core);
if (self->pixbuf != NULL)
g_object_unref (self->pixbuf);
g_clear_object (&self->core);
g_clear_object (&self->pixbuf);
G_OBJECT_CLASS (retro_gl_display_parent_class)->finalize (object);
}
......
......@@ -131,11 +131,10 @@ RetroKeyJoypadMapping *
retro_key_joypad_mapping_new_default (void)
{
RetroKeyJoypadMapping *self;
RetroJoypadId button;
self = g_object_new (RETRO_TYPE_KEY_JOYPAD_MAPPING, NULL);
for (button = 0; button < RETRO_JOYPAD_ID_COUNT; button ++)
for (RetroJoypadId button = 0; button < RETRO_JOYPAD_ID_COUNT; button ++)
/* GDK adds 8 to the Linux input event codes to create the hardware keycode.
* These codes are the only ones not coming from GDK so lets standardize on
* what GDK does.
......
......@@ -73,15 +73,13 @@ new_for_subdirectory (const gchar *lookup_path,
static gboolean
was_current_directory_visited (RetroModuleIterator *self)
{
GFile *current_directory_file;
gchar *current_directory_path;
g_autoptr (GFile) current_directory_file = NULL;
g_autofree gchar *current_directory_path = NULL;
gboolean result;
current_directory_file = g_file_new_for_path (self->directories[self->current_directory]);
current_directory_path = g_file_get_path (current_directory_file);
g_object_unref (current_directory_file);
result = g_hash_table_contains (self->visited, current_directory_path);
g_free (current_directory_path);
return result;
}
......@@ -89,31 +87,25 @@ was_current_directory_visited (RetroModuleIterator *self)
static void
set_current_directory_as_visited (RetroModuleIterator *self)
{
GFile *current_directory_file;
gchar *current_directory_path;
g_autoptr (GFile) current_directory_file = NULL;
g_autofree gchar *current_directory_path = NULL;
current_directory_file = g_file_new_for_path (self->directories[self->current_directory]);
current_directory_path = g_file_get_path (current_directory_file);
g_object_unref (current_directory_file);
g_hash_table_add (self->visited, current_directory_path);
g_hash_table_add (self->visited, g_steal_pointer (&current_directory_path));
}
static gboolean
next_in_sub_directory (RetroModuleIterator *self)
{
if (retro_module_iterator_next (self->sub_directory)) {
if (self->core_descriptor != NULL)
g_object_unref (self->core_descriptor);
g_clear_object (&self->core_descriptor);
self->core_descriptor = retro_module_iterator_get (self->sub_directory);
return TRUE;
}
if (self->sub_directory != NULL) {
g_object_unref (self->sub_directory);
self->sub_directory = NULL;
}
g_clear_object (&self->sub_directory);
return FALSE;
}
......@@ -124,12 +116,9 @@ iterate_next_in_current_path (RetroModuleIterator *self,
GFileInfo *info,
GError **error)
{
const gchar *sub_directory_basename;
GFile *sub_directory_file;
gchar *sub_directory_path;
const gchar *core_descriptor_basename;
GFile *core_descriptor_file;
gchar *core_descriptor_path;
g_autoptr (GFile) core_descriptor_file = NULL;
g_autofree gchar *core_descriptor_path = NULL;
RetroCoreDescriptor *core_descriptor;
GError *tmp_error = NULL;
......@@ -139,19 +128,18 @@ iterate_next_in_current_path (RetroModuleIterator *self,
if (self->recursive &&
g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY &&
self->sub_directory == NULL) {
const gchar *sub_directory_basename;
g_autoptr (GFile) sub_directory_file = NULL;
g_autofree gchar *sub_directory_path = NULL;
sub_directory_basename = g_file_info_get_name (info);
sub_directory_file = g_file_get_child (directory, sub_directory_basename);
sub_directory_path = g_file_get_path (sub_directory_file);
g_object_unref (sub_directory_file);
if (g_hash_table_contains (self->visited, sub_directory_path)) {
g_free (sub_directory_path);
if (g_hash_table_contains (self->visited, sub_directory_path))
return FALSE;
}
self->sub_directory = new_for_subdirectory (sub_directory_path, self->visited);
g_free (sub_directory_path);
return next_in_sub_directory (self);
}
......@@ -162,18 +150,15 @@ iterate_next_in_current_path (RetroModuleIterator *self,
core_descriptor_file = g_file_get_child (directory, core_descriptor_basename);
core_descriptor_path = g_file_get_path (core_descriptor_file);
g_object_unref (core_descriptor_file);
core_descriptor = retro_core_descriptor_new (core_descriptor_path, &tmp_error);
if (G_UNLIKELY (tmp_error != NULL)) {
g_debug ("%s", tmp_error->message);
g_error_free (tmp_error);
g_free (core_descriptor_path);
return FALSE;
}
g_free (core_descriptor_path);
g_clear_object (&self->core_descriptor);
self->core_descriptor = core_descriptor;
......@@ -184,10 +169,8 @@ static gboolean
next_in_current_path (RetroModuleIterator *self,
GError **error)
{
GFile *directory = NULL;
GFileInfo *info = NULL;
g_autoptr (GFile) directory = NULL;
gboolean found = FALSE;
GError *tmp_error = NULL;
if (self->sub_directory != NULL && next_in_sub_directory (self))
......@@ -204,28 +187,21 @@ next_in_current_path (RetroModuleIterator *self,
&tmp_error);
if (G_UNLIKELY (tmp_error != NULL)) {
g_propagate_error (error, tmp_error);
g_object_unref (directory);
g_clear_object (&self->file_enumerator);
return FALSE;
}
}
if (self->file_enumerator == NULL) {
g_object_unref (directory);
if (self->file_enumerator == NULL)
return FALSE;
}
while (TRUE) {
if (info != NULL)
g_object_unref (info);
g_autoptr (GFileInfo) info = NULL;
info = g_file_enumerator_next_file (self->file_enumerator, NULL, &tmp_error);
if (G_UNLIKELY (tmp_error != NULL)) {
g_propagate_error (error, tmp_error);
g_clear_object (&info);
g_object_unref (directory);
return FALSE;
}
......@@ -236,22 +212,15 @@ next_in_current_path (RetroModuleIterator *self,
found = iterate_next_in_current_path (self, directory, info, &tmp_error);
if (G_UNLIKELY (tmp_error != NULL)) {
g_propagate_error (error, tmp_error);
g_object_unref (info);
g_object_unref (directory);
return FALSE;
}
if (found) {
g_object_unref (info);
g_object_unref (directory);
if (found)
return TRUE;
}
}
g_clear_object (&self->file_enumerator);
g_object_unref (directory);
return FALSE;
}
......@@ -313,10 +282,7 @@ retro_module_iterator_next (RetroModuleIterator *self)
g_clear_object (&self->file_enumerator);
g_clear_object (&self->core_descriptor);
if (self->sub_directory != NULL) {
g_object_unref (self->sub_directory);
self->sub_directory = NULL;
}
g_clear_object (&self->sub_directory);
return FALSE;
}
......
......@@ -185,9 +185,9 @@ retro_option_new (const gchar *key,
const gchar *definition,
GError **error)
{
RetroOption *self;
g_autoptr (RetroOption) self;
gchar *description_separator;
gchar **values;
g_auto(GStrv) values = NULL;
g_return_val_if_fail (key != NULL, NULL);
g_return_val_if_fail (definition != NULL, NULL);
......@@ -204,8 +204,6 @@ retro_option_new (const gchar *key,
values = g_strsplit (description_separator + 2, "|", 0);
if (G_UNLIKELY (*values == NULL)) {
g_strfreev (values);
g_set_error_literal (error,
RETRO_OPTION_ERROR,
RETRO_OPTION_ERROR_NO_VALUES,
......@@ -219,7 +217,7 @@ retro_option_new (const gchar *key,
self->key = g_strdup (key);
self->description = g_strndup (definition,
description_separator - definition);
self->values = values;
self->values = g_steal_pointer (&values);
return self;
return g_steal_pointer (&self);
}
......@@ -137,27 +137,18 @@ rgba8888_from_video (gconstpointer src,
gsize pitch,
GetRGBA8888 get_pixel)
{
gsize row, src_row, dst_row, col, src_col;
for (gsize row = 0 ; row < height ; row++) {
gsize src_row = row * pitch;
gsize dst_row = row * width;
for (row = 0 ; row < height ; row++) {
src_row = row * pitch;
dst_row = row * width;
for (col = 0 ; col < width ; col++) {
src_col = col * pixel_size;
for (gsize col = 0 ; col < width ; col++) {
gsize src_col = col * pixel_size;
dst[dst_row + col] = get_pixel (src_row + src_col + src);
}
}
}
static void
pixels_free (guchar *pixels,
gpointer data)
{
g_free (pixels);
}
/**
* retro_pixdata_new:
* @data: the video data
......@@ -360,7 +351,7 @@ retro_pixdata_to_pixbuf (RetroPixdata *self)
GDK_COLORSPACE_RGB, TRUE, 8,
self->width, self->height,
self->width * sizeof (rgba8888),
pixels_free, NULL);
(GdkPixbufDestroyNotify) g_free, NULL);
/* x-dpi and y-dpi are deprecated, retro_pixbuf_get_aspect_ratio() and
* retro_pixbuf_set_aspect_ratio() should be used instead. */
......
......@@ -218,23 +218,6 @@ create_connection (GSubprocessLauncher *launcher,
return connection;
}
static gboolean
is_debug (void)
{
gchar **envp;
const gchar *env_value;
gboolean result = FALSE;
envp = g_get_environ ();
env_value = g_environ_getenv (envp, "RETRO_DEBUG");
result = (g_strcmp0 ("1", env_value) == 0);
g_strfreev (envp);
return result;
}
/**
* retro_runner_process_start:
* @self: a #RetroRunnerProcess
......@@ -260,24 +243,12 @@ retro_runner_process_start (RetroRunnerProcess *self,
if (!(connection = create_connection (launcher, 3, error)))
return;
if (is_debug ()) {
if (!(process = g_subprocess_launcher_spawn (launcher, &tmp_error,
"gdb", "-batch", "-ex", "run",
"-ex", "bt", "--args",
RETRO_RUNNER_PATH,
g_get_application_name (),
self->filename, NULL))) {
g_propagate_error (error, tmp_error);
return;
}
} else {
if (!(process = g_subprocess_launcher_spawn (launcher, &tmp_error,
RETRO_RUNNER_PATH,
g_get_application_name (),
self->filename, NULL))) {
g_propagate_error (error, tmp_error);
return;
}
if (!(process = g_subprocess_launcher_spawn (launcher, &tmp_error,
RETRO_RUNNER_PATH,
g_get_application_name (),
self->filename, NULL))) {
g_propagate_error (error, tmp_error);
return;
}
if (!(self->connection = g_dbus_connection_new_sync (G_IO_STREAM (connection),
......
......@@ -21,9 +21,9 @@
RetroVideoFilter
retro_video_filter_from_string (const gchar *filter)
{
GEnumClass* enum_class;
g_autoptr (GEnumClass) enum_class = NULL;
GEnumValue* eval;
RetroVideoFilter result;
GEnumValue* eval = NULL;
g_return_val_if_fail (filter != NULL, RETRO_VIDEO_FILTER_SMOOTH);
......@@ -34,7 +34,5 @@ retro_video_filter_from_string (const gchar *filter)
RETRO_VIDEO_FILTER_SMOOTH :
(RetroVideoFilter) eval->value;
g_type_class_unref (enum_class);
return result;
}
......@@ -457,12 +457,11 @@ variables_set_cb (RetroCore *core,
RetroVariable *variables,
IpcRunnerImpl *self)
{
gint i;
GVariantBuilder* builder;
builder = g_variant_builder_new (G_VARIANT_TYPE ("a(ss)"));
for (i = 0; variables[i].key && variables[i].value; i++)
for (gsize i = 0; variables[i].key && variables[i].value; i++)
g_variant_builder_add (builder, "(ss)", variables[i].key, variables[i].value);
if (retro_core_get_is_initiated (self->core))
......
......@@ -116,13 +116,11 @@ retro_core_finalize (GObject *object)
deinit = retro_module_get_deinit (self->module);
deinit ();
if (self->media_uris != NULL)
g_strfreev (self->media_uris);
g_clear_pointer (&self->media_uris, g_strfreev);
g_object_unref (self->module);
g_object_unref (self->framebuffer);
if (self->default_controller)
g_object_unref (self->default_controller);
g_clear_object (&self->default_controller);
g_hash_table_unref (self->controllers);
g_hash_table_unref (self->variables);
g_hash_table_unref (self->variable_overrides);
......@@ -820,7 +818,6 @@ load_discs (RetroCore *self,
{
guint length;
gboolean fullpath;
guint index;
GError *tmp_error = NULL;
set_disk_ejected (self, TRUE, &tmp_error);
......@@ -848,7 +845,7 @@ load_discs (RetroCore *self,
}
fullpath = get_needs_full_path (self);
for (index = 0; index < length; index++) {
for (gsize index = 0; index < length; index++) {
g_autoptr (GFile) file = g_file_new_for_uri (self->media_uris[index]);
g_autofree gchar *path = g_file_get_path (file);
g_autoptr (RetroGameInfo) game_info = fullpath ?
......@@ -1238,7 +1235,7 @@ retro_core_get_support_no_game (RetroCore *self)
/**
* retro_core_set_support_no_game:
* @self: a #RetroCore
* @support_no_game: the save directory
* @support_no_game: whether the core supports running with no game
*
* Sets whether the core supports running with no game.
*/
......@@ -1248,6 +1245,8 @@ retro_core_set_support_no_game (RetroCore *self,
{
g_return_if_fail (RETRO_IS_CORE (self));
support_no_game = !!support_no_game;
if (retro_core_get_support_no_game (self) == support_no_game)
return;
......@@ -1320,9 +1319,7 @@ retro_core_set_medias (RetroCore *self,
g_return_if_fail (RETRO_IS_CORE (self));
g_return_if_fail (!retro_core_get_is_initiated (self));
if (self->media_uris != NULL)
g_strfreev (self->media_uris);
g_clear_pointer (&self->media_uris, g_strfreev);
self->media_uris = g_strdupv ((gchar **) uris);
}
......
......@@ -3,11 +3,17 @@
#include "retro-core-private.h"
#include <stdbool.h>
#include "retro-debug-private.h"
#include "retro-input-private.h"
#include "retro-gl-renderer-private.h"
#include "retro-hw-render-callback-private.h"
#include "retro-rumble-effect.h"
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "RetroEnvironment"
#define TRUENESS(boolean) ((boolean) ? "true" : "false")
#define RETRO_ENVIRONMENT_EXPERIMENTAL 0x10000
#define RETRO_ENVIRONMENT_PRIVATE 0x20000
#define RETRO_ENVIRONMENT_SET_ROTATION 1
......@@ -136,7 +142,7 @@ log_cb (guint level, const gchar *format, ...)
break;
default:
g_debug ("Unexpected log level: %d", level);
retro_debug ("Unexpected log level: %d", level);
return;
}
......@@ -150,14 +156,68 @@ log_cb (guint level, const gchar *format, ...)
g_signal_emit_by_name (self, "log", log_domain, log_level, message);
}
static const gchar *
get_input_string (RetroInputDescriptor *descriptor) {
const gchar *controller_type_name = NULL;
g_autoptr (GEnumClass) index_enum_class = NULL;
g_autoptr (GEnumClass) id_enum_class = NULL;
GEnumValue *id_enum_value;
switch (descriptor->controller_type & RETRO_CONTROLLER_TYPE_TYPE_MASK) {
case RETRO_CONTROLLER_TYPE_JOYPAD:
controller_type_name = "joypad";
id_enum_class = g_type_class_ref (RETRO_TYPE_JOYPAD_ID);
break;
case RETRO_CONTROLLER_TYPE_MOUSE:
controller_type_name = "mouse";
id_enum_class = g_type_class_ref (RETRO_TYPE_MOUSE_ID);
break;
case RETRO_CONTROLLER_TYPE_LIGHTGUN:
controller_type_name = "lightgun";
id_enum_class = g_type_class_ref (RETRO_TYPE_LIGHTGUN_ID);
break;
case RETRO_CONTROLLER_TYPE_ANALOG:
controller_type_name = "analog";
index_enum_class = g_type_class_ref (RETRO_TYPE_ANALOG_INDEX);
id_enum_class = g_type_class_ref (RETRO_TYPE_ANALOG_ID);
break;
case RETRO_CONTROLLER_TYPE_POINTER:
controller_type_name = "pointer";
id_enum_class = g_type_class_ref (RETRO_TYPE_POINTER_ID);
break;
case RETRO_CONTROLLER_TYPE_KEYBOARD:
return g_strdup ("keyboard key");
case RETRO_CONTROLLER_TYPE_NONE:
return g_strdup ("none");
default:
return g_strdup ("unknown input");
}
id_enum_value = g_enum_get_value (id_enum_class, descriptor->id);
if (index_enum_class) {
GEnumValue *index_enum_value = g_enum_get_value (index_enum_class, descriptor->index);
return (index_enum_value && id_enum_value) ?
g_strdup_printf ("%s %s %s", controller_type_name, index_enum_value->value_nick, id_enum_value->value_nick) :
g_strdup_printf ("unknown %s input", controller_type_name);
}
return (id_enum_value) ?
g_strdup_printf ("%s %s", controller_type_name, id_enum_value->value_nick) :
g_strdup_printf ("unknown %s input", controller_type_name);
}
/* Environment commands */
static gboolean
get_can_dupe (RetroCore *self,
gboolean *can_dupe)
bool *can_dupe)
{
*can_dupe = TRUE;
retro_debug ("Get can dupe: true");
return TRUE;
}
......@@ -167,6 +227,8 @@ get_content_directory (RetroCore *self,
{
*(content_directory) = retro_core_get_content_directory (self);
retro_debug ("Get content directory: %s", *content_directory);
return TRUE;
}
......@@ -176,6 +238,8 @@ get_input_device_capabilities (RetroCore *self,
{
*capabilities = retro_core_get_controller_capabilities (self);
retro_debug ("Get input device capabilities");
return TRUE;
}
......@@ -207,9 +271,9 @@ get_language (RetroCore *self,
};
const gchar * const *locales = g_get_language_names ();
gsize locale_i, language_i = 0;
gsize language_i = 0;
for (locale_i = 0; locales[locale_i] != NULL; locale_i++) {
for (gsize locale_i = 0; locales[locale_i] != NULL; locale_i++) {
for (language_i = 0;
!g_str_equal (values[language_i].locale, "C") &&
!g_str_equal (locales[locale_i], values[language_i].locale);
......@@ -220,6 +284,8 @@ get_language (RetroCore *self,
*language = values[language_i].language;
retro_debug ("Get language: %s", values[language_i].locale);
return TRUE;
}
......@@ -229,6 +295,8 @@ get_libretro_path (RetroCore *self,
{
*(libretro_directory) = retro_core_get_libretro_path (self);
retro_debug ("Get libretro directory: %s", *libretro_directory);
return TRUE;
}
......@@ -238,15 +306,19 @@ get_log_callback (RetroCore *self,
{
cb->log = log_cb;
retro_debug ("Get log callback");
return TRUE;
}
static gboolean
get_overscan (RetroCore *self,
gboolean *overscan)
bool *overscan)
{
*overscan = self->overscan;
retro_debug ("Get overscan: %s", TRUENESS (*overscan));
return TRUE;
}
......@@ -256,6 +328,8 @@ get_rumble_callback (RetroCore *self,
{
cb->set_rumble_state = rumble_callback_set_rumble_state;
retro_debug ("Get rumble callback");
return TRUE;
}
......@@ -265,6 +339,8 @@ get_save_directory (RetroCore *self,
{
*(save_directory) = retro_core_get_save_directory (self);
retro_debug ("Get save directory: %s", *save_directory);
return TRUE;
}
......@@ -274,6 +350,8 @@ get_system_directory (RetroCore *self,
{
*(system_directory) = retro_core_get_system_directory (self);
retro_debug ("Get system directory: %s", *system_directory);
return TRUE;
}
......@@ -285,11 +363,16 @@ get_variable (RetroCore *self,
value = g_hash_table_lookup (self->variables, variable->key);
if (!value)
if (G_UNLIKELY (!value)) {
g_critical ("Couldn't get variable %s", variable->key);
return FALSE;
}
variable->value = value;
retro_debug ("Get variable %s: %s", variable->key, variable->value);
return TRUE;
}
......@@ -300,6 +383,8 @@ get_variable_update (RetroCore *self,
{
*update = retro_core_get_variable_update (self);
retro_debug ("Get variable update: %s", TRUENESS (*update));
return TRUE;
}
......@@ -329,15 +414,21 @@ set_hw_render (RetroCore *self,
case RETRO_HW_CONTEXT_OPENGLES2:
case RETRO_HW_CONTEXT_OPENGLES3:
case RETRO_HW_CONTEXT_OPENGLES_VERSION:
retro_debug ("Set hardware render callback: OpenGL");
self->renderer = retro_gl_renderer_new (self, callback);
break;
case RETRO_HW_CONTEXT_VULKAN:
g_critical ("Vulkan support isn't implemented");
g_critical ("Couldn't set hardware render callback: Vulkan support is unimplemented");
return FALSE;
case RETRO_HW_CONTEXT_DIRECT3D:
g_critical ("Couldn't set hardware render callback: Direct3D is unsupported");
return FALSE;
default:
g_critical ("Unknown context type: %d", callback->context_type);
g_critical ("Couldn't set hardware render callback for unknown context type %d", callback->context_type);
return FALSE;
}
......@@ -352,6 +443,8 @@ static gboolean
set_disk_control_interface (RetroCore *self,
RetroDiskControlCallback *callback)
{
retro_debug ("Set disk control callback");
self->disk_control_callback = callback;
return TRUE;
......@@ -361,6 +454,11 @@ static gboolean
set_geometry (RetroCore *self,
RetroGameGeometry *geometry)
{
retro_debug ("Set geometry: base %u × %u, max %u × %u, aspect ratio %f",
geometry->base_width, geometry->base_height,
geometry->max_width, geometry->max_height,
geometry->aspect_ratio);
retro_core_set_geometry (self, geometry);
return TRUE;
......@@ -372,7 +470,16 @@ set_input_descriptors (RetroCore *self,
{
int length;
for (length = 0 ; descriptors[length].description ; length++);
for (length = 0 ; descriptors[length].description ; length++)
retro_debug ("Set input descriptor: port %u, type %u, index %u, id %u (%s%s): %s",
descriptors[length].port,
descriptors[length].controller_type,
descriptors[length].index,
descriptors[length].id,
get_input_string (&descriptors[length]),
(descriptors[length].controller_type & ~RETRO_CONTROLLER_TYPE_TYPE_MASK) ? ", specialized" : "",
descriptors[length].description);
retro_core_set_controller_descriptors (self, descriptors, length);
return TRUE;
......@@ -382,6 +489,8 @@ static gboolean
set_keyboard_callback (RetroCore *self,
RetroKeyboardCallback *callback)
{
retro_debug ("Set keyboard callback");
self->keyboard_callback = *callback;
return TRUE;
......@@ -391,6 +500,8 @@ static gboolean
set_message (RetroCore *self,
const RetroMessage *message)
{
retro_debug ("Emit message for %u frames: %s", message->frames, message->msg);
g_signal_emit_by_name (self, "message", message->msg, message->frames);
return TRUE;
......@@ -400,6 +511,25 @@ static gboolean
set_pixel_format (RetroCore *self,
const RetroPixelFormat *pixel_format)
{
switch (*pixel_format) {
case RETRO_PIXEL_FORMAT_XRGB1555:
retro_debug ("Set pixel format: XRGB1555");
break;
case RETRO_PIXEL_FORMAT_XRGB8888:
retro_debug ("Set pixel format: XRGB8888");
break;
case RETRO_PIXEL_FORMAT_RGB565:
retro_debug ("Set pixel format: RGB565");
break;
default:
g_critical ("Couldn't set unknown pixel format %d", *pixel_format);
return FALSE;
}
self->pixel_format = *pixel_format;
return TRUE;
......@@ -409,15 +539,25 @@ static gboolean
set_rotation (RetroCore *self,
const RetroRotation *rotation)
{
if (G_UNLIKELY (*rotation >= CLOCKWISE)) {
g_critical ("Couldn't set unknown rotation %d", *rotation);
return FALSE;
}
retro_debug ("Set rotation: %d°", *rotation * 90);
self->rotation = *rotation;
return TRUE;
}
static gboolean
set_support_no_game (RetroCore *self,
gboolean *support_no_game)
set_support_no_game (RetroCore *self,
const bool *support_no_game)
{
retro_debug ("Set support no game: %s", TRUENESS (*support_no_game));
retro_core_set_support_no_game (self, *support_no_game);
return TRUE;
......@@ -427,6 +567,12 @@ static gboolean
set_system_av_info (RetroCore *self,
RetroSystemAvInfo *system_av_info)
{
retro_debug ("Set system AV info: base %u × %u, max %u × %u, aspect ratio %f, %lf FPS, %lf Hz",
system_av_info->geometry.base_width, system_av_info->geometry.base_height,
system_av_info->geometry.max_width, system_av_info->geometry.max_height,
system_av_info->geometry.aspect_ratio,
system_av_info->timing.fps, system_av_info->timing.sample_rate);
retro_core_set_system_av_info (self, system_av_info);
return TRUE;
......@@ -436,10 +582,11 @@ static gboolean
set_variables (RetroCore *self,
RetroVariable *variable_array)
{
int i;
for (gsize i = 0 ; variable_array[i].key && variable_array[i].value ; i++) {
retro_debug ("Set variable %s: %s", variable_array[i].key, variable_array[i].value);
for (i = 0 ; variable_array[i].key && variable_array[i].value ; i++)
retro_core_insert_variable (self, &variable_array[i]);
}
g_signal_emit_by_name (self, "variables-set", variable_array);
......@@ -449,11 +596,23 @@ set_variables (RetroCore *self,
static gboolean
shutdown (RetroCore *self)
{
retro_debug ("Emit shutdown");
g_signal_emit_by_name (self, "shutdown");
return TRUE;
}
#define RETRO_UNIMPLEMENT_ENVIRONMENT(cmd) \
case cmd: \
G_STMT_START { \
if (cmd & RETRO_ENVIRONMENT_EXPERIMENTAL) \
g_critical ("Unimplemented experimental command %s", #cmd); \
else \
g_critical ("Unimplemented command %s", #cmd); \
return FALSE; \
} G_STMT_END
static gboolean
environment_core_command (RetroCore *self,
unsigned cmd,
......@@ -464,7 +623,7 @@ environment_core_command (RetroCore *self,
switch (cmd) {
case RETRO_ENVIRONMENT_GET_CAN_DUPE:
return get_can_dupe (self, (gboolean *) data);
return get_can_dupe (self, (bool *) data);
case RETRO_ENVIRONMENT_GET_CONTENT_DIRECTORY:
return get_content_directory (self, (const gchar **) data);
......@@ -482,7 +641,7 @@ environment_core_command (RetroCore *self,
return get_log_callback (self, (RetroLogCallback *) data);
case RETRO_ENVIRONMENT_GET_OVERSCAN:
return get_overscan (self, (gboolean *) data);
return get_overscan (self, (bool *) data);
case RETRO_ENVIRONMENT_GET_RUMBLE_INTERFACE:
return get_rumble_callback (self, (RetroRumbleCallback *) data);
......@@ -524,7 +683,7 @@ environment_core_command (RetroCore *self,
return set_rotation (self, (RetroRotation *) data);
case RETRO_ENVIRONMENT_SET_SUPPORT_NO_GAME:
return set_support_no_game (self, (gboolean *) data);
return set_support_no_game (self, (const bool *) data);
case RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO:
return set_system_av_info (self, (RetroSystemAvInfo *) data);
......@@ -535,24 +694,30 @@ environment_core_command (RetroCore *self,
case RETRO_ENVIRONMENT_SHUTDOWN:
return shutdown (self);
case RETRO_ENVIRONMENT_GET_CAMERA_INTERFACE:
case RETRO_ENVIRONMENT_GET_CURRENT_SOFTWARE_FRAMEBUFFER:
case RETRO_ENVIRONMENT_GET_HW_RENDER_INTERFACE:
case RETRO_ENVIRONMENT_GET_LOCATION_INTERFACE:
case RETRO_ENVIRONMENT_GET_PERF_INTERFACE:
case RETRO_ENVIRONMENT_GET_SENSOR_INTERFACE:
case RETRO_ENVIRONMENT_GET_USERNAME:
case RETRO_ENVIRONMENT_SET_AUDIO_CALLBACK:
case RETRO_ENVIRONMENT_SET_CONTROLLER_INFO:
case RETRO_ENVIRONMENT_SET_FRAME_TIME_CALLBACK:
case RETRO_ENVIRONMENT_SET_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE:
case RETRO_ENVIRONMENT_SET_MEMORY_MAPS:
case RETRO_ENVIRONMENT_SET_PERFORMANCE_LEVEL:
case RETRO_ENVIRONMENT_SET_PROC_ADDRESS_CALLBACK:
case RETRO_ENVIRONMENT_SET_SERIALIZATION_QUIRKS:
case RETRO_ENVIRONMENT_SET_SUBSYSTEM_INFO:
case RETRO_ENVIRONMENT_SET_SUPPORT_ACHIEVEMENTS:
RETRO_UNIMPLEMENT_ENVIRONMENT (RETRO_ENVIRONMENT_GET_CAMERA_INTERFACE);
RETRO_UNIMPLEMENT_ENVIRONMENT (RETRO_ENVIRONMENT_GET_CURRENT_SOFTWARE_FRAMEBUFFER);
RETRO_UNIMPLEMENT_ENVIRONMENT (RETRO_ENVIRONMENT_GET_HW_RENDER_INTERFACE);
RETRO_UNIMPLEMENT_ENVIRONMENT (RETRO_ENVIRONMENT_GET_LOCATION_INTERFACE);
RETRO_UNIMPLEMENT_ENVIRONMENT (RETRO_ENVIRONMENT_GET_PERF_INTERFACE);
RETRO_UNIMPLEMENT_ENVIRONMENT (RETRO_ENVIRONMENT_GET_SENSOR_INTERFACE);
RETRO_UNIMPLEMENT_ENVIRONMENT (RETRO_ENVIRONMENT_GET_USERNAME);
RETRO_UNIMPLEMENT_ENVIRONMENT (RETRO_ENVIRONMENT_SET_AUDIO_CALLBACK);
RETRO_UNIMPLEMENT_ENVIRONMENT (RETRO_ENVIRONMENT_SET_CONTROLLER_INFO);
RETRO_UNIMPLEMENT_ENVIRONMENT (RETRO_ENVIRONMENT_SET_FRAME_TIME_CALLBACK);
RETRO_UNIMPLEMENT_ENVIRONMENT (RETRO_ENVIRONMENT_SET_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE);
RETRO_UNIMPLEMENT_ENVIRONMENT (RETRO_ENVIRONMENT_SET_MEMORY_MAPS);
RETRO_UNIMPLEMENT_ENVIRONMENT (RETRO_ENVIRONMENT_SET_PERFORMANCE_LEVEL);
RETRO_UNIMPLEMENT_ENVIRONMENT (RETRO_ENVIRONMENT_SET_PROC_ADDRESS_CALLBACK);
RETRO_UNIMPLEMENT_ENVIRONMENT (RETRO_ENVIRONMENT_SET_SERIALIZATION_QUIRKS);
RETRO_UNIMPLEMENT_ENVIRONMENT (RETRO_ENVIRONMENT_SET_SUBSYSTEM_INFO);
RETRO_UNIMPLEMENT_ENVIRONMENT (RETRO_ENVIRONMENT_SET_SUPPORT_ACHIEVEMENTS);
default:
if (cmd & RETRO_ENVIRONMENT_EXPERIMENTAL)
g_critical ("Unknown experimental command %d", cmd ^ RETRO_ENVIRONMENT_EXPERIMENTAL);
else
g_critical ("Unknown command %d", cmd);
return FALSE;
}
}
......@@ -587,7 +752,7 @@ video_refresh_cb (guint8 *data,
if (self->renderer) {
gint pixel_size;
if (data && data != RETRO_HW_FRAME_BUFFER_VALID) {
if (G_UNLIKELY (data && data != RETRO_HW_FRAME_BUFFER_VALID)) {
g_critical ("Video data must be NULL or RETRO_HW_FRAME_BUFFER_VALID if "
"rendering to hardware.");
......