1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2025-12-19 05:52:27 +01:00

fix fullscreen resolution, fixes #89

This commit is contained in:
IntelOrca
2015-01-23 20:47:33 +00:00
parent a7a89fcf0f
commit 7cdcb6402e
6 changed files with 191 additions and 25 deletions

View File

@@ -88,6 +88,8 @@ general_configuration_t gGeneral_config_default = {
0, // show_height_as_units 0, // show_height_as_units
1, // save_plugin_data 1, // save_plugin_data
0, // fullscreen mode (default: windowed) 0, // fullscreen mode (default: windowed)
-1, // fullscreen_width
-1, // fullscreen_height
-1, // window_width -1, // window_width
-1, // window_height -1, // window_height
LANGUAGE_ENGLISH_UK, // language LANGUAGE_ENGLISH_UK, // language
@@ -252,6 +254,11 @@ void config_write_ini_general(FILE *fp)
else else
fprintf(fp, "fullscreen_mode = borderless_fullscreen\n"); fprintf(fp, "fullscreen_mode = borderless_fullscreen\n");
if (gGeneral_config.fullscreen_width != -1)
fprintf(fp, "fullscreen_width = %d\n", gGeneral_config.fullscreen_width);
if (gGeneral_config.window_height != -1)
fprintf(fp, "fullscreen_height = %d\n", gGeneral_config.fullscreen_height);
if (gGeneral_config.window_width != -1) if (gGeneral_config.window_width != -1)
fprintf(fp, "window_width = %d\n", gGeneral_config.window_width); fprintf(fp, "window_width = %d\n", gGeneral_config.window_width);
if (gGeneral_config.window_height != -1) if (gGeneral_config.window_height != -1)
@@ -557,6 +564,12 @@ static void config_general(char *setting, char *value){
else else
gGeneral_config.fullscreen_mode = 2; gGeneral_config.fullscreen_mode = 2;
} }
else if (strcmp(setting, "fullscreen_width") == 0) {
gGeneral_config.fullscreen_width = atoi(value);
}
else if (strcmp(setting, "fullscreen_height") == 0) {
gGeneral_config.fullscreen_height = atoi(value);
}
else if (strcmp(setting, "window_width") == 0) { else if (strcmp(setting, "window_width") == 0) {
gGeneral_config.window_width = atoi(value); gGeneral_config.window_width = atoi(value);
} }

View File

@@ -132,6 +132,8 @@ typedef struct general_configuration {
//new //new
uint8 fullscreen_mode; uint8 fullscreen_mode;
sint16 fullscreen_width;
sint16 fullscreen_height;
sint16 window_width; sint16 window_width;
sint16 window_height; sint16 window_height;
uint16 language; uint16 language;

View File

@@ -49,7 +49,6 @@ static void osinterface_create_window();
static void osinterface_close_window(); static void osinterface_close_window();
static void osinterface_resize(int width, int height); static void osinterface_resize(int width, int height);
static SDL_Window *_window;
static SDL_Surface *_surface; static SDL_Surface *_surface;
static SDL_Palette *_palette; static SDL_Palette *_palette;
@@ -204,16 +203,16 @@ static void osinterface_create_window()
RCT2_GLOBAL(0x009E2D8C, sint32) = 0; RCT2_GLOBAL(0x009E2D8C, sint32) = 0;
_window = SDL_CreateWindow("OpenRCT2", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, gWindow = SDL_CreateWindow("OpenRCT2", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height,
_fullscreen_modes[gGeneral_config.fullscreen_mode] | SDL_WINDOW_RESIZABLE); _fullscreen_modes[gGeneral_config.fullscreen_mode] | SDL_WINDOW_RESIZABLE);
if (!_window) { if (!gWindow) {
RCT2_ERROR("SDL_CreateWindow failed %s", SDL_GetError()); RCT2_ERROR("SDL_CreateWindow failed %s", SDL_GetError());
exit(-1); exit(-1);
} }
SDL_VERSION(&wmInfo.version); SDL_VERSION(&wmInfo.version);
// Get the HWND context // Get the HWND context
if (SDL_GetWindowWMInfo(_window, &wmInfo) != SDL_TRUE) { if (SDL_GetWindowWMInfo(gWindow, &wmInfo) != SDL_TRUE) {
RCT2_ERROR("SDL_GetWindowWMInfo failed %s", SDL_GetError()); RCT2_ERROR("SDL_GetWindowWMInfo failed %s", SDL_GetError());
exit(-1); exit(-1);
} }
@@ -225,6 +224,8 @@ static void osinterface_create_window()
// Initialise the surface, palette and draw buffer // Initialise the surface, palette and draw buffer
osinterface_resize(width, height); osinterface_resize(width, height);
platform_update_fullscreen_resolutions();
} }
@@ -297,7 +298,7 @@ void osinterface_update_palette(char* colours, int start_index, int num_colours)
SDL_Surface *surface; SDL_Surface *surface;
int i; int i;
surface = SDL_GetWindowSurface(_window); surface = SDL_GetWindowSurface(gWindow);
if (!surface) { if (!surface) {
RCT2_ERROR("SDL_GetWindowSurface failed %s", SDL_GetError()); RCT2_ERROR("SDL_GetWindowSurface failed %s", SDL_GetError());
exit(1); exit(1);
@@ -334,11 +335,11 @@ void osinterface_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(_window), NULL)) { if (SDL_BlitSurface(_surface, NULL, SDL_GetWindowSurface(gWindow), NULL)) {
RCT2_ERROR("SDL_BlitSurface %s", SDL_GetError()); RCT2_ERROR("SDL_BlitSurface %s", SDL_GetError());
exit(1); exit(1);
} }
if (SDL_UpdateWindowSurface(_window)) { if (SDL_UpdateWindowSurface(gWindow)) {
RCT2_ERROR("SDL_UpdateWindowSurface %s", SDL_GetError()); RCT2_ERROR("SDL_UpdateWindowSurface %s", SDL_GetError());
exit(1); exit(1);
} }
@@ -508,8 +509,8 @@ void osinterface_process_messages()
static void osinterface_close_window() static void osinterface_close_window()
{ {
if (_window != NULL) if (gWindow != NULL)
SDL_DestroyWindow(_window); SDL_DestroyWindow(gWindow);
if (_surface != NULL) if (_surface != NULL)
SDL_FreeSurface(_surface); SDL_FreeSurface(_surface);
if (_palette != NULL) if (_palette != NULL)
@@ -525,16 +526,45 @@ void osinterface_free()
SDL_Quit(); SDL_Quit();
} }
void osinterface_set_fullscreen_mode(int mode){ void osinterface_set_fullscreen_mode(int mode)
if (mode == gGeneral_config.fullscreen_mode) {
return; int i, destinationArea, areaDiff, closestAreaDiff, closestWidth, closestHeight;
if (SDL_SetWindowFullscreen(_window, _fullscreen_modes[mode])){ if (mode == SDL_WINDOW_FULLSCREEN)
SDL_SetWindowFullscreen(gWindow, 0);
if (mode == SDL_WINDOW_FULLSCREEN) {
platform_update_fullscreen_resolutions();
closestAreaDiff = -1;
destinationArea = gGeneral_config.fullscreen_width * gGeneral_config.fullscreen_height;
for (i = 0; i < gNumResolutions; i++) {
// Check if exact match
if (gResolutions[i].width == gGeneral_config.fullscreen_width && gResolutions[i].height == gGeneral_config.fullscreen_height) {
closestWidth = gResolutions[i].width;
closestHeight = gResolutions[i].height;
break;
}
// Check if area is closer to best match
areaDiff = abs((gResolutions[i].width * gResolutions[i].height) - destinationArea);
if (closestAreaDiff == -1 || areaDiff < closestAreaDiff) {
closestAreaDiff = areaDiff;
closestWidth = gResolutions[i].width;
closestHeight = gResolutions[i].height;
}
}
if (closestAreaDiff != -1)
SDL_SetWindowSize(gWindow, closestWidth, closestHeight);
} else if (mode == 0) {
SDL_SetWindowSize(gWindow, gGeneral_config.window_width, gGeneral_config.window_height);
}
if (SDL_SetWindowFullscreen(gWindow, _fullscreen_modes[mode])){
RCT2_ERROR("SDL_SetWindowFullscreen %s", SDL_GetError()); RCT2_ERROR("SDL_SetWindowFullscreen %s", SDL_GetError());
exit(1); exit(1);
} }
//SDL automatically resizes the fullscreen window to the nearest allowed screen resolution
//No need to call osinterface_resize() here, SDL_WINDOWEVENT_SIZE_CHANGED event will be triggered anyway
gGeneral_config.fullscreen_mode = mode; gGeneral_config.fullscreen_mode = mode;

View File

@@ -21,6 +21,8 @@
#ifndef _PLATFORM_H_ #ifndef _PLATFORM_H_
#define _PLATFORM_H_ #define _PLATFORM_H_
#include <SDL.h>
#include "../common.h" #include "../common.h"
#ifndef MAX_PATH #ifndef MAX_PATH
@@ -29,12 +31,24 @@
#define INVALID_HANDLE -1 #define INVALID_HANDLE -1
typedef struct {
int width, height;
} resolution;
typedef struct { typedef struct {
const char *path; const char *path;
uint64 size; uint64 size;
uint64 last_modified; uint64 last_modified;
} file_info; } file_info;
extern int gResolutionsAllowAnyAspectRatio;
extern int gNumResolutions;
extern resolution *gResolutions;
extern SDL_Window *gWindow;
// Platform shared definitions
void platform_update_fullscreen_resolutions();
// Platform specific definitions // Platform specific definitions
char platform_get_path_separator(); char platform_get_path_separator();
int platform_file_exists(const char *path); int platform_file_exists(const char *path);

View File

@@ -18,3 +18,81 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/ *****************************************************************************/
#include <math.h>
#include <SDL.h>
#include "../config.h"
#include "platform.h"
int gNumResolutions;
resolution *gResolutions = NULL;
SDL_Window *gWindow;
int gResolutionsAllowAnyAspectRatio = 0;
int resolution_sort_func(const void *pa, const void *pb)
{
const resolution *a = (resolution*)pa;
const resolution *b = (resolution*)pb;
int areaA = a->width * a->height;
int areaB = b->height * b->height;
if (areaA == areaB) return 0;
if (areaA < areaB) return -1;
return 1;
}
void platform_update_fullscreen_resolutions()
{
int i, displayIndex, numDisplayModes;
SDL_DisplayMode mode;
resolution *resLook, *resPlace;
float desktopAspectRatio, aspectRatio;
// Query number of display modes
displayIndex = SDL_GetWindowDisplayIndex(gWindow);
numDisplayModes = SDL_GetNumDisplayModes(displayIndex);
// Get desktop aspect ratio
SDL_GetDesktopDisplayMode(displayIndex, &mode);
desktopAspectRatio = (float)mode.w / mode.h;
if (gResolutions != NULL)
free(gResolutions);
// Get resolutions
gNumResolutions = numDisplayModes;
gResolutions = malloc(gNumResolutions * sizeof(resolution));
gNumResolutions = 0;
for (i = 0; i < numDisplayModes; i++) {
SDL_GetDisplayMode(displayIndex, i, &mode);
aspectRatio = (float)mode.w / mode.h;
if (gResolutionsAllowAnyAspectRatio || fabs(desktopAspectRatio - aspectRatio) < 0.0001f) {
gResolutions[gNumResolutions].width = mode.w;
gResolutions[gNumResolutions].height = mode.h;
gNumResolutions++;
}
}
// Sort by area
qsort(gResolutions, gNumResolutions, sizeof(resolution), resolution_sort_func);
// Remove duplicates
resPlace = &gResolutions[0];
for (int i = 1; i < gNumResolutions; i++) {
resLook = &gResolutions[i];
if (resLook->width != resPlace->width || resLook->height != resPlace->height)
*++resPlace = *resLook;
}
gNumResolutions = (int)(resPlace - &gResolutions[0]) + 1;
// Update config fullscreen resolution if not set
if (gGeneral_config.fullscreen_width == -1 || gGeneral_config.fullscreen_height == -1) {
gGeneral_config.fullscreen_width = gResolutions[gNumResolutions - 1].width;
gGeneral_config.fullscreen_height = gResolutions[gNumResolutions - 1].height;
}
}

View File

@@ -409,7 +409,30 @@ static void window_options_mousedown(int widgetIndex, rct_window*w, rct_widget*
gDropdownItemsChecked = 1 << gGeneral_config.measurement_format; gDropdownItemsChecked = 1 << gGeneral_config.measurement_format;
break; break;
case WIDX_RESOLUTION_DROPDOWN: case WIDX_RESOLUTION_DROPDOWN:
// RCT2_CALLPROC_EBPSAFE(0x006BB2AF); {
platform_update_fullscreen_resolutions();
int selectedResolution = -1;
for (i = 0; i < gNumResolutions; i++) {
resolution *resolution = &gResolutions[i];
gDropdownItemsFormat[i] = 1142;
uint16 *args = (uint16*)&gDropdownItemsArgs[i];
args[0] = 839;
args[1] = resolution->width;
args[2] = resolution->height;
if (resolution->width == gGeneral_config.fullscreen_width && resolution->height == gGeneral_config.fullscreen_height)
selectedResolution = i;
}
window_options_show_dropdown(w, widget, gNumResolutions);
if (selectedResolution != -1 && selectedResolution < 32)
gDropdownItemsChecked = 1 << selectedResolution;
}
break; break;
case WIDX_FULLSCREEN_DROPDOWN: case WIDX_FULLSCREEN_DROPDOWN:
gDropdownItemsFormat[0] = 1142; gDropdownItemsFormat[0] = 1142;
@@ -527,13 +550,19 @@ static void window_options_dropdown()
window_options_update_height_markers(); window_options_update_height_markers();
break; break;
case WIDX_RESOLUTION_DROPDOWN: case WIDX_RESOLUTION_DROPDOWN:
#ifdef _MSC_VER {
__asm movzx ax, dropdownIndex resolution *resolution = &gResolutions[dropdownIndex];
#else if (resolution->width != gGeneral_config.fullscreen_width || resolution->height != gGeneral_config.fullscreen_height) {
__asm__ ( "movzx ax, %[dropdownIndex] " : : [dropdownIndex] "g" ((char)dropdownIndex) ); gGeneral_config.fullscreen_width = resolution->width;
#endif gGeneral_config.fullscreen_height = resolution->height;
// the switch replaces ax value
RCT2_CALLPROC_EBPSAFE(0x006BB37D); if (gGeneral_config.fullscreen_mode == SDL_WINDOW_FULLSCREEN)
osinterface_set_fullscreen_mode(SDL_WINDOW_FULLSCREEN);
config_save();
gfx_invalidate_screen();
}
}
break; break;
case WIDX_FULLSCREEN_DROPDOWN: case WIDX_FULLSCREEN_DROPDOWN:
if (dropdownIndex != gGeneral_config.fullscreen_mode){ if (dropdownIndex != gGeneral_config.fullscreen_mode){
@@ -592,8 +621,8 @@ static void window_options_invalidate()
switch (w->page) { switch (w->page) {
case WINDOW_OPTIONS_PAGE_DISPLAY: case WINDOW_OPTIONS_PAGE_DISPLAY:
// resolution // resolution
RCT2_GLOBAL(0x013CE952 + 16, uint16) = RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_RESOLUTION_WIDTH, uint16); RCT2_GLOBAL(0x013CE952 + 16, uint16) = gGeneral_config.fullscreen_width;
RCT2_GLOBAL(0x013CE952 + 18, uint16) = RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_RESOLUTION_HEIGHT, uint16); RCT2_GLOBAL(0x013CE952 + 18, uint16) = gGeneral_config.fullscreen_height;
RCT2_GLOBAL(0x013CE952 + 12, uint16) = 2773 + gGeneral_config.fullscreen_mode; RCT2_GLOBAL(0x013CE952 + 12, uint16) = 2773 + gGeneral_config.fullscreen_mode;
// landscape tile smoothing checkbox // landscape tile smoothing checkbox