Archived
1
Fork 0
This repository has been archived on 2025-04-12. You can view files and clone it, but cannot push or open issues or pull requests.
prism/platforms/windows/main.cpp.in

335 lines
7.2 KiB
C++
Raw Normal View History

2020-08-11 12:07:21 -04:00
#ifndef UNICODE
#define UNICODE
#endif
2020-08-13 07:48:50 -04:00
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
2020-08-11 12:07:21 -04:00
#include <windows.h>
#include <windowsx.h>
2020-08-13 07:48:50 -04:00
#undef far
#undef near
2020-08-11 12:07:21 -04:00
#include "platform.hpp"
#include <gfx_vulkan.hpp>
2020-08-13 07:48:50 -04:00
#include <@APP_INCLUDE@>
2020-08-11 12:07:21 -04:00
#include <engine.hpp>
GFX* ginterface = nullptr;
2020-08-13 07:48:50 -04:00
@APP_CLASS@* app = nullptr;
2020-08-11 12:07:21 -04:00
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";
2020-08-11 12:07:21 -04:00
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() {}
2020-08-13 07:48:50 -04:00
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};
2020-08-11 12:07:21 -04:00
AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE);
2020-08-13 07:48:50 -04:00
defaultWidth = rect.extent.width;
defaultHeight = rect.extent.height;
2020-08-11 12:07:21 -04:00
2020-08-13 07:48:50 -04:00
wchar_t* title_uni = convertToUnicode(title.data());
2020-08-11 12:07:21 -04:00
window = CreateWindowEx(
0,
CLASS_NAME,
title_uni,
flags == WindowFlags::Resizable ? WS_OVERLAPPEDWINDOW : (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX), // Window style
2020-08-13 07:48:50 -04:00
rect.offset.x,
rect.offset.y,
2020-08-11 12:07:21 -04:00
wr.right - wr.left,
wr.bottom - wr.top,
NULL,
NULL,
instance,
NULL
);
delete[] title_uni;
ShowWindow(window, cmdShow);
2020-08-13 07:48:50 -04:00
engine->add_window(window, 0, rect.extent);
app->initialize_render();
2020-08-13 07:48:50 -04:00
return 0;
2020-08-11 12:07:21 -04:00
}
2020-08-13 07:48:50 -04:00
void platform::close_window(const int identifier) {
2020-08-11 12:07:21 -04:00
// does nothing
}
bool showingCursor = true;
2020-08-13 07:48:50 -04:00
void platform::capture_mouse(const bool capture) {
2020-08-11 12:07:21 -04:00
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;
}
}
2020-08-13 07:48:50 -04:00
prism::Offset platform::get_cursor_position() {
2020-08-11 12:07:21 -04:00
POINT p;
GetCursorPos(&p);
ScreenToClient(window, &p);
return {p.x, p.y};
}
2020-08-13 07:48:50 -04:00
prism::Offset platform::get_window_position(const int identifier) {
2020-08-11 12:07:21 -04:00
RECT rect;
GetWindowRect(window, &rect);
return {rect.left, rect.top};
}
2020-08-13 07:48:50 -04:00
prism::Extent platform::get_window_size(const int identifier) {
2020-08-11 12:07:21 -04:00
RECT rect;
GetClientRect(window, &rect);
int width = rect.right - rect.left;
int height = rect.bottom- rect.top;
2020-08-13 07:48:50 -04:00
return {static_cast<uint32_t>(width), static_cast<uint32_t>(height)};
2020-08-11 12:07:21 -04:00
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
2020-08-13 07:48:50 -04:00
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow) {
2020-08-11 12:07:21 -04:00
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;
2020-08-13 07:48:50 -04:00
engine = new Engine(0, nullptr);
2020-08-11 12:07:21 -04:00
ginterface = new GFXVulkan();
2020-08-13 07:48:50 -04:00
if(ginterface->initialize(GFXCreateInfo())) {
engine->set_gfx(ginterface);
2020-08-11 12:07:21 -04:00
} else {
return -1;
}
2020-08-13 07:48:50 -04:00
app = new @APP_CLASS@();
engine->set_app(app);
2020-08-11 12:07:21 -04:00
2020-08-13 07:48:50 -04:00
app_main(engine);
2020-08-11 12:07:21 -04:00
MSG msg = { };
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
2020-08-13 07:48:50 -04:00
delete app;
2020-08-11 12:07:21 -04:00
delete ginterface;
delete engine;
fclose(stream);
return 0;
}
int timeout = 0;
2020-09-23 12:28:21 -04:00
bool mouse_down = false;
2020-08-11 12:07:21 -04:00
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
case WM_DESTROY:
{
2020-08-13 07:48:50 -04:00
engine->prepare_quit();
2020-08-11 12:07:21 -04:00
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);
2020-08-13 07:48:50 -04:00
engine->render(0);
2020-08-11 12:07:21 -04:00
2020-08-13 07:48:50 -04:00
if(engine->is_quitting()) {
engine->prepare_quit();
2020-08-11 12:07:21 -04:00
PostQuitMessage(0);
}
}
return 0;
case WM_LBUTTONDOWN:
{
int xPos = GET_X_LPARAM(lParam);
int yPos = GET_Y_LPARAM(lParam);
2020-08-13 07:48:50 -04:00
engine->process_mouse_down(0, {xPos, yPos});
2020-09-23 12:28:21 -04:00
mouse_down = true;
}
return 0;
case WM_LBUTTONUP:
{
mouse_down = false;
2020-08-11 12:07:21 -04:00
}
return 0;
case WM_KEYDOWN:
{
2020-08-13 07:48:50 -04:00
engine->process_key_down((unsigned int)wParam);
2020-08-11 12:07:21 -04:00
}
return 0;
case WM_KEYUP:
{
2020-08-13 07:48:50 -04:00
engine->process_key_up((unsigned int)wParam);
2020-08-11 12:07:21 -04:00
}
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 {
2020-08-13 07:48:50 -04:00
engine->resize(0, {static_cast<uint32_t>(width), static_cast<uint32_t>(height)});
2020-08-11 12:07:21 -04:00
}
}
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
2020-08-13 07:48:50 -04:00
void platform::set_window_title(const int identifier, const std::string_view title) {
SetWindowTextA(window, title.data());
}
std::tuple<float, float> platform::get_right_stick_position() {
return {0.0f, 0.0f};
}
std::tuple<float, float> 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<uint32_t>(width), static_cast<uint32_t>(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) {
2020-09-23 12:28:21 -04:00
return mouse_down;
}
float platform::get_monitor_dpi() {
return 1.0f;
}
std::tuple<float, float> platform::get_wheel_delta() {
return {0.0f, 0.0f};
}