window.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. #include "window.h"
  2. #include <logs/assert.h>
  3. #include "callbacks.h"
  4. #include <filesystem>
  5. #ifdef PIKA_WINDOWS
  6. #define GLFW_EXPOSE_NATIVE_WIN32
  7. #include <Windows.h>
  8. #include <GLFW/glfw3native.h>
  9. #endif
  10. #include <pikaSizes.h>
  11. #include <safeSave/safeSave.h>
  12. struct WindowRect
  13. {
  14. int x = 100, y = 100, z = 640, w = 480;
  15. };
  16. void pika::PikaWindow::create()
  17. {
  18. WindowRect wr = {};
  19. #if PIKA_DEVELOPMENT
  20. if (sfs::safeLoad(&wr, sizeof(wr), PIKA_ENGINE_SAVES_PATH "windowPos", false) != sfs::noError)
  21. {
  22. wr = {};
  23. }
  24. #endif
  25. if (wr.x < 0 || wr.y < 0 || wr.z <= 0 || wr.w <= 0)
  26. {
  27. wr = {};
  28. }
  29. //todo debug from engine
  30. //glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, true);
  31. //glfwWindowHint(GLFW_SAMPLES, 1);
  32. //glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
  33. //glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
  34. //glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
  35. context.wind = glfwCreateWindow(wr.z, wr.w, "Pika", NULL, NULL);
  36. glfwSetWindowPos(context.wind, wr.x, wr.y);
  37. input.hasFocus = true;
  38. PIKA_PERMA_ASSERT(context.wind, "problem initializing window");
  39. glfwMakeContextCurrent(context.wind);
  40. glfwSetWindowUserPointer(context.wind, this);
  41. glfwSetMouseButtonCallback(context.wind, mouseCallback);
  42. glfwSetWindowFocusCallback(context.wind, windowFocusCallback);
  43. glfwSetCharCallback(context.wind, characterCallback);
  44. glfwSetKeyCallback(context.wind, keyCallback);
  45. #if PIKA_SHOULD_REMOVE_IMGUI == 0
  46. //todo macro
  47. context.imguiAllocator.init(malloc(pika::MB(20)), pika::MB(20));
  48. #endif
  49. //HWND hwnd = glfwGetWin32Window(context.wind);
  50. //LONG exStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
  51. //exStyle &= ~WS_EX_APPWINDOW;
  52. //exStyle |= WS_EX_TOOLWINDOW;
  53. //exStyle |= WS_EX_CONTEXTHELP;
  54. //exStyle &= ~WS_MAXIMIZEBOX;
  55. //exStyle &= ~WS_MINIMIZEBOX;
  56. //SetWindowLongPtr(hwnd, GWL_EXSTYLE, exStyle);
  57. //LONG style = GetWindowLongPtr(hwnd, GWL_STYLE);
  58. //style &= ~WS_MAXIMIZEBOX;
  59. //style &= ~WS_MINIMIZEBOX;
  60. //style &= ~WS_CAPTION;
  61. //style |= WS_DLGFRAME;
  62. //SetWindowLongPtr(hwnd, GWL_STYLE, style);
  63. timer = std::chrono::high_resolution_clock::now();
  64. }
  65. void pika::PikaWindow::saveWindowPositions()
  66. {
  67. #if PIKA_DEVELOPMENT
  68. WindowRect wr = {};
  69. glfwGetWindowPos(context.wind, &wr.x, &wr.y);
  70. wr.z = windowState.windowW;
  71. wr.w = windowState.windowH;
  72. if (!std::filesystem::is_directory(PIKA_ENGINE_RESOURCES_PATH))
  73. {
  74. std::filesystem::create_directory(PIKA_ENGINE_RESOURCES_PATH);
  75. }
  76. if (!std::filesystem::is_directory(PIKA_ENGINE_SAVES_PATH))
  77. {
  78. std::filesystem::create_directory(PIKA_ENGINE_SAVES_PATH);
  79. }
  80. sfs::safeSave(&wr, sizeof(wr), PIKA_ENGINE_SAVES_PATH "windowPos", false);
  81. #endif
  82. }
  83. bool pika::PikaWindow::shouldClose()
  84. {
  85. return glfwWindowShouldClose(context.wind);
  86. }
  87. void pika::PikaWindow::update()
  88. {
  89. #pragma region deltaTime
  90. auto end = std::chrono::high_resolution_clock::now();
  91. input.deltaTime = (std::chrono::duration_cast<std::chrono::microseconds>(end - timer)).count() / 1000000.0f;
  92. timer = end;
  93. if (input.deltaTime > 1.f / 10) { input.deltaTime = 1.f / 10; }
  94. #pragma endregion
  95. #pragma region input
  96. auto processInputBefore = [](pika::Button &b)
  97. {
  98. b.setTyped(false);
  99. };
  100. processInputBefore(input.lMouse);
  101. processInputBefore(input.rMouse);
  102. for (int i = 0; i < Button::BUTTONS_COUNT; i++)
  103. {
  104. processInputBefore(input.buttons[i]);
  105. }
  106. memset(input.typedInput, 0, sizeof(input.typedInput));
  107. for (int i = 0; i < Input::MAX_CONTROLLERS_COUNT; i++)
  108. {
  109. for (int j = 0; j < Controller::Buttons::ButtonsCount; j++)
  110. {
  111. processInputBefore(input.controllers[i].buttons[j]);
  112. }
  113. }
  114. #pragma endregion
  115. glfwPollEvents();
  116. glfwSwapBuffers(context.wind);
  117. #pragma region window state
  118. {
  119. int w = 0;
  120. int h = 0;
  121. glfwGetWindowSize(context.wind, &w, &h);
  122. windowState.windowW = w;
  123. windowState.windowH = h;
  124. glfwGetFramebufferSize(context.wind, &w, &h);
  125. windowState.frameBufferW = w;
  126. windowState.frameBufferH = h;
  127. }
  128. #pragma endregion
  129. #pragma region input
  130. #pragma region controller
  131. for (int i = 0; i <= Input::MAX_CONTROLLERS_COUNT; i++)
  132. {
  133. if (glfwJoystickPresent(i) && glfwJoystickIsGamepad(i))
  134. {
  135. input.controllers[i].connected = true;
  136. GLFWgamepadstate state;
  137. if (glfwGetGamepadState(i, &state))
  138. {
  139. for (int b = 0; b <= GLFW_GAMEPAD_BUTTON_LAST; b++)
  140. {
  141. pika::processAButton(input.controllers[i].buttons[b], state.buttons[b]);
  142. //updateButton(controllerButtons.buttons[i], deltaTime); //todo implement double epressed
  143. }
  144. input.controllers[i].LT = state.axes[GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER];
  145. input.controllers[i].RT = state.axes[GLFW_GAMEPAD_AXIS_LEFT_TRIGGER];
  146. input.controllers[i].LStick.x = state.axes[GLFW_GAMEPAD_AXIS_LEFT_X];
  147. input.controllers[i].LStick.y = state.axes[GLFW_GAMEPAD_AXIS_LEFT_Y];
  148. input.controllers[i].RStick.x = state.axes[GLFW_GAMEPAD_AXIS_RIGHT_X];
  149. input.controllers[i].RStick.y = state.axes[GLFW_GAMEPAD_AXIS_RIGHT_Y];
  150. }
  151. }
  152. else
  153. {
  154. input.controllers[i].resetAllButtons();
  155. }
  156. }
  157. #pragma endregion
  158. double mouseX = 0;
  159. double mouseY = 0;
  160. glfwGetCursorPos(context.wind, &mouseX, &mouseY);
  161. input.mouseX = (int)mouseX;
  162. input.mouseY = (int)mouseY;
  163. auto processInput = [](pika::Button &b)
  164. {
  165. if (!b.lastState() && b.held())
  166. {
  167. b.setPressed(true);
  168. b.setTyped(true);
  169. }
  170. else
  171. {
  172. b.setPressed(false);
  173. }
  174. if (b.lastState() && !b.held())
  175. {
  176. b.setReleased(true);
  177. }
  178. else
  179. {
  180. b.setReleased(false);
  181. }
  182. b.setLastState(b.held());
  183. };
  184. processInput(input.lMouse);
  185. processInput(input.rMouse);
  186. for (int i = 0; i < Button::BUTTONS_COUNT; i++)
  187. {
  188. processInput(input.buttons[i]);
  189. }
  190. #pragma region controller
  191. for (int i = 0; i < Input::MAX_CONTROLLERS_COUNT; i++)
  192. {
  193. if(input.controllers[i].connected)
  194. for (int b = 0; b <= GLFW_GAMEPAD_BUTTON_LAST; b++)
  195. {
  196. processInput(input.controllers[i].buttons[b]);
  197. }
  198. }
  199. input.anyController.resetAllButtons();
  200. for (int i = 0; i <= Input::MAX_CONTROLLERS_COUNT; i++)
  201. {
  202. input.controllers[i].connected = true;
  203. if (input.controllers[i].connected)
  204. {
  205. input.anyController.connected = true;
  206. for (int b = 0; b <= GLFW_GAMEPAD_BUTTON_LAST; b++)
  207. {
  208. input.anyController.buttons[b].flags
  209. |= input.controllers[i].buttons[b].flags;
  210. }
  211. if (!input.anyController.LT) input.anyController.LT = input.controllers[i].LT;
  212. if (!input.anyController.RT) input.anyController.RT = input.controllers[i].RT;
  213. if (!input.anyController.LStick.x) input.anyController.LStick.x = input.controllers[i].LStick.x;
  214. if (!input.anyController.LStick.y) input.anyController.LStick.y = input.controllers[i].LStick.y;
  215. if (!input.anyController.RStick.x) input.anyController.RStick.x = input.controllers[i].RStick.x;
  216. if (!input.anyController.RStick.y) input.anyController.RStick.y = input.controllers[i].RStick.y;
  217. }
  218. }
  219. #pragma endregion
  220. #pragma endregion
  221. }