From 13cce68a32e395935dc3c1a6c6137700efc8b022 Mon Sep 17 00:00:00 2001
From: Mikolaj 'lich' Halber <lich@opmbx.org>
Date: Tue, 9 Oct 2018 14:24:32 +0300
Subject: Added Haiku support


diff --git a/Makefile b/Makefile
index 3aae339..518791f 100644
--- a/Makefile
+++ b/Makefile
@@ -900,7 +900,53 @@ ifeq ($(PLATFORM),sunos)
   RENDERER_LIBS = $(SDL_LIBS) -lGL
 
 else # ifeq sunos
+#############################################################################
+# SETUP AND BUILD -- HAIKU
+#############################################################################
+ifeq ($(PLATFORM),haiku)
+
+  ifeq ($(shell uname -m), BePC)
+    ARCH=x86
+  endif
+
+  SHLIBEXT=so
+  SHLIBCFLAGS=-fPIC
+  SHLIBLDFLAGS=-shared $(LDFLAGS)
+  LDFLAGS=-lnetwork
+  BASE_CFLAGS = -Wall -fno-strict-aliasing -Wimplicit -Wstrict-prototypes -fPIC
+  CLIENT_CFLAGS =
+  CLIENT_CFLAGS += $(SDL_CFLAGS)
+  SERVER_CFLAGS =
+  LIB=
+  CLIENT_LIBS=$(SDL_LIBS) -lGL
+  USE_CODEC_VORBIS = 1
+  HAVE_VM_COMPILED=true
+
+  BUILD_CLIENT = 1
+  BUILD_GAME_QVM = 0
+  BASE_CFLAGS+=-D_BSD_SOURCE -DUSE_ICON
+  ifeq ($(USE_OPENAL),1)
+    CLIENT_CFLAGS += -DUSE_OPENAL
+    ifeq ($(USE_OPENAL_DLOPEN),1)
+      CLIENT_CFLAGS += -DUSE_OPENAL_DLOPEN
+    endif
+  endif
+
+  ifeq ($(USE_CURL),1)
+    CLIENT_CFLAGS += -DUSE_CURL
+    ifeq ($(USE_CURL_DLOPEN),1)
+      CLIENT_CFLAGS += -DUSE_CURL_DLOPEN
+    endif
+  endif
+
+
+  ifeq ($(USE_CODEC_VORBIS),1)
+    CLIENT_CFLAGS += -DUSE_CODEC_VORBIS
+    CLIENT_LIBS += -lvorbisfile -lvorbis -logg
+  endif
+
 
+else # ifeq haiku
 #############################################################################
 # SETUP AND BUILD -- GENERIC
 #############################################################################
@@ -919,6 +965,7 @@ endif #OpenBSD
 endif #NetBSD
 endif #IRIX
 endif #SunOS
+endif #haiku
 
 ifndef CC
   CC=gcc
diff --git a/code/qcommon/net_ip.c b/code/qcommon/net_ip.c
index 4ef3e34..0ea922e 100644
--- a/code/qcommon/net_ip.c
+++ b/code/qcommon/net_ip.c
@@ -1268,7 +1268,7 @@ static void NET_AddLocalAddress(char *ifname, struct sockaddr *addr, struct sock
 	}
 }
 
-#if defined(__linux__) || defined(MACOSX) || defined(__BSD__)
+#if defined(__linux__) || defined(MACOSX) || defined(__BSD__) || defined(__HAIKU__)
 static void NET_GetLocalAddress(void)
 {
 	struct ifaddrs *ifap, *search;
diff --git a/code/qcommon/q_platform.h b/code/qcommon/q_platform.h
index 999dd39..9f89ab8 100644
--- a/code/qcommon/q_platform.h
+++ b/code/qcommon/q_platform.h
@@ -324,6 +324,29 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
 #endif
 
+//================================================================== HAIKU ===
+
+#ifdef __HAIKU__
+
+#include <endian.h>
+#define OS_STRING "HAIKU"
+#define ID_INLINE inline
+#define PATH_SEP '/'
+
+#ifdef __i386__
+#define ARCH_STRING "x86"
+#elif defined __amd64__
+#undef idx64
+#define idx64 1
+#define ARCH_STRING "x86_64"
+#endif
+
+#define Q3_LITTLE_ENDIAN // HAIKU's i386 are always little endian
+
+#define DLL_EXT ".so"
+
+#endif
+
 //===========================================================================
 
 //catch missing defines in above blocks
diff --git a/code/sys/sys_unix.c b/code/sys/sys_unix.c
index d11ecf6..43f4d15 100644
--- a/code/sys/sys_unix.c
+++ b/code/sys/sys_unix.c
@@ -964,7 +964,7 @@ void Sys_PlatformInit( void )
 	signal( SIGHUP, Sys_SigHandler );
 	signal( SIGQUIT, Sys_SigHandler );
 	signal( SIGTRAP, Sys_SigHandler );
-	signal( SIGIOT, Sys_SigHandler );
+	signal( SIGABRT, Sys_SigHandler );
 	signal( SIGBUS, Sys_SigHandler );
 
 	stdinIsATTY = isatty( STDIN_FILENO ) &&
-- 
2.26.0


From 1926d31270fb4097d7f076e990cc47d87defbb8d Mon Sep 17 00:00:00 2001
From: Gerasim Troeglazov <3dEyes@gmail.com>
Date: Wed, 20 May 2020 17:19:16 +1000
Subject: Fix settings dir


diff --git a/code/sys/sys_unix.c b/code/sys/sys_unix.c
index 43f4d15..da2a148 100644
--- a/code/sys/sys_unix.c
+++ b/code/sys/sys_unix.c
@@ -193,6 +193,14 @@ const char *Sys_DefaultHomePath(void)
 			Q_strcat(homePath, sizeof(homePath),
 				"Library/Application Support/");
 
+			if(com_homepath->string[0])
+				Q_strcat(homePath, sizeof(homePath), com_homepath->string);
+			else
+				Q_strcat(homePath, sizeof(homePath), HOMEPATH_NAME_MACOSX);
+#elif defined(__HAIKU__)
+			Q_strcat(homePath, sizeof(homePath),
+				"config/settings/");
+
 			if(com_homepath->string[0])
 				Q_strcat(homePath, sizeof(homePath), com_homepath->string);
 			else
@@ -207,6 +215,7 @@ const char *Sys_DefaultHomePath(void)
 	return homePath;
 }
 
+
 /*
 ================
 Sys_Milliseconds
@@ -252,6 +261,8 @@ qboolean Sys_RandomBytes( byte *string, int len )
 	if( !fp )
 		return qfalse;
 
+	setvbuf( fp, NULL, _IONBF, 0 ); // don't buffer reads from /dev/urandom
+
 	if( fread( string, sizeof( byte ), len, fp ) != len )
 	{
 		fclose( fp );
@@ -277,16 +288,6 @@ char *Sys_GetCurrentUser( void )
 	return p->pw_name;
 }
 
-/*
-==================
-Sys_GetClipboardData
-==================
-*/
-char *Sys_GetClipboardData(void)
-{
-	return NULL;
-}
-
 #define MEM_THRESHOLD 96*1024*1024
 
 /*
@@ -336,6 +337,16 @@ FILE *Sys_FOpen( const char *ospath, const char *mode ) {
 	return fopen( ospath, mode );
 }
 
+/*
+==================
+Sys_GetClipboardData
+==================
+*/
+char *Sys_GetClipboardData(void)
+{
+	return NULL;
+}
+
 /*
 ==================
 Sys_Mkdir
@@ -343,6 +354,12 @@ Sys_Mkdir
 */
 qboolean Sys_Mkdir( const char *path )
 {
+#ifdef __HAIKU__
+	struct stat buff;
+	if (stat(path, &buff) == 0)
+		if (S_ISDIR(buff.st_mode))
+			return qtrue;
+#endif
 	int result = mkdir( path, 0750 );
 
 	if( result != 0 )
@@ -858,6 +875,7 @@ dialogResult_t Sys_Dialog( dialogType_t type, const char *message, const char *t
 	qboolean                tried[ NUM_DIALOG_PROGRAMS ] = { qfalse };
 	dialogCommandBuilder_t  commands[ NUM_DIALOG_PROGRAMS ] = { NULL };
 	dialogCommandType_t     preferredCommandType = NONE;
+	int                     i;
 
 	commands[ ZENITY ] = &Sys_ZenityCommand;
 	commands[ KDIALOG ] = &Sys_KdialogCommand;
@@ -869,50 +887,37 @@ dialogResult_t Sys_Dialog( dialogType_t type, const char *message, const char *t
 	else if( !Q_stricmp( session, "kde" ) )
 		preferredCommandType = KDIALOG;
 
-	while( 1 )
+	for( i = NONE + 1; i < NUM_DIALOG_PROGRAMS; i++ )
 	{
-		int i;
+		if( preferredCommandType != NONE && preferredCommandType != i )
+			continue;
 
-		for( i = NONE + 1; i < NUM_DIALOG_PROGRAMS; i++ )
+		if( !tried[ i ] )
 		{
-			if( preferredCommandType != NONE && preferredCommandType != i )
-				continue;
-
-			if( !tried[ i ] )
-			{
-				int exitCode;
+			int exitCode;
 
-				commands[ i ]( type, message, title );
-				exitCode = Sys_Exec( );
+			commands[ i ]( type, message, title );
+			exitCode = Sys_Exec( );
 
-				if( exitCode >= 0 )
+			if( exitCode >= 0 )
+			{
+				switch( type )
 				{
-					switch( type )
-					{
-						case DT_YES_NO:    return exitCode ? DR_NO : DR_YES;
-						case DT_OK_CANCEL: return exitCode ? DR_CANCEL : DR_OK;
-						default:           return DR_OK;
-					}
+					case DT_YES_NO:    return exitCode ? DR_NO : DR_YES;
+					case DT_OK_CANCEL: return exitCode ? DR_CANCEL : DR_OK;
+					default:           return DR_OK;
 				}
+			}
 
-				tried[ i ] = qtrue;
+			tried[ i ] = qtrue;
 
-				// The preference failed, so start again in order
-				if( preferredCommandType != NONE )
-				{
-					preferredCommandType = NONE;
-					break;
-				}
+			// The preference failed, so start again in order
+			if( preferredCommandType != NONE )
+			{
+				preferredCommandType = NONE;
+				i = NONE + 1;
 			}
 		}
-
-		for( i = NONE + 1; i < NUM_DIALOG_PROGRAMS; i++ )
-		{
-			if( !tried[ i ] )
-				continue;
-		}
-
-		break;
 	}
 
 	Com_DPrintf( S_COLOR_YELLOW "WARNING: failed to show a dialog\n" );
@@ -967,6 +972,8 @@ void Sys_PlatformInit( void )
 	signal( SIGABRT, Sys_SigHandler );
 	signal( SIGBUS, Sys_SigHandler );
 
+	Sys_SetFloatEnv();
+
 	stdinIsATTY = isatty( STDIN_FILENO ) &&
 		!( term && ( !strcmp( term, "raw" ) || !strcmp( term, "dumb" ) ) );
 }
-- 
2.26.0


From 2673d4a2987544b7f3c98be4a12f6a7fa96422a7 Mon Sep 17 00:00:00 2001
From: Gerasim Troeglazov <3dEyes@gmail.com>
Date: Wed, 20 May 2020 22:03:56 +1000
Subject: Don't disable video subsystem when shutdown


diff --git a/code/sdl/sdl_glimp.c b/code/sdl/sdl_glimp.c
index a931e81..92632e8 100644
--- a/code/sdl/sdl_glimp.c
+++ b/code/sdl/sdl_glimp.c
@@ -98,8 +98,9 @@ GLimp_Shutdown
 void GLimp_Shutdown( void )
 {
 	ri.IN_Shutdown();
-
+#ifndef __HAIKU__
 	SDL_QuitSubSystem( SDL_INIT_VIDEO );
+#endif
 	screen = NULL;
 }
 
-- 
2.26.0


From e01e6b0ac9f02e88761d4162f29502d302975754 Mon Sep 17 00:00:00 2001
From: Gerasim Troeglazov <3dEyes@gmail.com>
Date: Thu, 21 May 2020 23:22:15 +1000
Subject: Add fake fullscreen mode


diff --git a/code/sdl/sdl_glimp.c b/code/sdl/sdl_glimp.c
index 92632e8..2398582 100644
--- a/code/sdl/sdl_glimp.c
+++ b/code/sdl/sdl_glimp.c
@@ -58,6 +58,11 @@ float tvAspectW;	// leilei - for aspect correction
 //int vresWidth;		
 //int vresHeight;		
 
+#ifdef __HAIKU__
+static int lastWinWidth = -1;
+static int lastWinHeight = -1;
+#endif
+
 
 typedef enum
 {
@@ -281,6 +286,34 @@ static int GLimp_SetMode(int mode, qboolean fullscreen, qboolean noborder)
 	}
 	ri.Printf( PRINT_ALL, " %d %d\n", glConfig.vidWidth, glConfig.vidHeight);
 
+#ifdef __HAIKU__
+	// Use fake fullscreen mode for Haiku
+	if (fullscreen)
+	{
+		flags |= SDL_NOFRAME;
+		glConfig.isFullscreen = qfalse;
+		glConfig.vidWidth = videoInfo->current_w;
+		glConfig.vidHeight = videoInfo->current_h;
+		glConfig.windowAspect = (float)glConfig.vidWidth / (float)glConfig.vidHeight;
+	}
+	else
+	{
+		if (noborder)
+			flags |= SDL_NOFRAME;
+		if (lastWinWidth <= 0 || lastWinHeight <= 0) {
+			lastWinWidth = glConfig.vidWidth;
+			lastWinHeight = glConfig.vidHeight;
+		}
+		if (lastWinWidth >= videoInfo->current_w || lastWinHeight >= videoInfo->current_h) {
+			lastWinWidth = 800;
+			lastWinHeight = 600;
+		}
+		glConfig.vidWidth = lastWinWidth;
+		glConfig.vidHeight = lastWinHeight;
+		glConfig.isFullscreen = qfalse;
+		glConfig.windowAspect = (float)glConfig.vidWidth / (float)glConfig.vidHeight;
+	}
+#else
 	if (fullscreen)
 	{
 		flags |= SDL_FULLSCREEN;
@@ -293,6 +326,7 @@ static int GLimp_SetMode(int mode, qboolean fullscreen, qboolean noborder)
 
 		glConfig.isFullscreen = qfalse;
 	}
+#endif
 
 	colorbits = r_colorbits->value;
 	if ((!colorbits) || (colorbits >= 32))
@@ -446,8 +480,11 @@ static int GLimp_SetMode(int mode, qboolean fullscreen, qboolean noborder)
 
 		SDL_WM_SetCaption(CLIENT_WINDOW_TITLE, CLIENT_WINDOW_MIN_TITLE);
 		SDL_ShowCursor(0);
-
+#ifdef __HAIKU__
+		if (!(vidscreen = SDL_SetVideoMode(glConfig.vidWidth + 1, glConfig.vidHeight + 1, colorbits, flags)))
+#else
 		if (!(vidscreen = SDL_SetVideoMode(glConfig.vidWidth, glConfig.vidHeight, colorbits, flags)))
+#endif
 		{
 			ri.Printf( PRINT_DEVELOPER, "SDL_SetVideoMode failed: %s\n", SDL_GetError( ) );
 			continue;
@@ -788,7 +825,11 @@ void GLimp_Init( void )
 	r_allowSoftwareGL = ri.Cvar_Get( "r_allowSoftwareGL", "0", CVAR_LATCH );
 	r_sdlDriver = ri.Cvar_Get( "r_sdlDriver", "", CVAR_ROM );
 	r_allowResize = ri.Cvar_Get( "r_allowResize", "0", CVAR_ARCHIVE | CVAR_LATCH );
+#ifdef __HAIKU__
+	r_centerWindow = ri.Cvar_Get( "r_centerWindow", "1", CVAR_ARCHIVE | CVAR_LATCH );
+#else
 	r_centerWindow = ri.Cvar_Get( "r_centerWindow", "0", CVAR_ARCHIVE | CVAR_LATCH );
+#endif
 // leilei - tv mode hack
 	r_tvMode = ri.Cvar_Get( "r_virtualMode", "-1", CVAR_LATCH | CVAR_ARCHIVE );
 	r_tvModeAspect = ri.Cvar_Get( "r_tvModeAspect", "0", CVAR_LATCH | CVAR_ARCHIVE ); // yes
@@ -905,7 +946,11 @@ void GLimp_EndFrame( void )
 		qboolean    needToToggle = qtrue;
 		qboolean    sdlToggled = qfalse;
 		SDL_Surface *s = SDL_GetVideoSurface( );
-
+#ifdef __HAIKU__
+		// Don't set real fullscren mode for Haiku (only restart)
+		ri.Cmd_ExecuteText(EXEC_APPEND, "vid_restart\n");
+		ri.IN_Restart( );
+#else
 		if( s )
 		{
 			// Find out the current state
@@ -933,7 +978,7 @@ void GLimp_EndFrame( void )
 
 			ri.IN_Restart( );
 		}
-
+#endif
 		r_fullscreen->modified = qfalse;
 	}
 }
-- 
2.26.0


From cf8f58eca19a9347f0b406efda80a7fc4492d84c Mon Sep 17 00:00:00 2001
From: Gerasim Troeglazov <3dEyes@gmail.com>
Date: Thu, 21 May 2020 23:34:03 +1000
Subject: Resolve symlink for argv[0]


diff --git a/code/sys/sys_main.c b/code/sys/sys_main.c
index cfaab69..86724ed 100644
--- a/code/sys/sys_main.c
+++ b/code/sys/sys_main.c
@@ -591,6 +591,12 @@ int main( int argc, char **argv )
 	int   i;
 	char  commandLine[ MAX_STRING_CHARS ] = { 0 };
 
+#ifdef __HAIKU__
+	char *binpath = realpath(argv[0], NULL);
+	if (binpath != NULL)
+		argv[0] = binpath;
+#endif
+
 #ifndef DEDICATED
 	// SDL version check
 
-- 
2.26.0

