From 27ce5b3b824c1bc9516bf0ec16d10ef2ad85c941 Mon Sep 17 00:00:00 2001
From: Gerasim Troeglazov <3dEyes@gmail.com>
Date: Sun, 26 Sep 2021 14:31:33 +1000
Subject: Add Haiku support


diff --git a/CMakeLists.txt b/CMakeLists.txt
index 700d37b..2d41f24 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -61,6 +61,7 @@ if("${CMAKE_SYSTEM_NAME}" MATCHES "Windows")
     set(PLATFORM_LINUX   0)
     set(PLATFORM_MACOSX  0)
     set(PLATFORM_FREEBSD 0)
+    set(PLATFORM_HAIKU   0)
     set(PLATFORM_OTHER   0)
 
     # Platform-dependent implementation of system.h
@@ -73,11 +74,25 @@ elseif("${CMAKE_SYSTEM_NAME}" MATCHES "Linux")
     set(PLATFORM_GNU     1)
     set(PLATFORM_MACOSX  0)
     set(PLATFORM_FREEBSD 0)
+    set(PLATFORM_HAIKU   0)
     set(PLATFORM_OTHER   0)
 
     # Platform-dependent implementation of system.h
     set(SYSTEM_CPP_MODULE "system_linux.cpp")
     set(SYSTEM_H_MODULE "system_linux.h")
+elseif("${CMAKE_SYSTEM_NAME}" MATCHES "Haiku")
+    message(STATUS "Build for Haiku")
+    set(PLATFORM_WINDOWS 0)
+    set(PLATFORM_LINUX   0)
+    set(PLATFORM_GNU     0)
+    set(PLATFORM_MACOSX  0)
+    set(PLATFORM_FREEBSD 0)
+    set(PLATFORM_HAIKU   1)
+    set(PLATFORM_OTHER   0)    
+
+    # Platform-dependent implementation of system.h
+    set(SYSTEM_CPP_MODULE "system_haiku.cpp")
+    set(SYSTEM_H_MODULE "system_haiku.h")
 elseif("${CMAKE_SYSTEM_NAME}" MATCHES "kFreeBSD" OR "${CMAKE_SYSTEM_NAME}" STREQUAL "GNU")
     message(STATUS "Build for kFreeBSD system")
     set(PLATFORM_WINDOWS 0)
@@ -85,6 +100,7 @@ elseif("${CMAKE_SYSTEM_NAME}" MATCHES "kFreeBSD" OR "${CMAKE_SYSTEM_NAME}" STREQ
     set(PLATFORM_GNU     1)
     set(PLATFORM_MACOSX  0)
     set(PLATFORM_FREEBSD 0)
+    set(PLATFORM_HAIKU   0)
     set(PLATFORM_OTHER   0)
 
     # Platform-dependent implementation of system.h
@@ -96,6 +112,7 @@ elseif("${CMAKE_SYSTEM_NAME}" MATCHES "Darwin")
     set(PLATFORM_LINUX   0)
     set(PLATFORM_GNU     0)
     set(PLATFORM_MACOSX  1)
+    set(PLATFORM_HAIKU   0)
     set(PLATFORM_OTHER   0)
     set(PLATFORM_FREEBSD 0)
 
@@ -111,6 +128,7 @@ elseif("${CMAKE_SYSTEM_NAME}" MATCHES "FreeBSD")
     set(PLATFORM_GNU     0)
     set(PLATFORM_MACOSX  0)
     set(PLATFORM_FREEBSD 1)
+    set(PLATFORM_HAIKU   0)
     set(PLATFORM_OTHER   0)
 
     # Platform-dependent implementation of system.h
@@ -126,6 +144,7 @@ else()
     set(PLATFORM_GNU     0)
     set(PLATFORM_MACOSX  0)
     set(PLATFORM_FREEBSD 0)
+    set(PLATFORM_HAIKU   0)
     set(PLATFORM_OTHER   1)
 
     # Platform-dependent implementation of system.h
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 3c5f406..1ae67d6 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -108,6 +108,8 @@ elseif(PLATFORM_GNU)
 elseif(PLATFORM_LINUX)
     # for clock_gettime
     set(PLATFORM_LIBS "-lrt")
+elseif(PLATFORM_HAIKU)
+    set(PLATFORM_LIBS "-lbe -lintl")
 elseif(PLATFORM_MACOSX)
     find_library(LIBINTL_LIBRARY NAMES intl libintl)
     find_path(LIBINTL_INCLUDE_PATH NAMES libintl.h)
diff --git a/src/app/signal_handlers.cpp b/src/app/signal_handlers.cpp
index ebcfe27..292888f 100644
--- a/src/app/signal_handlers.cpp
+++ b/src/app/signal_handlers.cpp
@@ -32,6 +32,12 @@
 #include <sstream>
 #include <iostream>
 
+#ifdef __HAIKU__
+#include <unistd.h>
+#include <sys/types.h>
+#include <signal.h>
+#endif
+
 CSystemUtils* CSignalHandlers::m_systemUtils = nullptr;
 
 void CSignalHandlers::Init(CSystemUtils* systemUtils)
@@ -181,6 +187,9 @@ void CSignalHandlers::ReportError(const std::string& errorMessage)
             m_systemUtils->SystemDialog(SDT_INFO, "Try to save?", "Saving finished.\nPlease restart the game now");
         }
     }
-
+#ifdef __HAIKU__
+	kill (::getpid(), SIGKILL);
+#else
     exit(1);
+#endif
 }
diff --git a/src/common/config.h.cmake b/src/common/config.h.cmake
index 556e067..d523ded 100644
--- a/src/common/config.h.cmake
+++ b/src/common/config.h.cmake
@@ -5,6 +5,7 @@
 #cmakedefine PLATFORM_LINUX @PLATFORM_LINUX@
 #cmakedefine PLATFORM_GNU @PLATFORM_GNU@
 #cmakedefine PLATFORM_MACOSX @PLATFORM_MACOSX@
+#cmakedefine PLATFORM_HAIKU @PLATFORM_HAIKU@
 #cmakedefine PLATFORM_OTHER @PLATFORM_OTHER@
 
 #ifdef PLATFORM_MACOSX
diff --git a/src/common/system/system.cpp b/src/common/system/system.cpp
index b489365..4bc139b 100644
--- a/src/common/system/system.cpp
+++ b/src/common/system/system.cpp
@@ -28,6 +28,8 @@
     #include "common/system/system_linux.h"
 #elif defined(PLATFORM_MACOSX)
     #include "common/system/system_macosx.h"
+#elif defined(PLATFORM_HAIKU)
+    #include "common/system/system_haiku.h"    
 #else
     #include "common/system/system_other.h"
 #endif
@@ -47,6 +49,8 @@ std::unique_ptr<CSystemUtils> CSystemUtils::Create()
     instance = MakeUnique<CSystemUtilsLinux>();
 #elif defined(PLATFORM_MACOSX)
     instance = MakeUnique<CSystemUtilsMacOSX>();
+#elif defined(PLATFORM_HAIKU)
+    instance = MakeUnique<CSystemUtilsHaiku>();
 #else
     instance = MakeUnique<CSystemUtilsOther>();
 #endif
-- 
2.30.2


From ac3427450ac58cf7d98b09e86bbd15779a38e167 Mon Sep 17 00:00:00 2001
From: Gerasim Troeglazov <3dEyes@gmail.com>
Date: Sun, 26 Sep 2021 14:31:42 +1000
Subject: Disable vsync for Haiku


diff --git a/src/app/app.cpp b/src/app/app.cpp
index 1e4515e..78deca3 100644
--- a/src/app/app.cpp
+++ b/src/app/app.cpp
@@ -847,6 +847,7 @@ bool CApplication::CreateVideoSurface()
 
     m_private->glcontext = SDL_GL_CreateContext(m_private->window);
 
+#ifndef __HAIKU__
     int vsync = 0;
     if (GetConfigFile().GetIntProperty("Setup", "VSync", vsync))
     {
@@ -857,7 +858,7 @@ bool CApplication::CreateVideoSurface()
 
         GetLogger()->Info("Using Vsync: %s\n", (vsync == -1 ? "adaptive" : (vsync ? "true" : "false")));
     }
-
+#endif
     return true;
 }
 
diff --git a/src/common/system/system_haiku.cpp b/src/common/system/system_haiku.cpp
new file mode 100644
index 0000000..538aa94
--- /dev/null
+++ b/src/common/system/system_haiku.cpp
@@ -0,0 +1,83 @@
+#include "common/system/system_haiku.h"
+#include "common/logger.h"
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+
+#include <FindDirectory.h>
+
+void CSystemUtilsHaiku::Init()
+{
+}
+
+SystemDialogResult CSystemUtilsHaiku::SystemDialog(SystemDialogType type, const std::string& title, const std::string& message)
+{
+    std::string options = "";
+    std::string buttons = "";
+
+    switch (type) {
+        case SDT_INFO:
+        default:
+            options = "--info";
+            break;
+        case SDT_WARNING:
+            options = "--warning";
+            break;
+        case SDT_ERROR:
+            options = "--stop";
+            break;
+        case SDT_YES_NO:
+            buttons = "Yes No";
+            break;
+        case SDT_OK_CANCEL:
+            buttons = "OK Cancel";
+            break;
+    }
+
+    std::string command = "alert " + options + " \"" + message + "\" " + buttons;
+    int code = system(command.c_str());
+
+    SystemDialogResult result = SDR_OK;
+    switch (type)
+    {
+        case SDT_YES_NO:
+            result = (code == 0) ? SDR_YES : SDR_NO;
+            break;
+        case SDT_OK_CANCEL:
+            result = (code == 0) ? SDR_OK : SDR_CANCEL;
+            break;
+        default:
+            break;
+    }
+
+    return result;
+}
+
+void CSystemUtilsHaiku::GetCurrentTimeStamp(SystemTimeStamp *stamp)
+{
+    stamp->sdlTicks = SDL_GetTicks();
+}
+
+long long CSystemUtilsHaiku::TimeStampExactDiff(SystemTimeStamp *before, SystemTimeStamp *after)
+{
+	return (after->sdlTicks - before->sdlTicks) * 1000000ll;
+}
+
+std::string CSystemUtilsHaiku::GetSaveDir()
+{
+    static char settingsDir[PATH_MAX] = "";
+	if (find_directory(B_USER_SETTINGS_DIRECTORY, -1, false, settingsDir, sizeof(settingsDir)) != B_OK)
+		sprintf(settingsDir, "/boot/home/config/settings");
+
+	std::string savegameDir = std::string (settingsDir) + "/colobot";
+
+    GetLogger()->Trace("Saved game files are going to %s\n", savegameDir);
+
+    return savegameDir;
+}
+
+void CSystemUtilsHaiku::Usleep(int usec)
+{
+    SDL_Delay(usec / 1000);
+}
diff --git a/src/common/system/system_haiku.h b/src/common/system/system_haiku.h
new file mode 100644
index 0000000..81168d0
--- /dev/null
+++ b/src/common/system/system_haiku.h
@@ -0,0 +1,28 @@
+#include "common/system/system.h"
+
+#include <SDL.h>
+#include <sys/time.h>
+#include <iostream>
+
+//@colobot-lint-exclude UndefinedFunctionRule
+
+struct SystemTimeStamp
+{
+    Uint32 sdlTicks;
+    SystemTimeStamp() {
+        sdlTicks = 0;
+    }
+};
+
+class CSystemUtilsHaiku : public CSystemUtils
+{
+public:
+    void Init() override;
+    SystemDialogResult SystemDialog(SystemDialogType type, const std::string& title, const std::string& message) override;
+    void GetCurrentTimeStamp(SystemTimeStamp *stamp) override;
+    long long TimeStampExactDiff(SystemTimeStamp *before, SystemTimeStamp *after) override;
+    std::string GetSaveDir() override;
+    void Usleep(int usec) override;
+};
+
+//@end-colobot-lint-exclude
-- 
2.30.2


From fc70040e81f0246bd4230f6aa3c79d777df14964 Mon Sep 17 00:00:00 2001
From: Gerasim Troeglazov <3dEyes@gmail.com>
Date: Sun, 26 Sep 2021 14:48:34 +1000
Subject: Add missing method after API changes


diff --git a/src/common/system/system_haiku.cpp b/src/common/system/system_haiku.cpp
index 538aa94..aea53a1 100644
--- a/src/common/system/system_haiku.cpp
+++ b/src/common/system/system_haiku.cpp
@@ -59,6 +59,11 @@ void CSystemUtilsHaiku::GetCurrentTimeStamp(SystemTimeStamp *stamp)
     stamp->sdlTicks = SDL_GetTicks();
 }
 
+void CSystemUtilsHaiku::InterpolateTimeStamp(SystemTimeStamp *dst, SystemTimeStamp *a, SystemTimeStamp *b, float i)
+{
+    dst->sdlTicks = a->sdlTicks + static_cast<Uint32>((b->sdlTicks - a->sdlTicks) * i);
+}
+
 long long CSystemUtilsHaiku::TimeStampExactDiff(SystemTimeStamp *before, SystemTimeStamp *after)
 {
 	return (after->sdlTicks - before->sdlTicks) * 1000000ll;
diff --git a/src/common/system/system_haiku.h b/src/common/system/system_haiku.h
index 81168d0..0e45f1e 100644
--- a/src/common/system/system_haiku.h
+++ b/src/common/system/system_haiku.h
@@ -19,9 +19,13 @@ class CSystemUtilsHaiku : public CSystemUtils
 public:
     void Init() override;
     SystemDialogResult SystemDialog(SystemDialogType type, const std::string& title, const std::string& message) override;
+
+    void InterpolateTimeStamp(SystemTimeStamp *dst, SystemTimeStamp *a, SystemTimeStamp *b, float i) override;
     void GetCurrentTimeStamp(SystemTimeStamp *stamp) override;
     long long TimeStampExactDiff(SystemTimeStamp *before, SystemTimeStamp *after) override;
+
     std::string GetSaveDir() override;
+
     void Usleep(int usec) override;
 };
 
-- 
2.30.2

