mirror of
https://github.com/godotengine/godot.git
synced 2026-01-06 10:11:57 +03:00
GODOT IS OPEN SOURCE
This commit is contained in:
22
platform/android/.old/SCsub
Normal file
22
platform/android/.old/SCsub
Normal file
@@ -0,0 +1,22 @@
|
||||
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])
|
||||
104
platform/android/.old/audio_driver_android.cpp
Normal file
104
platform/android/.old/audio_driver_android.cpp
Normal file
@@ -0,0 +1,104 @@
|
||||
#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;
|
||||
}
|
||||
|
||||
29
platform/android/.old/audio_driver_android.h
Normal file
29
platform/android/.old/audio_driver_android.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#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
|
||||
38
platform/android/.old/context_gl_android.cpp
Normal file
38
platform/android/.old/context_gl_android.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
#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() {
|
||||
|
||||
};
|
||||
|
||||
24
platform/android/.old/context_gl_android.h
Normal file
24
platform/android/.old/context_gl_android.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#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
|
||||
107
platform/android/.old/detect.py
Normal file
107
platform/android/.old/detect.py
Normal file
@@ -0,0 +1,107 @@
|
||||
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'])
|
||||
217
platform/android/.old/dir_access_jandroid.cpp
Normal file
217
platform/android/.old/dir_access_jandroid.cpp
Normal file
@@ -0,0 +1,217 @@
|
||||
#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();;
|
||||
}
|
||||
63
platform/android/.old/dir_access_jandroid.h
Normal file
63
platform/android/.old/dir_access_jandroid.h
Normal file
@@ -0,0 +1,63 @@
|
||||
#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
|
||||
204
platform/android/.old/file_access_jandroid.cpp
Normal file
204
platform/android/.old/file_access_jandroid.cpp
Normal file
@@ -0,0 +1,204 @@
|
||||
#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();
|
||||
}
|
||||
|
||||
|
||||
56
platform/android/.old/file_access_jandroid.h
Normal file
56
platform/android/.old/file_access_jandroid.h
Normal file
@@ -0,0 +1,56 @@
|
||||
#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
|
||||
3
platform/android/.old/gdb.setup.base
Normal file
3
platform/android/.old/gdb.setup.base
Normal file
@@ -0,0 +1,3 @@
|
||||
set solib-search-path .
|
||||
directory ../..
|
||||
file app_process
|
||||
22
platform/android/.old/java/AndroidManifest.xml
Normal file
22
platform/android/.old/java/AndroidManifest.xml
Normal file
@@ -0,0 +1,22 @@
|
||||
<?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>
|
||||
17
platform/android/.old/java/build.properties
Normal file
17
platform/android/.old/java/build.properties
Normal file
@@ -0,0 +1,17 @@
|
||||
# This file is used to override default values used by the Ant build system.
|
||||
#
|
||||
# This file must be checked in Version Control Systems, as it is
|
||||
# integral to the build system of your project.
|
||||
|
||||
# This file is only used by the Ant script.
|
||||
|
||||
# You can use this to override default values such as
|
||||
# 'source.dir' for the location of your java source folder and
|
||||
# 'out.dir' for the location of your output folder.
|
||||
|
||||
# You can also use it define how the release builds are signed by declaring
|
||||
# the following properties:
|
||||
# 'key.store' for the location of your keystore and
|
||||
# 'key.alias' for the name of the key to use.
|
||||
# The password will be asked during the build when you use the 'release' target.
|
||||
|
||||
79
platform/android/.old/java/build.xml
Normal file
79
platform/android/.old/java/build.xml
Normal file
@@ -0,0 +1,79 @@
|
||||
<?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>
|
||||
11
platform/android/.old/java/default.properties
Normal file
11
platform/android/.old/java/default.properties
Normal file
@@ -0,0 +1,11 @@
|
||||
# This file is automatically generated by Android Tools.
|
||||
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
||||
#
|
||||
# This file must be checked in Version Control Systems.
|
||||
#
|
||||
# To customize properties used by the Ant build system use,
|
||||
# "build.properties", and override values to adapt the script to your
|
||||
# project structure.
|
||||
|
||||
# Project target.
|
||||
target=android-8
|
||||
BIN
platform/android/.old/java/libs/armeabi/gdbserver
Executable file
BIN
platform/android/.old/java/libs/armeabi/gdbserver
Executable file
Binary file not shown.
10
platform/android/.old/java/local.properties
Normal file
10
platform/android/.old/java/local.properties
Normal file
@@ -0,0 +1,10 @@
|
||||
# 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
|
||||
36
platform/android/.old/java/proguard.cfg
Normal file
36
platform/android/.old/java/proguard.cfg
Normal file
@@ -0,0 +1,36 @@
|
||||
-optimizationpasses 5
|
||||
-dontusemixedcaseclassnames
|
||||
-dontskipnonpubliclibraryclasses
|
||||
-dontpreverify
|
||||
-verbose
|
||||
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
|
||||
|
||||
-keep public class * extends android.app.Activity
|
||||
-keep public class * extends android.app.Application
|
||||
-keep public class * extends android.app.Service
|
||||
-keep public class * extends android.content.BroadcastReceiver
|
||||
-keep public class * extends android.content.ContentProvider
|
||||
-keep public class * extends android.app.backup.BackupAgentHelper
|
||||
-keep public class * extends android.preference.Preference
|
||||
-keep public class com.android.vending.licensing.ILicensingService
|
||||
|
||||
-keepclasseswithmembernames class * {
|
||||
native <methods>;
|
||||
}
|
||||
|
||||
-keepclasseswithmembernames class * {
|
||||
public <init>(android.content.Context, android.util.AttributeSet);
|
||||
}
|
||||
|
||||
-keepclasseswithmembernames class * {
|
||||
public <init>(android.content.Context, android.util.AttributeSet, int);
|
||||
}
|
||||
|
||||
-keepclassmembers enum * {
|
||||
public static **[] values();
|
||||
public static ** valueOf(java.lang.String);
|
||||
}
|
||||
|
||||
-keep class * implements android.os.Parcelable {
|
||||
public static final android.os.Parcelable$Creator *;
|
||||
}
|
||||
BIN
platform/android/.old/java/res/drawable-hdpi/icon.png
Normal file
BIN
platform/android/.old/java/res/drawable-hdpi/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.0 KiB |
BIN
platform/android/.old/java/res/drawable-ldpi/icon.png
Normal file
BIN
platform/android/.old/java/res/drawable-ldpi/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
BIN
platform/android/.old/java/res/drawable-mdpi/icon.png
Normal file
BIN
platform/android/.old/java/res/drawable-mdpi/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.5 KiB |
4
platform/android/.old/java/res/values/strings.xml
Normal file
4
platform/android/.old/java/res/values/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="godot">Godot</string>
|
||||
</resources>
|
||||
85
platform/android/.old/java/src/com/android/godot/Godot.java
Normal file
85
platform/android/.old/java/src/com/android/godot/Godot.java
Normal file
@@ -0,0 +1,85 @@
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
277
platform/android/.old/java/src/com/android/godot/GodotIO.java
Normal file
277
platform/android/.old/java/src/com/android/godot/GodotIO.java
Normal file
@@ -0,0 +1,277 @@
|
||||
|
||||
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>();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
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);
|
||||
}
|
||||
319
platform/android/.old/java/src/com/android/godot/GodotView.java
Normal file
319
platform/android/.old/java/src/com/android/godot/GodotView.java
Normal file
@@ -0,0 +1,319 @@
|
||||
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.
|
||||
}
|
||||
}
|
||||
}
|
||||
181
platform/android/.old/java_glue.cpp
Normal file
181
platform/android/.old/java_glue.cpp
Normal file
@@ -0,0 +1,181 @@
|
||||
#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();
|
||||
16
platform/android/.old/java_glue.h
Normal file
16
platform/android/.old/java_glue.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#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
|
||||
426
platform/android/.old/os_android.cpp
Normal file
426
platform/android/.old/os_android.cpp
Normal file
@@ -0,0 +1,426 @@
|
||||
|
||||
#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;
|
||||
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;
|
||||
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() {
|
||||
|
||||
|
||||
}
|
||||
108
platform/android/.old/os_android.h
Normal file
108
platform/android/.old/os_android.h
Normal file
@@ -0,0 +1,108 @@
|
||||
#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
platform/android/.old/platform_config.h
Normal file
1
platform/android/.old/platform_config.h
Normal file
@@ -0,0 +1 @@
|
||||
#include <alloca.h>
|
||||
40
platform/android/.old/run_debug.sh
Executable file
40
platform/android/.old/run_debug.sh
Executable file
@@ -0,0 +1,40 @@
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
|
||||
|
||||
40
platform/android/AndroidManifest.xml.template
Normal file
40
platform/android/AndroidManifest.xml.template
Normal file
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.godot.game"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0"
|
||||
android:installLocation="preferExternal"
|
||||
>
|
||||
<application android:label="@string/godot_project_name_string" android:icon="@drawable/icon">
|
||||
<activity android:name="com.android.godot.Godot"
|
||||
android:label="@string/godot_project_name_string"
|
||||
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
|
||||
android:launchMode="singleTask"
|
||||
android:screenOrientation="landscape"
|
||||
android:configChanges="orientation|keyboardHidden">
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
|
||||
|
||||
|
||||
$$ADD_APPLICATION_CHUNKS$$
|
||||
|
||||
</application>
|
||||
<uses-feature android:glEsVersion="0x00020000"/>
|
||||
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
|
||||
<uses-permission android:name="android.permission.READ_CONTACTS"/>
|
||||
<uses-permission android:name="com.android.vending.BILLING" />
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
|
||||
|
||||
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="11"/>
|
||||
|
||||
</manifest>
|
||||
66
platform/android/SCsub
Normal file
66
platform/android/SCsub
Normal file
@@ -0,0 +1,66 @@
|
||||
import shutil
|
||||
|
||||
Import('env')
|
||||
|
||||
android_files = [
|
||||
|
||||
'os_android.cpp',
|
||||
'godot_android.cpp',
|
||||
'file_access_android.cpp',
|
||||
'dir_access_android.cpp',
|
||||
'audio_driver_android.cpp',
|
||||
'file_access_jandroid.cpp',
|
||||
'dir_access_jandroid.cpp',
|
||||
'thread_jandroid.cpp',
|
||||
'audio_driver_jandroid.cpp',
|
||||
'android_native_app_glue.c',
|
||||
'java_glue.cpp'
|
||||
]
|
||||
|
||||
#env.Depends('#core/math/vector3.h', 'vector3_psp.h')
|
||||
|
||||
#obj = env.SharedObject('godot_android.cpp')
|
||||
|
||||
env_android = env.Clone()
|
||||
if env['target'] == "profile":
|
||||
env_android.Append(CPPFLAGS=['-DPROFILER_ENABLED'])
|
||||
|
||||
android_objects=[]
|
||||
for x in android_files:
|
||||
android_objects.append( env_android.SharedObject( x ) )
|
||||
|
||||
prog = None
|
||||
|
||||
abspath=env.Dir(".").abspath
|
||||
|
||||
|
||||
pp_basein = open(abspath+"/project.properties.template","rb")
|
||||
pp_baseout = open(abspath+"/java/project.properties","wb")
|
||||
pp_baseout.write( pp_basein.read() )
|
||||
refcount=1
|
||||
for x in env.android_source_modules:
|
||||
pp_baseout.write("android.library.reference."+str(refcount)+"="+x+"\n")
|
||||
refcount+=1
|
||||
|
||||
|
||||
|
||||
pp_baseout.close()
|
||||
|
||||
|
||||
pp_basein = open(abspath+"/AndroidManifest.xml.template","rb")
|
||||
pp_baseout = open(abspath+"/java/AndroidManifest.xml","wb")
|
||||
manifest = pp_basein.read()
|
||||
manifest = manifest.replace("$$ADD_APPLICATION_CHUNKS$$",env.android_manifest_chunk)
|
||||
pp_baseout.write( manifest )
|
||||
|
||||
|
||||
for x in env.android_source_files:
|
||||
shutil.copy(x,abspath+"/java/src/com/android/godot")
|
||||
|
||||
for x in env.android_module_libraries:
|
||||
shutil.copy(x,abspath+"/java/libs")
|
||||
|
||||
|
||||
env_android.SharedLibrary("#platform/android/libgodot_android.so",[android_objects])
|
||||
|
||||
env.Command('#bin/libgodot_android.so', '#platform/android/libgodot_android.so', Copy('bin/libgodot_android.so', 'platform/android/libgodot_android.so'))
|
||||
437
platform/android/android_native_app_glue.c
Normal file
437
platform/android/android_native_app_glue.c
Normal file
@@ -0,0 +1,437 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef ANDROID_NATIVE_ACTIVITY
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
#include "android_native_app_glue.h"
|
||||
#include <android/log.h>
|
||||
|
||||
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "threaded_app", __VA_ARGS__))
|
||||
|
||||
static void free_saved_state(struct android_app* android_app) {
|
||||
pthread_mutex_lock(&android_app->mutex);
|
||||
if (android_app->savedState != NULL) {
|
||||
free(android_app->savedState);
|
||||
android_app->savedState = NULL;
|
||||
android_app->savedStateSize = 0;
|
||||
}
|
||||
pthread_mutex_unlock(&android_app->mutex);
|
||||
}
|
||||
|
||||
int8_t android_app_read_cmd(struct android_app* android_app) {
|
||||
int8_t cmd;
|
||||
if (read(android_app->msgread, &cmd, sizeof(cmd)) == sizeof(cmd)) {
|
||||
switch (cmd) {
|
||||
case APP_CMD_SAVE_STATE:
|
||||
free_saved_state(android_app);
|
||||
break;
|
||||
}
|
||||
return cmd;
|
||||
} else {
|
||||
LOGI("No data on command pipe!");
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void print_cur_config(struct android_app* android_app) {
|
||||
char lang[2], country[2];
|
||||
AConfiguration_getLanguage(android_app->config, lang);
|
||||
AConfiguration_getCountry(android_app->config, country);
|
||||
|
||||
LOGI("Config: mcc=%d mnc=%d lang=%c%c cnt=%c%c orien=%d touch=%d dens=%d "
|
||||
"keys=%d nav=%d keysHid=%d navHid=%d sdk=%d size=%d long=%d "
|
||||
"modetype=%d modenight=%d",
|
||||
AConfiguration_getMcc(android_app->config),
|
||||
AConfiguration_getMnc(android_app->config),
|
||||
lang[0], lang[1], country[0], country[1],
|
||||
AConfiguration_getOrientation(android_app->config),
|
||||
AConfiguration_getTouchscreen(android_app->config),
|
||||
AConfiguration_getDensity(android_app->config),
|
||||
AConfiguration_getKeyboard(android_app->config),
|
||||
AConfiguration_getNavigation(android_app->config),
|
||||
AConfiguration_getKeysHidden(android_app->config),
|
||||
AConfiguration_getNavHidden(android_app->config),
|
||||
AConfiguration_getSdkVersion(android_app->config),
|
||||
AConfiguration_getScreenSize(android_app->config),
|
||||
AConfiguration_getScreenLong(android_app->config),
|
||||
AConfiguration_getUiModeType(android_app->config),
|
||||
AConfiguration_getUiModeNight(android_app->config));
|
||||
}
|
||||
|
||||
void android_app_pre_exec_cmd(struct android_app* android_app, int8_t cmd) {
|
||||
switch (cmd) {
|
||||
case APP_CMD_INPUT_CHANGED:
|
||||
LOGI("APP_CMD_INPUT_CHANGED\n");
|
||||
pthread_mutex_lock(&android_app->mutex);
|
||||
if (android_app->inputQueue != NULL) {
|
||||
AInputQueue_detachLooper(android_app->inputQueue);
|
||||
}
|
||||
android_app->inputQueue = android_app->pendingInputQueue;
|
||||
if (android_app->inputQueue != NULL) {
|
||||
LOGI("Attaching input queue to looper");
|
||||
AInputQueue_attachLooper(android_app->inputQueue,
|
||||
android_app->looper, LOOPER_ID_INPUT, NULL,
|
||||
&android_app->inputPollSource);
|
||||
}
|
||||
pthread_cond_broadcast(&android_app->cond);
|
||||
pthread_mutex_unlock(&android_app->mutex);
|
||||
break;
|
||||
|
||||
case APP_CMD_INIT_WINDOW:
|
||||
LOGI("APP_CMD_INIT_WINDOW\n");
|
||||
pthread_mutex_lock(&android_app->mutex);
|
||||
android_app->window = android_app->pendingWindow;
|
||||
pthread_cond_broadcast(&android_app->cond);
|
||||
pthread_mutex_unlock(&android_app->mutex);
|
||||
break;
|
||||
|
||||
case APP_CMD_TERM_WINDOW:
|
||||
LOGI("APP_CMD_TERM_WINDOW\n");
|
||||
pthread_cond_broadcast(&android_app->cond);
|
||||
break;
|
||||
|
||||
case APP_CMD_RESUME:
|
||||
case APP_CMD_START:
|
||||
case APP_CMD_PAUSE:
|
||||
case APP_CMD_STOP:
|
||||
LOGI("activityState=%d\n", cmd);
|
||||
pthread_mutex_lock(&android_app->mutex);
|
||||
android_app->activityState = cmd;
|
||||
pthread_cond_broadcast(&android_app->cond);
|
||||
pthread_mutex_unlock(&android_app->mutex);
|
||||
break;
|
||||
|
||||
case APP_CMD_CONFIG_CHANGED:
|
||||
LOGI("APP_CMD_CONFIG_CHANGED\n");
|
||||
AConfiguration_fromAssetManager(android_app->config,
|
||||
android_app->activity->assetManager);
|
||||
print_cur_config(android_app);
|
||||
break;
|
||||
|
||||
case APP_CMD_DESTROY:
|
||||
LOGI("APP_CMD_DESTROY\n");
|
||||
android_app->destroyRequested = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void android_app_post_exec_cmd(struct android_app* android_app, int8_t cmd) {
|
||||
switch (cmd) {
|
||||
case APP_CMD_TERM_WINDOW:
|
||||
LOGI("APP_CMD_TERM_WINDOW\n");
|
||||
pthread_mutex_lock(&android_app->mutex);
|
||||
android_app->window = NULL;
|
||||
pthread_cond_broadcast(&android_app->cond);
|
||||
pthread_mutex_unlock(&android_app->mutex);
|
||||
break;
|
||||
|
||||
case APP_CMD_SAVE_STATE:
|
||||
LOGI("APP_CMD_SAVE_STATE\n");
|
||||
pthread_mutex_lock(&android_app->mutex);
|
||||
android_app->stateSaved = 1;
|
||||
pthread_cond_broadcast(&android_app->cond);
|
||||
pthread_mutex_unlock(&android_app->mutex);
|
||||
break;
|
||||
|
||||
case APP_CMD_RESUME:
|
||||
free_saved_state(android_app);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void app_dummy() {
|
||||
|
||||
}
|
||||
|
||||
static void android_app_destroy(struct android_app* android_app) {
|
||||
LOGI("android_app_destroy!");
|
||||
free_saved_state(android_app);
|
||||
pthread_mutex_lock(&android_app->mutex);
|
||||
if (android_app->inputQueue != NULL) {
|
||||
AInputQueue_detachLooper(android_app->inputQueue);
|
||||
}
|
||||
AConfiguration_delete(android_app->config);
|
||||
android_app->destroyed = 1;
|
||||
pthread_cond_broadcast(&android_app->cond);
|
||||
pthread_mutex_unlock(&android_app->mutex);
|
||||
// Can't touch android_app object after this.
|
||||
}
|
||||
|
||||
static void process_input(struct android_app* app, struct android_poll_source* source) {
|
||||
AInputEvent* event = NULL;
|
||||
if (AInputQueue_getEvent(app->inputQueue, &event) >= 0) {
|
||||
LOGI("New input event: type=%d\n", AInputEvent_getType(event));
|
||||
if (AInputQueue_preDispatchEvent(app->inputQueue, event)) {
|
||||
return;
|
||||
}
|
||||
int32_t handled = 0;
|
||||
if (app->onInputEvent != NULL) handled = app->onInputEvent(app, event);
|
||||
AInputQueue_finishEvent(app->inputQueue, event, handled);
|
||||
} else {
|
||||
LOGI("Failure reading next input event: %s\n", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
static void process_cmd(struct android_app* app, struct android_poll_source* source) {
|
||||
int8_t cmd = android_app_read_cmd(app);
|
||||
android_app_pre_exec_cmd(app, cmd);
|
||||
if (app->onAppCmd != NULL) app->onAppCmd(app, cmd);
|
||||
android_app_post_exec_cmd(app, cmd);
|
||||
}
|
||||
|
||||
static void* android_app_entry(void* param) {
|
||||
struct android_app* android_app = (struct android_app*)param;
|
||||
|
||||
android_app->config = AConfiguration_new();
|
||||
AConfiguration_fromAssetManager(android_app->config, android_app->activity->assetManager);
|
||||
|
||||
print_cur_config(android_app);
|
||||
|
||||
android_app->cmdPollSource.id = LOOPER_ID_MAIN;
|
||||
android_app->cmdPollSource.app = android_app;
|
||||
android_app->cmdPollSource.process = process_cmd;
|
||||
android_app->inputPollSource.id = LOOPER_ID_INPUT;
|
||||
android_app->inputPollSource.app = android_app;
|
||||
android_app->inputPollSource.process = process_input;
|
||||
|
||||
ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
|
||||
ALooper_addFd(looper, android_app->msgread, LOOPER_ID_MAIN, ALOOPER_EVENT_INPUT, NULL,
|
||||
&android_app->cmdPollSource);
|
||||
android_app->looper = looper;
|
||||
|
||||
pthread_mutex_lock(&android_app->mutex);
|
||||
android_app->running = 1;
|
||||
pthread_cond_broadcast(&android_app->cond);
|
||||
pthread_mutex_unlock(&android_app->mutex);
|
||||
|
||||
android_main(android_app);
|
||||
|
||||
android_app_destroy(android_app);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// Native activity interaction (called from main thread)
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
static struct android_app* android_app_create(ANativeActivity* activity,
|
||||
void* savedState, size_t savedStateSize) {
|
||||
struct android_app* android_app = (struct android_app*)malloc(sizeof(struct android_app));
|
||||
memset(android_app, 0, sizeof(struct android_app));
|
||||
android_app->activity = activity;
|
||||
|
||||
pthread_mutex_init(&android_app->mutex, NULL);
|
||||
pthread_cond_init(&android_app->cond, NULL);
|
||||
|
||||
if (savedState != NULL) {
|
||||
android_app->savedState = malloc(savedStateSize);
|
||||
android_app->savedStateSize = savedStateSize;
|
||||
memcpy(android_app->savedState, savedState, savedStateSize);
|
||||
}
|
||||
|
||||
int msgpipe[2];
|
||||
if (pipe(msgpipe)) {
|
||||
LOGI("could not create pipe: %s", strerror(errno));
|
||||
}
|
||||
android_app->msgread = msgpipe[0];
|
||||
android_app->msgwrite = msgpipe[1];
|
||||
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||
pthread_create(&android_app->thread, &attr, android_app_entry, android_app);
|
||||
|
||||
// Wait for thread to start.
|
||||
pthread_mutex_lock(&android_app->mutex);
|
||||
while (!android_app->running) {
|
||||
pthread_cond_wait(&android_app->cond, &android_app->mutex);
|
||||
}
|
||||
pthread_mutex_unlock(&android_app->mutex);
|
||||
|
||||
return android_app;
|
||||
}
|
||||
|
||||
static void android_app_write_cmd(struct android_app* android_app, int8_t cmd) {
|
||||
if (write(android_app->msgwrite, &cmd, sizeof(cmd)) != sizeof(cmd)) {
|
||||
LOGI("Failure writing android_app cmd: %s\n", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
static void android_app_set_input(struct android_app* android_app, AInputQueue* inputQueue) {
|
||||
pthread_mutex_lock(&android_app->mutex);
|
||||
android_app->pendingInputQueue = inputQueue;
|
||||
android_app_write_cmd(android_app, APP_CMD_INPUT_CHANGED);
|
||||
while (android_app->inputQueue != android_app->pendingInputQueue) {
|
||||
pthread_cond_wait(&android_app->cond, &android_app->mutex);
|
||||
}
|
||||
pthread_mutex_unlock(&android_app->mutex);
|
||||
}
|
||||
|
||||
static void android_app_set_window(struct android_app* android_app, ANativeWindow* window) {
|
||||
pthread_mutex_lock(&android_app->mutex);
|
||||
if (android_app->pendingWindow != NULL) {
|
||||
android_app_write_cmd(android_app, APP_CMD_TERM_WINDOW);
|
||||
}
|
||||
android_app->pendingWindow = window;
|
||||
if (window != NULL) {
|
||||
android_app_write_cmd(android_app, APP_CMD_INIT_WINDOW);
|
||||
}
|
||||
while (android_app->window != android_app->pendingWindow) {
|
||||
pthread_cond_wait(&android_app->cond, &android_app->mutex);
|
||||
}
|
||||
pthread_mutex_unlock(&android_app->mutex);
|
||||
}
|
||||
|
||||
static void android_app_set_activity_state(struct android_app* android_app, int8_t cmd) {
|
||||
pthread_mutex_lock(&android_app->mutex);
|
||||
android_app_write_cmd(android_app, cmd);
|
||||
while (android_app->activityState != cmd) {
|
||||
pthread_cond_wait(&android_app->cond, &android_app->mutex);
|
||||
}
|
||||
pthread_mutex_unlock(&android_app->mutex);
|
||||
}
|
||||
|
||||
static void android_app_free(struct android_app* android_app) {
|
||||
pthread_mutex_lock(&android_app->mutex);
|
||||
android_app_write_cmd(android_app, APP_CMD_DESTROY);
|
||||
while (!android_app->destroyed) {
|
||||
pthread_cond_wait(&android_app->cond, &android_app->mutex);
|
||||
}
|
||||
pthread_mutex_unlock(&android_app->mutex);
|
||||
|
||||
close(android_app->msgread);
|
||||
close(android_app->msgwrite);
|
||||
pthread_cond_destroy(&android_app->cond);
|
||||
pthread_mutex_destroy(&android_app->mutex);
|
||||
free(android_app);
|
||||
}
|
||||
|
||||
static void onDestroy(ANativeActivity* activity) {
|
||||
LOGI("Destroy: %p\n", activity);
|
||||
android_app_free((struct android_app*)activity->instance);
|
||||
}
|
||||
|
||||
static void onStart(ANativeActivity* activity) {
|
||||
LOGI("Start: %p\n", activity);
|
||||
android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_START);
|
||||
}
|
||||
|
||||
static void onResume(ANativeActivity* activity) {
|
||||
LOGI("Resume: %p\n", activity);
|
||||
android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_RESUME);
|
||||
}
|
||||
|
||||
static void* onSaveInstanceState(ANativeActivity* activity, size_t* outLen) {
|
||||
struct android_app* android_app = (struct android_app*)activity->instance;
|
||||
void* savedState = NULL;
|
||||
|
||||
LOGI("SaveInstanceState: %p\n", activity);
|
||||
pthread_mutex_lock(&android_app->mutex);
|
||||
android_app->stateSaved = 0;
|
||||
android_app_write_cmd(android_app, APP_CMD_SAVE_STATE);
|
||||
while (!android_app->stateSaved) {
|
||||
pthread_cond_wait(&android_app->cond, &android_app->mutex);
|
||||
}
|
||||
|
||||
if (android_app->savedState != NULL) {
|
||||
savedState = android_app->savedState;
|
||||
*outLen = android_app->savedStateSize;
|
||||
android_app->savedState = NULL;
|
||||
android_app->savedStateSize = 0;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&android_app->mutex);
|
||||
|
||||
return savedState;
|
||||
}
|
||||
|
||||
static void onPause(ANativeActivity* activity) {
|
||||
LOGI("Pause: %p\n", activity);
|
||||
android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_PAUSE);
|
||||
}
|
||||
|
||||
static void onStop(ANativeActivity* activity) {
|
||||
LOGI("Stop: %p\n", activity);
|
||||
android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_STOP);
|
||||
}
|
||||
|
||||
static void onConfigurationChanged(ANativeActivity* activity) {
|
||||
struct android_app* android_app = (struct android_app*)activity->instance;
|
||||
LOGI("ConfigurationChanged: %p\n", activity);
|
||||
android_app_write_cmd(android_app, APP_CMD_CONFIG_CHANGED);
|
||||
}
|
||||
|
||||
static void onLowMemory(ANativeActivity* activity) {
|
||||
struct android_app* android_app = (struct android_app*)activity->instance;
|
||||
LOGI("LowMemory: %p\n", activity);
|
||||
android_app_write_cmd(android_app, APP_CMD_LOW_MEMORY);
|
||||
}
|
||||
|
||||
static void onWindowFocusChanged(ANativeActivity* activity, int focused) {
|
||||
LOGI("WindowFocusChanged: %p -- %d\n", activity, focused);
|
||||
android_app_write_cmd((struct android_app*)activity->instance,
|
||||
focused ? APP_CMD_GAINED_FOCUS : APP_CMD_LOST_FOCUS);
|
||||
}
|
||||
|
||||
static void onNativeWindowCreated(ANativeActivity* activity, ANativeWindow* window) {
|
||||
LOGI("NativeWindowCreated: %p -- %p\n", activity, window);
|
||||
android_app_set_window((struct android_app*)activity->instance, window);
|
||||
}
|
||||
|
||||
static void onNativeWindowDestroyed(ANativeActivity* activity, ANativeWindow* window) {
|
||||
LOGI("NativeWindowDestroyed: %p -- %p\n", activity, window);
|
||||
android_app_set_window((struct android_app*)activity->instance, NULL);
|
||||
}
|
||||
|
||||
static void onInputQueueCreated(ANativeActivity* activity, AInputQueue* queue) {
|
||||
LOGI("InputQueueCreated: %p -- %p\n", activity, queue);
|
||||
android_app_set_input((struct android_app*)activity->instance, queue);
|
||||
}
|
||||
|
||||
static void onInputQueueDestroyed(ANativeActivity* activity, AInputQueue* queue) {
|
||||
LOGI("InputQueueDestroyed: %p -- %p\n", activity, queue);
|
||||
android_app_set_input((struct android_app*)activity->instance, NULL);
|
||||
}
|
||||
|
||||
void ANativeActivity_onCreate(ANativeActivity* activity,
|
||||
void* savedState, size_t savedStateSize) {
|
||||
LOGI("Creating: %p\n", activity);
|
||||
activity->callbacks->onDestroy = onDestroy;
|
||||
activity->callbacks->onStart = onStart;
|
||||
activity->callbacks->onResume = onResume;
|
||||
activity->callbacks->onSaveInstanceState = onSaveInstanceState;
|
||||
activity->callbacks->onPause = onPause;
|
||||
activity->callbacks->onStop = onStop;
|
||||
activity->callbacks->onConfigurationChanged = onConfigurationChanged;
|
||||
activity->callbacks->onLowMemory = onLowMemory;
|
||||
activity->callbacks->onWindowFocusChanged = onWindowFocusChanged;
|
||||
activity->callbacks->onNativeWindowCreated = onNativeWindowCreated;
|
||||
activity->callbacks->onNativeWindowDestroyed = onNativeWindowDestroyed;
|
||||
activity->callbacks->onInputQueueCreated = onInputQueueCreated;
|
||||
activity->callbacks->onInputQueueDestroyed = onInputQueueDestroyed;
|
||||
|
||||
activity->instance = android_app_create(activity, savedState, savedStateSize);
|
||||
}
|
||||
#endif
|
||||
378
platform/android/android_native_app_glue.h
Normal file
378
platform/android/android_native_app_glue.h
Normal file
@@ -0,0 +1,378 @@
|
||||
/*************************************************************************/
|
||||
/* android_native_app_glue.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _ANDROID_NATIVE_APP_GLUE_H
|
||||
#define _ANDROID_NATIVE_APP_GLUE_H
|
||||
#ifdef ANDROID_NATIVE_ACTIVITY
|
||||
|
||||
#include <poll.h>
|
||||
#include <pthread.h>
|
||||
#include <sched.h>
|
||||
|
||||
#include <android/configuration.h>
|
||||
#include <android/looper.h>
|
||||
#include <android/native_activity.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The native activity interface provided by <android/native_activity.h>
|
||||
* is based on a set of application-provided callbacks that will be called
|
||||
* by the Activity's main thread when certain events occur.
|
||||
*
|
||||
* This means that each one of this callbacks _should_ _not_ block, or they
|
||||
* risk having the system force-close the application. This programming
|
||||
* model is direct, lightweight, but constraining.
|
||||
*
|
||||
* The 'threaded_native_app' static library is used to provide a different
|
||||
* execution model where the application can implement its own main event
|
||||
* loop in a different thread instead. Here's how it works:
|
||||
*
|
||||
* 1/ The application must provide a function named "android_main()" that
|
||||
* will be called when the activity is created, in a new thread that is
|
||||
* distinct from the activity's main thread.
|
||||
*
|
||||
* 2/ android_main() receives a pointer to a valid "android_app" structure
|
||||
* that contains references to other important objects, e.g. the
|
||||
* ANativeActivity obejct instance the application is running in.
|
||||
*
|
||||
* 3/ the "android_app" object holds an ALooper instance that already
|
||||
* listens to two important things:
|
||||
*
|
||||
* - activity lifecycle events (e.g. "pause", "resume"). See APP_CMD_XXX
|
||||
* declarations below.
|
||||
*
|
||||
* - input events coming from the AInputQueue attached to the activity.
|
||||
*
|
||||
* Each of these correspond to an ALooper identifier returned by
|
||||
* ALooper_pollOnce with values of LOOPER_ID_MAIN and LOOPER_ID_INPUT,
|
||||
* respectively.
|
||||
*
|
||||
* Your application can use the same ALooper to listen to additional
|
||||
* file-descriptors. They can either be callback based, or with return
|
||||
* identifiers starting with LOOPER_ID_USER.
|
||||
*
|
||||
* 4/ Whenever you receive a LOOPER_ID_MAIN or LOOPER_ID_INPUT event,
|
||||
* the returned data will point to an android_poll_source structure. You
|
||||
* can call the process() function on it, and fill in android_app->onAppCmd
|
||||
* and android_app->onInputEvent to be called for your own processing
|
||||
* of the event.
|
||||
*
|
||||
* Alternatively, you can call the low-level functions to read and process
|
||||
* the data directly... look at the process_cmd() and process_input()
|
||||
* implementations in the glue to see how to do this.
|
||||
*
|
||||
* See the sample named "native-activity" that comes with the NDK with a
|
||||
* full usage example. Also look at the JavaDoc of NativeActivity.
|
||||
*/
|
||||
|
||||
struct android_app;
|
||||
|
||||
/**
|
||||
* Data associated with an ALooper fd that will be returned as the "outData"
|
||||
* when that source has data ready.
|
||||
*/
|
||||
struct android_poll_source {
|
||||
// The identifier of this source. May be LOOPER_ID_MAIN or
|
||||
// LOOPER_ID_INPUT.
|
||||
int32_t id;
|
||||
|
||||
// The android_app this ident is associated with.
|
||||
struct android_app* app;
|
||||
|
||||
// Function to call to perform the standard processing of data from
|
||||
// this source.
|
||||
void (*process)(struct android_app* app, struct android_poll_source* source);
|
||||
};
|
||||
|
||||
/**
|
||||
* This is the interface for the standard glue code of a threaded
|
||||
* application. In this model, the application's code is running
|
||||
* in its own thread separate from the main thread of the process.
|
||||
* It is not required that this thread be associated with the Java
|
||||
* VM, although it will need to be in order to make JNI calls any
|
||||
* Java objects.
|
||||
*/
|
||||
struct android_app {
|
||||
// The application can place a pointer to its own state object
|
||||
// here if it likes.
|
||||
void* userData;
|
||||
|
||||
// Fill this in with the function to process main app commands (APP_CMD_*)
|
||||
void (*onAppCmd)(struct android_app* app, int32_t cmd);
|
||||
|
||||
// Fill this in with the function to process input events. At this point
|
||||
// the event has already been pre-dispatched, and it will be finished upon
|
||||
// return. Return 1 if you have handled the event, 0 for any default
|
||||
// dispatching.
|
||||
int32_t (*onInputEvent)(struct android_app* app, AInputEvent* event);
|
||||
|
||||
// The ANativeActivity object instance that this app is running in.
|
||||
ANativeActivity* activity;
|
||||
|
||||
// The current configuration the app is running in.
|
||||
AConfiguration* config;
|
||||
|
||||
// This is the last instance's saved state, as provided at creation time.
|
||||
// It is NULL if there was no state. You can use this as you need; the
|
||||
// memory will remain around until you call android_app_exec_cmd() for
|
||||
// APP_CMD_RESUME, at which point it will be freed and savedState set to NULL.
|
||||
// These variables should only be changed when processing a APP_CMD_SAVE_STATE,
|
||||
// at which point they will be initialized to NULL and you can malloc your
|
||||
// state and place the information here. In that case the memory will be
|
||||
// freed for you later.
|
||||
void* savedState;
|
||||
size_t savedStateSize;
|
||||
|
||||
// The ALooper associated with the app's thread.
|
||||
ALooper* looper;
|
||||
|
||||
// When non-NULL, this is the input queue from which the app will
|
||||
// receive user input events.
|
||||
AInputQueue* inputQueue;
|
||||
|
||||
// When non-NULL, this is the window surface that the app can draw in.
|
||||
ANativeWindow* window;
|
||||
|
||||
// Current content rectangle of the window; this is the area where the
|
||||
// window's content should be placed to be seen by the user.
|
||||
ARect contentRect;
|
||||
|
||||
// Current state of the app's activity. May be either APP_CMD_START,
|
||||
// APP_CMD_RESUME, APP_CMD_PAUSE, or APP_CMD_STOP; see below.
|
||||
int activityState;
|
||||
|
||||
// This is non-zero when the application's NativeActivity is being
|
||||
// destroyed and waiting for the app thread to complete.
|
||||
int destroyRequested;
|
||||
|
||||
// -------------------------------------------------
|
||||
// Below are "private" implementation of the glue code.
|
||||
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t cond;
|
||||
|
||||
int msgread;
|
||||
int msgwrite;
|
||||
|
||||
pthread_t thread;
|
||||
|
||||
struct android_poll_source cmdPollSource;
|
||||
struct android_poll_source inputPollSource;
|
||||
|
||||
int running;
|
||||
int stateSaved;
|
||||
int destroyed;
|
||||
int redrawNeeded;
|
||||
AInputQueue* pendingInputQueue;
|
||||
ANativeWindow* pendingWindow;
|
||||
ARect pendingContentRect;
|
||||
};
|
||||
|
||||
enum {
|
||||
/**
|
||||
* Looper data ID of commands coming from the app's main thread, which
|
||||
* is returned as an identifier from ALooper_pollOnce(). The data for this
|
||||
* identifier is a pointer to an android_poll_source structure.
|
||||
* These can be retrieved and processed with android_app_read_cmd()
|
||||
* and android_app_exec_cmd().
|
||||
*/
|
||||
LOOPER_ID_MAIN = 1,
|
||||
|
||||
/**
|
||||
* Looper data ID of events coming from the AInputQueue of the
|
||||
* application's window, which is returned as an identifier from
|
||||
* ALooper_pollOnce(). The data for this identifier is a pointer to an
|
||||
* android_poll_source structure. These can be read via the inputQueue
|
||||
* object of android_app.
|
||||
*/
|
||||
LOOPER_ID_INPUT = 2,
|
||||
|
||||
/**
|
||||
* Start of user-defined ALooper identifiers.
|
||||
*/
|
||||
LOOPER_ID_USER = 3,
|
||||
};
|
||||
|
||||
enum {
|
||||
/**
|
||||
* Command from main thread: the AInputQueue has changed. Upon processing
|
||||
* this command, android_app->inputQueue will be updated to the new queue
|
||||
* (or NULL).
|
||||
*/
|
||||
APP_CMD_INPUT_CHANGED,
|
||||
|
||||
/**
|
||||
* Command from main thread: a new ANativeWindow is ready for use. Upon
|
||||
* receiving this command, android_app->window will contain the new window
|
||||
* surface.
|
||||
*/
|
||||
APP_CMD_INIT_WINDOW,
|
||||
|
||||
/**
|
||||
* Command from main thread: the existing ANativeWindow needs to be
|
||||
* terminated. Upon receiving this command, android_app->window still
|
||||
* contains the existing window; after calling android_app_exec_cmd
|
||||
* it will be set to NULL.
|
||||
*/
|
||||
APP_CMD_TERM_WINDOW,
|
||||
|
||||
/**
|
||||
* Command from main thread: the current ANativeWindow has been resized.
|
||||
* Please redraw with its new size.
|
||||
*/
|
||||
APP_CMD_WINDOW_RESIZED,
|
||||
|
||||
/**
|
||||
* Command from main thread: the system needs that the current ANativeWindow
|
||||
* be redrawn. You should redraw the window before handing this to
|
||||
* android_app_exec_cmd() in order to avoid transient drawing glitches.
|
||||
*/
|
||||
APP_CMD_WINDOW_REDRAW_NEEDED,
|
||||
|
||||
/**
|
||||
* Command from main thread: the content area of the window has changed,
|
||||
* such as from the soft input window being shown or hidden. You can
|
||||
* find the new content rect in android_app::contentRect.
|
||||
*/
|
||||
APP_CMD_CONTENT_RECT_CHANGED,
|
||||
|
||||
/**
|
||||
* Command from main thread: the app's activity window has gained
|
||||
* input focus.
|
||||
*/
|
||||
APP_CMD_GAINED_FOCUS,
|
||||
|
||||
/**
|
||||
* Command from main thread: the app's activity window has lost
|
||||
* input focus.
|
||||
*/
|
||||
APP_CMD_LOST_FOCUS,
|
||||
|
||||
/**
|
||||
* Command from main thread: the current device configuration has changed.
|
||||
*/
|
||||
APP_CMD_CONFIG_CHANGED,
|
||||
|
||||
/**
|
||||
* Command from main thread: the system is running low on memory.
|
||||
* Try to reduce your memory use.
|
||||
*/
|
||||
APP_CMD_LOW_MEMORY,
|
||||
|
||||
/**
|
||||
* Command from main thread: the app's activity has been started.
|
||||
*/
|
||||
APP_CMD_START,
|
||||
|
||||
/**
|
||||
* Command from main thread: the app's activity has been resumed.
|
||||
*/
|
||||
APP_CMD_RESUME,
|
||||
|
||||
/**
|
||||
* Command from main thread: the app should generate a new saved state
|
||||
* for itself, to restore from later if needed. If you have saved state,
|
||||
* allocate it with malloc and place it in android_app.savedState with
|
||||
* the size in android_app.savedStateSize. The will be freed for you
|
||||
* later.
|
||||
*/
|
||||
APP_CMD_SAVE_STATE,
|
||||
|
||||
/**
|
||||
* Command from main thread: the app's activity has been paused.
|
||||
*/
|
||||
APP_CMD_PAUSE,
|
||||
|
||||
/**
|
||||
* Command from main thread: the app's activity has been stopped.
|
||||
*/
|
||||
APP_CMD_STOP,
|
||||
|
||||
/**
|
||||
* Command from main thread: the app's activity is being destroyed,
|
||||
* and waiting for the app thread to clean up and exit before proceeding.
|
||||
*/
|
||||
APP_CMD_DESTROY,
|
||||
};
|
||||
|
||||
/**
|
||||
* Call when ALooper_pollAll() returns LOOPER_ID_MAIN, reading the next
|
||||
* app command message.
|
||||
*/
|
||||
int8_t android_app_read_cmd(struct android_app* android_app);
|
||||
|
||||
/**
|
||||
* Call with the command returned by android_app_read_cmd() to do the
|
||||
* initial pre-processing of the given command. You can perform your own
|
||||
* actions for the command after calling this function.
|
||||
*/
|
||||
void android_app_pre_exec_cmd(struct android_app* android_app, int8_t cmd);
|
||||
|
||||
/**
|
||||
* Call with the command returned by android_app_read_cmd() to do the
|
||||
* final post-processing of the given command. You must have done your own
|
||||
* actions for the command before calling this function.
|
||||
*/
|
||||
void android_app_post_exec_cmd(struct android_app* android_app, int8_t cmd);
|
||||
|
||||
/**
|
||||
* Dummy function you can call to ensure glue code isn't stripped.
|
||||
*/
|
||||
void app_dummy();
|
||||
|
||||
/**
|
||||
* This is the function that application code must implement, representing
|
||||
* the main entry to the app.
|
||||
*/
|
||||
extern void android_main(struct android_app* app);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ANDROID_NATIVE_APP_GLUE_H */
|
||||
#endif
|
||||
393
platform/android/audio_driver_android.cpp
Normal file
393
platform/android/audio_driver_android.cpp
Normal file
@@ -0,0 +1,393 @@
|
||||
/*************************************************************************/
|
||||
/* audio_driver_android.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include "audio_driver_android.h"
|
||||
#include <string.h>
|
||||
#ifdef ANDROID_NATIVE_ACTIVITY
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define MAX_NUMBER_INTERFACES 3
|
||||
#define MAX_NUMBER_OUTPUT_DEVICES 6
|
||||
|
||||
/* Structure for passing information to callback function */
|
||||
|
||||
|
||||
void AudioDriverAndroid::_buffer_callback(
|
||||
SLAndroidSimpleBufferQueueItf queueItf
|
||||
/* SLuint32 eventFlags,
|
||||
const void * pBuffer,
|
||||
SLuint32 bufferSize,
|
||||
SLuint32 dataUsed*/) {
|
||||
|
||||
|
||||
|
||||
if (mutex)
|
||||
mutex->lock();
|
||||
|
||||
audio_server_process(buffer_size,mixdown_buffer);
|
||||
|
||||
if (mutex)
|
||||
mutex->unlock();
|
||||
|
||||
|
||||
const int32_t* src_buff=mixdown_buffer;
|
||||
|
||||
int16_t *ptr = (int16_t*)buffers[last_free];
|
||||
last_free=(last_free+1)%BUFFER_COUNT;
|
||||
|
||||
for(int i=0;i<buffer_size*2;i++) {
|
||||
|
||||
ptr[i]=src_buff[i]>>16;
|
||||
}
|
||||
|
||||
(*queueItf)->Enqueue(queueItf, ptr, 4 * buffer_size);
|
||||
|
||||
|
||||
#if 0
|
||||
SLresult res;
|
||||
CallbackCntxt *pCntxt = (CallbackCntxt*)pContext;
|
||||
if(pCntxt->pData < (pCntxt->pDataBase + pCntxt->size))
|
||||
{
|
||||
res = (*queueItf)->Enqueue(queueItf, (void*) pCntxt->pData,
|
||||
2 * AUDIO_DATA_BUFFER_SIZE, SL_BOOLEAN_FALSE); /* Size given
|
||||
in bytes. */
|
||||
CheckErr(res);
|
||||
/* Increase data pointer by buffer size */
|
||||
pCntxt->pData += AUDIO_DATA_BUFFER_SIZE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void AudioDriverAndroid::_buffer_callbacks(
|
||||
SLAndroidSimpleBufferQueueItf queueItf,
|
||||
/*SLuint32 eventFlags,
|
||||
const void * pBuffer,
|
||||
SLuint32 bufferSize,
|
||||
SLuint32 dataUsed,*/
|
||||
void *pContext) {
|
||||
|
||||
|
||||
AudioDriverAndroid *ad = (AudioDriverAndroid*)pContext;
|
||||
|
||||
// ad->_buffer_callback(queueItf,eventFlags,pBuffer,bufferSize,dataUsed);
|
||||
ad->_buffer_callback(queueItf);
|
||||
|
||||
}
|
||||
|
||||
|
||||
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(){
|
||||
|
||||
SLresult
|
||||
res;
|
||||
SLEngineOption EngineOption[] = {
|
||||
(SLuint32) SL_ENGINEOPTION_THREADSAFE,
|
||||
(SLuint32) SL_BOOLEAN_TRUE
|
||||
|
||||
};
|
||||
res = slCreateEngine( &sl, 1, EngineOption, 0, NULL, NULL);
|
||||
if (res!=SL_RESULT_SUCCESS) {
|
||||
|
||||
ERR_EXPLAIN("Could not Initialize OpenSL");
|
||||
ERR_FAIL_V(ERR_INVALID_PARAMETER);
|
||||
}
|
||||
res = (*sl)->Realize(sl, SL_BOOLEAN_FALSE);
|
||||
if (res!=SL_RESULT_SUCCESS) {
|
||||
|
||||
ERR_EXPLAIN("Could not Realize OpenSL");
|
||||
ERR_FAIL_V(ERR_INVALID_PARAMETER);
|
||||
}
|
||||
|
||||
print_line("OpenSL Init OK!");
|
||||
|
||||
return OK;
|
||||
|
||||
}
|
||||
void AudioDriverAndroid::start(){
|
||||
|
||||
|
||||
mutex = Mutex::create();
|
||||
active=false;
|
||||
|
||||
|
||||
SLint32 numOutputs = 0;
|
||||
SLuint32 deviceID = 0;
|
||||
SLresult res;
|
||||
|
||||
|
||||
buffer_size = 1024;
|
||||
|
||||
for(int i=0;i<BUFFER_COUNT;i++) {
|
||||
|
||||
buffers[i]=memnew_arr( int16_t,buffer_size*2 );
|
||||
memset(buffers[i],0,buffer_size*4);
|
||||
}
|
||||
|
||||
mixdown_buffer = memnew_arr( int32_t,buffer_size* 2);
|
||||
|
||||
/* Callback context for the buffer queue callback function */
|
||||
|
||||
/* Get the SL Engine Interface which is implicit */
|
||||
res = (*sl)->GetInterface(sl, SL_IID_ENGINE, (void*)&EngineItf);
|
||||
|
||||
ERR_FAIL_COND( res !=SL_RESULT_SUCCESS );
|
||||
/* Initialize arrays required[] and iidArray[] */
|
||||
int i;
|
||||
SLboolean required[MAX_NUMBER_INTERFACES];
|
||||
SLInterfaceID iidArray[MAX_NUMBER_INTERFACES];
|
||||
|
||||
#if 0
|
||||
|
||||
for (i=0; i<MAX_NUMBER_INTERFACES; i++)
|
||||
{
|
||||
required[i] = SL_BOOLEAN_FALSE;
|
||||
iidArray[i] = SL_IID_NULL;
|
||||
}
|
||||
// Set arrays required[] and iidArray[] for VOLUME interface
|
||||
required[0] = SL_BOOLEAN_TRUE;
|
||||
iidArray[0] = SL_IID_VOLUME;
|
||||
|
||||
// Create Output Mix object to be used by player
|
||||
res = (*EngineItf)->CreateOutputMix(EngineItf, &OutputMix, 1,
|
||||
iidArray, required);
|
||||
#else
|
||||
|
||||
{
|
||||
const SLInterfaceID ids[1] = {SL_IID_ENVIRONMENTALREVERB};
|
||||
const SLboolean req[1] = {SL_BOOLEAN_FALSE};
|
||||
res = (*EngineItf)->CreateOutputMix(EngineItf, &OutputMix, 0,
|
||||
ids, req);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
ERR_FAIL_COND( res !=SL_RESULT_SUCCESS );
|
||||
// Realizing the Output Mix object in synchronous mode.
|
||||
res = (*OutputMix)->Realize(OutputMix, SL_BOOLEAN_FALSE);
|
||||
ERR_FAIL_COND( res !=SL_RESULT_SUCCESS );
|
||||
|
||||
SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, BUFFER_COUNT};
|
||||
// bufferQueue.locatorType = SL_DATALOCATOR_BUFFERQUEUE;
|
||||
// bufferQueue.numBuffers = BUFFER_COUNT; /* Four buffers in our buffer queue */
|
||||
/* Setup the format of the content in the buffer queue */
|
||||
pcm.formatType = SL_DATAFORMAT_PCM;
|
||||
pcm.numChannels = 2;
|
||||
pcm.samplesPerSec = SL_SAMPLINGRATE_44_1;
|
||||
pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16;
|
||||
pcm.containerSize = SL_PCMSAMPLEFORMAT_FIXED_16;
|
||||
pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
|
||||
#ifdef BIG_ENDIAN_ENABLED
|
||||
pcm.endianness = SL_BYTEORDER_BIGENDIAN;
|
||||
#else
|
||||
pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
|
||||
#endif
|
||||
audioSource.pFormat = (void *)&pcm;
|
||||
audioSource.pLocator = (void *)&loc_bufq;
|
||||
|
||||
|
||||
/* Setup the data sink structure */
|
||||
locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
|
||||
locator_outputmix.outputMix= OutputMix;
|
||||
audioSink.pLocator = (void *)&locator_outputmix;
|
||||
audioSink.pFormat = NULL;
|
||||
/* Initialize the context for Buffer queue callbacks */
|
||||
// cntxt.pDataBase = (void*)&pcmData;
|
||||
//cntxt.pData = cntxt.pDataBase;
|
||||
//cntxt.size = sizeof(pcmData);
|
||||
/* Set arrays required[] and iidArray[] for SEEK interface
|
||||
(PlayItf is implicit) */
|
||||
required[0] = SL_BOOLEAN_TRUE;
|
||||
iidArray[0] = SL_IID_BUFFERQUEUE;
|
||||
/* Create the music player */
|
||||
|
||||
{
|
||||
const SLInterfaceID ids[2] = {SL_IID_BUFFERQUEUE, SL_IID_EFFECTSEND};
|
||||
const SLboolean req[2] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
|
||||
|
||||
res = (*EngineItf)->CreateAudioPlayer(EngineItf, &player,
|
||||
&audioSource, &audioSink, 1, ids, req);
|
||||
ERR_FAIL_COND( res !=SL_RESULT_SUCCESS );
|
||||
}
|
||||
/* Realizing the player in synchronous mode. */
|
||||
res = (*player)->Realize(player, SL_BOOLEAN_FALSE);
|
||||
ERR_FAIL_COND( res !=SL_RESULT_SUCCESS );
|
||||
/* Get seek and play interfaces */
|
||||
res = (*player)->GetInterface(player, SL_IID_PLAY, (void*)&playItf);
|
||||
ERR_FAIL_COND( res !=SL_RESULT_SUCCESS );
|
||||
res = (*player)->GetInterface(player, SL_IID_BUFFERQUEUE,
|
||||
(void*)&bufferQueueItf);
|
||||
ERR_FAIL_COND( res !=SL_RESULT_SUCCESS );
|
||||
/* Setup to receive buffer queue event callbacks */
|
||||
res = (*bufferQueueItf)->RegisterCallback(bufferQueueItf,
|
||||
_buffer_callbacks, this);
|
||||
ERR_FAIL_COND( res !=SL_RESULT_SUCCESS );
|
||||
/* Before we start set volume to -3dB (-300mB) */
|
||||
#if 0
|
||||
res = (*OutputMix)->GetInterface(OutputMix, SL_IID_VOLUME,
|
||||
(void*)&volumeItf);
|
||||
ERR_FAIL_COND( res !=SL_RESULT_SUCCESS );
|
||||
/* Setup the data source structure for the buffer queue */
|
||||
|
||||
res = (*volumeItf)->SetVolumeLevel(volumeItf, -300);
|
||||
ERR_FAIL_COND( res !=SL_RESULT_SUCCESS );
|
||||
#endif
|
||||
last_free=0;
|
||||
#if 1
|
||||
//fill up buffers
|
||||
for(int i=0;i<BUFFER_COUNT;i++) {
|
||||
/* Enqueue a few buffers to get the ball rolling */
|
||||
res = (*bufferQueueItf)->Enqueue(bufferQueueItf, buffers[i],
|
||||
4 * buffer_size); /* Size given in */
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
res = (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_PLAYING);
|
||||
ERR_FAIL_COND( res !=SL_RESULT_SUCCESS );
|
||||
|
||||
#if 0
|
||||
res = (*bufferQueueItf)->GetState(bufferQueueItf, &state);
|
||||
ERR_FAIL_COND( res !=SL_RESULT_SUCCESS );
|
||||
while(state.count)
|
||||
{
|
||||
(*bufferQueueItf)->GetState(bufferQueueItf, &state);
|
||||
}
|
||||
/* Make sure player is stopped */
|
||||
res = (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_STOPPED);
|
||||
CheckErr(res);
|
||||
/* Destroy the player */
|
||||
(*player)->Destroy(player);
|
||||
/* Destroy Output Mix object */
|
||||
(*OutputMix)->Destroy(OutputMix);
|
||||
#endif
|
||||
|
||||
active=true;
|
||||
}
|
||||
int AudioDriverAndroid::get_mix_rate() const {
|
||||
|
||||
return 44100;
|
||||
}
|
||||
AudioDriverSW::OutputFormat AudioDriverAndroid::get_output_format() const{
|
||||
|
||||
return OUTPUT_STEREO;
|
||||
}
|
||||
void AudioDriverAndroid::lock(){
|
||||
|
||||
//if (active && mutex)
|
||||
// mutex->lock();
|
||||
|
||||
}
|
||||
void AudioDriverAndroid::unlock() {
|
||||
|
||||
//if (active && mutex)
|
||||
// mutex->unlock();
|
||||
|
||||
}
|
||||
void AudioDriverAndroid::finish(){
|
||||
|
||||
(*sl)->Destroy(sl);
|
||||
|
||||
}
|
||||
|
||||
|
||||
AudioDriverAndroid::AudioDriverAndroid()
|
||||
{
|
||||
s_ad=this;
|
||||
mutex=NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
105
platform/android/audio_driver_android.h
Normal file
105
platform/android/audio_driver_android.h
Normal file
@@ -0,0 +1,105 @@
|
||||
/*************************************************************************/
|
||||
/* audio_driver_android.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#ifndef AUDIO_DRIVER_ANDROID_H
|
||||
#define AUDIO_DRIVER_ANDROID_H
|
||||
|
||||
#ifdef ANDROID_NATIVE_ACTIVITY
|
||||
|
||||
#include "servers/audio/audio_server_sw.h"
|
||||
#include "os/mutex.h"
|
||||
#include <SLES/OpenSLES.h>
|
||||
#include "SLES/OpenSLES_Android.h"
|
||||
class AudioDriverAndroid : public AudioDriverSW {
|
||||
|
||||
bool active;
|
||||
Mutex *mutex;
|
||||
|
||||
enum {
|
||||
|
||||
BUFFER_COUNT=2
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
uint32_t buffer_size;
|
||||
int16_t *buffers[BUFFER_COUNT];
|
||||
int32_t *mixdown_buffer;
|
||||
int last_free;
|
||||
|
||||
|
||||
SLPlayItf playItf;
|
||||
SLObjectItf sl;
|
||||
SLEngineItf EngineItf;
|
||||
SLObjectItf OutputMix;
|
||||
SLVolumeItf volumeItf;
|
||||
SLObjectItf player;
|
||||
SLAndroidSimpleBufferQueueItf bufferQueueItf;
|
||||
SLDataSource audioSource;
|
||||
SLDataFormat_PCM pcm;
|
||||
SLDataSink audioSink;
|
||||
SLDataLocator_OutputMix locator_outputmix;
|
||||
SLBufferQueueState state;
|
||||
|
||||
static AudioDriverAndroid* s_ad;
|
||||
|
||||
void _buffer_callback(
|
||||
SLAndroidSimpleBufferQueueItf queueItf
|
||||
/* SLuint32 eventFlags,
|
||||
const void * pBuffer,
|
||||
SLuint32 bufferSize,
|
||||
SLuint32 dataUsed*/);
|
||||
|
||||
static void _buffer_callbacks(
|
||||
SLAndroidSimpleBufferQueueItf queueItf,
|
||||
/*SLuint32 eventFlags,
|
||||
const void * pBuffer,
|
||||
SLuint32 bufferSize,
|
||||
SLuint32 dataUsed,*/
|
||||
void *pContext);
|
||||
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
|
||||
#endif
|
||||
248
platform/android/audio_driver_jandroid.cpp
Normal file
248
platform/android/audio_driver_jandroid.cpp
Normal file
@@ -0,0 +1,248 @@
|
||||
/*************************************************************************/
|
||||
/* audio_driver_jandroid.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include "audio_driver_jandroid.h"
|
||||
#include "globals.h"
|
||||
#include "os/os.h"
|
||||
#include "thread_jandroid.h"
|
||||
#ifndef ANDROID_NATIVE_ACTIVITY
|
||||
|
||||
AudioDriverAndroid* AudioDriverAndroid::s_ad=NULL;
|
||||
|
||||
jobject AudioDriverAndroid::io;
|
||||
jmethodID AudioDriverAndroid::_init_audio;
|
||||
jmethodID AudioDriverAndroid::_write_buffer;
|
||||
jmethodID AudioDriverAndroid::_quit;
|
||||
jmethodID AudioDriverAndroid::_pause;
|
||||
bool AudioDriverAndroid::active=false;
|
||||
jclass AudioDriverAndroid::cls;
|
||||
int AudioDriverAndroid::audioBufferFrames=0;
|
||||
int AudioDriverAndroid::mix_rate=44100;
|
||||
bool AudioDriverAndroid::quit=false;
|
||||
jobject AudioDriverAndroid::audioBuffer = NULL;
|
||||
void* AudioDriverAndroid::audioBufferPinned = NULL;
|
||||
Mutex *AudioDriverAndroid::mutex=NULL;
|
||||
int32_t* AudioDriverAndroid::audioBuffer32=NULL;
|
||||
|
||||
|
||||
const char* AudioDriverAndroid::get_name() const {
|
||||
|
||||
return "Android";
|
||||
}
|
||||
|
||||
|
||||
Error AudioDriverAndroid::init(){
|
||||
|
||||
mutex = Mutex::create();
|
||||
/*
|
||||
// TODO: pass in/return a (Java) device ID, also whether we're opening for input or output
|
||||
this->spec.samples = Android_JNI_OpenAudioDevice(this->spec.freq, this->spec.format == AUDIO_U8 ? 0 : 1, this->spec.channels, this->spec.samples);
|
||||
SDL_CalculateAudioSpec(&this->spec);
|
||||
|
||||
if (this->spec.samples == 0) {
|
||||
// Init failed?
|
||||
SDL_SetError("Java-side initialization failed!");
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
// Android_JNI_SetupThread();
|
||||
|
||||
|
||||
// __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device");
|
||||
|
||||
|
||||
JNIEnv *env = ThreadAndroid::get_env();
|
||||
int mix_rate = GLOBAL_DEF("audio/mix_rate",44100);
|
||||
|
||||
int latency = GLOBAL_DEF("audio/output_latency",25);
|
||||
latency=50;
|
||||
unsigned int buffer_size = nearest_power_of_2( latency * mix_rate / 1000 );
|
||||
if (OS::get_singleton()->is_stdout_verbose()) {
|
||||
print_line("audio buffer size: "+itos(buffer_size));
|
||||
}
|
||||
|
||||
__android_log_print(ANDROID_LOG_INFO,"godot","Initializing audio! params: %i,%i ",mix_rate,buffer_size);
|
||||
audioBuffer = env->CallObjectMethod(io,_init_audio, mix_rate, buffer_size);
|
||||
|
||||
|
||||
ERR_FAIL_COND_V( audioBuffer == NULL, ERR_INVALID_PARAMETER);
|
||||
|
||||
audioBuffer = env->NewGlobalRef(audioBuffer);
|
||||
|
||||
jboolean isCopy = JNI_FALSE;
|
||||
audioBufferPinned = env->GetShortArrayElements((jshortArray)audioBuffer, &isCopy);
|
||||
audioBufferFrames = env->GetArrayLength((jshortArray)audioBuffer);
|
||||
audioBuffer32 = memnew_arr(int32_t,audioBufferFrames);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
void AudioDriverAndroid::start(){
|
||||
active=true;
|
||||
|
||||
}
|
||||
|
||||
void AudioDriverAndroid::setup( jobject p_io) {
|
||||
|
||||
JNIEnv *env = ThreadAndroid::get_env();
|
||||
io=p_io;
|
||||
|
||||
jclass c = env->GetObjectClass(io);
|
||||
cls = (jclass)env->NewGlobalRef(c);
|
||||
|
||||
|
||||
__android_log_print(ANDROID_LOG_INFO,"godot","starting to attempt get methods");
|
||||
|
||||
_init_audio = env->GetMethodID(cls, "audioInit", "(II)Ljava/lang/Object;");
|
||||
if(_init_audio != 0) {
|
||||
__android_log_print(ANDROID_LOG_INFO,"godot","*******GOT METHOD _init_audio ok!!");
|
||||
} else {
|
||||
__android_log_print(ANDROID_LOG_INFO,"godot","audioinit ok!");
|
||||
}
|
||||
|
||||
_write_buffer = env->GetMethodID(cls, "audioWriteShortBuffer", "([S)V");
|
||||
if(_write_buffer != 0) {
|
||||
__android_log_print(ANDROID_LOG_INFO,"godot","*******GOT METHOD _write_buffer ok!!");
|
||||
}
|
||||
|
||||
|
||||
_quit = env->GetMethodID(cls, "audioQuit", "()V");
|
||||
if(_quit != 0) {
|
||||
__android_log_print(ANDROID_LOG_INFO,"godot","*******GOT METHOD _quit ok!!");
|
||||
}
|
||||
|
||||
_pause = env->GetMethodID(cls, "audioPause", "(Z)V");
|
||||
if(_quit != 0) {
|
||||
__android_log_print(ANDROID_LOG_INFO,"godot","*******GOT METHOD _pause ok!!");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void AudioDriverAndroid::thread_func(JNIEnv *env) {
|
||||
|
||||
jclass cls = env->FindClass("com/android/godot/Godot");
|
||||
if (cls) {
|
||||
|
||||
cls=(jclass)env->NewGlobalRef(cls);
|
||||
__android_log_print(ANDROID_LOG_INFO,"godot","*******CLASS FOUND!!!");
|
||||
}
|
||||
jfieldID fid = env->GetStaticFieldID(cls, "io", "Lcom/android/godot/GodotIO;");
|
||||
jobject ob = env->GetStaticObjectField(cls,fid);
|
||||
jobject gob = env->NewGlobalRef(ob);
|
||||
jclass c = env->GetObjectClass(gob);
|
||||
jclass lcls = (jclass)env->NewGlobalRef(c);
|
||||
_write_buffer = env->GetMethodID(lcls, "audioWriteShortBuffer", "([S)V");
|
||||
if(_write_buffer != 0) {
|
||||
__android_log_print(ANDROID_LOG_INFO,"godot","*******GOT METHOD _write_buffer ok!!");
|
||||
}
|
||||
|
||||
while(!quit) {
|
||||
|
||||
|
||||
int16_t* ptr = (int16_t*)audioBufferPinned;
|
||||
int fc = audioBufferFrames;
|
||||
|
||||
if (!s_ad->active || mutex->try_lock()!=OK) {
|
||||
|
||||
for(int i=0;i<fc;i++) {
|
||||
ptr[i]=0;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
s_ad->audio_server_process(fc/2,audioBuffer32);
|
||||
|
||||
mutex->unlock();
|
||||
|
||||
for(int i=0;i<fc;i++) {
|
||||
|
||||
ptr[i]=audioBuffer32[i]>>16;
|
||||
}
|
||||
|
||||
}
|
||||
env->ReleaseShortArrayElements((jshortArray)audioBuffer, (jshort *)ptr, JNI_COMMIT);
|
||||
env->CallVoidMethod(gob, _write_buffer, (jshortArray)audioBuffer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
int AudioDriverAndroid::get_mix_rate() const {
|
||||
|
||||
return mix_rate;
|
||||
}
|
||||
AudioDriverSW::OutputFormat AudioDriverAndroid::get_output_format() const{
|
||||
|
||||
return OUTPUT_STEREO;
|
||||
}
|
||||
void AudioDriverAndroid::lock(){
|
||||
|
||||
if (mutex)
|
||||
mutex->lock();
|
||||
|
||||
}
|
||||
void AudioDriverAndroid::unlock() {
|
||||
|
||||
if (mutex)
|
||||
mutex->unlock();
|
||||
}
|
||||
void AudioDriverAndroid::finish(){
|
||||
|
||||
JNIEnv *env = ThreadAndroid::get_env();
|
||||
env->CallVoidMethod(io, _quit);
|
||||
|
||||
if (audioBuffer) {
|
||||
env->DeleteGlobalRef(audioBuffer);
|
||||
audioBuffer = NULL;
|
||||
audioBufferPinned = NULL;
|
||||
}
|
||||
|
||||
active=false;
|
||||
}
|
||||
|
||||
void AudioDriverAndroid::set_pause(bool p_pause) {
|
||||
|
||||
JNIEnv *env = ThreadAndroid::get_env();
|
||||
env->CallVoidMethod(io, _pause,p_pause);
|
||||
|
||||
}
|
||||
|
||||
AudioDriverAndroid::AudioDriverAndroid()
|
||||
{
|
||||
s_ad=this;
|
||||
active=false;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
82
platform/android/audio_driver_jandroid.h
Normal file
82
platform/android/audio_driver_jandroid.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/*************************************************************************/
|
||||
/* audio_driver_jandroid.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#ifndef AUDIO_DRIVER_ANDROID_H
|
||||
#define AUDIO_DRIVER_ANDROID_H
|
||||
|
||||
#include "servers/audio/audio_server_sw.h"
|
||||
#ifndef ANDROID_NATIVE_ACTIVITY
|
||||
|
||||
#include "java_glue.h"
|
||||
|
||||
class AudioDriverAndroid : public AudioDriverSW {
|
||||
|
||||
|
||||
static Mutex *mutex;
|
||||
static AudioDriverAndroid* s_ad;
|
||||
static jobject io;
|
||||
static jmethodID _init_audio;
|
||||
static jmethodID _write_buffer;
|
||||
static jmethodID _quit;
|
||||
static jmethodID _pause;
|
||||
static bool active;
|
||||
static bool quit;
|
||||
|
||||
static jclass cls;
|
||||
|
||||
static jobject audioBuffer;
|
||||
static void* audioBufferPinned;
|
||||
static int32_t* audioBuffer32;
|
||||
static int audioBufferFrames;
|
||||
static int mix_rate;
|
||||
|
||||
|
||||
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();
|
||||
|
||||
virtual void set_pause(bool p_pause);
|
||||
|
||||
static void setup( jobject act);
|
||||
static void thread_func(JNIEnv *env);
|
||||
|
||||
AudioDriverAndroid();
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // AUDIO_DRIVER_ANDROID_H
|
||||
175
platform/android/detect.py
Normal file
175
platform/android/detect.py
Normal file
@@ -0,0 +1,175 @@
|
||||
import os
|
||||
import sys
|
||||
import string
|
||||
import platform
|
||||
|
||||
def is_active():
|
||||
return True
|
||||
|
||||
def get_name():
|
||||
return "Android"
|
||||
|
||||
def can_build():
|
||||
|
||||
import os
|
||||
if (not os.environ.has_key("ANDROID_NDK_ROOT")):
|
||||
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.3
|
||||
('ndk_platform', 'compile for platform: (2.2,2.3)',"2.2"),
|
||||
('NDK_TARGET', 'toolchain to use for the NDK',"arm-linux-androideabi-4.7"),
|
||||
('android_stl','enable STL support in android port (for modules)','no'),
|
||||
('armv6','compile for older phones running arm v6 (instead of v7+neon+smp)','no')
|
||||
|
||||
]
|
||||
|
||||
def get_flags():
|
||||
|
||||
return [
|
||||
('lua', 'no'),
|
||||
('tools', 'no'),
|
||||
('nedmalloc', 'no'),
|
||||
('builtin_zlib', 'no'),
|
||||
]
|
||||
|
||||
|
||||
def create(env):
|
||||
tools = env['TOOLS']
|
||||
if "mingw" in tools:
|
||||
tools.remove('mingw')
|
||||
if "applelink" in tools:
|
||||
tools.remove("applelink")
|
||||
env.Tool('gcc')
|
||||
return env.Clone(tools=tools);
|
||||
|
||||
def configure(env):
|
||||
|
||||
if env['PLATFORM'] == 'win32':
|
||||
import methods
|
||||
env.Tool('gcc')
|
||||
env['SPAWN'] = methods.win32_spawn
|
||||
|
||||
ndk_platform=""
|
||||
|
||||
if (env["ndk_platform"]=="2.2"):
|
||||
ndk_platform="android-8"
|
||||
else:
|
||||
ndk_platform="android-9"
|
||||
env.Append(CPPFLAGS=["-DANDROID_NATIVE_ACTIVITY"])
|
||||
|
||||
print("Godot Android!!!!!")
|
||||
|
||||
env.Append(CPPPATH=['#platform/android'])
|
||||
|
||||
env['OBJSUFFIX'] = ".android.o"
|
||||
env['LIBSUFFIX'] = ".android.a"
|
||||
env['PROGSUFFIX'] = ".android"
|
||||
env['SHLIBSUFFIX'] = ".so"
|
||||
|
||||
gcc_path=env["ANDROID_NDK_ROOT"]+"/toolchains/"+env["NDK_TARGET"]+"/prebuilt/";
|
||||
|
||||
import os
|
||||
if (sys.platform.find("linux")==0):
|
||||
if (platform.architecture()[0]=='64bit' or os.path.isdir(gcc_path+"linux-x86_64/bin")): # check was not working
|
||||
gcc_path=gcc_path+"/linux-x86_64/bin"
|
||||
else:
|
||||
gcc_path=gcc_path+"/linux-x86/bin"
|
||||
elif (sys.platform=="darwin"):
|
||||
gcc_path=gcc_path+"/darwin-x86_64/bin" #this may be wrong
|
||||
env['SHLINKFLAGS'][1] = '-shared'
|
||||
elif (os.name=="nt"):
|
||||
gcc_path=gcc_path+"/windows/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"
|
||||
env['RANLIB'] = gcc_path+"/arm-linux-androideabi-ranlib"
|
||||
env['AS'] = gcc_path+"/arm-linux-androideabi-as"
|
||||
|
||||
import string
|
||||
#include path
|
||||
gcc_include=env["ANDROID_NDK_ROOT"]+"/platforms/"+ndk_platform+"/arch-arm/usr/include"
|
||||
ld_sysroot=env["ANDROID_NDK_ROOT"]+"/platforms/"+ndk_platform+"/arch-arm"
|
||||
#glue_include=env["ANDROID_NDK_ROOT"]+"/sources/android/native_app_glue"
|
||||
ld_path=env["ANDROID_NDK_ROOT"]+"/platforms/"+ndk_platform+"/arch-arm/usr/lib"
|
||||
env.Append(CPPPATH=[gcc_include])
|
||||
# env['CCFLAGS'] = string.split('-DNO_THREADS -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 ')
|
||||
print("********* armv6", env['armv6'])
|
||||
if env["armv6"]!="no":
|
||||
env['CCFLAGS'] = string.split('-DNO_STATVFS -MMD -MP -MF -fpic -ffunction-sections -funwind-tables -fstack-protector -D__ARM_ARCH_6__ -D__GLIBC__ -Wno-psabi -march=armv6 -mfpu=vfp -mfloat-abi=softfp -funsafe-math-optimizations -fno-strict-aliasing -DANDROID -Wa,--noexecstack -DGLES2_ENABLED -DGLES1_ENABLED')
|
||||
else:
|
||||
env['CCFLAGS'] = string.split('-DNO_STATVFS -MMD -MP -MF -fpic -ffunction-sections -funwind-tables -fstack-protector -D__ARM_ARCH_7__ -D__GLIBC__ -Wno-psabi -march=armv6 -mfpu=neon -mfloat-abi=softfp -ftree-vectorize -funsafe-math-optimizations -fno-strict-aliasing -DANDROID -Wa,--noexecstack -DGLES2_ENABLED -DGLES1_ENABLED')
|
||||
|
||||
env.Append(LDPATH=[ld_path])
|
||||
# env.Append(LIBS=['c','m','stdc++','log','EGL','GLESv1_CM','GLESv2','OpenSLES','supc++','android'])
|
||||
if (env["ndk_platform"]!="2.2"):
|
||||
env.Append(LIBS=['EGL','OpenSLES','android'])
|
||||
env.Append(LIBS=['c','m','stdc++','log','GLESv1_CM','GLESv2', 'z'])
|
||||
|
||||
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"]=="release_debug"):
|
||||
|
||||
env.Append(CCFLAGS=['-O2', '-ffast-math','-DDEBUG_ENABLED'])
|
||||
env['OBJSUFFIX'] = "_optd"+env['OBJSUFFIX']
|
||||
env['LIBSUFFIX'] = "_optd"+env['LIBSUFFIX']
|
||||
|
||||
elif (env["target"]=="profile"):
|
||||
|
||||
env.Append(CCFLAGS=['-O2', '-ffast-math','-fomit-frame-pointer', '-g1'])
|
||||
env.Append(LIBPATH=['#platform/android/armeabi'])
|
||||
env.Append(LIBS=['andprof'])
|
||||
env['OBJSUFFIX'] = "_prof"+env['OBJSUFFIX']
|
||||
env['LIBSUFFIX'] = "_prof"+env['LIBSUFFIX']
|
||||
env['SHLIBSUFFIX'] = "_prof"+env['SHLIBSUFFIX']
|
||||
|
||||
elif (env["target"]=="debug"):
|
||||
|
||||
env.Append(CCFLAGS=['-D_DEBUG', '-g1', '-Wall', '-O0', '-DDEBUG_ENABLED'])
|
||||
env.Append(CPPFLAGS=['-DDEBUG_MEMORY_ALLOC'])
|
||||
|
||||
if env["armv6"] == "no":
|
||||
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(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cpufeatures"])
|
||||
|
||||
#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'])
|
||||
|
||||
import methods
|
||||
env.Append( BUILDERS = { 'GLSL120' : env.Builder(action = methods.build_legacygl_headers, suffix = 'glsl.h',src_suffix = '.glsl') } )
|
||||
env.Append( BUILDERS = { 'GLSL' : env.Builder(action = methods.build_glsl_headers, suffix = 'glsl.h',src_suffix = '.glsl') } )
|
||||
env.Append( BUILDERS = { 'GLSL120GLES' : env.Builder(action = methods.build_gles2_headers, suffix = 'glsl.h',src_suffix = '.glsl') } )
|
||||
|
||||
189
platform/android/dir_access_android.cpp
Normal file
189
platform/android/dir_access_android.cpp
Normal file
@@ -0,0 +1,189 @@
|
||||
/*************************************************************************/
|
||||
/* dir_access_android.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#ifdef ANDROID_NATIVE_ACTIVITY
|
||||
#include "dir_access_android.h"
|
||||
#include "file_access_android.h"
|
||||
|
||||
|
||||
|
||||
DirAccess *DirAccessAndroid::create_fs() {
|
||||
|
||||
return memnew(DirAccessAndroid);
|
||||
}
|
||||
|
||||
bool DirAccessAndroid::list_dir_begin() {
|
||||
|
||||
list_dir_end();
|
||||
|
||||
AAssetDir* aad = AAssetManager_openDir(FileAccessAndroid::asset_manager,current_dir.utf8().get_data());
|
||||
if (!aad)
|
||||
return true; //nothing
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
String DirAccessAndroid::get_next(){
|
||||
|
||||
const char* fn= AAssetDir_getNextFileName(aad);
|
||||
if (!fn)
|
||||
return "";
|
||||
String s;
|
||||
s.parse_utf8(fn);
|
||||
current=s;
|
||||
return s;
|
||||
|
||||
|
||||
}
|
||||
bool DirAccessAndroid::current_is_dir() const{
|
||||
|
||||
String sd;
|
||||
if (current_dir=="")
|
||||
sd=current;
|
||||
else
|
||||
sd=current_dir+"/"+current;
|
||||
|
||||
AAssetDir* aad2 = AAssetManager_openDir(FileAccessAndroid::asset_manager,sd.utf8().get_data());
|
||||
if (aad2) {
|
||||
|
||||
AAssetDir_close(aad2);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
void DirAccessAndroid::list_dir_end(){
|
||||
|
||||
if (aad==NULL)
|
||||
return;
|
||||
|
||||
AAssetDir_close(aad);
|
||||
aad=NULL;
|
||||
|
||||
}
|
||||
|
||||
int DirAccessAndroid::get_drive_count(){
|
||||
|
||||
return 0;
|
||||
}
|
||||
String DirAccessAndroid::get_drive(int p_drive){
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
Error DirAccessAndroid::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();
|
||||
|
||||
AAssetDir* aad = AAssetManager_openDir(FileAccessAndroid::asset_manager,new_dir.utf8().get_data());
|
||||
if (aad) {
|
||||
|
||||
current_dir=new_dir;
|
||||
AAssetDir_close(aad);
|
||||
return OK;
|
||||
}
|
||||
|
||||
return ERR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
String DirAccessAndroid::get_current_dir(){
|
||||
|
||||
return "/"+current_dir;
|
||||
}
|
||||
|
||||
|
||||
bool DirAccessAndroid::file_exists(String p_file){
|
||||
|
||||
String sd;
|
||||
if (current_dir=="")
|
||||
sd=p_file;
|
||||
else
|
||||
sd=current_dir+"/"+p_file;
|
||||
|
||||
AAsset *a=AAssetManager_open(FileAccessAndroid::asset_manager,sd.utf8().get_data(),AASSET_MODE_STREAMING);
|
||||
if (a) {
|
||||
AAsset_close(a);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Error DirAccessAndroid::make_dir(String p_dir){
|
||||
|
||||
ERR_FAIL_V(ERR_UNAVAILABLE);
|
||||
}
|
||||
|
||||
Error DirAccessAndroid::rename(String p_from, String p_to){
|
||||
|
||||
ERR_FAIL_V(ERR_UNAVAILABLE);
|
||||
}
|
||||
Error DirAccessAndroid::remove(String p_name){
|
||||
|
||||
ERR_FAIL_V(ERR_UNAVAILABLE);
|
||||
}
|
||||
|
||||
//FileType get_file_type() const;
|
||||
size_t DirAccessAndroid::get_space_left() {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DirAccessAndroid::make_default() {
|
||||
|
||||
instance_func=create_fs;
|
||||
}
|
||||
|
||||
DirAccessAndroid::DirAccessAndroid() {
|
||||
|
||||
aad=NULL;
|
||||
}
|
||||
|
||||
DirAccessAndroid::~DirAccessAndroid() {
|
||||
|
||||
list_dir_end();;
|
||||
}
|
||||
#endif
|
||||
82
platform/android/dir_access_android.h
Normal file
82
platform/android/dir_access_android.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/*************************************************************************/
|
||||
/* dir_access_android.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#ifndef DIR_ACCESS_ANDROID_H
|
||||
#define DIR_ACCESS_ANDROID_H
|
||||
|
||||
#ifdef ANDROID_NATIVE_ACTIVITY
|
||||
|
||||
#include "os/dir_access.h"
|
||||
#include <stdio.h>
|
||||
#include <android/asset_manager.h>
|
||||
#include <android/log.h>
|
||||
#include <android_native_app_glue.h>
|
||||
|
||||
|
||||
|
||||
class DirAccessAndroid : public DirAccess {
|
||||
|
||||
AAssetDir* aad;
|
||||
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 bool file_exists(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();
|
||||
|
||||
DirAccessAndroid();
|
||||
~DirAccessAndroid();
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // DIR_ACCESS_ANDROID_H
|
||||
241
platform/android/dir_access_jandroid.cpp
Normal file
241
platform/android/dir_access_jandroid.cpp
Normal file
@@ -0,0 +1,241 @@
|
||||
/*************************************************************************/
|
||||
/* dir_access_jandroid.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#ifndef ANDROID_NATIVE_ACTIVITY
|
||||
|
||||
#include "dir_access_jandroid.h"
|
||||
#include "file_access_jandroid.h"
|
||||
#include "thread_jandroid.h"
|
||||
jobject DirAccessJAndroid::io=NULL;
|
||||
jclass DirAccessJAndroid::cls=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();
|
||||
JNIEnv *env = ThreadAndroid::get_env();
|
||||
|
||||
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,"");
|
||||
|
||||
JNIEnv *env = ThreadAndroid::get_env();
|
||||
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{
|
||||
|
||||
JNIEnv *env = ThreadAndroid::get_env();
|
||||
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;
|
||||
|
||||
JNIEnv *env = ThreadAndroid::get_env();
|
||||
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){
|
||||
|
||||
JNIEnv *env = ThreadAndroid::get_env();
|
||||
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;
|
||||
}
|
||||
|
||||
bool DirAccessJAndroid::file_exists(String p_file){
|
||||
|
||||
JNIEnv *env = ThreadAndroid::get_env();
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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::setup( jobject p_io) {
|
||||
|
||||
|
||||
JNIEnv *env = ThreadAndroid::get_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();;
|
||||
}
|
||||
#endif
|
||||
90
platform/android/dir_access_jandroid.h
Normal file
90
platform/android/dir_access_jandroid.h
Normal file
@@ -0,0 +1,90 @@
|
||||
/*************************************************************************/
|
||||
/* dir_access_jandroid.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#ifndef DIR_ACCESS_JANDROID_H
|
||||
#define DIR_ACCESS_JANDROID_H
|
||||
|
||||
#ifndef ANDROID_NATIVE_ACTIVITY
|
||||
|
||||
|
||||
#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;
|
||||
|
||||
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 bool file_exists(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 setup( jobject io);
|
||||
|
||||
DirAccessJAndroid();
|
||||
~DirAccessJAndroid();
|
||||
};
|
||||
|
||||
#endif // DIR_ACCESS_JANDROID_H
|
||||
#endif
|
||||
1229
platform/android/export/export.cpp
Normal file
1229
platform/android/export/export.cpp
Normal file
File diff suppressed because it is too large
Load Diff
3
platform/android/export/export.h
Normal file
3
platform/android/export/export.h
Normal file
@@ -0,0 +1,3 @@
|
||||
|
||||
|
||||
void register_android_exporter();
|
||||
187
platform/android/file_access_android.cpp
Normal file
187
platform/android/file_access_android.cpp
Normal file
@@ -0,0 +1,187 @@
|
||||
/*************************************************************************/
|
||||
/* file_access_android.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include "file_access_android.h"
|
||||
#include "print_string.h"
|
||||
|
||||
#ifdef ANDROID_NATIVE_ACTIVITY
|
||||
|
||||
|
||||
AAssetManager *FileAccessAndroid::asset_manager=NULL;
|
||||
|
||||
|
||||
void FileAccessAndroid::make_default() {
|
||||
|
||||
create_func=create_android;
|
||||
}
|
||||
|
||||
FileAccess* FileAccessAndroid::create_android() {
|
||||
|
||||
return memnew(FileAccessAndroid);
|
||||
}
|
||||
|
||||
|
||||
Error FileAccessAndroid::open(const String& p_path, int p_mode_flags) {
|
||||
|
||||
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());
|
||||
|
||||
|
||||
|
||||
ERR_FAIL_COND_V(p_mode_flags&FileAccess::WRITE,ERR_UNAVAILABLE); //can't write on android..
|
||||
a=AAssetManager_open(asset_manager,path.utf8().get_data(),AASSET_MODE_STREAMING);
|
||||
if (!a)
|
||||
return ERR_CANT_OPEN;
|
||||
//ERR_FAIL_COND_V(!a,ERR_FILE_NOT_FOUND);
|
||||
len=AAsset_getLength(a);
|
||||
pos=0;
|
||||
eof=false;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
void FileAccessAndroid::close() {
|
||||
|
||||
if (!a)
|
||||
return;
|
||||
AAsset_close(a);
|
||||
a=NULL;
|
||||
}
|
||||
bool FileAccessAndroid::is_open() const {
|
||||
|
||||
return a!=NULL;
|
||||
}
|
||||
|
||||
void FileAccessAndroid::seek(size_t p_position) {
|
||||
|
||||
ERR_FAIL_COND(!a);
|
||||
AAsset_seek(a,p_position,SEEK_SET);
|
||||
pos=p_position;
|
||||
if (pos>len) {
|
||||
pos=len;
|
||||
eof=true;
|
||||
} else {
|
||||
eof=false;
|
||||
}
|
||||
|
||||
}
|
||||
void FileAccessAndroid::seek_end(int64_t p_position) {
|
||||
|
||||
ERR_FAIL_COND(!a);
|
||||
AAsset_seek(a,p_position,SEEK_END);
|
||||
pos=len+p_position;
|
||||
|
||||
}
|
||||
size_t FileAccessAndroid::get_pos() const {
|
||||
|
||||
return pos;
|
||||
}
|
||||
size_t FileAccessAndroid::get_len() const {
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
bool FileAccessAndroid::eof_reached() const {
|
||||
|
||||
return eof;
|
||||
}
|
||||
|
||||
uint8_t FileAccessAndroid::get_8() const {
|
||||
|
||||
|
||||
if (pos>=len) {
|
||||
eof=true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
uint8_t byte;
|
||||
AAsset_read(a,&byte,1);
|
||||
pos++;
|
||||
return byte;
|
||||
|
||||
}
|
||||
int FileAccessAndroid::get_buffer(uint8_t *p_dst, int p_length) const {
|
||||
|
||||
|
||||
off_t r = AAsset_read(a,p_dst,p_length);
|
||||
if (r>=0) {
|
||||
pos+=r;
|
||||
if (pos>len) {
|
||||
pos=len;
|
||||
eof=true;
|
||||
}
|
||||
}
|
||||
return r;
|
||||
|
||||
}
|
||||
|
||||
Error FileAccessAndroid::get_error() const {
|
||||
|
||||
return eof?ERR_FILE_EOF:OK; //not sure what else it may happen
|
||||
}
|
||||
|
||||
void FileAccessAndroid::store_8(uint8_t p_dest) {
|
||||
|
||||
ERR_FAIL();
|
||||
|
||||
}
|
||||
|
||||
bool FileAccessAndroid::file_exists(const String& p_path) {
|
||||
|
||||
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());
|
||||
|
||||
AAsset *at=AAssetManager_open(asset_manager,path.utf8().get_data(),AASSET_MODE_STREAMING);
|
||||
|
||||
if (!at)
|
||||
return false;
|
||||
|
||||
AAsset_close(at);
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
FileAccessAndroid::FileAccessAndroid() {
|
||||
a=NULL;
|
||||
eof=false;
|
||||
}
|
||||
|
||||
|
||||
FileAccessAndroid::~FileAccessAndroid()
|
||||
{
|
||||
close();
|
||||
}
|
||||
#endif
|
||||
82
platform/android/file_access_android.h
Normal file
82
platform/android/file_access_android.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/*************************************************************************/
|
||||
/* file_access_android.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#ifndef FILE_ACCESS_ANDROID_H
|
||||
#define FILE_ACCESS_ANDROID_H
|
||||
|
||||
#ifdef ANDROID_NATIVE_ACTIVITY
|
||||
|
||||
|
||||
#include "os/file_access.h"
|
||||
#include <stdio.h>
|
||||
#include <android/asset_manager.h>
|
||||
#include <android/log.h>
|
||||
#include <android_native_app_glue.h>
|
||||
|
||||
|
||||
class FileAccessAndroid : public FileAccess {
|
||||
|
||||
static FileAccess* create_android();
|
||||
mutable AAsset *a;
|
||||
mutable size_t len;
|
||||
mutable size_t pos;
|
||||
mutable bool eof;
|
||||
|
||||
public:
|
||||
|
||||
static AAssetManager *asset_manager;
|
||||
|
||||
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();
|
||||
|
||||
FileAccessAndroid();
|
||||
~FileAccessAndroid();
|
||||
};
|
||||
|
||||
#endif // FILE_ACCESS_ANDROID_H
|
||||
#endif
|
||||
253
platform/android/file_access_jandroid.cpp
Normal file
253
platform/android/file_access_jandroid.cpp
Normal file
@@ -0,0 +1,253 @@
|
||||
/*************************************************************************/
|
||||
/* file_access_jandroid.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#ifndef ANDROID_NATIVE_ACTIVITY
|
||||
|
||||
#include "file_access_jandroid.h"
|
||||
#include "os/os.h"
|
||||
#include <unistd.h>
|
||||
#include "thread_jandroid.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;
|
||||
|
||||
|
||||
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());
|
||||
|
||||
JNIEnv *env = ThreadAndroid::get_env();
|
||||
|
||||
//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);
|
||||
|
||||
env->DeleteLocalRef(js);
|
||||
|
||||
if (res<=0)
|
||||
return ERR_FILE_CANT_OPEN;
|
||||
id=res;
|
||||
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
void FileAccessJAndroid::close() {
|
||||
|
||||
if (!is_open())
|
||||
return;
|
||||
|
||||
JNIEnv *env = ThreadAndroid::get_env();
|
||||
|
||||
env->CallVoidMethod(io,_file_close,id);
|
||||
id=0;
|
||||
|
||||
}
|
||||
bool FileAccessJAndroid::is_open() const {
|
||||
|
||||
return id!=0;
|
||||
}
|
||||
|
||||
void FileAccessJAndroid::seek(size_t p_position) {
|
||||
|
||||
JNIEnv *env = ThreadAndroid::get_env();
|
||||
|
||||
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 {
|
||||
|
||||
JNIEnv *env = ThreadAndroid::get_env();
|
||||
ERR_FAIL_COND_V(!is_open(),0);
|
||||
return env->CallIntMethod(io,_file_tell,id);
|
||||
|
||||
}
|
||||
size_t FileAccessJAndroid::get_len() const {
|
||||
|
||||
JNIEnv *env = ThreadAndroid::get_env();
|
||||
ERR_FAIL_COND_V(!is_open(),0);
|
||||
return env->CallIntMethod(io,_file_get_size,id);
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool FileAccessJAndroid::eof_reached() const {
|
||||
|
||||
JNIEnv *env = ThreadAndroid::get_env();
|
||||
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;
|
||||
JNIEnv *env = ThreadAndroid::get_env();
|
||||
|
||||
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) {
|
||||
|
||||
JNIEnv *env = ThreadAndroid::get_env();
|
||||
|
||||
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());
|
||||
|
||||
jstring js = env->NewStringUTF(path.utf8().get_data());
|
||||
int res = env->CallIntMethod(io,_file_open,js,false);
|
||||
if (res<=0)
|
||||
return false;
|
||||
env->CallVoidMethod(io,_file_close,res);
|
||||
env->DeleteLocalRef(js);
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void FileAccessJAndroid::setup( jobject p_io) {
|
||||
|
||||
|
||||
io=p_io;
|
||||
JNIEnv *env = ThreadAndroid::get_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();
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
87
platform/android/file_access_jandroid.h
Normal file
87
platform/android/file_access_jandroid.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/*************************************************************************/
|
||||
/* file_access_jandroid.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#ifndef FILE_ACCESS_JANDROID_H
|
||||
#define FILE_ACCESS_JANDROID_H
|
||||
|
||||
#ifndef ANDROID_NATIVE_ACTIVITY
|
||||
|
||||
#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;
|
||||
|
||||
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 setup( jobject io);
|
||||
|
||||
virtual uint64_t _get_modified_time(const String& p_file) { return 0; }
|
||||
|
||||
FileAccessJAndroid();
|
||||
~FileAccessJAndroid();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif // FILE_ACCESS_JANDROID_H
|
||||
13
platform/android/globals/global_defaults.cpp
Normal file
13
platform/android/globals/global_defaults.cpp
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
#include "global_defaults.h"
|
||||
#include "globals.h"
|
||||
|
||||
|
||||
void register_android_global_defaults() {
|
||||
|
||||
GLOBAL_DEF("rasterizer.Android/use_fragment_lighting",false);
|
||||
GLOBAL_DEF("display.Android/driver","GLES2");
|
||||
GLOBAL_DEF("rasterizer.Android/trilinear_mipmap_filter",false);
|
||||
|
||||
Globals::get_singleton()->set_custom_property_info("display.Android/driver",PropertyInfo(Variant::STRING,"display.Android/driver",PROPERTY_HINT_ENUM,"GLES1,GLES2"));
|
||||
}
|
||||
3
platform/android/globals/global_defaults.h
Normal file
3
platform/android/globals/global_defaults.h
Normal file
@@ -0,0 +1,3 @@
|
||||
|
||||
|
||||
void register_android_global_defaults();
|
||||
993
platform/android/godot_android.cpp
Normal file
993
platform/android/godot_android.cpp
Normal file
@@ -0,0 +1,993 @@
|
||||
/*************************************************************************/
|
||||
/* godot_android.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#ifdef ANDROID_NATIVE_ACTIVITY
|
||||
|
||||
#include <jni.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <EGL/egl.h>
|
||||
#include <GLES2/gl2.h>
|
||||
|
||||
#include <android/sensor.h>
|
||||
#include <android/window.h>
|
||||
#include <android/log.h>
|
||||
#include <android_native_app_glue.h>
|
||||
#include "file_access_android.h"
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include "os_android.h"
|
||||
#include "globals.h"
|
||||
#include "main/main.h"
|
||||
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "godot", __VA_ARGS__))
|
||||
#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "godot", __VA_ARGS__))
|
||||
|
||||
|
||||
extern "C" {
|
||||
JNIEXPORT void JNICALL Java_com_android_godot_Godot_registerSingleton(JNIEnv * env, jobject obj, jstring name,jobject p_object);
|
||||
JNIEXPORT void JNICALL Java_com_android_godot_Godot_registerMethod(JNIEnv * env, jobject obj, jstring sname, jstring name, jstring ret, jobjectArray args);
|
||||
JNIEXPORT jstring JNICALL Java_com_android_godot_Godot_getGlobal(JNIEnv * env, jobject obj, jstring path);
|
||||
};
|
||||
|
||||
class JNISingleton : public Object {
|
||||
|
||||
OBJ_TYPE( JNISingleton, Object );
|
||||
|
||||
|
||||
struct MethodData {
|
||||
|
||||
|
||||
jmethodID method;
|
||||
Variant::Type ret_type;
|
||||
Vector<Variant::Type> argtypes;
|
||||
};
|
||||
|
||||
jobject instance;
|
||||
Map<StringName,MethodData> method_map;
|
||||
JNIEnv *env;
|
||||
|
||||
public:
|
||||
|
||||
void update_env(JNIEnv *p_env) { env=p_env; }
|
||||
|
||||
virtual Variant call(const StringName& p_method,const Variant** p_args,int p_argcount,Variant::CallError &r_error) {
|
||||
|
||||
print_line("attempt to call "+String(p_method));
|
||||
|
||||
r_error.error=Variant::CallError::CALL_OK;
|
||||
|
||||
Map<StringName,MethodData >::Element *E=method_map.find(p_method);
|
||||
if (!E) {
|
||||
|
||||
print_line("no exists");
|
||||
r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
|
||||
return Variant();
|
||||
}
|
||||
|
||||
|
||||
int ac = E->get().argtypes.size();
|
||||
if (ac<p_argcount) {
|
||||
|
||||
print_line("fewargs");
|
||||
r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
|
||||
r_error.argument=ac;
|
||||
return Variant();
|
||||
}
|
||||
|
||||
if (ac>p_argcount) {
|
||||
|
||||
print_line("manyargs");
|
||||
r_error.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
|
||||
r_error.argument=ac;
|
||||
return Variant();
|
||||
}
|
||||
|
||||
|
||||
|
||||
for(int i=0;i<p_argcount;i++) {
|
||||
|
||||
if (!Variant::can_convert(p_args[i]->get_type(),E->get().argtypes[i])) {
|
||||
|
||||
r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
|
||||
r_error.argument=i;
|
||||
r_error.expected=E->get().argtypes[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
jvalue *v=NULL;
|
||||
|
||||
if (p_argcount) {
|
||||
|
||||
v=(jvalue*)alloca( sizeof(jvalue)*p_argcount );
|
||||
}
|
||||
|
||||
for(int i=0;i<p_argcount;i++) {
|
||||
|
||||
|
||||
switch(E->get().argtypes[i]) {
|
||||
|
||||
case Variant::BOOL: {
|
||||
|
||||
v[i].z=*p_args[i];
|
||||
} break;
|
||||
case Variant::INT: {
|
||||
|
||||
v[i].i=*p_args[i];
|
||||
} break;
|
||||
case Variant::REAL: {
|
||||
|
||||
v[i].f=*p_args[i];
|
||||
} break;
|
||||
case Variant::STRING: {
|
||||
|
||||
String s = *p_args[i];
|
||||
jstring jStr = env->NewStringUTF(s.utf8().get_data());
|
||||
v[i].l=jStr;
|
||||
} break;
|
||||
case Variant::STRING_ARRAY: {
|
||||
|
||||
DVector<String> sarray = *p_args[i];
|
||||
jobjectArray arr = env->NewObjectArray(sarray.size(),env->FindClass("java/lang/String"),env->NewStringUTF(""));
|
||||
|
||||
for(int j=0;j<sarray.size();j++) {
|
||||
|
||||
env->SetObjectArrayElement(arr,j,env->NewStringUTF( sarray[i].utf8().get_data() ));
|
||||
}
|
||||
v[i].l=arr;
|
||||
|
||||
} break;
|
||||
case Variant::INT_ARRAY: {
|
||||
|
||||
DVector<int> array = *p_args[i];
|
||||
jintArray arr = env->NewIntArray(array.size());
|
||||
DVector<int>::Read r = array.read();
|
||||
env->SetIntArrayRegion(arr,0,array.size(),r.ptr());
|
||||
v[i].l=arr;
|
||||
|
||||
} break;
|
||||
case Variant::REAL_ARRAY: {
|
||||
|
||||
DVector<float> array = *p_args[i];
|
||||
jfloatArray arr = env->NewFloatArray(array.size());
|
||||
DVector<float>::Read r = array.read();
|
||||
env->SetFloatArrayRegion(arr,0,array.size(),r.ptr());
|
||||
v[i].l=arr;
|
||||
|
||||
} break;
|
||||
default: {
|
||||
|
||||
ERR_FAIL_V(Variant());
|
||||
} break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
print_line("calling method!!");
|
||||
|
||||
Variant ret;
|
||||
|
||||
switch(E->get().ret_type) {
|
||||
|
||||
case Variant::NIL: {
|
||||
|
||||
|
||||
print_line("call void");
|
||||
env->CallVoidMethodA(instance,E->get().method,v);
|
||||
} break;
|
||||
case Variant::BOOL: {
|
||||
|
||||
ret = env->CallBooleanMethodA(instance,E->get().method,v);
|
||||
print_line("call bool");
|
||||
} break;
|
||||
case Variant::INT: {
|
||||
|
||||
ret = env->CallIntMethodA(instance,E->get().method,v);
|
||||
print_line("call int");
|
||||
} break;
|
||||
case Variant::REAL: {
|
||||
|
||||
ret = env->CallFloatMethodA(instance,E->get().method,v);
|
||||
} break;
|
||||
case Variant::STRING: {
|
||||
|
||||
jobject o = env->CallObjectMethodA(instance,E->get().method,v);
|
||||
String singname = env->GetStringUTFChars((jstring)o, NULL );
|
||||
} break;
|
||||
case Variant::STRING_ARRAY: {
|
||||
|
||||
jobjectArray arr = (jobjectArray)env->CallObjectMethodA(instance,E->get().method,v);
|
||||
|
||||
int stringCount = env->GetArrayLength(arr);
|
||||
DVector<String> sarr;
|
||||
|
||||
for (int i=0; i<stringCount; i++) {
|
||||
jstring string = (jstring) env->GetObjectArrayElement(arr, i);
|
||||
const char *rawString = env->GetStringUTFChars(string, 0);
|
||||
sarr.push_back(String(rawString));
|
||||
}
|
||||
|
||||
ret=sarr;
|
||||
|
||||
} break;
|
||||
case Variant::INT_ARRAY: {
|
||||
|
||||
jintArray arr = (jintArray)env->CallObjectMethodA(instance,E->get().method,v);
|
||||
|
||||
int fCount = env->GetArrayLength(arr);
|
||||
DVector<int> sarr;
|
||||
sarr.resize(fCount);
|
||||
|
||||
DVector<int>::Write w = sarr.write();
|
||||
env->GetIntArrayRegion(arr,0,fCount,w.ptr());
|
||||
w = DVector<int>::Write();
|
||||
ret=sarr;
|
||||
} break;
|
||||
case Variant::REAL_ARRAY: {
|
||||
|
||||
jfloatArray arr = (jfloatArray)env->CallObjectMethodA(instance,E->get().method,v);
|
||||
|
||||
int fCount = env->GetArrayLength(arr);
|
||||
DVector<float> sarr;
|
||||
sarr.resize(fCount);
|
||||
|
||||
DVector<float>::Write w = sarr.write();
|
||||
env->GetFloatArrayRegion(arr,0,fCount,w.ptr());
|
||||
w = DVector<float>::Write();
|
||||
ret=sarr;
|
||||
} break;
|
||||
default: {
|
||||
|
||||
|
||||
print_line("failure..");
|
||||
ERR_FAIL_V(Variant());
|
||||
} break;
|
||||
}
|
||||
|
||||
print_line("success");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
jobject get_instance() const {
|
||||
|
||||
return instance;
|
||||
}
|
||||
void set_instance(jobject p_instance) {
|
||||
|
||||
instance=p_instance;
|
||||
}
|
||||
|
||||
|
||||
void add_method(const StringName& p_name, jmethodID p_method,const Vector<Variant::Type>& p_args, Variant::Type p_ret_type) {
|
||||
|
||||
MethodData md;
|
||||
md.method=p_method;
|
||||
md.argtypes=p_args;
|
||||
md.ret_type=p_ret_type;
|
||||
method_map[p_name]=md;
|
||||
|
||||
}
|
||||
|
||||
|
||||
JNISingleton() {}
|
||||
|
||||
};
|
||||
|
||||
//JNIEnv *JNISingleton::env=NULL;
|
||||
|
||||
static HashMap<String,JNISingleton*> jni_singletons;
|
||||
|
||||
|
||||
struct engine {
|
||||
struct android_app* app;
|
||||
OS_Android *os;
|
||||
JNIEnv *jni;
|
||||
|
||||
ASensorManager* sensorManager;
|
||||
const ASensor* accelerometerSensor;
|
||||
ASensorEventQueue* sensorEventQueue;
|
||||
|
||||
bool display_active;
|
||||
bool requested_quit;
|
||||
int animating;
|
||||
EGLDisplay display;
|
||||
EGLSurface surface;
|
||||
EGLContext context;
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize an EGL context for the current display.
|
||||
*/
|
||||
static int engine_init_display(struct engine* engine,bool p_gl2) {
|
||||
// initialize OpenGL ES and EGL
|
||||
|
||||
/*
|
||||
* Here specify the attributes of the desired configuration.
|
||||
* Below, we select an EGLConfig with at least 8 bits per color
|
||||
* component compatible with on-screen windows
|
||||
*/
|
||||
const EGLint gl2_attribs[] = {
|
||||
// EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
||||
EGL_BLUE_SIZE, 4,
|
||||
EGL_GREEN_SIZE, 4,
|
||||
EGL_RED_SIZE, 4,
|
||||
EGL_ALPHA_SIZE, 0,
|
||||
EGL_DEPTH_SIZE, 16,
|
||||
EGL_STENCIL_SIZE, EGL_DONT_CARE,
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
const EGLint gl1_attribs[] = {
|
||||
// EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
||||
EGL_BLUE_SIZE, 4,
|
||||
EGL_GREEN_SIZE, 4,
|
||||
EGL_RED_SIZE, 4,
|
||||
EGL_ALPHA_SIZE, 0,
|
||||
EGL_DEPTH_SIZE, 16,
|
||||
EGL_STENCIL_SIZE, EGL_DONT_CARE,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
const EGLint *attribs=p_gl2?gl2_attribs:gl1_attribs;
|
||||
|
||||
|
||||
EGLint w, h, dummy, format;
|
||||
EGLint numConfigs;
|
||||
EGLConfig config;
|
||||
EGLSurface surface;
|
||||
EGLContext context;
|
||||
|
||||
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
|
||||
eglInitialize(display, 0, 0);
|
||||
|
||||
|
||||
/* Here, the application chooses the configuration it desires. In this
|
||||
* sample, we have a very simplified selection process, where we pick
|
||||
* the first EGLConfig that matches our criteria */
|
||||
|
||||
eglChooseConfig(display, attribs, &config, 1, &numConfigs);
|
||||
|
||||
LOGI("Num configs: %i\n",numConfigs);
|
||||
|
||||
/* EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is
|
||||
* guaranteed to be accepted by ANativeWindow_setBuffersGeometry().
|
||||
* As soon as we picked a EGLConfig, we can safely reconfigure the
|
||||
* ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID. */
|
||||
eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format);
|
||||
|
||||
ANativeWindow_setBuffersGeometry(engine->app->window, 0, 0, format);
|
||||
//ANativeWindow_setFlags(engine->app->window, 0, 0, format|);
|
||||
|
||||
surface = eglCreateWindowSurface(display, config, engine->app->window, NULL);
|
||||
|
||||
const EGLint context_attribs[] = {
|
||||
EGL_CONTEXT_CLIENT_VERSION,2,
|
||||
EGL_NONE
|
||||
};
|
||||
context = eglCreateContext(display, config, EGL_NO_CONTEXT, p_gl2?context_attribs:NULL);
|
||||
|
||||
if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) {
|
||||
LOGW("Unable to eglMakeCurrent");
|
||||
return -1;
|
||||
}
|
||||
|
||||
eglQuerySurface(display, surface, EGL_WIDTH, &w);
|
||||
eglQuerySurface(display, surface, EGL_HEIGHT, &h);
|
||||
print_line("INIT VIDEO MODE: "+itos(w)+","+itos(h));
|
||||
|
||||
//engine->os->set_egl_extensions(eglQueryString(display,EGL_EXTENSIONS));
|
||||
engine->os->init_video_mode(w,h);
|
||||
|
||||
|
||||
engine->display = display;
|
||||
engine->context = context;
|
||||
engine->surface = surface;
|
||||
engine->width = w;
|
||||
engine->height = h;
|
||||
engine->display_active=true;
|
||||
|
||||
//engine->state.angle = 0;
|
||||
|
||||
// Initialize GL state.
|
||||
//glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
|
||||
glEnable(GL_CULL_FACE);
|
||||
// glShadeModel(GL_SMOOTH);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
LOGI("GL Version: %s - %s %s\n", glGetString(GL_VERSION),glGetString(GL_VENDOR), glGetString(GL_RENDERER));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void engine_draw_frame(struct engine* engine) {
|
||||
if (engine->display == NULL) {
|
||||
// No display.
|
||||
return;
|
||||
}
|
||||
|
||||
// Just fill the screen with a color.
|
||||
//glClearColor(0,1,0,1);
|
||||
//glClear(GL_COLOR_BUFFER_BIT);
|
||||
if (engine->os && engine->os->main_loop_iterate()==true) {
|
||||
|
||||
engine->requested_quit=true;
|
||||
return; //should exit instead
|
||||
}
|
||||
|
||||
eglSwapBuffers(engine->display, engine->surface);
|
||||
}
|
||||
|
||||
|
||||
static void engine_term_display(struct engine* engine) {
|
||||
if (engine->display != EGL_NO_DISPLAY) {
|
||||
eglMakeCurrent(engine->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
if (engine->context != EGL_NO_CONTEXT) {
|
||||
eglDestroyContext(engine->display, engine->context);
|
||||
}
|
||||
if (engine->surface != EGL_NO_SURFACE) {
|
||||
eglDestroySurface(engine->display, engine->surface);
|
||||
}
|
||||
eglTerminate(engine->display);
|
||||
}
|
||||
|
||||
engine->animating = 0;
|
||||
engine->display = EGL_NO_DISPLAY;
|
||||
engine->context = EGL_NO_CONTEXT;
|
||||
engine->surface = EGL_NO_SURFACE;
|
||||
engine->display_active=false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the next input event.
|
||||
*/
|
||||
static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) {
|
||||
struct engine* engine = (struct engine*)app->userData;
|
||||
|
||||
if (!engine->os)
|
||||
return 0;
|
||||
|
||||
switch(AInputEvent_getType(event)) {
|
||||
|
||||
case AINPUT_EVENT_TYPE_KEY: {
|
||||
|
||||
int ac = AKeyEvent_getAction(event);
|
||||
switch(ac) {
|
||||
|
||||
case AKEY_EVENT_ACTION_DOWN: {
|
||||
|
||||
int32_t code = AKeyEvent_getKeyCode(event);
|
||||
if (code==AKEYCODE_BACK) {
|
||||
|
||||
//AInputQueue_finishEvent(AInputQueue* queue, AInputEvent* event, int handled);
|
||||
if (engine->os)
|
||||
engine->os->main_loop_request_quit();
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
} break;
|
||||
case AKEY_EVENT_ACTION_UP: {
|
||||
|
||||
|
||||
} break;
|
||||
}
|
||||
|
||||
|
||||
} break;
|
||||
case AINPUT_EVENT_TYPE_MOTION: {
|
||||
|
||||
|
||||
Vector<OS_Android::TouchPos> touchvec;
|
||||
|
||||
int pc = AMotionEvent_getPointerCount(event);
|
||||
|
||||
touchvec.resize(pc);
|
||||
|
||||
for(int i=0;i<pc;i++) {
|
||||
|
||||
touchvec[i].pos.x=AMotionEvent_getX(event,i);
|
||||
touchvec[i].pos.y=AMotionEvent_getY(event,i);
|
||||
touchvec[i].id=AMotionEvent_getPointerId(event,i);
|
||||
}
|
||||
|
||||
|
||||
//System.out.printf("gaction: %d\n",event.getAction());
|
||||
int pidx=(AMotionEvent_getAction(event)&AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)>>8;
|
||||
switch(AMotionEvent_getAction(event)&AMOTION_EVENT_ACTION_MASK) {
|
||||
|
||||
case AMOTION_EVENT_ACTION_DOWN: {
|
||||
engine->os->process_touch(0,0,touchvec);
|
||||
|
||||
//System.out.printf("action down at: %f,%f\n", event.getX(),event.getY());
|
||||
} break;
|
||||
case AMOTION_EVENT_ACTION_MOVE: {
|
||||
engine->os->process_touch(1,0,touchvec);
|
||||
//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 AMOTION_EVENT_ACTION_POINTER_UP: {
|
||||
|
||||
engine->os->process_touch(4,pidx,touchvec);
|
||||
//System.out.printf("%d - s.up at: %f,%f\n",pointer_idx, event.getX(pointer_idx),event.getY(pointer_idx));
|
||||
} break;
|
||||
case AMOTION_EVENT_ACTION_POINTER_DOWN: {
|
||||
engine->os->process_touch(3,pidx,touchvec);
|
||||
//System.out.printf("%d - s.down at: %f,%f\n",pointer_idx, event.getX(pointer_idx),event.getY(pointer_idx));
|
||||
} break;
|
||||
case AMOTION_EVENT_ACTION_CANCEL:
|
||||
case AMOTION_EVENT_ACTION_UP: {
|
||||
engine->os->process_touch(2,0,touchvec);
|
||||
//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 1;
|
||||
} break;
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the next main command.
|
||||
*/
|
||||
|
||||
static void _gfx_init(void *ud,bool p_gl2) {
|
||||
|
||||
struct engine* engine = (struct engine*)ud;
|
||||
engine_init_display(engine,p_gl2);
|
||||
}
|
||||
|
||||
static void engine_handle_cmd(struct android_app* app, int32_t cmd) {
|
||||
struct engine* engine = (struct engine*)app->userData;
|
||||
// LOGI("**** CMD %i\n",cmd);
|
||||
switch (cmd) {
|
||||
case APP_CMD_SAVE_STATE:
|
||||
// The system has asked us to save our current state. Do so.
|
||||
//engine->app->savedState = malloc(sizeof(struct saved_state));
|
||||
//*((struct saved_state*)engine->app->savedState) = engine->state;
|
||||
//engine->app->savedStateSize = sizeof(struct saved_state);
|
||||
break;
|
||||
case APP_CMD_CONFIG_CHANGED:
|
||||
case APP_CMD_WINDOW_RESIZED: {
|
||||
|
||||
#if 0
|
||||
// android blows
|
||||
if (engine->display_active) {
|
||||
|
||||
EGLint w,h;
|
||||
eglQuerySurface(engine->display, engine->surface, EGL_WIDTH, &w);
|
||||
eglQuerySurface(engine->display, engine->surface, EGL_HEIGHT, &h);
|
||||
engine->os->init_video_mode(w,h);
|
||||
//print_line("RESIZED VIDEO MODE: "+itos(w)+","+itos(h));
|
||||
engine_draw_frame(engine);
|
||||
|
||||
}
|
||||
#else
|
||||
|
||||
if (engine->display_active) {
|
||||
|
||||
|
||||
EGLint w,h;
|
||||
eglQuerySurface(engine->display, engine->surface, EGL_WIDTH, &w);
|
||||
eglQuerySurface(engine->display, engine->surface, EGL_HEIGHT, &h);
|
||||
// if (w==engine->os->get_video_mode().width && h==engine->os->get_video_mode().height)
|
||||
// break;
|
||||
|
||||
engine_term_display(engine);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
engine->os->reload_gfx();
|
||||
engine_draw_frame(engine);
|
||||
engine->animating=1;
|
||||
|
||||
/*
|
||||
EGLint w,h;
|
||||
eglQuerySurface(engine->display, engine->surface, EGL_WIDTH, &w);
|
||||
eglQuerySurface(engine->display, engine->surface, EGL_HEIGHT, &h);
|
||||
engine->os->init_video_mode(w,h);
|
||||
//print_line("RESIZED VIDEO MODE: "+itos(w)+","+itos(h));
|
||||
|
||||
}*/
|
||||
|
||||
#endif
|
||||
|
||||
} break;
|
||||
case APP_CMD_INIT_WINDOW:
|
||||
//The window is being shown, get it ready.
|
||||
// LOGI("INIT WINDOW");
|
||||
if (engine->app->window != NULL) {
|
||||
|
||||
if (engine->os==NULL) {
|
||||
|
||||
//do initialization here, when there's OpenGL! hackish but the only way
|
||||
engine->os = new OS_Android(_gfx_init,engine);
|
||||
|
||||
// char *args[]={"-test","gui",NULL};
|
||||
__android_log_print(ANDROID_LOG_INFO,"godot","pre asdasd setup...");
|
||||
#if 0
|
||||
Error err = Main::setup("apk",2,args);
|
||||
#else
|
||||
Error err = Main::setup("apk",0,NULL);
|
||||
|
||||
String modules = Globals::get_singleton()->get("android/modules");
|
||||
Vector<String> mods = modules.split(",",false);
|
||||
mods.push_back("GodotOS");
|
||||
__android_log_print(ANDROID_LOG_INFO,"godot","mod count: %i",mods.size());
|
||||
|
||||
if (mods.size()) {
|
||||
|
||||
jclass activityClass = engine->jni->FindClass("android/app/NativeActivity");
|
||||
|
||||
jmethodID getClassLoader = engine->jni->GetMethodID(activityClass,"getClassLoader", "()Ljava/lang/ClassLoader;");
|
||||
|
||||
jobject cls = engine->jni->CallObjectMethod(app->activity->clazz, getClassLoader);
|
||||
|
||||
jclass classLoader = engine->jni->FindClass("java/lang/ClassLoader");
|
||||
|
||||
jmethodID findClass = engine->jni->GetMethodID(classLoader, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
|
||||
|
||||
|
||||
static JNINativeMethod methods[] = {
|
||||
{"registerSingleton", "(Ljava/lang/String;Ljava/lang/Object;)V",(void *)&Java_com_android_godot_Godot_registerSingleton},
|
||||
{"registerMethod", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)V",(void *)&Java_com_android_godot_Godot_registerMethod},
|
||||
{"getGlobal", "(Ljava/lang/String;)Ljava/lang/String;", (void *)&Java_com_android_godot_Godot_getGlobal},
|
||||
};
|
||||
|
||||
jstring gstrClassName = engine->jni->NewStringUTF("com/android/godot/Godot");
|
||||
jclass GodotClass = (jclass)engine->jni->CallObjectMethod(cls, findClass, gstrClassName);
|
||||
|
||||
__android_log_print(ANDROID_LOG_INFO,"godot","godot ****^*^*?^*^*class data %x",GodotClass);
|
||||
|
||||
engine->jni->RegisterNatives(GodotClass,methods,sizeof(methods)/sizeof(methods[0]));
|
||||
|
||||
for (int i=0;i<mods.size();i++) {
|
||||
|
||||
String m = mods[i];
|
||||
//jclass singletonClass = engine->jni->FindClass(m.utf8().get_data());
|
||||
|
||||
jstring strClassName = engine->jni->NewStringUTF(m.utf8().get_data());
|
||||
jclass singletonClass = (jclass)engine->jni->CallObjectMethod(cls, findClass, strClassName);
|
||||
|
||||
__android_log_print(ANDROID_LOG_INFO,"godot","****^*^*?^*^*class data %x",singletonClass);
|
||||
jmethodID initialize = engine->jni->GetStaticMethodID(singletonClass, "initialize", "(Landroid/app/Activity;)Lcom/android/godot/Godot$SingletonBase;");
|
||||
|
||||
|
||||
jobject obj = engine->jni->CallStaticObjectMethod(singletonClass,initialize,app->activity->clazz);
|
||||
__android_log_print(ANDROID_LOG_INFO,"godot","****^*^*?^*^*class instance %x",obj);
|
||||
jobject gob = engine->jni->NewGlobalRef(obj);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
if (!Main::start())
|
||||
return; //should exit instead and print the error
|
||||
|
||||
engine->os->main_loop_begin();
|
||||
} else {
|
||||
//i guess recreate resources?
|
||||
engine->os->reload_gfx();
|
||||
}
|
||||
|
||||
|
||||
engine->animating=1;
|
||||
engine_draw_frame(engine);
|
||||
}
|
||||
break;
|
||||
case APP_CMD_TERM_WINDOW:
|
||||
// The window is being hidden or closed, clean it up.
|
||||
// LOGI("TERM WINDOW");
|
||||
engine_term_display(engine);
|
||||
break;
|
||||
case APP_CMD_GAINED_FOCUS:
|
||||
// When our app gains focus, we start monitoring the accelerometer.
|
||||
if (engine->accelerometerSensor != NULL) {
|
||||
ASensorEventQueue_enableSensor(engine->sensorEventQueue,
|
||||
engine->accelerometerSensor);
|
||||
// We'd like to get 60 events per second (in us).
|
||||
ASensorEventQueue_setEventRate(engine->sensorEventQueue,
|
||||
engine->accelerometerSensor, (1000L/60)*1000);
|
||||
|
||||
}
|
||||
engine->animating = 1;
|
||||
break;
|
||||
case APP_CMD_LOST_FOCUS:
|
||||
// When our app loses focus, we stop monitoring the accelerometer.
|
||||
// This is to avoid consuming battery while not being used.
|
||||
if (engine->accelerometerSensor != NULL) {
|
||||
ASensorEventQueue_disableSensor(engine->sensorEventQueue,
|
||||
engine->accelerometerSensor);
|
||||
}
|
||||
// Also stop animating.
|
||||
engine->animating = 0;
|
||||
engine_draw_frame(engine);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void android_main(struct android_app* state) {
|
||||
struct engine engine;
|
||||
// Make sure glue isn't stripped.
|
||||
app_dummy();
|
||||
|
||||
memset(&engine, 0, sizeof(engine));
|
||||
state->userData = &engine;
|
||||
state->onAppCmd = engine_handle_cmd;
|
||||
state->onInputEvent = engine_handle_input;
|
||||
engine.app = state;
|
||||
engine.requested_quit=false;
|
||||
engine.os=NULL;
|
||||
engine.display_active=false;
|
||||
|
||||
FileAccessAndroid::asset_manager=state->activity->assetManager;
|
||||
|
||||
// Prepare to monitor accelerometer
|
||||
engine.sensorManager = ASensorManager_getInstance();
|
||||
engine.accelerometerSensor = ASensorManager_getDefaultSensor(engine.sensorManager,
|
||||
ASENSOR_TYPE_ACCELEROMETER);
|
||||
engine.sensorEventQueue = ASensorManager_createEventQueue(engine.sensorManager,
|
||||
state->looper, LOOPER_ID_USER, NULL, NULL);
|
||||
|
||||
|
||||
ANativeActivity_setWindowFlags(state->activity,AWINDOW_FLAG_FULLSCREEN|AWINDOW_FLAG_KEEP_SCREEN_ON,0);
|
||||
|
||||
state->activity->vm->AttachCurrentThread(&engine.jni, NULL);
|
||||
|
||||
|
||||
|
||||
// loop waiting for stuff to do.
|
||||
|
||||
while (1) {
|
||||
// Read all pending events.
|
||||
int ident;
|
||||
int events;
|
||||
struct android_poll_source* source;
|
||||
|
||||
// If not animating, we will block forever waiting for events.
|
||||
// If animating, we loop until all events are read, then continue
|
||||
// to draw the next frame of animation.
|
||||
|
||||
int nullmax=50;
|
||||
while ((ident=ALooper_pollAll(engine.animating ? 0 : -1, NULL, &events,
|
||||
(void**)&source)) >= 0) {
|
||||
|
||||
// Process this event.
|
||||
|
||||
if (source != NULL) {
|
||||
// LOGI("process\n");
|
||||
source->process(state, source);
|
||||
} else {
|
||||
nullmax--;
|
||||
if (nullmax<0)
|
||||
break;
|
||||
}
|
||||
|
||||
// If a sensor has data, process it now.
|
||||
// LOGI("events\n");
|
||||
if (ident == LOOPER_ID_USER) {
|
||||
if (engine.accelerometerSensor != NULL) {
|
||||
ASensorEvent event;
|
||||
while (ASensorEventQueue_getEvents(engine.sensorEventQueue,
|
||||
&event, 1) > 0) {
|
||||
|
||||
|
||||
if (engine.os) {
|
||||
engine.os->process_accelerometer(Vector3(event.acceleration.x, event.acceleration.y,
|
||||
event.acceleration.z));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we are exiting.
|
||||
if (state->destroyRequested != 0) {
|
||||
if (engine.os) {
|
||||
engine.os->main_loop_request_quit();
|
||||
}
|
||||
state->destroyRequested=0;
|
||||
}
|
||||
|
||||
if (engine.requested_quit) {
|
||||
engine_term_display(&engine);
|
||||
exit(0);
|
||||
return;
|
||||
}
|
||||
|
||||
// LOGI("end\n");
|
||||
|
||||
|
||||
}
|
||||
|
||||
// LOGI("engine animating? %i\n",engine.animating);
|
||||
|
||||
if (engine.animating) {
|
||||
//do os render
|
||||
|
||||
engine_draw_frame(&engine);
|
||||
//LOGI("TERM WINDOW");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_android_godot_Godot_registerSingleton(JNIEnv * env, jobject obj, jstring name,jobject p_object){
|
||||
|
||||
String singname = env->GetStringUTFChars( name, NULL );
|
||||
JNISingleton *s = memnew( JNISingleton );
|
||||
s->update_env(env);
|
||||
s->set_instance(env->NewGlobalRef(p_object));
|
||||
jni_singletons[singname]=s;
|
||||
|
||||
Globals::get_singleton()->add_singleton(Globals::Singleton(singname,s));
|
||||
|
||||
}
|
||||
|
||||
|
||||
static Variant::Type get_jni_type(const String& p_type) {
|
||||
|
||||
static struct {
|
||||
const char *name;
|
||||
Variant::Type type;
|
||||
} _type_to_vtype[]={
|
||||
{"void",Variant::NIL},
|
||||
{"boolean",Variant::BOOL},
|
||||
{"int",Variant::INT},
|
||||
{"float",Variant::REAL},
|
||||
{"java.lang.String",Variant::STRING},
|
||||
{"[I",Variant::INT_ARRAY},
|
||||
{"[F",Variant::REAL_ARRAY},
|
||||
{"[java.lang.String",Variant::STRING_ARRAY},
|
||||
{NULL,Variant::NIL}
|
||||
};
|
||||
|
||||
int idx=0;
|
||||
|
||||
while (_type_to_vtype[idx].name) {
|
||||
|
||||
if (p_type==_type_to_vtype[idx].name)
|
||||
return _type_to_vtype[idx].type;
|
||||
|
||||
idx++;
|
||||
}
|
||||
|
||||
return Variant::NIL;
|
||||
}
|
||||
|
||||
|
||||
static const char* get_jni_sig(const String& p_type) {
|
||||
|
||||
static struct {
|
||||
const char *name;
|
||||
const char *sig;
|
||||
} _type_to_vtype[]={
|
||||
{"void","V"},
|
||||
{"boolean","Z"},
|
||||
{"int","I"},
|
||||
{"float","F"},
|
||||
{"java.lang.String","Ljava/lang/String;"},
|
||||
{"[I","[I"},
|
||||
{"[F","[F"},
|
||||
{"[java.lang.String","[Ljava/lang/String;"},
|
||||
{NULL,"V"}
|
||||
};
|
||||
|
||||
int idx=0;
|
||||
|
||||
while (_type_to_vtype[idx].name) {
|
||||
|
||||
if (p_type==_type_to_vtype[idx].name)
|
||||
return _type_to_vtype[idx].sig;
|
||||
|
||||
idx++;
|
||||
}
|
||||
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
JNIEXPORT jstring JNICALL Java_com_android_godot_Godot_getGlobal(JNIEnv * env, jobject obj, jstring path) {
|
||||
|
||||
String js = env->GetStringUTFChars( path, NULL );
|
||||
|
||||
return env->NewStringUTF(Globals::get_singleton()->get(js).operator String().utf8().get_data());
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_android_godot_Godot_registerMethod(JNIEnv * env, jobject obj, jstring sname, jstring name, jstring ret, jobjectArray args){
|
||||
|
||||
String singname = env->GetStringUTFChars( sname, NULL );
|
||||
|
||||
ERR_FAIL_COND(!jni_singletons.has(singname));
|
||||
|
||||
JNISingleton *s = jni_singletons.get(singname);
|
||||
|
||||
|
||||
String mname = env->GetStringUTFChars( name, NULL );
|
||||
String retval = env->GetStringUTFChars( ret, NULL );
|
||||
Vector<Variant::Type> types;
|
||||
String cs="(";
|
||||
|
||||
|
||||
int stringCount = env->GetArrayLength(args);
|
||||
|
||||
print_line("Singl: "+singname+" Method: "+mname+" RetVal: "+retval);
|
||||
for (int i=0; i<stringCount; i++) {
|
||||
|
||||
jstring string = (jstring) env->GetObjectArrayElement(args, i);
|
||||
const char *rawString = env->GetStringUTFChars(string, 0);
|
||||
types.push_back(get_jni_type(String(rawString)));
|
||||
cs+=get_jni_sig(String(rawString));
|
||||
}
|
||||
|
||||
cs+=")";
|
||||
cs+=get_jni_sig(retval);
|
||||
jclass cls = env->GetObjectClass(s->get_instance());
|
||||
print_line("METHOD: "+mname+" sig: "+cs);
|
||||
jmethodID mid = env->GetMethodID(cls, mname.ascii().get_data(), cs.ascii().get_data());
|
||||
if (!mid) {
|
||||
|
||||
print_line("FAILED GETTING METHOID "+mname);
|
||||
}
|
||||
|
||||
s->add_method(mname,mid,types,get_jni_type(retval));
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
22
platform/android/java/ant.properties
Normal file
22
platform/android/java/ant.properties
Normal file
@@ -0,0 +1,22 @@
|
||||
# This file is used to override default values used by the Ant build system.
|
||||
#
|
||||
# This file must be checked into Version Control Systems, as it is
|
||||
# integral to the build system of your project.
|
||||
|
||||
# This file is only used by the Ant script.
|
||||
|
||||
# You can use this to override default values such as
|
||||
# 'source.dir' for the location of your java source folder and
|
||||
# 'out.dir' for the location of your output folder.
|
||||
|
||||
# You can also use it define how the release builds are signed by declaring
|
||||
# the following properties:
|
||||
# 'key.store' for the location of your keystore and
|
||||
# 'key.alias' for the name of the key to use.
|
||||
# The password will be asked during the build when you use the 'release' target.
|
||||
|
||||
key.store=my-release-key.keystore
|
||||
key.alias=mykey
|
||||
|
||||
key.store.password=123456
|
||||
key.alias.password=123456
|
||||
17
platform/android/java/build.properties
Normal file
17
platform/android/java/build.properties
Normal file
@@ -0,0 +1,17 @@
|
||||
# This file is used to override default values used by the Ant build system.
|
||||
#
|
||||
# This file must be checked in Version Control Systems, as it is
|
||||
# integral to the build system of your project.
|
||||
|
||||
# This file is only used by the Ant script.
|
||||
|
||||
# You can use this to override default values such as
|
||||
# 'source.dir' for the location of your java source folder and
|
||||
# 'out.dir' for the location of your output folder.
|
||||
|
||||
# You can also use it define how the release builds are signed by declaring
|
||||
# the following properties:
|
||||
# 'key.store' for the location of your keystore and
|
||||
# 'key.alias' for the name of the key to use.
|
||||
# The password will be asked during the build when you use the 'release' target.
|
||||
|
||||
92
platform/android/java/build.xml
Normal file
92
platform/android/java/build.xml
Normal file
@@ -0,0 +1,92 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="Godot" default="help">
|
||||
|
||||
<!-- The local.properties file is created and updated by the 'android' tool.
|
||||
It contains the path to the SDK. It should *NOT* be checked into
|
||||
Version Control Systems. -->
|
||||
<property file="local.properties" />
|
||||
|
||||
<!-- The ant.properties file can be created by you. It is only edited by the
|
||||
'android' tool to add properties to it.
|
||||
This is the place to change some Ant specific build properties.
|
||||
Here are some properties you may want to change/update:
|
||||
|
||||
source.dir
|
||||
The name of the source directory. Default is 'src'.
|
||||
out.dir
|
||||
The name of the output directory. Default is 'bin'.
|
||||
|
||||
For other overridable properties, look at the beginning of the rules
|
||||
files in the SDK, at tools/ant/build.xml
|
||||
|
||||
Properties related to the SDK location or the project target should
|
||||
be updated using the 'android' tool with the 'update' action.
|
||||
|
||||
This file is an integral part of the build system for your
|
||||
application and should be checked into Version Control Systems.
|
||||
|
||||
-->
|
||||
<property file="ant.properties" />
|
||||
|
||||
<!-- if sdk.dir was not set from one of the property file, then
|
||||
get it from the ANDROID_HOME env var.
|
||||
This must be done before we load project.properties since
|
||||
the proguard config can use sdk.dir -->
|
||||
<property environment="env" />
|
||||
<condition property="sdk.dir" value="${env.ANDROID_HOME}">
|
||||
<isset property="env.ANDROID_HOME" />
|
||||
</condition>
|
||||
|
||||
<!-- The project.properties file is created and updated by the 'android'
|
||||
tool, as well as ADT.
|
||||
|
||||
This contains project specific properties such as project target, and library
|
||||
dependencies. Lower level build properties are stored in ant.properties
|
||||
(or in .classpath for Eclipse projects).
|
||||
|
||||
This file is an integral part of the build system for your
|
||||
application and should be checked into Version Control Systems. -->
|
||||
<loadproperties srcFile="project.properties" />
|
||||
|
||||
<!-- quick check on sdk.dir -->
|
||||
<fail
|
||||
message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
|
||||
unless="sdk.dir"
|
||||
/>
|
||||
|
||||
<!--
|
||||
Import per project custom build rules if present at the root of the project.
|
||||
This is the place to put custom intermediary targets such as:
|
||||
-pre-build
|
||||
-pre-compile
|
||||
-post-compile (This is typically used for code obfuscation.
|
||||
Compiled code location: ${out.classes.absolute.dir}
|
||||
If this is not done in place, override ${out.dex.input.absolute.dir})
|
||||
-post-package
|
||||
-post-build
|
||||
-pre-clean
|
||||
-->
|
||||
<import file="custom_rules.xml" optional="true" />
|
||||
|
||||
<!-- Import the actual build file.
|
||||
|
||||
To customize existing targets, there are two options:
|
||||
- Customize only one target:
|
||||
- copy/paste the target into this file, *before* the
|
||||
<import> task.
|
||||
- customize it to your needs.
|
||||
- Customize the whole content of build.xml
|
||||
- copy/paste the content of the rules files (minus the top node)
|
||||
into this file, replacing the <import> task.
|
||||
- customize to your needs.
|
||||
|
||||
***********************
|
||||
****** IMPORTANT ******
|
||||
***********************
|
||||
In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
|
||||
in order to avoid having your file be overridden by tools such as "android update project"
|
||||
-->
|
||||
<!-- version-tag: 1 -->
|
||||
<import file="${sdk.dir}/tools/ant/build.xml" />
|
||||
|
||||
</project>
|
||||
11
platform/android/java/default.properties
Normal file
11
platform/android/java/default.properties
Normal file
@@ -0,0 +1,11 @@
|
||||
# This file is automatically generated by Android Tools.
|
||||
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
||||
#
|
||||
# This file must be checked in Version Control Systems.
|
||||
#
|
||||
# To customize properties used by the Ant build system use,
|
||||
# "build.properties", and override values to adapt the script to your
|
||||
# project structure.
|
||||
|
||||
# Project target.
|
||||
target=android-8
|
||||
BIN
platform/android/java/my-release-key.keystore
Normal file
BIN
platform/android/java/my-release-key.keystore
Normal file
Binary file not shown.
20
platform/android/java/proguard-project.txt
Normal file
20
platform/android/java/proguard-project.txt
Normal file
@@ -0,0 +1,20 @@
|
||||
# To enable ProGuard in your project, edit project.properties
|
||||
# to define the proguard.config property as described in that file.
|
||||
#
|
||||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in ${sdk.dir}/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the ProGuard
|
||||
# include property in project.properties.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
36
platform/android/java/proguard.cfg
Normal file
36
platform/android/java/proguard.cfg
Normal file
@@ -0,0 +1,36 @@
|
||||
-optimizationpasses 5
|
||||
-dontusemixedcaseclassnames
|
||||
-dontskipnonpubliclibraryclasses
|
||||
-dontpreverify
|
||||
-verbose
|
||||
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
|
||||
|
||||
-keep public class * extends android.app.Activity
|
||||
-keep public class * extends android.app.Application
|
||||
-keep public class * extends android.app.Service
|
||||
-keep public class * extends android.content.BroadcastReceiver
|
||||
-keep public class * extends android.content.ContentProvider
|
||||
-keep public class * extends android.app.backup.BackupAgentHelper
|
||||
-keep public class * extends android.preference.Preference
|
||||
-keep public class com.android.vending.licensing.ILicensingService
|
||||
|
||||
-keepclasseswithmembernames class * {
|
||||
native <methods>;
|
||||
}
|
||||
|
||||
-keepclasseswithmembernames class * {
|
||||
public <init>(android.content.Context, android.util.AttributeSet);
|
||||
}
|
||||
|
||||
-keepclasseswithmembernames class * {
|
||||
public <init>(android.content.Context, android.util.AttributeSet, int);
|
||||
}
|
||||
|
||||
-keepclassmembers enum * {
|
||||
public static **[] values();
|
||||
public static ** valueOf(java.lang.String);
|
||||
}
|
||||
|
||||
-keep class * implements android.os.Parcelable {
|
||||
public static final android.os.Parcelable$Creator *;
|
||||
}
|
||||
BIN
platform/android/java/res/drawable/icon.png
Normal file
BIN
platform/android/java/res/drawable/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 90 KiB |
4
platform/android/java/res/values-ar/strings.xml
Normal file
4
platform/android/java/res/values-ar/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="godot_project_name_string">godot-project-name-ar</string>
|
||||
</resources>
|
||||
4
platform/android/java/res/values-bg/strings.xml
Normal file
4
platform/android/java/res/values-bg/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="godot_project_name_string">godot-project-name-bg</string>
|
||||
</resources>
|
||||
4
platform/android/java/res/values-ca/strings.xml
Normal file
4
platform/android/java/res/values-ca/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="godot_project_name_string">godot-project-name-ca</string>
|
||||
</resources>
|
||||
4
platform/android/java/res/values-cs/strings.xml
Normal file
4
platform/android/java/res/values-cs/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="godot_project_name_string">godot-project-name-cs</string>
|
||||
</resources>
|
||||
4
platform/android/java/res/values-da/strings.xml
Normal file
4
platform/android/java/res/values-da/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="godot_project_name_string">godot-project-name-da</string>
|
||||
</resources>
|
||||
4
platform/android/java/res/values-de/strings.xml
Normal file
4
platform/android/java/res/values-de/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="godot_project_name_string">godot-project-name-de</string>
|
||||
</resources>
|
||||
4
platform/android/java/res/values-el/strings.xml
Normal file
4
platform/android/java/res/values-el/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="godot_project_name_string">godot-project-name-el</string>
|
||||
</resources>
|
||||
4
platform/android/java/res/values-en/strings.xml
Normal file
4
platform/android/java/res/values-en/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="godot_project_name_string">godot-project-name-en</string>
|
||||
</resources>
|
||||
4
platform/android/java/res/values-es-rES/strings.xml
Normal file
4
platform/android/java/res/values-es-rES/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="godot_project_name_string">godot-project-name-es_ES</string>
|
||||
</resources>
|
||||
4
platform/android/java/res/values-es/strings.xml
Normal file
4
platform/android/java/res/values-es/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="godot_project_name_string">godot-project-name-es</string>
|
||||
</resources>
|
||||
4
platform/android/java/res/values-fi/strings.xml
Normal file
4
platform/android/java/res/values-fi/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="godot_project_name_string">godot-project-name-fi</string>
|
||||
</resources>
|
||||
4
platform/android/java/res/values-fr/strings.xml
Normal file
4
platform/android/java/res/values-fr/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="godot_project_name_string">godot-project-name-fr</string>
|
||||
</resources>
|
||||
4
platform/android/java/res/values-he/strings.xml
Normal file
4
platform/android/java/res/values-he/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="godot_project_name_string">godot-project-name-he</string>
|
||||
</resources>
|
||||
4
platform/android/java/res/values-hi/strings.xml
Normal file
4
platform/android/java/res/values-hi/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="godot_project_name_string">godot-project-name-hi</string>
|
||||
</resources>
|
||||
4
platform/android/java/res/values-hr/strings.xml
Normal file
4
platform/android/java/res/values-hr/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="godot_project_name_string">godot-project-name-hr</string>
|
||||
</resources>
|
||||
4
platform/android/java/res/values-hu/strings.xml
Normal file
4
platform/android/java/res/values-hu/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="godot_project_name_string">godot-project-name-hu</string>
|
||||
</resources>
|
||||
4
platform/android/java/res/values-id/strings.xml
Normal file
4
platform/android/java/res/values-id/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="godot_project_name_string">godot-project-name-id</string>
|
||||
</resources>
|
||||
4
platform/android/java/res/values-it/strings.xml
Normal file
4
platform/android/java/res/values-it/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="godot_project_name_string">godot-project-name-it</string>
|
||||
</resources>
|
||||
4
platform/android/java/res/values-ja/strings.xml
Normal file
4
platform/android/java/res/values-ja/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="godot_project_name_string">godot-project-name-ja</string>
|
||||
</resources>
|
||||
4
platform/android/java/res/values-ko/strings.xml
Normal file
4
platform/android/java/res/values-ko/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="godot_project_name_string">godot-project-name-ko</string>
|
||||
</resources>
|
||||
4
platform/android/java/res/values-lt/strings.xml
Normal file
4
platform/android/java/res/values-lt/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="godot_project_name_string">godot-project-name-lt</string>
|
||||
</resources>
|
||||
4
platform/android/java/res/values-lv/strings.xml
Normal file
4
platform/android/java/res/values-lv/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="godot_project_name_string">godot-project-name-lv</string>
|
||||
</resources>
|
||||
4
platform/android/java/res/values-nb/strings.xml
Normal file
4
platform/android/java/res/values-nb/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="godot_project_name_string">godot-project-name-nb</string>
|
||||
</resources>
|
||||
4
platform/android/java/res/values-nl/strings.xml
Normal file
4
platform/android/java/res/values-nl/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="godot_project_name_string">godot-project-name-nl</string>
|
||||
</resources>
|
||||
4
platform/android/java/res/values-pl/strings.xml
Normal file
4
platform/android/java/res/values-pl/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="godot_project_name_string">godot-project-name-pl</string>
|
||||
</resources>
|
||||
4
platform/android/java/res/values-pt/strings.xml
Normal file
4
platform/android/java/res/values-pt/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="godot_project_name_string">godot-project-name-pt</string>
|
||||
</resources>
|
||||
4
platform/android/java/res/values-ro/strings.xml
Normal file
4
platform/android/java/res/values-ro/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="godot_project_name_string">godot-project-name-ro</string>
|
||||
</resources>
|
||||
4
platform/android/java/res/values-ru/strings.xml
Normal file
4
platform/android/java/res/values-ru/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="godot_project_name_string">godot-project-name-ru</string>
|
||||
</resources>
|
||||
4
platform/android/java/res/values-sk/strings.xml
Normal file
4
platform/android/java/res/values-sk/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="godot_project_name_string">godot-project-name-sk</string>
|
||||
</resources>
|
||||
4
platform/android/java/res/values-sl/strings.xml
Normal file
4
platform/android/java/res/values-sl/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="godot_project_name_string">godot-project-name-sl</string>
|
||||
</resources>
|
||||
4
platform/android/java/res/values-sr/strings.xml
Normal file
4
platform/android/java/res/values-sr/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="godot_project_name_string">godot-project-name-sr</string>
|
||||
</resources>
|
||||
4
platform/android/java/res/values-sv/strings.xml
Normal file
4
platform/android/java/res/values-sv/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="godot_project_name_string">godot-project-name-sv</string>
|
||||
</resources>
|
||||
4
platform/android/java/res/values-th/strings.xml
Normal file
4
platform/android/java/res/values-th/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="godot_project_name_string">godot-project-name-th</string>
|
||||
</resources>
|
||||
4
platform/android/java/res/values-tl/strings.xml
Normal file
4
platform/android/java/res/values-tl/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="godot_project_name_string">godot-project-name-tl</string>
|
||||
</resources>
|
||||
4
platform/android/java/res/values-tr/strings.xml
Normal file
4
platform/android/java/res/values-tr/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="godot_project_name_string">godot-project-name-tr</string>
|
||||
</resources>
|
||||
4
platform/android/java/res/values-uk/strings.xml
Normal file
4
platform/android/java/res/values-uk/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="godot_project_name_string">godot-project-name-uk</string>
|
||||
</resources>
|
||||
4
platform/android/java/res/values-vi/strings.xml
Normal file
4
platform/android/java/res/values-vi/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="godot_project_name_string">godot-project-name-vi</string>
|
||||
</resources>
|
||||
4
platform/android/java/res/values-zh/strings.xml
Normal file
4
platform/android/java/res/values-zh/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="godot_project_name_string">godot-project-name-zh</string>
|
||||
</resources>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user