From 1effcd1e6d52cc5d9f3e9dad6cd17e4b34c49351 Mon Sep 17 00:00:00 2001 From: Li Date: Sun, 19 Apr 2026 22:38:38 +0000 Subject: [PATCH] Haiku port --- CMakeLists.txt | 157 +++++++++++------- .../raknet/jni/RaknetSources/SocketLayer.cpp | 27 ++- .../raknet/jni/RaknetSources/UDPForwarder.cpp | 4 + src/platform/CThread.cpp | 6 +- src/platform/CThread.h | 4 +- src/raknet/SocketLayer.cpp | 27 ++- src/raknet/UDPForwarder.cpp | 4 + .../ExternalFileLevelStorageSource.cpp | 18 +- 8 files changed, 167 insertions(+), 80 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cdd27f0..6a0a6a5 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,10 @@ cmake_minimum_required(VERSION 3.21) project(MinecraftPE) +if(CMAKE_SYSTEM_NAME STREQUAL "Haiku") +set(HAIKU, 1) +endif() + include(cmake/CPM.cmake) set(CMAKE_CXX_STANDARD 14) @@ -26,6 +30,10 @@ if (${PLATFORM} STREQUAL "Desktop") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libstdc++ -static-libgcc") endif() + if(HAIKU) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libstdc++ -static-libgcc -static") + endif() + if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-c++11-narrowing -Wno-narrowing -Wno-invalid-source-encoding -Wno-reserved-user-defined-literal") endif() @@ -34,6 +42,10 @@ if (${PLATFORM} STREQUAL "Desktop") add_definitions(-D_CRT_SECURE_NO_WARNINGS) include_directories(misc/windows) set(EXTRA_LIBS ws2_32 winhttp) + elseif(HAIKU) + find_library(pthread NAMES pthread) + find_library(network NAMES network) + set(EXTRA_LIBS pthread m network) elseif(UNIX) find_library(pthread NAMES pthread) set(EXTRA_LIBS pthread m) @@ -44,73 +56,88 @@ elseif (${PLATFORM} STREQUAL "Web") set(EXTRA_LIBS "idbfs.js") endif() -# I totally shocked -if(${PLATFORM} MATCHES "Web") - set(PNG_LIB png) - set(AL_LIBTYPE "STATIC") +if(!HAIKU) + if(${PLATFORM} MATCHES "Web") + set(PNG_LIB png) + set(ZLIB_LIB zlib) + set(AL_LIBTYPE "STATIC") - add_library(zlib INTERFACE IMPORTED) - set_target_properties(zlib PROPERTIES - INTERFACE_LINK_OPTIONS "-sUSE_ZLIB=1" - ) + add_library(zlib INTERFACE IMPORTED) + set_target_properties(zlib PROPERTIES + INTERFACE_LINK_OPTIONS "-sUSE_ZLIB=1" + ) - add_library(png INTERFACE IMPORTED) - set_target_properties(png PROPERTIES - INTERFACE_COMPILE_OPTIONS "-sUSE_LIBPNG=1" - INTERFACE_LINK_OPTIONS "-sUSE_LIBPNG=1" - ) + add_library(png INTERFACE IMPORTED) + set_target_properties(png PROPERTIES + INTERFACE_COMPILE_OPTIONS "-sUSE_LIBPNG=1" + INTERFACE_LINK_OPTIONS "-sUSE_LIBPNG=1" + ) - add_library(glfw INTERFACE IMPORTED) - set_target_properties(glfw PROPERTIES - INTERFACE_LINK_OPTIONS "-sUSE_GLFW=3" + add_library(glfw INTERFACE IMPORTED) + set_target_properties(glfw PROPERTIES + INTERFACE_LINK_OPTIONS "-sUSE_GLFW=3" + ) + + else() + set(PNG_LIB png_shared) + set(ZLIB_LIB zlib) + set(AL_LIB "OpenAL::OpenAL") + set(AL_LIBTYPE "SHARED") + + CPMAddPackage( + NAME "zlib" + GIT_REPOSITORY "https://github.com/madler/zlib" + GIT_TAG "v1.3.2" + ) + + CPMAddPackage( + NAME "libpng" + GIT_REPOSITORY "https://github.com/pnggroup/libpng.git" + GIT_TAG "v1.6.55" + OPTIONS + "ZLIB_ROOT ${zlib_SOURCE_DIR}" + "ZLIB_INCLUDE_DIRS ${zlib_SOURCE_DIR}" + "PNG_TOOLS OFF" + "PNG_TESTS OFF" + ) + CPMAddPackage( + NAME "glfw" + GIT_REPOSITORY "https://github.com/glfw/glfw.git" + GIT_TAG "3.4" + EXCLUDE_FROM_ALL TRUE + OPTIONS + "GLFW_BUILD_EXAMPLES OFF" + "GLFW_BUILD_TESTS OFF" + "GLFW_BUILD_DOCS OFF" + ) + + endif() + + CPMAddPackage( + NAME "openal" + GIT_REPOSITORY "https://github.com/kcat/openal-soft.git" + GIT_TAG "1.25.1" + OPTIONS + "ALSOFT_EXAMPLES OFF" + "ALSOFT_TESTS OFF" + "ALSOFT_UTILS OFF" + "LIBTYPE ${AL_LIBTYPE}" + "ALSOFT_ENABLE_MODULES OFF" + "ALSOFT_STATIC_STDCXX ON" + "ALSOFT_STATIC_LIBGCC ON" ) else() - set(PNG_LIB png_shared) - set(AL_LIBTYPE "SHARED") + # alot of these have haikuports specific versions, + find_library(glfw NAMES glfw) + find_library(openal NAMES openal) + find_library(png NAMES png) + find_library(zlib NAMES zlib) - CPMAddPackage( - NAME "zlib" - GIT_REPOSITORY "https://github.com/madler/zlib" - GIT_TAG "v1.3.2" - ) - - CPMAddPackage( - NAME "libpng" - GIT_REPOSITORY "https://github.com/pnggroup/libpng.git" - GIT_TAG "v1.6.55" - OPTIONS - "ZLIB_ROOT ${zlib_SOURCE_DIR}" - "ZLIB_INCLUDE_DIRS ${zlib_SOURCE_DIR}" - "PNG_TOOLS OFF" - "PNG_TESTS OFF" - ) - - CPMAddPackage( - NAME "glfw" - GIT_REPOSITORY "https://github.com/glfw/glfw.git" - GIT_TAG "3.4" - EXCLUDE_FROM_ALL TRUE - OPTIONS - "GLFW_BUILD_EXAMPLES OFF" - "GLFW_BUILD_TESTS OFF" - "GLFW_BUILD_DOCS OFF" - ) + set(PNG_LIB png) + set(ZLIB_LIB z) + set(AL_LIB openal) endif() -CPMAddPackage( - NAME "openal" - GIT_REPOSITORY "https://github.com/kcat/openal-soft.git" - GIT_TAG "1.25.1" - OPTIONS - "ALSOFT_EXAMPLES OFF" - "ALSOFT_TESTS OFF" - "ALSOFT_UTILS OFF" - "LIBTYPE ${AL_LIBTYPE}" - "ALSOFT_ENABLE_MODULES OFF" - "ALSOFT_STATIC_STDCXX ON" - "ALSOFT_STATIC_LIBGCC ON" -) - # TODO: Clear this paths with * file(GLOB SERVER_SOURCES "project/lib_projects/raknet/jni/RaknetSources/*.cpp" @@ -316,7 +343,8 @@ if(UNIX) "project/lib_projects/raknet/jni/RaknetSources" ) - target_link_libraries("${PROJECT_NAME}-server" ${CMAKE_THREAD_LIBS_INIT}) + target_link_libraries("${PROJECT_NAME}-server" ${EXTRA_LIBS}) + endif() add_executable(${PROJECT_NAME} ${CLIENT_SOURCES}) @@ -372,11 +400,16 @@ if(${PLATFORM} MATCHES "Web") endif() target_compile_definitions(${PROJECT_NAME} PUBLIC "__EMSCRIPTEN__" "NO_SOUND" "NO_NETWORK") +else() + target_compile_options(${PROJECT_NAME} PUBLIC + "-O3" + ) endif() # Client target_compile_definitions(${PROJECT_NAME} PUBLIC "OPENGL_ES" "NO_EGL" ${PLATFORM}) -target_link_libraries(${PROJECT_NAME} zlib ${PNG_LIB} OpenAL::OpenAL glfw ${EXTRA_LIBS}) + +target_link_libraries(${PROJECT_NAME} ${ZLIB_LIB} ${PNG_LIB} ${AL_LIB} glfw ${EXTRA_LIBS}) if (OpenSSL_FOUND) target_link_libraries(${PROJECT_NAME} OpenSSL::SSL OpenSSL::Crypto) @@ -407,4 +440,4 @@ else() endif() message(STATUS "Compiling with the flags:") -message(STATUS " PLATFORM=" ${PLATFORM_CPP}) \ No newline at end of file +message(STATUS " PLATFORM=" ${PLATFORM_CPP}) diff --git a/project/lib_projects/raknet/jni/RaknetSources/SocketLayer.cpp b/project/lib_projects/raknet/jni/RaknetSources/SocketLayer.cpp index ae11076..4ed4aae 100755 --- a/project/lib_projects/raknet/jni/RaknetSources/SocketLayer.cpp +++ b/project/lib_projects/raknet/jni/RaknetSources/SocketLayer.cpp @@ -42,10 +42,10 @@ SocketLayerOverride *SocketLayer::slo=0; #endif - - - - +#if defined(__HAIKU__) +#include +#include +#endif @@ -1436,8 +1436,25 @@ RakNet::RakString SocketLayer::GetSubNetForSocketAndIp(SOCKET inSock, RakNet::Ra } } return ""; -#else +#elif defined(__HAIKU__) + struct ifaddrs *ifap, *ifa; + getifaddrs (&ifap); + for (ifa = ifap; ifa; ifa = ifa->ifa_next) { + if (ifa->ifa_addr && ifa->ifa_addr->sa_family==AF_INET) { + sockaddr_in* sa = (sockaddr_in*)ifa->ifa_addr; + char* ip_addr = inet_ntoa(sa->sin_addr); + if (inIpString == ip_addr) { + sockaddr_in* sa = (sockaddr_in*)ifa->ifa_netmask; + char* netmask = inet_ntoa(sa->sin_addr); + freeifaddrs(ifap); + return netmask; + } + } + } + freeifaddrs(ifap); + return ""; +#else int fd,fd2; fd2 = socket__(AF_INET, SOCK_DGRAM, 0); diff --git a/project/lib_projects/raknet/jni/RaknetSources/UDPForwarder.cpp b/project/lib_projects/raknet/jni/RaknetSources/UDPForwarder.cpp index c043e5e..5dacdf4 100755 --- a/project/lib_projects/raknet/jni/RaknetSources/UDPForwarder.cpp +++ b/project/lib_projects/raknet/jni/RaknetSources/UDPForwarder.cpp @@ -1,5 +1,9 @@ #include "UDPForwarder.h" +#if defined(__HAIKU__) +#include +#endif + #if _RAKNET_SUPPORT_UDPForwarder==1 #include "GetTime.h" diff --git a/src/platform/CThread.cpp b/src/platform/CThread.cpp index e136198..1592747 100755 --- a/src/platform/CThread.cpp +++ b/src/platform/CThread.cpp @@ -25,7 +25,7 @@ &m_threadID // pointer to receive thread ID ); #endif - #if defined(__linux__) || defined(ANDROID) || defined(__APPLE__) || defined(POSIX) || defined(__EMSCRIPTEN__) + #if defined(__linux__) || defined(ANDROID) || defined(__APPLE__) || defined(POSIX) || defined(__EMSCRIPTEN__) || defined(__HAIKU__) mp_threadFunc = (pthread_fn)threadFunc; pthread_attr_init(&m_attributes); @@ -53,7 +53,7 @@ #ifdef WIN32 Sleep( millis ); #endif - #if defined(LINUX) || defined(ANDROID) || defined(__APPLE__) || defined(POSIX) + #if defined(LINUX) || defined(ANDROID) || defined(__APPLE__) || defined(POSIX) || defined(__HAIKU__) usleep(millis * 1000); #endif } @@ -63,7 +63,7 @@ #ifdef WIN32 TerminateThread(m_threadHandle, 0); #endif - #if defined(LINUX) || defined(ANDROID) || defined(__APPLE__) || defined(POSIX) + #if defined(LINUX) || defined(ANDROID) || defined(__APPLE__) || defined(POSIX) || defined(__HAIKU__) // Thread was created detached; pthread_join on a detached thread is undefined // and causes SIGABRT when the pthread_t is no longer valid. pthread_attr_destroy(&m_attributes); diff --git a/src/platform/CThread.h b/src/platform/CThread.h index c608e92..2cb1704 100755 --- a/src/platform/CThread.h +++ b/src/platform/CThread.h @@ -13,7 +13,7 @@ typedef void *( * pthread_fn )( void * ); -#if defined(__linux__) || defined(ANDROID) || defined(__APPLE__) || defined(POSIX) || defined(__EMSCRIPTEN__) +#if defined(__linux__) || defined(ANDROID) || defined(__APPLE__) || defined(POSIX) || defined(__EMSCRIPTEN__) || defined(__HAIKU__) #include #include @@ -38,7 +38,7 @@ typedef void *( * pthread_fn )( void * ); DWORD m_threadID; HANDLE m_threadHandle; #endif - #if defined(__linux__) || defined(ANDROID) || defined(__APPLE__) || defined(POSIX) || defined(__EMSCRIPTEN__) + #if defined(__linux__) || defined(ANDROID) || defined(__APPLE__) || defined(POSIX) || defined(__EMSCRIPTEN__) || defined(__HAIKU__) pthread_fn mp_threadFunc; pthread_t m_thread; pthread_attr_t m_attributes; diff --git a/src/raknet/SocketLayer.cpp b/src/raknet/SocketLayer.cpp index badae95..55d5327 100755 --- a/src/raknet/SocketLayer.cpp +++ b/src/raknet/SocketLayer.cpp @@ -42,11 +42,10 @@ SocketLayerOverride *SocketLayer::slo=0; #endif - - - - - +#if defined(__HAIKU__) +#include +#include +#endif @@ -1436,6 +1435,24 @@ RakNet::RakString SocketLayer::GetSubNetForSocketAndIp(SOCKET inSock, RakNet::Ra } } return ""; +#elif defined(__HAIKU__) + struct ifaddrs *ifap, *ifa; + getifaddrs (&ifap); + for (ifa = ifap; ifa; ifa = ifa->ifa_next) { + if (ifa->ifa_addr && ifa->ifa_addr->sa_family==AF_INET) { + sockaddr_in* sa = (sockaddr_in*)ifa->ifa_addr; + char* ip_addr = inet_ntoa(sa->sin_addr); + if (inIpString == ip_addr) { + sockaddr_in* sa = (sockaddr_in*)ifa->ifa_netmask; + char* netmask = inet_ntoa(sa->sin_addr); + + freeifaddrs(ifap); + return netmask; + } + } + } + freeifaddrs(ifap); + return ""; #else int fd,fd2; diff --git a/src/raknet/UDPForwarder.cpp b/src/raknet/UDPForwarder.cpp index c043e5e..5dacdf4 100755 --- a/src/raknet/UDPForwarder.cpp +++ b/src/raknet/UDPForwarder.cpp @@ -1,5 +1,9 @@ #include "UDPForwarder.h" +#if defined(__HAIKU__) +#include +#endif + #if _RAKNET_SUPPORT_UDPForwarder==1 #include "GetTime.h" diff --git a/src/world/level/storage/ExternalFileLevelStorageSource.cpp b/src/world/level/storage/ExternalFileLevelStorageSource.cpp index b09b48f..aa4133d 100755 --- a/src/world/level/storage/ExternalFileLevelStorageSource.cpp +++ b/src/world/level/storage/ExternalFileLevelStorageSource.cpp @@ -9,6 +9,10 @@ #include #include +#if defined(__HAIKU__) +#include +#endif + #ifdef __APPLE__ #include "MoveFolder.h" #endif @@ -66,7 +70,7 @@ void ExternalFileLevelStorageSource::addLevelSummaryIfExists(LevelSummaryList& d void ExternalFileLevelStorageSource::getLevelList(LevelSummaryList& dest) { -#ifdef WIN32 +#if defined(WIN32) WIN32_FIND_DATAA fileData; HANDLE hFind; @@ -83,8 +87,6 @@ void ExternalFileLevelStorageSource::getLevelList(LevelSummaryList& dest) } while (FindNextFileA(hFind, &fileData)); FindClose(hFind); } - - #else DIR *dp; struct dirent *dirp; @@ -94,10 +96,20 @@ void ExternalFileLevelStorageSource::getLevelList(LevelSummaryList& dest) } while ((dirp = readdir(dp)) != NULL) { +#if defined(__HAIKU__) + struct stat st; + const auto fullPath = basePath + "/" + dirp->d_name; + if (!lstat(fullPath.c_str(), &st)) { + if(st.st_mode & S_IFDIR) { + addLevelSummaryIfExists(dest, dirp->d_name); + } + } +#else if (dirp->d_type == DT_DIR) { addLevelSummaryIfExists(dest, dirp->d_name); } +#endif } closedir(dp); #endif