From dd85f3dde34513315bdcdfb0c6635f90097c6058 Mon Sep 17 00:00:00 2001
From: Crestwave <crest.wave@yahoo.com>
Date: Sat, 7 Aug 2021 09:22:11 +0800
Subject: [PATCH] fix: add support for Haiku

---
 source/Makefile     |  6 ++++++
 source/crash.cc     |  2 ++
 source/endianness.h |  4 ++++
 source/files.cc     | 30 +++++++++++++++++++++++++++++-
 source/initfile.cc  | 18 ++++++++++++++++++
 5 files changed, 59 insertions(+), 1 deletion(-)

diff --git a/source/Makefile b/source/Makefile
index eb65f6d..29e9342 100644
--- a/source/Makefile
+++ b/source/Makefile
@@ -382,9 +382,11 @@ ifdef WIN32
 EXTRA_OBJECTS += icon.o
 else
 ifndef ANDROID
+ifneq ($(uname_S),Haiku)
 EXTRA_LIBS += -pthread
 endif
 endif
+endif
 
 ifndef TILES
 ifdef NEED_LIBW32C
@@ -799,6 +801,10 @@ ifneq ($(SRC_BRANCH),$(filter master release stone_soup-%, $(SRC_BRANCH)))
 endif
 endif
 
+ifdef HAIKU_HYBRID_SECONDARY
+DEFINES_L += -DHAIKU_HYBRID_SECONDARY="\"$(HAIKU_HYBRID_SECONDARY)\""
+endif
+
 #
 # Figure out the build settings for this type of build
 #
diff --git a/source/crash.cc b/source/crash.cc
index 7b4f65d..76a5fc6 100644
--- a/source/crash.cc
+++ b/source/crash.cc
@@ -10,8 +10,10 @@
 #if defined(UNIX)
 #include <unistd.h>
 #include <sys/param.h>
+#ifndef __HAIKU__
         #define BACKTRACE_SUPPORTED
 #endif
+#endif
 
 #ifdef USE_UNIX_SIGNALS
 #include <sys/time.h>
diff --git a/source/endianness.h b/source/endianness.h
index 30b8644..881a78c 100644
--- a/source/endianness.h
+++ b/source/endianness.h
@@ -18,6 +18,10 @@
 # endif
 #endif
 
+#ifdef __HAIKU__
+#include <endian.h>
+#endif
+
 #ifndef htole32
  #if BYTE_ORDER == LITTLE_ENDIAN
   #define htole32(x) (x)
diff --git a/source/files.cc b/source/files.cc
index 9f7a2e6..14b33bc 100644
--- a/source/files.cc
+++ b/source/files.cc
@@ -105,6 +105,10 @@
 #define F_OK 0
 #endif
 
+#ifdef __HAIKU__
+#include <FindDirectory.h>
+#endif
+
 #define BONES_DIAGNOSTICS (defined(WIZARD) || defined(DEBUG_BONES) || defined(DEBUG_DIAGNOSTICS))
 
 #ifdef BONES_DIAGNOSTICS
@@ -354,7 +358,7 @@ static bool _create_directory(const char *dir)
 {
     if (!mkdir_u(dir, 0755))
         return true;
-    if (errno == EEXIST) // might be not a directory
+    if (errno == EEXIST || errno == EROFS) // might be not a directory
         return dir_exists(dir);
     return false;
 }
@@ -417,6 +421,22 @@ string canonicalise_file_separator(const string &path)
 
 static vector<string> _get_base_dirs()
 {
+#ifdef __HAIKU__
+    char data_path[B_PATH_NAME_LENGTH];
+    char docs_path[B_PATH_NAME_LENGTH];
+
+    find_path(B_APP_IMAGE_SYMBOL,
+            B_FIND_PATH_DATA_DIRECTORY,
+            "crawl/",
+            data_path,
+            B_PATH_NAME_LENGTH);
+
+    find_path(B_APP_IMAGE_SYMBOL,
+            B_FIND_PATH_DOCUMENTATION_DIRECTORY,
+            "packages/crawl",
+            docs_path,
+            B_PATH_NAME_LENGTH);
+#endif
     const string rawbases[] =
     {
 #ifdef DATA_DIR_PATH
@@ -431,6 +451,14 @@ static vector<string> _get_base_dirs()
 #ifdef __ANDROID__
         ANDROID_ASSETS,
         "/sdcard/Android/data/org.develz.crawl/files/",
+#endif
+#ifdef __HAIKU__
+        std::string(data_path),
+#ifdef HAIKU_HYBRID_SECONDARY
+        std::string(docs_path) + "_" + HAIKU_HYBRID_SECONDARY + FILE_SEPARATOR,
+#else
+        std::string(docs_path) + FILE_SEPARATOR,
+#endif
 #endif
     };
 
diff --git a/source/initfile.cc b/source/initfile.cc
index 94f76ff..7491eb4 100644
--- a/source/initfile.cc
+++ b/source/initfile.cc
@@ -95,6 +95,10 @@ extern char **NXArgv;
 #include <unistd.h>
 #endif
 
+#ifdef __HAIKU__
+#include <FindDirectory.h>
+#endif
+
 const string game_options::interrupt_prefix = "interrupt_";
 system_environment SysEnv;
 
@@ -4019,6 +4023,20 @@ void get_system_environment()
     }
 #endif
 
+#ifdef __HAIKU__
+    if (SysEnv.crawl_dir.empty())
+    {
+        char path[B_PATH_NAME_LENGTH];
+        find_directory(B_USER_SETTINGS_DIRECTORY,
+                        0,
+                        false,
+                        path,
+                        B_PATH_NAME_LENGTH);
+
+        SysEnv.crawl_dir = catpath(std::string(path), "/crawl");
+    }
+#endif
+
 #ifdef SAVE_DIR_PATH
     if (SysEnv.crawl_dir.empty())
         SysEnv.crawl_dir = SAVE_DIR_PATH;
-- 
2.30.2

