mirror of https://github.com/OpenRCT2/OpenRCT2.git
fix fullscreen resolution, fixes #89
This commit is contained in:
parent
a7a89fcf0f
commit
7cdcb6402e
13
src/config.c
13
src/config.c
|
@ -88,6 +88,8 @@ general_configuration_t gGeneral_config_default = {
|
|||
0, // show_height_as_units
|
||||
1, // save_plugin_data
|
||||
0, // fullscreen mode (default: windowed)
|
||||
-1, // fullscreen_width
|
||||
-1, // fullscreen_height
|
||||
-1, // window_width
|
||||
-1, // window_height
|
||||
LANGUAGE_ENGLISH_UK, // language
|
||||
|
@ -252,6 +254,11 @@ void config_write_ini_general(FILE *fp)
|
|||
else
|
||||
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)
|
||||
fprintf(fp, "window_width = %d\n", gGeneral_config.window_width);
|
||||
if (gGeneral_config.window_height != -1)
|
||||
|
@ -557,6 +564,12 @@ static void config_general(char *setting, char *value){
|
|||
else
|
||||
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) {
|
||||
gGeneral_config.window_width = atoi(value);
|
||||
}
|
||||
|
|
|
@ -132,6 +132,8 @@ typedef struct general_configuration {
|
|||
|
||||
//new
|
||||
uint8 fullscreen_mode;
|
||||
sint16 fullscreen_width;
|
||||
sint16 fullscreen_height;
|
||||
sint16 window_width;
|
||||
sint16 window_height;
|
||||
uint16 language;
|
||||
|
|
|
@ -49,7 +49,6 @@ static void osinterface_create_window();
|
|||
static void osinterface_close_window();
|
||||
static void osinterface_resize(int width, int height);
|
||||
|
||||
static SDL_Window *_window;
|
||||
static SDL_Surface *_surface;
|
||||
static SDL_Palette *_palette;
|
||||
|
||||
|
@ -204,16 +203,16 @@ static void osinterface_create_window()
|
|||
|
||||
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);
|
||||
if (!_window) {
|
||||
if (!gWindow) {
|
||||
RCT2_ERROR("SDL_CreateWindow failed %s", SDL_GetError());
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
SDL_VERSION(&wmInfo.version);
|
||||
// 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());
|
||||
exit(-1);
|
||||
}
|
||||
|
@ -225,6 +224,8 @@ static void osinterface_create_window()
|
|||
|
||||
// Initialise the surface, palette and draw buffer
|
||||
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;
|
||||
int i;
|
||||
|
||||
surface = SDL_GetWindowSurface(_window);
|
||||
surface = SDL_GetWindowSurface(gWindow);
|
||||
if (!surface) {
|
||||
RCT2_ERROR("SDL_GetWindowSurface failed %s", SDL_GetError());
|
||||
exit(1);
|
||||
|
@ -334,11 +335,11 @@ void osinterface_draw()
|
|||
SDL_UnlockSurface(_surface);
|
||||
|
||||
// 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());
|
||||
exit(1);
|
||||
}
|
||||
if (SDL_UpdateWindowSurface(_window)) {
|
||||
if (SDL_UpdateWindowSurface(gWindow)) {
|
||||
RCT2_ERROR("SDL_UpdateWindowSurface %s", SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
|
@ -508,8 +509,8 @@ void osinterface_process_messages()
|
|||
|
||||
static void osinterface_close_window()
|
||||
{
|
||||
if (_window != NULL)
|
||||
SDL_DestroyWindow(_window);
|
||||
if (gWindow != NULL)
|
||||
SDL_DestroyWindow(gWindow);
|
||||
if (_surface != NULL)
|
||||
SDL_FreeSurface(_surface);
|
||||
if (_palette != NULL)
|
||||
|
@ -525,16 +526,45 @@ void osinterface_free()
|
|||
SDL_Quit();
|
||||
}
|
||||
|
||||
void osinterface_set_fullscreen_mode(int mode){
|
||||
if (mode == gGeneral_config.fullscreen_mode)
|
||||
return;
|
||||
void osinterface_set_fullscreen_mode(int mode)
|
||||
{
|
||||
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());
|
||||
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;
|
||||
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
#ifndef _PLATFORM_H_
|
||||
#define _PLATFORM_H_
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#include "../common.h"
|
||||
|
||||
#ifndef MAX_PATH
|
||||
|
@ -29,12 +31,24 @@
|
|||
|
||||
#define INVALID_HANDLE -1
|
||||
|
||||
typedef struct {
|
||||
int width, height;
|
||||
} resolution;
|
||||
|
||||
typedef struct {
|
||||
const char *path;
|
||||
uint64 size;
|
||||
uint64 last_modified;
|
||||
} 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
|
||||
char platform_get_path_separator();
|
||||
int platform_file_exists(const char *path);
|
||||
|
|
|
@ -18,3 +18,81 @@
|
|||
* 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;
|
||||
}
|
||||
}
|
|
@ -409,7 +409,30 @@ static void window_options_mousedown(int widgetIndex, rct_window*w, rct_widget*
|
|||
gDropdownItemsChecked = 1 << gGeneral_config.measurement_format;
|
||||
break;
|
||||
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;
|
||||
case WIDX_FULLSCREEN_DROPDOWN:
|
||||
gDropdownItemsFormat[0] = 1142;
|
||||
|
@ -527,13 +550,19 @@ static void window_options_dropdown()
|
|||
window_options_update_height_markers();
|
||||
break;
|
||||
case WIDX_RESOLUTION_DROPDOWN:
|
||||
#ifdef _MSC_VER
|
||||
__asm movzx ax, dropdownIndex
|
||||
#else
|
||||
__asm__ ( "movzx ax, %[dropdownIndex] " : : [dropdownIndex] "g" ((char)dropdownIndex) );
|
||||
#endif
|
||||
// the switch replaces ax value
|
||||
RCT2_CALLPROC_EBPSAFE(0x006BB37D);
|
||||
{
|
||||
resolution *resolution = &gResolutions[dropdownIndex];
|
||||
if (resolution->width != gGeneral_config.fullscreen_width || resolution->height != gGeneral_config.fullscreen_height) {
|
||||
gGeneral_config.fullscreen_width = resolution->width;
|
||||
gGeneral_config.fullscreen_height = resolution->height;
|
||||
|
||||
if (gGeneral_config.fullscreen_mode == SDL_WINDOW_FULLSCREEN)
|
||||
osinterface_set_fullscreen_mode(SDL_WINDOW_FULLSCREEN);
|
||||
|
||||
config_save();
|
||||
gfx_invalidate_screen();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WIDX_FULLSCREEN_DROPDOWN:
|
||||
if (dropdownIndex != gGeneral_config.fullscreen_mode){
|
||||
|
@ -592,8 +621,8 @@ static void window_options_invalidate()
|
|||
switch (w->page) {
|
||||
case WINDOW_OPTIONS_PAGE_DISPLAY:
|
||||
// resolution
|
||||
RCT2_GLOBAL(0x013CE952 + 16, uint16) = RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_RESOLUTION_WIDTH, uint16);
|
||||
RCT2_GLOBAL(0x013CE952 + 18, uint16) = RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_RESOLUTION_HEIGHT, uint16);
|
||||
RCT2_GLOBAL(0x013CE952 + 16, uint16) = gGeneral_config.fullscreen_width;
|
||||
RCT2_GLOBAL(0x013CE952 + 18, uint16) = gGeneral_config.fullscreen_height;
|
||||
RCT2_GLOBAL(0x013CE952 + 12, uint16) = 2773 + gGeneral_config.fullscreen_mode;
|
||||
|
||||
// landscape tile smoothing checkbox
|
||||
|
|
Loading…
Reference in New Issue