399 lines
12 KiB
Text
399 lines
12 KiB
Text
$NetBSD: patch-ag,v 1.10 2006/10/18 13:11:59 rillig Exp $
|
|
|
|
--- unix/unix.cpp.orig 2004-12-30 23:15:47.000000000 +0100
|
|
+++ unix/unix.cpp 2006-10-18 14:03:16.729013960 +0200
|
|
@@ -117,15 +117,25 @@
|
|
|
|
#ifdef USE_THREADS
|
|
#include <pthread.h>
|
|
+#ifdef __NetBSD__
|
|
+#include <sys/sched.h>
|
|
+#else
|
|
#include <sched.h>
|
|
+#endif
|
|
|
|
pthread_t thread;
|
|
pthread_mutex_t mutex;
|
|
#endif
|
|
|
|
-#if !defined(NOSOUND) && defined(__linux)
|
|
+#if !defined(NOSOUND)
|
|
+#if defined(__linux)
|
|
#include <sys/soundcard.h>
|
|
#include <sys/mman.h>
|
|
+#elif defined(__NetBSD__)
|
|
+#include <soundcard.h>
|
|
+#elif defined(__DragonFly__)
|
|
+#include <sys/soundcard.h>
|
|
+#endif
|
|
#endif
|
|
|
|
#if !defined(NOSOUND) && defined(__sun)
|
|
@@ -140,6 +150,9 @@ pthread_mutex_t mutex;
|
|
//#if defined(__sun) && defined(__GNUC__)
|
|
//typedef void (*SIG_PF)();
|
|
//#endif
|
|
+#if defined(__NetBSD__) || defined(__DragonFly__)
|
|
+typedef void (*SIG_PF)(int);
|
|
+#endif
|
|
|
|
#include "snes9x.h"
|
|
#include "memmap.h"
|
|
@@ -168,6 +181,62 @@ uint32 joypads [5] = {0};
|
|
int NumControllers = 5;
|
|
|
|
#ifdef JOYSTICK_SUPPORT
|
|
+#if defined(__NetBSD__) || defined(__DragonFly__)
|
|
+#if defined(__DragonFly__)
|
|
+extern "C" {
|
|
+#include <libusbhid.h>
|
|
+}
|
|
+#elif defined(HAVE_USBHID_H)
|
|
+START_EXTERN_C
|
|
+#include <usbhid.h>
|
|
+END_EXTERN_C
|
|
+#else
|
|
+#include <usb.h>
|
|
+#endif
|
|
+#define class Class
|
|
+#if defined(__DragonFly__)
|
|
+#include <bus/usb/usb.h>
|
|
+#include <bus/usb/usbhid.h>
|
|
+#else
|
|
+#include <dev/usb/usb.h>
|
|
+#include <dev/usb/usbhid.h>
|
|
+#endif
|
|
+
|
|
+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
|
|
#if defined(__linux)
|
|
#include <linux/joystick.h>
|
|
int js_fd [4] = {-1, -1, -1, -1};
|
|
@@ -227,7 +296,7 @@ char *snapshot_filename = NULL;
|
|
char *SDD1_pack = NULL;
|
|
|
|
//FIXME: I see no reason not to configureenable this for all Unixen
|
|
-#if defined(DEBUGGER) && (defined(__linux) || defined(__sun))
|
|
+#if defined(DEBUGGER) && (defined(__linux) || defined(__sun) || defined(__NetBSD__) || defined(__DragonFly__))
|
|
static void sigbrkhandler(int)
|
|
{
|
|
CPU.Flags |= DEBUG_MODE_FLAG;
|
|
@@ -700,6 +769,110 @@ void S9xInitInputDevices ()
|
|
#ifdef JOYSTICK_SUPPORT
|
|
void InitJoysticks ()
|
|
{
|
|
+#if defined(__NetBSD__) || defined(__DragonFly__)
|
|
+ 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;
|
|
+
|
|
+#if defined(HAVE_USBHID_H)
|
|
+ if (ioctl(js_fd [i], USB_GET_REPORT_ID, &report_id) < 0)
|
|
+ {
|
|
+ perror (js_device [i]);
|
|
+ close (js_fd [i]);
|
|
+ }
|
|
+
|
|
+#if defined(__DragonFly__)
|
|
+ size = hid_report_size(rd, report_id, hid_input);
|
|
+#else
|
|
+ size = hid_report_size(rd, hid_input, report_id);
|
|
+#endif
|
|
+ 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 = (char*)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;
|
|
+#if defined(HAVE_USBHID_H) && !defined(__DragonFly__)
|
|
+ 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 = (struct hid_item *)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;
|
|
@@ -756,6 +929,77 @@ void InitJoysticks ()
|
|
|
|
void ReadJoysticks ()
|
|
{
|
|
+#if defined(__NetBSD__) || defined(__DragonFly__)
|
|
+ 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;
|
|
@@ -1129,11 +1373,11 @@ void _splitpath (const char *path, char
|
|
{
|
|
*drive = 0;
|
|
|
|
- char *slash = strrchr (path, '/');
|
|
+ const char *slash = strrchr (path, '/');
|
|
if (!slash)
|
|
slash = strrchr (path, '\\');
|
|
|
|
- char *dot = strrchr (path, '.');
|
|
+ const char *dot = strrchr (path, '.');
|
|
|
|
if (dot && slash && dot < slash)
|
|
dot = NULL;
|
|
@@ -1646,7 +1890,7 @@ bool8 S9xOpenSoundDevice (int mode, bool
|
|
}
|
|
#endif
|
|
|
|
-#if !defined(NOSOUND) && defined(__linux)
|
|
+#if !defined(NOSOUND) && (defined(__linux) || defined(__NetBSD__) || defined(__DragonFly__))
|
|
static int Rates[8] =
|
|
{
|
|
0, 8000, 11025, 16000, 22050, 32000, 44100, 48000
|
|
@@ -1662,12 +1906,19 @@ bool8 S9xOpenSoundDevice (int mode, bool
|
|
/* Linux version (OSS) */
|
|
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)
|
|
{
|
|
@@ -1711,14 +1962,14 @@ bool8 S9xOpenSoundDevice (int mode, bool
|
|
so.sixteen_bit = TRUE;
|
|
|
|
so.stereo = stereo;
|
|
- if (ioctl (so.sound_fd, SNDCTL_DSP_STEREO, &so.stereo) < 0)
|
|
+ if (ioctl (so.sound_fd, SNDCTL_DSP_STEREO, (void *)&so.stereo) < 0)
|
|
{
|
|
perror ("ioctl SNDCTL_DSP_STEREO");
|
|
return (FALSE);
|
|
}
|
|
|
|
so.playback_rate = Rates[mode & 0x07];
|
|
- if (ioctl (so.sound_fd, SNDCTL_DSP_SPEED, &so.playback_rate) < 0)
|
|
+ if (ioctl (so.sound_fd, SNDCTL_DSP_SPEED, (void *)&so.playback_rate) < 0)
|
|
{
|
|
perror ("ioctl SNDCTL_DSP_SPEED");
|
|
return (FALSE);
|
|
@@ -1743,7 +1994,7 @@ bool8 S9xOpenSoundDevice (int mode, bool
|
|
perror ("ioctl SNDCTL_DSP_SETFRAGMENT");
|
|
return (FALSE);
|
|
}
|
|
- ioctl (so.sound_fd, SNDCTL_DSP_GETBLKSIZE, &so.buffer_size);
|
|
+ ioctl (so.sound_fd, SNDCTL_DSP_GETBLKSIZE, (void *)&so.buffer_size);
|
|
|
|
#ifdef MMAP_SOUND
|
|
J = PCM_ENABLE_OUTPUT;
|
|
@@ -1768,7 +2019,7 @@ bool8 S9xOpenSoundDevice (int mode, bool
|
|
#endif
|
|
|
|
|
|
-#if !defined(NOSOUND) && (defined (__linux) || defined (__sun))
|
|
+#if !defined(NOSOUND) && (defined (__linux) || defined (__sun) || defined(__NetBSD__) || defined(__DragonFly__))
|
|
void S9xUnixProcessSound (void)
|
|
{
|
|
}
|
|
@@ -1810,7 +2061,7 @@ void *S9xProcessSound (void *)
|
|
}
|
|
#endif
|
|
|
|
-#if !defined(NOSOUND) && (defined (__linux) || defined (__sun))
|
|
+#if !defined(NOSOUND) && (defined (__linux) || defined (__sun) || defined(__NetBSD__) || defined(__DragonFly__))
|
|
void S9xGenerateSound ()
|
|
{
|
|
/* Linux and Sun versions */
|
|
@@ -1902,7 +2153,7 @@ void *S9xProcessSound (void *)
|
|
/* If threads in use, this is to loop indefinitely */
|
|
/* If not, this will be called by timer */
|
|
|
|
-#ifdef __linux
|
|
+#if defined(__linux) || defined(__NetBSD__) || defined(__DragonFly__)
|
|
audio_buf_info info;
|
|
|
|
if (!Settings.ThreadSound &&
|