Просмотр исходного кода

Merge branch 'master' of https://github.com/taylor001/crown

mikymod 12 лет назад
Родитель
Сommit
29e3006bf7

+ 1 - 1
CMakeLists.txt

@@ -4,7 +4,7 @@ project(crown)
 
 set (CROWN_VERSION_MAJOR 0)
 set (CROWN_VERSION_MINOR 1)
-set (CROWN_VERSION_MICRO 10)
+set (CROWN_VERSION_MICRO 11)
 
 option (CROWN_BUILD_SAMPLES "Whether to build the samples" ON)
 option (CROWN_BUILD_TOOLS "Whether to build the tools" ON)

+ 9 - 6
engine/Device.cpp

@@ -123,6 +123,7 @@ bool Device::init(int argc, char** argv)
 			if (!m_bundle_compiler->compile(m_bundle_dir, m_source_dir))
 			{
 				CE_DELETE(m_allocator, m_bundle_compiler);
+				m_allocator.clear();
 				Log::e("Exiting.");
 				exit(EXIT_FAILURE);
 			}
@@ -130,6 +131,7 @@ bool Device::init(int argc, char** argv)
 			if (!m_continue)
 			{
 				CE_DELETE(m_allocator, m_bundle_compiler);
+				m_allocator.clear();
 				exit(EXIT_SUCCESS);
 			}
 		}
@@ -172,10 +174,11 @@ bool Device::init(int argc, char** argv)
 
 	CE_ASSERT(m_window != NULL, "Unable to create the window");
 
+	// Create main window
 	m_window->set_title("Crown Game Engine");
-	m_window->show();
 	Log::d("Window created.");
 
+	// Create renderer
 	m_renderer = Renderer::create(m_allocator);
 	m_renderer->init();
 	Log::d("Renderer created.");
@@ -198,6 +201,7 @@ bool Device::init(int argc, char** argv)
 	m_resource_manager->flush();
 	m_lua_environment->load((LuaResource*) m_resource_manager->data(luagame_id));
 	m_lua_environment->call_global("init", 0);
+	m_resource_manager->unload(luagame_id);
 
 	if (m_quit_after_init == 1)
 	{
@@ -205,17 +209,16 @@ bool Device::init(int argc, char** argv)
 		shutdown();
 	}
 
+	// Show main window
+	m_window->show();
+
 	return true;
 }
 
 //-----------------------------------------------------------------------------
 void Device::shutdown()
 {
-	if (is_init() == false)
-	{
-		Log::e("Crown Engine is not initialized.");	
-		return;
-	}
+	CE_ASSERT(is_init(), "Engine is not initialized");
 
 	// Shutdowns the game
 	m_lua_environment->call_global("shutdown", 0);

+ 10 - 12
engine/compilers/BundleCompiler.cpp

@@ -59,28 +59,26 @@ bool BundleCompiler::compile(const char* bundle_dir, const char* source_dir)
 	// Compile all resources
 	for (uint32_t i = 0; i < files.size(); i++)
 	{
-		DynamicString& filename = files[i];
+		const char* filename = files[i].c_str();
+		uint64_t filename_hash = hash::murmur2_64(filename, string::strlen(filename), 0);
 
-		char resource_name[1024];
-		char resource_type[1024];
-		path::filename_without_extension(filename.c_str(), resource_name, 1024);
-		path::extension(filename.c_str(), resource_type, 1024);
+		char filename_extension[32];
+		path::extension(filename, filename_extension, 32);
+		uint32_t resource_type_hash = hash::murmur2_32(filename_extension, string::strlen(filename_extension), 0);
 
-		uint32_t resource_name_hash = hash::murmur2_32(resource_name, string::strlen(resource_name), 0);
-		uint32_t resource_type_hash = hash::murmur2_32(resource_type, string::strlen(resource_type), 0);
+		char out_name[65];
+		snprintf(out_name, 65, "%.16llx", filename_hash);
 
-		char out_name[1024];
-		snprintf(out_name, 1024, "%.8X%.8X", resource_name_hash, resource_type_hash);
-		Log::i("%s <= %s", out_name, filename.c_str());
+		Log::i("%s <= %s", out_name, filename);
 
 		bool result = false;
 		if (resource_type_hash == TEXTURE_TYPE)
 		{
-			result = m_tga.compile(source_dir, bundle_dir, filename.c_str(), out_name);
+			result = m_tga.compile(source_dir, bundle_dir, filename, out_name);
 		}
 		else if (resource_type_hash == LUA_TYPE)
 		{
-			result = m_lua.compile(source_dir, bundle_dir, filename.c_str(), out_name);
+			result = m_lua.compile(source_dir, bundle_dir, filename, out_name);
 		}
 		else
 		{

+ 7 - 4
engine/compilers/tga/TGACompiler.cpp

@@ -42,10 +42,6 @@ TGACompiler::TGACompiler() :
 //-----------------------------------------------------------------------------
 TGACompiler::~TGACompiler()
 {
-	if (m_texture_data)
-	{
-		default_allocator().deallocate(m_texture_data);
-	}
 }
 
 //-----------------------------------------------------------------------------
@@ -141,6 +137,13 @@ void TGACompiler::write_impl(File* out_file)
 {
 	out_file->write((char*)&m_texture_header, sizeof(TextureHeader));
 	out_file->write((char*)m_texture_data, m_texture_data_size);
+
+	if (m_texture_data)
+	{
+		default_allocator().deallocate(m_texture_data);
+		m_texture_data_size = 0;
+		m_texture_data = NULL;
+	}
 }
 
 //-----------------------------------------------------------------------------

+ 56 - 1
engine/core/strings/Hash.h

@@ -44,6 +44,7 @@ const uint64_t FNV1A_PRIME_64				= 1099511628211ull;
 
 // Functions
 uint32_t murmur2_32(const void* key, size_t len, uint32_t seed);
+uint64_t murmur2_64(const void* key, size_t len, unsigned int seed);
 uint32_t fnv1a_32(const void* key, size_t len);
 uint64_t fnv1a_64(const void* key, size_t len);
 
@@ -63,7 +64,7 @@ uint64_t fnv1a_64(const void* key, size_t len);
 ///    machines.
 inline uint32_t murmur2_32(const void* key, size_t len, uint32_t seed)
 {
-	CE_ASSERT(key != NULL, "Key must be != NULL");
+	CE_ASSERT_NOT_NULL(key);
 
 	// 'm' and 'r' are mixing constants generated offline.
 	// They're not really 'magic', they just happen to work well.
@@ -109,6 +110,60 @@ inline uint32_t murmur2_32(const void* key, size_t len, uint32_t seed)
 	return h;
 }
 
+//-----------------------------------------------------------------------------
+inline uint64_t murmur2_64(const void* key, size_t len, unsigned int seed)
+{
+	CE_ASSERT_NOT_NULL(key);
+
+	const unsigned int m = 0x5bd1e995;
+	const int r = 24;
+
+	unsigned int h1 = seed ^ len;
+	unsigned int h2 = 0;
+
+	const unsigned int * data = (const unsigned int *)key;
+
+	while(len >= 8)
+	{
+		unsigned int k1 = *data++;
+		k1 *= m; k1 ^= k1 >> r; k1 *= m;
+		h1 *= m; h1 ^= k1;
+		len -= 4;
+
+		unsigned int k2 = *data++;
+		k2 *= m; k2 ^= k2 >> r; k2 *= m;
+		h2 *= m; h2 ^= k2;
+		len -= 4;
+	}
+
+	if(len >= 4)
+	{
+		unsigned int k1 = *data++;
+		k1 *= m; k1 ^= k1 >> r; k1 *= m;
+		h1 *= m; h1 ^= k1;
+		len -= 4;
+	}
+
+	switch(len)
+	{
+	case 3: h2 ^= ((unsigned char*)data)[2] << 16;
+	case 2: h2 ^= ((unsigned char*)data)[1] << 8;
+	case 1: h2 ^= ((unsigned char*)data)[0];
+			h2 *= m;
+	};
+
+	h1 ^= h2 >> 18; h1 *= m;
+	h2 ^= h1 >> 22; h2 *= m;
+	h1 ^= h2 >> 17; h1 *= m;
+	h2 ^= h1 >> 19; h2 *= m;
+
+	uint64_t h = h1;
+
+	h = (h << 32) | h2;
+
+	return h;
+} 
+
 //-----------------------------------------------------------------------------
 /// FNV-1a hash, 32 bit
 inline uint32_t fnv1a_32(const void* key, size_t len)

+ 12 - 0
engine/os/android/ApkFilesystem.cpp

@@ -56,6 +56,18 @@ void ApkFilesystem::close(File* file)
 	CE_DELETE(default_allocator(), file);
 }
 
+//-----------------------------------------------------------------------------
+bool ApkFilesystem::is_directory(const char* path)
+{
+	return false;
+}
+
+//-----------------------------------------------------------------------------
+bool ApkFilesystem::is_file(const char* path)
+{
+	return false;
+}
+
 //-----------------------------------------------------------------------------
 void ApkFilesystem::create_directory(const char* /*path*/)
 {

+ 6 - 0
engine/os/android/ApkFilesystem.h

@@ -47,6 +47,12 @@ public:
 	/// @copydoc Filesystem::close()
 	void close(File* file);
 
+	/// Returns always false under Android.
+	bool is_directory(const char* path);
+
+	/// Returns always false under Android.
+	bool is_file(const char* path);
+
 	/// Stub method, assets folder is read-only.
 	void create_directory(const char* path);
 

+ 1 - 1
engine/resource/FileBundle.cpp

@@ -61,7 +61,7 @@ public:
 	{
 		// Convert name/type into strings
 		char resource_name[512];
-		snprintf(resource_name, 512, "%.8X%.8X", name.name, name.type);
+		snprintf(resource_name, 512, "%.16llx", name.id);
 		
 		// Search the resource in the filesystem
 		// bool exists = m_filesystem.exists(resource_name);

+ 3 - 1
engine/resource/LuaResource.h

@@ -53,13 +53,15 @@ public:
 	static void* load(Allocator& allocator, Bundle& bundle, ResourceId id)
 	{
 		File* file = bundle.open(id);
-		CE_ASSERT(file != NULL, "Resource does not exist: %.8X%.8X", id.name, id.type);
+		CE_ASSERT(file != NULL, "Resource does not exist: %.16llx", id.id);
 
 		const size_t file_size = file->size() - 12;
 		LuaResource* res = (LuaResource*) allocator.allocate(sizeof(LuaResource));
 		res->m_data = (uint8_t*) allocator.allocate(file_size);
 		file->read(res->m_data, file_size);
 
+		bundle.close(file);
+
 		return res;
 	}
 

+ 1 - 1
engine/resource/MeshResource.h

@@ -56,7 +56,7 @@ public:
 	{
 		File* file = bundle.open(id);
 
-		CE_ASSERT(file != NULL, "Resource does not exist: %.8X%.8X", id.name, id.type);
+		CE_ASSERT(file != NULL, "Resource does not exist: %.16llx", id.id);
 
 		MeshResource* resource = (MeshResource*)allocator.allocate(sizeof(MeshResource));
 		file->read(&resource->m_header, sizeof(MeshHeader));

+ 2 - 3
engine/resource/Resource.h

@@ -53,10 +53,9 @@ const uint32_t SOUND_TYPE					= 0x8E128AA1;
 /// the index to the resource list where it is stored.
 struct ResourceId
 {
-	bool operator==(const ResourceId& b) const { return name == b.name && type == b.type; }
+	bool operator==(const ResourceId& b) const { return id == b.id; }
 
-	uint32_t		name;
-	uint32_t		type;
+	uint64_t id;
 };
 
 class Allocator;

+ 3 - 2
engine/resource/ResourceLoader.cpp

@@ -47,7 +47,7 @@ ResourceLoader::ResourceLoader(Bundle& bundle, Allocator& resource_heap) :
 }
 
 //-----------------------------------------------------------------------------
-LoadResourceId ResourceLoader::load_resource(ResourceId resource)
+LoadResourceId ResourceLoader::load_resource(uint32_t type, ResourceId resource)
 {
 
 	m_requests_mutex.lock();
@@ -55,6 +55,7 @@ LoadResourceId ResourceLoader::load_resource(ResourceId resource)
 	LoadResourceId lr_id = m_num_requests++;
 	LoadResource lr;
 	lr.id = lr_id;
+	lr.type = type;
 	lr.resource = resource;
 
 	m_requests.push_back(lr);
@@ -108,7 +109,7 @@ int32_t ResourceLoader::run()
 
 		m_results[request.id % MAX_LOAD_REQUESTS].status = LRS_LOADING;
 
-		void* data = resource_on_load(request.resource.type, m_resource_heap, m_bundle, request.resource);
+		void* data = resource_on_load(request.type, m_resource_heap, m_bundle, request.resource);
 
 		m_results[request.id % MAX_LOAD_REQUESTS].data = data;
 		m_results[request.id % MAX_LOAD_REQUESTS].status = LRS_LOADED;

+ 2 - 1
engine/resource/ResourceLoader.h

@@ -54,6 +54,7 @@ enum LoadResourceStatus
 struct LoadResource
 {
 	LoadResourceId id;
+	uint32_t type;
 	ResourceId resource;
 };
 
@@ -73,7 +74,7 @@ public:
 							ResourceLoader(Bundle& bundle, Allocator& resource_heap);
 
 	/// Loads the @a resource in a background thread.
-	LoadResourceId			load_resource(ResourceId resource);
+	LoadResourceId			load_resource(uint32_t type, ResourceId resource);
 
 	/// Returns the status of the given load request @a id.
 	LoadResourceStatus		load_resource_status(LoadResourceId id) const;

+ 21 - 14
engine/resource/ResourceManager.cpp

@@ -32,6 +32,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "StringUtils.h"
 #include "Hash.h"
 #include "TempAllocator.h"
+#include "DynamicString.h"
 
 namespace crown
 {
@@ -56,13 +57,13 @@ ResourceManager::~ResourceManager()
 //-----------------------------------------------------------------------------
 ResourceId ResourceManager::load(const char* type, const char* name)
 {
-	return load(resource_id(type, name));
+	return load(hash::murmur2_32(type, string::strlen(type), 0), resource_id(type, name));
 }
 
 //-----------------------------------------------------------------------------
 void ResourceManager::unload(ResourceId name)
 {
-	CE_ASSERT(has(name), "Resource not loaded: %.8X%.8X", name.name, name.type);
+	CE_ASSERT(has(name), "Resource not loaded: %.16llx", name.id);
 
 	ResourceEntry* entry = find(name);
 
@@ -70,7 +71,7 @@ void ResourceManager::unload(ResourceId name)
 	
 	if (entry->references == 0)
 	{
-		resource_on_unload(name.type, m_resource_heap, entry->resource);
+		resource_on_unload(entry->type, m_resource_heap, entry->resource);
 		entry->resource = NULL;
 	}
 }
@@ -86,7 +87,7 @@ bool ResourceManager::has(ResourceId name) const
 //-----------------------------------------------------------------------------
 const void* ResourceManager::data(ResourceId name) const
 {
-	CE_ASSERT(has(name), "Resource not loaded: %.8X%.8X", name.name, name.type);
+	CE_ASSERT(has(name), "Resource not loaded: %.16llx", name.id);
 
 	return find(name)->resource;
 }
@@ -94,7 +95,7 @@ const void* ResourceManager::data(ResourceId name) const
 //-----------------------------------------------------------------------------
 bool ResourceManager::is_loaded(ResourceId name) const
 {
-	CE_ASSERT(has(name), "Resource not loaded: %.8X%.8X", name.name, name.type);
+	CE_ASSERT(has(name), "Resource not loaded: %.16llx", name.id);
 
 	return find(name)->resource != NULL;
 }
@@ -102,7 +103,7 @@ bool ResourceManager::is_loaded(ResourceId name) const
 //-----------------------------------------------------------------------------
 uint32_t ResourceManager::references(ResourceId name) const
 {
-	CE_ASSERT(has(name), "Resource not loaded: %.8X%.8X", name.name, name.type);
+	CE_ASSERT(has(name), "Resource not loaded: %.16llx", name.id);
 
 	return find(name)->references;
 }
@@ -125,11 +126,16 @@ uint32_t ResourceManager::seed() const
 //-----------------------------------------------------------------------------
 ResourceId ResourceManager::resource_id(const char* type, const char* name) const
 {
-	ResourceId id;
-	id.type = hash::murmur2_32(type, string::strlen(type), 0);
-	id.name = hash::murmur2_32(name, string::strlen(name), m_seed);
+	TempAllocator256 alloc;
+	DynamicString res_name(alloc);
+	res_name += name;
+	res_name += '.';
+	res_name += type;
 
-	return id;
+	ResourceId res_id;
+	res_id.id = hash::murmur2_64(res_name.c_str(), string::strlen(res_name.c_str()), m_seed);
+
+	return res_id;
 }
 
 //-----------------------------------------------------------------------------
@@ -158,7 +164,7 @@ void ResourceManager::poll_resource_loader()
 }
 
 //-----------------------------------------------------------------------------
-ResourceId ResourceManager::load(ResourceId name)
+ResourceId ResourceManager::load(uint32_t type, ResourceId name)
 {
 	// Search for an already existent resource
 	ResourceEntry* entry = find(name);
@@ -169,6 +175,7 @@ ResourceId ResourceManager::load(ResourceId name)
 		ResourceEntry entry;
 
 		entry.id = name;
+		entry.type = type;
 		entry.references = 1;
 		entry.resource = NULL;
 
@@ -177,7 +184,7 @@ ResourceId ResourceManager::load(ResourceId name)
 		// Issue request to resource loader
 		PendingRequest pr;
 		pr.resource = name;
-		pr.id = m_loader.load_resource(name);
+		pr.id = m_loader.load_resource(type, name);
 
 		m_pendings.push_back(pr);
 
@@ -193,9 +200,9 @@ ResourceId ResourceManager::load(ResourceId name)
 //-----------------------------------------------------------------------------
 void ResourceManager::online(ResourceId name, void* resource)
 {
-	resource_on_online(name.type, resource);
-
 	ResourceEntry* entry = find(name);
+	resource_on_online(entry->type, resource);
+
 	entry->resource = resource;
 }
 

+ 4 - 2
engine/resource/ResourceManager.h

@@ -41,14 +41,16 @@ struct ResourceEntry
 	bool operator==(const ResourceEntry& b) const { return id == b.id; }
 
 	ResourceId		id;
+	uint32_t		type;
 	uint32_t		references;
 	void*			resource;
 };
 
 struct PendingRequest
 {
-	ResourceId resource;
 	LoadResourceId id;
+	ResourceId resource;
+	uint32_t type;
 };
 
 class Bundle;
@@ -106,7 +108,7 @@ private:
 	void					poll_resource_loader();
 
 	// Loads the resource by name and type and returns its ResourceId.
-	ResourceId				load(ResourceId name);
+	ResourceId				load(uint32_t type, ResourceId name);
 	void					online(ResourceId name, void* resource);
 
 private:

+ 1 - 1
engine/resource/SoundResource.h

@@ -53,7 +53,7 @@ public:
 	{
 		File* file = bundle.open(id);
 
-		CE_ASSERT(file != NULL, "Resource does not exist: %.8X%.8X", id.name, id.type);
+		CE_ASSERT(file != NULL, "Resource does not exist: %.16llx", id.id);
 
 		SoundResource* resource = (SoundResource*)allocator.allocate(sizeof(SoundResource));
 

+ 1 - 1
engine/resource/TextureResource.h

@@ -57,7 +57,7 @@ public:
 	{
 		File* file = bundle.open(id);
 
-		CE_ASSERT(file != NULL, "Resource does not exist: %.8X%.8X", id.name, id.type);
+		CE_ASSERT(file != NULL, "Resource does not exist: %.16llx", id.id);
 
 		TextureResource* resource = (TextureResource*)allocator.allocate(sizeof(TextureResource));