$NetBSD: patch-ag,v 1.4 2002/07/14 07:44:44 kristerw Exp $ --- unix/unix.cpp.orig Tue Sep 18 08:03:40 2001 +++ unix/unix.cpp Sun Jul 14 04:09:32 2002 @@ -51,7 +51,7 @@ #include #include -#if defined(__linux) || defined(__sun) +#if defined(__linux) || defined(__sun) || defined(__NetBSD__) #undef USE_THREADS #define USE_THREADS #include @@ -62,7 +62,11 @@ #ifdef USE_THREADS #include +#ifdef __NetBSD__ +#include +#else #include +#endif pthread_t thread; pthread_mutex_t mutex; @@ -72,6 +76,9 @@ #include #include #endif +#ifdef __NetBSD__ +#include +#endif #ifdef __sun #ifdef __SVR4 @@ -84,6 +91,9 @@ #if defined(__sun) && defined(__GNUC__) typedef void (*SIG_PF)(); #endif +#if defined(__NetBSD__) +typedef void (*SIG_PF)(int); +#endif #include "snes9x.h" #include "memmap.h" @@ -111,6 +121,51 @@ int NumControllers = 5; #ifdef JOYSTICK_SUPPORT +#ifdef __NetBSD__ +#ifdef HAVE_USBHID_H +#include +#else +#include +#endif +#define class Class +#include +#include + +struct priv_joydata_struct +{ + struct hid_item *hids; + int dlen; + int offset; + char *data_buf; +} priv_joy_data[4]; + +int js_fd [4] = {-1, -1, -1, -1}; +int js_map_button [4][16] = { + { + SNES_A_MASK, SNES_B_MASK, SNES_X_MASK, SNES_Y_MASK, + SNES_TL_MASK, SNES_TR_MASK, SNES_START_MASK, SNES_SELECT_MASK, + 0, 0, 0, 0, 0, 0, 0, 0 + }, + { + SNES_A_MASK, SNES_B_MASK, SNES_X_MASK, SNES_Y_MASK, + SNES_TL_MASK, SNES_TR_MASK, SNES_START_MASK, SNES_SELECT_MASK, + 0, 0, 0, 0, 0, 0, 0, 0 + }, + { + SNES_A_MASK, SNES_B_MASK, SNES_X_MASK, SNES_Y_MASK, + SNES_TL_MASK, SNES_TR_MASK, SNES_START_MASK, SNES_SELECT_MASK, + 0, 0, 0, 0, 0, 0, 0, 0 + }, + { + SNES_A_MASK, SNES_B_MASK, SNES_X_MASK, SNES_Y_MASK, + SNES_TL_MASK, SNES_TR_MASK, SNES_START_MASK, SNES_SELECT_MASK, + 0, 0, 0, 0, 0, 0, 0, 0 + } +}; + +char *js_device [4] = {"/dev/uhid0", "/dev/uhid1", "/dev/uhid2", "/dev/uhid3"}; + +#endif #ifdef __linux #include int js_fd [4] = {-1, -1, -1, -1}; @@ -168,7 +223,7 @@ char *rom_filename = NULL; char *snapshot_filename = NULL; -#if defined(__linux) || defined(__sun) +#if defined(__linux) || defined(__sun) || defined(__NetBSD__) static void sigbrkhandler(int) { #ifdef DEBUGGER @@ -612,6 +667,106 @@ #ifdef JOYSTICK_SUPPORT void InitJoysticks () { +#ifdef __NetBSD__ + int i, size, is_joystick, report_id = 0; + struct hid_data *d; + struct hid_item h; + report_desc_t rd; + + printf("USB joystick interface initialization...\n"); + + for (i = 0; i < 4; i++) + { + if ((js_fd [i] = open (js_device [i], O_RDONLY | O_NONBLOCK)) != -1) + { + if ((rd = hid_get_report_desc(js_fd [i])) == 0) + { + perror (js_device [i]); + close (js_fd [i]); + } + + priv_joy_data[i].hids = NULL; + +#ifdef HAVE_USBHID_H + if (ioctl(js_fd [i], USB_GET_REPORT_ID, &report_id) < 0) + { + perror (js_device [i]); + close (js_fd [i]); + } + + size = hid_report_size(rd, hid_input, report_id); + priv_joy_data[i].offset = 0; +#else + size = hid_report_size(rd, hid_input, &report_id); + priv_joy_data[i].offset = (report_id != 0); +#endif + if ((priv_joy_data[i].data_buf = malloc(size)) == NULL) + { + printf("error: couldn't malloc %d bytes\n", size); + hid_dispose_report_desc(rd); + } + priv_joy_data[i].dlen = size; + + is_joystick = 0; +#ifdef HAVE_USBHID_H + for (d = hid_start_parse(rd, 1 << hid_input, report_id); hid_get_item(d, &h); ) +#else + for (d = hid_start_parse(rd, 1 << hid_input); hid_get_item(d, &h); ) +#endif + { + int axes = 0, buttons = 0, usage, page, interesting_hid; + + page = HID_PAGE(h.usage); + usage = HID_USAGE(h.usage); + + is_joystick = is_joystick || + (h.kind == hid_collection && + page == HUP_GENERIC_DESKTOP && + (usage == HUG_JOYSTICK || usage == HUG_GAME_PAD)); + + if (h.kind != hid_input) + continue; + + if (!is_joystick) + continue; + + interesting_hid = TRUE; + if (page == HUP_GENERIC_DESKTOP) + { + if (usage == HUG_X || usage == HUG_RX) + axes = 1; + else if (usage == HUG_Y || usage == HUG_RY) + axes = 2; + else if (usage == HUG_Z || usage == HUG_RZ) + axes = 3; + else + interesting_hid = FALSE; + } + else if (page == HUP_BUTTON) + { + if (usage > 0) + buttons = usage; + else + interesting_hid = FALSE; + + } + + 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) + { + printf("error: Not enough memory for joystick.\n"); + break; + } + *(priv_joy_data[i].hids) = h; + } + } + hid_end_parse(d); + } + } +#endif #ifdef JSIOCGVERSION int version; unsigned char axes, buttons; @@ -664,6 +819,77 @@ void ReadJoysticks () { +#ifdef __NetBSD__ + int i, usage, page, d; + struct hid_item *h; + + for (i = 0; i < 4 && js_fd [i] >= 0; i++) + { + int len; + + len = read(js_fd [i], priv_joy_data[i].data_buf, priv_joy_data[i].dlen); + if (len < priv_joy_data[i].dlen) + continue; + + 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); + + if (page == HUP_GENERIC_DESKTOP) + { + int center, trigger_point; + + center = (h->logical_maximum + h->logical_minimum) / 2; + trigger_point = (h->logical_maximum - h->logical_minimum) / 4; + + if (usage == HUG_X || usage == HUG_RX) + { + if (d < (center - trigger_point)) + { + joypads [i] |= SNES_LEFT_MASK; + joypads [i] &= ~SNES_RIGHT_MASK; + continue; + } + if (d > (center + trigger_point)) + { + joypads [i] &= ~SNES_LEFT_MASK; + joypads [i] |= SNES_RIGHT_MASK; + continue; + } + joypads [i] &= ~SNES_LEFT_MASK; + joypads [i] &= ~SNES_RIGHT_MASK; + } + if (usage == HUG_Y || usage == HUG_RY) + { + if (d < (center - trigger_point)) + { + joypads [i] |= SNES_UP_MASK; + joypads [i] &= ~SNES_DOWN_MASK; + continue; + } + if (d > (center + trigger_point)) + { + joypads [i] &= ~SNES_UP_MASK; + joypads [i] |= SNES_DOWN_MASK; + continue; + } + joypads [i] &= ~SNES_UP_MASK; + joypads [i] &= ~SNES_DOWN_MASK; + } + } + else if (page == HUP_BUTTON) + { + if (d == h->logical_maximum) + joypads [i] |= js_map_button [i][usage - 1]; + else + joypads [i] &= ~js_map_button [i][usage - 1]; + } + } + } +#endif #ifdef JSIOCGVERSION struct js_event js_ev; int i; @@ -1422,7 +1648,7 @@ } #endif -#if defined(__linux) +#if defined(__linux) || defined(__NetBSD__) static int Rates[8] = { 0, 8192, 11025, 16500, 22050, 29300, 36600, 44000 @@ -1437,11 +1663,19 @@ { int J, K; +#if defined(__NetBSD__) + if ((so.sound_fd = open ("/dev/audio", O_WRONLY)) < 0) + { + perror ("/dev/audio"); + return (FALSE); + } +#else if ((so.sound_fd = open ("/dev/dsp", O_WRONLY)) < 0) { perror ("/dev/dsp"); return (FALSE); } +#endif #ifdef MMAP_SOUND if (ioctl (so.sound_fd, SNDCTL_DSP_GETCAPS, &J) < 0) @@ -1541,7 +1775,7 @@ } #endif -#if defined (__linux) || defined (__sun) +#if defined (__linux) || defined (__sun) || defined(__NetBSD__) void S9xUnixProcessSound (void) { } @@ -1640,7 +1874,7 @@ void *S9xProcessSound (void *) { -#ifdef __linux +#if defined(__linux) || defined(__NetBSD__) audio_buf_info info; if (!Settings.ThreadSound &&