mirror of
https://github.com/godotengine/godot.git
synced 2026-01-05 06:11:29 +03:00
-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:
@@ -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])
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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() {
|
||||
|
||||
};
|
||||
|
||||
@@ -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
|
||||
@@ -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'])
|
||||
@@ -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();;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -1,3 +0,0 @@
|
||||
set solib-search-path .
|
||||
directory ../..
|
||||
file app_process
|
||||
@@ -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>
|
||||
@@ -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.
|
||||
|
||||
@@ -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>
|
||||
@@ -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
|
||||
Binary file not shown.
@@ -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
|
||||
@@ -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 |
@@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="godot">Godot</string>
|
||||
</resources>
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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>();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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.
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
@@ -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
|
||||
@@ -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() {
|
||||
|
||||
|
||||
}
|
||||
@@ -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
|
||||
@@ -1 +0,0 @@
|
||||
#include <alloca.h>
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -37,7 +37,8 @@ def get_flags():
|
||||
('tools', 'no'),
|
||||
('nedmalloc', 'no'),
|
||||
('builtin_zlib', 'no'),
|
||||
]
|
||||
('openssl','builtin'), #use builtin openssl
|
||||
]
|
||||
|
||||
|
||||
def create(env):
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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) );
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user