diff options
| author | Stenzek <stenzek@gmail.com> | 2019-11-26 15:25:19 +1100 |
|---|---|---|
| committer | Stenzek <stenzek@gmail.com> | 2019-12-28 08:56:27 +1000 |
| commit | 5a65031611349e22bdcd694479f11c91d87afca7 (patch) | |
| tree | 4693fab8401d13e95d19a5443d8fd7e4924780d0 /Source/Core/DolphinNoGUI/PlatformWin32.cpp | |
| parent | 0755f9297957881e5c487378a7ba0a9fe92cbd42 (diff) | |
Add a Win32 NoGUI platform and project
Diffstat (limited to 'Source/Core/DolphinNoGUI/PlatformWin32.cpp')
| -rw-r--r-- | Source/Core/DolphinNoGUI/PlatformWin32.cpp | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/Source/Core/DolphinNoGUI/PlatformWin32.cpp b/Source/Core/DolphinNoGUI/PlatformWin32.cpp new file mode 100644 index 0000000000..add981b361 --- /dev/null +++ b/Source/Core/DolphinNoGUI/PlatformWin32.cpp @@ -0,0 +1,201 @@ +// Copyright 2019 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "DolphinNoGUI/Platform.h" + +#include "Common/MsgHandler.h" +#include "Core/Config/MainSettings.h" +#include "Core/ConfigManager.h" +#include "Core/Core.h" +#include "Core/State.h" + +#include <Windows.h> +#include <climits> +#include <cstdio> + +#include "VideoCommon/RenderBase.h" +#include "resource.h" + +namespace +{ +class PlatformWin32 : public Platform +{ +public: + ~PlatformWin32() override; + + bool Init() override; + void SetTitle(const std::string& string) override; + void MainLoop() override; + + WindowSystemInfo GetWindowSystemInfo() const; + +private: + static constexpr TCHAR WINDOW_CLASS_NAME[] = _T("DolphinNoGUI"); + + static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); + + bool RegisterRenderWindowClass(); + bool CreateRenderWindow(); + void UpdateWindowPosition(); + void ProcessEvents(); + + HWND m_hwnd{}; + + int m_window_x = Config::Get(Config::MAIN_RENDER_WINDOW_XPOS); + int m_window_y = Config::Get(Config::MAIN_RENDER_WINDOW_YPOS); + int m_window_width = Config::Get(Config::MAIN_RENDER_WINDOW_WIDTH); + int m_window_height = Config::Get(Config::MAIN_RENDER_WINDOW_HEIGHT); +}; + +PlatformWin32::~PlatformWin32() +{ + if (m_hwnd) + DestroyWindow(m_hwnd); +} + +bool PlatformWin32::RegisterRenderWindowClass() +{ + WNDCLASSEX wc = {}; + wc.cbSize = sizeof(WNDCLASSEX); + wc.style = 0; + wc.lpfnWndProc = WndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = GetModuleHandle(nullptr); + wc.hIcon = LoadIcon(NULL, IDI_ICON1); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); + wc.lpszMenuName = NULL; + wc.lpszClassName = WINDOW_CLASS_NAME; + wc.hIconSm = LoadIcon(NULL, IDI_ICON1); + + if (!RegisterClassEx(&wc)) + { + MessageBox(nullptr, _T("Window registration failed."), _T("Error"), MB_ICONERROR | MB_OK); + return false; + } + + return true; +} + +bool PlatformWin32::CreateRenderWindow() +{ + m_hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, WINDOW_CLASS_NAME, _T("Dolphin"), WS_OVERLAPPEDWINDOW, + m_window_x < 0 ? CW_USEDEFAULT : m_window_x, + m_window_y < 0 ? CW_USEDEFAULT : m_window_y, m_window_width, + m_window_height, nullptr, nullptr, GetModuleHandle(nullptr), this); + if (!m_hwnd) + { + MessageBox(nullptr, _T("CreateWindowEx failed."), _T("Error"), MB_ICONERROR | MB_OK); + return false; + } + + ShowWindow(m_hwnd, SW_SHOW); + UpdateWindow(m_hwnd); + return true; +} + +bool PlatformWin32::Init() +{ + if (!RegisterRenderWindowClass() || !CreateRenderWindow()) + return false; + + // TODO: Enter fullscreen if enabled. + if (Config::Get(Config::MAIN_FULLSCREEN)) + { + ProcessEvents(); + } + + UpdateWindowPosition(); + return true; +} + +void PlatformWin32::SetTitle(const std::string& string) +{ + SetWindowTextW(m_hwnd, UTF8ToUTF16(string).c_str()); +} + +void PlatformWin32::MainLoop() +{ + while (IsRunning()) + { + UpdateRunningFlag(); + Core::HostDispatchJobs(); + ProcessEvents(); + UpdateWindowPosition(); + + // TODO: Is this sleep appropriate? + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } +} + +WindowSystemInfo PlatformWin32::GetWindowSystemInfo() const +{ + WindowSystemInfo wsi; + wsi.type = WindowSystemType::Windows; + wsi.render_surface = reinterpret_cast<void*>(m_hwnd); + return wsi; +} + +void PlatformWin32::UpdateWindowPosition() +{ + if (m_window_fullscreen) + return; + + RECT rc = {}; + if (!GetWindowRect(m_hwnd, &rc)) + return; + + m_window_x = rc.left; + m_window_y = rc.top; + m_window_width = rc.right - rc.left; + m_window_height = rc.bottom - rc.top; +} + +void PlatformWin32::ProcessEvents() +{ + MSG msg; + while (PeekMessage(&msg, m_hwnd, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } +} + +LRESULT PlatformWin32::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + PlatformWin32* platform = reinterpret_cast<PlatformWin32*>(GetWindowLongPtr(hwnd, GWLP_USERDATA)); + switch (msg) + { + case WM_NCCREATE: + { + platform = + reinterpret_cast<PlatformWin32*>(reinterpret_cast<CREATESTRUCT*>(lParam)->lpCreateParams); + SetWindowLongPtr(hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(platform)); + return DefWindowProc(hwnd, msg, wParam, lParam); + } + + case WM_SIZE: + { + if (g_renderer) + g_renderer->ResizeSurface(); + } + break; + + case WM_CLOSE: + platform->RequestShutdown(); + break; + + default: + return DefWindowProc(hwnd, msg, wParam, lParam); + } + + return 0; +} +} // namespace + +std::unique_ptr<Platform> Platform::CreateWin32Platform() +{ + return std::make_unique<PlatformWin32>(); +} |
