summaryrefslogtreecommitdiff
path: root/Source/Core/DolphinNoGUI/PlatformWin32.cpp
diff options
context:
space:
mode:
authorStenzek <stenzek@gmail.com>2019-11-26 15:25:19 +1100
committerStenzek <stenzek@gmail.com>2019-12-28 08:56:27 +1000
commit5a65031611349e22bdcd694479f11c91d87afca7 (patch)
tree4693fab8401d13e95d19a5443d8fd7e4924780d0 /Source/Core/DolphinNoGUI/PlatformWin32.cpp
parent0755f9297957881e5c487378a7ba0a9fe92cbd42 (diff)
Add a Win32 NoGUI platform and project
Diffstat (limited to 'Source/Core/DolphinNoGUI/PlatformWin32.cpp')
-rw-r--r--Source/Core/DolphinNoGUI/PlatformWin32.cpp201
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>();
+}