From 23af82c2a4a458ef8d0bbbfbe8cda2305f85a3b1 Mon Sep 17 00:00:00 2001
From: Gerasim Troeglazov <3dEyes@gmail.com>
Date: Tue, 7 Sep 2021 15:06:51 +1000
Subject: Fix build for Haiku


diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt
index 2be4e6b..db67d01 100644
--- a/data/CMakeLists.txt
+++ b/data/CMakeLists.txt
@@ -1,5 +1,6 @@
-
+if(NOT HAIKU)
 include(Icons)
+endif()
 
 set(ICON_BINARY_DIR "${PROJECT_BINARY_DIR}/data.generated/icons")
 set(ICON_SOURCE_DIRS "${PROJECT_SOURCE_DIR}/data/icons")
@@ -107,6 +108,7 @@ set(overview_sizes
 	512
 )
 
+if(NOT HAIKU)
 add_icon(arx-libertatis
 	arx-libertatis.svg    1024
 	arx-libertatis-32.svg 32@2x 512
@@ -120,6 +122,7 @@ add_icon(arx-libertatis
 )
 
 add_icon(TARGET arx-libertatis-logo arx-libertatis-logo.svg 58 3080x512)
+endif()
 
 add_custom_target(data DEPENDS
 	arx-libertatis-icon
diff --git a/src/audio/openal/OpenALSource.cpp b/src/audio/openal/OpenALSource.cpp
index de0f8e2..879246b 100644
--- a/src/audio/openal/OpenALSource.cpp
+++ b/src/audio/openal/OpenALSource.cpp
@@ -311,13 +311,15 @@ aalError OpenALSource::fillBuffer(size_t i, size_t size) {
 	
 	TraceAL("filling buffer " << m_buffers[i] << " with " << size << " bytes");
 	
-	char data[StreamLimitBytes * NBUFFERS];
-	
-	arx_assert(size <= sizeof(data));
+	char * data = new char[size];
+	if(!data) {
+		return AAL_ERROR_MEMORY;
+	}
 	
 	size_t read;
 	m_stream->read(data, left, read);
 	if(read != left) {
+		delete[] data;
 		return AAL_ERROR_SYSTEM;
 	}
 	m_written += read;
@@ -332,6 +334,7 @@ aalError OpenALSource::fillBuffer(size_t i, size_t size) {
 			if(size > left) {
 				m_stream->read(data + left, size - left, read);
 				if(read != size - left) {
+					delete[] data;
 					return AAL_ERROR_SYSTEM;
 				}
 				m_written += read;
@@ -343,6 +346,7 @@ aalError OpenALSource::fillBuffer(size_t i, size_t size) {
 	const PCMFormat & f = m_sample->getFormat();
 	if((f.channels != 1 && f.channels != 2) || (f.quality != 8 && f.quality != 16)) {
 		LogError << "Unsupported audio format: quality=" << f.quality << " channels=" << f.channels;
+		delete[] data;
 		return AAL_ERROR_SYSTEM;
 	}
 	
@@ -359,6 +363,7 @@ aalError OpenALSource::fillBuffer(size_t i, size_t size) {
 	}
 	
 	alBufferData(m_buffers[i], alformat, data, alsize, f.frequency);
+	delete[] data;
 	AL_CHECK_ERROR("setting buffer data")
 	
 	m_bufferSizes[i] = size;
diff --git a/src/core/Config.cpp b/src/core/Config.cpp
index f61ac29..848d2d8 100644
--- a/src/core/Config.cpp
+++ b/src/core/Config.cpp
@@ -83,7 +83,11 @@ const int
 	quickLevelTransition = JumpToChangeLevel;
 
 const bool
+#if ARX_PLATFORM == ARX_PLATFORM_HAIKU
+	fullscreen = false,
+#else
 	fullscreen = true,
+#endif
 	viewBobbing = true,
 	screenShake = true,
 	showCrosshair = true,
@@ -449,6 +453,10 @@ bool Config::save() {
 	// video
 	writer.beginSection(Section::Video);
 	writer.writeKey(Key::renderer, video.renderer);
+#if ARX_PLATFORM == ARX_PLATFORM_HAIKU
+	writer.writeKey(Key::resolution, Default::resolution);
+	writer.writeKey(Key::fullscreen, false);
+#else
 	if(video.mode.resolution == Vec2i(0)) {
 		writer.writeKey(Key::resolution, Default::resolution);
 	} else {
@@ -458,6 +466,7 @@ bool Config::save() {
 	}
 	writer.writeKey(Key::refreshRate, int(video.mode.refresh));
 	writer.writeKey(Key::fullscreen, video.fullscreen);
+#endif
 	writer.writeKey(Key::levelOfDetail, video.levelOfDetail);
 	writer.writeKey(Key::fogDistance, video.fogDistance);
 	writer.writeKey(Key::gamma, video.gamma);
@@ -599,6 +608,10 @@ bool Config::init(const fs::path & file) {
 	
 	// Get video settings
 	video.renderer = reader.getKey(Section::Video, Key::renderer, Default::renderer);
+#if ARX_PLATFORM == ARX_PLATFORM_HAIKU
+	video.mode.resolution = Vec2i(0);
+	video.fullscreen = false;
+#else
 	std::string resolution = reader.getKey(Section::Video, Key::resolution, Default::resolution);
 	if(resolution == "auto") {
 		video.mode.resolution = Vec2i(0);
@@ -607,6 +620,7 @@ bool Config::init(const fs::path & file) {
 	}
 	video.mode.refresh = reader.getKey(Section::Video, Key::refreshRate, Default::refreshRate);
 	video.fullscreen = reader.getKey(Section::Video, Key::fullscreen, Default::fullscreen);
+#endif
 	video.levelOfDetail = reader.getKey(Section::Video, Key::levelOfDetail, Default::levelOfDetail);
 	video.fogDistance = reader.getKey(Section::Video, Key::fogDistance, Default::fogDistance);
 	video.gamma = reader.getKey(Section::Video, Key::gamma, Default::gamma);
diff --git a/src/core/Startup.cpp b/src/core/Startup.cpp
index 992da02..e0f2f07 100644
--- a/src/core/Startup.cpp
+++ b/src/core/Startup.cpp
@@ -175,5 +175,7 @@ int utf8_main(int argc, char ** argv) {
 	
 	Random::shutdown();
 	
+	kill(::getpid(), SIGKILL);
+	
 	return (status == ExitFailure) ? EXIT_FAILURE : EXIT_SUCCESS;
 }
diff --git a/src/graphics/opengl/OpenGLRenderer.cpp b/src/graphics/opengl/OpenGLRenderer.cpp
index d362674..f2f7873 100644
--- a/src/graphics/opengl/OpenGLRenderer.cpp
+++ b/src/graphics/opengl/OpenGLRenderer.cpp
@@ -328,7 +328,7 @@ void OpenGLRenderer::initialize() {
 
 void OpenGLRenderer::beforeResize(bool wasOrIsFullscreen) {
 	
-#if ARX_PLATFORM == ARX_PLATFORM_LINUX || ARX_PLATFORM == ARX_PLATFORM_BSD
+#if ARX_PLATFORM == ARX_PLATFORM_LINUX || ARX_PLATFORM == ARX_PLATFORM_BSD || ARX_PLATFORM == ARX_PLATFORM_HAIKU
 	// No re-initialization needed
 	ARX_UNUSED(wasOrIsFullscreen);
 #else
diff --git a/src/platform/OS.cpp b/src/platform/OS.cpp
index 631da70..4ea510d 100644
--- a/src/platform/OS.cpp
+++ b/src/platform/OS.cpp
@@ -211,6 +211,8 @@ std::string getOSName() {
 	return "macOS";
 	#elif ARX_PLATFORM == ARX_PLATFORM_BSD
 	return "BSD";
+	#elif ARX_PLATFORM == ARX_PLATFORM_HAIKU
+	return "Haiku";
 	#elif ARX_PLATFORM == ARX_PLATFORM_UNIX
 	return "UNIX";
 	#else
diff --git a/src/platform/Platform.h b/src/platform/Platform.h
index 686e93b..8c4f4fb 100644
--- a/src/platform/Platform.h
+++ b/src/platform/Platform.h
@@ -36,6 +36,7 @@
 #define ARX_PLATFORM_WIN32   1
 #define ARX_PLATFORM_LINUX   2
 #define ARX_PLATFORM_MACOS   3
+#define ARX_PLATFORM_HAIKU   4
 #define ARX_PLATFORM_BSD     100 // Generic BSD system
 #define ARX_PLATFORM_UNIX    101 // Generic UNIX system
 
@@ -45,6 +46,8 @@
 	#define ARX_PLATFORM ARX_PLATFORM_WIN32
 #elif defined(__MACH__)
 	#define ARX_PLATFORM ARX_PLATFORM_MACOS
+#elif defined(__HAIKU__)
+	#define ARX_PLATFORM ARX_PLATFORM_HAIKU
 #elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) \
       || defined(__bsdi__) || defined(__DragonFly__)
 	#define ARX_PLATFORM ARX_PLATFORM_BSD
diff --git a/src/platform/Thread.cpp b/src/platform/Thread.cpp
index 002f7ce..f217491 100644
--- a/src/platform/Thread.cpp
+++ b/src/platform/Thread.cpp
@@ -41,6 +41,10 @@
 #include ARX_INCLUDED_CPUID_H
 #endif
 
+#if ARX_PLATFORM == ARX_PLATFORM_HAIKU
+#include <OS.h>
+#endif
+
 #include <boost/static_assert.hpp>
 
 #include "math/Random.h"
@@ -144,6 +148,9 @@ void * Thread::entryPoint(void * param) {
 	#elif ARX_HAVE_PRCTL && defined(PR_SET_NAME)
 	// Linux
 	prctl(PR_SET_NAME, reinterpret_cast<unsigned long>(thread.m_threadName.c_str()), 0, 0, 0);
+	#elif ARX_PLATFORM == ARX_PLATFORM_HAIKU
+	// Haiku	
+	rename_thread(get_pthread_thread_id(thread.m_thread), thread.m_threadName.c_str());
 	#else
 	// This is non-fatal, but let's print a warning so future ports will be
 	// reminded to implement it.
diff --git a/src/window/SDL2Window.cpp b/src/window/SDL2Window.cpp
index 64bc597..4656ae3 100644
--- a/src/window/SDL2Window.cpp
+++ b/src/window/SDL2Window.cpp
@@ -87,6 +87,7 @@ SDL2Window::SDL2Window()
 
 SDL2Window::~SDL2Window() {
 	
+#if ARX_PLATFORM != ARX_PLATFORM_HAIKU
 	delete m_input;
 	
 	if(m_renderer) {
@@ -105,6 +106,7 @@ SDL2Window::~SDL2Window() {
 	if(s_mainWindow) {
 		SDL_Quit(), s_mainWindow = NULL;
 	}
+#endif
 	
 }
 
@@ -206,6 +208,7 @@ bool SDL2Window::initializeFramework() {
 	}
 	#endif
 	
+	#if ARX_PLATFORM != ARX_PLATFORM_HAIKU
 	int ndisplays = SDL_GetNumVideoDisplays();
 	for(int display = 0; display < ndisplays; display++) {
 		int modes = SDL_GetNumDisplayModes(display);
@@ -220,6 +223,7 @@ bool SDL2Window::initializeFramework() {
 	std::sort(m_displayModes.begin(), m_displayModes.end());
 	m_displayModes.erase(std::unique(m_displayModes.begin(), m_displayModes.end()),
 	                     m_displayModes.end());
+	#endif
 	
 	s_mainWindow = this;
 	
@@ -255,6 +259,9 @@ int SDL2Window::createWindowAndGLContext(const char * profile) {
 	Uint32 windowFlags = getSDLFlagsForMode(m_mode.resolution, m_fullscreen);
 	windowFlags |= SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN;
 	
+#if ARX_PLATFORM == ARX_PLATFORM_HAIKU
+       m_maxMSAALevel = 1;
+#endif
 	for(int msaa = m_maxMSAALevel; true; msaa--) {
 		bool lastTry = (msaa == 0);
 		
diff --git a/src/window/SDL2X11Util.c b/src/window/SDL2X11Util.c
index 72ab23b..21f495f 100644
--- a/src/window/SDL2X11Util.c
+++ b/src/window/SDL2X11Util.c
@@ -26,7 +26,9 @@
 #define ARX_STATIC_ASSERT(Cond, Msg) typedef char static_assertion_ ## Msg[(Cond) ? 1 : -1]
 
 uint64_t SDL2X11_getNativeWindowHandle(SDL_Window * window) {
-	
+#if ARX_PLATFORM == ARX_PLATFORM_HAIKU
+	return 0;
+#else
 	/*
 	 * The size of the SDL_SysWMinfo structure depends on the build-time configuration of SDL.
 	 * If Arx is built with a SDL install that was configured without Wayland, but is run on
@@ -49,4 +51,5 @@ uint64_t SDL2X11_getNativeWindowHandle(SDL_Window * window) {
 	}
 	
 	return info.data.info.x11.window;
+#endif
 }
diff --git a/src/window/SDL2X11Util.h b/src/window/SDL2X11Util.h
index b9432e4..dee2d87 100644
--- a/src/window/SDL2X11Util.h
+++ b/src/window/SDL2X11Util.h
@@ -27,9 +27,9 @@
 #ifdef __cplusplus
 extern "C" {
 #endif
-
+#if ARX_PLATFORM != ARX_PLATFORM_HAIKU
 uint64_t SDL2X11_getNativeWindowHandle(SDL_Window * window);
-
+#endif
 #ifdef __cplusplus
 } // extern "C"
 #endif
-- 
2.30.2

