Skip to content

Instantly share code, notes, and snippets.

@punesemu
Last active May 5, 2020 08:08
Show Gist options
  • Save punesemu/4d655dea169bc93337ab623a3fc387c0 to your computer and use it in GitHub Desktop.
Save punesemu/4d655dea169bc93337ab623a3fc387c0 to your computer and use it in GitHub Desktop.
diff --git a/configure.ac b/configure.ac
index 6550ae9..9a886a8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -94,15 +94,30 @@
my_CPPFLAGS="${my_CPPFLAGS} -I${TOP_SRCDIR}/src/gui/linux -I${TOP_SRCDIR}/src/video/opengl"
linux=yes
- openbsd=no
+ bsd=no
windows=no
with_d3d9=no
with_opengl=yes
],
+ [freebsd*], [
+ LDFLAGS="${LDFLAGS} -L/usr/local/lib"
+ MOCDEFINES="${MOCDEFINES} -D__FreeBSD__"
+ CUSTOMDEFINES="${CUSTOMDEFINES} -DWITH_OPENGL -DGLEW_STATIC"
+ my_CPPFLAGS="${my_CPPFLAGS} -I${TOP_SRCDIR}/src/gui/bsd -I${TOP_SRCDIR}/src/video/opengl"
+ linux=no
+ bsd=yes
+ windows=no
+ with_d3d9=no
+ with_opengl=yes
+ my_CXXFLAGS=""
+ export CC
+ export CXX
+ ],
[openbsd*], [
+ LDFLAGS="${LDFLAGS} -L/usr/local/lib"
MOCDEFINES="${MOCDEFINES} -D__OpenBSD__"
CUSTOMDEFINES="${CUSTOMDEFINES} -DWITH_OPENGL -DGLEW_STATIC"
- my_CPPFLAGS="${my_CPPFLAGS} -I${TOP_SRCDIR}/src/gui/openbsd -I${TOP_SRCDIR}/src/video/opengl"
+ my_CPPFLAGS="${my_CPPFLAGS} -I${TOP_SRCDIR}/src/gui/bsd -I${TOP_SRCDIR}/src/video/opengl"
linux=no
- openbsd=yes
+ bsd=yes
windows=no
with_d3d9=no
@@ -116,5 +131,5 @@
my_CPPFLAGS="${my_CPPFLAGS} -I${TOP_SRCDIR}/src/gui/windows"
linux=no
- openbsd=no
+ bsd=no
windows=yes
AS_IF([test "x$with_opengl" = xyes], [
@@ -143,5 +158,5 @@
AM_CONDITIONAL(LINUX,[test "x$linux" = xyes])
-AM_CONDITIONAL(OPENBSD,[test "x$openbsd" = xyes])
+AM_CONDITIONAL(BSD,[test "x$bsd" = xyes])
AM_CONDITIONAL(WINDOWS,[test "x$windows" = xyes])
AM_CONDITIONAL(ENAB_RELEASE,[test "x$enable_release" = xyes])
@@ -695,5 +710,5 @@
])
-AM_COND_IF([OPENBSD], [
+AM_COND_IF([BSD], [
PKG_CHECK_MODULES(GL, [gl], [
my_CPPFLAGS="${my_CPPFLAGS} ${GL_CFLAGS}"
@@ -895,6 +910,6 @@
my_LIBS="${my_LIBS} -ldl -lpthread"
])
-AM_COND_IF([OPENBSD], [
- my_LIBS="${my_LIBS} -L/usr/local/lib -lstdc++ -lpthread"
+AM_COND_IF([BSD], [
+ my_LIBS="${my_LIBS} -lc++ -lpthread"
])
AM_COND_IF([WINDOWS], [
diff --git a/src/audio/Makefile.am b/src/audio/Makefile.am
index a420a4a..0de2408 100644
--- a/src/audio/Makefile.am
+++ b/src/audio/Makefile.am
@@ -23,5 +23,5 @@
endif
-if OPENBSD
+if BSD
libaudio_a_SOURCES += \
sndio/snd.c
diff --git a/src/audio/sndio/snd.c b/src/audio/sndio/snd.c
index 4bb1b28..eab4c74 100644
--- a/src/audio/sndio/snd.c
+++ b/src/audio/sndio/snd.c
@@ -239,9 +239,7 @@
par.bits = 16;
- par.sig = 1;
par.pchan = snd.channels;
par.rate = snd.samplerate;
par.round = snd.period.samples;
- par.appbufsz = snd.period.samples;
par.xrun = SIO_IGNORE;
diff --git a/src/core/cheat.c b/src/core/cheat.c
index 4e970d0..9d6b24c 100644
--- a/src/core/cheat.c
+++ b/src/core/cheat.c
@@ -142,10 +142,10 @@
}
- ustrncpy(info.rom.file, gg_rom_file, usizeof(info.rom.file));
+ ustrncpy(info.rom.file, gg_rom_file, usizeof(info.rom.file) - 1);
if (!(fp = ufopen(info.rom.file, uL("rb")))) {
gui_overlay_info_append_msg_precompiled(3, NULL);
fprintf(stderr, "error loading Game Genie rom\n");
- ustrncpy(info.rom.file, gamegenie.rom, usizeof(info.rom.file));
+ ustrncpy(info.rom.file, gamegenie.rom, usizeof(info.rom.file) - 1);
gamegenie_free_paths();
return;
@@ -160,5 +160,5 @@
if ((gg_rom_mem = (BYTE *) malloc(size)) == NULL) {
fclose(fp);
- ustrncpy(info.rom.file, gamegenie.rom, usizeof(info.rom.file));
+ ustrncpy(info.rom.file, gamegenie.rom, usizeof(info.rom.file) - 1);
gamegenie_free_paths();
return;
@@ -168,5 +168,5 @@
fclose(fp);
free(gg_rom_mem);
- ustrncpy(info.rom.file, gamegenie.rom, usizeof(info.rom.file));
+ ustrncpy(info.rom.file, gamegenie.rom, usizeof(info.rom.file) - 1);
gamegenie_free_paths();
return;
diff --git a/src/core/emu.c b/src/core/emu.c
index 4f9f9e3..79cacb0 100644
--- a/src/core/emu.c
+++ b/src/core/emu.c
@@ -971,5 +971,5 @@
dst = (uTCHAR *)malloc(sizeof(uTCHAR) * size);
umemset(dst, 0x00, size);
- ustrncpy(dst, src, size);
+ ustrcpy(dst, src);
return (dst);
@@ -1159,9 +1159,9 @@
if (info.rom.from_load_menu) {
- ustrncpy(file, info.rom.from_load_menu, usizeof(file));
+ ustrncpy(file, info.rom.from_load_menu, usizeof(file) - 1);
free(info.rom.from_load_menu);
info.rom.from_load_menu = NULL;
} else if (gamegenie.rom) {
- ustrncpy(file, gamegenie.rom, usizeof(file));
+ ustrncpy(file, gamegenie.rom, usizeof(file) - 1);
} else {
ustrncpy(file, info.rom.file, usizeof(file));
@@ -1176,5 +1176,5 @@
if (rc == UNCOMPRESS_EXIT_OK) {
BYTE is_rom = FALSE, is_patch = FALSE;
- uTCHAR *rom = NULL, *patch = NULL;
+ uTCHAR *patch = NULL;
if (archive->rom.count > 0) {
@@ -1190,5 +1190,5 @@
switch ((rc = uncompress_archive_extract_file(archive,UNCOMPRESS_TYPE_ROM))) {
case UNCOMPRESS_EXIT_OK:
- rom = uncompress_archive_extracted_file_name(archive, UNCOMPRESS_TYPE_ROM);
+ ustrncpy(file, uncompress_archive_extracted_file_name(archive, UNCOMPRESS_TYPE_ROM), usizeof(file) - 1);
found = TRUE;
break;
@@ -1197,12 +1197,9 @@
case UNCOMPRESS_EXIT_IS_COMP_BUT_NOT_SELECTED:
case UNCOMPRESS_EXIT_IS_COMP_BUT_NO_ITEMS:
- rom = info.rom.file;
+ ustrncpy(file, info.rom.file, usizeof(file));
break;
default:
break;
}
- if (rom) {
- ustrncpy(file, rom, usizeof(file));
- }
}
if (is_patch) {
diff --git a/src/core/patcher.c b/src/core/patcher.c
index f89086b..4473955 100644
--- a/src/core/patcher.c
+++ b/src/core/patcher.c
@@ -65,9 +65,9 @@
if (patch) {
- ustrncpy(file, patch, usizeof(file));
+ ustrncpy(file, patch, usizeof(file) - 1);
} else if (patcher.file) {
- ustrncpy(file, patcher.file, usizeof(file));
+ ustrncpy(file, patcher.file, usizeof(file) - 1);
} else if (gamegenie.patch) {
- ustrncpy(file, gamegenie.patch, usizeof(file));
+ ustrncpy(file, gamegenie.patch, usizeof(file) - 1);
} else {
ustrncpy(file, info.rom.file, usizeof(file));
@@ -84,5 +84,4 @@
{
_uncompress_archive *archive;
- uTCHAR *upatch = NULL;
BYTE rc;
@@ -93,5 +92,5 @@
switch ((rc = uncompress_archive_extract_file(archive,UNCOMPRESS_TYPE_PATCH))) {
case UNCOMPRESS_EXIT_OK:
- upatch = uncompress_archive_extracted_file_name(archive, UNCOMPRESS_TYPE_PATCH);
+ ustrncpy(file, uncompress_archive_extracted_file_name(archive, UNCOMPRESS_TYPE_PATCH), usizeof(file) - 1);
found = TRUE;
break;
@@ -101,7 +100,4 @@
break;
}
- if (upatch) {
- ustrncpy(file, upatch, usizeof(file));
- }
}
uncompress_archive_free(archive);
diff --git a/src/core/uncompress.c b/src/core/uncompress.c
index ec80b9d..94b573e 100644
--- a/src/core/uncompress.c
+++ b/src/core/uncompress.c
@@ -115,5 +115,5 @@
}
umemset(archive->file, 0x00, size);
- ustrncpy(archive->file, file, size);
+ ustrcpy(archive->file, file);
archive->rom.count = 0;
diff --git a/src/core/unicode_def.h b/src/core/unicode_def.h
index fade619..2170af7 100644
--- a/src/core/unicode_def.h
+++ b/src/core/unicode_def.h
@@ -44,4 +44,5 @@
#define uvsnprintf vswprintf
#define umemset wmemset
+#define ustrcpy wcscpy
#define ustrncpy wcsncpy
#define usnprintf swprintf
@@ -67,5 +68,5 @@
#define ustrdup _wcsdup
-// linux
+// linux, bsd
#else
@@ -86,4 +87,5 @@
#define uvsnprintf vsnprintf
#define umemset memset
+#define ustrcpy strcpy
#define ustrncpy strncpy
#define usnprintf snprintf
diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am
index 1b16f07..cf9f400 100644
--- a/src/gui/Makefile.am
+++ b/src/gui/Makefile.am
@@ -259,9 +259,9 @@
endif
-if OPENBSD
+if BSD
libgui_a_SOURCES += \
- openbsd/jstick.c \
- openbsd/jstick.h \
- openbsd/os_openbsd.h
+ bsd/jstick.c \
+ bsd/jstick.h \
+ bsd/os_bsd.h
AM_CXXFLAGS = -fPIC
diff --git a/src/gui/bsd/jstick.c b/src/gui/bsd/jstick.c
new file mode 100644
index 0000000..370e85f
--- /dev/null
+++ b/src/gui/bsd/jstick.c
@@ -0,0 +1,1395 @@
+/*
+ * Copyright (C) 2010-2020 Fabio Cavallo (aka FHorse)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <pthread.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include "gui.h"
+#include "conf.h"
+
+#if defined (HAVE_USB_H)
+#include <usb.h>
+#endif
+#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
+
+#if defined (HAVE_USBHID_H)
+#include <usbhid.h>
+#elif defined (HAVE_LIBUSB_H)
+#include <libusb.h>
+#elif defined (HAVE_LIBUSBHID_H)
+#include <libusbhid.h>
+#endif
+
+#if defined (__FreeBSD__) || defined (__FreeBSD_kernel__)
+#if !defined (__DragonFly__)
+#include <osreldate.h>
+#endif
+#include <dev/usb/usb_ioctl.h>
+#include <sys/joystick.h>
+#endif
+
+#if defined (USBHID_UCR_DATA)
+#define REP_BUF_DATA(rep) (rep.buf->ucr_data)
+#elif defined (__FreeBSD__)
+#define REP_BUF_DATA(rep) (rep.buf)
+#else
+#define REP_BUF_DATA(rep) (rep.buf->data)
+#endif
+
+#define JDEV ((_js_device *)joy->jdev)
+#define JS_AXIS_SENSIBILITY 0.45f
+#define JS_AXIS_SENSIBILITY_DIALOG 0.45f
+#define JS_AXIS_TO_FLOAT(vl) (float)(vl - jdev->axis[index].min) / (float)(jdev->axis[index].max - jdev->axis[index].min) * 2.0f - 1.0f
+
+enum _js_types {
+ JS_TYPE_JOY,
+ JS_TYPE_UHID,
+ JS_TYPE_UNKNOW
+};
+enum _js_limit_devs {
+ JS_MAX_JOY_DEV = 0,
+ JS_MAX_UHID_DEV = MAX_JOYSTICK - JS_MAX_JOY_DEV,
+ JS_MAX_DEV = JS_MAX_UHID_DEV + JS_MAX_JOY_DEV
+};
+enum _js_states {
+ JS_ST_CTRL,
+ JS_ST_SCH,
+ JS_ST_MAX
+};
+enum _js_misc {
+ JS_MS_UPDATE_DETECT_DEVICES = 5000,
+};
+enum _js_sc_flags {
+ JS_SC_NONE,
+ JS_SC_MS_XBOX_360_GAMEPD = (1 << 0),
+};
+enum _js_hat {
+ JS_HAT_UP,
+ JS_HAT_UP_RIGHT,
+ JS_HAT_RIGHT,
+ JS_HAT_RIGHT_DOWN,
+ JS_HAT_DOWN,
+ JS_HAT_DOWN_LEFT,
+ JS_HAT_LEFT,
+ JS_HAT_LEFT_UP,
+ JS_HATS = 2,
+};
+enum _js_axes {
+ JS_AXE_X,
+ JS_AXE_Y,
+ JS_AXE_Z,
+ JS_AXE_RX,
+ JS_AXE_RY,
+ JS_AXE_RZ,
+ JS_AXE_SLIDER,
+ JS_AXE_WHEEL,
+ JS_HAT0_A,
+ JS_HAT0_B,
+ JS_HAT1_A,
+ JS_HAT1_B,
+ JS_AXES,
+ // xbox 360 (I treat them like buttons)
+ JS_DPAD_UP = JS_HAT0_A,
+ JS_DPAD_DOWN = JS_HAT0_B,
+ JS_DPAD_LEFT = JS_HAT1_A,
+ JS_DPAD_RIGHT = JS_HAT1_B
+};
+
+typedef struct _usb_hid_device {
+ uTCHAR *desc;
+ uTCHAR *serial;
+ unsigned int flags;
+} _usb_hid_device;
+typedef struct _js_last_states {
+ float *axis;
+ SDBWORD *hat;
+ SDBWORD *button;
+} _js_last_states;
+typedef struct _js_device {
+ BYTE id;
+ BYTE type;
+ uTCHAR dev[30];
+ int fd;
+ struct report_desc *repdesc;
+ struct _js_report {
+ int id;
+#if defined (__FreeBSD__)
+ void *buf;
+#else
+ struct usb_ctl_report *buf;
+#endif
+ int size;
+ } report;
+ struct _js_info {
+ int axes;
+ int buttons;
+ int hats;
+ int balls;
+ } info;
+ struct js_axis_info {
+ BYTE used;
+ float min;
+ float max;
+ float center;
+ } axis[JS_AXES];
+ struct js_hat_info {
+ BYTE used;
+ float min;
+ float max;
+ } hat[JS_HATS];
+ _js_last_states states[JS_ST_MAX];
+ // uhidev
+ _usb_hid_device *usb;
+} _js_device;
+
+static _usb_hid_device *usb_alloc_device(void);
+static void usb_free_device(_usb_hid_device *udev);
+static void usb_free_udd(void);
+static void usb_detect_devices(void);
+
+static _js_device *js_alloc_device(void);
+static void js_free_device(_js_device *jdev);
+static void js_free_jdd(void);
+static void js_detect_devices(void);
+static void js_close_detected_devices(void);
+
+static void js_update_jdev(_js *joy, BYTE enable_decode, BYTE decode_index);
+static void js_update_jdevs(void);
+
+INLINE static DBWORD js_update_axis(_js *joy, _port *port, enum _js_states st, int index, float value, BYTE *mode);
+INLINE static DBWORD js_update_button(_js *joy, _port *port, enum _js_states st, int index, SDBWORD value, BYTE *mode);
+INLINE static DBWORD js_update_hat(_js *joy, _port *port, enum _js_states st, int index, SDBWORD value, BYTE *mode);
+
+INLINE static void js_hat_to_xy(SDBWORD hat, float *x, float *y);
+INLINE static int js_usage_to_axis(unsigned int usage);
+
+INLINE static void js_lock(void);
+INLINE static void js_unlock(void);
+
+#if !defined (__FreeBSD__)
+static const struct _js_special {
+ u_int16_t vendor;
+ u_int16_t product;
+ enum _js_sc_flags flags;
+} js_special_case[] = {
+ { 0x045E, 0x028E, JS_SC_MS_XBOX_360_GAMEPD },
+};
+#endif
+static struct _jstick {
+ double ts_update_devices;
+ pthread_mutex_t lock;
+ struct _usb_devices_detected {
+ int count;
+ _usb_hid_device **devices;
+ } udd;
+ struct _js_devices_detected {
+ int count;
+ _js_device **devices;
+ } jdd;
+} jstick;
+
+_js js[PORT_MAX], js_shcut;
+
+void js_init(BYTE first_time) {
+ int i;
+
+ if (first_time) {
+ memset(&jstick, 0x00, sizeof(jstick));
+
+ if (pthread_mutex_init(&jstick.lock, NULL) != 0) {
+ fprintf(stderr, "Unable to allocate the thread mutex\n");
+ }
+ }
+
+ js_lock();
+ for (i = PORT1; i < PORT_MAX; i++) {
+ memset(&js[i], 0x00, sizeof(_js));
+ js[i].id = port[i].joy_id;
+ }
+ js_detect_devices();
+ js_unlock();
+}
+void js_quit(BYTE last_time) {
+ int i;
+
+ js_close_detected_devices();
+
+ for (i = PORT1; i < PORT_MAX; i++) {
+ js[i].jdev = NULL;
+ }
+
+ if (last_time) {
+ pthread_mutex_destroy(&jstick.lock);
+ }
+}
+void js_update_detected_devices(void) {
+ js_lock();
+ js_detect_devices();
+ js_unlock();
+}
+void js_control(_js *joy, _port *port) {
+ struct hid_item hitem;
+ struct hid_data *hdata;
+ _js_device *jdev = NULL;
+ _js_last_states *states = NULL;
+ BYTE mode = 0;
+
+ js_lock();
+
+ jdev = joy->jdev;
+
+ if (joy->inited == FALSE) {
+ js_unlock();
+ return;
+ } else if (jdev == NULL) {
+ double now = gui_get_ms();
+
+ if ((now - jstick.ts_update_devices) > JS_MS_UPDATE_DETECT_DEVICES) {
+ js_detect_devices();
+ }
+ js_unlock();
+ return;
+ }
+
+ states = &jdev->states[JS_ST_CTRL];
+
+#define js_control_axis(index)\
+ dvl = hid_get_data(REP_BUF_DATA(jdev->report), &hitem);\
+ fvl = JS_AXIS_TO_FLOAT(dvl);\
+ js_update_axis(joy, port, JS_ST_CTRL, index, fvl, &mode);
+#define js_control_button(index)\
+ dvl = hid_get_data(REP_BUF_DATA(jdev->report), &hitem);\
+ js_update_button(joy, port, JS_ST_CTRL, index, dvl, &mode);
+#define js_control_hat(index)\
+ dvl = hid_get_data(REP_BUF_DATA(jdev->report), &hitem);\
+ js_update_hat(joy, port, JS_ST_CTRL, index, dvl, &mode);
+
+ while (read(jdev->fd, REP_BUF_DATA(jdev->report), jdev->report.size) == jdev->report.size) {
+ int hat = 0;
+
+#if defined (USBHID_NEW) || defined (__FreeBSD__)
+ if ((hdata = hid_start_parse(jdev->repdesc, 1 << hid_input, jdev->report.id)) == NULL) {
+#else
+ if ((hdata = hid_start_parse(jdev->repdesc, 1 << hid_input)) == NULL) {
+#endif
+ continue;
+ }
+
+ while (hid_get_item(hdata, &hitem) > 0) {
+ unsigned int usage = HID_USAGE(hitem.usage);
+ unsigned int page = HID_PAGE(hitem.usage);
+ SDBWORD dvl = 0;
+ float fvl = 0;
+
+ if (hitem.kind != hid_input) {
+ continue;
+ }
+
+ if (page == HUP_GENERIC_DESKTOP) {
+ int index;
+
+ if (usage == HUG_HAT_SWITCH) {
+ if (hat >= JS_HATS) {
+ hat++;
+ continue;
+ }
+ js_control_hat(hat);
+ hat++;
+ continue;
+ }
+
+ switch ((index = js_usage_to_axis(usage))) {
+ case JS_DPAD_UP:
+ case JS_DPAD_DOWN:
+ case JS_DPAD_LEFT:
+ case JS_DPAD_RIGHT:
+ if (index >= jdev->info.buttons) {
+ break;
+ }
+ js_control_button((index - JS_DPAD_UP + jdev->info.buttons))
+ break;
+ case JS_AXE_X:
+ case JS_AXE_Y:
+ case JS_AXE_RX:
+ case JS_AXE_RY:
+ case JS_AXE_Z:
+ case JS_AXE_RZ:
+ if (index >= jdev->info.axes) {
+ break;
+ }
+ js_control_axis(index)
+ break;
+ case JS_AXE_SLIDER:
+ case JS_AXE_WHEEL:
+ break;
+ default:
+ break;
+ }
+ } else if (page == HUP_BUTTON) {
+ js_control_button((hitem.usage & 0x0F))
+ }
+ }
+ hid_end_parse(hdata);
+ }
+
+#undef js_control_axis
+#undef js_control_button
+#undef js_control_hat
+
+ js_unlock();
+}
+
+BYTE js_is_connected(int dev) {
+ struct stat sb;
+
+ if (dev >= jstick.jdd.count) {
+ return (EXIT_ERROR);
+ }
+
+ return ((fstat(jstick.jdd.devices[dev]->fd, &sb) == -1) ? EXIT_ERROR : EXIT_OK);
+}
+BYTE js_is_this(BYTE dev, BYTE *id) {
+ if (dev >= jstick.jdd.count) {
+ return (FALSE);
+ }
+
+ return (jstick.jdd.devices[dev]->id == (*id));
+}
+BYTE js_is_null(BYTE *id) {
+ return ((*id) == name_to_jsn(uL("NULL")));
+}
+void js_set_id(BYTE *id, int dev) {
+ if (dev >= jstick.jdd.count) {
+ (*id) = name_to_jsn(uL("NULL"));
+ return;
+ }
+
+ (*id) = jstick.jdd.devices[dev]->id;
+}
+uTCHAR *js_name_device(int dev) {
+ if (dev >= jstick.jdd.count) {
+ return (NULL);
+ }
+
+ // uhidev
+ return (jstick.jdd.devices[dev]->usb->desc);
+}
+uTCHAR *js_to_joyname(const DBWORD val) {
+ static uTCHAR str[20];
+
+ umemset(str, 0x00, usizeof(str));
+
+ if (val < JS_MAX_DEV) {
+ usnprintf(str, usizeof(str), uL("JOYSTICKID%d"), val + 1);
+ } else {
+ usnprintf(str, usizeof(str), uL("NULL"));
+ }
+
+ return (str);
+}
+uTCHAR *js_to_name(const DBWORD val, const _js_element *list, const DBWORD length) {
+ BYTE index;
+ static uTCHAR str[20];
+
+ umemset(str, 0x00, usizeof(str));
+
+ for (index = 0; index < length; index++) {
+ if (val == list[index].value) {
+ ustrncpy(str, list[index].name, usizeof(str));
+ return ((uTCHAR *)str);
+ }
+ }
+ return ((uTCHAR *)list[0].name);
+}
+DBWORD js_from_joyname(const uTCHAR *name) {
+ if (ustrncmp(name, uL("NULL"), 4) == 0) {
+ return (0xFF);
+ }
+
+ if (ustrncmp(name, uL("JOYSTICKID"), 10) == 0) {
+ return (((DBWORD)strtol(name + 10, NULL, 10) - 1));
+ }
+
+ return (0);
+}
+DBWORD js_from_name(const uTCHAR *name, const _js_element *list, const DBWORD length) {
+ DBWORD js = 0;
+ BYTE index;
+
+ for (index = 0; index < length; index++) {
+ if (!ustrcmp(name, list[index].name)) {
+ return (list[index].value);
+ }
+ }
+
+ return (js);
+}
+DBWORD js_read_in_dialog(BYTE *id, UNUSED(int fd)) {
+ struct hid_item hitem;
+ struct hid_data *hdata;
+ _js_device *jdev = NULL;
+ _js_last_states *states = NULL;
+ DBWORD value = 0;
+ int i;
+
+ js_lock();
+
+ for (i = 0; i < jstick.jdd.count; i++) {
+ if ((*id) == jstick.jdd.devices[i]->id) {
+ jdev = jstick.jdd.devices[i];
+ }
+ }
+
+ if (jdev == NULL) {
+ js_unlock();
+ return (value);
+ }
+
+ states = &jdev->states[JS_ST_SCH];
+
+ for (i = 0; i < jdev->info.axes; i++) {
+ states->axis[i] = 0.0f;
+ }
+ for (i = 0; i < jdev->info.hats; i++) {
+ states->hat[i] = 0;
+ }
+ for (i = 0; i < jdev->info.buttons; i++) {
+ states->button[i] = 0;
+ }
+
+#define js_read_in_dialog_axis(axis, vl)\
+ fvl = vl;\
+ if (fvl >= JS_AXIS_SENSIBILITY_DIALOG) {\
+ value = (axis << 1) + 1 + 1;\
+ } else if (fvl <= -JS_AXIS_SENSIBILITY_DIALOG) {\
+ value = (axis << 1) + 1;\
+ }
+#define js_read_in_dialog_button(btn)\
+ if ((dvl = hid_get_data(REP_BUF_DATA(jdev->report), &hitem))) {\
+ value = btn | 0x400;\
+ }
+
+ while (read(jdev->fd, REP_BUF_DATA(jdev->report), jdev->report.size) == jdev->report.size) {
+ int hat = 0;
+
+#if defined (USBHID_NEW) || defined (__FreeBSD__)
+ if ((hdata = hid_start_parse(jdev->repdesc, 1 << hid_input, jdev->report.id)) == NULL) {
+#else
+ if ((hdata = hid_start_parse(jdev->repdesc, 1 << hid_input)) == NULL) {
+#endif
+ continue;
+ }
+
+ while (hid_get_item(hdata, &hitem) > 0) {
+ unsigned int usage = HID_USAGE(hitem.usage);
+ unsigned int page = HID_PAGE(hitem.usage);
+ SDBWORD dvl = 0;
+ float fvl = 0;
+
+ if (hitem.kind != hid_input) {
+ continue;
+ }
+
+ if (page == HUP_GENERIC_DESKTOP) {
+ int index = js_usage_to_axis(usage);
+
+ if (usage == HUG_HAT_SWITCH) {
+ float x, y;
+
+ dvl = hid_get_data(REP_BUF_DATA(jdev->report), &hitem);
+
+ if ((hat >= JS_HATS) || (states->hat[hat] == dvl)) {
+ hat++;
+ continue;
+ }
+
+ states->hat[hat] = dvl;
+ js_hat_to_xy(dvl, &x, &y);
+
+ if (x != 0.0f) {
+ js_read_in_dialog_axis((JS_HAT0_A + hat), x)
+ } else {
+ js_read_in_dialog_axis((JS_HAT0_B + hat), y)
+ }
+
+ hat++;
+ continue;
+ }
+
+ switch (index) {
+ case JS_DPAD_UP:
+ case JS_DPAD_DOWN:
+ case JS_DPAD_LEFT:
+ case JS_DPAD_RIGHT:
+ if (index >= jdev->info.buttons) {
+ break;
+ }
+ js_read_in_dialog_button((index - JS_DPAD_UP + jdev->info.buttons))
+ break;
+ case JS_AXE_X:
+ case JS_AXE_Y:
+ case JS_AXE_RX:
+ case JS_AXE_RY:
+ case JS_AXE_Z:
+ case JS_AXE_RZ:
+ if (index >= jdev->info.axes) {
+ break;
+ }
+ dvl = hid_get_data(REP_BUF_DATA(jdev->report), &hitem);
+ fvl = JS_AXIS_TO_FLOAT(dvl);
+
+ if (states->axis[index] == fvl) {
+ break;
+ }
+
+ states->axis[index] = fvl;
+ js_read_in_dialog_axis(index, fvl)
+ break;
+ case JS_AXE_SLIDER:
+ case JS_AXE_WHEEL:
+ break;
+ default:
+ break;
+ }
+ } else if (page == HUP_BUTTON) {
+ js_read_in_dialog_button((hitem.usage & 0x0F))
+ }
+ }
+ hid_end_parse(hdata);
+ }
+
+#undef js_read_in_dialog_axis
+#undef js_read_in_dialog_button
+
+ js_unlock();
+
+ return (value);
+}
+
+void js_shcut_init(void) {
+ memset(&js_shcut, 0x00, sizeof(_js));
+ js_shcut.id = cfg->input.shcjoy_id;
+ js_update_jdev(&js_shcut, FALSE, 0);
+}
+void js_shcut_stop(void) {}
+BYTE js_shcut_read(_js_sch *js_sch) {
+ struct hid_item hitem;
+ struct hid_data *hdata;
+ _js *joy= &js_shcut;
+ _js_device *jdev;
+ _js_last_states *states = NULL;
+ SDBWORD value = 0;
+ BYTE mode = 0;
+
+ js_sch->value = 0;
+ js_sch->mode = 255;
+
+ js_lock();
+
+ jdev = joy->jdev;
+
+ if (joy->inited == FALSE) {
+ js_unlock();
+ return (value);
+ } else if (jdev == NULL) {
+ double now = gui_get_ms();
+
+ if ((now - jstick.ts_update_devices) > JS_MS_UPDATE_DETECT_DEVICES) {
+ js_detect_devices();
+ }
+ js_unlock();
+ return (value);
+ }
+
+ states = &jdev->states[JS_ST_CTRL];
+
+#define _js_shcut_read_control(funct, index, val)\
+ if ((value = funct(joy, NULL, JS_ST_SCH, index, val, &mode))) {\
+ js_sch->value = value;\
+ js_sch->mode = mode;\
+ js_unlock();\
+ return (EXIT_OK);\
+ }
+#define js_shcut_read_axis(index)\
+ dvl = hid_get_data(REP_BUF_DATA(jdev->report), &hitem);\
+ fvl = JS_AXIS_TO_FLOAT(dvl);\
+ _js_shcut_read_control(js_update_axis, index, fvl)
+#define js_shcut_read_button(index)\
+ dvl = hid_get_data(REP_BUF_DATA(jdev->report), &hitem);\
+ _js_shcut_read_control(js_update_button, index, dvl)
+#define js_shcut_read_hat(index)\
+ dvl = hid_get_data(REP_BUF_DATA(jdev->report), &hitem);\
+ _js_shcut_read_control(js_update_hat, index, dvl)
+
+ while (read(jdev->fd, REP_BUF_DATA(jdev->report), jdev->report.size) == jdev->report.size) {
+ int hat = 0;
+
+#if defined (USBHID_NEW) || defined (__FreeBSD__) || defined (__FreeBSD_kernel__)
+ if ((hdata = hid_start_parse(jdev->repdesc, 1 << hid_input, jdev->report.id)) == NULL) {
+#else
+ if ((hdata = hid_start_parse(jdev->repdesc, 1 << hid_input)) == NULL) {
+#endif
+ continue;
+ }
+
+ while (hid_get_item(hdata, &hitem) > 0) {
+ unsigned int usage = HID_USAGE(hitem.usage);
+ unsigned int page = HID_PAGE(hitem.usage);
+ SDBWORD dvl = 0;
+ float fvl = 0;
+
+ if (hitem.kind != hid_input) {
+ continue;
+ }
+
+ if (page == HUP_GENERIC_DESKTOP) {
+ int index;
+
+ if (usage == HUG_HAT_SWITCH) {
+ if (hat >= JS_HATS) {
+ hat++;
+ continue;
+ }
+ js_shcut_read_hat(hat);
+ hat++;
+ continue;
+ }
+
+ switch ((index = js_usage_to_axis(usage))) {
+ case JS_DPAD_UP:
+ case JS_DPAD_DOWN:
+ case JS_DPAD_LEFT:
+ case JS_DPAD_RIGHT:
+ if (index >= jdev->info.buttons) {
+ break;
+ }
+ js_shcut_read_button((index - JS_DPAD_UP + jdev->info.buttons))
+ break;
+ case JS_AXE_X:
+ case JS_AXE_Y:
+ case JS_AXE_RX:
+ case JS_AXE_RY:
+ case JS_AXE_Z:
+ case JS_AXE_RZ:
+ if (index >= jdev->info.axes) {
+ break;
+ }
+ js_shcut_read_axis(index)
+ break;
+ case JS_AXE_SLIDER:
+ case JS_AXE_WHEEL:
+ break;
+ default:
+ break;
+ }
+ } else if (page == HUP_BUTTON) {
+ js_shcut_read_button((hitem.usage & 0x0F))
+ }
+ }
+ hid_end_parse(hdata);
+ }
+
+#undef _js_shcut_read_control
+#undef js_shcut_read_axis
+#undef js_shcut_read_button
+#undef js_shcut_read_hat
+
+ js_unlock();
+
+ return (EXIT_ERROR);
+}
+
+static _usb_hid_device *usb_alloc_device(void) {
+ _usb_hid_device *udev;
+
+ udev = malloc(sizeof(_usb_hid_device));
+
+ udev->desc = NULL;
+ udev->serial = NULL;
+
+ udev->flags = JS_SC_NONE;
+
+ return (udev);
+}
+static void usb_free_device(_usb_hid_device *udev) {
+ if (udev->desc) {
+ free(udev->desc);
+ udev->desc = NULL;
+ }
+ if (udev->serial) {
+ free(udev->serial);
+ udev->serial = NULL;
+ }
+
+ free(udev);
+}
+static void usb_free_udd(void) {
+ if (jstick.udd.devices) {
+ int i;
+
+ for (i = 0; i < jstick.udd.count; i++) {
+ _usb_hid_device *udev = jstick.udd.devices[i];
+
+ usb_free_device(udev);
+ }
+
+ free(jstick.udd.devices);
+ jstick.udd.devices = NULL;
+ }
+
+ jstick.udd.count = 0;
+}
+#if defined (__FreeBSD__)
+static void usb_detect_devices(void) {
+ uTCHAR dev[30];
+ int i, fd, size;
+
+ usb_free_udd();
+
+ for (i = 0; i < JS_MAX_DEV; i++) {
+ _usb_hid_device *udev;
+ _usb_hid_device **devices;
+
+ usnprintf(dev, usizeof(dev), uL("" UHID_DEV_PATH "%d"), i);
+
+ if ((fd = uopen(dev, O_RDONLY | O_NONBLOCK)) < 0) {
+ continue;
+ }
+ close(fd);
+
+ udev = usb_alloc_device();
+
+ size = ustrlen(dev) + 1;
+
+ if ((udev->desc = (uTCHAR *)malloc(size * sizeof(uTCHAR))) == NULL) {
+ fprintf(stderr, "%s: out of memory\n", dev);
+ goto usb_detect_devices_error;
+ }
+
+ umemset(udev->desc, 0x00, size);
+ usnprintf(udev->desc, size, uL("" uPERCENTs), dev);
+
+ if ((devices = (_usb_hid_device **)realloc(jstick.udd.devices, (jstick.udd.count + 1) * sizeof(_usb_hid_device *))) == NULL) {
+ fprintf(stderr, "%s: out of memory\n", dev);
+ goto usb_detect_devices_error;
+ }
+
+ jstick.udd.devices = devices;
+ jstick.udd.devices[jstick.udd.count] = udev;
+ jstick.udd.count++;
+ continue;
+
+ usb_detect_devices_error:
+ usb_free_device(udev);
+ }
+}
+#else
+static void usb_detect_devices(void) {
+ int i;
+
+ usb_free_udd();
+
+ for (i = 0; i < JS_MAX_UHID_DEV; i++) {
+ struct usb_device_info udi;
+ uTCHAR dev[30];
+ int a, fd;
+
+ usnprintf(dev, usizeof(dev), uL("" USB_DEV_PATH "%d"), i);
+
+ if ((fd = uopen(dev, O_RDONLY | O_NONBLOCK)) < 0) {
+ continue;
+ }
+
+ for (a = 1; a < USB_MAX_DEVICES; a++) {
+ BYTE vendor = FALSE;
+ udi.udi_addr = a;
+ int b, size;
+
+ if (ioctl(fd, USB_DEVICEINFO, &udi) == -1) {
+ continue;
+ }
+
+ for (b = 0; b < USB_MAX_DEVNAMES; b++) {
+ _usb_hid_device *udev;
+ _usb_hid_device **devices;
+ unsigned int c;
+
+ if (ustrncmp(udi.udi_devnames[b], uL("uhidev"), 6) != 0) {
+ continue;
+ }
+
+ udev = usb_alloc_device();
+
+#if defined (__NetBSD__)
+ {
+ usb_device_descriptor_t udd;
+ struct usb_string_desc usd;
+
+ if (ioctl(fd, USB_GET_DEVICE_DESC, &udd) != -1) {
+ // Get default language
+ usd.usd_string_index = USB_LANGUAGE_TABLE;
+ usd.usd_language_id = 0;
+
+ if ((ioctl(fd, USB_GET_STRING_DESC, &usd) == -1) || (usd.usd_desc.bLength < 4)) {
+ usd.usd_language_id = 0;
+ } else {
+ usd.usd_language_id = UGETW(usd.usd_desc.bString[0]);
+ }
+
+ usd.usd_string_index = udd.iProduct;
+
+ if (ioctl(fd, USB_GET_STRING_DESC, &usd) == 0) {
+ char str[128];
+ int d;
+
+ for (d = 0; d < (usd.usd_desc.bLength >> 1) - 1 && d < sizeof(str) - 1; d++) {
+ str[d] = UGETW(usd.usd_desc.bString[d]);
+ }
+ str[d] = '\0';
+
+ asprintf(&udev->desc, "%s", str);
+ }
+ }
+ }
+#else
+ size = ustrlen(udi.udi_product) + 1;
+
+ if (ustrlen(udi.udi_vendor) && ustrncmp(udi.udi_vendor, uL("vendor 0x"), 9) != 0) {
+ size += ustrlen(udi.udi_vendor) + 1;
+ vendor = TRUE;
+ }
+
+ if (size > 1) {
+ if ((udev->desc = (uTCHAR *)malloc(size * sizeof(uTCHAR))) == NULL) {
+ fprintf(stderr, "%s: out of memory\n", dev);
+ goto usb_detect_devices_error;
+ }
+
+ umemset(udev->desc, 0x00, size);
+
+ if (vendor == TRUE) {
+ usnprintf(udev->desc, size, uL("" uPERCENTs " " uPERCENTs), udi.udi_vendor, udi.udi_product);
+ } else {
+ usnprintf(udev->desc, size, uL("" uPERCENTs), udi.udi_product);
+ }
+ }
+
+ if ((size = ustrlen(udi.udi_serial) + 1) > 1) {
+ if ((udev->serial = (uTCHAR *)malloc(size * sizeof(uTCHAR))) == NULL) {
+ fprintf(stderr, "%s: out of memory\n", dev);
+ goto usb_detect_devices_error;
+ }
+
+ umemset(udev->serial, 0x00, size);
+
+ usnprintf(udev->serial, size, uL("" uPERCENTs), udi.udi_serial);
+ }
+#endif
+
+ // special case
+ for (c = 0; c < LENGTH(js_special_case); c++) {
+ if ((udi.udi_vendorNo == js_special_case[c].vendor) &&
+ (udi.udi_productNo == js_special_case[c].product)) {
+ udev->flags |= js_special_case[c].flags;
+ }
+ }
+
+ if ((devices = (_usb_hid_device **)realloc(jstick.udd.devices,
+ (jstick.udd.count + 1) * sizeof(_usb_hid_device *))) == NULL) {
+ fprintf(stderr, "%s: out of memory\n", dev);
+ goto usb_detect_devices_error;
+ }
+
+ jstick.udd.devices = devices;
+ jstick.udd.devices[jstick.udd.count] = udev;
+ jstick.udd.count++;
+ continue;
+
+ usb_detect_devices_error:
+ usb_free_device(udev);
+ }
+ }
+ close(fd);
+ }
+}
+#endif
+
+static _js_device *js_alloc_device(void) {
+ _js_device *jdev;
+ int i;
+
+ jdev = malloc(sizeof(_js_device));
+
+ jdev->type = JS_TYPE_UNKNOW;
+ jdev->fd = 0;
+ jdev->repdesc = NULL;
+ jdev->report.buf = NULL;
+ jdev->report.id = -1;
+ jdev->report.size = 0;
+ jdev->info.axes = 0;
+ jdev->info.buttons = 0;
+ jdev->info.hats = 0;
+ jdev->info.balls = 0;
+
+ umemset(&jdev->dev, 0x00, usizeof(jdev->dev));
+
+ for (i = 0; i < JS_AXES; i++) {
+ jdev->axis[i].used = FALSE;
+ jdev->axis[i].min = 0.0f;
+ jdev->axis[i].max = 0.0f;
+ jdev->axis[i].center = 0.0f;
+ }
+
+ for (i = 0; i < JS_HATS; i++) {
+ jdev->hat[i].used = FALSE;
+ jdev->hat[i].min = 0.0f;
+ jdev->hat[i].max = 0.0f;
+ }
+
+ for (i = 0; i < JS_ST_MAX; i++) {
+ jdev->states[i].axis = NULL;
+ jdev->states[i].hat = NULL;
+ jdev->states[i].button = NULL;
+ };
+
+ jdev->usb = NULL;
+
+ return (jdev);
+}
+static void js_free_device(_js_device *jdev) {
+ int i;
+
+ if (jdev->repdesc) {
+ hid_dispose_report_desc(jdev->repdesc);
+ jdev->repdesc = NULL;
+ }
+ if (jdev->report.buf) {
+ free(jdev->report.buf);
+ jdev->report.buf = NULL;
+ }
+ if (jdev->fd) {
+ close(jdev->fd);
+ jdev->fd = 0;
+ }
+ for (i = 0; i < JS_ST_MAX; i++) {
+ if (jdev->states[i].axis) {
+ free(jdev->states[i].axis);
+ jdev->states[i].axis = NULL;
+ }
+ if (jdev->states[i].hat) {
+ free(jdev->states[i].hat);
+ jdev->states[i].hat = NULL;
+ }
+ if (jdev->states[i].button) {
+ free(jdev->states[i].button);
+ jdev->states[i].button = NULL;
+ }
+ }
+ jdev->usb = NULL;
+
+ free(jdev);
+}
+static void js_free_jdd(void) {
+ if (jstick.jdd.devices) {
+ int i;
+
+ for (i = 0; i < jstick.jdd.count; i++) {
+ _js_device *jdev = jstick.jdd.devices[i];
+
+ js_free_device(jdev);
+ }
+
+ free(jstick.jdd.devices);
+ jstick.jdd.devices = NULL;
+ }
+
+ jstick.jdd.count = 0;
+}
+static void js_detect_devices(void) {
+ int i, hid_connected = 0;
+
+ js_free_jdd();
+ usb_detect_devices();
+
+ for (i = 0; i < JS_MAX_DEV; i++) {
+ static _js_device *jdev;
+ struct hid_item hitem;
+ struct hid_data *hdata;
+
+ jdev = js_alloc_device();
+
+ jdev->id = i;
+
+ usnprintf(jdev->dev, usizeof(jdev->dev), uL("" UHID_DEV_PATH "%d"), jdev->id);
+ jdev->type = JS_TYPE_UHID;
+
+ if ((jdev->fd = uopen(jdev->dev, O_RDONLY | O_NONBLOCK)) < 0) {
+ goto js_detect_devices_error;
+ }
+
+ if ((jdev->repdesc = hid_get_report_desc(jdev->fd)) == NULL) {
+ fprintf(stderr, "%s: hid_get_report_desc: %s\n", jdev->dev, strerror(errno));
+ goto js_detect_devices_error;
+ }
+
+#if defined (__FreeBSD__)
+ if ((jdev->report.id = hid_get_report_id(jdev->fd)) < 0) {
+#else
+ if (ioctl(jdev->fd, USB_GET_REPORT_ID, &jdev->report.id) < 0) {
+#endif
+ jdev->report.id = -1;
+ }
+
+#if defined (__DragonFly__)
+ if ((jdev->report.size = hid_report_size(jdev->repdesc, jdev->report.id, hid_input)) <= 0) {
+#elif defined (__FreeBSD__)
+ if ((jdev->report.size = hid_report_size(jdev->repdesc, hid_input, jdev->report.id)) <= 0) {
+#elif defined (USBHID_NEW)
+ if ((jdev->report.size = hid_report_size(jdev->repdesc, hid_input, jdev->report.id)) <= 0) {
+#else
+ if ((jdev->report.size = hid_report_size(jdev->repdesc, hid_input, &jdev->report.id)) <= 0) {
+#endif
+ fprintf(stderr, "%s: hid_report_size() return invalid size\n", jdev->dev);
+ goto js_detect_devices_error;
+ }
+
+#if defined (__FreeBSD__)
+ if ((jdev->report.buf = malloc(jdev->report.size)) == NULL) {
+#else
+ if ((jdev->report.buf = malloc(sizeof(*jdev->report.buf) - sizeof(REP_BUF_DATA(jdev->report)) + jdev->report.size)) == NULL) {
+#endif
+ fprintf(stderr, "%s: error on malloc report buf\n", jdev->dev);
+ goto js_detect_devices_error;
+ }
+
+#if defined (USBHID_NEW) || defined (__FreeBSD__)
+ if ((hdata = hid_start_parse(jdev->repdesc, 1 << hid_input, jdev->report.id)) == NULL) {
+#else
+ if ((hdata = hid_start_parse(jdev->repdesc, 1 << hid_input)) == NULL) {
+#endif
+ fprintf(stderr, "%s: hid_start_parse() don't start", jdev->dev);
+ goto js_detect_devices_error;
+ }
+
+ while (hid_get_item(hdata, &hitem) > 0) {
+ unsigned int usage = HID_USAGE(hitem.usage);
+ unsigned int page = HID_PAGE(hitem.usage);
+
+ switch (hitem.kind) {
+ case hid_collection:
+ if ((page == HUP_GENERIC_DESKTOP) && ((usage == HUG_JOYSTICK) || (usage == HUG_GAME_PAD))) {
+ jdev->usb = jstick.udd.devices[hid_connected];
+ }
+ break;
+ case hid_input:
+ if (page == HUP_GENERIC_DESKTOP) {
+ int index = js_usage_to_axis(usage);
+
+ if (index >= 0) {
+ jdev->axis[index].used = TRUE;
+ jdev->axis[index].min = hitem.logical_minimum;
+ jdev->axis[index].max = hitem.logical_maximum;
+ if ((jdev->usb->flags & JS_SC_MS_XBOX_360_GAMEPD) && ((index == JS_AXE_Z) || (index == JS_AXE_RZ))) {
+ jdev->axis[index].min = -hitem.logical_maximum;
+ }
+ jdev->axis[index].center = (jdev->axis[index].min / jdev->axis[index].max) * 0.5f;
+ jdev->info.axes++;
+ } else if (usage == HUG_HAT_SWITCH) {
+ if (jdev->info.hats < JS_HATS) {
+ jdev->hat[jdev->info.hats].used = TRUE;
+ jdev->hat[jdev->info.hats].min = hitem.logical_minimum;
+ jdev->hat[jdev->info.hats].max = hitem.logical_maximum;
+ jdev->info.hats++;
+ }
+ }
+ } else if (page == HUP_BUTTON) {
+ jdev->info.buttons++;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ hid_end_parse(hdata);
+
+ hid_connected++;
+
+ if ((jdev->info.axes == 0) && (jdev->info.buttons == 0) && (jdev->info.hats == 0) && (jdev->info.balls == 0)) {
+ fprintf(stderr, "%s: is not a joystick\n", jdev->dev);
+ goto js_detect_devices_error;
+ }
+
+ // flush pending events
+ while (read(jdev->fd, REP_BUF_DATA(jdev->report), jdev->report.size) == jdev->report.size) {
+ ;
+ }
+
+ {
+ _js_device **devices;
+ int a;
+
+ for (a = 0; a < JS_ST_MAX; a++) {
+ _js_last_states *st = &jdev->states[a];
+
+ if (jdev->info.axes && ((st->axis = malloc(jdev->info.axes * sizeof(float))) == NULL)) {
+ fprintf(stderr, "%s: error on malloc states axes\n", jdev->dev);
+ goto js_detect_devices_error;
+ }
+ if (jdev->info.hats && ((st->hat = malloc(jdev->info.hats * sizeof(SDBWORD))) == NULL)) {
+ fprintf(stderr, "%s: error on malloc states hats\n", jdev->dev);
+ goto js_detect_devices_error;
+ }
+ if (jdev->info.buttons && ((st->button = malloc(jdev->info.buttons * sizeof(SDBWORD)))) == NULL) {
+ fprintf(stderr, "%s: error on malloc states buttons\n", jdev->dev);
+ goto js_detect_devices_error;
+ }
+ memset(st->axis, 0x00, jdev->info.axes * sizeof(float));
+ memset(st->hat, 0x00, jdev->info.hats * sizeof(SDBWORD));
+ memset(st->button, 0x00, jdev->info.buttons * sizeof(SDBWORD));
+ }
+
+ if ((devices = (_js_device **)realloc(jstick.jdd.devices, (jstick.jdd.count + 1) * sizeof(_js_device))) == NULL) {
+ fprintf(stderr, "%s: out of memory\n", jdev->dev);
+ goto js_detect_devices_error;
+ }
+
+ jstick.jdd.devices = devices;
+ jstick.jdd.devices[jstick.jdd.count] = jdev;
+ jstick.jdd.count++;
+
+ jdev = jstick.jdd.devices[jstick.jdd.count - 1];
+ continue;
+ }
+
+ js_detect_devices_error:
+ js_free_device(jdev);
+ }
+
+ js_update_jdevs();
+
+ jstick.ts_update_devices = gui_get_ms();
+}
+static void js_close_detected_devices(void) {
+ js_free_jdd();
+ usb_free_udd();
+}
+
+static void js_update_jdev(_js *joy, BYTE enable_decode, BYTE decode_index) {
+ joy->jdev = NULL;
+ joy->inited = FALSE;
+ joy->input_decode_event = NULL;
+
+ if (js_is_null(&joy->id) == FALSE) {
+ int d;
+
+ for (d = 0; d < jstick.jdd.count; d++) {
+ if (joy->id == jstick.jdd.devices[d]->id) {
+ joy->jdev = jstick.jdd.devices[d];
+ break;
+ }
+ }
+
+ joy->inited = TRUE;
+
+ if (enable_decode) {
+ joy->input_decode_event = port_funct[decode_index].input_decode_event;
+ }
+ }
+}
+static void js_update_jdevs(void) {
+ int i;
+
+ for (i = PORT1; i < PORT_MAX; i++) {
+ js_update_jdev(&js[i], TRUE, i);
+ }
+ // shortcut
+ js_update_jdev(&js_shcut, FALSE, 0);
+}
+
+INLINE static DBWORD js_update_axis(_js *joy, _port *port, enum _js_states st, int index, float value, BYTE *mode) {
+ DBWORD event = (index << 1) + 1;
+ float last_value;
+
+ (*mode) = PRESSED;
+
+ last_value = JDEV->states[st].axis[index];
+
+ if ((value < JS_AXIS_SENSIBILITY) && (value > -JS_AXIS_SENSIBILITY)) {
+ value = 0.0f;
+ (*mode) = RELEASED;
+ if (last_value > 0) {
+ event++;
+ }
+ } else if (value <= - JS_AXIS_SENSIBILITY) {
+ value = -1.0f;
+ } else {
+ value = 1.0f;
+ event++;
+ }
+
+ JDEV->states[st].axis[index] = value;
+
+ if (value != last_value) {
+ if (joy->input_decode_event) {
+ joy->input_decode_event((*mode), FALSE, event, JOYSTICK, port);
+ }
+ return (event);
+ }
+ return (0);
+}
+INLINE static DBWORD js_update_button(_js *joy, _port *port, enum _js_states st, int index, SDBWORD value, UNUSED(BYTE *mode)) {
+ DBWORD event = 0;
+
+ if (value != JDEV->states[st].button[index]) {
+ JDEV->states[st].button[index] = value;
+ event = index | 0x400;
+ if (joy->input_decode_event) {
+ joy->input_decode_event(value, FALSE, event, JOYSTICK, port);
+ }
+ }
+ return (event);
+}
+INLINE static DBWORD js_update_hat(_js *joy, _port *port, enum _js_states st, int index, SDBWORD value, BYTE *mode) {
+ float x = 0.0f, y = 0.0f;
+ DBWORD event = 0;
+
+ js_hat_to_xy(value, &x, &y);
+
+ if (!(event = js_update_axis(joy, port, st, JS_HAT0_A + index, x, mode))) {
+ event = js_update_axis(joy, port, st, JS_HAT0_B + index, y, mode);
+ }
+ return (event);
+}
+
+INLINE static void js_hat_to_xy(SDBWORD hat, float *x, float *y) {
+ static const int hat_map[8] = {
+ JS_HAT_UP,
+ JS_HAT_UP_RIGHT,
+ JS_HAT_RIGHT,
+ JS_HAT_RIGHT_DOWN,
+ JS_HAT_DOWN,
+ JS_HAT_DOWN_LEFT,
+ JS_HAT_LEFT,
+ JS_HAT_LEFT_UP,
+ };
+
+ (*x) = (*y) = 0.0f;
+
+ if ((hat & 0x000F) == 0x000F) {
+ return;
+ }
+
+ if ((hat & 0x07) == hat) {
+ switch (hat_map[hat]) {
+ case JS_HAT_UP:
+ (*x) = 1.0f;
+ break;
+ case JS_HAT_UP_RIGHT:
+ (*x) = 1.0f;
+ (*y) = 1.0f;
+ break;
+ case JS_HAT_RIGHT:
+ (*y) = 1.0f;
+ break;
+ case JS_HAT_RIGHT_DOWN:
+ (*x) = -1.0f;
+ (*y) = 1.0f;
+ break;
+ case JS_HAT_DOWN:
+ (*x) = -1.0f;
+ break;
+ case JS_HAT_DOWN_LEFT:
+ (*x) = -1.0f;
+ (*y) = -1.0f;
+ break;
+ case JS_HAT_LEFT:
+ (*y) = -1.0f;
+ break;
+ case JS_HAT_LEFT_UP:
+ (*x) = 1.0f;
+ (*y) = -1.0f;
+ break;
+ }
+ }
+}
+INLINE static int js_usage_to_axis(unsigned int usage) {
+ int axis;
+
+ switch (usage) {
+ case HUG_X:
+ axis = JS_AXE_X;
+ break;
+ case HUG_Y:
+ axis = JS_AXE_Y;
+ break;
+ case HUG_Z:
+ axis = JS_AXE_Z;
+ break;
+ case HUG_RX:
+ axis = JS_AXE_RX;
+ break;
+ case HUG_RY:
+ axis = JS_AXE_RY;
+ break;
+ case HUG_RZ:
+ axis = JS_AXE_RZ;
+ break;
+ case HUG_SLIDER:
+ axis = JS_AXE_SLIDER;
+ break;
+ case HUG_WHEEL:
+ axis = JS_AXE_WHEEL;
+ break;
+ case 0x90:
+ axis = JS_DPAD_UP;
+ break;
+ case 0x91:
+ axis = JS_DPAD_DOWN;
+ break;
+ case 0x93:
+ axis = JS_DPAD_LEFT;
+ break;
+ case 0x92:
+ axis = JS_DPAD_RIGHT;
+ break;
+ default:
+ axis = -1;
+ break;
+ }
+
+ return (axis);
+}
+
+INLINE static void js_lock(void) {
+ pthread_mutex_lock(&jstick.lock);
+}
+INLINE static void js_unlock(void) {
+ pthread_mutex_unlock(&jstick.lock);
+}
diff --git a/src/gui/bsd/jstick.h b/src/gui/bsd/jstick.h
new file mode 100644
index 0000000..8670636
--- /dev/null
+++ b/src/gui/bsd/jstick.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2010-2020 Fabio Cavallo (aka FHorse)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef JSTICK_H_
+#define JSTICK_H_
+
+#include "common.h"
+#include "input.h"
+
+#define JOY_DEV_PATH "/dev/joy"
+#define UHID_DEV_PATH "/dev/uhid"
+#define USB_DEV_PATH "/dev/usb"
+#define name_to_jsv(name) js_from_name(name, jsv_list, LENGTH(jsv_list))
+#define name_to_jsn(name) js_from_joyname(name)
+#define jsv_to_name(jsvl) js_to_name(jsvl, jsv_list, LENGTH(jsv_list))
+#define jsn_to_name(jsvl) js_to_joyname(jsvl)
+
+typedef struct _js {
+ BYTE inited;
+ BYTE id;
+ void *jdev;
+ BYTE (*input_decode_event)(BYTE mode, BYTE autorepeat, DBWORD event, BYTE type, _port *port);
+} _js;
+typedef struct _js_element {
+ DBWORD value;
+ uTCHAR name[20];
+} _js_element;
+typedef struct _js_sch {
+ DBWORD value;
+ BYTE mode;
+} _js_sch;
+
+static const _js_element jsv_list[] = {
+ { 0x000, uL("NULL") },
+ { 0x001, uL("JA0MIN") }, { 0x002, uL("JA0PLS") },
+ { 0x003, uL("JA1MIN") }, { 0x004, uL("JA1PLS") },
+ { 0x005, uL("JA2MIN") }, { 0x006, uL("JA2PLS") },
+ { 0x007, uL("JA3MIN") }, { 0x008, uL("JA3PLS") },
+ { 0x009, uL("JA4MIN") }, { 0x00A, uL("JA4PLS") },
+ { 0x00B, uL("JA5MIN") }, { 0x00C, uL("JA5PLS") },
+ { 0x00D, uL("JA6MIN") }, { 0x00E, uL("JA6PLS") },
+ { 0x00F, uL("JA7MIN") }, { 0x010, uL("JA7PLS") },
+ { 0x011, uL("JA8MIN") }, { 0x012, uL("JA8PLS") },
+ { 0x013, uL("JA9MIN") }, { 0x014, uL("JA9PLS") },
+ { 0x015, uL("JAAMIN") }, { 0x016, uL("JAAPLS") },
+ { 0x017, uL("JABMIN") }, { 0x018, uL("JABPLS") },
+ { 0x019, uL("JACMIN") }, { 0x01A, uL("JACPLS") },
+ { 0x01B, uL("JADMIN") }, { 0x01C, uL("JADPLS") },
+ { 0x01D, uL("JAEMIN") }, { 0x01E, uL("JAEPLS") },
+ { 0x01F, uL("JAFMIN") }, { 0x020, uL("JAFPLS") },
+ { 0x400, uL("JB0") }, { 0x401, uL("JB1") },
+ { 0x402, uL("JB2") }, { 0x403, uL("JB3") },
+ { 0x404, uL("JB4") }, { 0x405, uL("JB5") },
+ { 0x406, uL("JB6") }, { 0x407, uL("JB7") },
+ { 0x408, uL("JB8") }, { 0x409, uL("JB9") },
+ { 0x40A, uL("JB10") }, { 0x40B, uL("JB11") },
+ { 0x40C, uL("JB12") }, { 0x40D, uL("JB13") },
+ { 0x40E, uL("JB14") }, { 0x40F, uL("JB15") },
+ { 0x410, uL("JB16") }, { 0x411, uL("JB17") },
+ { 0x412, uL("JB18") }, { 0x413, uL("JB19") },
+ { 0x414, uL("JB20") }, { 0x415, uL("JB21") },
+ { 0x416, uL("JB22") }, { 0x417, uL("JB23") },
+ { 0x418, uL("JB24") }, { 0x419, uL("JB25") },
+ { 0x41A, uL("JB26") }, { 0x41B, uL("JB27") },
+ { 0x41C, uL("JB28") }, { 0x41D, uL("JB29") },
+ { 0x41E, uL("JB30") }, { 0x41F, uL("JB31") },
+ { 0x420, uL("JB32") }, { 0x421, uL("JB33") },
+ { 0x422, uL("JB34") }, { 0x423, uL("JB35") },
+};
+
+extern _js js[PORT_MAX], js_shcut;
+
+#if defined (__cplusplus)
+#define EXTERNC extern "C"
+#else
+#define EXTERNC
+#endif
+
+EXTERNC void js_init(BYTE first_time);
+EXTERNC void js_quit(BYTE last_time);
+EXTERNC void js_update_detected_devices(void);
+EXTERNC void js_control(_js *joy, _port *port);
+
+EXTERNC BYTE js_is_connected(int dev);
+EXTERNC BYTE js_is_this(BYTE dev, BYTE *id);
+EXTERNC BYTE js_is_null(BYTE *id);
+EXTERNC void js_set_id(BYTE *id, int dev);
+EXTERNC uTCHAR *js_name_device(int dev);
+EXTERNC uTCHAR *js_to_joyname(const DBWORD val);
+EXTERNC uTCHAR *js_to_name(const DBWORD val, const _js_element *list, const DBWORD length);
+EXTERNC DBWORD js_from_joyname(const uTCHAR *name);
+EXTERNC DBWORD js_from_name(const uTCHAR *name, const _js_element *list, const DBWORD length);
+EXTERNC DBWORD js_read_in_dialog(BYTE *id, int fd);
+
+EXTERNC void js_shcut_init(void);
+EXTERNC void js_shcut_stop(void);
+EXTERNC BYTE js_shcut_read(_js_sch *js_sch);
+
+#undef EXTERNC
+
+#endif /* JSTICK_H_ */
diff --git a/src/gui/bsd/os_bsd.h b/src/gui/bsd/os_bsd.h
new file mode 100644
index 0000000..815f15b
--- /dev/null
+++ b/src/gui/bsd/os_bsd.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2010-2020 Fabio Cavallo (aka FHorse)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef OS_BSD_H_
+#define OS_BSD_H_
+
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#include <time.h>
+
+#include <stdio.h>
+
+static double high_resolution_ms(void);
+static int __nsleep(const struct timespec *req, struct timespec *rem);
+
+void gui_init(int *argc, char **argv) {
+ memset(&gui, 0, sizeof(gui));
+ qt = {};
+
+ qt.app = new QApplication((*argc), argv);
+
+ info.gui = TRUE;
+ gui.in_update = FALSE;
+ gui.main_win_lfp = 0;
+
+ // cerco la HOME e imposto la directory base
+ {
+ gui.home = getenv("HOME");
+
+ if (!gui.home) {
+ gui.home = QDir::homePath().toUtf8().constData();
+ }
+
+ if (info.portable) {
+ uTCHAR path[usizeof(info.base_folder)];
+ size_t len = usizeof(path);
+ int name[] = { CTL_KERN, KERN_PROC_CWD, 0 };
+
+ name[2] = getpid();
+ umemset(&path, 0x00, usizeof(path));
+
+ if (sysctl(name, 3, &path, &len, NULL, 0) != 0) {
+ fprintf(stderr, "INFO: Error on sysctl.\n");
+ info.portable = FALSE;
+ } else {
+ ustrncpy(info.base_folder, path, usizeof(info.base_folder));
+ }
+ } else {
+ usnprintf(info.base_folder, usizeof(info.base_folder), uL("" uPERCENTs "/." NAME), gui.home);
+ }
+ }
+
+ gettimeofday(&gui.counterStart, nullptr);
+ gui_get_ms = high_resolution_ms;
+}
+void gui_sleep(double ms) {
+ struct timespec req = {}, rem = {};
+ time_t sec;
+
+ if (ms <= 0) {
+ return;
+ }
+
+ sec = (time_t)(ms / 1000.0f);
+ ms = ms - ((double)sec * 1000.0f);
+ req.tv_sec = sec;
+ req.tv_nsec = ms * 1000000L;
+ __nsleep(&req, &rem);
+}
+int gui_screen_id(void) {
+ int wid = qt.screen->wogl->winId();
+
+ return (wid);
+}
+
+static double high_resolution_ms(void) {
+ struct timeval time;
+ double elapsed_seconds;
+ double elapsed_useconds;
+
+ gettimeofday(&time, nullptr);
+
+ elapsed_seconds = time.tv_sec - gui.counterStart.tv_sec;
+ elapsed_useconds = time.tv_usec - gui.counterStart.tv_usec;
+
+ return ((elapsed_seconds * 1000.0f) + (elapsed_useconds / 1000.0f));
+}
+static int __nsleep(const struct timespec *req, struct timespec *rem) {
+ struct timespec temp_rem;
+
+ if (nanosleep(req, rem) == -1) {
+ __nsleep(rem, &temp_rem);
+ } else {
+ return (EXIT_ERROR);
+ }
+
+ return (EXIT_OK);
+}
+
+#endif /* OS_BSD_H_ */
diff --git a/src/gui/dlgStdPad.cpp b/src/gui/dlgStdPad.cpp
index e6a5b56..35aba9c 100644
--- a/src/gui/dlgStdPad.cpp
+++ b/src/gui/dlgStdPad.cpp
@@ -205,4 +205,7 @@
#endif
+ js_quit(FALSE);
+ js_init(FALSE);
+
mainwin->shcjoy_start();
@@ -353,6 +356,5 @@
findChild<QLabel *>("label_" + SPT(type) + "_" + SPB(a))->setStyleSheet("");
findChild<QPushButton *>("pushButton_" + SPT(type) + "_" + SPB(a))->setEnabled(mode);
- findChild<QPushButton *>("pushButton_" + SPT(type) +
- "_unset_" + SPB(a))->setEnabled(mode);
+ findChild<QPushButton *>("pushButton_" + SPT(type) + "_unset_" + SPB(a))->setEnabled(mode);
}
}
@@ -587,12 +589,10 @@
}
- bt = findChild<QPushButton *>(
- "pushButton_" + SPT(data.seq.type) + "_" + SPB(order[data.seq.counter]));
+ bt = findChild<QPushButton *>("pushButton_" + SPT(data.seq.type) + "_" + SPB(order[data.seq.counter]));
bt->setEnabled(true);
bt->click();
}
void dlgStdPad::s_apply_clicked(UNUSED(bool checked)) {
- _cfg_port *cfg_port = ((_cfg_port *)((QPushButton *)sender())->property(
- "myPointer").value<void *>());
+ _cfg_port *cfg_port = ((_cfg_port *)((QPushButton *)sender())->property("myPointer").value<void *>());
memcpy(cfg_port, &data.cfg, sizeof(_cfg_port));
diff --git a/src/gui/openbsd/jstick.c b/src/gui/openbsd/jstick.c
deleted file mode 100644
index 51f80fb..0000000
--- a/src/gui/openbsd/jstick.c
+++ /dev/null
@@ -1,1442 +0,0 @@
-/*
- * Copyright (C) 2010-2020 Fabio Cavallo (aka FHorse)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <errno.h>
-#include <pthread.h>
-#include <sys/stat.h>
-#include "gui.h"
-#include "conf.h"
-
-#ifndef __FreeBSD_kernel_version
-#define __FreeBSD_kernel_version __FreeBSD_version
-#endif
-
-#if defined (HAVE_USB_H)
-#include <usb.h>
-#endif
-#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
-
-#if defined (HAVE_USBHID_H)
-#include <usbhid.h>
-#elif defined (HAVE_LIBUSB_H)
-#include <libusb.h>
-#elif defined (HAVE_LIBUSBHID_H)
-#include <libusbhid.h>
-#endif
-
-#if defined (__FREEBSD__) || defined (__FreeBSD_kernel__)
-#if !defned (__DragonFly__)
-#include <osreldate.h>
-#endif
-#if __FreeBSD_kernel_version > 800063
-#include <dev/usb/usb_ioctl.h>
-#endif
-#include <sys/joystick.h>
-#endif
-
-#if defined (USBHID_MACHINE_JOYSTICK)
-#include <machine/joystick.h>
-#endif
-
-#if defined (USBHID_UCR_DATA) || (defined (__FreeBSD_kernel__) && __FreeBSD_kernel_version <= 800063)
-#define REP_BUF_DATA(rep) (rep.buf->ucr_data)
-#elif (defined (__FREEBSD__) && (__FreeBSD_kernel_version > 900000))
-#define REP_BUF_DATA(rep) (rep.buf)
-#elif (defined (__FREEBSD__) && (__FreeBSD_kernel_version > 800063))
-#define REP_BUF_DATA(rep) (rep.buf->ugd_data)
-#else
-#define REP_BUF_DATA(rep) (rep.buf->data)
-#endif
-
-#define JDEV ((_js_device *)joy->jdev)
-#define JS_AXIS_SENSIBILITY 0.45f
-#define JS_AXIS_SENSIBILITY_DIALOG 0.45f
-#define JS_AXIS_TO_FLOAT(vl)\
- (float)(vl - jdev->axis[index].min) / (float)(jdev->axis[index].max - jdev->axis[index].min) * 2.0f - 1.0f
-
-enum _js_types {
- JS_TYPE_JOY,
- JS_TYPE_UHID,
- JS_TYPE_UNKNOW
-};
-enum _js_limit_devs {
-#if defined (__FREEBSD__) || defined (USBHID_MACHINE_JOYSTICK) || defined (__FreeBSD_kernel__)
- JS_MAX_JOY_DEV = 2,
-#else
- JS_MAX_JOY_DEV = 0,
-#endif
- JS_MAX_UHID_DEV = MAX_JOYSTICK - JS_MAX_JOY_DEV,
- JS_MAX_DEV = JS_MAX_UHID_DEV + JS_MAX_JOY_DEV
-};
-enum _js_states {
- JS_ST_CTRL,
- JS_ST_SCH,
- JS_ST_MAX
-};
-enum _js_misc {
- JS_MS_UPDATE_DETECT_DEVICES = 5000,
-};
-enum _js_hat {
- JS_HAT_UP,
- JS_HAT_UP_RIGHT,
- JS_HAT_RIGHT,
- JS_HAT_RIGHT_DOWN,
- JS_HAT_DOWN,
- JS_HAT_DOWN_LEFT,
- JS_HAT_LEFT,
- JS_HAT_LEFT_UP,
- JS_HATS = 2,
-};
-enum _js_axes {
- JS_AXE_X,
- JS_AXE_Y,
- JS_AXE_Z,
- JS_AXE_RX,
- JS_AXE_RY,
- JS_AXE_RZ,
- JS_AXE_SLIDER,
- JS_AXE_WHEEL,
- JS_HAT0_A,
- JS_HAT0_B,
- JS_HAT1_A,
- JS_HAT1_B,
- JS_AXES,
- // xbox 360 (I treat them like buttons)
- JS_DPAD_UP = JS_HAT0_A,
- JS_DPAD_DOWN = JS_HAT0_B,
- JS_DPAD_LEFT = JS_HAT1_A,
- JS_DPAD_RIGHT = JS_HAT1_B
-};
-
-typedef struct _udb_hid_device {
- uTCHAR *desc;
- uTCHAR *serial;
- unsigned int flags;
-} _usb_hid_device;
-typedef struct _js_last_states {
- float *axis;
- SDBWORD *hat;
- SDBWORD *button;
-} _js_last_states;
-typedef struct _js_device {
- BYTE id;
- BYTE type;
- uTCHAR dev[30];
- int fd;
- struct report_desc *repdesc;
- struct _js_report {
- int id;
-#if defined (__FREEBSD__) && (__FreeBSD_kernel_version > 900000)
- void *buf;
-#elif defined (__FREEBSD__) && (__FreeBSD_kernel_version > 800063)
- struct usb_gen_descriptor *buf;
-#else
- struct usb_ctl_report *buf;
-#endif
- int size;
- } report;
- struct _js_info {
- int axes;
- int buttons;
- int hats;
- int balls;
- } info;
- struct js_axis_info {
- BYTE used;
- float min;
- float max;
- float center;
- } axis [JS_AXES];
- struct js_hat_info {
- BYTE used;
- float min;
- float max;
- } hat [JS_HATS];
- _js_last_states states[JS_ST_MAX];
-#if defined (__FREEBSD__) || defined (USBHID_MACHINE_JOYSTICK) || defined (__FreeBSD_kernel__)
- // only with gameport joystick
- uTCHAR *desc;
-#endif
- // uhidev
- _usb_hid_device *usb;
-} _js_device;
-
-static _usb_hid_device *usb_alloc_device(void);
-static void usb_free_device(_usb_hid_device *udev);
-static void usb_free_udd(void);
-static void usb_detect_devices(void);
-
-static _js_device *js_alloc_device(void);
-static void js_free_device(_js_device *jdev);
-static void js_free_jdd(void);
-static void js_detect_devices(void);
-static void js_close_detected_devices(void);
-
-static void js_update_jdev(_js *joy, BYTE enable_decode, BYTE decode_index);
-static void js_update_jdevs(void);
-
-INLINE static DBWORD js_update_axis(_js *joy, _port *port, enum _js_states st, int index, float value, BYTE *mode);
-INLINE static DBWORD js_update_button(_js *joy, _port *port, enum _js_states st, int index, SDBWORD value, BYTE *mode);
-INLINE static DBWORD js_update_hat(_js *joy, _port *port, enum _js_states st, int index, SDBWORD value, BYTE *mode);
-
-INLINE static void js_hat_to_xy(SDBWORD hat, float *x, float *y);
-INLINE static int js_usage_to_axis(unsigned int usage);
-
-INLINE static void js_lock(void);
-INLINE static void js_unlock(void);
-
-static const struct _js_special {
- u_int16_t vendor;
- u_int16_t product;
- enum _js_sc_flags {
- JS_SC_NONE,
- JS_SC_MS_XBOX_360_GAMEPD = (1 << 0),
- } flags;
-} js_special_case[] = {
- { 0x045E, 0x028E, JS_SC_MS_XBOX_360_GAMEPD },
-};
-static struct _jstick {
- double ts_update_devices;
- pthread_mutex_t lock;
- struct _usb_devices_detected {
- int count;
- _usb_hid_device **devices;
- } udd;
- struct _js_devices_detected {
- int count;
- _js_device **devices;
- } jdd;
-} jstick;
-
-_js js[PORT_MAX], js_shcut;
-
-void js_init(BYTE first_time) {
- int i;
-
- if (first_time) {
- memset(&jstick, 0x00, sizeof(jstick));
-
- if (pthread_mutex_init(&jstick.lock, NULL) != 0) {
- fprintf(stderr, "Unable to allocate the thread mutex\n");
- }
- }
-
- js_lock();
- for (i = PORT1; i < PORT_MAX; i++) {
- memset(&js[i], 0x00, sizeof(_js));
- js[i].id = port[i].joy_id;
- }
- js_detect_devices();
- js_unlock();
-}
-void js_quit(BYTE last_time) {
- int i;
-
- js_close_detected_devices();
-
- for (i = PORT1; i < PORT_MAX; i++) {
- js[i].jdev = NULL;
- }
-
- if (last_time) {
- pthread_mutex_destroy(&jstick.lock);
- }
-}
-void js_update_detected_devices(void) {
- js_lock();
- js_detect_devices();
- js_unlock();
-}
-void js_control(_js *joy, _port *port) {
- struct hid_item hitem;
- struct hid_data *hdata;
- _js_device *jdev = joy->jdev;
- _js_last_states *states = NULL;
- BYTE mode = 0;
-
- js_lock();
-
- jdev = joy->jdev;
-
- if (joy->inited == FALSE) {
- js_unlock();
- return;
- } else if (jdev == NULL) {
- double now = gui_get_ms();
-
- if ((now - jstick.ts_update_devices) > JS_MS_UPDATE_DETECT_DEVICES) {
- js_detect_devices();
- }
- js_unlock();
- return;
- }
-
- states = &jdev->states[JS_ST_CTRL];
-
-#if defined (__FREEBSD__) || defined (USBHID_MACHINE_JOYSTICK) || defined (__FreeBSD_kernel__)
- if (jdev->type == JS_TYPE_JOY) {
- // FIXME : to implement
- js_unlock();
- return;
- }
-#endif
-
-#define js_control_axis(index)\
- dvl = hid_get_data(REP_BUF_DATA(jdev->report), &hitem);\
- fvl = JS_AXIS_TO_FLOAT(dvl);\
- js_update_axis(joy, port, JS_ST_CTRL, index, fvl, &mode);
-#define js_control_button(index)\
- dvl = hid_get_data(REP_BUF_DATA(jdev->report), &hitem);\
- js_update_button(joy, port, JS_ST_CTRL, index, dvl, &mode);
-#define js_control_hat(index)\
- dvl = hid_get_data(REP_BUF_DATA(jdev->report), &hitem);\
- js_update_hat(joy, port, JS_ST_CTRL, index, dvl, &mode);
-
- while (read(jdev->fd, REP_BUF_DATA(jdev->report), jdev->report.size) == jdev->report.size) {
- int hat = 0;
-
-#if defined (USBHID_NEW) || (defined (__FREEBSD__) && __FreeBSD_kernel_version >= 500111) || defined (__FreeBSD_kernel__)
- if ((hdata = hid_start_parse(jdev->repdesc, 1 << hid_input, jdev->report.id)) == NULL) {
-#else
- if ((hdata = hid_start_parse(jdev->repdesc, 1 << hid_input)) == NULL) {
-#endif
- continue;
- }
-
- while (hid_get_item(hdata, &hitem) > 0) {
- unsigned int usage = HID_USAGE(hitem.usage);
- unsigned int page = HID_PAGE(hitem.usage);
- SDBWORD dvl = 0;
- float fvl = 0;
-
- if (hitem.kind != hid_input) {
- continue;
- }
-
- if (page == HUP_GENERIC_DESKTOP) {
- int index;
-
- if (usage == HUG_HAT_SWITCH) {
- if (hat >= JS_HATS) {
- hat++;
- continue;
- }
- js_control_hat(hat);
- hat++;
- continue;
- }
-
- switch ((index = js_usage_to_axis(usage))) {
- case JS_DPAD_UP:
- case JS_DPAD_DOWN:
- case JS_DPAD_LEFT:
- case JS_DPAD_RIGHT:
- js_control_button((index - JS_DPAD_UP + jdev->info.buttons))
- break;
- case JS_AXE_X:
- case JS_AXE_Y:
- case JS_AXE_RX:
- case JS_AXE_RY:
- case JS_AXE_Z:
- case JS_AXE_RZ:
- js_control_axis(index)
- break;
- case JS_AXE_SLIDER:
- case JS_AXE_WHEEL:
- break;
- default:
- break;
- }
- } else if (page == HUP_BUTTON) {
- js_control_button((hitem.usage & 0x0F))
- }
- }
- hid_end_parse(hdata);
- }
-
-#undef js_control_axis
-#undef js_control_button
-#undef js_control_hat
-
- js_unlock();
-}
-
-BYTE js_is_connected(int dev) {
- struct stat sb;
-
- if (dev >= jstick.jdd.count) {
- return (EXIT_ERROR);
- }
-
- return ((fstat(jstick.jdd.devices[dev]->fd, &sb) == -1) ? EXIT_ERROR : EXIT_OK);
-}
-BYTE js_is_this(BYTE dev, BYTE *id) {
- if (dev >= jstick.jdd.count) {
- return (FALSE);
- }
-
- return (jstick.jdd.devices[dev]->id == (*id));
-}
-BYTE js_is_null(BYTE *id) {
- return ((*id) == name_to_jsn(uL("NULL")));
-}
-void js_set_id(BYTE *id, int dev) {
- if (dev >= jstick.jdd.count) {
- (*id) = name_to_jsn(uL("NULL"));
- return;
- }
-
- (*id) = jstick.jdd.devices[dev]->id;
-}
-uTCHAR *js_name_device(int dev) {
- if (dev >= jstick.jdd.count) {
- return (NULL);
- }
-
-#if defined (__FREEBSD__) || defined (USBHID_MACHINE_JOYSTICK) || defined (__FreeBSD_kernel__)
- // only with gameport joystick
- if (jstick.jdd.devices[dev]->desc) {
- return (jstick.jdd.devices[dev]->desc);
- }
-#endif
-
- // uhidev
- return (jstick.jdd.devices[dev]->usb->desc);
-}
-uTCHAR *js_to_joyname(const DBWORD val) {
- static uTCHAR str[20];
-
- umemset(str, 0x00, usizeof(str));
-
- if (val < JS_MAX_DEV) {
- usnprintf(str, usizeof(str), uL("JOYSTICKID%d"), val + 1);
- } else {
- usnprintf(str, usizeof(str), uL("NULL"));
- }
-
- return (str);
-}
-uTCHAR *js_to_name(const DBWORD val, const _js_element *list, const DBWORD length) {
- BYTE index;
- static uTCHAR str[20];
-
- umemset(str, 0x00, usizeof(str));
-
- for (index = 0; index < length; index++) {
- if (val == list[index].value) {
- ustrncpy(str, list[index].name, usizeof(str));
- return ((uTCHAR *)str);
- }
- }
- return ((uTCHAR *)list[0].name);
-}
-DBWORD js_from_joyname(const uTCHAR *name) {
- if (ustrncmp(name, uL("NULL"), 4) == 0) {
- return (0xFF);
- }
-
- if (ustrncmp(name, uL("JOYSTICKID"), 10) == 0) {
- return (((DBWORD)strtol(name + 10, NULL, 10) - 1));
- }
-
- return (0);
-}
-DBWORD js_from_name(const uTCHAR *name, const _js_element *list, const DBWORD length) {
- DBWORD js = 0;
- BYTE index;
-
- for (index = 0; index < length; index++) {
- if (!ustrcmp(name, list[index].name)) {
- return (list[index].value);
- }
- }
-
- return (js);
-}
-DBWORD js_read_in_dialog(BYTE *id, UNUSED(int fd)) {
- struct hid_item hitem;
- struct hid_data *hdata;
- _js_device *jdev = NULL;
- _js_last_states *states = NULL;
- DBWORD value = 0;
- int i;
-
- js_lock();
-
- for (i = 0; i < jstick.jdd.count; i++) {
- if ((*id) == jstick.jdd.devices[i]->id) {
- jdev = jstick.jdd.devices[i];
- }
- }
-
- if (jdev == NULL) {
- js_unlock();
- return (value);
- }
-
- states = &jdev->states[JS_ST_SCH];
-
-#if defined (__FREEBSD__) || defined (USBHID_MACHINE_JOYSTICK) || defined (__FreeBSD_kernel__)
- if (jdev->type == JS_TYPE_JOY) {
- // FIXME : to implement
- js_unlock();
- return (value);
- }
-#endif
-
- for (i = 0; i < jdev->info.axes; i++) {
- states->axis[i] = 0.0f;
- }
- for (i = 0; i < jdev->info.hats; i++) {
- states->hat[i] = 0;
- }
- for (i = 0; i < jdev->info.buttons; i++) {
- states->button[i] = 0;
- }
-
-#define js_read_in_dialog_axis(axis, vl)\
- fvl = vl;\
- if (fvl >= JS_AXIS_SENSIBILITY_DIALOG) {\
- value = (axis << 1) + 1 + 1;\
- } else if (fvl <= -JS_AXIS_SENSIBILITY_DIALOG) {\
- value = (axis << 1) + 1;\
- }
-#define js_read_in_dialog_button(btn)\
- if ((dvl = hid_get_data(REP_BUF_DATA(jdev->report), &hitem))) {\
- value = btn | 0x400;\
- }
-
- while (read(jdev->fd, REP_BUF_DATA(jdev->report), jdev->report.size) == jdev->report.size) {
- int hat = 0;
-
-#if defined (USBHID_NEW) || (defined (__FREEBSD__) && __FreeBSD_kernel_version >= 500111) || defined (__FreeBSD_kernel__)
- if ((hdata = hid_start_parse(jdev->repdesc, 1 << hid_input, jdev->report.id)) == NULL) {
-#else
- if ((hdata = hid_start_parse(jdev->repdesc, 1 << hid_input)) == NULL) {
-#endif
- continue;
- }
-
- while (hid_get_item(hdata, &hitem) > 0) {
- unsigned int usage = HID_USAGE(hitem.usage);
- unsigned int page = HID_PAGE(hitem.usage);
- SDBWORD dvl = 0;
- float fvl = 0;
-
- if (hitem.kind != hid_input) {
- continue;
- }
-
- if (page == HUP_GENERIC_DESKTOP) {
- int index = js_usage_to_axis(usage);
-
- if (usage == HUG_HAT_SWITCH) {
- float x, y;
-
- dvl = hid_get_data(REP_BUF_DATA(jdev->report), &hitem);
-
- if ((hat >= JS_HATS) || (states->hat[hat] == dvl)) {
- hat++;
- continue;
- }
-
- states->hat[hat] = dvl;
- js_hat_to_xy(dvl, &x, &y);
-
- if (x != 0.0f) {
- js_read_in_dialog_axis((JS_HAT0_A + hat), x)
- } else {
- js_read_in_dialog_axis((JS_HAT0_B + hat), y)
- }
-
- hat++;
- continue;
- }
-
- switch (index) {
- case JS_DPAD_UP:
- case JS_DPAD_DOWN:
- case JS_DPAD_LEFT:
- case JS_DPAD_RIGHT:
- js_read_in_dialog_button((index - JS_DPAD_UP + jdev->info.buttons))
- break;
- case JS_AXE_X:
- case JS_AXE_Y:
- case JS_AXE_RX:
- case JS_AXE_RY:
- case JS_AXE_Z:
- case JS_AXE_RZ:
- dvl = hid_get_data(REP_BUF_DATA(jdev->report), &hitem);
- fvl = JS_AXIS_TO_FLOAT(dvl);
-
- if (states->axis[index] == fvl) {
- break;
- }
-
- states->axis[index] = fvl;
- js_read_in_dialog_axis(index, fvl)
- break;
- case JS_AXE_SLIDER:
- case JS_AXE_WHEEL:
- break;
- default:
- break;
- }
- } else if (page == HUP_BUTTON) {
- js_read_in_dialog_button((hitem.usage & 0x0F))
- }
- }
- hid_end_parse(hdata);
- }
-
-#undef js_read_in_dialog_axis
-#undef js_read_in_dialog_button
-
- js_unlock();
-
- return (value);
-}
-
-void js_shcut_init(void) {
- memset(&js_shcut, 0x00, sizeof(_js));
- js_shcut.id = cfg->input.shcjoy_id;
- js_update_jdev(&js_shcut, FALSE, 0);
-}
-void js_shcut_stop(void) {}
-BYTE js_shcut_read(_js_sch *js_sch) {
- struct hid_item hitem;
- struct hid_data *hdata;
- _js *joy= &js_shcut;
- _js_device *jdev;
- _js_last_states *states = NULL;
- SDBWORD value = 0;
- BYTE mode = 0;
-
- js_sch->value = 0;
- js_sch->mode = 255;
-
- js_lock();
-
- jdev = joy->jdev;
-
- if (joy->inited == FALSE) {
- js_unlock();
- return (value);
- } else if (jdev == NULL) {
- double now = gui_get_ms();
-
- if ((now - jstick.ts_update_devices) > JS_MS_UPDATE_DETECT_DEVICES) {
- js_detect_devices();
- }
- js_unlock();
- return (value);
- }
-
- states = &jdev->states[JS_ST_CTRL];
-
-#if defined (__FREEBSD__) || defined (USBHID_MACHINE_JOYSTICK) || defined (__FreeBSD_kernel__)
- if (jdev->type == JS_TYPE_JOY) {
- // FIXME : to implement
- js_unlock();
- return (value);
- }
-#endif
-
-#define _js_shcut_read_control(funct, index, val)\
- if ((value = funct(joy, NULL, JS_ST_SCH, index, val, &mode))) {\
- js_sch->value = value;\
- js_sch->mode = mode;\
- js_unlock();\
- return (EXIT_OK);\
- }
-#define js_shcut_read_axis(index)\
- dvl = hid_get_data(REP_BUF_DATA(jdev->report), &hitem);\
- fvl = JS_AXIS_TO_FLOAT(dvl);\
- _js_shcut_read_control(js_update_axis, index, fvl)
-#define js_shcut_read_button(index)\
- dvl = hid_get_data(REP_BUF_DATA(jdev->report), &hitem);\
- _js_shcut_read_control(js_update_button, index, dvl)
-#define js_shcut_read_hat(index)\
- dvl = hid_get_data(REP_BUF_DATA(jdev->report), &hitem);\
- _js_shcut_read_control(js_update_hat, index, dvl)
-
- while (read(jdev->fd, REP_BUF_DATA(jdev->report), jdev->report.size) == jdev->report.size) {
- int hat = 0;
-
-#if defined (USBHID_NEW) || (defined (__FREEBSD__) && __FreeBSD_kernel_version >= 500111) || defined (__FreeBSD_kernel__)
- if ((hdata = hid_start_parse(jdev->repdesc, 1 << hid_input, jdev->report.id)) == NULL) {
-#else
- if ((hdata = hid_start_parse(jdev->repdesc, 1 << hid_input)) == NULL) {
-#endif
- continue;
- }
-
- while (hid_get_item(hdata, &hitem) > 0) {
- unsigned int usage = HID_USAGE(hitem.usage);
- unsigned int page = HID_PAGE(hitem.usage);
- SDBWORD dvl = 0;
- float fvl = 0;
-
- if (hitem.kind != hid_input) {
- continue;
- }
-
- if (page == HUP_GENERIC_DESKTOP) {
- int index;
-
- if (usage == HUG_HAT_SWITCH) {
- if (hat >= JS_HATS) {
- hat++;
- continue;
- }
- js_shcut_read_hat(hat);
- hat++;
- continue;
- }
-
- switch ((index = js_usage_to_axis(usage))) {
- case JS_DPAD_UP:
- case JS_DPAD_DOWN:
- case JS_DPAD_LEFT:
- case JS_DPAD_RIGHT:
- js_shcut_read_button((index - JS_DPAD_UP + jdev->info.buttons))
- break;
- case JS_AXE_X:
- case JS_AXE_Y:
- case JS_AXE_RX:
- case JS_AXE_RY:
- case JS_AXE_Z:
- case JS_AXE_RZ:
- js_shcut_read_axis(index)
- break;
- case JS_AXE_SLIDER:
- case JS_AXE_WHEEL:
- break;
- default:
- break;
- }
- } else if (page == HUP_BUTTON) {
- js_shcut_read_button((hitem.usage & 0x0F))
- }
- }
- hid_end_parse(hdata);
- }
-
-#undef _js_shcut_read_control
-#undef js_shcut_read_axis
-#undef js_shcut_read_button
-#undef js_shcut_read_hat
-
- js_unlock();
-
- return (EXIT_ERROR);
-}
-
-static _usb_hid_device *usb_alloc_device(void) {
- _usb_hid_device *udev;
-
- udev = malloc(sizeof(_usb_hid_device));
-
- udev->desc = NULL;
- udev->serial = NULL;
-
- udev->flags = JS_SC_NONE;
-
- return (udev);
-}
-static void usb_free_device(_usb_hid_device *udev) {
- if (udev->desc) {
- free(udev->desc);
- udev->desc = NULL;
- }
- if (udev->serial) {
- free(udev->serial);
- udev->serial = NULL;
- }
-
- free(udev);
-}
-static void usb_free_udd(void) {
- if (jstick.udd.devices) {
- int i;
-
- for (i = 0; i < jstick.udd.count; i++) {
- _usb_hid_device *udev = jstick.udd.devices[i];
-
- usb_free_device(udev);
- }
-
- free(jstick.udd.devices);
- jstick.udd.devices = NULL;
- }
-
- jstick.udd.count = 0;
-}
-static void usb_detect_devices(void) {
- int i;
-
- usb_free_udd();
-
- for (i = 0; i < JS_MAX_UHID_DEV; i++) {
- struct usb_device_info udi;
- uTCHAR dev[30];
- int a, fd;
-
- usnprintf(dev, usizeof(dev), uL("" USB_DEV_PATH "%d"), i);
-
- if ((fd = uopen(dev, O_RDONLY | O_NONBLOCK)) < 0) {
- continue;
- }
-
- for (a = 1; a < USB_MAX_DEVICES; a++) {
- BYTE vendor = FALSE;
- udi.udi_addr = a;
- int b, size;
-
- if (ioctl(fd, USB_DEVICEINFO, &udi) == -1) {
- continue;
- }
-
- for (b = 0; b < USB_MAX_DEVNAMES; b++) {
- _usb_hid_device *udev;
- _usb_hid_device **devices;
- unsigned int c;
-
- if (ustrncmp(udi.udi_devnames[b], uL("uhidev"), 6) != 0) {
- continue;
- }
-
- udev = usb_alloc_device();
-
-#if defined (__NetBSD__)
- {
- usb_device_descriptor_t udd;
- struct usb_string_desc usd;
-
- if (ioctl(fd, USB_GET_DEVICE_DESC, &udd) != -1) {
- // Get default language
- usd.usd_string_index = USB_LANGUAGE_TABLE;
- usd.usd_language_id = 0;
-
- if ((ioctl(fd, USB_GET_STRING_DESC, &usd) == -1) || (usd.usd_desc.bLength < 4)) {
- usd.usd_language_id = 0;
- } else {
- usd.usd_language_id = UGETW(usd.usd_desc.bString[0]);
- }
-
- usd.usd_string_index = udd.iProduct;
-
- if (ioctl(fd, USB_GET_STRING_DESC, &usd) == 0) {
- char str[128];
- int d;
-
- for (d = 0; d < (usd.usd_desc.bLength >> 1) - 1 && d < sizeof(str) - 1; d++) {
- str[d] = UGETW(usd.usd_desc.bString[d]);
- }
- str[d] = '\0';
-
- asprintf(&udev->desc, "%s", str);
- }
- }
- }
-#else
- size = ustrlen(udi.udi_product) + 1;
-
- if (ustrlen(udi.udi_vendor) && ustrncmp(udi.udi_vendor, uL("vendor 0x"), 9) != 0) {
- size += ustrlen(udi.udi_vendor) + 1;
- vendor = TRUE;
- }
-
- if (size > 1) {
- if ((udev->desc = (uTCHAR *)malloc(size * sizeof(uTCHAR))) == NULL) {
- fprintf(stderr, "%s: out of memory\n", dev);
- goto usb_detect_devices_error;
- }
-
- umemset(udev->desc, 0x00, size);
-
- if (vendor == TRUE) {
- usnprintf(udev->desc, size, uL("" uPERCENTs " " uPERCENTs), udi.udi_vendor, udi.udi_product);
- } else {
- usnprintf(udev->desc, size, uL("" uPERCENTs), udi.udi_product);
- }
- }
-
- if ((size = ustrlen(udi.udi_serial) + 1) > 1) {
- if ((udev->serial = (uTCHAR *)malloc(size * sizeof(uTCHAR))) == NULL) {
- fprintf(stderr, "%s: out of memory\n", dev);
- goto usb_detect_devices_error;
- }
-
- umemset(udev->serial, 0x00, size);
-
- usnprintf(udev->serial, size, uL("" uPERCENTs), udi.udi_serial);
- }
-#endif
-
- // special case
- for (c = 0; c < LENGTH(js_special_case); c++) {
- if ((udi.udi_vendorNo == js_special_case[c].vendor) &&
- (udi.udi_productNo == js_special_case[c].product)) {
- udev->flags |= js_special_case[c].flags;
- }
- }
-
- if ((devices = (_usb_hid_device **)realloc(jstick.udd.devices,
- (jstick.udd.count + 1) * sizeof(_usb_hid_device *))) == NULL) {
- fprintf(stderr, "%s: out of memory\n", dev);
- goto usb_detect_devices_error;
- }
-
- jstick.udd.devices = devices;
- jstick.udd.devices[jstick.udd.count] = udev;
- jstick.udd.count++;
- continue;
-
- usb_detect_devices_error:
- usb_free_device(udev);
- }
- }
- close(fd);
- }
-}
-
-static _js_device *js_alloc_device(void) {
- _js_device *jdev;
- int i;
-
- jdev = malloc(sizeof(_js_device));
-
- jdev->type = JS_TYPE_UNKNOW;
- jdev->fd = 0;
- jdev->repdesc = NULL;
- jdev->report.buf = NULL;
- jdev->report.id = -1;
- jdev->report.size = 0;
- jdev->info.axes = 0;
- jdev->info.buttons = 0;
- jdev->info.hats = 0;
- jdev->info.balls = 0;
-
- umemset(&jdev->dev, 0x00, usizeof(jdev->dev));
-
- for (i = 0; i < JS_AXES; i++) {
- jdev->axis[i].used = FALSE;
- jdev->axis[i].min = 0.0f;
- jdev->axis[i].max = 0.0f;
- jdev->axis[i].center = 0.0f;
- }
-
- for (i = 0; i < JS_HATS; i++) {
- jdev->hat[i].used = FALSE;
- jdev->hat[i].min = 0.0f;
- jdev->hat[i].max = 0.0f;
- }
-
- for (i = 0; i < JS_ST_MAX; i++) {
- jdev->states[i].axis = NULL;
- jdev->states[i].hat = NULL;
- jdev->states[i].button = NULL;
- };
-
-#if defined (__FREEBSD__) || defined (USBHID_MACHINE_JOYSTICK) || defined (__FreeBSD_kernel__)
- jdev->desc = NULL;
-#endif
- jdev->usb = NULL;
-
- return (jdev);
-}
-static void js_free_device(_js_device *jdev) {
- int i;
-
- if (jdev->repdesc) {
- hid_dispose_report_desc(jdev->repdesc);
- jdev->repdesc = NULL;
- }
- if (jdev->report.buf) {
- free(jdev->report.buf);
- jdev->report.buf = NULL;
- }
- if (jdev->fd) {
- close(jdev->fd);
- jdev->fd = 0;
- }
- for (i = 0; i < JS_ST_MAX; i++) {
- if (jdev->states[i].axis) {
- free(jdev->states[i].axis);
- jdev->states[i].axis = NULL;
- }
- if (jdev->states[i].hat) {
- free(jdev->states[i].hat);
- jdev->states[i].hat = NULL;
- }
- if (jdev->states[i].button) {
- free(jdev->states[i].button);
- jdev->states[i].button = NULL;
- }
- }
-#if defined (__FREEBSD__) || defined (USBHID_MACHINE_JOYSTICK) || defined (__FreeBSD_kernel__)
- if (jdev->desc) {
- free(jdev->desc);
- jdev->desc = NULL;
- }
-#endif
- jdev->usb = NULL;
-
- free(jdev);
-}
-static void js_free_jdd(void) {
- if (jstick.jdd.devices) {
- int i;
-
- for (i = 0; i < jstick.jdd.count; i++) {
- _js_device *jdev = jstick.jdd.devices[i];
-
- js_free_device(jdev);
- }
-
- free(jstick.jdd.devices);
- jstick.jdd.devices = NULL;
- }
-
- jstick.jdd.count = 0;
-}
-static void js_detect_devices(void) {
- int i, hid_connected = 0;
-
- usb_detect_devices();
-
- js_free_jdd();
-
- for (i = 0; i < JS_MAX_DEV; i++) {
- static _js_device *jdev;
- struct hid_item hitem;
- struct hid_data *hdata;
-
- jdev = js_alloc_device();
-
- jdev->id = i;
-
-#if defined (__FREEBSD__) || defined (USBHID_MACHINE_JOYSTICK) || defined (__FreeBSD_kernel__)
- if (jdev->id < JS_MAX_JOY_DEV) {
- usnprintf(jdev->dev, usizeof(jdev->dev), uL("" JOY_DEV_PATH "%d"), jdev->id);
- jdev->type = JS_TYPE_JOY;
- } else {
- usnprintf(jdev->dev, usizeof(jdev->dev), uL("" UHID_DEV_PATH "%d"), jdev->id - JS_MAX_JOY_DEV);
- jdev->type = JS_TYPE_UHID;
- }
-#else
- usnprintf(jdev->dev, usizeof(jdev->dev), uL("" UHID_DEV_PATH "%d"), jdev->id);
- jdev->type = JS_TYPE_UHID;
-#endif
-
- if ((jdev->fd = uopen(jdev->dev, O_RDONLY | O_NONBLOCK)) < 0) {
- goto js_detect_devices_error;
- }
-
-#if defined (__FREEBSD__) || defined (USBHID_MACHINE_JOYSTICK) || defined (__FreeBSD_kernel__)
- if (jdev->type == JS_TYPE_JOY) {
- uTCHAR joystick_desc[] = uL("Gameport Joystick");
-
- jdev->desc = malloc(ustrlen(joystick_desc) + 1);
- umemcpy(jdev->desc, joystick_desc, ustrlen(joystick_desc));
-
- jdev->info.axes = 2;
- jdev->info.buttons = 2;
- jdev->info.hats = 0;
- jdev->info.balls = 0;
-
- goto js_detect_devices_ok;
- }
-#endif
-
- if ((jdev->repdesc = hid_get_report_desc(jdev->fd)) == NULL) {
- fprintf(stderr, "%s: hid_get_report_desc: %s\n", jdev->dev, strerror(errno));
- goto js_detect_devices_error;
- }
-
-#if defined (__FREEBSD__) && (__FreeBSD_kernel_version > 800063) || defined (__FreeBSD_kernel__)
- if ((jdev->report.id = hid_get_report_id(jdev->fd)) < 0) {
-#else
- if (ioctl(jdev->fd, USB_GET_REPORT_ID, &jdev->report.id) < 0) {
-#endif
- jdev->report.id = -1;
- }
-
-#if defined (__DragonFly__)
- if ((jdev->report.size = hid_report_size(jdev->repdesc, jdev->report.id, hid_input)) <= 0) {
-#elif defined (__FREEBSD__)
-#if (__FreeBSD_kernel_version >= 460000) || defined (__FreeBSD_kernel__)
-#if (__FreeBSD_kernel_version <= 500111)
- if ((jdev->report.size = hid_report_size(jdev->repdesc, jdev->report.id, hid_input)) <= 0) {
-#else
- if ((jdev->report.size = hid_report_size(jdev->repdesc, hid_input, jdev->report.id)) <= 0) {
-#endif
-#else
- if ((jdev->report.size = hid_report_size(jdev->repdesc, hid_input, &jdev->report.id)) <= 0) {
-#endif
-#else
-#if defined (USBHID_NEW)
- if ((jdev->report.size = hid_report_size(jdev->repdesc, hid_input, jdev->report.id)) <= 0) {
-#else
- if ((jdev->report.size = hid_report_size(jdev->repdesc, hid_input, &jdev->report.id)) <= 0) {
-#endif
-#endif
- fprintf(stderr, "%s: hid_report_size() return invalid size\n", jdev->dev);
- goto js_detect_devices_error;
- }
-
-#if defined (__FREEBSD__) && (__FreeBSD_kernel_version > 900000)
- if ((jdev->report.buf = malloc(jdev->report.size)) == NULL) {
-#else
- if ((jdev->report.buf = malloc(sizeof(*jdev->report.buf) - sizeof(REP_BUF_DATA(jdev->report)) + jdev->report.size)) == NULL) {
-#endif
- fprintf(stderr, "%s: error on malloc report buf\n", jdev->dev);
- goto js_detect_devices_error;
- }
-
-#if defined (USBHID_NEW) || (defined (__FREEBSD__) && __FreeBSD_kernel_version >= 500111) || defined (__FreeBSD_kernel__)
- if ((hdata = hid_start_parse(jdev->repdesc, 1 << hid_input, jdev->report.id)) == NULL) {
-#else
- if ((hdata = hid_start_parse(jdev->repdesc, 1 << hid_input)) == NULL) {
-#endif
- fprintf(stderr, "%s: hid_start_parse() don't start", jdev->dev);
- goto js_detect_devices_error;
- }
-
- while (hid_get_item(hdata, &hitem) > 0) {
- unsigned int usage = HID_USAGE(hitem.usage);
- unsigned int page = HID_PAGE(hitem.usage);
-
- switch (hitem.kind) {
- case hid_collection:
- if ((page == HUP_GENERIC_DESKTOP) &&
- ((usage == HUG_JOYSTICK) || (usage == HUG_GAME_PAD))) {
- jdev->usb = jstick.udd.devices[hid_connected];
- }
- break;
- case hid_input:
- if (page == HUP_GENERIC_DESKTOP) {
- int index = js_usage_to_axis(usage);
-
- if (index >= 0) {
- jdev->axis[index].used = TRUE;
- jdev->axis[index].min = hitem.logical_minimum;
- jdev->axis[index].max = hitem.logical_maximum;
- if ((jdev->usb->flags & JS_SC_MS_XBOX_360_GAMEPD) &&
- ((index == JS_AXE_Z) || (index == JS_AXE_RZ))) {
- jdev->axis[index].min = -hitem.logical_maximum;
- }
- jdev->axis[index].center = (jdev->axis[index].min / jdev->axis[index].max) * 0.5f;
- jdev->info.axes++;
- } else if (usage == HUG_HAT_SWITCH) {
- if (jdev->info.hats < JS_HATS) {
- jdev->hat[jdev->info.hats].used = TRUE;
- jdev->hat[jdev->info.hats].min = hitem.logical_minimum;
- jdev->hat[jdev->info.hats].max = hitem.logical_maximum;
- jdev->info.hats++;
- }
- }
- } else if (page == HUP_BUTTON) {
- jdev->info.buttons++;
- }
- break;
- default:
- break;
- }
- }
- hid_end_parse(hdata);
-
- hid_connected++;
-
- if ((jdev->info.axes == 0) && (jdev->info.buttons == 0) &&
- (jdev->info.hats == 0) && (jdev->info.balls == 0)) {
- fprintf(stderr, "%s: is not a joystick\n", jdev->dev);
- goto js_detect_devices_error;
- }
-
- // flush pending events
- while (read(jdev->fd, REP_BUF_DATA(jdev->report), jdev->report.size) == jdev->report.size) {
- ;
- }
-
-#if defined (__FREEBSD__) || defined (USBHID_MACHINE_JOYSTICK) || defined (__FreeBSD_kernel__)
- js_detect_devices_ok:
-#endif
- {
- _js_device **devices;
- int a;
-
- for (a = 0; a < JS_ST_MAX; a++) {
- _js_last_states *st = &jdev->states[a];
-
- if (jdev->info.axes && ((st->axis = malloc(jdev->info.axes * sizeof(float))) == NULL)) {
- fprintf(stderr, "%s: error on malloc states axes\n", jdev->dev);
- goto js_detect_devices_error;
- }
- if (jdev->info.hats && ((st->hat = malloc(jdev->info.hats * sizeof(SDBWORD))) == NULL)) {
- fprintf(stderr, "%s: error on malloc states hats\n", jdev->dev);
- goto js_detect_devices_error;
- }
- if (jdev->info.buttons && ((st->button = malloc(jdev->info.buttons * sizeof(SDBWORD)))) == NULL) {
- fprintf(stderr, "%s: error on malloc states buttons\n", jdev->dev);
- goto js_detect_devices_error;
- }
- memset(st->axis, 0x00, jdev->info.axes * sizeof(float));
- memset(st->hat, 0x00, jdev->info.hats * sizeof(SDBWORD));
- memset(st->button, 0x00, jdev->info.buttons * sizeof(SDBWORD));
- }
-
- if ((devices = (_js_device **)realloc(jstick.jdd.devices,
- (jstick.jdd.count + 1) * sizeof(_js_device))) == NULL) {
- fprintf(stderr, "%s: out of memory\n", jdev->dev);
- goto js_detect_devices_error;
- }
-
- jstick.jdd.devices = devices;
- jstick.jdd.devices[jstick.jdd.count] = jdev;
- jstick.jdd.count++;
-
- jdev = jstick.jdd.devices[jstick.jdd.count - 1];
-
-#if !defined (RELEASE)
- fprintf(stderr, "%d : %s @ %s\n",
- jstick.jdd.count,
- jdev->dev,
- jdev->usb->desc);
-#endif
-
- continue;
- }
-
- js_detect_devices_error:
- js_free_device(jdev);
- }
-
- js_update_jdevs();
-
- jstick.ts_update_devices = gui_get_ms();
-}
-static void js_close_detected_devices(void) {
- usb_free_udd();
- js_free_jdd();
-}
-
-static void js_update_jdev(_js *joy, BYTE enable_decode, BYTE decode_index) {
- joy->jdev = NULL;
- joy->inited = FALSE;
- joy->input_decode_event = NULL;
-
- if (js_is_null(&joy->id) == FALSE) {
- int d;
-
- for (d = 0; d < jstick.jdd.count; d++) {
- if (joy->id == jstick.jdd.devices[d]->id) {
- joy->jdev = jstick.jdd.devices[d];
- break;
- }
- }
-
- joy->inited = TRUE;
-
- if (enable_decode) {
- joy->input_decode_event = port_funct[decode_index].input_decode_event;
- }
- }
-}
-static void js_update_jdevs(void) {
- int i;
-
- for (i = PORT1; i < PORT_MAX; i++) {
- js_update_jdev(&js[i], TRUE, i);
- }
- // shortcut
- js_update_jdev(&js_shcut, FALSE, 0);
-}
-
-INLINE static DBWORD js_update_axis(_js *joy, _port *port, enum _js_states st, int index, float value, BYTE *mode) {
- DBWORD event = (index << 1) + 1;
- float last_value;
-
- (*mode) = PRESSED;
-
- last_value = JDEV->states[st].axis[index];
-
- if ((value < JS_AXIS_SENSIBILITY) && (value > -JS_AXIS_SENSIBILITY)) {
- value = 0.0f;
- (*mode) = RELEASED;
- if (last_value > 0) {
- event++;
- }
- } else if (value <= - JS_AXIS_SENSIBILITY) {
- value = -1.0f;
- } else {
- value = 1.0f;
- event++;
- }
-
- JDEV->states[st].axis[index] = value;
-
- if (value != last_value) {
- if (joy->input_decode_event) {
- joy->input_decode_event((*mode), FALSE, event, JOYSTICK, port);
- }
- return (event);
- }
- return (0);
-}
-INLINE static DBWORD js_update_button(_js *joy, _port *port, enum _js_states st, int index, SDBWORD value, UNUSED(BYTE *mode)) {
- DBWORD event = 0;
-
- if (value != JDEV->states[st].button[index]) {
- JDEV->states[st].button[index] = value;
- event = index | 0x400;
- if (joy->input_decode_event) {
- joy->input_decode_event(value, FALSE, event, JOYSTICK, port);
- }
- }
- return (event);
-}
-INLINE static DBWORD js_update_hat(_js *joy, _port *port, enum _js_states st, int index, SDBWORD value, BYTE *mode) {
- float x = 0.0f, y = 0.0f;
- DBWORD event = 0;
-
- js_hat_to_xy(value, &x, &y);
-
- if (!(event = js_update_axis(joy, port, st, JS_HAT0_A + index, x, mode))) {
- event = js_update_axis(joy, port, st, JS_HAT0_B + index, y, mode);
- }
- return (event);
-}
-
-INLINE static void js_hat_to_xy(SDBWORD hat, float *x, float *y) {
- static const int hat_map[8] = {
- JS_HAT_UP,
- JS_HAT_UP_RIGHT,
- JS_HAT_RIGHT,
- JS_HAT_RIGHT_DOWN,
- JS_HAT_DOWN,
- JS_HAT_DOWN_LEFT,
- JS_HAT_LEFT,
- JS_HAT_LEFT_UP,
- };
-
- (*x) = (*y) = 0.0f;
-
- if ((hat & 0x000F) == 0x000F) {
- return;
- }
-
- if ((hat & 0x07) == hat) {
- switch (hat_map[hat]) {
- case JS_HAT_UP:
- (*x) = 1.0f;
- break;
- case JS_HAT_UP_RIGHT:
- (*x) = 1.0f;
- (*y) = 1.0f;
- break;
- case JS_HAT_RIGHT:
- (*y) = 1.0f;
- break;
- case JS_HAT_RIGHT_DOWN:
- (*x) = -1.0f;
- (*y) = 1.0f;
- break;
- case JS_HAT_DOWN:
- (*x) = -1.0f;
- break;
- case JS_HAT_DOWN_LEFT:
- (*x) = -1.0f;
- (*y) = -1.0f;
- break;
- case JS_HAT_LEFT:
- (*y) = -1.0f;
- break;
- case JS_HAT_LEFT_UP:
- (*x) = 1.0f;
- (*y) = -1.0f;
- break;
- }
- }
-}
-INLINE static int js_usage_to_axis(unsigned int usage) {
- int axis;
-
- switch (usage) {
- case HUG_X:
- axis = JS_AXE_X;
- break;
- case HUG_Y:
- axis = JS_AXE_Y;
- break;
- case HUG_Z:
- axis = JS_AXE_Z;
- break;
- case HUG_RX:
- axis = JS_AXE_RX;
- break;
- case HUG_RY:
- axis = JS_AXE_RY;
- break;
- case HUG_RZ:
- axis = JS_AXE_RZ;
- break;
- case HUG_SLIDER:
- axis = JS_AXE_SLIDER;
- break;
- case HUG_WHEEL:
- axis = JS_AXE_WHEEL;
- break;
- case 0x90:
- axis = JS_DPAD_UP;
- break;
- case 0x91:
- axis = JS_DPAD_DOWN;
- break;
- case 0x93:
- axis = JS_DPAD_LEFT;
- break;
- case 0x92:
- axis = JS_DPAD_RIGHT;
- break;
- default:
- axis = -1;
- break;
- }
-
- return (axis);
-}
-
-INLINE static void js_lock(void) {
- pthread_mutex_lock(&jstick.lock);
-}
-INLINE static void js_unlock(void) {
- pthread_mutex_unlock(&jstick.lock);
-}
diff --git a/src/gui/openbsd/jstick.h b/src/gui/openbsd/jstick.h
deleted file mode 100644
index 8670636..0000000
--- a/src/gui/openbsd/jstick.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2010-2020 Fabio Cavallo (aka FHorse)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef JSTICK_H_
-#define JSTICK_H_
-
-#include "common.h"
-#include "input.h"
-
-#define JOY_DEV_PATH "/dev/joy"
-#define UHID_DEV_PATH "/dev/uhid"
-#define USB_DEV_PATH "/dev/usb"
-#define name_to_jsv(name) js_from_name(name, jsv_list, LENGTH(jsv_list))
-#define name_to_jsn(name) js_from_joyname(name)
-#define jsv_to_name(jsvl) js_to_name(jsvl, jsv_list, LENGTH(jsv_list))
-#define jsn_to_name(jsvl) js_to_joyname(jsvl)
-
-typedef struct _js {
- BYTE inited;
- BYTE id;
- void *jdev;
- BYTE (*input_decode_event)(BYTE mode, BYTE autorepeat, DBWORD event, BYTE type, _port *port);
-} _js;
-typedef struct _js_element {
- DBWORD value;
- uTCHAR name[20];
-} _js_element;
-typedef struct _js_sch {
- DBWORD value;
- BYTE mode;
-} _js_sch;
-
-static const _js_element jsv_list[] = {
- { 0x000, uL("NULL") },
- { 0x001, uL("JA0MIN") }, { 0x002, uL("JA0PLS") },
- { 0x003, uL("JA1MIN") }, { 0x004, uL("JA1PLS") },
- { 0x005, uL("JA2MIN") }, { 0x006, uL("JA2PLS") },
- { 0x007, uL("JA3MIN") }, { 0x008, uL("JA3PLS") },
- { 0x009, uL("JA4MIN") }, { 0x00A, uL("JA4PLS") },
- { 0x00B, uL("JA5MIN") }, { 0x00C, uL("JA5PLS") },
- { 0x00D, uL("JA6MIN") }, { 0x00E, uL("JA6PLS") },
- { 0x00F, uL("JA7MIN") }, { 0x010, uL("JA7PLS") },
- { 0x011, uL("JA8MIN") }, { 0x012, uL("JA8PLS") },
- { 0x013, uL("JA9MIN") }, { 0x014, uL("JA9PLS") },
- { 0x015, uL("JAAMIN") }, { 0x016, uL("JAAPLS") },
- { 0x017, uL("JABMIN") }, { 0x018, uL("JABPLS") },
- { 0x019, uL("JACMIN") }, { 0x01A, uL("JACPLS") },
- { 0x01B, uL("JADMIN") }, { 0x01C, uL("JADPLS") },
- { 0x01D, uL("JAEMIN") }, { 0x01E, uL("JAEPLS") },
- { 0x01F, uL("JAFMIN") }, { 0x020, uL("JAFPLS") },
- { 0x400, uL("JB0") }, { 0x401, uL("JB1") },
- { 0x402, uL("JB2") }, { 0x403, uL("JB3") },
- { 0x404, uL("JB4") }, { 0x405, uL("JB5") },
- { 0x406, uL("JB6") }, { 0x407, uL("JB7") },
- { 0x408, uL("JB8") }, { 0x409, uL("JB9") },
- { 0x40A, uL("JB10") }, { 0x40B, uL("JB11") },
- { 0x40C, uL("JB12") }, { 0x40D, uL("JB13") },
- { 0x40E, uL("JB14") }, { 0x40F, uL("JB15") },
- { 0x410, uL("JB16") }, { 0x411, uL("JB17") },
- { 0x412, uL("JB18") }, { 0x413, uL("JB19") },
- { 0x414, uL("JB20") }, { 0x415, uL("JB21") },
- { 0x416, uL("JB22") }, { 0x417, uL("JB23") },
- { 0x418, uL("JB24") }, { 0x419, uL("JB25") },
- { 0x41A, uL("JB26") }, { 0x41B, uL("JB27") },
- { 0x41C, uL("JB28") }, { 0x41D, uL("JB29") },
- { 0x41E, uL("JB30") }, { 0x41F, uL("JB31") },
- { 0x420, uL("JB32") }, { 0x421, uL("JB33") },
- { 0x422, uL("JB34") }, { 0x423, uL("JB35") },
-};
-
-extern _js js[PORT_MAX], js_shcut;
-
-#if defined (__cplusplus)
-#define EXTERNC extern "C"
-#else
-#define EXTERNC
-#endif
-
-EXTERNC void js_init(BYTE first_time);
-EXTERNC void js_quit(BYTE last_time);
-EXTERNC void js_update_detected_devices(void);
-EXTERNC void js_control(_js *joy, _port *port);
-
-EXTERNC BYTE js_is_connected(int dev);
-EXTERNC BYTE js_is_this(BYTE dev, BYTE *id);
-EXTERNC BYTE js_is_null(BYTE *id);
-EXTERNC void js_set_id(BYTE *id, int dev);
-EXTERNC uTCHAR *js_name_device(int dev);
-EXTERNC uTCHAR *js_to_joyname(const DBWORD val);
-EXTERNC uTCHAR *js_to_name(const DBWORD val, const _js_element *list, const DBWORD length);
-EXTERNC DBWORD js_from_joyname(const uTCHAR *name);
-EXTERNC DBWORD js_from_name(const uTCHAR *name, const _js_element *list, const DBWORD length);
-EXTERNC DBWORD js_read_in_dialog(BYTE *id, int fd);
-
-EXTERNC void js_shcut_init(void);
-EXTERNC void js_shcut_stop(void);
-EXTERNC BYTE js_shcut_read(_js_sch *js_sch);
-
-#undef EXTERNC
-
-#endif /* JSTICK_H_ */
diff --git a/src/gui/openbsd/os_openbsd.h b/src/gui/openbsd/os_openbsd.h
deleted file mode 100644
index f367d8a..0000000
--- a/src/gui/openbsd/os_openbsd.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2010-2020 Fabio Cavallo (aka FHorse)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef OS_OPENBSD_H_
-#define OS_OPENBSD_H_
-
-#include <sys/types.h>
-#include <sys/sysctl.h>
-#include <time.h>
-
-#include <stdio.h>
-
-static double high_resolution_ms(void);
-static int __nsleep(const struct timespec *req, struct timespec *rem);
-
-void gui_init(int *argc, char **argv) {
- memset(&gui, 0, sizeof(gui));
- qt = {};
-
- qt.app = new QApplication((*argc), argv);
-
- info.gui = TRUE;
- gui.in_update = FALSE;
- gui.main_win_lfp = 0;
-
- // cerco la HOME e imposto la directory base
- {
- gui.home = getenv("HOME");
-
- if (!gui.home) {
- gui.home = QDir::homePath().toUtf8().constData();
- }
-
- if (info.portable) {
- uTCHAR path[usizeof(info.base_folder)];
- size_t len = usizeof(path);
- int name[] = { CTL_KERN, KERN_PROC_CWD, 0 };
-
- name[2] = getpid();
- umemset(&path, 0x00, usizeof(path));
-
- if (sysctl(name, 3, &path, &len, NULL, 0) != 0) {
- fprintf(stderr, "INFO: Error on sysctl.\n");
- info.portable = FALSE;
- } else {
- ustrncpy(info.base_folder, path, usizeof(info.base_folder));
- }
- } else {
- usnprintf(info.base_folder, usizeof(info.base_folder), uL("" uPERCENTs "/." NAME), gui.home);
- }
- }
-
- gettimeofday(&gui.counterStart, nullptr);
- gui_get_ms = high_resolution_ms;
-}
-void gui_sleep(double ms) {
- struct timespec req = {}, rem = {};
- time_t sec;
-
- if (ms <= 0) {
- return;
- }
-
- sec = (time_t)(ms / 1000.0f);
- ms = ms - ((double)sec * 1000.0f);
- req.tv_sec = sec;
- req.tv_nsec = ms * 1000000L;
- __nsleep(&req, &rem);
-}
-int gui_screen_id(void) {
- int wid = qt.screen->wogl->winId();
-
- return (wid);
-}
-
-static double high_resolution_ms(void) {
- struct timeval time;
- double elapsed_seconds;
- double elapsed_useconds;
-
- gettimeofday(&time, nullptr);
-
- elapsed_seconds = time.tv_sec - gui.counterStart.tv_sec;
- elapsed_useconds = time.tv_usec - gui.counterStart.tv_usec;
-
- return ((elapsed_seconds * 1000.0f) + (elapsed_useconds / 1000.0f));
-}
-static int __nsleep(const struct timespec *req, struct timespec *rem) {
- struct timespec temp_rem;
-
- if (nanosleep(req, rem) == -1) {
- __nsleep(rem, &temp_rem);
- } else {
- return (EXIT_ERROR);
- }
-
- return (EXIT_OK);
-}
-
-#endif /* OS_OPENBSD_H_ */
diff --git a/src/gui/qt.cpp b/src/gui/qt.cpp
index 9129b57..1dfcb2a 100644
--- a/src/gui/qt.cpp
+++ b/src/gui/qt.cpp
@@ -581,6 +581,6 @@
#if defined (__linux__)
#include "os_linux.h"
-#elif defined (__OpenBSD__)
-#include "os_openbsd.h"
+#elif defined (__OpenBSD__) || defined (__FreeBSD__)
+#include "os_bsd.h"
#elif defined (_WIN32)
#include "os_windows.h"
diff --git a/src/gui/qt.h b/src/gui/qt.h
index 00c1a25..59fed1f 100644
--- a/src/gui/qt.h
+++ b/src/gui/qt.h
@@ -30,8 +30,4 @@
#include "jstick.h"
-enum _overlay_info_messages {
- PROVA
-};
-
#define tools_stylesheet()\
"QGroupBox {"\
diff --git a/src/video/opengl/opengl.c b/src/video/opengl/opengl.c
index 1008472..1ba8d4d 100644
--- a/src/video/opengl/opengl.c
+++ b/src/video/opengl/opengl.c
@@ -528,5 +528,7 @@
}
void opengl_draw_scene(void) {
+#if defined (WITH_OPENGL_CG)
static GLuint prev_type = MS_MEM;
+#endif
const _texture_simple *scrtex = &opengl.screen.tex[opengl.screen.index];
GLuint offset_x = 0, offset_y = 0;
@@ -628,5 +630,7 @@
opengl_shader_glsl_disable_attrib();
}
+#if defined (WITH_OPENGL_CG)
prev_type = texture->shader.type;
+#endif
}
@@ -666,5 +670,7 @@
glDisable(GL_BLEND);
opengl_shader_glsl_disable_attrib();
+#if defined (WITH_OPENGL_CG)
prev_type = MS_MEM;
+#endif
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment