diff options
author | dillo <dillo> | 2004-07-26 18:40:06 +0000 |
---|---|---|
committer | dillo <dillo> | 2004-07-26 18:40:06 +0000 |
commit | dd7c4ea616c2b59d6bd5badae8303e07623680ca (patch) | |
tree | 4fdcbade1370800e902a41b6043799125b2839a1 /emulators | |
parent | 8ef40f191df0c24ca3347847001f25882d2f7ca9 (diff) | |
download | pkgsrc-dd7c4ea616c2b59d6bd5badae8303e07623680ca.tar.gz |
USB joystick driver rewritten, will be in next xmame release.
okayed by kristerw.
PKGREVISION++
Diffstat (limited to 'emulators')
-rw-r--r-- | emulators/xmame/Makefile | 3 | ||||
-rw-r--r-- | emulators/xmame/distinfo | 4 | ||||
-rw-r--r-- | emulators/xmame/patches/patch-ab | 401 | ||||
-rw-r--r-- | emulators/xmess/Makefile | 3 | ||||
-rw-r--r-- | emulators/xmess/distinfo | 4 | ||||
-rw-r--r-- | emulators/xmess/patches/patch-ab | 401 |
6 files changed, 796 insertions, 20 deletions
diff --git a/emulators/xmame/Makefile b/emulators/xmame/Makefile index 7eb0e26c8a7..882608647f0 100644 --- a/emulators/xmame/Makefile +++ b/emulators/xmame/Makefile @@ -1,7 +1,8 @@ -# $NetBSD: Makefile,v 1.114 2004/07/20 04:38:43 xtraeme Exp $ +# $NetBSD: Makefile,v 1.115 2004/07/26 18:40:06 dillo Exp $ # DISTNAME= xmame-0.84.1 +PKGREVISION= 1 CATEGORIES= emulators games x11 MASTER_SITES= http://x.mame.net/download/ EXTRACT_SUFX= .tar.bz2 diff --git a/emulators/xmame/distinfo b/emulators/xmame/distinfo index 861e2d726ed..f224f9a9ca4 100644 --- a/emulators/xmame/distinfo +++ b/emulators/xmame/distinfo @@ -1,7 +1,7 @@ -$NetBSD: distinfo,v 1.52 2004/07/18 23:36:17 kristerw Exp $ +$NetBSD: distinfo,v 1.53 2004/07/26 18:40:06 dillo Exp $ SHA1 (xmame-0.84.1.tar.bz2) = 51b9c091a9c6bae72695482ad1672ea98d9dec43 Size (xmame-0.84.1.tar.bz2) = 14456105 bytes SHA1 (patch-aa) = 0b9ffcb7c4305e7c349f229b2646acb31553d549 -SHA1 (patch-ab) = 098c3f51099136306a48929ee9f57aa6607dee2d +SHA1 (patch-ab) = af88f3d9a907ae2719df89b15f4eba3d79b2494c SHA1 (patch-ae) = df9ce91871bfcff611ff8f616482d4ff2e8204a3 diff --git a/emulators/xmame/patches/patch-ab b/emulators/xmame/patches/patch-ab index b99f63648c1..0693dfc523a 100644 --- a/emulators/xmame/patches/patch-ab +++ b/emulators/xmame/patches/patch-ab @@ -1,17 +1,333 @@ -$NetBSD: patch-ab,v 1.25 2004/05/26 09:34:17 dillo Exp $ +$NetBSD: patch-ab,v 1.26 2004/07/26 18:40:06 dillo Exp $ ---- src/unix/joystick-drivers/joy_usb.c.orig Sun Mar 7 01:01:12 2004 +--- src/unix/joystick-drivers/joy_usb.c.orig 2004-07-02 19:09:36.000000000 +0200 +++ src/unix/joystick-drivers/joy_usb.c -@@ -255,11 +255,14 @@ static void joy_usb_poll(void) +@@ -2,12 +2,18 @@ + * X-Mame USB HID joystick driver for NetBSD. + * + * Written by Krister Walfridsson <cato@df.lth.se> ++ * Improved by Dieter Baron <dillo@giga.or.at> + */ + #include "xmame.h" + #include "devices.h" + ++static int calibrate=0; ++ + struct rc_option joy_usb_opts[] = { + /* name, shortname, type, dest, deflt, min, max, func, help */ ++ { "joyusb-calibrate", NULL, rc_bool, &calibrate, ++ "0", 0, 0, NULL, ++ "Manually calibrate USB joysticks" }, + { NULL, NULL, rc_end, NULL, + NULL, 0, 0, NULL, + NULL } +@@ -16,8 +22,7 @@ struct rc_option joy_usb_opts[] = { + #ifdef USB_JOYSTICK + + #if !defined(__ARCH_netbsd) && !defined(__ARCH_freebsd) +-#error "USB joysticks are only supported under NetBSD and FreeBSD. " +- "Patches to support other archs are welcome ;)" ++#error "USB joysticks are only supported under NetBSD and FreeBSD. Patches to support other archs are welcome ;)" + #endif + + #if defined(HAVE_USBHID_H) || defined(HAVE_LIBUSBHID_H) +@@ -44,14 +49,26 @@ struct rc_option joy_usb_opts[] = { + #include <dev/usb/usb.h> + #include <dev/usb/usbhid.h> + ++int axis_usage[] = { ++ HUG_X, HUG_Y, HUG_Z, ++ HUG_RX, HUG_RY, HUG_RZ, ++ HUG_SLIDER, ++}; ++ ++int axis_max = sizeof(axis_usage)/sizeof(axis_usage[0]); ++ + struct priv_joydata_struct + { +- struct hid_item *hids; + int dlen; + int offset; + char *data_buf; ++ struct hid_item *axis_item[JOY_AXIS]; ++ struct hid_item *button_item[JOY_BUTTONS]; ++ struct hid_item *hat_item; ++ int hat_axis; + } priv_joy_data[JOY]; + ++static struct hid_item *itemdup(struct hid_item *s); + static int joy_initialize_hid(int i); + static void joy_usb_poll(void); + static int joy_read(int fd, int i); +@@ -88,7 +105,10 @@ static int joy_initialize_hid(int i) + int size, is_joystick, report_id = 0; + struct hid_data *d; + struct hid_item h; ++ struct hid_item *axis_item[axis_max]; + report_desc_t rd; ++ int got_something; ++ int j, n; + + if ((rd = hid_get_report_desc(joy_data[i].fd)) == 0) + { +@@ -96,8 +116,6 @@ static int joy_initialize_hid(int i) + return FALSE; + } + +- priv_joy_data[i].hids = NULL; +- + #if defined(HAVE_USBHID_H) || defined(HAVE_LIBUSBHID_H) + #if defined(__ARCH_netbsd) || (defined(__ARCH_freebsd) && __FreeBSD_version > 500000) + if (ioctl(joy_data[i].fd, USB_GET_REPORT_ID, &report_id) < 0) +@@ -121,7 +139,16 @@ static int joy_initialize_hid(int i) + } + priv_joy_data[i].dlen = size; + ++ for (j=0; j<axis_max; j++) ++ axis_item[j] = NULL; ++ priv_joy_data[i].hat_item = NULL; ++ for (j=0; j<JOY_AXIS; j++) ++ priv_joy_data[i].axis_item[j] = NULL; ++ for (j=0; j<JOY_BUTTONS; j++) ++ priv_joy_data[i].button_item[j] = NULL; ++ + is_joystick = 0; ++ got_something = 0; + #if defined(HAVE_USBHID_H) + for (d = hid_start_parse(rd, 1 << hid_input, report_id); + hid_get_item(d, &h); ) +@@ -129,7 +156,7 @@ static int joy_initialize_hid(int i) + for (d = hid_start_parse(rd, 1 << hid_input); hid_get_item(d, &h); ) + #endif + { +- int axis, usage, page, interesting_hid; ++ int axis, usage, page; + + page = HID_PAGE(h.usage); + usage = HID_USAGE(h.usage); +@@ -147,92 +174,135 @@ static int joy_initialize_hid(int i) + if (!is_joystick) + continue; + +- interesting_hid = TRUE; + if (page == HUP_GENERIC_DESKTOP) + { +- if (usage == HUG_X || usage == HUG_RX) +- axis = 0; +- else if (usage == HUG_Y || usage == HUG_RY) +- axis = 1; +- else if (usage == HUG_Z || usage == HUG_RZ) +- axis = 2; ++ if (usage == HUG_HAT_SWITCH) ++ { ++ got_something = 1; ++ if (priv_joy_data[i].hat_item == NULL) ++ priv_joy_data[i].hat_item = itemdup(&h); ++ } + else +- interesting_hid = FALSE; +- +- if (interesting_hid) + { +- joy_data[i].axis[axis].min = h.logical_minimum; +- joy_data[i].axis[axis].max = h.logical_maximum; +- +- /* Set the theoretical center. This will be used in case +- * the heuristic below fails. */ +- joy_data[i].axis[axis].center = +- (h.logical_minimum + h.logical_maximum) / 2; +- +- if (joy_data[i].num_axis < (axis + 1)) +- joy_data[i].num_axis = axis + 1; ++ for (j=0; j<axis_max; j++) ++ if (usage == axis_usage[j]) ++ { ++ got_something = 1; ++ if (axis_item[j] == NULL) ++ axis_item[j] = itemdup(&h); ++ break; ++ } + } + } + else if (page == HUP_BUTTON) + { +- interesting_hid = (usage > 0) && (usage <= JOY_BUTTONS); +- +- if (interesting_hid && usage > joy_data[i].num_buttons) +- joy_data[i].num_buttons = usage; +- } +- +- if (interesting_hid) +- { +- h.next = priv_joy_data[i].hids; +- priv_joy_data[i].hids = malloc(sizeof *(priv_joy_data[i].hids)); +- if (priv_joy_data[i].hids == NULL) ++ if ((usage > 0) && (usage <= JOY_BUTTONS)) + { +- fprintf(stderr_file, "error: Not enough memory for joystick. " +- "Your joystick may fail to work correctly.\n"); +- break; ++ got_something = 1; ++ if (priv_joy_data[i].button_item[usage-1] == NULL) ++ priv_joy_data[i].button_item[usage-1] = itemdup(&h); ++ if (usage > joy_data[i].num_buttons) ++ joy_data[i].num_buttons = usage; + } +- *(priv_joy_data[i].hids) = h; + } + } + hid_end_parse(d); + +- if (priv_joy_data[i].hids != NULL) ++ if (!got_something) + { +- /* We'll approximate the center with the current joystick value if +- * that can be read (some HID devices returns no data if the state +- * has not changed since the last time it was read.) */ +- if (joy_read(joy_data[i].fd, i)) +- { +- joy_data[i].axis[0].center = joy_data[i].axis[0].val; +- joy_data[i].axis[1].center = joy_data[i].axis[1].val; +- joy_data[i].axis[2].center = joy_data[i].axis[2].val; ++ free(priv_joy_data[i].data_buf); ++ return 0; ++ } ++ ++ ++ for (j=0; j<axis_max; j++) ++ { ++ if (axis_item[j]) ++ { ++ n = joy_data[i].num_axis++; ++ priv_joy_data[i].axis_item[n] = axis_item[j]; ++ ++ joy_data[i].axis[n].min ++ = priv_joy_data[i].axis_item[n]->logical_minimum; ++ joy_data[i].axis[n].max ++ = priv_joy_data[i].axis_item[n]->logical_maximum; ++ joy_data[i].axis[n].center ++ = ((joy_data[i].axis[n].max-joy_data[i].axis[n].min+1)/2 ++ + joy_data[i].axis[n].min); ++ joy_data[i].axis[n].val = joy_data[i].axis[n].center; ++ } ++ } ++ ++ if (priv_joy_data[i].hat_item) ++ { ++ if (joy_data[i].num_axis < JOY_AXIS-2) ++ { ++ n = joy_data[i].num_axis; ++ joy_data[i].num_axis += 2; ++ priv_joy_data[i].hat_axis = n; ++ for (j=0; j<2; j++) ++ { ++ joy_data[i].axis[n+j].min = -1; ++ joy_data[i].axis[n+j].max = 1; ++ joy_data[i].axis[n+j].center = 0; ++ joy_data[i].axis[n+j].val = 0; ++ } + } + else +- { +- /* Assume that the joystick is positioned in the center. +- * This is needed, or else the system will think that the +- * joystick is in position left/up (or something) until it +- * is moved the first time. */ +- joy_data[i].axis[0].val = joy_data[i].axis[0].center; +- joy_data[i].axis[1].val = joy_data[i].axis[1].center; +- joy_data[i].axis[2].val = joy_data[i].axis[2].center; ++ { ++ /* too many axes to support hat */ ++ free(priv_joy_data[i].hat_item); ++ priv_joy_data[i].hat_item = NULL; + } +- +- /* Approximate min/max values. Observe that we cannot use the +- * max/min values that the HID reports, since that is theoretical +- * values that may be wrong for analogs joystics (especially if +- * you have a joystick -> USB adaptor.) We cannot use greater delta +- * values than +/- 1, since it is OK for a gamepad (or my USB TAC 2) +- * to reports directions as center +/- 1. */ +- joy_data[i].axis[0].min = joy_data[i].axis[0].center - 1; +- joy_data[i].axis[1].min = joy_data[i].axis[1].center - 1; +- joy_data[i].axis[2].min = joy_data[i].axis[2].center - 1; +- joy_data[i].axis[0].max = joy_data[i].axis[0].center + 1; +- joy_data[i].axis[1].max = joy_data[i].axis[1].center + 1; +- joy_data[i].axis[2].max = joy_data[i].axis[2].center + 1; + } + +- return (priv_joy_data[i].hids != NULL); ++ if (calibrate) ++ { ++ int got_values; ++ ++ /* ++ The values returned in the HID report may be wrong. However, ++ it works for most joysticks and krister's method requires ++ moving the joystick about when starting xmame to calibrate, ++ which is annoying. ++ ++ For such joysticks, calibration can be enabled with the ++ -joyusb-calibrate command line option. ++ ++ We'll approximate the center with the current joystick value ++ if that can be read (some HID devices returns no data if the ++ state has not changed since the last time it was read.) ++ */ ++ ++ got_values = joy_read(joy_data[i].fd, i); ++ ++ for (j=0; j<joy_data[i].num_axis; j++) ++ { ++ if (priv_joy_data[i].axis_item[j] == NULL) ++ { ++ /* HAT item doesn't need calibration */ ++ continue; ++ } ++ ++ if (got_values) ++ joy_data[i].axis[j].center = joy_data[i].axis[j].val; ++ ++ /* ++ Approximate min/max values. Observe that we cannot use the ++ max/min values that the HID reports, since that is ++ theoretical values that may be wrong for analogs joystics ++ (especially if you have a joystick -> USB adaptor.) We ++ cannot use greater delta values than +/- 1, since it is OK ++ for a gamepad (or my USB TAC 2) to reports directions as ++ center +/- 1. ++ */ ++ ++ joy_data[i].axis[j].min = joy_data[i].axis[j].center - 1; ++ joy_data[i].axis[j].max = joy_data[i].axis[j].center + 1; ++ } ++ } ++ ++ return 1; + } + + +@@ -255,37 +325,76 @@ static void joy_usb_poll(void) static int joy_read(int fd, int i) { - int len, axis, usage, page, d; -+ int len, new, axis, usage, page, d; - struct hid_item *h; - +- struct hid_item *h; +- - len = read(fd, priv_joy_data[i].data_buf, priv_joy_data[i].dlen); - if (len != priv_joy_data[i].dlen) ++ /* 0 1 2 3 4 5 6 7 */ ++ /* u ru r rd d ld l lu */ ++ const int hat_x[] = { ++ 0, 1, 1, 1, 0, -1, -1, -1 ++ }; ++ const int hat_y[] = { ++ -1, -1, 0, 1, 1, 1, 0, -1 ++ }; ++ ++ int len, new, d, j; ++ char *p; ++ + new = 0; + while ((len=read(fd, priv_joy_data[i].data_buf, priv_joy_data[i].dlen)) + == priv_joy_data[i].dlen) @@ -19,4 +335,75 @@ $NetBSD: patch-ab,v 1.25 2004/05/26 09:34:17 dillo Exp $ + if (!new) return FALSE; - for (h = priv_joy_data[i].hids; h; h = h->next) +- for (h = priv_joy_data[i].hids; h; h = h->next) +- { +- d = hid_get_data(priv_joy_data[i].data_buf + priv_joy_data[i].offset, h); +- +- page = HID_PAGE(h->usage); +- usage = HID_USAGE(h->usage); ++ p = priv_joy_data[i].data_buf + priv_joy_data[i].offset; + +- if (page == HUP_GENERIC_DESKTOP) +- { +- if (usage == HUG_X || usage == HUG_RX) +- axis = 0; +- else if (usage == HUG_Y || usage == HUG_RY) +- axis = 1; +- else +- axis = 2; ++ for (j=0; j<joy_data[i].num_axis; j++) ++ { ++ if (priv_joy_data[i].axis_item[j]) ++ joy_data[i].axis[j].val=hid_get_data(p, priv_joy_data[i].axis_item[j]); ++ } + +- joy_data[i].axis[axis].val = d; ++ if (priv_joy_data[i].hat_item != NULL) ++ { ++ d = hid_get_data(p, priv_joy_data[i].hat_item) ++ - priv_joy_data[i].hat_item->logical_minimum; ++ j = priv_joy_data[i].hat_axis; ++ if (d < 0 || d >= 8) ++ { ++ joy_data[i].axis[j].val = 0; ++ joy_data[i].axis[j+1].val = 0; + } +- else if (page == HUP_BUTTON) +- { +- joy_data[i].buttons[usage - 1] = (d == h->logical_maximum); ++ else ++ { ++ joy_data[i].axis[j].val = hat_x[d]; ++ joy_data[i].axis[j+1].val = hat_y[d]; + } + } + ++ for (j=0; j<joy_data[i].num_buttons; j++) ++ { ++ if (priv_joy_data[i].button_item[j]) ++ joy_data[i].buttons[j] ++ = (hid_get_data(p, priv_joy_data[i].button_item[j]) ++ == priv_joy_data[i].button_item[j]->logical_maximum); ++ } ++ + return TRUE; + } ++ ++static struct hid_item *itemdup(struct hid_item *s) ++{ ++ struct hid_item *t; ++ ++ t = malloc(sizeof(*t)); ++ if (t == NULL) ++ { ++ fprintf(stderr_file, "error: Not enough memory for joystick. " ++ "Your joystick may fail to work correctly.\n"); ++ return NULL; ++ } ++ ++ memcpy(t, s, sizeof(*t)); ++ ++ return t; ++} ++ + #endif diff --git a/emulators/xmess/Makefile b/emulators/xmess/Makefile index 704b8ba5efc..727c272ed87 100644 --- a/emulators/xmess/Makefile +++ b/emulators/xmess/Makefile @@ -1,8 +1,9 @@ -# $NetBSD: Makefile,v 1.55 2004/07/20 04:38:43 xtraeme Exp $ +# $NetBSD: Makefile,v 1.56 2004/07/26 18:45:09 dillo Exp $ # DISTNAME= xmame-0.84.1 PKGNAME= xmess-0.84.1 +PKGREVISION= 1 CATEGORIES= emulators games x11 MASTER_SITES= http://x.mame.net/download/ EXTRACT_SUFX= .tar.bz2 diff --git a/emulators/xmess/distinfo b/emulators/xmess/distinfo index eb351b8c9fe..f0cb71eb0ee 100644 --- a/emulators/xmess/distinfo +++ b/emulators/xmess/distinfo @@ -1,7 +1,7 @@ -$NetBSD: distinfo,v 1.26 2004/07/18 23:37:55 kristerw Exp $ +$NetBSD: distinfo,v 1.27 2004/07/26 18:45:09 dillo Exp $ SHA1 (xmame-0.84.1.tar.bz2) = 51b9c091a9c6bae72695482ad1672ea98d9dec43 Size (xmame-0.84.1.tar.bz2) = 14456105 bytes SHA1 (patch-aa) = 0b9ffcb7c4305e7c349f229b2646acb31553d549 -SHA1 (patch-ab) = 098c3f51099136306a48929ee9f57aa6607dee2d +SHA1 (patch-ab) = af88f3d9a907ae2719df89b15f4eba3d79b2494c SHA1 (patch-ae) = 4f7ebb8c0eef93e38197ca1f176056462f179757 diff --git a/emulators/xmess/patches/patch-ab b/emulators/xmess/patches/patch-ab index 0dbf1aff6e4..84abc08bb50 100644 --- a/emulators/xmess/patches/patch-ab +++ b/emulators/xmess/patches/patch-ab @@ -1,17 +1,333 @@ -$NetBSD: patch-ab,v 1.16 2004/05/28 00:46:27 dillo Exp $ +$NetBSD: patch-ab,v 1.17 2004/07/26 18:45:09 dillo Exp $ ---- src/unix/joystick-drivers/joy_usb.c.orig Sun Mar 7 01:01:12 2004 +--- src/unix/joystick-drivers/joy_usb.c.orig 2004-07-02 19:09:36.000000000 +0200 +++ src/unix/joystick-drivers/joy_usb.c -@@ -255,11 +255,14 @@ static void joy_usb_poll(void) +@@ -2,12 +2,18 @@ + * X-Mame USB HID joystick driver for NetBSD. + * + * Written by Krister Walfridsson <cato@df.lth.se> ++ * Improved by Dieter Baron <dillo@giga.or.at> + */ + #include "xmame.h" + #include "devices.h" + ++static int calibrate=0; ++ + struct rc_option joy_usb_opts[] = { + /* name, shortname, type, dest, deflt, min, max, func, help */ ++ { "joyusb-calibrate", NULL, rc_bool, &calibrate, ++ "0", 0, 0, NULL, ++ "Manually calibrate USB joysticks" }, + { NULL, NULL, rc_end, NULL, + NULL, 0, 0, NULL, + NULL } +@@ -16,8 +22,7 @@ struct rc_option joy_usb_opts[] = { + #ifdef USB_JOYSTICK + + #if !defined(__ARCH_netbsd) && !defined(__ARCH_freebsd) +-#error "USB joysticks are only supported under NetBSD and FreeBSD. " +- "Patches to support other archs are welcome ;)" ++#error "USB joysticks are only supported under NetBSD and FreeBSD. Patches to support other archs are welcome ;)" + #endif + + #if defined(HAVE_USBHID_H) || defined(HAVE_LIBUSBHID_H) +@@ -44,14 +49,26 @@ struct rc_option joy_usb_opts[] = { + #include <dev/usb/usb.h> + #include <dev/usb/usbhid.h> + ++int axis_usage[] = { ++ HUG_X, HUG_Y, HUG_Z, ++ HUG_RX, HUG_RY, HUG_RZ, ++ HUG_SLIDER, ++}; ++ ++int axis_max = sizeof(axis_usage)/sizeof(axis_usage[0]); ++ + struct priv_joydata_struct + { +- struct hid_item *hids; + int dlen; + int offset; + char *data_buf; ++ struct hid_item *axis_item[JOY_AXIS]; ++ struct hid_item *button_item[JOY_BUTTONS]; ++ struct hid_item *hat_item; ++ int hat_axis; + } priv_joy_data[JOY]; + ++static struct hid_item *itemdup(struct hid_item *s); + static int joy_initialize_hid(int i); + static void joy_usb_poll(void); + static int joy_read(int fd, int i); +@@ -88,7 +105,10 @@ static int joy_initialize_hid(int i) + int size, is_joystick, report_id = 0; + struct hid_data *d; + struct hid_item h; ++ struct hid_item *axis_item[axis_max]; + report_desc_t rd; ++ int got_something; ++ int j, n; + + if ((rd = hid_get_report_desc(joy_data[i].fd)) == 0) + { +@@ -96,8 +116,6 @@ static int joy_initialize_hid(int i) + return FALSE; + } + +- priv_joy_data[i].hids = NULL; +- + #if defined(HAVE_USBHID_H) || defined(HAVE_LIBUSBHID_H) + #if defined(__ARCH_netbsd) || (defined(__ARCH_freebsd) && __FreeBSD_version > 500000) + if (ioctl(joy_data[i].fd, USB_GET_REPORT_ID, &report_id) < 0) +@@ -121,7 +139,16 @@ static int joy_initialize_hid(int i) + } + priv_joy_data[i].dlen = size; + ++ for (j=0; j<axis_max; j++) ++ axis_item[j] = NULL; ++ priv_joy_data[i].hat_item = NULL; ++ for (j=0; j<JOY_AXIS; j++) ++ priv_joy_data[i].axis_item[j] = NULL; ++ for (j=0; j<JOY_BUTTONS; j++) ++ priv_joy_data[i].button_item[j] = NULL; ++ + is_joystick = 0; ++ got_something = 0; + #if defined(HAVE_USBHID_H) + for (d = hid_start_parse(rd, 1 << hid_input, report_id); + hid_get_item(d, &h); ) +@@ -129,7 +156,7 @@ static int joy_initialize_hid(int i) + for (d = hid_start_parse(rd, 1 << hid_input); hid_get_item(d, &h); ) + #endif + { +- int axis, usage, page, interesting_hid; ++ int axis, usage, page; + + page = HID_PAGE(h.usage); + usage = HID_USAGE(h.usage); +@@ -147,92 +174,135 @@ static int joy_initialize_hid(int i) + if (!is_joystick) + continue; + +- interesting_hid = TRUE; + if (page == HUP_GENERIC_DESKTOP) + { +- if (usage == HUG_X || usage == HUG_RX) +- axis = 0; +- else if (usage == HUG_Y || usage == HUG_RY) +- axis = 1; +- else if (usage == HUG_Z || usage == HUG_RZ) +- axis = 2; ++ if (usage == HUG_HAT_SWITCH) ++ { ++ got_something = 1; ++ if (priv_joy_data[i].hat_item == NULL) ++ priv_joy_data[i].hat_item = itemdup(&h); ++ } + else +- interesting_hid = FALSE; +- +- if (interesting_hid) + { +- joy_data[i].axis[axis].min = h.logical_minimum; +- joy_data[i].axis[axis].max = h.logical_maximum; +- +- /* Set the theoretical center. This will be used in case +- * the heuristic below fails. */ +- joy_data[i].axis[axis].center = +- (h.logical_minimum + h.logical_maximum) / 2; +- +- if (joy_data[i].num_axis < (axis + 1)) +- joy_data[i].num_axis = axis + 1; ++ for (j=0; j<axis_max; j++) ++ if (usage == axis_usage[j]) ++ { ++ got_something = 1; ++ if (axis_item[j] == NULL) ++ axis_item[j] = itemdup(&h); ++ break; ++ } + } + } + else if (page == HUP_BUTTON) + { +- interesting_hid = (usage > 0) && (usage <= JOY_BUTTONS); +- +- if (interesting_hid && usage > joy_data[i].num_buttons) +- joy_data[i].num_buttons = usage; +- } +- +- if (interesting_hid) +- { +- h.next = priv_joy_data[i].hids; +- priv_joy_data[i].hids = malloc(sizeof *(priv_joy_data[i].hids)); +- if (priv_joy_data[i].hids == NULL) ++ if ((usage > 0) && (usage <= JOY_BUTTONS)) + { +- fprintf(stderr_file, "error: Not enough memory for joystick. " +- "Your joystick may fail to work correctly.\n"); +- break; ++ got_something = 1; ++ if (priv_joy_data[i].button_item[usage-1] == NULL) ++ priv_joy_data[i].button_item[usage-1] = itemdup(&h); ++ if (usage > joy_data[i].num_buttons) ++ joy_data[i].num_buttons = usage; + } +- *(priv_joy_data[i].hids) = h; + } + } + hid_end_parse(d); + +- if (priv_joy_data[i].hids != NULL) ++ if (!got_something) + { +- /* We'll approximate the center with the current joystick value if +- * that can be read (some HID devices returns no data if the state +- * has not changed since the last time it was read.) */ +- if (joy_read(joy_data[i].fd, i)) +- { +- joy_data[i].axis[0].center = joy_data[i].axis[0].val; +- joy_data[i].axis[1].center = joy_data[i].axis[1].val; +- joy_data[i].axis[2].center = joy_data[i].axis[2].val; ++ free(priv_joy_data[i].data_buf); ++ return 0; ++ } ++ ++ ++ for (j=0; j<axis_max; j++) ++ { ++ if (axis_item[j]) ++ { ++ n = joy_data[i].num_axis++; ++ priv_joy_data[i].axis_item[n] = axis_item[j]; ++ ++ joy_data[i].axis[n].min ++ = priv_joy_data[i].axis_item[n]->logical_minimum; ++ joy_data[i].axis[n].max ++ = priv_joy_data[i].axis_item[n]->logical_maximum; ++ joy_data[i].axis[n].center ++ = ((joy_data[i].axis[n].max-joy_data[i].axis[n].min+1)/2 ++ + joy_data[i].axis[n].min); ++ joy_data[i].axis[n].val = joy_data[i].axis[n].center; ++ } ++ } ++ ++ if (priv_joy_data[i].hat_item) ++ { ++ if (joy_data[i].num_axis < JOY_AXIS-2) ++ { ++ n = joy_data[i].num_axis; ++ joy_data[i].num_axis += 2; ++ priv_joy_data[i].hat_axis = n; ++ for (j=0; j<2; j++) ++ { ++ joy_data[i].axis[n+j].min = -1; ++ joy_data[i].axis[n+j].max = 1; ++ joy_data[i].axis[n+j].center = 0; ++ joy_data[i].axis[n+j].val = 0; ++ } + } + else +- { +- /* Assume that the joystick is positioned in the center. +- * This is needed, or else the system will think that the +- * joystick is in position left/up (or something) until it +- * is moved the first time. */ +- joy_data[i].axis[0].val = joy_data[i].axis[0].center; +- joy_data[i].axis[1].val = joy_data[i].axis[1].center; +- joy_data[i].axis[2].val = joy_data[i].axis[2].center; ++ { ++ /* too many axes to support hat */ ++ free(priv_joy_data[i].hat_item); ++ priv_joy_data[i].hat_item = NULL; + } +- +- /* Approximate min/max values. Observe that we cannot use the +- * max/min values that the HID reports, since that is theoretical +- * values that may be wrong for analogs joystics (especially if +- * you have a joystick -> USB adaptor.) We cannot use greater delta +- * values than +/- 1, since it is OK for a gamepad (or my USB TAC 2) +- * to reports directions as center +/- 1. */ +- joy_data[i].axis[0].min = joy_data[i].axis[0].center - 1; +- joy_data[i].axis[1].min = joy_data[i].axis[1].center - 1; +- joy_data[i].axis[2].min = joy_data[i].axis[2].center - 1; +- joy_data[i].axis[0].max = joy_data[i].axis[0].center + 1; +- joy_data[i].axis[1].max = joy_data[i].axis[1].center + 1; +- joy_data[i].axis[2].max = joy_data[i].axis[2].center + 1; + } + +- return (priv_joy_data[i].hids != NULL); ++ if (calibrate) ++ { ++ int got_values; ++ ++ /* ++ The values returned in the HID report may be wrong. However, ++ it works for most joysticks and krister's method requires ++ moving the joystick about when starting xmame to calibrate, ++ which is annoying. ++ ++ For such joysticks, calibration can be enabled with the ++ -joyusb-calibrate command line option. ++ ++ We'll approximate the center with the current joystick value ++ if that can be read (some HID devices returns no data if the ++ state has not changed since the last time it was read.) ++ */ ++ ++ got_values = joy_read(joy_data[i].fd, i); ++ ++ for (j=0; j<joy_data[i].num_axis; j++) ++ { ++ if (priv_joy_data[i].axis_item[j] == NULL) ++ { ++ /* HAT item doesn't need calibration */ ++ continue; ++ } ++ ++ if (got_values) ++ joy_data[i].axis[j].center = joy_data[i].axis[j].val; ++ ++ /* ++ Approximate min/max values. Observe that we cannot use the ++ max/min values that the HID reports, since that is ++ theoretical values that may be wrong for analogs joystics ++ (especially if you have a joystick -> USB adaptor.) We ++ cannot use greater delta values than +/- 1, since it is OK ++ for a gamepad (or my USB TAC 2) to reports directions as ++ center +/- 1. ++ */ ++ ++ joy_data[i].axis[j].min = joy_data[i].axis[j].center - 1; ++ joy_data[i].axis[j].max = joy_data[i].axis[j].center + 1; ++ } ++ } ++ ++ return 1; + } + + +@@ -255,37 +325,76 @@ static void joy_usb_poll(void) static int joy_read(int fd, int i) { - int len, axis, usage, page, d; -+ int len, new, axis, usage, page, d; - struct hid_item *h; - +- struct hid_item *h; +- - len = read(fd, priv_joy_data[i].data_buf, priv_joy_data[i].dlen); - if (len != priv_joy_data[i].dlen) ++ /* 0 1 2 3 4 5 6 7 */ ++ /* u ru r rd d ld l lu */ ++ const int hat_x[] = { ++ 0, 1, 1, 1, 0, -1, -1, -1 ++ }; ++ const int hat_y[] = { ++ -1, -1, 0, 1, 1, 1, 0, -1 ++ }; ++ ++ int len, new, d, j; ++ char *p; ++ + new = 0; + while ((len=read(fd, priv_joy_data[i].data_buf, priv_joy_data[i].dlen)) + == priv_joy_data[i].dlen) @@ -19,4 +335,75 @@ $NetBSD: patch-ab,v 1.16 2004/05/28 00:46:27 dillo Exp $ + if (!new) return FALSE; - for (h = priv_joy_data[i].hids; h; h = h->next) +- for (h = priv_joy_data[i].hids; h; h = h->next) +- { +- d = hid_get_data(priv_joy_data[i].data_buf + priv_joy_data[i].offset, h); +- +- page = HID_PAGE(h->usage); +- usage = HID_USAGE(h->usage); ++ p = priv_joy_data[i].data_buf + priv_joy_data[i].offset; + +- if (page == HUP_GENERIC_DESKTOP) +- { +- if (usage == HUG_X || usage == HUG_RX) +- axis = 0; +- else if (usage == HUG_Y || usage == HUG_RY) +- axis = 1; +- else +- axis = 2; ++ for (j=0; j<joy_data[i].num_axis; j++) ++ { ++ if (priv_joy_data[i].axis_item[j]) ++ joy_data[i].axis[j].val=hid_get_data(p, priv_joy_data[i].axis_item[j]); ++ } + +- joy_data[i].axis[axis].val = d; ++ if (priv_joy_data[i].hat_item != NULL) ++ { ++ d = hid_get_data(p, priv_joy_data[i].hat_item) ++ - priv_joy_data[i].hat_item->logical_minimum; ++ j = priv_joy_data[i].hat_axis; ++ if (d < 0 || d >= 8) ++ { ++ joy_data[i].axis[j].val = 0; ++ joy_data[i].axis[j+1].val = 0; + } +- else if (page == HUP_BUTTON) +- { +- joy_data[i].buttons[usage - 1] = (d == h->logical_maximum); ++ else ++ { ++ joy_data[i].axis[j].val = hat_x[d]; ++ joy_data[i].axis[j+1].val = hat_y[d]; + } + } + ++ for (j=0; j<joy_data[i].num_buttons; j++) ++ { ++ if (priv_joy_data[i].button_item[j]) ++ joy_data[i].buttons[j] ++ = (hid_get_data(p, priv_joy_data[i].button_item[j]) ++ == priv_joy_data[i].button_item[j]->logical_maximum); ++ } ++ + return TRUE; + } ++ ++static struct hid_item *itemdup(struct hid_item *s) ++{ ++ struct hid_item *t; ++ ++ t = malloc(sizeof(*t)); ++ if (t == NULL) ++ { ++ fprintf(stderr_file, "error: Not enough memory for joystick. " ++ "Your joystick may fail to work correctly.\n"); ++ return NULL; ++ } ++ ++ memcpy(t, s, sizeof(*t)); ++ ++ return t; ++} ++ + #endif |