mirror of
https://github.com/hedge-dev/UnleashedRecomp
synced 2026-05-29 08:43:12 -04:00
Window: add game icon and window events
This commit is contained in:
@@ -2,6 +2,80 @@
|
||||
#include <config.h>
|
||||
#include <kernel/function.h>
|
||||
#include <SDL_syswm.h>
|
||||
#include "game.h"
|
||||
|
||||
bool m_isFullscreenKeyReleased = true;
|
||||
|
||||
int Window_OnSDLEvent(void*, SDL_Event* event)
|
||||
{
|
||||
// TODO (Hyper): prevent window changes during boot to avoid buffer resize crashes.
|
||||
switch (event->type)
|
||||
{
|
||||
// TODO: use Game::Exit().
|
||||
case SDL_QUIT:
|
||||
ExitProcess(0);
|
||||
break;
|
||||
|
||||
case SDL_KEYDOWN:
|
||||
{
|
||||
switch (event->key.keysym.sym)
|
||||
{
|
||||
// Toggle fullscreen on ALT+ENTER.
|
||||
case SDLK_RETURN:
|
||||
{
|
||||
if (!(event->key.keysym.mod & KMOD_ALT) || !m_isFullscreenKeyReleased)
|
||||
break;
|
||||
|
||||
Window::SetFullscreen(!Window::IsFullscreen());
|
||||
|
||||
// Block holding ALT+ENTER spamming window changes.
|
||||
m_isFullscreenKeyReleased = false;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_KEYUP:
|
||||
{
|
||||
switch (event->key.keysym.sym)
|
||||
{
|
||||
// Allow user to input ALT+ENTER again.
|
||||
case SDLK_RETURN:
|
||||
m_isFullscreenKeyReleased = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
case SDL_WINDOWEVENT:
|
||||
{
|
||||
switch (event->window.event)
|
||||
{
|
||||
case SDL_WINDOWEVENT_FOCUS_LOST:
|
||||
Window::s_isFocused = false;
|
||||
SDL_ShowCursor(SDL_ENABLE);
|
||||
break;
|
||||
|
||||
case SDL_WINDOWEVENT_FOCUS_GAINED:
|
||||
Window::s_isFocused = true;
|
||||
SDL_ShowCursor(Window::IsFullscreen() ? SDL_DISABLE : SDL_ENABLE);
|
||||
break;
|
||||
|
||||
case SDL_WINDOWEVENT_RESIZED:
|
||||
Window::s_width = event->window.data1;
|
||||
Window::s_height = event->window.data2;
|
||||
Window::RaiseResizeEvents();
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Window::Init()
|
||||
{
|
||||
@@ -11,9 +85,18 @@ void Window::Init()
|
||||
|
||||
SDL_InitSubSystem(SDL_INIT_VIDEO);
|
||||
SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE);
|
||||
SDL_AddEventWatch(Window_OnSDLEvent, s_window);
|
||||
|
||||
s_window = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_RESIZABLE);
|
||||
|
||||
if (auto icon = GetIconSurface())
|
||||
{
|
||||
SDL_SetWindowIcon(s_window, icon);
|
||||
SDL_FreeSurface(icon);
|
||||
}
|
||||
|
||||
SetFullscreen(Config::Fullscreen);
|
||||
|
||||
SDL_SysWMinfo info;
|
||||
SDL_VERSION(&info.version);
|
||||
SDL_GetWindowWMInfo(s_window, &info);
|
||||
|
||||
+111
-2
@@ -1,10 +1,119 @@
|
||||
#pragma once
|
||||
|
||||
#include <SDL.h>
|
||||
#include "res/icon.h"
|
||||
|
||||
struct Window
|
||||
{
|
||||
static inline SDL_Window* s_window;
|
||||
static inline HWND s_windowHandle;
|
||||
inline static std::vector<std::function<void(int, int)>> ms_resizeEvents;
|
||||
|
||||
public:
|
||||
inline static SDL_Window* s_window;
|
||||
inline static HWND s_windowHandle;
|
||||
|
||||
inline static bool s_isFocused;
|
||||
|
||||
inline static int s_width;
|
||||
inline static int s_height;
|
||||
|
||||
static SDL_Surface* GetIconSurface(void* pIconBmp = nullptr)
|
||||
{
|
||||
auto rw = SDL_RWFromMem(pIconBmp ? pIconBmp : (void*)g_icon, g_icon_size);
|
||||
auto surface = SDL_LoadBMP_RW(rw, 1);
|
||||
|
||||
if (!surface)
|
||||
printf("Failed to load icon: %s\n", SDL_GetError());
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
static bool IsDisplayResolution(int w, int h, bool isExact = true)
|
||||
{
|
||||
auto width = w <= 0 ? Config::Width : w;
|
||||
auto height = h <= 0 ? Config::Height : h;
|
||||
|
||||
SDL_Rect displayRect;
|
||||
if (SDL_GetDisplayBounds(SDL_GetWindowDisplayIndex(s_window), &displayRect) == ERROR_SUCCESS)
|
||||
{
|
||||
if (isExact)
|
||||
{
|
||||
if (displayRect.w == width && displayRect.h == height)
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (displayRect.w <= width && displayRect.h <= height)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool IsFullscreen()
|
||||
{
|
||||
return SDL_GetWindowFlags(s_window) & SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||
}
|
||||
|
||||
static bool SetFullscreen(bool isEnabled)
|
||||
{
|
||||
if (isEnabled)
|
||||
{
|
||||
SDL_SetWindowFullscreen(s_window, SDL_WINDOW_FULLSCREEN_DESKTOP);
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_SetWindowFullscreen(s_window, 0);
|
||||
SDL_ShowCursor(SDL_ENABLE);
|
||||
|
||||
SDL_Rect displayRect;
|
||||
if (SDL_GetDisplayBounds(SDL_GetWindowDisplayIndex(s_window), &displayRect) == ERROR_SUCCESS)
|
||||
{
|
||||
// Maximise window if the config resolution is greater than the display.
|
||||
if (IsDisplayResolution(Config::Width, Config::Height, false))
|
||||
SDL_MaximizeWindow(s_window);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static void SetWindowDimensions(int w, int h)
|
||||
{
|
||||
auto width = w <= 0 ? Config::Width : w;
|
||||
auto height = h <= 0 ? Config::Height : h;
|
||||
auto isPendingMaximise = false;
|
||||
|
||||
if (IsDisplayResolution(width, height))
|
||||
{
|
||||
height -= GetSystemMetrics(31);
|
||||
isPendingMaximise = true;
|
||||
}
|
||||
|
||||
SDL_SetWindowSize(s_window, width, height);
|
||||
SDL_SetWindowMinimumSize(s_window, 640, 480);
|
||||
SDL_SetWindowPosition(s_window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
|
||||
|
||||
if (!isPendingMaximise)
|
||||
return;
|
||||
|
||||
// Maximise window if the config resolution matches the display.
|
||||
SDL_MaximizeWindow(s_window);
|
||||
}
|
||||
|
||||
static void AddResizeEvent(std::function<void(int, int)> resizeEvent)
|
||||
{
|
||||
ms_resizeEvents.push_back(resizeEvent);
|
||||
}
|
||||
|
||||
static void RaiseResizeEvents()
|
||||
{
|
||||
for (const auto& resizeEvent : ms_resizeEvents)
|
||||
resizeEvent(s_width, s_height);
|
||||
}
|
||||
|
||||
static void Init();
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user