From 783b99f3e730660e52c184a23f257f738e52ba95 Mon Sep 17 00:00:00 2001 From: Ihar Hubchyk Date: Wed, 10 Dec 2025 11:49:38 +0800 Subject: [PATCH] Fix multiple iOS issues and add iOS compilation (#10426) --- .github/workflows/ios.yml | 36 ++++++++ .github/workflows/pull_request.yml | 5 ++ .gitignore | 4 + docs/DEVELOPMENT.md | 9 +- .../AppIcon.appiconset/Contents.json | 3 +- .../AppIcon.appiconset/icon.jpg | Bin 0 -> 24791 bytes ios/fheroes2.xcodeproj/project.pbxproj | 12 +-- script/ios/README.md | 3 + script/ios/install_packages.sh | 82 ++++++++++++++++++ src/engine/system.cpp | 10 +-- src/fheroes2/gui/interface_events.cpp | 8 +- 11 files changed, 151 insertions(+), 21 deletions(-) create mode 100644 .github/workflows/ios.yml create mode 100644 ios/Assets.xcassets/AppIcon.appiconset/icon.jpg create mode 100644 script/ios/README.md create mode 100755 script/ios/install_packages.sh diff --git a/.github/workflows/ios.yml b/.github/workflows/ios.yml new file mode 100644 index 000000000..0726d2681 --- /dev/null +++ b/.github/workflows/ios.yml @@ -0,0 +1,36 @@ +name: iOS + +on: + workflow_call: + +permissions: + contents: write + +jobs: + ios: + name: iOS + runs-on: macos-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v6 + - name: check Xcode version + run: | + /usr/bin/xcodebuild -version + - name: Install dependencies + run: | + ./script/ios/install_packages.sh + # TODO: remove this step once we figure out how to build without the need of resources. + - name: Prepare build + run: | + mkdir anim + mkdir data + mkdir music + - name: Build + # TODO: compile for a proper target, not for simulator. + run: | + cd ios + xcodebuild -project fheroes2.xcodeproj \ + -scheme fheroes2 \ + -destination 'platform=iOS Simulator,name=iPhone 16' \ + build + # TODO: add signing stage. diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 9e595ce6c..052b07ffc 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -98,3 +98,8 @@ jobs: needs: - msvc uses: ./.github/workflows/make.yml + ios: + name: iOS + needs: + - msvc + uses: ./.github/workflows/ios.yml diff --git a/.gitignore b/.gitignore index 85e88bb21..e96930005 100644 --- a/.gitignore +++ b/.gitignore @@ -98,6 +98,10 @@ android/app/src/main/assets/ ios/*/xcuserdata ios/**/xcuserdata +# Third-party packages for XCode +ios/SDL2/ +ios/SDL2_mixer/ + # Mac magic folders .DS_Store diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md index d501472f4..5c65e6681 100644 --- a/docs/DEVELOPMENT.md +++ b/docs/DEVELOPMENT.md @@ -39,15 +39,8 @@ Please follow the instructions below to be able to build the project from source * To build this build you need to have the necessary Data, Anim, Maps and Music folders for the engine present in the fheroes2 project's folder. * Download and install Xcode on your macos device. Download the iOS SDK during installation. +* Go to the directory `script/ios` and run the file `install_packages.sh`. This script will install all the required packages to build the project using Xcode. * Open `fheroes2.xcodeproj` in the "iOS" folder". -* Download SDL2 and SDL_mixer source codes from their GitHub repositories's release pages. Make sure you get SDL2 and not SDL3. -* Paste the SDL2 and SDL_mixer folders in the same parent directory as your fheroes2 source folder. This means that next to the folder containing -your fheroes2 local clone, you will have the two SDL folders. -* Remove any version number from the name of the SDL2 and SDL_mixer folder so that their names are respectively `SDL` and `SDL_mixer`. -* In Xcode SDL and SDL_mixer should now be recognized in the Navigator area, recognized by them not having read names. Open on `SDL_mixer` in the Navigator on the left side. -* Click "fheroes2" in the Navigator area on the left side of Xcode. -* In the right side Editor area select "fheroes2" under "Project". Open the `Build Settings` tab. Make sure to set `All` options and scroll down to `Search Paths`. -* Open up the `User Header Search Paths` and add `$(SRCROOT)/../../SDL/include` to the list of paths. * In the Editor area select "fheroes2" under the "Targets" menu instead of "Projects". Open the "Signing & Capabilities" tab. Under "Signing", add your AppleID in the "Team" field. * Connect your iOS device to your mac device with the necessary cable. Select the device in the devices in Xcode's upper Toolbar. diff --git a/ios/Assets.xcassets/AppIcon.appiconset/Contents.json b/ios/Assets.xcassets/AppIcon.appiconset/Contents.json index 13613e3ee..d6c51b6c6 100644 --- a/ios/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/ios/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,9 +1,10 @@ { "images" : [ { + "filename" : "icon.jpg", "idiom" : "universal", "platform" : "ios", - "size" : "1024x1024" + "size" : "256x256" } ], "info" : { diff --git a/ios/Assets.xcassets/AppIcon.appiconset/icon.jpg b/ios/Assets.xcassets/AppIcon.appiconset/icon.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e060ee19bd2445fe55fc2d1c3a4e2e5ae8ef3981 GIT binary patch literal 24791 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 "$TMP_DIR/checksums" + +if [[ -n "$(command -v shasum)" ]]; then + (cd "$TMP_DIR" && shasum --check --algorithm 256 checksums) +elif [[ -n "$(command -v sha256sum)" ]]; then + (cd "$TMP_DIR" && sha256sum --check --strict checksums) +else + echo "Neither shasum nor sha256sum were found in your system. Unable to verify the downloaded file. Installation aborted." + exit 1 +fi + +unzip -d "$(dirname "$0")/../../ios" "$TMP_DIR/$PKG_FILE" + +mv "$(dirname "$0")/../../ios/SDL-$PKG_NAME" "$(dirname "$0")/../../ios/SDL2" + +PKG_NAME="release-2.8.1" +PKG_FILE="$PKG_NAME.zip" +PKG_FILE_SHA256="3738827df73c86268dfa52898780769d1a796316d73b535e2ab5ff2d8d0ff44f" +PKG_URL="https://github.com/libsdl-org/SDL_mixer/archive/refs/tags/$PKG_FILE" + +if [[ -n "$(command -v wget)" ]]; then + wget -O "$TMP_DIR/$PKG_FILE" "$PKG_URL" +elif [[ -n "$(command -v curl)" ]]; then + curl -o "$TMP_DIR/$PKG_FILE" -L "$PKG_URL" +else + echo "Neither wget nor curl were found in your system. Unable to download the package archive. Installation aborted." + exit 1 +fi + +echo "$PKG_FILE_SHA256 *$PKG_FILE" > "$TMP_DIR/checksums" + +unzip -d "$(dirname "$0")/../../ios" "$TMP_DIR/$PKG_FILE" + +mv "$(dirname "$0")/../../ios/SDL_Mixer-$PKG_NAME" "$(dirname "$0")/../../ios/SDL2_Mixer" + +# Patch SDL_Mixer project. +# It is needed since we are trying to build SDL Mixer using the latest SDL2 version. +# Also, SDL Mixer doesn't support iPhone Simulator so we have to change this code or another one. +sed -i '' 's#$(SRCROOT)/$(PLATFORM)/SDL2.framework/Headers#$(SRCROOT)/../../SDL2/include#' \ + ios/SDL2_Mixer/Xcode/SDL_mixer.xcodeproj/project.pbxproj diff --git a/src/engine/system.cpp b/src/engine/system.cpp index c1f0f69aa..88bf718fb 100644 --- a/src/engine/system.cpp +++ b/src/engine/system.cpp @@ -1,6 +1,6 @@ /*************************************************************************** * fheroes2: https://github.com/ihhub/fheroes2 * - * Copyright (C) 2019 - 2024 * + * Copyright (C) 2019 - 2025 * * * * Free Heroes2 Engine: http://sourceforge.net/projects/fheroes2 * * Copyright (C) 2009 by Andrey Afletdinov * @@ -95,7 +95,7 @@ namespace { const char * homeEnvPath = getenv( "HOME" ); -#if defined( MACOS_APP_BUNDLE ) +#if defined( MACOS_APP_BUNDLE ) || defined( __IPHONEOS__ ) if ( homeEnvPath != nullptr ) { return System::concatPath( System::concatPath( homeEnvPath, "Library/Preferences" ), appName ); } @@ -267,7 +267,7 @@ namespace bool System::isHandheldDevice() { -#if defined( ANDROID ) +#if defined( ANDROID ) || defined( __IPHONEOS__ ) return true; #else return false; @@ -281,7 +281,7 @@ bool System::isTouchInputAvailable() bool System::isVirtualKeyboardSupported() { -#if defined( ANDROID ) || defined( TARGET_PS_VITA ) || defined( TARGET_NINTENDO_SWITCH ) +#if defined( ANDROID ) || defined( TARGET_PS_VITA ) || defined( TARGET_NINTENDO_SWITCH ) || defined( __IPHONEOS__ ) return true; #else return false; @@ -382,7 +382,7 @@ std::string System::GetDataDirectory( const std::string_view appName ) } return {}; -#elif defined( MACOS_APP_BUNDLE ) +#elif defined( MACOS_APP_BUNDLE ) || defined( __IPHONEOS__ ) if ( const char * homeEnv = getenv( "HOME" ); homeEnv != nullptr ) { return concatPath( concatPath( homeEnv, "Library/Application Support" ), appName ); } diff --git a/src/fheroes2/gui/interface_events.cpp b/src/fheroes2/gui/interface_events.cpp index 0ea8da4c0..1f67fba7f 100644 --- a/src/fheroes2/gui/interface_events.cpp +++ b/src/fheroes2/gui/interface_events.cpp @@ -301,8 +301,14 @@ void Interface::AdventureMap::EventSystemDialog() const fheroes2::GameMode Interface::BaseInterface::EventExit() { - if ( Dialog::YES & fheroes2::showStandardTextMessage( _( "Quit" ), _( "Are you sure you want to quit?" ), Dialog::YES | Dialog::NO ) ) +#if defined( __IPHONEOS__ ) + // iOS discourages to exit a running application. + fheroes2::showStandardTextMessage( _( "Quit" ), _( "To exit fheroes2, press the Home button or swipe up." ), Dialog::OK ); +#else + if ( Dialog::YES & fheroes2::showStandardTextMessage( _( "Quit" ), _( "Are you sure you want to quit?" ), Dialog::YES | Dialog::NO ) ) { return fheroes2::GameMode::QUIT_GAME; + } +#endif return fheroes2::GameMode::CANCEL; }