aboutsummaryrefslogtreecommitdiff
path: root/platform/android/java
diff options
context:
space:
mode:
authorJuan Linietsky2014-02-09 22:10:30 -0300
committerJuan Linietsky2014-02-09 22:10:30 -0300
commit0b806ee0fc9097fa7bda7ac0109191c9c5e0a1ac (patch)
tree276c4d099e178eb67fbd14f61d77b05e3808e9e3 /platform/android/java
parent0e49da1687bc8192ed210947da52c9e5c5f301bb (diff)
downloadgodot-0b806ee.tar.gz
godot-0b806ee.tar.zst
godot-0b806ee.zip
GODOT IS OPEN SOURCE
Diffstat (limited to '')
-rw-r--r--platform/android/java/ant.properties22
-rw-r--r--platform/android/java/build.properties17
-rw-r--r--platform/android/java/build.xml92
-rw-r--r--platform/android/java/default.properties11
-rw-r--r--platform/android/java/my-release-key.keystorebin0 -> 2218 bytes
-rw-r--r--platform/android/java/proguard-project.txt20
-rw-r--r--platform/android/java/proguard.cfg36
-rw-r--r--platform/android/java/res/drawable/icon.pngbin0 -> 91728 bytes
-rw-r--r--platform/android/java/res/values-ar/strings.xml4
-rw-r--r--platform/android/java/res/values-bg/strings.xml4
-rw-r--r--platform/android/java/res/values-ca/strings.xml4
-rw-r--r--platform/android/java/res/values-cs/strings.xml4
-rw-r--r--platform/android/java/res/values-da/strings.xml4
-rw-r--r--platform/android/java/res/values-de/strings.xml4
-rw-r--r--platform/android/java/res/values-el/strings.xml4
-rw-r--r--platform/android/java/res/values-en/strings.xml4
-rw-r--r--platform/android/java/res/values-es-rES/strings.xml4
-rw-r--r--platform/android/java/res/values-es/strings.xml4
-rw-r--r--platform/android/java/res/values-fi/strings.xml4
-rw-r--r--platform/android/java/res/values-fr/strings.xml4
-rw-r--r--platform/android/java/res/values-he/strings.xml4
-rw-r--r--platform/android/java/res/values-hi/strings.xml4
-rw-r--r--platform/android/java/res/values-hr/strings.xml4
-rw-r--r--platform/android/java/res/values-hu/strings.xml4
-rw-r--r--platform/android/java/res/values-id/strings.xml4
-rw-r--r--platform/android/java/res/values-it/strings.xml4
-rw-r--r--platform/android/java/res/values-ja/strings.xml4
-rw-r--r--platform/android/java/res/values-ko/strings.xml4
-rw-r--r--platform/android/java/res/values-lt/strings.xml4
-rw-r--r--platform/android/java/res/values-lv/strings.xml4
-rw-r--r--platform/android/java/res/values-nb/strings.xml4
-rw-r--r--platform/android/java/res/values-nl/strings.xml4
-rw-r--r--platform/android/java/res/values-pl/strings.xml4
-rw-r--r--platform/android/java/res/values-pt/strings.xml4
-rw-r--r--platform/android/java/res/values-ro/strings.xml4
-rw-r--r--platform/android/java/res/values-ru/strings.xml4
-rw-r--r--platform/android/java/res/values-sk/strings.xml4
-rw-r--r--platform/android/java/res/values-sl/strings.xml4
-rw-r--r--platform/android/java/res/values-sr/strings.xml4
-rw-r--r--platform/android/java/res/values-sv/strings.xml4
-rw-r--r--platform/android/java/res/values-th/strings.xml4
-rw-r--r--platform/android/java/res/values-tl/strings.xml4
-rw-r--r--platform/android/java/res/values-tr/strings.xml4
-rw-r--r--platform/android/java/res/values-uk/strings.xml4
-rw-r--r--platform/android/java/res/values-vi/strings.xml4
-rw-r--r--platform/android/java/res/values-zh/strings.xml4
-rw-r--r--platform/android/java/res/values/strings.xml7
-rw-r--r--platform/android/java/src/com/android/godot/Dictionary.java80
-rw-r--r--platform/android/java/src/com/android/godot/Godot.java300
-rw-r--r--platform/android/java/src/com/android/godot/GodotIO.java514
-rw-r--r--platform/android/java/src/com/android/godot/GodotLib.java63
-rw-r--r--platform/android/java/src/com/android/godot/GodotView.java378
-rw-r--r--platform/android/java_glue.cpp1153
-rw-r--r--platform/android/java_glue.h58
54 files changed, 2903 insertions, 0 deletions
diff --git a/platform/android/java/ant.properties b/platform/android/java/ant.properties
new file mode 100644
index 000000000..950b8b019
--- /dev/null
+++ b/platform/android/java/ant.properties
@@ -0,0 +1,22 @@
+# This file is used to override default values used by the Ant build system.
+#
+# This file must be checked into Version Control Systems, as it is
+# integral to the build system of your project.
+
+# This file is only used by the Ant script.
+
+# You can use this to override default values such as
+# 'source.dir' for the location of your java source folder and
+# 'out.dir' for the location of your output folder.
+
+# You can also use it define how the release builds are signed by declaring
+# the following properties:
+# 'key.store' for the location of your keystore and
+# 'key.alias' for the name of the key to use.
+# The password will be asked during the build when you use the 'release' target.
+
+key.store=my-release-key.keystore
+key.alias=mykey
+
+key.store.password=123456
+key.alias.password=123456
diff --git a/platform/android/java/build.properties b/platform/android/java/build.properties
new file mode 100644
index 000000000..ee52d86d9
--- /dev/null
+++ b/platform/android/java/build.properties
@@ -0,0 +1,17 @@
+# This file is used to override default values used by the Ant build system.
+#
+# This file must be checked in Version Control Systems, as it is
+# integral to the build system of your project.
+
+# This file is only used by the Ant script.
+
+# You can use this to override default values such as
+# 'source.dir' for the location of your java source folder and
+# 'out.dir' for the location of your output folder.
+
+# You can also use it define how the release builds are signed by declaring
+# the following properties:
+# 'key.store' for the location of your keystore and
+# 'key.alias' for the name of the key to use.
+# The password will be asked during the build when you use the 'release' target.
+
diff --git a/platform/android/java/build.xml b/platform/android/java/build.xml
new file mode 100644
index 000000000..424e2827d
--- /dev/null
+++ b/platform/android/java/build.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="Godot" default="help">
+
+ <!-- The local.properties file is created and updated by the 'android' tool.
+ It contains the path to the SDK. It should *NOT* be checked into
+ Version Control Systems. -->
+ <property file="local.properties" />
+
+ <!-- The ant.properties file can be created by you. It is only edited by the
+ 'android' tool to add properties to it.
+ This is the place to change some Ant specific build properties.
+ Here are some properties you may want to change/update:
+
+ source.dir
+ The name of the source directory. Default is 'src'.
+ out.dir
+ The name of the output directory. Default is 'bin'.
+
+ For other overridable properties, look at the beginning of the rules
+ files in the SDK, at tools/ant/build.xml
+
+ Properties related to the SDK location or the project target should
+ be updated using the 'android' tool with the 'update' action.
+
+ This file is an integral part of the build system for your
+ application and should be checked into Version Control Systems.
+
+ -->
+ <property file="ant.properties" />
+
+ <!-- if sdk.dir was not set from one of the property file, then
+ get it from the ANDROID_HOME env var.
+ This must be done before we load project.properties since
+ the proguard config can use sdk.dir -->
+ <property environment="env" />
+ <condition property="sdk.dir" value="${env.ANDROID_HOME}">
+ <isset property="env.ANDROID_HOME" />
+ </condition>
+
+ <!-- The project.properties file is created and updated by the 'android'
+ tool, as well as ADT.
+
+ This contains project specific properties such as project target, and library
+ dependencies. Lower level build properties are stored in ant.properties
+ (or in .classpath for Eclipse projects).
+
+ This file is an integral part of the build system for your
+ application and should be checked into Version Control Systems. -->
+ <loadproperties srcFile="project.properties" />
+
+ <!-- quick check on sdk.dir -->
+ <fail
+ message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
+ unless="sdk.dir"
+ />
+
+ <!--
+ Import per project custom build rules if present at the root of the project.
+ This is the place to put custom intermediary targets such as:
+ -pre-build
+ -pre-compile
+ -post-compile (This is typically used for code obfuscation.
+ Compiled code location: ${out.classes.absolute.dir}
+ If this is not done in place, override ${out.dex.input.absolute.dir})
+ -post-package
+ -post-build
+ -pre-clean
+ -->
+ <import file="custom_rules.xml" optional="true" />
+
+ <!-- Import the actual build file.
+
+ To customize existing targets, there are two options:
+ - Customize only one target:
+ - copy/paste the target into this file, *before* the
+ <import> task.
+ - customize it to your needs.
+ - Customize the whole content of build.xml
+ - copy/paste the content of the rules files (minus the top node)
+ into this file, replacing the <import> task.
+ - customize to your needs.
+
+ ***********************
+ ****** IMPORTANT ******
+ ***********************
+ In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
+ in order to avoid having your file be overridden by tools such as "android update project"
+ -->
+ <!-- version-tag: 1 -->
+ <import file="${sdk.dir}/tools/ant/build.xml" />
+
+</project>
diff --git a/platform/android/java/default.properties b/platform/android/java/default.properties
new file mode 100644
index 000000000..e2e8061f2
--- /dev/null
+++ b/platform/android/java/default.properties
@@ -0,0 +1,11 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system use,
+# "build.properties", and override values to adapt the script to your
+# project structure.
+
+# Project target.
+target=android-8
diff --git a/platform/android/java/my-release-key.keystore b/platform/android/java/my-release-key.keystore
new file mode 100644
index 000000000..410cccd86
--- /dev/null
+++ b/platform/android/java/my-release-key.keystore
Binary files differ
diff --git a/platform/android/java/proguard-project.txt b/platform/android/java/proguard-project.txt
new file mode 100644
index 000000000..f2fe1559a
--- /dev/null
+++ b/platform/android/java/proguard-project.txt
@@ -0,0 +1,20 @@
+# To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/platform/android/java/proguard.cfg b/platform/android/java/proguard.cfg
new file mode 100644
index 000000000..12dd0392c
--- /dev/null
+++ b/platform/android/java/proguard.cfg
@@ -0,0 +1,36 @@
+-optimizationpasses 5
+-dontusemixedcaseclassnames
+-dontskipnonpubliclibraryclasses
+-dontpreverify
+-verbose
+-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
+
+-keep public class * extends android.app.Activity
+-keep public class * extends android.app.Application
+-keep public class * extends android.app.Service
+-keep public class * extends android.content.BroadcastReceiver
+-keep public class * extends android.content.ContentProvider
+-keep public class * extends android.app.backup.BackupAgentHelper
+-keep public class * extends android.preference.Preference
+-keep public class com.android.vending.licensing.ILicensingService
+
+-keepclasseswithmembernames class * {
+ native <methods>;
+}
+
+-keepclasseswithmembernames class * {
+ public <init>(android.content.Context, android.util.AttributeSet);
+}
+
+-keepclasseswithmembernames class * {
+ public <init>(android.content.Context, android.util.AttributeSet, int);
+}
+
+-keepclassmembers enum * {
+ public static **[] values();
+ public static ** valueOf(java.lang.String);
+}
+
+-keep class * implements android.os.Parcelable {
+ public static final android.os.Parcelable$Creator *;
+}
diff --git a/platform/android/java/res/drawable/icon.png b/platform/android/java/res/drawable/icon.png
new file mode 100644
index 000000000..050a1cf93
--- /dev/null
+++ b/platform/android/java/res/drawable/icon.png
Binary files differ
diff --git a/platform/android/java/res/values-ar/strings.xml b/platform/android/java/res/values-ar/strings.xml
new file mode 100644
index 000000000..9f3dc6d6a
--- /dev/null
+++ b/platform/android/java/res/values-ar/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_project_name_string">godot-project-name-ar</string>
+</resources> \ No newline at end of file
diff --git a/platform/android/java/res/values-bg/strings.xml b/platform/android/java/res/values-bg/strings.xml
new file mode 100644
index 000000000..bd8109277
--- /dev/null
+++ b/platform/android/java/res/values-bg/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_project_name_string">godot-project-name-bg</string>
+</resources> \ No newline at end of file
diff --git a/platform/android/java/res/values-ca/strings.xml b/platform/android/java/res/values-ca/strings.xml
new file mode 100644
index 000000000..494cb8846
--- /dev/null
+++ b/platform/android/java/res/values-ca/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_project_name_string">godot-project-name-ca</string>
+</resources> \ No newline at end of file
diff --git a/platform/android/java/res/values-cs/strings.xml b/platform/android/java/res/values-cs/strings.xml
new file mode 100644
index 000000000..30ce00f89
--- /dev/null
+++ b/platform/android/java/res/values-cs/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_project_name_string">godot-project-name-cs</string>
+</resources> \ No newline at end of file
diff --git a/platform/android/java/res/values-da/strings.xml b/platform/android/java/res/values-da/strings.xml
new file mode 100644
index 000000000..4c2a1cf0f
--- /dev/null
+++ b/platform/android/java/res/values-da/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_project_name_string">godot-project-name-da</string>
+</resources> \ No newline at end of file
diff --git a/platform/android/java/res/values-de/strings.xml b/platform/android/java/res/values-de/strings.xml
new file mode 100644
index 000000000..52946d4cc
--- /dev/null
+++ b/platform/android/java/res/values-de/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_project_name_string">godot-project-name-de</string>
+</resources> \ No newline at end of file
diff --git a/platform/android/java/res/values-el/strings.xml b/platform/android/java/res/values-el/strings.xml
new file mode 100644
index 000000000..181dc5176
--- /dev/null
+++ b/platform/android/java/res/values-el/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_project_name_string">godot-project-name-el</string>
+</resources> \ No newline at end of file
diff --git a/platform/android/java/res/values-en/strings.xml b/platform/android/java/res/values-en/strings.xml
new file mode 100644
index 000000000..976a56501
--- /dev/null
+++ b/platform/android/java/res/values-en/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_project_name_string">godot-project-name-en</string>
+</resources> \ No newline at end of file
diff --git a/platform/android/java/res/values-es-rES/strings.xml b/platform/android/java/res/values-es-rES/strings.xml
new file mode 100644
index 000000000..73f63a08f
--- /dev/null
+++ b/platform/android/java/res/values-es-rES/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_project_name_string">godot-project-name-es_ES</string>
+</resources> \ No newline at end of file
diff --git a/platform/android/java/res/values-es/strings.xml b/platform/android/java/res/values-es/strings.xml
new file mode 100644
index 000000000..07b718a64
--- /dev/null
+++ b/platform/android/java/res/values-es/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_project_name_string">godot-project-name-es</string>
+</resources> \ No newline at end of file
diff --git a/platform/android/java/res/values-fi/strings.xml b/platform/android/java/res/values-fi/strings.xml
new file mode 100644
index 000000000..323d82aff
--- /dev/null
+++ b/platform/android/java/res/values-fi/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_project_name_string">godot-project-name-fi</string>
+</resources> \ No newline at end of file
diff --git a/platform/android/java/res/values-fr/strings.xml b/platform/android/java/res/values-fr/strings.xml
new file mode 100644
index 000000000..32bead266
--- /dev/null
+++ b/platform/android/java/res/values-fr/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_project_name_string">godot-project-name-fr</string>
+</resources> \ No newline at end of file
diff --git a/platform/android/java/res/values-he/strings.xml b/platform/android/java/res/values-he/strings.xml
new file mode 100644
index 000000000..f52ede208
--- /dev/null
+++ b/platform/android/java/res/values-he/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_project_name_string">godot-project-name-he</string>
+</resources> \ No newline at end of file
diff --git a/platform/android/java/res/values-hi/strings.xml b/platform/android/java/res/values-hi/strings.xml
new file mode 100644
index 000000000..8aab2a8c6
--- /dev/null
+++ b/platform/android/java/res/values-hi/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_project_name_string">godot-project-name-hi</string>
+</resources> \ No newline at end of file
diff --git a/platform/android/java/res/values-hr/strings.xml b/platform/android/java/res/values-hr/strings.xml
new file mode 100644
index 000000000..caf55e224
--- /dev/null
+++ b/platform/android/java/res/values-hr/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_project_name_string">godot-project-name-hr</string>
+</resources> \ No newline at end of file
diff --git a/platform/android/java/res/values-hu/strings.xml b/platform/android/java/res/values-hu/strings.xml
new file mode 100644
index 000000000..e7f9e5122
--- /dev/null
+++ b/platform/android/java/res/values-hu/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_project_name_string">godot-project-name-hu</string>
+</resources> \ No newline at end of file
diff --git a/platform/android/java/res/values-id/strings.xml b/platform/android/java/res/values-id/strings.xml
new file mode 100644
index 000000000..9e9a8b0c0
--- /dev/null
+++ b/platform/android/java/res/values-id/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_project_name_string">godot-project-name-id</string>
+</resources> \ No newline at end of file
diff --git a/platform/android/java/res/values-it/strings.xml b/platform/android/java/res/values-it/strings.xml
new file mode 100644
index 000000000..1f5e5a049
--- /dev/null
+++ b/platform/android/java/res/values-it/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_project_name_string">godot-project-name-it</string>
+</resources> \ No newline at end of file
diff --git a/platform/android/java/res/values-ja/strings.xml b/platform/android/java/res/values-ja/strings.xml
new file mode 100644
index 000000000..7f85f57df
--- /dev/null
+++ b/platform/android/java/res/values-ja/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_project_name_string">godot-project-name-ja</string>
+</resources> \ No newline at end of file
diff --git a/platform/android/java/res/values-ko/strings.xml b/platform/android/java/res/values-ko/strings.xml
new file mode 100644
index 000000000..6d27498af
--- /dev/null
+++ b/platform/android/java/res/values-ko/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_project_name_string">godot-project-name-ko</string>
+</resources> \ No newline at end of file
diff --git a/platform/android/java/res/values-lt/strings.xml b/platform/android/java/res/values-lt/strings.xml
new file mode 100644
index 000000000..6e3677fde
--- /dev/null
+++ b/platform/android/java/res/values-lt/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_project_name_string">godot-project-name-lt</string>
+</resources> \ No newline at end of file
diff --git a/platform/android/java/res/values-lv/strings.xml b/platform/android/java/res/values-lv/strings.xml
new file mode 100644
index 000000000..701fc271a
--- /dev/null
+++ b/platform/android/java/res/values-lv/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_project_name_string">godot-project-name-lv</string>
+</resources> \ No newline at end of file
diff --git a/platform/android/java/res/values-nb/strings.xml b/platform/android/java/res/values-nb/strings.xml
new file mode 100644
index 000000000..73147ca1a
--- /dev/null
+++ b/platform/android/java/res/values-nb/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_project_name_string">godot-project-name-nb</string>
+</resources> \ No newline at end of file
diff --git a/platform/android/java/res/values-nl/strings.xml b/platform/android/java/res/values-nl/strings.xml
new file mode 100644
index 000000000..e501928a3
--- /dev/null
+++ b/platform/android/java/res/values-nl/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_project_name_string">godot-project-name-nl</string>
+</resources> \ No newline at end of file
diff --git a/platform/android/java/res/values-pl/strings.xml b/platform/android/java/res/values-pl/strings.xml
new file mode 100644
index 000000000..ea5da73b6
--- /dev/null
+++ b/platform/android/java/res/values-pl/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_project_name_string">godot-project-name-pl</string>
+</resources> \ No newline at end of file
diff --git a/platform/android/java/res/values-pt/strings.xml b/platform/android/java/res/values-pt/strings.xml
new file mode 100644
index 000000000..bdda7cd2c
--- /dev/null
+++ b/platform/android/java/res/values-pt/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_project_name_string">godot-project-name-pt</string>
+</resources> \ No newline at end of file
diff --git a/platform/android/java/res/values-ro/strings.xml b/platform/android/java/res/values-ro/strings.xml
new file mode 100644
index 000000000..3686da4c1
--- /dev/null
+++ b/platform/android/java/res/values-ro/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_project_name_string">godot-project-name-ro</string>
+</resources> \ No newline at end of file
diff --git a/platform/android/java/res/values-ru/strings.xml b/platform/android/java/res/values-ru/strings.xml
new file mode 100644
index 000000000..954067658
--- /dev/null
+++ b/platform/android/java/res/values-ru/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_project_name_string">godot-project-name-ru</string>
+</resources> \ No newline at end of file
diff --git a/platform/android/java/res/values-sk/strings.xml b/platform/android/java/res/values-sk/strings.xml
new file mode 100644
index 000000000..37d128312
--- /dev/null
+++ b/platform/android/java/res/values-sk/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_project_name_string">godot-project-name-sk</string>
+</resources> \ No newline at end of file
diff --git a/platform/android/java/res/values-sl/strings.xml b/platform/android/java/res/values-sl/strings.xml
new file mode 100644
index 000000000..0bb249c37
--- /dev/null
+++ b/platform/android/java/res/values-sl/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_project_name_string">godot-project-name-sl</string>
+</resources> \ No newline at end of file
diff --git a/platform/android/java/res/values-sr/strings.xml b/platform/android/java/res/values-sr/strings.xml
new file mode 100644
index 000000000..0e83cab1a
--- /dev/null
+++ b/platform/android/java/res/values-sr/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_project_name_string">godot-project-name-sr</string>
+</resources> \ No newline at end of file
diff --git a/platform/android/java/res/values-sv/strings.xml b/platform/android/java/res/values-sv/strings.xml
new file mode 100644
index 000000000..e3a04ac2e
--- /dev/null
+++ b/platform/android/java/res/values-sv/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_project_name_string">godot-project-name-sv</string>
+</resources> \ No newline at end of file
diff --git a/platform/android/java/res/values-th/strings.xml b/platform/android/java/res/values-th/strings.xml
new file mode 100644
index 000000000..0aa893b8b
--- /dev/null
+++ b/platform/android/java/res/values-th/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_project_name_string">godot-project-name-th</string>
+</resources> \ No newline at end of file
diff --git a/platform/android/java/res/values-tl/strings.xml b/platform/android/java/res/values-tl/strings.xml
new file mode 100644
index 000000000..e7e2af490
--- /dev/null
+++ b/platform/android/java/res/values-tl/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_project_name_string">godot-project-name-tl</string>
+</resources> \ No newline at end of file
diff --git a/platform/android/java/res/values-tr/strings.xml b/platform/android/java/res/values-tr/strings.xml
new file mode 100644
index 000000000..97af1243a
--- /dev/null
+++ b/platform/android/java/res/values-tr/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_project_name_string">godot-project-name-tr</string>
+</resources> \ No newline at end of file
diff --git a/platform/android/java/res/values-uk/strings.xml b/platform/android/java/res/values-uk/strings.xml
new file mode 100644
index 000000000..3dea6908a
--- /dev/null
+++ b/platform/android/java/res/values-uk/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_project_name_string">godot-project-name-uk</string>
+</resources> \ No newline at end of file
diff --git a/platform/android/java/res/values-vi/strings.xml b/platform/android/java/res/values-vi/strings.xml
new file mode 100644
index 000000000..a6552130b
--- /dev/null
+++ b/platform/android/java/res/values-vi/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_project_name_string">godot-project-name-vi</string>
+</resources> \ No newline at end of file
diff --git a/platform/android/java/res/values-zh/strings.xml b/platform/android/java/res/values-zh/strings.xml
new file mode 100644
index 000000000..397e66285
--- /dev/null
+++ b/platform/android/java/res/values-zh/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_project_name_string">godot-project-name-zh</string>
+</resources> \ No newline at end of file
diff --git a/platform/android/java/res/values/strings.xml b/platform/android/java/res/values/strings.xml
new file mode 100644
index 000000000..3a38d4059
--- /dev/null
+++ b/platform/android/java/res/values/strings.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_project_name_string">godot-project-name</string>
+ <string name="testuf8">元気です</string>
+ <string name="testuf2">元気です元気です元気です</string>
+
+</resources>
diff --git a/platform/android/java/src/com/android/godot/Dictionary.java b/platform/android/java/src/com/android/godot/Dictionary.java
new file mode 100644
index 000000000..4ed12f581
--- /dev/null
+++ b/platform/android/java/src/com/android/godot/Dictionary.java
@@ -0,0 +1,80 @@
+/*************************************************************************/
+/* Dictionary.java */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* 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 com.android.godot;
+
+import java.util.HashMap;
+import java.util.Set;
+
+
+public class Dictionary extends HashMap<String, Object> {
+
+ protected String[] keys_cache;
+
+ public String[] get_keys() {
+
+ String[] ret = new String[size()];
+ int i=0;
+ Set<String> keys = keySet();
+ for (String key : keys) {
+
+ ret[i] = key;
+ i++;
+ };
+
+ return ret;
+ };
+
+ public Object[] get_values() {
+
+ Object[] ret = new Object[size()];
+ int i=0;
+ Set<String> keys = keySet();
+ for (String key : keys) {
+
+ ret[i] = get(key);
+ i++;
+ };
+
+ return ret;
+ };
+
+ public void set_keys(String[] keys) {
+ keys_cache = keys;
+ };
+
+ public void set_values(Object[] vals) {
+
+ int i=0;
+ for (String key : keys_cache) {
+ put(key, vals[i]);
+ i++;
+ };
+ keys_cache = null;
+ };
+};
diff --git a/platform/android/java/src/com/android/godot/Godot.java b/platform/android/java/src/com/android/godot/Godot.java
new file mode 100644
index 000000000..cf1545df8
--- /dev/null
+++ b/platform/android/java/src/com/android/godot/Godot.java
@@ -0,0 +1,300 @@
+/*************************************************************************/
+/* Godot.java */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* 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 com.android.godot;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.MotionEvent;
+import android.widget.RelativeLayout;
+import android.widget.LinearLayout;
+import android.view.ViewGroup.LayoutParams;
+
+
+import android.app.*;
+import android.content.*;
+import android.view.*;
+import android.view.inputmethod.InputMethodManager;
+import android.os.*;
+import android.util.Log;
+import android.graphics.*;
+import android.text.method.*;
+import android.text.*;
+import android.media.*;
+import android.hardware.*;
+import android.content.*;
+
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.ArrayList;
+import android.provider.Settings.Secure;
+
+
+public class Godot extends Activity implements SensorEventListener
+{
+
+ static public class SingletonBase {
+
+ protected void registerClass(String p_name, String[] p_methods) {
+
+ GodotLib.singleton(p_name,this);
+
+ Class clazz = getClass();
+ Method[] methods = clazz.getDeclaredMethods();
+ for (Method method : methods) {
+ boolean found=false;
+ System.out.printf("METHOD: %s\n",method.getName());
+
+ for (String s : p_methods) {
+ System.out.printf("METHOD CMP WITH: %s\n",s);
+ if (s.equals(method.getName())) {
+ found=true;
+ System.out.printf("METHOD CMP VALID");
+ break;
+ }
+ }
+ if (!found)
+ continue;
+
+ System.out.printf("METHOD FOUND: %s\n",method.getName());
+
+ List<String> ptr = new ArrayList<String>();
+
+ Class[] paramTypes = method.getParameterTypes();
+ for (Class c : paramTypes) {
+ ptr.add(c.getName());
+ }
+
+ String[] pt = new String[ptr.size()];
+ ptr.toArray(pt);
+
+ GodotLib.method(p_name,method.getName(),method.getReturnType().getName(),pt);
+
+
+ }
+ }
+
+ public void registerMethods() {}
+ }
+
+/*
+ protected List<SingletonBase> singletons = new ArrayList<SingletonBase>();
+ protected void instanceSingleton(SingletonBase s) {
+
+ s.registerMethods();
+ singletons.add(s);
+ }
+
+*/
+
+ public GodotView mView;
+
+ private SensorManager mSensorManager;
+ private Sensor mAccelerometer;
+
+ public RelativeLayout layout;
+
+
+ static public GodotIO io;
+
+ public static void setWindowTitle(String title) {
+ //setTitle(title);
+ }
+
+ public interface ResultCallback {
+ public void callback(int requestCode, int resultCode, Intent data);
+ };
+ public ResultCallback result_callback;
+
+ @Override protected void onActivityResult (int requestCode, int resultCode, Intent data) {
+ if (result_callback != null) {
+ result_callback.callback(requestCode, resultCode, data);
+ result_callback = null;
+ };
+ };
+
+ public void onVideoInit(boolean use_gl2) {
+
+// mView = new GodotView(getApplication(),io,use_gl2);
+// setContentView(mView);
+
+ layout = new RelativeLayout(this);
+ layout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));
+ setContentView(layout);
+ mView = new GodotView(getApplication(),io,use_gl2, this);
+ layout.addView(mView,new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));
+ mView.setKeepScreenOn(true);
+
+ }
+
+ @Override protected void onCreate(Bundle icicle) {
+
+
+ super.onCreate(icicle);
+
+
+
+ Window window = getWindow();
+ window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
+ | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+
+ io = new GodotIO(this);
+ io.unique_id = Secure.getString(getContentResolver(), Secure.ANDROID_ID);
+ GodotLib.io=io;
+ GodotLib.initialize(this,io.needsReloadHooks());
+ mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
+ mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
+ mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
+
+ result_callback = null;
+
+ // instanceSingleton( new GodotFacebook(this) );
+
+
+ }
+
+ @Override protected void onPause() {
+ super.onPause();
+ mView.onPause();
+ mSensorManager.unregisterListener(this);
+ GodotLib.focusout();
+
+ }
+
+ @Override protected void onResume() {
+ super.onResume();
+ mView.onResume();
+ mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
+ GodotLib.focusin();
+ }
+
+ @Override public void onSensorChanged(SensorEvent event) {
+ float x = event.values[0];
+ float y = event.values[1];
+ float z = event.values[2];
+ GodotLib.accelerometer(x,y,z);
+ }
+
+ @Override public final void onAccuracyChanged(Sensor sensor, int accuracy) {
+ // Do something here if sensor accuracy changes.
+ }
+
+/*
+ @Override public boolean dispatchKeyEvent(KeyEvent event) {
+
+ if (event.getKeyCode()==KeyEvent.KEYCODE_BACK) {
+
+ System.out.printf("** BACK REQUEST!\n");
+
+ GodotLib.quit();
+ return true;
+ }
+ System.out.printf("** OTHER KEY!\n");
+
+ return false;
+ }
+*/
+
+ @Override public void onBackPressed() {
+
+ GodotLib.quit();
+ }
+
+ public void forceQuit() {
+
+ System.exit(0);
+ }
+
+
+ //@Override public boolean dispatchTouchEvent (MotionEvent event) {
+ public boolean gotTouchEvent(MotionEvent event) {
+
+ super.onTouchEvent(event);
+ int evcount=event.getPointerCount();
+ if (evcount==0)
+ return true;
+
+ int[] arr = new int[event.getPointerCount()*3];
+
+ for(int i=0;i<event.getPointerCount();i++) {
+
+ arr[i*3+0]=(int)event.getPointerId(i);
+ arr[i*3+1]=(int)event.getX(i);
+ arr[i*3+2]=(int)event.getY(i);
+ }
+
+ //System.out.printf("gaction: %d\n",event.getAction());
+ switch(event.getAction()&MotionEvent.ACTION_MASK) {
+
+ case MotionEvent.ACTION_DOWN: {
+ GodotLib.touch(0,0,evcount,arr);
+ //System.out.printf("action down at: %f,%f\n", event.getX(),event.getY());
+ } break;
+ case MotionEvent.ACTION_MOVE: {
+ GodotLib.touch(1,0,evcount,arr);
+ //for(int i=0;i<event.getPointerCount();i++) {
+ // System.out.printf("%d - moved to: %f,%f\n",i, event.getX(i),event.getY(i));
+ //}
+ } break;
+ case MotionEvent.ACTION_POINTER_UP: {
+ int pointer_idx = event.getActionIndex();
+ GodotLib.touch(4,pointer_idx,evcount,arr);
+ //System.out.printf("%d - s.up at: %f,%f\n",pointer_idx, event.getX(pointer_idx),event.getY(pointer_idx));
+ } break;
+ case MotionEvent.ACTION_POINTER_DOWN: {
+ int pointer_idx = event.getActionIndex();
+ GodotLib.touch(3,pointer_idx,evcount,arr);
+ //System.out.printf("%d - s.down at: %f,%f\n",pointer_idx, event.getX(pointer_idx),event.getY(pointer_idx));
+ } break;
+ case MotionEvent.ACTION_CANCEL:
+ case MotionEvent.ACTION_UP: {
+ GodotLib.touch(2,0,evcount,arr);
+ //for(int i=0;i<event.getPointerCount();i++) {
+ // System.out.printf("%d - up! %f,%f\n",i, event.getX(i),event.getY(i));
+ //}
+ } break;
+
+ }
+ return true;
+ }
+
+ @Override public boolean onKeyUp(int keyCode, KeyEvent event) {
+ GodotLib.key(event.getUnicodeChar(0), false);
+ return super.onKeyUp(keyCode, event);
+ };
+
+ @Override public boolean onKeyDown(int keyCode, KeyEvent event) {
+ GodotLib.key(event.getUnicodeChar(0), true);
+ return super.onKeyDown(keyCode, event);
+ };
+
+
+ // Audio
+
+
+}
diff --git a/platform/android/java/src/com/android/godot/GodotIO.java b/platform/android/java/src/com/android/godot/GodotIO.java
new file mode 100644
index 000000000..1f3967cb8
--- /dev/null
+++ b/platform/android/java/src/com/android/godot/GodotIO.java
@@ -0,0 +1,514 @@
+/*************************************************************************/
+/* GodotIO.java */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* 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 com.android.godot;
+import java.util.HashMap;
+import java.util.Locale;
+import android.net.Uri;
+import android.content.Intent;
+import android.content.res.AssetManager;
+import java.io.InputStream;
+import java.io.IOException;
+import android.app.*;
+import android.content.*;
+import android.view.*;
+import android.view.inputmethod.InputMethodManager;
+import android.os.*;
+import android.util.Log;
+import android.graphics.*;
+import android.text.method.*;
+import android.text.*;
+import android.media.*;
+import android.hardware.*;
+import android.content.*;
+import android.content.pm.ActivityInfo;
+//android.os.Build
+
+// Wrapper for native library
+
+public class GodotIO {
+
+
+ AssetManager am;
+ Activity activity;
+
+ final int SCREEN_LANDSCAPE=0;
+ final int SCREEN_PORTRAIT=1;
+ final int SCREEN_REVERSE_LANDSCAPE=2;
+ final int SCREEN_REVERSE_PORTRAIT=3;
+ final int SCREEN_SENSOR_LANDSCAPE=4;
+ final int SCREEN_SENSOR_PORTRAIT=5;
+ final int SCREEN_SENSOR=6;
+
+ /////////////////////////
+ /// FILES
+ /////////////////////////
+
+ public int last_file_id=1;
+
+ class AssetData {
+
+
+ public boolean eof=false;
+ public String path;
+ public InputStream is;
+ public int len;
+ public int pos;
+ }
+
+
+ HashMap<Integer,AssetData> streams;
+
+
+ public int file_open(String path,boolean write) {
+
+ //System.out.printf("file_open: Attempt to Open %s\n",path);
+
+ if (write)
+ return -1;
+
+
+ AssetData ad = new AssetData();
+
+ try {
+ ad.is = am.open(path);
+
+ } catch (Exception e) {
+
+ //System.out.printf("Exception on file_open: %s\n",e);
+ return -1;
+ }
+
+ try {
+ ad.len=ad.is.available();
+ } catch (Exception e) {
+
+ System.out.printf("Exception availabling on file_open: %s\n",e);
+ return -1;
+ }
+
+ ad.path=path;
+ ad.pos=0;
+ ++last_file_id;
+ streams.put(last_file_id,ad);
+
+ return last_file_id;
+ }
+ public int file_get_size(int id) {
+
+ if (!streams.containsKey(id)) {
+ System.out.printf("file_get_size: Invalid file id: %d\n",id);
+ return -1;
+ }
+
+ return streams.get(id).len;
+
+ }
+ public void file_seek(int id,int bytes) {
+
+ if (!streams.containsKey(id)) {
+ System.out.printf("file_get_size: Invalid file id: %d\n",id);
+ return;
+ }
+ //seek sucks
+ AssetData ad = streams.get(id);
+ if (bytes>ad.len)
+ bytes=ad.len;
+ if (bytes<0)
+ bytes=0;
+
+ try {
+
+ if (bytes > (int)ad.pos) {
+ int todo=bytes-(int)ad.pos;
+ while(todo>0) {
+ todo-=ad.is.skip(todo);
+ }
+ ad.pos=bytes;
+ } else if (bytes<(int)ad.pos) {
+
+ ad.is=am.open(ad.path);
+
+ ad.pos=bytes;
+ int todo=bytes;
+ while(todo>0) {
+ todo-=ad.is.skip(todo);
+ }
+ }
+
+ ad.eof=false;
+ } catch (IOException e) {
+
+ System.out.printf("Exception on file_seek: %s\n",e);
+ return;
+ }
+
+
+ }
+
+ public int file_tell(int id) {
+
+ if (!streams.containsKey(id)) {
+ System.out.printf("file_read: Can't tell eof for invalid file id: %d\n",id);
+ return 0;
+ }
+
+ AssetData ad = streams.get(id);
+ return ad.pos;
+ }
+ public boolean file_eof(int id) {
+
+ if (!streams.containsKey(id)) {
+ System.out.printf("file_read: Can't check eof for invalid file id: %d\n",id);
+ return false;
+ }
+
+ AssetData ad = streams.get(id);
+ return ad.eof;
+ }
+
+ public byte[] file_read(int id, int bytes) {
+
+ if (!streams.containsKey(id)) {
+ System.out.printf("file_read: Can't read invalid file id: %d\n",id);
+ return new byte[0];
+ }
+
+
+ AssetData ad = streams.get(id);
+
+ if (ad.pos + bytes > ad.len) {
+
+ bytes=ad.len-ad.pos;
+ ad.eof=true;
+ }
+
+
+ if (bytes==0) {
+
+ return new byte[0];
+ }
+
+
+
+ byte[] buf1=new byte[bytes];
+ int r=0;
+ try {
+ r = ad.is.read(buf1);
+ } catch (IOException e) {
+
+ System.out.printf("Exception on file_read: %s\n",e);
+ return new byte[bytes];
+ }
+
+ if (r==0) {
+ return new byte[0];
+ }
+
+ ad.pos+=r;
+
+ if (r<bytes) {
+
+ byte[] buf2=new byte[r];
+ for(int i=0;i<r;i++)
+ buf2[i]=buf1[i];
+ return buf2;
+ } else {
+
+ return buf1;
+ }
+
+ }
+
+ public void file_close(int id) {
+
+ if (!streams.containsKey(id)) {
+ System.out.printf("file_close: Can't close invalid file id: %d\n",id);
+ return;
+ }
+
+ streams.remove(id);
+
+ }
+
+
+ /////////////////////////
+ /// DIRECTORIES
+ /////////////////////////
+
+
+ class AssetDir {
+
+ public String[] files;
+ public int current;
+ }
+
+ public int last_dir_id=1;
+
+ HashMap<Integer,AssetDir> dirs;
+
+ public int dir_open(String path) {
+
+ AssetDir ad = new AssetDir();
+ ad.current=0;
+
+ try {
+ ad.files = am.list(path);
+ } catch (IOException e) {
+
+ System.out.printf("Exception on dir_open: %s\n",e);
+ return -1;
+ }
+
+ ++last_dir_id;
+ dirs.put(last_dir_id,ad);
+
+ return last_dir_id;
+
+ }
+
+ public String dir_next(int id) {
+
+ if (!dirs.containsKey(id)) {
+ System.out.printf("dir_next: invalid dir id: %d\n",id);
+ return "";
+ }
+
+ AssetDir ad = dirs.get(id);
+ if (ad.current>=ad.files.length)
+ return "";
+ String r = ad.files[ad.current];
+ ad.current++;
+ return r;
+
+ }
+
+ public void dir_close(int id) {
+
+ if (!dirs.containsKey(id)) {
+ System.out.printf("dir_close: invalid dir id: %d\n",id);
+ return;
+ }
+
+ dirs.remove(id);
+ }
+
+
+
+ GodotIO(Activity p_activity) {
+
+ am=p_activity.getAssets();
+ activity=p_activity;
+ streams=new HashMap<Integer,AssetData>();
+ dirs=new HashMap<Integer,AssetDir>();
+
+
+ }
+
+
+ /////////////////////////
+ // AUDIO
+ /////////////////////////
+
+ private Object buf;
+ private Thread mAudioThread;
+ private AudioTrack mAudioTrack;
+
+ public Object audioInit(int sampleRate, int desiredFrames) {
+ int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_STEREO;
+ int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
+ int frameSize = 4;
+
+ System.out.printf("audioInit: initializing audio:\n");
+
+ //Log.v("Godot", "Godot audio: wanted " + (isStereo ? "stereo" : "mono") + " " + (is16Bit ? "16-bit" : "8-bit") + " " + ((float)sampleRate / 1000f) + "kHz, " + desiredFrames + " frames buffer");
+
+ // Let the user pick a larger buffer if they really want -- but ye
+ // gods they probably shouldn't, the minimums are horrifyingly high
+ // latency already
+ desiredFrames = Math.max(desiredFrames, (AudioTrack.getMinBufferSize(sampleRate, channelConfig, audioFormat) + frameSize - 1) / frameSize);
+
+ mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
+ channelConfig, audioFormat, desiredFrames * frameSize, AudioTrack.MODE_STREAM);
+
+ audioStartThread();
+
+ //Log.v("Godot", "Godot audio: got " + ((mAudioTrack.getChannelCount() >= 2) ? "stereo" : "mono") + " " + ((mAudioTrack.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT) ? "16-bit" : "8-bit") + " " + ((float)mAudioTrack.getSampleRate() / 1000f) + "kHz, " + desiredFrames + " frames buffer");
+
+ buf = new short[desiredFrames * 2];
+ return buf;
+ }
+
+ public void audioStartThread() {
+ mAudioThread = new Thread(new Runnable() {
+ public void run() {
+ mAudioTrack.play();
+ GodotLib.audio();
+ }
+ });
+
+ // I'd take REALTIME if I could get it!
+ mAudioThread.setPriority(Thread.MAX_PRIORITY);
+ mAudioThread.start();
+ }
+
+ public void audioWriteShortBuffer(short[] buffer) {
+ for (int i = 0; i < buffer.length; ) {
+ int result = mAudioTrack.write(buffer, i, buffer.length - i);
+ if (result > 0) {
+ i += result;
+ } else if (result == 0) {
+ try {
+ Thread.sleep(1);
+ } catch(InterruptedException e) {
+ // Nom nom
+ }
+ } else {
+ Log.w("Godot", "Godot audio: error return from write(short)");
+ return;
+ }
+ }
+ }
+
+
+
+ public void audioQuit() {
+ if (mAudioThread != null) {
+ try {
+ mAudioThread.join();
+ } catch(Exception e) {
+ Log.v("Godot", "Problem stopping audio thread: " + e);
+ }
+ mAudioThread = null;
+
+ //Log.v("Godot", "Finished waiting for audio thread");
+ }
+
+ if (mAudioTrack != null) {
+ mAudioTrack.stop();
+ mAudioTrack = null;
+ }
+ }
+
+ public void audioPause(boolean p_pause) {
+
+ if (p_pause)
+ mAudioTrack.pause();
+ else
+ mAudioTrack.play();
+ }
+
+ /////////////////////////
+ // MISCELANEOUS OS IO
+ /////////////////////////
+
+
+
+ public int openURI(String p_uri) {
+
+ try {
+ Log.v("MyApp", "TRYING TO OPEN URI: " + p_uri);
+ Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(p_uri));
+ activity.startActivity(myIntent);
+ return 0;
+ } catch (ActivityNotFoundException e) {
+
+ return 1;
+ }
+ }
+
+ public String getDataDir() {
+
+ return activity.getFilesDir().getAbsolutePath();
+ }
+
+ public String getLocale() {
+
+ return Locale.getDefault().toString();
+ }
+
+ public String getModel() {
+ return Build.MODEL;
+ }
+
+ public boolean needsReloadHooks() {
+
+ return android.os.Build.VERSION.SDK_INT < 11;
+ }
+
+ public void showKeyboard(String p_existing_text) {
+
+ InputMethodManager inputMgr = (InputMethodManager)activity.getSystemService(Context.INPUT_METHOD_SERVICE);
+ inputMgr.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
+ };
+
+ public void hideKeyboard() {
+
+ InputMethodManager inputMgr = (InputMethodManager)activity.getSystemService(Context.INPUT_METHOD_SERVICE);
+ inputMgr.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
+ };
+
+ public void setScreenOrientation(int p_orientation) {
+
+ switch(p_orientation) {
+
+ case SCREEN_LANDSCAPE: {
+ activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
+ } break;
+ case SCREEN_PORTRAIT: {
+ activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+ } break;
+ case SCREEN_REVERSE_LANDSCAPE: {
+ activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
+ } break;
+ case SCREEN_REVERSE_PORTRAIT: {
+ activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
+ } break;
+ case SCREEN_SENSOR_LANDSCAPE: {
+ activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
+ } break;
+ case SCREEN_SENSOR_PORTRAIT: {
+ activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
+ } break;
+ case SCREEN_SENSOR: {
+ activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
+ } break;
+
+ }
+ };
+
+ protected static final String PREFS_FILE = "device_id.xml";
+ protected static final String PREFS_DEVICE_ID = "device_id";
+
+ public static String unique_id="";
+ public String getUniqueID() {
+
+ return unique_id;
+ }
+
+}
diff --git a/platform/android/java/src/com/android/godot/GodotLib.java b/platform/android/java/src/com/android/godot/GodotLib.java
new file mode 100644
index 000000000..8d002c5eb
--- /dev/null
+++ b/platform/android/java/src/com/android/godot/GodotLib.java
@@ -0,0 +1,63 @@
+/*************************************************************************/
+/* GodotLib.java */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* 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 com.android.godot;
+
+// Wrapper for native library
+
+public class GodotLib {
+
+
+ public static GodotIO io;
+
+ static {
+ System.loadLibrary("godot_android");
+ }
+
+ /**
+ * @param width the current view width
+ * @param height the current view height
+ */
+
+ public static native void initialize(Godot p_instance,boolean need_reload_hook);
+ public static native void resize(int width, int height,boolean reload);
+ public static native void newcontext();
+ public static native void quit();
+ public static native void step();
+ public static native void touch(int what,int pointer,int howmany, int[] arr);
+ public static native void accelerometer(float x, float y, float z);
+ public static native void key(int p_unicode_char, boolean p_pressed);
+ public static native void focusin();
+ public static native void focusout();
+ public static native void audio();
+ public static native void singleton(String p_name,Object p_object);
+ public static native void method(String p_sname,String p_name,String p_ret,String[] p_params);
+ public static native String getGlobal(String p_key);
+ public static native void callobject(int p_ID, String p_method, Object[] p_params);
+
+}
diff --git a/platform/android/java/src/com/android/godot/GodotView.java b/platform/android/java/src/com/android/godot/GodotView.java
new file mode 100644
index 000000000..093757bfb
--- /dev/null
+++ b/platform/android/java/src/com/android/godot/GodotView.java
@@ -0,0 +1,378 @@
+/*************************************************************************/
+/* GodotView.java */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* 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 com.android.godot;
+import android.content.Context;
+import android.graphics.PixelFormat;
+import android.opengl.GLSurfaceView;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.content.ContextWrapper;
+
+import java.io.File;
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.egl.EGLContext;
+import javax.microedition.khronos.egl.EGLDisplay;
+import javax.microedition.khronos.opengles.GL10;
+
+/**
+ * A simple GLSurfaceView sub-class that demonstrate how to perform
+ * OpenGL ES 2.0 rendering into a GL Surface. Note the following important
+ * details:
+ *
+ * - The class must use a custom context factory to enable 2.0 rendering.
+ * See ContextFactory class definition below.
+ *
+ * - The class must use a custom EGLConfigChooser to be able to select
+ * an EGLConfig that supports 2.0. This is done by providing a config
+ * specification to eglChooseConfig() that has the attribute
+ * EGL10.ELG_RENDERABLE_TYPE containing the EGL_OPENGL_ES2_BIT flag
+ * set. See ConfigChooser class definition below.
+ *
+ * - The class must select the surface's format, then choose an EGLConfig
+ * that matches it exactly (with regards to red/green/blue/alpha channels
+ * bit depths). Failure to do so would result in an EGL_BAD_MATCH error.
+ */
+class GodotView extends GLSurfaceView {
+ private static String TAG = "GodotView";
+ private static final boolean DEBUG = false;
+ private static Context ctx;
+
+ private static GodotIO io;
+ private static boolean firsttime=true;
+ private static boolean use_gl2=false;
+
+ private Godot activity;
+
+ public GodotView(Context context,GodotIO p_io,boolean p_use_gl2, Godot p_activity) {
+ super(context);
+ ctx=context;
+ io=p_io;
+ use_gl2=p_use_gl2;
+
+ activity = p_activity;
+
+ if (!p_io.needsReloadHooks()) {
+ //will only work on SDK 11+!!
+ setPreserveEGLContextOnPause(true);
+ }
+
+ init(false, 16, 0);
+ }
+
+ public GodotView(Context context, boolean translucent, int depth, int stencil) {
+ super(context);
+ init(translucent, depth, stencil);
+ }
+
+ @Override public boolean onTouchEvent (MotionEvent event) {
+
+ return activity.gotTouchEvent(event);
+ };
+
+ private void init(boolean translucent, int depth, int stencil) {
+
+ /* By default, GLSurfaceView() creates a RGB_565 opaque surface.
+ * If we want a translucent one, we should change the surface's
+ * format here, using PixelFormat.TRANSLUCENT for GL Surfaces
+ * is interpreted as any 32-bit surface with alpha by SurfaceFlinger.
+ */
+ if (translucent) {
+ this.getHolder().setFormat(PixelFormat.TRANSLUCENT);
+ }
+
+ /* Setup the context factory for 2.0 rendering.
+ * See ContextFactory class definition below
+ */
+ setEGLContextFactory(new ContextFactory());
+
+ /* We need to choose an EGLConfig that matches the format of
+ * our surface exactly. This is going to be done in our
+ * custom config chooser. See ConfigChooser class definition
+ * below.
+ */
+ setEGLConfigChooser( translucent ?
+ new ConfigChooser(8, 8, 8, 8, depth, stencil) :
+ new ConfigChooser(5, 6, 5, 0, depth, stencil) );
+
+ /* Set the renderer responsible for frame rendering */
+ setRenderer(new Renderer());
+ }
+
+ private static class ContextFactory implements GLSurfaceView.EGLContextFactory {
+ private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
+ public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {
+ if (use_gl2)
+ Log.w(TAG, "creating OpenGL ES 2.0 context :");
+ else
+ Log.w(TAG, "creating OpenGL ES 1.1 context :");
+
+ checkEglError("Before eglCreateContext", egl);
+ int[] attrib_list2 = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
+ EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, use_gl2?attrib_list2:null);
+ checkEglError("After eglCreateContext", egl);
+ return context;
+ }
+
+ public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) {
+ egl.eglDestroyContext(display, context);
+ }
+ }
+
+ private static void checkEglError(String prompt, EGL10 egl) {
+ int error;
+ while ((error = egl.eglGetError()) != EGL10.EGL_SUCCESS) {
+ Log.e(TAG, String.format("%s: EGL error: 0x%x", prompt, error));
+ }
+ }
+
+ private static class ConfigChooser implements GLSurfaceView.EGLConfigChooser {
+
+ public ConfigChooser(int r, int g, int b, int a, int depth, int stencil) {
+ mRedSize = r;
+ mGreenSize = g;
+ mBlueSize = b;
+ mAlphaSize = a;
+ mDepthSize = depth;
+ mStencilSize = stencil;
+ }
+
+ /* This EGL config specification is used to specify 2.0 rendering.
+ * We use a minimum size of 4 bits for red/green/blue, but will
+ * perform actual matching in chooseConfig() below.
+ */
+ private static int EGL_OPENGL_ES2_BIT = 4;
+ private static int[] s_configAttribs2 =
+ {
+ EGL10.EGL_RED_SIZE, 4,
+ EGL10.EGL_GREEN_SIZE, 4,
+ EGL10.EGL_BLUE_SIZE, 4,
+ // EGL10.EGL_DEPTH_SIZE, 16,
+ // EGL10.EGL_STENCIL_SIZE, EGL10.EGL_DONT_CARE,
+ EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+ EGL10.EGL_NONE
+ };
+ private static int[] s_configAttribs =
+ {
+ EGL10.EGL_RED_SIZE, 4,
+ EGL10.EGL_GREEN_SIZE, 4,
+ EGL10.EGL_BLUE_SIZE, 4,
+ // EGL10.EGL_DEPTH_SIZE, 16,
+ // EGL10.EGL_STENCIL_SIZE, EGL10.EGL_DONT_CARE,
+ EGL10.EGL_NONE
+ };
+
+ public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
+
+ /* Get the number of minimally matching EGL configurations
+ */
+ int[] num_config = new int[1];
+ egl.eglChooseConfig(display, use_gl2?s_configAttribs2:s_configAttribs, null, 0, num_config);
+
+ int numConfigs = num_config[0];
+
+ if (numConfigs <= 0) {
+ throw new IllegalArgumentException("No configs match configSpec");
+ }
+
+ /* Allocate then read the array of minimally matching EGL configs
+ */
+ EGLConfig[] configs = new EGLConfig[numConfigs];
+ egl.eglChooseConfig(display, use_gl2?s_configAttribs2:s_configAttribs, configs, numConfigs, num_config);
+
+ if (DEBUG) {
+ printConfigs(egl, display, configs);
+ }
+ /* Now return the "best" one
+ */
+ return chooseConfig(egl, display, configs);
+ }
+
+ public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display,
+ EGLConfig[] configs) {
+ for(EGLConfig config : configs) {
+ int d = findConfigAttrib(egl, display, config,
+ EGL10.EGL_DEPTH_SIZE, 0);
+ int s = findConfigAttrib(egl, display, config,
+ EGL10.EGL_STENCIL_SIZE, 0);
+
+ // We need at least mDepthSize and mStencilSize bits
+ if (d < mDepthSize || s < mStencilSize)
+ continue;
+
+ // We want an *exact* match for red/green/blue/alpha
+ int r = findConfigAttrib(egl, display, config,
+ EGL10.EGL_RED_SIZE, 0);
+ int g = findConfigAttrib(egl, display, config,
+ EGL10.EGL_GREEN_SIZE, 0);
+ int b = findConfigAttrib(egl, display, config,
+ EGL10.EGL_BLUE_SIZE, 0);
+ int a = findConfigAttrib(egl, display, config,
+ EGL10.EGL_ALPHA_SIZE, 0);
+
+ if (r == mRedSize && g == mGreenSize && b == mBlueSize && a == mAlphaSize)
+ return config;
+ }
+ return null;
+ }
+
+ private int findConfigAttrib(EGL10 egl, EGLDisplay display,
+ EGLConfig config, int attribute, int defaultValue) {
+
+ if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) {
+ return mValue[0];
+ }
+ return defaultValue;
+ }
+
+ private void printConfigs(EGL10 egl, EGLDisplay display,
+ EGLConfig[] configs) {
+ int numConfigs = configs.length;
+ Log.w(TAG, String.format("%d configurations", numConfigs));
+ for (int i = 0; i < numConfigs; i++) {
+ Log.w(TAG, String.format("Configuration %d:\n", i));
+ printConfig(egl, display, configs[i]);
+ }
+ }
+
+ private void printConfig(EGL10 egl, EGLDisplay display,
+ EGLConfig config) {
+ int[] attributes = {
+ EGL10.EGL_BUFFER_SIZE,
+ EGL10.EGL_ALPHA_SIZE,
+ EGL10.EGL_BLUE_SIZE,
+ EGL10.EGL_GREEN_SIZE,
+ EGL10.EGL_RED_SIZE,
+ EGL10.EGL_DEPTH_SIZE,
+ EGL10.EGL_STENCIL_SIZE,
+ EGL10.EGL_CONFIG_CAVEAT,
+ EGL10.EGL_CONFIG_ID,
+ EGL10.EGL_LEVEL,
+ EGL10.EGL_MAX_PBUFFER_HEIGHT,
+ EGL10.EGL_MAX_PBUFFER_PIXELS,
+ EGL10.EGL_MAX_PBUFFER_WIDTH,
+ EGL10.EGL_NATIVE_RENDERABLE,
+ EGL10.EGL_NATIVE_VISUAL_ID,
+ EGL10.EGL_NATIVE_VISUAL_TYPE,
+ 0x3030, // EGL10.EGL_PRESERVED_RESOURCES,
+ EGL10.EGL_SAMPLES,
+ EGL10.EGL_SAMPLE_BUFFERS,
+ EGL10.EGL_SURFACE_TYPE,
+ EGL10.EGL_TRANSPARENT_TYPE,
+ EGL10.EGL_TRANSPARENT_RED_VALUE,
+ EGL10.EGL_TRANSPARENT_GREEN_VALUE,
+ EGL10.EGL_TRANSPARENT_BLUE_VALUE,
+ 0x3039, // EGL10.EGL_BIND_TO_TEXTURE_RGB,
+ 0x303A, // EGL10.EGL_BIND_TO_TEXTURE_RGBA,
+ 0x303B, // EGL10.EGL_MIN_SWAP_INTERVAL,
+ 0x303C, // EGL10.EGL_MAX_SWAP_INTERVAL,
+ EGL10.EGL_LUMINANCE_SIZE,
+ EGL10.EGL_ALPHA_MASK_SIZE,
+ EGL10.EGL_COLOR_BUFFER_TYPE,
+ EGL10.EGL_RENDERABLE_TYPE,
+ 0x3042 // EGL10.EGL_CONFORMANT
+ };
+ String[] names = {
+ "EGL_BUFFER_SIZE",
+ "EGL_ALPHA_SIZE",
+ "EGL_BLUE_SIZE",
+ "EGL_GREEN_SIZE",
+ "EGL_RED_SIZE",
+ "EGL_DEPTH_SIZE",
+ "EGL_STENCIL_SIZE",
+ "EGL_CONFIG_CAVEAT",
+ "EGL_CONFIG_ID",
+ "EGL_LEVEL",
+ "EGL_MAX_PBUFFER_HEIGHT",
+ "EGL_MAX_PBUFFER_PIXELS",
+ "EGL_MAX_PBUFFER_WIDTH",
+ "EGL_NATIVE_RENDERABLE",
+ "EGL_NATIVE_VISUAL_ID",
+ "EGL_NATIVE_VISUAL_TYPE",
+ "EGL_PRESERVED_RESOURCES",
+ "EGL_SAMPLES",
+ "EGL_SAMPLE_BUFFERS",
+ "EGL_SURFACE_TYPE",
+ "EGL_TRANSPARENT_TYPE",
+ "EGL_TRANSPARENT_RED_VALUE",
+ "EGL_TRANSPARENT_GREEN_VALUE",
+ "EGL_TRANSPARENT_BLUE_VALUE",
+ "EGL_BIND_TO_TEXTURE_RGB",
+ "EGL_BIND_TO_TEXTURE_RGBA",
+ "EGL_MIN_SWAP_INTERVAL",
+ "EGL_MAX_SWAP_INTERVAL",
+ "EGL_LUMINANCE_SIZE",
+ "EGL_ALPHA_MASK_SIZE",
+ "EGL_COLOR_BUFFER_TYPE",
+ "EGL_RENDERABLE_TYPE",
+ "EGL_CONFORMANT"
+ };
+ int[] value = new int[1];
+ for (int i = 0; i < attributes.length; i++) {
+ int attribute = attributes[i];
+ String name = names[i];
+ if ( egl.eglGetConfigAttrib(display, config, attribute, value)) {
+ Log.w(TAG, String.format(" %s: %d\n", name, value[0]));
+ } else {
+ // Log.w(TAG, String.format(" %s: failed\n", name));
+ while (egl.eglGetError() != EGL10.EGL_SUCCESS);
+ }
+ }
+ }
+
+ // Subclasses can adjust these values:
+ protected int mRedSize;
+ protected int mGreenSize;
+ protected int mBlueSize;
+ protected int mAlphaSize;
+ protected int mDepthSize;
+ protected int mStencilSize;
+ private int[] mValue = new int[1];
+ }
+
+ private static class Renderer implements GLSurfaceView.Renderer {
+
+
+ public void onDrawFrame(GL10 gl) {
+ GodotLib.step();
+ }
+
+ public void onSurfaceChanged(GL10 gl, int width, int height) {
+
+ GodotLib.resize(width, height,!firsttime);
+ firsttime=false;
+ }
+
+ public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+ GodotLib.newcontext();
+ }
+ }
+}
diff --git a/platform/android/java_glue.cpp b/platform/android/java_glue.cpp
new file mode 100644
index 000000000..9c5003cb1
--- /dev/null
+++ b/platform/android/java_glue.cpp
@@ -0,0 +1,1153 @@
+/*************************************************************************/
+/* java_glue.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* 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. */
+/*************************************************************************/
+#ifndef ANDROID_NATIVE_ACTIVITY
+
+#include "java_glue.h"
+#include "os_android.h"
+#include "main/main.h"
+#include <unistd.h>
+#include "file_access_jandroid.h"
+#include "dir_access_jandroid.h"
+#include "audio_driver_jandroid.h"
+#include "globals.h"
+#include "thread_jandroid.h"
+#include "core/os/keyboard.h"
+static OS_Android *os_android=NULL;
+
+
+jvalue _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_arg, bool force_jobject = false) {
+
+ jvalue v;
+
+ switch(p_type) {
+
+ case Variant::BOOL: {
+
+ if (force_jobject) {
+ jclass bclass = env->FindClass("java/lang/Boolean");
+ jmethodID ctor = env->GetMethodID(bclass, "<init>", "(Z)V");
+ jvalue val;
+ val.z = (bool)(*p_arg);
+ jobject obj = env->NewObjectA(bclass, ctor, &val);
+ v.l = obj;
+ } else {
+ v.z=*p_arg;
+ };
+ } break;
+ case Variant::INT: {
+
+ if (force_jobject) {
+
+ jclass bclass = env->FindClass("java/lang/Integer");
+ jmethodID ctor = env->GetMethodID(bclass, "<init>", "(I)V");
+ jvalue val;
+ val.i = (int)(*p_arg);
+ jobject obj = env->NewObjectA(bclass, ctor, &val);
+ v.l = obj;
+
+ } else {
+ v.i=*p_arg;
+ };
+ } break;
+ case Variant::REAL: {
+
+ if (force_jobject) {
+
+ jclass bclass = env->FindClass("java/lang/Double");
+ jmethodID ctor = env->GetMethodID(bclass, "<init>", "(D)V");
+ jvalue val;
+ val.d = (double)(*p_arg);
+ jobject obj = env->NewObjectA(bclass, ctor, &val);
+ v.l = obj;
+
+ } else {
+ v.f=*p_arg;
+ };
+ } break;
+ case Variant::STRING: {
+
+ String s = *p_arg;
+ jstring jStr = env->NewStringUTF(s.utf8().get_data());
+ v.l=jStr;
+ } break;
+ case Variant::STRING_ARRAY: {
+
+ DVector<String> sarray = *p_arg;
+ jobjectArray arr = env->NewObjectArray(sarray.size(),env->FindClass("java/lang/String"),env->NewStringUTF(""));
+
+ for(int j=0;j<sarray.size();j++) {
+
+ env->SetObjectArrayElement(arr,j,env->NewStringUTF( sarray[j].utf8().get_data() ));
+ }
+ v.l=arr;
+
+ } break;
+
+ case Variant::DICTIONARY: {
+
+ Dictionary dict = *p_arg;
+ jclass dclass = env->FindClass("com/android/godot/Dictionary");
+ jmethodID ctor = env->GetMethodID(dclass, "<init>", "()V");
+ jobject jdict = env->NewObject(dclass, ctor);
+
+ Array keys = dict.keys();
+
+ jobjectArray jkeys = env->NewObjectArray(keys.size(), env->FindClass("java/lang/String"), env->NewStringUTF(""));
+ for (int j=0; j<keys.size(); j++) {
+ env->SetObjectArrayElement(jkeys, j, env->NewStringUTF(String(keys[j]).utf8().get_data()));
+ };
+
+ jmethodID set_keys = env->GetMethodID(dclass, "set_keys", "([Ljava/lang/String;)V");
+ jvalue val;
+ val.l = jkeys;
+ env->CallVoidMethodA(jdict, set_keys, &val);
+
+ jobjectArray jvalues = env->NewObjectArray(keys.size(), env->FindClass("java/lang/Object"), NULL);
+
+ for (int j=0; j<keys.size(); j++) {
+ Variant var = dict[keys[j]];
+ val = _variant_to_jvalue(env, var.get_type(), &var, true);
+ env->SetObjectArrayElement(jvalues, j, val.l);
+ };
+
+ jmethodID set_values = env->GetMethodID(dclass, "set_values", "([Ljava/lang/Object;)V");
+ val.l = jvalues;
+ env->CallVoidMethodA(jdict, set_values, &val);
+
+ v.l = jdict;
+ } break;
+
+ case Variant::INT_ARRAY: {
+
+ DVector<int> array = *p_arg;
+ jintArray arr = env->NewIntArray(array.size());
+ DVector<int>::Read r = array.read();
+ env->SetIntArrayRegion(arr,0,array.size(),r.ptr());
+ v.l=arr;
+
+ } break;
+ case Variant::REAL_ARRAY: {
+
+ DVector<float> array = *p_arg;
+ jfloatArray arr = env->NewFloatArray(array.size());
+ DVector<float>::Read r = array.read();
+ env->SetFloatArrayRegion(arr,0,array.size(),r.ptr());
+ v.l=arr;
+
+ } break;
+ default: {
+
+ v.i = 0;
+ } break;
+
+ }
+ return v;
+};
+
+String _get_class_name(JNIEnv * env, jclass cls, bool* array) {
+
+ jclass cclass = env->FindClass("java/lang/Class");
+ jmethodID getName = env->GetMethodID(cclass, "getName", "()Ljava/lang/String;");
+ jstring clsName=(jstring) env->CallObjectMethod(cls, getName);
+
+ if (array) {
+ jmethodID isArray = env->GetMethodID(cclass, "isArray", "()Z");
+ jboolean isarr = env->CallBooleanMethod(cls, isArray);
+ (*array) = isarr ? true : false;
+ }
+
+ return env->GetStringUTFChars( clsName, NULL );
+};
+
+
+Variant _jobject_to_variant(JNIEnv * env, jobject obj) {
+
+ jclass c = env->GetObjectClass(obj);
+ bool array;
+ String name = _get_class_name(env, c, &array);
+ //print_line("name is " + name + ", array "+Variant(array));
+
+ if (name == "java.lang.String") {
+
+ return String::utf8(env->GetStringUTFChars( (jstring)obj, NULL ));
+ };
+
+
+ if (name == "[Ljava.lang.String;") {
+
+ jobjectArray arr = (jobjectArray)obj;
+ int stringCount = env->GetArrayLength(arr);
+ //print_line("String array! " + String::num(stringCount));
+ DVector<String> sarr;
+
+ for (int i=0; i<stringCount; i++) {
+ jstring string = (jstring) env->GetObjectArrayElement(arr, i);
+ const char *rawString = env->GetStringUTFChars(string, 0);
+ sarr.push_back(String(rawString));
+ }
+
+ return sarr;
+ };
+
+ if (name == "java.lang.Boolean") {
+
+ jmethodID boolValue = env->GetMethodID(c, "booleanValue", "()Z");
+ bool ret = env->CallBooleanMethod(obj, boolValue);
+ return ret;
+ };
+
+ if (name == "java.lang.Integer") {
+
+ jclass nclass = env->FindClass("java/lang/Number");
+ jmethodID intValue = env->GetMethodID(nclass, "intValue", "()I");
+ int ret = env->CallIntMethod(obj, intValue);
+ return ret;
+ };
+
+ if (name == "[I") {
+
+ jintArray arr = (jintArray)obj;
+ int fCount = env->GetArrayLength(arr);
+ DVector<int> sarr;
+ sarr.resize(fCount);
+
+ DVector<int>::Write w = sarr.write();
+ env->GetIntArrayRegion(arr,0,fCount,w.ptr());
+ w = DVector<int>::Write();
+ return sarr;
+ };
+
+ if (name == "java.lang.Float" || name == "java.lang.Double") {
+
+ jclass nclass = env->FindClass("java/lang/Number");
+ jmethodID doubleValue = env->GetMethodID(nclass, "doubleValue", "()D");
+ double ret = env->CallDoubleMethod(obj, doubleValue);
+ return ret;
+ };
+
+ if (name == "[D") {
+
+ jdoubleArray arr = (jdoubleArray)obj;
+ int fCount = env->GetArrayLength(arr);
+ RealArray sarr;
+ sarr.resize(fCount);
+
+ RealArray::Write w = sarr.write();
+
+ for (int i=0; i<fCount; i++) {
+
+ double n;
+ env->GetDoubleArrayRegion(arr, i, 1, &n);
+ w.ptr()[i] = n;
+
+ };
+ return sarr;
+ };
+
+ if (name == "[F") {
+
+ jfloatArray arr = (jfloatArray)obj;
+ int fCount = env->GetArrayLength(arr);
+ RealArray sarr;
+ sarr.resize(fCount);
+
+
+ RealArray::Write w = sarr.write();
+
+ for (int i=0; i<fCount; i++) {
+
+ float n;
+ env->GetFloatArrayRegion(arr, i, 1, &n);
+ w.ptr()[i] = n;
+
+ };
+ return sarr;
+ };
+
+
+ if (name == "[Ljava.lang.Object;") {
+
+ jobjectArray arr = (jobjectArray)obj;
+ int objCount = env->GetArrayLength(arr);
+ Array varr;
+
+ for (int i=0; i<objCount; i++) {
+ jobject jobj = env->GetObjectArrayElement(arr, i);
+ Variant v = _jobject_to_variant(env, jobj);
+ varr.push_back(v);
+ }
+
+ return varr;
+ };
+
+ if (name == "com.android.godot.Dictionary") {
+
+ Dictionary ret;
+ jclass oclass = c;
+ jmethodID get_keys = env->GetMethodID(oclass, "get_keys", "()[Ljava/lang/String;");
+ jobjectArray arr = (jobjectArray)env->CallObjectMethod(obj, get_keys);
+
+ StringArray keys = _jobject_to_variant(env, arr);
+
+ jmethodID get_values = env->GetMethodID(oclass, "get_values", "()[Ljava/lang/Object;");
+ arr = (jobjectArray)env->CallObjectMethod(obj, get_values);
+
+ Array vals = _jobject_to_variant(env, arr);
+
+ //print_line("adding " + String::num(keys.size()) + " to Dictionary!");
+ for (int i=0; i<keys.size(); i++) {
+
+ ret[keys[i]] = vals[i];
+ };
+
+ return ret;
+ };
+
+ return Variant();
+};
+
+class JNISingleton : public Object {
+
+ OBJ_TYPE( JNISingleton, Object );
+
+
+ struct MethodData {
+
+
+ jmethodID method;
+ Variant::Type ret_type;
+ Vector<Variant::Type> argtypes;
+ };
+
+ jobject instance;
+ Map<StringName,MethodData> method_map;
+
+public:
+
+ virtual Variant call(const StringName& p_method,const Variant** p_args,int p_argcount,Variant::CallError &r_error) {
+
+ //print_line("attempt to call "+String(p_method));
+
+ r_error.error=Variant::CallError::CALL_OK;
+
+ Map<StringName,MethodData >::Element *E=method_map.find(p_method);
+ if (!E) {
+
+ print_line("no exists");
+ r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ return Variant();
+ }
+
+
+ int ac = E->get().argtypes.size();
+ if (ac<p_argcount) {
+
+ print_line("fewargs");
+ r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+ r_error.argument=ac;
+ return Variant();
+ }
+
+ if (ac>p_argcount) {
+
+ print_line("manyargs");
+ r_error.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
+ r_error.argument=ac;
+ return Variant();
+ }
+
+
+
+ for(int i=0;i<p_argcount;i++) {
+
+ if (!Variant::can_convert(p_args[i]->get_type(),E->get().argtypes[i])) {
+
+ r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.argument=i;
+ r_error.expected=E->get().argtypes[i];
+ }
+ }
+
+
+ jvalue *v=NULL;
+
+ if (p_argcount) {
+
+ v=(jvalue*)alloca( sizeof(jvalue)*p_argcount );
+ }
+
+ JNIEnv *env = ThreadAndroid::get_env();
+
+ //print_line("argcount "+String::num(p_argcount));
+ for(int i=0;i<p_argcount;i++) {
+
+ v[i] = _variant_to_jvalue(env, E->get().argtypes[i], p_args[i]);
+ }
+
+ //print_line("calling method!!");
+
+ Variant ret;
+
+ switch(E->get().ret_type) {
+
+ case Variant::NIL: {
+
+
+ //print_line("call void");
+ env->CallVoidMethodA(instance,E->get().method,v);
+ } break;
+ case Variant::BOOL: {
+
+ ret = env->CallBooleanMethodA(instance,E->get().method,v);
+ //print_line("call bool");
+ } break;
+ case Variant::INT: {
+
+ ret = env->CallIntMethodA(instance,E->get().method,v);
+ //print_line("call int");
+ } break;
+ case Variant::REAL: {
+
+ ret = env->CallFloatMethodA(instance,E->get().method,v);
+ } break;
+ case Variant::STRING: {
+
+ jobject o = env->CallObjectMethodA(instance,E->get().method,v);
+ String singname = env->GetStringUTFChars((jstring)o, NULL );
+ } break;
+ case Variant::STRING_ARRAY: {
+
+ jobjectArray arr = (jobjectArray)env->CallObjectMethodA(instance,E->get().method,v);
+
+ ret = _jobject_to_variant(env, arr);
+
+ } break;
+ case Variant::INT_ARRAY: {
+
+ jintArray arr = (jintArray)env->CallObjectMethodA(instance,E->get().method,v);
+
+ int fCount = env->GetArrayLength(arr);
+ DVector<int> sarr;
+ sarr.resize(fCount);
+
+ DVector<int>::Write w = sarr.write();
+ env->GetIntArrayRegion(arr,0,fCount,w.ptr());
+ w = DVector<int>::Write();
+ ret=sarr;
+ } break;
+ case Variant::REAL_ARRAY: {
+
+ jfloatArray arr = (jfloatArray)env->CallObjectMethodA(instance,E->get().method,v);
+
+ int fCount = env->GetArrayLength(arr);
+ DVector<float> sarr;
+ sarr.resize(fCount);
+
+ DVector<float>::Write w = sarr.write();
+ env->GetFloatArrayRegion(arr,0,fCount,w.ptr());
+ w = DVector<float>::Write();
+ ret=sarr;
+ } break;
+
+ case Variant::DICTIONARY: {
+
+ //print_line("call dictionary");
+ jobject obj = env->CallObjectMethodA(instance, E->get().method, v);
+ ret = _jobject_to_variant(env, obj);
+
+ } break;
+ default: {
+
+
+ print_line("failure..");
+ ERR_FAIL_V(Variant());
+ } break;
+ }
+
+ //print_line("success");
+
+ return ret;
+ }
+
+
+ jobject get_instance() const {
+
+ return instance;
+ }
+ void set_instance(jobject p_instance) {
+
+ instance=p_instance;
+ }
+
+
+ void add_method(const StringName& p_name, jmethodID p_method,const Vector<Variant::Type>& p_args, Variant::Type p_ret_type) {
+
+ MethodData md;
+ md.method=p_method;
+ md.argtypes=p_args;
+ md.ret_type=p_ret_type;
+ method_map[p_name]=md;
+
+ }
+
+
+ JNISingleton() {}
+
+};
+
+
+struct TST {
+
+ int a;
+ TST() {
+
+ a=5;
+ }
+};
+
+TST tst;
+
+struct JAndroidPointerEvent {
+
+ Vector<OS_Android::TouchPos> points;
+ int pointer;
+ int what;
+};
+
+static List<JAndroidPointerEvent> pointer_events;
+static List<InputEvent> key_events;
+static bool initialized=false;
+static Mutex *input_mutex=NULL;
+static Mutex *suspend_mutex=NULL;
+static int step=0;
+static bool resized=false;
+static bool resized_reload=false;
+static bool quit_request=false;
+static Size2 new_size;
+static Vector3 accelerometer;
+static HashMap<String,JNISingleton*> jni_singletons;
+static jobject godot_io;
+
+typedef void (*GFXInitFunc)(void *ud,bool gl2);
+
+static jmethodID _on_video_init=0;
+static jobject _godot_instance;
+
+static jmethodID _openURI=0;
+static jmethodID _getDataDir=0;
+static jmethodID _getLocale=0;
+static jmethodID _getModel=0;
+static jmethodID _showKeyboard=0;
+static jmethodID _hideKeyboard=0;
+static jmethodID _setScreenOrientation=0;
+static jmethodID _getUniqueID=0;
+
+
+static void _gfx_init_func(void* ud, bool gl2) {
+
+}
+
+
+static int _open_uri(const String& p_uri) {
+
+ JNIEnv *env = ThreadAndroid::get_env();
+ jstring jStr = env->NewStringUTF(p_uri.utf8().get_data());
+ return env->CallIntMethod(godot_io,_openURI,jStr) ;
+}
+
+static String _get_data_dir() {
+
+ JNIEnv *env = ThreadAndroid::get_env();
+ jstring s =(jstring)env->CallObjectMethod(godot_io,_getDataDir);
+ return String(env->GetStringUTFChars( s, NULL ));
+}
+
+static String _get_locale() {
+
+ JNIEnv *env = ThreadAndroid::get_env();
+ jstring s =(jstring)env->CallObjectMethod(godot_io,_getLocale);
+ return String(env->GetStringUTFChars( s, NULL ));
+}
+
+static String _get_model() {
+
+ JNIEnv *env = ThreadAndroid::get_env();
+ jstring s =(jstring)env->CallObjectMethod(godot_io,_getModel);
+ return String(env->GetStringUTFChars( s, NULL ));
+}
+
+static String _get_unique_id() {
+
+ JNIEnv *env = ThreadAndroid::get_env();
+ jstring s =(jstring)env->CallObjectMethod(godot_io,_getUniqueID);
+ return String(env->GetStringUTFChars( s, NULL ));
+}
+
+static void _show_vk(const String& p_existing) {
+
+ JNIEnv* env = ThreadAndroid::get_env();
+ jstring jStr = env->NewStringUTF(p_existing.utf8().get_data());
+ env->CallVoidMethod(godot_io, _showKeyboard, jStr);
+};
+
+static void _set_screen_orient(int p_orient) {
+
+ JNIEnv* env = ThreadAndroid::get_env();
+ env->CallVoidMethod(godot_io, _setScreenOrientation, p_orient );
+};
+
+static void _hide_vk() {
+
+ JNIEnv* env = ThreadAndroid::get_env();
+ env->CallVoidMethod(godot_io, _hideKeyboard);
+};
+
+JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_initialize(JNIEnv * env, jobject obj, jobject activity,jboolean p_need_reload_hook) {
+
+ __android_log_print(ANDROID_LOG_INFO,"godot","**INIT EVENT! - %p\n",env);
+
+
+ initialized=true;
+ _godot_instance=activity;
+
+ JavaVM *jvm;
+ env->GetJavaVM(&jvm);
+
+
+ __android_log_print(ANDROID_LOG_INFO,"godot","***************** HELLO FROM JNI!!!!!!!!");
+
+ {
+ //setup IO Object
+
+ jclass cls = env->FindClass("com/android/godot/Godot");
+ if (cls) {
+
+ cls=(jclass)env->NewGlobalRef(cls);
+ __android_log_print(ANDROID_LOG_INFO,"godot","*******CLASS FOUND!!!");
+ }
+
+ __android_log_print(ANDROID_LOG_INFO,"godot","STEP2, %p",cls);
+ jfieldID fid = env->GetStaticFieldID(cls, "io", "Lcom/android/godot/GodotIO;");
+ __android_log_print(ANDROID_LOG_INFO,"godot","STEP3 %i",fid);
+ jobject ob = env->GetStaticObjectField(cls,fid);
+ __android_log_print(ANDROID_LOG_INFO,"godot","STEP4, %p",ob);
+ jobject gob = env->NewGlobalRef(ob);
+
+ __android_log_print(ANDROID_LOG_INFO,"godot","STEP4.5, %p",gob);
+ godot_io=gob;
+
+ _on_video_init = env->GetMethodID(cls, "onVideoInit", "(Z)V");
+
+ jclass clsio = env->FindClass("com/android/godot/Godot");
+ if (cls) {
+ jclass c = env->GetObjectClass(gob);
+ _openURI = env->GetMethodID(c,"openURI","(Ljava/lang/String;)I");
+ _getDataDir = env->GetMethodID(c,"getDataDir","()Ljava/lang/String;");
+ _getLocale = env->GetMethodID(c,"getLocale","()Ljava/lang/String;");
+ _getModel = env->GetMethodID(c,"getModel","()Ljava/lang/String;");
+ _getUniqueID = env->GetMethodID(c,"getUniqueID","()Ljava/lang/String;");
+ _showKeyboard = env->GetMethodID(c,"showKeyboard","(Ljava/lang/String;)V");
+ _hideKeyboard = env->GetMethodID(c,"hideKeyboard","()V");
+ _setScreenOrientation = env->GetMethodID(c,"setScreenOrientation","(I)V");
+ }
+
+ ThreadAndroid::make_default(jvm);
+ FileAccessJAndroid::setup(gob);
+ DirAccessJAndroid::setup(gob);
+ AudioDriverAndroid::setup(gob);
+ }
+
+
+
+ os_android = new OS_Android(_gfx_init_func,env,_open_uri,_get_data_dir,_get_locale, _get_model,_show_vk, _hide_vk,_set_screen_orient,_get_unique_id);
+ os_android->set_need_reload_hooks(p_need_reload_hook);
+
+ char wd[500];
+ getcwd(wd,500);
+
+ __android_log_print(ANDROID_LOG_INFO,"godot","test construction %i\n",tst.a);
+ __android_log_print(ANDROID_LOG_INFO,"godot","running from dir %s\n",wd);
+
+ __android_log_print(ANDROID_LOG_INFO,"godot","**SETUP");
+
+
+#if 0
+ char *args[]={"-test","render",NULL};
+ __android_log_print(ANDROID_LOG_INFO,"godot","pre asdasd setup...");
+ Error err = Main::setup("apk",2,args,false);
+#else
+ Error err = Main::setup("apk",0,NULL,false);
+#endif
+
+ if (err!=OK) {
+ __android_log_print(ANDROID_LOG_INFO,"godot","*****UNABLE TO SETUP");
+
+ return; //should exit instead and print the error
+ }
+
+ __android_log_print(ANDROID_LOG_INFO,"godot","*****SETUP OK");
+
+ //video driver is determined here, because once initialized, it cant be changed
+ String vd = Globals::get_singleton()->get("display/driver");
+
+
+ if (vd.to_upper()=="GLES1")
+ env->CallVoidMethod(_godot_instance, _on_video_init, (jboolean)false);
+ else
+ env->CallVoidMethod(_godot_instance, _on_video_init, (jboolean)true);
+
+ __android_log_print(ANDROID_LOG_INFO,"godot","**START");
+
+ input_mutex=Mutex::create();
+ suspend_mutex=Mutex::create();
+
+
+}
+
+JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_resize(JNIEnv * env, jobject obj, jint width, jint height, jboolean reload) {
+
+ __android_log_print(ANDROID_LOG_INFO,"godot","^_^_^_^_^ resize %lld, %i, %i\n",Thread::get_caller_ID(),width,height);
+ if (os_android)
+ os_android->set_display_size(Size2(width,height));
+
+ /*input_mutex->lock();
+ resized=true;
+ if (reload)
+ resized_reload=true;
+ new_size=Size2(width,height);
+ input_mutex->unlock();*/
+
+}
+
+JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_newcontext(JNIEnv * env, jobject obj) {
+
+ __android_log_print(ANDROID_LOG_INFO,"godot","^_^_^_^_^ newcontext %lld\n",Thread::get_caller_ID());
+ if (os_android && step > 0) {
+
+ os_android->reload_gfx();
+ }
+
+}
+
+
+JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_quit(JNIEnv * env, jobject obj) {
+
+ input_mutex->lock();
+ quit_request=true;
+ input_mutex->unlock();
+
+}
+
+static void _initialize_java_modules() {
+
+
+ String modules = Globals::get_singleton()->get("android/modules");
+ Vector<String> mods = modules.split(",",false);
+ __android_log_print(ANDROID_LOG_INFO,"godot","mod count: %i",mods.size());
+
+ if (mods.size()) {
+
+ JNIEnv *env = ThreadAndroid::get_env();
+
+ jclass activityClass = env->FindClass("com/android/godot/Godot");
+
+ jmethodID getClassLoader = env->GetMethodID(activityClass,"getClassLoader", "()Ljava/lang/ClassLoader;");
+
+ jobject cls = env->CallObjectMethod(_godot_instance, getClassLoader);
+
+ jclass classLoader = env->FindClass("java/lang/ClassLoader");
+
+ jmethodID findClass = env->GetMethodID(classLoader, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
+
+ for (int i=0;i<mods.size();i++) {
+
+ String m = mods[i];
+ //jclass singletonClass = env->FindClass(m.utf8().get_data());
+
+ print_line("LOADING MODULE: "+m);
+ jstring strClassName = env->NewStringUTF(m.utf8().get_data());
+ jclass singletonClass = (jclass)env->CallObjectMethod(cls, findClass, strClassName);
+
+ if (!singletonClass) {
+
+ ERR_EXPLAIN("Couldn't find singleton for class: "+m);
+ ERR_CONTINUE(!singletonClass);
+ }
+
+ __android_log_print(ANDROID_LOG_INFO,"godot","****^*^*?^*^*class data %x",singletonClass);
+ jmethodID initialize = env->GetStaticMethodID(singletonClass, "initialize", "(Landroid/app/Activity;)Lcom/android/godot/Godot$SingletonBase;");
+
+ jobject obj = env->CallStaticObjectMethod(singletonClass,initialize,_godot_instance);
+ __android_log_print(ANDROID_LOG_INFO,"godot","****^*^*?^*^*class instance %x",obj);
+ jobject gob = env->NewGlobalRef(obj);
+
+
+ }
+
+ }
+
+}
+
+
+JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_step(JNIEnv * env, jobject obj)
+{
+
+
+ ThreadAndroid::setup_thread();
+
+ //__android_log_print(ANDROID_LOG_INFO,"godot","**STEP EVENT! - %p-%i\n",env,Thread::get_caller_ID());
+
+
+ suspend_mutex->lock();
+ input_mutex->lock();
+ //first time step happens, initialize
+ if (step == 0) {
+ // ugly hack to initialize the rest of the engine
+ // because of the way android forces you to do everything with threads
+
+ _initialize_java_modules();
+
+ Main::setup2();
+ ++step;
+ suspend_mutex->unlock();
+ input_mutex->unlock();
+ return;
+ };
+ if (step == 1) {
+ if (!Main::start()) {
+
+ input_mutex->unlock();
+ suspend_mutex->lock();
+ return; //should exit instead and print the error
+ }
+
+ os_android->main_loop_begin();
+ ++step;
+ }
+
+ while(pointer_events.size()) {
+
+ JAndroidPointerEvent jpe=pointer_events.front()->get();
+ os_android->process_touch(jpe.what,jpe.pointer,jpe.points);
+
+ pointer_events.pop_front();
+ }
+
+ while (key_events.size()) {
+
+ InputEvent event = key_events.front()->get();
+ os_android->process_event(event);
+
+ key_events.pop_front();
+ };
+
+ if (quit_request) {
+
+ os_android->main_loop_request_quit();
+ quit_request=false;
+ }
+
+
+ input_mutex->unlock();
+
+ os_android->process_accelerometer(accelerometer);
+
+ if (os_android->main_loop_iterate()==true) {
+
+ jclass cls = env->FindClass("com/android/godot/Godot");
+ jmethodID _finish = env->GetMethodID(cls, "forceQuit", "()V");
+ env->CallVoidMethod(_godot_instance, _finish);
+ __android_log_print(ANDROID_LOG_INFO,"godot","**FINISH REQUEST!!! - %p-%i\n",env,Thread::get_caller_ID());
+
+ }
+
+ suspend_mutex->unlock();
+
+}
+
+JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_touch(JNIEnv * env, jobject obj, jint ev,jint pointer, jint count, jintArray positions) {
+
+
+
+ //__android_log_print(ANDROID_LOG_INFO,"godot","**TOUCH EVENT! - %p-%i\n",env,Thread::get_caller_ID());
+
+
+ Vector<OS_Android::TouchPos> points;
+ for(int i=0;i<count;i++) {
+
+ jint p[3];
+ env->GetIntArrayRegion(positions,i*3,3,p);
+ OS_Android::TouchPos tp;
+ tp.pos=Point2(p[1],p[2]);
+ tp.id=p[0];
+ points.push_back(tp);
+ }
+
+ JAndroidPointerEvent jpe;
+ jpe.pointer=pointer;
+ jpe.points=points;
+ jpe.what=ev;
+
+ input_mutex->lock();
+
+ pointer_events.push_back(jpe);
+
+ input_mutex->unlock();
+ //if (os_android)
+// os_android->process_touch(ev,pointer,points);
+
+}
+
+JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_key(JNIEnv * env, jobject obj, jint ev, jint p_unicode_char, jboolean p_pressed) {
+
+ InputEvent ievent;
+ ievent.type = InputEvent::KEY;
+ ievent.device = 0;
+ int val = p_unicode_char;
+ ievent.key.scancode = val;
+ ievent.key.unicode = val;
+ if (val == 61448) {
+ ievent.key.scancode = KEY_BACKSPACE;
+ ievent.key.unicode = KEY_BACKSPACE;
+ };
+ if (val == 61453) {
+ ievent.key.scancode = KEY_ENTER;
+ ievent.key.unicode = KEY_ENTER;
+ };
+
+ input_mutex->lock();
+ key_events.push_back(ievent);
+ input_mutex->unlock();
+};
+
+
+JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_accelerometer(JNIEnv * env, jobject obj, jfloat x, jfloat y, jfloat z) {
+
+ input_mutex->lock();
+ accelerometer=Vector3(x,y,z);
+ input_mutex->unlock();
+
+}
+
+JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_focusin(JNIEnv * env, jobject obj){
+
+ if (!suspend_mutex)
+ return;
+ suspend_mutex->lock();
+
+ if (os_android && step > 0)
+ os_android->main_loop_focusin();
+
+ suspend_mutex->unlock();
+}
+
+JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_focusout(JNIEnv * env, jobject obj){
+
+ if (!suspend_mutex)
+ return;
+ suspend_mutex->lock();
+
+ if (os_android && step > 0)
+ os_android->main_loop_focusout();
+
+ suspend_mutex->unlock();
+
+}
+
+
+
+JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_audio(JNIEnv * env, jobject obj) {
+
+ ThreadAndroid::setup_thread();
+ AudioDriverAndroid::thread_func(env);
+
+
+}
+
+
+JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_singleton(JNIEnv * env, jobject obj, jstring name,jobject p_object){
+
+ String singname = env->GetStringUTFChars( name, NULL );
+ JNISingleton *s = memnew( JNISingleton );
+ s->set_instance(env->NewGlobalRef(p_object));
+ jni_singletons[singname]=s;
+
+ Globals::get_singleton()->add_singleton(Globals::Singleton(singname,s));
+ Globals::get_singleton()->set(singname,s);
+
+}
+
+
+static Variant::Type get_jni_type(const String& p_type) {
+
+ static struct {
+ const char *name;
+ Variant::Type type;
+ } _type_to_vtype[]={
+ {"void",Variant::NIL},
+ {"boolean",Variant::BOOL},
+ {"int",Variant::INT},
+ {"float",Variant::REAL},
+ {"double", Variant::REAL},
+ {"java.lang.String",Variant::STRING},
+ {"[I",Variant::INT_ARRAY},
+ {"[F",Variant::REAL_ARRAY},
+ {"[java.lang.String",Variant::STRING_ARRAY},
+ {"com.android.godot.Dictionary", Variant::DICTIONARY},
+ {NULL,Variant::NIL}
+ };
+
+ int idx=0;
+
+ while (_type_to_vtype[idx].name) {
+
+ if (p_type==_type_to_vtype[idx].name)
+ return _type_to_vtype[idx].type;
+
+ idx++;
+ }
+
+ return Variant::NIL;
+}
+
+
+static const char* get_jni_sig(const String& p_type) {
+
+ print_line("getting sig for " + p_type);
+ static struct {
+ const char *name;
+ const char *sig;
+ } _type_to_vtype[]={
+ {"void","V"},
+ {"boolean","Z"},
+ {"int","I"},
+ {"float","F"},
+ {"double","D"},
+ {"java.lang.String","Ljava/lang/String;"},
+ {"com.android.godot.Dictionary", "Lcom/android/godot/Dictionary;"},
+ {"[I","[I"},
+ {"[F","[F"},
+ {"[java.lang.String","[Ljava/lang/String;"},
+ {NULL,"V"}
+ };
+
+ int idx=0;
+
+ while (_type_to_vtype[idx].name) {
+
+ if (p_type==_type_to_vtype[idx].name)
+ return _type_to_vtype[idx].sig;
+
+ idx++;
+ }
+
+
+ return "Ljava/lang/Object;";
+}
+
+JNIEXPORT jstring JNICALL Java_com_android_godot_GodotLib_getGlobal(JNIEnv * env, jobject obj, jstring path) {
+
+ String js = env->GetStringUTFChars( path, NULL );
+
+ return env->NewStringUTF(Globals::get_singleton()->get(js).operator String().utf8().get_data());
+
+
+}
+
+
+JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_method(JNIEnv * env, jobject obj, jstring sname, jstring name, jstring ret, jobjectArray args){
+
+ String singname = env->GetStringUTFChars( sname, NULL );
+
+ ERR_FAIL_COND(!jni_singletons.has(singname));
+
+ JNISingleton *s = jni_singletons.get(singname);
+
+
+ String mname = env->GetStringUTFChars( name, NULL );
+ String retval = env->GetStringUTFChars( ret, NULL );
+ Vector<Variant::Type> types;
+ String cs="(";
+
+
+ int stringCount = env->GetArrayLength(args);
+
+ print_line("Singl: "+singname+" Method: "+mname+" RetVal: "+retval);
+ for (int i=0; i<stringCount; i++) {
+
+ jstring string = (jstring) env->GetObjectArrayElement(args, i);
+ const char *rawString = env->GetStringUTFChars(string, 0);
+ types.push_back(get_jni_type(String(rawString)));
+ cs+=get_jni_sig(String(rawString));
+ }
+
+ cs+=")";
+ cs+=get_jni_sig(retval);
+ jclass cls = env->GetObjectClass(s->get_instance());
+ print_line("METHOD: "+mname+" sig: "+cs);
+ jmethodID mid = env->GetMethodID(cls, mname.ascii().get_data(), cs.ascii().get_data());
+ if (!mid) {
+
+ print_line("FAILED GETTING METHOID "+mname);
+ }
+
+ s->add_method(mname,mid,types,get_jni_type(retval));
+
+
+}
+
+JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_callobject(JNIEnv * env, jobject p_obj, jint ID, jstring method, jobjectArray params) {
+
+ String str_method = env->GetStringUTFChars( method, NULL );
+
+ Object* obj = ObjectDB::get_instance(ID);
+ ERR_FAIL_COND(!obj);
+
+ int count = env->GetArrayLength(params);
+ Variant* vlist = (Variant*)alloca(sizeof(Variant) * count);
+ Variant** vptr = (Variant**)alloca(sizeof(Variant*) * count);
+ for (int i=0; i<count; i++) {
+
+ jobject obj = env->GetObjectArrayElement(params, i);
+ Variant v = _jobject_to_variant(env, obj);
+ memnew_placement(&vlist[i], Variant);
+ vlist[i] = v;
+ vptr[i] = &vlist[i];
+ };
+
+ Variant::CallError err;
+ obj->call(str_method, (const Variant**)vptr, count, err);
+ // something
+};
+
+
+//Main::cleanup();
+
+//return os.get_exit_code();
+#endif
diff --git a/platform/android/java_glue.h b/platform/android/java_glue.h
new file mode 100644
index 000000000..7a0666f63
--- /dev/null
+++ b/platform/android/java_glue.h
@@ -0,0 +1,58 @@
+/*************************************************************************/
+/* java_glue.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* 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. */
+/*************************************************************************/
+#ifndef ANDROID_NATIVE_ACTIVITY
+
+#ifndef JAVA_GLUE_H
+#define JAVA_GLUE_H
+
+#include <jni.h>
+#include <android/log.h>
+
+
+extern "C" {
+ JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_initialize(JNIEnv * env, jobject obj, jobject activity,jboolean p_need_reload_hook);
+ JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_resize(JNIEnv * env, jobject obj, jint width, jint height, jboolean reload);
+ JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_newcontext(JNIEnv * env, jobject obj);
+ JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_step(JNIEnv * env, jobject obj);
+ JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_quit(JNIEnv * env, jobject obj);
+ JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_touch(JNIEnv * env, jobject obj, jint ev,jint pointer, jint count, jintArray positions);
+ JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_key(JNIEnv * env, jobject obj, jint ev, jint p_unicode_char, jboolean p_pressed);
+ JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_audio(JNIEnv * env, jobject obj);
+ JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_accelerometer(JNIEnv * env, jobject obj, jfloat x, jfloat y, jfloat z);
+ JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_focusin(JNIEnv * env, jobject obj);
+ JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_focusout(JNIEnv * env, jobject obj);
+ JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_singleton(JNIEnv * env, jobject obj, jstring name,jobject p_object);
+ JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_method(JNIEnv * env, jobject obj, jstring sname, jstring name, jstring ret, jobjectArray args);
+ JNIEXPORT jstring JNICALL Java_com_android_godot_GodotLib_getGlobal(JNIEnv * env, jobject obj, jstring path);
+ JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_callobject(JNIEnv * env, jobject obj, jint ID, jstring method, jobjectArray params);
+};
+
+
+#endif
+#endif // JAVA_GLUE_H