tr2/shell: fix high dpi problems

Resolves #1845.
This commit is contained in:
Marcin Kurczewski 2024-12-12 19:44:28 +01:00
parent fa6fefa4ca
commit 5694724529
6 changed files with 90 additions and 59 deletions

View file

@ -44,6 +44,7 @@
- fixed resizing game window on the stats dialog cloning the UI elements, eventually crashing the game (#1999)
- fixed exiting the game with Alt+F4 not immediately working in cutscenes
- fixed game freezing when starting demo/credits/inventory offscreen
- fixed problems when trying to launch the game with High DPI mode enabled (#1845)
- fixed controllers dialog missing background in the software renderer mode (#1978, regression from 0.6)
- fixed a crash relating to audio decoding (#1895, regression from 0.2)
- fixed depth problems when drawing certain rooms (#1853, regression from 0.6)

View file

@ -3,6 +3,73 @@
#include "log.h"
#include "memory.h"
#ifdef _WIN32
#include <objbase.h>
#include <windows.h>
#endif
#include <libavcodec/version.h>
static void M_SetupHiDPI(void);
static void M_SetupLibAV(void);
static void M_SetupSDL(void);
static void M_ShowFatalError(const char *message);
static void M_SetupHiDPI(void)
{
#ifdef _WIN32
// Enable HiDPI mode in Windows to detect DPI scaling
typedef enum {
PROCESS_DPI_UNAWARE = 0,
PROCESS_SYSTEM_DPI_AWARE = 1,
PROCESS_PER_MONITOR_DPI_AWARE = 2
} PROCESS_DPI_AWARENESS;
HRESULT(WINAPI * SetProcessDpiAwareness)
(PROCESS_DPI_AWARENESS dpiAwareness); // Windows 8.1 and later
void *shcore_dll = SDL_LoadObject("SHCORE.DLL");
if (shcore_dll) {
SetProcessDpiAwareness =
(HRESULT(WINAPI *)(PROCESS_DPI_AWARENESS))SDL_LoadFunction(
shcore_dll, "SetProcessDpiAwareness");
if (SetProcessDpiAwareness) {
SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
}
}
#endif
}
static void M_SetupLibAV(void)
{
#ifdef _WIN32
// necessary for SDL_OpenAudioDevice to work with WASAPI
// https://www.mail-archive.com/ffmpeg-trac@avcodec.org/msg43300.html
CoInitializeEx(NULL, COINIT_MULTITHREADED);
#endif
#if LIBAVCODEC_VERSION_MAJOR <= 57
av_register_all();
#endif
}
static void M_SetupSDL(void)
{
if (SDL_Init(SDL_INIT_EVENTS | SDL_INIT_VIDEO) < 0) {
Shell_ExitSystemFmt("Cannot initialize SDL: %s", SDL_GetError());
}
}
static void M_SetupGL(void)
{
// Setup minimum properties of GL context
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
}
static void M_ShowFatalError(const char *const message)
{
LOG_ERROR("%s", message);
@ -12,6 +79,14 @@ static void M_ShowFatalError(const char *const message)
Shell_Terminate(1);
}
void Shell_Setup(void)
{
M_SetupHiDPI();
M_SetupLibAV();
M_SetupSDL();
M_SetupGL();
}
void Shell_Terminate(int32_t exit_code)
{
Shell_Shutdown();

View file

@ -109,6 +109,7 @@ GFX_2D_RENDERER *GFX_2D_Renderer_Create(void)
r->vertices = NULL;
r->vertex_count = 6;
r->vertex_format.initialized = false;
GFX_GL_Buffer_Init(&r->surface_buffer, GL_ARRAY_BUFFER);
GFX_GL_Buffer_Bind(&r->surface_buffer);

View file

@ -6,6 +6,7 @@
extern void Shell_Shutdown(void);
extern SDL_Window *Shell_GetWindow(void);
void Shell_Setup(void);
void Shell_Terminate(int32_t exit_code);
void Shell_ExitSystem(const char *message);
void Shell_ExitSystemFmt(const char *fmt, ...);

View file

@ -17,14 +17,8 @@
#include <libtrx/log.h>
#include <libtrx/memory.h>
#include <libavcodec/version.h>
#define SDL_MAIN_HANDLED
#ifdef _WIN32
#include <objbase.h>
#include <windows.h>
#endif
#include <libtrx/debug.h>
#include <SDL2/SDL.h>
@ -248,53 +242,11 @@ int main(int argc, char **argv)
LOG_INFO("Game directory: %s", File_GetGameDirectory());
#ifdef _WIN32
// Enable HiDPI mode in Windows to detect DPI scaling
typedef enum {
PROCESS_DPI_UNAWARE = 0,
PROCESS_SYSTEM_DPI_AWARE = 1,
PROCESS_PER_MONITOR_DPI_AWARE = 2
} PROCESS_DPI_AWARENESS;
HRESULT(WINAPI * SetProcessDpiAwareness)
(PROCESS_DPI_AWARENESS dpiAwareness); // Windows 8.1 and later
void *shcore_dll = SDL_LoadObject("SHCORE.DLL");
if (shcore_dll) {
SetProcessDpiAwareness =
(HRESULT(WINAPI *)(PROCESS_DPI_AWARENESS))SDL_LoadFunction(
shcore_dll, "SetProcessDpiAwareness");
if (SetProcessDpiAwareness) {
SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
}
}
// necessary for SDL_OpenAudioDevice to work with WASAPI
// https://www.mail-archive.com/ffmpeg-trac@avcodec.org/msg43300.html
CoInitializeEx(NULL, COINIT_MULTITHREADED);
#endif
#if LIBAVCODEC_VERSION_MAJOR <= 57
av_register_all();
#endif
m_ArgCount = argc;
m_ArgStrings = argv;
if (SDL_Init(SDL_INIT_EVENTS | SDL_INIT_VIDEO) < 0) {
Shell_ExitSystemFmt("Cannot initialize SDL: %s", SDL_GetError());
return 1;
}
// Setup minimum properties of GL context
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
Shell_Setup();
Shell_Main();
Shell_Terminate(0);
return 0;
}
@ -323,6 +275,16 @@ static void M_SetGLBackend(const GFX_GL_BACKEND backend)
void S_Shell_CreateWindow(void)
{
SDL_Window *const window = SDL_CreateWindow(
"TR1X", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1280, 720,
SDL_WINDOW_HIDDEN | SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_RESIZABLE
| SDL_WINDOW_OPENGL);
if (window == NULL) {
Shell_ExitSystem("System Error: cannot create window");
return;
}
const GFX_GL_BACKEND backends_to_try[] = {
// clang-format off
GFX_GL_33C,
@ -336,16 +298,6 @@ void S_Shell_CreateWindow(void)
M_SetGLBackend(backend);
SDL_Window *const window = SDL_CreateWindow(
"TR1X", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1280, 720,
SDL_WINDOW_HIDDEN | SDL_WINDOW_FULLSCREEN_DESKTOP
| SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL);
if (window == NULL) {
Shell_ExitSystem("System Error: cannot create window");
return;
}
int32_t major;
int32_t minor;
SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, &major);

View file

@ -60,6 +60,7 @@ int32_t __stdcall WinMain(
g_AppResultCode = 0;
g_IsGameToExit = false;
Shell_Setup();
Shell_Main();
Shell_Shutdown();