diff --git a/.gitignore b/.gitignore index 5465697..d76aac1 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ out/ bin/ lib/ build-apk/ +build-haiku/ cmake-build-*/ CMakeFiles/ CMakeCache.txt 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/haiku/createpkg.sh b/project/haiku/createpkg.sh new file mode 100755 index 0000000..8558551 --- /dev/null +++ b/project/haiku/createpkg.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +mkdir build-haiku +cd build-haiku +cmake .. +make -j10 + +rm -rf pkg + +mkdir pkg +mkdir -p ./pkg/apps/ +mkdir -p ./pkg/data/minecraftpe +mkdir -p ./pkg/settings/minecraftpe +mkdir -p ./pkg/data/deskbar/menu/Applications/ +mkdir -p ./pkg/data/deskbar/menu/Games/ + +cp -rv ../project/haiku/pkg ./ +cp -v MinecraftPE ./pkg/apps/minecraftpe +cp -v MinecraftPE-server ./pkg/apps/minecraftpe-server +cp -rv data ./pkg/data/minecraftpe + +ln -s ../../../../apps/minecraftpe ./pkg/data/deskbar/menu/Applications/minecraftpe +ln -s ../../../../apps/minecraftpe ./pkg/data/deskbar/menu/Games/minecraftpe + + +package create -C pkg minecraftpe-0.6.1-x86_64.hpkg diff --git a/project/haiku/pkg/.PackageInfo b/project/haiku/pkg/.PackageInfo new file mode 100644 index 0000000..1888644 --- /dev/null +++ b/project/haiku/pkg/.PackageInfo @@ -0,0 +1,27 @@ +name minecraftpe +version 0.6.1-1 +architecture x86_64 +summary "Minecraft Pocket Edition" +description "A port of minecraft pocket edition to Haiku" +packager "Li " +vendor "Mojang" +copyrights { + "Copyright (C) 2026 by Mojang" +} +licenses { + "MIT" +} +provides { + minecraftpe = 0.6.1-1 + app:minecraftpe = 0.6.1-1 +} +requires { + glfw >= 3.3.7-1 + openal >= 1.21.1-5 +} +global-writable-files { + "settings/minecraftpe" directory keep-old +} +urls { + "https://gitea.sffempire.ru/Kolyah35/minecraft-pe-0.6.1/" +} diff --git a/project/lib_projects/raknet/jni/RaknetSources/RakPeer.cpp b/project/lib_projects/raknet/jni/RaknetSources/RakPeer.cpp index a24a2b5..5e6de82 100755 --- a/project/lib_projects/raknet/jni/RaknetSources/RakPeer.cpp +++ b/project/lib_projects/raknet/jni/RaknetSources/RakPeer.cpp @@ -351,7 +351,8 @@ StartupResult RakPeer::Startup( unsigned short maxConnections, SocketDescriptor #if defined(_WIN32) threadPriority=0; - +#elif defined(__HAIKU__) + threadPriority=40; #else threadPriority=1000; #endif diff --git a/project/lib_projects/raknet/jni/RaknetSources/RakThread.cpp b/project/lib_projects/raknet/jni/RaknetSources/RakThread.cpp index 268ee3a..5b91ff3 100755 --- a/project/lib_projects/raknet/jni/RaknetSources/RakThread.cpp +++ b/project/lib_projects/raknet/jni/RaknetSources/RakThread.cpp @@ -17,8 +17,8 @@ using namespace RakNet; #endif - - +#elif defined(__HAIKU__) +#include #else #include #endif @@ -93,9 +93,10 @@ int RakThread::Create( void* start_address( void* ), void *arglist, int priority - - - +#elif defined(__HAIKU__) + thread_id threadHandle = spawn_thread((thread_func)start_address, "RakThread", priority, arglist); + int res = resume_thread(threadHandle); + return res == B_OK ? 0 : 1; #else pthread_t threadHandle; // Create thread linux diff --git a/project/lib_projects/raknet/jni/RaknetSources/SocketLayer.cpp b/project/lib_projects/raknet/jni/RaknetSources/SocketLayer.cpp index ae11076..3731571 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); @@ -1648,7 +1665,7 @@ void GetMyIP_Win32( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] ) } } // #else -/* + void GetMyIP_Linux( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] ) { struct ifaddrs *ifaddr, *ifa; @@ -1699,7 +1716,7 @@ void GetMyIP_Linux( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] ) freeifaddrs(ifaddr); } -*/ + @@ -1707,10 +1724,10 @@ void SocketLayer::GetMyIP( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_ID { - - #if defined(_WIN32) GetMyIP_Win32(addresses); +#elif defined(__HAIKU__) + GetMyIP_Linux(addresses); #else // GetMyIP_Linux(addresses); GetMyIP_Win32(addresses); 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/AppPlatform_glfw.h b/src/AppPlatform_glfw.h index d996860..eeb0444 100755 --- a/src/AppPlatform_glfw.h +++ b/src/AppPlatform_glfw.h @@ -20,6 +20,7 @@ #include #endif + #ifdef __EMSCRIPTEN__ #include #endif @@ -31,12 +32,19 @@ static void png_funcReadFile(png_structp pngPtr, png_bytep data, png_size_t leng class AppPlatform_glfw: public AppPlatform { public: - AppPlatform_glfw() + +#ifdef __HAIKU__ + std::string game_directory = "/system/data/minecraftpe/"; +#else + std::string game_directory = ""; +#endif + + AppPlatform_glfw() { } BinaryBlob readAssetFile(const std::string& filename) override { - FILE* fp = fopen(("data/" + filename).c_str(), "r"); + FILE* fp = fopen((game_directory + "data/" + filename).c_str(), "r"); if (!fp) return BinaryBlob(); @@ -73,7 +81,7 @@ public: TextureData out; - std::string filename = textureFolder? "data/images/" + filename_ + std::string filename = textureFolder? (game_directory + "data/images/") + filename_ : filename_; std::ifstream source(filename.c_str(), std::ios::binary); diff --git a/src/client/OptionsFile.cpp b/src/client/OptionsFile.cpp index ef2a0dc..e86e2ac 100755 --- a/src/client/OptionsFile.cpp +++ b/src/client/OptionsFile.cpp @@ -18,6 +18,8 @@ OptionsFile::OptionsFile() { settingsPath = "options.txt"; #elif defined(__EMSCRIPTEN__) settingsPath = "/games/com.mojang/options.txt"; +#elif defined(__HAIKU__) + settingsPath = "/system/settings/minecraftpe/options.txt"; #else settingsPath = "options.txt"; #endif diff --git a/src/main_glfw.h b/src/main_glfw.h index 042c9fb..a0fc283 100755 --- a/src/main_glfw.h +++ b/src/main_glfw.h @@ -191,8 +191,13 @@ int main(void) { App* app = new MAIN_CLASS(); g_app = app; +#ifdef __HAIKU__ + ((MAIN_CLASS*)g_app)->externalStoragePath = "/system/settings/minecraftpe"; + ((MAIN_CLASS*)g_app)->externalCacheStoragePath = "/system/settings/minecraftpe"; +#else ((MAIN_CLASS*)g_app)->externalStoragePath = "."; ((MAIN_CLASS*)g_app)->externalCacheStoragePath = "."; +#endif g_app->init(appContext); g_app->setSize(appContext.platform->getScreenWidth(), appContext.platform->getScreenHeight()); diff --git a/src/platform/CThread.cpp b/src/platform/CThread.cpp index e136198..6bcd08a 100755 --- a/src/platform/CThread.cpp +++ b/src/platform/CThread.cpp @@ -31,6 +31,13 @@ pthread_attr_init(&m_attributes); pthread_attr_setdetachstate( &m_attributes, PTHREAD_CREATE_DETACHED ); /*int error =*/ pthread_create(&m_thread, &m_attributes, mp_threadFunc, threadParam); + #endif + #if defined(__HAIKU__) + + mp_threadFunc = (thread_func)threadFunc; + m_thread = spawn_thread(mp_threadFunc, "CThread", 10, threadParam); + int res = resume_thread(m_thread); + #endif #ifdef MACOSX mp_threadFunc = (TaskProc) threadFunc; @@ -56,6 +63,9 @@ #if defined(LINUX) || defined(ANDROID) || defined(__APPLE__) || defined(POSIX) usleep(millis * 1000); #endif + #if defined(__HAIKU__) + snooze((bigtime_t)(millis * 1000)); + #endif } CThread::~CThread() @@ -68,6 +78,9 @@ // and causes SIGABRT when the pthread_t is no longer valid. pthread_attr_destroy(&m_attributes); #endif + #if defined(__HAIKU__) + kill_thread(m_thread); + #endif } diff --git a/src/platform/CThread.h b/src/platform/CThread.h index c608e92..8781af4 100755 --- a/src/platform/CThread.h +++ b/src/platform/CThread.h @@ -21,6 +21,9 @@ typedef void *( * pthread_fn )( void * ); #ifdef MACOSX #include #include +#endif +#ifdef __HAIKU__ +#include #endif class CThread @@ -43,6 +46,10 @@ typedef void *( * pthread_fn )( void * ); pthread_t m_thread; pthread_attr_t m_attributes; #endif +#if defined(__HAIKU__) + thread_func mp_threadFunc; + thread_id m_thread; +#endif #ifdef MACOSX TaskProc mp_threadFunc; MPTaskID m_threadID; diff --git a/src/raknet/RakPeer.cpp b/src/raknet/RakPeer.cpp index a24a2b5..5e6de82 100755 --- a/src/raknet/RakPeer.cpp +++ b/src/raknet/RakPeer.cpp @@ -351,7 +351,8 @@ StartupResult RakPeer::Startup( unsigned short maxConnections, SocketDescriptor #if defined(_WIN32) threadPriority=0; - +#elif defined(__HAIKU__) + threadPriority=40; #else threadPriority=1000; #endif diff --git a/src/raknet/RakThread.cpp b/src/raknet/RakThread.cpp index 268ee3a..184bea7 100755 --- a/src/raknet/RakThread.cpp +++ b/src/raknet/RakThread.cpp @@ -19,6 +19,8 @@ using namespace RakNet; +#elif defined(__HAIKU__) +#include #else #include #endif @@ -92,10 +94,10 @@ int RakThread::Create( void* start_address( void* ), void *arglist, int priority - - - - +#elif defined(__HAIKU__) + thread_id threadHandle = spawn_thread((thread_func)start_address, "RakThread", priority, arglist); + int res = resume_thread(threadHandle); + return res == B_OK ? 0 : 1; #else pthread_t threadHandle; // Create thread linux diff --git a/src/raknet/SocketLayer.cpp b/src/raknet/SocketLayer.cpp index badae95..aab591b 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; @@ -1648,7 +1665,7 @@ void GetMyIP_Win32( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] ) } } // #else -/* + void GetMyIP_Linux( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] ) { struct ifaddrs *ifaddr, *ifa; @@ -1699,7 +1716,7 @@ void GetMyIP_Linux( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_IDS] ) freeifaddrs(ifaddr); } -*/ + @@ -1711,6 +1728,8 @@ void SocketLayer::GetMyIP( SystemAddress addresses[MAXIMUM_NUMBER_OF_INTERNAL_ID #if defined(_WIN32) GetMyIP_Win32(addresses); +#elif defined(__HAIKU__) + GetMyIP_Linux(addresses); #else // GetMyIP_Linux(addresses); GetMyIP_Win32(addresses); 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