mikymod %!s(int64=12) %!d(string=hai) anos
pai
achega
1a6acecd57
Modificáronse 3 ficheiros con 287 adicións e 116 borrados
  1. 231 66
      engine/os/win/main.cpp
  2. 21 21
      engine/tests/CMakeLists.txt
  3. 35 29
      engine/tests/events.cpp

+ 231 - 66
engine/os/win/main.cpp

@@ -31,6 +31,9 @@ OTHER DEALINGS IN THE SOFTWARE.
 #define WM_USER_MOUSE_LOCK          (WM_USER+2)
 
 #include "Crown.h"
+#include "OsTypes.h"
+#include "EventQueue.h"
+#include "BundleCompiler.h"
 
 #define ENTRY_DEFAULT_WIDTH 1024
 #define ENTRY_DEFAULT_HEIGHT 768
@@ -54,59 +57,59 @@ void shutdown()
 }
 
 //-----------------------------------------------------------------------------
-static Key translate_key(int32_t winKey)
+static KeyboardButton::Enum translate_key(int32_t winKey)
 {
 	if ((winKey > 0x40 && winKey < 0x5B) || (winKey > 0x60 && winKey < 0x7B) || (winKey > 0x2F && winKey < 0x3A))
 	{
-		return (Key)winKey;
+		return (KeyboardButton::Enum)winKey;
 	}
 
 	switch (winKey)
 	{
-		case VK_BACK:		return KC_BACKSPACE;
-		case VK_TAB:		return KC_TAB;
-		case VK_SPACE:		return KC_SPACE;
-		case VK_ESCAPE:		return KC_ESCAPE;
-		case VK_RETURN:		return KC_ENTER;
-		case VK_F1:			return KC_F1;
-		case VK_F2:			return KC_F2;
-		case VK_F3:			return KC_F3;
-		case VK_F4:			return KC_F4;
-		case VK_F5:			return KC_F5;
-		case VK_F6:			return KC_F6;
-		case VK_F7:			return KC_F7;
-		case VK_F8:			return KC_F8;
-		case VK_F9:			return KC_F9;
-		case VK_F10:		return KC_F10;
-		case VK_F11:		return KC_F11;
-		case VK_F12:		return KC_F12;
-		case VK_HOME:		return KC_HOME;
-		case VK_LEFT:		return KC_LEFT;
-		case VK_UP:			return KC_UP;
-		case VK_RIGHT:		return KC_RIGHT;
-		case VK_DOWN:		return KC_DOWN;
-		case VK_PRIOR:		return KC_PAGE_UP;
-		case VK_NEXT:		return KC_PAGE_DOWN;
-		case VK_LSHIFT:		return KC_LSHIFT;
-		case VK_RSHIFT:		return KC_RSHIFT;
-		case VK_LCONTROL:	return KC_LCONTROL;
-		case VK_RCONTROL:	return KC_RCONTROL;
-		case VK_CAPITAL:	return KC_CAPS_LOCK;
-		case VK_LMENU:		return KC_LALT;
-		case VK_RMENU:		return KC_RALT;
-		case VK_LWIN:		return KC_LSUPER;
-		case VK_RWIN:		return KC_RSUPER;
-		case VK_NUMPAD0:	return KC_KP_0;
-		case VK_NUMPAD1:	return KC_KP_1;
-		case VK_NUMPAD2:	return KC_KP_2;
-		case VK_NUMPAD3:	return KC_KP_3;
-		case VK_NUMPAD4:	return KC_KP_4;
-		case VK_NUMPAD5:	return KC_KP_5;
-		case VK_NUMPAD6:	return KC_KP_6;
-		case VK_NUMPAD7:	return KC_KP_7;
-		case VK_NUMPAD8:	return KC_KP_8;
-		case VK_NUMPAD9:	return KC_KP_9;
-		default:			return KC_NOKEY;
+		case VK_BACK:		return KeyboardButton::BACKSPACE;
+		case VK_TAB:		return KeyboardButton::TAB;
+		case VK_SPACE:		return KeyboardButton::SPACE;
+		case VK_ESCAPE:		return KeyboardButton::ESCAPE;
+		case VK_RETURN:		return KeyboardButton::ENTER;
+		case VK_F1:			return KeyboardButton::F1;
+		case VK_F2:			return KeyboardButton::F2;
+		case VK_F3:			return KeyboardButton::F3;
+		case VK_F4:			return KeyboardButton::F4;
+		case VK_F5:			return KeyboardButton::F5;
+		case VK_F6:			return KeyboardButton::F6;
+		case VK_F7:			return KeyboardButton::F7;
+		case VK_F8:			return KeyboardButton::F8;
+		case VK_F9:			return KeyboardButton::F9;
+		case VK_F10:		return KeyboardButton::F10;
+		case VK_F11:		return KeyboardButton::F11;
+		case VK_F12:		return KeyboardButton::F12;
+		case VK_HOME:		return KeyboardButton::HOME;
+		case VK_LEFT:		return KeyboardButton::LEFT;
+		case VK_UP:			return KeyboardButton::UP;
+		case VK_RIGHT:		return KeyboardButton::RIGHT;
+		case VK_DOWN:		return KeyboardButton::DOWN;
+		case VK_PRIOR:		return KeyboardButton::PAGE_UP;
+		case VK_NEXT:		return KeyboardButton::PAGE_DOWN;
+		case VK_LSHIFT:		return KeyboardButton::LSHIFT;
+		case VK_RSHIFT:		return KeyboardButton::RSHIFT;
+		case VK_LCONTROL:	return KeyboardButton::LCONTROL;
+		case VK_RCONTROL:	return KeyboardButton::RCONTROL;
+		case VK_CAPITAL:	return KeyboardButton::CAPS_LOCK;
+		case VK_LMENU:		return KeyboardButton::LALT;
+		case VK_RMENU:		return KeyboardButton::RALT;
+		case VK_LWIN:		return KeyboardButton::LSUPER;
+		case VK_RWIN:		return KeyboardButton::RSUPER;
+		case VK_NUMPAD0:	return KeyboardButton::KP_0;
+		case VK_NUMPAD1:	return KeyboardButton::KP_1;
+		case VK_NUMPAD2:	return KeyboardButton::KP_2;
+		case VK_NUMPAD3:	return KeyboardButton::KP_3;
+		case VK_NUMPAD4:	return KeyboardButton::KP_4;
+		case VK_NUMPAD5:	return KeyboardButton::KP_5;
+		case VK_NUMPAD6:	return KeyboardButton::KP_6;
+		case VK_NUMPAD7:	return KeyboardButton::KP_7;
+		case VK_NUMPAD8:	return KeyboardButton::KP_8;
+		case VK_NUMPAD9:	return KeyboardButton::KP_9;
+		default:			return KeyboardButton::NONE;
 	}
 }
 
@@ -132,9 +135,37 @@ public:
 		, m_mouse_lock(false)
 		, m_started(false)
 		, m_exit(false)
+		, m_alloc(m_event_buffer, 1024 * 4)
+		, m_queue(m_alloc)
 	{
 	}
 
+	//-----------------------------------------------------------------------------
+	void init(int argc, char** argv)
+	{
+		parse_command_line(argc, argv);
+		check_preferred_settings();
+
+		#if defined(CROWN_DEBUG) || defined(CROWN_DEVELOPMENT)
+			if (m_compile == 1)
+			{
+				m_bundle_compiler = CE_NEW(default_allocator(), BundleCompiler);
+				if (!m_bundle_compiler->compile(m_bundle_dir, m_source_dir))
+				{
+					CE_DELETE(default_allocator(), m_bundle_compiler);
+					Log::e("Exiting.");
+					exit(EXIT_FAILURE);
+				}
+
+				if (!m_continue)
+				{
+					CE_DELETE(default_allocator(), m_bundle_compiler);
+					exit(EXIT_SUCCESS);
+				}
+			}
+		#endif
+	}
+
 	//-----------------------------------------------------------------------------
 	int32_t	run(int argc, char** argv)
 	{
@@ -181,7 +212,7 @@ public:
 		m_argv = argv;
 
 		OsThread thread("game-loop");
-		thread.start(WindowsDevice::thread_proc, this);
+		thread.start(WindowsDevice::main_loop, this);
 		m_started = true;
 
 //		m_eventQueue.postSizeEvent(m_width, m_height);
@@ -208,6 +239,23 @@ public:
 		return 0;
 	}
 
+	//-----------------------------------------------------------------------------
+	int32_t loop()
+	{
+		Device::init();
+
+		while(is_running())
+		{
+			Device::frame();
+		}
+
+		Device::shutdown();
+
+		m_exit = true;
+
+		return 0;
+	}
+
 	//-----------------------------------------------------------------------------
 	void adjust(uint32_t width, uint32_t height, bool window_frame)
 	{
@@ -327,23 +375,9 @@ public:
 
 public:
 	
-	static int32_t thread_proc(void* data)
+	static int32_t main_loop(void* data)
 	{
-		WindowsDevice* engine = (WindowsDevice*)data;
-
-		if (!engine->init(engine->m_argc, engine->m_argv))
-		{
-			exit(-1);
-		}
-
-		while (engine->is_running())
-		{
-			engine->frame();
-		}
-
-		engine->shutdown();
-
-		return 0;
+		return ((WindowsDevice*)data)->loop();
 	}
 
 	LRESULT process(HWND hwnd, UINT id, WPARAM wparam, LPARAM lparam)
@@ -515,7 +549,7 @@ public:
 			case WM_KEYUP:
 			case WM_SYSKEYUP:
 			{
-				Key key = translate_key(wparam);
+				KeyboardButton::Enum key = translate_key(wparam);
 				uint8_t modifiers = 0;
 				// m_eventQueue.postKeyEvent(key, modifiers, id == WM_KEYDOWN || id == WM_SYSKEYDOWN);
 				Log::i("Key! '%d'", key);
@@ -529,6 +563,126 @@ public:
 		return DefWindowProc(hwnd, id, wparam, lparam);
 	}
 
+	void parse_command_line(int argc, char** argv)
+	{
+		static const char* help_message =
+			"Usage: crown [options]\n"
+			"Options:\n\n"
+
+			"All of the following options take precedence over\n"
+			"environment variables and configuration files.\n\n"
+
+			"  --help                     Show this help.\n"
+			"  --bundle-dir <path>        Use <path> as the source directory for compiled resources.\n"
+			"  --width <width>            Set the <width> of the main window.\n"
+			"  --height <width>           Set the <height> of the main window.\n"
+			"  --fullscreen               Start in fullscreen.\n"
+			"  --parent-window <handle>   Set the parent window <handle> of the main window.\n"
+			"                             Used only by tools.\n"
+
+			"\nAvailable only in debug and development builds:\n\n"
+
+			"  --source-dir <path>        Use <path> as the source directory for resource compilation.\n"
+			"  --compile                  Run the engine as resource compiler.\n"
+			"  --continue                 Do a full compile of the resources and continue the execution.\n";
+
+		static ArgsOption options[] = 
+		{
+			{ "help",             AOA_NO_ARGUMENT,       NULL,        'i' },
+			{ "source-dir",       AOA_REQUIRED_ARGUMENT, NULL,        's' },
+			{ "bundle-dir",       AOA_REQUIRED_ARGUMENT, NULL,        'b' },
+			{ "compile",          AOA_NO_ARGUMENT,       &m_compile,   1 },
+			{ "continue",         AOA_NO_ARGUMENT,       &m_continue,  1 },
+			{ "width",            AOA_REQUIRED_ARGUMENT, NULL,        'w' },
+			{ "height",           AOA_REQUIRED_ARGUMENT, NULL,        'h' },
+			{ "fullscreen",       AOA_NO_ARGUMENT,       &m_fullscreen, 1 },
+			{ "parent-window",    AOA_REQUIRED_ARGUMENT, NULL,        'p' },
+			{ NULL, 0, NULL, 0 }
+		};
+
+		Args args(argc, argv, "", options);
+
+		int32_t opt;
+		while ((opt = args.getopt()) != -1)
+		{
+			switch (opt)
+			{
+				case 0:
+				{
+					break;
+				}
+				// Source directory
+				case 's':
+				{
+					string::strncpy(m_source_dir, args.optarg(), MAX_PATH_LENGTH);
+					break;
+				}
+				// Bundle directory
+				case 'b':
+				{
+					string::strncpy(m_bundle_dir, args.optarg(), MAX_PATH_LENGTH);
+					break;
+				}
+				// Window width
+				case 'w':
+				{
+					m_width = atoi(args.optarg());
+					break;
+				}
+				// Window height
+				case 'h':
+				{
+					m_height = atoi(args.optarg());
+					break;
+				}
+				// Parent window
+				case 'p':
+				{
+					m_parent_window_handle = string::parse_uint(args.optarg());
+					break;
+				}
+				case 'i':
+				case '?':
+				default:
+				{
+					os::printf(help_message);
+					exit(EXIT_FAILURE);
+				}
+			}
+		}
+	}
+
+	//-----------------------------------------------------------------------------
+	void check_preferred_settings()
+	{
+		if (m_compile == 1)
+		{
+			if (string::strcmp(m_source_dir, "") == 0)
+			{
+				Log::e("You have to specify the source directory when running in compile mode.");
+				exit(EXIT_FAILURE);
+			}
+
+			if (!os::is_absolute_path(m_source_dir))
+			{
+				Log::e("The source directory must be absolute.");
+				exit(EXIT_FAILURE);
+			}
+		}
+
+		if (!os::is_absolute_path(m_bundle_dir))
+		{
+			Log::e("The bundle directory must be absolute.");
+			exit(EXIT_FAILURE);
+		}
+
+		if (m_width == 0 || m_height == 0)
+		{
+			Log::e("Window width and height must be greater than zero.");
+			exit(EXIT_FAILURE);
+		}
+	}
+
 private:
 
 	static LRESULT CALLBACK window_proc(HWND hwnd, UINT id, WPARAM wparam, LPARAM lparam);
@@ -554,6 +708,15 @@ public:
 
 	int32_t m_argc;
 	char**	m_argv;
+
+	uint32_t m_parent_window_handle;
+	int32_t m_fullscreen;
+	int32_t m_compile;
+	int32_t m_continue;	
+
+	char m_event_buffer[1024 * 4];
+	LinearAllocator m_alloc;
+	EventQueue m_queue;
 };
 
 WindowsDevice* engine;
@@ -574,9 +737,11 @@ int main(int argc, char** argv)
 	engine = CE_NEW(default_allocator(), WindowsDevice)();
 	set_device(crown::engine);
 	
-	((WindowsDevice*)engine)->run(argc, argv);
+	int32_t ret = ((WindowsDevice*)engine)->run(argc, argv);
+
+	CE_DELETE(default_allocator(), engine);
 
 	shutdown();
 
-	return 0;
+	return ret;
 }

+ 21 - 21
engine/tests/CMakeLists.txt

@@ -2,30 +2,30 @@ cmake_minimum_required(VERSION 2.8)
 
 project(crown-tests)
 
-add_executable(allocators allocators.cpp)
-add_executable(containers containers.cpp)
-add_executable(compressors compressors.cpp)
-add_executable(strings strings.cpp)
-add_executable(paths paths.cpp)
-add_executable(dynamic-strings dynamic-strings.cpp)
-add_executable(json json.cpp)
+#add_executable(allocators allocators.cpp)
+#add_executable(containers containers.cpp)
+#add_executable(compressors compressors.cpp)
+#add_executable(strings strings.cpp)
+#add_executable(paths paths.cpp)
+#add_executable(dynamic-strings dynamic-strings.cpp)
+#add_executable(json json.cpp)
 add_executable(events events.cpp)
 
-target_link_libraries(allocators crown)
-target_link_libraries(containers crown)
-target_link_libraries(compressors crown)
-target_link_libraries(strings crown)
-target_link_libraries(paths crown)
-target_link_libraries(dynamic-strings crown)
-target_link_libraries(json crown)
+#target_link_libraries(allocators crown)
+#target_link_libraries(containers crown)
+#target_link_libraries(compressors crown)
+#target_link_libraries(strings crown)
+#target_link_libraries(paths crown)
+#target_link_libraries(dynamic-strings crown)
+#target_link_libraries(json crown)
 target_link_libraries(events crown)
 
-install (TARGETS allocators DESTINATION test)
-install (TARGETS containers DESTINATION test)
-install (TARGETS compressors DESTINATION test)
-install (TARGETS strings DESTINATION test)
-install (TARGETS paths DESTINATION test)
-install (TARGETS dynamic-strings DESTINATION test)
-install (TARGETS json DESTINATION test)
+#install (TARGETS allocators DESTINATION test)
+#install (TARGETS containers DESTINATION test)
+#install (TARGETS compressors DESTINATION test)
+#install (TARGETS strings DESTINATION test)
+#install (TARGETS paths DESTINATION test)
+#install (TARGETS dynamic-strings DESTINATION test)
+#install (TARGETS json DESTINATION test)
 install (TARGETS events DESTINATION test)
 

+ 35 - 29
engine/tests/events.cpp

@@ -10,67 +10,69 @@
 
 using namespace crown;
 
-EventBuffer* g_buffer_1;
-EventBuffer* g_buffer_2;
-EventBuffer* g_tmp;
+EventBuffer* g_write;
+EventBuffer* g_read;
 
 OsThread g_thread("consumer-thread");
-Semaphore g_process_sem;
-Semaphore g_thread_sem;
+Semaphore g_write_sem;
+Semaphore g_read_sem;
 
 bool g_exit = false;
 
 //-----------------------------------------------------------------------------
-void push_event()
+void push_event(int32_t x, int32_t y)
 {
-	uint32_t x = (rand() % 100) + 1;
-	uint32_t y = (rand() % 100) + 1;
-
 	OsMouseEvent ome;
 	ome.button = MouseButton::LEFT;
 	ome.x = x;
 	ome.y = y;
 	ome.pressed = true;
 
-	g_buffer_1->push_event((uint32_t)OsEvent::MOUSE, &ome, sizeof(OsMouseEvent));
+	g_write->push_event((uint32_t)OsEvent::MOUSE, &ome, sizeof(OsMouseEvent));
 	Log::i("Event pushed");
 }
 
 //-----------------------------------------------------------------------------
 void swap()
 {
-	g_tmp = g_buffer_1;
-	g_buffer_1 = g_buffer_2;
-	g_buffer_2 = g_tmp;
+	EventBuffer* tmp;
+
+	tmp = g_write;
+	g_write = g_read;
+	g_read = tmp;
+
 	Log::i("Buffers swapped");
 }
 
 //-----------------------------------------------------------------------------
 int32_t thread_proc(void* /*user_data*/)
 {
+	static uint32_t count = 0;
+
 	OsMouseEvent* result;
 	uint32_t et; size_t es;
 
 	while (true)
 	{
-		while (!g_buffer_1->is_empty())
+		Log::i("%p", g_read);
+		
+		do
 		{
-			result = (OsMouseEvent*)g_buffer_1->get_next_event(et, es);
+			result = (OsMouseEvent*)g_read->get_next_event(et, es);
 
 			if (result != NULL)
 			{
 				Log::d("x: %d, y: %d", result->x, result->y);
 			}
-			else
-			{
-				g_buffer_1->clear();
+		}
+		while (result != NULL);
 
-				swap();
+		g_exit = ++count == 3 ? true : false;
 
-				g_process_sem.post();
-				g_thread_sem.wait();
-			}
-		}
+		g_read->clear();
+
+		g_write_sem.post();
+		g_read_sem.wait();
 	}
 
 	return 0;
@@ -80,19 +82,23 @@ int32_t thread_proc(void* /*user_data*/)
 int main()
 {
 	memory::init();
-	srand(time(NULL));
 
-	g_buffer_1 = CE_NEW(default_allocator(), EventBuffer);
-	g_buffer_2 = CE_NEW(default_allocator(), EventBuffer);
+	g_write = CE_NEW(default_allocator(), EventBuffer);
+	g_read = CE_NEW(default_allocator(), EventBuffer);
 
 	g_thread.start(thread_proc);
 
 	while (!g_exit)
 	{
-		push_event();
+		g_write_sem.wait();
+
+		push_event(10, 10);
+		push_event(20, 20);
+		push_event(30, 30);
+
+		swap();
 
-		g_thread_sem.post();
-		g_process_sem.wait();
+		g_read_sem.post();
 	}
 
 	g_thread.stop();