From 2aa94201dc19b86e2c1bb5e2c724b52332833ccc Mon Sep 17 00:00:00 2001 From: Darkvater Date: Sat, 14 May 2005 21:01:57 +0000 Subject: [PATCH] (svn r2310) - Fix: Game would crash if you full-screened with the 'fullscreen' button than chose a resolution from the dropdown box that was no longer valid. Big thanks to DaleStan for track down the crashing bug. - Fix: There would be duplicate entries in the resolutions dropdown box. Copy SDL method or removing duplicates and sort the list. - Feature: in the settings menu, you don't have to click on the arrows anymore, clicking on the dropdown box itself has the same effect. Consistent with other dropdowns in the game --- gfx.c | 17 +++++++++-------- gfx.h | 3 ++- sdl.c | 39 +++++++++++++++++++++++---------------- settings_gui.c | 36 ++++++++++++++++++------------------ win32.c | 37 +++++++++++++++++++++++-------------- 5 files changed, 75 insertions(+), 57 deletions(-) diff --git a/gfx.c b/gfx.c index 4bdf404419..6a306c3bc7 100644 --- a/gfx.c +++ b/gfx.c @@ -1979,15 +1979,16 @@ bool ChangeResInGame(int w, int h) return true; } -void ToggleFullScreen(const bool full_screen) +static int CDECL compare_res(const void *pa, const void *pb) { - _fullscreen = full_screen; - /* use preset resolutions, not _screen.height and _screen.width. On windows for example - if Desktop-size is 1280x1024, and gamesize is also 1280x1024, _screen.height will be - only 1000 because of possible start-bar. For this reason you cannot switch to - fullscreen mode from this resolution. Use of preset resolution will fix this */ - if (!_video_driver->change_resolution(_cur_resolution[0], _cur_resolution[1])) - _fullscreen ^= true; // switching resolution failed, put back full_screen to original status + int x = ((const uint16*)pa)[0] - ((const uint16*)pb)[0]; + if (x != 0) return x; + return ((const uint16*)pa)[1] - ((const uint16*)pb)[1]; +} + +void SortResolutions(int count) +{ + qsort(_resolutions, count, sizeof(_resolutions[0]), compare_res); } uint16 GetDrawStringPlayerColor(byte player) diff --git a/gfx.h b/gfx.h index 965fd6e044..e52cbdbbad 100644 --- a/gfx.h +++ b/gfx.h @@ -66,7 +66,8 @@ void DrawMouseCursor(void); void ScreenSizeChanged(void); void UndrawMouseCursor(void); bool ChangeResInGame(int w, int h); -void ToggleFullScreen(const bool full_screen); +void SortResolutions(int count); +void ToggleFullScreen(bool full_screen); /* gfx.c */ #define ASCII_LETTERSTART 32 diff --git a/sdl.c b/sdl.c index 6858fdbfdd..e039a51d94 100644 --- a/sdl.c +++ b/sdl.c @@ -277,18 +277,19 @@ static void GetVideoModes(void) 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) - break; + for (j = 0; j < n; j++) { + if (_resolutions[j][0] == w && _resolutions[j][1] == h) break; + } + if (j == n) { - _resolutions[n][0] = w; - _resolutions[n][1] = h; + _resolutions[j][0] = w; + _resolutions[j][1] = h; if (++n == lengthof(_resolutions)) break; } } } _num_resolutions = n; - qsort(_resolutions, n, sizeof(_resolutions[0]), compare_res); + SortResolutions(_num_resolutions); } } @@ -519,16 +520,13 @@ static int PollEvent(void) return ML_QUIT; break; - case SDL_KEYDOWN: + case SDL_KEYDOWN: /* Toggle full-screen on ALT + ENTER/F */ if ((ev.key.keysym.mod & (KMOD_ALT | KMOD_META)) && (ev.key.keysym.sym == SDLK_RETURN || ev.key.keysym.sym == SDLK_f)) { - _fullscreen ^= true; - GetVideoModes(); - CreateMainSurface(_screen.width, _screen.height); - MarkWholeScreenDirty(); - } else { + ToggleFullScreen(!_fullscreen); + } else _pressed_key = ConvertSdlKeyIntoMy(&ev.key.keysym); - } + break; case SDL_VIDEORESIZE: { @@ -634,14 +632,23 @@ static int SdlVideoMainLoop(void) static bool SdlVideoChangeRes(int w, int h) { - // see if the mode is available - if (GetAvailableVideoMode(&w, &h) != 1) - return false; + /* See if the mode is available. Ignore return value + * since we will get back a valid resolution anyways. Either exactly + * the same one, or one clamped to the closest available one */ + GetAvailableVideoMode(&w, &h); CreateMainSurface(w, h); return true; } +void ToggleFullScreen(bool full_screen) +{ + _fullscreen ^= full_screen; + GetVideoModes(); // get the list of available video modes + if (!_video_driver->change_resolution(_cur_resolution[0], _cur_resolution[1])) + _fullscreen ^= true; // switching resolution failed, put back full_screen to original status +} + const HalVideoDriver _sdl_video_driver = { SdlVideoStart, SdlVideoStop, diff --git a/settings_gui.c b/settings_gui.c index bbe4af72a5..cfdf18c3bc 100644 --- a/settings_gui.c +++ b/settings_gui.c @@ -102,13 +102,13 @@ static void GameOptionsWndProc(Window *w, WindowEvent *e) case WE_CLICK: switch (e->click.widget) { - case 5: /* Setup currencies dropdown */ - ShowDropDownMenu(w, _currency_string_list, _opt_ptr->currency, e->click.widget, _game_mode == GM_MENU ? 0 : ~GetMaskOfAllowedCurrencies(), 0); + case 4: case 5: /* Setup currencies dropdown */ + ShowDropDownMenu(w, _currency_string_list, _opt_ptr->currency, 5, _game_mode == GM_MENU ? 0 : ~GetMaskOfAllowedCurrencies(), 0); return; - case 8: /* Setup distance unit dropdown */ - ShowDropDownMenu(w, _distances_dropdown, _opt_ptr->kilometers, e->click.widget, 0, 0); + case 7: case 8: /* Setup distance unit dropdown */ + ShowDropDownMenu(w, _distances_dropdown, _opt_ptr->kilometers, 8, 0, 0); return; - case 11: { /* Setup road-side dropdown */ + case 10: case 11: { /* Setup road-side dropdown */ int i = 0; /* You can only change the drive side if you are in the menu or ingame with @@ -116,34 +116,34 @@ static void GameOptionsWndProc(Window *w, WindowEvent *e) if ((_game_mode != GM_MENU && RoadVehiclesAreBuilt()) || (_networking && !_network_server)) i = (-1) ^ (1 << _opt_ptr->road_side); // disable the other value - ShowDropDownMenu(w, _driveside_dropdown, _opt_ptr->road_side, e->click.widget, i, 0); + ShowDropDownMenu(w, _driveside_dropdown, _opt_ptr->road_side, 11, i, 0); } return; - case 14: { /* Setup townname dropdown */ + case 13: case 14: { /* Setup townname dropdown */ int i = _opt_ptr->town_name; - ShowDropDownMenu(w, BuildDynamicDropdown(STR_TOWNNAME_ORIGINAL_ENGLISH, SPECSTR_TOWNNAME_LAST - SPECSTR_TOWNNAME_START + 1), i, e->click.widget, (_game_mode == GM_MENU) ? 0 : (-1) ^ (1 << i), 0); + ShowDropDownMenu(w, BuildDynamicDropdown(STR_TOWNNAME_ORIGINAL_ENGLISH, SPECSTR_TOWNNAME_LAST - SPECSTR_TOWNNAME_START + 1), i, 14, (_game_mode == GM_MENU) ? 0 : (-1) ^ (1 << i), 0); return; } - case 17: /* Setup autosave dropdown */ - ShowDropDownMenu(w, _autosave_dropdown, _opt_ptr->autosave, e->click.widget, 0, 0); + case 16: case 17: /* Setup autosave dropdown */ + ShowDropDownMenu(w, _autosave_dropdown, _opt_ptr->autosave, 17, 0, 0); return; - case 20: /* Setup customized vehicle-names dropdown */ - ShowDropDownMenu(w, _designnames_dropdown, (_vehicle_design_names&1)?1:0, e->click.widget, (_vehicle_design_names&2)?0:2, 0); + case 19: case 20: /* Setup customized vehicle-names dropdown */ + ShowDropDownMenu(w, _designnames_dropdown, (_vehicle_design_names & 1) ? 1 : 0, 20, (_vehicle_design_names & 2) ? 0 : 2, 0); return; case 21: /* Save customized vehicle-names to disk */ return; - case 24: /* Setup interface language dropdown */ - ShowDropDownMenu(w, _dynlang.dropdown, _dynlang.curr, e->click.widget, 0, 0); + case 23: case 24: /* Setup interface language dropdown */ + ShowDropDownMenu(w, _dynlang.dropdown, _dynlang.curr, 24, 0, 0); return; - case 27: /* Setup resolution dropdown */ - ShowDropDownMenu(w, BuildDynamicDropdown(SPECSTR_RESOLUTION_START, _num_resolutions), GetCurRes(), e->click.widget, 0, 0); + case 26: case 27: /* Setup resolution dropdown */ + ShowDropDownMenu(w, BuildDynamicDropdown(SPECSTR_RESOLUTION_START, _num_resolutions), GetCurRes(), 27, 0, 0); return; case 28: /* Click fullscreen on/off */ (_fullscreen) ? CLRBIT(w->click_state, 28) : SETBIT(w->click_state, 28); ToggleFullScreen(!_fullscreen); // toggle full-screen on/off SetWindowDirty(w); return; - case 31: /* Setup screenshot format dropdown */ - ShowDropDownMenu(w, BuildDynamicDropdown(SPECSTR_SCREENSHOT_START, _num_screenshot_formats), _cur_screenshot_format, e->click.widget, 0, 0); + case 30: case 31: /* Setup screenshot format dropdown */ + ShowDropDownMenu(w, BuildDynamicDropdown(SPECSTR_SCREENSHOT_START, _num_screenshot_formats), _cur_screenshot_format, 31, 0, 0); return; } break; diff --git a/win32.c b/win32.c index fc4b4f5447..6382ae0bfe 100644 --- a/win32.c +++ b/win32.c @@ -322,11 +322,10 @@ static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP } } break; - case WM_SYSKEYDOWN: /* user presses F10 or Alt, both activating the title-menu */ switch (wParam) { - case VK_RETURN: /* Full Screen */ - MakeWindow(!_wnd.fullscreen); + case VK_RETURN: case 0x46: /* Full Screen on ALT + ENTER/F(VK_F) */ + ToggleFullScreen(!_wnd.fullscreen); return 0; case VK_MENU: /* Just ALT */ return 0; // do nothing @@ -602,26 +601,34 @@ static void FindResolutions(void) int i = 0, n = 0; DEVMODE dm; - while (EnumDisplaySettings(NULL, i++, &dm)) { - if (dm.dmBitsPerPel == 8 && - IS_INT_INSIDE(dm.dmPelsWidth, 640, MAX_SCREEN_WIDTH + 1) && - IS_INT_INSIDE(dm.dmPelsHeight, 480, MAX_SCREEN_HEIGHT + 1) && ( - n == 0 || - _resolutions[n - 1][0] != dm.dmPelsWidth || - _resolutions[n - 1][1] != dm.dmPelsHeight - )) { - _resolutions[n][0] = dm.dmPelsWidth; - _resolutions[n][1] = dm.dmPelsHeight; - if (++n == lengthof(_resolutions)) break; + while (EnumDisplaySettings(NULL, i++, &dm) != 0) { + if (dm.dmBitsPerPel == 8 && IS_INT_INSIDE(dm.dmPelsWidth, 640, MAX_SCREEN_WIDTH + 1) && + IS_INT_INSIDE(dm.dmPelsHeight, 480, MAX_SCREEN_HEIGHT + 1)){ + int j; + for (j = 0; j < n; j++) { + if (_resolutions[j][0] == dm.dmPelsWidth && _resolutions[j][1] == dm.dmPelsHeight) break; + } + + /* In the previous loop we have checked already existing/added resolutions if + * they are the same as the new ones. If this is not the case (j == n); we have + * looped all and found none, add the new one to the list. If we have reached the + * maximum amount of resolutions, then quit querying the display */ + if (j == n) { + _resolutions[j][0] = dm.dmPelsWidth; + _resolutions[j][1] = dm.dmPelsHeight; + if (++n == lengthof(_resolutions)) break; + } } } + /* We have found no resolutions, show the default list */ if (n == 0) { memcpy(_resolutions, default_resolutions, sizeof(default_resolutions)); n = lengthof(default_resolutions); } _num_resolutions = n; + SortResolutions(_num_resolutions); } @@ -776,6 +783,8 @@ static bool Win32GdiChangeRes(int w, int h) return true; } +void ToggleFullScreen(bool full_screen) {MakeWindow(full_screen);} + const HalVideoDriver _win32_video_driver = { Win32GdiStart, Win32GdiStop,