Jelajahi Sumber

android window work with jni, touch input and acc sensor

mikymod 13 tahun lalu
induk
melakukan
9f5a159ccc

+ 4 - 1
android/AndroidManifest.xml

@@ -8,7 +8,10 @@
 
     <application android:label="@string/app_name" >
         <activity android:name="CrownActivity"
-                  android:label="@string/app_name">
+                  android:label="@string/app_name"
+				  android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
+				  android:screenOrientation="landscape" 
+				  android:configChanges="orientation|keyboardHidden">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />

+ 3 - 2
android/jni/Android.mk

@@ -16,6 +16,7 @@ LOCAL_PATH := $(call my-dir)
 
 include $(CLEAR_VARS)
 LOCAL_MODULE    := crown
+
 LOCAL_SRC_FILES :=\
 	core/bv/Circle.cpp\
 	core/bv/Frustum.cpp\
@@ -47,6 +48,7 @@ LOCAL_SRC_FILES :=\
 	os/OS.cpp\
 	os/android/AndroidOS.cpp\
 	os/android/AndroidRenderWindow.cpp\
+	os/android/AndroidInput.cpp\
 \
 	Filesystem.cpp\
 \
@@ -106,7 +108,6 @@ LOCAL_C_INCLUDES	:=\
 
 LOCAL_CPPFLAGS	:= -g -fexceptions
 LOCAL_LDLIBS	:= -llog -landroid -lEGL -lGLESv1_CM
-LOCAL_STATIC_LIBRARIES := android_native_app_glue
 include $(BUILD_SHARED_LIBRARY)
 
 #include $(CLEAR_VARS)
@@ -160,5 +161,5 @@ include $(BUILD_SHARED_LIBRARY)
 #LOCAL_LDLIBS	:= -llog -landroid -lEGL -lGLESv1_CM -lz
 #LOCAL_STATIC_LIBRARIES := android_native_app_glue
 #include $(BUILD_SHARED_LIBRARY)
-$(call import-module,android/native_app_glue)
+#$(call import-module,android/native_app_glue)
 

+ 1 - 0
android/jni/Application.mk

@@ -1,2 +1,3 @@
 APP_PLATFORM := android-9
 APP_STL := gnustl_static
+APP_ABI := armeabi-v7a

+ 0 - 1
android/res/layout/main.xml

@@ -7,7 +7,6 @@
 <TextView  
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
-    android:text="Hello World, CrownActivity"
     />
 </LinearLayout>
 

+ 89 - 4
android/src/crown/android/CrownActivity.java

@@ -2,18 +2,37 @@ package crown.android;
 
 import android.app.Activity;
 import android.os.Bundle;
+import android.util.Log;
+import android.view.WindowManager;
+import android.view.MotionEvent;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.content.Context;
 import android.widget.Toast;
 
+
 public class CrownActivity extends Activity
 {
+	public static String TAG = "CrownActivity";
+
+	private CrownView mView;
+
+	private static SensorManager sm;
+	private Sensor sensor;
+
+	
     /** Called when the activity is first created. */
     @Override
     public void onCreate(Bundle savedInstanceState)
     {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.main);
-		CrownLib.create();
-		Toast.makeText(this, "EGL window created", Toast.LENGTH_SHORT).show();
+        mView = new CrownView(getApplication());
+	    sm = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
+	    sensor = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
+
     }
 
 	public void onStart()
@@ -29,11 +48,26 @@ public class CrownActivity extends Activity
 	public void onResume()
 	{
 		super.onResume();
+        mView.onResume();
+		if (sensor != null) 
+		{
+		  sm.registerListener(sensorEventListener, sensor, SensorManager.SENSOR_DELAY_NORMAL);
+		  Log.i(TAG, "Registerered for ORIENTATION Sensor");
+
+		} 
+		else 
+		{
+		  Log.e("Compass MainActivity", "Registerered for ORIENTATION Sensor");
+		  Toast.makeText(this, "ORIENTATION Sensor not found", Toast.LENGTH_LONG).show();
+		  finish();
+		}
 	}
 
 	public void onPause()
 	{
 		super.onPause();
+        mView.onPause();
+		sm.unregisterListener(sensorEventListener);
 	}
 
 	public void onStop()
@@ -44,7 +78,58 @@ public class CrownActivity extends Activity
 	public void onDestroy()
 	{
 		super.onDestroy();
-		CrownLib.destroy();
-		Toast.makeText(this, "EGL window destroyed", Toast.LENGTH_SHORT).show();
 	}
+
+	@Override
+	public boolean onTouchEvent(MotionEvent event)
+	{
+	    float x = event.getX();
+	    float y = event.getY();
+
+		switch (event.getAction()) 
+		{	
+	        case MotionEvent.ACTION_MOVE:
+			{
+				Log.i(TAG, "event = ACTION_MOVE");
+				CrownLib.pushEvent(10,(int) x,(int) y, 0, 0);
+				break;
+			}
+
+			case MotionEvent.ACTION_DOWN:
+			{
+				Log.i(TAG, "event = ACTION_DOWN");
+				CrownLib.pushEvent(10,(int) x,(int) y, 0, 0);
+				break;			
+			}
+
+			case MotionEvent.ACTION_UP:
+			{
+				Log.i(TAG, "event = ACTION_UP");
+				CrownLib.pushEvent(10,(int) x,(int) y, 0, 0);
+				break;			
+			}
+		}
+		return true;
+	}
+	
+  	private SensorEventListener sensorEventListener = new SensorEventListener() 
+	{
+    	@Override
+    	public void onAccuracyChanged(Sensor sensor, int accuracy) 
+		{
+    	}
+
+    	@Override
+    	public void onSensorChanged(SensorEvent event) 
+		{
+     	 	// angle between the magnetic north directio
+     	 	// 0=North, 90=East, 180=South, 270=West
+     	 	float x = event.values[0];
+			float y = event.values[1];
+			float z = event.values[2];
+			Log.i(TAG, "X:" + x + "Y:" + y + "Z:" + z);
+    	}
+  };
+
+
 }

+ 1 - 2
android/src/crown/android/CrownLib.java

@@ -7,6 +7,5 @@ public class CrownLib
 		System.loadLibrary("crown");
 	}
 
-	public static native boolean create();
-	public static native void destroy();
+	public static native void pushEvent(int type, int a, int b, int c, int d);
 }

+ 322 - 0
android/src/crown/android/CrownView.java

@@ -0,0 +1,322 @@
+package crown.android;
+
+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 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;
+
+class CrownView extends GLSurfaceView 
+{
+    private static String TAG = "CrownView";
+
+    private static final boolean DEBUG = false;
+
+    public CrownView(Context context) 
+	{
+        super(context);
+        init(false, 0, 0);
+    }
+
+    public CrownView(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)
+		{
+
+        }
+
+        public void onSurfaceChanged(GL10 gl, int width, int height)
+		{
+
+        }
+
+        public void onSurfaceCreated(GL10 gl, EGLConfig config)
+		{
+            // Do nothing.
+        }
+    }
+}

+ 2 - 2
src/Material.h

@@ -350,8 +350,8 @@ public:
 	//! Sets the texture wrap mode for all layers
 	void SetTextureWrap(TextureWrap wrap);
 
-	virtual void	Load(const char* name);
-	virtual void	Unload(const char* name, bool reload);
+	//virtual void	Load(const char* name);
+	//virtual void	Unload(const char* name, bool reload);
 
 //private:
 

+ 11 - 0
src/core/streams/MemoryStream.cpp

@@ -89,6 +89,17 @@ void DynamicMemoryBuffer::write(uint8_t* src, size_t offset, size_t size)
 	}
 }
 
+//-----------------------------------------------------------------------------
+void DynamicMemoryBuffer::release()
+{
+	// FIXME
+}
+
+//-----------------------------------------------------------------------------
+void DynamicMemoryBuffer::allocate(size_t capacity)
+{
+	// FIXME
+}
 //-----------------------------------------------------------------------------
 MemoryStream::MemoryStream(MemoryBuffer* buffer, StreamOpenMode mode) :
 	Stream(mode),

+ 5 - 0
src/input/InputManager.cpp

@@ -93,6 +93,11 @@ void InputManager::EventLoop()
 
 				break;
 			}
+			case os::OSET_TOUCH_MOVE:
+			{
+				Log::I("Touch coord = %d:%d\n", event.data_a, event.data_b);
+				break;
+			}
 			default:
 			{
 				break;

+ 2 - 1
src/os/OS.h

@@ -111,7 +111,8 @@ enum OSEventType
 
 	OSET_BUTTON_PRESS		= 3,
 	OSET_BUTTON_RELEASE		= 4,
-	OSET_MOTION_NOTIFY		= 5
+	OSET_MOTION_NOTIFY		= 5,
+	OSET_TOUCH_MOVE			= 10
 };
 
 struct OSEvent

+ 45 - 0
src/os/android/AndroidInput.cpp

@@ -0,0 +1,45 @@
+#include "OS.h"
+#include <jni.h>
+
+namespace crown
+{
+namespace os
+{
+
+extern "C" 
+{
+    JNIEXPORT void JNICALL Java_crown_android_CrownLib_pushEvent(JNIEnv * env, jobject obj, jint type, jint a, jint b, jint c, jint d);
+
+};
+JNIEXPORT void JNICALL Java_crown_android_CrownLib_pushEvent(JNIEnv * env, jobject obj, jint type, jint a, jint b, jint c, jint d)
+{
+	push_event((OSEventType)type, a, b, c, d);
+}
+
+
+void init_input()
+{
+	// FIXME
+}
+
+void get_cursor_xy(int32_t& x, int32_t& y)
+{
+	// FIXME
+}
+
+void set_cursor_xy(int32_t x, int32_t y)
+{
+	// FIXME
+}
+
+void hide_cursor()
+{
+	// FIXME
+}
+
+void show_cursor()
+{
+	// FIXME
+}
+} // namespace os
+} // namespace crown

+ 144 - 29
src/os/android/AndroidOS.cpp

@@ -25,8 +25,15 @@ OTHER DEALINGS IN THE SOFTWARE.
 
 #include "OS.h"
 #include <android/log.h>
+#include <cstdio>
+#include <cstdarg>
 #include <sys/stat.h>
 #include <unistd.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <cstdlib>
+#include <sys/time.h>
+#include <time.h>
 
 #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "crown", __VA_ARGS__))
 #define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "crown", __VA_ARGS__))
@@ -38,85 +45,193 @@ namespace crown
 namespace os
 {
 
+static timespec base_time;
+
+//-----------------------------------------------------------------------------
 void printf(const char* string, ...)
 {
-	LOGI(string);
+	va_list args;
+
+	va_start(args, string);
+	::vprintf(string, args);
+	va_end(args);
+}
+
+//-----------------------------------------------------------------------------
+void vprintf(const char* string, va_list arg)
+{
+	::vprintf(string, arg);
 }
 
-void log_debug(const char* string, ...)
+//-----------------------------------------------------------------------------
+void log_debug(const char* string, va_list arg)
 {
-	LOGD(string);
+	printf("D: ");
+	vprintf(string, arg);
+	printf("\n");
 }
 
-void log_error(const char* string, ...)
+//-----------------------------------------------------------------------------
+void log_error(const char* string, va_list arg)
 {
-	LOGE(string);
+	printf("E: ");
+	vprintf(string, arg);
+	printf("\n");
 }
 
-void log_warning(const char* string, ...)
+//-----------------------------------------------------------------------------
+void log_warning(const char* string, va_list arg)
 {
-	LOGW(string);
+	printf("W: ");
+	vprintf(string, arg);
+	printf("\n");
 }
 
-void log_info(const char* string, ...)
+//-----------------------------------------------------------------------------
+void log_info(const char* string, va_list arg)
 {
-	LOGI(string);
+	LOGI(string, arg);
 }
 
-bool exists(const Str& path)
+//-----------------------------------------------------------------------------
+bool exists(const char* path)
 {
 	struct stat dummy;
-	return (stat(path.c_str(), &dummy) == 0);
+	return (stat(path, &dummy) == 0);
 }
 
-bool is_dir(const Str& path)
+//-----------------------------------------------------------------------------
+bool is_dir(const char* path)
 {
 	struct stat info;
-	stat(path.c_str(), &info);
-	return (S_ISDIR(info.st_mode)) != 0;
+	memset(&info, 0, sizeof(struct stat));
+	lstat(path, &info);
+	return ((S_ISDIR(info.st_mode)) != 0 && (S_ISLNK(info.st_mode) == 0));
 }
 
-bool is_reg(const Str& path)
+//-----------------------------------------------------------------------------
+bool is_reg(const char* path)
 {
 	struct stat info;
-	stat(path.c_str(), &info);
-	return (S_ISREG(info.st_mode)) != 0;
+	memset(&info, 0, sizeof(struct stat));
+	lstat(path, &info);
+	return ((S_ISREG(info.st_mode) != 0) && (S_ISLNK(info.st_mode) == 0));
 }
 
-bool mknod(const Str& path)
+//-----------------------------------------------------------------------------
+bool mknod(const char* path)
 {
 	// Permission mask: rw-r--r--
-	return ::mknod(path.c_str(), S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH, 0) == 0;
+	return ::mknod(path, S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH, 0) == 0;
 }
 
-bool unlink(const Str& path)
+//-----------------------------------------------------------------------------
+bool unlink(const char* path)
 {
-	return (::unlink(path.c_str()) == 0);
+	return (::unlink(path) == 0);
 }
 
-bool mkdir(const Str& path)
+//-----------------------------------------------------------------------------
+bool mkdir(const char* path)
 {
 	// rwxr-xr-x permission mask
-	return (::mkdir(path.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == 0);
+	return (::mkdir(path, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == 0);
+}
+
+//-----------------------------------------------------------------------------
+bool rmdir(const char* path)
+{
+	return (::rmdir(path) == 0);
+}
+
+//-----------------------------------------------------------------------------
+const char* get_cwd()
+{
+	static char cwdBuf[MAX_PATH_LENGTH];
+	if (getcwd(cwdBuf, MAX_PATH_LENGTH) == NULL)
+	{
+		return Str::EMPTY;
+	}
+
+	return cwdBuf;
+}
+
+//-----------------------------------------------------------------------------
+const char* get_home()
+{
+	char* envHome = NULL;
+	envHome = getenv("HOME");
+
+	if (envHome == NULL)
+	{
+		return Str::EMPTY;
+	}
+
+	return envHome;
 }
 
-bool rmdir(const Str& path)
+//-----------------------------------------------------------------------------
+const char* get_env(const char* env)
 {
-	return (::rmdir(path.c_str()) == 0);
+	char* envDevel = NULL;
+	envDevel = getenv(env);
+
+	if (envDevel == NULL)
+	{
+		return Str::EMPTY;
+	}
+
+	return envDevel;
 }
 
-bool get_cwd(Str& ret)
+//-----------------------------------------------------------------------------
+bool ls(const char* path, List<Str>& fileList)
 {
-	static char cwdBuf[1024];
-	if (getcwd(cwdBuf, 1024) == NULL)
+	DIR *dir;
+	struct dirent *ent;
+
+	dir = opendir(path);
+
+	if (dir == NULL)
 	{
 		return false;
 	}
 
-	ret = cwdBuf;
+	while ((ent = readdir (dir)) != NULL)
+	{
+		fileList.push_back(Str(ent->d_name));
+	}
+
+	closedir (dir);
+
 	return true;
 }
 
+//-----------------------------------------------------------------------------
+void init_os()
+{
+	// Initilize the base time
+	clock_gettime(CLOCK_MONOTONIC, &base_time);
+}
+
+//-----------------------------------------------------------------------------
+uint64_t milliseconds()
+{
+	timespec tmp;
+
+	clock_gettime(CLOCK_MONOTONIC, &tmp);
+
+	return (tmp.tv_sec - base_time.tv_sec) * 1000 + (tmp.tv_nsec - base_time.tv_nsec) / 1000000;
+}
+
+//-----------------------------------------------------------------------------
+uint64_t microseconds()
+{
+	timespec tmp;
+	clock_gettime(CLOCK_MONOTONIC, &tmp);
+	return (tmp.tv_sec - base_time.tv_sec) * 1000000 + (tmp.tv_nsec - base_time.tv_nsec) / 1000;
+}
+
 } // namespace os
 } // namespace crown
 

+ 84 - 81
src/os/android/AndroidRenderWindow.cpp

@@ -23,12 +23,11 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 OTHER DEALINGS IN THE SOFTWARE.
 */
 
-#include "Device.h"
 #include "Log.h"
 #include "Types.h"
-#include "Config.h"
+#include "OS.h"
 #include <EGL/egl.h>
-#include <android_native_app_glue.h>
+//#include <android_native_app_glue.h>
 #include <jni.h>
 
 namespace crown
@@ -41,116 +40,120 @@ EGLint h;
 EGLDisplay display;
 EGLSurface surface;
 EGLContext context;
-android_app* application;
+//android_app* application;
 
-bool create_render_window()
+bool create_render_window(uint32_t x, uint32_t y, uint32_t width, uint32_t height, bool fullscreen)
 {
-	assert(width != 0 && height != 0);
+//	display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
 
-	display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+//	assert(display != EGL_NO_DISPLAY);
 
-	assert(display != EGL_NO_DISPLAY);
+//	const EGLint attribs[] =
+//	{
+//		EGL_BUFFER_SIZE, 24,
+//		EGL_DEPTH_SIZE, 24,
+//		EGL_SURFACE_TYPE, 
+//		EGL_WINDOW_BIT,
+//		EGL_RENDERABLE_TYPE, 
+//		EGL_OPENGL_ES_BIT,
+//		EGL_NONE
+//	};
+//	
+//	EGLint major;
+//	EGLint minor;
 
-	const EGLint attribs[] =
-	{
-		EGL_BUFFER_SIZE, 24,
-		EGL_DEPTH_SIZE, 24,
-		EGL_SURFACE_TYPE, 
-		EGL_WINDOW_BIT,
-		EGL_RENDERABLE_TYPE, 
-		EGL_OPENGL_ES_BIT,
-		EGL_NONE
-	};
-	
-	EGLint major;
-	EGLint minor;
+//	assert(eglInitialize(display, &major, &minor));
 
-	assert(eglInitialize(display, &major, &minor));
+//	EGLConfig  config;
+//	EGLint     num_config;
+//	assert(eglChooseConfig(display, attribs, &config, 1, &num_config));
 
-	EGLConfig  config;
-	EGLint     num_config;
-	assert(eglChooseConfig(display, attribs, &config, 1, &num_config));
+//	EGLint format;
+//    eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format);
 
-	EGLint format;
-    eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format);
+//	// Reconfigure ANativeWindow buffer
+//    ANativeWindow_setBuffersGeometry(application->window, 0, 0, format);
 
-	// Reconfigure ANativeWindow buffer
-    ANativeWindow_setBuffersGeometry(application->window, 0, 0, format);
+//	surface = eglCreateWindowSurface(display, config, application->window, NULL);
+//	assert(surface != EGL_NO_SURFACE);
 
-	surface = eglCreateWindowSurface(display, config, application->window, NULL);
-	assert(surface != EGL_NO_SURFACE);
 
+//	EGLint ctxattr[] =
+//	{
+//		EGL_CONTEXT_CLIENT_VERSION, 
+//		1,
+//		EGL_NONE
+//	};
 
-	EGLint ctxattr[] =
-	{
-		EGL_CONTEXT_CLIENT_VERSION, 
-		1,
-		EGL_NONE
-	};
+//	context = eglCreateContext(display, config, EGL_NO_CONTEXT, ctxattr);
+//	assert(context != EGL_NO_CONTEXT);
 
-	context = eglCreateContext(display, config, EGL_NO_CONTEXT, ctxattr);
-	assert(context != EGL_NO_CONTEXT);
+//	assert(eglMakeCurrent(display, surface, surface, context) != EGL_NO_CONTEXT);
 
-	assert(eglMakeCurrent(display, surface, surface, context) != EGL_NO_CONTEXT);
+//	eglQuerySurface(display, surface, EGL_WIDTH, &w);
+//    eglQuerySurface(display, surface, EGL_HEIGHT, &h);
 
-	eglQuerySurface(display, surface, EGL_WIDTH, &w);
-    eglQuerySurface(display, surface, EGL_HEIGHT, &h);
-
-	return true;
+//	return true;
 }
 
-void destroy_render_window()
+bool destroy_render_window()
 {
-	if (display != EGL_NO_DISPLAY)
-	{
-		eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-
-		if (context != EGL_NO_CONTEXT)
-		{
-            eglDestroyContext(display, context);
-		}
-		
-		if (surface != EGL_NO_SURFACE)
-		{
-            eglDestroySurface(display, surface);
-		}
-
-		eglTerminate(display);
-	}
+//	if (display != EGL_NO_DISPLAY)
+//	{
+//		eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+
+//		if (context != EGL_NO_CONTEXT)
+//		{
+//            eglDestroyContext(display, context);
+//		}
+//		
+//		if (surface != EGL_NO_SURFACE)
+//		{
+//            eglDestroySurface(display, surface);
+//		}
+
+//		eglTerminate(display);
+//	}
 }
 
-void bind()
+void get_render_window_metrics(uint32_t& width, uint32_t& height)
 {
-	eglMakeCurrent(display, surface, surface, context);
+//	width = w;
+//	height = h;
 }
 
-void unbind()
+void swap_buffers()
 {
-	eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+//	eglSwapBuffers(display, surface);
 }
 
-void swap_buffers()
+void event_loop()
 {
-	eglSwapBuffers(display, surface);
+	// FIXME
 }
 
 
-// JNI definitions - just tmp
-extern "C"
-{
-	JNIEXPORT bool JNICALL Java_crown_android_CrownLib_create(JNIEnv* env, jobject obj);
-	JNIEXPORT void JNICALL Java_crown_android_CrownLib_destroy(JNIEnv* env, jobject obj);
-}
 
-JNIEXPORT bool JNICALL Java_crown_android_CrownLib_create(JNIEnv* env, jobject obj)
-{
-	return create_render_window();
-}
 
-JNIEXPORT void JNICALL Java_crown_android_CrownLib_destroy(JNIEnv* env, jobject obj)
-{
-	destroy_render_window();
-}
+/* 
+tmp JNI definitions, just for testing
+TODO: remove this methods
+*/
+//extern "C"
+//{
+//	JNIEXPORT bool JNICALL Java_crown_android_CrownLib_create(JNIEnv* env, jobject obj);
+//	JNIEXPORT bool JNICALL Java_crown_android_CrownLib_destroy(JNIEnv* env, jobject obj);
+//}
+
+//JNIEXPORT bool JNICALL Java_crown_android_CrownLib_create(JNIEnv* env, jobject obj, jint x, jint y, jint width, jint height, jboolean fullscreen)
+//{
+//	create_render_window(x, y, width, height, fullscreen);
+//}
+
+//JNIEXPORT bool JNICALL Java_crown_android_CrownLib_destroy(JNIEnv* env, jobject obj)
+//{
+//	destroy_render_window();
+//}
 
 
 } // namespace os