os_winrt.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672
  1. /*************************************************************************/
  2. /* os_winrt.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* http://www.godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
  9. /* */
  10. /* Permission is hereby granted, free of charge, to any person obtaining */
  11. /* a copy of this software and associated documentation files (the */
  12. /* "Software"), to deal in the Software without restriction, including */
  13. /* without limitation the rights to use, copy, modify, merge, publish, */
  14. /* distribute, sublicense, and/or sell copies of the Software, and to */
  15. /* permit persons to whom the Software is furnished to do so, subject to */
  16. /* the following conditions: */
  17. /* */
  18. /* The above copyright notice and this permission notice shall be */
  19. /* included in all copies or substantial portions of the Software. */
  20. /* */
  21. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  22. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  23. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
  24. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  25. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  26. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  27. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  28. /*************************************************************************/
  29. #include "drivers/gles2/rasterizer_gles2.h"
  30. #include "os_winrt.h"
  31. #include "drivers/nedmalloc/memory_pool_static_nedmalloc.h"
  32. #include "drivers/unix/memory_pool_static_malloc.h"
  33. #include "os/memory_pool_dynamic_static.h"
  34. #include "thread_winrt.h"
  35. //#include "drivers/windows/semaphore_windows.h"
  36. #include "drivers/windows/mutex_windows.h"
  37. #include "main/main.h"
  38. #include "drivers/windows/file_access_windows.h"
  39. #include "drivers/windows/dir_access_windows.h"
  40. #include "servers/visual/visual_server_raster.h"
  41. #include "servers/audio/audio_server_sw.h"
  42. #include "servers/visual/visual_server_wrap_mt.h"
  43. #include "os/pc_joystick_map.h"
  44. #include "os/memory_pool_dynamic_prealloc.h"
  45. #include "globals.h"
  46. #include "io/marshalls.h"
  47. #include <wrl.h>
  48. using namespace Windows::ApplicationModel::Core;
  49. using namespace Windows::ApplicationModel::Activation;
  50. using namespace Windows::UI::Core;
  51. using namespace Windows::UI::Input;
  52. using namespace Windows::Foundation;
  53. using namespace Windows::Graphics::Display;
  54. using namespace Microsoft::WRL;
  55. int OSWinrt::get_video_driver_count() const {
  56. return 1;
  57. }
  58. const char * OSWinrt::get_video_driver_name(int p_driver) const {
  59. return "GLES2";
  60. }
  61. OS::VideoMode OSWinrt::get_default_video_mode() const {
  62. return video_mode;
  63. }
  64. int OSWinrt::get_audio_driver_count() const {
  65. return AudioDriverManagerSW::get_driver_count();
  66. }
  67. const char * OSWinrt::get_audio_driver_name(int p_driver) const {
  68. AudioDriverSW* driver = AudioDriverManagerSW::get_driver(p_driver);
  69. ERR_FAIL_COND_V( !driver, "" );
  70. return AudioDriverManagerSW::get_driver(p_driver)->get_name();
  71. }
  72. static MemoryPoolStatic *mempool_static=NULL;
  73. static MemoryPoolDynamic *mempool_dynamic=NULL;
  74. void OSWinrt::initialize_core() {
  75. last_button_state=0;
  76. //RedirectIOToConsole();
  77. ThreadWinrt::make_default();
  78. //SemaphoreWindows::make_default();
  79. MutexWindows::make_default();
  80. FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_RESOURCES);
  81. FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_USERDATA);
  82. FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_FILESYSTEM);
  83. //FileAccessBufferedFA<FileAccessWindows>::make_default();
  84. DirAccess::make_default<DirAccessWindows>(DirAccess::ACCESS_RESOURCES);
  85. DirAccess::make_default<DirAccessWindows>(DirAccess::ACCESS_USERDATA);
  86. DirAccess::make_default<DirAccessWindows>(DirAccess::ACCESS_FILESYSTEM);
  87. //TCPServerWinsock::make_default();
  88. //StreamPeerWinsock::make_default();
  89. mempool_static = new MemoryPoolStaticMalloc;
  90. #if 1
  91. mempool_dynamic = memnew( MemoryPoolDynamicStatic );
  92. #else
  93. #define DYNPOOL_SIZE 4*1024*1024
  94. void * buffer = malloc( DYNPOOL_SIZE );
  95. mempool_dynamic = memnew( MemoryPoolDynamicPrealloc(buffer,DYNPOOL_SIZE) );
  96. #endif
  97. // We need to know how often the clock is updated
  98. if( !QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second) )
  99. ticks_per_second = 1000;
  100. // If timeAtGameStart is 0 then we get the time since
  101. // the start of the computer when we call GetGameTime()
  102. ticks_start = 0;
  103. ticks_start = get_ticks_usec();
  104. cursor_shape=CURSOR_ARROW;
  105. }
  106. bool OSWinrt::can_draw() const {
  107. return !minimized;
  108. };
  109. void OSWinrt::set_gl_context(ContextEGL* p_context) {
  110. gl_context = p_context;
  111. };
  112. void OSWinrt::screen_size_changed() {
  113. gl_context->reset();
  114. };
  115. void OSWinrt::initialize(const VideoMode& p_desired,int p_video_driver,int p_audio_driver) {
  116. main_loop=NULL;
  117. outside=true;
  118. gl_context->initialize();
  119. VideoMode vm;
  120. vm.width = gl_context->get_window_width();
  121. vm.height = gl_context->get_window_height();
  122. vm.fullscreen = true;
  123. vm.resizable = false;
  124. set_video_mode(vm);
  125. gl_context->make_current();
  126. rasterizer = memnew( RasterizerGLES2 );
  127. visual_server = memnew( VisualServerRaster(rasterizer) );
  128. if (get_render_thread_mode()!=RENDER_THREAD_UNSAFE) {
  129. visual_server =memnew(VisualServerWrapMT(visual_server,get_render_thread_mode()==RENDER_SEPARATE_THREAD));
  130. }
  131. //
  132. physics_server = memnew( PhysicsServerSW );
  133. physics_server->init();
  134. physics_2d_server = memnew( Physics2DServerSW );
  135. physics_2d_server->init();
  136. visual_server->init();
  137. input = memnew( InputDefault );
  138. AudioDriverManagerSW::get_driver(p_audio_driver)->set_singleton();
  139. if (AudioDriverManagerSW::get_driver(p_audio_driver)->init()!=OK) {
  140. ERR_PRINT("Initializing audio failed.");
  141. }
  142. sample_manager = memnew( SampleManagerMallocSW );
  143. audio_server = memnew( AudioServerSW(sample_manager) );
  144. audio_server->init();
  145. spatial_sound_server = memnew( SpatialSoundServerSW );
  146. spatial_sound_server->init();
  147. spatial_sound_2d_server = memnew( SpatialSound2DServerSW );
  148. spatial_sound_2d_server->init();
  149. _ensure_data_dir();
  150. }
  151. void OSWinrt::set_clipboard(const String& p_text) {
  152. /*
  153. if (!OpenClipboard(hWnd)) {
  154. ERR_EXPLAIN("Unable to open clipboard.");
  155. ERR_FAIL();
  156. };
  157. EmptyClipboard();
  158. HGLOBAL mem = GlobalAlloc(GMEM_MOVEABLE, (p_text.length() + 1) * sizeof(CharType));
  159. if (mem == NULL) {
  160. ERR_EXPLAIN("Unable to allocate memory for clipboard contents.");
  161. ERR_FAIL();
  162. };
  163. LPWSTR lptstrCopy = (LPWSTR)GlobalLock(mem);
  164. memcpy(lptstrCopy, p_text.c_str(), (p_text.length() + 1) * sizeof(CharType));
  165. //memset((lptstrCopy + p_text.length()), 0, sizeof(CharType));
  166. GlobalUnlock(mem);
  167. SetClipboardData(CF_UNICODETEXT, mem);
  168. // set the CF_TEXT version (not needed?)
  169. CharString utf8 = p_text.utf8();
  170. mem = GlobalAlloc(GMEM_MOVEABLE, utf8.length() + 1);
  171. if (mem == NULL) {
  172. ERR_EXPLAIN("Unable to allocate memory for clipboard contents.");
  173. ERR_FAIL();
  174. };
  175. LPTSTR ptr = (LPTSTR)GlobalLock(mem);
  176. memcpy(ptr, utf8.get_data(), utf8.length());
  177. ptr[utf8.length()] = 0;
  178. GlobalUnlock(mem);
  179. SetClipboardData(CF_TEXT, mem);
  180. CloseClipboard();
  181. */
  182. };
  183. String OSWinrt::get_clipboard() const {
  184. /*
  185. String ret;
  186. if (!OpenClipboard(hWnd)) {
  187. ERR_EXPLAIN("Unable to open clipboard.");
  188. ERR_FAIL_V("");
  189. };
  190. if (IsClipboardFormatAvailable(CF_UNICODETEXT)) {
  191. HGLOBAL mem = GetClipboardData(CF_UNICODETEXT);
  192. if (mem != NULL) {
  193. LPWSTR ptr = (LPWSTR)GlobalLock(mem);
  194. if (ptr != NULL) {
  195. ret = String((CharType*)ptr);
  196. GlobalUnlock(mem);
  197. };
  198. };
  199. } else if (IsClipboardFormatAvailable(CF_TEXT)) {
  200. HGLOBAL mem = GetClipboardData(CF_UNICODETEXT);
  201. if (mem != NULL) {
  202. LPTSTR ptr = (LPTSTR)GlobalLock(mem);
  203. if (ptr != NULL) {
  204. ret.parse_utf8((const char*)ptr);
  205. GlobalUnlock(mem);
  206. };
  207. };
  208. };
  209. CloseClipboard();
  210. return ret;
  211. */
  212. return "";
  213. };
  214. void OSWinrt::input_event(InputEvent &p_event) {
  215. p_event.ID = ++last_id;
  216. input->parse_input_event(p_event);
  217. };
  218. void OSWinrt::delete_main_loop() {
  219. if (main_loop)
  220. memdelete(main_loop);
  221. main_loop=NULL;
  222. }
  223. void OSWinrt::set_main_loop( MainLoop * p_main_loop ) {
  224. input->set_main_loop(p_main_loop);
  225. main_loop=p_main_loop;
  226. }
  227. void OSWinrt::finalize() {
  228. if(main_loop)
  229. memdelete(main_loop);
  230. main_loop=NULL;
  231. visual_server->finish();
  232. memdelete(visual_server);
  233. #ifdef OPENGL_ENABLED
  234. if (gl_context)
  235. memdelete(gl_context);
  236. #endif
  237. if (rasterizer)
  238. memdelete(rasterizer);
  239. spatial_sound_server->finish();
  240. memdelete(spatial_sound_server);
  241. spatial_sound_2d_server->finish();
  242. memdelete(spatial_sound_2d_server);
  243. //if (debugger_connection_console) {
  244. // memdelete(debugger_connection_console);
  245. //}
  246. audio_server->finish();
  247. memdelete(audio_server);
  248. memdelete(sample_manager);
  249. memdelete(input);
  250. physics_server->finish();
  251. memdelete(physics_server);
  252. physics_2d_server->finish();
  253. memdelete(physics_2d_server);
  254. }
  255. void OSWinrt::finalize_core() {
  256. if (mempool_dynamic)
  257. memdelete( mempool_dynamic );
  258. if (mempool_static)
  259. delete mempool_static;
  260. }
  261. void OSWinrt::vprint(const char* p_format, va_list p_list, bool p_stderr) {
  262. char buf[16384+1];
  263. int len = vsnprintf(buf,16384,p_format,p_list);
  264. if (len<=0)
  265. return;
  266. buf[len]=0;
  267. int wlen = MultiByteToWideChar(CP_UTF8,0,buf,len,NULL,0);
  268. if (wlen<0)
  269. return;
  270. wchar_t *wbuf = (wchar_t*)malloc((len+1)*sizeof(wchar_t));
  271. MultiByteToWideChar(CP_UTF8,0,buf,len,wbuf,wlen);
  272. wbuf[wlen]=0;
  273. if (p_stderr)
  274. fwprintf(stderr,L"%s",wbuf);
  275. else
  276. wprintf(L"%s",wbuf);
  277. #ifdef STDOUT_FILE
  278. //vwfprintf(stdo,p_format,p_list);
  279. #endif
  280. free(wbuf);
  281. fflush(stdout);
  282. };
  283. void OSWinrt::alert(const String& p_alert,const String& p_title) {
  284. print_line("ALERT: "+p_alert);
  285. }
  286. void OSWinrt::set_mouse_mode(MouseMode p_mode) {
  287. }
  288. OSWinrt::MouseMode OSWinrt::get_mouse_mode() const{
  289. return mouse_mode;
  290. }
  291. Point2 OSWinrt::get_mouse_pos() const {
  292. return Point2(old_x, old_y);
  293. }
  294. int OSWinrt::get_mouse_button_state() const {
  295. return last_button_state;
  296. }
  297. void OSWinrt::set_window_title(const String& p_title) {
  298. }
  299. void OSWinrt::set_video_mode(const VideoMode& p_video_mode,int p_screen) {
  300. video_mode = p_video_mode;
  301. }
  302. OS::VideoMode OSWinrt::get_video_mode(int p_screen) const {
  303. return video_mode;
  304. }
  305. void OSWinrt::get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen) const {
  306. }
  307. void OSWinrt::print_error(const char* p_function,const char* p_file,int p_line,const char *p_code,const char*p_rationale,ErrorType p_type) {
  308. if (p_rationale && p_rationale[0]) {
  309. print("\E[1;31;40mERROR: %s: \E[1;37;40m%s\n",p_function,p_rationale);
  310. print("\E[0;31;40m At: %s:%i.\E[0;0;37m\n",p_file,p_line);
  311. } else {
  312. print("\E[1;31;40mERROR: %s: \E[1;37;40m%s\n",p_function,p_code);
  313. print("\E[0;31;40m At: %s:%i.\E[0;0;37m\n",p_file,p_line);
  314. }
  315. }
  316. String OSWinrt::get_name() {
  317. return "WinRT";
  318. }
  319. OS::Date OSWinrt::get_date() const {
  320. SYSTEMTIME systemtime;
  321. GetSystemTime(&systemtime);
  322. Date date;
  323. date.day=systemtime.wDay;
  324. date.month=Month(systemtime.wMonth);
  325. date.weekday=Weekday(systemtime.wDayOfWeek);
  326. date.year=systemtime.wYear;
  327. date.dst=false;
  328. return date;
  329. }
  330. OS::Time OSWinrt::get_time() const {
  331. SYSTEMTIME systemtime;
  332. GetSystemTime(&systemtime);
  333. Time time;
  334. time.hour=systemtime.wHour;
  335. time.min=systemtime.wMinute;
  336. time.sec=systemtime.wSecond;
  337. return time;
  338. }
  339. uint64_t OSWinrt::get_unix_time() const {
  340. FILETIME ft;
  341. SYSTEMTIME st;
  342. GetSystemTime(&st);
  343. SystemTimeToFileTime(&st, &ft);
  344. SYSTEMTIME ep;
  345. ep.wYear = 1970;
  346. ep.wMonth = 1;
  347. ep.wDayOfWeek = 4;
  348. ep.wDay = 1;
  349. ep.wHour = 0;
  350. ep.wMinute = 0;
  351. ep.wSecond = 0;
  352. ep.wMilliseconds = 0;
  353. FILETIME fep;
  354. SystemTimeToFileTime(&ep, &fep);
  355. return (*(uint64_t*)&ft - *(uint64_t*)&fep) / 10000000;
  356. };
  357. void OSWinrt::delay_usec(uint32_t p_usec) const {
  358. int msec = p_usec < 1000 ? 1 : p_usec / 1000;
  359. // no Sleep()
  360. WaitForSingleObjectEx(GetCurrentThread(), msec, false);
  361. }
  362. uint64_t OSWinrt::get_ticks_usec() const {
  363. uint64_t ticks;
  364. uint64_t time;
  365. // This is the number of clock ticks since start
  366. QueryPerformanceCounter((LARGE_INTEGER *)&ticks);
  367. // Divide by frequency to get the time in seconds
  368. time = ticks * 1000000L / ticks_per_second;
  369. // Subtract the time at game start to get
  370. // the time since the game started
  371. time -= ticks_start;
  372. return time;
  373. }
  374. void OSWinrt::process_events() {
  375. }
  376. void OSWinrt::set_cursor_shape(CursorShape p_shape) {
  377. }
  378. Error OSWinrt::execute(const String& p_path, const List<String>& p_arguments,bool p_blocking,ProcessID *r_child_id,String* r_pipe,int *r_exitcode) {
  379. return FAILED;
  380. };
  381. Error OSWinrt::kill(const ProcessID& p_pid) {
  382. return FAILED;
  383. };
  384. Error OSWinrt::set_cwd(const String& p_cwd) {
  385. return FAILED;
  386. }
  387. String OSWinrt::get_executable_path() const {
  388. return "";
  389. }
  390. void OSWinrt::set_icon(const Image& p_icon) {
  391. }
  392. bool OSWinrt::has_environment(const String& p_var) const {
  393. return false;
  394. };
  395. String OSWinrt::get_environment(const String& p_var) const {
  396. return "";
  397. };
  398. String OSWinrt::get_stdin_string(bool p_block) {
  399. return String();
  400. }
  401. void OSWinrt::move_window_to_foreground() {
  402. }
  403. Error OSWinrt::shell_open(String p_uri) {
  404. return FAILED;
  405. }
  406. String OSWinrt::get_locale() const {
  407. #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP // this should work on phone 8.1, but it doesn't
  408. return "en";
  409. #else
  410. Platform::String ^language = Windows::Globalization::Language::CurrentInputMethodLanguageTag;
  411. return language->Data();
  412. #endif
  413. }
  414. void OSWinrt::release_rendering_thread() {
  415. gl_context->release_current();
  416. }
  417. void OSWinrt::make_rendering_thread() {
  418. gl_context->make_current();
  419. }
  420. void OSWinrt::swap_buffers() {
  421. gl_context->swap_buffers();
  422. }
  423. void OSWinrt::run() {
  424. if (!main_loop)
  425. return;
  426. main_loop->init();
  427. uint64_t last_ticks=get_ticks_usec();
  428. int frames=0;
  429. uint64_t frame=0;
  430. while (!force_quit) {
  431. CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
  432. process_events(); // get rid of pending events
  433. if (Main::iteration()==true)
  434. break;
  435. };
  436. main_loop->finish();
  437. }
  438. MainLoop *OSWinrt::get_main_loop() const {
  439. return main_loop;
  440. }
  441. String OSWinrt::get_data_dir() const {
  442. Windows::Storage::StorageFolder ^data_folder = Windows::Storage::ApplicationData::Current->LocalFolder;
  443. return data_folder->Path->Data();
  444. }
  445. OSWinrt::OSWinrt() {
  446. key_event_pos=0;
  447. force_quit=false;
  448. alt_mem=false;
  449. gr_mem=false;
  450. shift_mem=false;
  451. control_mem=false;
  452. meta_mem=false;
  453. minimized = false;
  454. pressrc=0;
  455. old_invalid=true;
  456. last_id=0;
  457. mouse_mode=MOUSE_MODE_VISIBLE;
  458. #ifdef STDOUT_FILE
  459. stdo=fopen("stdout.txt","wb");
  460. #endif
  461. gl_context = NULL;
  462. AudioDriverManagerSW::add_driver(&audio_driver);
  463. }
  464. OSWinrt::~OSWinrt()
  465. {
  466. #ifdef STDOUT_FILE
  467. fclose(stdo);
  468. #endif
  469. }