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
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);
}

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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