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

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

mikymod 12 лет назад
Родитель
Сommit
25e834bc7e

+ 5 - 1
.gitignore

@@ -26,4 +26,8 @@ test-results
 /engine/third/ARMv7/physx/include
 /engine/third/ARMv7/physx/lib
 /engine/third/x86_64/physx/include
-/engine/third/x86_64/physx/lib
+/engine/third/x86_64/physx/lib
+/engine/third/win32/physx
+/engine/third/win32/zlib
+/engine/third/win32/freetype/include
+/engine/third/win32/freetype/lib

+ 72 - 5
engine/CMakeLists.txt

@@ -626,11 +626,7 @@ if (WINDOWS)
 	)
 
 	list (APPEND AUDIO_SRC
-		audio/al/ALRenderer.cpp
-	)
-
-	list (APPEND AUDIO_HEADERS
-		audio/al/ALRenderer.h
+		audio/backend/ALSoundWorld.cpp
 	)
 
 	list (APPEND CROWN_LIBRARIES
@@ -645,6 +641,77 @@ if (WINDOWS)
 
 	set (COMPILER_FLAGS
 	)
+	
+	if (CROWN_ARCH MATCHES "win32")
+		set (WIN_PHYSXARCH x86)
+	elseif (CROWN_ARCH MATCHES "win64")
+		set (WIN_PHYSXARCH x64)
+  else ()
+    message (FATAL_ERROR "Oops, you should not be here")
+	endif (CROWN_ARCH MATCHES "win32")
+
+	if (CROWN_DEBUG)
+		#list (APPEND COMPILER_FLAGS -g -D_DEBUG)
+		list (APPEND CROWN_LIBRARIES
+			#LowLevelCHECKED
+			#LowLevelClothCHECKED
+			PhysX3CharacterKinematicCHECKED_${WIN_PHYSXARCH}
+			PhysX3CHECKED_${WIN_PHYSXARCH}
+			PhysX3CommonCHECKED_${WIN_PHYSXARCH}
+			PhysX3CookingCHECKED_${WIN_PHYSXARCH}
+			PhysX3ExtensionsCHECKED
+			PhysXProfileSDKCHECKED
+			PhysXVisualDebuggerSDKCHECKED
+			#PvdRuntimeCHECKED
+			PxTaskCHECKED
+			#SceneQueryCHECKED
+			#SimulationControllerCHECKED
+		)
+	elseif (CROWN_DEVELOPMENT)
+		#list (APPEND COMPILER_FLAGS -O2 -DNDEBUG)
+		list (APPEND CROWN_LIBRARIES
+			#LowLevelPROFILE
+			#LowLevelClothPROFILE
+			PhysX3CharacterKinematicPROFILE_${WIN_PHYSXARCH}
+			PhysX3PROFILE_${WIN_PHYSXARCH}
+			PhysX3CommonPROFILE_${WIN_PHYSXARCH}
+			PhysX3CookingPROFILE_${WIN_PHYSXARCH}
+			PhysX3ExtensionsPROFILE
+			PhysXProfileSDKPROFILE
+			PhysXVisualDebuggerSDKPROFILE
+			#PvdRuntimePROFILE
+			PxTaskPROFILE
+			#SceneQueryPROFILE
+			#SimulationControllerPROFILE
+		)
+	elseif (CROWN_RELEASE)
+		list (APPEND COMPILER_FLAGS
+			#-DNDEBUG
+			#-O2
+			#-Wno-unused-variable
+			#-Wno-unused-parameter
+			#-Wno-maybe-uninitialized
+			#-Wno-unused-but-set-variable
+			#-Wno-unused-function
+		)
+		list (APPEND CROWN_LIBRARIES
+			#LowLevel
+			#LowLevelCloth
+			PhysX3CharacterKinematic_${WIN_PHYSXARCH}
+			PhysX3_${WIN_PHYSXARCH}
+			PhysX3Common_${WIN_PHYSXARCH}
+			PhysX3Cooking_${WIN_PHYSXARCH}
+			PhysX3Extensions
+			PhysXProfileSDK
+			PhysXVisualDebuggerSDK
+			#PvdRuntime
+			PxTask
+			#SceneQuery
+			#SimulationController
+		)
+	else ()
+		message (FATAL_ERROR "Oops, you should not be here")
+	endif (CROWN_DEBUG)
 
 	set (CROWN_MAIN_SRC os/win/main.cpp)
 endif(WINDOWS)

+ 4 - 0
engine/ConsoleServer.cpp

@@ -36,6 +36,10 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "Filesystem.h"
 #include "MathUtils.h"
 
+#ifdef WINDOWS
+#undef NO_ERROR
+#endif
+
 namespace crown
 {
 

+ 5 - 0
engine/core/Log.cpp

@@ -28,6 +28,11 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "Device.h"
 #include "ConsoleServer.h"
 
+#ifdef WINDOWS
+#undef ERROR
+#define __va_copy(dest, src) (dest = src)
+#endif
+
 namespace crown
 {
 

+ 4 - 0
engine/core/Log.h

@@ -31,6 +31,10 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "Types.h"
 #include "Macros.h"
 
+#ifdef WINDOWS
+#undef ERROR
+#endif
+
 namespace crown
 {
 

+ 1 - 0
engine/core/Types.h

@@ -26,6 +26,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 
 #pragma once
 
+#define NOMINMAX
 #include <cstddef>
 #include <stdint.h>
 #include "Config.h"

+ 5 - 0
engine/core/bv/Frustum.h

@@ -31,6 +31,11 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "Vector3.h"
 #include "Plane.h"
 
+#ifdef WINDOWS
+#undef NEAR
+#undef FAR
+#endif
+
 namespace crown
 {
 

+ 2 - 2
engine/core/filesystem/NetworkFilesystem.cpp

@@ -63,13 +63,13 @@ void NetworkFilesystem::close(File* file)
 //-----------------------------------------------------------------------------
 bool NetworkFilesystem::is_directory(const char* path)
 {
-
+  return false;
 }
 
 //-----------------------------------------------------------------------------
 bool NetworkFilesystem::is_file(const char* path)
 {
-
+  return false;
 }
 
 //-----------------------------------------------------------------------------

+ 1 - 0
engine/os/OS.h

@@ -48,6 +48,7 @@ namespace crown
 
 	#undef MK_SHIFT
 	#undef MK_ALT
+	#undef ERROR
 
 #elif defined(ANDROID)
 	const size_t	MAX_PATH_LENGTH = 1024;

+ 2 - 0
engine/os/OsEventQueue.h

@@ -35,6 +35,8 @@ OTHER DEALINGS IN THE SOFTWARE.
 namespace crown
 {
 
+/// Single Producer Single Consumer event queue.
+/// Used only to pass events from os thread to main thread.
 struct OsEventQueue
 {
 	//-----------------------------------------------------------------------------

+ 320 - 134
engine/os/win/OsSocket.h

@@ -26,6 +26,14 @@ OTHER DEALINGS IN THE SOFTWARE.
 
 #pragma once
 
+//Undefined in Frustum.h, but winsock2 ecc need it.
+#ifndef NEAR
+#define NEAR
+#endif
+#ifndef FAR
+#define FAR
+#endif
+
 #include <winsock2.h>
 #include <windows.h>
 
@@ -35,25 +43,28 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "OS.h"
 
 #pragma comment(lib, "Ws2_32.lib")
+#undef NO_ERROR
 
 namespace crown
 {
 
-//-----------------------------------------------------------------------------
 struct ReadResult
 {
-	enum { NO_RESULT_ERROR, UNKNOWN, REMOTE_CLOSED } error;
-	size_t received_bytes;
+	enum { NO_ERROR, REMOTE_CLOSED, TIMEOUT, UNKNOWN } error;
+	size_t bytes_read;
 };
 
-//-----------------------------------------------------------------------------
 struct WriteResult
 {
-	enum { NO_RESULT_ERROR, UNKNOWN, REMOTE_CLOSED } error;
-	size_t sent_bytes;
+	enum { NO_ERROR, REMOTE_CLOSED, TIMEOUT, UNKNOWN } error;
+	size_t bytes_wrote;
+};
+
+struct AcceptResult
+{
+	enum { NO_ERROR, NO_CONNECTION, UNKNOWN } error;
 };
 
-//-----------------------------------------------------------------------------
 class TCPSocket
 {
 public:
@@ -72,17 +83,10 @@ public:
 	//-----------------------------------------------------------------------------
 	bool connect(const NetAddress& destination, uint16_t port)
 	{		
-		int sd = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+		m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 
-		if (sd <= 0)
-		{
-			os::printf("failed to open socket\n");
-			m_socket = 0;
-			return false;
-		}
+		CE_ASSERT(m_socket > 0, "Failed to create socket");
 		
-		m_socket = sd;
-
 		sockaddr_in address;
 		address.sin_family = AF_INET;
 		address.sin_addr.s_addr = ::htonl(destination.address());
@@ -90,7 +94,7 @@ public:
 
 		if (::connect(m_socket, (const sockaddr*)&address, sizeof(sockaddr_in)) < 0)
 		{
-			os::printf("failed to connect socket\n");
+			os::printf("Failed to connect socket\n");
 			close();
 			return false;
 		}
@@ -109,52 +113,176 @@ public:
 	}
 
 	//-----------------------------------------------------------------------------
-	ReadResult read(void* data, int32_t size)
+	ReadResult read_nonblock(void* data, size_t size)
 	{
-		CE_ASSERT_NOT_NULL(data);
-
-		int received_bytes = ::recv(m_socket, (char*)data, size, 0);
+		set_blocking(false);
+		int read_bytes = ::recv(m_socket, (char*) data, size, 0);
 
 		ReadResult result;
-
-		if (received_bytes < 0)
+		if (read_bytes == SOCKET_ERROR && (errno == WSAEWOULDBLOCK))
+		{
+			result.error = ReadResult::NO_ERROR;
+			result.bytes_read = 0;
+		}
+		else if (read_bytes == SOCKET_ERROR && errno == WSAETIMEDOUT)
+		{
+			result.error = ReadResult::TIMEOUT;
+		}
+		else if (read_bytes == SOCKET_ERROR)
 		{
-			result.error = ReadResult::NO_RESULT_ERROR;
-			result.received_bytes = 0;
+			result.error = ReadResult::UNKNOWN;
 		}
-		if (received_bytes == 0)
+		else if (read_bytes == 0)
 		{
 			result.error = ReadResult::REMOTE_CLOSED;
 		}
 		else
 		{
-			result.error = ReadResult::NO_RESULT_ERROR;
-			result.received_bytes = received_bytes;
+			result.error = ReadResult::NO_ERROR;
+			result.bytes_read = read_bytes;
 		}
 
-		return result;
+		return result;		
 	}
 
 	//-----------------------------------------------------------------------------
-	WriteResult write(const void* data, int32_t size)
+	ReadResult read(void* data, size_t size)
 	{
-		CE_ASSERT_NOT_NULL(data);
+		set_blocking(true);
 
-		int sent_bytes = ::send(m_socket, (const char*)data, size, 0);
+		// Ensure all data is read
+		char* buf = (char*) data;
+		size_t to_read = size;
+		ReadResult result;
+		result.bytes_read = 0;
+		result.error = ReadResult::NO_ERROR;
 
-		WriteResult result;
+		while (to_read > 0)
+		{
+			int read_bytes = recv(m_socket, buf, to_read, 0);
+			
+			if (read_bytes == SOCKET_ERROR && (errno == WSAEWOULDBLOCK)) continue;
+			else if (read_bytes == SOCKET_ERROR && errno == WSAETIMEDOUT)
+			{
+				result.error = ReadResult::TIMEOUT;
+				return result;
+			}
+			else if (read_bytes == 0)
+			{
+				result.error = ReadResult::REMOTE_CLOSED;
+				return result;
+			}
+
+			buf += read_bytes;
+			to_read -= read_bytes;
+			result.bytes_read += read_bytes;
+		}
+
+		result.error = ReadResult::NO_ERROR;
+		return result;
+	}
 
-		if (sent_bytes < 0)
+	//-----------------------------------------------------------------------------
+	WriteResult write_nonblock(const void* data, size_t size)
+	{
+		set_blocking(false);
+		int bytes_wrote = ::send(m_socket, (char*)data, size, 0);
+
+		WriteResult result;
+		if (bytes_wrote == SOCKET_ERROR && (errno == WSAEWOULDBLOCK))
 		{
-			result.error = WriteResult::UNKNOWN;
+			result.error = WriteResult::NO_ERROR;
+			result.bytes_wrote = 0;
+		}
+		else if (bytes_wrote == SOCKET_ERROR && errno == WSAETIMEDOUT)
+		{
+			result.error = WriteResult::TIMEOUT;
+		}
+		else if (bytes_wrote == 0)
+		{
+			result.error = WriteResult::REMOTE_CLOSED;
 		}
 		else
 		{
-			result.error = WriteResult::NO_RESULT_ERROR;
-			result.sent_bytes = sent_bytes;
+			result.error = WriteResult::UNKNOWN;
 		}
 
-		return result;  
+		return result;
+	}
+
+	//-----------------------------------------------------------------------------
+	WriteResult write(const void* data, size_t size)
+	{
+		set_blocking(true);
+
+		const char* buf = (const char*) data;
+		size_t to_send = size;
+		WriteResult result;
+		result.bytes_wrote = 0;
+		result.error = WriteResult::NO_ERROR;
+
+		// Ensure all data is sent
+		while (to_send > 0)
+		{
+			int bytes_wrote = ::send(m_socket, (const char*) buf, to_send, 0);
+
+			// Check for errors
+			if (bytes_wrote == SOCKET_ERROR)
+			{
+				switch (errno)
+				{
+					case WSAEWOULDBLOCK:
+					{
+						continue;
+					}
+					case WSAETIMEDOUT:
+					{
+						result.error = WriteResult::TIMEOUT;
+						return result;
+					}
+					default:
+					{
+						result.error = WriteResult::UNKNOWN;
+						return result;
+					}
+				}
+			}
+
+			buf += bytes_wrote;
+			to_send -= bytes_wrote;
+			result.bytes_wrote += bytes_wrote;
+		}
+
+		result.error = WriteResult::NO_ERROR;
+		return result;
+	}
+
+	//-----------------------------------------------------------------------------
+	void set_blocking(bool blocking)
+	{
+		//Warning! Blocking sockets under windows seem to have some drawback, see http://www.sockets.com/winsock.htm#IoctlSocket
+		u_long non_blocking = blocking ? 0 : 1;
+		ioctlsocket(m_socket, FIONBIO, &non_blocking);
+	}
+
+	//-----------------------------------------------------------------------------
+	void set_resuse_address(bool reuse)
+	{
+		int optval = (int) reuse;
+		setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, (char*)&optval, sizeof(optval));
+	}
+
+	//-----------------------------------------------------------------------------
+	void set_timeout(uint32_t seconds)
+	{
+		struct timeval timeout;
+		timeout.tv_sec = seconds;
+		timeout.tv_usec = 0;
+		int res;
+		res = setsockopt (m_socket, SOL_SOCKET, SO_RCVTIMEO, (char*) &timeout, sizeof(timeout));
+		CE_ASSERT(res == 0, "Failed to set timeout on socket: errno: %d", errno);
+		res = setsockopt (m_socket, SOL_SOCKET, SO_SNDTIMEO, (char*) &timeout, sizeof(timeout));
+		CE_ASSERT(res == 0, "Failed to set timeout on socket: errno: %d", errno);
 	}
 
 public:
@@ -162,88 +290,127 @@ public:
 	int m_socket;
 };
 
-//-----------------------------------------------------------------------------
-class TCPListener
+class TCPServer
 {
 public:
 
 	//-----------------------------------------------------------------------------
 	bool open(uint16_t port)
 	{
-		int& sock_id = m_listener.m_socket;
+		m_server.m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+		CE_ASSERT(m_server.m_socket > 0, "Failed to create socket");
 
-		sock_id = ::socket(AF_INET, SOCK_STREAM, 0);
-		CE_ASSERT(sock_id != INVALID_SOCKET, "Unable to open socket");
-
-		// set non-blocking io
-		DWORD non_blocking = 1;
-		int result = ::ioctlsocket(sock_id, FIONBIO, &non_blocking);
-		CE_ASSERT(result == 0, "Unable to set socket non-blocking");
+		m_server.set_resuse_address(true);
 
 		// Bind socket
 		sockaddr_in address;
 		address.sin_family = AF_INET;
-		address.sin_addr.s_addr = ::htonl(INADDR_ANY);
-		address.sin_port = ::htons(port);
+		address.sin_addr.s_addr = htonl(INADDR_ANY);
+		address.sin_port = htons(port);
 
-		result = ::bind(sock_id, (const sockaddr*)&address, sizeof(sockaddr_in));
-		CE_ASSERT(result == 0, "Unable to bind socket");
-		
-		result = ::listen(sock_id, 5);
-		CE_ASSERT(result == 0, "Unable to listen on socket");
+		int bind_ret = bind(m_server.m_socket, (const sockaddr*) &address, sizeof(sockaddr_in));
+		CE_ASSERT(bind_ret != -1, "Failed to bind socket: errno: %d", errno);
 
-		return true;  
+		return true;
 	}
 
 	//-----------------------------------------------------------------------------
 	void close()
 	{
-		m_listener.close();
+		m_server.close();
 	}
 
 	//-----------------------------------------------------------------------------
-	bool listen(TCPSocket& c)
+	void listen(uint32_t max)
 	{
-		int& sock_id = m_listener.m_socket;
+		int listen_ret = ::listen(m_server.m_socket, max);
+		CE_ASSERT(listen_ret != -1, "Failed to listen on socket: errno: %d", errno);
+	}
+
+	//-----------------------------------------------------------------------------
+	AcceptResult accept_nonblock(TCPSocket& c)
+	{
+		m_server.set_blocking(false);
 
 		sockaddr_in client;
-		int client_length = sizeof(client);
+		size_t client_size = sizeof(client);
+		int sock = ::accept(m_server.m_socket, (sockaddr*) &client, (int*) &client_size);
 
-		int asd = ::accept(sock_id, (sockaddr*)&client, &client_length);
-		if (asd < 0)
+		AcceptResult result;
+		if (sock == SOCKET_ERROR && (errno == WSAEWOULDBLOCK))
 		{
-			return false;
+			result.error = AcceptResult::NO_CONNECTION;
+		}
+		else if (sock == SOCKET_ERROR)
+		{
+			result.error = AcceptResult::UNKNOWN;
+		}
+		else
+		{
+			result.error = AcceptResult::NO_ERROR;
+			c.m_socket = sock;
 		}
 
-		DWORD non_blocking = 1;
-		int result = ::ioctlsocket(asd, FIONBIO, &non_blocking);
-		CE_ASSERT(result == 0, "Unable to set socket non-blocking");		
+		return result;
+	}
 
-		c.m_socket = asd;
+	//-----------------------------------------------------------------------------
+	AcceptResult accept(TCPSocket& c)
+	{
+		m_server.set_blocking(true);
 
-		return true;
+		sockaddr_in client;
+		size_t client_size = sizeof(client);
+
+		int sock = ::accept(m_server.m_socket, (sockaddr*) &client, (int*) &client_size);
+
+		AcceptResult result;
+		if (sock == SOCKET_ERROR)
+		{
+			result.error = AcceptResult::UNKNOWN;
+		}
+		else
+		{
+			result.error = AcceptResult::NO_ERROR;
+			c.m_socket = sock;
+		}
+
+		return result;
+	}
+
+	//-----------------------------------------------------------------------------
+	ReadResult read_nonblock(void* data, size_t size)
+	{
+		return m_server.read_nonblock(data, size);
 	}
 
 	//-----------------------------------------------------------------------------
 	ReadResult read(void* data, size_t size)
 	{
-		return m_listener.read(data, size);
+		return m_server.read(data, size);
+	}
+
+	//-----------------------------------------------------------------------------
+	WriteResult write_nonblock(void* data, size_t size)
+	{
+		return m_server.write_nonblock(data, size);
 	}
 
 	//-----------------------------------------------------------------------------
 	WriteResult write(const void* data, size_t size)
 	{
-		return m_listener.write(data, size);
+		return m_server.write(data, size);
 	}
 
 private:
 
-	TCPSocket m_listener;
+	TCPSocket m_server;
 };
 
-//-----------------------------------------------------------------------------
 class UDPSocket
 {
+public:
+
 	//-----------------------------------------------------------------------------
 	UDPSocket()
 		: m_socket(0)
@@ -253,59 +420,89 @@ class UDPSocket
 	//-----------------------------------------------------------------------------
 	bool open(uint16_t port)
 	{
-		// CE_ASSERT(!is_open(), "Socket is already open");
+		CE_ASSERT(!is_open(), "Socket is already open");
 
-		// m_socket = ::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
-		// CE_ASSERT(m_socket != INVALID_SOCKET, "Unable to open socket");
+		m_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
 
-		// // bind to port
-		// sockaddr_in address;
-		// address.sin_family = AF_INET;
-		// address.sin_addr.s_addr = INADDR_ANY;
-		// address.sin_port = ::htons(port);
+		if (m_socket <= 0)
+		{
+			os::printf("Failed to create socket.\n");
+			m_socket = 0;
 
-		// int result = ::bind(m_socket, (const sockaddr*)&address, sizeof(sockaddr_in));
-		// CE_ASSERT(result == 0, "Unable to bind socket");
+			return false;
+		}
 
-		// // set non-blocking io
-		// DWORD non_blocking = 1;
-		// result = ::ioctlsocket(m_socket, FIONBIO, &non_blocking);
-		// CE_ASSERT(result == 0, "Unable to bind socket");
+		// Bind to port
+		sockaddr_in address;
+		address.sin_family = AF_INET;
+		address.sin_addr.s_addr = INADDR_ANY;
+		address.sin_port = htons(port);
+
+		if (bind(m_socket, (const sockaddr*) &address, sizeof(sockaddr_in)) < 0)
+		{
+			os::printf("Failed to bind socket\n");
+			close();
+
+			return false;
+		}
+
+		//Warning! Blocking sockets under windows seem to have some drawback, see http://www.sockets.com/winsock.htm#IoctlSocket
+		u_long non_blocking = 1;
+		//if (fcntl(m_socket, F_SETFL, O_NONBLOCK, 1) == -1)
+		if (ioctlsocket(m_socket, FIONBIO, &non_blocking) == SOCKET_ERROR)
+		{
+			os::printf("Failed to set non-blocking socket\n");
+			close();
 
+			return false;
+		}
+		
 		return true;
 	}
 
 	//-----------------------------------------------------------------------------
-	ReadResult read(NetAddress& sender, uint16_t& port, const void* data, size_t size)
+	void close()
 	{
-		// CE_ASSERT_NOT_NULL(data);
+		if (m_socket != 0)
+		{
+			::closesocket(m_socket);
+			m_socket = 0;
+		}
+	}
 
-		// typedef int socklen_t;
+	//-----------------------------------------------------------------------------
+	ReadResult read(NetAddress& sender, uint16_t& port, const void* data, size_t size)
+	{
+		CE_ASSERT_NOT_NULL(data);
 
-		// sockaddr_in from;
-		// socklen_t from_length = sizeof(from);
+		sockaddr_in from;
+		int from_length = sizeof(from);
 
-		// int received_bytes = ::recvfrom(m_socket, (char*)data, size, 0, (sockaddr*)&from, &from_length);
+		int received_bytes = recvfrom(m_socket, (char*)data, size, 0, (sockaddr*)&from, &from_length);
 
 		ReadResult result;
 
-		// if (received_bytes < 0)
-		// {
-		// 	result.error = ReadResult::NO_RESULT_ERROR;
-		// 	result.received_bytes = 0;
-		// }
-		// else if (received_bytes == 0)
-		// {
-		// 	result.error = ReadResult::REMOTE_CLOSED;
-		// }
-		// else
-		// {
-		// 	result.error = ReadResult::NO_RESULT_ERROR;
-		// 	result.received_bytes = received_bytes;
-		// }
-
-		// sender.set(::ntohl(from.sin_addr.s_addr));
-		// port = ::ntohs(from.sin_port);
+		if (received_bytes == SOCKET_ERROR && errno == WSAEWOULDBLOCK)
+		{
+			result.error = ReadResult::NO_ERROR;
+			result.bytes_read = 0;
+		}
+		else if (received_bytes == SOCKET_ERROR)
+		{
+			result.error = ReadResult::UNKNOWN;
+		}
+		else if (received_bytes == 0)
+		{
+			result.error = ReadResult::REMOTE_CLOSED;
+		}
+		else
+		{
+			result.error = ReadResult::NO_ERROR;
+			result.bytes_read = received_bytes;
+		}
+
+		sender.set(ntohl(from.sin_addr.s_addr));
+		port = ntohs(from.sin_port);
 
 		return result;
 	}
@@ -313,43 +510,32 @@ class UDPSocket
 	//-----------------------------------------------------------------------------
 	WriteResult write(const NetAddress& receiver, uint16_t port, void* data, size_t size)
 	{
-		// CE_ASSERT_NOT_NULL(data);
+		CE_ASSERT_NOT_NULL(data);
 
-		// sockaddr_in address;
-		// address.sin_family = AF_INET;
-		// address.sin_addr.s_addr = htonl(receiver.address());
-		// address.sin_port = htons(port);
+		sockaddr_in address;
+		address.sin_family = AF_INET;
+		address.sin_addr.s_addr = htonl(receiver.address());
+		address.sin_port = htons(port);
 
-		// int sent_bytes = sendto(m_socket, (const char*)data, size, 0, (sockaddr*)&address, sizeof(sockaddr_in));
+		int bytes_wrote = sendto(m_socket, (const char*) data, size, 0, (sockaddr*) &address, sizeof(sockaddr_in));
 
 		WriteResult result;
 
-		// if (sent_bytes < 0)
-		// {
-		// 	result.error = WriteResult::UNKNOWN;
-		// 	return result;
-		// }
-
-		// result.error = WriteResult::NO_RESULT_ERROR;
-		// result.sent_bytes = sent_bytes;
+		if (bytes_wrote == SOCKET_ERROR)
+		{
+			result.error = WriteResult::UNKNOWN;
+			return result;
+		}
 
+		result.error = WriteResult::NO_ERROR;
+		result.bytes_wrote = bytes_wrote;
 		return result;
 	}
 
-	//-----------------------------------------------------------------------------
-	void close()
-	{
-		// if (m_socket != 0)
-		// {
-		// 	::closesocket(m_socket);
-		// 	m_socket = 0;
-		// }
-	}
-
 	//-----------------------------------------------------------------------------
 	bool is_open()
 	{
-		return m_socket != 0; 
+		return m_socket != 0;
 	}
 
 public:

+ 1 - 0
engine/os/win/OsWindow.h

@@ -33,6 +33,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include <windows.h>
 
 #include "Types.h"
+#include "Macros.h"
 
 namespace crown
 {

+ 1 - 0
engine/renderers/backend/gl/wgl/GLContext.h

@@ -29,6 +29,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "wglext.h"
 
 #include "Types.h"
+#include "Macros.h"
 
 namespace crown
 {

+ 1 - 1
engine/resource/PhysicsResource.cpp

@@ -491,7 +491,7 @@ namespace physics_config_resource
 			pa2.flags = 0;
 			if (!dynamic.is_nil())
 			{
-				pa2.flags |= dynamic.to_bool() ? : 0;
+				pa2.flags |= dynamic.to_bool() ? 1 : 0;
 			}
 			if (!kinematic.is_nil())
 			{

+ 1 - 1
engine/world/Unit.h

@@ -63,7 +63,6 @@ struct Component
 };
 
 
-class Material;
 class SceneGraphManager;
 class World;
 struct Actor;
@@ -71,6 +70,7 @@ struct Camera;
 struct Controller;
 struct Mesh;
 struct Sprite;
+struct Material;
 struct UnitResource;
 
 struct Unit

+ 2 - 1
engine/world/World.cpp

@@ -196,7 +196,7 @@ void World::destroy_camera(CameraId id)
 //-----------------------------------------------------------------------------
 SoundInstanceId World::play_sound(const char* name, const bool loop, const float volume, const Vector3& pos, const float range)
 {
-	m_sound_world->play(name, loop, volume, pos);
+	return m_sound_world->play(name, loop, volume, pos);
 }
 
 //-----------------------------------------------------------------------------
@@ -245,6 +245,7 @@ GuiId World::create_window_gui(const char* name)
 GuiId World::create_world_gui(const Matrix4x4 pose, const uint32_t width, const uint32_t height)
 {
 	// Must be implemented
+	return GuiId();
 }
 
 //-----------------------------------------------------------------------------