diff --git a/desktop_version/AppIcon.xcassets/AppIcon.appiconset/AppIcon.png b/desktop_version/AppIcon.xcassets/AppIcon.appiconset/AppIcon.png new file mode 100644 index 00000000..6b3a72b7 Binary files /dev/null and b/desktop_version/AppIcon.xcassets/AppIcon.appiconset/AppIcon.png differ diff --git a/desktop_version/AppIcon.xcassets/AppIcon.appiconset/Contents.json b/desktop_version/AppIcon.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..cefcc878 --- /dev/null +++ b/desktop_version/AppIcon.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,14 @@ +{ + "images" : [ + { + "filename" : "AppIcon.png", + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/desktop_version/AppIcon.xcassets/Contents.json b/desktop_version/AppIcon.xcassets/Contents.json new file mode 100644 index 00000000..73c00596 --- /dev/null +++ b/desktop_version/AppIcon.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/desktop_version/CMakeLists.txt b/desktop_version/CMakeLists.txt index f2cfa3b9..bc316c5e 100644 --- a/desktop_version/CMakeLists.txt +++ b/desktop_version/CMakeLists.txt @@ -25,7 +25,7 @@ option(REMOVE_ABSOLUTE_PATHS "If supported by the compiler, replace all absolute # Architecture Flags -if(APPLE) +if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") # Wow, Apple is a huge jerk these days huh? set(OSX_10_9_SDK_PATH /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk) if(NOT CMAKE_OSX_SYSROOT) @@ -38,6 +38,8 @@ if(APPLE) set(CMAKE_OSX_DEPLOYMENT_TARGET 10.9) link_directories(/usr/local/lib) add_compile_options(-Werror=partial-availability) +elseif(CMAKE_SYSTEM_NAME STREQUAL "iOS") + set(CMAKE_OSX_DEPLOYMENT_TARGET 12.0) # SDL goes back to iOS 8.0, but modern Xcode doesn't endif() project(VVVVVV) @@ -48,7 +50,10 @@ endif() # RPATH if(NOT WIN32) - if(APPLE) + if(CMAKE_SYSTEM_NAME STREQUAL "iOS") + set(BIN_LIBROOT "Frameworks") + set(BIN_RPATH "@executable_path/Frameworks") + elseif(APPLE) set(BIN_LIBROOT "osx") set(BIN_RPATH "@executable_path/osx") elseif(CMAKE_SIZEOF_VOID_P MATCHES "8") @@ -128,6 +133,9 @@ endif() if(GOG) list(APPEND VVV_C_SRC src/GOGNetwork.c) endif() +if(CMAKE_SYSTEM_NAME STREQUAL "iOS") + list(APPEND VVV_C_SRC src/SDL_uikit_main.c) +endif() set(VVV_SRC ${VVV_CXX_SRC} ${VVV_C_SRC}) @@ -136,6 +144,30 @@ if(WIN32) add_executable(VVVVVV WIN32 ${VVV_SRC} icon.rc) elseif(ANDROID) add_library(VVVVVV SHARED ${VVV_SRC}) +elseif(CMAKE_SYSTEM_NAME STREQUAL "iOS") + file(GLOB_RECURSE REPO_RESOURCES "fonts/*" "lang/*") + + add_executable(VVVVVV MACOSX_BUNDLE ${VVV_SRC} ${DATA_ZIP} AppIcon.xcassets ${REPO_RESOURCES}) + set_target_properties(VVVVVV PROPERTIES + XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "com.distractionware.vvvvvvmobile" + XCODE_ATTRIBUTE_PRODUCT_NAME "VVVVVV" + XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "1,2" # iPhone, iPad + XCODE_ATTRIBUTE_CURRENT_PROJECT_VERSION "2.5" + XCODE_ATTRIBUTE_MARKETING_VERSION "2.5" + XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_APPICON_NAME AppIcon + XCODE_ATTRIBUTE_GENERATE_INFOPLIST_FILE YES + MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Info.plist" + XCODE_ATTRIBUTE_INFOPLIST_KEY_LSSupportsOpeningDocumentsInPlace YES + XCODE_ATTRIBUTE_INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents YES + RESOURCE "${DATA_ZIP};AppIcon.xcassets" + ) + + foreach(REPO_FILE ${REPO_RESOURCES}) + file(RELATIVE_PATH REPO_FILE_REL "${CMAKE_CURRENT_SOURCE_DIR}" ${REPO_FILE}) + get_filename_component(REPO_FILE_DIR ${REPO_FILE_REL} DIRECTORY) + set_property(SOURCE ${REPO_FILE} PROPERTY MACOSX_PACKAGE_LOCATION "Resources/${REPO_FILE_DIR}") + source_group("Resources/${REPO_FILE_DIR}" FILES "${REPO_FILE}") + endforeach() else() add_executable(VVVVVV ${VVV_SRC}) endif() @@ -419,6 +451,15 @@ elseif (EMSCRIPTEN) target_compile_options(faudio-static PUBLIC -sUSE_SDL=2) target_link_libraries(faudio-static -sUSE_SDL=2) endif() +elseif(DEFINED SDL2_FRAMEWORK) + message(STATUS "Using pre-defined SDL2 variable SDL2_FRAMEWORK") + target_include_directories(VVVVVV SYSTEM PRIVATE "$") + target_link_libraries(VVVVVV ${SDL2_FRAMEWORK}) + if(BUNDLE_DEPENDENCIES) + target_include_directories(faudio-static SYSTEM PRIVATE "$") + target_link_libraries(faudio-static ${SDL2_FRAMEWORK}) + endif() + set_target_properties(VVVVVV PROPERTIES XCODE_EMBED_FRAMEWORKS ${SDL2_FRAMEWORK}) else() # Only try to autodetect if both SDL2 variables aren't explicitly set find_package(SDL2 CONFIG) diff --git a/desktop_version/Info.plist b/desktop_version/Info.plist new file mode 100644 index 00000000..ff579a6c --- /dev/null +++ b/desktop_version/Info.plist @@ -0,0 +1,8 @@ + + + + + UIFileSharingEnabled + + + diff --git a/desktop_version/VVVVVV-android/app/build.gradle b/desktop_version/VVVVVV-android/app/build.gradle index f1b358ce..58692135 100644 --- a/desktop_version/VVVVVV-android/app/build.gradle +++ b/desktop_version/VVVVVV-android/app/build.gradle @@ -14,8 +14,8 @@ android { defaultConfig { minSdkVersion 29 targetSdkVersion 34 - versionCode 20004000 - versionName "2.4" + versionCode 20005000 + versionName "2.5" applicationId "air.com.distractionware.vvvvvvmobile" externalNativeBuild { cmake { diff --git a/desktop_version/src/ButtonGlyphs.cpp b/desktop_version/src/ButtonGlyphs.cpp index 53171708..4abbf4ed 100644 --- a/desktop_version/src/ButtonGlyphs.cpp +++ b/desktop_version/src/ButtonGlyphs.cpp @@ -178,7 +178,7 @@ bool BUTTONGLYPHS_keyboard_is_available(void) return true; } -#ifdef __ANDROID__ +#if defined(__ANDROID__) || defined(TARGET_OS_IPHONE) return false; #else return !SDL_GetHintBoolean("SteamDeck", SDL_FALSE); diff --git a/desktop_version/src/FileSystemUtils.cpp b/desktop_version/src/FileSystemUtils.cpp index 5f61146a..cd3e6e2c 100644 --- a/desktop_version/src/FileSystemUtils.cpp +++ b/desktop_version/src/FileSystemUtils.cpp @@ -1331,6 +1331,19 @@ static int PLATFORM_getOSDirectory(char* output, const size_t output_size) } SDL_snprintf(output, output_size, "%s/", externalStoragePath); return 1; +#elif defined(TARGET_OS_IPHONE) + // (ab)use SDL APIs to get the path to the Documents folder without needing Objective-C + const char* prefsPath = SDL_GetPrefPath("", ""); + if (prefsPath == NULL) + { + vlog_error( + "Could not get OS directory: %s", + SDL_GetError() + ); + return 0; + } + SDL_snprintf(output, output_size, "%s/../../Documents/", prefsPath); + return 1; #else const char* prefDir = PHYSFS_getPrefDir("distractionware", "VVVVVV"); if (prefDir == NULL) diff --git a/desktop_version/src/Game.cpp b/desktop_version/src/Game.cpp index 6114a446..201007c2 100644 --- a/desktop_version/src/Game.cpp +++ b/desktop_version/src/Game.cpp @@ -377,7 +377,7 @@ void Game::init(void) screenshot_border_timer = 0; screenshot_saved_success = false; -#ifdef __ANDROID__ +#if defined(__ANDROID__) || defined(TARGET_OS_IPHONE) checkpoint_saving = true; #else checkpoint_saving = false; diff --git a/desktop_version/src/SDL_uikit_main.c b/desktop_version/src/SDL_uikit_main.c new file mode 100644 index 00000000..6ce34929 --- /dev/null +++ b/desktop_version/src/SDL_uikit_main.c @@ -0,0 +1,23 @@ +/* + SDL_uikit_main.c, placed in the public domain by Sam Lantinga 3/18/2019 +*/ + +/* Include the SDL main definition header */ +#include "SDL_main.h" + +#if defined(__IPHONEOS__) || defined(__TVOS__) + +#ifndef SDL_MAIN_HANDLED +#ifdef main +#undef main +#endif + +int main(int argc, char *argv[]) +{ + return SDL_UIKitRunApp(argc, argv, SDL_main); +} +#endif /* !SDL_MAIN_HANDLED */ + +#endif /* __IPHONEOS__ || __TVOS__ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/desktop_version/src/Screen.cpp b/desktop_version/src/Screen.cpp index cedf3115..6dabc8ba 100644 --- a/desktop_version/src/Screen.cpp +++ b/desktop_version/src/Screen.cpp @@ -383,7 +383,7 @@ bool Screen::isForcedFullscreen(void) * If you're working on a tenfoot-only build, add a def that always * returns true! */ -#ifdef __ANDROID__ +#if defined(__ANDROID__) || defined(TARGET_OS_IPHONE) return true; #else return SDL_GetHintBoolean("SteamTenfoot", SDL_FALSE); diff --git a/desktop_version/src/Vlogging.c b/desktop_version/src/Vlogging.c index c0d19781..8a3a730a 100644 --- a/desktop_version/src/Vlogging.c +++ b/desktop_version/src/Vlogging.c @@ -3,8 +3,9 @@ #include #include -#ifdef __ANDROID__ +#if defined(__ANDROID__) || defined(TARGET_OS_IPHONE) // forward to SDL logging on Android, since stdout/stderr are /dev/null +// they exist on iOS, but just get forwarded to the system log anyway, so might as well provide proper metadata #define VLOG_USE_SDL 1 #endif diff --git a/desktop_version/src/main.cpp b/desktop_version/src/main.cpp index 2f884ec7..4b87dbff 100644 --- a/desktop_version/src/main.cpp +++ b/desktop_version/src/main.cpp @@ -604,6 +604,8 @@ int main(int argc, char *argv[]) /* We already do the button swapping in ButtonGlyphs, disable SDL's swapping */ SDL_SetHintWithPriority(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS, "0", SDL_HINT_OVERRIDE); + SDL_SetHintWithPriority(SDL_HINT_ORIENTATIONS, "LandscapeLeft LandscapeRight", SDL_HINT_OVERRIDE); + if(!FILESYSTEM_init(argv[0], baseDir, assetsPath, langDir, fontsDir)) { vlog_error("Unable to initialize filesystem!");