Przeglądaj źródła

Merge branch 'filesystem-mount-points'

Daniele Bartolini 12 lat temu
rodzic
commit
f73d9b8eff

+ 4 - 0
engine/Android.mk

@@ -31,6 +31,7 @@ LOCAL_SRC_FILES :=\
 	core/filesystem/Filesystem.cpp\
 	core/filesystem/TextReader.cpp\
 	core/filesystem/TextWriter.cpp\
+	core/filesystem/DiskMountPoint.cpp\
 \
 	core/json/JSONParser.cpp\
 \
@@ -70,6 +71,9 @@ LOCAL_SRC_FILES :=\
 	os/android/AndroidOS.cpp\
 	os/android/AndroidDevice.cpp\
 	os/android/OsWindow.cpp\
+	os/android/APKFile.cpp\
+	os/android/AndroidFile.cpp\
+	os/android/AndroidMountPoint.cpp\
 	os/posix/OsFile.cpp\
 	os/posix/Thread.cpp\
 	os/posix/Mutex.cpp\

+ 3 - 1
engine/CMakeLists.txt

@@ -153,6 +153,7 @@ set (FILESYSTEM_SRC
 	core/filesystem/TextReader.cpp
 	core/filesystem/TextWriter.cpp
 
+	core/filesystem/DiskMountPoint.cpp
 	core/filesystem/Filesystem.cpp
 )
 
@@ -166,6 +167,7 @@ set (FILESYSTEM_HEADERS
 	core/filesystem/TextReader.h
 	core/filesystem/TextWriter.h
 
+	core/filesystem/DiskMountPoint.h
 	core/filesystem/Filesystem.h
 )
 
@@ -519,7 +521,7 @@ add_executable(${CROWN_EXECUTABLE_NAME} ${CROWN_MAIN_SRC})
 target_link_libraries(${CROWN_EXECUTABLE_NAME} crown)
 
 if (CROWN_BUILD_TESTS)
-	add_subdirectory(tests)
+	#add_subdirectory(tests)
 endif (CROWN_BUILD_TESTS)
 
 install (TARGETS crown DESTINATION bin)

+ 25 - 7
engine/Device.cpp

@@ -22,6 +22,7 @@ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 OTHER DEALINGS IN THE SOFTWARE.
+OTHER DEALINGS IN THE SOFTWARE.
 */
 
 #include <cstdlib>
@@ -52,12 +53,20 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "LuaEnvironment.h"
 #include "ConsoleServer.h"
 #include "TextReader.h"
+#include "SoundResource.h"
+#include "StringSetting.h"
 
 namespace crown
 {
 
+#ifdef ANDROID
+	StringSetting g_default_mountpoint("default_mountpoint", "define default mount point for filesystem", "android");
+#else
+	StringSetting g_default_mountpoint("default_mountpoint", "define default mount point for filesystem", "disk");
+#endif
+
 //-----------------------------------------------------------------------------
-Device::Device() :
+Device::Device() : 
 	m_allocator(m_subsystems_heap, MAX_SUBSYSTEMS_HEAP),
 
 	m_preferred_window_width(1000),
@@ -90,6 +99,12 @@ Device::Device() :
 {
 	// Select executable dir by default
 	string::strncpy(m_preferred_root_path, os::get_cwd(), MAX_PATH_LENGTH);
+
+	#ifdef ANDROID
+	m_root_mountpoint = AndroidMountPoint();
+	#else
+	m_root_mountpoint = DiskMountPoint();
+	#endif
 }
 
 //-----------------------------------------------------------------------------
@@ -126,7 +141,7 @@ bool Device::init(int argc, char** argv)
 
 	create_lua_environment();
 
-	create_console_server();
+	// create_console_server();
 
 	read_engine_settings();
 
@@ -356,10 +371,9 @@ void Device::frame()
 
 	m_window->frame();
 	m_input_manager->frame(frame_count());
-
 	m_lua_environment->game_frame(last_delta_time());
 
-	//m_console_server->execute();
+	// m_console_server->execute();
 
 	m_debug_renderer->draw_all();
 	m_renderer->frame();
@@ -376,10 +390,14 @@ void Device::reload(ResourceId name)
 //-----------------------------------------------------------------------------
 void Device::create_filesystem()
 {
-	m_filesystem = CE_NEW(m_allocator, Filesystem)(m_preferred_root_path);
+	m_filesystem = CE_NEW(m_allocator, Filesystem)();
+
+	m_root_mountpoint.set_root_path(m_preferred_root_path);
+
+	m_filesystem->mount(m_root_mountpoint);
 
 	Log::d("Filesystem created.");
-	Log::d("Filesystem root path: %s", m_filesystem->root_path());
+	Log::d("Filesystem root path: %s", m_root_mountpoint.root_path());
 }
 
 //-----------------------------------------------------------------------------
@@ -396,7 +414,7 @@ void Device::create_resource_manager()
 	}
 
 	// Read resource seed
-	DiskFile* seed_file = filesystem()->open("seed.ini", FOM_READ);
+	DiskFile* seed_file = (DiskFile*)filesystem()->open(g_default_mountpoint.value(), "seed.ini", FOM_READ);
 	TextReader reader(*seed_file);
 
 	char tmp_buf[32];

+ 13 - 0
engine/Device.h

@@ -31,6 +31,11 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "OS.h"
 #include "LinearAllocator.h"
 #include "Resource.h"
+#include "DiskMountPoint.h"
+
+#ifdef ANDROID
+#include "AndroidMountPoint.h"
+#endif
 
 #define MAX_SUBSYSTEMS_HEAP 1024 * 1024
 
@@ -170,6 +175,14 @@ private:
 	// Debug subsystems
 	ConsoleServer*			m_console_server;
 
+	#ifdef ANDROID
+	AndroidMountPoint		m_root_mountpoint;
+	#else
+	DiskMountPoint			m_root_mountpoint;
+	#endif
+
+	// TODO set default StringSetting for default_mountpoint
+
 private:
 
 	enum

+ 205 - 0
engine/core/filesystem/DiskMountPoint.cpp

@@ -0,0 +1,205 @@
+/*
+Copyright (c) 2013 Daniele Bartolini, Michele Rossi
+Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include "DiskMountPoint.h"
+#include "Assert.h"
+#include "DiskFile.h"
+#include "StringUtils.h"
+#include "Allocator.h"
+
+namespace crown
+{
+
+//-----------------------------------------------------------------------------
+DiskMountPoint::DiskMountPoint() : MountPoint(DISK_TYPE)
+{
+}
+
+//-----------------------------------------------------------------------------
+File* DiskMountPoint::open(const char* relative_path, FileOpenMode mode)
+{
+	CE_ASSERT(exists(relative_path), "File does not exist: %s", relative_path);
+	CE_ASSERT(is_file(relative_path), "File is not a regular file: %s", relative_path);
+
+	return CE_NEW(default_allocator(), DiskFile)(mode, os_path(relative_path));
+}
+
+//-----------------------------------------------------------------------------
+void DiskMountPoint::close(File* file)
+{
+	CE_DELETE(default_allocator(), file);
+}
+
+void DiskMountPoint::set_root_path(const char* root_path)
+{
+	CE_ASSERT(root_path != NULL, "Root path must be != NULL");
+	CE_ASSERT(os::is_absolute_path(root_path), "Root path must be absolute");
+
+	string::strncpy(m_root_path, root_path, MAX_PATH_LENGTH);
+}
+
+
+//-----------------------------------------------------------------------------
+const char*	DiskMountPoint::root_path() const
+{
+	return m_root_path;
+}
+
+//-----------------------------------------------------------------------------
+bool DiskMountPoint::exists(const char* relative_path)
+{
+	MountPointEntry info;
+
+	return get_info(relative_path, info);	
+}
+//-----------------------------------------------------------------------------
+bool DiskMountPoint::get_info(const char* relative_path, MountPointEntry& info)
+{
+	// Entering OS-DEPENDENT-PATH-MODE
+	// (i.e. os_path is of the form: C:\foo\relative_path or /foo/relative_path)
+
+	const char* os_path = build_os_path(m_root_path, relative_path);
+
+	Log::d("path : %s", os_path);
+
+	string::strncpy(info.os_path, os_path, MAX_PATH_LENGTH);
+	string::strncpy(info.relative_path, relative_path, MAX_PATH_LENGTH);
+
+	if (os::is_reg(os_path))
+	{
+		info.type = MountPointEntry::FILE;
+		return true;
+	}
+	else if (os::is_dir(os_path))
+	{
+		info.type = MountPointEntry::DIRECTORY;
+		return true;
+	}
+	
+	info.type = MountPointEntry::UNKNOWN;
+
+	return false;
+}
+
+//-----------------------------------------------------------------------------
+bool DiskMountPoint::is_file(const char* relative_path)
+{
+	MountPointEntry info;
+
+	if (get_info(relative_path, info))
+	{
+		return info.type == MountPointEntry::FILE;
+	}
+
+	return false;
+}
+
+//-----------------------------------------------------------------------------
+bool DiskMountPoint::is_dir(const char* relative_path)
+{
+	MountPointEntry info;
+
+	if (get_info(relative_path, info))
+	{
+		return info.type == MountPointEntry::DIRECTORY;
+	}
+
+	return false;
+}
+
+//-----------------------------------------------------------------------------
+bool DiskMountPoint::create_file(const char* relative_path)
+{
+	const char* os_path = build_os_path(m_root_path, relative_path);
+
+	return os::mknod(os_path);
+}
+
+//-----------------------------------------------------------------------------
+bool DiskMountPoint::create_dir(const char* relative_path)
+{
+	const char* os_path = build_os_path(m_root_path, relative_path);
+
+	return os::mkdir(os_path);
+}
+
+//-----------------------------------------------------------------------------
+bool DiskMountPoint::delete_file(const char* relative_path)
+{
+	const char* os_path = build_os_path(m_root_path, relative_path);
+
+	return os::unlink(os_path);
+}
+
+//-----------------------------------------------------------------------------
+bool DiskMountPoint::delete_dir(const char* relative_path)
+{
+	const char* os_path = build_os_path(m_root_path, relative_path);
+
+	return os::rmdir(os_path);
+}
+
+//-----------------------------------------------------------------------------
+const char* DiskMountPoint::os_path(const char* relative_path)
+{
+	static char os_path[MAX_PATH_LENGTH];
+
+	MountPointEntry entry;
+
+	get_info(relative_path, entry);
+
+	string::strncpy(os_path, entry.os_path, MAX_PATH_LENGTH);
+
+	return os_path;
+}
+
+//-----------------------------------------------------------------------------
+const char* DiskMountPoint::build_os_path(const char* base_path, const char* relative_path)
+{
+	static char os_path[MAX_PATH_LENGTH];
+
+	string::strncpy(os_path, base_path, MAX_PATH_LENGTH);
+
+	size_t base_path_len = string::strlen(base_path);
+
+	os_path[base_path_len] = PATH_SEPARATOR;
+	os_path[base_path_len + 1] = '\0';
+
+	string::strcat(os_path, relative_path);
+
+	// FIXME FIXME FIXME Replace Crown-specific path separator with OS-specific one
+	for (size_t j = 0; j < string::strlen(os_path); j++)
+	{
+		if (os_path[j] == '/')
+		{
+			os_path[j] = PATH_SEPARATOR;
+		}
+	}
+
+	return os_path;
+}
+
+} // namespace crown

+ 92 - 0
engine/core/filesystem/DiskMountPoint.h

@@ -0,0 +1,92 @@
+/*
+Copyright (c) 2013 Daniele Bartolini, Michele Rossi
+Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#pragma once
+
+#include "MountPoint.h"
+
+namespace crown
+{
+
+class DiskMountPoint : public MountPoint
+{
+public:
+						DiskMountPoint();
+
+	/// Opens file @a relative_path in specified @a mode
+	File*				open(const char* relative_path, FileOpenMode mode);
+
+	/// Closes @a file
+	void				close(File* file);
+
+	/// Sets @a root_path
+	void				set_root_path(const char* root_path);
+
+	/// Returns the root path of the mount point
+	const char*			root_path() const;
+
+	/// Returns true if file @a relative_path exists
+	bool				exists(const char* relative_path);
+
+	/// Returns whether the @a relative_path exists and fills @a info with
+	/// with informations about the given @a relative_path path
+	bool				get_info(const char* relative_path, MountPointEntry& info);
+	
+	/// Returns whether @a relative_path is a regular file
+	bool				is_file(const char* relative_path);
+
+	/// Returns whether @a relative_path is a directory
+	bool				is_dir(const char* relative_path);
+
+	/// Creates a regular file called @a relative_path
+	bool				create_file(const char* relative_path);
+
+	/// Creates a directory called @a relative_path
+	bool 				create_dir(const char* relative_path);
+
+	/// Deletes a regular file called @a relative_path
+	bool				delete_file(const char* relative_path);
+
+	/// Deletes a directory called @a relative_path
+	bool 				delete_dir(const char* relative_path);
+
+	/// Returns the os-specific path which @a relative_path refers to.
+	/// @note
+	/// In general, you typically do not want to use it for normal
+	/// file interactions. Prefer using the other methods whenever possible.
+	const char*			os_path(const char* relative_path);
+
+protected:
+
+	// Builds the OS-dependent path from base_path and relative_path
+	const char*			build_os_path(const char* base_path, const char* relative_path);
+
+protected:
+
+	char				m_root_path[MAX_PATH_LENGTH];
+};
+
+} // namespace crown

+ 73 - 104
engine/core/filesystem/Filesystem.cpp

@@ -29,17 +29,20 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "OS.h"
 #include "DiskFile.h"
 #include "Memory.h"
+#include "Hash.h"
+#include "DiskMountPoint.h"
+#include "StringSetting.h"
+#include "MountPoint.h"
+
 
 namespace crown
 {
 
 //-----------------------------------------------------------------------------
-Filesystem::Filesystem(const char* root_path)
+Filesystem::Filesystem() :
+	m_mount_point_head(NULL)
 {
-	CE_ASSERT(root_path != NULL, "Root path must be != NULL");
-	CE_ASSERT(os::is_absolute_path(root_path), "Root path must be absolute");
 
-	string::strncpy(m_root_path, root_path, MAX_PATH_LENGTH);
 }
 
 //-----------------------------------------------------------------------------
@@ -48,158 +51,124 @@ Filesystem::~Filesystem()
 }
 
 //-----------------------------------------------------------------------------
-const char* Filesystem::root_path() const
+void Filesystem::mount(MountPoint& mp)
 {
-	return m_root_path;
+	if (m_mount_point_head != NULL)
+	{
+		mp.m_next = m_mount_point_head; 
+	}
+
+	m_mount_point_head = &mp;
 }
 
 //-----------------------------------------------------------------------------
-const char* Filesystem::build_os_path(const char* base_path, const char* relative_path)
+void Filesystem::umount(MountPoint& mp)
 {
-	static char os_path[MAX_PATH_LENGTH];
+	MountPoint* current = m_mount_point_head;
+	MountPoint* previous;
+	MountPoint* tmp;
+	(void)tmp;
 
-	string::strncpy(os_path, base_path, MAX_PATH_LENGTH);
+	if (&mp == current)
+	{	
+		tmp = current;
 
-	size_t base_path_len = string::strlen(base_path);
+		current = current->m_next;
 
-	os_path[base_path_len] = PATH_SEPARATOR;
-	os_path[base_path_len + 1] = '\0';
+		tmp = NULL;
 
-	string::strcat(os_path, relative_path);
-
-	// FIXME FIXME FIXME Replace Crown-specific path separator with OS-speficic one
-	for (size_t j = 0; j < string::strlen(os_path); j++)
+		return;
+	}
+	else
 	{
-		if (os_path[j] == '/')
+		previous = current;
+		current = current->m_next;
+
+		while (current != NULL && &mp != current)
 		{
-			os_path[j] = PATH_SEPARATOR;
+			previous = current;
+
+			current = current->m_next;
 		}
-	}
 
-	return os_path;
+		if (current != NULL)
+		{
+			tmp = current;
+
+			previous->m_next = current->m_next;
+
+			tmp = NULL;
+
+			return;
+		}
+	}
 }
 
 //-----------------------------------------------------------------------------
-bool Filesystem::get_info(const char* relative_path, FilesystemEntry& info)
+File* Filesystem::open(const char* mount_point, const char* relative_path, FileOpenMode mode)
 {
-	// Entering OS-DEPENDENT-PATH-MODE
-	// (i.e. os_path is of the form: C:\foo\relative_path or /foo/relative_path)
-
-	const char* os_path = build_os_path(m_root_path, relative_path);
-	
-	string::strncpy(info.os_path, os_path, MAX_PATH_LENGTH);
-	string::strncpy(info.relative_path, relative_path, MAX_PATH_LENGTH);
+	MountPoint* mp = find_mount_point(mount_point);
 
-	if (os::is_reg(os_path))
-	{
-		info.type = FilesystemEntry::FILE;
-		return true;
-	}
-	else if (os::is_dir(os_path))
+	if (mp)
 	{
-		info.type = FilesystemEntry::DIRECTORY;
-		return true;
+		return mp->open(relative_path, mode);
 	}
-	
-	info.type = FilesystemEntry::UNKNOWN;
 
-	return false;
+	return NULL;
 }
 
 //-----------------------------------------------------------------------------
-bool Filesystem::exists(const char* relative_path)
+void Filesystem::close(File* file)
 {
-	FilesystemEntry dummy;
-
-	return get_info(relative_path, dummy);
+	CE_DELETE(m_allocator, file);
 }
 
 //-----------------------------------------------------------------------------
-bool Filesystem::is_file(const char* relative_path)
+bool Filesystem::exists(const char* mount_point, const char* relative_path)
 {
-	FilesystemEntry info;
+	MountPoint* mp = find_mount_point(mount_point);
 
-	if (get_info(relative_path, info))
+	if (mp)
 	{
-		return info.type == FilesystemEntry::FILE;
+		return mp->exists(relative_path);
 	}
 
 	return false;
 }
 
 //-----------------------------------------------------------------------------
-bool Filesystem::is_dir(const char* relative_path)
+const char* Filesystem::os_path(const char* mount_point, const char* relative_path)
 {
-	FilesystemEntry info;
+	MountPoint* mp = find_mount_point(mount_point);
 
-	if (get_info(relative_path, info))
+	if (mp)
 	{
-		return info.type == FilesystemEntry::DIRECTORY;
+		return mp->os_path(relative_path);
 	}
 
-	return false;
+	return NULL;
 }
 
 //-----------------------------------------------------------------------------
-bool Filesystem::create_file(const char* relative_path)
+MountPoint*	Filesystem::find_mount_point(const char* mount_point)
 {
-	const char* os_path = build_os_path(m_root_path, relative_path);
+	MountPoint* curr = m_mount_point_head;
 
-	return os::mknod(os_path);
-}
-
-//-----------------------------------------------------------------------------
-bool Filesystem::create_dir(const char* relative_path)
-{
-	const char* os_path = build_os_path(m_root_path, relative_path);
-
-	return os::mkdir(os_path);
-}
+	uint32_t type_hash = hash::murmur2_32(mount_point, string::strlen(mount_point), 0);
 
-//-----------------------------------------------------------------------------
-bool Filesystem::delete_file(const char* relative_path)
-{
-	const char* os_path = build_os_path(m_root_path, relative_path);
-
-	return os::unlink(os_path);
-}
-
-//-----------------------------------------------------------------------------
-bool Filesystem::delete_dir(const char* relative_path)
-{
-	const char* os_path = build_os_path(m_root_path, relative_path);
-
-	return os::rmdir(os_path);
-}
-
-//-----------------------------------------------------------------------------
-const char* Filesystem::os_path(const char* relative_path)
-{
-	static char os_path[MAX_PATH_LENGTH];
-
-	FilesystemEntry entry;
-
-	get_info(relative_path, entry);
-
-	string::strncpy(os_path, entry.os_path, MAX_PATH_LENGTH);
-
-	return os_path;
-}
+	while(curr != NULL)
+	{
+		if (curr->type() == type_hash)
+		{
+			return curr;
+		}
 
-//-----------------------------------------------------------------------------
-DiskFile* Filesystem::open(const char* relative_path, FileOpenMode mode)
-{
-	CE_ASSERT(exists(relative_path), "File does not exist: %s", relative_path);
-	CE_ASSERT(is_file(relative_path), "File is not a regular file: %s", relative_path);
+		curr = curr->m_next;
+	}
 
-	return CE_NEW(m_allocator, DiskFile)(mode, os_path(relative_path));
+	return NULL;
 }
 
-//-----------------------------------------------------------------------------
-void Filesystem::close(DiskFile* stream)
-{
-	CE_DELETE(m_allocator, stream);
-}
 
 } // namespace crown
 

+ 25 - 60
engine/core/filesystem/Filesystem.h

@@ -30,28 +30,12 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "OS.h"
 #include "File.h"
 #include "HeapAllocator.h"
+#include "MountPoint.h"
 
 namespace crown
 {
 
-struct FilesystemEntry
-{
-	enum Type
-	{
-		DIRECTORY = 0,		///< The entry is a directory
-		FILE,				///< The entry is a file
-		MEMORY,				///< The entry is a memory file (i.e. does not exist on the disk)
-		UNKNOWN				///< The entry type is unknown
-	};
-
-	FilesystemEntry() : type(UNKNOWN) {}
-
-	Type			type;								///< Type of the entry
-	char			os_path[MAX_PATH_LENGTH];			///< OS-specific path (use only for debug)
-	char			relative_path[MAX_PATH_LENGTH];		///< Relative path of the entry
-};
-
-class DiskFile;
+class File;
 
 /// Provides a platform-independent way to access files and directories
 /// on the host filesystem.
@@ -102,64 +86,45 @@ class Filesystem
 {
 public:
 
-	/// The @a root_path must be absolute.
-						Filesystem(const char* root_path);
+						Filesystem();
 						~Filesystem();
 
-	/// Returns the root path of the filesystem
-	const char*			root_path() const;
-
-	/// Returns whether the @a relative_path exists and fills @a info with
-	/// with informations about the given @a relative_path path
-	bool				get_info(const char* relative_path, FilesystemEntry& info);
-	
-	/// Returns whether the @a relative_path exists on disk
-	bool				exists(const char* relative_path);
-
-	/// Returns whether @a relative_path is a regular file
-	bool				is_file(const char* relative_path);
-
-	/// Returns whether @a relative_path is a directory
-	bool				is_dir(const char* relative_path);
-
-	/// Creates a regular file named @a relative_path
-	bool				create_file(const char* relative_path);
-
-	/// Creates a directory named @a relative_path
-	bool				create_dir(const char* relative_path);
-
-	/// Deletes the regular file @a relative_path
-	bool				delete_file(const char* relative_path);
-
-	/// Deletes the directory @a relative_path
-	bool				delete_dir(const char* relative_path);
+	/// Makes available mount point @a mp
+	void				mount(MountPoint& mp);
 
-	/// Returns the os-specific path which @a relative_path refers to.
-	/// @note
-	/// In general, you typically do not want to use it for normal
-	/// file interactions. Prefer using the other methods whenever possible.
-	const char*			os_path(const char* relative_path);
+	/// Makes unavailable mount point @a mp
+	void				umount(MountPoint& mp);
 
 	/// Opens the file @a relative_path with the specified access @a mode
-	DiskFile*			open(const char* relative_path, FileOpenMode mode);
+	/// contained in @a mount_point
+	File*				open(const char* mount_point, const char* relative_path, FileOpenMode mode);
 
 	/// Closes a previously opened file @a stream
-	void				close(DiskFile* stream);
+	void				close(File* stream);
 
-private:
+	/// Returns true if file @a relative_path exists in @a mount_point
+	bool				exists(const char* mount_point, const char* relative_path);
+
+	/// Returns path of file @a relative_path in @a mount_point
+	const char*			os_path(const char* mount_point, const char* relative_path);
 
-	// Builds the OS-dependent path from base_path and relative_path
-	const char*			build_os_path(const char* base_path, const char* relative_path);
+private:
 	
+	/// Gets __first__ mount point fetchable by @a mount_point
+	MountPoint*			find_mount_point(const char* mount_point);				
+
+	// Disable copying
+						Filesystem(const Filesystem&);
+	Filesystem&			operator=(const Filesystem&);
+		
 private:
 
 	HeapAllocator		m_allocator;
 
 	char				m_root_path[MAX_PATH_LENGTH];
 
-	// Disable copying
-						Filesystem(const Filesystem&);
-	Filesystem&			operator=(const Filesystem&);
+	MountPoint* 		m_mount_point_head;
+
 
 	friend class		Device;
 };

+ 110 - 0
engine/core/filesystem/MountPoint.h

@@ -0,0 +1,110 @@
+/*
+Copyright (c) 2013 Daniele Bartolini, Michele Rossi
+Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#pragma once
+
+#include "OS.h"
+#include "File.h"
+
+
+namespace crown
+{
+
+/// Hashed values for supported MountPoint types
+const char* const DISK_MOUNT_POINT			= "disk";
+const char* const ANDROID_MOUNT_POINT		= "asset";
+
+const uint32_t DISK_TYPE 					= 0x7BCBC5EE;
+const uint32_t ANDROID_TYPE					= 0xAAD5F176;
+
+/// Represent single entity in MountPoint
+struct MountPointEntry
+{
+	enum Type
+	{
+		DIRECTORY = 0,		/// The entry is a directory
+		FILE,				/// The entry is a file
+		MEMORY,				/// The entry is a memory file (i.e. does not exist on the disk)
+		UNKNOWN				/// The entry type is unknown
+	};
+
+	MountPointEntry() : type(UNKNOWN) {}
+
+	Type			type;								/// Type of the entry
+	char			os_path[MAX_PATH_LENGTH];			/// OS-specific path (use only for debug)
+	char			relative_path[MAX_PATH_LENGTH];		/// Relative path of the entry
+};
+
+
+/// Interface which provides a platform-independent way to access files and directories.
+/// Each MountPoint are managed by FileSystem.
+/// There may be several types of MountPoint:
+///
+/// - DiskMountPoint 	- provides interaction with HDD, DVD, BlueRay...
+/// - ZipMountPoint  	- provides interaction with compressed archives
+/// - NetworkMountPoint	- provides interaction with network
+///
+/// Accessing files:
+/// Every file and every directory must be accessed through the Filesystem's MountPoints.
+/// Not a single C/C++ std file io call or other similar facilities
+/// should be used in any other part of the engine in order to maintain
+/// absolute platform independence.
+///
+/// MountPoint maintains a root path which acts as base directory for every
+/// file operation; access to files outside the root path is not allowed. If
+/// you really need it, instantiate another filesystem whith the appropriate
+/// root path (e.g.)
+///
+/// The MountPoint will take care of the necessary path conversions.
+/// The root path must be an absolute path for the underlying operating system.
+class MountPoint
+{
+public:
+	inline						MountPoint(uint32_t type) : m_type(type) {}
+
+	/// Opens a file and returns a specific instance
+	virtual File*				open(const char* path, FileOpenMode mode) = 0;
+
+	/// Close file
+	virtual void				close(File* file) = 0;
+
+	/// Returns whether the @a relative_path exists
+	virtual bool				exists(const char* relative_path) = 0;
+
+	virtual const char*			os_path(const char* relative_path) = 0;
+
+	uint32_t					type() const { return m_type; }
+
+protected:
+
+	MountPoint*			m_next;
+
+	uint32_t			m_type;
+
+	friend class Filesystem;
+};
+
+} // namespace crown

+ 4 - 2
engine/lua/LuaEnvironment.cpp

@@ -36,6 +36,8 @@ OTHER DEALINGS IN THE SOFTWARE.
 namespace crown
 {
 
+extern StringSetting g_default_mountpoint;
+
 StringSetting g_boot("boot_file", "lua main file", "lua/game.raw");
 
 /*
@@ -170,7 +172,7 @@ void LuaEnvironment::execute(int32_t args, int32_t results)
 //-----------------------------------------------------------------------------
 void LuaEnvironment::game_init()
 {
-	const char* path = device()->filesystem()->os_path(g_boot.value());
+	const char* path = device()->filesystem()->os_path(g_default_mountpoint.value(), g_boot.value());
 
 	load_file(path);
 	execute(0, 0);
@@ -190,7 +192,7 @@ void LuaEnvironment::game_shutdown()
 void LuaEnvironment::game_frame(float dt)
 {
 	LuaStack stack(m_state);
-
+	
 	get_global_symbol("frame");
 	stack.push_float(dt);
 	execute(1, 0);

+ 15 - 15
engine/os/android/OsFile2.cpp → engine/os/android/APKFile.cpp

@@ -26,10 +26,9 @@ OTHER DEALINGS IN THE SOFTWARE.
 
 #include <android/asset_manager_jni.h>
 
+#include "APKFile.h"
 #include "Assert.h"
 #include "OS.h"
-#include "OsFile.h"
-#include "AndroidOS.h"
 
 namespace crown
 {
@@ -37,10 +36,11 @@ namespace crown
 static AAssetManager*	g_android_asset_manager = NULL;
 
 //-----------------------------------------------------------------------------
-OsFile::OsFile(const char* path, FileOpenMode mode)
+APKFile::APKFile(const char* path, FileOpenMode mode)
 {
 	// Android assets are always read-only
 	(void) mode;
+
 	m_mode = FOM_READ;
 	m_asset = AAssetManager_open(get_android_asset_manager(), path, AASSET_MODE_RANDOM);
 
@@ -48,13 +48,13 @@ OsFile::OsFile(const char* path, FileOpenMode mode)
 }
 
 //-----------------------------------------------------------------------------
-OsFile::~OsFile()
+APKFile::~APKFile()
 {
 	close();
 }
 
 //-----------------------------------------------------------------------------
-void OsFile::close()
+void APKFile::close()
 {
 	if (m_asset != NULL)
 	{
@@ -64,25 +64,25 @@ void OsFile::close()
 }
 
 //-----------------------------------------------------------------------------
-bool OsFile::is_open() const
+bool APKFile::is_open() const
 {
 	return m_asset != NULL;
 }
 
 //-----------------------------------------------------------------------------
-FileOpenMode OsFile::mode() const
+FileOpenMode APKFile::mode() const
 {
 	return m_mode;
 }
 
 //-----------------------------------------------------------------------------
-size_t OsFile::size() const
+size_t APKFile::size() const
 {
 	return AAsset_getLength(m_asset);
 }
 
 //-----------------------------------------------------------------------------
-size_t OsFile::read(void* data, size_t size)
+size_t APKFile::read(void* data, size_t size)
 {
 	CE_ASSERT(data != NULL, "Data must be != NULL");
 
@@ -90,7 +90,7 @@ size_t OsFile::read(void* data, size_t size)
 }
 
 //-----------------------------------------------------------------------------
-size_t OsFile::write(const void* data, size_t size)
+size_t APKFile::write(const void* data, size_t /*size*/)
 {
 	CE_ASSERT(data != NULL, "Data must be != NULL");
 
@@ -100,34 +100,34 @@ size_t OsFile::write(const void* data, size_t size)
 }
 
 //-----------------------------------------------------------------------------
-void OsFile::seek(size_t position)
+void APKFile::seek(size_t position)
 {
 	off_t seek_result = AAsset_seek(m_asset, (off_t)position, SEEK_SET);
 	CE_ASSERT(seek_result != (off_t) -1, "Failed to seek");
 }
 
 //-----------------------------------------------------------------------------
-void OsFile::seek_to_end()
+void APKFile::seek_to_end()
 {
 	off_t seek_result = AAsset_seek(m_asset, 0, SEEK_END);
 	CE_ASSERT(seek_result != (off_t) -1, "Failed to seek");
 }
 
 //-----------------------------------------------------------------------------
-void OsFile::skip(size_t bytes)
+void APKFile::skip(size_t bytes)
 {
 	off_t seek_result = AAsset_seek(m_asset, (off_t) bytes, SEEK_CUR);
 	CE_ASSERT(seek_result != (off_t) -1, "Failed to seek");
 }
 
 //-----------------------------------------------------------------------------
-size_t OsFile::position() const
+size_t APKFile::position() const
 {
 	return (size_t) (AAsset_getLength(m_asset) - AAsset_getRemainingLength(m_asset));
 }
 
 //-----------------------------------------------------------------------------
-bool OsFile::eof() const
+bool APKFile::eof() const
 {
 	return AAsset_getRemainingLength(m_asset) == 0;
 }

+ 5 - 3
engine/os/android/OsFile2.h → engine/os/android/APKFile.h

@@ -35,14 +35,16 @@ OTHER DEALINGS IN THE SOFTWARE.
 namespace crown
 {
 
+AAssetManager* get_android_asset_manager();
+
 /// Android assets wrapper
-class OsFile
+class APKFile
 {
 public:
 
 	/// Opens the file located at @a path with the given @a mode.
-							OsFile(const char* path, FileOpenMode mode);
-							~OsFile();
+							APKFile(const char* path, FileOpenMode mode);
+							~APKFile();
 
 	/// Closes the file.
 	void					close();

+ 151 - 0
engine/os/android/AndroidFile.cpp

@@ -0,0 +1,151 @@
+/*
+Copyright (c) 2013 Daniele Bartolini, Michele Rossi
+Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include "AndroidFile.h"
+#include "Log.h"
+
+namespace crown
+{
+
+//-----------------------------------------------------------------------------
+AndroidFile::AndroidFile(const char* path) :
+	File(FOM_READ),
+	m_file(path, FOM_READ),
+	m_last_was_read(true)
+{
+}
+
+//-----------------------------------------------------------------------------
+void AndroidFile::seek(size_t position)
+{
+	check_valid();
+
+	m_file.seek(position);
+}
+
+//-----------------------------------------------------------------------------
+void AndroidFile::seek_to_end()
+{
+	check_valid();
+
+	m_file.seek_to_end();
+}
+
+//-----------------------------------------------------------------------------
+void AndroidFile::skip(size_t bytes)
+{
+	check_valid();
+
+	m_file.skip(bytes);
+}
+
+//-----------------------------------------------------------------------------
+void AndroidFile::read(void* buffer, size_t size)
+{
+	check_valid();
+
+	if (!m_last_was_read)
+	{
+		m_last_was_read = true;
+		m_file.seek(0);
+	}
+
+	size_t bytes_read = m_file.read(buffer, size);
+	CE_ASSERT(bytes_read == size, "Failed to read from file");
+}
+
+//-----------------------------------------------------------------------------
+void AndroidFile::write(const void* /*buffer*/, size_t /*size*/)
+{
+	// Not needed
+}
+
+//-----------------------------------------------------------------------------
+bool AndroidFile::copy_to(File& /*file*/, size_t /*size = 0*/)
+{
+	// Not needed
+	return false;
+}
+
+//-----------------------------------------------------------------------------
+void AndroidFile::flush()
+{
+	// Not needed
+}
+
+//-----------------------------------------------------------------------------
+bool AndroidFile::is_valid() const
+{
+	return m_file.is_open();
+}
+
+//-----------------------------------------------------------------------------
+bool AndroidFile::end_of_file() const
+{
+	return position() == size();
+}
+
+//-----------------------------------------------------------------------------
+size_t AndroidFile::size() const
+{
+	check_valid();
+
+	return m_file.size();
+}
+
+//-----------------------------------------------------------------------------
+size_t AndroidFile::position() const
+{
+	check_valid();
+
+	return m_file.position();
+}
+
+//-----------------------------------------------------------------------------
+bool AndroidFile::can_read() const
+{
+	check_valid();
+
+	return true;
+}
+
+//-----------------------------------------------------------------------------
+bool AndroidFile::can_write() const
+{
+	check_valid();
+
+	return true;
+}
+
+//-----------------------------------------------------------------------------
+bool AndroidFile::can_seek() const
+{
+	check_valid();
+
+	return true;
+}
+
+} // namespace crown

+ 83 - 0
engine/os/android/AndroidFile.h

@@ -0,0 +1,83 @@
+/*
+Copyright (c) 2013 Daniele Bartolini, Michele Rossi
+Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#pragma once
+
+#include "APKFile.h"
+#include "Assert.h"
+
+namespace crown
+{
+
+class AndroidFile : public File 
+{
+public:
+
+				AndroidFile(const char* path);
+
+	void		seek(size_t position);
+
+	void		seek_to_end();
+
+	void		skip(size_t bytes);
+
+	void		read(void* buffer, size_t size);
+
+	void		write(const void* buffer, size_t size);
+
+	bool		copy_to(File& file, size_t size = 0);
+
+	void		flush();
+
+	bool		is_valid() const;
+
+	bool		end_of_file() const;
+
+	size_t		size() const;
+
+	size_t		position() const;
+
+	bool		can_read() const;
+
+	bool		can_write() const;
+
+	bool		can_seek() const;
+
+private:
+
+	APKFile		m_file;
+
+	bool		m_last_was_read;
+
+protected:
+
+	inline void		check_valid() const
+	{
+		CE_ASSERT(m_file.is_open(), "File is not open");
+	}
+};
+
+} // namespace crown

+ 144 - 0
engine/os/android/AndroidMountPoint.cpp

@@ -0,0 +1,144 @@
+/*
+Copyright (c) 2013 Daniele Bartolini, Michele Rossi
+Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include "AndroidMountPoint.h"
+#include "AndroidFile.h"
+#include "StringUtils.h"
+#include "Allocator.h"
+
+namespace crown
+{
+
+//-----------------------------------------------------------------------------
+AndroidMountPoint::AndroidMountPoint() : MountPoint(ANDROID_TYPE)
+{
+}
+
+//-----------------------------------------------------------------------------
+File* AndroidMountPoint::open(const char* relative_path, FileOpenMode /*mode*/)
+{
+	CE_ASSERT(exists(relative_path), "File does not exist: %s", relative_path);
+	CE_ASSERT(is_file(relative_path), "File is not a regular file: %s", relative_path);
+
+	return CE_NEW(default_allocator(), AndroidFile)(relative_path);
+}
+
+//-----------------------------------------------------------------------------
+void AndroidMountPoint::close(File* file)
+{
+	CE_DELETE(default_allocator(), file);
+}
+
+//-----------------------------------------------------------------------------
+void AndroidMountPoint::set_root_path(const char* /*root_path*/)
+{
+	Log::w("Stub: Android root path is always assets folder");
+}
+
+
+//-----------------------------------------------------------------------------
+const char* AndroidMountPoint::root_path()
+{
+	Log::w("Stub: Android root path is always assets folder");
+	return "Assets Folder";
+}
+
+//-----------------------------------------------------------------------------
+bool AndroidMountPoint::exists(const char* relative_path)
+{
+	MountPointEntry info;
+
+	return get_info(relative_path, info);
+}
+
+//-----------------------------------------------------------------------------
+bool AndroidMountPoint::get_info(const char* relative_path, MountPointEntry& info)
+{
+	// Entering OS-DEPENDENT-PATH-MODE (Android assets folder)
+
+	const char* os_path = relative_path;
+
+	string::strncpy(info.os_path, "", MAX_PATH_LENGTH);
+	string::strncpy(info.relative_path, relative_path, MAX_PATH_LENGTH);
+
+	AAssetDir* root = AAssetManager_openDir(get_android_asset_manager(), info.os_path);
+
+	char asset_name[512];
+
+	string::strncpy(asset_name, AAssetDir_getNextFileName(root), 512);
+
+	while (asset_name != NULL)
+	{
+		if (string::strcmp(asset_name, relative_path) == 0)
+		{
+			info.type = MountPointEntry::FILE;
+			AAssetDir_rewind(root);
+			return true;			
+		}
+
+		string::strncpy(asset_name, AAssetDir_getNextFileName(root), 512);
+	}
+	
+	info.type = MountPointEntry::UNKNOWN;
+
+	return false;
+}
+
+//-----------------------------------------------------------------------------
+bool AndroidMountPoint::is_file(const char* relative_path)
+{
+	MountPointEntry info;
+
+	if (get_info(relative_path, info))
+	{
+		return info.type == MountPointEntry::FILE;
+	}
+
+	return false;
+}
+
+//-----------------------------------------------------------------------------
+bool AndroidMountPoint::is_dir(const char* relative_path)
+{
+	MountPointEntry info;
+
+	if (get_info(relative_path, info))
+	{
+		return info.type == MountPointEntry::DIRECTORY;
+	}
+
+	return false;
+}
+
+//-----------------------------------------------------------------------------
+const char* AndroidMountPoint::os_path(const char* /*relative_path*/)
+{
+	return "";
+}
+
+
+
+} // namespace crown

+ 58 - 0
engine/os/android/AndroidMountPoint.h

@@ -0,0 +1,58 @@
+/*
+Copyright (c) 2013 Daniele Bartolini, Michele Rossi
+Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#pragma once
+
+#include "MountPoint.h"
+
+namespace crown
+{
+
+class AndroidMountPoint : public MountPoint
+{
+public:
+						AndroidMountPoint();
+
+	File* 				open(const char* relative_path, FileOpenMode mode);
+
+	void				close(File* file);
+
+	void				set_root_path(const char*);
+
+	const char*			root_path();
+
+	bool				exists(const char* relative_path);
+
+	bool				get_info(const char* relative_path, MountPointEntry& info);
+	
+	bool				is_file(const char* relative_path);
+
+	bool				is_dir(const char* relative_path);
+
+	const char*			os_path(const char* relative_path);
+};
+
+} // namespace crown

+ 1 - 1
engine/os/android/CrownActivity.java

@@ -70,7 +70,7 @@ public class CrownActivity extends Activity
 
 		// init AssetManager
 		mAssetManager = getAssets();
-		//CrownLib.initAssetManager(mAssetManager);
+		CrownLib.initAssetManager(mAssetManager);
 
 		// init Native Window
         mWindow = new CrownSurfaceView(this);

+ 1 - 1
engine/resource/ArchiveBundle.cpp

@@ -42,7 +42,7 @@ ArchiveBundle::ArchiveBundle(Filesystem& fs) :
 	m_entries(NULL)
 {
 	// FIXME Default archive name
-	m_archive_file = (DiskFile*)m_filesystem.open("archive.bin", FOM_READ);
+	m_archive_file = (DiskFile*)m_filesystem.open("disk", "archive.bin", FOM_READ);
 	
 	ArchiveHeader header;
 	

+ 6 - 3
engine/resource/FileBundle.cpp

@@ -32,10 +32,13 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "Log.h"
 #include "StringUtils.h" 
 #include "OS.h"
+#include "StringSetting.h"
 
 namespace crown
 {
 
+extern StringSetting g_default_mountpoint;
+
 //-----------------------------------------------------------------------------
 FileBundle::FileBundle(Filesystem& fs) :
 	m_filesystem(fs)
@@ -53,13 +56,13 @@ DiskFile* FileBundle::open(ResourceId name)
 	// Convert name/type into strings
 	char resource_name[512];
 	snprintf(resource_name, 512, "%.8X%.8X", name.name, name.type);
-
+	
 	// Search the resource in the filesystem
-	bool exists = m_filesystem.exists(resource_name);
+	bool exists = m_filesystem.exists(g_default_mountpoint.value(), resource_name);
 	CE_ASSERT(exists == true, "Resource does not exist: %s", resource_name);
 
 	// Open the resource and check magic number/version
-	DiskFile* file = (DiskFile*)m_filesystem.open(resource_name, FOM_READ);
+	DiskFile* file = (DiskFile*)m_filesystem.open(g_default_mountpoint.value(), resource_name, FOM_READ);
 
 	ResourceHeader header;
 	file->read(&header, sizeof(ResourceHeader));

+ 1 - 0
engine/resource/ResourceLoader.cpp

@@ -49,6 +49,7 @@ ResourceLoader::ResourceLoader(Bundle& bundle, Allocator& resource_heap) :
 //-----------------------------------------------------------------------------
 LoadResourceId ResourceLoader::load_resource(ResourceId resource)
 {
+
 	m_requests_mutex.lock();
 
 	LoadResourceId lr_id = m_num_requests++;

+ 9 - 0
utils/crown-android.rb

@@ -78,6 +78,7 @@ def create_android_project(target, name, path)
 
 	engine_dest 	= path + "/jni"
 	android_dest	= path + "/src/crown/android"
+	assets_dest		= path + "/assets"
 
 	# Creates path if not exists
 	if not Dir.exists?(path)
@@ -99,6 +100,12 @@ def create_android_project(target, name, path)
 		FileUtils.mkdir_p(engine_dest)
 		print "Created directory " + engine_dest + "\n"
 	end
+
+	# if assets dir does not exists, create it!
+	if not Dir.exists?(assets_dest)
+		FileUtils.mkdir_p(assets_dest)
+		print "Created directory " + assets_dest + "\n"
+	end
 end
 
 #------------------------------------------------------------------------------
@@ -113,9 +120,11 @@ def fill_android_project(path)
 
 	# Copy luajit dir
 	FileUtils.cp_r($luajit, engine_dest, :remove_destination => true)
+	print "Copied luajit dir to " + engine_dest + "\n"
 
 	# Copy luajit lib
 	FileUtils.cp($luajit + "/lib/libluajit-5.1.so.2.0.2", engine_dest + "/libluajit-5.1.so")
+	print "Copied libluajit to " + engine_dest + "\n"
 
 	# Copy Java files
 	FileUtils.cp_r(Dir.glob($android_src), android_dest, :remove_destination => true)