[retro-gtk/gamepad: 3/3] inpupt: Add Gamepad
- From: Adrien Plazas <aplazas src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [retro-gtk/gamepad: 3/3] inpupt: Add Gamepad
- Date: Tue, 25 Jul 2017 10:31:21 +0000 (UTC)
commit 1c7df68bbe06fb12d4d4407577186f2e9055af95
Author: Adrien Plazas <kekun plazas laposte net>
Date: Tue Jul 25 12:02:49 2017 +0200
inpupt: Add Gamepad
This will help frontends to use gamepads with the library. The gamepad
object expects Linux event codes rather than Libretro inputs.
retro-gtk/Makefile.am | 2 +
retro-gtk/input/device.vala | 6 +-
retro-gtk/input/gamepad.vala | 35 +++++++
retro-gtk/input/retro-gamepad.c | 202 +++++++++++++++++++++++++++++++++++++++
4 files changed, 243 insertions(+), 2 deletions(-)
---
diff --git a/retro-gtk/Makefile.am b/retro-gtk/Makefile.am
index 344b4f9..42ba049 100644
--- a/retro-gtk/Makefile.am
+++ b/retro-gtk/Makefile.am
@@ -31,12 +31,14 @@ libretro_gtk_la_SOURCES = \
\
input/controller.vala \
input/device.vala \
+ input/gamepad.vala \
input/gamepad-configuration.vala \
input/input.vala \
input/input-device.vala \
input/input-device-manager.vala \
input/keyboard-state.vala \
input/mouse.vala \
+ input/retro-gamepad.c \
input/retro-keyboard-key.c \
input/virtual-gamepad.vala \
\
diff --git a/retro-gtk/input/device.vala b/retro-gtk/input/device.vala
index ce8a5bf..e9ff6da 100644
--- a/retro-gtk/input/device.vala
+++ b/retro-gtk/input/device.vala
@@ -62,7 +62,8 @@ public enum JoypadId {
*/
public enum AnalogIndex {
LEFT,
- RIGHT
+ RIGHT,
+ COUNT,
}
/**
@@ -70,7 +71,8 @@ public enum AnalogIndex {
*/
public enum AnalogId {
X,
- Y
+ Y,
+ COUNT,
}
/**
diff --git a/retro-gtk/input/gamepad.vala b/retro-gtk/input/gamepad.vala
new file mode 100644
index 0000000..6f7b117
--- /dev/null
+++ b/retro-gtk/input/gamepad.vala
@@ -0,0 +1,35 @@
+// This file is part of retro-gtk. License: GPL-3.0+.
+
+public class Retro.Gamepad: Object, InputDevice {
+ internal void *internal;
+
+ public Gamepad (bool analog) {
+ internal_init (analog);
+ }
+
+ ~Gamepad () {
+ internal_finalize ();
+ }
+
+ public void poll () {}
+
+ public int16 get_input_state (DeviceType device, uint index, uint id) {
+ return internal_get_input_state (device, index, id);
+ }
+
+ public DeviceType get_device_type () {
+ return internal_get_device_type ();
+ }
+ public uint64 get_device_capabilities () {
+ return internal_get_device_capabilities ();
+ }
+
+ public extern void button_press_event (uint16 button);
+ public extern void button_release_event (uint16 button);
+ public extern void axis_event (uint16 axis, double value);
+ private extern int16 internal_get_input_state (DeviceType device, uint index, uint id);
+ private extern DeviceType internal_get_device_type ();
+ private extern uint64 internal_get_device_capabilities ();
+ private extern void internal_init (bool analog);
+ private extern void internal_finalize ();
+}
diff --git a/retro-gtk/input/retro-gamepad.c b/retro-gtk/input/retro-gamepad.c
new file mode 100644
index 0000000..eec4c7a
--- /dev/null
+++ b/retro-gtk/input/retro-gamepad.c
@@ -0,0 +1,202 @@
+// This file is part of retro-gtk. License: GPL-3.0+.
+
+#include <linux/input-event-codes.h>
+#include "retro-gtk-internal.h"
+
+typedef struct {
+ gboolean analog;
+ gint16 buttons[RETRO_JOYPAD_ID_COUNT];
+ gint16 axes[RETRO_ANALOG_INDEX_COUNT][RETRO_ANALOG_ID_COUNT];
+} RetroGamepadInternal;
+
+#define RETRO_GAMEPAD_INTERNAL(self) ((RetroGamepadInternal *) ((self)->internal))
+
+/* Private */
+
+static RetroJoypadId
+button_to_retro_button (guint16 button)
+{
+ switch (button) {
+ case BTN_A:
+ return RETRO_JOYPAD_ID_B;
+ case BTN_Y:
+ return RETRO_JOYPAD_ID_Y;
+ case BTN_SELECT:
+ return RETRO_JOYPAD_ID_SELECT;
+ case BTN_START:
+ return RETRO_JOYPAD_ID_START;
+ case BTN_DPAD_UP:
+ return RETRO_JOYPAD_ID_UP;
+ case BTN_DPAD_DOWN:
+ return RETRO_JOYPAD_ID_DOWN;
+ case BTN_DPAD_LEFT:
+ return RETRO_JOYPAD_ID_LEFT;
+ case BTN_DPAD_RIGHT:
+ return RETRO_JOYPAD_ID_RIGHT;
+ case BTN_B:
+ return RETRO_JOYPAD_ID_A;
+ case BTN_X:
+ return RETRO_JOYPAD_ID_X;
+ case BTN_TL:
+ return RETRO_JOYPAD_ID_L;
+ case BTN_TR:
+ return RETRO_JOYPAD_ID_R;
+ case BTN_TL2:
+ return RETRO_JOYPAD_ID_L2;
+ case BTN_TR2:
+ return RETRO_JOYPAD_ID_R2;
+ case BTN_THUMBL:
+ return RETRO_JOYPAD_ID_L3;
+ case BTN_THUMBR:
+ return RETRO_JOYPAD_ID_R3;
+ default:
+ return RETRO_JOYPAD_ID_COUNT;
+ }
+
+ return RETRO_JOYPAD_ID_COUNT;
+}
+
+static gboolean
+axis_to_retro_axis (guint16 axis,
+ RetroAnalogIndex *index,
+ RetroAnalogId *id)
+{
+ switch (axis) {
+ case ABS_X:
+ *index = RETRO_ANALOG_INDEX_LEFT;
+ *id = RETRO_ANALOG_ID_X;
+
+ return TRUE;
+ case ABS_Y:
+ *index = RETRO_ANALOG_INDEX_LEFT;
+ *id = RETRO_ANALOG_ID_Y;
+
+ return TRUE;
+ case ABS_RX:
+ *index = RETRO_ANALOG_INDEX_RIGHT;
+ *id = RETRO_ANALOG_ID_X;
+
+ return TRUE;
+ case ABS_RY:
+ *index = RETRO_ANALOG_INDEX_RIGHT;
+ *id = RETRO_ANALOG_ID_Y;
+
+ return TRUE;
+ default:
+ return FALSE;
+ }
+
+ return FALSE;
+}
+
+/* Public */
+
+void
+retro_gamepad_button_press_event (RetroGamepad *self,
+ guint16 button)
+{
+ RetroJoypadId retro_button;
+
+ g_return_if_fail (self != NULL);
+
+ retro_button = button_to_retro_button (button);
+
+ if (retro_button == RETRO_JOYPAD_ID_COUNT)
+ return;
+
+ RETRO_GAMEPAD_INTERNAL (self)->buttons[button] = G_MAXINT16;
+}
+
+void
+retro_gamepad_button_release_event (RetroGamepad *self,
+ guint16 button)
+{
+ RetroJoypadId retro_button;
+
+ g_return_if_fail (self != NULL);
+
+ retro_button = button_to_retro_button (button);
+
+ if (retro_button == RETRO_JOYPAD_ID_COUNT)
+ return;
+
+ RETRO_GAMEPAD_INTERNAL (self)->buttons[button] = 0;
+}
+
+void
+retro_gamepad_axis_event (RetroGamepad *self,
+ guint16 axis,
+ gdouble value)
+{
+ RetroAnalogIndex retro_index;
+ RetroAnalogId retro_id;
+
+ g_return_if_fail (self != NULL);
+
+ if (!axis_to_retro_axis (axis, &retro_index, &retro_id))
+ return;
+
+ RETRO_GAMEPAD_INTERNAL (self)->axes[retro_index][retro_id] = value * G_MAXINT16;
+}
+
+gint16
+retro_gamepad_internal_get_input_state (RetroInputDevice *base,
+ RetroDeviceType device,
+ guint index,
+ guint id)
+{
+ RetroGamepad *self = RETRO_GAMEPAD (base);
+
+ g_return_val_if_fail (self != NULL, 0);
+
+ switch (device) {
+ case RETRO_DEVICE_TYPE_JOYPAD:
+ g_return_val_if_fail (id < RETRO_JOYPAD_ID_COUNT, 0);
+
+ return RETRO_GAMEPAD_INTERNAL (self)->buttons[id];
+ case RETRO_DEVICE_TYPE_ANALOG:
+ g_return_val_if_fail (index < RETRO_ANALOG_INDEX_COUNT, 0);
+ g_return_val_if_fail (id < RETRO_ANALOG_ID_COUNT, 0);
+
+ return RETRO_GAMEPAD_INTERNAL (self)->axes[index][id];
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+
+RetroDeviceType
+retro_gamepad_internal_get_device_type (RetroInputDevice *base)
+{
+ RetroGamepad *self = RETRO_GAMEPAD (base);
+
+ g_return_val_if_fail (self != NULL, RETRO_DEVICE_TYPE_NONE);
+
+ if (RETRO_GAMEPAD_INTERNAL (self)->analog)
+ return RETRO_DEVICE_TYPE_ANALOG;
+
+ return RETRO_DEVICE_TYPE_JOYPAD;
+}
+
+guint64
+retro_gamepad_internal_get_device_capabilities (RetroInputDevice *base) {
+ return (1 << RETRO_DEVICE_TYPE_JOYPAD) | (1 << RETRO_DEVICE_TYPE_ANALOG);
+}
+
+void
+retro_gamepad_internal_init (RetroGamepad *self, gboolean analog) {
+ g_return_if_fail (self != NULL);
+
+ self->internal = g_new0 (RetroGamepadInternal, 1);
+
+ RETRO_GAMEPAD_INTERNAL (self)->analog = analog;
+}
+
+void
+retro_gamepad_internal_finalize (RetroGamepad *self)
+{
+ g_return_if_fail (self != NULL);
+
+ g_free (self->internal);
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]