Subject: pkg/15566: Update snes9x to 1.39 plus USB gamepad support
To: None <gnats-bugs@gnats.netbsd.org>
From: None <rxg@ms25.url.com.tw>
List: netbsd-bugs
Date: 02/10/2002 16:51:22
>Number:         15566
>Category:       pkg
>Synopsis:       Update snes9x to 1.39 plus USB gamepad support
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    pkg-manager
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Sun Feb 10 00:52:00 PST 2002
>Closed-Date:
>Last-Modified:
>Originator:     Rui-Xiang Guo
>Release:        NetBSD 1.5ZA
>Organization:
	
>Environment:
	
	
System: NetBSD rxgpc.sparqnet.net 1.5ZA NetBSD 1.5ZA (HIVE) #0: Mon Feb 4 14:41:48 CST 2002 rxg@rxgpc.sparqnet.net:/usr/src/sys/arch/i386/compile/HIVE i386
Architecture: i386
Machine: i386
>Description:
	Update snes9x to 1.39 plus USB gamepad support. Only test with mine. ;)
>How-To-Repeat:
	1. change the Makefile with this:
--- /usr/pkgsrc/emulators/snes9x/Makefile       Tue Jul 17 23:31:24 2001
+++ Makefile
@@ -2,4 +2,4 @@
 
-DISTNAME=              s9xs137c
-PKGNAME=               snes9x-1.37.3
+DISTNAME=              s9xs139
+PKGNAME=               snes9x-1.39
 WRKSRC=                        ${WRKDIR}/release
@@ -44,3 +44,2 @@
 MAKE_ENV+=     ASMCPU=1
-.if defined(USE_MMX) && ${USE_MMX} == "YES"
 MAKE_ENV+=     ASMKREED=1
@@ -48,3 +47,2 @@
 .endif
-.endif
 
@@ -52,2 +50,9 @@
 MAKE_ENV+=     NETBSD_USE_DGA=1
+.endif
+
+.if exists(/usr/include/usb.h) || exists(/usr/include/usbhid.h)
+MAKE_ENV+=     USBJOY=1
+.if exists(/usr/include/usbhid.h)
+MAKE_ENV+=     USBHID_H=1
+.endif
 .endif

	2. remove patch-ac and replace these patches:
patch-aa:
$NetBSD$

--- Makefile.orig       Tue Sep 18 14:03:58 2001
+++ Makefile
@@ -1,14 +1,14 @@
-ZSNESFX=1
-ZSNESC4=1
-ASMCPU=1
+#ZSNESFX=1
+#ZSNESC4=1
+#ASMCPU=1
 #SPC700ASM=1
 NETPLAY=1
 UNZIP=1
 #GLIDE=1
 #OPENGL=1
 #GUI=1
-THREAD_SOUND=1
-ASMKREED=1
+#THREAD_SOUND=1
+#ASMKREED=1
 
 ifdef ZSNESFX
 FXOBJ=i386/fxemu2b.o i386/fxemu2.o i386/fxemu2c.o i386/fxtable.o i386/sfxproc.o
 i386/zsnes.o
@@ -34,7 +34,10 @@
 C4NO_DEPENDS=zsnes_c4
 endif
 
+ifdef NETBSD_USE_DGA
 LINUXDEFINES=-DUSE_DGA_EXTENSION -DUSE_VIDMODE_EXTENSION
+DGALIBS=-lXxf86dga -lXxf86vm
+endif
 
 ifdef SPC700ASM
 SOUNDOBJ=spctool/spc700.o spctool/dsp.o spctool.o spctool/soundmod.o spc.o
@@ -58,6 +61,16 @@
 KREEDOBJ=2xsai.o
 endif
 
+ifdef USBJOY
+ifdef USBHID_H
+USBJOYDEFINES=-DJOYSTICK_SUPPORT -DHAVE_USBHID_H
+EXTRALIBS+=-lusbhid
+else
+USBJOYDEFINES=-DJOYSTICK_SUPPORT
+EXTRALIBS+=-lusb
+endif
+endif
+
 OBJECTS=$(CPUOBJ) $(SOUNDOBJ) apudebug.o $(FXOBJ) $(C4OBJ) \
        cpu.o sa1.o debug.o sdd1.o tile.o srtc.o \
        gfx.o memmap.o snaporig.o clip.o dsp1.o \
@@ -82,8 +95,8 @@
 endif
 
 ifdef THREAD_SOUND
-CPUDEFINES += -DUSE_THREADS
-EXTRALIBS += -lpthread
+CPUDEFINES += -DUSE_THREADS -I${BUILDLINK_DIR}/include
+EXTRALIBS += -Wl,-R${LOCALBASE}/lib -L${BUILDLINK_DIR}/lib -lpthread
 endif
 
 ifdef GLIDE
@@ -113,9 +126,13 @@
 CC = gcc
 NASM = nasm
 
-INCLUDES=-I/usr/X11R6/include -I/usr/local/include
+INCLUDES=-I${X11BASE}/include
 
-OPTIMISE= -O6 -mpentium -fomit-frame-pointer -fno-exceptions -Wall -W -pedantic
 -pipe 
+ifdef USING_I386
+OPTIMISE=-O6 -mpentium -fomit-frame-pointer -fno-exceptions -Wall -W -pedantic 
-pipe 
+else
+OPTIMISE=-fno-exceptions -Wall -W -pedantic -pipe -fomit-frame-pointer
+endif
 
 #OPTIMISE=-g -fno-exceptions
 #-DMITSHM 
@@ -124,7 +141,6 @@
 -Ii386 \
 -I. \
 -Iunzip \
--DJOYSTICK_SUPPORT \
 -DZLIB \
 -DVAR_CYCLES \
 -DDEBUGGER \
@@ -142,7 +158,8 @@
 $(OPENGLDEFINES) \
 $(GUIDEFINES) \
 $(KREEDDEFINES) \
--DNO_INLINE_SET_GET
+$(USBJOYDEFINES)
+#-DNO_INLINE_SET_GET
 
 #-DSOUND
 #-DDEBUGGER
@@ -154,9 +171,9 @@
 CFLAGS=$(CCFLAGS)
 
 .SUFFIXES: .o .cpp .c .cc .h .m .i .S .asm .obj
-LDLIBS = -L/usr/X11R6/lib
+LDLIBS = -Wl,-R${X11BASE}/lib -L${X11BASE}/lib
 
-all: offsets snes9x ssnes9x
+all: offsets snes9x
 
 #ggisnes9x
 #xf86snes9x
@@ -182,7 +199,7 @@
        ./offsets >i386/offsets.h
 
 snes9x: $(OBJECTS) unix/x11.o $(GLIDEOBJS) $(OPENGLOBJS) $(GUIOBJS) $(KREEDOBJ)
-       $(CCC) $(INCLUDES) -o $@ $(OBJECTS) $(GLIDEOBJS) $(OPENGLOBJS) $(KREEDOB
J) unix/x11.o $(GUIOBJS) $(LDLIBS) $(GLIDELIBS) $(OPENGLLIBS) $(GUILIBS) -lXxf86
dga -lXxf86vm -lXext -lX11 $(EXTRALIBS) -lz -lm
+       $(CCC) $(INCLUDES) -o $@ $(OBJECTS) $(GLIDEOBJS) $(OPENGLOBJS) $(KREEDOB
J) unix/x11.o $(GUIOBJS) $(LDLIBS) $(GLIDELIBS) $(OPENGLLIBS) $(GUILIBS) $(DGALI
BS) -lXext -lX11 $(EXTRALIBS) -lz -lm
 
 ssnes9x: $(OBJECTS) unix/svga.o $(GLIDEOBJS) 
        $(CCC) $(INCLUDES) -o $@ $(OBJECTS) $(GLIDEOBJS) unix/svga.o $(LDLIBS) $
(GLIDELIBS) -lvga -lvgagl -lz $(EXTRALIBS) -lm
@@ -212,7 +229,7 @@
        $(CCC) $(INCLUDES) -c -E $(CCFLAGS) $*.S -o $@
 
 .asm.o:
-       $(NASM) -f elf $(FXDEFINES) -i. -ii386 -o $@ $*.asm
+       $(NASM) -f ${FILEFORMAT} $(FXDEFINES) -i. -ii386 -o $@ $*.asm
 
 .obj.o:
        cp $*.obj $*.o

patch-ag:
$NetBSD$

--- unix/unix.cpp.orig  Tue Sep 18 14:03:40 2001
+++ unix/unix.cpp
@@ -51,7 +51,7 @@
 #include <ctype.h>
 #include <dirent.h>
 
-#if defined(__linux) || defined(__sun)
+#if defined(__linux) || defined(__sun) || defined(__NetBSD__)
 #undef USE_THREADS
 #define USE_THREADS
 #include <unistd.h>
@@ -62,7 +62,11 @@
 
 #ifdef USE_THREADS
 #include <pthread.h>
+#ifdef __NetBSD__
+#include <sys/sched.h>
+#else
 #include <sched.h>
+#endif
 
 pthread_t thread;
 pthread_mutex_t mutex;
@@ -81,7 +85,14 @@
 #endif
 #endif
 
-#if defined(__sun) && defined(__GNUC__)
+#ifdef __NetBSD__
+#include <sys/ioctl.h>
+#include <sys/audioio.h>
+#endif
+
+#if defined(__NetBSD__)
+typedef void (*SIG_PF)(int);
+#elif defined(__sun) && defined(__GNUC__)
 typedef void (*SIG_PF)();
 #endif
 
@@ -111,6 +122,51 @@
 int NumControllers = 5;
 
 #ifdef JOYSTICK_SUPPORT
+#ifdef __NetBSD__
+#ifdef HAVE_USBHID_H
+#include <usbhid.h>
+#else
+#include <usb.h>
+#endif
+#define class Class
+#include <dev/usb/usb.h>
+#include <dev/usb/usbhid.h>
+
+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 <linux/joystick.h>
 int js_fd [4] = {-1, -1, -1, -1};
@@ -168,7 +224,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 +668,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_ite
m(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].hid
s));
+                   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 +820,68 @@
 
 void ReadJoysticks ()
 {
+#ifdef __NetBSD__
+    int i, usage, page, d;
+    struct hid_item *h;
+
+    for (i = 0; i < 4 && js_fd [i] >= 0; i++)
+    {
+       read(js_fd [i], priv_joy_data[i].data_buf, priv_joy_data[i].dlen);
+
+       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) & h->physical_maximum;
+
+           page = HID_PAGE(h->usage);
+           usage = HID_USAGE(h->usage);
+
+           if (page == HUP_GENERIC_DESKTOP)
+           {
+               if (usage == HUG_X || usage == HUG_RX)
+               {
+                   if (d == h->physical_minimum)
+                   {
+                       joypads [i] |= SNES_LEFT_MASK;
+                       joypads [i] &= ~SNES_RIGHT_MASK;
+                       continue;
+                   }
+                   if (d == h->physical_maximum)
+                   {
+                       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 == h->physical_minimum)
+                   {
+                       joypads [i] |= SNES_UP_MASK;
+                       joypads [i] &= ~SNES_DOWN_MASK;
+                       continue;
+                   }
+                   if (d == h->physical_maximum)
+                   {
+                       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->physical_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;
@@ -1368,7 +1586,7 @@
 }
 #endif
 
-#ifdef __sun
+#if defined(__sun) || defined(__NetBSD__)
 static int Rates[8] =
 {
     0, 8000, 11025, 16000, 22050, 32000, 37800, 44100
@@ -1541,7 +1759,7 @@
 }
 #endif
 
-#if defined (__linux) || defined (__sun)
+#if defined (__linux) || defined (__sun) || defined(__NetBSD__)
 void S9xUnixProcessSound (void)
 {
 }
@@ -1664,7 +1882,7 @@
 #endif
 
 #endif
-#ifdef __sun
+#if defined(__sun) || defined(__NetBSD__)
     audio_info_t audio;
     if (!Settings.ThreadSound)
     {
@@ -1766,7 +1984,7 @@
     } while (Settings.ThreadSound);
 #endif
 
-#ifdef __sun
+#if defined(__sun) || defined(__NetBSD__)
     if (!Settings.ThreadSound)
        write (so.sound_fd, NULL, 0);
 #endif
@@ -1786,7 +2004,7 @@
     return (0);
 }
 
-#ifdef __sun
+#if defined(__sun) || defined(__NetBSD__)
 uint8 int2ulaw(int ch)
 {
     int mask;

patch-aj:
$NetBSD$

--- snes9x.cpp.orig     Sat Feb  9 11:07:04 2002
+++ snes9x.cpp
@@ -141,6 +141,10 @@
 -joydevX /dev/jsY         Use joystick device /dev/jsY for emulation of gamepad
 X\n");
     S9xMessage (S9X_INFO, S9X_USAGE, "\
 -joymapX 0 1 2 3 4 5 6 7  Joystick buttons which should be assigned to gamepad 
X - A B X Y TL TR Start and Select\n");
+#endif
+#ifdef __NetBSD__
+    S9xMessage (S9X_INFO, S9X_USAGE, "\
+-joymapX 0 1 2 3 4 5 6 7  Joystick buttons which should be assigned to gamepad 
X - A B X Y TL TR Start and Select\n");
 #else
     S9xMessage (S9X_INFO, S9X_USAGE, "\
 -four or -4               Single standard PC joystick has four buttons\n");

	3. make makesum ; make makepatchsum ; make ; make install
	4. if no one report problem, I will feedback the USB support
	   to snes9x.com. ;)
>Fix:
	
>Release-Note:
>Audit-Trail:
>Unformatted: