diff options
author | Brian Feldman <green@FreeBSD.org> | 2000-11-19 07:10:40 +0000 |
---|---|---|
committer | Brian Feldman <green@FreeBSD.org> | 2000-11-19 07:10:40 +0000 |
commit | c47b39040920576c9f952764493d63b66a998eb7 (patch) | |
tree | 811cc131a8ec561abc3266afc75cfc082646d9c7 /emulators/snes9x | |
parent | New port: zh-wangttf (diff) |
Add a UHID joystick driver (USB Joysticks/GamePads/etc.) as the
FreeBSD machdep joystick handling code. Along with this, make a few
cleanups, and add a new switch, "-joyshift", which enables USB HID
numbering to start with the second gamepad.
The upshot of all this is that I can now play two-player games and
have second player on the gamepad. Yay!
Notes
Notes:
svn path=/head/; revision=35257
Diffstat (limited to 'emulators/snes9x')
-rw-r--r-- | emulators/snes9x/Makefile | 4 | ||||
-rw-r--r-- | emulators/snes9x/files/patch-aa | 16 | ||||
-rw-r--r-- | emulators/snes9x/files/patch-af | 410 |
3 files changed, 418 insertions, 12 deletions
diff --git a/emulators/snes9x/Makefile b/emulators/snes9x/Makefile index 065e0973ab3d..71defeabde98 100644 --- a/emulators/snes9x/Makefile +++ b/emulators/snes9x/Makefile @@ -27,6 +27,10 @@ MAKE_ENV= CC="${CC}" CXX="${CXX}" CFLAGS="${CFLAGS}" \ USE_ZIP= YES WRKSRC= ${WRKDIR}/release +.if exists(/usr/lib/libusb.a) +MAKE_ENV+= USB_JOYSTICK_SUPPORT=yes +.endif + ONLY_FOR_ARCHS= i386 alpha .if ${MACHINE_ARCH} == alpha diff --git a/emulators/snes9x/files/patch-aa b/emulators/snes9x/files/patch-aa index f9b5126bf69d..4bf161cb863e 100644 --- a/emulators/snes9x/files/patch-aa +++ b/emulators/snes9x/files/patch-aa @@ -1,5 +1,5 @@ --- Makefile.orig Mon Oct 2 03:36:11 2000 -+++ Makefile Fri Oct 13 20:56:31 2000 ++++ Makefile Sun Nov 19 01:59:35 2000 @@ -3,7 +3,6 @@ #SPC700ASM=1 NETPLAY=1 @@ -53,7 +53,19 @@ $(LINUXDEFINES) \ $(FXDEFINES) \ $(CPUDEFINES) \ -@@ -115,12 +107,12 @@ +@@ -108,6 +100,11 @@ + $(GLIDEDEFINES) \ + $(GUIDEFINES) + ++ifdef USB_JOYSTICK_SUPPORT ++CCFLAGS += -DJOYSTICK_SUPPORT ++EXTRALIBS += -lusb ++endif ++ + #-DSOUND + #-DDEBUGGER + #-DNO_INLINE_SET_GET +@@ -115,12 +112,12 @@ #-DCPU_SHUTDOWN #-DSPC700_SHUTDOWN diff --git a/emulators/snes9x/files/patch-af b/emulators/snes9x/files/patch-af index 54a57f28d494..fbc768902502 100644 --- a/emulators/snes9x/files/patch-af +++ b/emulators/snes9x/files/patch-af @@ -1,6 +1,5 @@ -diff -ru ../../work/release/unix/unix.cpp ./unix/unix.cpp ---- ../../work/release/unix/unix.cpp Thu Sep 23 19:56:48 1999 -+++ ./unix/unix.cpp Wed Dec 29 01:56:32 1999 +--- unix/unix.cpp.orig Fri Oct 6 17:02:40 2000 ++++ unix/unix.cpp Sat Nov 18 23:12:45 2000 @@ -49,9 +49,11 @@ #include <ctype.h> @@ -27,18 +26,94 @@ diff -ru ../../work/release/unix/unix.cpp ./unix/unix.cpp #include <sys/mman.h> #endif -@@ -83,6 +89,10 @@ +@@ -83,6 +89,11 @@ typedef void (*SIG_PF)(); #endif +#if defined(__FreeBSD__) +typedef sig_t SIG_PF; ++#include <err.h> +#endif + #include "snes9x.h" #include "memmap.h" #include "debug.h" -@@ -159,7 +169,7 @@ +@@ -109,7 +120,10 @@ + int NumControllers = 5; + + #ifdef JOYSTICK_SUPPORT ++#define JOYSTICK_MAX_DEVICES 4 ++int JoystickShift = 0; + #ifdef __linux ++#define JOYSTICK_MAX_BUTTONS 4 + #include <linux/joystick.h> + int js_fd [4] = {-1, -1, -1, -1}; + int js_map_button [4][16] = { +@@ -156,6 +170,63 @@ + char *js_device [4] = {"/dev/js0", "/dev/js1", "/dev/js2", "/dev/js3"}; + #endif + ++#if defined(__FreeBSD__) ++#include <sys/types.h> ++ ++extern "C" { ++#define class klass ++#include <dev/usb/usb.h> ++#include <dev/usb/usbhid.h> ++#undef class ++ ++#include <libusb.h> ++} ++ ++#define JOYSTICK_MAX_BUTTONS 16 ++ ++#define JOYSTICK_MAP_BUTTON_INITIALIZER \ ++ { \ ++ SNES_Y_MASK, SNES_B_MASK, SNES_A_MASK, \ ++ SNES_X_MASK, SNES_TL_MASK, SNES_TR_MASK, \ ++ SNES_TL_MASK, SNES_TR_MASK, \ ++ SNES_SELECT_MASK, SNES_START_MASK, 0, 0, 0, 0, 0, 0 \ ++ } ++ ++int js_map_button[JOYSTICK_MAX_BUTTONS][16] = { ++ JOYSTICK_MAP_BUTTON_INITIALIZER, ++ JOYSTICK_MAP_BUTTON_INITIALIZER, ++ JOYSTICK_MAP_BUTTON_INITIALIZER, ++ JOYSTICK_MAP_BUTTON_INITIALIZER, ++ JOYSTICK_MAP_BUTTON_INITIALIZER, ++ JOYSTICK_MAP_BUTTON_INITIALIZER, ++ JOYSTICK_MAP_BUTTON_INITIALIZER, ++ JOYSTICK_MAP_BUTTON_INITIALIZER, ++ JOYSTICK_MAP_BUTTON_INITIALIZER, ++ JOYSTICK_MAP_BUTTON_INITIALIZER, ++ JOYSTICK_MAP_BUTTON_INITIALIZER, ++ JOYSTICK_MAP_BUTTON_INITIALIZER, ++ JOYSTICK_MAP_BUTTON_INITIALIZER, ++ JOYSTICK_MAP_BUTTON_INITIALIZER, ++ JOYSTICK_MAP_BUTTON_INITIALIZER, ++ JOYSTICK_MAP_BUTTON_INITIALIZER ++}; ++char *js_device [4] = {"/dev/uhid0", "/dev/uhid1", "/dev/uhid2", "/dev/uhid3"}; ++struct js_range { ++ int min, max, lower_third, higher_third; ++}; ++struct js_info { ++ char *buf; ++ int reportlen; ++ int offset; ++ struct js_range x, y; ++ int buttons; ++ struct hid_item *hids; ++ int fd; ++ int joy; ++} js_info[4]; ++int js_count = 0; ++#endif ++ + void InitJoysticks (); + void ReadJoysticks (); + #endif +@@ -167,7 +238,7 @@ char *rom_filename = NULL; char *snapshot_filename = NULL; @@ -47,7 +122,134 @@ diff -ru ../../work/release/unix/unix.cpp ./unix/unix.cpp static void sigbrkhandler(int) { #ifdef DEBUGGER -@@ -402,7 +412,7 @@ +@@ -194,91 +265,43 @@ + if (strcmp (argv [i], "-j") == 0 || + strcasecmp (argv [i], "-nojoy") == 0) + Settings.JoystickEnabled = FALSE; +- else if (strcasecmp (argv [i], "-joydev1") == 0) +- { +- if (i + 1 < argc) +- js_device[0] = argv[++i]; ++#ifdef __FreeBSD__ ++ else if (strcasecmp(argv[i], "-joyshift") == 0) ++ JoystickShift = 1; ++#endif ++ else if (strncasecmp(argv[i], "-joydev", sizeof("-joydev") - 1) == 0) { ++ char *end, *snum = argv[i] + sizeof("-joydev") - 1; ++ unsigned long num; ++ ++ if (*snum == '\0' || argc < i + 1) ++ S9xUsage(); ++ if ((num = strtoul(snum, &end, 10)) < JOYSTICK_MAX_DEVICES && ++ num > 0 && *end == '\0') ++ js_device[num - 1] = argv[++i]; + else +- S9xUsage (); ++ S9xUsage(); + } +- else if (strcasecmp (argv [i], "-joydev2") == 0) +- { +- if (i + 1 < argc) +- js_device[1] = argv[++i]; +- else +- S9xUsage (); +- } +- else if (strcasecmp (argv [i], "-joymap1") == 0) +- { +- if (i + 8 < argc) +- { +- int t; +- +- if ((t = atoi (argv [++i])) < 15) js_map_button [0][t] = SNES_A_MASK; +- if ((t = atoi (argv [++i])) < 15) js_map_button [0][t] = SNES_B_MASK; +- if ((t = atoi (argv [++i])) < 15) js_map_button [0][t] = SNES_X_MASK; +- if ((t = atoi (argv [++i])) < 15) js_map_button [0][t] = SNES_Y_MASK; +- if ((t = atoi (argv [++i])) < 15) js_map_button [0][t] = SNES_TL_MASK; +- if ((t = atoi (argv [++i])) < 15) js_map_button [0][t] = SNES_TR_MASK; +- if ((t = atoi (argv [++i])) < 15) js_map_button [0][t] = SNES_START_MASK; +- if ((t = atoi (argv [++i])) < 15) js_map_button [0][t] = SNES_SELECT_MASK; +- } +- else +- S9xUsage (); +- } +- else if (strcasecmp (argv [i], "-joymap2") == 0) +- { +- if (i + 8 < argc) +- { +- int t; +- +- if ((t = atoi (argv [++i])) < 15) js_map_button [1][t] = SNES_A_MASK; +- if ((t = atoi (argv [++i])) < 15) js_map_button [1][t] = SNES_B_MASK; +- if ((t = atoi (argv [++i])) < 15) js_map_button [1][t] = SNES_X_MASK; +- if ((t = atoi (argv [++i])) < 15) js_map_button [1][t] = SNES_Y_MASK; +- if ((t = atoi (argv [++i])) < 15) js_map_button [1][t] = SNES_TL_MASK; +- if ((t = atoi (argv [++i])) < 15) js_map_button [1][t] = SNES_TR_MASK; +- if ((t = atoi (argv [++i])) < 15) js_map_button [1][t] = SNES_START_MASK; +- if ((t = atoi (argv [++i])) < 15) js_map_button [1][t] = SNES_SELECT_MASK; +- } +- else +- S9xUsage (); +- } +- else if (strcasecmp (argv [i], "-joymap3") == 0) +- { +- if (i + 8 < argc) +- { +- int t; +- +- if ((t = atoi (argv [++i])) < 15) js_map_button [2][t] = SNES_A_MASK; +- if ((t = atoi (argv [++i])) < 15) js_map_button [2][t] = SNES_B_MASK; +- if ((t = atoi (argv [++i])) < 15) js_map_button [2][t] = SNES_X_MASK; +- if ((t = atoi (argv [++i])) < 15) js_map_button [2][t] = SNES_Y_MASK; +- if ((t = atoi (argv [++i])) < 15) js_map_button [2][t] = SNES_TL_MASK; +- if ((t = atoi (argv [++i])) < 15) js_map_button [2][t] = SNES_TR_MASK; +- if ((t = atoi (argv [++i])) < 15) js_map_button [2][t] = SNES_START_MASK; +- if ((t = atoi (argv [++i])) < 15) js_map_button [2][t] = SNES_SELECT_MASK; +- } +- else +- S9xUsage (); +- } +- else if (strcasecmp (argv [i], "-joymap4") == 0) +- { +- if (i + 8 < argc) +- { +- int t; +- +- if ((t = atoi (argv [++i])) < 15) js_map_button [3][t] = SNES_A_MASK; +- if ((t = atoi (argv [++i])) < 15) js_map_button [3][t] = SNES_B_MASK; +- if ((t = atoi (argv [++i])) < 15) js_map_button [3][t] = SNES_X_MASK; +- if ((t = atoi (argv [++i])) < 15) js_map_button [3][t] = SNES_Y_MASK; +- if ((t = atoi (argv [++i])) < 15) js_map_button [3][t] = SNES_TL_MASK; +- if ((t = atoi (argv [++i])) < 15) js_map_button [3][t] = SNES_TR_MASK; +- if ((t = atoi (argv [++i])) < 15) js_map_button [3][t] = SNES_START_MASK; +- if ((t = atoi (argv [++i])) < 15) js_map_button [3][t] = SNES_SELECT_MASK; +- } +- else +- S9xUsage (); ++ else if (strncasecmp(argv[i], "-joymap", sizeof("-joymap") - 1) == 0) { ++ static const int button_masks[] = { ++ SNES_A_MASK, SNES_B_MASK, SNES_X_MASK, SNES_Y_MASK, ++ SNES_TL_MASK, SNES_TR_MASK, SNES_START_MASK, SNES_SELECT_MASK ++ }; ++ char *end, *snum = argv[i] + sizeof("-joymap") - 1; ++ unsigned long num; ++ int *js_buttons, b; ++ ++ if (argc < i + (sizeof(button_masks) / sizeof(int)) || *snum == '\0') ++ S9xUsage(); ++ num = strtoul(snum, &end, 10); ++ if (*end != '\0') ++ S9xUsage(); ++ if (num == 0 || num > 4) /* hardcode: max joysticks */ ++ S9xUsage(); ++ js_buttons = js_map_button[num - 1]; ++ for (b = 0; b < (sizeof(button_masks) / sizeof(int)); b++) ++ if ((num = strtoul(argv[++i], &end, 10)) <= 16 && num != 0 && ++ *end == '\0') ++ js_buttons[num - 1] = button_masks[b]; + } + else + #endif +@@ -415,7 +438,7 @@ #if !defined(__MSDOS) && defined(DEBUGGER) #if defined(__unix) && !defined(__NeXT__) struct sigaction sa; @@ -56,7 +258,195 @@ diff -ru ../../work/release/unix/unix.cpp ./unix/unix.cpp sa.sa_handler = sigbrkhandler; #else sa.sa_handler = (SIG_PF) sigbrkhandler; -@@ -1397,7 +1407,7 @@ +@@ -618,6 +641,7 @@ + } + + #ifdef JOYSTICK_SUPPORT ++#ifdef linux + void InitJoysticks () + { + #ifdef JSIOCGVERSION +@@ -738,6 +762,179 @@ + } + #endif + } ++#endif ++#if defined(__FreeBSD__) ++ ++/* ++ * USB HID code for FreeBSD/NetBSD ++ * Brian Feldman <green@FreeBSD.org> ++ * ++ * Reference used: ++ * X-Mame USB HID joystick driver for NetBSD. ++ * ++ * Written by Krister Walfridsson <cato@df.lth.se> ++ */ ++ ++int ++InitJoystickFd(int fd, char *dev) { ++ report_desc_t rd; ++ struct hid_data *d; ++ struct hid_item h, new_h; ++ struct js_info *my_info; ++ int reportlen, report_id, is_joystick; ++ ++ my_info = &js_info[js_count]; ++ rd = hid_get_report_desc(fd); ++ if (rd == 0) { ++ warn("%s", dev); ++ return (-1); ++ } ++ reportlen = hid_report_size(rd, hid_input, &report_id); ++ my_info->buf = (char *)malloc(reportlen); ++ if (my_info->buf == NULL) ++ err(1, "malloc"); ++ my_info->reportlen = reportlen; ++ my_info->offset = report_id != 0; ++ my_info->buttons = 0; ++ my_info->hids = NULL; ++ ++ is_joystick = 0; ++ for (d = hid_start_parse(rd, 1 << hid_input); hid_get_item(d, &h);) { ++ int usage, page, link_it = 0; ++ struct js_range *axis; ++ ++ page = HID_PAGE(h.usage); ++ usage = HID_USAGE(h.usage); ++ if (!is_joystick) ++ is_joystick = (h.kind == hid_collection && ++ page == HUP_GENERIC_DESKTOP && ++ (usage == HUG_JOYSTICK || usage == HUG_GAME_PAD)); ++ if (h.kind != hid_input || !is_joystick) ++ continue; ++ axis = NULL; ++ if (page == HUP_GENERIC_DESKTOP) { ++ switch (usage) { ++ case HUG_X: ++ case HUG_RX: ++ axis = &my_info->x; ++ break; ++ case HUG_Y: ++ case HUG_RY: ++ axis = &my_info->y; ++ break; ++ } ++ } ++ if (axis != NULL) { ++ axis->min = h.logical_minimum; ++ axis->max = h.logical_maximum; ++ axis->lower_third = axis->min + ++ (axis->max - axis->min) / 3; ++ axis->higher_third = axis->min + ++ (axis->max - axis->min) * 2 / 3; ++ link_it = 1; ++ } ++ if (!link_it) { ++ if (page != HUP_BUTTON || usage > 16) ++ continue; ++ if (usage > my_info->buttons) ++ my_info->buttons = usage; ++ } ++ new_h = h; ++ new_h.next = my_info->hids; ++ my_info->hids = (struct hid_item *) ++ malloc(sizeof(*my_info->hids)); ++ if (my_info->hids == NULL) ++ err(1, "malloc"); ++ *my_info->hids = new_h; ++ } ++ printf("Joystick %s: %d buttons, X range %d - %d, Y range %d - %d\n", ++ dev, my_info->buttons, my_info->x.min, my_info->x.max, ++ my_info->y.min, my_info->y.max); ++ my_info->fd = fd; ++ if (JoystickShift) { ++ my_info->joy = js_count + 1; ++ } else ++ my_info->joy = js_count; ++ return (0); ++} ++ ++void ++InitJoysticks() { ++ int i, fd; ++ ++ for (i = 0; i < (sizeof(js_device) / sizeof(js_device[0])); i++) { ++ fd = open(js_device[i], O_RDONLY | O_NONBLOCK); ++ if (fd == -1) ++ continue; ++ if (InitJoystickFd(fd, js_device[i]) == 0) ++ js_count++; ++ else ++ close(fd); ++ } ++} ++ ++void ++ReadJoysticks() { ++ struct hid_item *h; ++ int page, usage, njoy, joy; ++ ++ for (njoy = 0; njoy < js_count; njoy++) { ++ struct js_info *jsi; ++ ++ jsi = &js_info[njoy]; ++ joy = jsi->joy; ++ ++ if (read(jsi->fd, jsi->buf, jsi->reportlen) != jsi->reportlen) ++ continue; ++ for (h = jsi->hids; h != NULL; h = h->next) { ++ int d; ++ ++ d = hid_get_data(jsi->buf + jsi->offset, h); ++ page = HID_PAGE(h->usage); ++ usage = HID_USAGE(h->usage); ++ ++ switch (page) { ++ case HUP_GENERIC_DESKTOP: ++ switch (usage) { ++ case HUG_X: ++ case HUG_RX: ++ if (d < jsi->x.lower_third) { ++ joypads[joy] |= SNES_LEFT_MASK; ++ joypads[joy] &= ~SNES_RIGHT_MASK; ++ } else if (d < jsi->x.higher_third) { ++ joypads[joy] &= ~SNES_LEFT_MASK; ++ joypads[joy] &= ~SNES_RIGHT_MASK; ++ } else { ++ joypads[joy] &= ~SNES_LEFT_MASK; ++ joypads[joy] |= SNES_RIGHT_MASK; ++ } ++ break; ++ case HUG_Y: ++ case HUG_RY: ++ if (d < jsi->y.lower_third) { ++ joypads[joy] |= SNES_UP_MASK; ++ joypads[joy] &= ~SNES_DOWN_MASK; ++ } else if (d < jsi->y.higher_third) { ++ joypads[joy] &= ~SNES_UP_MASK; ++ joypads[joy] &= ~SNES_DOWN_MASK; ++ } else { ++ joypads[joy] &= ~SNES_UP_MASK; ++ joypads[joy] |= SNES_DOWN_MASK; ++ } ++ break; ++ } ++ break; ++ case HUP_BUTTON: ++ if (d) ++ joypads[joy] |= js_map_button[njoy][usage - 1]; ++ else ++ joypads[joy] &= ~js_map_button[njoy][usage - 1]; ++ break; ++ } ++ } ++ } ++} ++#endif // defined(__FreeBSD__) + #endif // defined (JOYSTICK_SUPPORT) + + const char *GetHomeDirectory () +@@ -1427,7 +1624,7 @@ } #endif @@ -65,7 +455,7 @@ diff -ru ../../work/release/unix/unix.cpp ./unix/unix.cpp static int Rates[8] = { 0, 8192, 11025, 16500, 22050, 29300, 36600, 44000 -@@ -1514,7 +1524,7 @@ +@@ -1546,7 +1743,7 @@ } #endif @@ -74,12 +464,12 @@ diff -ru ../../work/release/unix/unix.cpp ./unix/unix.cpp void S9xUnixProcessSound (void) { } -@@ -1613,7 +1623,7 @@ +@@ -1645,7 +1842,7 @@ void *S9xProcessSound (void *) { -#ifdef __linux +#if defined(__linux) || defined(__FreeBSD__) audio_buf_info info; - count_info count; + if (!Settings.ThreadSound && |