diff --git a/build.gradle.kts b/build.gradle.kts index 60ec644d1b..4a6ec2c56a 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,6 +3,7 @@ import com.unciv.build.BuildConfig.coroutinesVersion import com.unciv.build.BuildConfig.gdxVersion import com.unciv.build.BuildConfig.kotlinVersion import com.unciv.build.BuildConfig.ktorVersion +import com.unciv.build.BuildConfig.roboVMVersion // You'll still get kotlin-reflect-1.3.70.jar in your classpath, but will no longer be used @@ -25,6 +26,7 @@ buildscript { dependencies { classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${com.unciv.build.BuildConfig.kotlinVersion}") classpath("com.android.tools.build:gradle:8.2.2") + classpath("com.mobidevelop.robovm:robovm-gradle-plugin:2.3.1") } } @@ -111,6 +113,18 @@ project(":android") { } } +project(":ios") { + apply(plugin = "kotlin") + apply(plugin = "robovm") + + dependencies { + "implementation"(project(":core")) + "implementation"("com.mobidevelop.robovm:robovm-rt:$roboVMVersion") + "implementation"("com.mobidevelop.robovm:robovm-cocoatouch:$roboVMVersion") + "implementation"("com.badlogicgames.gdx:gdx-backend-robovm:$gdxVersion") + "implementation"("com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-ios") + } +} project(":core") { apply(plugin = "kotlin") diff --git a/buildSrc/src/main/kotlin/BuildConfig.kt b/buildSrc/src/main/kotlin/BuildConfig.kt index 3e330c53f8..e85b649e0e 100644 --- a/buildSrc/src/main/kotlin/BuildConfig.kt +++ b/buildSrc/src/main/kotlin/BuildConfig.kt @@ -10,6 +10,7 @@ object BuildConfig { const val gdxVersion = "1.12.1" const val ktorVersion = "2.3.12" const val coroutinesVersion = "1.8.1" + const val roboVMVersion = "2.3.1" const val identifier = "com.unciv.app" } diff --git a/ios/Info.plist.xml b/ios/Info.plist.xml new file mode 100644 index 0000000000..9842ae2906 --- /dev/null +++ b/ios/Info.plist.xml @@ -0,0 +1,50 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + ${app.name} + CFBundleExecutable + ${app.executable} + CFBundleIdentifier + ${app.id} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${app.name} + CFBundlePackageType + APPL + CFBundleShortVersionString + ${app.version} + CFBundleSignature + ???? + CFBundleVersion + ${app.build} + LSRequiresIPhoneOS + + UIViewControllerBasedStatusBarAppearance + + UIStatusBarHidden + + UIDeviceFamily + + 1 + 2 + + UIRequiredDeviceCapabilities + + armv7 + opengles-2 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + CFBundleIconName + AppIcon + + diff --git a/ios/build.gradle.kts b/ios/build.gradle.kts new file mode 100644 index 0000000000..1349fb05cd --- /dev/null +++ b/ios/build.gradle.kts @@ -0,0 +1,35 @@ +import com.android.build.gradle.internal.tasks.factory.dependsOn +import com.unciv.build.BuildConfig + +sourceSets { + main { + java.srcDir("src/") + } +} + +tasks { + compileJava { + options.encoding = "UTF-8" + } + compileTestJava { + options.encoding = "UTF-8" + } +} + +extra.set("mainClassName", "IOSLauncher") + +tasks { + launchIPhoneSimulator.dependsOn(build) + launchIPadSimulator.dependsOn(build) + launchIOSDevice.dependsOn(build) + createIPA.dependsOn(build) +} + +robovm { + archs = "thumbv7:arm64" +} + +eclipse.project { + name = "${BuildConfig.appName}-ios" + natures("org.robovm.eclipse.RoboVMNature") +} diff --git a/ios/data/Default-1024w-1366h@2x~ipad.png b/ios/data/Default-1024w-1366h@2x~ipad.png new file mode 100644 index 0000000000..b175eaab6d Binary files /dev/null and b/ios/data/Default-1024w-1366h@2x~ipad.png differ diff --git a/ios/data/Default-375w-667h@2x.png b/ios/data/Default-375w-667h@2x.png new file mode 100644 index 0000000000..f213ce60df Binary files /dev/null and b/ios/data/Default-375w-667h@2x.png differ diff --git a/ios/data/Default-414w-736h@3x.png b/ios/data/Default-414w-736h@3x.png new file mode 100644 index 0000000000..685ba51fcb Binary files /dev/null and b/ios/data/Default-414w-736h@3x.png differ diff --git a/ios/data/Default-568h@2x.png b/ios/data/Default-568h@2x.png new file mode 100644 index 0000000000..101752fe77 Binary files /dev/null and b/ios/data/Default-568h@2x.png differ diff --git a/ios/data/Default.png b/ios/data/Default.png new file mode 100644 index 0000000000..f1a5582a01 Binary files /dev/null and b/ios/data/Default.png differ diff --git a/ios/data/Default@2x.png b/ios/data/Default@2x.png new file mode 100644 index 0000000000..ca32f62fc2 Binary files /dev/null and b/ios/data/Default@2x.png differ diff --git a/ios/data/Default@2x~ipad.png b/ios/data/Default@2x~ipad.png new file mode 100644 index 0000000000..bb77ef073e Binary files /dev/null and b/ios/data/Default@2x~ipad.png differ diff --git a/ios/data/Default~ipad.png b/ios/data/Default~ipad.png new file mode 100644 index 0000000000..855e4f2ad9 Binary files /dev/null and b/ios/data/Default~ipad.png differ diff --git a/ios/data/Media.xcassets/AppIcon.appiconset/Contents.json b/ios/data/Media.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000000..9ed19e123f --- /dev/null +++ b/ios/data/Media.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,116 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "iphone-notification-icon-20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "iphone-notification-icon-20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "iphone-spotlight-settings-icon-29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "iphone-spotlight-settings-icon-29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "iphone-spotlight-icon-40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "iphone-spotlight-icon-40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "iphone-app-icon-60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "iphone-app-icon-60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "ipad-notifications-icon-20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "ipad-notifications-icon-20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "ipad-settings-icon-29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "ipad-settings-icon-29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "ipad-spotlight-icon-40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "ipad-spotlight-icon-40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "ipad-app-icon-76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "ipad-app-icon-76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "ipad-pro-app-icon-83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "app-store-icon-1024@1x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/ios/data/Media.xcassets/AppIcon.appiconset/app-store-icon-1024@1x.png b/ios/data/Media.xcassets/AppIcon.appiconset/app-store-icon-1024@1x.png new file mode 100644 index 0000000000..b4a987c1c5 Binary files /dev/null and b/ios/data/Media.xcassets/AppIcon.appiconset/app-store-icon-1024@1x.png differ diff --git a/ios/data/Media.xcassets/AppIcon.appiconset/ipad-app-icon-76@1x.png b/ios/data/Media.xcassets/AppIcon.appiconset/ipad-app-icon-76@1x.png new file mode 100644 index 0000000000..d425b2ffc8 Binary files /dev/null and b/ios/data/Media.xcassets/AppIcon.appiconset/ipad-app-icon-76@1x.png differ diff --git a/ios/data/Media.xcassets/AppIcon.appiconset/ipad-app-icon-76@2x.png b/ios/data/Media.xcassets/AppIcon.appiconset/ipad-app-icon-76@2x.png new file mode 100644 index 0000000000..192460f2c6 Binary files /dev/null and b/ios/data/Media.xcassets/AppIcon.appiconset/ipad-app-icon-76@2x.png differ diff --git a/ios/data/Media.xcassets/AppIcon.appiconset/ipad-notifications-icon-20@1x.png b/ios/data/Media.xcassets/AppIcon.appiconset/ipad-notifications-icon-20@1x.png new file mode 100644 index 0000000000..3ad5eb6ebf Binary files /dev/null and b/ios/data/Media.xcassets/AppIcon.appiconset/ipad-notifications-icon-20@1x.png differ diff --git a/ios/data/Media.xcassets/AppIcon.appiconset/ipad-notifications-icon-20@2x.png b/ios/data/Media.xcassets/AppIcon.appiconset/ipad-notifications-icon-20@2x.png new file mode 100644 index 0000000000..0dbad4557f Binary files /dev/null and b/ios/data/Media.xcassets/AppIcon.appiconset/ipad-notifications-icon-20@2x.png differ diff --git a/ios/data/Media.xcassets/AppIcon.appiconset/ipad-pro-app-icon-83.5@2x.png b/ios/data/Media.xcassets/AppIcon.appiconset/ipad-pro-app-icon-83.5@2x.png new file mode 100644 index 0000000000..0710fdb954 Binary files /dev/null and b/ios/data/Media.xcassets/AppIcon.appiconset/ipad-pro-app-icon-83.5@2x.png differ diff --git a/ios/data/Media.xcassets/AppIcon.appiconset/ipad-settings-icon-29@1x.png b/ios/data/Media.xcassets/AppIcon.appiconset/ipad-settings-icon-29@1x.png new file mode 100644 index 0000000000..949fbaa0bc Binary files /dev/null and b/ios/data/Media.xcassets/AppIcon.appiconset/ipad-settings-icon-29@1x.png differ diff --git a/ios/data/Media.xcassets/AppIcon.appiconset/ipad-settings-icon-29@2x.png b/ios/data/Media.xcassets/AppIcon.appiconset/ipad-settings-icon-29@2x.png new file mode 100644 index 0000000000..0a82ae9a80 Binary files /dev/null and b/ios/data/Media.xcassets/AppIcon.appiconset/ipad-settings-icon-29@2x.png differ diff --git a/ios/data/Media.xcassets/AppIcon.appiconset/ipad-spotlight-icon-40@1x.png b/ios/data/Media.xcassets/AppIcon.appiconset/ipad-spotlight-icon-40@1x.png new file mode 100644 index 0000000000..0dbad4557f Binary files /dev/null and b/ios/data/Media.xcassets/AppIcon.appiconset/ipad-spotlight-icon-40@1x.png differ diff --git a/ios/data/Media.xcassets/AppIcon.appiconset/ipad-spotlight-icon-40@2x.png b/ios/data/Media.xcassets/AppIcon.appiconset/ipad-spotlight-icon-40@2x.png new file mode 100644 index 0000000000..4fc801a854 Binary files /dev/null and b/ios/data/Media.xcassets/AppIcon.appiconset/ipad-spotlight-icon-40@2x.png differ diff --git a/ios/data/Media.xcassets/AppIcon.appiconset/iphone-app-icon-60@2x.png b/ios/data/Media.xcassets/AppIcon.appiconset/iphone-app-icon-60@2x.png new file mode 100644 index 0000000000..4ce7690c23 Binary files /dev/null and b/ios/data/Media.xcassets/AppIcon.appiconset/iphone-app-icon-60@2x.png differ diff --git a/ios/data/Media.xcassets/AppIcon.appiconset/iphone-app-icon-60@3x.png b/ios/data/Media.xcassets/AppIcon.appiconset/iphone-app-icon-60@3x.png new file mode 100644 index 0000000000..a0a4ae42cb Binary files /dev/null and b/ios/data/Media.xcassets/AppIcon.appiconset/iphone-app-icon-60@3x.png differ diff --git a/ios/data/Media.xcassets/AppIcon.appiconset/iphone-notification-icon-20@2x.png b/ios/data/Media.xcassets/AppIcon.appiconset/iphone-notification-icon-20@2x.png new file mode 100644 index 0000000000..0dbad4557f Binary files /dev/null and b/ios/data/Media.xcassets/AppIcon.appiconset/iphone-notification-icon-20@2x.png differ diff --git a/ios/data/Media.xcassets/AppIcon.appiconset/iphone-notification-icon-20@3x.png b/ios/data/Media.xcassets/AppIcon.appiconset/iphone-notification-icon-20@3x.png new file mode 100644 index 0000000000..b4fc090a26 Binary files /dev/null and b/ios/data/Media.xcassets/AppIcon.appiconset/iphone-notification-icon-20@3x.png differ diff --git a/ios/data/Media.xcassets/AppIcon.appiconset/iphone-spotlight-icon-40@2x.png b/ios/data/Media.xcassets/AppIcon.appiconset/iphone-spotlight-icon-40@2x.png new file mode 100644 index 0000000000..4fc801a854 Binary files /dev/null and b/ios/data/Media.xcassets/AppIcon.appiconset/iphone-spotlight-icon-40@2x.png differ diff --git a/ios/data/Media.xcassets/AppIcon.appiconset/iphone-spotlight-icon-40@3x.png b/ios/data/Media.xcassets/AppIcon.appiconset/iphone-spotlight-icon-40@3x.png new file mode 100644 index 0000000000..4ce7690c23 Binary files /dev/null and b/ios/data/Media.xcassets/AppIcon.appiconset/iphone-spotlight-icon-40@3x.png differ diff --git a/ios/data/Media.xcassets/AppIcon.appiconset/iphone-spotlight-settings-icon-29@2x.png b/ios/data/Media.xcassets/AppIcon.appiconset/iphone-spotlight-settings-icon-29@2x.png new file mode 100644 index 0000000000..0a82ae9a80 Binary files /dev/null and b/ios/data/Media.xcassets/AppIcon.appiconset/iphone-spotlight-settings-icon-29@2x.png differ diff --git a/ios/data/Media.xcassets/AppIcon.appiconset/iphone-spotlight-settings-icon-29@3x.png b/ios/data/Media.xcassets/AppIcon.appiconset/iphone-spotlight-settings-icon-29@3x.png new file mode 100644 index 0000000000..eb0446e0e1 Binary files /dev/null and b/ios/data/Media.xcassets/AppIcon.appiconset/iphone-spotlight-settings-icon-29@3x.png differ diff --git a/ios/data/Media.xcassets/Contents.json b/ios/data/Media.xcassets/Contents.json new file mode 100644 index 0000000000..da4a164c91 --- /dev/null +++ b/ios/data/Media.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/ios/robovm.properties b/ios/robovm.properties new file mode 100644 index 0000000000..e12bf5565f --- /dev/null +++ b/ios/robovm.properties @@ -0,0 +1,6 @@ +app.version=1.0 +app.id=com.mygdx.game +app.mainclass=com.unciv.game.IOSLauncher +app.executable=IOSLauncher +app.build=1 +app.name=my-gdx-game diff --git a/ios/robovm.xml b/ios/robovm.xml new file mode 100644 index 0000000000..ee0da2d5c9 --- /dev/null +++ b/ios/robovm.xml @@ -0,0 +1,47 @@ + + ${app.executable} + ${app.mainclass} + ios + thumbv7 + ios + Info.plist.xml + + + ../android/assets + + ** + + true + + + data + + + + com.badlogic.gdx.scenes.scene2d.ui.* + com.badlogic.gdx.graphics.g3d.particles.** + com.android.okhttp.HttpHandler + com.android.okhttp.HttpsHandler + com.android.org.conscrypt.** + com.android.org.bouncycastle.jce.provider.BouncyCastleProvider + com.android.org.bouncycastle.jcajce.provider.keystore.BC$Mappings + com.android.org.bouncycastle.jcajce.provider.keystore.bc.BcKeyStoreSpi + com.android.org.bouncycastle.jcajce.provider.keystore.bc.BcKeyStoreSpi$Std + com.android.org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi + com.android.org.bouncycastle.crypto.digests.AndroidDigestFactoryOpenSSL + org.apache.harmony.security.provider.cert.DRLCertFactory + org.apache.harmony.security.provider.crypto.CryptoProvider + + + z + + + UIKit + OpenGLES + QuartzCore + CoreGraphics + OpenAL + AudioToolbox + AVFoundation + + diff --git a/ios/src/com/unciv/app/IOSLauncher.java b/ios/src/com/unciv/app/IOSLauncher.java new file mode 100644 index 0000000000..f56b442e4f --- /dev/null +++ b/ios/src/com/unciv/app/IOSLauncher.java @@ -0,0 +1,21 @@ +package com.unciv.app; + +import com.badlogic.gdx.backends.iosrobovm.IOSApplication; +import com.badlogic.gdx.backends.iosrobovm.IOSApplicationConfiguration; + +import org.robovm.apple.foundation.NSAutoreleasePool; +import org.robovm.apple.uikit.UIApplication; + +class IOSLauncher extends IOSApplication.Delegate { + @Override + protected IOSApplication createApplication() { + IOSApplicationConfiguration config = new IOSApplicationConfiguration(); + return new IOSApplication(new com.unciv.UncivGame(), config); + } + + public static void main(String[] argv) { + NSAutoreleasePool pool = new NSAutoreleasePool(); + UIApplication.main(argv, null, IOSLauncher.class); + pool.close(); + } +} diff --git a/settings.gradle.kts b/settings.gradle.kts index 9b0f76ae3d..76c2c65126 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1 +1 @@ -include("desktop", "android", "core", "tests", "server") +include("desktop", "android", "ios", "core", "tests", "server")