#ifndef UNICODE #define UNICODE #endif #define WIN32_LEAN_AND_MEAN #define NOMINMAX #include #include #undef far #undef near #include "platform.hpp" #include #include <@APP_INCLUDE@> #include GFX* ginterface = nullptr; @APP_CLASS@* app = nullptr; HINSTANCE instance = NULL; HWND window = NULL; int cmdShow = 0; HDC windowDC = NULL; int defaultWidth, defaultHeight; bool shouldConfineMouse = false; const wchar_t CLASS_NAME[] = L"PrismApp"; wchar_t* convertToUnicode(const char* str) { size_t ret = 0; mbsrtowcs_s(&ret, NULL, 0, &str, 0, NULL); wchar_t * buf = new wchar_t[ret + 1](); mbsrtowcs_s(&ret, buf, ret + 1 , &str, ret + 1, NULL); return buf; } void platform::force_quit() {} int platform::open_window(const std::string_view title, const prism::Rectangle rect, const WindowFlags flags) { RECT wr = {rect.offset.x, rect.offset.y, rect.extent.width, rect.extent.height}; AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE); defaultWidth = rect.extent.width; defaultHeight = rect.extent.height; wchar_t* title_uni = convertToUnicode(title.data()); window = CreateWindowEx( 0, CLASS_NAME, title_uni, flags == WindowFlags::Resizable ? WS_OVERLAPPEDWINDOW : (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX), // Window style rect.offset.x, rect.offset.y, wr.right - wr.left, wr.bottom - wr.top, NULL, NULL, instance, NULL ); delete[] title_uni; ShowWindow(window, cmdShow); engine->add_window(window, 0, rect.extent); app->initialize_render(); return 0; } void platform::close_window(const int identifier) { // does nothing } bool showingCursor = true; void platform::capture_mouse(const bool capture) { shouldConfineMouse = capture; // the reason why we do this is because windows expects a ShowCursor(false) to be followed by a ShowCursor(true), // if you don't do this your cursor pretty much gets sent to bill gate's purgatory and it can never escape // so this code is to ensure every ShowCursor call gets matched by it's counterpart when you call setCaptureMouse if(showingCursor && capture) { ShowCursor(false); showingCursor = false; } else if(!showingCursor && !capture) { ShowCursor(true); showingCursor = true; } } prism::Offset platform::get_cursor_position() { POINT p; GetCursorPos(&p); ScreenToClient(window, &p); return {p.x, p.y}; } prism::Offset platform::get_window_position(const int identifier) { RECT rect; GetWindowRect(window, &rect); return {rect.left, rect.top}; } prism::Extent platform::get_window_size(const int identifier) { RECT rect; GetClientRect(window, &rect); int width = rect.right - rect.left; int height = rect.bottom- rect.top; return {static_cast(width), static_cast(height)}; } LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow) { AllocConsole(); FILE* stream; freopen_s(&stream, "CONOUT$", "w", stdout); freopen_s(&stream, "CONOUT$", "w", stderr); WNDCLASS wc {}; wc.lpfnWndProc = WindowProc; wc.hInstance = hInstance; wc.lpszClassName = CLASS_NAME; RegisterClass(&wc); instance = hInstance; cmdShow = nCmdShow; engine = new Engine(0, nullptr); ginterface = new GFXVulkan(); if(ginterface->initialize(GFXCreateInfo())) { engine->set_gfx(ginterface); } else { return -1; } app = new @APP_CLASS@(); engine->set_app(app); app_main(engine); MSG msg = { }; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } delete app; delete ginterface; delete engine; fclose(stream); return 0; } int timeout = 0; bool mouse_down = false; LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_DESTROY: { engine->prepare_quit(); PostQuitMessage(0); } return 0; case WM_PAINT: { if(shouldConfineMouse && timeout > 5) { RECT rect; GetClientRect(hwnd, &rect); int width = rect.right - rect.left; int height = rect.bottom- rect.top; POINT p; p.x = width / 2; p.y = height / 2; ClientToScreen(window, &p); SetCursorPos(p.x, p.y); timeout = 0; } timeout++; HCURSOR arrowCursor = LoadCursor(NULL, IDC_ARROW); SetCursor(arrowCursor); engine->update(1.0f / 60.0f); engine->begin_frame(1.0f / 60.0f); engine->render(0); if(engine->is_quitting()) { engine->prepare_quit(); PostQuitMessage(0); } } return 0; case WM_LBUTTONDOWN: { int xPos = GET_X_LPARAM(lParam); int yPos = GET_Y_LPARAM(lParam); engine->process_mouse_down(0, {xPos, yPos}); mouse_down = true; } return 0; case WM_LBUTTONUP: { mouse_down = false; } return 0; case WM_KEYDOWN: { engine->process_key_down((unsigned int)wParam); } return 0; case WM_KEYUP: { engine->process_key_up((unsigned int)wParam); } return 0; case WM_SIZE: { RECT rect; GetClientRect(hwnd, &rect); int width = rect.right - rect.left; int height = rect.bottom- rect.top; if(width == defaultWidth && height == defaultHeight) { // don't resize when the window was first created!! } else { engine->resize(0, {static_cast(width), static_cast(height)}); } } return 0; } return DefWindowProc(hwnd, uMsg, wParam, lParam); } void platform::set_window_title(const int identifier, const std::string_view title) { SetWindowTextA(window, title.data()); } std::tuple platform::get_right_stick_position() { return {0.0f, 0.0f}; } std::tuple platform::get_left_stick_position() { return {0.0f, 0.0f}; } bool platform::is_window_focused(const int index) { return false; } void platform::set_window_focused(const int index) { } prism::Extent platform::get_window_drawable_size(const int identifier) { RECT rect; GetClientRect(window, &rect); int width = rect.right - rect.left; int height = rect.bottom- rect.top; return {static_cast(width), static_cast(height)}; } void platform::set_window_size(const int index, const prism::Extent extent) { } void platform::set_window_position(const int index, const prism::Offset offset) { } prism::Rectangle platform::get_monitor_resolution() { return prism::Rectangle(); } prism::Rectangle platform::get_monitor_work_area() { return prism::Rectangle(); } prism::Offset platform::get_screen_cursor_position() { return prism::Offset(); } float platform::get_window_dpi(const int index) { return 1.0f; } bool platform::get_mouse_button_down(const int index) { return mouse_down; } float platform::get_monitor_dpi() { return 1.0f; } std::tuple platform::get_wheel_delta() { return {0.0f, 0.0f}; }