Prechádzať zdrojové kódy

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 rokov pred
rodič
commit
bb2bda49c6

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

@@ -22,7 +22,7 @@
 					<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">
 							<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">
 								<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;"/>

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

@@ -19,7 +19,7 @@
 				</dictionary>
 				<dictionary>
 					<key>org.eclipse.cdt.make.core.buildArguments</key>
-					<value>NDEBUG=1</value>
+					<value>NDK_DEBUG=1</value>
 				</dictionary>
 				<dictionary>
 					<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:label="@string/app_name"
         android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
-        android:hardwareAccelerated="true">
+        android:hardwareAccelerated="true" android:hasCode="true" android:debuggable="true">
         <activity
             android:name="android.app.NativeActivity"
             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)
 
 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
-$(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)
 
+include $(CLEAR_VARS)
+
 LOCAL_MODULE    := torque2d
 LOCAL_C_INCLUDES := $(LOCAL_PATH) \
 					$(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_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
 

+ 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.
 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
 
+#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;
 }
 

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

@@ -51,6 +51,10 @@ public:
     ~DynamicTexture();
 
     void setSize( const U32 texelWidth, const U32 texelHeight );
+    TextureHandle getTextureHandle()
+    {
+    	return mTextureHandle;
+    }
 };
 
 #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
 // IN THE SOFTWARE.
 //-----------------------------------------------------------------------------
-
 #ifndef _PLATFORM_FILEIO_H_
 #define _PLATFORM_FILEIO_H_
 
@@ -62,6 +61,12 @@ private:
    Status currentStatus;   ///< Current status of the file (Ok, IOError, etc.).
    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& 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)
    {
-         printf("%s\n", consoleLine);
+         adprintf("%s\n", consoleLine);
    }
 	//%PUAP%
 	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
 // IN THE SOFTWARE.
 //-----------------------------------------------------------------------------
-
 #include "platform/platform.h"
 #include "platformAndroid/platformAndroid.h"
 #include "platform/platformFileIO.h"
 #include "collection/vector.h"
 #include "string/stringTable.h"
+#include "string/stringUnit.h"
 #include "console/console.h"
 #include "debug/profiler.h"
 #include "io/resource/resourceManager.h"
@@ -45,24 +45,18 @@
 //-----------------------------------------------------------------------------
 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)
 {
-   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()
 : currentStatus(Closed), capability(0)
 {
-   handle = NULL;
+   buffer = NULL;
+   size = 0;
+   filePointer = 0;
 }
 
 //-----------------------------------------------------------------------------
@@ -88,8 +84,8 @@ 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...");
    
    // Close the file if it was already open...
-   if (currentStatus != Closed)
+   if (currentStatus != Closed || buffer != NULL)
       close();
    
    // create the appropriate type of file...
    switch (openMode)
    {
       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:
-         handle = (void *)fopen(filename, "wb"); // write only
-         break;
+    	  AssertFatal(false, "File::open: Write not supported on Android");
+          return currentStatus;
       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:
-         handle = (void *)fopen(filename, "ab"); // write(append) only
-         break;
+    	  AssertFatal(false, "File::open: WriteAppend not supported on Android");
+    	  return currentStatus;
       default:
          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.
    currentStatus = Ok;
-   
-   if (openMode == ReadWrite)
-      setPosition(0);
-   
+
    // success!
    return currentStatus;                                
 }
@@ -166,9 +144,9 @@ File::Status File::open(const char *filename, const AccessMode openMode)
 U32 File::getPosition() const
 {
    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)
 {
    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 )
       return currentStatus;
@@ -197,16 +175,16 @@ File::Status File::setPosition(S32 position, bool absolutePos)
       // absolute position
       AssertFatal(0 <= position, "File::setPosition: negative absolute position");
       // position beyond EOS is OK
-      fseek((FILE*)handle, position, SEEK_SET);
-      finalPos = ftell((FILE*)handle);
+      filePointer = position;
+      finalPos = filePointer;
    }
    else
    {
       // relative position
       AssertFatal((getPosition() + position) >= 0, "File::setPosition: negative relative position");
       // 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
@@ -230,17 +208,11 @@ File::Status File::setPosition(S32 position, bool absolutePos)
 U32 File::getSize() const
 {
    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)
    {
-      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;
@@ -254,13 +226,10 @@ U32 File::getSize() const
 File::Status File::flush()
 {
    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");
    
-   if (fflush((FILE*)handle) != 0)
-      return setStatus();
-   else
-      return currentStatus = Ok;
+   return setStatus();
 }
 
 //-----------------------------------------------------------------------------
@@ -275,12 +244,14 @@ File::Status File::close()
       return currentStatus;
    
    // 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;
 }
 
@@ -297,19 +268,7 @@ File::Status File::getStatus() const
 //-----------------------------------------------------------------------------
 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;
 }
 
@@ -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
 // 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(handle != NULL, "File::read: invalid file handle");
+   AssertFatal(buffer != NULL, "File::read: invalid file buffer");
    AssertFatal(NULL != dst, "File::read: NULL destination pointer");
    AssertFatal(true == hasCapability(FileRead), "File::read: file lacks capability");
    AssertWarn(0 != size, "File::read: size of zero");
@@ -339,8 +298,23 @@ File::Status File::read(U32 size, char *dst, U32 *bytesRead)
       return currentStatus;
    
    // 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?
    if( nBytes != size)
       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)
 {
-   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) 
       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;
 }
@@ -436,50 +381,8 @@ bool Platform::getFileTimes(const char *path, FileTime *createTime, FileTime *mo
 //-----------------------------------------------------------------------------
 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) 
       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) 
       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) 
       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);
 }
 
+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()
 // 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) 
 {
-   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)
 {
-   DIR *dir;
-   dirent *entry;
    const U32 len = dStrlen(basePath) + dStrlen(path) + 2;
    char pathbuf[len];
    
@@ -671,68 +549,51 @@ bool recurseDumpDirectories(const char *basePath, const char *path, Vector<Strin
    dSprintf(pathbuf, len, "%s/%s", basePath, path);
    
    // be sure it opens.
-   dir = opendir(pathbuf);
-   if(!dir)
-      return false;
+   android_InitDirList(pathbuf);
    
    // 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)
 {
-	//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
-   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
-       //TODO: android
-      const U32 len = 0;//dStrlen(curPath) + entry->d_namlen + 2;
+      const U32 len = dStrlen(curPath) + dStrlen(dir) + 2;
       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
-      {
-         //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;
    
 }

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

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

@@ -70,11 +70,14 @@ double timeGetTime() {
 
 bool T2DActivity::createFramebuffer() {
 	
+	framebufferTexture.setSize(platState.engine->width, platState.engine->height);
 	glGenFramebuffersOES(1, &viewFramebuffer);
+	framebufferTexture.getTextureHandle().setClamp(true);
 	glGenRenderbuffersOES(1, &viewRenderbuffer);
 	
 	glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
 	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);
 	
 	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.y = AMotionEvent_getY(event, i);
 
-        		if (rawLastTouches.size() < i)
+        		if (rawLastTouches.size() < i+1)
         			rawLastTouches.push_back(point);
         		else
         		{
@@ -542,7 +545,7 @@ bool _AndroidGetFileDescriptor(const char* fileName, int32_t *mDescriptor, off_t
 	return false;
 }
 
-char* _AndroidLoadFile(const char* fileName, int *size) {
+char* _AndroidLoadFile(const char* fileName, U32 *size) {
 
 	AAsset *asset;
 	uint8_t buf[1024];
@@ -669,7 +672,7 @@ static int engine_init_display(struct engine* engine) {
     };
 
     static const EGLint ctx_attribs[] = {
-          EGL_CONTEXT_CLIENT_VERSION, 2,
+          EGL_CONTEXT_CLIENT_VERSION, 1,
           EGL_NONE
         };
 
@@ -723,9 +726,9 @@ static int engine_init_display(struct engine* engine) {
 
     if (SetupCompleted == false)
     {
-    	activity.finishGLSetup();
     	_AndroidRunTorqueMain(engine);
-
+    	activity.finishGLSetup();
+    	SetupCompleted = true;
     }
     else
     {
@@ -788,31 +791,24 @@ static void engine_update_frame(struct engine* engine) {
 	if (timeElapsed > 1.0f)
 		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 {
-
-		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();
-	}
 
 }
 
@@ -999,6 +995,8 @@ struct engine engine;
  */
 void android_main(struct android_app* state) {
 
+	sleep(10);
+
     // Make sure glue isn't stripped.
     app_dummy();
 
@@ -1021,6 +1019,8 @@ void android_main(struct android_app* state) {
         engine.state = *(struct saved_state*)state->savedState;
     }
 
+    platState.engine = &engine;
+
     keepScreenOn();
 
     //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);
 }
 
+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.")
 {
 	// Vibrate for 500 milliseconds

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

@@ -22,6 +22,7 @@
 #ifndef T2DACTIVITY_H
 #define T2DACTIVITY_H
 #include "platformAndroid/AndroidGL2ES.h"
+#include "graphics/DynamicTexture.h"
 #include <errno.h>
 #include <EGL/egl.h>
 //#include <android/sensor.h>
@@ -39,6 +40,13 @@ extern void adprintf(const char* fmt,...);
 extern int _AndroidGetScreenWidth();
 extern int _AndroidGetScreenHeight();
 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.
@@ -72,12 +80,14 @@ class T2DActivity {
 
 private:
 	// 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
 	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)
 	GLuint depthRenderbuffer;
     

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

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