[retro-gtk/wip/aplazas/core-view: 4/8] core-view: Add joypad support from keyboard inputs



commit ec2ff1a18c6fab479ffe9b1b1e29f6dfdc174acd
Author: Adrien Plazas <kekun plazas laposte net>
Date:   Sun Jul 30 12:50:50 2017 +0100

    core-view: Add joypad support from keyboard inputs

 retro-gtk/retro-core-view-extern.c |  111 +++++++++++++++++++++++++++++++++++-
 retro-gtk/retro-core-view.vala     |    9 +++
 2 files changed, 119 insertions(+), 1 deletions(-)
---
diff --git a/retro-gtk/retro-core-view-extern.c b/retro-gtk/retro-core-view-extern.c
index b8ea03b..be9a1ef 100644
--- a/retro-gtk/retro-core-view-extern.c
+++ b/retro-gtk/retro-core-view-extern.c
@@ -1,10 +1,114 @@
 // This file is part of retro-gtk. License: GPL-3.0+.
 
+#include <linux/input-event-codes.h>
 #include "retro-gtk-internal.h"
 #include "retro-core-view-input-device.h"
 
+static guint16 DEFAULT_KEY_JOYPAD_BUTTON_MAPPING[RETRO_JOYPAD_ID_COUNT] = {
+  KEY_S,
+  KEY_A,
+  KEY_BACKSPACE,
+  KEY_ENTER,
+  KEY_UP,
+  KEY_DOWN,
+  KEY_LEFT,
+  KEY_RIGHT,
+  KEY_D,
+  KEY_W,
+  KEY_Q,
+  KEY_E,
+  KEY_Z,
+  KEY_C,
+  KEY_1,
+  KEY_3,
+};
+
 /* Private */
 
+static void
+set_input_pressed (GHashTable *table,
+                   guint       input)
+{
+  static gboolean value = TRUE;
+
+  if (g_hash_table_contains (table, &input))
+    g_hash_table_replace (table,
+                          g_memdup (&input, sizeof (guint)),
+                          g_memdup (&value, sizeof (gboolean)));
+  else
+    g_hash_table_insert (table,
+                         g_memdup (&input, sizeof (guint)),
+                         g_memdup (&value, sizeof (gboolean)));
+}
+
+static void
+set_input_released (GHashTable *table,
+                    guint       input)
+{
+  g_hash_table_remove (table, &input);
+}
+
+static gboolean
+get_input_state (GHashTable *table,
+                 guint       input)
+{
+  return g_hash_table_contains (table, &input);
+}
+
+// FIXME Make static as soon as possible.
+gboolean
+retro_core_view_on_key_press_event (RetroCoreView *self,
+                                    GtkWidget     *source,
+                                    GdkEventKey   *event)
+{
+  g_return_val_if_fail (self != NULL, FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  set_input_pressed (self->key_state, event->hardware_keycode);
+
+  return FALSE;
+}
+
+// FIXME Make static as soon as possible.
+gboolean
+retro_core_view_on_key_release_event (RetroCoreView *self,
+                                      GtkWidget     *source,
+                                      GdkEventKey   *event)
+{
+  g_return_val_if_fail (self != NULL, FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  set_input_released (self->key_state, event->hardware_keycode);
+
+  return FALSE;
+}
+
+static gboolean
+retro_core_view_get_key_state (RetroCoreView *self,
+                               guint16        hardware_keycode)
+{
+  g_return_val_if_fail (self != NULL, FALSE);
+
+  return get_input_state (self->key_state, hardware_keycode);
+}
+
+static gboolean
+retro_core_view_get_joypad_button_state (RetroCoreView *self,
+                                         RetroJoypadId  button)
+{
+  guint16 hardware_keycode;
+
+  g_return_val_if_fail (self != NULL, FALSE);
+
+  if (button >= RETRO_JOYPAD_ID_COUNT)
+    return 0;
+
+  // GDK adds 8 to the Linux input event codes to create the hardware keycode.
+  hardware_keycode = DEFAULT_KEY_JOYPAD_BUTTON_MAPPING[button] + 8;
+
+  return retro_core_view_get_key_state (self, hardware_keycode);
+}
+
 // FIXME Make static as soon as possible.
 gint16
 retro_core_view_get_input_state (RetroCoreView   *self,
@@ -15,6 +119,11 @@ retro_core_view_get_input_state (RetroCoreView   *self,
   g_return_val_if_fail (self != NULL, 0);
 
   switch (device) {
+  case RETRO_DEVICE_TYPE_JOYPAD:
+    if (id >= RETRO_JOYPAD_ID_COUNT)
+      return 0;
+
+    return retro_core_view_get_joypad_button_state (self, id) ? G_MAXINT16 : 0;
   default:
     return 0;
   }
@@ -26,7 +135,7 @@ retro_core_view_get_device_capabilities (RetroCoreView *self)
 {
   g_return_val_if_fail (self != NULL, 0);
 
-  return 0;
+  return 1 << RETRO_DEVICE_TYPE_JOYPAD;
 }
 
 /* Public */
diff --git a/retro-gtk/retro-core-view.vala b/retro-gtk/retro-core-view.vala
index 4e46225..a180fbe 100644
--- a/retro-gtk/retro-core-view.vala
+++ b/retro-gtk/retro-core-view.vala
@@ -4,6 +4,8 @@ public class Retro.CoreView : Gtk.EventBox {
        private Core core;
        private CairoDisplay display;
 
+       internal HashTable<uint?, bool?> key_state;
+
        construct {
                can_focus = true;
 
@@ -11,6 +13,11 @@ public class Retro.CoreView : Gtk.EventBox {
                display.visible = true;
                display.can_focus = false;
                add (display);
+
+               key_state = new HashTable<uint?, bool?> (int_hash, int_equal);
+
+               key_press_event.connect (on_key_press_event);
+               key_release_event.connect (on_key_release_event);
        }
 
        public void set_core (Core? core) {
@@ -26,4 +33,6 @@ public class Retro.CoreView : Gtk.EventBox {
        public extern InputDevice as_input_device (DeviceType device_type);
        internal extern int16 get_input_state (DeviceType device, uint index, uint id);
        internal extern uint64 get_device_capabilities ();
+       internal extern bool on_key_press_event (Gtk.Widget source, Gdk.EventKey event);
+       internal extern bool on_key_release_event (Gtk.Widget source, Gdk.EventKey event);
 }


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