Revision: 45527
http://sourceforge.net/p/vice-emu/code/45527
Author: compyx
Date: 2025-03-13 08:34:04 +0000 (Thu, 13 Mar 2025)
Log Message:
-----------
Joystick: BSD: clean up ordered inputs code, properly document said code
Modified Paths:
--------------
branches/compyx/joymap-001/vice/src/arch/gtk3/joystickdrv/joystick_bsd.c
Modified: branches/compyx/joymap-001/vice/src/arch/gtk3/joystickdrv/joystick_bsd.c
===================================================================
--- branches/compyx/joymap-001/vice/src/arch/gtk3/joystickdrv/joystick_bsd.c 2025-03-12 20:52:19 UTC (rev 45526)
+++ branches/compyx/joymap-001/vice/src/arch/gtk3/joystickdrv/joystick_bsd.c 2025-03-13 08:34:04 UTC (rev 45527)
@@ -92,22 +92,57 @@
int fd;
} joy_priv_t;
+/** \brief Function to free data in a input node list
+ *
+ * Function to call on the \c data member of an #input_node_t if #input_list_free()
+ * is called with \c with_data set to <tt>true</tt>.
+ * This typedef allows us to cast #joystick_axis_free(). #joystick_button_free()
+ * and #joystick_hat_free() to the type expected by #input_list_init(), avoiding
+ * wrapper functions.
+ */
+typedef void (*data_free_t)(void*);
+/** \brief Node in an ordered linked list of inputs
+ */
typedef struct input_node_s {
- struct input_node_s *next;
- void *data;
+ struct input_node_s *next; /**< next node */
+ void *data; /**< data (axis/button/hat object pointer) */
} input_node_t;
+/** \brief Ordered list of inputs
+ */
typedef struct input_list_s {
- input_node_t *head;
- void (*data_free)(void *);
- int (*data_comp)(void *, void *);
+ /** \brief Head node */
+ input_node_t *head;
+
+ /** \brief Function to call to free the data of a node
+ *
+ * This function is called on the \c data member of a node if #input_list_free()
+ * is called with its \c with_data argument set to <tt>true</tt>. This
+ * allows cleaning up the list and its data when an error occurs during
+ * scanning.
+ */
+ void (*data_free)(void *);
+
+ /** \brief Comparison function for ordered insertion
+ *
+ * Return 0 when the codes of both arguments are equal, return < 0 when
+ * \c arg1->code < \c arg2->code, return > 0 when \c arg1->code
+ * > \c arg2->code.
+ */
+ int (*data_comp)(const void *, const void *);
} input_list_t;
+/** \brief Initialize ordered input list
+ *
+ * \param[in] list input list
+ * \param[in] data_free function to free the \c data member of the list nodes
+ * \param[in] data_comp function to compare two \c data members
+ */
static void input_list_init(input_list_t *list,
void (*data_free)(void *),
- int (*data_comp)(void *, void *))
+ int (*data_comp)(const void *, const void *))
{
list->head = NULL;
list->data_free = data_free;
@@ -114,6 +149,13 @@
list->data_comp = data_comp;
}
+/** \brief Free input list
+ *
+ * Free input list node and optionally free each node's \c data member.
+ *
+ * \param[in] list input list
+ * \param[in] with_data also free the \c data member of each node
+ */
static void input_list_free(input_list_t *list, bool with_data)
{
input_node_t *node = list->head;
@@ -128,6 +170,17 @@
list->head = NULL;
}
+/** \brief Insert data into input list in-order
+ *
+ * Insert \a data into \a list, using the \c data_comp function specified in
+ * #input_list_init() to determine its location in the list.
+ *
+ * \param[in] list input list
+ * \param[in] data input object to insert into \a list
+ *
+ * \return <tt>true</tt> on success, <tt>false</tt> if an input with the same
+ * code is already present (which should not happen)
+ */
static bool input_list_insert(input_list_t *list, void *data)
{
input_node_t *node = lib_malloc(sizeof *node);
@@ -182,10 +235,16 @@
/** \brief Log for BSD joystick driver */
static log_t bsd_joy_log;
+/** \brief Temporary ordered list of axes */
static input_list_t axis_list;
+
+/** \brief Temporary ordered list of buttons */
static input_list_t button_list;
+
+/** \brief Temporary ordered list of hats */
static input_list_t hat_list;
+
/** \brief BSD joystick driver declaration */
static joystick_driver_t driver = {
.open = bsd_joy_open,
@@ -500,7 +559,7 @@
axis->maximum = item->logical_maximum;
log_message(bsd_joy_log, "axis %u: %s", axis->code, axis->name);
- joystick_device_add_axis(joydev, axis);
+ input_list_insert(&axis_list, axis);
}
/** \brief Add button to joystick device
@@ -515,10 +574,9 @@
button = joystick_button_new(hid_usage_in_page(item->usage));
button->code = (uint32_t)HID_USAGE(item->usage);
+
log_message(bsd_joy_log, "button %u: %s", button->code, button->name);
-
input_list_insert(&button_list, button);
-// joystick_device_add_button(joydev, button);
}
/** \brief Add hat to joystick device
@@ -533,8 +591,9 @@
hat = joystick_hat_new(hid_usage_in_page(item->usage));
hat->code = (uint32_t)HID_USAGE(item->usage);
+
log_message(bsd_joy_log, "hat %u: %s", hat->code, hat->name);
- joystick_device_add_hat(joydev, hat);
+ input_list_insert(&hat_list, hat);
}
/** \brief Scan device for inputs
@@ -608,9 +667,6 @@
*
* \param[in] node device node to scan
*
- * \todo Order axes, buttons and hats by HID_USAGE() (event code), otherwise
- * our default mappings fail spectacularly =D
- *
* \return new joystick device instance or <tt>NULL</tt> on error
*/
static joystick_device_t *scan_device(const char *node)
@@ -650,11 +706,19 @@
return joydev;
}
-
-static int axis_comp(void *a1, void *a2)
+/** \brief Ordered list comparison callback for axes
+ *
+ * Compare code of axis \a a1 with code of axis \a a2.
+ *
+ * \param[in] a1 joystick axis object
+ * \param[in] a2 joystick axis object
+ *
+ * \return 0 if equal, < 0 if \a a1 < \a a2, > 0 if \a a1 > \a a2
+ */
+static int axis_comp(const void *a1, const void *a2)
{
- joystick_axis_t *axis1 = a1;
- joystick_axis_t *axis2 = a2;
+ const joystick_axis_t *axis1 = a1;
+ const joystick_axis_t *axis2 = a2;
if (axis1->code == axis2->code) {
return 0;
@@ -665,16 +729,20 @@
}
}
-static void axis_free(void *a)
+/** \brief Ordered list comparison callback for buttons
+ *
+ * Compare code of button \a b1 with code of button \a b2.
+ *
+ * \param[in] b1 joystick button object
+ * \param[in] b2 joystick button object
+ *
+ * \return 0 if equal, < 0 if \a b1 < \a b2, > 0 if \a b1 > \a b2
+ */
+static int button_comp(const void *b1, const void *b2)
{
- joystick_axis_free(a);
-}
+ const joystick_button_t *btn1 = b1;
+ const joystick_button_t *btn2 = b2;
-static int button_comp(void *b1, void *b2)
-{
- joystick_button_t *btn1 = b1;
- joystick_button_t *btn2 = b2;
-
if (btn1->code == btn2->code) {
return 0;
} else if (btn1->code < btn2->code) {
@@ -684,14 +752,19 @@
}
}
-static void button_free(void *b)
+/** \brief Ordered list comparison callback for hats
+ *
+ * Compare code of hat \a h1 with code of hat \a h2.
+ *
+ * \param[in] h1 joystick hat object
+ * \param[in] h2 joystick hat object
+ *
+ * \return 0 if equal, < 0 if \a h1 < \a h2, > 0 if \a h1 > \a h2
+ */
+static int hat_comp(const void *h1, const void *h2)
{
- joystick_button_free(b);
-}
-static int hat_comp(void *h1, void *h2)
-{
- joystick_hat_t *hat1 = h1;
- joystick_hat_t *hat2 = h2;
+ const joystick_hat_t *hat1 = h1;
+ const joystick_hat_t *hat2 = h2;
if (hat1->code == hat2->code) {
return 0;
@@ -702,47 +775,44 @@
}
}
-static void hat_free(void *h)
+/* kept for debugging */
+#if 0
+static void add_ordered_buttons(joystick_device_t *joydev)
{
- joystick_hat_free(h);
-}
+ input_node_t *node;
+ int num = 0;
+ for (node = button_list.head; node != NULL; node = node->next) {
+ joystick_button_t *button = node->data;
-static void add_ordered_axes(joystick_device_t *joydev)
-{
- input_node_t *node = axis_list.head;
- while (node != NULL) {
- joystick_device_add_axis(joydev, node->data);
- node = node->next;
+ printf("BUTTON LIST: %d: 0x%04x \"%s\"\n", num++, button->code, button->name);
+ joystick_device_add_button(joydev, node->data);
}
}
+#endif
-static void add_ordered_buttons(joystick_device_t *joydev)
+/** \brief Add inputs ordered by code
+ *
+ * Add axes, buttons and hats ordered by their code (hid usage) to \a joydev.
+ *
+ * \param[in] joydev joystick device
+ */
+static void add_ordered_inputs(joystick_device_t *joydev)
{
- input_node_t *node = button_list.head;
- int num = 0;
- while (node != NULL) {
- joystick_button_t *button = node->data;
+ input_node_t *node;
- printf("BUTTON LIST: %d: 0x%04x \"%s\"\n", num, button->code, button->name);
- joystick_device_add_button(joydev, button);
- num++;
- node = node->next;
+ for (node = axis_list.head; node != NULL; node = node->next) {
+ joystick_device_add_axis(joydev, node->data);
}
-}
-
-static void add_ordered_hats(joystick_device_t *joydev)
-{
- input_node_t *node = hat_list.head;
- while (node != NULL) {
+ for (node = button_list.head; node != NULL; node = node->next) {
+ joystick_device_add_button(joydev, node->data);
+ }
+ for (node = hat_list.head; node != NULL; node = node->next) {
joystick_device_add_hat(joydev, node->data);
- node = node->next;
}
}
-
-
/** \brief Initialize BSD joystick driver and add available devices
*/
void bsd_joystick_init(void)
@@ -784,16 +854,14 @@
log_message(bsd_joy_log, "%s: %s", joydev->node, joydev->name);
/* initialize lists to sort inputs on code */
- input_list_init(&axis_list, axis_free, axis_comp);
- input_list_init(&button_list, button_free, button_comp);
- input_list_init(&hat_list, hat_free, hat_comp);
+ input_list_init(&axis_list, (data_free_t)joystick_axis_free, axis_comp);
+ input_list_init(&button_list, (data_free_t)joystick_button_free, button_comp);
+ input_list_init(&hat_list, (data_free_t)joystick_hat_free, hat_comp);
/* scan axes, buttons and hats */
if (scan_inputs(joydev)) {
/* add inputs to device in-order */
- add_ordered_axes (joydev);
- add_ordered_buttons(joydev);
- add_ordered_hats (joydev);
+ add_ordered_inputs(joydev);
/* OK: try to register */
if (!joystick_device_register(joydev)) {
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|