瀏覽代碼

Added android file system calls and fixed some other issues. Currently have openal setup as static so that needs to change before release

Tim Newell 12 年之前
父節點
當前提交
bb2bda49c6

+ 1 - 1
engine/compilers/android/.cproject

@@ -22,7 +22,7 @@
 					<folderInfo id="com.android.toolchain.gcc.1442582075.1056020003" name="/" resourcePath="">
 					<folderInfo id="com.android.toolchain.gcc.1442582075.1056020003" name="/" resourcePath="">
 						<toolChain id="com.android.toolchain.gcc.1400756764" name="com.android.toolchain.gcc" superClass="com.android.toolchain.gcc">
 						<toolChain id="com.android.toolchain.gcc.1400756764" name="com.android.toolchain.gcc" superClass="com.android.toolchain.gcc">
 							<targetPlatform binaryParser="org.eclipse.cdt.core.ELF" id="com.android.targetPlatform.1302199400" isAbstract="false" superClass="com.android.targetPlatform"/>
 							<targetPlatform binaryParser="org.eclipse.cdt.core.ELF" id="com.android.targetPlatform.1302199400" isAbstract="false" superClass="com.android.targetPlatform"/>
-							<builder arguments="NDEBUG=1" command="ndk-build" id="com.android.builder.1818800065" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Android Builder" superClass="com.android.builder"/>
+							<builder arguments="NDK_DEBUG=1" command="ndk-build" id="com.android.builder.1818800065" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Android Builder" superClass="com.android.builder"/>
 							<tool id="com.android.gcc.compiler.1014866906" name="Android GCC Compiler" superClass="com.android.gcc.compiler">
 							<tool id="com.android.gcc.compiler.1014866906" name="Android GCC Compiler" superClass="com.android.gcc.compiler">
 								<option id="com.android.gcc.option.includePath.100688008" superClass="com.android.gcc.option.includePath" valueType="includePath">
 								<option id="com.android.gcc.option.includePath.100688008" superClass="com.android.gcc.option.includePath" valueType="includePath">
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/Torque2D/jni/include/libpng}&quot;"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/Torque2D/jni/include/libpng}&quot;"/>

+ 1 - 1
engine/compilers/android/.project

@@ -19,7 +19,7 @@
 				</dictionary>
 				</dictionary>
 				<dictionary>
 				<dictionary>
 					<key>org.eclipse.cdt.make.core.buildArguments</key>
 					<key>org.eclipse.cdt.make.core.buildArguments</key>
-					<value>NDEBUG=1</value>
+					<value>NDK_DEBUG=1</value>
 				</dictionary>
 				</dictionary>
 				<dictionary>
 				<dictionary>
 					<key>org.eclipse.cdt.make.core.buildCommand</key>
 					<key>org.eclipse.cdt.make.core.buildCommand</key>

+ 1 - 1
engine/compilers/android/AndroidManifest.xml

@@ -20,7 +20,7 @@
         android:icon="@drawable/ic_launcher"
         android:icon="@drawable/ic_launcher"
         android:label="@string/app_name"
         android:label="@string/app_name"
         android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
         android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
-        android:hardwareAccelerated="true">
+        android:hardwareAccelerated="true" android:hasCode="true" android:debuggable="true">
         <activity
         <activity
             android:name="android.app.NativeActivity"
             android:name="android.app.NativeActivity"
             android:label="@string/app_name"
             android:label="@string/app_name"

+ 8 - 6
engine/compilers/android/jni/Android.mk

@@ -28,14 +28,16 @@ LOCAL_PATH := $(MY_LOCAL_PATH)
 include $(CLEAR_VARS)
 include $(CLEAR_VARS)
 
 
 LOCAL_MODULE    := libopenal-prebuilt
 LOCAL_MODULE    := libopenal-prebuilt
-LOCAL_SRC_FILES := ../../../lib/openal/Android/$(TARGET_ARCH_ABI)/libopenal.so
+#LOCAL_SRC_FILES := ../../../lib/openal/Android/$(TARGET_ARCH_ABI)/libopenal.so
+LOCAL_SRC_FILES := ../../../lib/openal/Android/$(TARGET_ARCH_ABI)/libopenal.a
 LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../../../lib/openal/Android
 LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../../../lib/openal/Android
-$(info $(shell ($(LOCAL_PATH)/copylib.sh $(LOCAL_PATH) $(TARGET_ARCH_ABI))))
-
-include $(PREBUILT_SHARED_LIBRARY)
+include $(PREBUILT_STATIC_LIBRARY)
+#include $(PREBUILT_SHARED_LIBRARY)
 
 
 LOCAL_PATH := $(MY_LOCAL_PATH)
 LOCAL_PATH := $(MY_LOCAL_PATH)
 
 
+include $(CLEAR_VARS)
+
 LOCAL_MODULE    := torque2d
 LOCAL_MODULE    := torque2d
 LOCAL_C_INCLUDES := $(LOCAL_PATH) \
 LOCAL_C_INCLUDES := $(LOCAL_PATH) \
 					$(LOCAL_PATH)/../../../lib/ljpeg \
 					$(LOCAL_PATH)/../../../lib/ljpeg \
@@ -525,8 +527,8 @@ LOCAL_SRC_FILES :=  ../../../lib/ljpeg/jcapimin.c \
 			   
 			   
 LOCAL_CFLAGS := -DENABLE_CONSOLE_MSGS -D__ANDROID__ -DTORQUE_OS_ANDROID -DGL_GLEXT_PROTOTYPES -O0 -fsigned-char   
 LOCAL_CFLAGS := -DENABLE_CONSOLE_MSGS -D__ANDROID__ -DTORQUE_OS_ANDROID -DGL_GLEXT_PROTOTYPES -O0 -fsigned-char   
 LOCAL_LDLIBS    := -llog -landroid -lEGL -lGLESv1_CM -lz -lOpenSLES -L../../../lib/openal/Android/$(TARGET_ARCH_ABI)
 LOCAL_LDLIBS    := -llog -landroid -lEGL -lGLESv1_CM -lz -lOpenSLES -L../../../lib/openal/Android/$(TARGET_ARCH_ABI)
-LOCAL_STATIC_LIBRARIES := android_native_app_glue libpng-prebuilt
-LOCAL_SHARED_LIBRARIES := libopenal-prebuilt
+LOCAL_STATIC_LIBRARIES := android_native_app_glue libpng-prebuilt libopenal-prebuilt
+#LOCAL_SHARED_LIBRARIES := libopenal-prebuilt
 
 
 LOCAL_ARM_MODE := arm
 LOCAL_ARM_MODE := arm
 
 

+ 0 - 3
engine/compilers/android/jni/copylib.sh

@@ -1,3 +0,0 @@
-#!/bin/bash
-echo copying openal lib to $2
-cp $1/../../../lib/openal/Android/$2/libopenal.so $1/../obj/local/$2/libopenal.so

+ 1 - 0
engine/compilers/android/project.properties

@@ -12,3 +12,4 @@
 
 
 # Project target.
 # Project target.
 target=android-18
 target=android-18
+android.library=false

+ 14 - 0
engine/source/game/defaultGame.cc

@@ -382,6 +382,20 @@ bool DefaultGame::mainInitialize(int argc, const char **argv)
 #endif
 #endif
     #endif
     #endif
 
 
+#ifdef TORQUE_OS_ANDROID
+
+      //-Mat this is a bit of a hack, but if we don't want the network, we shut it off now.
+    // We can't do it until we've run the entry script, otherwise the script variable will not have ben loaded
+    bool usesNet = false; //dAtob( Con::getVariable( "$pref::iOS::UseNetwork" ) );
+    if( !usesNet ) {
+        Net::shutdown();
+    }
+
+#ifdef TORQUE_OS_ANDROID_PROFILE
+    AndroidProfilerProfilerInit();
+#endif
+    #endif
+
    return true;
    return true;
 }
 }
 
 

+ 4 - 0
engine/source/graphics/DynamicTexture.h

@@ -51,6 +51,10 @@ public:
     ~DynamicTexture();
     ~DynamicTexture();
 
 
     void setSize( const U32 texelWidth, const U32 texelHeight );
     void setSize( const U32 texelWidth, const U32 texelHeight );
+    TextureHandle getTextureHandle()
+    {
+    	return mTextureHandle;
+    }
 };
 };
 
 
 #endif // _DYNAMIC_TEXTURE_H_
 #endif // _DYNAMIC_TEXTURE_H_

+ 6 - 1
engine/source/platform/platformFileIO.h

@@ -19,7 +19,6 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 // IN THE SOFTWARE.
 // IN THE SOFTWARE.
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-
 #ifndef _PLATFORM_FILEIO_H_
 #ifndef _PLATFORM_FILEIO_H_
 #define _PLATFORM_FILEIO_H_
 #define _PLATFORM_FILEIO_H_
 
 
@@ -62,6 +61,12 @@ private:
    Status currentStatus;   ///< Current status of the file (Ok, IOError, etc.).
    Status currentStatus;   ///< Current status of the file (Ok, IOError, etc.).
    U32 capability;         ///< Keeps track of file capabilities.
    U32 capability;         ///< Keeps track of file capabilities.
 
 
+#ifdef TORQUE_OS_ANDROID
+    U8* buffer;
+   	U32 size;
+   	U32 filePointer;
+#endif
+
    File(const File&);              ///< This is here to disable the copy constructor.
    File(const File&);              ///< This is here to disable the copy constructor.
    File& operator=(const File&);   ///< This is here to disable assignment.
    File& operator=(const File&);   ///< This is here to disable assignment.
 
 

+ 2 - 2
engine/source/platformAndroid/AndroidConsole.cpp

@@ -122,12 +122,12 @@ void AndroidConsole::processConsoleLine(const char *consoleLine)
 {
 {
    if(consoleEnabled)
    if(consoleEnabled)
    {
    {
-         printf("%s\n", consoleLine);
+         adprintf("%s\n", consoleLine);
    }
    }
 	//%PUAP%
 	//%PUAP%
 	if(debugOutputEnabled)
 	if(debugOutputEnabled)
 	{
 	{
-		printf("%s\n", consoleLine);
+		adprintf("%s\n", consoleLine);
 	}
 	}
 
 
 }
 }

+ 190 - 319
engine/source/platformAndroid/AndroidFileio.cpp

@@ -19,12 +19,12 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 // IN THE SOFTWARE.
 // IN THE SOFTWARE.
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-
 #include "platform/platform.h"
 #include "platform/platform.h"
 #include "platformAndroid/platformAndroid.h"
 #include "platformAndroid/platformAndroid.h"
 #include "platform/platformFileIO.h"
 #include "platform/platformFileIO.h"
 #include "collection/vector.h"
 #include "collection/vector.h"
 #include "string/stringTable.h"
 #include "string/stringTable.h"
+#include "string/stringUnit.h"
 #include "console/console.h"
 #include "console/console.h"
 #include "debug/profiler.h"
 #include "debug/profiler.h"
 #include "io/resource/resourceManager.h"
 #include "io/resource/resourceManager.h"
@@ -45,24 +45,18 @@
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 bool Platform::fileDelete(const char * name)
 bool Platform::fileDelete(const char * name)
 {
 {
-   if(!name )
-      return(false);
-   
-   if (dStrlen(name) > MAX_MAC_PATH_LONG)
-      Con::warnf("Platform::FileDelete() - Filename length is pretty long...");
+   Con::warnf("Platform::FileDelete() - Not supported on android.");
    
    
-   return(remove(name) == 0); // remove returns 0 on success
+   return false;
 }
 }
 
 
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 bool dFileTouch(const char *path)
 bool dFileTouch(const char *path)
 {
 {
-   if (!path || !*path) 
-      return false;
-   
-   // set file at path's modification and access times to now.
-   return( utimes( path, NULL) == 0); // utimes returns 0 on success.
+	Con::warnf("Platform::dFileTouch() - Not supported on android.");
+
+	return true;
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
@@ -76,7 +70,9 @@ bool dFileTouch(const char *path)
 File::File()
 File::File()
 : currentStatus(Closed), capability(0)
 : currentStatus(Closed), capability(0)
 {
 {
-   handle = NULL;
+   buffer = NULL;
+   size = 0;
+   filePointer = 0;
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
@@ -88,8 +84,8 @@ File::File()
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 File::~File()
 File::~File()
 {
 {
-   close();
-   handle = NULL;
+	if (buffer != NULL)
+		close();
 }
 }
 
 
 
 
@@ -107,55 +103,37 @@ File::Status File::open(const char *filename, const AccessMode openMode)
       Con::warnf("File::open: Filename length is pretty long...");
       Con::warnf("File::open: Filename length is pretty long...");
    
    
    // Close the file if it was already open...
    // Close the file if it was already open...
-   if (currentStatus != Closed)
+   if (currentStatus != Closed || buffer != NULL)
       close();
       close();
    
    
    // create the appropriate type of file...
    // create the appropriate type of file...
    switch (openMode)
    switch (openMode)
    {
    {
       case Read:
       case Read:
-         handle = (void *)fopen(filename, "rb"); // read only
-         break;
+    	filePointer = 0;
+    	buffer = (U8*)_AndroidLoadFile(filename, &size);
+		if (buffer == NULL) {
+			currentStatus = UnknownError;
+		}
+		break;
       case Write:
       case Write:
-         handle = (void *)fopen(filename, "wb"); // write only
-         break;
+    	  AssertFatal(false, "File::open: Write not supported on Android");
+          return currentStatus;
       case ReadWrite:
       case ReadWrite:
-         handle = (void *)fopen(filename, "ab+"); // write(append) and read
-         break;
+    	  AssertFatal(false, "File::open: ReadWrite not supported on Android");
+    	  return currentStatus;
       case WriteAppend:
       case WriteAppend:
-         handle = (void *)fopen(filename, "ab"); // write(append) only
-         break;
+    	  AssertFatal(false, "File::open: WriteAppend not supported on Android");
+    	  return currentStatus;
       default:
       default:
          AssertFatal(false, "File::open: bad access mode");
          AssertFatal(false, "File::open: bad access mode");
    }
    }
    
    
-   // handle not created successfully
-   if (handle == NULL)                
-      return setStatus();
-   
-   // successfully created file, so set the file capabilities...
-   switch (openMode)
-   {
-      case Read:
-         capability = FileRead;
-         break;
-      case Write:
-      case WriteAppend:
-         capability = FileWrite;
-         break;
-      case ReadWrite:
-         capability = FileRead | FileWrite;
-         break;
-      default:
-         AssertFatal(false, "File::open: bad access mode");
-   }
+   capability = FileRead;
    
    
    // must set the file status before setting the position.
    // must set the file status before setting the position.
    currentStatus = Ok;
    currentStatus = Ok;
-   
-   if (openMode == ReadWrite)
-      setPosition(0);
-   
+
    // success!
    // success!
    return currentStatus;                                
    return currentStatus;                                
 }
 }
@@ -166,9 +144,9 @@ File::Status File::open(const char *filename, const AccessMode openMode)
 U32 File::getPosition() const
 U32 File::getPosition() const
 {
 {
    AssertFatal(currentStatus != Closed , "File::getPosition: file closed");
    AssertFatal(currentStatus != Closed , "File::getPosition: file closed");
-   AssertFatal(handle != NULL, "File::getPosition: invalid file handle");
+   AssertFatal(buffer != NULL, "File::getPosition: invalid file buffer");
    
    
-   return ftell((FILE*)handle);
+   return filePointer;
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
@@ -186,7 +164,7 @@ U32 File::getPosition() const
 File::Status File::setPosition(S32 position, bool absolutePos)
 File::Status File::setPosition(S32 position, bool absolutePos)
 {
 {
    AssertFatal(Closed != currentStatus, "File::setPosition: file closed");
    AssertFatal(Closed != currentStatus, "File::setPosition: file closed");
-   AssertFatal(handle != NULL, "File::setPosition: invalid file handle");
+   AssertFatal(buffer != NULL, "File::setPosition: invalid file buffer");
    
    
    if (currentStatus != Ok && currentStatus != EOS )
    if (currentStatus != Ok && currentStatus != EOS )
       return currentStatus;
       return currentStatus;
@@ -197,16 +175,16 @@ File::Status File::setPosition(S32 position, bool absolutePos)
       // absolute position
       // absolute position
       AssertFatal(0 <= position, "File::setPosition: negative absolute position");
       AssertFatal(0 <= position, "File::setPosition: negative absolute position");
       // position beyond EOS is OK
       // position beyond EOS is OK
-      fseek((FILE*)handle, position, SEEK_SET);
-      finalPos = ftell((FILE*)handle);
+      filePointer = position;
+      finalPos = filePointer;
    }
    }
    else
    else
    {
    {
       // relative position
       // relative position
       AssertFatal((getPosition() + position) >= 0, "File::setPosition: negative relative position");
       AssertFatal((getPosition() + position) >= 0, "File::setPosition: negative relative position");
       // position beyond EOS is OK
       // position beyond EOS is OK
-      fseek((FILE*)handle, position, SEEK_CUR);
-      finalPos = ftell((FILE*)handle);
+      filePointer += position;
+      finalPos = filePointer;
    }
    }
    
    
    // ftell returns -1 on error. set error status
    // ftell returns -1 on error. set error status
@@ -230,17 +208,11 @@ File::Status File::setPosition(S32 position, bool absolutePos)
 U32 File::getSize() const
 U32 File::getSize() const
 {
 {
    AssertWarn(Closed != currentStatus, "File::getSize: file closed");
    AssertWarn(Closed != currentStatus, "File::getSize: file closed");
-   AssertFatal(handle != NULL, "File::getSize: invalid file handle");
+   AssertFatal(buffer != NULL, "File::getSize: invalid file buffer");
    
    
    if (Ok == currentStatus || EOS == currentStatus)
    if (Ok == currentStatus || EOS == currentStatus)
    {
    {
-      struct stat statData;
-      
-      if(fstat(fileno((FILE*)handle), &statData) != 0)
-         return 0;
-      
-      // return the size in bytes
-      return statData.st_size;
+      return size;
    }
    }
    
    
    return 0;
    return 0;
@@ -254,13 +226,10 @@ U32 File::getSize() const
 File::Status File::flush()
 File::Status File::flush()
 {
 {
    AssertFatal(Closed != currentStatus, "File::flush: file closed");
    AssertFatal(Closed != currentStatus, "File::flush: file closed");
-   AssertFatal(handle != NULL, "File::flush: invalid file handle");
+   AssertFatal(buffer != NULL, "File::flush: invalid file buffer");
    AssertFatal(true == hasCapability(FileWrite), "File::flush: cannot flush a read-only file");
    AssertFatal(true == hasCapability(FileWrite), "File::flush: cannot flush a read-only file");
    
    
-   if (fflush((FILE*)handle) != 0)
-      return setStatus();
-   else
-      return currentStatus = Ok;
+   return setStatus();
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
@@ -275,12 +244,14 @@ File::Status File::close()
       return currentStatus;
       return currentStatus;
    
    
    // it's not, so close it...
    // it's not, so close it...
-   if (handle != NULL)
+   if (buffer != NULL)
    {
    {
-      if (fclose((FILE*)handle) != 0)
-         return setStatus();
+		delete[] buffer;
+		buffer = NULL;
+		size = 0;
+		filePointer = 0;
    }
    }
-   handle = NULL;
+
    return currentStatus = Closed;
    return currentStatus = Closed;
 }
 }
 
 
@@ -297,19 +268,7 @@ File::Status File::getStatus() const
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 File::Status File::setStatus()
 File::Status File::setStatus()
 {
 {
-   switch (errno)
-   {
-      case EACCES:   // permission denied
-         currentStatus = IOError;
-         break;
-      case EBADF:   // Bad File Pointer
-      case EINVAL:   // Invalid argument
-      case ENOENT:   // file not found
-      case ENAMETOOLONG:
-      default:
-         currentStatus = UnknownError;
-   }
-   
+   currentStatus = UnknownError;
    return currentStatus;
    return currentStatus;
 }
 }
 
 
@@ -327,10 +286,10 @@ File::Status File::setStatus(File::Status status)
 // The number of bytes read is available in bytesRead if a non-Null pointer is
 // The number of bytes read is available in bytesRead if a non-Null pointer is
 // provided.
 // provided.
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-File::Status File::read(U32 size, char *dst, U32 *bytesRead)
+File::Status File::read(U32 _size, char *dst, U32 *bytesRead)
 {
 {
    AssertFatal(Closed != currentStatus, "File::read: file closed");
    AssertFatal(Closed != currentStatus, "File::read: file closed");
-   AssertFatal(handle != NULL, "File::read: invalid file handle");
+   AssertFatal(buffer != NULL, "File::read: invalid file buffer");
    AssertFatal(NULL != dst, "File::read: NULL destination pointer");
    AssertFatal(NULL != dst, "File::read: NULL destination pointer");
    AssertFatal(true == hasCapability(FileRead), "File::read: file lacks capability");
    AssertFatal(true == hasCapability(FileRead), "File::read: file lacks capability");
    AssertWarn(0 != size, "File::read: size of zero");
    AssertWarn(0 != size, "File::read: size of zero");
@@ -339,8 +298,23 @@ File::Status File::read(U32 size, char *dst, U32 *bytesRead)
       return currentStatus;
       return currentStatus;
    
    
    // read from stream
    // read from stream
-   U32 nBytes = fread(dst, 1, size, (FILE*)handle);
+   U32 nBytes = 0;
    
    
+   if ((size-filePointer) > (_size * *bytesRead))
+   {
+   		memcpy(dst, buffer+filePointer, _size * *bytesRead);
+   		nBytes = *bytesRead;
+   }
+   else if (size-filePointer <= 0)
+   {
+	    nBytes = 0;
+   }
+   else
+   {
+	   memcpy(dst, buffer+filePointer, size-filePointer);
+	   nBytes = *bytesRead;
+   }
+
    // did we hit the end of the stream?
    // did we hit the end of the stream?
    if( nBytes != size)
    if( nBytes != size)
       currentStatus = EOS;
       currentStatus = EOS;
@@ -361,28 +335,8 @@ File::Status File::read(U32 size, char *dst, U32 *bytesRead)
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 File::Status File::write(U32 size, const char *src, U32 *bytesWritten)
 File::Status File::write(U32 size, const char *src, U32 *bytesWritten)
 {
 {
-   AssertFatal(Closed != currentStatus, "File::write: file closed");
-   AssertFatal(handle != NULL, "File::write: invalid file handle");
-   AssertFatal(NULL != src, "File::write: NULL source pointer");
-   AssertFatal(true == hasCapability(FileWrite), "File::write: file lacks capability");
-   AssertWarn(0 != size, "File::write: size of zero");
-   
-   if ((Ok != currentStatus && EOS != currentStatus) || 0 == size)
-      return currentStatus;
-
-   // write bytes to the stream
-   U32 nBytes = fwrite(src, 1, size,(FILE*)handle);
-   
-   // if we couldn't write everything, we've got a problem. set error status.
-   if(nBytes != size)
-      setStatus();
-   
-   // if bytesWritten is a valid pointer, put number of bytes read there.
-   if(bytesWritten)
-      *bytesWritten = nBytes;
-   
-   // return current File status, whether good or ill.
-   return currentStatus;
+   AssertFatal(0, "File::write: Not supported on Android.");
+   return setStatus();
 }
 }
 
 
 
 
@@ -418,16 +372,7 @@ bool Platform::getFileTimes(const char *path, FileTime *createTime, FileTime *mo
    if (!path || !*path) 
    if (!path || !*path) 
       return false;
       return false;
    
    
-   struct stat statData;
-   
-   if (stat(path, &statData) == -1)
-      return false;
-   
-   if(createTime)
-      *createTime = statData.st_ctime;
-   
-   if(modifyTime)
-      *modifyTime = statData.st_mtime;
+   Con::warnf("Platform::getFileTimes - Not supported on android.");
    
    
    return true;
    return true;
 }
 }
@@ -436,50 +381,8 @@ bool Platform::getFileTimes(const char *path, FileTime *createTime, FileTime *mo
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 bool Platform::createPath(const char *file)
 bool Platform::createPath(const char *file)
 {
 {
-    //<Mat> needless console noise
-   //Con::warnf("creating path %s",file);
-   // if the path exists, we're done.
-   struct stat statData;
-   if( stat(file, &statData) == 0 )
-   { 
-      return true;               // exists, rejoice.
-   }
-   
-   // get the parent path.
-   // we're not using basename because it's not thread safe.
-   const U32 len = dStrlen(file) + 1;
-   char parent[len];
-   bool isDirPath = false;
-   
-   dSprintf(parent, len, "%s", file);
-
-   if(parent[len - 2] == '/')
-   {
-      parent[len - 2] = '\0';    // cut off the trailing slash, if there is one
-      isDirPath = true;          // we got a trailing slash, so file is a directory.
-   }
-   
-   // recusively create the parent path.
-   // only recurse if newpath has a slash that isn't a leading slash.
-   char *slash = dStrrchr(parent,'/');
-   if( slash && slash != parent)
-   {
-      // snip the path just after the last slash.
-      slash[1] = '\0';
-      // recusively create the parent path. fail if parent path creation failed.
-      if(!Platform::createPath(parent))
-         return false;
-   }
-   
-   // create *file if it is a directory path.
-   if(isDirPath)
-   {
-      // try to create the directory
-      if( mkdir(file, 0777) != 0) // app may reside in global apps dir, and so must be writable to all.
-         return false;
-   }
-   
-   return true;
+   Con::warnf("Platform::createPath() - Not supported on android.");
+   return false;
 }
 }
 
 
 
 
@@ -566,17 +469,8 @@ bool Platform::isFile(const char *path)
 {
 {
    if (!path || !*path) 
    if (!path || !*path) 
       return false;
       return false;
-   
-   // make sure we can stat the file
-   struct stat statData;
-   if( stat(path, &statData) < 0 )
-      return false;
-   
-   // now see if it's a regular file
-   if( (statData.st_mode & S_IFMT) == S_IFREG)
-      return true;
-   
-   return false;
+
+   return android_IsFile(path);
 }
 }
 
 
 
 
@@ -586,16 +480,7 @@ bool Platform::isDirectory(const char *path)
    if (!path || !*path) 
    if (!path || !*path) 
       return false;
       return false;
    
    
-   // make sure we can stat the file
-   struct stat statData;
-   if( stat(path, &statData) < 0 )
-      return false;
-   
-   // now see if it's a directory
-   if( (statData.st_mode & S_IFMT) == S_IFDIR)
-      return true;
-   
-   return false;
+   return android_IsDir(path);
 }
 }
 
 
 
 
@@ -604,12 +489,7 @@ S32 Platform::getFileSize(const char* pFilePath)
    if (!pFilePath || !*pFilePath) 
    if (!pFilePath || !*pFilePath) 
       return 0;
       return 0;
    
    
-   struct stat statData;
-   if( stat(pFilePath, &statData) < 0 )
-      return 0;
-   
-   // and return it's size in bytes
-   return (S32)statData.st_size;
+   return android_GetFileSize(pFilePath);
 }
 }
 
 
 
 
@@ -621,49 +501,47 @@ bool Platform::isSubDirectory(const char *pathParent, const char *pathSub)
    return isDirectory((const char *)fullpath);
    return isDirectory((const char *)fullpath);
 }
 }
 
 
+void getDirectoryName(const char* path, char* name)
+{
+	int cnt = StringUnit::getUnitCount(path, "/");
+	strcpy(name,StringUnit::getUnit(path, cnt-1, "/"));
+}
+
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 // utility for platform::hasSubDirectory() and platform::dumpDirectories()
 // utility for platform::hasSubDirectory() and platform::dumpDirectories()
 // ensures that the entry is a directory, and isnt on the ignore lists.
 // ensures that the entry is a directory, and isnt on the ignore lists.
-inline bool isGoodDirectory(dirent* entry)
+inline bool isGoodDirectory(const char* path)
 {
 {
-   return (entry->d_type == DT_DIR                          // is a dir
-           && dStrcmp(entry->d_name,".") != 0                 // not here
-           && dStrcmp(entry->d_name,"..") != 0                // not parent
-           && !Platform::isExcludedDirectory(entry->d_name)); // not excluded
+   char name[80];
+   getDirectoryName(path, name);
+   return (Platform::isDirectory(path)                          // is a dir
+           && dStrcmp(name,".") != 0                 // not here
+           && dStrcmp(name,"..") != 0                // not parent
+           && !Platform::isExcludedDirectory(name)); // not excluded
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 bool Platform::hasSubDirectory(const char *path) 
 bool Platform::hasSubDirectory(const char *path) 
 {
 {
-   DIR *dir;
-   dirent *entry;
-   
-   dir = opendir(path);
-   if(!dir)
-      return false; // we got a bad path, so no, it has no subdirectory.
-   
-   while( true )
-   {
-       entry = readdir(dir);
-       if ( entry == NULL )
-           break;
-       
-      if(isGoodDirectory(entry) ) 
-      {
-         closedir(dir);
-         return true; // we have a subdirectory, that isnt on the exclude list.
-      }
-   }
-   
-   closedir(dir);
-   return false; // either this dir had no subdirectories, or they were all on the exclude list.
+	android_InitDirList(path);
+	char dir[80];
+	char pdir[255];
+	strcpy(dir,"");
+	android_GetNextDir(path, dir);
+	while(strcmp(dir,"") != 0)
+	{
+		sprintf(pdir, "%s/%s", path, dir);
+		if (isGoodDirectory(pdir))
+			return true;
+		android_GetNextDir(path, dir);
+	}
+
+    return false;
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 bool recurseDumpDirectories(const char *basePath, const char *path, Vector<StringTableEntry> &directoryVector, S32 depth, bool noBasePath)
 bool recurseDumpDirectories(const char *basePath, const char *path, Vector<StringTableEntry> &directoryVector, S32 depth, bool noBasePath)
 {
 {
-   DIR *dir;
-   dirent *entry;
    const U32 len = dStrlen(basePath) + dStrlen(path) + 2;
    const U32 len = dStrlen(basePath) + dStrlen(path) + 2;
    char pathbuf[len];
    char pathbuf[len];
    
    
@@ -671,68 +549,51 @@ bool recurseDumpDirectories(const char *basePath, const char *path, Vector<Strin
    dSprintf(pathbuf, len, "%s/%s", basePath, path);
    dSprintf(pathbuf, len, "%s/%s", basePath, path);
    
    
    // be sure it opens.
    // be sure it opens.
-   dir = opendir(pathbuf);
-   if(!dir)
-      return false;
+   android_InitDirList(pathbuf);
    
    
    // look inside the current directory
    // look inside the current directory
-   while( true )
+   char dir[80];
+   char pdir[255];
+   strcpy(dir,"");
+   android_GetNextDir(pathbuf, dir);
+   while(strcmp(dir,"") != 0)
    {
    {
-       entry = readdir(dir);
-       if ( entry == NULL )
-           break;
-       
-      // we just want directories.
-      if(!isGoodDirectory(entry))
-         continue;
+		sprintf(pdir, "%s/%s", pathbuf, dir);
+		if (!isGoodDirectory(pdir))
+			return false;
       
       
-      // TODO: better unicode file name handling
-      //      // Apple's file system stores unicode file names in decomposed form.
-      //      // ATSUI will not reliably draw out just the accent character by itself,
-      //      // so our text renderer has no chance of rendering decomposed form unicode.
-      //      // We have to convert the entry name to precomposed normalized form.
-      //      CFStringRef cfdname = CFStringCreateWithCString(NULL,entry->d_name,kCFStringEncodingUTF8);
-      //      CFMutableStringRef cfentryName = CFStringCreateMutableCopy(NULL,0,cfdname);
-      //      CFStringNormalize(cfentryName,kCFStringNormalizationFormC);
-      //      
-      //      U32 entryNameLen = CFStringGetLength(cfentryName) * 4 + 1;
-      //      char entryName[entryNameLen];
-      //      CFStringGetCString(cfentryName, entryName, entryNameLen, kCFStringEncodingUTF8);
-      //      entryName[entryNameLen-1] = NULL; // sometimes, CFStringGetCString() doesn't null terminate.
-      //      CFRelease(cfentryName);
-      //      CFRelease(cfdname);
+		// construct the new path string, we'll need this below.
+        const U32 newpathlen = dStrlen(path) + dStrlen(dir) + 2;
+        char newpath[newpathlen];
+        if(dStrlen(path) > 0)
+        {
+            dSprintf(newpath, newpathlen, "%s/%s", path, dir);
+        }
+        else
+        {
+           dSprintf(newpath, newpathlen, "%s", dir);
+        }
       
       
-      // construct the new path string, we'll need this below.
-      const U32 newpathlen = dStrlen(path) + dStrlen(entry->d_name) + 2;
-      char newpath[newpathlen];
-      if(dStrlen(path) > 0)
-      {
-          dSprintf(newpath, newpathlen, "%s/%s", path, entry->d_name);
-      }
-      else
-      {
-         dSprintf(newpath, newpathlen, "%s", entry->d_name);
-      }
-      
-      // we have a directory, add it to the list.
-      if( noBasePath )
-      {
-         directoryVector.push_back(StringTable->insert(newpath));
-      }
-      else
-      {
-         const U32 fullpathlen = dStrlen(basePath) + dStrlen(newpath) + 2;
-         char fullpath[fullpathlen];
-         dSprintf(fullpath, fullpathlen, "%s/%s",basePath,newpath);
-         directoryVector.push_back(StringTable->insert(fullpath));
-      }
+        // we have a directory, add it to the list.
+        if( noBasePath )
+        {
+           directoryVector.push_back(StringTable->insert(newpath));
+        }
+        else
+        {
+           const U32 fullpathlen = dStrlen(basePath) + dStrlen(newpath) + 2;
+           char fullpath[fullpathlen];
+           dSprintf(fullpath, fullpathlen, "%s/%s",basePath,newpath);
+           directoryVector.push_back(StringTable->insert(fullpath));
+        }
       
       
-      // and recurse into it, unless we've run out of depth
-      if( depth != 0) // passing a val of -1 as the recurse depth means go forever
-         recurseDumpDirectories(basePath, newpath, directoryVector, depth-1, noBasePath);
-   }
-   closedir(dir);
-   return true;
+        // and recurse into it, unless we've run out of depth
+        if( depth != 0) // passing a val of -1 as the recurse depth means go forever
+           recurseDumpDirectories(basePath, newpath, directoryVector, depth-1, noBasePath);
+
+        android_GetNextDir(pathbuf, dir);
+     }
+     return true;
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
@@ -761,56 +622,66 @@ bool Platform::dumpDirectories(const char *path, Vector<StringTableEntry> &direc
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 static bool recurseDumpPath(const char* curPath, Vector<Platform::FileInfo>& fileVector, U32 depth)
 static bool recurseDumpPath(const char* curPath, Vector<Platform::FileInfo>& fileVector, U32 depth)
 {
 {
-	//TODO: is this used on android?
-   DIR *dir;
-   dirent *entry;
-   
-   // be sure it opens.
-   dir = opendir(curPath);
-   if(!dir)
-      return false;
+   android_InitDirList(curPath);
    
    
    // look inside the current directory
    // look inside the current directory
-   while( true )
+   char dir[80];
+   char file[80];
+   strcpy(dir,"");
+   strcpy(file,"");
+   android_GetNextDir(curPath, dir);
+   android_GetNextFile(curPath, file);
+
+   while(strcmp(file,"") != 0)
+   {
+  	 // construct the full file path. we need this to get the file size and to recurse
+  	 const U32 len = dStrlen(curPath) + dStrlen(file) + 2;
+  	 char pathbuf[len];
+  	 dSprintf( pathbuf, len, "%s/%s", curPath, file);
+
+  	 //add the file entry to the list
+  	 // unlike recurseDumpDirectories(), we need to return more complex info here.
+  	  //<Mat> commented this out in case we ever want a dir file printout again
+  	  //printf( "File Name: %s ", entry->d_name );
+  	 const U32 fileSize = Platform::getFileSize(pathbuf);
+  	 fileVector.increment();
+  	 Platform::FileInfo& rInfo = fileVector.last();
+  	 rInfo.pFullPath = StringTable->insert(curPath);
+  	 rInfo.pFileName = StringTable->insert(file);
+  	 rInfo.fileSize  = fileSize;
+
+  	 android_GetNextFile(curPath, file);
+   }
+
+   while(strcmp(dir,"") != 0)
    {
    {
-       entry = readdir(dir);
-       if ( entry == NULL )
-           break;
-       
       // construct the full file path. we need this to get the file size and to recurse
       // construct the full file path. we need this to get the file size and to recurse
-       //TODO: android
-      const U32 len = 0;//dStrlen(curPath) + entry->d_namlen + 2;
+      const U32 len = dStrlen(curPath) + dStrlen(dir) + 2;
       char pathbuf[len];
       char pathbuf[len];
-      dSprintf( pathbuf, len, "%s/%s", curPath, entry->d_name);
-      
-      // ok, deal with directories and files seperately.
-      if( entry->d_type == DT_DIR )
-      {
-         if( depth == 0)
-            continue;
-         
-         // filter out dirs we dont want.
-         if( !isGoodDirectory(entry) )
-            continue;
-         
-         // recurse into the dir
-         recurseDumpPath( pathbuf, fileVector, depth-1);
-      }
+      if (strcmp(curPath,"") == 0)
+    	  dSprintf( pathbuf, len, "%s", dir);
       else
       else
-      {
-         //add the file entry to the list
-         // unlike recurseDumpDirectories(), we need to return more complex info here.
-          //<Mat> commented this out in case we ever want a dir file printout again
-          //printf( "File Name: %s ", entry->d_name );
-         const U32 fileSize = Platform::getFileSize(pathbuf);
-         fileVector.increment();
-         Platform::FileInfo& rInfo = fileVector.last();
-         rInfo.pFullPath = StringTable->insert(curPath);
-         rInfo.pFileName = StringTable->insert(entry->d_name);
-         rInfo.fileSize  = fileSize;
-      }
+    	  dSprintf( pathbuf, len, "%s/%s", curPath, dir);
+      
+	  if( depth == 0)
+	  {
+		  android_GetNextDir(curPath, dir);
+		continue;
+	  }
+
+	  // filter out dirs we dont want.
+	  if( !isGoodDirectory(pathbuf) )
+	  {
+		android_GetNextDir(curPath, dir);
+		continue;
+	  }
+
+	  // recurse into the dir
+	  recurseDumpPath( pathbuf, fileVector, depth-1);
+
+	  android_GetNextDir(curPath, dir);
    }
    }
-   closedir(dir);
+
    return true;
    return true;
    
    
 }
 }

+ 6 - 0
engine/source/platformAndroid/AndroidInput.cpp

@@ -834,6 +834,9 @@ bool createMouseMoveEvent( S32 touchNumber, S32 x, S32 y, S32 lastX, S32 lastY )
 {	
 {	
 	S32 currentSlot = -1;
 	S32 currentSlot = -1;
 	
 	
+	if (Canvas == NULL)
+		return false;
+
 	for( int i = 0 ; (i < MAX_TOUCH_EVENTS) && (currentSlot == -1) ; i++ )
 	for( int i = 0 ; (i < MAX_TOUCH_EVENTS) && (currentSlot == -1) ; i++ )
 	{
 	{
 		if( (lastX == lastTouches[i].lastX ) &&
 		if( (lastX == lastTouches[i].lastX ) &&
@@ -872,6 +875,9 @@ bool createMouseDownEvent( S32 touchNumber, S32 x, S32 y, U32 numTouches )
 {
 {
 	S32 vacantSlot = -1;
 	S32 vacantSlot = -1;
 	
 	
+	if (Canvas == NULL)
+		return false;
+
 	for( int i = 0 ; (i < MAX_TOUCH_EVENTS) && (vacantSlot == -1) ; i++ )
 	for( int i = 0 ; (i < MAX_TOUCH_EVENTS) && (vacantSlot == -1) ; i++ )
 	{
 	{
 		if( lastTouches[i].lastX == -1 )
 		if( lastTouches[i].lastX == -1 )

+ 278 - 25
engine/source/platformAndroid/T2DActivity.cpp

@@ -70,11 +70,14 @@ double timeGetTime() {
 
 
 bool T2DActivity::createFramebuffer() {
 bool T2DActivity::createFramebuffer() {
 	
 	
+	framebufferTexture.setSize(platState.engine->width, platState.engine->height);
 	glGenFramebuffersOES(1, &viewFramebuffer);
 	glGenFramebuffersOES(1, &viewFramebuffer);
+	framebufferTexture.getTextureHandle().setClamp(true);
 	glGenRenderbuffersOES(1, &viewRenderbuffer);
 	glGenRenderbuffersOES(1, &viewRenderbuffer);
 	
 	
 	glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
 	glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
 	glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
 	glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
+	glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, platState.engine->width, platState.engine->height);
 	glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);
 	glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);
 	
 	
 	glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
 	glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
@@ -372,7 +375,7 @@ static int32_t engine_handle_input(struct android_app* app, AInputEvent* event)
         		point.x = AMotionEvent_getX(event, i);
         		point.x = AMotionEvent_getX(event, i);
         		point.y = AMotionEvent_getY(event, i);
         		point.y = AMotionEvent_getY(event, i);
 
 
-        		if (rawLastTouches.size() < i)
+        		if (rawLastTouches.size() < i+1)
         			rawLastTouches.push_back(point);
         			rawLastTouches.push_back(point);
         		else
         		else
         		{
         		{
@@ -542,7 +545,7 @@ bool _AndroidGetFileDescriptor(const char* fileName, int32_t *mDescriptor, off_t
 	return false;
 	return false;
 }
 }
 
 
-char* _AndroidLoadFile(const char* fileName, int *size) {
+char* _AndroidLoadFile(const char* fileName, U32 *size) {
 
 
 	AAsset *asset;
 	AAsset *asset;
 	uint8_t buf[1024];
 	uint8_t buf[1024];
@@ -669,7 +672,7 @@ static int engine_init_display(struct engine* engine) {
     };
     };
 
 
     static const EGLint ctx_attribs[] = {
     static const EGLint ctx_attribs[] = {
-          EGL_CONTEXT_CLIENT_VERSION, 2,
+          EGL_CONTEXT_CLIENT_VERSION, 1,
           EGL_NONE
           EGL_NONE
         };
         };
 
 
@@ -723,9 +726,9 @@ static int engine_init_display(struct engine* engine) {
 
 
     if (SetupCompleted == false)
     if (SetupCompleted == false)
     {
     {
-    	activity.finishGLSetup();
     	_AndroidRunTorqueMain(engine);
     	_AndroidRunTorqueMain(engine);
-
+    	activity.finishGLSetup();
+    	SetupCompleted = true;
     }
     }
     else
     else
     {
     {
@@ -788,31 +791,24 @@ static void engine_update_frame(struct engine* engine) {
 	if (timeElapsed > 1.0f)
 	if (timeElapsed > 1.0f)
 		timeElapsed = 1.0f; // clamp it
 		timeElapsed = 1.0f; // clamp it
 
 
-	if (SetupCompleted == false) {
-		if (timeElapsed > 0.25f) {
-			SetupCompleted = true;
-			lastSystemTime = timeGetTime();
+	lastSystemTime = thisSysTime;
+
+	if (keyboardShowing) {
+		if (keyboardTransition > 0.0f) {
+			keyboardTransition -= timeElapsed * 2.0f;
+			if (keyboardTransition < 0.0f)
+				keyboardTransition = 0.0f;
 		}
 		}
 	} else {
 	} else {
-
-		lastSystemTime = thisSysTime;
-
-		if (keyboardShowing) {
-			if (keyboardTransition > 0.0f) {
-				keyboardTransition -= timeElapsed * 2.0f;
-				if (keyboardTransition < 0.0f)
-					keyboardTransition = 0.0f;
-			}
-		} else {
-			if (keyboardTransition < 1.0f) {
-				keyboardTransition += timeElapsed * 2.0f;
-				if (keyboardTransition > 1.0f)
-					keyboardTransition = 1.0f;
-			}
+		if (keyboardTransition < 1.0f) {
+			keyboardTransition += timeElapsed * 2.0f;
+			if (keyboardTransition > 1.0f)
+				keyboardTransition = 1.0f;
 		}
 		}
+	}
 
 
+	if (SetupCompleted == true)
 		_AndroidGameInnerLoop();
 		_AndroidGameInnerLoop();
-	}
 
 
 }
 }
 
 
@@ -999,6 +995,8 @@ struct engine engine;
  */
  */
 void android_main(struct android_app* state) {
 void android_main(struct android_app* state) {
 
 
+	sleep(10);
+
     // Make sure glue isn't stripped.
     // Make sure glue isn't stripped.
     app_dummy();
     app_dummy();
 
 
@@ -1021,6 +1019,8 @@ void android_main(struct android_app* state) {
         engine.state = *(struct saved_state*)state->savedState;
         engine.state = *(struct saved_state*)state->savedState;
     }
     }
 
 
+    platState.engine = &engine;
+
     keepScreenOn();
     keepScreenOn();
 
 
     //This is to help the debugger catch up.  If you dont have this you cant debug this early in the execution
     //This is to help the debugger catch up.  If you dont have this you cant debug this early in the execution
@@ -1099,6 +1099,259 @@ void android_main(struct android_app* state) {
     engine_term_display(&engine, true);
     engine_term_display(&engine, true);
 }
 }
 
 
+void android_InitDirList(const char* dir)
+{
+	// Attaches the current thread to the JVM.
+	jint lResult;
+	jint lFlags = 0;
+
+	JavaVM* lJavaVM = engine.app->activity->vm;
+	JNIEnv* lJNIEnv = engine.app->activity->env;
+
+	JavaVMAttachArgs lJavaVMAttachArgs;
+	lJavaVMAttachArgs.version = JNI_VERSION_1_6;
+	lJavaVMAttachArgs.name = "NativeThread";
+	lJavaVMAttachArgs.group = NULL;
+
+	lResult=lJavaVM->AttachCurrentThread(&lJNIEnv, &lJavaVMAttachArgs);
+	if (lResult == JNI_ERR) {
+		return;
+	}
+
+	// Retrieves NativeActivity.
+	jobject lNativeActivity = engine.app->activity->clazz;
+	jclass ClassNativeActivity = lJNIEnv->GetObjectClass(lNativeActivity);
+
+	jmethodID getClassLoader = lJNIEnv->GetMethodID(ClassNativeActivity,"getClassLoader", "()Ljava/lang/ClassLoader;");
+	jobject cls = lJNIEnv->CallObjectMethod(lNativeActivity, getClassLoader);
+	jclass classLoader = lJNIEnv->FindClass("java/lang/ClassLoader");
+	jmethodID findClass = lJNIEnv->GetMethodID(classLoader, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
+	jstring strClassName = lJNIEnv->NewStringUTF("com/garagegames/torque2d/FileWalker");
+	jclass FileWalkerClass = (jclass)lJNIEnv->CallObjectMethod(cls, findClass, strClassName);
+	jstring strDirName = lJNIEnv->NewStringUTF(dir);
+	jmethodID MethodFileWalker = lJNIEnv->GetStaticMethodID(FileWalkerClass, "InitDirList", "(Landroid/content/Context;Ljava/lang/String;)V");
+	lJNIEnv->CallStaticObjectMethod(FileWalkerClass, MethodFileWalker, lNativeActivity, strDirName);
+	lJNIEnv->DeleteLocalRef(strClassName);
+	lJNIEnv->DeleteLocalRef(strDirName);
+
+	// Finished with the JVM.
+	lJavaVM->DetachCurrentThread();
+
+
+}
+
+void android_GetNextDir(const char* pdir, char *dir)
+{
+	// Attaches the current thread to the JVM.
+	jint lResult;
+	jint lFlags = 0;
+
+	JavaVM* lJavaVM = engine.app->activity->vm;
+	JNIEnv* lJNIEnv = engine.app->activity->env;
+
+	JavaVMAttachArgs lJavaVMAttachArgs;
+	lJavaVMAttachArgs.version = JNI_VERSION_1_6;
+	lJavaVMAttachArgs.name = "NativeThread";
+	lJavaVMAttachArgs.group = NULL;
+
+	lResult=lJavaVM->AttachCurrentThread(&lJNIEnv, &lJavaVMAttachArgs);
+	if (lResult == JNI_ERR) {
+		return;
+	}
+
+	// Retrieves NativeActivity.
+	jobject lNativeActivity = engine.app->activity->clazz;
+	jclass ClassNativeActivity = lJNIEnv->GetObjectClass(lNativeActivity);
+
+	jmethodID getClassLoader = lJNIEnv->GetMethodID(ClassNativeActivity,"getClassLoader", "()Ljava/lang/ClassLoader;");
+	jobject cls = lJNIEnv->CallObjectMethod(lNativeActivity, getClassLoader);
+	jclass classLoader = lJNIEnv->FindClass("java/lang/ClassLoader");
+	jmethodID findClass = lJNIEnv->GetMethodID(classLoader, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
+	jstring strClassName = lJNIEnv->NewStringUTF("com/garagegames/torque2d/FileWalker");
+	jclass FileWalkerClass = (jclass)lJNIEnv->CallObjectMethod(cls, findClass, strClassName);
+	jstring strDirName = lJNIEnv->NewStringUTF(pdir);
+	jmethodID MethodFileWalker = lJNIEnv->GetStaticMethodID(FileWalkerClass, "GetNextDir", "(Ljava/lang/String;)Ljava/lang/String;");
+	jstring jpath = (jstring)lJNIEnv->CallStaticObjectMethod(FileWalkerClass, MethodFileWalker, strDirName);
+	if (jpath != NULL)
+	{
+		const char* path = lJNIEnv->GetStringUTFChars(jpath, NULL);
+		strcpy(dir, path);
+        dir[strlen(path)] = '\0';
+        lJNIEnv->ReleaseStringUTFChars(jpath, path);
+	}
+	else
+	{
+		strcpy(dir,"");
+	}
+
+	lJNIEnv->DeleteLocalRef(strClassName);
+	lJNIEnv->DeleteLocalRef(strDirName);
+
+	// Finished with the JVM.
+	lJavaVM->DetachCurrentThread();
+}
+
+void android_GetNextFile(const char* pdir, char *file)
+{
+	// Attaches the current thread to the JVM.
+	jint lResult;
+	jint lFlags = 0;
+
+	JavaVM* lJavaVM = engine.app->activity->vm;
+	JNIEnv* lJNIEnv = engine.app->activity->env;
+
+	JavaVMAttachArgs lJavaVMAttachArgs;
+	lJavaVMAttachArgs.version = JNI_VERSION_1_6;
+	lJavaVMAttachArgs.name = "NativeThread";
+	lJavaVMAttachArgs.group = NULL;
+
+	lResult=lJavaVM->AttachCurrentThread(&lJNIEnv, &lJavaVMAttachArgs);
+	if (lResult == JNI_ERR) {
+		return;
+	}
+
+	// Retrieves NativeActivity.
+	jobject lNativeActivity = engine.app->activity->clazz;
+	jclass ClassNativeActivity = lJNIEnv->GetObjectClass(lNativeActivity);
+
+	jmethodID getClassLoader = lJNIEnv->GetMethodID(ClassNativeActivity,"getClassLoader", "()Ljava/lang/ClassLoader;");
+	jobject cls = lJNIEnv->CallObjectMethod(lNativeActivity, getClassLoader);
+	jclass classLoader = lJNIEnv->FindClass("java/lang/ClassLoader");
+	jmethodID findClass = lJNIEnv->GetMethodID(classLoader, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
+	jstring strClassName = lJNIEnv->NewStringUTF("com/garagegames/torque2d/FileWalker");
+	jclass FileWalkerClass = (jclass)lJNIEnv->CallObjectMethod(cls, findClass, strClassName);
+	jstring strDirName = lJNIEnv->NewStringUTF(pdir);
+	jmethodID MethodFileWalker = lJNIEnv->GetStaticMethodID(FileWalkerClass, "GetNextFile", "(Ljava/lang/String;)Ljava/lang/String;");
+	jstring jpath = (jstring)lJNIEnv->CallStaticObjectMethod(FileWalkerClass, MethodFileWalker, strDirName);
+	if (jpath != NULL)
+	{
+		const char* path = lJNIEnv->GetStringUTFChars(jpath, NULL);
+		strcpy(file, path);
+        file[strlen(path)] = '\0';
+        lJNIEnv->ReleaseStringUTFChars(jpath, path);
+	}
+	else
+	{
+		strcpy(file,"");
+	}
+
+	lJNIEnv->DeleteLocalRef(strClassName);
+	lJNIEnv->DeleteLocalRef(strDirName);
+
+	// Finished with the JVM.
+	lJavaVM->DetachCurrentThread();
+}
+
+bool android_IsFile(const char* path)
+{
+	// Attaches the current thread to the JVM.
+	jint lResult;
+	jint lFlags = 0;
+
+	JavaVM* lJavaVM = engine.app->activity->vm;
+	JNIEnv* lJNIEnv = engine.app->activity->env;
+
+	JavaVMAttachArgs lJavaVMAttachArgs;
+	lJavaVMAttachArgs.version = JNI_VERSION_1_6;
+	lJavaVMAttachArgs.name = "NativeThread";
+	lJavaVMAttachArgs.group = NULL;
+
+	lResult=lJavaVM->AttachCurrentThread(&lJNIEnv, &lJavaVMAttachArgs);
+	if (lResult == JNI_ERR) {
+		return false;
+	}
+
+	// Retrieves NativeActivity.
+	jobject lNativeActivity = engine.app->activity->clazz;
+	jclass ClassNativeActivity = lJNIEnv->GetObjectClass(lNativeActivity);
+
+	jmethodID getClassLoader = lJNIEnv->GetMethodID(ClassNativeActivity,"getClassLoader", "()Ljava/lang/ClassLoader;");
+	jobject cls = lJNIEnv->CallObjectMethod(lNativeActivity, getClassLoader);
+	jclass classLoader = lJNIEnv->FindClass("java/lang/ClassLoader");
+	jmethodID findClass = lJNIEnv->GetMethodID(classLoader, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
+	jstring strClassName = lJNIEnv->NewStringUTF("com/garagegames/torque2d/FileWalker");
+	jclass FileWalkerClass = (jclass)lJNIEnv->CallObjectMethod(cls, findClass, strClassName);
+	jstring strDirName = lJNIEnv->NewStringUTF(path);
+	jmethodID MethodFileWalker = lJNIEnv->GetStaticMethodID(FileWalkerClass, "IsFile", "(Landroid/content/Context;Ljava/lang/String;)Z");
+	jboolean jpath = lJNIEnv->CallStaticBooleanMethod(FileWalkerClass, MethodFileWalker, lNativeActivity, strDirName);
+	if (jpath)
+	{
+		lJNIEnv->DeleteLocalRef(strClassName);
+		lJNIEnv->DeleteLocalRef(strDirName);
+
+		// Finished with the JVM.
+		lJavaVM->DetachCurrentThread();
+		return true;
+	}
+	else
+	{
+		lJNIEnv->DeleteLocalRef(strClassName);
+		lJNIEnv->DeleteLocalRef(strDirName);
+
+		// Finished with the JVM.
+		lJavaVM->DetachCurrentThread();
+		return false;
+	}
+}
+
+bool android_IsDir(const char* path)
+{
+	// Attaches the current thread to the JVM.
+	jint lResult;
+	jint lFlags = 0;
+
+	JavaVM* lJavaVM = engine.app->activity->vm;
+	JNIEnv* lJNIEnv = engine.app->activity->env;
+
+	JavaVMAttachArgs lJavaVMAttachArgs;
+	lJavaVMAttachArgs.version = JNI_VERSION_1_6;
+	lJavaVMAttachArgs.name = "NativeThread";
+	lJavaVMAttachArgs.group = NULL;
+
+	lResult=lJavaVM->AttachCurrentThread(&lJNIEnv, &lJavaVMAttachArgs);
+	if (lResult == JNI_ERR) {
+		return false;
+	}
+
+	// Retrieves NativeActivity.
+	jobject lNativeActivity = engine.app->activity->clazz;
+	jclass ClassNativeActivity = lJNIEnv->GetObjectClass(lNativeActivity);
+
+	jmethodID getClassLoader = lJNIEnv->GetMethodID(ClassNativeActivity,"getClassLoader", "()Ljava/lang/ClassLoader;");
+	jobject cls = lJNIEnv->CallObjectMethod(lNativeActivity, getClassLoader);
+	jclass classLoader = lJNIEnv->FindClass("java/lang/ClassLoader");
+	jmethodID findClass = lJNIEnv->GetMethodID(classLoader, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
+	jstring strClassName = lJNIEnv->NewStringUTF("com/garagegames/torque2d/FileWalker");
+	jclass FileWalkerClass = (jclass)lJNIEnv->CallObjectMethod(cls, findClass, strClassName);
+	jstring strDirName = lJNIEnv->NewStringUTF(path);
+	jmethodID MethodFileWalker = lJNIEnv->GetStaticMethodID(FileWalkerClass, "IsDir", "(Landroid/content/Context;Ljava/lang/String;)Z");
+	jboolean jpath = lJNIEnv->CallStaticBooleanMethod(FileWalkerClass, MethodFileWalker, lNativeActivity, strDirName);
+	if (jpath)
+	{
+		lJNIEnv->DeleteLocalRef(strClassName);
+		lJNIEnv->DeleteLocalRef(strDirName);
+
+		// Finished with the JVM.
+		lJavaVM->DetachCurrentThread();
+		return true;
+	}
+	else
+	{
+		lJNIEnv->DeleteLocalRef(strClassName);
+		lJNIEnv->DeleteLocalRef(strDirName);
+
+		// Finished with the JVM.
+		lJavaVM->DetachCurrentThread();
+		return false;
+	}
+}
+
+U32 android_GetFileSize(const char* pFilePath)
+{
+	//TODO: get file size
+	return 0;
+}
+
 ConsoleFunction(doDeviceVibrate, void, 1, 1, "Makes the device do a quick vibration. Only works on devices with vibration functionality.")
 ConsoleFunction(doDeviceVibrate, void, 1, 1, "Makes the device do a quick vibration. Only works on devices with vibration functionality.")
 {
 {
 	// Vibrate for 500 milliseconds
 	// Vibrate for 500 milliseconds

+ 12 - 2
engine/source/platformAndroid/T2DActivity.h

@@ -22,6 +22,7 @@
 #ifndef T2DACTIVITY_H
 #ifndef T2DACTIVITY_H
 #define T2DACTIVITY_H
 #define T2DACTIVITY_H
 #include "platformAndroid/AndroidGL2ES.h"
 #include "platformAndroid/AndroidGL2ES.h"
+#include "graphics/DynamicTexture.h"
 #include <errno.h>
 #include <errno.h>
 #include <EGL/egl.h>
 #include <EGL/egl.h>
 //#include <android/sensor.h>
 //#include <android/sensor.h>
@@ -39,6 +40,13 @@ extern void adprintf(const char* fmt,...);
 extern int _AndroidGetScreenWidth();
 extern int _AndroidGetScreenWidth();
 extern int _AndroidGetScreenHeight();
 extern int _AndroidGetScreenHeight();
 extern S32 _AndroidGameGetOrientation();
 extern S32 _AndroidGameGetOrientation();
+extern char* _AndroidLoadFile(const char* fileName, U32 *size);
+extern void android_InitDirList(const char* dir);
+extern void android_GetNextDir(const char* pdir, char *dir);
+extern void android_GetNextFile(const char* pdir, char *file);
+extern bool android_IsDir(const char* path);
+extern bool android_IsFile(const char* path);
+extern U32 android_GetFileSize(const char* pFilePath);
 
 
 /**
 /**
  * Our saved state data.
  * Our saved state data.
@@ -72,12 +80,14 @@ class T2DActivity {
 
 
 private:
 private:
 	// The pixel dimensions of the backbuffer
 	// The pixel dimensions of the backbuffer
-	GLint backingWidth;
-	GLint backingHeight;
+	S32 backingWidth;
+	S32 backingHeight;
 	
 	
     // OpenGL names for the renderbuffer and framebuffers used to render to this view
     // OpenGL names for the renderbuffer and framebuffers used to render to this view
 	GLuint viewRenderbuffer, viewFramebuffer;
 	GLuint viewRenderbuffer, viewFramebuffer;
 	
 	
+	DynamicTexture framebufferTexture;
+
 	// OpenGL name for the depth buffer that is attached to viewFramebuffer, if it exists (0 if it does not exist)
 	// OpenGL name for the depth buffer that is attached to viewFramebuffer, if it exists (0 if it does not exist)
 	GLuint depthRenderbuffer;
 	GLuint depthRenderbuffer;
     
     

+ 0 - 1
engine/source/platformAndroid/main.cpp

@@ -34,7 +34,6 @@ bool appIsRunning = true;
 
 
 int _AndroidRunTorqueMain(engine *eng)
 int _AndroidRunTorqueMain(engine *eng)
 {
 {
-	platState.engine = eng;
     platState.firstThreadId = ThreadManager::getCurrentThreadId();
     platState.firstThreadId = ThreadManager::getCurrentThreadId();
     
     
 	printf("performing mainInit()\n");
 	printf("performing mainInit()\n");