(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
This commit is contained in:
Darkvater 2005-05-14 21:01:57 +00:00
parent d99dddc704
commit 2aa94201dc
5 changed files with 75 additions and 57 deletions

17
gfx.c
View File

@ -1979,15 +1979,16 @@ bool ChangeResInGame(int w, int h)
return true; return true;
} }
void ToggleFullScreen(const bool full_screen) static int CDECL compare_res(const void *pa, const void *pb)
{ {
_fullscreen = full_screen; int x = ((const uint16*)pa)[0] - ((const uint16*)pb)[0];
/* use preset resolutions, not _screen.height and _screen.width. On windows for example if (x != 0) return x;
if Desktop-size is 1280x1024, and gamesize is also 1280x1024, _screen.height will be return ((const uint16*)pa)[1] - ((const uint16*)pb)[1];
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])) void SortResolutions(int count)
_fullscreen ^= true; // switching resolution failed, put back full_screen to original status {
qsort(_resolutions, count, sizeof(_resolutions[0]), compare_res);
} }
uint16 GetDrawStringPlayerColor(byte player) uint16 GetDrawStringPlayerColor(byte player)

3
gfx.h
View File

@ -66,7 +66,8 @@ void DrawMouseCursor(void);
void ScreenSizeChanged(void); void ScreenSizeChanged(void);
void UndrawMouseCursor(void); void UndrawMouseCursor(void);
bool ChangeResInGame(int w, int h); bool ChangeResInGame(int w, int h);
void ToggleFullScreen(const bool full_screen); void SortResolutions(int count);
void ToggleFullScreen(bool full_screen);
/* gfx.c */ /* gfx.c */
#define ASCII_LETTERSTART 32 #define ASCII_LETTERSTART 32

39
sdl.c
View File

@ -277,18 +277,19 @@ static void GetVideoModes(void)
if (IS_INT_INSIDE(w, 640, MAX_SCREEN_WIDTH + 1) && if (IS_INT_INSIDE(w, 640, MAX_SCREEN_WIDTH + 1) &&
IS_INT_INSIDE(h, 480, MAX_SCREEN_HEIGHT + 1)) { IS_INT_INSIDE(h, 480, MAX_SCREEN_HEIGHT + 1)) {
int j; int j;
for (j = 0; j < n; ++j) for (j = 0; j < n; j++) {
if (_resolutions[j][0] == w && _resolutions[j][1] == h) if (_resolutions[j][0] == w && _resolutions[j][1] == h) break;
break; }
if (j == n) { if (j == n) {
_resolutions[n][0] = w; _resolutions[j][0] = w;
_resolutions[n][1] = h; _resolutions[j][1] = h;
if (++n == lengthof(_resolutions)) break; if (++n == lengthof(_resolutions)) break;
} }
} }
} }
_num_resolutions = n; _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; return ML_QUIT;
break; break;
case SDL_KEYDOWN: case SDL_KEYDOWN: /* Toggle full-screen on ALT + ENTER/F */
if ((ev.key.keysym.mod & (KMOD_ALT | KMOD_META)) && if ((ev.key.keysym.mod & (KMOD_ALT | KMOD_META)) &&
(ev.key.keysym.sym == SDLK_RETURN || ev.key.keysym.sym == SDLK_f)) { (ev.key.keysym.sym == SDLK_RETURN || ev.key.keysym.sym == SDLK_f)) {
_fullscreen ^= true; ToggleFullScreen(!_fullscreen);
GetVideoModes(); } else
CreateMainSurface(_screen.width, _screen.height);
MarkWholeScreenDirty();
} else {
_pressed_key = ConvertSdlKeyIntoMy(&ev.key.keysym); _pressed_key = ConvertSdlKeyIntoMy(&ev.key.keysym);
}
break; break;
case SDL_VIDEORESIZE: { case SDL_VIDEORESIZE: {
@ -634,14 +632,23 @@ static int SdlVideoMainLoop(void)
static bool SdlVideoChangeRes(int w, int h) static bool SdlVideoChangeRes(int w, int h)
{ {
// see if the mode is available /* See if the mode is available. Ignore return value
if (GetAvailableVideoMode(&w, &h) != 1) * since we will get back a valid resolution anyways. Either exactly
return false; * the same one, or one clamped to the closest available one */
GetAvailableVideoMode(&w, &h);
CreateMainSurface(w, h); CreateMainSurface(w, h);
return true; 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 = { const HalVideoDriver _sdl_video_driver = {
SdlVideoStart, SdlVideoStart,
SdlVideoStop, SdlVideoStop,

View File

@ -102,13 +102,13 @@ static void GameOptionsWndProc(Window *w, WindowEvent *e)
case WE_CLICK: case WE_CLICK:
switch (e->click.widget) { switch (e->click.widget) {
case 5: /* Setup currencies dropdown */ case 4: case 5: /* Setup currencies dropdown */
ShowDropDownMenu(w, _currency_string_list, _opt_ptr->currency, e->click.widget, _game_mode == GM_MENU ? 0 : ~GetMaskOfAllowedCurrencies(), 0); ShowDropDownMenu(w, _currency_string_list, _opt_ptr->currency, 5, _game_mode == GM_MENU ? 0 : ~GetMaskOfAllowedCurrencies(), 0);
return; return;
case 8: /* Setup distance unit dropdown */ case 7: case 8: /* Setup distance unit dropdown */
ShowDropDownMenu(w, _distances_dropdown, _opt_ptr->kilometers, e->click.widget, 0, 0); ShowDropDownMenu(w, _distances_dropdown, _opt_ptr->kilometers, 8, 0, 0);
return; return;
case 11: { /* Setup road-side dropdown */ case 10: case 11: { /* Setup road-side dropdown */
int i = 0; int i = 0;
/* You can only change the drive side if you are in the menu or ingame with /* 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)) if ((_game_mode != GM_MENU && RoadVehiclesAreBuilt()) || (_networking && !_network_server))
i = (-1) ^ (1 << _opt_ptr->road_side); // disable the other value 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; } return;
case 14: { /* Setup townname dropdown */ case 13: case 14: { /* Setup townname dropdown */
int i = _opt_ptr->town_name; 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; return;
} }
case 17: /* Setup autosave dropdown */ case 16: case 17: /* Setup autosave dropdown */
ShowDropDownMenu(w, _autosave_dropdown, _opt_ptr->autosave, e->click.widget, 0, 0); ShowDropDownMenu(w, _autosave_dropdown, _opt_ptr->autosave, 17, 0, 0);
return; return;
case 20: /* Setup customized vehicle-names dropdown */ case 19: 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); ShowDropDownMenu(w, _designnames_dropdown, (_vehicle_design_names & 1) ? 1 : 0, 20, (_vehicle_design_names & 2) ? 0 : 2, 0);
return; return;
case 21: /* Save customized vehicle-names to disk */ case 21: /* Save customized vehicle-names to disk */
return; return;
case 24: /* Setup interface language dropdown */ case 23: case 24: /* Setup interface language dropdown */
ShowDropDownMenu(w, _dynlang.dropdown, _dynlang.curr, e->click.widget, 0, 0); ShowDropDownMenu(w, _dynlang.dropdown, _dynlang.curr, 24, 0, 0);
return; return;
case 27: /* Setup resolution dropdown */ case 26: case 27: /* Setup resolution dropdown */
ShowDropDownMenu(w, BuildDynamicDropdown(SPECSTR_RESOLUTION_START, _num_resolutions), GetCurRes(), e->click.widget, 0, 0); ShowDropDownMenu(w, BuildDynamicDropdown(SPECSTR_RESOLUTION_START, _num_resolutions), GetCurRes(), 27, 0, 0);
return; return;
case 28: /* Click fullscreen on/off */ case 28: /* Click fullscreen on/off */
(_fullscreen) ? CLRBIT(w->click_state, 28) : SETBIT(w->click_state, 28); (_fullscreen) ? CLRBIT(w->click_state, 28) : SETBIT(w->click_state, 28);
ToggleFullScreen(!_fullscreen); // toggle full-screen on/off ToggleFullScreen(!_fullscreen); // toggle full-screen on/off
SetWindowDirty(w); SetWindowDirty(w);
return; return;
case 31: /* Setup screenshot format dropdown */ case 30: case 31: /* Setup screenshot format dropdown */
ShowDropDownMenu(w, BuildDynamicDropdown(SPECSTR_SCREENSHOT_START, _num_screenshot_formats), _cur_screenshot_format, e->click.widget, 0, 0); ShowDropDownMenu(w, BuildDynamicDropdown(SPECSTR_SCREENSHOT_START, _num_screenshot_formats), _cur_screenshot_format, 31, 0, 0);
return; return;
} }
break; break;

37
win32.c
View File

@ -322,11 +322,10 @@ static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP
} }
} break; } break;
case WM_SYSKEYDOWN: /* user presses F10 or Alt, both activating the title-menu */ case WM_SYSKEYDOWN: /* user presses F10 or Alt, both activating the title-menu */
switch (wParam) { switch (wParam) {
case VK_RETURN: /* Full Screen */ case VK_RETURN: case 0x46: /* Full Screen on ALT + ENTER/F(VK_F) */
MakeWindow(!_wnd.fullscreen); ToggleFullScreen(!_wnd.fullscreen);
return 0; return 0;
case VK_MENU: /* Just ALT */ case VK_MENU: /* Just ALT */
return 0; // do nothing return 0; // do nothing
@ -602,26 +601,34 @@ static void FindResolutions(void)
int i = 0, n = 0; int i = 0, n = 0;
DEVMODE dm; DEVMODE dm;
while (EnumDisplaySettings(NULL, i++, &dm)) { while (EnumDisplaySettings(NULL, i++, &dm) != 0) {
if (dm.dmBitsPerPel == 8 && if (dm.dmBitsPerPel == 8 && IS_INT_INSIDE(dm.dmPelsWidth, 640, MAX_SCREEN_WIDTH + 1) &&
IS_INT_INSIDE(dm.dmPelsWidth, 640, MAX_SCREEN_WIDTH + 1) && IS_INT_INSIDE(dm.dmPelsHeight, 480, MAX_SCREEN_HEIGHT + 1)){
IS_INT_INSIDE(dm.dmPelsHeight, 480, MAX_SCREEN_HEIGHT + 1) && ( int j;
n == 0 || for (j = 0; j < n; j++) {
_resolutions[n - 1][0] != dm.dmPelsWidth || if (_resolutions[j][0] == dm.dmPelsWidth && _resolutions[j][1] == dm.dmPelsHeight) break;
_resolutions[n - 1][1] != dm.dmPelsHeight }
)) {
_resolutions[n][0] = dm.dmPelsWidth; /* In the previous loop we have checked already existing/added resolutions if
_resolutions[n][1] = dm.dmPelsHeight; * they are the same as the new ones. If this is not the case (j == n); we have
if (++n == lengthof(_resolutions)) break; * 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) { if (n == 0) {
memcpy(_resolutions, default_resolutions, sizeof(default_resolutions)); memcpy(_resolutions, default_resolutions, sizeof(default_resolutions));
n = lengthof(default_resolutions); n = lengthof(default_resolutions);
} }
_num_resolutions = n; _num_resolutions = n;
SortResolutions(_num_resolutions);
} }
@ -776,6 +783,8 @@ static bool Win32GdiChangeRes(int w, int h)
return true; return true;
} }
void ToggleFullScreen(bool full_screen) {MakeWindow(full_screen);}
const HalVideoDriver _win32_video_driver = { const HalVideoDriver _win32_video_driver = {
Win32GdiStart, Win32GdiStart,
Win32GdiStop, Win32GdiStop,