pkgsrc/emulators/snes9x/patches/patch-ag

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 &&