diff --git a/client/eventsSDL/InputHandler.cpp b/client/eventsSDL/InputHandler.cpp
index f6e32166b..b0d20711a 100644
--- a/client/eventsSDL/InputHandler.cpp
+++ b/client/eventsSDL/InputHandler.cpp
@@ -237,7 +237,7 @@ void InputHandler::preprocessEvent(const SDL_Event & ev)
#endif
break;
case SDL_WINDOWEVENT_SIZE_CHANGED:
-#ifdef VCMI_ANDROID
+#ifdef VCMI_MOBILE
{
boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex);
GH.onScreenResize(true);
diff --git a/clientapp/ios/Info.plist b/clientapp/ios/Info.plist
index 0fba21025..32d1f671d 100644
--- a/clientapp/ios/Info.plist
+++ b/clientapp/ios/Info.plist
@@ -53,10 +53,5 @@
UIStatusBarHidden
- UISupportedInterfaceOrientations
-
- UIInterfaceOrientationLandscapeLeft
- UIInterfaceOrientationLandscapeRight
-
diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt
index 7f163cbf1..47530635a 100644
--- a/launcher/CMakeLists.txt
+++ b/launcher/CMakeLists.txt
@@ -31,6 +31,11 @@ if(APPLE_IOS)
ios/revealdirectoryinfiles.mm
ios/selectdirectory.h
ios/selectdirectory.mm
+ prepare_ios.mm
+ )
+elseif(ANDROID)
+ list(APPEND launcher_SRCS
+ prepare_android.cpp
)
endif()
@@ -55,6 +60,7 @@ set(launcher_HEADERS
helper.h
innoextract.h
prepare.h
+ prepare_p.h
)
set(launcher_FORMS
diff --git a/launcher/prepare.cpp b/launcher/prepare.cpp
index 7e158d4ac..f971bf644 100644
--- a/launcher/prepare.cpp
+++ b/launcher/prepare.cpp
@@ -9,75 +9,17 @@
*/
#include "StdInc.h"
#include "prepare.h"
+#include "prepare_p.h"
#include "../vcmiqt/launcherdirs.h"
-#include
-#include
-#include
-
-#ifdef VCMI_ANDROID
-#include "../lib/CAndroidVMHelper.h"
-
-#include
-#include
-#include
-
-namespace
-{
-// https://gist.github.com/ssendeavour/7324701
-bool copyRecursively(const QString &srcFilePath, const QString &tgtFilePath)
-{
- QFileInfo srcFileInfo{srcFilePath};
- if(srcFileInfo.isDir()) {
- QDir targetDir{tgtFilePath};
- targetDir.cdUp();
- if(!targetDir.mkpath(QFileInfo{tgtFilePath}.fileName()))
- return false;
- targetDir.setPath(tgtFilePath);
-
- QDir sourceDir{srcFilePath};
- const auto fileNames = sourceDir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden | QDir::System);
- for(const auto & fileName : fileNames) {
- const auto newSrcFilePath = sourceDir.filePath(fileName);
- const auto newTgtFilePath = targetDir.filePath(fileName);
- if(!copyRecursively(newSrcFilePath, newTgtFilePath))
- return false;
- }
- } else {
- if(!QFile::copy(srcFilePath, tgtFilePath))
- return false;
- }
- return true;
-}
-
-void prepareAndroid()
-{
- QAndroidJniEnvironment jniEnv;
- CAndroidVMHelper::initClassloader(static_cast(jniEnv));
-
- const bool justLaunched = QtAndroid::androidActivity().getField("justLaunched") == JNI_TRUE;
- if(!justLaunched)
- return;
-
- // copy core data to internal directory
- const auto vcmiDir = QAndroidJniObject::callStaticObjectMethod("eu/vcmi/vcmi/NativeMethods", "internalDataRoot").toString();
- for(auto vcmiFilesResource : {QLatin1String{"config"}, QLatin1String{"Mods"}})
- {
- QDir destDir = QString{"%1/%2"}.arg(vcmiDir, vcmiFilesResource);
- destDir.removeRecursively();
- copyRecursively(QString{":/%1"}.arg(vcmiFilesResource), destDir.absolutePath());
- }
-}
-}
-#endif
-
-
namespace launcher
{
void prepare()
{
#ifdef VCMI_ANDROID
prepareAndroid();
+#elif defined(VCMI_IOS)
+ prepareIos();
#endif
CLauncherDirs::prepare();
diff --git a/launcher/prepare_android.cpp b/launcher/prepare_android.cpp
new file mode 100644
index 000000000..0a25b3972
--- /dev/null
+++ b/launcher/prepare_android.cpp
@@ -0,0 +1,71 @@
+/*
+ * prepare_android.cpp, part of VCMI engine
+ *
+ * Authors: listed in file AUTHORS in main folder
+ *
+ * License: GNU General Public License v2.0 or later
+ * Full text of license available in license.txt file, in main folder
+ *
+ */
+#include "StdInc.h"
+#include "prepare_p.h"
+#include "../lib/CAndroidVMHelper.h"
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+namespace
+{
+// https://gist.github.com/ssendeavour/7324701
+bool copyRecursively(const QString & srcFilePath, const QString & tgtFilePath)
+{
+ QFileInfo srcFileInfo{srcFilePath};
+ if(srcFileInfo.isDir()) {
+ QDir targetDir{tgtFilePath};
+ targetDir.cdUp();
+ if(!targetDir.mkpath(QFileInfo{tgtFilePath}.fileName()))
+ return false;
+ targetDir.setPath(tgtFilePath);
+
+ QDir sourceDir{srcFilePath};
+ const auto fileNames = sourceDir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden | QDir::System);
+ for(const auto & fileName : fileNames) {
+ const auto newSrcFilePath = sourceDir.filePath(fileName);
+ const auto newTgtFilePath = targetDir.filePath(fileName);
+ if(!copyRecursively(newSrcFilePath, newTgtFilePath))
+ return false;
+ }
+ } else {
+ if(!QFile::copy(srcFilePath, tgtFilePath))
+ return false;
+ }
+ return true;
+}
+}
+
+namespace launcher
+{
+void prepareAndroid()
+{
+ QAndroidJniEnvironment jniEnv;
+ CAndroidVMHelper::initClassloader(static_cast(jniEnv));
+
+ const bool justLaunched = QtAndroid::androidActivity().getField("justLaunched") == JNI_TRUE;
+ if(!justLaunched)
+ return;
+
+ // copy core data to internal directory
+ const auto vcmiDir = QAndroidJniObject::callStaticObjectMethod("eu/vcmi/vcmi/NativeMethods", "internalDataRoot").toString();
+ for(auto vcmiFilesResource : {QLatin1String{"config"}, QLatin1String{"Mods"}})
+ {
+ QDir destDir = QString{"%1/%2"}.arg(vcmiDir, vcmiFilesResource);
+ destDir.removeRecursively();
+ copyRecursively(QString{":/%1"}.arg(vcmiFilesResource), destDir.absolutePath());
+ }
+}
+}
diff --git a/launcher/prepare_ios.mm b/launcher/prepare_ios.mm
new file mode 100644
index 000000000..25f4d2c79
--- /dev/null
+++ b/launcher/prepare_ios.mm
@@ -0,0 +1,40 @@
+/*
+ * prepare_ios.mm, part of VCMI engine
+ *
+ * Authors: listed in file AUTHORS in main folder
+ *
+ * License: GNU General Public License v2.0 or later
+ * Full text of license available in license.txt file, in main folder
+ *
+ */
+#include "StdInc.h"
+#include "prepare_p.h"
+
+#import
+
+#include
+
+namespace
+{
+UIInterfaceOrientationMask swizzled_supportedInterfaceOrientationsForWindow
+ (id __unused self, SEL __unused _cmd, UIApplication * __unused application, UIWindow * __unused _Nullable window)
+{
+ if(UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad)
+ return UIInterfaceOrientationMaskAll;
+ return UIInterfaceOrientationMaskLandscape;
+}
+}
+
+namespace launcher
+{
+void prepareIos()
+{
+ auto sel = @selector(application:supportedInterfaceOrientationsForWindow:);
+ auto methodDesc = protocol_getMethodDescription(@protocol(UIApplicationDelegate), sel, NO, YES);
+ auto appDelegateClass = object_getClass(UIApplication.sharedApplication.delegate);
+ [[maybe_unused]] auto existingImp = class_replaceMethod(
+ appDelegateClass, sel, (IMP)swizzled_supportedInterfaceOrientationsForWindow, methodDesc.types);
+ // also check implementation in qtbase - src/plugins/platforms/ios/qiosapplicationdelegate.mm
+ NSCAssert(existingImp == nullptr, @"original app delegate has this method, don't ignore it");
+}
+}
diff --git a/launcher/prepare_p.h b/launcher/prepare_p.h
new file mode 100644
index 000000000..904353cea
--- /dev/null
+++ b/launcher/prepare_p.h
@@ -0,0 +1,19 @@
+/*
+ * prepare_p.h, part of VCMI engine
+ *
+ * Authors: listed in file AUTHORS in main folder
+ *
+ * License: GNU General Public License v2.0 or later
+ * Full text of license available in license.txt file, in main folder
+ *
+ */
+#pragma once
+
+namespace launcher
+{
+#ifdef VCMI_ANDROID
+void prepareAndroid();
+#elif defined(VCMI_IOS)
+void prepareIos();
+#endif
+}
diff --git a/launcher/settingsView/csettingsview_moc.cpp b/launcher/settingsView/csettingsview_moc.cpp
index c1cb1cbb5..b45025274 100644
--- a/launcher/settingsView/csettingsview_moc.cpp
+++ b/launcher/settingsView/csettingsview_moc.cpp
@@ -120,6 +120,8 @@ void CSettingsView::loadSettings()
ui->labelHapticFeedback->hide();
ui->labelResetTutorialTouchscreen->hide();
ui->pushButtonResetTutorialTouchscreen->hide();
+ ui->labelAllowPortrait->hide();
+ ui->buttonAllowPortrait->hide();
if (settings["video"]["realFullscreen"].Bool())
ui->comboBoxFullScreen->setCurrentIndex(2);
else
@@ -128,8 +130,6 @@ void CSettingsView::loadSettings()
#ifndef VCMI_ANDROID
ui->buttonHandleBackRightMouseButton->hide();
ui->labelHandleBackRightMouseButton->hide();
- ui->buttonAllowPortrait->hide();
- ui->labelAllowPortrait->hide();
#endif
fillValidScalingRange();