ソースを参照

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="">
 						<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");