godot_win.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /*************************************************************************/
  2. /* godot_win.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* http://www.godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2015 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 "os_windows.h"
  30. #include "main/main.h"
  31. #include <stdio.h>
  32. #include <locale.h>
  33. PCHAR*
  34. CommandLineToArgvA(
  35. PCHAR CmdLine,
  36. int* _argc
  37. )
  38. {
  39. PCHAR* argv;
  40. PCHAR _argv;
  41. ULONG len;
  42. ULONG argc;
  43. CHAR a;
  44. ULONG i, j;
  45. BOOLEAN in_QM;
  46. BOOLEAN in_TEXT;
  47. BOOLEAN in_SPACE;
  48. len = strlen(CmdLine);
  49. i = ((len+2)/2)*sizeof(PVOID) + sizeof(PVOID);
  50. argv = (PCHAR*)GlobalAlloc(GMEM_FIXED,
  51. i + (len+2)*sizeof(CHAR));
  52. _argv = (PCHAR)(((PUCHAR)argv)+i);
  53. argc = 0;
  54. argv[argc] = _argv;
  55. in_QM = FALSE;
  56. in_TEXT = FALSE;
  57. in_SPACE = TRUE;
  58. i = 0;
  59. j = 0;
  60. while( (a = CmdLine[i]) ) {
  61. if(in_QM) {
  62. if(a == '\"') {
  63. in_QM = FALSE;
  64. } else {
  65. _argv[j] = a;
  66. j++;
  67. }
  68. } else {
  69. switch(a) {
  70. case '\"':
  71. in_QM = TRUE;
  72. in_TEXT = TRUE;
  73. if(in_SPACE) {
  74. argv[argc] = _argv+j;
  75. argc++;
  76. }
  77. in_SPACE = FALSE;
  78. break;
  79. case ' ':
  80. case '\t':
  81. case '\n':
  82. case '\r':
  83. if(in_TEXT) {
  84. _argv[j] = '\0';
  85. j++;
  86. }
  87. in_TEXT = FALSE;
  88. in_SPACE = TRUE;
  89. break;
  90. default:
  91. in_TEXT = TRUE;
  92. if(in_SPACE) {
  93. argv[argc] = _argv+j;
  94. argc++;
  95. }
  96. _argv[j] = a;
  97. j++;
  98. in_SPACE = FALSE;
  99. break;
  100. }
  101. }
  102. i++;
  103. }
  104. _argv[j] = '\0';
  105. argv[argc] = NULL;
  106. (*_argc) = argc;
  107. return argv;
  108. }
  109. char* wc_to_utf8(const wchar_t* wc) {
  110. int ulen = WideCharToMultiByte(CP_UTF8,0,wc,-1,NULL,0,NULL,NULL);
  111. char * ubuf = new char[ulen + 1];
  112. WideCharToMultiByte(CP_UTF8,0,wc,-1,ubuf,ulen,NULL,NULL);
  113. ubuf[ulen] = 0;
  114. return ubuf;
  115. }
  116. int widechar_main(int argc, wchar_t** argv) {
  117. OS_Windows os(NULL);
  118. setlocale(LC_CTYPE, "");
  119. char ** argv_utf8 = new char*[argc];
  120. for(int i=0; i<argc; ++i) {
  121. argv_utf8[i] = wc_to_utf8(argv[i]);
  122. }
  123. Error err = Main::setup(argv_utf8[0], argc - 1, &argv_utf8[1]);
  124. if (err!=OK)
  125. return 255;
  126. if (Main::start())
  127. os.run();
  128. Main::cleanup();
  129. for (int i=0; i<argc; ++i) {
  130. delete[] argv_utf8[i];
  131. }
  132. delete[] argv_utf8;
  133. return os.get_exit_code();
  134. };
  135. int main(int _argc, char** _argv) {
  136. // _argc and _argv are ignored
  137. // we are going to use the WideChar version of them instead
  138. LPWSTR *wc_argv;
  139. int argc;
  140. int result;
  141. wc_argv = CommandLineToArgvW(GetCommandLineW(), &argc);
  142. if( NULL == wc_argv ) {
  143. wprintf(L"CommandLineToArgvW failed\n");
  144. return 0;
  145. }
  146. result = widechar_main(argc, wc_argv);
  147. LocalFree(wc_argv);
  148. return result;
  149. }
  150. HINSTANCE godot_hinstance = NULL;
  151. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
  152. godot_hinstance = hInstance;
  153. return main(0,NULL);
  154. }