瀏覽代碼

Make PhysFS usable on Android.

Extracting assets from apk in assets/extract folder to internalDataPath. Makes physfs able to read .pak files. Extracting folders is not supported!
Joachim Meyer 9 年之前
父節點
當前提交
2b90aa60f7

+ 4 - 3
build/android/TemplateApp/build.gradle

@@ -18,7 +18,8 @@ android {
             proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
         }
         debug {
-            jniDebuggable = true
+            debuggable true
+            jniDebuggable false
         }
     }
     sourceSets.main {
@@ -35,8 +36,8 @@ android {
         }
     }
     task copyAssets(type: Copy) {
-        from '../../../assets/default/default'
-        into 'src/main/assets/default'
+        from '../../../assets/default_mobile/default.pak'
+        into 'src/main/assets/extract/'
     }
     tasks.withType(JavaCompile) {
         compileTask -> compileTask.dependsOn ndkBuild, copyAssets

+ 1 - 0
build/android/TemplateApp/jni/PolycodeTemplateApp.cpp

@@ -9,6 +9,7 @@
 PolycodeTemplateApp::PolycodeTemplateApp(PolycodeView *view) {
     core = new POLYCODE_CORE(view, 800,480,false,false, 0,0,60, -1, true);
 
+    core->addFileSource("archive", "default.pak");
     ResourcePool *globalPool = Services()->getResourceManager()->getGlobalPool();
     globalPool->loadResourcesFromFolder("default", true);
 

+ 3 - 1
include/polycode/core/PolyAndroidCore.h

@@ -93,6 +93,8 @@ namespace Polycode {
 		void copyStringToClipboard(const String& str);
 		String getClipboardString();
 		
+		void addFileSource(const String &type, const String &source);
+		
 		void createFolder(const String& folderPath);
 		void copyDiskItem(const String& itemPath, const String& destItemPath);
 		void moveDiskItem(const String& itemPath, const String& destItemPath);
@@ -129,7 +131,7 @@ namespace Polycode {
 		bool recreateContext;
 		
 		PolyKEY mapKey(int keyCode);
-		
+		void extractResources();
 	private:
 		PolycodeView* view;
 		

+ 1 - 1
include/polycode/core/PolyCore.h

@@ -312,7 +312,7 @@ namespace Polycode {
 		CoreFile *openFile(const Polycode::String& fileName, const Polycode::String& opts);
 		void closeFile(CoreFile *file);
 		
-		void addFileSource(const String &type, const String &source);
+		virtual void addFileSource(const String &type, const String &source);
 		void removeFileSource(const String &type, const String &source);
 		
 		std::vector<OSFileEntry> parseFolder(const Polycode::String& pathString, bool showHidden);

+ 2 - 3
include/polycode/view/android/PolycodeView.h

@@ -73,13 +73,12 @@ namespace Polycode {
 			
 			ASensorManager* sensorManager;
 			ASensorEventQueue* sensorQueue;
-			
 			int64_t gyroTimestamp;
 			
+			jobject WakeLock;
+			
 			unsigned int lifecycleFlags;
 			bool isInteractable();
-			
-			jobject WakeLock;
     };
 }
 

+ 7 - 3
src/core/PolyAAssetFileProvider.cpp

@@ -74,13 +74,17 @@ Polycode::CoreFile *AAssetFileProvider::openFile(const String &fileName, const S
 
 bool AAssetFileProvider::parseFolder(const String& pathString, bool showHidden, std::vector< OSFileEntry >& targetVector){
 	String path = pathString;
-	if(pathString.substr(pathString.length(),1)!="/")
+	
+	if(pathString.substr(pathString.length()-1,1)!="/")
 		path = pathString + "/";
 	
 	AAssetDir* dir = AAssetManager_openDir(manager, pathString.c_str());
-	if(!dir)
+	
+	if(AAssetDir_getNextFileName(dir) == NULL)
 		return false;
 	
+	AAssetDir_rewind(dir);
+	
 	while(true){
 		String name = AAssetDir_getNextFileName(dir);
 		if(name == "")
@@ -111,5 +115,5 @@ int AAssetFile::seek(long int offset, int origin) {
 }
 
 long AAssetFile::tell() {
-	return AAsset_getLength(file);
+	return AAsset_getLength64(file);
 }

+ 52 - 1
src/core/PolyAndroidCore.cpp

@@ -82,7 +82,7 @@ AndroidCore::AndroidCore(PolycodeView *view, int xRes, int yRes, bool fullScreen
 	setVideoMode(AConfiguration_getScreenWidthDp(view->native_config), AConfiguration_getScreenHeightDp(view->native_config), fullScreen, vSync, aaLevel, anisotropyLevel, retinaSupport);
 	
 	defaultWorkingDirectory = view->native_activity->internalDataPath;
-	userHomeDirectory = view->native_activity->internalDataPath;
+	userHomeDirectory = view->native_activity->externalDataPath;
 	
 // 	services->getSoundManager()->setAudioInterface(new OpenSLAudioInterface());
 	paused = true;
@@ -91,6 +91,8 @@ AndroidCore::AndroidCore(PolycodeView *view, int xRes, int yRes, bool fullScreen
 	
 	this->view = view;
 	core = this;
+	
+	extractResources();
 }
 
 AndroidCore::~AndroidCore() {
@@ -220,6 +222,55 @@ String AndroidCore::getClipboardString() {
 	return "";
 }
 
+void AndroidCore::extractResources(){
+	std::vector<OSFileEntry> entries;
+	CoreFileProvider *afileProvider;
+	CoreFileProvider *bfileProvider;
+	
+	for (int i = 0; i < fileProviders.size(); i++){
+		if(fileProviders[i]->type == "aasset"){
+			afileProvider = fileProviders[i];
+		} else if(fileProviders[i]->type == "folder"){
+			bfileProvider = fileProviders[i];
+		}
+	}
+	
+	afileProvider->parseFolder("extract", true, entries);
+	
+	struct stat st = {0};
+	if(stat(defaultWorkingDirectory.c_str(), &st)==-1)
+		mkdir(defaultWorkingDirectory.c_str(), 0700);
+	
+	CoreFile* source;
+	CoreFile* dest;
+	char* buffer = (char*)malloc(1*sizeof(char));
+	
+	for(int i = 0; i < entries.size(); i++){
+		source = afileProvider->openFile(entries[i].fullPath,"r");
+		dest = bfileProvider->openFile(defaultWorkingDirectory+"/"+entries[i].name, "wb");
+		
+		if(source->tell() != dest->tell()){
+			while(source->read(buffer, sizeof(char), 1) > 0){
+				dest->write(buffer,sizeof(char), 1);
+			}
+		}
+		
+		afileProvider->closeFile(source);
+		bfileProvider->closeFile(dest);
+	}
+	
+	free(buffer);
+}
+
+void AndroidCore::addFileSource(const String &type, const String &source) {
+	for(int i=0; i < fileProviders.size(); i++) {
+		if(fileProviders[i]->type == type) {
+			fileProviders[i]->addSource(defaultWorkingDirectory+"/"+source);
+			return;
+		}
+	}
+}
+
 void AndroidCore::createFolder(const String& folderPath) {
 
 }

+ 1 - 1
src/core/PolyPhysFSFileProvider.cpp

@@ -4,7 +4,7 @@
 
 using namespace Polycode;
 
-PhysFSFileProvider::PhysFSFileProvider() {
+PhysFSFileProvider::PhysFSFileProvider() : CoreFileProvider() {
 	canListFiles = true;
 	type = "archive";
 	PHYSFS_init(NULL);

+ 6 - 2
src/view/android/PolycodeView.cpp

@@ -56,7 +56,7 @@ PolycodeView::PolycodeView(ANativeActivity* native, String title){
 	native_config = AConfiguration_new();
 	AConfiguration_fromAssetManager(native_config, native_activity->assetManager);
 	
-	sensorManager = ASensorManager_getInstance();		
+	sensorManager = ASensorManager_getInstance();
 	
 	const ASensor* accelerometer = ASensorManager_getDefaultSensor(sensorManager, ASENSOR_TYPE_ACCELEROMETER);
 	const ASensor* gyroscope = ASensorManager_getDefaultSensor(sensorManager, ASENSOR_TYPE_GYROSCOPE);
@@ -220,7 +220,11 @@ void onContentRectChanged(ANativeActivity* activity, const ARect *rect){
 
 void onConfiguartionChanged(ANativeActivity* activity){
 	Logger::log("onConfiguartionChanged");
-// 	activity->assetManager
+	core->getEGLMutex()->lock();
+	AConfiguration_delete(((PolycodeView*)activity->instance)->native_config);
+	((PolycodeView*)activity->instance)->native_config = AConfiguration_new();
+	AConfiguration_fromAssetManager(((PolycodeView*)activity->instance)->native_config, activity->assetManager);
+	core->getEGLMutex()->unlock();
 }
 
 void onLowMemory(ANativeActivity* activity){