Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

macOS Tiger platform and instructions #7578

Merged
merged 7 commits into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ end_of_line = crlf
[*.tsv]
trim_trailing_whitespace = false

[*.plist]
end_of_line = lf

[AppRun]
end_of_line = lf

Expand Down
7 changes: 6 additions & 1 deletion 3rdParty/Lua/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions 3rdParty/googletest/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
12 changes: 12 additions & 0 deletions CMake/Platforms.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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()
20 changes: 20 additions & 0 deletions CMake/platforms/macos_tiger.cmake
Original file line number Diff line number Diff line change
@@ -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)
30 changes: 30 additions & 0 deletions CMake/platforms/macports/finders/FindMacportsLegacySupport.cmake
Original file line number Diff line number Diff line change
@@ -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()
12 changes: 9 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand All @@ -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 ./)
Expand Down
Binary file added Packaging/apple/AppIcon_128.icns
Binary file not shown.
2 changes: 1 addition & 1 deletion Packaging/apple/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
<key>NSHumanReadableCopyright</key>
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
<key>SDL_FILESYSTEM_BASE_DIR_TYPE</key>
<string>parent</string>
<string>resource</string>
<key>NSSupportsAutomaticGraphicsSwitching</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
Expand Down
7 changes: 7 additions & 0 deletions Source/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion Source/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ std::vector<std::string> 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");
Expand Down
77 changes: 67 additions & 10 deletions Source/interfac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<int> type;
std::string error;
} NextCustomEvent;
#endif

constexpr uint32_t MaxProgress = 534;
constexpr uint32_t ProgressStepSize = 23;

Expand Down Expand Up @@ -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<int>(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<int>(WM_DONE);
#endif
}

struct {
Expand Down Expand Up @@ -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<int>(WM_PROGRESS);
#endif
}
}

Expand All @@ -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();
Expand Down Expand Up @@ -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<interface_mode>(customEventType));
if (static_cast<interface_mode>(customEventType) == static_cast<int>(WM_ERROR)) {
event.user.data1 = &NextCustomEvent.error;
}
if (!processEvent(event)) return;
}
#endif
}
}

Expand Down
Loading
Loading