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

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

Daniele Bartolini 10 лет назад
Родитель
Сommit
02e9f583aa

+ 3 - 3
src/compilers/bundle_compiler.cpp

@@ -27,7 +27,7 @@ BundleCompiler::BundleCompiler(const char* source_dir, const char* bundle_dir)
 	temp.create_directory(bundle_dir);
 }
 
-bool BundleCompiler::compile(const char* type, const char* name, Platform::Enum platform)
+bool BundleCompiler::compile(const char* type, const char* name, const char* platform)
 {
 	StringId64 _type(type);
 	StringId64 _name(name);
@@ -57,7 +57,7 @@ bool BundleCompiler::compile(const char* type, const char* name, Platform::Enum
 	return true;
 }
 
-bool BundleCompiler::compile_all(Platform::Enum platform)
+bool BundleCompiler::compile_all(const char* platform)
 {
 	Vector<DynamicString> files(default_allocator());
 	BundleCompiler::scan("", files);
@@ -132,7 +132,7 @@ void BundleCompiler::scan(const char* cur_dir, Vector<DynamicString>& files)
 
 namespace bundle_compiler
 {
-	bool main(bool do_compile, bool do_continue, Platform::Enum platform)
+	bool main(bool do_compile, bool do_continue, const char* platform)
 	{
 		if (do_compile)
 		{

+ 3 - 3
src/compilers/bundle_compiler.h

@@ -18,11 +18,11 @@ public:
 
 	BundleCompiler(const char* source_dir, const char* bundle_dir);
 
-	bool compile(const char* type, const char* name, Platform::Enum platform);
+	bool compile(const char* type, const char* name, const char* platform);
 
 	/// Compiles all the resources found in @a source_dir and puts them in @a bundle_dir.
 	/// Returns true on success, false otherwise.
-	bool compile_all(Platform::Enum platform);
+	bool compile_all(const char* platform);
 
 	void scan(const char* cur_dir, Vector<DynamicString>& files);
 
@@ -34,7 +34,7 @@ private:
 
 namespace bundle_compiler
 {
-	bool main(bool do_compile, bool do_continue, Platform::Enum platform);
+	bool main(bool do_compile, bool do_continue, const char* platform);
 } // namespace bundle_compiler
 
 namespace bundle_compiler_globals

+ 3 - 3
src/compilers/compile_options.h

@@ -16,7 +16,7 @@ typedef Array<char> Buffer;
 
 struct CompileOptions
 {
-	CompileOptions(Filesystem& fs, File* out, Platform::Enum platform)
+	CompileOptions(Filesystem& fs, File* out, const char* platform)
 		: _fs(fs)
 		, _bw(*out)
 		, _platform(platform)
@@ -65,14 +65,14 @@ struct CompileOptions
 		return _bw;
 	}
 
-	Platform::Enum platform() const
+	const char* platform() const
 	{
 		return _platform;
 	}
 
 	Filesystem& _fs;
 	BinaryWriter _bw;
-	Platform::Enum _platform;
+	const char* _platform;
 };
 
 } // namespace crown

+ 0 - 59
src/core/containers/blob.h

@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2012-2015 Daniele Bartolini and individual contributors.
- * License: https://github.com/taylor001/crown/blob/master/LICENSE
- */
-
-#pragma once
-
-#include "types.h"
-#include "error.h"
-
-namespace crown
-{
-
-/// Block of raw memory.
-///
-/// @ingroup Containers
-struct Blob
-{
-	uint32_t _size;
-	uintptr_t _data;
-};
-
-/// Functions to manipulate Blob.
-///
-/// @ingroup Containers
-namespace blob
-{
-	/// Returns the size of the blob @a b.
-	uint32_t size(const Blob& b);
-
-	/// Retuns a pointer to the byte at the given absolute @a offset into the blob @a b.
-	template <typename T> const T* get(const Blob& b, uint32_t offset);
-
-	/// @copydoc blob::get<T>(const Blob&, uint32_t)
-	template <typename T> T* get(Blob& b, uint32_t offset);
-} // namespace blob
-
-namespace blob
-{
-	inline uint32_t size(const Blob& b)
-	{
-		return b._size;
-	}
-
-	template <typename T>
-	inline const T* get(const Blob& b, uint32_t offset)
-	{
-		CE_ASSERT(offset < b._size, "Overflow (size = %d, offset = %d", b._size, offset);
-		return (T*) b._data + offset;
-	}
-
-	template <typename T>
-	inline T* get(Blob& b, uint32_t offset)
-	{
-		CE_ASSERT(offset < b._size, "Overflow (size = %d, offset = %d", b._size, offset);
-		return (T*) b._data + offset;
-	}
-} // namespace blob
-} // namespace crown

+ 0 - 73
src/core/containers/dynamic_blob.h

@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2012-2015 Daniele Bartolini and individual contributors.
- * License: https://github.com/taylor001/crown/blob/master/LICENSE
- */
-
-#pragma once
-
-#include "allocator.h"
-#include "array.h"
-
-namespace crown
-{
-
-/// Dynamic block of raw memory.
-///
-/// @ingroup Containers
-typedef Array<char> DynamicBlob;
-
-/// Functions to manipulate DynamicBlob.
-///
-/// @ingroup Containers
-namespace dynamic_blob
-{
-	/// Returns the size of the blob @a b.
-	uint32_t size(const DynamicBlob& b);
-
-	/// Retuns a pointer to the byte at the given absolute @a offset into the blob @a b.
-	template <typename T> const T* get(const DynamicBlob& b, uint32_t offset);
-
-	/// @copydoc blob::get<T>(const DynamicBlob&, uint32_t)
-	template <typename T> T* get(DynamicBlob& b, uint32_t offset);
-
-	/// Appends @a num @a items to the blob @a b and returns the size of the
-	/// blob after the append operation.
-	template <typename T> uint32_t push(DynamicBlob& b, const T* items, uint32_t num);
-
-	/// Appends @a blob to @a b and returns the size of the blob after the append operation.
-	uint32_t push_blob(DynamicBlob& b, const DynamicBlob& other);
-} // namespace dynamic_blob
-
-namespace dynamic_blob
-{
-	inline uint32_t size(const DynamicBlob& b)
-	{
-		return array::size(b);
-	}
-
-	template <typename T>
-	inline const T* get(const DynamicBlob& b, uint32_t offset)
-	{
-		CE_ASSERT(offset < size(b), "Overflow (size = %d, offset = %d", size(b), offset);
-		return (T*) array::begin(b) + offset;
-	}
-
-	template <typename T>
-	inline T* get(DynamicBlob& b, uint32_t offset)
-	{
-		CE_ASSERT(offset < size(b), "Overflow (size = %d, offset = %d", size(b), offset);
-		return (T*) array::begin(b) + offset;
-	}
-
-	template <typename T>
-	inline uint32_t push(DynamicBlob& b, const T* items, uint32_t num)
-	{
-		return array::push(b, (const char*) items, num);
-	}
-
-	inline uint32_t push_blob(DynamicBlob& b, const DynamicBlob& other)
-	{
-		return array::push(b, array::begin(other), size(other));
-	}
-} // namespace dynamic_blob
-} // namespace crown

+ 2 - 2
src/core/filesystem/disk_file.cpp

@@ -12,11 +12,11 @@
 namespace crown
 {
 
-DiskFile::DiskFile(FileOpenMode mode, const char* filename)
+DiskFile::DiskFile(FileOpenMode mode, const char* path)
 	: File(mode)
-	, _file(filename, mode)
 	, _last_was_read(true)
 {
+	_file.open(path, mode);
 }
 
 DiskFile::~DiskFile()

+ 2 - 2
src/core/filesystem/disk_file.h

@@ -19,8 +19,8 @@ class DiskFile: public File
 {
 public:
 
-	/// Opens @a filename with specified @a mode
-	DiskFile(FileOpenMode mode, const char* filename);
+	/// Opens @a path with specified @a mode
+	DiskFile(FileOpenMode mode, const char* path);
 	virtual ~DiskFile();
 
 	/// @copydoc File::seek()

+ 0 - 152
src/core/filesystem/network_file.cpp

@@ -1,152 +0,0 @@
-/*
- * Copyright (c) 2012-2015 Daniele Bartolini and individual contributors.
- * License: https://github.com/taylor001/crown/blob/master/LICENSE
- */
-
-#include "json_parser.h"
-#include "container_types.h"
-#include "log.h"
-#include "math_utils.h"
-#include "network_file.h"
-#include "network_filesystem.h"
-#include "string_stream.h"
-#include "string_utils.h"
-#include "temp_allocator.h"
-#include "types.h"
-#include "dynamic_string.h"
-
-namespace crown
-{
-
-NetworkFile::NetworkFile(const NetAddress& addr, uint16_t port, const char* filename)
-	: File(FOM_READ)
-	, _address(addr)
-	, _port(port)
-	, _position(0)
-{
-	strncpy(_filename, filename, 1024);
-	_socket.connect(addr, port);
-}
-
-NetworkFile::~NetworkFile()
-{
-	_socket.close();
-}
-
-void NetworkFile::seek(uint32_t position)
-{
-	_position = position;
-}
-
-void NetworkFile::seek_to_end()
-{
-	_position = size();
-}
-
-void NetworkFile::skip(uint32_t bytes)
-{
-	_position += bytes;
-}
-
-void NetworkFile::read(void* buffer, uint32_t size)
-{
-	using namespace string_stream;
-
-	TempAllocator1024 alloc;
-	StringStream command(alloc);
-
-	// Request the file
-	command << "{\"type\":\"filesystem\",\"filesystem\":\"read\",";
-	command << "\"file\":\"" << _filename << "\",";
-	command << "\"position\":" << _position << ",";
-	command << "\"size\":" << size << "}";
-
-	network_filesystem::send(_socket, c_str(command));
-
-	// Wait for response
-	Array<char> response(default_allocator());
-	network_filesystem::read_response(_socket, response);
-
-	// Parse the response
-	JSONParser json(array::begin(response));
-	JSONElement root = json.root();
-
-	// DynamicString data_base64;
-	// root.key("data").to_string(data_base64);
-
-	// uint32_t out_len = 0;
-	// unsigned char* data = base64_decode(data_base64.c_str(), data_base64.length(), &out_len);
-	// memcpy(buffer, data, sizeof(unsigned char) * out_len);
-	// default_allocator().deallocate(data);
-}
-
-void NetworkFile::write(const void* /*buffer*/, uint32_t /*size*/)
-{
-	CE_FATAL("Cannot write to a network file");
-}
-
-bool NetworkFile::copy_to(File& file, uint32_t size)
-{
-	return true;
-}
-
-bool NetworkFile::end_of_file()
-{
-	return position() == size();
-}
-
-bool NetworkFile::is_valid()
-{
-	return true;
-}
-
-void NetworkFile::flush()
-{
-	// Do nothing
-}
-
-uint32_t NetworkFile::position()
-{
-	return _position;
-}
-
-uint32_t NetworkFile::size()
-{
-	using namespace string_stream;
-
-	TempAllocator1024 alloc;
-	StringStream command(alloc);
-
-	// Request the file
-	command << "{\"type\":\"filesystem\",\"filesystem\":\"size\",";
-	command << "\"file\":\"" << _filename << "\"}";
-
-	network_filesystem::send(_socket, c_str(command));
-
-	// Wait for response
-	Array<char> response(default_allocator());
-	network_filesystem::read_response(_socket, response);
-
-	JSONParser parser(array::begin(response));
-	JSONElement root = parser.root();
-
-	return (uint32_t) root.key("size").to_int();
-}
-
-bool NetworkFile::can_read() const
-{
-	return true;
-}
-
-bool NetworkFile::can_write() const
-{
-	return false;
-}
-
-bool NetworkFile::can_seek() const
-{
-	return true;
-}
-
-} // namespace crown
-

+ 0 - 78
src/core/filesystem/network_file.h

@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2012-2015 Daniele Bartolini and individual contributors.
- * License: https://github.com/taylor001/crown/blob/master/LICENSE
- */
-
-#pragma once
-
-#include "error.h"
-#include "socket.h"
-#include "os.h"
-#include "file.h"
-
-namespace crown
-{
-
-/// Access file on a remote file server.
-///
-/// @ingroup Filesystem
-class NetworkFile: public File
-{
-public:
-
-	/// Reads the file named @a filename from the given @a socket.
-	NetworkFile(const NetAddress& addr, uint16_t port, const char* filename);
-	virtual ~NetworkFile();
-
-	/// @copydoc File::seek()
-	void seek(uint32_t position);
-
-	/// @copydoc File::seek_to_end()
-	void seek_to_end();
-
-	/// @copydoc File::skip()
-	void skip(uint32_t bytes);
-
-	/// @copydoc File::read()
-	void read(void* buffer, uint32_t size);
-
-	/// @copydoc File::write()
-	void write(const void* buffer, uint32_t size);
-
-	/// @copydoc File::copy_to()
-	bool copy_to(File& file, uint32_t size = 0);
-
-	/// @copydoc File::flush()
-	void flush();
-
-	/// @copydoc File::end_of_file()
-	bool end_of_file();
-
-	/// @copydoc File::is_valid()
-	bool is_valid();
-
-	/// @copydoc File::size()
-	uint32_t size();
-
-	/// @copydoc File::position()
-	uint32_t position();
-
-	/// @copydoc File::can_read()
-	bool can_read() const;
-
-	/// @copydoc File::can_write()
-	bool can_write() const;
-
-	/// @copydoc File::can_seek()
-	bool can_seek() const;
-
-private:
-
-	char _filename[1024];
-	NetAddress _address;
-	uint16_t _port;
-	TCPSocket _socket;
-	uint32_t _position;
-};
-
-} // namespace crown

+ 0 - 85
src/core/filesystem/network_filesystem.cpp

@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 2012-2015 Daniele Bartolini and individual contributors.
- * License: https://github.com/taylor001/crown/blob/master/LICENSE
- */
-
-#include "json_parser.h"
-#include "network_file.h"
-#include "network_filesystem.h"
-#include "os.h"
-#include "string_utils.h"
-#include "temp_allocator.h"
-#include "string_stream.h"
-
-namespace crown
-{
-
-NetworkFilesystem::NetworkFilesystem()
-{
-}
-
-NetworkFilesystem::NetworkFilesystem(const NetAddress& addr, uint16_t port)
-	: _address(addr)
-	, _port(port)
-{
-}
-
-File* NetworkFilesystem::open(const char* path, FileOpenMode mode)
-{
-	return CE_NEW(default_allocator(), NetworkFile)(_address, _port, path);
-}
-
-void NetworkFilesystem::close(File* file)
-{
-	CE_ASSERT_NOT_NULL(file);
-	CE_DELETE(default_allocator(), file);
-}
-
-bool NetworkFilesystem::exists(const char* path)
-{
-	return false;
-}
-
-bool NetworkFilesystem::is_directory(const char* path)
-{
-  return false;
-}
-
-bool NetworkFilesystem::is_file(const char* path)
-{
-  return false;
-}
-
-void NetworkFilesystem::create_directory(const char* /*path*/)
-{
-}
-
-void NetworkFilesystem::delete_directory(const char* /*path*/)
-{
-}
-
-void NetworkFilesystem::create_file(const char* /*path*/)
-{
-}
-
-void NetworkFilesystem::delete_file(const char* /*path*/)
-{
-}
-
-void NetworkFilesystem::list_files(const char* /*path*/, Vector<DynamicString>& /*files*/)
-{
-}
-
-void NetworkFilesystem::get_absolute_path(const char* path, DynamicString& os_path)
-{
-
-}
-
-TCPSocket NetworkFilesystem::new_connection()
-{
-	TCPSocket socket;
-	socket.connect(_address, _port);
-	return socket;
-}
-
-} // namespace crown

+ 0 - 105
src/core/filesystem/network_filesystem.h

@@ -1,105 +0,0 @@
-/*
- * Copyright (c) 2012-2015 Daniele Bartolini and individual contributors.
- * License: https://github.com/taylor001/crown/blob/master/LICENSE
- */
-
-#pragma once
-
-#include "filesystem.h"
-#include "socket.h"
-#include "os.h" // for max_path_length
-#include "log.h"
-
-namespace crown
-{
-namespace network_filesystem
-{
-	inline void read_response(TCPSocket socket, Array<char>& response)
-	{
-		// Read message length
-		uint32_t msg_len = 0;
-		socket.read(&msg_len, 4);
-
-		array::resize(response, msg_len);
-		socket.read(array::begin(response), msg_len);
-
-		// Ensure NUL-terminated
-		array::push_back(response, '\0');
-	}
-
-	inline void send(TCPSocket socket, const char* msg)
-	{
-		uint32_t msg_len = strlen(msg);
-		socket.write(&msg_len, 4);
-		socket.write(msg, msg_len);
-	}
-} // namespace network_filesystem
-
-/// Access files on a remote file server.
-/// All the file paths can be either relative or absolute.
-/// When a relative path is given, it is automatically translated
-/// to its absolute counterpart based on the file server's root path.
-/// Accessing files using absolute path directly is also possible,
-/// but platform-specific and thus generally not recommended.
-///
-/// @ingroup Filesystem
-class NetworkFilesystem : public Filesystem
-{
-public:
-
-	/// Sets the root path to the current working directory of
-	/// the engine executable.
-	NetworkFilesystem();
-
-	/// Sets the file server address and port.
-	/// @note
-	/// The @a root_path must be absolute.
-	NetworkFilesystem(const NetAddress& addr, uint16_t port);
-
-	/// Opens the file at the given @a path with the given @a mode.
-	File* open(const char* path, FileOpenMode mode);
-
-	/// Closes the given @a file.
-	void close(File* file);
-
-	/// Returns whether @a path exists.
-	bool exists(const char* path);
-
-	/// Returns true if @a path is a directory.
-	bool is_directory(const char* path);
-
-	/// Returns true if @a path is a regular file.
-	bool is_file(const char* path);
-
-	/// Creates the directory at the given @a path.
-	void create_directory(const char* path);
-
-	/// Deletes the directory at the given @a path.
-	void delete_directory(const char* path);
-
-	/// Creates the file at the given @a path.
-	void create_file(const char* path);
-
-	/// Deletes the file at the given @a path.
-	void delete_file(const char* path);
-
-	/// Returns the relative file names in the given @a path.
-	void list_files(const char* path, Vector<DynamicString>& files);
-
-	/// Returns the absolute path of the given @a path based on
-	/// the root path of the file source. If @a path is absolute,
-	/// the given path is returned.
-	void get_absolute_path(const char* path, DynamicString& os_path);
-
-private:
-
-	// Returns a new connection to the file server
-	TCPSocket new_connection();
-
-private:
-
-	NetAddress _address;
-	uint16_t _port;
-};
-
-} // namespace crown

+ 50 - 46
src/core/filesystem/os_file.h

@@ -9,10 +9,10 @@
 #include "types.h"
 #include "error.h"
 #include "macros.h"
-#include "config.h"
+#include "platform.h"
 
 #if CROWN_PLATFORM_POSIX
-	#include <cstdio>
+	#include <stdio.h>
 #elif CROWN_PLATFORM_WINDOWS
 	#include "tchar.h"
 	#include "win_headers.h"
@@ -27,24 +27,14 @@ class OsFile
 public:
 
 	/// Opens the file located at @a path with the given @a mode.
-	OsFile(const char* path, FileOpenMode mode)
-#if CROWN_PLATFORM_WINDOWS
-		: _eof(false)
-#endif
-	{
+	OsFile()
 #if CROWN_PLATFORM_POSIX
-		_file = fopen(path, (mode == FOM_READ) ? "rb" : "wb");
-		CE_ASSERT(_file != NULL, "Unable to open file: %s", path);
+		: _file(NULL)
 #elif CROWN_PLATFORM_WINDOWS
-		_file = CreateFile(path,
-			mode == FOM_READ ? GENERIC_READ : GENERIC_WRITE,
-			0,
-			NULL,
-			OPEN_ALWAYS,
-			FILE_ATTRIBUTE_NORMAL,
-			NULL);
-		CE_ASSERT(_file != INVALID_HANDLE_VALUE, "Unable to open file: %s", path);
+		: _file(INVALID_HANDLE_VALUE)
+		, _eof(false)
 #endif
+	{
 	}
 
 	~OsFile()
@@ -52,6 +42,23 @@ public:
 		close();
 	}
 
+	void open(const char* path, FileOpenMode mode)
+	{
+#if CROWN_PLATFORM_POSIX
+		_file = fopen(path, (mode == FOM_READ) ? "rb" : "wb");
+		CE_ASSERT(_file != NULL, "Unable to open file: %s", path);
+#elif CROWN_PLATFORM_WINDOWS
+		_file = CreateFile(path
+			, mode == FOM_READ ? GENERIC_READ : GENERIC_WRITE,
+			, 0
+			, NULL
+			, OPEN_ALWAYS
+			, FILE_ATTRIBUTE_NORMAL
+			, NULL);
+		CE_ASSERT(_file != INVALID_HANDLE_VALUE, "Unable to open file: %s", path);
+#endif
+	}
+
 	/// Closes the file.
 	void close()
 	{
@@ -65,32 +72,36 @@ public:
 		if (is_open())
 		{
 			CloseHandle(_file);
-			_file = NULL;
+			_file = INVALID_HANDLE_VALUE;
 		}
 #endif
 	}
 
 	bool is_open() const
 	{
+#if CROWN_PLATFORM_POSIX
 		return _file != NULL;
+#elif CROWN_PLATFORM_WINDOWS
+		return _file != INVALID_HANDLE_VALUE;
+#endif
 	}
 
 	/// Return the size of the file in bytes.
-	size_t size() const
+	uint32_t size() const
 	{
 #if CROWN_PLATFORM_POSIX
 		size_t pos = position();
 
-		int fseek_result = fseek(_file, 0, SEEK_END);
-		CE_ASSERT(fseek_result == 0, "Failed to seek");
+		int err = fseek(_file, 0, SEEK_END);
+		CE_ASSERT(err == 0, "Failed to seek");
 
 		size_t size = position();
 
-		fseek_result = fseek(_file, (long) pos, SEEK_SET);
-		CE_ASSERT(fseek_result == 0, "Failed to seek");
-		CE_UNUSED(fseek_result);
+		err = fseek(_file, (long)pos, SEEK_SET);
+		CE_ASSERT(err == 0, "Failed to seek");
+		CE_UNUSED(err);
 
-		return size;
+		return (uint32_t)size;
 #elif CROWN_PLATFORM_WINDOWS
 		return GetFileSize(_file, NULL);
 #endif
@@ -98,22 +109,18 @@ public:
 
 	/// Reads @a size bytes from the file and stores it into @a data.
 	/// Returns the number of bytes read.
-	size_t read(void* data, size_t size)
+	uint32_t read(void* data, uint32_t size)
 	{
 		CE_ASSERT(data != NULL, "Data must be != NULL");
 #if CROWN_PLATFORM_POSIX
 		return fread(data, 1, size, _file);
 #elif CROWN_PLATFORM_WINDOWS
 		DWORD bytes_read;
-
 		BOOL result = ReadFile(_file, data, size, &bytes_read, NULL);
-
 		CE_ASSERT(result == TRUE, "Unable to read from file");
 
 		if (result && bytes_read == 0)
-		{
 			_eof = true;
-		}
 
 		return bytes_read;
 #endif
@@ -121,7 +128,7 @@ public:
 
 	/// Writes @a size bytes of data stored in @a data and returns the
 	/// number of bytes written.
-	size_t write(const void* data, size_t size)
+	uint32_t write(const void* data, uint32_t size)
 	{
 		CE_ASSERT(data != NULL, "Data must be != NULL");
 #if CROWN_PLATFORM_POSIX
@@ -135,7 +142,7 @@ public:
 	}
 
 	/// Moves the file pointer to the given @a position.
-	void seek(size_t position)
+	void seek(uint32_t position)
 	{
 #if CROWN_PLATFORM_POSIX
 		int err = fseek(_file, (long) position, SEEK_SET);
@@ -162,31 +169,28 @@ public:
 
 	/// Moves the file pointer @a bytes bytes ahead the current
 	/// file pointer position.
-	void skip(size_t bytes)
+	void skip(uint32_t bytes)
 	{
 #if CROWN_PLATFORM_POSIX
-		int fseek_result = fseek(_file, bytes, SEEK_CUR);
-		CE_ASSERT(fseek_result == 0, "Failed to seek");
-		CE_UNUSED(fseek_result);
+		int err = fseek(_file, bytes, SEEK_CUR);
+		CE_ASSERT(err == 0, "Failed to seek");
+		CE_UNUSED(err);
 #elif CROWN_PLATFORM_WINDOWS
-		DWORD seek_result = SetFilePointer(_file, bytes, NULL, FILE_CURRENT);
-
-		CE_ASSERT(seek_result != INVALID_SET_FILE_POINTER, "Failed to skip");
+		DWORD err = SetFilePointer(_file, bytes, NULL, FILE_CURRENT);
+		CE_ASSERT(err != INVALID_SET_FILE_POINTER, "Failed to skip");
 #endif
 	}
 
 	/// Returns the position of the file pointer from the
 	/// start of the file in bytes.
-	size_t position() const
+	uint32_t position() const
 	{
 #if CROWN_PLATFORM_POSIX
-		return (size_t) ftell(_file);
+		return (uint32_t)ftell(_file);
 #elif CROWN_PLATFORM_WINDOWS
-		DWORD position = SetFilePointer(_file, 0, NULL, FILE_CURRENT);
-
-		CE_ASSERT(position != INVALID_SET_FILE_POINTER, "Failed to get position");
-
-		return position;
+		DWORD pos = SetFilePointer(_file, 0, NULL, FILE_CURRENT);
+		CE_ASSERT(pos != INVALID_SET_FILE_POINTER, "Failed to get position");
+		return (uint32_t)pos;
 #endif
 	}
 

+ 6 - 6
src/core/os.h

@@ -176,18 +176,18 @@ namespace os
 		HANDLE file = INVALID_HANDLE_VALUE;
 		WIN32_FIND_DATA ffd;
 
-		char cur_path[1024];
+		TempAllocator1024 ta;
+		DynamicString cur_path(path, ta);
+		cur_path += "\\*";
 
-		strncpy(cur_path, path, strlen(path) + 1);
-		strncat(cur_path, "\\*", 2);
-
-		file = FindFirstFile(cur_path, &ffd);
+		file = FindFirstFile(cur_path.c_str(), &ffd);
 
 		do
 		{
 			CE_ASSERT(file != INVALID_HANDLE_VALUE, "Unable to list files. errono %d", GetLastError());
 
-			if ((strcmp(ffd.cFileName, ".") == 0) || (strcmp(ffd.cFileName, "..") == 0))
+			if (strcmp(ffd.cFileName, ".") == 0
+				|| strcmp(ffd.cFileName, "..") == 0)
 			{
 				continue;
 			}

+ 25 - 26
src/core/strings/path.cpp

@@ -12,12 +12,6 @@ namespace crown
 {
 namespace path
 {
-#if CROWN_PLATFORM_POSIX
-	const char SEPARATOR = '/';
-#elif CROWN_PLATFORM_WINDOWS
-	const char SEPARATOR = '\\';
-#endif // CROWN_PLATFORM_POSIX
-
 	bool is_absolute_path(const char* path)
 	{
 		CE_ASSERT(path != NULL, "Path must be != NULL");
@@ -99,15 +93,16 @@ namespace path
 		CE_ASSERT(path != NULL, "Path must be != NULL");
 		CE_ASSERT(str != NULL, "Str must be != NULL");
 
-		const char* last_separator = find_last(path, '/');
+		const char* last_separator = strrchr(path, '/');
+		const char* end = path + strlen(path) + 1;
 
-		if (last_separator == end(path))
+		if (last_separator == end)
 		{
 			strncpy(str, "", len);
 		}
 		else
 		{
-			substring(begin(path), last_separator, str, len);
+			substring(path, last_separator, str, len);
 		}
 	}
 
@@ -124,15 +119,16 @@ namespace path
 		CE_ASSERT(path != NULL, "Path must be != NULL");
 		CE_ASSERT(str != NULL, "Str must be != NULL");
 
-		const char* last_separator = find_last(path, '/');
+		const char* last_separator = strrchr(path, '/');
+		const char* end = str + strlen(path) + 1;
 
-		if (last_separator == end(path))
+		if (last_separator == end)
 		{
 			strncpy(str, "", len);
 		}
 		else
 		{
-			substring(last_separator + 1, end(path), str, len);
+			substring(last_separator + 1, end, str, len);
 		}
 	}
 
@@ -148,18 +144,19 @@ namespace path
 		CE_ASSERT(path != NULL, "Path must be != NULL");
 		CE_ASSERT(str != NULL, "Str must be != NULL");
 
-		const char* last_separator = find_last(path, '/');
-		const char* last_dot = find_last(path, '.');
+		const char* last_separator = strrchr(path, '/');
+		const char* last_dot = strrchr(path, '.');
+		const char* end = path + strlen(path) + 1;
 
-		if (last_separator == end(path) && last_dot != end(path))
+		if (last_separator == end && last_dot != end)
 		{
-			substring(begin(path), last_dot, str, len);
+			substring(path, last_dot, str, len);
 		}
-		else if (last_separator != end(path) && last_dot == end(path))
+		else if (last_separator != end && last_dot == end)
 		{
-			substring(last_separator + 1, end(path), str, len);
+			substring(last_separator + 1, end, str, len);
 		}
-		else if (last_separator == end(path) && last_dot == end(path))
+		else if (last_separator == end && last_dot == end)
 		{
 			strncpy(str, path, len);
 		}
@@ -180,15 +177,16 @@ namespace path
 		CE_ASSERT(path != NULL, "Path must be != NULL");
 		CE_ASSERT(str != NULL, "Str must be != NULL");
 
-		const char* last_dot = find_last(path, '.');
+		const char* last_dot = strrchr(path, '.');
+		const char* end = path + strlen(path) + 1;
 
-		if (last_dot == end(path))
+		if (last_dot == end)
 		{
 			strncpy(str, "", len);
 		}
 		else
 		{
-			substring(last_dot + 1, end(path), str, len);
+			substring(last_dot + 1, end, str, len);
 		}
 	}
 
@@ -203,9 +201,9 @@ namespace path
 		CE_ASSERT(path != NULL, "Path must be != NULL");
 		CE_ASSERT(str != NULL, "Str must be != NULL");
 
-		const char* last_dot = find_last(path, '.');
+		const char* last_dot = strrchr(path, '.');
 
-		substring(begin(path), last_dot, str, len);
+		substring(path, last_dot, str, len);
 	}
 
 	/// Fills 'ret' with the same path but without the trailing directory separator.
@@ -220,14 +218,15 @@ namespace path
 		CE_ASSERT(str != NULL, "Str must be != NULL");
 
 		size_t path_len = strlen(path);
+		const char* end = path + strlen(path) + 1;
 
 		if (path[path_len - 1] == '/')
 		{
-			substring(begin(path), end(path) - 2, str, len);
+			substring(path, end - 2, str, len);
 		}
 		else
 		{
-			substring(begin(path), end(path), str, len);
+			substring(path, end, str, len);
 		}
 	}
 } // namespace path

+ 6 - 0
src/core/strings/path.h

@@ -17,6 +17,12 @@ namespace crown
 /// @ingroup Path
 namespace path
 {
+#if CROWN_PLATFORM_POSIX
+	const char SEPARATOR = '/';
+#elif CROWN_PLATFORM_WINDOWS
+	const char SEPARATOR = '\\';
+#endif // CROWN_PLATFORM_POSIX
+
 	/// Returns whether the @a path is absolute.
 	bool is_absolute_path(const char* path);
 

+ 17 - 115
src/core/strings/string_utils.h

@@ -5,56 +5,18 @@
 
 #pragma once
 
-#include "error.h"
 #include "types.h"
+#include "error.h"
 #include "config.h"
 #include "macros.h"
-#include <cstdio>
-#include <cstring>
-#include <cstdarg>
-#include <cctype>
+#include <stdio.h> // sscanf
+#include <string.h>
+#include <stdarg.h>
+#include <ctype.h> // isspace
 
 namespace crown
 {
 
-inline size_t strlen(const char* str)
-{
-	return ::strlen(str);
-}
-
-inline const char* strstr(const char* str1, const char* str2)
-{
-	return ::strstr(str1, str2);
-}
-
-inline int32_t strcmp(const char* str1, const char* str2)
-{
-	return ::strcmp(str1, str2);
-}
-
-inline int32_t strncmp(const char* s1, const char* s2, size_t len)
-{
-	return ::strncmp(s1, s2, len);
-}
-
-inline char* strncpy(char* dest, const char* src, size_t len)
-{
-	char* ret = ::strncpy(dest, src, len);
-	dest[len - 1] = '\0';
-
-	return ret;
-}
-
-inline char* strcat(char* dest, const char* src)
-{
-	return ::strcat(dest, src);
-}
-
-inline char* strncat(char* dest, const char* src, size_t len)
-{
-	return ::strncat(dest, src, len);
-}
-
 inline int32_t vsnprintf(char* str, size_t num, const char* format, va_list args)
 {
 #if CROWN_COMPILER_MSVC
@@ -99,58 +61,6 @@ inline const char* skip_block(const char* str, char a, char b)
 	return NULL;
 }
 
-inline const char* begin(const char* str)
-{
-	CE_ASSERT(str != NULL, "Str must be != NULL");
-
-	return str;
-}
-
-inline const char* end(const char* str)
-{
-	CE_ASSERT(str != NULL, "Str must be != NULL");
-
-	return str + strlen(str) + 1;
-}
-
-inline const char* find_first(const char* str, char c)
-{
-	CE_ASSERT(str != NULL, "Str must be != NULL");
-
-	const char* str_begin = begin(str);
-
-	while (str_begin != end(str))
-	{
-		if ((*str_begin) == c)
-		{
-			return str_begin;
-		}
-
-		str_begin++;
-	}
-
-	return end(str);
-}
-
-inline const char* find_last(const char* str, char c)
-{
-	CE_ASSERT(str != NULL, "Str must be != NULL");
-
-	const char* str_end = end(str) - 1;
-
-	while (str_end != begin(str) - 1)
-	{
-		if ((*str_end) == c)
-		{
-			return str_end;
-		}
-
-		str_end--;
-	}
-
-	return end(str);
-}
-
 inline void substring(const char* begin, const char* end, char* out, size_t len)
 {
 	CE_ASSERT(begin != NULL, "Begin must be != NULL");
@@ -173,47 +83,39 @@ inline void substring(const char* begin, const char* end, char* out, size_t len)
 	out[i] = '\0';
 }
 
-inline int32_t parse_int(const char* string)
+inline int32_t parse_int(const char* str)
 {
 	int val;
-	int ok = sscanf(string, "%d", &val);
-
-	CE_ASSERT(ok == 1, "Failed to parse int: %s", string);
+	int ok = sscanf(str, "%d", &val);
+	CE_ASSERT(ok == 1, "Failed to parse int: %s", str);
 	CE_UNUSED(ok);
-
 	return val;
 }
 
-inline uint32_t parse_uint(const char* string)
+inline uint32_t parse_uint(const char* str)
 {
 	unsigned int val;
-	int ok = sscanf(string, "%u", &val);
-
-	CE_ASSERT(ok == 1, "Failed to parse uint: %s", string);
+	int ok = sscanf(str, "%u", &val);
+	CE_ASSERT(ok == 1, "Failed to parse uint: %s", str);
 	CE_UNUSED(ok);
-
 	return val;
 }
 
-inline float parse_float(const char* string)
+inline float parse_float(const char* str)
 {
 	float val;
-	int ok = sscanf(string, "%f", &val);
-
-	CE_ASSERT(ok == 1, "Failed to parse float: %s", string);
+	int ok = sscanf(str, "%f", &val);
+	CE_ASSERT(ok == 1, "Failed to parse float: %s", str);
 	CE_UNUSED(ok);
-
 	return val;
 }
 
-inline double parse_double(const char* string)
+inline double parse_double(const char* str)
 {
 	double val;
-	int ok = sscanf(string, "%lf", &val);
-
-	CE_ASSERT(ok == 1, "Failed to parse float: %s", string);
+	int ok = sscanf(str, "%lf", &val);
+	CE_ASSERT(ok == 1, "Failed to parse float: %s", str);
 	CE_UNUSED(ok);
-
 	return val;
 }
 

+ 2 - 126
src/crown.cpp

@@ -23,29 +23,6 @@
 namespace crown
 {
 
-struct PlatformInfo
-{
-	const char* name;
-	Platform::Enum target;
-};
-
-static const PlatformInfo s_platform[Platform::COUNT] =
-{
-	{ "linux",   Platform::LINUX   },
-	{ "windows", Platform::WINDOWS },
-	{ "android", Platform::ANDROID }
-};
-
-static Platform::Enum string_to_platform(const char* platform)
-{
-	for (uint32_t i = 0; platform != NULL && i < Platform::COUNT; i++)
-	{
-		if (strcmp(platform, s_platform[i].name) == 0)
-			return s_platform[i].target;
-	}
-	return Platform::COUNT;
-}
-
 static void help(const char* msg = NULL)
 {
 	if (msg)
@@ -79,114 +56,13 @@ static void help(const char* msg = NULL)
 	);
 }
 
-void parse_command_line(int argc, char** argv, ConfigSettings& cs)
-{
-	CommandLine cmd(argc, argv);
-
-	if (cmd.has_argument("help", 'h'))
-	{
-		help();
-		exit(EXIT_SUCCESS);
-	}
-
-	if (cmd.has_argument("version", 'v'))
-	{
-		printf(CROWN_PLATFORM_NAME "-" CROWN_CPU_NAME " (" CROWN_ARCH_NAME ")" " (" CROWN_COMPILER_NAME ")\n");
-		exit(EXIT_SUCCESS);
-	}
-
-	cs.source_dir = cmd.get_parameter("source-dir");
-	if (!cs.source_dir)
-	{
-		help("Source directory must be specified.");
-		exit(EXIT_FAILURE);
-	}
-
-	cs.bundle_dir = cmd.get_parameter("bundle-dir");
-	if (!cs.bundle_dir)
-	{
-		help("Bundle directory must be specified.");
-		exit(EXIT_FAILURE);
-	}
-
-	if (strcmp(cs.source_dir, cs.bundle_dir) == 0)
-	{
-		help("Source and Bundle directories must differ.");
-		exit(EXIT_FAILURE);
-	}
-
-	cs.project = cmd.get_parameter("project");
-
-	cs.wait_console = cmd.has_argument("wait-console");
-	cs.do_compile = cmd.has_argument("compile");
-	cs.do_continue = cmd.has_argument("continue");
-
-	cs.platform = string_to_platform(cmd.get_parameter("platform"));
-	if (cs.do_compile && cs.platform == Platform::COUNT)
-	{
-		help("Platform must be specified.");
-		exit(EXIT_FAILURE);
-	}
-
-	const char* parent = cmd.get_parameter("parent-window");
-	if (parent)
-	{
-		cs.parent_window = parse_uint(parent);
-	}
-
-	const char* port = cmd.get_parameter("console-port");
-	if (port)
-	{
-		cs.console_port = parse_uint(port);
-	}
-}
-
-void parse_config_file(Filesystem& fs, ConfigSettings& cs)
-{
-	TempAllocator512 alloc;
-	DynamicString project_path(alloc);
-
-	if (cs.project != NULL)
-	{
-		project_path += cs.project;
-		project_path += "/";
-	}
-	project_path += "crown.config";
-
-	File* tmpfile = fs.open(project_path.c_str(), FOM_READ);
-	JSONParser config(*tmpfile);
-	fs.close(tmpfile);
-	JSONElement root = config.root();
-
-	JSONElement cport = root.key_or_nil("console_port");
-	if (!cport.is_nil())
-	{
-		cs.console_port = (int16_t) cport.to_int();
-	}
-
-	JSONElement window_width = root.key_or_nil("window_width");
-	if (!window_width.is_nil())
-	{
-		cs.window_width = max((uint16_t)1, (uint16_t)window_width.to_int());
-	}
-
-	JSONElement window_height = root.key_or_nil("window_height");
-	if (!window_height.is_nil())
-	{
-		cs.window_height = max((uint16_t)1, (uint16_t)window_height.to_int());
-	}
-
-	cs.boot_script = root.key("boot_script").to_resource_id();
-	cs.boot_package = root.key("boot_package").to_resource_id();
-}
-
-bool init(Filesystem& fs, const ConfigSettings& cs)
+bool init(const DeviceOptions& opts, Filesystem& fs)
 {
 	profiler_globals::init();
 	audio_globals::init();
 	physics_globals::init();
 	bgfx::init();
-	device_globals::init(cs, fs);
+	device_globals::init(opts, fs);
 	device()->init();
 	return true;
 }

+ 2 - 52
src/crown.h

@@ -7,62 +7,12 @@
 
 #include "types.h"
 #include "filesystem_types.h"
+#include "device_options.h"
 
 namespace crown
 {
-	struct Platform
-	{
-		enum Enum
-		{
-			LINUX,
-			WINDOWS,
-			ANDROID,
-
-			COUNT
-		};
-	};
-
-	struct ConfigSettings
-	{
-		ConfigSettings()
-			: source_dir(NULL)
-			, bundle_dir(NULL)
-			, project(NULL)
-			, platform(Platform::COUNT)
-			, wait_console(false)
-			, do_compile(false)
-			, do_continue(false)
-			, parent_window(0)
-			, console_port(CROWN_DEFAULT_CONSOLE_PORT)
-			, boot_package(uint64_t(0))
-			, boot_script(uint64_t(0))
-			, window_width(CROWN_DEFAULT_WINDOW_WIDTH)
-			, window_height(CROWN_DEFAULT_WINDOW_HEIGHT)
-		{
-		}
-
-		const char* source_dir;
-		const char* bundle_dir;
-		const char* project;
-		Platform::Enum platform;
-		bool wait_console;
-		bool do_compile;
-		bool do_continue;
-		uint32_t parent_window;
-		uint16_t console_port;
-		StringId64 boot_package;
-		StringId64 boot_script;
-		uint16_t window_width;
-		uint16_t window_height;
-	};
-
-	void parse_command_line(int argc, char** argv, ConfigSettings& cs);
-
-	/// Read configuration file from @a fs.
-	void parse_config_file(Filesystem& fs, ConfigSettings& cs);
-
 	/// Initializes the engine.
-	bool init(Filesystem& fs, const ConfigSettings& cs);
+	bool init(const DeviceOptions& opts, Filesystem& fs);
 
 	/// Updates all the subsystems.
 	void update();

+ 61 - 21
src/device.cpp

@@ -17,12 +17,16 @@
 #include "resource_package.h"
 #include "types.h"
 #include "world.h"
+#include "json_parser.h"
+#include "filesystem.h"
+#include "path.h"
 
 #define MAX_SUBSYSTEMS_HEAP 8 * 1024 * 1024
 
 namespace crown
 {
-Device::Device(const ConfigSettings& cs, Filesystem& fs)
+
+Device::Device(const DeviceOptions& opts, Filesystem& fs)
 	: _allocator(default_allocator(), MAX_SUBSYSTEMS_HEAP)
 	, _width(0)
 	, _height(0)
@@ -34,10 +38,10 @@ Device::Device(const ConfigSettings& cs, Filesystem& fs)
 	, _current_time(0)
 	, _last_delta_time(0.0f)
 	, _time_since_start(0.0)
-	, _cs(cs)
+	, _device_options(opts)
 	, _fs(fs)
-	, _boot_package_id(cs.boot_package)
-	, _boot_script_id(cs.boot_script)
+	, _boot_package_id(uint64_t(0))
+	, _boot_script_id(uint64_t(0))
 	, _boot_package(NULL)
 	, _lua_environment(NULL)
 	, _resource_manager(NULL)
@@ -51,6 +55,8 @@ void Device::init()
 	// Initialize
 	CE_LOGI("Initializing Crown Engine %s...", version());
 
+	read_config();
+
 	// Create resource manager
 	CE_LOGD("Creating resource manager...");
 	_resource_manager = CE_NEW(_allocator, ResourceManager)(_fs);
@@ -104,21 +110,6 @@ void Device::shutdown()
 	_is_init = false;
 }
 
-ResourceManager* Device::resource_manager()
-{
-	return _resource_manager;
-}
-
-LuaEnvironment* Device::lua_environment()
-{
-	return _lua_environment;
-}
-
-InputManager* Device::input_manager()
-{
-	return _input_manager;
-}
-
 void Device::quit()
 {
 	_is_running = false;
@@ -136,6 +127,18 @@ void Device::unpause()
 	CE_LOGI("Engine unpaused.");
 }
 
+void Device::update_resolution(uint16_t width, uint16_t height)
+{
+	_width = width;
+	_height = height;
+}
+
+void Device::resolution(uint16_t& width, uint16_t& height)
+{
+	width = _width;
+	height = _height;
+}
+
 bool Device::is_running() const
 {
 	return _is_running;
@@ -228,15 +231,52 @@ void Device::reload(StringId64 type, StringId64 name)
 	}
 }
 
+ResourceManager* Device::resource_manager()
+{
+	return _resource_manager;
+}
+
+LuaEnvironment* Device::lua_environment()
+{
+	return _lua_environment;
+}
+
+InputManager* Device::input_manager()
+{
+	return _input_manager;
+}
+
+void Device::read_config()
+{
+	TempAllocator1024 ta;
+	DynamicString project_path(ta);
+
+	if (_device_options.project() != NULL)
+	{
+		project_path += _device_options.project();
+		project_path += path::SEPARATOR;
+	}
+
+	project_path += "crown.config";
+
+	File* tmpfile = _fs.open(project_path.c_str(), FOM_READ);
+	JSONParser config(*tmpfile);
+	_fs.close(tmpfile);
+	JSONElement root = config.root();
+
+	_boot_script_id = root.key("boot_script").to_resource_id();
+	_boot_package_id = root.key("boot_package").to_resource_id();
+}
+
 namespace device_globals
 {
 	char _buffer[sizeof(Device)];
 	Device* _device = NULL;
 
-	void init(const ConfigSettings& cs, Filesystem& fs)
+	void init(const DeviceOptions& opts, Filesystem& fs)
 	{
 		CE_ASSERT(_device == NULL, "Crown already initialized");
-		_device = new (_buffer) Device(cs, fs);
+		_device = new (_buffer) Device(opts, fs);
 	}
 
 	void shutdown()

+ 10 - 14
src/device.h

@@ -14,7 +14,7 @@
 #include "filesystem_types.h"
 #include "container_types.h"
 #include "input_types.h"
-#include "crown.h"
+#include "device_options.h"
 
 namespace crown
 {
@@ -27,7 +27,7 @@ namespace crown
 /// @ingroup Device
 struct Device
 {
-	Device(const ConfigSettings& cs, Filesystem& fs);
+	Device(const DeviceOptions& opts, Filesystem& fs);
 
 	void init();
 
@@ -65,18 +65,10 @@ struct Device
 	/// Unpauses the engine.
 	void unpause();
 
-	void update_resolution(uint16_t width, uint16_t height)
-	{
-		_width = width;
-		_height = height;
-	}
+	void update_resolution(uint16_t width, uint16_t height);
 
 	/// Returns the main window resolution.
-	void resolution(uint16_t& width, uint16_t& height)
-	{
-		width = _width;
-		height = _height;
-	}
+	void resolution(uint16_t& width, uint16_t& height);
 
 	/// Updates all the subsystems.
 	void update();
@@ -111,6 +103,10 @@ struct Device
 	/// Returns the input manager.
 	InputManager* input_manager();
 
+private:
+
+	void read_config();
+
 private:
 
 	// Used to allocate all subsystems
@@ -129,7 +125,7 @@ private:
 	float _last_delta_time;
 	double _time_since_start;
 
-	const ConfigSettings& _cs;
+	const DeviceOptions& _device_options;
 	Filesystem& _fs;
 	StringId64 _boot_package_id;
 	StringId64 _boot_script_id;
@@ -150,7 +146,7 @@ private:
 
 namespace device_globals
 {
-	void init(const ConfigSettings& cs, Filesystem& fs);
+	void init(const DeviceOptions& opts, Filesystem& fs);
 	void shutdown();
 } // namespace device_globals
 

+ 48 - 0
src/device_options.cpp

@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2012-2015 Daniele Bartolini and individual contributors.
+ * License: https://github.com/taylor001/crown/blob/master/LICENSE
+ */
+
+#include "device_options.h"
+#include "command_line.h"
+
+namespace crown
+{
+
+DeviceOptions::DeviceOptions(int argc, char** argv)
+	: _source_dir(NULL)
+	, _bundle_dir(NULL)
+	, _project(NULL)
+	, _platform(NULL)
+	, _wait_console(false)
+	, _do_compile(false)
+	, _do_continue(false)
+	, _parent_window(0)
+	, _console_port(CROWN_DEFAULT_CONSOLE_PORT)
+	, _window_x(0)
+	, _window_y(0)
+	, _window_width(CROWN_DEFAULT_WINDOW_WIDTH)
+	, _window_height(CROWN_DEFAULT_WINDOW_HEIGHT)
+{
+	CommandLine cmd(argc, argv);
+
+	_source_dir = cmd.get_parameter("source-dir");
+	_bundle_dir = cmd.get_parameter("bundle-dir");
+	_project = cmd.get_parameter("project");
+	_platform = cmd.get_parameter("platform");
+
+	_wait_console = cmd.has_argument("wait-console");
+	_do_compile = cmd.has_argument("compile");
+	_do_continue = cmd.has_argument("continue");
+
+	const char* parent = cmd.get_parameter("parent-window");
+	if (parent)
+		_parent_window = parse_uint(parent);
+
+	const char* port = cmd.get_parameter("console-port");
+	if (port)
+		_console_port = parse_uint(port);
+}
+
+}
+

+ 48 - 0
src/device_options.h

@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2012-2015 Daniele Bartolini and individual contributors.
+ * License: https://github.com/taylor001/crown/blob/master/LICENSE
+ */
+
+#pragma once
+
+#include "types.h"
+
+namespace crown
+{
+
+struct DeviceOptions
+{
+	DeviceOptions(int argc, char** argv);
+
+	const char* source_dir() const { return _source_dir; }
+	const char* bundle_dir() const { return _bundle_dir; }
+	const char* project() const { return _project; }
+	const char* platform() const { return _platform; }
+	bool wait_console() const { return _wait_console; }
+	bool do_compile() const { return _do_compile; }
+	bool do_continue() const { return _do_continue; }
+	uint32_t parent_window() const { return _parent_window; }
+	uint16_t console_port() const { return _console_port; }
+	uint16_t window_x() const { return _window_x; }
+	uint16_t window_y() const { return _window_y; }
+	uint16_t window_width() const { return _window_width; }
+	uint16_t window_height() const { return _window_height; }
+
+private:
+
+	const char* _source_dir;
+	const char* _bundle_dir;
+	const char* _project;
+	const char* _platform;
+	bool _wait_console;
+	bool _do_compile;
+	bool _do_continue;
+	uint32_t _parent_window;
+	uint16_t _console_port;
+	uint16_t _window_x;
+	uint16_t _window_y;
+	uint16_t _window_width;
+	uint16_t _window_height;
+};
+
+} // namespace crown

+ 16 - 23
src/main/main_linux.cpp

@@ -166,13 +166,13 @@ static bool s_exit = false;
 struct MainThreadArgs
 {
 	Filesystem* fs;
-	ConfigSettings* cs;
+	DeviceOptions* ds;
 };
 
 int32_t func(void* data)
 {
 	MainThreadArgs* args = (MainThreadArgs*) data;
-	crown::init(*args->fs, *args->cs);
+	crown::init(*args->ds, *args->fs);
 	crown::update();
 	crown::shutdown();
 	s_exit = true;
@@ -190,7 +190,7 @@ struct LinuxDevice
 	{
 	}
 
-	int32_t run(Filesystem* fs, ConfigSettings* cs)
+	int32_t run(Filesystem* fs, DeviceOptions* ds)
 	{
 		// http://tronche.com/gui/x/xlib/display/XInitThreads.html
 		Status xs = XInitThreads();
@@ -204,8 +204,8 @@ struct LinuxDevice
 		int depth = DefaultDepth(_x11_display, screen);
 		Visual* visual = DefaultVisual(_x11_display, screen);
 
-		_x11_parent_window = (cs->parent_window == 0) ? RootWindow(_x11_display, screen) :
-			(Window) cs->parent_window;
+		_x11_parent_window = (ds->parent_window() == 0) ? RootWindow(_x11_display, screen) :
+			(Window)ds->parent_window();
 
 		// Create main window
 		XSetWindowAttributes win_attribs;
@@ -221,10 +221,10 @@ struct LinuxDevice
 
 		_x11_window = XCreateWindow(_x11_display
 			, _x11_parent_window
-			, 0
-			, 0
-			, cs->window_width
-			, cs->window_height
+			, ds->window_x()
+			, ds->window_y()
+			, ds->window_width()
+			, ds->window_height()
 			, 0
 			, depth
 			, InputOutput
@@ -264,7 +264,7 @@ struct LinuxDevice
 		// Start main thread
 		MainThreadArgs mta;
 		mta.fs = fs;
-		mta.cs = cs;
+		mta.ds = ds;
 
 		Thread main_thread;
 		main_thread.start(func, &mta);
@@ -401,29 +401,22 @@ bool next_event(OsEvent& ev)
 int main(int argc, char** argv)
 {
 	using namespace crown;
-
-	ConfigSettings cs;
-	parse_command_line(argc, argv, cs);
-
 	memory_globals::init();
-	{
-		DiskFilesystem fs(cs.source_dir);
-		parse_config_file(fs, cs);
-	}
 
-	console_server_globals::init(cs.console_port, cs.wait_console);
+	DeviceOptions opts(argc, argv);
 
-	bundle_compiler_globals::init(cs.source_dir, cs.bundle_dir);
+	console_server_globals::init(opts.console_port(), opts.wait_console());
+	bundle_compiler_globals::init(opts.source_dir(), opts.bundle_dir());
 
 	bool do_continue = true;
 	int exitcode = EXIT_SUCCESS;
 
-	do_continue = bundle_compiler::main(cs.do_compile, cs.do_continue, cs.platform);
+	do_continue = bundle_compiler::main(opts.do_compile(), opts.do_continue(), opts.platform());
 
 	if (do_continue)
 	{
-		DiskFilesystem dst_fs(cs.bundle_dir);
-		exitcode = crown::s_ldvc.run(&dst_fs, &cs);
+		DiskFilesystem dst_fs(opts.bundle_dir());
+		exitcode = crown::s_ldvc.run(&dst_fs, &opts);
 	}
 
 	bundle_compiler_globals::shutdown();

+ 2 - 9
src/renderers/shader.cpp

@@ -32,13 +32,6 @@ namespace crown
 {
 namespace shader_resource
 {
-	static const char* _scplatform[Platform::COUNT] =
-	{
-		"linux",
-		"windows",
-		"android"
-	};
-
 	void compile(const char* path, CompileOptions& opts)
 	{
 		Buffer buf = opts.read(path);
@@ -92,7 +85,7 @@ namespace shader_resource
 			"-o", tmpvs_path.c_str(),
 			"--varyingdef", varying_def_path.c_str(),
 			"--type", "vertex",
-			"--platform", _scplatform[opts.platform()],
+			"--platform", opts.platform(),
 			"--profile",
 #if CROWN_PLATFORM_LINUX
 			"120",
@@ -111,7 +104,7 @@ namespace shader_resource
 			"-o", tmpfs_path.c_str(),
 			"--varyingdef", varying_def_path.c_str(),
 			"--type", "fragment",
-			"--platform", _scplatform[opts.platform()],
+			"--platform", opts.platform(),
 			"--profile",
 #if CROWN_PLATFORM_LINUX
 			"120",