Fix Win32 window creation

This commit is contained in:
mrkubax10 2023-06-01 11:34:52 +02:00
parent f7dd288908
commit 55c24686f1
5 changed files with 99 additions and 35 deletions

View File

@ -24,60 +24,80 @@ SOFTWARE.
#include "game/window/win32_window.hpp"
#include <atomic>
#include "common/logger.hpp"
using namespace polygun::window;
static HINSTANCE g_instance;
static std::atomic<Win32Window*> g_current_window = nullptr;
extern int main(int argc, char** args);
int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev_inst, PTSTR cmd_line, int show_cmd) {
g_instance = inst;
main(1, &cmd_line);
return main(1, &cmd_line);
}
static LRESULT CALLBACK window_proc(HWND window_handle, UINT message, WPARAM param1, LPARAM param2) {
LRESULT result = 0;
Event event;
switch(message) {
case WM_SIZE:
event.m_type = EventType::EVENT_TYPE_WINDOW_RESIZE;
event.m_data.m_window_event.m_width = LOWORD(param2);
event.m_data.m_window_event.m_height = HIWORD(param2);
g_current_window.load()->push_event(event);
break;
default:
result = DefWindowProc(window_handle, message, param1, param2);
break;
}
return result;
}
Win32Window::Win32Window(const std::string& title, unsigned width, unsigned height) :
m_window_handle(),
m_message_thread(),
m_access_mutex()
m_window_thread()
{
WNDCLASSEX window_class;
window_class.cbSize = sizeof(window_class);
window_class.style = 0;
window_class.lpfnWndProc = DefWindowProc;
window_class.cbClsExtra = 0;
window_class.hInstance = g_instance;
const TCHAR* class_name = title.c_str();
window_class.lpszClassName = class_name;
if(!RegisterClassEx(&window_class))
LOG_FATAL("Failed to register window class");
m_window_handle = CreateWindowEx(WS_EX_LEFT, class_name, nullptr, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, nullptr, nullptr, g_instance, nullptr);
if(!m_window_handle)
LOG_FATAL("Failed to create window");
ShowWindow(m_window_handle, false);
UpdateWindow(m_window_handle);
m_message_thread.reset(new std::thread(&Win32Window::message_thread_func, this));
g_current_window = this;
m_window_thread.reset(new std::thread(&Win32Window::window_thread_func, this, title, width, height));
}
Win32Window::~Win32Window() {
if(m_message_thread->joinable())
m_message_thread->join();
if(m_window_thread->joinable())
m_window_thread->join();
}
size_t Win32Window::poll_events(Event& event) {
return Window::poll_events(event);
}
void Win32Window::message_thread_func() {
MSG msg;
while(GetMessage(&msg, m_window_handle, 0, 0)) {
void Win32Window::window_thread_func(const std::string& title, unsigned width, unsigned height) {
WNDCLASS window_class={0};
window_class.lpfnWndProc = window_proc;
window_class.hInstance = g_instance;
const char class_name[] = "polygun";
window_class.lpszClassName = class_name;
if(!RegisterClass(&window_class))
LOG_FATAL("Failed to register window class (error code: %d)", GetLastError());
m_window_handle = CreateWindowEx(0, class_name, title.c_str(), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, nullptr, nullptr, g_instance, nullptr);
if(!m_window_handle)
LOG_FATAL("Failed to create window (error code: %d)", GetLastError());
ShowWindow(m_window_handle, true);
MSG msg={0};
while(GetMessage(&msg, m_window_handle, 0, 0)>0) {
g_current_window = this;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
m_access_mutex.lock();
acquire();
Event close_event;
close_event.m_type = EventType::EVENT_TYPE_WINDOW_CLOSE;
m_event_queue.push_back(close_event);
release();
}

View File

@ -28,7 +28,6 @@ SOFTWARE.
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <thread>
#include <mutex>
#include <memory>
namespace polygun::window {
@ -41,10 +40,9 @@ namespace polygun::window {
private:
HWND m_window_handle;
std::unique_ptr<std::thread> m_message_thread;
std::mutex m_access_mutex;
std::unique_ptr<std::thread> m_window_thread;
private:
void message_thread_func();
void window_thread_func(const std::string& title, unsigned width, unsigned height);
};
}

View File

@ -24,12 +24,38 @@ SOFTWARE.
#include "game/window/window.hpp"
#include <config.hpp>
#if defined(WINDOW_WIN32)
#include "game/window/win32_window.hpp"
#endif
#include "common/logger.hpp"
using namespace polygun::window;
void Window::push_event(const Event& event) {
acquire();
m_event_queue.push_back(event);
release();
}
size_t Window::poll_events(Event& event) {
acquire();
size_t result = m_event_queue.size();
if(!m_event_queue.empty()) {
event = m_event_queue.back();
m_event_queue.pop_back();
}
return m_event_queue.size();
release();
return result;
}
Window* Window::create_window(const std::string& title, unsigned width, unsigned height) {
#if defined(_WIN32)
#if defined(WINDOW_WIN32)
return new Win32Window(title, width, height);
#else
LOG_FATAL("Win32Window creation is not compiled in");
return nullptr;
#endif
#endif
}

View File

@ -25,21 +25,30 @@ SOFTWARE.
#ifndef POLYGUN_WINDOW_WINDOW_HPP
#define POLYGUN_WINDOW_WINDOW_HPP
#include "common/thread_safe.hpp"
#include <vector>
#include <string>
#include "game/window/event.hpp"
namespace polygun::window {
class Window {
class Window : public utils::ThreadSafe{
public:
Window() = default;
virtual ~Window() {}
void push_event(const Event& event);
virtual size_t poll_events(Event& event);
static Window* create_window(const std::string& title, unsigned width, unsigned height);
protected:
std::vector<Event> m_event_queue;
int m_mouse_x;
int m_mouse_y;
};
}

View File

@ -11,6 +11,7 @@
#include "common/command_arguments_parser.hpp"
#include "common/logger.hpp"
#include "common/locale/translation_manager.hpp"
#include "game/window/window.hpp"
int main(int argc, char** argv) {
polygun::utils::Logger::create(false, true);
@ -54,8 +55,18 @@ int main(int argc, char** argv) {
direct_join->m_host_server = false;
}
polygun::audio::init();
polygun::engine::Engine engine;
engine.init(direct_join);
//polygun::engine::Engine engine;
//engine.init(direct_join);
polygun::window::Window* wnd = polygun::window::Window::create_window("PolyGun", 800, 600);
polygun::window::Event event;
bool running = true;
while(running) {
while(wnd->poll_events(event)>0) {
if(event.m_type==polygun::window::EventType::EVENT_TYPE_WINDOW_CLOSE)
running = false;
}
}
delete wnd;
polygun::audio::cleanup();
if(direct_join)
delete direct_join;