summaryrefslogtreecommitdiff
path: root/emulators/snes9x
diff options
context:
space:
mode:
authorBrian Feldman <green@FreeBSD.org>2000-11-19 07:10:40 +0000
committerBrian Feldman <green@FreeBSD.org>2000-11-19 07:10:40 +0000
commitc47b39040920576c9f952764493d63b66a998eb7 (patch)
tree811cc131a8ec561abc3266afc75cfc082646d9c7 /emulators/snes9x
parentNew 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/Makefile4
-rw-r--r--emulators/snes9x/files/patch-aa16
-rw-r--r--emulators/snes9x/files/patch-af410
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 &&