Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add OpenBSD support #51

Merged
merged 12 commits into from Jul 31, 2016
113 changes: 110 additions & 3 deletions Makefile
Expand Up @@ -590,6 +590,103 @@ ifeq ($(PLATFORM),freebsd)

else # ifeq freebsd

#############################################################################
# SETUP AND BUILD -- OPENBSD
#############################################################################

ifeq ($(PLATFORM),openbsd)

# Get the machine type
ARCH=$(shell uname -m)

BASE_CFLAGS = -Wall -fno-strict-aliasing -Wimplicit -Wstrict-prototypes

ifeq ($(USE_OPENAL),1)
BASE_CFLAGS += -DUSE_OPENAL
ifeq ($(USE_OPENAL_DLOPEN),1)
BASE_CFLAGS += -DUSE_OPENAL_DLOPEN
endif
endif

ifeq ($(USE_CURL),1)
BASE_CFLAGS += -DUSE_CURL=1
ifeq ($(USE_CURL_DLOPEN),1)
BASE_CFLAGS += -DUSE_CURL_DLOPEN=1
endif
endif

ifeq ($(USE_CODEC_VORBIS),1)
BASE_CFLAGS += -DUSE_CODEC_VORBIS
endif

ifeq ($(USE_SDL),1)
BASE_CFLAGS += -DUSE_SDL_VIDEO=1 -DUSE_SDL_SOUND=1 \
$(shell pkg-config sdl --cflags)
else
BASE_CFLAGS += -I/usr/X11R6/include
endif

ifeq ($(USE_ALTGAMMA), 1)
BASE_CFLAGS += -DUSE_ALTGAMMA=1
endif

OPTIMIZE = -O2 -ffast-math -funroll-loops -fomit-frame-pointer

ifeq ($(ARCH),amd64)
HAVE_VM_COMPILED = true
else
ifeq ($(ARCH),i386)
HAVE_VM_COMPILED=true
else
ifeq ($(ARCH),ppc)
BASE_CFLAGS += -maltivec
HAVE_VM_COMPILED=false
endif
endif
endif

ifneq ($(HAVE_VM_COMPILED),true)
BASE_CFLAGS += -DNO_VM_COMPILED
endif

DEBUG_CFLAGS=$(BASE_CFLAGS) -g -O0

RELEASE_CFLAGS=$(BASE_CFLAGS) -DNDEBUG $(OPTIMIZE)

SHLIBEXT=so
SHLIBCFLAGS=-fPIC
SHLIBLDFLAGS=-shared $(LDFLAGS)

THREAD_LDFLAGS=-lpthread
LDFLAGS=-lm

ifeq ($(USE_SDL),1)
CLIENT_LDFLAGS=$(shell pkg-config sdl --libs)
ifeq ($(USE_ALTGAMMA), 1)
CLIENT_LDFLAGS += -lX11 -lXxf86vm
endif
else
CLIENT_LDFLAGS=-L/usr/X11R6/lib -lX11 -lXext -lXxf86dga -lXxf86vm
endif

ifeq ($(USE_OPENAL),1)
ifneq ($(USE_OPENAL_DLOPEN),1)
CLIENT_LDFLAGS += $(shell pkg-config openal --libs)
endif
endif

ifeq ($(USE_CURL),1)
ifneq ($(USE_CURL_DLOPEN),1)
CLIENT_LDFLAGS += -lcurl
endif
endif

ifeq ($(USE_CODEC_VORBIS),1)
CLIENT_LDFLAGS += -lvorbisfile -lvorbis -logg
endif

else # ifeq openbsd

#############################################################################
# SETUP AND BUILD -- NETBSD
#############################################################################
Expand Down Expand Up @@ -731,6 +828,7 @@ endif #Linux
endif #darwin
endif #mingw32
endif #FreeBSD
endif #OpenBSD
endif #NetBSD
endif #IRIX
endif #SunOS
Expand Down Expand Up @@ -1121,6 +1219,9 @@ ifeq ($(HAVE_VM_COMPILED),true)
ifeq ($(ARCH),x86_64)
Q3OBJ += $(B)/client/vm_x86_64.o $(B)/client/vm_x86_64_assembler.o
endif
ifeq ($(ARCH),amd64)
Q3OBJ += $(B)/client/vm_x86_64.o $(B)/client/vm_x86_64_assembler.o
endif
ifeq ($(ARCH),ppc)
Q3OBJ += $(B)/client/vm_ppc.o
endif
Expand Down Expand Up @@ -1157,12 +1258,15 @@ else
endif
endif

Q3POBJ = \
$(B)/client/linux_glimp.o \
ifneq ($(PLATFORM),openbsd)
Q3POBJ += \
$(B)/clientsmp/linux_glimp.o
endif

Q3POBJ += \
$(B)/client/sdl_glimp.o

Q3POBJ_SMP = \
$(B)/clientsmp/linux_glimp.o \
$(B)/clientsmp/sdl_glimp.o
endif

Expand Down Expand Up @@ -1291,6 +1395,9 @@ ifeq ($(HAVE_VM_COMPILED),true)
ifeq ($(ARCH),x86_64)
Q3DOBJ += $(B)/ded/vm_x86_64.o $(B)/client/vm_x86_64_assembler.o
endif
ifeq ($(ARCH),amd64)
Q3DOBJ += $(B)/ded/vm_x86_64.o $(B)/client/vm_x86_64_assembler.o
endif
ifeq ($(ARCH),ppc)
Q3DOBJ += $(B)/ded/vm_ppc.o
endif
Expand Down
4 changes: 2 additions & 2 deletions code/client/cl_curl.c
Expand Up @@ -41,7 +41,7 @@ cvar_t *cl_cURLLib;
#define SYMLOAD(x,y) GetProcAddress(x,y)
#define OBJFREE(x) FreeLibrary(x)

#elif defined __linux__ || defined __FreeBSD__ || defined MACOS_X || defined __sun
#elif defined __linux__ || defined __FreeBSD__ || defined __OpenBSD__ || defined MACOS_X || defined __sun
#include <dlfcn.h>
#define OBJTYPE void *
#define OBJLOAD(x) dlopen(x, RTLD_LAZY | RTLD_GLOBAL)
Expand All @@ -52,7 +52,7 @@ cvar_t *cl_cURLLib;
#error "Your platform has no lib loading code or it is disabled"
#endif

#if defined __linux__ || defined __FreeBSD__ || defined MACOS_X
#if defined __linux__ || defined __FreeBSD__ || defined __OpenBSD__ || defined MACOS_X
#include <unistd.h>
#include <sys/types.h>
#endif
Expand Down
2 changes: 2 additions & 0 deletions code/client/cl_curl.h
Expand Up @@ -33,6 +33,8 @@ extern cvar_t *cl_cURLLib;
#define DEFAULT_CURL_LIB "libcurl-4.dll"
#elif defined(MACOS_X)
#define DEFAULT_CURL_LIB "libcurl.dylib"
#elif defined(__OpenBSD__)
#define DEFAULT_CURL_LIB "libcurl.so"
#else
#define DEFAULT_CURL_LIB "libcurl.so.4"
#endif
Expand Down
4 changes: 2 additions & 2 deletions code/client/qal.c
Expand Up @@ -44,7 +44,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define SYMLOAD(x,y) GetProcAddress(x,y)
#define OBJFREE(x) FreeLibrary(x)

#elif defined __linux__ || defined __FreeBSD__ || defined MACOS_X || defined __sun
#elif defined __linux__ || defined __FreeBSD__ || defined __OpenBSD__ || defined MACOS_X || defined __sun
#include <dlfcn.h>
#define OBJTYPE void *
#define OBJLOAD(x) dlopen(x, RTLD_LAZY | RTLD_GLOBAL)
Expand All @@ -55,7 +55,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#error "Your platform has no lib loading code or it is disabled"
#endif

#if defined __linux__ || defined __FreeBSD__ || defined MACOS_X
#if defined __linux__ || defined __FreeBSD__ || defined __OpenBSD__ || defined MACOS_X
#include <unistd.h>
#include <sys/types.h>
#endif
Expand Down
157 changes: 157 additions & 0 deletions code/client/snd_sndio.c
@@ -0,0 +1,157 @@
/*
* Copyright (c) 2010 Jacob Meuser <jakemsr@sdf.lonestar.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <poll.h>
#include <errno.h>

#include <sndio.h>

#include "../qcommon/q_shared.h"
#include "../client/snd_local.h"

static struct sio_hdl *hdl;
static int snd_inited;

unsigned char *dma_buffer;
size_t dma_buffer_size, dma_ptr;


qboolean
SNDDMA_Init(void)
{
struct sio_par par;
int i;

if (snd_inited)
return qtrue;

hdl = sio_open(NULL, SIO_PLAY, 1);
if (hdl == NULL) {
Com_Printf("Could not open sndio device\n");
return qfalse;
}

sio_initpar(&par);

par.bits = 16;
par.sig = 1;
par.pchan = 2;
par.rate = 44100;
par.le = SIO_LE_NATIVE;
par.appbufsz = par.rate / 10; /* 1/10 second latency */

if (!sio_setpar(hdl, &par) || !sio_getpar(hdl, &par)) {
Com_Printf("Error setting audio parameters\n");
sio_close(hdl);
return qfalse;
}
if ((par.pchan != 1 && par.pchan != 2) ||
!((par.bits == 16 && par.sig == 1) ||
(par.bits == 8 && par.sig == 0))) {
Com_Printf("Could not set appropriate audio parameters\n");
sio_close(hdl);
return qfalse;
}
dma.speed = par.rate;
dma.channels = par.pchan;
dma.samplebits = par.bits;
dma.submission_chunk = 1;

/*
* find the smallest power of two larger than the buffer size
* and use it as the internal buffer's size
*/
for (i = 1; i < par.appbufsz; i <<= 2)
; /* nothing */
dma.samples = i * par.pchan;

dma_buffer_size = dma.samples * dma.samplebits / 8;
dma_buffer = calloc(1, dma_buffer_size);
if (dma_buffer == NULL) {
Com_Printf("Could not allocate audio ring buffer\n");
return qfalse;
}
dma_ptr = 0;
dma.buffer = dma_buffer;
if (!sio_start(hdl)) {
Com_Printf("Could not start audio\n");
sio_close(hdl);
return qfalse;
}

snd_inited = qtrue;
return qtrue;
}

void
SNDDMA_Shutdown(void)
{
if (snd_inited == qtrue) {
sio_close(hdl);
snd_inited = qfalse;
}
free(dma_buffer);
}

int
SNDDMA_GetDMAPos(void)
{
if (!snd_inited)
return (0);

return (dma_ptr / (dma.samplebits / 8));
}

void
SNDDMA_Submit(void)
{
struct pollfd pfd;
size_t count, todo, avail;
int n;

n = sio_pollfd(hdl, &pfd, POLLOUT);
while (poll(&pfd, n, 0) < 0 && errno == EINTR)
;
if (!(sio_revents(hdl, &pfd) & POLLOUT))
return;
avail = dma_buffer_size;
while (avail > 0) {
todo = dma_buffer_size - dma_ptr;
if (todo > avail)
todo = avail;
count = sio_write(hdl, dma_buffer + dma_ptr, todo);
if (count == 0)
break;
dma_ptr += count;
if (dma_ptr >= dma_buffer_size)
dma_ptr -= dma_buffer_size;
avail -= count;
}
}

void
SNDDMA_BeginPainting(void)
{
}
2 changes: 2 additions & 0 deletions code/qcommon/q_platform.h
Expand Up @@ -188,6 +188,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

#ifdef __i386__
#define ARCH_STRING "i386"
#elif defined __amd64__
#define ARCH_STRING "amd64"
#elif defined __axp__
#define ARCH_STRING "alpha"
#endif
Expand Down
5 changes: 5 additions & 0 deletions code/qcommon/vm_x86.c
Expand Up @@ -1081,7 +1081,12 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
// copy to an exact size buffer on the hunk
vm->codeLength = compiledOfs;
#ifdef VM_X86_MMAP
#if defined(__OpenBSD__)
// OpenBSD mmap(2) requires PROT_READ with PROT_WRITE
vm->codeBase = mmap(NULL, compiledOfs, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANON, -1, 0);
#else
vm->codeBase = mmap(NULL, compiledOfs, PROT_WRITE, MAP_SHARED|MAP_ANON, -1, 0);
#endif
if(vm->codeBase == (void*)-1)
Com_Error(ERR_DROP, "VM_CompileX86: can't mmap memory");
#elif _WIN32
Expand Down
7 changes: 6 additions & 1 deletion code/qcommon/vm_x86_64.c
Expand Up @@ -246,7 +246,7 @@ void emit(const char* fmt, ...)
#else
#define JMPIARG \
emit("movq $%lu, %%rax", vm->codeBase+vm->instructionPointers[iarg]); \
emit("jmpq *%rax");
emit("jmpq *%%rax");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also small asm fix that I believe is required for more platforms
than just OpenBSD, but I am too ignorant to know for sure :)
does this change fly for you on your platforms?

I can confirm the asm register fix is also needed for x86_64 on Mac OS X and FreeBSD, AFAIK it should be escaped, i'm guessing the only reason it worked at all on other platforms is because the compiler is more relaxed and coerced invalid operand references into a literal %

#endif

// integer compare and jump
Expand Down Expand Up @@ -534,7 +534,12 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
{
compiledOfs = assembler_get_code_size();
vm->codeLength = compiledOfs;
#if defined(__OpenBSD__)
// openbsd mmap(2) requires PROT_READ before PROT_WRITE
vm->codeBase = mmap(NULL, compiledOfs, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
#else
vm->codeBase = mmap(NULL, compiledOfs, PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
#endif
if(vm->codeBase == (void*)-1)
Com_Error(ERR_DROP, "VM_CompileX86: can't mmap memory");

Expand Down