Added Android Java JNI functions that set 'app' and 'ext' directories that correspond to the application data directory and the external storage app directory respectively. Shaders now use Assets. Assets no longer exist in a 'data/' directory within an AssetCache directory, but rather as their location relative to the root of the AssetCache directory. fileToMem now exists as a separate function to asset_fileToMem, as the old method does not quite fit the new AssetCache scheme. Windows version needs to be fixed to match this update. Android version needs proper Asset management via the ApkAssetCache class - this involves iterating through files in a JNI acceptable manner.
parent
c5f013d693
commit
abf9b299b5
|
@ -40,6 +40,7 @@ LOCAL_SRC_FILES := $(SDL_PATH)/src/main/android/SDL_android_main.c \
|
|||
../../../../src/AssetCache.hpp \
|
||||
../../../../src/Asset.cpp \
|
||||
../../../../src/Asset.hpp \
|
||||
../../../../src/HashTable.hpp \
|
||||
../../../../src/checksum.cpp \
|
||||
../../../../src/checksum.hpp \
|
||||
../../../../src/common.hpp \
|
||||
|
|
|
@ -3,17 +3,26 @@ package com.polymathic.RtB;
|
|||
import org.libsdl.app.SDLActivity;
|
||||
import android.content.res.AssetManager;
|
||||
import android.os.*;
|
||||
import java.io.File;
|
||||
|
||||
public class RtB extends SDLActivity {
|
||||
// Java-side to provide access to the AssetManager in C/C++
|
||||
// See Android-section in fio.cpp/fio.hpp for the C/C++ portion of asset management.
|
||||
private AssetManager manager;
|
||||
private static native void setAssetManager(AssetManager manager);
|
||||
private static native void setAppDirectory(String dir);
|
||||
private static native void setExtDirectory(String dir);
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
// set up and send native C/C++ our manager
|
||||
manager = getResources().getAssets();
|
||||
setAssetManager(manager);
|
||||
// set up and send our application directory
|
||||
File dir = getApplicationContext().getDir("data", 0);
|
||||
setAppDirectory(dir.getPath());
|
||||
File ext_dir = getApplicationContext().getExternalFilesDir(null);
|
||||
setExtDirectory(ext_dir.getPath());
|
||||
// Pass on to SDLActivity
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
|
|
|
@ -182,6 +182,7 @@
|
|||
20F746661AA27B8C00F5846A /* AssetCache.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = AssetCache.hpp; path = ../../src/AssetCache.hpp; sourceTree = SOURCE_ROOT; };
|
||||
20F746671AA27B8C00F5846A /* AssetManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AssetManager.cpp; path = ../../src/AssetManager.cpp; sourceTree = SOURCE_ROOT; };
|
||||
20F746681AA27B8C00F5846A /* AssetManager.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = AssetManager.hpp; path = ../../src/AssetManager.hpp; sourceTree = SOURCE_ROOT; };
|
||||
20F7468F1AA3265900F5846A /* HashTable.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = HashTable.hpp; path = ../../src/HashTable.hpp; sourceTree = SOURCE_ROOT; };
|
||||
20FD2D3A1A67470A00B32F7B /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = main.cpp; path = ../../src/main.cpp; sourceTree = SOURCE_ROOT; };
|
||||
28FD14FF0DC6FC520079059D /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; };
|
||||
28FD15070DC6FC5B0079059D /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
|
||||
|
@ -336,6 +337,7 @@
|
|||
20A7A9131A89F8F600EDC1A0 /* Classes */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
20F7468F1AA3265900F5846A /* HashTable.hpp */,
|
||||
20F746631AA27B8C00F5846A /* Asset.cpp */,
|
||||
20F746641AA27B8C00F5846A /* Asset.hpp */,
|
||||
20F746651AA27B8C00F5846A /* AssetCache.cpp */,
|
||||
|
|
|
@ -117,6 +117,7 @@
|
|||
20E3F2931A8CE8470071FD41 /* Mesh.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Mesh.hpp; path = ../../src/Mesh.hpp; sourceTree = SOURCE_ROOT; };
|
||||
20F7464E1AA1DE0F00F5846A /* AssetCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AssetCache.cpp; path = ../../src/AssetCache.cpp; sourceTree = SOURCE_ROOT; };
|
||||
20F7464F1AA1DE0F00F5846A /* AssetCache.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = AssetCache.hpp; path = ../../src/AssetCache.hpp; sourceTree = SOURCE_ROOT; };
|
||||
20F746731AA325C000F5846A /* HashTable.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = HashTable.hpp; path = ../../src/HashTable.hpp; sourceTree = SOURCE_ROOT; };
|
||||
8D1107320486CEB800E47090 /* Roll them Bones.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Roll them Bones.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
|
@ -138,6 +139,7 @@
|
|||
080E96DDFE201D6D7F000001 /* Classes */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
20F746731AA325C000F5846A /* HashTable.hpp */,
|
||||
20F7464E1AA1DE0F00F5846A /* AssetCache.cpp */,
|
||||
20F7464F1AA1DE0F00F5846A /* AssetCache.hpp */,
|
||||
205183CA1A9F330000DE49E9 /* Asset.cpp */,
|
||||
|
|
|
@ -35,9 +35,10 @@ AssetCache::~AssetCache() {
|
|||
/* ======== Cache loading ======== */
|
||||
int AssetCache::fromFile(const char *cache_file) {
|
||||
int ret;
|
||||
FILE *file = asset_fopen(cache_file, "rb");
|
||||
FILE *file = fopen(cache_file, "rb");
|
||||
//FILE *file = asset_fopen(cache_file, "rb");
|
||||
if (file == NULL) {
|
||||
LOG(LOG_ERROR) << "Could not open cache file: " << cache_file;
|
||||
LOG(LOG_WARNING) << "Could not open cache file: " << cache_file;
|
||||
return 1;
|
||||
}
|
||||
char fpath[1024];
|
||||
|
@ -58,6 +59,7 @@ int AssetCache::fromFile(const char *cache_file) {
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* fromDir
|
||||
This function will first attempt to load the .CACHE file contained in the given directory. If found, it is read in and updateCache() is called.
|
||||
If not, the function will traverse the full hierarchy of the given directory and populate the cache accordingly.
|
||||
|
@ -73,7 +75,7 @@ int AssetCache::fromDir(const char *dir) {
|
|||
LOG(LOG_INFO) << FUNC_NAME << ": " << cachepath << " does not exist";
|
||||
}
|
||||
directory.assign(dir);
|
||||
traverseDir_r(dir);
|
||||
traverseDir_r("");
|
||||
// TODO: move this to a "genChecksum()" sort of function
|
||||
/*HashEntry<Asset*> *entry;
|
||||
while ((entry = assets->iterate()) != NULL) {
|
||||
|
@ -89,6 +91,8 @@ int AssetCache::fromDir(const char *dir) {
|
|||
return 0;
|
||||
}
|
||||
int AssetCache::traverseDir_r(const char *dir) {
|
||||
char full_dir[1024]; // "full" dir path, e.g, "<appdata>/data/models"
|
||||
snprintf(full_dir, 1024, "%s/%s", directory.c_str(), dir);
|
||||
size_t dir_len = strlen(dir)+1;
|
||||
#if _WIN32
|
||||
WIN32_FIND_DATA ffd;
|
||||
|
@ -135,36 +139,47 @@ int AssetCache::traverseDir_r(const char *dir) {
|
|||
struct stat file_stat;
|
||||
int n, i;
|
||||
char udir[1024];
|
||||
char fpath[1024];
|
||||
char fpath[1024]; // "full" file path, e.g., "<appdir>/data/models/cube.obj"
|
||||
char lpath[1024]; // "local" file path, e.g., "data/models/cube.obj"
|
||||
Asset *asset;
|
||||
n = scandir(dir, &files, NULL, alphasort);
|
||||
n = scandir(full_dir, &files, NULL, alphasort);
|
||||
if (n < 0) {
|
||||
LOG(LOG_INFO) << FUNC_NAME << ": No files in dir " << dir;
|
||||
LOG(LOG_INFO) << FUNC_NAME << ": No files in dir " << full_dir;
|
||||
return 2;
|
||||
}
|
||||
for (i = 0; i < n; i++) {
|
||||
snprintf(fpath, 1024, "%s/%s", dir, files[i]->d_name);
|
||||
if (strlen(dir) > 0) { // if directory is not fully relative
|
||||
snprintf(lpath, 1024, "%s/%s", dir, files[i]->d_name);
|
||||
} else {
|
||||
snprintf(lpath, 1024, "%s", files[i]->d_name);
|
||||
}
|
||||
if (directory.size() > 0) {
|
||||
snprintf(fpath, 1024, "%s/%s", directory.c_str(), lpath);
|
||||
} else {
|
||||
snprintf(fpath, 1024, "%s", lpath);
|
||||
}
|
||||
stat(fpath, &file_stat);
|
||||
switch(file_stat.st_mode & S_IFMT) {
|
||||
case S_IFDIR:
|
||||
if (strcmp(files[i]->d_name, "..") == 0 || strcmp(files[i]->d_name, ".") == 0) continue;
|
||||
traverseDir_r(fpath);
|
||||
traverseDir_r(lpath);
|
||||
break;
|
||||
case S_IFREG:
|
||||
if (strcmp(files[i]->d_name, ".CACHE") == 0) continue;
|
||||
asset = assets->get(fpath);
|
||||
asset = assets->get(lpath);
|
||||
if (asset != NULL) {
|
||||
if (file_stat.st_size != asset->data_length) {
|
||||
LOG(LOG_DEBUG) << " file " << fpath << " changed from " << asset->data_length << " to " << file_stat.st_size;
|
||||
LOG(LOG_DEBUG) << " file " << lpath << " changed from " << asset->data_length << " to " << file_stat.st_size;
|
||||
asset->data_length = file_stat.st_size;
|
||||
// TODO: recalculate checksum?
|
||||
}
|
||||
} else {
|
||||
asset = new Asset();
|
||||
asset->filename.assign(fpath);
|
||||
asset->data_length = files[i]->d_off;
|
||||
assets->set(fpath, asset);
|
||||
asset->filename.assign(lpath);
|
||||
asset->data_length = file_stat.st_size;
|
||||
assets->set(lpath, asset);
|
||||
}
|
||||
LOG(LOG_DEBUG) << FUNC_NAME << "loaded " << lpath << " " << file_stat.st_size;
|
||||
asset->flags &= ~Asset::IS_NULL;
|
||||
break;
|
||||
case S_IFLNK:
|
||||
|
@ -184,9 +199,10 @@ int AssetCache::traverseDir_r(const char *dir) {
|
|||
This function saves the AssetCache to the given asset cache file
|
||||
*/
|
||||
int AssetCache::toFile(const char *cache_file) {
|
||||
FILE *file = asset_fopen(cache_file, "wb");
|
||||
//FILE *file = asset_fopen(cache_file, "wb");
|
||||
FILE *file = fopen(cache_file, "wb");
|
||||
if (file == NULL) {
|
||||
LOG(LOG_ERROR) << FUNC_NAME << ": Could not open cache file: " << cache_file << " " << errno;
|
||||
LOG(LOG_WARNING) << FUNC_NAME << ": Could not open cache file: " << cache_file << " " << errno;
|
||||
return 1;
|
||||
}
|
||||
HashEntry<Asset*> *entry;
|
||||
|
@ -228,7 +244,9 @@ Asset* AssetCache::loadAsset(const char *filename) {
|
|||
Asset *asset = getAsset(filename);
|
||||
if (asset == NULL) return NULL;
|
||||
if (!(asset->flags & Asset::IS_LOADED)) {
|
||||
asset->data_length = asset_fileToMem(asset->filename.c_str(), &(asset->data));
|
||||
char fpath[1024];
|
||||
snprintf(fpath, 1024, "%s/%s", directory.c_str(), asset->filename.c_str());
|
||||
asset->data_length = fileToMem(fpath, &(asset->data));
|
||||
asset->flags |= Asset::IS_LOADED;
|
||||
if (asset->data_checksum == 0) {
|
||||
asset->data_checksum = crc32(1337, asset->data, asset->data_length);
|
||||
|
|
|
@ -35,7 +35,7 @@ class AssetCache {
|
|||
#ifdef __ANDROID__
|
||||
class ApkAssetCache : public AssetCache {
|
||||
public:
|
||||
ApkAssetCache() : AssetCache() {};
|
||||
ApkAssetCache(const char *cache_dir) : AssetCache(cache_dir) {};
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
|
81
src/Core.cpp
81
src/Core.cpp
|
@ -20,7 +20,6 @@ Core::Core() {
|
|||
asset_manager = NULL;
|
||||
}
|
||||
Core::~Core() {
|
||||
if (asset_manager != NULL) delete asset_manager;
|
||||
}
|
||||
int Core::initSystem() {
|
||||
if (SDL_Init(SDL_INIT_EVERYTHING & ~SDL_INIT_HAPTIC) != 0) {
|
||||
|
@ -81,7 +80,9 @@ int Core::initSystem() {
|
|||
asset_manager = new AssetManager();
|
||||
// TODO: load APP cache as first cache (using ApkAssetCache in the case of Android)
|
||||
#ifdef __ANDROID__
|
||||
asset_manager->addCache(new ApkAssetCache(""));
|
||||
//asset_manager->addCache(new ApkAssetCache(""));
|
||||
asset_manager->addCache(new AssetCache(android_app_dir.c_str()));
|
||||
asset_manager->addCache(new AssetCache(android_ext_dir.c_str()));
|
||||
#else
|
||||
asset_manager->addCache(new AssetCache("data"));
|
||||
#endif
|
||||
|
@ -92,40 +93,13 @@ int Core::initSystem() {
|
|||
Program *program = new Program();
|
||||
// FIXME: check for GLSL version and automagically load the appropriate shader file
|
||||
#ifdef HAVE_OPENGLES
|
||||
if (program->addShader("data/shaders/fb_fs.100.glsl", GL_FRAGMENT_SHADER) != 0) {
|
||||
LOG(LOG_ERROR) << "Failed to add Shader!";
|
||||
return 1;
|
||||
}
|
||||
if (program->addShader("data/shaders/fb_vs.100.glsl", GL_VERTEX_SHADER) != 0) {
|
||||
LOG(LOG_ERROR) << "Failed to add Shader!";
|
||||
return 1;
|
||||
}
|
||||
if (program->doCompile() != 0) {
|
||||
LOG(LOG_ERROR) << "Failed to compile GLSL Program!";
|
||||
return 1;
|
||||
}
|
||||
// TEMP: our model rendering program
|
||||
Program *program_model = new Program();
|
||||
if (program_model->addShader("data/shaders/default_fs.100.glsl", GL_FRAGMENT_SHADER) != 0) {
|
||||
LOG(LOG_ERROR) << "Failed to add Shader!";
|
||||
return 1;
|
||||
}
|
||||
if (program_model->addShader("data/shaders/default_vs.100.glsl", GL_VERTEX_SHADER) != 0) {
|
||||
LOG(LOG_ERROR) << "Failed to add Shdaer!";
|
||||
return 1;
|
||||
}
|
||||
if (program_model->doCompile() != 0) {
|
||||
LOG(LOG_ERROR) << "Failed to compile GLSL Program!";
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
Asset *shader_asset = asset_manager->loadFile("data/shaders/fb_fs.glsl");
|
||||
Asset *shader_asset = asset_manager->loadFile("shaders/fb_fs.100.glsl");
|
||||
if (program->addShader(shader_asset->getData(), shader_asset->getDataLength(), GL_FRAGMENT_SHADER) != 0) {
|
||||
LOG(LOG_ERROR) << "Failed to add Shader!";
|
||||
return 1;
|
||||
}
|
||||
shader_asset->unloadData();
|
||||
shader_asset = asset_manager->loadFile("data/shaders/fb_vs.glsl");
|
||||
shader_asset = asset_manager->loadFile("shaders/fb_vs.100.glsl");
|
||||
if (program->addShader(shader_asset->getData(), shader_asset->getDataLength(), GL_VERTEX_SHADER) != 0) {
|
||||
LOG(LOG_ERROR) << "Failed to add Shader!";
|
||||
return 1;
|
||||
|
@ -137,13 +111,48 @@ int Core::initSystem() {
|
|||
}
|
||||
// TEMP: our model rendering program
|
||||
Program *program_model = new Program();
|
||||
shader_asset = asset_manager->loadFile("data/shaders/default_fs.glsl");
|
||||
shader_asset = asset_manager->loadFile("shaders/default_fs.100.glsl");
|
||||
if (program_model->addShader(shader_asset->getData(), shader_asset->getDataLength(), GL_FRAGMENT_SHADER) != 0) {
|
||||
LOG(LOG_ERROR) << "Failed to add Shader!";
|
||||
return 1;
|
||||
}
|
||||
shader_asset->unloadData();
|
||||
shader_asset = asset_manager->loadFile("data/shaders/default_vs.glsl");
|
||||
shader_asset = asset_manager->loadFile("shaders/default_vs.100.glsl");
|
||||
if (program_model->addShader(shader_asset->getData(), shader_asset->getDataLength(), GL_VERTEX_SHADER) != 0) {
|
||||
LOG(LOG_ERROR) << "Failed to add Shdaer!";
|
||||
return 1;
|
||||
}
|
||||
shader_asset->unloadData();
|
||||
if (program_model->doCompile() != 0) {
|
||||
LOG(LOG_ERROR) << "Failed to compile GLSL Program!";
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
Asset *shader_asset = asset_manager->loadFile("shaders/fb_fs.glsl");
|
||||
if (program->addShader(shader_asset->getData(), shader_asset->getDataLength(), GL_FRAGMENT_SHADER) != 0) {
|
||||
LOG(LOG_ERROR) << "Failed to add Shader!";
|
||||
return 1;
|
||||
}
|
||||
shader_asset->unloadData();
|
||||
shader_asset = asset_manager->loadFile("shaders/fb_vs.glsl");
|
||||
if (program->addShader(shader_asset->getData(), shader_asset->getDataLength(), GL_VERTEX_SHADER) != 0) {
|
||||
LOG(LOG_ERROR) << "Failed to add Shader!";
|
||||
return 1;
|
||||
}
|
||||
shader_asset->unloadData();
|
||||
if (program->doCompile() != 0) {
|
||||
LOG(LOG_ERROR) << "Failed to compile GLSL Program!";
|
||||
return 1;
|
||||
}
|
||||
// TEMP: our model rendering program
|
||||
Program *program_model = new Program();
|
||||
shader_asset = asset_manager->loadFile("shaders/default_fs.glsl");
|
||||
if (program_model->addShader(shader_asset->getData(), shader_asset->getDataLength(), GL_FRAGMENT_SHADER) != 0) {
|
||||
LOG(LOG_ERROR) << "Failed to add Shader!";
|
||||
return 1;
|
||||
}
|
||||
shader_asset->unloadData();
|
||||
shader_asset = asset_manager->loadFile("shaders/default_vs.glsl");
|
||||
if (program_model->addShader(shader_asset->getData(), shader_asset->getDataLength(), GL_VERTEX_SHADER) != 0) {
|
||||
LOG(LOG_ERROR) << "Failed to add Shader!";
|
||||
return 1;
|
||||
|
@ -173,7 +182,7 @@ int Core::initSystem() {
|
|||
Asset *asset_mesh;
|
||||
|
||||
RenderObject *objerct = new RenderObject();
|
||||
asset_mesh = asset_manager->loadFile("data/models/cube.obj");
|
||||
asset_mesh = asset_manager->loadFile("models/cube.obj");
|
||||
Mesh *mersh = new Mesh(asset_mesh->getData(), asset_mesh->getDataLength());
|
||||
asset_mesh->unloadData();
|
||||
mersh->buildMesh();
|
||||
|
@ -181,7 +190,7 @@ int Core::initSystem() {
|
|||
sert->addObject(objerct);
|
||||
|
||||
objerct = new RenderObject();
|
||||
asset_mesh = asset_manager->loadFile("data/models/chest.obj");
|
||||
asset_mesh = asset_manager->loadFile("models/chest.obj");
|
||||
mersh = new Mesh(asset_mesh->getData(), asset_mesh->getDataLength());
|
||||
asset_mesh->unloadData();
|
||||
mersh->buildMesh();
|
||||
|
@ -202,6 +211,8 @@ int Core::closeSystem() {
|
|||
delete scene;
|
||||
// TODO: delete scene should delete rendercameras, renderviews, rendersets, and renderobjects.
|
||||
// TODO: delete meshes loaded (assets) as well
|
||||
if (asset_manager != NULL) delete asset_manager;
|
||||
|
||||
SDL_GL_DeleteContext(v_context);
|
||||
SDL_DestroyWindow(v_window);
|
||||
SDL_Quit();
|
||||
|
|
47
src/fio.cpp
47
src/fio.cpp
|
@ -8,6 +8,37 @@ If any file is attempted to be read or written to, fio.hpp should be included fi
|
|||
#include "fio.hpp"
|
||||
#include "Log.hpp"
|
||||
#include <string.h> // malloc
|
||||
|
||||
size_t fileToMem(const char *filename, char **buffer) {
|
||||
char chunk[1024];
|
||||
#if _WIN32
|
||||
// _fsopen is used as we pass a FILE ptr back - fopen_s does not allow this
|
||||
FILE *file = _fsopen(filename, "rb", _SH_DENYNO);
|
||||
#else
|
||||
FILE *file = fopen(filename, "rb");
|
||||
#endif
|
||||
if (file == NULL) {
|
||||
LOG(LOG_ERROR) << FUNC_NAME << ": could not open " << filename;
|
||||
return 0;
|
||||
}
|
||||
fseek(file, 0, SEEK_END);
|
||||
size_t size = ftell(file)+1;
|
||||
fseek(file, 0, SEEK_SET);
|
||||
|
||||
*buffer = (char*)malloc(size*sizeof(char));
|
||||
if (*buffer == NULL) {
|
||||
LOG(LOG_ERROR) << FUNC_NAME << ": could not allocate " << size << " bytes for asset " << filename;
|
||||
return NULL;
|
||||
}
|
||||
int n = 0;
|
||||
size_t offset = 0;
|
||||
while ((n = fread(chunk, 1, 1024, file))) {
|
||||
memcpy((*buffer)+offset, chunk, n);
|
||||
offset += n;
|
||||
}
|
||||
fclose(file);
|
||||
return offset;
|
||||
}
|
||||
/* ======== Asset data access ======== */
|
||||
// Assets are files that may exist in an external storage directory (iOS/Android), a user data directory(all), or in the application itself (iOS/Android/OSX).
|
||||
/* asset_fileToMem
|
||||
|
@ -90,4 +121,20 @@ FILE* apk_fopen(const char *filename, const char *mode) {
|
|||
if (!asset) return NULL;
|
||||
return funopen(asset, apk_read, apk_write, apk_seek, apk_close);
|
||||
}
|
||||
|
||||
std::string android_app_dir;
|
||||
std::string android_ext_dir;
|
||||
JNIEXPORT void JNICALL Java_com_polymathic_RtB_RtB_setAppDirectory(JNIEnv* env, jobject obj, jstring app_dir) {
|
||||
jboolean iscopy;
|
||||
const char *native_string = env->GetStringUTFChars(app_dir, &iscopy);
|
||||
android_app_dir.assign(native_string);
|
||||
env->ReleaseStringUTFChars(app_dir, native_string);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_polymathic_RtB_RtB_setExtDirectory(JNIEnv* env, jobject obj, jstring ext_dir) {
|
||||
jboolean iscopy;
|
||||
const char *native_string = env->GetStringUTFChars(ext_dir, &iscopy);
|
||||
android_ext_dir.assign(native_string);
|
||||
env->ReleaseStringUTFChars(ext_dir, native_string);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -8,6 +8,8 @@ If any file is attempted to be read or written to, fio.hpp should be included fi
|
|||
#ifndef FIO_HPP
|
||||
#define FIO_HPP
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
size_t fileToMem(const char *filename, char **buffer);
|
||||
/* ======== Asset data access ======== */
|
||||
size_t asset_fileToMem(const char *filename, char **buffer);
|
||||
FILE *asset_fopen(const char *filename, const char *mode);
|
||||
|
@ -16,10 +18,14 @@ FILE *asset_fopen(const char *filename, const char *mode);
|
|||
#include <jni.h>
|
||||
#include <android/asset_manager.h>
|
||||
#include <android/asset_manager_jni.h>
|
||||
extern std::string android_app_dir;
|
||||
extern std::string android_ext_dir;
|
||||
extern "C" {
|
||||
void apk_set_asset_manager(AAssetManager* manager);
|
||||
FILE *apk_fopen(const char *filename, const char *mode);
|
||||
JNIEXPORT void JNICALL Java_com_polymathic_RtB_RtB_setAssetManager(JNIEnv* env, jobject obj, jobject assetManager);
|
||||
JNIEXPORT void JNICALL Java_com_polymathic_RtB_RtB_setAppDirectory(JNIEnv* env, jobject obj, jstring app_dir);
|
||||
JNIEXPORT void JNICALL Java_com_polymathic_RtB_RtB_setExtDirectory(JNIEnv* env, jobject obj, jstring ext_dir);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue