-Added OpenSSL and HTTPS support

-Built-in version of the library for Windows, Android and iOS (other OSs use system one)
-Small fixes all around
This commit is contained in:
Juan Linietsky
2014-04-28 21:56:43 -03:00
parent 7fadc2f93a
commit 87f37bc5a3
1382 changed files with 489992 additions and 2790 deletions

View File

@@ -1,22 +0,0 @@
Import('env')
android_files = [
'audio_driver_android.cpp',
'file_access_jandroid.cpp',
'dir_access_jandroid.cpp',
'os_android.cpp',
'java_glue.cpp'
]
#env.Depends('#core/math/vector3.h', 'vector3_psp.h')
#obj = env.SharedObject('godot_android.cpp')
android_objects=[]
for x in android_files:
android_objects.append( env.SharedObject( x ) )
prog = None
env.SharedLibrary("#platform/jandroid/libgodot_android.so",[android_objects])

View File

@@ -1,104 +0,0 @@
#include "audio_driver_android.h"
AudioDriverAndroid* AudioDriverAndroid::s_ad=NULL;
const char* AudioDriverAndroid::get_name() const {
return "Android";
}
#if 0
int AudioDriverAndroid::thread_func(SceSize args, void *argp) {
AudioDriverAndroid* ad = s_ad;
sceAudioOutput2Reserve(AUDIO_OUTPUT_SAMPLE);
int half=0;
while(!ad->exit_thread) {
int16_t *ptr = &ad->outbuff[AUDIO_OUTPUT_SAMPLE*2*half];
if (!ad->active) {
for(int i=0;i<AUDIO_OUTPUT_SAMPLE*2;i++) {
ptr[i]=0;
}
} else {
//printf("samples: %i\n",AUDIO_OUTPUT_SAMPLE);
ad->lock();
ad->audio_server_process(AUDIO_OUTPUT_SAMPLE,ad->outbuff_32);
ad->unlock();
const int32_t* src_buff=ad->outbuff_32;
for(int i=0;i<AUDIO_OUTPUT_SAMPLE*2;i++) {
ptr[i]=src_buff[i]>>16;
}
}
/* Output 16-bit PCM STEREO data that is in pcmBuf without changing the volume */
sceAudioOutput2OutputBlocking(
SCE_AUDIO_VOLUME_0dB*3, //0db at 0x8000, that's obvious
ptr
);
if (half)
half=0;
else
half=1;
}
sceAudioOutput2Release();
sceKernelExitThread(SCE_KERNEL_EXIT_SUCCESS);
ad->thread_exited=true;
return SCE_KERNEL_EXIT_SUCCESS;
}
#endif
Error AudioDriverAndroid::init(){
return OK;
}
void AudioDriverAndroid::start(){
}
int AudioDriverAndroid::get_mix_rate() const {
return 44100;
}
AudioDriverSW::OutputFormat AudioDriverAndroid::get_output_format() const{
return OUTPUT_STEREO;
}
void AudioDriverAndroid::lock(){
}
void AudioDriverAndroid::unlock() {
}
void AudioDriverAndroid::finish(){
}
AudioDriverAndroid::AudioDriverAndroid()
{
s_ad=this;
}

View File

@@ -1,29 +0,0 @@
#ifndef AUDIO_DRIVER_ANDROID_H
#define AUDIO_DRIVER_ANDROID_H
#include "servers/audio/audio_server_sw.h"
class AudioDriverAndroid : public AudioDriverSW {
static AudioDriverAndroid* s_ad;
public:
void set_singleton();
virtual const char* get_name() const;
virtual Error init();
virtual void start();
virtual int get_mix_rate() const ;
virtual OutputFormat get_output_format() const;
virtual void lock();
virtual void unlock();
virtual void finish();
AudioDriverAndroid();
};
#endif // AUDIO_DRIVER_ANDROID_H

View File

@@ -1,38 +0,0 @@
#include "context_gl_android.h"
#include <GLES2/gl2.h>
#include "os/os.h"
void ContextGLAndroid::make_current() {
};
int ContextGLAndroid::get_window_width() {
return OS::get_singleton()->get_default_video_mode().width;
};
int ContextGLAndroid::get_window_height() {
return OS::get_singleton()->get_default_video_mode().height;
};
void ContextGLAndroid::swap_buffers() {
};
Error ContextGLAndroid::initialize() {
return OK;
};
ContextGLAndroid::ContextGLAndroid() {
};
ContextGLAndroid::~ContextGLAndroid() {
};

View File

@@ -1,24 +0,0 @@
#ifndef CONTEXT_GL_ANDROID_H
#define CONTEXT_GL_ANDROID_H
class ContextGLAndroid : public ContextGL {
enum {
COMMAND_BUFFER_SIZE = 1024 * 1024,
};
public:
virtual void make_current();
virtual int get_window_width();
virtual int get_window_height();
virtual void swap_buffers();
virtual Error initialize();
ContextGLAndroid();
~ContextGLAndroid();
};
#endif // CONTEXT_GL_ANDROID_H

View File

@@ -1,107 +0,0 @@
import os
import sys
import string
def can_build():
import os
if (not os.environ.has_key("ANDROID_NDK_ROOT")):
print("ANDROID_NDK_ROOT not present, Android disabled.")
return False
return True
def get_opts():
return [
('ANDROID_NDK_ROOT', 'the path to Android NDK', os.environ.get("ANDROID_NDK_ROOT", 0)),
('NDK_TOOLCHAIN', 'toolchain to use for the NDK',"arm-eabi-4.4.0"),
#android 2.2
# ('NDK_PLATFORM', 'platform to use for the NDK',"android-8"),
# ('NDK_TARGET', 'toolchain to use for the NDK',"arm-linux-androideabi-4.4.3"),
]
def get_flags():
return [
('lua', 'no'),
('tools', 'no'),
('nedmalloc', 'no'),
]
def configure(env):
print("Godot Android!!!!!")
env.Append(CPPPATH=['#platform/android'])
env['OBJSUFFIX'] = ".jandroid.o"
env['LIBSUFFIX'] = ".jandroid.a"
env['PROGSUFFIX'] = ".jandroid"
gcc_path=env["ANDROID_NDK_ROOT"]+"/toolchains/"+env["NDK_TARGET"]+"/prebuilt/";
if (sys.platform.find("linux")==0):
gcc_path=gcc_path+"/linux-x86/bin"
elif (sys.platform=="darwin"):
gcc_path=gcc_path+"/darwin-x86/bin" #this may be wrong
elif (os.name=="nt"):
gcc_path=gcc_path+"/windows-x86/bin" #this may be wrong
env['ENV']['PATH'] = gcc_path+":"+env['ENV']['PATH']
env['CC'] = gcc_path+'/arm-linux-androideabi-gcc'
env['CXX'] = gcc_path+'/arm-linux-androideabi-g++'
env['AR'] = gcc_path+"/arm-linux-androideabi-ar"
import string
#include path
gcc_include=env["ANDROID_NDK_ROOT"]+"/platforms/"+env["NDK_PLATFORM"]+"/arch-arm/usr/include"
ld_sysroot=env["ANDROID_NDK_ROOT"]+"/platforms/"+env["NDK_PLATFORM"]+"/arch-arm"
ld_path=env["ANDROID_NDK_ROOT"]+"/platforms/"+env["NDK_PLATFORM"]+"/arch-arm/usr/lib"
#cxx_include=env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/system/include"
#env.Append(CPPPATH=[gcc_include,cxx_include])
env['CCFLAGS'] = string.split('-DNO_THREADS -DNO_STATVFS -MMD -MP -MF -fpic -ffunction-sections -funwind-tables -fstack-protector -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ -Wno-psabi -march=armv5te -mtune=xscale -msoft-float -fno-exceptions -mthumb -fno-strict-aliasing -DANDROID -Wa,--noexecstack -DGLES2_ENABLED ')
env.Append(LDPATH=[ld_path])
env.Append(LIBS=['c','m','stdc++','log','GLESv2'])
env["LINKFLAGS"]= string.split(" -g --sysroot="+ld_sysroot+" -Wl,--no-undefined -Wl,-z,noexecstack")
env.Append(LINKFLAGS=["-Wl,-soname,libgodot_android.so"])
if (env["target"]=="release"):
env.Append(CCFLAGS=['-O2', '-ffast-math','-fomit-frame-pointer'])
env['OBJSUFFIX'] = "_opt"+env['OBJSUFFIX']
env['LIBSUFFIX'] = "_opt"+env['LIBSUFFIX']
elif (env["target"]=="debug"):
env.Append(CCFLAGS=['-D_DEBUG', '-g', '-Wall', '-O0', '-DDEBUG_ENABLED'])
env.Append(CPPFLAGS=['-DDEBUG_MEMORY_ALLOC'])
env.Append(CPPFLAGS=['-DANDROID_ENABLED', '-DUNIX_ENABLED','-DNO_FCNTL'])
env['neon_enabled']=True
env.Append(CPPFLAGS=['-DANDROID_ENABLED', '-DUNIX_ENABLED', '-DNO_FCNTL','-DMPC_FIXED_POINT'])
# env.Append(CPPFLAGS=['-DANDROID_ENABLED', '-DUNIX_ENABLED','-DMPC_FIXED_POINT'])
if (env['android_stl']=='yes'):
#env.Append(CCFLAGS=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/system/include"])
env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.4.3/include"])
env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.4.3/libs/armeabi/include"])
env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.4.3/libs/armeabi"])
env.Append(LIBS=["gnustl_static","supc++"])
#env.Append(CCFLAGS=["-I"+env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/stlport/stlport"])
#env.Append(CCFLAGS=["-I"+env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/libs/armeabi/include"])
#env.Append(LINKFLAGS=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/libs/armeabi/libstdc++.a"])
else:
env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gabi++/include"])
env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cpufeatures"])
env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gabi++/libs/armeabi"])
env.Append(LIBS=['gabi++_static'])
env.Append(CCFLAGS=["-fno-exceptions",'-DNO_SAFE_CAST'])

View File

@@ -1,217 +0,0 @@
#include "dir_access_jandroid.h"
#include "file_access_jandroid.h"
jobject DirAccessJAndroid::io=NULL;
jclass DirAccessJAndroid::cls=NULL;
JNIEnv * DirAccessJAndroid::env=NULL;
jmethodID DirAccessJAndroid::_dir_open=NULL;
jmethodID DirAccessJAndroid::_dir_next=NULL;
jmethodID DirAccessJAndroid::_dir_close=NULL;
DirAccess *DirAccessJAndroid::create_fs() {
return memnew(DirAccessJAndroid);
}
bool DirAccessJAndroid::list_dir_begin() {
list_dir_end();
jstring js = env->NewStringUTF(current_dir.utf8().get_data());
int res = env->CallIntMethod(io,_dir_open,js);
if (res<=0)
return true;
id=res;
return false;
}
String DirAccessJAndroid::get_next(){
ERR_FAIL_COND_V(id==0,"");
jstring str= (jstring)env->CallObjectMethod(io,_dir_next,id);
if (!str)
return "";
int sl = env->GetStringLength(str);
if (sl==0) {
env->DeleteLocalRef((jobject)str);
return "";
}
CharString cs;
cs.resize(sl+1);
env->GetStringRegion(str,0,sl,(jchar*)&cs[0]);
cs[sl]=0;
String ret;
ret.parse_utf8(&cs[0]);
env->DeleteLocalRef((jobject)str);
return ret;
}
bool DirAccessJAndroid::current_is_dir() const{
String sd;
if (current_dir=="")
sd=current;
else
sd=current_dir+"/"+current;
jstring js = env->NewStringUTF(sd.utf8().get_data());
int res = env->CallIntMethod(io,_dir_open,js);
if (res<=0)
return false;
env->CallObjectMethod(io,_dir_close,res);
return true;
}
void DirAccessJAndroid::list_dir_end(){
if (id==0)
return;
env->CallObjectMethod(io,_dir_close,id);
id=0;
}
int DirAccessJAndroid::get_drive_count(){
return 0;
}
String DirAccessJAndroid::get_drive(int p_drive){
return "";
}
Error DirAccessJAndroid::change_dir(String p_dir){
p_dir=p_dir.simplify_path();
if (p_dir=="" || p_dir=="." || (p_dir==".." && current_dir==""))
return OK;
String new_dir;
if (p_dir.begins_with("/"))
new_dir=p_dir.substr(1,p_dir.length());
else if (p_dir.begins_with("res://"))
new_dir=p_dir.substr(6,p_dir.length());
else //relative
new_dir=new_dir+"/"+p_dir;
//test if newdir exists
new_dir=new_dir.simplify_path();
jstring js = env->NewStringUTF(new_dir.utf8().get_data());
int res = env->CallIntMethod(io,_dir_open,js);
if (res<=0)
return ERR_INVALID_PARAMETER;
env->CallObjectMethod(io,_dir_close,res);
return OK;
}
String DirAccessJAndroid::get_current_dir(){
return "/"+current_dir;
}
String DirAccessJAndroid::get_dir_separator() const{
return "/";
}
bool DirAccessJAndroid::file_exists(String p_file){
String sd;
if (current_dir=="")
sd=p_file;
else
sd=current_dir+"/"+p_file;
FileAccessJAndroid *f = memnew(FileAccessJAndroid);
bool exists = f->file_exists(sd);
memdelete(f);
return exists;
}
uint64_t DirAccessJAndroid::get_modified_time(String p_file){
return 0;
}
Error DirAccessJAndroid::make_dir(String p_dir){
ERR_FAIL_V(ERR_UNAVAILABLE);
}
Error DirAccessJAndroid::rename(String p_from, String p_to){
ERR_FAIL_V(ERR_UNAVAILABLE);
}
Error DirAccessJAndroid::remove(String p_name){
ERR_FAIL_V(ERR_UNAVAILABLE);
}
//FileType get_file_type() const;
size_t DirAccessJAndroid::get_space_left() {
return 0;
}
void DirAccessJAndroid::make_default() {
instance_func=create_fs;
}
void DirAccessJAndroid::setup( JNIEnv *p_env, jobject p_io) {
env=p_env;
io=p_io;
__android_log_print(ANDROID_LOG_INFO,"godot","STEP7");
jclass c = env->GetObjectClass(io);
cls = (jclass)env->NewGlobalRef(c);
__android_log_print(ANDROID_LOG_INFO,"godot","STEP8");
_dir_open = env->GetMethodID(cls, "dir_open", "(Ljava/lang/String;)I");
if(_dir_open != 0) {
__android_log_print(ANDROID_LOG_INFO,"godot","*******GOT METHOD _dir_open ok!!");
}
_dir_next = env->GetMethodID(cls, "dir_next", "(I)Ljava/lang/String;");
if(_dir_next != 0) {
__android_log_print(ANDROID_LOG_INFO,"godot","*******GOT METHOD _dir_next ok!!");
}
_dir_close = env->GetMethodID(cls, "dir_close", "(I)V");
if(_dir_close != 0) {
__android_log_print(ANDROID_LOG_INFO,"godot","*******GOT METHOD _dir_close ok!!");
}
// (*env)->CallVoidMethod(env,obj,aMethodID, myvar);
}
DirAccessJAndroid::DirAccessJAndroid() {
id=0;
}
DirAccessJAndroid::~DirAccessJAndroid() {
list_dir_end();;
}

View File

@@ -1,63 +0,0 @@
#ifndef DIR_ACCESS_JANDROID_H
#define DIR_ACCESS_JANDROID_H
#include "java_glue.h"
#include "os/dir_access.h"
#include <stdio.h>
class DirAccessJAndroid : public DirAccess {
//AAssetDir* aad;
static jobject io;
static jclass cls;
static jmethodID _dir_open;
static jmethodID _dir_next;
static jmethodID _dir_close;
static JNIEnv * env;
int id;
String current_dir;
String current;
static DirAccess *create_fs();
public:
virtual bool list_dir_begin(); ///< This starts dir listing
virtual String get_next();
virtual bool current_is_dir() const;
virtual void list_dir_end(); ///<
virtual int get_drive_count();
virtual String get_drive(int p_drive);
virtual Error change_dir(String p_dir); ///< can be relative or absolute, return false on success
virtual String get_current_dir(); ///< return current dir location
virtual String get_dir_separator() const ;
virtual bool file_exists(String p_file);
virtual uint64_t get_modified_time(String p_file);
virtual Error make_dir(String p_dir);
virtual Error rename(String p_from, String p_to);
virtual Error remove(String p_name);
//virtual FileType get_file_type() const;
size_t get_space_left();
static void make_default();
static void setup( JNIEnv *env, jobject io);
static void update_env( JNIEnv *p_env) { env=p_env; }
DirAccessJAndroid();
~DirAccessJAndroid();
};
#endif // DIR_ACCESS_JANDROID_H

View File

@@ -1,204 +0,0 @@
#include "file_access_jandroid.h"
#include "os/os.h"
#include <unistd.h>
jobject FileAccessJAndroid::io=NULL;
jclass FileAccessJAndroid::cls;
jmethodID FileAccessJAndroid::_file_open=0;
jmethodID FileAccessJAndroid::_file_get_size=0;
jmethodID FileAccessJAndroid::_file_seek=0;
jmethodID FileAccessJAndroid::_file_read=0;
jmethodID FileAccessJAndroid::_file_tell=0;
jmethodID FileAccessJAndroid::_file_eof=0;
jmethodID FileAccessJAndroid::_file_close=0;
JNIEnv * FileAccessJAndroid::env=NULL;
void FileAccessJAndroid::make_default() {
create_func=create_jandroid;
}
FileAccess* FileAccessJAndroid::create_jandroid() {
return memnew(FileAccessJAndroid);
}
Error FileAccessJAndroid::open(const String& p_path, int p_mode_flags) {
if (is_open())
close();
String path=fix_path(p_path).simplify_path();
if (path.begins_with("/"))
path=path.substr(1,path.length());
else if (path.begins_with("res://"))
path=path.substr(6,path.length());
//OS::get_singleton()->print("env: %p, io %p, fo: %p\n",env,io,_file_open);
jstring js = env->NewStringUTF(path.utf8().get_data());
int res = env->CallIntMethod(io,_file_open,js,p_mode_flags&WRITE?true:false);
if (res<=0)
return ERR_FILE_CANT_OPEN;
id=res;
return OK;
}
void FileAccessJAndroid::close() {
if (io==0)
return;
env->CallVoidMethod(io,_file_close,id);
id=0;
}
bool FileAccessJAndroid::is_open() const {
return id!=0;
}
void FileAccessJAndroid::seek(size_t p_position) {
ERR_FAIL_COND(!is_open());
env->CallVoidMethod(io,_file_seek,id,p_position);
}
void FileAccessJAndroid::seek_end(int64_t p_position) {
ERR_FAIL_COND(!is_open());
seek(get_len());
}
size_t FileAccessJAndroid::get_pos() const {
ERR_FAIL_COND_V(!is_open(),0);
return env->CallIntMethod(io,_file_tell,id);
}
size_t FileAccessJAndroid::get_len() const {
ERR_FAIL_COND_V(!is_open(),0);
return env->CallIntMethod(io,_file_get_size,id);
}
bool FileAccessJAndroid::eof_reached() const {
ERR_FAIL_COND_V(!is_open(),0);
return env->CallIntMethod(io,_file_eof,id);
}
uint8_t FileAccessJAndroid::get_8() const {
ERR_FAIL_COND_V(!is_open(),0);
uint8_t byte;
get_buffer(&byte,1);
return byte;
}
int FileAccessJAndroid::get_buffer(uint8_t *p_dst, int p_length) const {
ERR_FAIL_COND_V(!is_open(),0);
if (p_length==0)
return 0;
jbyteArray jca = (jbyteArray)env->CallObjectMethod(io,_file_read,id,p_length);
int len = env->GetArrayLength(jca);
env->GetByteArrayRegion(jca,0,len,(jbyte*)p_dst);
env->DeleteLocalRef((jobject)jca);
return len;
}
Error FileAccessJAndroid::get_error() const {
if (eof_reached())
return ERR_FILE_EOF;
return OK;
}
void FileAccessJAndroid::store_8(uint8_t p_dest) {
}
bool FileAccessJAndroid::file_exists(const String& p_path) {
jstring js = env->NewStringUTF(p_path.utf8().get_data());
int res = env->CallIntMethod(io,_file_open,js,false);
if (res<=0)
return false;
env->CallVoidMethod(io,_file_close,res);
return true;
}
void FileAccessJAndroid::setup( JNIEnv *p_env, jobject p_io) {
io=p_io;
env=p_env;
__android_log_print(ANDROID_LOG_INFO,"godot","STEP5");
jclass c = env->GetObjectClass(io);
__android_log_print(ANDROID_LOG_INFO,"godot","STEP6");
cls=(jclass)env->NewGlobalRef(c);
_file_open = env->GetMethodID(cls, "file_open", "(Ljava/lang/String;Z)I");
if(_file_open != 0) {
__android_log_print(ANDROID_LOG_INFO,"godot","*******GOT METHOD _file_open ok!!");
}
_file_get_size = env->GetMethodID(cls, "file_get_size", "(I)I");
if(_file_get_size != 0) {
__android_log_print(ANDROID_LOG_INFO,"godot","*******GOT METHOD _file_get_size ok!!");
}
_file_tell = env->GetMethodID(cls, "file_tell", "(I)I");
if(_file_tell != 0) {
__android_log_print(ANDROID_LOG_INFO,"godot","*******GOT METHOD _file_tell ok!!");
}
_file_eof = env->GetMethodID(cls, "file_eof", "(I)Z");
if(_file_eof != 0) {
__android_log_print(ANDROID_LOG_INFO,"godot","*******GOT METHOD _file_eof ok!!");
}
_file_seek = env->GetMethodID(cls, "file_seek", "(II)V");
if(_file_seek != 0) {
__android_log_print(ANDROID_LOG_INFO,"godot","*******GOT METHOD _file_seek ok!!");
}
_file_read = env->GetMethodID(cls, "file_read", "(II)[B");
if(_file_read != 0) {
__android_log_print(ANDROID_LOG_INFO,"godot","*******GOT METHOD _file_read ok!!");
}
_file_close = env->GetMethodID(cls, "file_close", "(I)V");
if(_file_close != 0) {
__android_log_print(ANDROID_LOG_INFO,"godot","*******GOT METHOD _file_close ok!!");
}
// (*env)->CallVoidMethod(env,obj,aMethodID, myvar);
}
FileAccessJAndroid::FileAccessJAndroid()
{
id=0;
}
FileAccessJAndroid::~FileAccessJAndroid()
{
if (is_open())
close();
}

View File

@@ -1,56 +0,0 @@
#ifndef FILE_ACCESS_JANDROID_H
#define FILE_ACCESS_JANDROID_H
#include "java_glue.h"
#include "os/file_access.h"
class FileAccessJAndroid : public FileAccess {
static jobject io;
static jclass cls;
static jmethodID _file_open;
static jmethodID _file_get_size;
static jmethodID _file_seek;
static jmethodID _file_tell;
static jmethodID _file_eof;
static jmethodID _file_read;
static jmethodID _file_close;
static JNIEnv * env;
int id;
static FileAccess* create_jandroid();
public:
virtual Error open(const String& p_path, int p_mode_flags); ///< open a file
virtual void close(); ///< close a file
virtual bool is_open() const; ///< true when file is open
virtual void seek(size_t p_position); ///< seek to a given position
virtual void seek_end(int64_t p_position=0); ///< seek from the end of file
virtual size_t get_pos() const; ///< get position in the file
virtual size_t get_len() const; ///< get size of the file
virtual bool eof_reached() const; ///< reading passed EOF
virtual uint8_t get_8() const; ///< get a byte
virtual int get_buffer(uint8_t *p_dst, int p_length) const;
virtual Error get_error() const; ///< get last error
virtual void store_8(uint8_t p_dest); ///< store a byte
virtual bool file_exists(const String& p_path); ///< return true if a file exists
static void make_default();
static void setup( JNIEnv *env, jobject io);
static void update_env( JNIEnv *p_env) { env=p_env; }
FileAccessJAndroid();
~FileAccessJAndroid();
};
#endif // FILE_ACCESS_JANDROID_H

View File

@@ -1,3 +0,0 @@
set solib-search-path .
directory ../..
file app_process

View File

@@ -1,22 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.godot"
android:versionCode="1"
android:versionName="1.0">
<application android:label="@string/godot" android:icon="@drawable/icon">
<activity android:name="Godot"
android:label="@string/godot"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:launchMode="singleTask"
android:configChanges="orientation|keyboardHidden">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-feature android:glEsVersion="0x00020000"/>
<uses-sdk android:minSdkVersion="8"/>
</manifest>

View File

@@ -1,17 +0,0 @@
# 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.

View File

@@ -1,79 +0,0 @@
<?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" />
<property name="asset-dir" value="assets" />
<!-- The build.properties file can be created by you and is never touched
by the 'android' tool. This is the place to change some of the
default property values used by the Ant rules.
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'.
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="build.properties" />
<!-- The default.properties file is created and updated by the 'android'
tool, as well as ADT.
This file is an integral part of the build system for your
application and should be checked into Version Control Systems. -->
<property file="default.properties" />
<!-- Required pre-setup import -->
<import file="${sdk.dir}/tools/ant/pre_setup.xml" />
<!-- extension targets. Uncomment the ones where you want to do custom work
in between standard targets -->
<!--
<target name="-pre-build">
</target>
<target name="-pre-compile">
</target>
[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}]
<target name="-post-compile">
</target>
-->
<!-- Execute the Android Setup task that will setup some properties
specific to the target, and import the build rules files.
The rules file is imported from
<SDK>/tools/ant/
Depending on the project type it can be either:
- main_rules.xml
- lib_rules.xml
- test_rules.xml
To customize existing targets, there are two options:
- Customize only one target:
- copy/paste the target into this file, *before* the
<setup> task.
- customize it to your needs.
- Customize the whole script.
- copy/paste the content of the rules files (minus the top node)
into this file, *after* the <setup> task
- disable the import of the rules by changing the setup task
below to <setup import="false" />.
- customize to your needs.
-->
<setup />
</project>

View File

@@ -1,11 +0,0 @@
# 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

View File

@@ -1,10 +0,0 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must *NOT* be checked in Version Control Systems,
# as it contains information specific to your local configuration.
# location of the SDK. This is only used by Ant
# For customization when using a Version Control System, please read the
# header note.
sdk.dir=/home/red/bin/android-sdk-linux_x86

View File

@@ -1,36 +0,0 @@
-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 *;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="godot">Godot</string>
</resources>

View File

@@ -1,85 +0,0 @@
package com.android.godot;
import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
public class Godot extends Activity
{
GodotView mView;
static public GodotIO io;
@Override protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
io = new GodotIO(getAssets());
GodotLib.io=io;
mView = new GodotView(getApplication(),io);
setContentView(mView);
}
@Override protected void onPause() {
super.onPause();
mView.onPause();
}
@Override protected void onResume() {
super.onResume();
mView.onResume();
}
@Override public boolean dispatchTouchEvent (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;
}
}

View File

@@ -1,277 +0,0 @@
package com.android.godot;
import java.util.HashMap;
import android.content.res.AssetManager;
import java.io.InputStream;
import java.io.IOException;
// Wrapper for native library
public class GodotIO {
AssetManager am;
/// 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(AssetManager p_am) {
am=p_am;
streams=new HashMap<Integer,AssetData>();
dirs=new HashMap<Integer,AssetDir>();
}
}

View File

@@ -1,22 +0,0 @@
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 init(int width, int height);
public static native void step();
public static native void touch(int what,int pointer,int howmany, int[] arr);
}

View File

@@ -1,319 +0,0 @@
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;
public GodotView(Context context,GodotIO p_io) {
super(context);
ctx=context;
io=p_io;
init(false, 0, 0);
}
public GodotView(Context context, boolean translucent, int depth, int stencil) {
super(context);
init(translucent, depth, stencil);
}
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) {
Log.w(TAG, "creating OpenGL ES 2.0 context");
checkEglError("Before eglCreateContext", egl);
int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list);
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_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
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, s_configAttribs2, 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, s_configAttribs2, 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) {
System.out.printf("** CONTENT DIR %s\n",ctx.getFilesDir().getPath());
GodotLib.init(width, height);
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// Do nothing.
}
}
}

View File

@@ -1,181 +0,0 @@
#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"
static OS_Android *os_android=NULL;
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 bool initialized=false;
static Mutex *input_mutex=NULL;
JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_init(JNIEnv * env, jobject obj, jint width, jint height)
{
if (initialized) // wtf
return;
__android_log_print(ANDROID_LOG_INFO,"godot","**INIT EVENT! - %p\n",env);
initialized=true;
__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);
FileAccessJAndroid::setup(env,gob);
DirAccessJAndroid::setup(env,gob);
}
os_android = new OS_Android(width,height);
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);
#else
Error err = Main::setup("apk",0,NULL);
#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","**START");
if (!Main::start()) {
return; //should exit instead and print the error
}
input_mutex=Mutex::create();
os_android->main_loop_begin();
}
JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_step(JNIEnv * env, jobject obj)
{
__android_log_print(ANDROID_LOG_INFO,"godot","**STEP EVENT! - %p-%i\n",env,Thread::get_caller_ID());
{
FileAccessJAndroid::update_env(env);
DirAccessJAndroid::update_env(env);
}
input_mutex->lock();
while(pointer_events.size()) {
JAndroidPointerEvent jpe=pointer_events.front()->get();
os_android->process_touch(jpe.what,jpe.pointer,jpe.points);
pointer_events.pop_front();
}
input_mutex->unlock();
if (os_android->main_loop_iterate()==true) {
return; //should exit instead
}
}
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);
}
//Main::cleanup();
//return os.get_exit_code();

View File

@@ -1,16 +0,0 @@
#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_init(JNIEnv * env, jobject obj, jint width, jint height);
JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_step(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);
};
#endif // JAVA_GLUE_H

View File

@@ -1,428 +0,0 @@
#include "os_android.h"
#include "java_glue.h"
#include "drivers/gles2/rasterizer_gles2.h"
#include "servers/visual/visual_server_raster.h"
#include "file_access_jandroid.h"
#include "dir_access_jandroid.h"
#include "core/io/file_access_buffered_fa.h"
#include "main/main.h"
int OS_Android::get_video_driver_count() const {
return 1;
}
const char * OS_Android::get_video_driver_name(int p_driver) const {
return "GLES2";
}
OS::VideoMode OS_Android::get_default_video_mode() const {
return OS::VideoMode();
}
int OS_Android::get_audio_driver_count() const {
return 1;
}
const char * OS_Android::get_audio_driver_name(int p_driver) const {
return "Android";
}
void OS_Android::initialize_core() {
OS_Unix::initialize_core();
//FileAccessJAndroid::make_default();
DirAccessJAndroid::make_default();
FileAccessBufferedFA<FileAccessJAndroid>::make_default();
}
void OS_Android::initialize(const VideoMode& p_desired,int p_video_driver,int p_audio_driver) {
AudioDriverManagerSW::add_driver(&audio_driver_android);
rasterizer = memnew( RasterizerGLES2 );
visual_server = memnew( VisualServerRaster(rasterizer) );
visual_server->init();
visual_server->cursor_set_visible(false, 0);
AudioDriverManagerSW::get_driver(p_audio_driver)->set_singleton();
if (AudioDriverManagerSW::get_driver(p_audio_driver)->init()!=OK) {
ERR_PRINT("Initializing audio failed.");
}
sample_manager = memnew( SampleManagerMallocSW );
audio_server = memnew( AudioServerSW(sample_manager) );
audio_server->set_mixer_params(AudioMixerSW::INTERPOLATION_LINEAR,false);
audio_server->init();
spatial_sound_server = memnew( SpatialSoundServerSW );
spatial_sound_server->init();
spatial_sound_2d_server = memnew( SpatialSound2DServerSW );
spatial_sound_2d_server->init();
//
physics_server = memnew( PhysicsServerSW );
physics_server->init();
physics_2d_server = memnew( Physics2DServerSW );
physics_2d_server->init();
input = memnew( InputDefault );
}
void OS_Android::set_main_loop( MainLoop * p_main_loop ) {
main_loop=p_main_loop;
}
void OS_Android::delete_main_loop() {
memdelete( main_loop );
}
void OS_Android::finalize() {
memdelete(input);
}
void OS_Android::vprint(const char* p_format, va_list p_list, bool p_stderr) {
__android_log_vprint(p_stderr?ANDROID_LOG_ERROR:ANDROID_LOG_INFO,"godot",p_format,p_list);
}
void OS_Android::print(const char *p_format, ... ) {
va_list argp;
va_start(argp, p_format);
__android_log_vprint(ANDROID_LOG_INFO,"godot",p_format,argp);
va_end(argp);
}
void OS_Android::alert(const String& p_alert) {
print("ALERT: %s\n",p_alert.utf8().get_data());
}
void OS_Android::set_mouse_show(bool p_show) {
//android has no mouse...
}
void OS_Android::set_mouse_grab(bool p_grab) {
//it really has no mouse...!
}
bool OS_Android::is_mouse_grab_enabled() const {
//*sigh* technology has evolved so much since i was a kid..
return false;
}
Point2 OS_Android::get_mouse_pos() const {
return Point2();
}
int OS_Android::get_mouse_button_state() const {
return 0;
}
void OS_Android::set_window_title(const String& p_title) {
}
//interesting byt not yet
//void set_clipboard(const String& p_text);
//String get_clipboard() const;
void OS_Android::set_video_mode(const VideoMode& p_video_mode,int p_screen) {
}
OS::VideoMode OS_Android::get_video_mode(int p_screen) const {
return default_videomode;
}
void OS_Android::get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen) const {
p_list->push_back(default_videomode);
}
String OS_Android::get_name() {
return "Android";
}
MainLoop *OS_Android::get_main_loop() const {
return main_loop;
}
bool OS_Android::can_draw() const {
return true; //always?
}
void OS_Android::set_cursor_shape(CursorShape p_shape) {
//android really really really has no mouse.. how amazing..
}
void OS_Android::main_loop_begin() {
if (main_loop)
main_loop->init();
}
bool OS_Android::main_loop_iterate() {
if (!main_loop)
return false;
return Main::iteration();
}
void OS_Android::main_loop_end() {
if (main_loop)
main_loop->finish();
}
void OS_Android::process_touch(int p_what,int p_pointer, const Vector<TouchPos>& p_points) {
switch(p_what) {
case 0: { //gesture begin
if (touch.size()) {
//end all if exist
InputEvent ev;
ev.type=InputEvent::MOUSE_BUTTON;
ev.ID=++last_id;
ev.mouse_button.button_index=BUTTON_LEFT;
ev.mouse_button.button_mask=BUTTON_MASK_LEFT;
ev.mouse_button.pressed=false;
ev.mouse_button.x=touch[0].pos.x;
ev.mouse_button.y=touch[0].pos.y;
ev.mouse_button.global_x=touch[0].pos.x;
ev.mouse_button.global_y=touch[0].pos.y;
input->set_mouse_pos(Point2(ev.mouse_button.x,ev.mouse_button.y));
main_loop->input_event(ev);
for(int i=0;i<touch.size();i++) {
InputEvent ev;
ev.type=InputEvent::SCREEN_TOUCH;
ev.ID=++last_id;
ev.screen_touch.index=touch[i].id;
ev.screen_touch.pressed=false;
ev.screen_touch.x=touch[i].pos.x;
ev.screen_touch.y=touch[i].pos.y;
main_loop->input_event(ev);
}
}
touch.resize(p_points.size());
for(int i=0;i<p_points.size();i++) {
touch[i].id=p_points[i].id;
touch[i].pos=p_points[i].pos;
}
{
//send mouse
InputEvent ev;
ev.type=InputEvent::MOUSE_BUTTON;
ev.ID=++last_id;
ev.mouse_button.button_index=BUTTON_LEFT;
ev.mouse_button.button_mask=BUTTON_MASK_LEFT;
ev.mouse_button.pressed=true;
ev.mouse_button.x=touch[0].pos.x;
ev.mouse_button.y=touch[0].pos.y;
ev.mouse_button.global_x=touch[0].pos.x;
ev.mouse_button.global_y=touch[0].pos.y;
last_mouse=touch[0].pos;
input->set_mouse_pos(Point2(ev.mouse_button.x,ev.mouse_button.y));
main_loop->input_event(ev);
}
//send touch
for(int i=0;i<touch.size();i++) {
InputEvent ev;
ev.type=InputEvent::SCREEN_TOUCH;
ev.ID=++last_id;
ev.screen_touch.index=touch[i].id;
ev.screen_touch.pressed=true;
ev.screen_touch.x=touch[i].pos.x;
ev.screen_touch.y=touch[i].pos.y;
main_loop->input_event(ev);
}
} break;
case 1: { //motion
if (p_points.size()) {
//send mouse, should look for point 0?
InputEvent ev;
ev.type=InputEvent::MOUSE_MOTION;
ev.ID=++last_id;
ev.mouse_motion.button_mask=BUTTON_MASK_LEFT;
ev.mouse_motion.x=p_points[0].pos.x;
ev.mouse_motion.y=p_points[0].pos.y;
input->set_mouse_pos(Point2(ev.mouse_motion.x,ev.mouse_motion.y));
ev.mouse_motion.speed_x=input->get_mouse_speed().x;
ev.mouse_motion.speed_y=input->get_mouse_speed().y;
ev.mouse_motion.relative_x=p_points[0].pos.x-last_mouse.x;
ev.mouse_motion.relative_y=p_points[0].pos.y-last_mouse.y;
last_mouse=p_points[0].pos;
main_loop->input_event(ev);
}
ERR_FAIL_COND(touch.size()!=p_points.size());
for(int i=0;i<touch.size();i++) {
int idx=-1;
for(int j=0;j<p_points.size();j++) {
if (touch[i].id==p_points[j].id) {
idx=j;
break;
}
}
ERR_CONTINUE(idx==-1);
if (touch[i].pos==p_points[idx].pos)
continue; //no move unncesearily
InputEvent ev;
ev.type=InputEvent::SCREEN_DRAG;
ev.ID=++last_id;
ev.screen_drag.index=touch[i].id;
ev.screen_drag.x=p_points[idx].pos.x;
ev.screen_drag.y=p_points[idx].pos.y;
ev.screen_drag.x=p_points[idx].pos.x - touch[i].pos.x;
ev.screen_drag.y=p_points[idx].pos.y - touch[i].pos.y;
main_loop->input_event(ev);
touch[i].pos=p_points[idx].pos;
}
} break;
case 2: { //release
if (touch.size()) {
//end all if exist
InputEvent ev;
ev.type=InputEvent::MOUSE_BUTTON;
ev.ID=++last_id;
ev.mouse_button.button_index=BUTTON_LEFT;
ev.mouse_button.button_mask=BUTTON_MASK_LEFT;
ev.mouse_button.pressed=false;
ev.mouse_button.x=touch[0].pos.x;
ev.mouse_button.y=touch[0].pos.y;
ev.mouse_button.global_x=touch[0].pos.x;
ev.mouse_button.global_y=touch[0].pos.y;
main_loop->input_event(ev);
for(int i=0;i<touch.size();i++) {
InputEvent ev;
ev.type=InputEvent::SCREEN_TOUCH;
ev.ID=++last_id;
ev.screen_touch.index=touch[i].id;
ev.screen_touch.pressed=false;
ev.screen_touch.x=touch[i].pos.x;
ev.screen_touch.y=touch[i].pos.y;
main_loop->input_event(ev);
}
}
} break;
case 3: { // add tuchi
ERR_FAIL_INDEX(p_pointer,p_points.size());
TouchPos tp=p_points[p_pointer];
touch.push_back(tp);
InputEvent ev;
ev.type=InputEvent::SCREEN_TOUCH;
ev.ID=++last_id;
ev.screen_touch.index=tp.id;
ev.screen_touch.pressed=true;
ev.screen_touch.x=tp.pos.x;
ev.screen_touch.y=tp.pos.y;
main_loop->input_event(ev);
} break;
case 4: {
for(int i=0;i<touch.size();i++) {
if (touch[i].id==p_pointer) {
InputEvent ev;
ev.type=InputEvent::SCREEN_TOUCH;
ev.ID=++last_id;
ev.screen_touch.index=touch[i].id;
ev.screen_touch.pressed=false;
ev.screen_touch.x=touch[i].pos.x;
ev.screen_touch.y=touch[i].pos.y;
main_loop->input_event(ev);
touch.remove(i);
i--;
}
}
} break;
}
}
OS_Android::OS_Android(int p_video_width,int p_video_height) {
default_videomode.width=p_video_width;
default_videomode.height=p_video_height;
default_videomode.fullscreen=true;
default_videomode.resizable=false;
main_loop=NULL;
last_id=1;
}
OS_Android::~OS_Android() {
}

View File

@@ -1,108 +0,0 @@
#ifndef OS_ANDROID_H
#define OS_ANDROID_H
#include "os/input.h"
#include "drivers/unix/os_unix.h"
#include "os/main_loop.h"
#include "servers/physics/physics_server_sw.h"
#include "servers/spatial_sound/spatial_sound_server_sw.h"
#include "servers/spatial_sound_2d/spatial_sound_2d_server_sw.h"
#include "servers/audio/audio_server_sw.h"
#include "servers/physics_2d/physics_2d_server_sw.h"
#include "servers/visual/rasterizer.h"
#include "audio_driver_android.h"
class OS_Android : public OS_Unix {
public:
struct TouchPos {
int id;
Point2 pos;
};
private:
Vector<TouchPos> touch;
Point2 last_mouse;
unsigned int last_id;
Rasterizer *rasterizer;
VisualServer *visual_server;
// AudioDriverPSP audio_driver_psp;
AudioServerSW *audio_server;
SampleManagerMallocSW *sample_manager;
SpatialSoundServerSW *spatial_sound_server;
SpatialSound2DServerSW *spatial_sound_2d_server;
PhysicsServer *physics_server;
Physics2DServer *physics_2d_server;
AudioDriverAndroid audio_driver_android;
InputDefault *input;
VideoMode default_videomode;
MainLoop * main_loop;
public:
void initialize_core();
// functions used by main to initialize/deintialize the OS
virtual int get_video_driver_count() const;
virtual const char * get_video_driver_name(int p_driver) const;
virtual VideoMode get_default_video_mode() const;
virtual int get_audio_driver_count() const;
virtual const char * get_audio_driver_name(int p_driver) const;
virtual void initialize(const VideoMode& p_desired,int p_video_driver,int p_audio_driver);
virtual void set_main_loop( MainLoop * p_main_loop );
virtual void delete_main_loop();
virtual void finalize();
typedef int64_t ProcessID;
static OS* get_singleton();
virtual void vprint(const char* p_format, va_list p_list, bool p_stderr=false);
virtual void print(const char *p_format, ... );
virtual void alert(const String& p_alert);
virtual void set_mouse_show(bool p_show);
virtual void set_mouse_grab(bool p_grab);
virtual bool is_mouse_grab_enabled() const;
virtual Point2 get_mouse_pos() const;
virtual int get_mouse_button_state() const;
virtual void set_window_title(const String& p_title);
//virtual void set_clipboard(const String& p_text);
//virtual String get_clipboard() const;
virtual void set_screen_orientation(ScreenOrientation p_orientation);
virtual void set_video_mode(const VideoMode& p_video_mode,int p_screen=0);
virtual VideoMode get_video_mode(int p_screen=0) const;
virtual void get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen=0) const;
virtual String get_name();
virtual MainLoop *get_main_loop() const;
virtual bool can_draw() const;
virtual void set_cursor_shape(CursorShape p_shape);
void main_loop_begin();
bool main_loop_iterate();
void main_loop_end();
void process_touch(int p_what,int p_pointer, const Vector<TouchPos>& p_points);
OS_Android(int p_video_width,int p_video_height);
~OS_Android();
};
#endif

View File

@@ -1 +0,0 @@
#include <alloca.h>

View File

@@ -1,40 +0,0 @@
# com.android.godot
# for this, need to push gdbserver to device
# adb push [location]/gdbserver /data/local
# run
DEBUG_PORT=5039
GDB_PATH="$ANDROID_NDK_ROOT/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gdb"
#kill existing previous gdbserver if exists
adb shell killall gdbserver
run-as com.android.godot killall com.android.godot
run-as com.android.godot killall gdbserver
#get data dir of the app
adb pull /system/bin/app_process app_process
DATA_DIR=`adb shell run-as com.android.godot /system/bin/sh -c pwd | tr -d '\n\r'`
echo "DATA DIR IS $DATA_DIR"
#start app
adb shell am start -n com.android.godot/com.android.godot.Godot
#get the pid of the app
PID=`adb shell pidof com.android.godot | tr -d '\n\r'`
echo "PID IS: $PID hoho"
#launch gdbserver
DEBUG_SOCKET=debug-socket
#echo adb shell /data/local/gdbserver +debug-socket --attach $PID
adb shell run-as com.android.godot lib/gdbserver +$DEBUG_SOCKET --attach $PID &
sleep 2s
#adb shell /data/local/gdbserver localhost:$DEBUG_PORT --attach $PID &
#setup network connection
adb forward tcp:$DEBUG_PORT localfilesystem:$DATA_DIR/$DEBUG_SOCKET
cp gdb.setup.base gdb.setup
echo "target remote :$DEBUG_PORT" >> gdb.setup
#echo "file
$GDB_PATH -x gdb.setup

View File

@@ -37,7 +37,8 @@ def get_flags():
('tools', 'no'),
('nedmalloc', 'no'),
('builtin_zlib', 'no'),
]
('openssl','builtin'), #use builtin openssl
]
def create(env):

View File

@@ -181,7 +181,11 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
String package;
String name;
String icon;
String cmdline;
bool _signed;
bool apk_expansion;
String apk_expansion_salt;
String apk_expansion_pkey;
int orientation;
String release_keystore;
@@ -257,6 +261,8 @@ bool EditorExportPlatformAndroid::_set(const StringName& p_name, const Variant&
version_code=p_value;
else if (n=="version/name")
version_name=p_value;
else if (n=="command_line/extra_args")
cmdline=p_value;
else if (n=="package/unique_name")
package=p_value;
else if (n=="package/name")
@@ -279,6 +285,12 @@ bool EditorExportPlatformAndroid::_set(const StringName& p_name, const Variant&
release_keystore=p_value;
else if (n=="keystore/release_user")
release_username=p_value;
else if (n=="apk_expansion/enable")
apk_expansion=p_value;
else if (n=="apk_expansion/SALT")
apk_expansion_salt=p_value;
else if (n=="apk_expansion/public_key")
apk_expansion_pkey=p_value;
else if (n.begins_with("permissions/")) {
String what = n.get_slice("/",1).to_upper();
@@ -307,6 +319,8 @@ bool EditorExportPlatformAndroid::_get(const StringName& p_name,Variant &r_ret)
r_ret=version_code;
else if (n=="version/name")
r_ret=version_name;
else if (n=="command_line/extra_args")
r_ret=cmdline;
else if (n=="package/unique_name")
r_ret=package;
else if (n=="package/name")
@@ -329,6 +343,12 @@ bool EditorExportPlatformAndroid::_get(const StringName& p_name,Variant &r_ret)
r_ret=release_keystore;
else if (n=="keystore/release_user")
r_ret=release_username;
else if (n=="apk_expansion/enable")
r_ret=apk_expansion;
else if (n=="apk_expansion/SALT")
r_ret=apk_expansion_salt;
else if (n=="apk_expansion/public_key")
r_ret=apk_expansion_pkey;
else if (n.begins_with("permissions/")) {
String what = n.get_slice("/",1).to_upper();
@@ -348,6 +368,7 @@ void EditorExportPlatformAndroid::_get_property_list( List<PropertyInfo> *p_list
p_list->push_back( PropertyInfo( Variant::STRING, "custom_package/debug", PROPERTY_HINT_FILE,"apk"));
p_list->push_back( PropertyInfo( Variant::STRING, "custom_package/release", PROPERTY_HINT_FILE,"apk"));
p_list->push_back( PropertyInfo( Variant::STRING, "command_line/extra_args"));
p_list->push_back( PropertyInfo( Variant::INT, "version/code", PROPERTY_HINT_RANGE,"1,65535,1"));
p_list->push_back( PropertyInfo( Variant::STRING, "version/name") );
p_list->push_back( PropertyInfo( Variant::STRING, "package/unique_name") );
@@ -361,6 +382,9 @@ void EditorExportPlatformAndroid::_get_property_list( List<PropertyInfo> *p_list
p_list->push_back( PropertyInfo( Variant::BOOL, "screen/support_xlarge") );
p_list->push_back( PropertyInfo( Variant::STRING, "keystore/release",PROPERTY_HINT_FILE,"keystore") );
p_list->push_back( PropertyInfo( Variant::STRING, "keystore/release_user" ) );
p_list->push_back( PropertyInfo( Variant::BOOL, "apk_expansion/enable" ) );
p_list->push_back( PropertyInfo( Variant::STRING, "apk_expansion/SALT" ) );
p_list->push_back( PropertyInfo( Variant::STRING, "apk_expansion/pubic_key" ) );
const char **perms = android_perms;
while(*perms) {
@@ -1065,13 +1089,65 @@ Error EditorExportPlatformAndroid::export_project(const String& p_path,bool p_de
ep.step("Adding Files..",1);
Error err=OK;
Vector<String> cl = cmdline.strip_edges().split(" ");
if (apk_expansion) {
String apkfname="main."+itos(version_code)+"."+package+".obb";
String fullpath=p_path.get_base_dir().plus_file(apkfname);
FileAccess *pf = FileAccess::open(fullpath,FileAccess::WRITE);
if (!pf) {
EditorNode::add_io_error("Could not write expansion package file: "+apkfname);
return OK;
}
err = save_pack(pf);
memdelete(pf);
cl.push_back("-main_pack");
cl.push_back(apkfname);
cl.push_back("-main_pack_md5");
cl.push_back(FileAccess::get_md5(fullpath));
cl.push_back("-main_pack_cfg");
cl.push_back(apk_expansion_salt+","+apk_expansion_pkey);
APKExportData ed;
ed.ep=&ep;
ed.apk=apk;
} else {
Error err = export_project_files(save_apk_file,&ed,false);
APKExportData ed;
ed.ep=&ep;
ed.apk=apk;
err = export_project_files(save_apk_file,&ed,false);
}
if (cl.size()) {
//add comandline
Vector<uint8_t> clf;
clf.resize(4);
encode_uint32(cl.size(),&clf[0]);
for(int i=0;i<cl.size();i++) {
CharString txt = cl[i].utf8();
int base = clf.size();
clf.resize(base+4+txt.length());
encode_uint32(txt.length(),&clf[base]);
copymem(&clf[base+4],txt.ptr(),txt.length());
print_line(itos(i)+" param: "+cl[i]);
}
zipOpenNewFileInZip(apk,
"assets/_cl_",
NULL,
NULL,
0,
NULL,
0,
NULL,
Z_DEFLATED,
Z_DEFAULT_COMPRESSION);
zipWriteInFileInZip(apk,clf.ptr(),clf.size());
zipCloseFileInZip(apk);
}
zipClose(apk,NULL);
unzClose(pkg);
@@ -1400,6 +1476,7 @@ EditorExportPlatformAndroid::EditorExportPlatformAndroid() {
package="com.android.noname";
name="";
_signed=true;
apk_expansion=false;
device_lock = Mutex::create();
quit_request=false;
orientation=0;
@@ -1461,6 +1538,18 @@ bool EditorExportPlatformAndroid::can_export(String *r_error) const {
err+="Custom release package not found.\n";
}
if (apk_expansion) {
if (apk_expansion_salt=="") {
valid=false;
err+="Invalid SALT for apk expansion.\n";
}
if (apk_expansion_pkey=="") {
valid=false;
err+="Invalid public key for apk expansion.\n";
}
}
if (r_error)
*r_error=err;

View File

@@ -60,6 +60,7 @@ import java.io.IOException;
import android.provider.Settings.Secure;
import android.widget.FrameLayout;
import com.android.godot.input.*;
import java.io.InputStream;
public class Godot extends Activity implements SensorEventListener
@@ -177,6 +178,48 @@ public class Godot extends Activity implements SensorEventListener
return Godot._self;
}
private String[] getCommandLine() {
InputStream is;
try {
is = getAssets().open("/_cl_");
byte[] len = new byte[4];
int r = is.read(len);
if (r<4) {
System.out.printf("**ERROR** Wrong cmdline length.\n");
return new String[0];
}
int argc=((int)(len[3])<<24) | ((int)(len[2])<<16) | ((int)(len[1])<<8) | ((int)(len[0]));
String[] cmdline = new String[argc];
for(int i=0;i<argc;i++) {
r = is.read(len);
if (r<4) {
System.out.printf("**ERROR** Wrong cmdline param lenght.\n");
return new String[0];
}
int strlen=((int)(len[3])<<24) | ((int)(len[2])<<16) | ((int)(len[1])<<8) | ((int)(len[0]));
if (strlen>65535) {
System.out.printf("**ERROR** Wrong command len\n");
return new String[0];
}
byte[] arg = new byte[strlen];
r = is.read(arg);
if (r!=strlen) {
cmdline[i]=new String(arg,"UTF-8");
}
}
return cmdline;
} catch (Exception e) {
return new String[0];
}
}
@Override protected void onCreate(Bundle icicle) {
System.out.printf("** GODOT ACTIVITY CREATED HERE ***\n");
@@ -187,10 +230,13 @@ public class Godot extends Activity implements SensorEventListener
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());
GodotLib.initialize(this,io.needsReloadHooks(),getCommandLine());
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
@@ -198,6 +244,8 @@ public class Godot extends Activity implements SensorEventListener
result_callback = null;
mPaymentsManager = PaymentsManager.createManager(this).initService();
// instanceSingleton( new GodotFacebook(this) );

View File

@@ -44,7 +44,7 @@ public class GodotLib {
* @param height the current view height
*/
public static native void initialize(Godot p_instance,boolean need_reload_hook);
public static native void initialize(Godot p_instance,boolean need_reload_hook,String[] p_cmdline);
public static native void resize(int width, int height,boolean reload);
public static native void newcontext();
public static native void quit();

View File

@@ -660,7 +660,7 @@ static void _stop_video() {
env->CallVoidMethod(godot_io, _stopVideo);
}
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_initialize(JNIEnv * env, jobject obj, jobject activity,jboolean p_need_reload_hook, jobjectArray p_cmdline) {
__android_log_print(ANDROID_LOG_INFO,"godot","**INIT EVENT! - %p\n",env);
@@ -723,8 +723,8 @@ JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_initialize(JNIEnv * env,
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, _play_video, _is_video_playing, _pause_video, _stop_video);
os_android->set_need_reload_hooks(p_need_reload_hook);
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, _play_video, _is_video_playing, _pause_video, _stop_video);
os_android->set_need_reload_hooks(p_need_reload_hook);
char wd[500];
getcwd(wd,500);
@@ -734,13 +734,23 @@ JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_initialize(JNIEnv * env,
__android_log_print(ANDROID_LOG_INFO,"godot","**SETUP");
const char ** cmdline=NULL;
int cmdlen = env->GetArrayLength(p_cmdline);
cmdline = (const char**)malloc((env->GetArrayLength(p_cmdline)+1)*sizeof(const char*));
cmdline[cmdlen]=NULL;
for (int i=0; i<cmdlen; i++) {
jstring string = (jstring) env->GetObjectArrayElement(p_cmdline, i);
const char *rawString = env->GetStringUTFChars(string, 0);
cmdline[i]=rawString;
}
#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);
Error err = Main::setup("apk",cmdlen,(char**)cmdline,false);
#endif
if (err!=OK) {

View File

@@ -36,7 +36,7 @@
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_initialize(JNIEnv * env, jobject obj, jobject activity,jboolean p_need_reload_hook, jobjectArray p_cmdline);
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);