Skip to content

Commit 2fc976c

Browse files
Add native macOS (Apple Silicon) support
Support mac-os (apple silicon) target. Step 1 of 2 that results in a native Apple application Full disclosure - this was built with conjunction with Claude - but not pure vibe coded. I've reviewed and adjusted much of it once I broke the back of the problem. Locally I have a full working app, which will be delivered by a subsequent PR for PathOfBuilding-PoE2. ## Notable Changes (non-exhaustive) **LuaJIT:** Bumped to include arm64 mcode_alloc fixes. See: LuaJIT/LuaJIT#285 Without this, the resulting mac build had significant performance issues **Retina:** Changed the relevant cursor coordinates to support retina displays. Otherwise mouseclicks, and tooltip rendering windows were being cut off. **Clang:** Support for clang compilation, whilst maintaining MSVC ## Verification Built on OS X 26.5, and on Win. Both result in success and a working application
1 parent c062b29 commit 2fc976c

27 files changed

Lines changed: 977 additions & 27 deletions

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
patches/* -text

CMakeLists.txt

Lines changed: 55 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -78,18 +78,18 @@ set(SIMPLEGRAPHIC_SOURCES
7878

7979
set (SIMPLEGRAPHIC_PLATFORM_SOURCES)
8080
if (APPLE)
81-
set (SIMPLEGRAPHIC_PLATFORM_SOURCES
81+
list (APPEND SIMPLEGRAPHIC_PLATFORM_SOURCES
8282
"engine/system/win/sys_macos.mm"
8383
)
8484
endif()
8585

8686
if (WIN32)
87-
set (SIMPLEGRAPHIC_PLATFORM_SOURCES
87+
list (APPEND SIMPLEGRAPHIC_PLATFORM_SOURCES
8888
"engine/system/win/sys_console.cpp"
8989
"SimpleGraphic.rc"
9090
)
9191
else()
92-
set (SIMPLEGRAPHIC_PLATFORM_SOURCES
92+
list (APPEND SIMPLEGRAPHIC_PLATFORM_SOURCES
9393
"engine/system/win/sys_console_unix.cpp"
9494
)
9595
endif()
@@ -131,6 +131,12 @@ find_package(zstd REQUIRED)
131131
find_package(ZLIB REQUIRED)
132132
find_package(WebP)
133133

134+
if (TARGET zstd::libzstd_shared)
135+
set(ZSTD_LIBRARY zstd::libzstd_shared)
136+
else ()
137+
set(ZSTD_LIBRARY zstd::libzstd_static)
138+
endif ()
139+
134140
add_library(cmp_core STATIC
135141
dep/compressonator/cmp_core/source/cmp_core.cpp
136142
dep/compressonator/cmp_core/source/cmp_core.h
@@ -240,7 +246,7 @@ target_link_libraries(SimpleGraphic
240246
Threads::Threads
241247
WebP::webpdecoder
242248
ZLIB::ZLIB
243-
zstd::libzstd_shared
249+
${ZSTD_LIBRARY}
244250
)
245251

246252
install(FILES $<TARGET_RUNTIME_DLLS:SimpleGraphic> DESTINATION ".")
@@ -277,6 +283,35 @@ if (WIN32)
277283
endif ()
278284

279285

286+
find_package(Git QUIET)
287+
if (NOT GIT_EXECUTABLE)
288+
set(GIT_EXECUTABLE git)
289+
endif ()
290+
291+
function(apply_submodule_patch SUBMODULE_DIR PATCH_FILE)
292+
execute_process(
293+
COMMAND ${GIT_EXECUTABLE} -C ${SUBMODULE_DIR} apply --ignore-whitespace --reverse --check ${PATCH_FILE}
294+
RESULT_VARIABLE _patch_in_place
295+
OUTPUT_QUIET ERROR_QUIET
296+
)
297+
if (NOT _patch_in_place EQUAL 0)
298+
execute_process(
299+
COMMAND ${GIT_EXECUTABLE} -C ${SUBMODULE_DIR} apply --ignore-whitespace ${PATCH_FILE}
300+
RESULT_VARIABLE _patch_result
301+
)
302+
if (NOT _patch_result EQUAL 0)
303+
message(FATAL_ERROR "Failed to apply ${PATCH_FILE}")
304+
endif ()
305+
message(STATUS "Applied patch: ${PATCH_FILE}")
306+
endif ()
307+
endfunction()
308+
309+
apply_submodule_patch(
310+
${CMAKE_CURRENT_SOURCE_DIR}/libs/Lua-cURLv3
311+
${CMAKE_CURRENT_SOURCE_DIR}/patches/Lua-cURLv3-skip-luaL_setfuncs-on-luajit.patch
312+
)
313+
314+
280315
# lcurl module
281316

282317
set(LCURL_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libs/Lua-cURLv3)
@@ -301,10 +336,12 @@ install(FILES $<TARGET_RUNTIME_DLLS:lcurl> DESTINATION ".")
301336

302337
add_library(lua-utf8 SHARED libs/luautf8/lutf8lib.c)
303338

304-
target_compile_definitions(lua-utf8
305-
PRIVATE
306-
LUA_BUILD_AS_DLL
307-
)
339+
if (WIN32)
340+
target_compile_definitions(lua-utf8
341+
PRIVATE
342+
LUA_BUILD_AS_DLL
343+
)
344+
endif ()
308345

309346
target_include_directories(lua-utf8
310347
PRIVATE
@@ -333,9 +370,14 @@ add_library(luasocket SHARED
333370
"libs/luasocket/src/tcp.c"
334371
"libs/luasocket/src/timeout.c"
335372
"libs/luasocket/src/udp.c"
336-
"libs/luasocket/src/wsocket.c"
337373
)
338374

375+
if (WIN32)
376+
target_sources(luasocket PRIVATE "libs/luasocket/src/wsocket.c")
377+
else ()
378+
target_sources(luasocket PRIVATE "libs/luasocket/src/usocket.c")
379+
endif ()
380+
339381
target_include_directories(luasocket
340382
PRIVATE
341383
${LSOCKET_SOURCE_DIR}/src
@@ -344,10 +386,12 @@ target_include_directories(luasocket
344386
target_link_libraries(luasocket
345387
PRIVATE
346388
LuaJIT::LuaJIT
347-
wsock32
348-
ws2_32
349389
)
350390

391+
if (WIN32)
392+
target_link_libraries(luasocket PRIVATE wsock32 ws2_32)
393+
endif ()
394+
351395
set_target_properties( luasocket PROPERTIES OUTPUT_NAME "socket" )
352396
install(TARGETS luasocket RUNTIME DESTINATION ".")
353397
install(FILES $<TARGET_RUNTIME_DLLS:luasocket> DESTINATION ".")

cmake/FindLuaJIT.cmake

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ if (DEFINED VCPKG_INSTALLED_DIR AND DEFINED VCPKG_TARGET_TRIPLET)
99

1010
find_path(LuaJIT_INCLUDE_DIR luajit.h
1111
PATHS ${LuaJIT_SEARCH_ROOT}/include
12-
PATH_SUFFIXES luajit
12+
PATH_SUFFIXES luajit luajit-2.0 luajit-2.1
1313
NO_DEFAULT_PATH)
1414

15-
find_library(LuaJIT_LIBRARY_RELEASE NAMES lua51
15+
find_library(LuaJIT_LIBRARY_RELEASE NAMES lua51 luajit-5.1
1616
PATHS ${LuaJIT_SEARCH_ROOT}
1717
PATH_SUFFIXES lib
1818
NO_DEFAULT_PATH)
1919

20-
find_library(LuaJIT_LIBRARY_DEBUG NAMES lua51
20+
find_library(LuaJIT_LIBRARY_DEBUG NAMES lua51 luajit-5.1
2121
PATHS ${LuaJIT_SEARCH_ROOT}
2222
PATH_SUFFIXES debug/lib
2323
NO_DEFAULT_PATH)

engine/common/base64.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "base64.h"
3030

3131
#include <stdlib.h>
32+
#include <string.h>
3233

3334
/* ---- Base64 Encoding/Decoding Table --- */
3435
/* Padding character string starts at offset 64. */

engine/common/base64.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
// Modified for standalone inclusion in SimpleGraphic.
2727

2828
#include <stdbool.h>
29+
#include <stddef.h>
2930

3031
#ifdef __cplusplus
3132
extern "C" {

engine/common/common.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,8 @@ char* NarrowUTF8String(const wchar_t* str)
437437
return NarrowCodepageString(str, CP_UTF8);
438438
}
439439

440+
#endif
441+
440442
IndexedUTF32String IndexUTF8ToUTF32(std::string_view input)
441443
{
442444
IndexedUTF32String ret{};
@@ -500,5 +502,3 @@ IndexedUTF32String IndexUTF8ToUTF32(std::string_view input)
500502
ret.text = std::u32string(codepoints.begin(), codepoints.end());
501503
return ret;
502504
}
503-
504-
#endif

engine/render/r_font.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ r_font_c::FontHeightEntry r_font_c::FindFontHeight(int height) {
321321
void r_font_c::DrawTextLine(scp_t pos, int align, int height, col4_t col, std::u32string_view str)
322322
{
323323
// Check if the line is visible
324-
if (pos[Y] >= renderer->sys->video->vid.size[1] || pos[Y] <= -height) {
324+
if (pos[Y] >= renderer->VirtualScreenHeight() || pos[Y] <= -height) {
325325
// Just process the colour codes
326326
while (!str.empty()) {
327327
// Check for escape character

engine/render/r_main.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212

1313
#include <algorithm>
1414
#include <array>
15+
#include <chrono>
16+
#include <thread>
1517
#include <filesystem>
1618
#include <fmt/chrono.h>
1719
#include <future>
@@ -1640,7 +1642,7 @@ void r_renderer_c::GetShaderImageSize(r_shaderHnd_c* hnd, int& width, int& heigh
16401642
if (hnd)
16411643
{
16421644
while (hnd->sh->tex->status < r_tex_c::SIZE_KNOWN) {
1643-
Sleep(1);
1645+
std::this_thread::sleep_for(std::chrono::milliseconds(1));
16441646
}
16451647
width = hnd->sh->tex->fileWidth;
16461648
height = hnd->sh->tex->fileHeight;

engine/render/r_texture.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <mutex>
88
#include <vector>
99
#include <atomic>
10+
#include <thread>
1011
#include "r_local.h"
1112

1213
#include "cmp_core.h"
@@ -504,7 +505,7 @@ static gli::texture2d_array TranscodeTexture(gli::texture2d_array src, gli::form
504505

505506
for (size_t blockRow = 0; blockRow < srcBlocksPerRow; ++blockRow) {
506507
const size_t rowBase = blockRow * srcBlockSize.y;
507-
const size_t rowsLeft = (std::min)(4ull, dstExtent.y - rowBase);
508+
const size_t rowsLeft = (std::min)(size_t(4),dstExtent.y - rowBase);
508509

509510
for (size_t blockCol = 0; blockCol < srcBlocksPerColumn; ++blockCol) {
510511
// Read source 4x4 texel block, no branching needed.
@@ -524,7 +525,7 @@ static gli::texture2d_array TranscodeTexture(gli::texture2d_array src, gli::form
524525

525526
// Here we work off that dstData points at the top left pixel of the block row in the destination.
526527
const size_t colBase = blockCol * srcBlockSize.x;
527-
const size_t colsLeft = (std::min)(4ull, dstExtent.x - colBase);
528+
const size_t colsLeft = (std::min)(size_t(4),dstExtent.x - colBase);
528529
const size_t colBytesLeft = colsLeft * 4;
529530
for (size_t innerRow = 0; innerRow < rowsLeft; ++innerRow) {
530531
auto* dstPtr = dstData + dstRowStride * innerRow + colBase * 4;

engine/system/win/sys_video.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ sys_video_c::sys_video_c(sys_IMain* sysHnd)
115115
platformType = GLFW_ANGLE_PLATFORM_TYPE_D3D11;
116116
else // Native Windows
117117
platformType = GLFW_ANGLE_PLATFORM_TYPE_D3D11;
118+
#elif defined(__APPLE__)
119+
platformType = GLFW_ANGLE_PLATFORM_TYPE_METAL;
118120
#endif
119121
glfwInitHint(GLFW_ANGLE_PLATFORM_TYPE, platformType);
120122
glfwInit();
@@ -489,7 +491,9 @@ int sys_video_c::Apply(sys_vidSet_s* set)
489491
return;
490492
}
491493
auto video = (sys_video_c*)sys->video;
492-
video->lastCursorPos = CursorPos{ (int)x, (int)y };
494+
double sx = video->vid.size[0] > 0 ? (double)video->vid.fbSize[0] / video->vid.size[0] : 1.0;
495+
double sy = video->vid.size[1] > 0 ? (double)video->vid.fbSize[1] / video->vid.size[1] : 1.0;
496+
video->lastCursorPos = CursorPos{ (int)(x * sx), (int)(y * sy) };
493497
});
494498
glfwSetWindowCloseCallback(wnd, [](GLFWwindow* wnd) {
495499
auto sys = (sys_main_c*)glfwGetWindowUserPointer(wnd);
@@ -737,14 +741,18 @@ void sys_video_c::GetRelativeCursor(int& x, int& y)
737741
if (!initialised) return;
738742
double xpos, ypos;
739743
glfwGetCursorPos(wnd, &xpos, &ypos);
740-
x = (int)floor(xpos);
741-
y = (int)floor(ypos);
744+
double sx = vid.size[0] > 0 ? (double)vid.fbSize[0] / vid.size[0] : 1.0;
745+
double sy = vid.size[1] > 0 ? (double)vid.fbSize[1] / vid.size[1] : 1.0;
746+
x = (int)floor(xpos * sx);
747+
y = (int)floor(ypos * sy);
742748
}
743749

744750
void sys_video_c::SetRelativeCursor(int x, int y)
745751
{
746752
if (!initialised) return;
747-
glfwSetCursorPos(wnd, (double)x, (double)y);
753+
double sx = vid.fbSize[0] > 0 ? (double)vid.size[0] / vid.fbSize[0] : 1.0;
754+
double sy = vid.fbSize[1] > 0 ? (double)vid.size[1] / vid.fbSize[1] : 1.0;
755+
glfwSetCursorPos(wnd, x * sx, y * sy);
748756
}
749757

750758
bool sys_video_c::IsCursorOverWindow()

0 commit comments

Comments
 (0)