1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2025-12-22 15:23:01 +01:00

Enable display scaling, useful on highdpi screens

This allows for NN-scaling of display, a much needed feature on highdpi
screens.

Scale can be set to positive integer value which will become a zoom
factor for whole rendered output.
This commit is contained in:
Michał Janiszewski
2015-11-09 00:02:51 +01:00
parent ed8e7c2d38
commit 681723869f
4 changed files with 47 additions and 20 deletions

View File

@@ -28,7 +28,7 @@
- Feature: Custom user data path specified by command line argument. - Feature: Custom user data path specified by command line argument.
- Feature: Full UTF-8 language support. - Feature: Full UTF-8 language support.
- Feature: TTF font integration for non-Latin languages. - Feature: TTF font integration for non-Latin languages.
- Feature: Added support for Traditional Chinese, Simplified Chinese, Korean, Russian, Finnish and Brazilian Portuguese. - Feature: Added support for Traditional Chinese, Simplified Chinese, Korean, Russian, Finnish and Brazilian Portuguese.
- Feature: Added South Korean Won and Russian Rouble as currencies. - Feature: Added South Korean Won and Russian Rouble as currencies.
- Feature: Allow different date formats. - Feature: Allow different date formats.
- Feature: Option to automatically pause the game on minimise from fullscreen. - Feature: Option to automatically pause the game on minimise from fullscreen.
@@ -38,6 +38,7 @@
- Feature: Option to automatically place staff after hire. - Feature: Option to automatically place staff after hire.
- Feature: Option to enable 'mow grass' by default for handymen (RCT1 style) - Feature: Option to enable 'mow grass' by default for handymen (RCT1 style)
- Feature: Option to ignore invalid checksums on loaded parks. - Feature: Option to ignore invalid checksums on loaded parks.
- Feature: Option to scale game display for better compatibility with high DPI screens.
- Alteration: Autosave is now measured in real-time rather than in-game date. - Alteration: Autosave is now measured in real-time rather than in-game date.
- Technical: DirectDraw, DirectInput, DirectPlay and DirectSound dependencies are no longer used. - Technical: DirectDraw, DirectInput, DirectPlay and DirectSound dependencies are no longer used.
- Removed: Six Flags branding and limitations. - Removed: Six Flags branding and limitations.

View File

@@ -197,6 +197,7 @@ config_property_definition _generalDefinitions[] = {
{ offsetof(general_configuration, upper_case_banners), "upper_case_banners", CONFIG_VALUE_TYPE_BOOLEAN, false, NULL }, { offsetof(general_configuration, upper_case_banners), "upper_case_banners", CONFIG_VALUE_TYPE_BOOLEAN, false, NULL },
{ offsetof(general_configuration, allow_loading_with_incorrect_checksum),"allow_loading_with_incorrect_checksum", CONFIG_VALUE_TYPE_BOOLEAN, false, NULL }, { offsetof(general_configuration, allow_loading_with_incorrect_checksum),"allow_loading_with_incorrect_checksum", CONFIG_VALUE_TYPE_BOOLEAN, false, NULL },
{ offsetof(general_configuration, steam_overlay_pause), "steam_overlay_pause", CONFIG_VALUE_TYPE_BOOLEAN, true, NULL }, { offsetof(general_configuration, steam_overlay_pause), "steam_overlay_pause", CONFIG_VALUE_TYPE_BOOLEAN, true, NULL },
{ offsetof(general_configuration, scale), "scale", CONFIG_VALUE_TYPE_SINT8, 1, NULL },
}; };
config_property_definition _interfaceDefinitions[] = { config_property_definition _interfaceDefinitions[] = {

View File

@@ -167,6 +167,7 @@ typedef struct {
uint8 upper_case_banners; uint8 upper_case_banners;
uint8 allow_loading_with_incorrect_checksum; uint8 allow_loading_with_incorrect_checksum;
uint8 steam_overlay_pause; uint8 steam_overlay_pause;
sint8 scale;
} general_configuration; } general_configuration;
typedef struct { typedef struct {

View File

@@ -65,8 +65,9 @@ bool gHardwareDisplay;
bool gSteamOverlayActive = false; bool gSteamOverlayActive = false;
static SDL_Surface *_surface; static SDL_Surface *_surface = NULL;
static SDL_Palette *_palette; static SDL_Surface *_RGBASurface = NULL;
static SDL_Palette *_palette = NULL;
static void *_screenBuffer; static void *_screenBuffer;
static int _screenBufferSize; static int _screenBufferSize;
@@ -285,9 +286,24 @@ void platform_draw()
SDL_UnlockSurface(_surface); SDL_UnlockSurface(_surface);
// Copy the surface to the window // Copy the surface to the window
if (SDL_BlitSurface(_surface, NULL, SDL_GetWindowSurface(gWindow), NULL)) { if (gConfigGeneral.scale == 1 || gConfigGeneral.scale <= 0)
log_fatal("SDL_BlitSurface %s", SDL_GetError()); {
exit(1); if (SDL_BlitSurface(_surface, NULL, SDL_GetWindowSurface(gWindow), NULL)) {
log_fatal("SDL_BlitSurface %s", SDL_GetError());
exit(1);
}
} else {
// first blit to rgba surface to change the pixel format
if (SDL_BlitSurface(_surface, NULL, _RGBASurface, NULL)) {
log_fatal("SDL_BlitSurface %s", SDL_GetError());
exit(1);
}
// then scale to window size. Without changing to RGBA first, SDL complains
// about blit configurations being incompatible.
if (SDL_BlitScaled(_RGBASurface, NULL, SDL_GetWindowSurface(gWindow), NULL)) {
log_fatal("SDL_BlitScaled %s", SDL_GetError());
exit(1);
}
} }
if (SDL_UpdateWindowSurface(gWindow)) { if (SDL_UpdateWindowSurface(gWindow)) {
log_fatal("SDL_UpdateWindowSurface %s", SDL_GetError()); log_fatal("SDL_UpdateWindowSurface %s", SDL_GetError());
@@ -300,17 +316,19 @@ void platform_draw()
static void platform_resize(int width, int height) static void platform_resize(int width, int height)
{ {
uint32 flags; uint32 flags;
int dst_w = width / gConfigGeneral.scale;
int dst_h = height / gConfigGeneral.scale;
RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, uint16) = width; RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, uint16) = dst_w;
RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, uint16) = height; RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, uint16) = dst_h;
platform_refresh_video(); platform_refresh_video();
flags = SDL_GetWindowFlags(gWindow); flags = SDL_GetWindowFlags(gWindow);
if ((flags & SDL_WINDOW_MINIMIZED) == 0) { if ((flags & SDL_WINDOW_MINIMIZED) == 0) {
window_resize_gui(width, height); window_resize_gui(dst_w, dst_h);
window_relocate_windows(width, height); window_relocate_windows(dst_w, dst_h);
} }
title_fix_location(); title_fix_location();
@@ -421,11 +439,11 @@ void platform_process_messages()
} }
break; break;
case SDL_MOUSEMOTION: case SDL_MOUSEMOTION:
RCT2_GLOBAL(0x0142406C, int) = e.motion.x; RCT2_GLOBAL(0x0142406C, int) = e.motion.x / gConfigGeneral.scale;
RCT2_GLOBAL(0x01424070, int) = e.motion.y; RCT2_GLOBAL(0x01424070, int) = e.motion.y / gConfigGeneral.scale;
gCursorState.x = e.motion.x; gCursorState.x = e.motion.x / gConfigGeneral.scale;
gCursorState.y = e.motion.y; gCursorState.y = e.motion.y / gConfigGeneral.scale;
break; break;
case SDL_MOUSEWHEEL: case SDL_MOUSEWHEEL:
if (gConsoleOpen) { if (gConsoleOpen) {
@@ -435,8 +453,8 @@ void platform_process_messages()
gCursorState.wheel += e.wheel.y * 128; gCursorState.wheel += e.wheel.y * 128;
break; break;
case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONDOWN:
RCT2_GLOBAL(0x01424318, int) = e.button.x; RCT2_GLOBAL(0x01424318, int) = e.button.x / gConfigGeneral.scale;
RCT2_GLOBAL(0x0142431C, int) = e.button.y; RCT2_GLOBAL(0x0142431C, int) = e.button.y / gConfigGeneral.scale;
switch (e.button.button) { switch (e.button.button) {
case SDL_BUTTON_LEFT: case SDL_BUTTON_LEFT:
store_mouse_input(1); store_mouse_input(1);
@@ -454,8 +472,8 @@ void platform_process_messages()
} }
break; break;
case SDL_MOUSEBUTTONUP: case SDL_MOUSEBUTTONUP:
RCT2_GLOBAL(0x01424318, int) = e.button.x; RCT2_GLOBAL(0x01424318, int) = e.button.x / gConfigGeneral.scale;
RCT2_GLOBAL(0x0142431C, int) = e.button.y; RCT2_GLOBAL(0x0142431C, int) = e.button.y / gConfigGeneral.scale;
switch (e.button.button) { switch (e.button.button) {
case SDL_BUTTON_LEFT: case SDL_BUTTON_LEFT:
store_mouse_input(2); store_mouse_input(2);
@@ -644,6 +662,8 @@ static void platform_close_window()
SDL_FreeSurface(_surface); SDL_FreeSurface(_surface);
if (_palette != NULL) if (_palette != NULL)
SDL_FreePalette(_palette); SDL_FreePalette(_palette);
if (_RGBASurface != NULL)
SDL_FreeSurface(_RGBASurface);
platform_unload_cursors(); platform_unload_cursors();
} }
@@ -916,14 +936,18 @@ void platform_refresh_video()
} else { } else {
if (_surface != NULL) if (_surface != NULL)
SDL_FreeSurface(_surface); SDL_FreeSurface(_surface);
if (_RGBASurface != NULL)
SDL_FreeSurface(_RGBASurface);
if (_palette != NULL) if (_palette != NULL)
SDL_FreePalette(_palette); SDL_FreePalette(_palette);
_surface = SDL_CreateRGBSurface(0, width, height, 8, 0, 0, 0, 0); _surface = SDL_CreateRGBSurface(0, width, height, 8, 0, 0, 0, 0);
_RGBASurface = SDL_CreateRGBSurface(0, width, height, 32, 0, 0, 0, 0);
SDL_SetSurfaceBlendMode(_RGBASurface, SDL_BLENDMODE_NONE);
_palette = SDL_AllocPalette(256); _palette = SDL_AllocPalette(256);
if (!_surface || !_palette) { if (!_surface || !_palette || !_RGBASurface) {
log_fatal("%p || %p == NULL %s", _surface, _palette, SDL_GetError()); log_fatal("%p || %p || %p == NULL %s", _surface, _palette, _RGBASurface, SDL_GetError());
exit(-1); exit(-1);
} }