Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
android: PhysicsFS now has actual Android support.
This compiled and worked on Android before, if you didn't care about PHYSFS_getBaseDir() and PHYSFS_getPrefDir() being useful. Now you can pass PHYSFS_init() some necessary Android objects to solve this. Passing NULL to PHYSFS_init is acceptable and will simply report "/" for the base dir and prefdir, under the assumption that the app queried the OS for these directly instead.
- Loading branch information
Showing
5 changed files
with
155 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
/* | ||
* Android support routines for PhysicsFS. | ||
* | ||
* Please see the file LICENSE.txt in the source's root directory. | ||
* | ||
* This file written by Ryan C. Gordon. | ||
*/ | ||
|
||
#define __PHYSICSFS_INTERNAL__ | ||
#include "physfs_platforms.h" | ||
|
||
#ifdef PHYSFS_PLATFORM_ANDROID | ||
|
||
#include <jni.h> | ||
#include <android/log.h> | ||
#include "physfs_internal.h" | ||
|
||
static char *prefpath = NULL; | ||
|
||
|
||
int __PHYSFS_platformInit(void) | ||
{ | ||
return 1; /* always succeed. */ | ||
} /* __PHYSFS_platformInit */ | ||
|
||
|
||
void __PHYSFS_platformDeinit(void) | ||
{ | ||
if (prefpath) | ||
{ | ||
allocator.Free(prefpath); | ||
prefpath = NULL; | ||
} /* if */ | ||
} /* __PHYSFS_platformDeinit */ | ||
|
||
|
||
void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data) | ||
{ | ||
/* no-op. */ | ||
} /* __PHYSFS_platformDetectAvailableCDs */ | ||
|
||
|
||
char *__PHYSFS_platformCalcBaseDir(const char *argv0) | ||
{ | ||
/* as a cheat, we expect argv0 to be a PHYSFS_AndroidInit* on Android. */ | ||
PHYSFS_AndroidInit *ainit = (PHYSFS_AndroidInit *) argv0; | ||
char *retval = NULL; | ||
JNIEnv *jenv = NULL; | ||
jobject jcontext; | ||
|
||
if (ainit == NULL) | ||
return __PHYSFS_strdup("/"); /* oh well. */ | ||
|
||
jenv = (JNIEnv *) ainit->jnienv; | ||
jcontext = (jobject) ainit->context; | ||
|
||
if ((*jenv)->PushLocalFrame(jenv, 16) >= 0) | ||
{ | ||
jobject jfileobj = 0; | ||
jmethodID jmeth = 0; | ||
jthrowable jexception = 0; | ||
jstring jstr = 0; | ||
|
||
jmeth = (*jenv)->GetMethodID(jenv, (*jenv)->GetObjectClass(jenv, jcontext), "getPackageResourcePath", "()Ljava/lang/String;"); | ||
jstr = (jstring)(*jenv)->CallObjectMethod(jenv, jcontext, jmeth); | ||
jexception = (*jenv)->ExceptionOccurred(jenv); /* this can't throw an exception, right? Just in case. */ | ||
if (jexception != NULL) | ||
(*jenv)->ExceptionClear(jenv); | ||
else | ||
{ | ||
const char *path = (*jenv)->GetStringUTFChars(jenv, jstr, NULL); | ||
retval = __PHYSFS_strdup(path); | ||
(*jenv)->ReleaseStringUTFChars(jenv, jstr, path); | ||
} /* else */ | ||
|
||
/* We only can rely on the Activity being valid during this function call, | ||
so go ahead and grab the prefpath too. */ | ||
jmeth = (*jenv)->GetMethodID(jenv, (*jenv)->GetObjectClass(jenv, jcontext), "getFilesDir", "()Ljava/io/File;"); | ||
jfileobj = (*jenv)->CallObjectMethod(jenv, jcontext, jmeth); | ||
if (jfileobj) | ||
{ | ||
jmeth = (*jenv)->GetMethodID(jenv, (*jenv)->GetObjectClass(jenv, jfileobj), "getCanonicalPath", "()Ljava/lang/String;"); | ||
jstr = (jstring)(*jenv)->CallObjectMethod(jenv, jfileobj, jmeth); | ||
jexception = (*jenv)->ExceptionOccurred(jenv); | ||
if (jexception != NULL) | ||
(*jenv)->ExceptionClear(jenv); | ||
else | ||
{ | ||
const char *path = (*jenv)->GetStringUTFChars(jenv, jstr, NULL); | ||
const size_t len = strlen(path) + 2; | ||
prefpath = allocator.Malloc(len); | ||
if (prefpath) | ||
snprintf(prefpath, len, "%s/", path); | ||
(*jenv)->ReleaseStringUTFChars(jenv, jstr, path); | ||
} /* else */ | ||
} /* if */ | ||
|
||
(*jenv)->PopLocalFrame(jenv, NULL); | ||
} /* if */ | ||
|
||
/* we can't return NULL because then PhysicsFS will treat argv0 as a string, but it's a non-NULL jobject! */ | ||
if (retval == NULL) | ||
retval = __PHYSFS_strdup("/"); /* we pray this works. */ | ||
|
||
return retval; | ||
} /* __PHYSFS_platformCalcBaseDir */ | ||
|
||
|
||
char *__PHYSFS_platformCalcPrefDir(const char *org, const char *app) | ||
{ | ||
return __PHYSFS_strdup(prefpath ? prefpath : "/"); | ||
} /* __PHYSFS_platformCalcPrefDir */ | ||
|
||
#endif /* PHYSFS_PLATFORM_ANDROID */ | ||
|
||
/* end of physfs_platform_android.c ... */ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters