diff --git a/gfx.c b/gfx.c index bbd760f51c..4a877328f4 100644 --- a/gfx.c +++ b/gfx.c @@ -1660,7 +1660,7 @@ void DrawMouseCursor() memcpy_pitch( _cursor_backup, _screen.dst_ptr + _cursor.draw_pos.x + _cursor.draw_pos.y * _screen.pitch, - _cursor.draw_size.x, _cursor.draw_size.y, _screen.width, _cursor.draw_size.x); + _cursor.draw_size.x, _cursor.draw_size.y, _screen.pitch, _cursor.draw_size.x); // Draw cursor on screen _cur_dpi = &_screen; @@ -1711,8 +1711,8 @@ void DrawDirtyBlocks() { byte *b = _dirty_blocks; int x=0,y=0; - int w = (_screen.width + 63) & ~63; - int h = _screen.height; + const int w = (_screen.width + 63) & ~63; + const int h = (_screen.height + 7) & ~7; do { if (*b != 0) { diff --git a/sdl.c b/sdl.c index e8bfb8d59e..d7782a7d86 100644 --- a/sdl.c +++ b/sdl.c @@ -248,9 +248,8 @@ static void GetVideoModes(void) { for(i = 0; modes[i]; i++) { int w = modes[i]->w; int h = modes[i]->h; - if (IS_INT_INSIDE(w, 640, MAX_SCREEN_WIDTH+1) && - IS_INT_INSIDE(h, 480, MAX_SCREEN_HEIGHT+1) && - w%8 == 0 && h%8 == 0) { // disable screen resolutions which are not multiples of 8 + if (IS_INT_INSIDE(w, 640, MAX_SCREEN_WIDTH + 1) && + IS_INT_INSIDE(h, 480, MAX_SCREEN_HEIGHT + 1)) { int j; for (j = 0; j < n; ++j) if (_resolutions[j][0] == w && _resolutions[j][1] == h) @@ -270,35 +269,42 @@ static void GetVideoModes(void) { static int GetAvailableVideoMode(int *w, int *h) { int i; - + int best; + uint delta; // all modes available? if (_all_modes) return 1; // is the wanted mode among the available modes? - for(i = 0; i != _num_resolutions; i++) { + for (i = 0; i != _num_resolutions; i++) { if(*w == _resolutions[i][0] && *h == _resolutions[i][1]) return 1; } + // use the closest possible resolution + best = 0; + delta = abs((_resolutions[0][0] - *w) * (_resolutions[0][1] - *h)); + for (i = 1; i != _num_resolutions; ++i) { + uint newdelta = abs((_resolutions[i][0] - *w) * (_resolutions[i][1] - *h)); + if (newdelta < delta) { + best = i; + delta = newdelta; + } + } + // use the default mode - *w = _resolutions[0][0]; - *h = _resolutions[0][1]; + *w = _resolutions[best][0]; + *h = _resolutions[best][1]; return 2; } static bool CreateMainSurface(int w, int h) { SDL_Surface *newscreen; - bool sizechange; GetAvailableVideoMode(&w, &h); - sizechange = (_screen.width != w || _screen.height != h); - _screen.pitch = _screen.width = w; - _screen.height = h; - DEBUG(misc, 0) ("sdl: using mode %dx%d", w, h); // DO NOT CHANGE TO HWSURFACE, IT DOES NOT WORK @@ -306,14 +312,17 @@ static bool CreateMainSurface(int w, int h) if(newscreen == NULL) return false; + _screen.width = newscreen->w; + _screen.height = newscreen->h; + _screen.pitch = newscreen->pitch; + _sdl_screen = newscreen; InitPalette(); SDL_CALL SDL_WM_SetCaption("OpenTTD", "OpenTTD"); SDL_CALL SDL_ShowCursor(0); -// if(sizechange) - GameSizeChanged(); + GameSizeChanged(); return true; } @@ -491,8 +500,8 @@ static int PollEvent() { w = ev.resize.w; h = ev.resize.h; - w = clamp(w & ~0x7, 64, MAX_SCREEN_WIDTH); - h = clamp(h & ~0x7, 64, MAX_SCREEN_HEIGHT); + w = clamp(w, 64, MAX_SCREEN_WIDTH); + h = clamp(h, 64, MAX_SCREEN_HEIGHT); ChangeResInGame(w, h); diff --git a/settings_gui.c b/settings_gui.c index ab413a8580..9c158569e4 100644 --- a/settings_gui.c +++ b/settings_gui.c @@ -53,8 +53,9 @@ static StringID *BuildDynamicDropdown(StringID base, int num) static int GetCurRes() { int i; - for(i=0; i!=_num_resolutions; i++) - if (_resolutions[i][0] == _cur_resolution[0] && _resolutions[i][1] == _cur_resolution[1]) + for(i = 0; i != _num_resolutions; i++) + if (_resolutions[i][0] == _screen.width && + _resolutions[i][1] == _screen.height) break; return i; } diff --git a/win32.c b/win32.c index 91c523cd10..6a1783c6ea 100644 --- a/win32.c +++ b/win32.c @@ -340,8 +340,8 @@ static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP w = r->right - r->left - (r2.right - r2.left); h = r->bottom - r->top - (r2.bottom - r2.top); if (_wnd.double_size) { w >>= 1; h >>= 1; } - w = clamp(w & ~0x7, 64, MAX_SCREEN_WIDTH); - h = clamp(h & ~0x7, 64, MAX_SCREEN_HEIGHT); + w = clamp(w, 64, MAX_SCREEN_WIDTH); + h = clamp(h, 64, MAX_SCREEN_HEIGHT); if (_wnd.double_size) { w <<= 1; h <<= 1; } SetRect(&r2, 0, 0, w, h); @@ -506,13 +506,14 @@ static bool AllocateDibSection(int w, int h) BITMAPINFO *bi; HDC dc; - w = clamp(w & ~7, 64, MAX_SCREEN_WIDTH); - h = clamp(h & ~7, 64, MAX_SCREEN_HEIGHT); + w = clamp(w, 64, MAX_SCREEN_WIDTH); + h = clamp(h, 64, MAX_SCREEN_HEIGHT); if (w == _screen.width && h == _screen.height) return false; - _screen.width = _screen.pitch = w; + _screen.width = w; + _screen.pitch = (w + 3) & ~0x3; _screen.height = h; if (_wnd.alloced_bits) { @@ -524,17 +525,16 @@ static bool AllocateDibSection(int w, int h) memset(bi, 0, sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*256); bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - { - if (_wnd.double_size) { - _wnd.alloced_bits = _wnd.buffer_bits = (byte*)malloc(w * h); - w *= 2; - h *= 2; - } - - bi->bmiHeader.biWidth = _wnd.width = w; - bi->bmiHeader.biHeight = -(_wnd.height = h); + if (_wnd.double_size) { + w = (w + 3) & ~0x3; + _wnd.alloced_bits = _wnd.buffer_bits = (byte*)malloc(w * h); + w *= 2; + h *= 2; } + bi->bmiHeader.biWidth = _wnd.width = w; + bi->bmiHeader.biHeight = -(_wnd.height = h); + bi->bmiHeader.biPlanes = 1; bi->bmiHeader.biBitCount = 8; bi->bmiHeader.biCompression = BI_RGB;