No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

win32platform.cpp 9.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. /* The MIT License
  2. *
  3. * Copyright (c) 2010 OTClient, https://github.com/edubart/otclient
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a copy
  6. * of this software and associated documentation files (the "Software"), to deal
  7. * in the Software without restriction, including without limitation the rights
  8. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. * copies of the Software, and to permit persons to whom the Software is
  10. * furnished to do so, subject to the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be included in
  13. * all copies or substantial portions of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. * THE SOFTWARE.
  22. */
  23. #include "platform.h"
  24. #include "engine.h"
  25. #include <windows.h>
  26. LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  27. struct Win32PlatformPrivate {
  28. HWND window;
  29. HINSTANCE instance;
  30. HDC hdc;
  31. HGLRC hrc;
  32. int x, y;
  33. int width, height;
  34. int minWidth, minHeight;
  35. bool maximized;
  36. } win32;
  37. void Platform::init()
  38. {
  39. win32.instance = GetModuleHandle(NULL);
  40. WNDCLASSA wc;
  41. wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw On Size, And Own DC For Window.
  42. wc.lpfnWndProc = (WNDPROC)WndProc; // WndProc Handles Messages
  43. wc.cbClsExtra = 0; // No Extra Window Data
  44. wc.cbWndExtra = 0; // No Extra Window Data
  45. wc.hInstance = win32.instance; // Set The Instance
  46. wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); // Load The Default Icon
  47. wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Load The Arrow Pointer
  48. wc.hbrBackground = NULL; // No Background Required For GL
  49. wc.lpszMenuName = NULL; // We Don't Want A Menu
  50. wc.lpszClassName = "OTClient"; // Set The Class Name
  51. if(!RegisterClassA(&wc))
  52. fatal("Failed to register the window class.");
  53. }
  54. void Platform::terminate()
  55. {
  56. if(win32.window) {
  57. destroyWindow();
  58. win32.window = NULL;
  59. }
  60. if(win32.instance) {
  61. if(!UnregisterClassA("OTClient", win32.instance))
  62. error("Unregister class failed.");
  63. win32.instance = NULL;
  64. }
  65. }
  66. void Platform::poll()
  67. {
  68. MSG msg;
  69. if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
  70. TranslateMessage(&msg);
  71. DispatchMessage(&msg);
  72. }
  73. }
  74. unsigned long Platform::getTicks()
  75. {
  76. return GetTickCount();
  77. }
  78. void Platform::sleep(unsigned long miliseconds)
  79. {
  80. Sleep(miliseconds);
  81. }
  82. bool Platform::createWindow(int x, int y, int width, int height, int minWidth, int minHeight, bool maximized)
  83. {
  84. DWORD dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
  85. DWORD dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
  86. win32.x = x;
  87. win32.y = y;
  88. win32.width = width;
  89. win32.height = height;
  90. win32.minWidth = minWidth;
  91. win32.minHeight = minHeight;
  92. win32.maximized = maximized;
  93. //AdjustWindowRectEx(&windowRect, dwStyle, FALSE, dwExStyle);
  94. win32.window = CreateWindowExA(dwExStyle, // Extended Style For The Window
  95. "OTClient", // Class Name
  96. "OTClient", // Window Title
  97. dwStyle, // Required Window Style
  98. x, // Window X Position
  99. y, // Window Y Position
  100. width, // Calculate Window Width
  101. height, // Calculate Window Height
  102. NULL, // No Parent Window
  103. NULL, // No Menu
  104. win32.instance, // Instance
  105. NULL);
  106. if(!win32.window) {
  107. terminate();
  108. fatal("Window creation error.");
  109. return false;
  110. }
  111. GLuint pixelFormat;
  112. static PIXELFORMATDESCRIPTOR pfd= // pfd Tells Windows How We Want Things To Be
  113. {
  114. sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
  115. 1, // Version Number
  116. PFD_DRAW_TO_WINDOW | // Format Must Support Window
  117. PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
  118. PFD_DOUBLEBUFFER, // Must Support Double Buffering
  119. PFD_TYPE_RGBA, // Request An RGBA Format
  120. 32, // Select Our Color Depth
  121. 0, 0, 0, 0, 0, 0, // Color Bits Ignored
  122. 0, // No Alpha Buffer
  123. 0, // Shift Bit Ignored
  124. 0, // No Accumulation Buffer
  125. 0, 0, 0, 0, // Accumulation Bits Ignored
  126. 16, // 16Bit Z-Buffer (Depth Buffer)
  127. 0, // No Stencil Buffer
  128. 0, // No Auxiliary Buffer
  129. PFD_MAIN_PLANE, // Main Drawing Layer
  130. 0, // Reserved
  131. 0, 0, 0 // Layer Masks Ignored
  132. };
  133. if(!(win32.hdc = GetDC(win32.window))) {
  134. terminate();
  135. fatal("Can't Create A GL Device Context.");
  136. return false;
  137. }
  138. if(!(pixelFormat = ChoosePixelFormat(win32.hdc, &pfd))) {
  139. terminate();
  140. fatal("Can't Find A Suitable PixelFormat.");
  141. return false;
  142. }
  143. if(!SetPixelFormat(win32.hdc, pixelFormat, &pfd)) {
  144. terminate();
  145. fatal("Can't Set The PixelFormat.");
  146. return false;
  147. }
  148. if(!(win32.hrc = wglCreateContext(win32.hdc))) {
  149. terminate();
  150. fatal("Can't Create A GL Rendering Context.");
  151. return false;
  152. }
  153. if(!wglMakeCurrent(win32.hdc, win32.hrc)) {
  154. terminate();
  155. fatal("Can't Activate The GL Rendering Context.");
  156. return false;
  157. }
  158. return true;
  159. }
  160. void Platform::destroyWindow()
  161. {
  162. if(win32.hrc) {
  163. if(!wglMakeCurrent(NULL, NULL))
  164. error("Release Of DC And RC Failed.");
  165. if(!wglDeleteContext(win32.hrc))
  166. error("Release Rendering Context Failed.");
  167. win32.hrc = NULL;
  168. }
  169. if(win32.hdc) {
  170. if(!ReleaseDC(win32.window, win32.hdc))
  171. error("Release Device Context Failed.");
  172. win32.hdc = NULL;
  173. }
  174. if(win32.window) {
  175. if(!DestroyWindow(win32.window))
  176. error("Destroy window failed.");
  177. win32.window = NULL;
  178. }
  179. }
  180. void Platform::showWindow()
  181. {
  182. if(win32.maximized)
  183. ShowWindow(win32.window, SW_MAXIMIZE);
  184. else
  185. ShowWindow(win32.window, SW_SHOW);
  186. }
  187. void Platform::setWindowTitle(const char *title)
  188. {
  189. SetWindowTextA(win32.window, title);
  190. }
  191. void *Platform::getExtensionProcAddress(const char *ext)
  192. {
  193. return (void*)wglGetProcAddress(ext);
  194. }
  195. bool Platform::isExtensionSupported(const char *ext)
  196. {
  197. const char *exts = NULL;//glXQueryExtensionsString(x11.display, DefaultScreen(x11.display));
  198. if(strstr(exts, ext))
  199. return true;
  200. return true;
  201. }
  202. void Platform::showMouseCursor()
  203. {
  204. ShowCursor(false);
  205. /*XUndefineCursor(x11.display, x11.window);
  206. if(x11.cursor != None) {
  207. XFreeCursor(x11.display, x11.cursor);
  208. x11.cursor = None;
  209. }*/
  210. }
  211. void Platform::setVsync(bool enable)
  212. {
  213. typedef GLint (*glSwapIntervalProc)(GLint);
  214. glSwapIntervalProc glSwapInterval = NULL;
  215. if(isExtensionSupported("GLX_MESA_swap_control"))
  216. glSwapInterval = (glSwapIntervalProc)getExtensionProcAddress("glXSwapIntervalMESA");
  217. else if(isExtensionSupported("GLX_SGI_swap_control"))
  218. glSwapInterval = (glSwapIntervalProc)getExtensionProcAddress("glXSwapIntervalSGI");
  219. if(glSwapInterval)
  220. glSwapInterval(enable ? 1 : 0);
  221. }
  222. void Platform::swapBuffers()
  223. {
  224. SwapBuffers(win32.hdc);
  225. }
  226. int Platform::getWindowWidth()
  227. {
  228. return win32.width;
  229. }
  230. int Platform::getWindowHeight()
  231. {
  232. return win32.height;
  233. }
  234. const char *Platform::getAppUserDir()
  235. {
  236. /*std::stringstream sdir;
  237. sdir << PHYSFS_getUserDir() << "/." << APP_NAME << "/";
  238. if((mkdir(sdir.str().c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0) && (errno != EEXIST))
  239. error("Couldn't create directory for saving configuration file. (%s)", sdir.str().c_str());
  240. return sdir.str().c_str();*/
  241. return "lol";
  242. }
  243. LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  244. {
  245. switch(uMsg)
  246. {
  247. case WM_CLOSE:
  248. {
  249. g_engine.onClose();
  250. break;
  251. }
  252. case WM_GETMINMAXINFO:
  253. {
  254. MINMAXINFO *minMax = (MINMAXINFO*)lParam;
  255. minMax->ptMinTrackSize.x = win32.minWidth;
  256. minMax->ptMinTrackSize.y = win32.minHeight;
  257. break;
  258. }
  259. case WM_MOVING:
  260. case WM_SIZING:
  261. {
  262. RECT *rect = (RECT*)lParam;
  263. win32.x = rect->left;
  264. win32.y = rect->top;
  265. win32.width = rect->right - rect->left;
  266. win32.height = rect->bottom - rect->top;
  267. break;
  268. }
  269. case WM_SIZE:
  270. {
  271. switch(wParam)
  272. {
  273. case SIZE_MAXIMIZED:
  274. win32.maximized = true;
  275. break;
  276. case SIZE_RESTORED:
  277. win32.maximized = false;
  278. break;
  279. }
  280. g_engine.onResize(LOWORD(lParam), HIWORD(lParam));
  281. break;
  282. }
  283. default:
  284. {
  285. return DefWindowProc(hWnd,uMsg,wParam,lParam);
  286. }
  287. }
  288. return 0;
  289. }