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 "game/window/win32_window.hpp"
#include <atomic>
#include "common/logger.hpp" #include "common/logger.hpp"
using namespace polygun::window; using namespace polygun::window;
static HINSTANCE g_instance; static HINSTANCE g_instance;
static std::atomic<Win32Window*> g_current_window = nullptr;
extern int main(int argc, char** args); extern int main(int argc, char** args);
int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev_inst, PTSTR cmd_line, int show_cmd) { int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev_inst, PTSTR cmd_line, int show_cmd) {
g_instance = inst; 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) : Win32Window::Win32Window(const std::string& title, unsigned width, unsigned height) :
m_window_handle(), m_window_handle(),
m_message_thread(), m_window_thread()
m_access_mutex()
{ {
WNDCLASSEX window_class; g_current_window = this;
window_class.cbSize = sizeof(window_class); m_window_thread.reset(new std::thread(&Win32Window::window_thread_func, this, title, width, height));
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));
} }
Win32Window::~Win32Window() { Win32Window::~Win32Window() {
if(m_message_thread->joinable()) if(m_window_thread->joinable())
m_message_thread->join(); m_window_thread->join();
} }
size_t Win32Window::poll_events(Event& event) { size_t Win32Window::poll_events(Event& event) {
return Window::poll_events(event); return Window::poll_events(event);
} }
void Win32Window::message_thread_func() { void Win32Window::window_thread_func(const std::string& title, unsigned width, unsigned height) {
MSG msg; WNDCLASS window_class={0};
while(GetMessage(&msg, m_window_handle, 0, 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); TranslateMessage(&msg);
DispatchMessage(&msg); DispatchMessage(&msg);
} }
m_access_mutex.lock();
acquire();
Event close_event; Event close_event;
close_event.m_type = EventType::EVENT_TYPE_WINDOW_CLOSE; close_event.m_type = EventType::EVENT_TYPE_WINDOW_CLOSE;
m_event_queue.push_back(close_event); m_event_queue.push_back(close_event);
release();
} }

View File

@ -28,7 +28,6 @@ SOFTWARE.
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <windows.h> #include <windows.h>
#include <thread> #include <thread>
#include <mutex>
#include <memory> #include <memory>
namespace polygun::window { namespace polygun::window {
@ -41,10 +40,9 @@ namespace polygun::window {
private: private:
HWND m_window_handle; HWND m_window_handle;
std::unique_ptr<std::thread> m_message_thread; std::unique_ptr<std::thread> m_window_thread;
std::mutex m_access_mutex;
private: 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 "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; 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) { size_t Window::poll_events(Event& event) {
acquire();
size_t result = m_event_queue.size();
if(!m_event_queue.empty()) { if(!m_event_queue.empty()) {
event = m_event_queue.back(); event = m_event_queue.back();
m_event_queue.pop_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 #ifndef POLYGUN_WINDOW_WINDOW_HPP
#define POLYGUN_WINDOW_WINDOW_HPP #define POLYGUN_WINDOW_WINDOW_HPP
#include "common/thread_safe.hpp"
#include <vector> #include <vector>
#include <string>
#include "game/window/event.hpp" #include "game/window/event.hpp"
namespace polygun::window { namespace polygun::window {
class Window { class Window : public utils::ThreadSafe{
public: public:
Window() = default; Window() = default;
virtual ~Window() {} virtual ~Window() {}
void push_event(const Event& event);
virtual size_t poll_events(Event& event); virtual size_t poll_events(Event& event);
static Window* create_window(const std::string& title, unsigned width, unsigned height);
protected: protected:
std::vector<Event> m_event_queue; 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/command_arguments_parser.hpp"
#include "common/logger.hpp" #include "common/logger.hpp"
#include "common/locale/translation_manager.hpp" #include "common/locale/translation_manager.hpp"
#include "game/window/window.hpp"
int main(int argc, char** argv) { int main(int argc, char** argv) {
polygun::utils::Logger::create(false, true); polygun::utils::Logger::create(false, true);
@ -54,8 +55,18 @@ int main(int argc, char** argv) {
direct_join->m_host_server = false; direct_join->m_host_server = false;
} }
polygun::audio::init(); polygun::audio::init();
polygun::engine::Engine engine; //polygun::engine::Engine engine;
engine.init(direct_join); //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(); polygun::audio::cleanup();
if(direct_join) if(direct_join)
delete direct_join; delete direct_join;