diff --git a/CMakeLists.txt b/CMakeLists.txt index 7793b4b1..f8d3b0b6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -110,7 +110,11 @@ if(DETHRACE_INSTALL) set(CPACK_PACKAGE_DIRECTORY dist) - if(MSVC) + if(APPLE) + set(CPACK_DMG_DISABLE_APPLICATIONS_SYMLINK "ON") + set(CPACK_GENERATOR "DragNDrop") + set(ext ".dmg") + elseif(MSVC) set(CPACK_GENERATOR ZIP) set(ext ".zip") else() diff --git a/packaging/icon_source.png b/packaging/icon_source.png new file mode 100644 index 00000000..de75fa50 Binary files /dev/null and b/packaging/icon_source.png differ diff --git a/packaging/macos/dethrace.icns b/packaging/macos/dethrace.icns new file mode 100644 index 00000000..6328e854 Binary files /dev/null and b/packaging/macos/dethrace.icns differ diff --git a/packaging/macos/generate_icns.sh b/packaging/macos/generate_icns.sh new file mode 100755 index 00000000..ef48728c --- /dev/null +++ b/packaging/macos/generate_icns.sh @@ -0,0 +1,40 @@ +#!/bin/sh +set -e + +SOURCE_IMAGE=$1 +TEMP_ICON_IMAGE=icon.png + +# resize to 412x with black canvas +convert ${SOURCE_IMAGE} -resize 412x412 -background Black -gravity center -extent 412x412 ${TEMP_ICON_IMAGE} + +# add rounded corners +convert ${TEMP_ICON_IMAGE} \ + \( +clone -alpha extract \ + -draw 'fill black polygon 0,0 0,50 50,0 fill white circle 50,50 50,0' \ + \( +clone -flip \) -compose Multiply -composite \ + \( +clone -flop \) -compose Multiply -composite \ + \) -alpha off -compose CopyOpacity -composite ${TEMP_ICON_IMAGE} + +# add margin +convert ${TEMP_ICON_IMAGE} -bordercolor transparent -border 40x40 ${TEMP_ICON_IMAGE} + +# add drop shadow +convert ${TEMP_ICON_IMAGE} \ + \( +clone -background black -shadow 100x5+0+0 \) +swap \ + -background none -layers merge +repage ${TEMP_ICON_IMAGE} + + +rm -r dethrace.iconset || true +mkdir -p dethrace.iconset +sips -z 16 16 ${TEMP_ICON_IMAGE} --out dethrace.iconset/icon_16x16.png +sips -z 32 32 ${TEMP_ICON_IMAGE} --out dethrace.iconset/icon_16x16@2x.png +sips -z 32 32 ${TEMP_ICON_IMAGE} --out dethrace.iconset/icon_32x32.png +sips -z 64 64 ${TEMP_ICON_IMAGE} --out dethrace.iconset/icon_32x32@2x.png +sips -z 128 128 ${TEMP_ICON_IMAGE} --out dethrace.iconset/icon_128x128.png +sips -z 256 256 ${TEMP_ICON_IMAGE} --out dethrace.iconset/icon_128x128@2x.png +sips -z 256 256 ${TEMP_ICON_IMAGE} --out dethrace.iconset/icon_256x256.png +sips -z 512 512 ${TEMP_ICON_IMAGE} --out dethrace.iconset/icon_256x256@2x.png +sips -z 512 512 ${TEMP_ICON_IMAGE} --out dethrace.iconset/icon_512x512.png +sips -z 1024 1024 ${TEMP_ICON_IMAGE} --out dethrace.iconset/icon_512x512@2x.png +iconutil -c icns dethrace.iconset +rm -r dethrace.iconset ${TEMP_ICON_IMAGE} diff --git a/packaging/windows/dethrace.ico b/packaging/windows/dethrace.ico new file mode 100644 index 00000000..31b170b3 Binary files /dev/null and b/packaging/windows/dethrace.ico differ diff --git a/packaging/windows/dethrace.rc b/packaging/windows/dethrace.rc new file mode 100644 index 00000000..c1ca05f3 --- /dev/null +++ b/packaging/windows/dethrace.rc @@ -0,0 +1 @@ +IDI_ICON1 ICON DISCARDABLE "dethrace.ico" diff --git a/packaging/windows/generate_ico.sh b/packaging/windows/generate_ico.sh new file mode 100755 index 00000000..aed9a8bd --- /dev/null +++ b/packaging/windows/generate_ico.sh @@ -0,0 +1,12 @@ +#!/bin/sh +set -e + +SOURCE_IMAGE=$1 +TEMP_ICON_IMAGE=icon.png + +# resize to 412x with black canvas +convert ${SOURCE_IMAGE} -resize 412x412 -background Black -gravity center -extent 412x412 ${TEMP_ICON_IMAGE} +# convert to ico format +convert -background transparent ${TEMP_ICON_IMAGE} -define icon:auto-resize=16,24,32,48,64,72,96,128,256 "dethrace.ico" + +rm ${TEMP_ICON_IMAGE} diff --git a/src/DETHRACE/CMakeLists.txt b/src/DETHRACE/CMakeLists.txt index c679a5cf..81734494 100644 --- a/src/DETHRACE/CMakeLists.txt +++ b/src/DETHRACE/CMakeLists.txt @@ -16,7 +16,7 @@ target_include_directories(dethrace_obj target_link_libraries(dethrace_obj PUBLIC SDL2::SDL2 smackw32 harness BRender::Full BRender::DDI s3) -if (CMAKE_C_COMPILER_ID MATCHES "MSVC") +if(MSVC) target_compile_definitions(dethrace_obj PRIVATE -D_CRT_SECURE_NO_WARNINGS) target_compile_options(dethrace_obj PRIVATE /wd4101 @@ -167,13 +167,16 @@ target_sources(dethrace_obj PRIVATE ) # Create our main game binary. -add_executable(dethrace) +add_executable(dethrace + WIN32 + ${CMAKE_SOURCE_DIR}/packaging/macos/dethrace.icns + ${CMAKE_SOURCE_DIR}/packaging/windows/dethrace.rc +) + target_link_libraries(dethrace PRIVATE dethrace_obj compile_with_werror) target_sources(dethrace PRIVATE main.c) -if(NOT MSVC) - -else() +if(MSVC) target_link_libraries(dethrace PRIVATE dbghelp) target_link_options(dethrace PRIVATE /subsystem:windows /ENTRY:mainCRTStartup) target_compile_definitions(dethrace PRIVATE -D_CRT_SECURE_NO_WARNINGS -DSDL_MAIN_HANDLED -DWIN32_LEAN_AND_MEAN) @@ -193,18 +196,49 @@ if(DETHRACE_IDE_ARGUMENTS) ) endif() -if (DETHRACE_INSTALL) +if(DETHRACE_INSTALL) install(TARGETS dethrace - RUNTIME DESTINATION "." + BUNDLE DESTINATION . COMPONENT Runtime + RUNTIME DESTINATION . COMPONENT Runtime ) + + if(APPLE) + set_target_properties(dethrace PROPERTIES + BUNDLE True + MACOSX_BUNDLE True + MACOSX_BUNDLE_DISPLAY_NAME "Deth Race" + OUTPUT_NAME "Deth Race" + MACOSX_BUNDLE_BUNDLE_VERSION ${DETHRACE_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${DETHRACE_VERSION} + MACOSX_BUNDLE_ICON_FILE dethrace.icns + ) + set_source_files_properties(${CMAKE_SOURCE_DIR}/packaging/macos/dethrace.icns PROPERTIES + MACOSX_PACKAGE_LOCATION "Resources" + ) + target_sources(dethrace_obj PRIVATE + ${CMAKE_SOURCE_DIR}/packaging/macos/dethrace.icns + ) + + install(CODE " + include(BundleUtilities) + fixup_bundle(\"${CMAKE_BINARY_DIR}/Deth Race.app\" \"\" \"/Library/Frameworks\") + execute_process(COMMAND + codesign -s - -f \"${CMAKE_BINARY_DIR}/Deth Race.app/Contents/Frameworks/SDL2.framework\" + ) + " + COMPONENT RUNTIME + ) + + endif() + if(MSVC) - INSTALL(FILES $ + install(FILES $ DESTINATION "." OPTIONAL ) endif() if(WIN32) - INSTALL(FILES $ + install(FILES $ DESTINATION "." OPTIONAL ) diff --git a/src/harness/harness.c b/src/harness/harness.c index e434090e..a428239a 100644 --- a/src/harness/harness.c +++ b/src/harness/harness.c @@ -175,7 +175,7 @@ void Harness_Init(int* argc, char* argv[]) { if (root_dir != NULL) { LOG_INFO("DETHRACE_ROOT_DIR is set to '%s'", root_dir); } else { - root_dir = OS_Dirname(argv[0]); + root_dir = OS_GetWorkingDirectory(argv[0]); } // if root_dir is null or empty, no need to chdir if (root_dir != NULL && root_dir[0] != '\0') { diff --git a/src/harness/include/harness/os.h b/src/harness/include/harness/os.h index 1ffac19a..404c36ce 100644 --- a/src/harness/include/harness/os.h +++ b/src/harness/include/harness/os.h @@ -34,4 +34,6 @@ char* OS_Dirname(const char* path); char* OS_Basename(const char* path); +char* OS_GetWorkingDirectory(char* argv0); + #endif diff --git a/src/harness/os/linux.c b/src/harness/os/linux.c index 6436e2c7..0c1b0445 100644 --- a/src/harness/os/linux.c +++ b/src/harness/os/linux.c @@ -319,3 +319,7 @@ char* OS_Basename(const char* path) { strcpy(name_buf, path); return basename(name_buf); } + +char* OS_GetWorkingDirectory(char* argv0) { + return OS_Dirname(argv0); +} diff --git a/src/harness/os/macos.c b/src/harness/os/macos.c index 4e9d4191..c6cd7f2d 100644 --- a/src/harness/os/macos.c +++ b/src/harness/os/macos.c @@ -249,3 +249,13 @@ char* OS_Basename(const char* path) { strcpy(name_buf, path); return basename(name_buf); } + +char* OS_GetWorkingDirectory(char* argv0) { + // The application executable in a MacOS bundle is in /Contents/MacOS/executable + // We strip off the bundle paths to get the path that the is located in + char* bundlePath = strstr(argv0, ".app/Contents/MacOS"); + if (bundlePath != NULL) { + *bundlePath = '\0'; + } + return OS_Dirname(argv0); +} diff --git a/src/harness/os/windows.c b/src/harness/os/windows.c index 104749f2..81f32070 100644 --- a/src/harness/os/windows.c +++ b/src/harness/os/windows.c @@ -185,3 +185,7 @@ char* OS_Basename(const char* path) { _splitpath(path, NULL, NULL, fname_buf, NULL); return fname_buf; } + +char* OS_GetWorkingDirectory(char* argv0) { + return OS_Dirname(argv0); +}