From ea882813492c8216eb32d5eaf7f2e2118ec9e5b8 Mon Sep 17 00:00:00 2001 From: Gleb Mazovetskiy Date: Tue, 10 Dec 2024 13:16:35 +0000 Subject: [PATCH 1/7] Bump googletest to v1.15.2 --- 3rdParty/googletest/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/3rdParty/googletest/CMakeLists.txt b/3rdParty/googletest/CMakeLists.txt index ed3463cf2e9..26c31d28492 100644 --- a/3rdParty/googletest/CMakeLists.txt +++ b/3rdParty/googletest/CMakeLists.txt @@ -2,8 +2,8 @@ include(functions/FetchContent_ExcludeFromAll_backport) FetchContent_Declare_ExcludeFromAll( googletest - URL https://github.com/google/googletest/archive/refs/tags/v1.14.0.tar.gz - URL_HASH MD5=c8340a482851ef6a3fe618a082304cfc + URL https://github.com/google/googletest/releases/download/v1.15.2/googletest-1.15.2.tar.gz + URL_HASH MD5=7e11f6cfcf6498324ac82d567dcb891e ) set(INSTALL_GTEST OFF) From e7fd6c749bf6c39020405a4e82989f016067380c Mon Sep 17 00:00:00 2001 From: Gleb Mazovetskiy Date: Mon, 9 Dec 2024 06:46:09 +0000 Subject: [PATCH 2/7] macOS Tiger platform and instructions --- 3rdParty/Lua/CMakeLists.txt | 7 ++- CMake/Platforms.cmake | 12 ++++++ CMake/platforms/macos_tiger.cmake | 20 +++++++++ .../finders/FindMacportsLegacySupport.cmake | 30 +++++++++++++ docs/building.md | 43 +++++++++++++++++++ 5 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 CMake/platforms/macos_tiger.cmake create mode 100644 CMake/platforms/macports/finders/FindMacportsLegacySupport.cmake diff --git a/3rdParty/Lua/CMakeLists.txt b/3rdParty/Lua/CMakeLists.txt index 2689c093c17..7dd61770735 100644 --- a/3rdParty/Lua/CMakeLists.txt +++ b/3rdParty/Lua/CMakeLists.txt @@ -15,7 +15,12 @@ FetchContent_Declare_ExcludeFromAll(Lua ) FetchContent_MakeAvailable_ExcludeFromAll(Lua) -if(ANDROID AND ("${ANDROID_ABI}" STREQUAL "armeabi-v7a" OR "${ANDROID_ABI}" STREQUAL "x86")) +if(CMAKE_SYSTEM_NAME MATCHES "Darwin" AND DARWIN_MAJOR_VERSION VERSION_EQUAL 8) + # We need legacy-support from MacPorts for: + # localtime_r gmtime_r + find_package(MacportsLegacySupport REQUIRED) + target_link_libraries(lua_static PRIVATE MacportsLegacySupport::MacportsLegacySupport) +elseif(ANDROID AND ("${ANDROID_ABI}" STREQUAL "armeabi-v7a" OR "${ANDROID_ABI}" STREQUAL "x86")) target_compile_definitions(lua_internal INTERFACE -DLUA_USE_C89) elseif(NINTENDO_3DS OR VITA OR NINTENDO_SWITCH OR NXDK) target_compile_definitions(lua_static PUBLIC -DLUA_USE_C89) diff --git a/CMake/Platforms.cmake b/CMake/Platforms.cmake index 76cd0d98a59..0c4f352a29e 100644 --- a/CMake/Platforms.cmake +++ b/CMake/Platforms.cmake @@ -88,4 +88,16 @@ if(CMAKE_SYSTEM_NAME MATCHES "Darwin") # to detect available APIs. string(REGEX REPLACE "^([0-9]+)\\.([0-9]+).*$" "\\1" DARWIN_MAJOR_VERSION "${CMAKE_SYSTEM_VERSION}") string(REGEX REPLACE "^([0-9]+)\\.([0-9]+).*$" "\\2" DARWIN_MINOR_VERSION "${CMAKE_SYSTEM_VERSION}") + + if(DARWIN_MAJOR_VERSION VERSION_EQUAL 8) + include(platforms/macos_tiger) + endif() + + # For older macOS, we assume MacPorts because Homebrew only supports newer version + if(DARWIN_MAJOR_VERSION VERSION_LESS 11) + list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/platforms/macports/finders") + + # On MacPorts, libfmt is in a subdirectory: + list(APPEND CMAKE_MODULE_PATH "/opt/local/lib/libfmt11/cmake") + endif() endif() diff --git a/CMake/platforms/macos_tiger.cmake b/CMake/platforms/macos_tiger.cmake new file mode 100644 index 00000000000..2367ac5a57d --- /dev/null +++ b/CMake/platforms/macos_tiger.cmake @@ -0,0 +1,20 @@ +# ASAN and UBSAN are not supported by macports gcc14 on PowerPC. +set(ASAN OFF) +set(UBSAN OFF) + +# SDL2 does not build for Tiger, so we use SDL1 instead. +set(USE_SDL1 ON) + +# ZeroTier is yet to be tested. +set(DISABLE_ZERO_TIER ON) + +# Use vendored libfmt until this issue is resolved: +# https://trac.macports.org/ticket/71503 +set(DEVILUTIONX_SYSTEM_LIBFMT OFF) +set(DEVILUTIONX_STATIC_LIBFMT ON) + +# https://trac.macports.org/ticket/71511 +set(DEVILUTIONX_SYSTEM_GOOGLETEST OFF) +set(DEVILUTIONX_STATIC_GOOGLETEST OFF) +set(DEVILUTIONX_SYSTEM_BENCHMARK OFF) +set(DEVILUTIONX_STATIC_BENCHMARK OFF) diff --git a/CMake/platforms/macports/finders/FindMacportsLegacySupport.cmake b/CMake/platforms/macports/finders/FindMacportsLegacySupport.cmake new file mode 100644 index 00000000000..34dbc1fe2d5 --- /dev/null +++ b/CMake/platforms/macports/finders/FindMacportsLegacySupport.cmake @@ -0,0 +1,30 @@ +# Provides missing functions, such as localtime_r +if(NOT TARGET MacportsLegacySupport::MacportsLegacySupport) + set(MacportsLegacySupport_INCLUDE_DIR /opt/local/include/LegacySupport) + mark_as_advanced(MacportsLegacySupport_INCLUDE_DIR) + + find_library(MacportsLegacySupport_LIBRARY NAMES MacportsLegacySupport + PATHS /opt/local/lib) + mark_as_advanced(MacportsLegacySupport_LIBRARY) + + include(FindPackageHandleStandardArgs) + FIND_PACKAGE_HANDLE_STANDARD_ARGS( + MacportsLegacySupport + DEFAULT_MSG + MacportsLegacySupport_LIBRARY MacportsLegacySupport_INCLUDE_DIR) + + if(MacportsLegacySupport_FOUND) + set(MacportsLegacySupport_LIBRARIES ${MacportsLegacySupport_LIBRARY}) + set(MacportsLegacySupport_INCLUDE_DIRS ${MacportsLegacySupport_INCLUDE_DIR}) + add_library(MacportsLegacySupport::MacportsLegacySupport UNKNOWN IMPORTED) + set_target_properties( + MacportsLegacySupport::MacportsLegacySupport PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${MacportsLegacySupport_INCLUDE_DIR}" + ) + set_target_properties( + MacportsLegacySupport::MacportsLegacySupport PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES "C" + IMPORTED_LOCATION "${MacportsLegacySupport_LIBRARY}" + ) + endif() +endif() diff --git a/docs/building.md b/docs/building.md index 7904f5a9bd8..e87f099002b 100644 --- a/docs/building.md +++ b/docs/building.md @@ -528,6 +528,49 @@ Executing `Packaging/miyoo_mini/build.sh` will create the folder `build-miyoo-mi OnionOS Port Collection. +
macOS 10.4 Tiger + +For macOS Tiger, DevilutionX can be compiled using the compiler and libraries from [MacPorts](https://www.macports.org/). + +For PowerPC, you can use precompiled dependencies from here: + +http://macports-tiger-ppc.glebm.com/ + +After installing MacPorts, run: + +~~~ bash +# Some packages may require you to manually deactivate certain ports during installation. +# Remember to reactivate them after installing. +sudo port install curl curl-ca-bundle gcc14 cmake \ + libsdl12 libsdl_image libsodium bzip2 zlib lua54 + +# Set GCC 14 as the default GCC: +sudo port select --set gcc mp-gcc14 +~~~ + + + +Then, build DevilutionX: + +~~~ bash +CC=gcc cmake -S. -Bbuild-rel -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF -DCPACK=ON -DMACOSX_STANDALONE_APP_BUNDLE=ON +cmake --build build-rel -j "$(sysctl -n hw.ncpu)" + +# `sudo` is required to produce a bundle with all the shared libraries. +sudo cmake --build build-rel --target package -j "$(sysctl -n hw.ncpu)" +~~~ + +To run tools from the `tools/` directory (only needed for development), you also need Python: + +~~~ bash +sudo port install python312 +sudo port select --set python python312 +sudo port select --set python3 python312 +~~~ + +
+
CMake build options ### General From eec5454f7227846a558c97391125163bb61afa77 Mon Sep 17 00:00:00 2001 From: Gleb Mazovetskiy Date: Tue, 10 Dec 2024 04:10:55 +0000 Subject: [PATCH 3/7] OSX Tiger: Fix icon Finder on OSX Tiger can only handle `icns` files with up to 128x128 icons. Adds a file with 128x128, 48x48, 32x32, and 16x16 icons. --- CMakeLists.txt | 12 +++++++++--- Packaging/apple/AppIcon_128.icns | Bin 0 -> 22560 bytes 2 files changed, 9 insertions(+), 3 deletions(-) create mode 100644 Packaging/apple/AppIcon_128.icns diff --git a/CMakeLists.txt b/CMakeLists.txt index 54f8cb638fd..9eb7d73fafe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -343,7 +343,6 @@ else() Source/main.cpp Packaging/windows/devilutionx.exe.manifest Packaging/windows/devilutionx.rc - Packaging/apple/AppIcon.icns Packaging/apple/LaunchScreen.storyboard) if(CMAKE_STRIP AND NOT DEVILUTIONX_DISABLE_STRIP) @@ -382,7 +381,6 @@ include(functions/set_relative_file_macro) set_relative_file_macro(${BIN_TARGET}) if(APPLE) - set_source_files_properties("./Packaging/apple/AppIcon.icns" PROPERTIES MACOSX_PACKAGE_LOCATION Resources) set(MACOSX_BUNDLE_GUI_IDENTIFIER com.diasurgical.devilutionx) set(MACOSX_BUNDLE_COPYRIGHT Unlicense) set(MACOSX_BUNDLE_BUNDLE_NAME devilutionx) @@ -399,7 +397,15 @@ if(APPLE) set(MACOSX_BUNDLE_REQUIRED_PLATFORM Carbon) set(CMAKE_OSX_DEPLOYMENT_TARGET "10.12.0") endif() - set_target_properties(${BIN_TARGET} PROPERTIES MACOSX_BUNDLE_ICON_FILE "AppIcon.icns") + if(DARWIN_MAJOR_VERSION VERSION_LESS 9) + # Finder on OSX Tiger can only handle icns files with up to 128x128 icons. + set(_icon_file AppIcon_128) + else() + set(_icon_file AppIcon) + endif() + target_sources(${BIN_TARGET} PRIVATE "Packaging/apple/${_icon_file}.icns") + set_source_files_properties("./Packaging/apple/${_icon_file}.icns" PROPERTIES MACOSX_PACKAGE_LOCATION Resources) + set_target_properties(${BIN_TARGET} PROPERTIES MACOSX_BUNDLE_ICON_FILE "${_icon_file}.icns") set_target_properties(${BIN_TARGET} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Packaging/apple/Info.plist") install (TARGETS ${BIN_TARGET} DESTINATION ./) diff --git a/Packaging/apple/AppIcon_128.icns b/Packaging/apple/AppIcon_128.icns new file mode 100644 index 0000000000000000000000000000000000000000..76108cf0a337e7103fb72314031db82d8354d2cc GIT binary patch literal 22560 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 literal 0 HcmV?d00001 From d5e0005ec96565ac428703c63679840cb3812c7f Mon Sep 17 00:00:00 2001 From: Gleb Mazovetskiy Date: Tue, 10 Dec 2024 12:26:50 +0000 Subject: [PATCH 4/7] items_test.cpp: add missing include --- test/items_test.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/items_test.cpp b/test/items_test.cpp index c829520b4c1..0a3caa2bc47 100644 --- a/test/items_test.cpp +++ b/test/items_test.cpp @@ -1,6 +1,8 @@ -#include +#include #include +#include + #include "engine/random.hpp" #include "items.h" #include "player.h" From e1342add77847e358d1b9564f68b12526a0b26ed Mon Sep 17 00:00:00 2001 From: Gleb Mazovetskiy Date: Tue, 10 Dec 2024 12:57:16 +0000 Subject: [PATCH 5/7] timedemo_test: SDL1.2 compat --- test/timedemo_test.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/test/timedemo_test.cpp b/test/timedemo_test.cpp index 79eb5d334e8..afb60a00a46 100644 --- a/test/timedemo_test.cpp +++ b/test/timedemo_test.cpp @@ -23,7 +23,14 @@ bool Dummy_GetHeroInfo(_uiheroinfo *pInfo) void RunTimedemo(std::string timedemoFolderName) { - if (SDL_Init(SDL_INIT_EVENTS) <= -1) { + if (SDL_Init( +#ifdef USE_SDL1 + 0 +#else + SDL_INIT_EVENTS +#endif + ) + <= -1) { ErrSdl(); } std::string unitTestFolderCompletePath = paths::BasePath() + "/test/fixtures/timedemo/" + timedemoFolderName; From a3a2f82978bcee1a52a22ae1a68013e9eac271df Mon Sep 17 00:00:00 2001 From: Gleb Mazovetskiy Date: Tue, 10 Dec 2024 18:56:46 +0000 Subject: [PATCH 6/7] OSX: Fix base/pref/config paths on Tiger --- .editorconfig | 3 + Packaging/apple/Info.plist | 2 +- Source/CMakeLists.txt | 7 + Source/init.cpp | 2 +- Source/platform/macos_sdl1/SDL_filesystem.m | 138 ++++++++++++++++++++ Source/utils/paths.cpp | 21 +++ Source/utils/paths.h | 1 - Source/utils/sdl2_to_1_2_backports.cpp | 11 +- Source/utils/sdl2_to_1_2_backports.h | 4 +- 9 files changed, 179 insertions(+), 10 deletions(-) create mode 100644 Source/platform/macos_sdl1/SDL_filesystem.m diff --git a/.editorconfig b/.editorconfig index 959e97e84ea..efd434d7897 100644 --- a/.editorconfig +++ b/.editorconfig @@ -67,6 +67,9 @@ end_of_line = crlf [*.tsv] trim_trailing_whitespace = false +[*.plist] +end_of_line = lf + [AppRun] end_of_line = lf diff --git a/Packaging/apple/Info.plist b/Packaging/apple/Info.plist index 91e32a9810c..52754cc115c 100644 --- a/Packaging/apple/Info.plist +++ b/Packaging/apple/Info.plist @@ -39,7 +39,7 @@ NSHumanReadableCopyright ${MACOSX_BUNDLE_COPYRIGHT} SDL_FILESYSTEM_BASE_DIR_TYPE - parent + resource NSSupportsAutomaticGraphicsSwitching UIApplicationSupportsIndirectInputEvents diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index f6276943606..07a4dde8cd1 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -335,6 +335,13 @@ if(USE_SDL1) target_link_libraries(DevilutionX::SDL INTERFACE libdevilutionx_sdl2_to_1_2_backports ) + if(APPLE) + enable_language(OBJC) + target_sources(libdevilutionx_sdl2_to_1_2_backports PRIVATE + platform/macos_sdl1/SDL_filesystem.m) + target_link_libraries(libdevilutionx_sdl2_to_1_2_backports PRIVATE + "-framework Foundation") + endif() endif() add_devilutionx_object_library(libdevilutionx_codec diff --git a/Source/init.cpp b/Source/init.cpp index 1e6488d58f7..02eafbc9d5c 100644 --- a/Source/init.cpp +++ b/Source/init.cpp @@ -130,7 +130,7 @@ std::vector GetMPQSearchPaths() if (paths[0] == paths[1] || (paths.size() == 3 && (paths[0] == paths[2] || paths[1] == paths[2]))) paths.pop_back(); -#if defined(__unix__) && !defined(__ANDROID__) +#if (defined(__unix__) || defined(__APPLE__)) && !defined(__ANDROID__) // `XDG_DATA_HOME` is usually the root path of `paths::PrefPath()`, so we only // add `XDG_DATA_DIRS`. const char *xdgDataDirs = std::getenv("XDG_DATA_DIRS"); diff --git a/Source/platform/macos_sdl1/SDL_filesystem.m b/Source/platform/macos_sdl1/SDL_filesystem.m new file mode 100644 index 00000000000..1bf4ed6e93d --- /dev/null +++ b/Source/platform/macos_sdl1/SDL_filesystem.m @@ -0,0 +1,138 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + An altered version based on: + https://github.com/libsdl-org/SDL/blob/3c142abcb2b0b0ad7e08b096ea8d9a1a1e1af1ef/src/filesystem/cocoa/SDL_sysfilesystem.m + + Modifications: + 1. Changes to compile with gcc (@autoreleasepool -> NSAutoreleasePool) + 2. Targets SDL-1.2 rather than SDL2 (SDL_InvalidParamError -> SDL_SetError) +*/ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* System dependent filesystem routines */ + +#include +#include +#include + +#include + +char *SDL_GetBasePath(void) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSBundle *bundle = [NSBundle mainBundle]; + const char *baseType = [[[bundle infoDictionary] objectForKey:@"SDL_FILESYSTEM_BASE_DIR_TYPE"] UTF8String]; + const char *base = NULL; + char *retval = NULL; + + if (baseType == NULL) { + baseType = "resource"; + } + if (SDL_strcasecmp(baseType, "bundle") == 0) { + base = [[bundle bundlePath] fileSystemRepresentation]; + } else if (SDL_strcasecmp(baseType, "parent") == 0) { + base = [[[bundle bundlePath] stringByDeletingLastPathComponent] fileSystemRepresentation]; + } else { + /* this returns the exedir for non-bundled and the resourceDir for bundled apps */ + base = [[bundle resourcePath] fileSystemRepresentation]; + } + + if (base) { + const size_t len = SDL_strlen(base) + 2; + retval = (char *)SDL_malloc(len); + if (retval == NULL) { + SDL_OutOfMemory(); + } else { + SDL_snprintf(retval, len, "%s/", base); + } + } + + [pool drain]; + return retval; +} + +char *SDL_GetPrefPath(const char *org, const char *app) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + char *retval = NULL; + NSArray *array; + + if (!app) { + SDL_SetError("SDL_GetPrefPath: app argument cannot be null"); + return NULL; + } + if (!org) { + org = ""; + } + +#if !TARGET_OS_TV + array = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES); +#else + /* tvOS does not have persistent local storage! + * The only place on-device where we can store data is + * a cache directory that the OS can empty at any time. + * + * It's therefore very likely that save data will be erased + * between sessions. If you want your app's save data to + * actually stick around, you'll need to use iCloud storage. + */ + { + static SDL_bool shown = SDL_FALSE; + if (!shown) { + shown = SDL_TRUE; + SDL_LogCritical(SDL_LOG_CATEGORY_SYSTEM, "tvOS does not have persistent local storage! Use iCloud storage if you want your data to persist between sessions.\n"); + } + } + + array = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); +#endif /* !TARGET_OS_TV */ + + if ([array count] > 0) { /* we only want the first item in the list. */ + NSString *str = [array objectAtIndex:0]; + const char *base = [str fileSystemRepresentation]; + if (base) { + const size_t len = SDL_strlen(base) + SDL_strlen(org) + SDL_strlen(app) + 4; + retval = (char *)SDL_malloc(len); + if (retval == NULL) { + SDL_OutOfMemory(); + } else { + char *ptr; + if (*org) { + SDL_snprintf(retval, len, "%s/%s/%s/", base, org, app); + } else { + SDL_snprintf(retval, len, "%s/%s/", base, app); + } + for (ptr = retval + 1; *ptr; ptr++) { + if (*ptr == '/') { + *ptr = '\0'; + mkdir(retval, 0700); + *ptr = '/'; + } + } + mkdir(retval, 0700); + } + } + } + + [pool drain]; + return retval; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/utils/paths.cpp b/Source/utils/paths.cpp index a5bd0db8560..d0f680555b8 100644 --- a/Source/utils/paths.cpp +++ b/Source/utils/paths.cpp @@ -1,5 +1,9 @@ #include "utils/paths.h" +#include +#include +#include + #include #include "appfat.h" @@ -130,6 +134,23 @@ const std::string &AssetsPath() assetsPath.emplace("D:\\assets\\"); #elif defined(__3DS__) || defined(__SWITCH__) assetsPath.emplace("romfs:/"); +#elif defined(__APPLE__) && defined(USE_SDL1) + // In `Info.plist` we have + // + // SDL_FILESYSTEM_BASE_DIR_TYPE + // resource + // + // This means `SDL_GetBasePath()` returns exedir for non-bundled + // and the `app_dir.app/Resources/` for bundles. + // + // Our built-in resources are directly in the `devilutionx.app/Resources` directory + // and are normally looked up via a relative lookup in `FindAsset`. + // In SDL2, this is implemented by calling `SDL_OpenFPFromBundleOrFallback` + // from `SDL_RWFromFile` but SDL1 doesn't do it, so we set the directory explicitly. + // + // Note that SDL3 reverts to SDL1 behaviour! + // https://github.com/libsdl-org/SDL/blob/962268ca21ed10b9cee31198c22681099293f20a/docs/README-migration.md?plain=1#L1623 + assetsPath.emplace(FromSDL(SDL_GetBasePath())); #else assetsPath.emplace(FromSDL(SDL_GetBasePath()) + ("assets" DIRECTORY_SEPARATOR_STR)); #endif diff --git a/Source/utils/paths.h b/Source/utils/paths.h index ca4cc36003b..35edfec3052 100644 --- a/Source/utils/paths.h +++ b/Source/utils/paths.h @@ -1,6 +1,5 @@ #pragma once -#include #include namespace devilution { diff --git a/Source/utils/sdl2_to_1_2_backports.cpp b/Source/utils/sdl2_to_1_2_backports.cpp index ee47b5d7260..f8de050bebd 100644 --- a/Source/utils/sdl2_to_1_2_backports.cpp +++ b/Source/utils/sdl2_to_1_2_backports.cpp @@ -544,7 +544,7 @@ int WIN_SetError(const char *prefix) } // namespace -char *SDL_GetBasePath(void) +extern "C" char *SDL_GetBasePath(void) { // From sdl2-2.0.9/src/filesystem/windows/SDL_sysfilesystem.c @@ -611,7 +611,7 @@ char *SDL_GetBasePath(void) return retval; } -char *SDL_GetPrefPath(const char *org, const char *app) +extern "C" char *SDL_GetPrefPath(const char *org, const char *app) { // From sdl2-2.0.9/src/filesystem/windows/SDL_sysfilesystem.c @@ -699,7 +699,8 @@ char *SDL_GetPrefPath(const char *org, const char *app) return retval; } -#else +// For Apple, definitions are in Source/platform/macos_sdl1/SDL_filesystem.m +#elif !defined(__APPLE__) namespace { #if !defined(__QNXNTO__) && !defined(__amigaos__) && !(defined(WINVER) && WINVER <= 0x0500 && (!defined(_WIN32_WINNT) || _WIN32_WINNT == 0)) @@ -736,7 +737,7 @@ char *readSymLink(const char *path) #endif } // namespace -char *SDL_GetBasePath() +extern "C" char *SDL_GetBasePath() { // From sdl2-2.0.9/src/filesystem/unix/SDL_sysfilesystem.c @@ -851,7 +852,7 @@ char *SDL_GetBasePath() return retval; } -char *SDL_GetPrefPath(const char *org, const char *app) +extern "C" char *SDL_GetPrefPath(const char *org, const char *app) { // From sdl2-2.0.9/src/filesystem/unix/SDL_sysfilesystem.c /* diff --git a/Source/utils/sdl2_to_1_2_backports.h b/Source/utils/sdl2_to_1_2_backports.h index a1b9e31d574..e089a5101d9 100644 --- a/Source/utils/sdl2_to_1_2_backports.h +++ b/Source/utils/sdl2_to_1_2_backports.h @@ -322,5 +322,5 @@ int SDL_BlitScaled(SDL_Surface *src, SDL_Rect *srcrect, Sint64 SDL_RWsize(SDL_RWops *context); -char *SDL_GetBasePath(); -char *SDL_GetPrefPath(const char *org, const char *app); +extern "C" char *SDL_GetBasePath(); +extern "C" char *SDL_GetPrefPath(const char *org, const char *app); From 07d243201f8d7f8150a93e73fb5ddd31b84a85c9 Mon Sep 17 00:00:00 2001 From: Gleb Mazovetskiy Date: Wed, 11 Dec 2024 03:04:48 +0000 Subject: [PATCH 7/7] Work around broken event pushing on Tiger Pushing events from a background thread on Tiger + SDL1 does not appear to do anything at all. I don't know if the issue is limited to Tiger, so apply the workaround on all macOS when using SDL1. --- Source/interfac.cpp | 77 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 67 insertions(+), 10 deletions(-) diff --git a/Source/interfac.cpp b/Source/interfac.cpp index 33777b571fb..94144901f09 100644 --- a/Source/interfac.cpp +++ b/Source/interfac.cpp @@ -37,6 +37,23 @@ namespace devilution { namespace { +#if defined(__APPLE__) && defined(USE_SDL1) +// On Tiger PPC, SDL_PushEvent from a background thread appears to do nothing. +#define SDL_PUSH_EVENT_BG_THREAD_WORKS 0 +#else +#define SDL_PUSH_EVENT_BG_THREAD_WORKS 1 +#endif + +#if !SDL_PUSH_EVENT_BG_THREAD_WORKS +// This workaround is not completely thread-safe but the worst +// that can happen is we miss some WM_PROGRESS events, +// which is not a problem. +struct { + std::atomic type; + std::string error; +} NextCustomEvent; +#endif + constexpr uint32_t MaxProgress = 534; constexpr uint32_t ProgressStepSize = 23; @@ -391,16 +408,31 @@ void DoLoad(interface_mode uMsg) } if (!loadResult.has_value()) { +#if SDL_PUSH_EVENT_BG_THREAD_WORKS SDL_Event event; event.type = CustomEventToSdlEvent(WM_ERROR); event.user.data1 = new std::string(std::move(loadResult).error()); - SDL_PushEvent(&event); + if (SDL_PushEvent(&event) < 0) { + LogError("Failed to send WM_ERROR {}", SDL_GetError()); + SDL_ClearError(); + } +#else + NextCustomEvent.error = std::move(loadResult).error(); + NextCustomEvent.type = static_cast(WM_ERROR); +#endif return; } +#if SDL_PUSH_EVENT_BG_THREAD_WORKS SDL_Event event; event.type = CustomEventToSdlEvent(WM_DONE); - SDL_PushEvent(&event); + if (SDL_PushEvent(&event) < 0) { + LogError("Failed to send WM_DONE {}", SDL_GetError()); + SDL_ClearError(); + } +#else + NextCustomEvent.type = static_cast(WM_DONE); +#endif } struct { @@ -561,9 +593,16 @@ void IncProgress(uint32_t steps) if (sgdwProgress > MaxProgress) sgdwProgress = MaxProgress; if (!HeadlessMode && sgdwProgress != prevProgress) { +#if SDL_PUSH_EVENT_BG_THREAD_WORKS SDL_Event event; event.type = CustomEventToSdlEvent(WM_PROGRESS); - SDL_PushEvent(&event); + if (SDL_PushEvent(&event) < 0) { + LogError("Failed to send WM_PROGRESS {}", SDL_GetError()); + SDL_ClearError(); + } +#else + NextCustomEvent.type = static_cast(WM_PROGRESS); +#endif } } @@ -589,6 +628,10 @@ void ShowProgress(interface_mode uMsg) ProgressEventHandlerState.done = false; ProgressEventHandlerState.drawnProgress = 0; +#if !SDL_PUSH_EVENT_BG_THREAD_WORKS + NextCustomEvent.type = -1; +#endif + #ifndef USE_SDL1 DeactivateVirtualGamepad(); FreeVirtualGamepadTextures(); @@ -623,21 +666,35 @@ void ShowProgress(interface_mode uMsg) LogVerbose("Load thread finished in {}ms", SDL_GetTicks() - start); }); + const auto processEvent = [&](const SDL_Event &event) { + CheckShouldSkipRendering(); + if (event.type != SDL_QUIT) { + HandleMessage(event, SDL_GetModState()); + } + if (ProgressEventHandlerState.done) { + loadThread.join(); + return false; + } + return true; + }; + while (true) { CheckShouldSkipRendering(); SDL_Event event; // We use the real `SDL_PollEvent` here instead of `FetchEvent` // to process real events rather than the recorded ones in demo mode. while (SDL_PollEvent(&event)) { - CheckShouldSkipRendering(); - if (event.type != SDL_QUIT) { - HandleMessage(event, SDL_GetModState()); - } - if (ProgressEventHandlerState.done) { - loadThread.join(); - return; + if (!processEvent(event)) return; + } +#if !SDL_PUSH_EVENT_BG_THREAD_WORKS + if (const int customEventType = NextCustomEvent.type.exchange(-1); customEventType != -1) { + event.type = CustomEventToSdlEvent(static_cast(customEventType)); + if (static_cast(customEventType) == static_cast(WM_ERROR)) { + event.user.data1 = &NextCustomEvent.error; } + if (!processEvent(event)) return; } +#endif } }