I have attached the new patch in which I added the sndio support.
I developed it on my linux box and it works perfectly but tested
on the virtual machine it didn't help me much, the virtual system
is too slow to get usable feedback.

Fabio Cavallo
diff --git a/autogen.sh b/autogen.sh
index 872167c6..07e8905d 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -1,3 +1,16 @@
 #!/bin/sh
 
+if [[ "$(uname)" == "OpenBSD" ]] ; then
+	if [[ -z "${AUTOCONF_VERSION:-}" ]] ; then
+		export AUTOCONF_VERSION
+		AUTOCONF_VERSION="$(ls -1 /usr/local/bin/autoreconf-* | sort | tail -n 1)"
+		AUTOCONF_VERSION="${AUTOCONF_VERSION##*-}"
+	fi
+	if [[ -z "${AUTOMAKE_VERSION:-}" ]] ; then
+		export AUTOMAKE_VERSION
+		AUTOMAKE_VERSION="$(ls -1 /usr/local/bin/automake-* | sort | tail -n 1)"
+		AUTOMAKE_VERSION="${AUTOMAKE_VERSION##*-}"
+	fi
+fi
+
 autoreconf -vif
diff --git a/configure.ac b/configure.ac
index 647763b0..4b51688c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -108,14 +108,29 @@ AS_CASE(["$host_os"],
 		CUSTOMDEFINES="${CUSTOMDEFINES} -DWITH_OPENGL -DGLEW_STATIC"
 		my_CPPFLAGS="${my_CPPFLAGS} -I${TOP_SRCDIR}/src/gui/linux -I${TOP_SRCDIR}/src/video/sdl"
 		linux=yes
+		openbsd=no
 		windows=no
 		with_d3d9=no
 		with_opengl=yes
 	],
+	[openbsd*], [
+		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/sdl"
+		linux=no
+		openbsd=yes
+		windows=no
+		with_d3d9=no
+		with_opengl=yes
+		my_CXXFLAGS="-fmessage-length=0 -finline-functions"
+		export CC
+		export CXX
+	],
 	[mingw32*], [
 		MOCDEFINES="${MOCDEFINES} -D__WIN32__"
 		my_CPPFLAGS="${my_CPPFLAGS} -I${TOP_SRCDIR}/src/gui/windows"
 		linux=no
+		openbsd=no
 		windows=yes
 		AS_IF([test "x$with_opengl" = xyes], [
 			with_d3d9=no
@@ -142,6 +157,7 @@ AS_CASE(["$host_os"],
 )
 
 AM_CONDITIONAL(LINUX,[test "x$linux" = xyes])
+AM_CONDITIONAL(OPENBSD,[test "x$openbsd" = xyes])
 AM_CONDITIONAL(WINDOWS,[test "x$windows" = xyes])
 AM_CONDITIONAL(ENAB_RELEASE,[test "x$enable_release" = xyes])
 AM_CONDITIONAL(ENAB_QT5,[test "x$enable_qt5" = xyes])
@@ -864,6 +880,37 @@ void blah(){
 	my_LIBS="${my_LIBS} ${alsa_LIBS}"
 ])
 
+AM_COND_IF([OPENBSD], [
+	AM_COND_IF([WITH_OPENGL_CG], [
+		PKG_CHECK_MODULES(nvidia_cg_toolkit_pkgconfig, [nvidia-cg-toolkit-gl], [
+			CUSTOMDEFINES="${CUSTOMDEFINES} -DWITH_OPENGL_CG"
+			my_CPPFLAGS="${my_CPPFLAGS} ${nvidia_cg_toolkit_pkgconfig_CFLAGS}"
+			my_LIBS="${my_LIBS} ${nvidia_cg_toolkit_pkgconfig_LIBS}"
+		], [
+			# Check if NVIDIA CG toolkit is present without pkg-config
+			AC_MSG_CHECKING([NVIDIA CG toolkit is present])
+			AC_COMPILE_IFELSE([AC_LANG_SOURCE([
+#include "Cg/cg.h"
+#include "Cg/cgGL.h"
+void blah(){
+	CGcontext cgx = cgCreateContext();
+}])
+			], [
+				AC_MSG_RESULT([yes])
+				CUSTOMDEFINES="${CUSTOMDEFINES} -DWITH_OPENGL_CG"
+				my_LIBS="${my_LIBS} -lCg -lCgGL"
+			], [
+				AC_MSG_RESULT([no])
+			])
+		])
+	])
+	AC_CHECK_LIB(sndio, main, [
+		my_LIBS="${my_LIBS} -lsndio"
+	], [
+		AC_MSG_ERROR([libsdnio.so not found])
+	])
+])
+
 AS_CASE(["$host_os"],
 	[mingw32*], [
 		AC_CHECK_TOOL(WINDRES, windres, [no])
@@ -893,6 +940,12 @@ AC_SUBST(LIB7ZIP_SRC)
 AC_SUBST(LIB7ZIP_LIBS)
 
 # The End
+AM_COND_IF([LINUX], [
+	my_LIBS="${my_LIBS} -ldl -lpthread"
+])
+AM_COND_IF([OPENBSD], [
+	my_LIBS="${my_LIBS} -lstdc++ -lpthread"
+])
 AM_COND_IF([WINDOWS], [
 	AM_COND_IF([ENAB_RELEASE], [
 		my_LDFLAGS="${my_LDFLAGS} -Wl,-subsystem,windows"
@@ -902,9 +955,6 @@ AM_COND_IF([WINDOWS], [
 	my_LDFLAGS="${my_LDFLAGS} -static-libgcc -static-libstdc++"
 	my_LIBS="${my_LIBS} -lwinmm -luuid -lole32 -lws2_32 -ladvapi32 -lshell32 -luser32 -lkernel32 -lgdi32 -loleaut32 -lcomdlg32 -limm32 -lwinspool"
 ])
-AM_COND_IF([LINUX], [
-	my_LIBS="${my_LIBS} -ldl -lpthread"
-])
 
 AC_SUBST(CUSTOMDEFINES)
 AC_SUBST(MOCDEFINES)
diff --git a/src/audio/Makefile.am b/src/audio/Makefile.am
index 19712065..0be11b95 100644
--- a/src/audio/Makefile.am
+++ b/src/audio/Makefile.am
@@ -21,6 +21,11 @@ libaudio_a_SOURCES += \
 	alsa/snd.c
 endif
 
+if OPENBSD
+libaudio_a_SOURCES += \
+	sndio/snd.c
+endif
+
 if WINDOWS
 libaudio_a_SOURCES += \
 	xaudio/snd.c
diff --git a/src/audio/sndio/snd.c b/src/audio/sndio/snd.c
index e69de29b..4eb24484 100644
--- a/src/audio/sndio/snd.c
+++ b/src/audio/sndio/snd.c
@@ -0,0 +1,447 @@
+/*
+ *  Copyright (C) 2010-2019 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 <signal.h>
+#include <poll.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <sndio.h>
+#include "info.h"
+#include "snd.h"
+#include "clock.h"
+#include "conf.h"
+#include "fps.h"
+#include "audio/blipbuf.h"
+#include "audio/channels.h"
+#include "gui.h"
+#include "wave.h"
+
+enum sndio_thread_loop_actions {
+	AT_UNINITIALIZED,
+	AT_RUN,
+	AT_STOP,
+	AT_PAUSE
+};
+
+typedef struct _sndio {
+	struct sio_hdl *playback;
+	struct pollfd *pfds;
+
+	size_t bsize;
+	size_t psize;
+} _sndio;
+typedef struct _thread {
+	pthread_t thread;
+	pthread_mutex_t lock;
+
+	BYTE action;
+	BYTE in_run;
+
+	void *cache;
+	_sndio *sndio;
+
+#if !defined (RELEASE)
+	double tick;
+#endif
+} _thread;
+
+static void *sndio_playback_loop(void *data);
+static void sndio_playback_loop_in_pause(void);
+static void INLINE sndio_wr_buf(_sndio *sndio, void *buffer, uint32_t avail);
+
+static _thread loop;
+static _sndio sndio;
+static _callback_data cbd;
+
+BYTE snd_init(void) {
+	memset(&snd, 0x00, sizeof(_snd));
+	memset(&sndio, 0x00, sizeof(_sndio));
+	memset(&cbd, 0x00, sizeof(_callback_data));
+	memset(&loop, 0x00, sizeof(_thread));
+
+	snd_apu_tick = NULL;
+	snd_end_frame = NULL;
+
+	// apro e avvio la riproduzione
+	if (snd_playback_start()) {
+		return (EXIT_ERROR);
+	}
+
+	return (EXIT_OK);
+}
+void snd_quit(void) {
+	// se e' in corso una registrazione, la concludo
+	wave_close();
+
+	if (loop.action != AT_UNINITIALIZED) {
+		loop.action = AT_STOP;
+
+		pthread_join(loop.thread, NULL);
+		pthread_mutex_destroy(&loop.lock);
+		memset(&loop, 0x00, sizeof(_thread));
+	}
+
+	snd_playback_stop();
+
+#if !defined (RELEASE)
+	fprintf(stderr, "\n");
+#endif
+}
+
+BYTE snd_playback_start(void) {
+	if (!cfg->apu.channel[APU_MASTER]) {
+		return (EXIT_OK);
+	}
+
+	// se il thread del loop e' gia' in funzione lo metto in pausa
+	if (loop.action == AT_RUN) {
+		sndio_playback_loop_in_pause();
+		snd_playback_lock(NULL);
+	}
+
+	// come prima cosa blocco eventuali riproduzioni
+	snd_playback_stop();
+
+	memset(&snd, 0x00, sizeof(_snd));
+	memset(&sndio, 0x00, sizeof(_sndio));
+	memset(&cbd, 0x00, sizeof(_callback_data));
+	snd.cache = &cbd;
+
+	audio_channels(cfg->channels_mode);
+
+	switch (cfg->samplerate) {
+		case S48000:
+			snd.samplerate = 48000;
+			break;
+		case S44100:
+			snd.samplerate = 44100;
+			break;
+		case S22050:
+			snd.samplerate = 22050;
+			break;
+		case S11025:
+			snd.samplerate = 11025;
+			break;
+	}
+
+	if ((sndio.playback = sio_open(SIO_DEVANY, SIO_PLAY, TRUE)) == NULL) {
+		fprintf(stderr, "sio_open() failed\n");
+		goto snd_playback_start_error;
+	}
+
+	if ((sndio.pfds = calloc(sio_nfds(sndio.playback), sizeof(struct pollfd))) == NULL) {
+		fprintf(stderr, "sio_nfds() failed\n");
+		goto snd_playback_start_error;
+	}
+
+	{
+		static int factor[10] = { 90, 80, 70, 60, 50, 40, 30, 20, 10, 5 };
+		struct sio_par par;
+
+		sio_initpar(&par);
+
+		// snd.samplarate / 50 = 20 ms
+		sndio.psize = (snd.samplerate / factor[cfg->audio_buffer_factor]);
+		sndio.bsize = sndio.psize;
+
+#if !defined (RELEASE)
+		fprintf(stderr, "psize and bsize : %ld %ld\n", sndio.psize, sndio.bsize);
+#endif
+
+		par.bits = 16;
+		par.sig = 1;
+		par.pchan = snd.channels;
+		par.rate = snd.samplerate;
+		par.round = sndio.psize;
+		par.appbufsz = sndio.bsize;
+		par.xrun = SIO_IGNORE;
+
+		if (!sio_setpar(sndio.playback, &par)) {
+			fprintf(stderr, "sio_setpar() failed\n");
+			goto snd_playback_start_error;
+		}
+
+		if (!sio_getpar(sndio.playback, &par)) {
+			fprintf(stderr, "sio_getpar() failed\n");
+			goto snd_playback_start_error;
+		}
+
+		sndio.psize = par.round;
+		sndio.bsize = par.appbufsz;
+
+#if !defined (RELEASE)
+		fprintf(stderr, "new psize and bsize : %ld %ld\n", sndio.psize, sndio.bsize);
+#endif
+	}
+
+	snd.samples = sndio.bsize * 4;
+	snd.frequency = machine.cpu_hz / (double) snd.samplerate;
+
+	{
+		// dimensione in bytes del buffer software
+		snd.buffer.size = (sndio.bsize * snd.channels * sizeof(*cbd.write)) * 10;
+
+		snd.buffer.limit.low = (snd.buffer.size / 100) * 25;
+		snd.buffer.limit.high = (snd.buffer.size / 100) * 55;
+
+#if !defined (RELEASE)
+		printf("softw bsize    : %10d - %10d\n", snd.buffer.size, snd.samples);
+		printf("softw limit    : %10d - %10d\n", snd.buffer.limit.high, snd.buffer.limit.low);
+#endif
+
+		// alloco il buffer in memoria
+		if (!(cbd.start = (SWORD *) malloc(snd.buffer.size))) {
+			fprintf(stderr, "Unable to allocate audio buffers\n");
+			goto snd_playback_start_error;
+		}
+
+		if (!(cbd.silence = (SWORD *) malloc(snd.buffer.size))) {
+			fprintf(stderr, "Unable to allocate silence buffer\n");
+			goto snd_playback_start_error;
+		}
+
+		// inizializzo il frame di scrittura
+		cbd.write = cbd.start;
+		// inizializzo il frame di lettura
+		cbd.read = (SBYTE *) cbd.start;
+		// punto alla fine del buffer
+		cbd.end = cbd.read + snd.buffer.size;
+		// azzero completamente i buffers
+		memset(cbd.start, 0x00, snd.buffer.size);
+		// azzero completamente il buffer del silenzio
+		memset(cbd.silence, 0x00, snd.buffer.size);
+
+		cbd.lock = (void *) &loop.lock;
+	}
+
+	if (extcl_snd_playback_start) {
+		extcl_snd_playback_start((WORD) snd.samplerate);
+	}
+
+	audio_channels_init_mode();
+
+	audio_init_blipbuf();
+
+	if (loop.action == AT_UNINITIALIZED) {
+		int rc;
+
+		loop.sndio = &sndio;
+		loop.action = AT_PAUSE;
+
+		// creo il lock
+		if (pthread_mutex_init(&loop.lock, NULL) != 0) {
+			fprintf(stderr, "Unable to allocate the thread mutex\n");
+			goto snd_playback_start_error;
+		}
+
+		snd_playback_lock(NULL);
+
+		if ((rc = pthread_create(&loop.thread, NULL, sndio_playback_loop, (void *) &loop))) {
+			fprintf(stderr, "Error - pthread_create() return code: %d\n", rc);
+			goto snd_playback_start_error;;
+		}
+	}
+
+	loop.cache = &cbd;
+
+	if (!sio_start(sndio.playback)) {
+		fprintf(stderr, "sio_start() failed\n");
+		goto snd_playback_start_error;
+	}
+
+	snd_playback_unlock(NULL);
+	gui_sleep(50);
+
+	loop.action = AT_RUN;
+
+	return (EXIT_OK);
+
+	snd_playback_start_error:
+	snd_playback_stop();
+	return (EXIT_ERROR);
+}
+void snd_playback_stop(void) {
+	sndio_playback_loop_in_pause();
+
+	if (snd.cache) {
+		if (SNDCACHE->start) {
+			free(SNDCACHE->start);
+		}
+
+		if (SNDCACHE->silence) {
+			free(SNDCACHE->silence);
+		}
+
+		snd.cache = NULL;
+	}
+
+	if (audio_channels_quit) {
+		audio_channels_quit();
+	}
+
+	audio_quit_blipbuf();
+
+	if (sndio.playback) {
+		sio_close(sndio.playback);
+		sndio.playback = NULL;
+	}
+
+	if (sndio.pfds) {
+		free(sndio.pfds);
+		sndio.pfds = NULL;
+	}
+}
+void snd_playback_lock(_callback_data *cache) {
+	pthread_mutex_lock(&loop.lock);
+}
+void snd_playback_unlock(_callback_data *cache) {
+	pthread_mutex_unlock(&loop.lock);
+}
+uTCHAR *snd_playback_device_desc(int dev) {
+	return (0);
+}
+uTCHAR *snd_playback_device_id(int dev) {
+	return (0);
+}
+
+uTCHAR *snd_capture_device_desc(int dev) {
+	return (0);
+}
+uTCHAR *snd_capture_device_id(int dev) {
+	return (0);
+}
+
+void snd_list_devices(void) {}
+
+static void *sndio_playback_loop(void *data) {
+	_thread *th = (_thread *) data;
+	uint32_t avail, len;
+
+#if !defined (RELEASE)
+	th->tick = gui_get_ms();
+#endif
+
+	while (TRUE) {
+		_callback_data *cache = (_callback_data *) th->cache;
+
+		if (th->action == AT_STOP) {
+				th->in_run = FALSE;
+				break;
+			} else if (th->action == AT_PAUSE) {
+				th->in_run = FALSE;
+				gui_sleep(10);
+				continue;
+			}
+
+			th->in_run = TRUE;
+
+			{
+				int nfds, event;
+
+				if ((nfds = sio_pollfd(sndio.playback, sndio.pfds, POLLOUT)) <= 0) {
+					fprintf(stderr, "sio_pollfd() failed\n");
+					continue;
+				}
+
+				if (poll(sndio.pfds, nfds, -1) < 0) {
+					if (errno == EINTR) {
+						continue;
+					}
+					perror("poll");
+					continue;
+				}
+
+				event = sio_revents(sndio.playback, sndio.pfds);
+
+				if (event & POLLHUP) {
+					continue;
+				}
+
+				if ((event & POLLOUT) == 0) {
+					continue;
+				}
+			}
+
+			snd_playback_lock(NULL);
+
+			avail = sndio.psize;
+			len = avail * snd.channels * sizeof(*cache->write);
+
+			if ((info.no_rom | info.turn_off | info.pause) || (snd.buffer.start == FALSE) ||
+				(fps.fast_forward == TRUE)) {
+				sndio_wr_buf(th->sndio, (void *) cache->silence, len);
+			} else if (cache->bytes_available < len) {
+				sndio_wr_buf(th->sndio, (void *) cache->silence, len);
+				snd.out_of_sync++;
+			} else {
+				wave_write((SWORD *) cache->read, avail);
+				sndio_wr_buf(th->sndio, (void *) cache->read, len);
+
+				cache->bytes_available -= len;
+				cache->samples_available -= avail;
+
+				if ((cache->read += len) >= cache->end) {
+					cache->read = (SBYTE *) cache->start;
+				}
+			}
+
+#if !defined (RELEASE)
+			uint32_t request = avail;
+
+			if ((gui_get_ms() - th->tick) >= 250.0f) {
+				th->tick = gui_get_ms();
+				if (info.snd_info == TRUE)
+				fprintf(stderr, "snd : %6d %6d %d %6d %d %6d %6d %f %3d %f %4s\r",
+					request,
+					avail,
+					len,
+					fps.total_frames_skipped,
+					cache->samples_available,
+					cache->bytes_available,
+					snd.out_of_sync,
+					snd.frequency,
+					(int) framerate.value,
+					machine.ms_frame,
+					" ");
+			}
+#endif
+
+			snd_playback_unlock(NULL);
+	 	}
+
+		pthread_exit((void *)EXIT_OK);
+}
+static void sndio_playback_loop_in_pause(void) {
+	if (loop.action != AT_UNINITIALIZED) {
+		loop.action = AT_PAUSE;
+
+		while (loop.in_run == TRUE) {
+			gui_sleep(10);
+		}
+	}
+}
+static void INLINE sndio_wr_buf(_sndio *sndio, void *buffer, uint32_t avail) {
+	if (sio_write(sndio->playback, buffer, avail) == 0) {
+		if (sio_eof(sndio->playback)) {
+			fprintf(stderr, "sio_write() failed\n");
+		}
+	}
+}
+
diff --git a/src/c++/xBRZ/xbrz.cpp b/src/c++/xBRZ/xbrz.cpp
index 99a928ca..b969a147 100644
--- a/src/c++/xBRZ/xbrz.cpp
+++ b/src/c++/xBRZ/xbrz.cpp
@@ -1131,10 +1131,10 @@ void xbrz::scale(BYTE factor, const WORD* src, uint32_t* trg, uint32_t* palette,
 }
 
 
-#if defined (__WIN32__)
-	DWORD WINAPI xbrz::scale_mt(void *param)
-#elif defined (__linux__)
+#if defined (__unix__)
     void *xbrz::scale_mt(void *param)
+#elif defined (__WIN32__)
+    DWORD WINAPI xbrz::scale_mt(void *param)
 #endif
 {
     _xbrz_wrap *p = (_xbrz_wrap *) param;
@@ -1195,10 +1195,10 @@ void xbrz::scale(BYTE factor, const WORD* src, uint32_t* trg, uint32_t* palette,
     }
     assert(false);
 
-#if defined (__WIN32__)
-    return (0);
-#elif defined (__linux__)
+#if defined (__unix__)
     return (NULL);
+#elif defined (__WIN32__)
+    return (0);
 #endif
 }
 
diff --git a/src/c++/xBRZ/xbrz.h b/src/c++/xBRZ/xbrz.h
index 2bb24e7e..47999766 100644
--- a/src/c++/xBRZ/xbrz.h
+++ b/src/c++/xBRZ/xbrz.h
@@ -68,10 +68,10 @@ void scale(BYTE factor, //valid range: 2 - 6
            const ScalerCfg& cfg = ScalerCfg(),
            int yFirst = 0, int yLast = std::numeric_limits<int>::max()); //slice of source image
 
-#if defined (__WIN32__)
-DWORD WINAPI scale_mt(void *param);
-#elif defined (__linux__)
+#if defined (__unix__)
 void *scale_mt(void *param);
+#elif defined (__WIN32__)
+DWORD WINAPI scale_mt(void *param);
 #endif
 
 void nearestNeighborScale(const uint32_t* src, int srcWidth, int srcHeight,
diff --git a/src/c++/xBRZ/xbrz_wrap.cpp b/src/c++/xBRZ/xbrz_wrap.cpp
index a59097f1..8530b259 100644
--- a/src/c++/xBRZ/xbrz_wrap.cpp
+++ b/src/c++/xBRZ/xbrz_wrap.cpp
@@ -18,7 +18,7 @@
 
 #include "c++/xBRZ/xbrz_wrap.h"
 #include "c++/xBRZ/xbrz.h"
-#if defined (__linux__)
+#if defined (__unix__)
 #include <pthread.h>
 #endif
 
@@ -33,11 +33,11 @@ extern "C" void xbrz_scale(BYTE factor, const WORD *src, uint32_t *trg, uint32_t
 
 extern "C" void xbrz_scale_mt(BYTE factor, const WORD *src, uint32_t *trg, uint32_t *palette,
 		int width, int height) {
-#if defined (__WIN32__)
+#if defined (__unix__)
+	pthread_t thread[XBRZ_NUM_SLICE];
+#elif defined (__WIN32__)
 	HANDLE thread[XBRZ_NUM_SLICE];
 	DWORD id[XBRZ_NUM_SLICE];
-#elif defined (__linux__)
-	pthread_t thread[XBRZ_NUM_SLICE];
 #endif
 	_xbrz_wrap param[XBRZ_NUM_SLICE];
 	int i;
@@ -55,21 +55,21 @@ extern "C" void xbrz_scale_mt(BYTE factor, const WORD *src, uint32_t *trg, uint3
 	#elif defined (WITH_OPENGL)
 		param[i].colFmt = (int) xbrz::ColorFormat::RGB;
 	#endif
-#if defined (__WIN32__)
-		thread[i] = CreateThread(NULL, 0, xbrz::scale_mt, &param[i], 0, &id[i]);
-#elif defined (__linux__)
+#if defined (__unix__)
 		pthread_create(&thread[i], NULL, xbrz::scale_mt, &param[i]);
+#elif defined (__WIN32__)
+		thread[i] = CreateThread(NULL, 0, xbrz::scale_mt, &param[i], 0, &id[i]);
 #endif
 	}
 
-#if defined (__WIN32__)
-	WaitForMultipleObjects(XBRZ_NUM_SLICE, thread, TRUE, INFINITE);
+#if defined (__unix__)
 	for (i = 0; i < XBRZ_NUM_SLICE; i++) {
-		CloseHandle(thread[i]);
+		pthread_join(thread[i], NULL);
 	}
-#elif defined (__linux__)
+#elif defined (__WIN32__)
+	WaitForMultipleObjects(XBRZ_NUM_SLICE, thread, TRUE, INFINITE);
 	for (i = 0; i < XBRZ_NUM_SLICE; i++) {
-		pthread_join(thread[i], NULL);
+		CloseHandle(thread[i]);
 	}
 #endif
 }
diff --git a/src/core/gfx.h b/src/core/gfx.h
index 90533fd3..0146e552 100644
--- a/src/core/gfx.h
+++ b/src/core/gfx.h
@@ -181,7 +181,7 @@ EXTERNC uint32_t gfx_color(BYTE alpha, BYTE r, BYTE g, BYTE b);
 EXTERNC void gfx_cursor_init(void);
 EXTERNC void gfx_cursor_quit(void);
 EXTERNC void gfx_cursor_set(void);
-#if defined (__linux__)
+#if defined (__unix__)
 EXTERNC void gfx_cursor_hide(BYTE hide);
 #endif
 
diff --git a/src/core/uncompress.c b/src/core/uncompress.c
index 69235d5e..23a8bf42 100644
--- a/src/core/uncompress.c
+++ b/src/core/uncompress.c
@@ -18,11 +18,15 @@
 
 #include <stdlib.h>
 #include <string.h>
+#if defined (__OpenBSD__)
+#include <stdio.h>
+#include <libgen.h>
+#endif
 #include "uncompress.h"
 #include "info.h"
 #include "c++/l7zip/l7z.h"
 #include "gui.h"
-#if defined (__linux__)
+#if defined (__unix__)
 #define MINIZ_NO_ARCHIVE_WRITING_APIS
 #define MINIZ_NO_TIME
 #include "miniz.h"
@@ -36,7 +40,7 @@ static BYTE (*uncompress_examine_archive)(_uncompress_archive *archive);
 static BYTE (*uncompress_extract_from_archive)(_uncompress_archive *archive, uint32_t selected, BYTE type);
 static uTCHAR *(*uncompress_item_file_name)(_uncompress_archive *archive, uint32_t selected, BYTE type);
 
-#if defined (__linux__)
+#if defined (__unix__)
 // zip
 static BYTE mz_zip_examine_archive(_uncompress_archive *archive);
 static BYTE mz_zip_extract_from_archive(_uncompress_archive *archive, uint32_t selected, BYTE type);
@@ -84,7 +88,7 @@ _uncompress_archive *uncompress_archive_alloc(uTCHAR *file, BYTE *rc) {
 		uncompress_examine_archive = l7z_examine_archive;
 		uncompress_extract_from_archive = l7z_extract_from_archive;
 		uncompress_item_file_name = l7z_item_file_name;
-#if defined (__linux__)
+#if defined (__unix__)
 	} else if (!ustrcasecmp(ext, uL(".zip"))) {
 		uncompress_examine_archive = mz_zip_examine_archive;
 		uncompress_extract_from_archive = mz_zip_extract_from_archive;
@@ -280,7 +284,7 @@ static uTCHAR *uncompress_storage_index_file_name(uint32_t index) {
 	return (sitem->file);
 }
 
-#if defined (__linux__)
+#if defined (__unix__)
 static BYTE mz_zip_examine_archive(_uncompress_archive *archive) {
 	mz_zip_archive mzarchive;
 	unsigned int a;
diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am
index 243184c2..7a8135bd 100644
--- a/src/gui/Makefile.am
+++ b/src/gui/Makefile.am
@@ -1,55 +1,55 @@
 application.cpp: designer/application.qrc
-	$(RCC) $< -name resources -o $@
+	$(RCC) $(srcdir)/designer/application.qrc -name resources -o $@
 
 cheatObject.moc: cheatObject.hpp
-	$(MOC) $< $(MOCDEFINES) $(CUSTOMDEFINES) -o $@
+	$(MOC) $(srcdir)/cheatObject.hpp $(MOCDEFINES) $(CUSTOMDEFINES) -o $@
 dlgApuChannels.moc: dlgApuChannels.hpp
-	$(MOC) $< $(MOCDEFINES) $(CUSTOMDEFINES) -o $@
+	$(MOC) $(srcdir)/dlgApuChannels.hpp $(MOCDEFINES) $(CUSTOMDEFINES) -o $@
 dlgCheats.moc: dlgCheats.hpp
-	$(MOC) $< $(MOCDEFINES) $(CUSTOMDEFINES) -o $@
+	$(MOC) $(srcdir)/dlgCheats.hpp $(MOCDEFINES) $(CUSTOMDEFINES) -o $@
 dlgInput.moc: dlgInput.hpp
-	$(MOC) $< $(MOCDEFINES) $(CUSTOMDEFINES) -o $@
+	$(MOC) $(srcdir)/dlgInput.hpp $(MOCDEFINES) $(CUSTOMDEFINES) -o $@
 dlgOverscanBorders.moc: dlgOverscanBorders.hpp
-	$(MOC) $< $(MOCDEFINES) $(CUSTOMDEFINES) -o $@
+	$(MOC) $(srcdir)/dlgOverscanBorders.hpp $(MOCDEFINES) $(CUSTOMDEFINES) -o $@
 dlgPPUHacks.moc: dlgPPUHacks.hpp
-	$(MOC) $< $(MOCDEFINES) $(CUSTOMDEFINES) -o $@
+	$(MOC) $(srcdir)/dlgPPUHacks.hpp $(MOCDEFINES) $(CUSTOMDEFINES) -o $@
 dlgStdPad.moc: dlgStdPad.hpp
-	$(MOC) $< $(MOCDEFINES) $(CUSTOMDEFINES) -o $@
+	$(MOC) $(srcdir)/dlgStdPad.hpp $(MOCDEFINES) $(CUSTOMDEFINES) -o $@
 dlgUncomp.moc: dlgUncomp.hpp
-	$(MOC) $< $(MOCDEFINES) $(CUSTOMDEFINES) -o $@
+	$(MOC) $(srcdir)/dlgUncomp.hpp $(MOCDEFINES) $(CUSTOMDEFINES) -o $@
 dlgVsSystem.moc: dlgVsSystem.hpp
-	$(MOC) $< $(MOCDEFINES) $(CUSTOMDEFINES) -o $@
+	$(MOC) $(srcdir)/dlgVsSystem.hpp $(MOCDEFINES) $(CUSTOMDEFINES) -o $@
 mainWindow.moc: mainWindow.hpp
-	$(MOC) $< $(MOCDEFINES) $(CUSTOMDEFINES) -o $@
+	$(MOC) $(srcdir)/mainWindow.hpp $(MOCDEFINES) $(CUSTOMDEFINES) -o $@
 pMenu.moc: pMenu.hpp
-	$(MOC) $< $(MOCDEFINES) $(CUSTOMDEFINES) -o $@
+	$(MOC) $(srcdir)/pMenu.hpp $(MOCDEFINES) $(CUSTOMDEFINES) -o $@
 pStyle.moc: pStyle.hpp
-	$(MOC) $< $(MOCDEFINES) $(CUSTOMDEFINES) -o $@
+	$(MOC) $(srcdir)/pStyle.hpp $(MOCDEFINES) $(CUSTOMDEFINES) -o $@
 sbarWidget.moc: sbarWidget.hpp
-	$(MOC) $< $(MOCDEFINES) $(CUSTOMDEFINES) -o $@
+	$(MOC) $(srcdir)/sbarWidget.hpp $(MOCDEFINES) $(CUSTOMDEFINES) -o $@
 screenWidget.moc: screenWidget.hpp
-	$(MOC) $< $(MOCDEFINES) $(CUSTOMDEFINES) -o $@
+	$(MOC) $(srcdir)/screenWidget.hpp $(MOCDEFINES) $(CUSTOMDEFINES) -o $@
 settingsObject.moc: settingsObject.hpp
-	$(MOC) $< $(MOCDEFINES) $(CUSTOMDEFINES) -o $@
+	$(MOC) $(srcdir)/settingsObject.hpp $(MOCDEFINES) $(CUSTOMDEFINES) -o $@
 
 application.hh: designer/application.ui
-	$(UIC) $< -o $@
+	$(UIC) $(srcdir)/designer/application.ui -o $@
 dlgOverscanBorders.hh: designer/dlgOverscanBorders.ui
-	$(UIC) $< -o $@
+	$(UIC) $(srcdir)/designer/dlgOverscanBorders.ui -o $@
 dlgApuChannels.hh: designer/dlgApuChannels.ui
-	$(UIC) $< -o $@
+	$(UIC) $(srcdir)/designer/dlgApuChannels.ui -o $@
 dlgStdPad.hh: designer/dlgStdPad.ui
-	$(UIC) $< -o $@
+	$(UIC) $(srcdir)/designer/dlgStdPad.ui -o $@
 dlgCheats.hh: designer/dlgCheats.ui
-	$(UIC) $< -o $@
+	$(UIC) $(srcdir)/designer/dlgCheats.ui -o $@
 dlgUncomp.hh: designer/dlgUncomp.ui
-	$(UIC) $< -o $@
+	$(UIC) $(srcdir)/designer/dlgUncomp.ui -o $@
 dlgVsSystem.hh: designer/dlgVsSystem.ui
-	$(UIC) $< -o $@
+	$(UIC) $(srcdir)/designer/dlgVsSystem.ui -o $@
 dlgPPUHacks.hh: designer/dlgPPUHacks.ui
-	$(UIC) $< -o $@
+	$(UIC) $(srcdir)/designer/dlgPPUHacks.ui -o $@
 dlgInput.hh: designer/dlgInput.ui
-	$(UIC) $< -o $@
+	$(UIC) $(srcdir)/designer/dlgInput.ui -o $@
 
 clean-local:
 	rm -f application.cpp *.{hh,moc}
@@ -143,6 +143,18 @@ endif
 
 endif
 
+if OPENBSD
+libgui_a_SOURCES += \
+	openbsd/jstick.c \
+	openbsd/jstick.h \
+	openbsd/os_openbsd.h
+
+if ENAB_QT5
+AM_CXXFLAGS = -fPIC
+endif
+
+endif
+
 if WINDOWS
 libgui_a_SOURCES += \
 	windows/jstick.c \
diff --git a/src/gui/dlgOverscanBorders.cpp b/src/gui/dlgOverscanBorders.cpp
index 9c0892c9..fe9be537 100644
--- a/src/gui/dlgOverscanBorders.cpp
+++ b/src/gui/dlgOverscanBorders.cpp
@@ -24,7 +24,7 @@
 #include "gfx.h"
 #include "emu.h"
 #include "gui.h"
-#if defined (__linux__) || defined (WITH_D3D9)
+#if defined (__unix__) || defined (WITH_D3D9)
 #define __GFX_FORCE_SCALE__
 #include "gfx_functions_inline.h"
 #undef __GFX_FORCE_SCALE__
diff --git a/src/gui/mainWindow.cpp b/src/gui/mainWindow.cpp
index b69fcddc..b53c3980 100644
--- a/src/gui/mainWindow.cpp
+++ b/src/gui/mainWindow.cpp
@@ -29,7 +29,7 @@
 #include <QtCore/QDateTime>
 #include <QtCore/QUrl>
 #include <QtGui/QDesktopServices>
-#if defined (__linux__)
+#if defined (__unix__)
 #include <unistd.h>
 #include <fcntl.h>
 #endif
@@ -56,7 +56,7 @@
 #include "audio/wave.h"
 #include "vs_system.h"
 #if defined (WITH_OPENGL)
-#if defined (__linux__)
+#if defined (__unix__)
 #include "sdl_wid.h"
 #endif
 #include "opengl.h"
@@ -64,7 +64,7 @@
 #include "timeline.h"
 #include "c++/l7zip/l7z.h"
 #include "gui.h"
-#if defined (__linux__) || defined (WITH_D3D9)
+#if defined (__unix__) || defined (WITH_D3D9)
 #define __GFX_OTHERS_FUNC__
 #include "gfx_functions_inline.h"
 #undef __GFX_OTHERS_FUNC__
@@ -977,6 +977,10 @@ void mainWindow::update_menu_settings() {
 #endif
 	ui->action_Fullscreen_in_window->setChecked(cfg->fullscreen_in_window);
 	ui->action_Stretch_in_fullscreen->setChecked(cfg->stretch);
+#if defined (__OpenBSD__)
+	// Settings/Audio/Output Device
+	ui->menu_Output_Device->menuAction()->setVisible(false);
+#endif
 	// Settings/Audio/Buffer Size factor
 	switch (cfg->audio_buffer_factor) {
 		case 0:
diff --git a/src/gui/openbsd/jstick.c b/src/gui/openbsd/jstick.c
index e69de29b..839d21d5 100644
--- a/src/gui/openbsd/jstick.c
+++ b/src/gui/openbsd/jstick.c
@@ -0,0 +1,73 @@
+/*
+ *  Copyright (C) 2010-2019 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 "jstick.h"
+#include "input.h"
+
+void js_init(BYTE first_time) {
+}
+void js_quit(BYTE last_time) {
+}
+void js_update_detected_devices(void) {}
+void js_control(_js *joy, _port *port) {
+}
+
+BYTE js_is_connected(int dev) {
+	return (EXIT_ERROR);
+}
+BYTE js_is_this(BYTE dev, BYTE *id) {
+	return (FALSE);
+}
+BYTE js_is_null(BYTE *id) {
+	return (FALSE);
+}
+void js_set_id(BYTE *id, int dev) {
+}
+uTCHAR *js_name_device(int dev) {
+	static uTCHAR name[128];
+
+	umemset(name, 0x00, usizeof(name));
+	ustrncpy(name, uL("Not connected"), usizeof(name));
+
+	return((uTCHAR *) name);
+}
+BYTE js_read_event(_js_event *event, _js *joy) {
+	return (EXIT_ERROR);
+}
+uTCHAR *js_to_name(const DBWORD val, const _js_element *list, const DBWORD length) {
+	return ((uTCHAR *) list[0].name);
+}
+DBWORD js_from_name(const uTCHAR *name, const _js_element *list, const DBWORD length) {
+	DBWORD js = 0;
+
+	return (js);
+}
+DBWORD js_read_in_dialog(BYTE *id, int fd) {
+	DBWORD value = 0;
+
+	return (value);
+}
+
+void js_shcut_init(void) {
+}
+void js_shcut_stop(void) {
+}
+BYTE js_shcut_read(_js_sch *js_sch) {
+	return (EXIT_ERROR);
+}
diff --git a/src/gui/openbsd/jstick.h b/src/gui/openbsd/jstick.h
index e69de29b..077ee62a 100644
--- a/src/gui/openbsd/jstick.h
+++ b/src/gui/openbsd/jstick.h
@@ -0,0 +1,124 @@
+/*
+ *  Copyright (C) 2010-2019 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 name_to_jsv(name) js_from_name(name, jsv_list, LENGTH(jsv_list))
+#define name_to_jsn(name) js_from_name(name, jsn_list, LENGTH(jsn_list))
+#define jsv_to_name(jsvl) js_to_name(jsvl, jsv_list, LENGTH(jsv_list))
+#define jsn_to_name(jsvl) js_to_name(jsvl, jsn_list, LENGTH(jsn_list))
+
+enum {
+	CENTER,
+	PLUS = 0x7FFF
+};
+
+typedef struct _js {
+	uTCHAR dev[30];
+	SDBWORD fd;
+	WORD open_try;
+	SWORD last[16];
+	SWORD last_value[16];
+	BYTE (*input_decode_event)(BYTE mode, BYTE autorepeat, DBWORD event, BYTE type, _port *port);
+} _js;
+typedef struct _js_event {
+	/* event timestamp in milliseconds */
+	DBWORD time;
+	/* value */
+	SWORD value;
+	/* event type */
+	BYTE type;
+	/* axis/button number */
+	BYTE number;
+} _js_event;
+typedef struct _js_element {
+	DBWORD value;
+	uTCHAR name[20];
+} _js_element;
+typedef struct _js_sch {
+	DBWORD value;
+	BYTE mode;
+} _js_sch;
+
+#if defined (__cplusplus)
+#define EXTERNC extern "C"
+#else
+#define EXTERNC
+#endif
+
+static const _js_element jsn_list[] = {
+	{ 0x0FF,  uL("NULL")        },
+	{ 0x000,  uL("JOYSTICKID1") },
+	{ 0x001,  uL("JOYSTICKID2") },
+	{ 0x002,  uL("JOYSTICKID3") },
+	{ 0x003,  uL("JOYSTICKID4") },
+};
+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") },
+	{ 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")   },
+};
+
+EXTERNC _js js[PORT_MAX], js_shcut;
+
+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 BYTE js_read_event(_js_event *event, _js *joy);
+EXTERNC uTCHAR *js_to_name(const DBWORD val, const _js_element *list, const DBWORD length);
+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
index e69de29b..d37eec7c 100644
--- a/src/gui/openbsd/os_openbsd.h
+++ b/src/gui/openbsd/os_openbsd.h
@@ -0,0 +1,116 @@
+/*
+ *  Copyright (C) 2010-2019 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>
+
+double high_resolution_ms(void);
+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 = { 0 }, rem = { 0 };
+	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->winId();
+
+	return (wid);
+}
+
+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));
+}
+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 92881ff5..0d1d9cbe 100644
--- a/src/gui/qt.cpp
+++ b/src/gui/qt.cpp
@@ -543,8 +543,10 @@ static void gui_enable_pmenu(QWidget *parent, QAction *action, QList<pMenu*> *pm
 	}
 }
 
-#if defined (__WIN32__)
-#include "os_windows.h"
-#else
+#if defined (__linux__)
 #include "os_linux.h"
+#elif defined (__OpenBSD__)
+#include "os_openbsd.h"
+#elif defined (__WIN32__)
+#include "os_windows.h"
 #endif
diff --git a/src/gui/sbarWidget.cpp b/src/gui/sbarWidget.cpp
index 58f2dfd3..9391e332 100644
--- a/src/gui/sbarWidget.cpp
+++ b/src/gui/sbarWidget.cpp
@@ -215,7 +215,7 @@ stateWidget::stateWidget(Ui::mainWindow *u, QWidget *parent) : QWidget(parent) {
 
 	setLayout(hbox);
 
-#if defined (__linux__)
+#if defined (__unix__)
 	vline = new QFrame(this);
 	vline->setFrameShape(QFrame::VLine);
 	vline->setFrameShadow(QFrame::Plain);
@@ -263,7 +263,7 @@ void stateWidget::retranslateUi() {
 	load->setText(tr("Load"));
 	load->setFixedWidth(QLabel(load->text()).sizeHint().width() + 12);
 
-#if defined (__linux__)
+#if defined (__unix__)
 	setFixedWidth(vline->width() + SPACING +
 			save->width() + SPACING +
 			slot->width() + SPACING +
@@ -317,7 +317,7 @@ timeLine::timeLine(QWidget *parent) : QWidget(parent) {
 
 	setLayout(hbox);
 
-#if defined (__linux__)
+#if defined (__unix__)
 	vline = new QFrame(this);
 	vline->setFrameShape(QFrame::VLine);
 	vline->setFrameShadow(QFrame::Plain);
@@ -388,7 +388,7 @@ void timeLine::retranslateUi() {
 
 	label->setFixedWidth(QLabel(tr("-00 sec")).sizeHint().width());
 
-#if defined (__linux__)
+#if defined (__unix__)
 	setFixedWidth(vline->width() + SPACING +
 			label->width() + SPACING +
 			slider->width());//+  (slider->sizeHandle() / 2));
diff --git a/src/gui/settingsObject.cpp b/src/gui/settingsObject.cpp
index be80a0ae..dad8fb39 100644
--- a/src/gui/settingsObject.cpp
+++ b/src/gui/settingsObject.cpp
@@ -24,7 +24,7 @@
 #include "conf.h"
 #include "emu.h"
 #include "jstick.h"
-#if defined (__linux__)
+#if defined (__unix__)
 #define XK_MISCELLANY
 #include <X11/keysymdef.h>
 #endif
@@ -72,7 +72,7 @@ static const struct _kvSpecials {
 	{ VK_RSHIFT,    0,                   Qt::Key_Shift,    "RShift",     277 },
 	{ VK_LCONTROL,  0,                   Qt::Key_Control,  "LCtrl",      278 },
 	{ VK_RCONTROL,  0,                   Qt::Key_Control,  "RCtrl",      279 },
-#elif defined (__linux__)
+#elif defined (__unix__)
 	/*
 	{ 0,            Qt::AltModifier,     Qt::Key_Alt,      "Alt",        273 },
 	{ 0,            Qt::NoModifier,      Qt::Key_AltGr,    "AltGr",      274 },
diff --git a/src/video/sdl/gfx.c b/src/video/sdl/gfx.c
index 971fdec4..8842ba35 100644
--- a/src/video/sdl/gfx.c
+++ b/src/video/sdl/gfx.c
@@ -759,7 +759,7 @@ void gfx_cursor_set(void) {
 	}
 #endif
 }
-#if defined (__linux__)
+#if defined (__unix__)
 void gfx_cursor_hide(BYTE hide) {
 	if (hide == TRUE) {
 		SDL_ShowCursor(SDL_DISABLE);

Reply via email to