From 9195f2337a7c4f9154058877093bbb74db33cf32 Mon Sep 17 00:00:00 2001 From: glx Date: Fri, 12 Apr 2019 18:46:49 +0200 Subject: [PATCH] Codechange: use std::vector for _resolutions --- src/core/geometry_type.hpp | 14 ++++++++++++++ src/driver.cpp | 17 ++++++++--------- src/gfx.cpp | 13 +++---------- src/gfx_func.h | 5 ++--- src/settings_gui.cpp | 21 +++++++++------------ src/video/allegro_v.cpp | 38 ++++++++++++++------------------------ src/video/cocoa/cocoa_v.mm | 20 +++++++++----------- src/video/sdl_v.cpp | 38 +++++++++++++------------------------- src/video/video_driver.hpp | 4 ++-- src/video/win32_v.cpp | 33 +++++++++------------------------ 10 files changed, 83 insertions(+), 120 deletions(-) diff --git a/src/core/geometry_type.hpp b/src/core/geometry_type.hpp index d1f363127b..2927cd9804 100644 --- a/src/core/geometry_type.hpp +++ b/src/core/geometry_type.hpp @@ -29,6 +29,20 @@ struct Point { struct Dimension { uint width; uint height; + + Dimension(uint w = 0, uint h = 0) : width(w), height(h) {}; + + bool operator< (const Dimension &other) const + { + int x = (*this).width - other.width; + if (x != 0) return x < 0; + return (*this).height < other.height; + } + + bool operator== (const Dimension &other) const + { + return (*this).width == other.width && (*this).height == other.height; + } }; /** Specification of a rectangle with absolute coordinates of all edges */ diff --git a/src/driver.cpp b/src/driver.cpp index 390fb381e0..f1b4d67ded 100644 --- a/src/driver.cpp +++ b/src/driver.cpp @@ -18,18 +18,17 @@ #include "safeguards.h" -char *_ini_videodriver; ///< The video driver a stored in the configuration file. -int _num_resolutions; ///< The number of resolutions. -Dimension _resolutions[32]; ///< List of resolutions. -Dimension _cur_resolution; ///< The current resolution. -bool _rightclick_emulate; ///< Whether right clicking is emulated. +char *_ini_videodriver; ///< The video driver a stored in the configuration file. +std::vector _resolutions; ///< List of resolutions. +Dimension _cur_resolution; ///< The current resolution. +bool _rightclick_emulate; ///< Whether right clicking is emulated. -char *_ini_sounddriver; ///< The sound driver a stored in the configuration file. +char *_ini_sounddriver; ///< The sound driver a stored in the configuration file. -char *_ini_musicdriver; ///< The music driver a stored in the configuration file. +char *_ini_musicdriver; ///< The music driver a stored in the configuration file. -char *_ini_blitter; ///< The blitter as stored in the configuration file. -bool _blitter_autodetected; ///< Was the blitter autodetected or specified by the user? +char *_ini_blitter; ///< The blitter as stored in the configuration file. +bool _blitter_autodetected; ///< Was the blitter autodetected or specified by the user? /** * Get a string parameter the list of parameters. diff --git a/src/gfx.cpp b/src/gfx.cpp index 279dd35a82..97ae0f510e 100644 --- a/src/gfx.cpp +++ b/src/gfx.cpp @@ -1691,20 +1691,13 @@ bool ChangeResInGame(int width, int height) bool ToggleFullScreen(bool fs) { bool result = VideoDriver::GetInstance()->ToggleFullscreen(fs); - if (_fullscreen != fs && _num_resolutions == 0) { + if (_fullscreen != fs && _resolutions.empty()) { DEBUG(driver, 0, "Could not find a suitable fullscreen resolution"); } return result; } -static int CDECL compare_res(const Dimension *pa, const Dimension *pb) +void SortResolutions() { - int x = pa->width - pb->width; - if (x != 0) return x; - return pa->height - pb->height; -} - -void SortResolutions(int count) -{ - QSortT(_resolutions, count, &compare_res); + std::sort(_resolutions.begin(), _resolutions.end()); } diff --git a/src/gfx_func.h b/src/gfx_func.h index bbace39132..1724a931f5 100644 --- a/src/gfx_func.h +++ b/src/gfx_func.h @@ -66,8 +66,7 @@ extern bool _right_button_clicked; extern DrawPixelInfo _screen; extern bool _screen_disable_anim; ///< Disable palette animation (important for 32bpp-anim blitter during giant screenshot) -extern int _num_resolutions; -extern Dimension _resolutions[32]; +extern std::vector _resolutions; extern Dimension _cur_resolution; extern Palette _cur_palette; ///< Current palette @@ -162,7 +161,7 @@ void SetAnimatedMouseCursor(const AnimCursor *table); void CursorTick(); void UpdateCursorSize(); bool ChangeResInGame(int w, int h); -void SortResolutions(int count); +void SortResolutions(); bool ToggleFullScreen(bool fs); /* gfx.cpp */ diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index 51b5340e39..f4c7e466c4 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -104,17 +104,14 @@ static inline StringID TownName(int town_name) /** * Get index of the current screen resolution. - * @return Index of the current screen resolution if it is a known resolution, #_num_resolutions otherwise. + * @return Index of the current screen resolution if it is a known resolution, _resolutions.size() otherwise. */ -static int GetCurRes() +static uint GetCurRes() { - int i; + uint i; - for (i = 0; i != _num_resolutions; i++) { - if ((int)_resolutions[i].width == _screen.width && - (int)_resolutions[i].height == _screen.height) { - break; - } + for (i = 0; i != _resolutions.size(); i++) { + if (_resolutions[i] == Dimension(_screen.width, _screen.height)) break; } return i; } @@ -286,10 +283,10 @@ struct GameOptionsWindow : Window { } case WID_GO_RESOLUTION_DROPDOWN: // Setup resolution dropdown - if (_num_resolutions == 0) break; + if (_resolutions.empty()) break; *selected_index = GetCurRes(); - for (int i = 0; i < _num_resolutions; i++) { + for (uint i = 0; i < _resolutions.size(); i++) { list.emplace_back(new DropDownListStringItem(SPECSTR_RESOLUTION_START + i, i, false)); } break; @@ -336,7 +333,7 @@ struct GameOptionsWindow : Window { case WID_GO_TOWNNAME_DROPDOWN: SetDParam(0, TownName(this->opt->game_creation.town_name)); break; case WID_GO_AUTOSAVE_DROPDOWN: SetDParam(0, _autosave_dropdown[_settings_client.gui.autosave]); break; case WID_GO_LANG_DROPDOWN: SetDParamStr(0, _current_language->own_name); break; - case WID_GO_RESOLUTION_DROPDOWN: SetDParam(0, GetCurRes() == _num_resolutions ? STR_GAME_OPTIONS_RESOLUTION_OTHER : SPECSTR_RESOLUTION_START + GetCurRes()); break; + case WID_GO_RESOLUTION_DROPDOWN: SetDParam(0, GetCurRes() == _resolutions.size() ? STR_GAME_OPTIONS_RESOLUTION_OTHER : SPECSTR_RESOLUTION_START + GetCurRes()); break; case WID_GO_GUI_ZOOM_DROPDOWN: SetDParam(0, _gui_zoom_dropdown[ZOOM_LVL_OUT_4X - _gui_zoom]); break; case WID_GO_FONT_ZOOM_DROPDOWN: SetDParam(0, _font_zoom_dropdown[ZOOM_LVL_OUT_4X - _font_zoom]); break; case WID_GO_BASE_GRF_DROPDOWN: SetDParamStr(0, BaseGraphics::GetUsedSet()->name); break; @@ -535,7 +532,7 @@ struct GameOptionsWindow : Window { break; case WID_GO_RESOLUTION_DROPDOWN: // Change resolution - if (index < _num_resolutions && ChangeResInGame(_resolutions[index].width, _resolutions[index].height)) { + if ((uint)index < _resolutions.size() && ChangeResInGame(_resolutions[index].width, _resolutions[index].height)) { this->SetDirty(); } break; diff --git a/src/video/allegro_v.cpp b/src/video/allegro_v.cpp index 47dd92e1e2..3d4aea8f11 100644 --- a/src/video/allegro_v.cpp +++ b/src/video/allegro_v.cpp @@ -28,6 +28,7 @@ #include "../thread.h" #include "allegro_v.h" #include +#include #include "../safeguards.h" @@ -139,34 +140,25 @@ static void GetVideoModes() * cards ourselves... and we need a card to get the modes. */ set_gfx_mode(_fullscreen ? GFX_AUTODETECT_FULLSCREEN : GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0); + _resolutions.clear(); + GFX_MODE_LIST *mode_list = get_gfx_mode_list(gfx_driver->id); if (mode_list == nullptr) { - memcpy(_resolutions, default_resolutions, sizeof(default_resolutions)); - _num_resolutions = lengthof(default_resolutions); + _resolutions.assign(std::begin(default_resolutions), std::end(default_resolutions)); return; } GFX_MODE *modes = mode_list->mode; - int n = 0; for (int i = 0; modes[i].bpp != 0; i++) { uint w = modes[i].width; uint h = modes[i].height; - if (w >= 640 && h >= 480) { - int j; - for (j = 0; j < n; j++) { - if (_resolutions[j].width == w && _resolutions[j].height == h) break; - } - - if (j == n) { - _resolutions[j].width = w; - _resolutions[j].height = h; - if (++n == lengthof(_resolutions)) break; - } - } + if (w < 640 || h < 480) continue; + if (std::find(_resolutions.begin(), _resolutions.end(), Dimension(w, h)) != _resolutions.end()) continue; + _resolutions.emplace_back(w, h); } - _num_resolutions = n; - SortResolutions(_num_resolutions); + + SortResolutions(); destroy_gfx_mode_list(mode_list); } @@ -174,17 +166,15 @@ static void GetVideoModes() static void GetAvailableVideoMode(uint *w, uint *h) { /* No video modes, so just try it and see where it ends */ - if (_num_resolutions == 0) return; + if (_resolutions.empty()) return; /* is the wanted mode among the available modes? */ - for (int i = 0; i != _num_resolutions; i++) { - if (*w == _resolutions[i].width && *h == _resolutions[i].height) return; - } + if (std::find(_resolutions.begin(), _resolutions.end(), Dimension(*w, *h)) != _resolutions.end()) return; /* use the closest possible resolution */ - int best = 0; + uint best = 0; uint delta = Delta(_resolutions[0].width, *w) * Delta(_resolutions[0].height, *h); - for (int i = 1; i != _num_resolutions; ++i) { + for (uint i = 1; i != _resolutions.size(); ++i) { uint newdelta = Delta(_resolutions[i].width, *w) * Delta(_resolutions[i].height, *h); if (newdelta < delta) { best = i; @@ -545,7 +535,7 @@ bool VideoDriver_Allegro::ToggleFullscreen(bool fullscreen) { _fullscreen = fullscreen; GetVideoModes(); // get the list of available video modes - if (_num_resolutions == 0 || !this->ChangeResolution(_cur_resolution.width, _cur_resolution.height)) { + if (_resolutions.empty() || !this->ChangeResolution(_cur_resolution.width, _cur_resolution.height)) { /* switching resolution failed, put back full_screen to original status */ _fullscreen ^= true; return false; diff --git a/src/video/cocoa/cocoa_v.mm b/src/video/cocoa/cocoa_v.mm index d165610245..17bca028ba 100644 --- a/src/video/cocoa/cocoa_v.mm +++ b/src/video/cocoa/cocoa_v.mm @@ -234,13 +234,13 @@ static void setupApplication() } -static int CDECL ModeSorter(const OTTD_Point *p1, const OTTD_Point *p2) +static bool ModeSorter(const OTTD_Point &p1, const OTTD_Point &p2) { - if (p1->x < p2->x) return -1; - if (p1->x > p2->x) return +1; - if (p1->y < p2->y) return -1; - if (p1->y > p2->y) return +1; - return 0; + if (p1.x < p2.x) return true; + if (p1.x > p2.x) return false; + if (p1.y < p2.y) return true; + if (p1.y > p2.y) return false; + return false; } static void QZ_GetDisplayModeInfo(CFArrayRef modes, CFIndex i, int &bpp, uint16 &width, uint16 &height) @@ -326,7 +326,7 @@ uint QZ_ListModes(OTTD_Point *modes, uint max_modes, CGDirectDisplayID display_i } /* Sort list smallest to largest */ - QSortT(modes, count, &ModeSorter); + std::sort(modes, modes + count, ModeSorter); #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6) if (MacOSVersionIsAtLeast(10, 6, 0)) CFRelease(mode_list); @@ -363,12 +363,10 @@ static void QZ_UpdateVideoModes() OTTD_Point modes[32]; uint count = _cocoa_subdriver->ListModes(modes, lengthof(modes)); + _resolutions.clear(); for (uint i = 0; i < count; i++) { - _resolutions[i].width = modes[i].x; - _resolutions[i].height = modes[i].y; + _resolutions.emplace_back(modes[i].x, modes[i].y); } - - _num_resolutions = count; } /** diff --git a/src/video/sdl_v.cpp b/src/video/sdl_v.cpp index 2f6184e852..87880dea7c 100644 --- a/src/video/sdl_v.cpp +++ b/src/video/sdl_v.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include "../safeguards.h" @@ -207,53 +208,40 @@ static void GetVideoModes() SDL_Rect **modes = SDL_ListModes(nullptr, SDL_SWSURFACE | SDL_FULLSCREEN); if (modes == nullptr) usererror("sdl: no modes available"); + _resolutions.clear(); + _all_modes = (SDL_ListModes(nullptr, SDL_SWSURFACE | (_fullscreen ? SDL_FULLSCREEN : 0)) == (void*)-1); if (modes == (void*)-1) { - int n = 0; for (uint i = 0; i < lengthof(_default_resolutions); i++) { if (SDL_VideoModeOK(_default_resolutions[i].width, _default_resolutions[i].height, 8, SDL_FULLSCREEN) != 0) { - _resolutions[n] = _default_resolutions[i]; - if (++n == lengthof(_resolutions)) break; + _resolutions.push_back(_default_resolutions[i]); } } - _num_resolutions = n; } else { - int n = 0; for (int i = 0; modes[i]; i++) { uint w = modes[i]->w; uint h = modes[i]->h; if (w < 640 || h < 480) continue; // reject too small resolutions - int j; - for (j = 0; j < n; j++) { - if (_resolutions[j].width == w && _resolutions[j].height == h) break; - } - - if (j == n) { - _resolutions[j].width = w; - _resolutions[j].height = h; - if (++n == lengthof(_resolutions)) break; - } + if (std::find(_resolutions.begin(), _resolutions.end(), Dimension(w, h)) != _resolutions.end()) continue; + _resolutions.emplace_back(w, h); } - if (n == 0) usererror("No usable screen resolutions found!\n"); - _num_resolutions = n; - SortResolutions(_num_resolutions); + if (_resolutions.empty()) usererror("No usable screen resolutions found!\n"); + SortResolutions(); } } static void GetAvailableVideoMode(uint *w, uint *h) { /* All modes available? */ - if (_all_modes || _num_resolutions == 0) return; + if (_all_modes || _resolutions.empty()) return; /* Is the wanted mode among the available modes? */ - for (int i = 0; i != _num_resolutions; i++) { - if (*w == _resolutions[i].width && *h == _resolutions[i].height) return; - } + if (std::find(_resolutions.begin(), _resolutions.end(), Dimension(*w, *h)) != _resolutions.end()) return; /* Use the closest possible resolution */ - int best = 0; + uint best = 0; uint delta = Delta(_resolutions[0].width, *w) * Delta(_resolutions[0].height, *h); - for (int i = 1; i != _num_resolutions; ++i) { + for (uint i = 1; i != _resolutions.size(); ++i) { uint newdelta = Delta(_resolutions[i].width, *w) * Delta(_resolutions[i].height, *h); if (newdelta < delta) { best = i; @@ -817,7 +805,7 @@ bool VideoDriver_SDL::ToggleFullscreen(bool fullscreen) _fullscreen = fullscreen; GetVideoModes(); // get the list of available video modes - bool ret = _num_resolutions != 0 && CreateMainSurface(_cur_resolution.width, _cur_resolution.height); + bool ret = !_resolutions.empty() && CreateMainSurface(_cur_resolution.width, _cur_resolution.height); if (!ret) { /* switching resolution failed, put back full_screen to original status */ diff --git a/src/video/video_driver.hpp b/src/video/video_driver.hpp index 5cb3c6cc3f..b774c7ba6e 100644 --- a/src/video/video_driver.hpp +++ b/src/video/video_driver.hpp @@ -14,6 +14,7 @@ #include "../driver.h" #include "../core/geometry_type.hpp" +#include /** The base of all video drivers. */ class VideoDriver : public Driver { @@ -101,8 +102,7 @@ public: }; extern char *_ini_videodriver; -extern int _num_resolutions; -extern Dimension _resolutions[32]; +extern std::vector _resolutions; extern Dimension _cur_resolution; extern bool _rightclick_emulate; diff --git a/src/video/win32_v.cpp b/src/video/win32_v.cpp index 7eea4782ac..cd2b298aea 100644 --- a/src/video/win32_v.cpp +++ b/src/video/win32_v.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include "../safeguards.h" @@ -1085,45 +1086,29 @@ static const Dimension default_resolutions[] = { static void FindResolutions() { - uint n = 0; uint i; DEVMODEA dm; /* Check modes for the relevant fullscreen bpp */ uint bpp = _support8bpp != S8BPP_HARDWARE ? 32 : BlitterFactory::GetCurrentBlitter()->GetScreenDepth(); + _resolutions.clear(); + /* XXX - EnumDisplaySettingsW crashes with unicows.dll on Windows95 * Doesn't really matter since we don't pass a string anyways, but still * a letdown */ for (i = 0; EnumDisplaySettingsA(nullptr, i, &dm) != 0; i++) { - if (dm.dmBitsPerPel == bpp && - dm.dmPelsWidth >= 640 && dm.dmPelsHeight >= 480) { - uint j; - - for (j = 0; j < n; j++) { - if (_resolutions[j].width == dm.dmPelsWidth && _resolutions[j].height == 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].width = dm.dmPelsWidth; - _resolutions[j].height = dm.dmPelsHeight; - if (++n == lengthof(_resolutions)) break; - } - } + if (dm.dmBitsPerPel != bpp || dm.dmPelsWidth < 640 || dm.dmPelsHeight < 480) continue; + if (std::find(_resolutions.begin(), _resolutions.end(), Dimension(dm.dmPelsWidth, dm.dmPelsHeight)) != _resolutions.end()) continue; + _resolutions.emplace_back(dm.dmPelsWidth, dm.dmPelsHeight); } /* We have found no resolutions, show the default list */ - if (n == 0) { - memcpy(_resolutions, default_resolutions, sizeof(default_resolutions)); - n = lengthof(default_resolutions); + if (_resolutions.empty()) { + _resolutions.assign(std::begin(default_resolutions), std::end(default_resolutions)); } - _num_resolutions = n; - SortResolutions(_num_resolutions); + SortResolutions(); } static FVideoDriver_Win32 iFVideoDriver_Win32;