浏览代码

Merge branch 'develop' into develop-tmp

Mark Sibly 7 年之前
父节点
当前提交
fc94d79972
共有 34 个文件被更改,包括 589 次插入295 次删除
  1. 1 0
      bananas/assetstest/assets/test1.txt
  2. 1 0
      bananas/assetstest/assets/test2.txt
  3. 73 0
      bananas/assetstest/assetstest.monkey2
  4. 57 0
      modules/android/android.monkey2
  5. 6 0
      modules/android/module.json
  6. 3 0
      modules/emscripten/emscripten.monkey2
  7. 3 1
      modules/emscripten/module.json
  8. 4 0
      modules/miniz/miniz.monkey2
  9. 3 3
      modules/mojo/audio/audio.monkey2
  10. 3 51
      modules/mojo/audio/native/bbmusic.cpp
  11. 3 1
      modules/mojo/audio/native/bbmusic.h
  12. 3 0
      modules/mojo/graphics/shader.monkey2
  13. 10 3
      modules/mojo3d/assets/shaders/imports/pbr.glsl
  14. 1 1
      modules/mojo3d/loader/gltf2loader.monkey2
  15. 3 2
      modules/mojo3d/mojo3d.monkey2
  16. 44 0
      modules/mojo3d/scene/entities/pivot.monkey2
  17. 16 7
      modules/mojo3d/scene/native/collisiondetect.cpp
  18. 2 0
      modules/mojo3d/tests/room.monkey2
  19. 8 8
      modules/monkey/newdocs/language/arrays.md
  20. 17 40
      modules/monkey/newdocs/language/enums.md
  21. 23 12
      modules/monkey/newdocs/language/strings.md
  22. 42 26
      modules/monkey/newdocs/language/types.md
  23. 5 3
      modules/monkey/newdocs/language/variants.md
  24. 3 1
      modules/stb-image/stb-image.monkey2
  25. 118 46
      modules/std/filesystem/filesystem.monkey2
  26. 53 0
      modules/std/filesystem/native/filesystem.cpp
  27. 4 2
      modules/std/filesystem/native/filesystem.h
  28. 1 2
      modules/std/graphics/pixmaploader.monkey2
  29. 11 4
      modules/std/misc/zipfile.monkey2
  30. 1 1
      modules/std/module.json
  31. 19 52
      modules/std/std.monkey2
  32. 4 12
      modules/std/stream/filestream.monkey2
  33. 36 16
      products/android/Monkey2Game/app/src/main/java/org/libsdl/app/SDLActivity.java
  34. 8 1
      products/android/Monkey2Game/build.gradle

+ 1 - 0
bananas/assetstest/assets/test1.txt

@@ -0,0 +1 @@
+Test One

+ 1 - 0
bananas/assetstest/assets/test2.txt

@@ -0,0 +1 @@
+Test Two - a bit longer.

+ 73 - 0
bananas/assetstest/assetstest.monkey2

@@ -0,0 +1,73 @@
+Namespace myapp
+
+#Import "<std>"
+#Import "<mojo>"
+
+Using std..
+Using mojo..
+
+#Import "assets/"
+
+Class MyWindow Extends Window
+
+	Method New( title:String="Simple mojo app",width:Int=640,height:Int=480,flags:WindowFlags=Null )
+
+		Super.New( title,width,height,flags )
+		
+		Print "AssetsDir()=~q"+AssetsDir()+"~q"
+		
+#If __DESKTOP_TARGET__
+		Print "DesktopDir()=~q"+DesktopDir()+"~q"
+		
+		Print "HomeDir()=~q"+HomeDir()+"~q"
+#endif
+		
+#If __MOBILE_TARGET__
+		Print "InternalDir()=~q"+InternalDir()+"~q"
+		DeleteFile( "internal::test.txt" )
+		SaveString( "Some Test Internal Text!","internal::test.txt" )
+		Print "LoadString(~qinternal::test.txt~q)=~q"+LoadString( "internal::test.txt" )+"~q"
+		
+		Print "ExternalDir()=~q"+ExternalDir()+"~q"
+		DeleteFile( "external::test.txt" )
+		SaveString( "Some Test External Text!","external::test.txt" )
+		Print "LoadString(~qexternal::test.txt~q)=~q"+LoadString( "external::test.txt" )+"~q"
+		
+#endif
+	
+		Print "LoadDir(~qasset::~q):"
+		PrintDir( "asset::" ) 
+		
+		Print "LoadDir(AssetsDir())"
+		PrintDir( AssetsDir() )
+		
+		Print "RealPath(AssetsDir())=~q"+RealPath( AssetsDir() )+"~q"
+		
+		Print "RealPath(~qasset::~q)=~q"+RealPath( "asset::" )+"~q"
+		
+	End
+	
+	Method PrintDir( dir:String,indent:String=" " )
+
+		For Local file:=Eachin LoadDir( dir )
+			Print indent+"file=~q"+file+"~q size="+GetFileSize( dir+file )+" type="+Int( GetFileType( dir+file ) )
+		Next
+	End		
+
+	Method OnRender( canvas:Canvas ) Override
+	
+		App.RequestRender()
+	
+		canvas.DrawText( "Hello World!",Width/2,Height/2,.5,.5 )
+	End
+	
+End
+
+Function Main()
+
+	New AppInstance
+	
+	New MyWindow
+	
+	App.Run()
+End

+ 57 - 0
modules/android/android.monkey2

@@ -0,0 +1,57 @@
+
+Namespace android
+
+#If __TARGET__="android"
+
+#Import "<libc>"
+#Import "<sdl2>"
+#Import "<jni>"
+
+#Import "<sdl2/SDL/src/core/android/SDL_android.h>"
+'#Import "<asset_manager.h>"
+'#Import "<SDL.h>"
+
+Extern Private
+
+'this is actually in SDL...
+Function Android_JNI_GetAssetManager:Void Ptr()
+
+Extern
+
+Const AASSET_MODE_UNKNOWN:Int	'0
+Const AASSET_MODE_RANDOM:Int	'1
+Const AASSET_MODE_STREAMING:Int	'2
+Const AASSET_MODE_BUFFER:Int	'3
+ 
+Class AAssetManager Extends Void
+End
+
+Class AAssetDir Extends Void
+End
+
+Class AAsset Extends Void
+End
+
+Function AAssetManager_open:AAsset( mgr:AAssetManager,filename:CString,mode:Int )
+Function AAssetManager_openDir:AAssetDir( mgr:AAssetManager,dirName:CString )
+	
+Function AAssetDir_getNextFileName:CString( assetDir:AAssetDir )
+Function AAssetDir_rewind( assetDir:AAssetDir )
+Function AAssetDir_close( assetDir:AAssetDir )
+	
+Function AAsset_getLength:Int( asset:AAsset )
+Function AAsset_getRemainingLength:Int( asset:AAsset )
+Function AAsset_read:Int( asset:AAsset,buf:Void Ptr,count:Int )
+Function AAsset_seek:Int( asset:AAsset,offset:Int,whence:Int )
+Function AAsset_close( asset:AAsset )
+	
+Public
+
+Function GetAssetManager:AAssetManager()
+	
+	Return Cast<AAssetManager>( Android_JNI_GetAssetManager() )
+End
+
+#endif
+
+

+ 6 - 0
modules/android/module.json

@@ -0,0 +1,6 @@
+{
+	"module":"android",
+	"version":"1.0.0",
+	"support":"http://monkeycoder.co.nz",
+	"depends":["libc","sdl2","jni"]
+}

+ 3 - 0
modules/emscripten/emscripten.monkey2

@@ -3,6 +3,9 @@ Namespace emscripten
 
 
 #If __TARGET__="emscripten"
 #If __TARGET__="emscripten"
 
 
+#Import "<libc>"
+#Import "<sdl2>"
+
 #Import "<emscripten.h>"
 #Import "<emscripten.h>"
 
 
 Extern
 Extern

+ 3 - 1
modules/emscripten/module.json

@@ -1,4 +1,6 @@
 {
 {
 	"module":"emscripten",
 	"module":"emscripten",
-	"version":"1.0.0"
+	"version":"1.0.0",
+	"support":"http://monkeycoder.co.nz",
+	"depends":["libc","sdl2"]
 }
 }

+ 4 - 0
modules/miniz/miniz.monkey2

@@ -91,6 +91,10 @@ Function mz_zip_reader_locate_file:Int( pZip:mz_zip_archive Ptr,pName:CString,pC
 'Returns detailed information about an archive file entry.
 'Returns detailed information about an archive file entry.
 Function mz_zip_reader_file_stat:Int( pZip:mz_zip_archive Ptr,file_index:Int,pStat:mz_zip_archive_file_stat Ptr )
 Function mz_zip_reader_file_stat:Int( pZip:mz_zip_archive Ptr,file_index:Int,pStat:mz_zip_archive_file_stat Ptr )
 
 
+'Determines if an archive file entry is a directory entry.
+Function mz_zip_reader_is_file_a_directory:Int( pZip:mz_zip_archive Ptr,file_index:Int )
+Function mz_zip_reader_is_file_encrypted:Int( pZip:mz_zip_archive Ptr,file_index:Int )
+
 'Extracts a archive file to a memory buffer.
 'Extracts a archive file to a memory buffer.
 Function mz_zip_reader_extract_to_mem:Int( pZip:mz_zip_archive Ptr,file_index:Int,pBuf:Void Ptr,buf_size:Int,flags:Int )
 Function mz_zip_reader_extract_to_mem:Int( pZip:mz_zip_archive Ptr,file_index:Int,pBuf:Void Ptr,buf_size:Int,flags:Int )
 Function mz_zip_reader_extract_file_to_mem:Int( pZip:mz_zip_archive Ptr,pFilename:CString,pBuf:Void Ptr,buf_size:Int,flags:Int )
 Function mz_zip_reader_extract_file_to_mem:Int( pZip:mz_zip_archive Ptr,pFilename:CString,pBuf:Void Ptr,buf_size:Int,flags:Int )

+ 3 - 3
modules/mojo/audio/audio.monkey2

@@ -12,7 +12,7 @@ Namespace mojo.audio
 
 
 Extern Private
 Extern Private
 
 
-Function playMusic:Int( path:CString,callback:Int,source:Int )="bbMusic::playMusic"
+Function playMusic:Int( file:libc.FILE ptr,callback:Int,source:Int )="bbMusic::playMusic"
 Function getBuffersProcessed:Int( source:Int )="bbMusic::getBuffersProcessed"
 Function getBuffersProcessed:Int( source:Int )="bbMusic::getBuffersProcessed"
 Function endMusic:Void( source:Int )="bbMusic::endMusic"
 Function endMusic:Void( source:Int )="bbMusic::endMusic"
 	
 	
@@ -72,9 +72,9 @@ Class AudioDevice
 			finished()
 			finished()
 		End,True )
 		End,True )
 		
 		
-		path=filesystem.RealPath( path )
+		Local file:=filesystem.OpenCFile( path,"rb" )
 		
 		
-		Local sampleRate:=playMusic( path,callback,channel._alSource )
+		Local sampleRate:=playMusic( file,callback,channel._alSource )
 	
 	
 		If Not sampleRate
 		If Not sampleRate
 			async.DestroyAsyncCallback( callback )
 			async.DestroyAsyncCallback( callback )

+ 3 - 51
modules/mojo/audio/native/bbmusic.cpp

@@ -13,9 +13,7 @@
 #include "../../../std/async/native/async_cb.h"
 #include "../../../std/async/native/async_cb.h"
 #include "../../../stb-vorbis/native/stb-vorbis.h"
 #include "../../../stb-vorbis/native/stb-vorbis.h"
 
 
-#if __ANDROID__
-#include "../../../sdl2/SDL/src/core/android/SDL_android.h"
-#endif
+#include <std/filesystem/native/filesystem.h>
 
 
 #include <atomic>
 #include <atomic>
 
 
@@ -25,7 +23,7 @@ namespace{
 
 
 	Counter *counters;
 	Counter *counters;
 	
 	
-	//Yikes! We have to make a little atomic counter class!
+	//little atomic counter class...
 	//
 	//
 	struct Counter{
 	struct Counter{
 		
 		
@@ -57,59 +55,13 @@ namespace{
 		return 0;
 		return 0;
 	}
 	}
 }
 }
-	
 
 
 namespace bbMusic{
 namespace bbMusic{
 
 
-#if __ANDROID__
-	
-	int android_read( void *cookie,char *buf,int size ){
-	
-	  return AAsset_read( (AAsset*)cookie,buf,size );
-	}
-	
-	int android_write( void *cookie,const char* buf,int size ){
-	
-	  return EACCES; // can't provide write access to the apk
-	}
-	
-	fpos_t android_seek( void *cookie,fpos_t offset,int whence ){
-	
-	  return AAsset_seek( (AAsset*)cookie,offset,whence );
-	}
-	
-	int android_close(void* cookie) {
-	
-	  AAsset_close( (AAsset*)cookie );
-	  return 0;
-	}
-	
-#endif
-	
-	FILE *fopen( const char *path,const char *mode ){
-	
-#if __ANDROID__
-		if( !strncmp( path,"asset::",7 ) ){
-			
-			AAssetManager *assetManager=Android_JNI_GetAssetManager();
-			if( !assetManager ) return 0;
-			
-	  		AAsset* asset=AAssetManager_open( assetManager,path+7,0 );
-			if( !asset ) return 0;
-	
-	  		return funopen( asset,android_read,android_write,android_seek,android_close );
-		}
-#endif
-		return ::fopen( path,mode );
-	}
-
-	int playMusic( const char *path,int callback,int alsource ){
+	int playMusic( FILE *file,int callback,int alsource ){
 	
 	
 		const int buffer_ms=100;
 		const int buffer_ms=100;
 			
 			
-		FILE *file=fopen( path,"rb" );
-		if( !file ) return false;
-	
 		int error=0;
 		int error=0;
 		stb_vorbis *vorbis=stb_vorbis_open_file( file,0,&error,0 );
 		stb_vorbis *vorbis=stb_vorbis_open_file( file,0,&error,0 );
 		if( !vorbis ) return false;
 		if( !vorbis ) return false;

+ 3 - 1
modules/mojo/audio/native/bbmusic.h

@@ -1,7 +1,9 @@
 
 
+#include <std/filesystem/native/filesystem.h>
+
 namespace bbMusic{
 namespace bbMusic{
 
 
-	int playMusic( const char *path,int callback,int source );
+	int playMusic( FILE *file,int callback,int source );
 	
 	
 	int getBuffersProcessed( int source );
 	int getBuffersProcessed( int source );
 	
 	

+ 3 - 0
modules/mojo/graphics/shader.monkey2

@@ -423,6 +423,9 @@ Class Shader
 		
 		
 			Local defs:="#define MX2_RENDERPASS "+rpass+"~n"
 			Local defs:="#define MX2_RENDERPASS "+rpass+"~n"
 			
 			
+'			Print "~n~n*************** Vertex Shader ***************~n"+defs+vs
+'			Print "~n~n*************** Fragment Shader ****************~n"+defs+fs
+			
 			Local vshader:=glCompile( GL_VERTEX_SHADER,defs+vs )
 			Local vshader:=glCompile( GL_VERTEX_SHADER,defs+vs )
 			Local fshader:=glCompile( GL_FRAGMENT_SHADER,defs+fs )
 			Local fshader:=glCompile( GL_FRAGMENT_SHADER,defs+fs )
 				
 				

+ 10 - 3
modules/mojo3d/assets/shaders/imports/pbr.glsl

@@ -7,9 +7,12 @@
 
 
 float pointAtten( float d,float r ){
 float pointAtten( float d,float r ){
 
 
-	float atten=max( 1.0-d*d/(r*r),0.0 );atten*=atten;
+//	Doesn't work on ANGLE!
+//	float atten=1.0-min( (d*d)/(r*r),1.0 );atten*=atten;
+
+	float atten=1.0-min( d/r,1.0 );atten*=atten;
 	
 	
-//	float d=length( lvec ),atten=1.0/(1.0+d*d);
+//	float atten=1.0/(1.0+d*d);
 
 
 	return atten;
 	return atten;
 }
 }
@@ -34,7 +37,11 @@ void emitPbrFragment( vec3 color,float metalness,float roughness,vec3 position,v
 	vec3 lvec=r_LightViewMatrix[3].xyz-position;
 	vec3 lvec=r_LightViewMatrix[3].xyz-position;
 
 
 	float atten=pointAtten( length( lvec ),r_LightRange );
 	float atten=pointAtten( length( lvec ),r_LightRange );
-
+	
+#ifdef GL_ES
+	if( atten!=atten ) return;
+#endif
+	
 	lvec=normalize( lvec );
 	lvec=normalize( lvec );
 	
 	
 #elif MX2_SPOTLIGHT
 #elif MX2_SPOTLIGHT

+ 1 - 1
modules/mojo3d/loader/gltf2loader.monkey2

@@ -149,7 +149,7 @@ Class Gltf2Loader
 			Local start:=ULong( GetData( source.bufferView ) )
 			Local start:=ULong( GetData( source.bufferView ) )
 			Local length:=source.bufferView.byteLength
 			Local length:=source.bufferView.byteLength
 			
 			
-			Local path:="memblock::("+start+","+length+")"
+			Local path:="memory::("+start+","+length+")"
 			If source.mimeType.StartsWith( "image/" ) path+="."+texture.source.mimeType.Slice( 6 )
 			If source.mimeType.StartsWith( "image/" ) path+="."+texture.source.mimeType.Slice( 6 )
 				
 				
 			tex=Texture.Load( path,flags )
 			tex=Texture.Load( path,flags )

+ 3 - 2
modules/mojo3d/mojo3d.monkey2

@@ -38,12 +38,13 @@ Using reflection..
 
 
 #Import "scene/entities/camera"
 #Import "scene/entities/camera"
 #Import "scene/entities/light"
 #Import "scene/entities/light"
+#Import "scene/entities/pivot"
+#Import "scene/entities/renderable"
 #Import "scene/entities/model"
 #Import "scene/entities/model"
+#Import "scene/entities/sprite"
 #Import "scene/entities/particlebuffer"
 #Import "scene/entities/particlebuffer"
 #Import "scene/entities/particlematerial"
 #Import "scene/entities/particlematerial"
 #Import "scene/entities/particlesystem"
 #Import "scene/entities/particlesystem"
-#Import "scene/entities/renderable"
-#Import "scene/entities/sprite"
 
 
 #Import "scene/materials/pbrmaterial"
 #Import "scene/materials/pbrmaterial"
 #Import "scene/materials/spritematerial"
 #Import "scene/materials/spritematerial"

+ 44 - 0
modules/mojo3d/scene/entities/pivot.monkey2

@@ -0,0 +1,44 @@
+
+Namespace mojo3d
+
+#rem monkeydoc The Pivot class.
+#end
+Class Pivot Extends Entity
+
+	#rem monkeydoc Creates a new pivot.
+	#end	
+	Method New( parent:Entity=Null )
+		
+		Super.New( parent )
+		
+		Visible=True
+		
+		AddInstance()
+	End
+
+	#rem monkeydoc Copies the pivot.
+	#end
+	Method Copy:Pivot( parent:Entity=Null ) Override
+		
+		Local copy:=OnCopy( parent )
+		
+		CopyTo( copy )
+		
+		Return copy
+	End
+	
+	Protected
+
+	Method New( pivot:Pivot,parent:Entity )
+		
+		Super.New( pivot,parent )
+		
+		AddInstance( pivot )
+	End
+	
+	Method OnCopy:Pivot( parent:Entity ) Override
+		
+		Return New Pivot( Self,parent )
+	End
+	
+End

+ 16 - 7
modules/mojo3d/scene/native/collisiondetect.cpp

@@ -14,15 +14,24 @@ void collisionCallback( btDynamicsWorld *world,btScalar timeStep ){
 	
 	
 	for( int i=0;i<numManifolds;++i ){
 	for( int i=0;i<numManifolds;++i ){
 
 
-		btPersistentManifold *manifold=world->getDispatcher()->getManifoldByIndexInternal( i );
+		btPersistentManifold *contactManifold=world->getDispatcher()->getManifoldByIndexInternal( i );
         
         
-		const btCollisionObject *body0=manifold->getBody0();
-		const btCollisionObject *body1=manifold->getBody1();
-       
-//		printf( "Collision! body0=%p body1=%p\n",body0,body1 );fflush( stdout );
+		const btCollisionObject *body0=contactManifold->getBody0();
+		const btCollisionObject *body1=contactManifold->getBody1();
 		
 		
-		*_collp++=body0->getUserPointer();
-		*_collp++=body1->getUserPointer();
+        int numContacts=contactManifold->getNumContacts();
+        
+        for( int j=0;j<numContacts;++j ){
+        
+            btManifoldPoint &pt=contactManifold->getContactPoint(j);
+            
+            if( pt.getDistance()<0.0f ){
+	            
+				*_collp++=body0->getUserPointer();
+				*_collp++=body1->getUserPointer();
+				break;
+			}
+        }
 	}
 	}
 }
 }
 
 

+ 2 - 0
modules/mojo3d/tests/room.monkey2

@@ -13,6 +13,8 @@ Using mojo3d..
 
 
 Function Main()
 Function Main()
 	
 	
+	SetConfig( "MOJO_OPENGL_PROFILE","es" )
+	
 	New AppInstance
 	New AppInstance
 	
 	
 	New MyWindow
 	New MyWindow

+ 8 - 8
modules/monkey/newdocs/language/arrays.md

@@ -5,13 +5,13 @@
 
 
 An array is a linear sequence of values that can be addressed using one or more integer indices.
 An array is a linear sequence of values that can be addressed using one or more integer indices.
 
 
-Each array has an associated element type. That is, the type of the values actually stored in the array. An array's element type is a purely static property. It is only known at compile time so arrays cannot be 'downcast' at runtime.
+Each array has an associated element type. That is, the type of the values actually stored in the array. An array's element type is a purely static property. It is only known at compile time so arrays cannot be 'cast' to different array types at runtime.
 
 
-The syntax used for declaring values and variables of array type is: 
+Array variables are declared using the syntax:
 
 
-_ElementType_ `[` [`,`...] `]`
+_ElementType_`[`[`,`...]`]`
 
 
-An array can also be multidimensional, in which case the '[]' will contain 1 or more commas.
+An array can be multidimensional, in which case the '[]' will contain 1 or more commas.
 
 
 Here are some example of declaring array variables:
 Here are some example of declaring array variables:
 
 
@@ -24,13 +24,13 @@ Local stacks:Stack<Int>[]	'One dimensional array of stacks of type Int.
 
 
 @#### Creating arrays
 @#### Creating arrays
 
 
-Declaring an array does not actually create an array. To do that you must use `New`.
+Declaring an array does not actually create an array. To do that you must use the `New` operator.
 
 
 `New` can be used to create either a null intialized or value initialized array. The syntax for creating a null initialized array is:
 `New` can be used to create either a null intialized or value initialized array. The syntax for creating a null initialized array is:
 
 
 `New` _ElementType_ `[` _Sizes_ `]`
 `New` _ElementType_ `[` _Sizes_ `]`
 
 
-...where sizes is a comma separated sequence of dimension size.
+...where sizes is a comma separated sequence of dimension sizes.
 
 
 The syntax for creating a value initialized array is:
 The syntax for creating a value initialized array is:
 
 
@@ -80,8 +80,8 @@ Local ints:=New Int[]( 1,2,3 )
 ints=ints.Resize( 5 )	'ints now contains 1,2,3,0,0
 ints=ints.Resize( 5 )	'ints now contains 1,2,3,0,0
 ```
 ```
 
 
-(Note that resize does not actually resize the array! It actually returns a resized *copy* of the array.)
+Note that resize actually returns a resized *copy* of the input array. The input array is not modified in any way.
 
 
-Note that mutidimensional arrays cannot currently be sliced or resized, and you cannot create an initialized multidimensional arrays. These features are planned for the future though.
+Multidimensional arrays cannot currently be sliced or resized.
 
 
 For more information, see the [[types.Array.Resize|Array.Resize]] API documentation.
 For more information, see the [[types.Array.Resize|Array.Resize]] API documentation.

+ 17 - 40
modules/monkey/newdocs/language/enums.md

@@ -3,56 +3,33 @@
 
 
 ### Enums
 ### Enums
 
 
-`Enum` is a data type containing a set of Int constants.
+An enum is a user defined data type that contains a set of named integer constants. Enums are frequently used to implement typesafe 'flags' or 'bitmasks'.
 
 
-By default the members will receive values starting from zero and incemented by one for each new member. You can assign a chosen value to each member when declaring them.
+Unintialized enum members are automatically assigned constant integer values starting with 0 and increasing by 1 for each successive enum member:
 
 
 ```
 ```
-Enum myBasicEnum
-	a,b,c 'a=0, b=1, c=2
+Enum MyEnum
+	A,B,C			'A, B, C will be assigned the values 0, 1, 2.
+	D,E,F			'D, E, F will be assigned the values 4, 5, 6.
 End
 End
 ```
 ```
-```
-Enum myCustomEnum
-	a=7
-	b=31,c,d 'c=32, d=33
-End
-```
-The values can be accessed with the postfix member acces operator (`.`).
-Enums values are implicitly converted to integral values when assigned to it.
-```
-Local i:UInt=myCustomEnum.b
-```
-
-You can also create `Enum` variables. An `Enum` variable contains an Int variable in addition to it's constant members (default value is zero).
 
 
-Bitwise operators (|,&,~) can be used with Enums variables and Enums members to compute combinations. Such Enums most often contain powers of 2 numbers as members! (1,2,4,8,16,32,64,... and 0 if needed).
+You can also initialize enum members with a constant integer value:
 
 
-A bitmask Enum example:
-```
-Enum Flags 'a classic Enum. (4 bits bitmask)
-	None=0
-  A=$0001 'bin OOOI dec 1
-  B=$0002 'bin OOIO dec 2
-  C=$0004 'bin OIOO dec 4
-  D=$0008 'bin IOOO dec 8
-End
-```
-An enum with modifiers example (in this case the bitwise operators should be used with at least one modifier):
 ```
 ```
-Enum Foo '(modifiers on 5th and 6th bit)
-	None=0
-	A=1,B,C,D,E,F,G,H,J,K,L,M ' max 15 because the 5th bit is used for modifier
-	Modifier_A=$0010 'bin IOOOO dec 16
-	Modifier_B=$0020 'bin IOOOOO dec 32
+Enum MyEnum
+	A=10,B=20,C=30	'A, B, C will be assigned the values 10,20,30
+	D,E,F			'D, E, F will be assigned the values 31, 32, 33.
 End
 End
 ```
 ```
 
 
-For now enums don't accept negative number literals. To assign a negative number you'll have to type a substraction until the bug is resolved.
+Enum members are accessed using the 'dot' operator:
+
 ```
 ```
-Enum Foo '(with a negative member)
-	Negative=0-1 'instead of -1
-	None=0
-	A=1,B,C,D,E,F,G,H,J,K,L,M
-End
+Local e:MyEnum=MyEnum.A
 ```
 ```
+
+Enum values can be implictly converted to any integer type, and can be used with the `&` (bitwise 'and'), `|` (bitwise 'or') and `~` (bitwise 'exclusive-or') binary operators. This allows you to use enums to represent 'bitmasks'.
+
+Enum values can also be compared with enum values of the same type, or with a `Null` which represents an enum value with the integer value 0.
+

+ 23 - 12
modules/monkey/newdocs/language/strings.md

@@ -3,15 +3,9 @@
 
 
 ### Strings
 ### Strings
 
 
-Values of type String are used to represent sequences of characters, such as text. The exact size of each character in a string value is target dependent, but is at least 8 bits.
+A String is an immutable sequence of 16 bit characters that is usually used to represent text.
 
 
-String variables are declared using the type name `String`, for example:
-
-```
-Local test:String="Hello World"
-```
-
-String literals are sequences of characters enclosed in "" (quotation marks). String literals may also include escape sequences, special sequences of characters used to represent unprintable characters.
+String literals are sequences of characters enclosed in `"``"` (quotation marks). String literals may also include escape sequences, special sequences of characters used to represent unprintable characters.
 
 
 You can use the following escape sequences in string literals:
 You can use the following escape sequences in string literals:
 
 
@@ -24,13 +18,30 @@ You can use the following escape sequences in string literals:
 |~z					| 0 (null)
 |~z					| 0 (null)
 |~~	 				| 126 (tilde ~)
 |~~	 				| 126 (tilde ~)
 
 
-For example, to include literal quotation marks in a string...
+For example, to include literal quotation marks in a string:
 
 
 ```
 ```
 Local test:="~qHello World~q" 
 Local test:="~qHello World~q" 
 ```
 ```
 
 
-You can index a string using the `[]' operator, eg:
+Strings can also be declared across multiple lines:
+
+```
+Const multiLine:="
+Multi Line String
+"
+```
+
+In this case, each newline inside the quote marks is simply included in the string, so the above example string actually contains 2 'hidden' newlines.
+
+String variables are declared using the type name `String`, for example:
+
+```
+Local test:String="Hello World"
+```
+
+You can index a string using the `[]' operator:
+
 ```
 ```
 Local str:="Hello World"
 Local str:="Hello World"
 For Local i:=0 Until str.Length
 For Local i:=0 Until str.Length
@@ -40,7 +51,7 @@ Next
 
 
 Indexing a string will return the character code at a given string index as an int.
 Indexing a string will return the character code at a given string index as an int.
 
 
-You can iterate through the characters in a string using `Eachin`, eg:
+You can iterate through the characters in a string using `Eachin`:
 
 
 ```
 ```
 For Local chr:=Eachin "Hello World"
 For Local chr:=Eachin "Hello World"
@@ -48,4 +59,4 @@ For Local chr:=Eachin "Hello World"
 Next
 Next
 ```
 ```
 
 
-For more information on strings, please see the [[types.String|String]] API reference.
+Strings have a number of useful methods including [[types.String.Slice|Slice]], [[types.String.Find|Find]] and [[types.String.Split|Split]]. For more information on strings, please see the [[types.String|String]] API reference.

+ 42 - 26
modules/monkey/newdocs/language/types.md

@@ -7,7 +7,7 @@
 
 
 The following primtive types are supported:
 The following primtive types are supported:
 
 
-| Type		| Description
+| Type Name	| Description
 |:----------|:-----------
 |:----------|:-----------
 | `Void`	| No type.
 | `Void`	| No type.
 | `Bool`	| Boolean type.
 | `Bool`	| Boolean type.
@@ -24,32 +24,35 @@ The following primtive types are supported:
 | `String`	| String of 16 bit characters.
 | `String`	| String of 16 bit characters.
 | `Object`	| Base type of all objects.
 | `Object`	| Base type of all objects.
 
 
+
 @#### Compound types
 @#### Compound types
 
 
 The following compound types are supported:
 The following compound types are supported:
 
 
-| Type						| Description
-|:--------------------------|:-----------
-| _Type_ `[` [,...] `]`		| Array type
-| _Type_ `Ptr`				| Pointer type
-| _Type_ `(` _Types_ `)`	| Function type
+| Type Syntax							| Description
+|:--------------------------------------|:-----------
+| _ElementType_`[]`						| Array type.
+| _PointeeType_ `Ptr`					| Pointer type.
+| _ReturnType_`(`_ParameterTypes_`)`	| Function type.
+
+Array types can have more than one dimension, for example: `[,]` declares a 2D array, `[,,]` declares a 3D array and so on.
+
+The parameter types for a function type can optionally include an identifier prefix, for example: `MyFunction:Int( arg:Int )`. The prefix must be a valid identifier but is otherwise ignored.
 
 
 
 
 @#### Implicit type conversions
 @#### Implicit type conversions
 
 
 These type conversions are performed automatically:
 These type conversions are performed automatically:
 
 
-| Source type					| Destination type
-|:------------------------------|:-----------------
-| Any numeric type	 			| `Bool`
-| String or array type 			| `Bool`
-| Class or interface type	 	| `Bool`
-| Any numeric type				| Any numeric type
-| Any numeric type or `Bool`	| `String`
-| Any pointer type				| `Void Ptr`
-| Any enum type					| Any integral type
-| Class or interface type		| Base class type or implemented interface type
-| Class, interface or struct type | `Bool`
+| Source type						| Destination type
+|:----------------------------------|:-----------------
+| `Bool`							| `String`
+| Any numeric type					| `Bool`, `String` or any numeric type.
+| `String` or any array type 		| `Bool`
+| Any pointer type					| `Void Ptr`
+| Class, interface or struct type	| `Bool`
+| Class or interface type			| Base class or implemented interface type
+| Enum type							| `Bool` or any integral type.
 
 
 When numeric values are converted to bool, the result will be true if the value is not equal to 0.
 When numeric values are converted to bool, the result will be true if the value is not equal to 0.
 
 
@@ -57,24 +60,37 @@ When strings and arrays are converted to bool, the result will be true if the le
 
 
 When class or interface instances are converted to bool, the result will be true if the instance is not equal to null.
 When class or interface instances are converted to bool, the result will be true if the instance is not equal to null.
 
 
-When struct values are converted, the result will be true if the struct value is not equal to null.
+When struct values are converted to bool, the result will be true if the struct value is not equal to null.
+
+When floating point values are converted to integral values, the fractional part of the floating point value is chopped off - no rounding is performed.
 
 
-When floating point values are converted to integral values, the fractional part of the floating point value is simply chopped off - no rounding is performed.
+When bools are converted to strings, the result will be either "True" or "False".
 
 
-When Bools are converted to strings, the result will be either "True" or "False".
 
 
+@#### Explicit type conversions 
 
 
-@#### Explicit type conversions
+Some type conversions must be explicitly performed using the 'cast' operator. The cast operator has the syntax:
 
 
-The `Cast` `<` _dest-type_ `>` `:` _dest-type_ `(` _expression_ `)` operator must be used for these type conversions:
+`Cast<`_DestinationType_`>:`_DestinationType_`(`_SourceExpression_`)`
+
+You must use the cast operator to perform the following type conversions:
 
 
 | Source type			| Destination type
 | Source type			| Destination type
 |:----------------------|:-----------------
 |:----------------------|:-----------------
 | `Bool`				| Any numeric type
 | `Bool`				| Any numeric type
 | `String`				| Any numeric type
 | `String`				| Any numeric type
-| Any pointer type		| Any pointer type, any integral type
-| Any integral type		| Any pointer type, any enum type
-| Class type			| Derived class type, any interface type
-| Interface type		| Any class type, any interface type
+| Any pointer type		| Any pointer type or any integral type
+| Any integral type		| Any pointer type or any enum type.
+| Class type			| Derived class or any interface type.
+| Interface type		| Any class or interface type.
+
+When using the cast operator to dynamically downcast an object or interface instance, the result will be `Null` if the cast failed.
 
 
 When casting bool values to a numeric type, the result will be 1 for true, 0 for false.
 When casting bool values to a numeric type, the result will be 1 for true, 0 for false.
+
+You can also use 'function syntax' to explictly cast values to primitive types:
+
+```
+Local floatValue:Float=3.14
+Local intValue:=Int( floatValue )
+```

+ 5 - 3
modules/monkey/newdocs/language/variants.md

@@ -3,7 +3,7 @@
 
 
 ### Variants
 ### Variants
 
 
-The Variant type is a primitive type that can be used to 'box' values of any type.
+A Variant is a special value that can be used to 'box' values of any other type.
 
 
 The easiest way to create a variant is to cast a value to Variant (much like casting an Int to String etc), eg:
 The easiest way to create a variant is to cast a value to Variant (much like casting an Int to String etc), eg:
 
 
@@ -17,7 +17,7 @@ v=10				'variant now contains an int 10.
 v="hello"			'variant now contains a string "hello".
 v="hello"			'variant now contains a string "hello".
 ```
 ```
 
 
-A variant is 'true' if it contains any value with a non-void type (including a bool false value!) and 'false' if it is uninitialized and has no (void) type.
+A variant is true if it is initialized (even if it contains a bool 'false' value) and false if it is uninitialized. There is currently no way to uninitialize a variant, so once a variant is initialized it will always be 'true'.
 
 
 Any type of value can be implicitly converted to a variant, so you can easily pass anything to a function with variant parameters:
 Any type of value can be implicitly converted to a variant, so you can easily pass anything to a function with variant parameters:
 
 
@@ -47,4 +47,6 @@ Local v:=Variant( 10 )
 Print Cast<String>( v )	'Runtime error! Variant contains an Int not a String!
 Print Cast<String>( v )	'Runtime error! Variant contains an Int not a String!
 ```
 ```
 
 
-The one exception to this is if the Variant contains a class object, in which case you can cast the variant to any valid base class of the object.
+The one exception to this is if the variant contains a instance of an object, in which case you can cast the variant to any valid base class of the object's actual type.
+
+Variants also have a number of useful methods including...

+ 3 - 1
modules/stb-image/stb-image.monkey2

@@ -1,6 +1,8 @@
 
 
 Namespace stb.image
 Namespace stb.image
 
 
+#Import "<libc>"
+
 #Import "native/stb_image.cpp"
 #Import "native/stb_image.cpp"
 #Import "native/stb_image.h"
 #Import "native/stb_image.h"
 
 
@@ -18,5 +20,5 @@ End
 Function stbi_load:UByte Ptr( filename:CString,x:Int Ptr,y:Int Ptr,comp:Int Ptr,req_comp:Int )
 Function stbi_load:UByte Ptr( filename:CString,x:Int Ptr,y:Int Ptr,comp:Int Ptr,req_comp:Int )
 Function stbi_load_from_memory:UByte Ptr( buffer:UByte Ptr,len:Int,x:Int Ptr,y:Int Ptr,comp:Int Ptr,req_comp:Int )
 Function stbi_load_from_memory:UByte Ptr( buffer:UByte Ptr,len:Int,x:Int Ptr,y:Int Ptr,comp:Int Ptr,req_comp:Int )
 Function stbi_load_from_callbacks:UByte Ptr( clbk:stbi_io_callbacks Ptr,user:Void Ptr,x:Int Ptr,y:Int Ptr,comp:Int Ptr,req_comp:Int )
 Function stbi_load_from_callbacks:UByte Ptr( clbk:stbi_io_callbacks Ptr,user:Void Ptr,x:Int Ptr,y:Int Ptr,comp:Int Ptr,req_comp:Int )
-
+Function stbi_load_from_file:UByte Ptr( f:libc.FILE Ptr,x:Int Ptr,y:Int Ptr,comp:Int Ptr,req_comp:Int )
 Function stbi_image_free( data:Void Ptr )
 Function stbi_image_free( data:Void Ptr )

+ 118 - 46
modules/std/filesystem/filesystem.monkey2

@@ -7,9 +7,23 @@ Using libc
 #Import "native/filesystem.cpp"
 #Import "native/filesystem.cpp"
 
 
 #If __TARGET__="android"
 #If __TARGET__="android"
+
 #Import "native/Monkey2FileSystem.java"
 #Import "native/Monkey2FileSystem.java"
+
+Using android
+
 #Elseif __TARGET__="ios"
 #Elseif __TARGET__="ios"
+
 #Import "native/filesystem.mm"
 #Import "native/filesystem.mm"
+
+#endif
+
+#If __TARGET__="android"
+
+Extern Private
+
+Function fopenAsset:FILE Ptr( asset:AAsset )="bbFileSystem::fopenAsset"
+	
 #endif
 #endif
 
 
 Extern
 Extern
@@ -63,8 +77,6 @@ Function FixPath:String( path:String )
 	
 	
 	Select root
 	Select root
 	Case "asset::" return AssetsDir()+path
 	Case "asset::" return AssetsDir()+path
-	Case "desktop::" Return DesktopDir()+path
-	Case "home::" Return HomeDir()+path
 #If __MOBILE_TARGET__
 #If __MOBILE_TARGET__
 	Case "internal::" Return InternalDir()+path
 	Case "internal::" Return InternalDir()+path
 	Case "external::" Return ExternalDir()+path
 	Case "external::" Return ExternalDir()+path
@@ -226,13 +238,13 @@ Note that only the desktop and web targets have an assets directory. Other targe
 Function AssetsDir:String()
 Function AssetsDir:String()
 	If Not _assetsDir
 	If Not _assetsDir
 #If __TARGET__="macos"
 #If __TARGET__="macos"
-		_assetsDir=ExtractDir( AppDir() )+"Resources/"	'enable me!
+		_assetsDir=ExtractDir( AppDir() )+"Resources/"
 #Else If __DESKTOP_TARGET__ Or __WEB_TARGET__
 #Else If __DESKTOP_TARGET__ Or __WEB_TARGET__
 		_assetsDir=AppDir()+"assets/"
 		_assetsDir=AppDir()+"assets/"
 #Else If __TARGET__="ios"
 #Else If __TARGET__="ios"
 		_assetsDir=GetSpecialDir( "assets" )
 		_assetsDir=GetSpecialDir( "assets" )
 #Else
 #Else
-		_assetsDir="asset::"
+		_assetsDir="${ASSETS}/"	'"asset::"
 #Endif
 #Endif
 	Endif
 	Endif
 	Return _assetsDir
 	Return _assetsDir
@@ -261,7 +273,7 @@ Function DesktopDir:String()
 #Else If __DESKTOP_TARGET__
 #Else If __DESKTOP_TARGET__
  	Return GetEnv( "HOME" )+"/Desktop/"
  	Return GetEnv( "HOME" )+"/Desktop/"
  #Else
  #Else
- 	Return "desktop::"
+ 	Return "${DESKTOP}/"
 #Endif
 #Endif
 End
 End
 
 
@@ -278,7 +290,7 @@ Function HomeDir:String()
 #Else if __DESKTOP_TARGET__
 #Else if __DESKTOP_TARGET__
 	Return GetEnv( "HOME" )+"/"
 	Return GetEnv( "HOME" )+"/"
 #Else
 #Else
-	Return "home::"
+	Return "${HOME}/"
 #Endif
 #Endif
 End
 End
 
 
@@ -333,19 +345,20 @@ Function ExtractRootDir:String( path:String )
 	
 	
 	If path.StartsWith( "//" ) Return "//"
 	If path.StartsWith( "//" ) Return "//"
 	
 	
+	If path.StartsWith( "/" ) Return "/"
+
 	Local i:=path.Find( "/" )
 	Local i:=path.Find( "/" )
-	If i=0 Return "/"
 	
 	
-	If i=-1 i=path.Length
+	If path.StartsWith( "$" ) And i<>-1 Return path.Slice( 0,i+1 )
 	
 	
-	Local j:=path.Find( "://" )
-	If j>0 And j<i Return path.Slice( 0,j+3 )
+	Local j:=path.Find( ":" )
+	If j=-1 Or (i<>-1 And j>i) Return ""
 	
 	
-	j=path.Find( ":/" )
-	If j>0 And j<i Return path.Slice( 0,j+2 )
+	If path.Slice( j,j+3 )="://" Return path.Slice( 0,j+3 )
 	
 	
-	j=path.Find( "::" )
-	If j>0 And j<i Return path.Slice( 0,j+2 )
+	If path.Slice( j,j+2 )=":/" Return path.Slice( 0,j+2 )
+	
+	If path.Slice( j,j+2 )="::" Return path.Slice( 0,j+2 )
 	
 	
 	Return ""
 	Return ""
 End
 End
@@ -359,26 +372,9 @@ End
 #end
 #end
 Function IsRootDir:Bool( path:String )
 Function IsRootDir:Bool( path:String )
 	
 	
-	path=path.Replace( "\","/" )
-	
-
-	If path="//" Return True
-	
-	If path="/" Return True
-	
-	Local i:=path.Find( "/" )
-	If i=-1 i=path.Length
-	
-	Local j:=path.Find( "://" )
-	If j>0 And j<i Return j+3=path.Length
-	
-	j=path.Find( ":/" )
-	If j>0 And j<i Return j+2=path.Length
-	
-	j=path.Find( "::" )
-	If j>0 And j<i Return j+2=path.Length
+	Local root:=ExtractRootDir( path )
 	
 	
-	Return False
+	Return root And root.Length=path.Length
 End
 End
 
 
 #rem monkeydoc Gets the process current directory.
 #rem monkeydoc Gets the process current directory.
@@ -418,30 +414,30 @@ Function RealPath:String( path:String )
 	
 	
 	path=FixPath( path )
 	path=FixPath( path )
 	
 	
-	Local rpath:=ExtractRootDir( path )
-	If rpath 
-		path=path.Slice( rpath.Length )
+	Local root:=ExtractRootDir( path )
+	If root 
+		path=path.Slice( root.Length )
 	Else
 	Else
-		rpath=CurrentDir()
+		root=CurrentDir()
 	Endif
 	Endif
 	
 	
 	While path
 	While path
 		Local i:=path.Find( "/" )
 		Local i:=path.Find( "/" )
-		If i=-1 Return rpath+path
+		If i=-1 Return root+path
 		Local t:=path.Slice( 0,i )
 		Local t:=path.Slice( 0,i )
 		path=path.Slice( i+1 )
 		path=path.Slice( i+1 )
 		Select t
 		Select t
 		Case ""
 		Case ""
 		Case "."
 		Case "."
 		Case ".."
 		Case ".."
-			If Not rpath rpath=CurrentDir()
-			rpath=ExtractDir( rpath )
+			If Not root root=CurrentDir()
+			root=ExtractDir( root )
 		Default
 		Default
-			rpath+=t+"/"
+			root+=t+"/"
 		End
 		End
 	Wend
 	Wend
 	
 	
-	Return rpath
+	Return root
 	
 	
 	#rem Not working on macos!
 	#rem Not working on macos!
 	
 	
@@ -593,6 +589,21 @@ End
 Function GetFileType:FileType( path:String )
 Function GetFileType:FileType( path:String )
 	
 	
 	path=FixFilePath( path )
 	path=FixFilePath( path )
+	
+#If __TARGET__="android"
+	If path.StartsWith( "${ASSETS}/" )
+		
+		path=path.Slice( 10 )
+		
+		Local asset:=AAssetManager_open( GetAssetManager(),path,0 )
+		If Not asset Return FileType.Unknown
+		
+		Local length:=AAsset_getLength( asset )
+		AAsset_close( asset )
+		
+		Return length<>0 ? FileType.File Else FileType.Unknown
+	End
+#Endif
 
 
 	Local st:stat_t
 	Local st:stat_t
 	If stat( path,Varptr st )<0 Return FileType.None
 	If stat( path,Varptr st )<0 Return FileType.None
@@ -630,9 +641,24 @@ End
 
 
 #end
 #end
 Function GetFileSize:Long( path:String )
 Function GetFileSize:Long( path:String )
-
+	
 	path=FixFilePath( path )
 	path=FixFilePath( path )
 
 
+#If __TARGET__="android"
+	If path.StartsWith( "${ASSETS}/" )
+		
+		path=path.Slice( 10 )
+		
+		Local asset:=AAssetManager_open( GetAssetManager(),path,0 )
+		If Not asset Return 0
+		
+		Local length:=AAsset_getLength( asset )
+		AAsset_close( asset )
+		
+		Return length
+	End
+#Endif
+
 	Local st:stat_t
 	Local st:stat_t
 	If stat( path,Varptr st )<0 Return 0
 	If stat( path,Varptr st )<0 Return 0
 
 
@@ -664,13 +690,33 @@ Does not return any '.' or '..' entries in a directory.
 #end
 #end
 Function LoadDir:String[]( path:String )
 Function LoadDir:String[]( path:String )
 	
 	
+	Local files:=New StringStack
+	
 	path=FixFilePath( path )
 	path=FixFilePath( path )
-
+	
+#If __TARGET__="android"
+	If path.StartsWith( "${ASSETS}/" )
+		
+		path=path.Slice( 10 )
+		
+		Local assetDir:=AAssetManager_openDir( GetAssetManager(),path )
+		
+		If assetDir
+			Repeat
+				Local file:=AAssetDir_getNextFileName( assetDir )
+				If Not file Exit
+				files.Add( file )
+			Forever
+			AAssetDir_close( assetDir )
+		Endif
+		
+		Return files.ToArray()
+	Endif
+#endif
+	
 	Local dir:=opendir( path )
 	Local dir:=opendir( path )
 	If Not dir Return Null
 	If Not dir Return Null
 	
 	
-	Local files:=New StringStack
-	
 	Repeat
 	Repeat
 		Local ent:=readdir( dir )
 		Local ent:=readdir( dir )
 		If Not ent Exit
 		If Not ent Exit
@@ -851,3 +897,29 @@ Function CopyDir:Bool( srcDir:String,dstDir:String,recursive:Bool=True )
 	Return True
 	Return True
 
 
 End
 End
+
+#rem monkeydoc Opens a 'C' file.
+
+Opens a file that can be used with the 'C' calls fopen, fread, fwrite and fclose. Similar to plain libc.fopen, except that it can also handle assets on android.
+
+`mode` should be one of: "r", "w" or "rw". When opening a file using "r" or "rw", the file must already exist or the function will fail and null will be returned. When opening a file using "w", any existing file at the same path will be overwritten.
+
+#end
+Function OpenCFile:FILE Ptr( path:String,mode:String )
+	
+	path=FixFilePath( path )
+	
+#If __TARGET__="android"
+	If path.StartsWith( "${ASSETS}/" )
+		
+		path=path.Slice( 10 )
+		
+		Local asset:=AAssetManager_open( GetAssetManager(),path,0 )
+		If Not asset Return Null
+		
+		Return fopenAsset( asset )
+	Endif
+#Endif
+	
+	Return libc.fopen( path,mode )
+End

+ 53 - 0
modules/std/filesystem/native/filesystem.cpp

@@ -37,6 +37,12 @@
 
 
 #endif
 #endif
 
 
+#if BB_ANDROID
+
+#include <sdl2/SDL/src/core/android/SDL_android.h>
+
+#endif
+
 namespace bbFileSystem{
 namespace bbFileSystem{
 
 
 	bbString _appDir;
 	bbString _appDir;
@@ -172,4 +178,51 @@ namespace bbFileSystem{
 #endif
 #endif
 	}
 	}
 	
 	
+#if BB_ANDROID
+	int android_read( void *cookie,char *buf,int size ){
+	
+	  return AAsset_read( (AAsset*)cookie,buf,size );
+	}
+	
+	int android_write( void *cookie,const char* buf,int size ){
+	
+	  return EACCES; // can't provide write access to the apk
+	}
+	
+	fpos_t android_seek( void *cookie,fpos_t offset,int whence ){
+	
+	  return AAsset_seek( (AAsset*)cookie,offset,whence );
+	}
+	
+	int android_close(void* cookie) {
+	
+	  AAsset_close( (AAsset*)cookie );
+	  return 0;
+	}
+
+	FILE *fopenAsset( void *asset ){
+
+		return funopen( asset,android_read,android_write,android_seek,android_close );
+	}
+
+#endif
+
+/*	
+	FILE *fopen( const char *path,const char *mode ){
+
+#if BB_ANDROID
+		if( !strncmp( path,"asset::",7 ) ){
+			
+			AAssetManager *assetManager=Android_JNI_GetAssetManager();
+			if( !assetManager ) return 0;
+			
+	  		AAsset* asset=AAssetManager_open( assetManager,path+7,0 );
+			if( !asset ) return 0;
+			
+			return fopenAsset( asset );
+		}
+#endif
+		return ::fopen( path,mode );
+	}
+*/	
 }
 }

+ 4 - 2
modules/std/filesystem/native/filesystem.h

@@ -16,9 +16,11 @@ namespace bbFileSystem{
 	bbBool copyFile( bbString srcPath,bbString dstPath );
 	bbBool copyFile( bbString srcPath,bbString dstPath );
 	
 	
 #if BB_IOS
 #if BB_IOS
-	
 	bbString getSpecialDir( bbString name );
 	bbString getSpecialDir( bbString name );
-	
+#endif
+
+#if BB_ANDROID
+	FILE *fopenAsset( void *asset );
 #endif
 #endif
 
 
 }
 }

+ 1 - 2
modules/std/graphics/pixmaploader.monkey2

@@ -72,9 +72,8 @@ Public
 Function LoadPixmap:Pixmap( path:String,format:PixelFormat )
 Function LoadPixmap:Pixmap( path:String,format:PixelFormat )
 	
 	
 	If ExtractExt( path )=".hdr"
 	If ExtractExt( path )=".hdr"
-		path=RealPath( path )
 		
 		
-		Local file:=libc.fopen( path,"rb" )
+		Local file:=filesystem.OpenCFile( path,"rb" )
 		If Not file Return Null
 		If Not file Return Null
 		
 		
 		Local width:=0,height:=0
 		Local width:=0,height:=0

+ 11 - 4
modules/std/misc/zipfile.monkey2

@@ -63,7 +63,7 @@ Class ZipFile
 	#rem monkeydoc @hidden
 	#rem monkeydoc @hidden
 	#end	
 	#end	
 	Method Extract:Bool( dir:String,prefix:String="" )
 	Method Extract:Bool( dir:String,prefix:String="" )
-	
+		
 		If Not dir.EndsWith( "/" ) dir+="/"
 		If Not dir.EndsWith( "/" ) dir+="/"
 		
 		
 		Local result:=True
 		Local result:=True
@@ -75,13 +75,20 @@ Class ZipFile
 			
 			
 			If prefix And Not name.StartsWith( prefix ) Continue
 			If prefix And Not name.StartsWith( prefix ) Continue
 			
 			
+			Local path:=dir+name
+				
+			If mz_zip_reader_is_file_a_directory( _zip,i )
+				
+				filesystem.CreateDir( path )
+				
+				Continue
+			Endif
+			
 			Local size:=_sizes[i]
 			Local size:=_sizes[i]
 
 
 			Local buf:=New DataBuffer( size )
 			Local buf:=New DataBuffer( size )
-		
-			If mz_zip_reader_extract_to_mem( _zip,i,buf.Data,size,0 ) 
 			
 			
-				Local path:=dir+name
+			If mz_zip_reader_extract_to_mem( _zip,i,buf.Data,size,0 ) 
 				
 				
 				filesystem.CreateDir( ExtractDir( path ) )
 				filesystem.CreateDir( ExtractDir( path ) )
 				
 				

+ 1 - 1
modules/std/module.json

@@ -4,5 +4,5 @@
 	"author":"Mark Sibly",
 	"author":"Mark Sibly",
 	"version":"1.0.0",
 	"version":"1.0.0",
 	"support":"http://monkeycoder.co.nz",
 	"support":"http://monkeycoder.co.nz",
-	"depends":["libc","emscripten","jni","sdl2","miniz","stb-image","stb-image-write","stb-vorbis","zlib"]
+	"depends":["libc","sdl2","jni","android","emscripten","zlib","miniz","stb-image","stb-image-write","stb-vorbis"]
 }
 }

+ 19 - 52
modules/std/std.monkey2

@@ -1,23 +1,20 @@
 
 
 Namespace std
 Namespace std
 
 
-#Import "<libc.monkey2>"
+#Import "<libc>"
+#Import "<zlib>"
+#Import "<miniz>"
 #Import "<stb-image>"
 #Import "<stb-image>"
 #Import "<stb-image-write>"
 #Import "<stb-image-write>"
 #import "<stb-vorbis>"
 #import "<stb-vorbis>"
-#Import "<miniz>"
-#Import "<zlib>"
 
 
-#If __MOBILE_TARGET__
-#Import "<sdl2>"
-#If __TARGET__="android"
-#Import "<jni>"
-#Endif
-#Endif
-
-#If __WEB_TARGET__
+#If __TARGET__="emscripten"
 #Import "<emscripten>"
 #Import "<emscripten>"
-#endif
+#ElseIf __TARGET__="android"
+#Import "<android>"
+#ElseIf __TARGET__="ios"
+'#Import "<ios>"
+#Endif
 
 
 #Import "collections/container"
 #Import "collections/container"
 #Import "collections/stack"
 #Import "collections/stack"
@@ -30,9 +27,9 @@ Namespace std
 #Import "stream/stream"
 #Import "stream/stream"
 #Import "stream/filestream"
 #Import "stream/filestream"
 
 
-#If __MOBILE_TARGET__
-#Import "stream/sdl_rwstream.monkey2"
-#Endif
+'#If __MOBILE_TARGET__
+'#Import "stream/sdl_rwstream.monkey2"
+'#Endif
 
 
 #Import "memory/byteorder"
 #Import "memory/byteorder"
 #Import "memory/databuffer"
 #Import "memory/databuffer"
@@ -107,9 +104,9 @@ Function Main()
 		Return FileStream.Open( path,mode )
 		Return FileStream.Open( path,mode )
 	End
 	End
 	
 	
-	Stream.OpenFuncs["memblock"]=Lambda:Stream( proto:String,path:String,mode:String )
+	Stream.OpenFuncs["asset"]=Lambda:Stream( proto:String,path:String,mode:String )
 	
 	
-		Return DataStream.Open( path,mode )
+		Return FileStream.Open( filesystem.AssetsDir()+path,mode )
 	End
 	End
 	
 	
 #If __MOBILE_TARGET__
 #If __MOBILE_TARGET__
@@ -126,46 +123,16 @@ Function Main()
 
 
 #endif
 #endif
 	
 	
-#If __DESKTOP_TARGET__
-
-	Stream.OpenFuncs["process"]=Lambda:Stream( proto:String,path:String,mode:String )
-
-		Return std.process.ProcessStream.Open( path,mode )
-	End
-	
-	Stream.OpenFuncs["desktop"]=Lambda:Stream( proto:String,path:String,mode:String )
+	Stream.OpenFuncs["memory"]=Lambda:Stream( proto:String,path:String,mode:String )
 	
 	
-		Return FileStream.Open( filesystem.DesktopDir()+path,mode )
-	End
-
-	Stream.OpenFuncs["home"]=Lambda:Stream( proto:String,path:String,mode:String )
-	
-		Return FileStream.Open( filesystem.HomeDir()+path,mode )
-	End
-	
-#Endif
-
-#If __DESKTOP_TARGET__ Or __WEB_TARGET__
-
-	'note: ios and android asset proto is implemented using SDL and implemented in mojo...
-	'
-	Stream.OpenFuncs["asset"]=Lambda:Stream( proto:String,path:String,mode:String )
-	
-		Return FileStream.Open( filesystem.AssetsDir()+path,mode )
+		Return DataStream.Open( path,mode )
 	End
 	End
-
-#Else If __TARGET__="android"
-
-	Stream.OpenFuncs["asset"]=Lambda:Stream( proto:String,path:String,mode:String )
 	
 	
-		Return SDL_RWStream.Open( path,mode )
-	End
+#If __DESKTOP_TARGET__
 
 
-#Else If __TARGET__="ios"
+	Stream.OpenFuncs["process"]=Lambda:Stream( proto:String,path:String,mode:String )
 
 
-	Stream.OpenFuncs["asset"]=Lambda:Stream( proto:String,path:String,mode:String )
-	
-		Return SDL_RWStream.Open( "assets/"+path,mode )
+		Return std.process.ProcessStream.Open( path,mode )
 	End
 	End
 	
 	
 #Endif
 #Endif

+ 4 - 12
modules/std/stream/filestream.monkey2

@@ -92,9 +92,6 @@ Class FileStream Extends Stream
 	
 	
 	When opening a file using "w", any existing file at the same path will be overwritten.
 	When opening a file using "w", any existing file at the same path will be overwritten.
 	
 	
-	Note: This method should not be used to open an 'asset stream' because assets are not always files. You should instead use 
-	[[Stream.Open]] for streams that have a stream path prefix such as `asset::`, `internal::`, `external::` etc.
-	
 	@param path The path of the file to open.
 	@param path The path of the file to open.
 	
 	
 	@param mode The mode to open the file in: "r", "w" or "rw".
 	@param mode The mode to open the file in: "r", "w" or "rw".
@@ -105,19 +102,14 @@ Class FileStream Extends Stream
 	Function Open:FileStream( path:String,mode:String )
 	Function Open:FileStream( path:String,mode:String )
 	
 	
 		Select mode
 		Select mode
-		Case "r"
-			mode="rb"
-		Case "w"
-			mode="wb"
-		Case "rw"
-			mode="r+b"
+		Case "r" mode="rb"
+		Case "w" mode="wb"
+		Case "rw" mode="r+b"
 		Default
 		Default
 			Return Null
 			Return Null
 		End
 		End
 		
 		
-		path=RealPath( path )
-		
-		Local file:=fopen( path,mode )
+		Local file:=OpenCFile( path,mode )
 		If Not file Return Null
 		If Not file Return Null
 		
 		
 		Return New FileStream( file )
 		Return New FileStream( file )

+ 36 - 16
products/android/Monkey2Game/app/src/main/java/org/libsdl/app/SDLActivity.java

@@ -546,6 +546,7 @@ public class SDLActivity extends Activity {
      * This method is called by SDL using JNI.
      * This method is called by SDL using JNI.
      */
      */
     public static int audioOpen(int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames) {
     public static int audioOpen(int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames) {
+/*
         int channelConfig = isStereo ? AudioFormat.CHANNEL_CONFIGURATION_STEREO : AudioFormat.CHANNEL_CONFIGURATION_MONO;
         int channelConfig = isStereo ? AudioFormat.CHANNEL_CONFIGURATION_STEREO : AudioFormat.CHANNEL_CONFIGURATION_MONO;
         int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT : AudioFormat.ENCODING_PCM_8BIT;
         int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT : AudioFormat.ENCODING_PCM_8BIT;
         int frameSize = (isStereo ? 2 : 1) * (is16Bit ? 2 : 1);
         int frameSize = (isStereo ? 2 : 1) * (is16Bit ? 2 : 1);
@@ -575,7 +576,7 @@ public class SDLActivity extends Activity {
         }
         }
 
 
         Log.v(TAG, "SDL audio: got " + ((mAudioTrack.getChannelCount() >= 2) ? "stereo" : "mono") + " " + ((mAudioTrack.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT) ? "16-bit" : "8-bit") + " " + (mAudioTrack.getSampleRate() / 1000f) + "kHz, " + desiredFrames + " frames buffer");
         Log.v(TAG, "SDL audio: got " + ((mAudioTrack.getChannelCount() >= 2) ? "stereo" : "mono") + " " + ((mAudioTrack.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT) ? "16-bit" : "8-bit") + " " + (mAudioTrack.getSampleRate() / 1000f) + "kHz, " + desiredFrames + " frames buffer");
-
+*/
         return 0;
         return 0;
     }
     }
 
 
@@ -583,6 +584,7 @@ public class SDLActivity extends Activity {
      * This method is called by SDL using JNI.
      * This method is called by SDL using JNI.
      */
      */
     public static void audioWriteShortBuffer(short[] buffer) {
     public static void audioWriteShortBuffer(short[] buffer) {
+/*
         for (int i = 0; i < buffer.length; ) {
         for (int i = 0; i < buffer.length; ) {
             int result = mAudioTrack.write(buffer, i, buffer.length - i);
             int result = mAudioTrack.write(buffer, i, buffer.length - i);
             if (result > 0) {
             if (result > 0) {
@@ -598,12 +600,14 @@ public class SDLActivity extends Activity {
                 return;
                 return;
             }
             }
         }
         }
+*/
     }
     }
 
 
     /**
     /**
      * This method is called by SDL using JNI.
      * This method is called by SDL using JNI.
      */
      */
     public static void audioWriteByteBuffer(byte[] buffer) {
     public static void audioWriteByteBuffer(byte[] buffer) {
+/*
         for (int i = 0; i < buffer.length; ) {
         for (int i = 0; i < buffer.length; ) {
             int result = mAudioTrack.write(buffer, i, buffer.length - i);
             int result = mAudioTrack.write(buffer, i, buffer.length - i);
             if (result > 0) {
             if (result > 0) {
@@ -619,12 +623,14 @@ public class SDLActivity extends Activity {
                 return;
                 return;
             }
             }
         }
         }
+*/
     }
     }
 
 
     /**
     /**
      * This method is called by SDL using JNI.
      * This method is called by SDL using JNI.
      */
      */
     public static int captureOpen(int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames) {
     public static int captureOpen(int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames) {
+/*
         int channelConfig = isStereo ? AudioFormat.CHANNEL_CONFIGURATION_STEREO : AudioFormat.CHANNEL_CONFIGURATION_MONO;
         int channelConfig = isStereo ? AudioFormat.CHANNEL_CONFIGURATION_STEREO : AudioFormat.CHANNEL_CONFIGURATION_MONO;
         int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT : AudioFormat.ENCODING_PCM_8BIT;
         int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT : AudioFormat.ENCODING_PCM_8BIT;
         int frameSize = (isStereo ? 2 : 1) * (is16Bit ? 2 : 1);
         int frameSize = (isStereo ? 2 : 1) * (is16Bit ? 2 : 1);
@@ -652,41 +658,51 @@ public class SDLActivity extends Activity {
         }
         }
 
 
         Log.v(TAG, "SDL capture: got " + ((mAudioRecord.getChannelCount() >= 2) ? "stereo" : "mono") + " " + ((mAudioRecord.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT) ? "16-bit" : "8-bit") + " " + (mAudioRecord.getSampleRate() / 1000f) + "kHz, " + desiredFrames + " frames buffer");
         Log.v(TAG, "SDL capture: got " + ((mAudioRecord.getChannelCount() >= 2) ? "stereo" : "mono") + " " + ((mAudioRecord.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT) ? "16-bit" : "8-bit") + " " + (mAudioRecord.getSampleRate() / 1000f) + "kHz, " + desiredFrames + " frames buffer");
-
+*/
         return 0;
         return 0;
     }
     }
 
 
     /** This method is called by SDL using JNI. */
     /** This method is called by SDL using JNI. */
     public static int captureReadShortBuffer(short[] buffer, boolean blocking) {
     public static int captureReadShortBuffer(short[] buffer, boolean blocking) {
+/*
         // !!! FIXME: this is available in API Level 23. Until then, we always block.  :(
         // !!! FIXME: this is available in API Level 23. Until then, we always block.  :(
         //return mAudioRecord.read(buffer, 0, buffer.length, blocking ? AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING);
         //return mAudioRecord.read(buffer, 0, buffer.length, blocking ? AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING);
         return mAudioRecord.read(buffer, 0, buffer.length);
         return mAudioRecord.read(buffer, 0, buffer.length);
+*/
+        return 0;
     }
     }
 
 
     /** This method is called by SDL using JNI. */
     /** This method is called by SDL using JNI. */
     public static int captureReadByteBuffer(byte[] buffer, boolean blocking) {
     public static int captureReadByteBuffer(byte[] buffer, boolean blocking) {
+/*
         // !!! FIXME: this is available in API Level 23. Until then, we always block.  :(
         // !!! FIXME: this is available in API Level 23. Until then, we always block.  :(
         //return mAudioRecord.read(buffer, 0, buffer.length, blocking ? AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING);
         //return mAudioRecord.read(buffer, 0, buffer.length, blocking ? AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING);
         return mAudioRecord.read(buffer, 0, buffer.length);
         return mAudioRecord.read(buffer, 0, buffer.length);
+*/
+        return 0;
     }
     }
 
 
 
 
     /** This method is called by SDL using JNI. */
     /** This method is called by SDL using JNI. */
     public static void audioClose() {
     public static void audioClose() {
+/*
         if (mAudioTrack != null) {
         if (mAudioTrack != null) {
             mAudioTrack.stop();
             mAudioTrack.stop();
             mAudioTrack.release();
             mAudioTrack.release();
             mAudioTrack = null;
             mAudioTrack = null;
         }
         }
+*/
     }
     }
 
 
     /** This method is called by SDL using JNI. */
     /** This method is called by SDL using JNI. */
     public static void captureClose() {
     public static void captureClose() {
+/*
         if (mAudioRecord != null) {
         if (mAudioRecord != null) {
             mAudioRecord.stop();
             mAudioRecord.stop();
             mAudioRecord.release();
             mAudioRecord.release();
             mAudioRecord = null;
             mAudioRecord = null;
         }
         }
+*/
     }
     }
 
 
 
 
@@ -834,7 +850,7 @@ public class SDLActivity extends Activity {
             final int[] buttonIds,
             final int[] buttonIds,
             final String[] buttonTexts,
             final String[] buttonTexts,
             final int[] colors) {
             final int[] colors) {
-
+/*
         messageboxSelection[0] = -1;
         messageboxSelection[0] = -1;
 
 
         // sanity checks
         // sanity checks
@@ -875,10 +891,12 @@ public class SDLActivity extends Activity {
         }
         }
 
 
         // return selected value
         // return selected value
-
         return messageboxSelection[0];
         return messageboxSelection[0];
+*/
+        return -1;
     }
     }
 
 
+/*
     @Override
     @Override
     protected Dialog onCreateDialog(int ignore, Bundle args) {
     protected Dialog onCreateDialog(int ignore, Bundle args) {
 
 
@@ -957,7 +975,7 @@ public class SDLActivity extends Activity {
                     mapping.put(KeyEvent.KEYCODE_ENTER, button);
                     mapping.put(KeyEvent.KEYCODE_ENTER, button);
                 }
                 }
                 if ((buttonFlags[i] & 0x00000002) != 0) {
                 if ((buttonFlags[i] & 0x00000002) != 0) {
-                    mapping.put(111, button); /* API 11: KeyEvent.KEYCODE_ESCAPE */
+                    mapping.put(111, button);
                 }
                 }
             }
             }
             button.setText(buttonTexts[i]);
             button.setText(buttonTexts[i]);
@@ -1012,6 +1030,7 @@ public class SDLActivity extends Activity {
 
 
         return dialog;
         return dialog;
     }
     }
+    */
 }
 }
 
 
 /**
 /**
@@ -1088,7 +1107,8 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
     @Override
     @Override
     public void surfaceCreated(SurfaceHolder holder) {
     public void surfaceCreated(SurfaceHolder holder) {
         Log.v("SDL", "surfaceCreated()");
         Log.v("SDL", "surfaceCreated()");
-        holder.setType(SurfaceHolder.SURFACE_TYPE_GPU);
+        //deprecated in API5!
+        //holder.setType(SurfaceHolder.SURFACE_TYPE_GPU);
     }
     }
 
 
     // Called when we lose the surface
     // Called when we lose the surface
@@ -1109,23 +1129,27 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
 
 
         int sdlFormat = 0x15151002; // SDL_PIXELFORMAT_RGB565 by default
         int sdlFormat = 0x15151002; // SDL_PIXELFORMAT_RGB565 by default
         switch (format) {
         switch (format) {
-        case PixelFormat.A_8:
-            Log.v("SDL", "pixel format A_8");
+        case 8://PixelFormat.A_8:
+          Log.v("SDL", "pixel format A_8");
             break;
             break;
-        case PixelFormat.LA_88:
+        case 10://PixelFormat.LA_88:
             Log.v("SDL", "pixel format LA_88");
             Log.v("SDL", "pixel format LA_88");
             break;
             break;
-        case PixelFormat.L_8:
+        case 9://PixelFormat.L_8:
             Log.v("SDL", "pixel format L_8");
             Log.v("SDL", "pixel format L_8");
             break;
             break;
-        case PixelFormat.RGBA_4444:
+        case 7://PixelFormat.RGBA_4444:
             Log.v("SDL", "pixel format RGBA_4444");
             Log.v("SDL", "pixel format RGBA_4444");
             sdlFormat = 0x15421002; // SDL_PIXELFORMAT_RGBA4444
             sdlFormat = 0x15421002; // SDL_PIXELFORMAT_RGBA4444
             break;
             break;
-        case PixelFormat.RGBA_5551:
+        case 6://PixelFormat.RGBA_5551:
             Log.v("SDL", "pixel format RGBA_5551");
             Log.v("SDL", "pixel format RGBA_5551");
             sdlFormat = 0x15441002; // SDL_PIXELFORMAT_RGBA5551
             sdlFormat = 0x15441002; // SDL_PIXELFORMAT_RGBA5551
             break;
             break;
+        case 11://PixelFormat.RGB_332:
+            Log.v("SDL", "pixel format RGB_332");
+            sdlFormat = 0x14110801; // SDL_PIXELFORMAT_RGB332
+            break;
         case PixelFormat.RGBA_8888:
         case PixelFormat.RGBA_8888:
             Log.v("SDL", "pixel format RGBA_8888");
             Log.v("SDL", "pixel format RGBA_8888");
             sdlFormat = 0x16462004; // SDL_PIXELFORMAT_RGBA8888
             sdlFormat = 0x16462004; // SDL_PIXELFORMAT_RGBA8888
@@ -1134,10 +1158,6 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
             Log.v("SDL", "pixel format RGBX_8888");
             Log.v("SDL", "pixel format RGBX_8888");
             sdlFormat = 0x16261804; // SDL_PIXELFORMAT_RGBX8888
             sdlFormat = 0x16261804; // SDL_PIXELFORMAT_RGBX8888
             break;
             break;
-        case PixelFormat.RGB_332:
-            Log.v("SDL", "pixel format RGB_332");
-            sdlFormat = 0x14110801; // SDL_PIXELFORMAT_RGB332
-            break;
         case PixelFormat.RGB_565:
         case PixelFormat.RGB_565:
             Log.v("SDL", "pixel format RGB_565");
             Log.v("SDL", "pixel format RGB_565");
             sdlFormat = 0x15151002; // SDL_PIXELFORMAT_RGB565
             sdlFormat = 0x15151002; // SDL_PIXELFORMAT_RGB565

+ 8 - 1
products/android/Monkey2Game/build.gradle

@@ -8,7 +8,7 @@ buildscript {
     }
     }
     
     
     dependencies {
     dependencies {
-	    classpath 'com.android.tools.build:gradle:3.1.0'
+	    classpath 'com.android.tools.build:gradle:3.1.2'
     }
     }
 }
 }
 
 
@@ -19,3 +19,10 @@ allprojects {
         google()
         google()
     }
     }
 }
 }
+
+allprojects {
+ 
+    tasks.withType(JavaCompile) {
+        options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
+    }
+}