Преглед на файлове

Merge branch 'master' into dae-compiler

Conflicts:
	engine/resource/ResourceManager.cpp
	tools/cli/resource-compiler.cpp
Daniele Bartolini преди 12 години
родител
ревизия
b60fb7b83b

+ 2 - 0
engine/CMakeLists.txt

@@ -280,6 +280,7 @@ set (RESOURCE_SRC
 	resource/FontResource.cpp
 	resource/VertexShaderResource.cpp
 	resource/PixelShaderResource.cpp
+	resource/SoundResource.cpp
 	resource/ArchiveBundle.cpp
 	resource/FileBundle.cpp
 )
@@ -295,6 +296,7 @@ set (RESOURCE_HEADERS
 	resource/FontResource.h
 	resource/VertexShaderResource.h
 	resource/PixelShaderResource.h
+	resource/SoundResource.h
 	resource/ArchiveBundle.h
 	resource/FileBundle.h
 )

+ 51 - 22
engine/core/json/JSONParser.cpp

@@ -194,23 +194,21 @@ static bool is_escapee(char c)
 }
 
 //--------------------------------------------------------------------------
-JSONParser::JSONParser(const char* s) :
-	m_document(s),
-	m_at(s)
+JSONElement::JSONElement() :
+	m_parser(NULL),
+	m_at(NULL)
 {
-	CE_ASSERT_NOT_NULL(s);
 }
 
 //--------------------------------------------------------------------------
-JSONParser&	JSONParser::root()
+JSONElement::JSONElement(JSONParser& parser, const char* at) :
+	m_parser(&parser),
+	m_at(at)
 {
-	m_at = skip_whites(m_document);
-
-	return *this;
 }
 
 //--------------------------------------------------------------------------
-JSONParser& JSONParser::operator[](uint32_t i)
+JSONElement& JSONElement::operator[](uint32_t i)
 {
 	TempAllocator1024 alloc;
 	List<const char*> array(alloc);
@@ -225,13 +223,13 @@ JSONParser& JSONParser::operator[](uint32_t i)
 }
 
 //--------------------------------------------------------------------------
-JSONParser& JSONParser::index(uint32_t i)
+JSONElement& JSONElement::index(uint32_t i)
 {
 	return this->operator[](i);
 }
 
 //--------------------------------------------------------------------------
-JSONParser& JSONParser::key(const char* k)
+JSONElement& JSONElement::key(const char* k)
 {
 	TempAllocator1024 alloc;
 	List<JSONPair> object(alloc);
@@ -260,25 +258,43 @@ JSONParser& JSONParser::key(const char* k)
 }
 
 //--------------------------------------------------------------------------
-bool JSONParser::bool_value() const
+bool JSONElement::has_key(const char* k) const
+{
+	TempAllocator1024 alloc;
+	List<JSONPair> object(alloc);
+	JSONParser::parse_object(m_at, object);
+
+	for (uint32_t i = 0; i < object.size(); i++)
+	{
+		if (string::strcmp(k, object[i].key) == 0)
+		{
+			return true;
+		}
+	}
+
+	return false;
+}
+
+//--------------------------------------------------------------------------
+bool JSONElement::bool_value() const
 {
 	return JSONParser::parse_bool(m_at);
 }
 
 //--------------------------------------------------------------------------
-int32_t JSONParser::int_value() const
+int32_t JSONElement::int_value() const
 {
 	return JSONParser::parse_int(m_at);
 }
 
 //--------------------------------------------------------------------------
-float JSONParser::float_value() const
+float JSONElement::float_value() const
 {
 	return JSONParser::parse_float(m_at);
 }
 
 //--------------------------------------------------------------------------
-const char* JSONParser::string_value() const
+const char* JSONElement::string_value() const
 {
 	static TempAllocator1024 alloc;
 	static List<char> string(alloc);
@@ -291,43 +307,43 @@ const char* JSONParser::string_value() const
 }
 
 //--------------------------------------------------------------------------
-bool JSONParser::is_nil() const
+bool JSONElement::is_nil() const
 {
 	return JSONParser::type(m_at) == JT_NIL;
 }
 
 //--------------------------------------------------------------------------
-bool JSONParser::is_bool() const
+bool JSONElement::is_bool() const
 {
 	return JSONParser::type(m_at) == JT_BOOL;
 }
 
 //--------------------------------------------------------------------------
-bool JSONParser::is_number() const
+bool JSONElement::is_number() const
 {
 	return JSONParser::type(m_at) == JT_NUMBER;
 }
 
 //--------------------------------------------------------------------------
-bool JSONParser::is_string() const
+bool JSONElement::is_string() const
 {
 	return JSONParser::type(m_at) == JT_STRING;
 }
 
 //--------------------------------------------------------------------------
-bool JSONParser::is_array() const
+bool JSONElement::is_array() const
 {
 	return JSONParser::type(m_at) == JT_ARRAY;
 }
 
 //--------------------------------------------------------------------------
-bool JSONParser::is_object() const
+bool JSONElement::is_object() const
 {
 	return JSONParser::type(m_at) == JT_OBJECT;
 }
 
 //--------------------------------------------------------------------------
-uint32_t JSONParser::size() const
+uint32_t JSONElement::size() const
 {
 	switch(JSONParser::type(m_at))
 	{
@@ -374,6 +390,19 @@ uint32_t JSONParser::size() const
 	}
 }
 
+//--------------------------------------------------------------------------
+JSONParser::JSONParser(const char* s) :
+	m_document(s)
+{
+	CE_ASSERT_NOT_NULL(s);
+}
+
+//--------------------------------------------------------------------------
+JSONElement JSONParser::root()
+{
+	return JSONElement(*this, skip_whites(m_document));
+}
+
 //-----------------------------------------------------------------------------
 JSONType JSONParser::type(const char* s)
 {

+ 59 - 25
engine/core/json/JSONParser.h

@@ -42,58 +42,63 @@ enum JSONType
 	JT_BOOL
 };
 
+/// Represents a pair
 struct JSONPair
 {
 	const char* key;
 	const char* val;
 };
 
-/// Parses JSON documents.
-class JSONParser
+class JSONParser;
+
+/// Represents a JSON element.
+/// The objects of this class are valid until the parser
+/// which has generated them, will exist.
+class JSONElement
 {
 public:
 
-	/// Read the JSON document contained in the non-null @a s string.
-	/// @note
-	/// The @a s string has to remain valid for the whole parser's
-	/// existence scope.
-						JSONParser(const char* s);
-
-	/// Returns the root element of the JSON document.
-	JSONParser&			root();
+	/// Used only to forward-instantiate elements.
+	/// In order to be able to use the element, it must be
+	/// obtained from JSONParser::root() or copied from an
+	/// already existent and valid element.
+						JSONElement();
 
 	/// Returns the @a i -th item of the current array.
-	JSONParser&			operator[](uint32_t i);
+	JSONElement&		operator[](uint32_t i);
 
 	/// @copydoc JSONParser::operator[]
-	JSONParser&			index(uint32_t i);
+	JSONElement&		index(uint32_t i);
 
 	/// Returns the element corresponding to key @a k of the
 	/// current object.
 	/// @note
 	/// If the key is not unique in the object scope, the last
 	/// key in order of appearance will be selected.
-	JSONParser&			key(const char* k);
+	JSONElement&		key(const char* k);
+
+	/// Returns whether the element has the @a k key.
+	bool				has_key(const char* k) const;
 
-	/// Returns true wheter the current element is the JSON nil special value.
+	/// Returns true wheter the element is the JSON nil special value.
 	bool				is_nil() const;
 
-	/// Returns true wheter the current element is a JSON boolean (true or false).
+	/// Returns true wheter the element is a JSON boolean (true or false).
 	bool				is_bool() const;
 
-	/// Returns true wheter the current element is a JSON number.
+	/// Returns true wheter the element is a JSON number.
 	bool				is_number() const;
 
-	/// Returns true whether the current element is a JSON string.
+	/// Returns true whether the element is a JSON string.
 	bool				is_string() const;
 
-	/// Returns true whether the current element is a JSON array.
+	/// Returns true whether the element is a JSON array.
 	bool				is_array() const;
 
-	/// Returns true whether the current element is a JSON object.
+	/// Returns true whether the element is a JSON object.
 	bool				is_object() const;
 
-	/// Returns the size of the current element based on the
+	/// Returns the size of the element based on the
 	/// element's type:
 	/// * nil, bool, number: 1
 	/// * string: length of the string
@@ -101,22 +106,46 @@ public:
 	/// * object: number of keys in the object
 	uint32_t			size() const;
 
-	/// Returns the boolean value of the current element.
+	/// Returns the boolean value of the element.
 	bool				bool_value() const;
 
-	/// Returns the integer value of the current element.
+	/// Returns the integer value of the element.
 	int32_t				int_value() const;
 
-	/// Returns the float value of the current element.
+	/// Returns the float value of the element.
 	float				float_value() const;
 
-	/// Returns the string value of the current element.
+	/// Returns the string value of the element.
 	/// @warning
 	/// The returned string is kept internally until the next call to
 	/// this function, so it is highly unsafe to just keep the pointer
 	/// instead of copying its content somewhere else.
 	const char*			string_value() const;
 
+private:
+
+						JSONElement(JSONParser& parser, const char* at);
+
+	JSONParser*			m_parser;
+	const char*			m_at;
+
+	friend class 		JSONParser;
+};
+
+/// Parses JSON documents.
+class JSONParser
+{
+public:
+
+	/// Read the JSON document contained in the non-null @a s string.
+	/// @note
+	/// The @a s string has to remain valid for the whole parser's
+	/// existence scope.
+						JSONParser(const char* s);
+
+	/// Returns the root element of the JSON document.
+	JSONElement			root();
+
 public:
 
 	/// Returns the type of the @a s JSON text. 
@@ -148,7 +177,12 @@ public:
 private:
 
 	const char* const	m_document;
-	const char*			m_at;
+
+private:
+
+	// Disable copying
+						JSONParser(const JSONParser&);
+	JSONParser&			operator=(const JSONParser&);
 };
 
 } // namespace crown

+ 13 - 0
engine/resource/ResourceManager.cpp

@@ -42,6 +42,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "VertexShaderResource.h"
 #include "PixelShaderResource.h"
 #include "MeshResource.h"
+#include "SoundResource.h"
 
 namespace crown
 {
@@ -361,6 +362,10 @@ void* ResourceManager::load_by_type(ResourceId name)
 	{
 		return MeshResource::load(m_resource_allocator, m_resource_bundle, name);
 	}
+	else if (name.type == SOUND_TYPE)
+	{
+		return SoundResource::load(m_resource_allocator, m_resource_bundle, name);
+	}
 
 	return NULL;
 }
@@ -384,6 +389,10 @@ void ResourceManager::unload_by_type(ResourceId name, void* resource)
 	{
 		PixelShaderResource::unload(m_resource_allocator, resource);
 	}
+	else if (name.type == SOUND_TYPE)
+	{
+		SoundResource::unload(m_resource_allocator, resource);
+	}
 
 	return;
 }
@@ -407,6 +416,10 @@ void ResourceManager::online(ResourceId name, void* resource)
 	{
 		PixelShaderResource::online(resource);
 	}
+	else if (name.type == SOUND_TYPE)
+	{
+		SoundResource::online(resource);
+	}
 
 	m_resources_mutex.lock();
 

+ 81 - 0
engine/resource/SoundResource.cpp

@@ -0,0 +1,81 @@
+/*
+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 "SoundResource.h"
+#include "Bundle.h"
+#include "Log.h"
+#include "DiskFile.h"
+#include "Assert.h"
+#include "Allocator.h"
+#include "Device.h"
+
+namespace crown
+{
+
+//-----------------------------------------------------------------------------
+void* SoundResource::load(Allocator& allocator, Bundle& bundle, ResourceId id)
+{
+	DiskFile* file = bundle.open(id);
+
+	CE_ASSERT(file != NULL, "Resource does not exist: %.8X%.8X", id.name, id.type);
+
+	SoundResource* resource = (SoundResource*)allocator.allocate(sizeof(SoundResource));
+
+	file->read(&resource->m_header, sizeof(SoundHeader));
+
+	size_t size = resource->size();
+
+	resource->m_data = (uint8_t*)allocator.allocate(sizeof(uint8_t) * size);
+
+	file->read(resource->m_data, size);
+
+	bundle.close(file);
+
+	return resource;
+}
+
+//-----------------------------------------------------------------------------
+void SoundResource::online(void* resource)
+{
+	CE_ASSERT(resource != NULL, "Resource not loaded");
+}
+
+//-----------------------------------------------------------------------------
+void SoundResource::unload(Allocator& allocator, void* resource)
+{
+	CE_ASSERT(resource != NULL, "Resource not loaded");
+
+	allocator.deallocate(((SoundResource*)resource)->m_data);
+	allocator.deallocate(resource);
+}
+
+//-----------------------------------------------------------------------------
+void SoundResource::offline()
+{
+
+}
+
+} // namespace crown

+ 71 - 0
engine/resource/SoundResource.h

@@ -0,0 +1,71 @@
+/*
+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 "Types.h"
+#include "Resource.h"
+
+namespace crown
+{
+
+const uint32_t SOUND_VERSION = 1;
+
+struct SoundHeader
+{
+	uint32_t	version;	// Sound file version
+	uint32_t	size;
+	uint32_t	channels;
+	uint32_t 	bits_per_sample;
+};
+
+class Bundle;
+class Allocator;
+
+class SoundResource
+{
+public:
+
+	static void*		load(Allocator& allocator, Bundle& bundle, ResourceId id);
+	static void			online(void* resource);
+	static void			unload(Allocator& allocator, void* resource);
+	static void			offline();
+
+public:
+
+	uint32_t 			size() const { return m_header.size; }
+	uint32_t			channels() const { return m_header.channels; }
+	uint32_t			bits_per_sample() const { return m_header.bits_per_sample; }
+	const uint8_t*		data() const { return m_data; }
+
+private:
+
+	SoundHeader		m_header;
+	uint8_t*		m_data;
+
+};
+
+} // namespace crown

+ 98 - 73
tools/cli/resource-compiler.cpp

@@ -24,7 +24,9 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 OTHER DEALINGS IN THE SOFTWARE.
 */
 
-#include <cstdio>
+#include <iostream>
+#include <string>
+#include <map>
 
 #include "Args.h"
 #include "Path.h"
@@ -35,74 +37,32 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "DAECompiler.h"
 
 using namespace crown;
+using std::cout;
+using std::endl;
+using std::ofstream;
+using std::map;
 
 // Max number of requests per run
-const uint32_t MAX_COMPILE_REQUESTS = 512;
-
+const uint32_t	MAX_COMPILE_REQUESTS = 512;
 const char*		root_path = NULL;
 const char*		dest_path = NULL;
 uint32_t		hash_seed = 0;
 
-// Help functions
-int32_t			parse_command_line(int argc, char* argv[]);
-void			print_help_message(const char* program_name);
-void			check_arguments(const char* root_path, const char* dest_path);
-void			compile_by_type(const char* resource);
-
 //-----------------------------------------------------------------------------
-int main(int argc, char** argv)
+static void print_help_message(const char* program_name)
 {
-	int32_t first_resource = parse_command_line(argc, argv);
-
-	// Check if all the mandatory options are set
-	check_arguments(root_path, dest_path);
-
-	// If there are no resources
-	if (first_resource >= argc)
-	{
-		printf("you have to specify at least one resource.");
-		exit(EXIT_FAILURE);
-	}
-
-
-	TGACompiler tga;
-	WAVCompiler wav;
-	DAECompiler dae;
-
-	char out_name[1024];
-	char resource_name[1024];
-	char resource_type[1024];
-
-	for (int32_t i = 0; i < argc - first_resource; i++)
-	{
-		path::filename_without_extension(argv[first_resource + i], resource_name, 1024);
-		path::extension(argv[first_resource + i], resource_type, 1024);
-
-		snprintf(out_name, 1024, "%.8X%.8X",
-			hash::murmur2_32(resource_name, string::strlen(resource_name), hash_seed),
-			hash::murmur2_32(resource_type, string::strlen(resource_type), 0));
-
-		printf("%s <= %s\n", out_name, argv[first_resource + i]);
-
-		if (string::strcmp(resource_type, "tga") == 0)
-		{
-			tga.compile(root_path, dest_path, argv[first_resource + i], out_name);
-		}
-		else if (string::strcmp(resource_type, "wav") == 0)
-		{
-			wav.compile(root_path, dest_path, argv[first_resource + i], out_name);
-		}
-		else if (string::strcmp(resource_type, "dae") == 0)
-		{
-			dae.compile(root_path, dest_path, argv[first_resource + i], out_name);
-		}
-	}
+	cout << "Usage: " << program_name << " [options] [resources]" << endl;
+	cout <<
+		"Options:\n\n"
 
-	return 0;
+		"  --help                  Show this help.\n"
+		"  --root-path <path>      The absolute <path> whether to look for the input resources.\n"
+		"  --dest-path <path>      The absolute <path> whether to put the compiled resources.\n"
+		"  --seed <value>          The seed to use for generating output resource hashes.\n";
 }
 
 //-----------------------------------------------------------------------------
-int32_t parse_command_line(int argc, char* argv[])
+static int32_t parse_command_line(int argc, char* argv[])
 {
 	// Parse arguments
 	static ArgsOption options[] = 
@@ -153,32 +113,97 @@ int32_t parse_command_line(int argc, char* argv[])
 }
 
 //-----------------------------------------------------------------------------
-void print_help_message(const char* program_name)
+static void check_arguments(const char* root_path, const char* dest_path)
 {
-	printf("Usage: %s [options] [resources]\n", program_name);
-	printf
-	(
-		"Options:\n\n"
+	if (root_path == NULL)
+	{
+		cout << "you have to specify the root path with `--root-path`" << endl;
+		exit(EXIT_FAILURE);
+	}
 
-		"  --help                  Show this help.\n"
-		"  --root-path <path>      The absolute <path> whether to look for the input resources.\n"
-		"  --dest-path <path>      The absolute <path> whether to put the compiled resources.\n"
-		"  --seed <value>          The seed to use for generating output resource hashes.\n"
-	);
+	if (dest_path == NULL)
+	{
+		cout << "you have to specify the destination path with `--dest-path`" << endl;
+		exit(EXIT_FAILURE);
+	}
 }
 
 //-----------------------------------------------------------------------------
-void check_arguments(const char* root_path, const char* dest_path)
+int main(int argc, char** argv)
 {
-	if (root_path == NULL)
+	int32_t first_resource = parse_command_line(argc, argv);
+
+	// Check if all the mandatory options are set
+	check_arguments(root_path, dest_path);
+
+	// If there are no resources
+	if (first_resource >= argc)
 	{
-		printf("you have to specify the root path with `--root-path`\n");
+		cout << "You have to specify at least one resource." << endl;
 		exit(EXIT_FAILURE);
 	}
 
-	if (dest_path == NULL)
+	// Register compilers
+	TGACompiler tga;
+	WAVCompiler wav;
+	DAECompiler dae;
+
+	map<const char*, Compiler*> compilers;
+	compilers["tga"] = &tga;
+	compilers["wav"] = &wav;
+	compilers["dae"] = &dae;
+
+	// Open debug output file
+	ofstream debug_file("/home/dani/Desktop/compiler.json");
+	if (debug_file.is_open())
 	{
-		printf("you have to specify the destination path with `--dest-path`\n");
-		exit(EXIT_FAILURE);
+		debug_file << "{\n";
+	}
+
+	for (int32_t i = 0; i < argc - first_resource; i++)
+	{
+		const char* resource = argv[first_resource + i];
+
+		char resource_name[1024];
+		char resource_type[1024];
+		path::filename_without_extension(resource, resource_name, 1024);
+		path::extension(resource, resource_type, 1024);
+
+		uint32_t resource_name_hash = hash::murmur2_32(resource_name, string::strlen(resource_name), hash_seed);
+		uint32_t resource_type_hash = hash::murmur2_32(resource_type, string::strlen(resource_type), 0);
+
+		char out_name[1024];
+		snprintf(out_name, 1024, "%.8X%.8X", resource_name_hash, resource_type_hash);
+
+		cout << out_name << " <= " << argv[first_resource + i] << endl;
+
+		map<const char*, Compiler*>::iterator it = compilers.find(resource_type);
+		if (it != compilers.end())
+		{
+			if (!it->second->compile(root_path, dest_path, argv[first_resource + i], out_name))
+			{
+				cout << "Exiting." << endl;
+				exit(EXIT_FAILURE);
+			}
+		}
+		else
+		{
+			cout << "No compilers found for type '" << resource_type << "'." << endl;
+			exit(EXIT_FAILURE);
+		}
+
+		// Debug stuff
+		debug_file << "    \"" << out_name << "\" : " << "\"" << argv[first_resource + i] << "\"";
+		if (argc - first_resource - i != 1)
+		{
+			debug_file << ",";
+		}
+
+		debug_file << "\n";
 	}
+
+	debug_file << "}\n";
+	debug_file.close();
+
+	return 0;
 }

+ 17 - 14
tools/compilers/Compiler.cpp

@@ -31,11 +31,14 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "Compiler.h"
 #include "ResourceFormat.h"
 
+using std::cout;
+using std::endl;
+
 namespace crown
 {
 
 //-----------------------------------------------------------------------------
-size_t Compiler::compile(const char* root_path, const char* dest_path, const char* name_in, const char* name_out)
+bool Compiler::compile(const char* root_path, const char* dest_path, const char* name_in, const char* name_out)
 {
 	std::string path_in = std::string(root_path) + "/" + std::string(name_in);
 	std::string path_out = std::string(dest_path) + "/" + std::string(name_out);
@@ -44,8 +47,8 @@ size_t Compiler::compile(const char* root_path, const char* dest_path, const cha
 	size_t resource_size = 0;
 	if ((resource_size = compile_impl(path_in.c_str())) == 0)
 	{
-		std::cout << "Compilation failed." << std::endl;
-		return 0;
+		cout << "Compilation failed." << endl;
+		return false;
 	}
 
 	// Setup resource header
@@ -58,21 +61,21 @@ size_t Compiler::compile(const char* root_path, const char* dest_path, const cha
 	std::fstream out_file;
 	out_file.open(path_out.c_str(), std::fstream::out | std::fstream::binary);
 
-	if (!out_file.is_open())
+	if (out_file.is_open())
 	{
-		std::cout << "Unable to write compiled file." << std::endl;
-		return 0;
-	}
+		// Write header
+		out_file.write((char*)&resource_header, sizeof(ResourceHeader));
 
-	out_file.write((char*)&resource_header, sizeof(ResourceHeader));
+		// Write resource-specific data
+		write_impl(out_file);
+		out_file.close();
 
-	// Write resource-specific data
-	write_impl(out_file);
-
-	out_file.close();
+		cleanup();
+		return true;
+	}
 
-	// Cleanup
-	cleanup();
+	cout << "Unable to write compiled file." << endl;
+	return false;
 }
 
 //-----------------------------------------------------------------------------

+ 1 - 1
tools/compilers/Compiler.h

@@ -43,7 +43,7 @@ public:
 
 	virtual					~Compiler() {}
 
-	size_t					compile(const char* root_path, const char* dest_path, const char* name_in, const char* name_out);
+	bool					compile(const char* root_path, const char* dest_path, const char* name_in, const char* name_out);
 	void					cleanup();
 
 protected:

+ 1 - 0
tools/compilers/wav/WAVCompiler.cpp

@@ -68,6 +68,7 @@ size_t WAVCompiler::compile_impl(const char* resource_path)
 	}
 
 	m_sound_header.version = SOUND_VERSION;
+	m_sound_header.size = m_wav_header.data_size;
 	m_sound_header.channels = m_wav_header.fmt_channels;
 	m_sound_header.bits_per_sample = m_wav_header.fmt_bits_per_sample;
 

+ 3 - 2
tools/core/formats/SoundFormat.h

@@ -36,8 +36,9 @@ const uint32_t SOUND_VERSION = 1;
 struct SoundHeader
 {
 	uint32_t	version;	// Sound file version
-	int32_t		channels;
-	int32_t 	bits_per_sample;
+	uint32_t	size;
+	uint32_t	channels;
+	uint32_t 	bits_per_sample;
 };
 
 }

+ 4 - 0
tools/pycrown/Compiler.py

@@ -119,6 +119,9 @@ class Compiler:
 	def compile_pixel_shaders(self):
 		self.compile(self.m_repository.pixel_shader_resources());
 
+	def compile_sounds(self):
+		self.compile(self.m_repository.sound_resources());
+
 	# Compiles all the resources in the repository
 	def compile_all(self):
 		self.compile_textures()
@@ -127,6 +130,7 @@ class Compiler:
 		self.compile_scripts()
 		self.compile_vertex_shaders()
 		self.compile_pixel_shaders()
+		self.compile_sounds()
 
 	# Compile a single resource from the repository
 	def compile(self, resources):

+ 12 - 1
tools/pycrown/Repository.py

@@ -30,8 +30,9 @@ MESH_EXTENSION				= ('.dae')
 LUA_EXTENSION				= ('.lua')
 VERTEX_SHADER_EXTENSION		= ('.vs')
 PIXEL_SHADER_EXTENSION		= ('.ps')
+SOUND_EXTENSION				= ('.wav')
 
-resource_extensions = ('.txt', '.tga', '.dae', '.lua', '.vs', '.ps')
+resource_extensions = ('.txt', '.tga', '.dae', '.lua', '.vs', '.ps', '.wav')
 
 # Represents the folder containing the resources
 # Can filter resources by type and other useful stuff
@@ -113,6 +114,16 @@ class Repository:
 
 		return pss
 
+	# Returns a list of all the sound resources found
+	def sound_resources(self):
+		sounds = []
+
+		for res in self.m_resources:
+			if (res.endswith(SOUND_EXTENSION)):
+				sounds.append(res)
+
+		return sounds
+
 	# Scans the root path to find resources
 	def scan(self):
 		# Clear the resources