diff --git a/src/kiwano/platform/Runner.cpp b/src/kiwano/platform/Runner.cpp index 737e294b..e2e0463c 100644 --- a/src/kiwano/platform/Runner.cpp +++ b/src/kiwano/platform/Runner.cpp @@ -82,8 +82,7 @@ void Runner::InitSettings() } // Create game window - WindowPtr window = Window::Create(settings_.title, settings_.width, settings_.height, settings_.icon, - settings_.resizable, settings_.fullscreen); + WindowPtr window = Window::Create(settings_.window); SetWindow(window); // Update renderer settings @@ -131,9 +130,9 @@ bool Runner::MainLoop(Duration dt) app.DispatchEvent(evt.Get()); } - // Update frame ticker if (frame_ticker_) { + // Update frame ticker if (frame_ticker_->Tick(dt)) { app.UpdateFrame(frame_ticker_->GetDeltaTime()); diff --git a/src/kiwano/platform/Runner.h b/src/kiwano/platform/Runner.h index 7240c573..dfe1da94 100644 --- a/src/kiwano/platform/Runner.h +++ b/src/kiwano/platform/Runner.h @@ -40,25 +40,14 @@ KGE_DECLARE_SMART_PTR(Runner); */ struct Settings { - uint32_t width; ///< 窗口宽度 - uint32_t height; ///< 窗口高度 - String title; ///< 窗口标题 - Icon icon; ///< 窗口图标 - bool resizable; ///< 窗口大小可调整 - bool fullscreen; ///< 窗口全屏 - Color bg_color; ///< 窗口背景色 - Duration frame_interval; ///< 帧间隔 - bool vsync_enabled; ///< 垂直同步 - bool debug_mode; ///< 调试模式 + WindowConfig window; ///< 窗口设置 + Color bg_color; ///< 背景色 + Duration frame_interval; ///< 帧间隔 + bool vsync_enabled; ///< 垂直同步 + bool debug_mode; ///< 调试模式 Settings() - : width(800) - , height(600) - , title("Kiwano") - , icon() - , resizable(false) - , fullscreen(false) - , bg_color(Color::Black) + : bg_color(Color::Black) , frame_interval(0) , vsync_enabled(true) , debug_mode(false) diff --git a/src/kiwano/platform/Window.h b/src/kiwano/platform/Window.h index 8b002286..77744ea3 100644 --- a/src/kiwano/platform/Window.h +++ b/src/kiwano/platform/Window.h @@ -82,6 +82,21 @@ struct Icon }; +/** + * \~chinese + * @brief 窗口设置 + */ +struct WindowConfig +{ + uint32_t width = 640; ///< 窗口宽度 + uint32_t height = 480; ///< 窗口高度 + String title = "Kiwano Game"; ///< 窗口标题 + Icon icon; ///< 窗口图标 + bool resizable = false; ///< 窗口大小可调整 + bool fullscreen = false; ///< 窗口全屏 +}; + + #if defined(KGE_PLATFORM_WINDOWS) typedef HWND WindowHandle; #endif @@ -97,15 +112,10 @@ public: /** * \~chinese * @brief 初始化窗口 - * @param title 标题 - * @param width 宽度 - * @param height 高度 - * @param icon 图标资源ID - * @param resizable 窗口大小可拉伸 + * @param config 窗口设置 * @throw kiwano::SystemError 窗口创建失败时抛出 */ - static WindowPtr Create(const String& title, uint32_t width, uint32_t height, Icon icon = Icon(), - bool resizable = false, bool fullscreen = false); + static WindowPtr Create(const WindowConfig& config); /** * \~chinese diff --git a/src/kiwano/platform/win32/WindowImpl.cpp b/src/kiwano/platform/win32/WindowImpl.cpp index b920bd34..abe33291 100644 --- a/src/kiwano/platform/win32/WindowImpl.cpp +++ b/src/kiwano/platform/win32/WindowImpl.cpp @@ -49,7 +49,7 @@ public: virtual ~WindowWin32Impl(); - void Init(const String& title, uint32_t width, uint32_t height, Icon icon, bool resizable, bool fullscreen); + void Init(const WindowConfig& config); void SetTitle(const String& title) override; @@ -88,13 +88,12 @@ private: std::array key_map_; }; -WindowPtr Window::Create(const String& title, uint32_t width, uint32_t height, Icon icon, bool resizable, - bool fullscreen) +WindowPtr Window::Create(const WindowConfig& config) { WindowWin32ImplPtr ptr = memory::New(); if (ptr) { - ptr->Init(title, width, height, icon, resizable, fullscreen); + ptr->Init(config); } return ptr; } @@ -142,6 +141,28 @@ void AdjustWindow(uint32_t width, uint32_t height, DWORD style, uint32_t* win_wi *win_height = screenh; } +HICON Icon2HIcon(const Icon& icon) +{ + HICON hicon = NULL; + if (icon.resource_id != 0 && IS_INTRESOURCE(icon.resource_id)) + { + HINSTANCE hinstance = ::GetModuleHandle(nullptr); + + hicon = (HICON)::LoadImage(hinstance, MAKEINTRESOURCE(icon.resource_id), IMAGE_ICON, 0, 0, + LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE); + } + else + { + String full_path = FileSystem::GetInstance().GetFullPathForFile(icon.file_path); + if (!full_path.empty()) + { + hicon = (HICON)::LoadImageA(NULL, full_path.c_str(), IMAGE_ICON, 0, 0, + LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE); + } + } + return hicon; +} + } // namespace WindowWin32Impl::WindowWin32Impl() @@ -206,16 +227,15 @@ WindowWin32Impl::~WindowWin32Impl() ::timeEndPeriod(0); } -void WindowWin32Impl::Init(const String& title, uint32_t width, uint32_t height, Icon icon, bool resizable, - bool fullscreen) +void WindowWin32Impl::Init(const WindowConfig& config) { - HINSTANCE hinst = GetModuleHandle(nullptr); + HINSTANCE hinst = GetModuleHandle(nullptr); WNDCLASSEXA wcex = { 0 }; wcex.cbSize = sizeof(WNDCLASSEX); wcex.lpszClassName = "KiwanoAppWnd"; wcex.style = CS_HREDRAW | CS_VREDRAW /* | CS_DBLCLKS */; wcex.lpfnWndProc = WindowWin32Impl::StaticWndProc; - wcex.hIcon = nullptr; + wcex.hIcon = Icon2HIcon(config.icon); wcex.cbClsExtra = 0; wcex.cbWndExtra = sizeof(LONG_PTR); wcex.hInstance = hinst; @@ -223,21 +243,6 @@ void WindowWin32Impl::Init(const String& title, uint32_t width, uint32_t height, wcex.lpszMenuName = nullptr; wcex.hCursor = ::LoadCursor(hinst, IDC_ARROW); - if (icon.resource_id != 0 && IS_INTRESOURCE(icon.resource_id)) - { - wcex.hIcon = (HICON)::LoadImage(hinst, MAKEINTRESOURCE(icon.resource_id), IMAGE_ICON, 0, 0, - LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE); - } - else - { - String full_path = FileSystem::GetInstance().GetFullPathForFile(icon.file_path); - if (!full_path.empty()) - { - wcex.hIcon = (HICON)::LoadImageA(NULL, full_path.c_str(), IMAGE_ICON, 0, 0, - LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE); - } - } - ::RegisterClassExA(&wcex); // Get the nearest monitor to this window @@ -256,21 +261,19 @@ void WindowWin32Impl::Init(const String& title, uint32_t width, uint32_t height, uint32_t screenh = monitor_info_ex.rcWork.bottom - monitor_info_ex.rcWork.top; uint32_t win_width, win_height; - AdjustWindow(width, height, GetStyle(), &win_width, &win_height); + AdjustWindow(config.width, config.height, GetStyle(), &win_width, &win_height); int left = monitor_info_ex.rcWork.left + (screenw - win_width) / 2; int top = monitor_info_ex.rcWork.top + (screenh - win_height) / 2; - width = win_width; - height = win_height; - width_ = width; - height_ = height; - resizable_ = resizable; - is_fullscreen_ = fullscreen; + width_ = win_width; + height_ = win_height; + resizable_ = config.resizable; + is_fullscreen_ = config.fullscreen; resolution_ = Resolution{ width_, height_, 0 }; - handle_ = ::CreateWindowExA(0, "KiwanoAppWnd", title.c_str(), GetStyle(), left, top, width, height, nullptr, - nullptr, hinst, nullptr); + handle_ = ::CreateWindowExA(0, "KiwanoAppWnd", config.title.c_str(), GetStyle(), left, top, width_, height_, + nullptr, nullptr, hinst, nullptr); if (handle_ == nullptr) { @@ -321,24 +324,7 @@ void WindowWin32Impl::SetIcon(Icon icon) { KGE_ASSERT(handle_); - HICON hicon = NULL; - if (icon.resource_id != 0 && IS_INTRESOURCE(icon.resource_id)) - { - HINSTANCE hinstance = ::GetModuleHandle(nullptr); - - hicon = (HICON)::LoadImage(hinstance, MAKEINTRESOURCE(icon.resource_id), IMAGE_ICON, 0, 0, - LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE); - } - else - { - String full_path = FileSystem::GetInstance().GetFullPathForFile(icon.file_path); - if (!full_path.empty()) - { - hicon = (HICON)::LoadImageA(NULL, full_path.c_str(), IMAGE_ICON, 0, 0, - LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE); - } - } - + HICON hicon = Icon2HIcon(icon); ::SendMessage(handle_, WM_SETICON, ICON_BIG, (LPARAM)hicon); ::SendMessage(handle_, WM_SETICON, ICON_SMALL, (LPARAM)hicon); }