mirror of
https://github.com/Relintai/pandemonium_engine.git
synced 2024-12-23 20:36:53 +01:00
Backported the 3.x android editor port pr by m4gr3d and thebestnom. (Godot pr 57747).
This commit is contained in:
parent
66be182f51
commit
b74c00ea65
@ -479,6 +479,10 @@ void EditorNode::_notification(int p_what) {
|
||||
get_tree()->get_root()->set_as_audio_listener(false);
|
||||
get_tree()->get_root()->set_as_audio_listener_2d(false);
|
||||
get_tree()->set_auto_accept_quit(false);
|
||||
//Note that this class will only compile if tools is enabled
|
||||
#ifdef ANDROID_ENABLED
|
||||
get_tree()->set_quit_on_go_back(false);
|
||||
#endif
|
||||
get_tree()->connect("files_dropped", this, "_dropped_files");
|
||||
get_tree()->connect("global_menu_action", this, "_global_menu_action");
|
||||
|
||||
|
@ -50,10 +50,17 @@ else:
|
||||
if lib_arch_dir != "":
|
||||
if env["target"] == "release":
|
||||
lib_type_dir = "release"
|
||||
else: # release_debug, debug
|
||||
elif env["target"] == "release_debug":
|
||||
lib_type_dir = "debug"
|
||||
else: # debug
|
||||
lib_type_dir = "dev"
|
||||
|
||||
out_dir = "#platform/android/java/lib/libs/" + lib_type_dir + "/" + lib_arch_dir
|
||||
lib_tools_dir = ""
|
||||
|
||||
if env["tools"]:
|
||||
lib_tools_dir = "tools/"
|
||||
|
||||
out_dir = "#platform/android/java/lib/libs/" + lib_tools_dir + lib_type_dir + "/" + lib_arch_dir
|
||||
env_android.Command(
|
||||
out_dir + "/libgodot_android.so", "#bin/libgodot" + env["SHLIBSUFFIX"], Move("$TARGET", "$SOURCE")
|
||||
)
|
||||
|
@ -42,6 +42,11 @@ allprojects {
|
||||
}
|
||||
}
|
||||
|
||||
configurations {
|
||||
// Initializes a placeholder for the devImplementation dependency configuration.
|
||||
devImplementation {}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation libraries.kotlinStdLib
|
||||
implementation libraries.androidxFragment
|
||||
@ -54,6 +59,7 @@ dependencies {
|
||||
// Custom build mode. In this scenario this project is the only one around and the Godot
|
||||
// library is available through the pre-generated godot-lib.*.aar android archive files.
|
||||
debugImplementation fileTree(dir: 'libs/debug', include: ['*.jar', '*.aar'])
|
||||
devImplementation fileTree(dir: 'libs/dev', include: ['*.jar', '*.aar'])
|
||||
releaseImplementation fileTree(dir: 'libs/release', include: ['*.jar', '*.aar'])
|
||||
}
|
||||
|
||||
@ -78,6 +84,7 @@ dependencies {
|
||||
android {
|
||||
compileSdkVersion versions.compileSdk
|
||||
buildToolsVersion versions.buildTools
|
||||
ndkVersion versions.ndkVersion
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility versions.javaVersion
|
||||
@ -105,6 +112,8 @@ android {
|
||||
versionName getExportVersionName()
|
||||
minSdkVersion getExportMinSdkVersion()
|
||||
targetSdkVersion getExportTargetSdkVersion()
|
||||
|
||||
missingDimensionStrategy 'products', 'template'
|
||||
//CHUNK_ANDROID_DEFAULTCONFIG_BEGIN
|
||||
//CHUNK_ANDROID_DEFAULTCONFIG_END
|
||||
}
|
||||
@ -160,6 +169,18 @@ android {
|
||||
}
|
||||
}
|
||||
|
||||
dev {
|
||||
initWith debug
|
||||
// Signing and zip-aligning are skipped for prebuilt builds, but
|
||||
// performed for custom builds.
|
||||
zipAlignEnabled shouldZipAlign()
|
||||
if (shouldSign()) {
|
||||
signingConfig signingConfigs.debug
|
||||
} else {
|
||||
signingConfig null
|
||||
}
|
||||
}
|
||||
|
||||
release {
|
||||
// Signing and zip-aligning are skipped for prebuilt builds, but
|
||||
// performed for custom builds.
|
||||
@ -200,6 +221,11 @@ android {
|
||||
'libs/debug'
|
||||
//DIR_JNI_DEBUG_BEGIN
|
||||
//DIR_JNI_DEBUG_END
|
||||
]
|
||||
dev.jniLibs.srcDirs = [
|
||||
'libs/dev'
|
||||
//DIR_JNI_DEV_BEGIN
|
||||
//DIR_JNI_DEV_END
|
||||
]
|
||||
release.jniLibs.srcDirs = [
|
||||
'libs/release'
|
||||
@ -221,6 +247,12 @@ task copyAndRenameDebugApk(type: Copy) {
|
||||
rename "android_debug.apk", getExportFilename()
|
||||
}
|
||||
|
||||
task copyAndRenameDevApk(type: Copy) {
|
||||
from "$buildDir/outputs/apk/dev/android_dev.apk"
|
||||
into getExportPath()
|
||||
rename "android_dev.apk", getExportFilename()
|
||||
}
|
||||
|
||||
task copyAndRenameReleaseApk(type: Copy) {
|
||||
from "$buildDir/outputs/apk/release/android_release.apk"
|
||||
into getExportPath()
|
||||
@ -233,6 +265,12 @@ task copyAndRenameDebugAab(type: Copy) {
|
||||
rename "build-debug.aab", getExportFilename()
|
||||
}
|
||||
|
||||
task copyAndRenameDevAab(type: Copy) {
|
||||
from "$buildDir/outputs/bundle/dev/build-dev.aab"
|
||||
into getExportPath()
|
||||
rename "build-dev.aab", getExportFilename()
|
||||
}
|
||||
|
||||
task copyAndRenameReleaseAab(type: Copy) {
|
||||
from "$buildDir/outputs/bundle/release/build-release.aab"
|
||||
into getExportPath()
|
||||
|
@ -76,7 +76,7 @@ ext.getGodotEditorVersion = { ->
|
||||
String editorVersion = project.hasProperty("godot_editor_version") ? project.property("godot_editor_version") : ""
|
||||
if (editorVersion == null || editorVersion.isEmpty()) {
|
||||
// Try the library version first
|
||||
editorVersion = getGodotLibraryVersion()
|
||||
editorVersion = getGodotLibraryVersionName()
|
||||
|
||||
if (editorVersion.isEmpty()) {
|
||||
// Fallback value.
|
||||
@ -86,9 +86,24 @@ ext.getGodotEditorVersion = { ->
|
||||
return editorVersion
|
||||
}
|
||||
|
||||
ext.getGodotLibraryVersionCode = { ->
|
||||
String versionName = ""
|
||||
int versionCode = 1
|
||||
(versionName, versionCode) = getGodotLibraryVersion()
|
||||
return versionCode
|
||||
}
|
||||
|
||||
ext.getGodotLibraryVersionName = { ->
|
||||
String versionName = ""
|
||||
int versionCode = 1
|
||||
(versionName, versionCode) = getGodotLibraryVersion()
|
||||
return versionName
|
||||
}
|
||||
|
||||
ext.getGodotLibraryVersion = { ->
|
||||
// Attempt to read the version from the `version.py` file.
|
||||
String libraryVersion = ""
|
||||
String libraryVersionName = ""
|
||||
int libraryVersionCode = 1
|
||||
|
||||
File versionFile = new File("../../../version.py")
|
||||
if (versionFile.isFile()) {
|
||||
@ -110,15 +125,20 @@ ext.getGodotLibraryVersion = { ->
|
||||
}
|
||||
|
||||
if (requiredKeys.empty) {
|
||||
libraryVersion = map.values().join(".")
|
||||
libraryVersionName = map.values().join(".")
|
||||
try {
|
||||
libraryVersionCode = Integer.parseInt(map["patch"]) +
|
||||
(Integer.parseInt(map["minor"]) * 100) +
|
||||
(Integer.parseInt(map["major"]) * 10000)
|
||||
} catch (NumberFormatException ignore) {}
|
||||
}
|
||||
}
|
||||
|
||||
if (libraryVersion.isEmpty()) {
|
||||
if (libraryVersionName.isEmpty()) {
|
||||
// Fallback value in case we're unable to read the file.
|
||||
libraryVersion = "custom_build"
|
||||
libraryVersionName = "custom_build"
|
||||
}
|
||||
return libraryVersion
|
||||
return [libraryVersionName, libraryVersionCode]
|
||||
}
|
||||
|
||||
final String VALUE_SEPARATOR_REGEX = "\\|"
|
||||
|
@ -22,21 +22,22 @@ allprojects {
|
||||
|
||||
ext {
|
||||
supportedAbis = ["armv7", "arm64v8", "x86", "x86_64"]
|
||||
supportedTargets = ["release", "debug"]
|
||||
supportedTargetsMap = [release: "release", dev: "debug", debug: "release_debug"]
|
||||
supportedFlavors = ["editor", "template"]
|
||||
|
||||
// Used by gradle to specify which architecture to build for by default when running `./gradlew build`.
|
||||
// This command is usually used by Android Studio.
|
||||
// Used by gradle to specify which architecture to build for by default when running
|
||||
// `./gradlew build` (this command is usually used by Android Studio).
|
||||
// If building manually on the command line, it's recommended to use the
|
||||
// `./gradlew generateGodotTemplates` build command instead after running the `scons` command.
|
||||
// The defaultAbi must be one of the {supportedAbis} values.
|
||||
defaultAbi = "arm64v8"
|
||||
// `./gradlew generateGodotTemplates` build command instead after running the `scons` command(s).
|
||||
// The {selectedAbis} values must be from the {supportedAbis} values.
|
||||
selectedAbis = ["arm64v8"]
|
||||
}
|
||||
|
||||
def rootDir = "../../.."
|
||||
def binDir = "$rootDir/bin/"
|
||||
|
||||
def getSconsTaskName(String buildType) {
|
||||
return "compileGodotNativeLibs" + buildType.capitalize()
|
||||
def getSconsTaskName(String flavor, String buildType, String abi) {
|
||||
return "compileGodotNativeLibs" + flavor.capitalize() + buildType.capitalize() + abi.capitalize()
|
||||
}
|
||||
|
||||
/**
|
||||
@ -50,6 +51,17 @@ task copyDebugBinaryToBin(type: Copy) {
|
||||
include('android_debug.apk')
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the generated 'android_dev.apk' binary template into the Godot bin directory.
|
||||
* Depends on the app build task to ensure the binary is generated prior to copying.
|
||||
*/
|
||||
task copyDevBinaryToBin(type: Copy) {
|
||||
dependsOn ':app:assembleDev'
|
||||
from('app/build/outputs/apk/dev')
|
||||
into(binDir)
|
||||
include('android_dev.apk')
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the generated 'android_release.apk' binary template into the Godot bin directory.
|
||||
* Depends on the app build task to ensure the binary is generated prior to copying.
|
||||
@ -66,7 +78,7 @@ task copyReleaseBinaryToBin(type: Copy) {
|
||||
* Depends on the library build task to ensure the AAR file is generated prior to copying.
|
||||
*/
|
||||
task copyDebugAARToAppModule(type: Copy) {
|
||||
dependsOn ':lib:assembleDebug'
|
||||
dependsOn ':lib:assembleTemplateDebug'
|
||||
from('lib/build/outputs/aar')
|
||||
into('app/libs/debug')
|
||||
include('godot-lib.debug.aar')
|
||||
@ -77,18 +89,40 @@ task copyDebugAARToAppModule(type: Copy) {
|
||||
* Depends on the library build task to ensure the AAR file is generated prior to copying.
|
||||
*/
|
||||
task copyDebugAARToBin(type: Copy) {
|
||||
dependsOn ':lib:assembleDebug'
|
||||
dependsOn ':lib:assembleTemplateDebug'
|
||||
from('lib/build/outputs/aar')
|
||||
into(binDir)
|
||||
include('godot-lib.debug.aar')
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the Godot android library archive dev file into the app module dev libs directory.
|
||||
* Depends on the library build task to ensure the AAR file is generated prior to copying.
|
||||
*/
|
||||
task copyDevAARToAppModule(type: Copy) {
|
||||
dependsOn ':lib:assembleTemplateDev'
|
||||
from('lib/build/outputs/aar')
|
||||
into('app/libs/dev')
|
||||
include('godot-lib.dev.aar')
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the Godot android library archive dev file into the root bin directory.
|
||||
* Depends on the library build task to ensure the AAR file is generated prior to copying.
|
||||
*/
|
||||
task copyDevAARToBin(type: Copy) {
|
||||
dependsOn ':lib:assembleTemplateDev'
|
||||
from('lib/build/outputs/aar')
|
||||
into(binDir)
|
||||
include('godot-lib.dev.aar')
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the Godot android library archive release file into the app module release libs directory.
|
||||
* Depends on the library build task to ensure the AAR file is generated prior to copying.
|
||||
*/
|
||||
task copyReleaseAARToAppModule(type: Copy) {
|
||||
dependsOn ':lib:assembleRelease'
|
||||
dependsOn ':lib:assembleTemplateRelease'
|
||||
from('lib/build/outputs/aar')
|
||||
into('app/libs/release')
|
||||
include('godot-lib.release.aar')
|
||||
@ -99,7 +133,7 @@ task copyReleaseAARToAppModule(type: Copy) {
|
||||
* Depends on the library build task to ensure the AAR file is generated prior to copying.
|
||||
*/
|
||||
task copyReleaseAARToBin(type: Copy) {
|
||||
dependsOn ':lib:assembleRelease'
|
||||
dependsOn ':lib:assembleToolsDisabledRelease'
|
||||
from('lib/build/outputs/aar')
|
||||
into(binDir)
|
||||
include('godot-lib.release.aar')
|
||||
@ -107,7 +141,7 @@ task copyReleaseAARToBin(type: Copy) {
|
||||
|
||||
/**
|
||||
* Generate Godot custom build template by zipping the source files from the app directory, as well
|
||||
* as the AAR files generated by 'copyDebugAAR' and 'copyReleaseAAR'.
|
||||
* as the AAR files generated by 'copyDebugAAR', 'copyDevAAR' and 'copyReleaseAAR'.
|
||||
* The zip file also includes some gradle tools to allow building of the custom build.
|
||||
*/
|
||||
task zipCustomBuild(type: Zip) {
|
||||
@ -126,8 +160,18 @@ def templateExcludedBuildTask() {
|
||||
def excludedTasks = []
|
||||
if (!isAndroidStudio()) {
|
||||
logger.lifecycle("Excluding Android studio build tasks")
|
||||
for (String buildType : supportedTargets) {
|
||||
excludedTasks += ":lib:" + getSconsTaskName(buildType)
|
||||
for (String flavor : supportedFlavors) {
|
||||
for (String buildType : supportedTargetsMap.keySet()) {
|
||||
if (buildType == "release" && flavor == "editor") {
|
||||
// The editor can't be used with target=release as debugging tools are then not
|
||||
// included, and it would crash on errors instead of reporting them.
|
||||
continue
|
||||
}
|
||||
|
||||
for (String abi : selectedAbis) {
|
||||
excludedTasks += ":lib:" + getSconsTaskName(flavor, buildType, abi)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return excludedTasks
|
||||
@ -137,7 +181,7 @@ def templateBuildTasks() {
|
||||
def tasks = []
|
||||
|
||||
// Only build the apks and aar files for which we have native shared libraries.
|
||||
for (String target : supportedTargets) {
|
||||
for (String target : supportedTargetsMap.keySet()) {
|
||||
File targetLibs = new File("lib/libs/" + target)
|
||||
if (targetLibs != null
|
||||
&& targetLibs.isDirectory()
|
||||
@ -163,6 +207,50 @@ def isAndroidStudio() {
|
||||
return sysProps != null && sysProps['idea.platform.prefix'] != null
|
||||
}
|
||||
|
||||
task copyEditorDebugBinaryToBin(type: Copy) {
|
||||
dependsOn ':editor:assembleDebug'
|
||||
from('editor/build/outputs/apk/debug')
|
||||
into(binDir)
|
||||
include('android_editor.apk')
|
||||
}
|
||||
|
||||
task copyEditorDevBinaryToBin(type: Copy) {
|
||||
dependsOn ':editor:assembleDev'
|
||||
from('editor/build/outputs/apk/dev')
|
||||
into(binDir)
|
||||
include('android_editor_dev.apk')
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the Godot Editor Android apk.
|
||||
*
|
||||
* Note: The Godot 'tools' shared libraries must have been generated (via scons) prior to running
|
||||
* this gradle task. The task will only build the apk(s) for which the shared libraries is
|
||||
* available.
|
||||
*/
|
||||
task generateGodotEditor {
|
||||
gradle.startParameter.excludedTaskNames += templateExcludedBuildTask()
|
||||
|
||||
def tasks = []
|
||||
|
||||
for (String target : supportedTargetsMap.keySet()) {
|
||||
if (target == "release") {
|
||||
// The editor can't be used with target=release as debugging tools are then not
|
||||
// included, and it would crash on errors instead of reporting them.
|
||||
continue
|
||||
}
|
||||
File targetLibs = new File("lib/libs/tools/" + target)
|
||||
if (targetLibs != null
|
||||
&& targetLibs.isDirectory()
|
||||
&& targetLibs.listFiles() != null
|
||||
&& targetLibs.listFiles().length > 0) {
|
||||
tasks += "copyEditor${target.capitalize()}BinaryToBin"
|
||||
}
|
||||
}
|
||||
|
||||
dependsOn = tasks
|
||||
}
|
||||
|
||||
/**
|
||||
* Master task used to coordinate the tasks defined above to generate the set of Godot templates.
|
||||
*/
|
||||
@ -187,7 +275,27 @@ task generateDevTemplate {
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean the generated artifacts.
|
||||
* Clean the generated editor artifacts.
|
||||
*/
|
||||
task cleanGodotEditor(type: Delete) {
|
||||
// Delete the generated native tools libs
|
||||
delete("lib/libs/tools")
|
||||
|
||||
// Delete the library generated AAR files
|
||||
delete("lib/build/outputs/aar")
|
||||
|
||||
// Delete the generated binary apks
|
||||
delete("editor/build/outputs/apk")
|
||||
|
||||
// Delete the Godot editor apks in the Godot bin directory
|
||||
delete("$binDir/android_editor.apk")
|
||||
delete("$binDir/android_editor_dev.apk")
|
||||
|
||||
finalizedBy getTasksByName("clean", true)
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean the generated template artifacts.
|
||||
*/
|
||||
task cleanGodotTemplates(type: Delete) {
|
||||
// Delete the generated native libs
|
||||
@ -204,9 +312,11 @@ task cleanGodotTemplates(type: Delete) {
|
||||
|
||||
// Delete the Godot templates in the Godot bin directory
|
||||
delete("$binDir/android_debug.apk")
|
||||
delete("$binDir/android_dev.apk")
|
||||
delete("$binDir/android_release.apk")
|
||||
delete("$binDir/android_source.zip")
|
||||
delete("$binDir/godot-lib.debug.aar")
|
||||
delete("$binDir/godot-lib.dev.aar")
|
||||
delete("$binDir/godot-lib.release.aar")
|
||||
|
||||
finalizedBy getTasksByName("clean", true)
|
||||
|
73
platform/android/java/editor/build.gradle
Normal file
73
platform/android/java/editor/build.gradle
Normal file
@ -0,0 +1,73 @@
|
||||
// Gradle build config for Godot Engine's Android port.
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
dependencies {
|
||||
implementation libraries.kotlinStdLib
|
||||
implementation libraries.androidxFragment
|
||||
implementation project(":lib")
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion versions.compileSdk
|
||||
buildToolsVersion versions.buildTools
|
||||
ndkVersion versions.ndkVersion
|
||||
|
||||
defaultConfig {
|
||||
// The 'applicationId' suffix allows to install Godot 3.x(v3) and 4.x(v4) on the same device
|
||||
applicationId "org.godotengine.editor.v3"
|
||||
versionCode getGodotLibraryVersionCode()
|
||||
versionName getGodotLibraryVersionName()
|
||||
minSdkVersion versions.minSdk
|
||||
//noinspection ExpiredTargetSdkVersion - Restrict to version 29 until https://github.com/godotengine/godot/pull/51815 is submitted
|
||||
targetSdkVersion 29 // versions.targetSdk
|
||||
missingDimensionStrategy 'products', 'editor'
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility versions.javaVersion
|
||||
targetCompatibility versions.javaVersion
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
dev {
|
||||
initWith debug
|
||||
applicationIdSuffix ".dev"
|
||||
}
|
||||
|
||||
debug {
|
||||
initWith release
|
||||
|
||||
// Need to swap with the release signing config when this is ready for public release.
|
||||
signingConfig signingConfigs.debug
|
||||
}
|
||||
|
||||
release {
|
||||
// This buildtype is disabled below.
|
||||
// The editor can't be used with target=release only, as debugging tools are then not
|
||||
// included, and it would crash on errors instead of reporting them.
|
||||
}
|
||||
}
|
||||
|
||||
packagingOptions {
|
||||
// 'doNotStrip' is enabled for development within Android Studio
|
||||
if (shouldNotStrip()) {
|
||||
doNotStrip '**/*.so'
|
||||
}
|
||||
}
|
||||
|
||||
// Disable 'release' buildtype.
|
||||
// The editor can't be used with target=release only, as debugging tools are then not
|
||||
// included, and it would crash on errors instead of reporting them.
|
||||
variantFilter { variant ->
|
||||
if (variant.buildType.name == "release") {
|
||||
setIgnore(true)
|
||||
}
|
||||
}
|
||||
|
||||
applicationVariants.all { variant ->
|
||||
variant.outputs.all { output ->
|
||||
def suffix = variant.name == "dev" ? "_dev" : ""
|
||||
output.outputFileName = "android_editor${suffix}.apk"
|
||||
}
|
||||
}
|
||||
}
|
67
platform/android/java/editor/src/main/AndroidManifest.xml
Normal file
67
platform/android/java/editor/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,67 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="org.godotengine.editor"
|
||||
android:installLocation="auto">
|
||||
|
||||
<supports-screens
|
||||
android:largeScreens="true"
|
||||
android:normalScreens="true"
|
||||
android:smallScreens="true"
|
||||
android:xlargeScreens="true" />
|
||||
|
||||
<uses-feature
|
||||
android:glEsVersion="0x00020000"
|
||||
android:required="true" />
|
||||
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
<application
|
||||
android:allowBackup="false"
|
||||
android:icon="@mipmap/icon"
|
||||
android:label="@string/godot_editor_name_string"
|
||||
tools:ignore="GoogleAppIndexingWarning"
|
||||
android:requestLegacyExternalStorage="true">
|
||||
|
||||
<activity
|
||||
android:name=".GodotProjectManager"
|
||||
android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize|density|keyboard|navigation|screenLayout|uiMode"
|
||||
android:launchMode="singleTask"
|
||||
android:resizeableActivity="false"
|
||||
android:screenOrientation="landscape"
|
||||
android:exported="true"
|
||||
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"
|
||||
android:process=":GodotProjectManager">
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".GodotEditor"
|
||||
android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize|density|keyboard|navigation|screenLayout|uiMode"
|
||||
android:process=":GodotEditor"
|
||||
android:launchMode="singleTask"
|
||||
android:resizeableActivity="false"
|
||||
android:screenOrientation="landscape"
|
||||
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen">
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".GodotGame"
|
||||
android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize|density|keyboard|navigation|screenLayout|uiMode"
|
||||
android:label="@string/godot_project_name_string"
|
||||
android:process=":GodotGame"
|
||||
android:launchMode="singleTask"
|
||||
android:resizeableActivity="false"
|
||||
android:screenOrientation="landscape"
|
||||
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen">
|
||||
</activity>
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
@ -0,0 +1,110 @@
|
||||
/*************************************************************************/
|
||||
/* GodotEditor.java */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
package org.godotengine.editor;
|
||||
|
||||
import org.godotengine.godot.FullScreenGodotApp;
|
||||
import org.godotengine.godot.utils.PermissionsUtil;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Debug;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Base class for the Godot Android Editor activities.
|
||||
*
|
||||
* This provides the basic templates for the activities making up this application.
|
||||
* Each derived activity runs in its own process, which enable up to have several instances of
|
||||
* the Godot engine up and running at the same time.
|
||||
*
|
||||
* It also plays the role of the primary editor window.
|
||||
*/
|
||||
public class GodotEditor extends FullScreenGodotApp {
|
||||
private static final boolean WAIT_FOR_DEBUGGER = false;
|
||||
private static final String COMMAND_LINE_PARAMS = "command_line_params";
|
||||
|
||||
private static final String EDITOR_ARG = "--editor";
|
||||
private static final String PROJECT_MANAGER_ARG = "--project-manager";
|
||||
|
||||
private final List<String> commandLineParams = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
PermissionsUtil.requestManifestPermissions(this);
|
||||
|
||||
String[] params = getIntent().getStringArrayExtra(COMMAND_LINE_PARAMS);
|
||||
updateCommandLineParams(params);
|
||||
|
||||
if (BuildConfig.BUILD_TYPE.equals("debug") && WAIT_FOR_DEBUGGER) {
|
||||
Debug.waitForDebugger();
|
||||
}
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
private void updateCommandLineParams(@Nullable String[] args) {
|
||||
// Update the list of command line params with the new args
|
||||
commandLineParams.clear();
|
||||
if (args != null && args.length > 0) {
|
||||
commandLineParams.addAll(Arrays.asList(args));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getCommandLine() {
|
||||
return commandLineParams;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewGodotInstanceRequested(String[] args) {
|
||||
// Parse the arguments to figure out which activity to start.
|
||||
Class<?> targetClass = GodotGame.class;
|
||||
for (String arg : args) {
|
||||
if (EDITOR_ARG.equals(arg)) {
|
||||
targetClass = GodotEditor.class;
|
||||
break;
|
||||
}
|
||||
|
||||
if (PROJECT_MANAGER_ARG.equals(arg)) {
|
||||
targetClass = GodotProjectManager.class;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Launch a new activity
|
||||
Intent newInstance = new Intent(this, targetClass).putExtra(COMMAND_LINE_PARAMS, args);
|
||||
startActivity(newInstance);
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
/*************************************************************************/
|
||||
/* GodotGame.java */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
package org.godotengine.editor;
|
||||
|
||||
/**
|
||||
* Drives the 'run project' window of the Godot Editor.
|
||||
*/
|
||||
public class GodotGame extends GodotEditor {
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
/*************************************************************************/
|
||||
/* GodotProjectManager.java */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
package org.godotengine.editor;
|
||||
|
||||
/**
|
||||
* Launcher activity for the Godot Android Editor.
|
||||
*
|
||||
* It presents the user with the project manager interface.
|
||||
* Upon selection of a project, this activity (via its parent logic) starts the
|
||||
* {@link GodotEditor} activity.
|
||||
*/
|
||||
public class GodotProjectManager extends GodotEditor {
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="godot_editor_name_string">Godot Editor</string>
|
||||
</resources>
|
@ -11,14 +11,13 @@ def pathToRootDir = "../../../../"
|
||||
android {
|
||||
compileSdkVersion versions.compileSdk
|
||||
buildToolsVersion versions.buildTools
|
||||
|
||||
ndkVersion versions.ndkVersion
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion versions.minSdk
|
||||
targetSdkVersion versions.targetSdk
|
||||
|
||||
manifestPlaceholders = [godotLibraryVersion: getGodotLibraryVersion()]
|
||||
manifestPlaceholders = [godotLibraryVersion: getGodotLibraryVersionName()]
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
@ -26,6 +25,18 @@ android {
|
||||
targetCompatibility versions.javaVersion
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
dev {
|
||||
initWith debug
|
||||
}
|
||||
}
|
||||
|
||||
flavorDimensions "products"
|
||||
productFlavors {
|
||||
editor {}
|
||||
template {}
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
abortOnError false
|
||||
disable 'MissingTranslation', 'UnusedResources'
|
||||
@ -49,24 +60,52 @@ android {
|
||||
aidl.srcDirs = ['aidl']
|
||||
assets.srcDirs = ['assets']
|
||||
}
|
||||
|
||||
debug.jniLibs.srcDirs = ['libs/debug']
|
||||
dev.jniLibs.srcDirs = ['libs/dev']
|
||||
release.jniLibs.srcDirs = ['libs/release']
|
||||
|
||||
// Editor jni library
|
||||
editorDebug.jniLibs.srcDirs = ['libs/tools/debug']
|
||||
editorDev.jniLibs.srcDirs = ['libs/tools/dev']
|
||||
}
|
||||
|
||||
// Disable 'editorRelease'.
|
||||
// The editor can't be used with target=release as debugging tools are then not
|
||||
// included, and it would crash on errors instead of reporting them.
|
||||
variantFilter { variant ->
|
||||
if (variant.name == "editorRelease") {
|
||||
setIgnore(true)
|
||||
}
|
||||
}
|
||||
|
||||
libraryVariants.all { variant ->
|
||||
def flavorName = variant.getFlavorName()
|
||||
|
||||
if (flavorName == null || flavorName == "") {
|
||||
throw new GradleException("Invalid product flavor: $flavorName")
|
||||
}
|
||||
|
||||
boolean toolsFlag = flavorName == "editor"
|
||||
|
||||
def buildType = variant.buildType.name
|
||||
if (buildType == null || buildType == "" || !supportedTargetsMap.containsKey(buildType)) {
|
||||
throw new GradleException("Invalid build type: $buildType")
|
||||
}
|
||||
|
||||
def sconsTarget = supportedTargetsMap[buildType]
|
||||
if (sconsTarget == null || sconsTarget == "") {
|
||||
throw new GradleException("Invalid scons target: $sconsTarget")
|
||||
}
|
||||
|
||||
// Update the name of the generated library
|
||||
def outputSuffix = "${buildType}.aar"
|
||||
if (toolsFlag) {
|
||||
outputSuffix = "tools.$outputSuffix"
|
||||
}
|
||||
|
||||
variant.outputs.all { output ->
|
||||
output.outputFileName = "godot-lib.${variant.name}.aar"
|
||||
}
|
||||
|
||||
def buildType = variant.buildType.name.capitalize()
|
||||
|
||||
def releaseTarget = buildType.toLowerCase()
|
||||
if (releaseTarget == null || releaseTarget == "") {
|
||||
throw new GradleException("Invalid build type: " + buildType)
|
||||
}
|
||||
|
||||
if (!supportedAbis.contains(defaultAbi)) {
|
||||
throw new GradleException("Invalid default abi: " + defaultAbi)
|
||||
output.outputFileName = "godot-lib.${outputSuffix}"
|
||||
}
|
||||
|
||||
// Find scons' executable path
|
||||
@ -101,14 +140,20 @@ android {
|
||||
logger.lifecycle("Found executable path for $sconsName: ${sconsExecutableFile.absolutePath}")
|
||||
}
|
||||
|
||||
// Creating gradle task to generate the native libraries for the default abi.
|
||||
def taskName = getSconsTaskName(buildType)
|
||||
tasks.create(name: taskName, type: Exec) {
|
||||
executable sconsExecutableFile.absolutePath
|
||||
args "--directory=${pathToRootDir}", "platform=android", "target=${releaseTarget}", "android_arch=${defaultAbi}", "-j" + Runtime.runtime.availableProcessors()
|
||||
}
|
||||
for (String selectedAbi : selectedAbis) {
|
||||
if (!supportedAbis.contains(selectedAbi)) {
|
||||
throw new GradleException("Invalid selected abi: $selectedAbi")
|
||||
}
|
||||
|
||||
// Schedule the tasks so the generated libs are present before the aar file is packaged.
|
||||
tasks["merge${buildType}JniLibFolders"].dependsOn taskName
|
||||
// Creating gradle task to generate the native libraries for the selected abi.
|
||||
def taskName = getSconsTaskName(flavorName, buildType, selectedAbi)
|
||||
tasks.create(name: taskName, type: Exec) {
|
||||
executable sconsExecutableFile.absolutePath
|
||||
args "--directory=${pathToRootDir}", "platform=android", "tools=${toolsFlag}", "target=${sconsTarget}", "android_arch=${selectedAbi}", "-j" + Runtime.runtime.availableProcessors()
|
||||
}
|
||||
|
||||
// Schedule the tasks so the generated libs are present before the aar file is packaged.
|
||||
tasks["merge${flavorName.capitalize()}${buildType.capitalize()}JniLibFolders"].dependsOn taskName
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -47,7 +47,6 @@ import android.app.AlertDialog;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
@ -449,9 +448,11 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
|
||||
}
|
||||
|
||||
public void restart() {
|
||||
if (godotHost != null) {
|
||||
godotHost.onGodotRestartRequested(this);
|
||||
}
|
||||
runOnUiThread(() -> {
|
||||
if (godotHost != null) {
|
||||
godotHost.onGodotRestartRequested(this);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void alert(final String message, final String title) {
|
||||
@ -995,9 +996,11 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
|
||||
private void forceQuit() {
|
||||
// TODO: This is a temp solution. The proper fix will involve tracking down and properly shutting down each
|
||||
// native Godot components that is started in Godot#onVideoInit.
|
||||
if (godotHost != null) {
|
||||
godotHost.onGodotForceQuit(this);
|
||||
}
|
||||
runOnUiThread(() -> {
|
||||
if (godotHost != null) {
|
||||
godotHost.onGodotForceQuit(this);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private boolean obbIsCorrupted(String f, String main_pack_md5) {
|
||||
@ -1146,7 +1149,17 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
|
||||
mProgressFraction.setText(Helpers.getDownloadProgressString(progress.mOverallProgress,
|
||||
progress.mOverallTotal));
|
||||
}
|
||||
|
||||
public void initInputDevices() {
|
||||
mView.initInputDevices();
|
||||
}
|
||||
|
||||
@Keep
|
||||
private void createNewGodotInstance(String[] args) {
|
||||
runOnUiThread(() -> {
|
||||
if (godotHost != null) {
|
||||
godotHost.onNewGodotInstanceRequested(args);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -60,8 +60,16 @@ public interface GodotHost {
|
||||
default void onGodotForceQuit(Godot instance) {}
|
||||
|
||||
/**
|
||||
* Invoked on the GL thread when the Godot instance wants to be restarted. It's up to the host
|
||||
* Invoked on the UI thread when the Godot instance wants to be restarted. It's up to the host
|
||||
* to perform the appropriate action(s).
|
||||
*/
|
||||
default void onGodotRestartRequested(Godot instance) {}
|
||||
|
||||
/**
|
||||
* Invoked on the UI thread when a new Godot instance is requested. It's up to the host to
|
||||
* perform the appropriate action(s).
|
||||
*
|
||||
* @param args Arguments used to initialize the new instance.
|
||||
*/
|
||||
default void onNewGodotInstanceRequested(String[] args) {}
|
||||
}
|
||||
|
@ -17,3 +17,5 @@ target_include_directories(${PROJECT_NAME}
|
||||
SYSTEM PUBLIC
|
||||
${GODOT_ROOT_DIR}
|
||||
${GODOT_ROOT_DIR}/modules/gdnative/include)
|
||||
|
||||
add_definitions(-DUNIX_ENABLED -DTOOLS_ENABLED)
|
@ -6,6 +6,7 @@ plugins {
|
||||
android {
|
||||
compileSdkVersion versions.compileSdk
|
||||
buildToolsVersion versions.buildTools
|
||||
ndkVersion versions.ndkVersion
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion versions.minSdk
|
||||
|
@ -4,6 +4,7 @@ rootProject.name = "Godot"
|
||||
include ':app'
|
||||
include ':lib'
|
||||
include ':nativeSrcsConfigs'
|
||||
include ':editor'
|
||||
|
||||
include ':assetPacks:installTime'
|
||||
project(':assetPacks:installTime').projectDir = file("app/assetPacks/installTime")
|
||||
|
@ -148,6 +148,9 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env, jclass clazz) {
|
||||
// lets cleanup
|
||||
if (java_class_wrapper) {
|
||||
memdelete(java_class_wrapper);
|
||||
}
|
||||
if (godot_io_java) {
|
||||
delete godot_io_java;
|
||||
}
|
||||
@ -188,7 +191,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jc
|
||||
}
|
||||
}
|
||||
|
||||
Error err = Main::setup("apk", cmdlen, (char **)cmdline, false);
|
||||
Error err = Main::setup(OS_Android::ANDROID_EXEC_PATH, cmdlen, (char **)cmdline, false);
|
||||
if (cmdline) {
|
||||
if (j_cmdline) {
|
||||
for (int i = 0; i < cmdlen; ++i) {
|
||||
|
@ -80,6 +80,7 @@ GodotJavaWrapper::GodotJavaWrapper(JNIEnv *p_env, jobject p_activity, jobject p_
|
||||
_get_input_fallback_mapping = p_env->GetMethodID(godot_class, "getInputFallbackMapping", "()Ljava/lang/String;");
|
||||
_on_godot_setup_completed = p_env->GetMethodID(godot_class, "onGodotSetupCompleted", "()V");
|
||||
_on_godot_main_loop_started = p_env->GetMethodID(godot_class, "onGodotMainLoopStarted", "()V");
|
||||
_create_new_godot_instance = p_env->GetMethodID(godot_class, "createNewGodotInstance", "([Ljava/lang/String;)V");
|
||||
|
||||
// get some Activity method pointers...
|
||||
_get_class_loader = p_env->GetMethodID(activity_class, "getClassLoader", "()Ljava/lang/ClassLoader;");
|
||||
@ -369,3 +370,16 @@ void GodotJavaWrapper::vibrate(int p_duration_ms) {
|
||||
env->CallVoidMethod(godot_instance, _vibrate, p_duration_ms);
|
||||
}
|
||||
}
|
||||
|
||||
void GodotJavaWrapper::create_new_godot_instance(List<String> args) {
|
||||
if (_create_new_godot_instance) {
|
||||
JNIEnv *env = get_jni_env();
|
||||
ERR_FAIL_COND(env == nullptr);
|
||||
|
||||
jobjectArray jargs = env->NewObjectArray(args.size(), env->FindClass("java/lang/String"), env->NewStringUTF(""));
|
||||
for (int i = 0; i < args.size(); i++) {
|
||||
env->SetObjectArrayElement(jargs, i, env->NewStringUTF(args[i].utf8().get_data()));
|
||||
}
|
||||
env->CallVoidMethod(godot_instance, _create_new_godot_instance, jargs);
|
||||
}
|
||||
}
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <android/log.h>
|
||||
#include <jni.h>
|
||||
|
||||
#include "core/list.h"
|
||||
#include "string_android.h"
|
||||
|
||||
// Class that makes functions in java/src/org/godotengine/godot/Godot.java callable from C++
|
||||
@ -69,6 +70,7 @@ private:
|
||||
jmethodID _on_godot_setup_completed = 0;
|
||||
jmethodID _on_godot_main_loop_started = 0;
|
||||
jmethodID _get_class_loader = 0;
|
||||
jmethodID _create_new_godot_instance = 0;
|
||||
|
||||
public:
|
||||
GodotJavaWrapper(JNIEnv *p_env, jobject p_activity, jobject p_godot_instance);
|
||||
@ -105,6 +107,7 @@ public:
|
||||
bool is_activity_resumed();
|
||||
void vibrate(int p_duration_ms);
|
||||
String get_input_fallback_mapping();
|
||||
void create_new_godot_instance(List<String> args);
|
||||
};
|
||||
|
||||
#endif /* !JAVA_GODOT_WRAPPER_H */
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "drivers/unix/dir_access_unix.h"
|
||||
#include "drivers/unix/file_access_unix.h"
|
||||
#include "main/main.h"
|
||||
#include "scene/main/scene_tree.h"
|
||||
#include "servers/visual/visual_server_raster.h"
|
||||
#include "servers/visual/visual_server_wrap_mt.h"
|
||||
|
||||
@ -49,6 +50,8 @@
|
||||
#include "java_godot_io_wrapper.h"
|
||||
#include "java_godot_wrapper.h"
|
||||
|
||||
const char *OS_Android::ANDROID_EXEC_PATH = "apk";
|
||||
|
||||
String _remove_symlink(const String &dir) {
|
||||
// Workaround for Android 6.0+ using a symlink.
|
||||
// Save the current directory.
|
||||
@ -97,17 +100,28 @@ const char *OS_Android::get_audio_driver_name(int p_driver) const {
|
||||
void OS_Android::initialize_core() {
|
||||
OS_Unix::initialize_core();
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_RESOURCES);
|
||||
#else
|
||||
if (use_apk_expansion)
|
||||
FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_RESOURCES);
|
||||
else {
|
||||
FileAccess::make_default<FileAccessAndroid>(FileAccess::ACCESS_RESOURCES);
|
||||
}
|
||||
#endif
|
||||
|
||||
FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_USERDATA);
|
||||
FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_FILESYSTEM);
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
DirAccess::make_default<DirAccessUnix>(DirAccess::ACCESS_RESOURCES);
|
||||
#else
|
||||
if (use_apk_expansion)
|
||||
DirAccess::make_default<DirAccessUnix>(DirAccess::ACCESS_RESOURCES);
|
||||
else
|
||||
DirAccess::make_default<DirAccessJAndroid>(DirAccess::ACCESS_RESOURCES);
|
||||
#endif
|
||||
|
||||
DirAccess::make_default<DirAccessUnix>(DirAccess::ACCESS_USERDATA);
|
||||
DirAccess::make_default<DirAccessUnix>(DirAccess::ACCESS_FILESYSTEM);
|
||||
|
||||
@ -263,6 +277,15 @@ void OS_Android::set_keep_screen_on(bool p_enabled) {
|
||||
godot_java->set_keep_screen_on(p_enabled);
|
||||
}
|
||||
|
||||
void OS_Android::set_low_processor_usage_mode(bool p_enabled) {
|
||||
#ifdef TOOLS_ENABLED
|
||||
// Disabled as it causes flickers. We also expect the devices running Godot in editor mode to be high end.
|
||||
OS_Unix::set_low_processor_usage_mode(false);
|
||||
#else
|
||||
OS_Unix::set_low_processor_usage_mode(p_enabled);
|
||||
#endif
|
||||
}
|
||||
|
||||
Size2 OS_Android::get_window_size() const {
|
||||
return Vector2(default_videomode.width, default_videomode.height);
|
||||
}
|
||||
@ -297,8 +320,15 @@ bool OS_Android::main_loop_iterate() {
|
||||
}
|
||||
|
||||
void OS_Android::main_loop_end() {
|
||||
if (main_loop)
|
||||
if (main_loop) {
|
||||
SceneTree *scene_tree = Object::cast_to<SceneTree>(main_loop);
|
||||
|
||||
if (scene_tree) {
|
||||
scene_tree->quit();
|
||||
}
|
||||
|
||||
main_loop->finish();
|
||||
}
|
||||
}
|
||||
|
||||
void OS_Android::main_loop_focusout() {
|
||||
@ -377,7 +407,11 @@ Error OS_Android::shell_open(String p_uri) {
|
||||
}
|
||||
|
||||
String OS_Android::get_resource_dir() const {
|
||||
#ifdef TOOLS_ENABLED
|
||||
return OS_Unix::get_resource_dir();
|
||||
#else
|
||||
return "/"; //android has its own filesystem for resources inside the APK
|
||||
#endif
|
||||
}
|
||||
|
||||
String OS_Android::get_locale() const {
|
||||
@ -436,6 +470,14 @@ String OS_Android::get_data_path() const {
|
||||
return get_user_data_dir();
|
||||
}
|
||||
|
||||
String OS_Android::get_executable_path() const {
|
||||
// Since unix process creation is restricted on Android, we bypass
|
||||
// OS_Unix::get_executable_path() so we can return ANDROID_EXEC_PATH.
|
||||
// Detection of ANDROID_EXEC_PATH allows to handle process creation in an Android compliant
|
||||
// manner.
|
||||
return OS::get_executable_path();
|
||||
}
|
||||
|
||||
String OS_Android::get_user_data_dir() const {
|
||||
if (data_dir_cache != String())
|
||||
return data_dir_cache;
|
||||
@ -508,6 +550,10 @@ void OS_Android::vibrate_handheld(int p_duration_ms) {
|
||||
godot_java->vibrate(p_duration_ms);
|
||||
}
|
||||
|
||||
String OS_Android::get_config_path() const {
|
||||
return get_user_data_dir().plus_file("config");
|
||||
}
|
||||
|
||||
bool OS_Android::_check_internal_feature_support(const String &p_feature) {
|
||||
if (p_feature == "mobile") {
|
||||
//TODO support etc2 only if GLES3 driver is selected
|
||||
@ -551,5 +597,18 @@ OS_Android::OS_Android(GodotJavaWrapper *p_godot_java, GodotIOJavaWrapper *p_god
|
||||
AudioDriverManager::add_driver(&audio_driver_android);
|
||||
}
|
||||
|
||||
Error OS_Android::execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex, bool p_open_console) {
|
||||
if (p_path == ANDROID_EXEC_PATH) {
|
||||
return create_instance(p_arguments, r_child_id);
|
||||
} else {
|
||||
return OS_Unix::execute(p_path, p_arguments, p_blocking, r_child_id, r_pipe, r_exitcode, read_stderr, p_pipe_mutex, p_open_console);
|
||||
}
|
||||
}
|
||||
|
||||
Error OS_Android::create_instance(const List<String> &p_arguments, ProcessID *r_child_id) {
|
||||
godot_java->create_new_godot_instance(p_arguments);
|
||||
return OK;
|
||||
}
|
||||
|
||||
OS_Android::~OS_Android() {
|
||||
}
|
||||
|
@ -69,6 +69,8 @@ class OS_Android : public OS_Unix {
|
||||
bool transparency_enabled = false;
|
||||
|
||||
public:
|
||||
static const char *ANDROID_EXEC_PATH;
|
||||
|
||||
// functions used by main to initialize/deinitialize the OS
|
||||
virtual int get_video_driver_count() const;
|
||||
virtual const char *get_video_driver_name(int p_driver) const;
|
||||
@ -110,6 +112,7 @@ public:
|
||||
virtual void get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen = 0) const;
|
||||
|
||||
virtual void set_keep_screen_on(bool p_enabled);
|
||||
virtual void set_low_processor_usage_mode(bool p_enabled);
|
||||
|
||||
virtual Size2 get_window_size() const;
|
||||
virtual Rect2 get_window_safe_area() const;
|
||||
@ -143,6 +146,7 @@ public:
|
||||
virtual ScreenOrientation get_screen_orientation() const;
|
||||
|
||||
virtual Error shell_open(String p_uri);
|
||||
virtual String get_executable_path() const;
|
||||
virtual String get_user_data_dir() const;
|
||||
virtual String get_data_path() const;
|
||||
virtual String get_cache_path() const;
|
||||
@ -172,9 +176,15 @@ public:
|
||||
virtual String get_joy_guid(int p_device) const;
|
||||
void vibrate_handheld(int p_duration_ms);
|
||||
|
||||
virtual String get_config_path() const;
|
||||
virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking = true, ProcessID *r_child_id = nullptr, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr, bool p_open_console = false);
|
||||
|
||||
virtual bool _check_internal_feature_support(const String &p_feature);
|
||||
OS_Android(GodotJavaWrapper *p_godot_java, GodotIOJavaWrapper *p_godot_io_java, bool p_use_apk_expansion);
|
||||
~OS_Android();
|
||||
|
||||
private:
|
||||
Error create_instance(const List<String> &p_arguments, ProcessID *r_child_id);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1380,6 +1380,10 @@ Vector2 Viewport::_get_window_offset() const {
|
||||
}
|
||||
|
||||
Ref<InputEvent> Viewport::_make_input_local(const Ref<InputEvent> &ev) {
|
||||
if (ev.is_null()) {
|
||||
return ev;
|
||||
}
|
||||
|
||||
Vector2 vp_ofs = _get_window_offset();
|
||||
Transform2D ai = get_final_transform().affine_inverse() * _get_input_pre_xform();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user