FIFE
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
devicecaps.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005-2013 by the FIFE team *
3  * http://www.fifengine.net *
4  * This file is part of FIFE. *
5  * *
6  * FIFE is free software; you can redistribute it and/or *
7  * modify it under the terms of the GNU Lesser General Public *
8  * License as published by the Free Software Foundation; either *
9  * version 2.1 of the License, or (at your option) any later version. *
10  * *
11  * This library is distributed in the hope that it will be useful, *
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
14  * Lesser General Public License for more details. *
15  * *
16  * You should have received a copy of the GNU Lesser General Public *
17  * License along with this library; if not, write to the *
18  * Free Software Foundation, Inc., *
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
20  ***************************************************************************/
21 
22 // Standard C++ library includes
23 #include <iostream>
24 #include <algorithm>
25 
26 // 3rd party library includes
27 #include <SDL.h>
28 #include <SDL_video.h>
29 
30 // FIFE includes
31 // These includes are split up in two parts, separated by one empty line
32 // First block: files included from the FIFE root src directory
33 // Second block: files included from the same folder
34 #include "util/base/exception.h"
35 
36 #include "devicecaps.h"
37 
38 namespace FIFE {
39 
41  m_width(0), m_height(0), m_bpp(0), m_SDLFlags(0){
42  }
43 
44  ScreenMode::ScreenMode(uint16_t width, uint16_t height, uint16_t bpp, uint32_t SDLFlags) :
45  m_width(width), m_height(height), m_bpp(bpp), m_SDLFlags(SDLFlags){
46  }
47 
49  m_width = rhs.getWidth();
50  m_height = rhs.getHeight();
51  m_bpp = rhs.getBPP();
52  m_SDLFlags = rhs.getSDLFlags();
53  }
54 
55  bool ScreenMode::operator <(const ScreenMode& rhs) const {
56 
57  //sort by fullscreen first
58  if (!isFullScreen() && rhs.isFullScreen()){
59  return true;
60  }
61  else if (isFullScreen() && !rhs.isFullScreen()){
62  return false;
63  }
64 
65  //next by bpp
66  if (m_bpp < rhs.getBPP()){
67  return true;
68  }
69  else if (m_bpp > rhs.getBPP()){
70  return false;
71  }
72 
73  //then by screen dimentions
74  if (m_width == rhs.getWidth() && m_height == rhs.getHeight()){
75  if (!(m_SDLFlags & SDL_HWSURFACE) && (rhs.getSDLFlags() & SDL_HWSURFACE)) {
76  //I would like return true so that we prefer hardware surfaces but
77  //it really slows the engine down in fullscreen. See the SDL FAQ for an
78  //explanation.
79  return false;
80  }
81  }
82 
83  else if (m_width < rhs.getWidth() || m_height < rhs.getHeight()) {
84  return true;
85  }
86 
87  return false;
88  }
89 
91  m_driverName("Invalid"),
92  m_hwAvailable(false),
93  m_wmAvailable(false),
94  m_hwBlitAccel(false),
95  m_hwCCBlitAccel(false),
96  m_hwToHwAlphaBlitAccel(false),
97  m_swToHwBlitAccel(false),
98  m_swToHwCCBlistAccel(false),
99  m_swToHwAlphaBlitAccel(false),
100  m_BlitFillAccel(false),
101  m_videoMem(0),
102  m_desktopWidth(0),
103  m_desktopHeight(0) {
104 
106  }
107 
108 
110  }
111 
113  m_screenModes.clear();
114  m_driverName = "Invalid";
115  m_hwAvailable = false;
116  m_wmAvailable = false;
117  m_hwBlitAccel = false;
118  m_hwCCBlitAccel = false;
119  m_hwToHwAlphaBlitAccel = false;
120  m_swToHwBlitAccel = false;
121  m_swToHwCCBlistAccel = false;
122  m_swToHwAlphaBlitAccel = false;
123  m_BlitFillAccel = false;
124  m_videoMem = 0;
125  m_desktopWidth = 0;
126  m_desktopHeight = 0;
127  }
128 
129 
131  m_availableDrivers.clear();
132 #if defined( __unix__ )
133  m_availableDrivers.push_back("x11");
134  m_availableDrivers.push_back("nanox");
135  m_availableDrivers.push_back("qtopia");
136  m_availableDrivers.push_back("fbcon");
137  m_availableDrivers.push_back("directfb");
138  m_availableDrivers.push_back("svgalib");
139 #endif
140 
141 // Win32
142 #if defined( WIN32 )
143  m_availableDrivers.push_back("directx");
144  m_availableDrivers.push_back("windib");
145 #endif
146 
147 // Macintosh
148 #if defined( __APPLE_CC__ )
149  m_availableDrivers.push_back("Quartz");
150  m_availableDrivers.push_back("x11");
151 #endif
152  }
153 
155  //buffer to store driver name
156  const uint32_t bufferSize = 256;
157  char buffer[bufferSize];
158 
159  //clear in case this is called twice
160  reset();
161 
162  //FLAGS
163 #ifdef HAVE_OPENGL
164  const uint32_t numFlags = 6;
165  uint32_t flags[numFlags];
166 
167  //OpenGL, windowed, hw accel
169  //OpenGL, fullscree, hw accel
171  //SDL, windowed
172  flags[2] = ScreenMode::WINDOWED_SDL;
173  //SDL, windowed, hw surface, double buffer
175  //SDL, fullscreen
176  flags[4] = ScreenMode::FULLSCREEN_SDL;
177  //SDL, fullscreen, hw surface, double buffer
179 
180 #else
181  const uint32_t numFlags = 4;
182  uint32_t flags[numFlags];
183 
184  //SDL, windowed
185  flags[0] = ScreenMode::WINDOWED_SDL;
186  //SDL, windowed, hw surface, double buffer
188  //SDL, fullscreen
189  flags[2] = ScreenMode::FULLSCREEN_SDL;
190  //SDL, fullscreen, hw surface, double buffer
192 #endif
193 
194  //BITS PER PIXEL
195  const uint32_t numBPP = 3;
196  uint16_t bpps[numBPP];
197 
198  bpps[0] = 16;
199  bpps[1] = 24;
200  bpps[2] = 32;
201 
202  //COMMON FS RESOLUTIONS
203  const uint32_t numRes = 16;
204  uint16_t resolutions[numRes][2] = {
205  {640, 480},
206  {800, 600},
207  {1024, 600},
208  {1024, 768},
209  {1152, 864},
210  {1280, 768},
211  {1280, 800},
212  {1280, 960},
213  {1280, 1024},
214  {1366, 768},
215  {1440, 900},
216  {1600, 900},
217  {1600, 1200},
218  {1680, 1050},
219  {1920, 1080},
220  {1920, 1200}
221  };
222 
223 
224  for (uint32_t i = 0; i < numBPP; ++i){
225  for (uint32_t j = 0; j < numFlags; ++j) {
226  for ( uint32_t k = 0; k < numRes; ++k) {
227  uint16_t bpp;
228  if (flags[j] & SDL_FULLSCREEN) {
229  bpp = SDL_VideoModeOK(resolutions[k][0],resolutions[k][1], bpps[i], flags[j]);
230 
231  if (bpp > 0) {
232  m_screenModes.push_back(ScreenMode(resolutions[k][0],resolutions[k][1], bpps[i], flags[j]));
233  }
234  }
235  else { //windowed mode
236  //check an arbitrary value as we know all resolutions are supported in windowed mode.
237  //we are checking to make sure the bpp is supported here.
238  bpp = SDL_VideoModeOK(resolutions[k][0],resolutions[k][1], bpps[i], flags[j]);
239  if (bpp > 0) {
240  m_screenModes.push_back(ScreenMode(0,0, bpps[i], flags[j]));
241  break; //insert windowed mode once as all resolutions are supported.
242  }
243  }
244 
245  }
246  }
247  }
248 
249  //sort the list to keep the most preferred modes at the top of the selection process
250  //in getNearestScreenMode()
251  std::sort(m_screenModes.begin(), m_screenModes.end());
252  std::reverse(m_screenModes.begin(), m_screenModes.end());
253 
254  if(SDL_VideoDriverName(buffer, bufferSize) != NULL) {
255  m_driverName = std::string(buffer);
256  }
257  else {
258  m_driverName = "Unknown";
259  }
260 
261  const SDL_VideoInfo* vInfo = SDL_GetVideoInfo();
262 
263  m_hwAvailable = vInfo->hw_available;
264  m_wmAvailable = vInfo->wm_available;
265  m_hwBlitAccel = vInfo->blit_hw;
266  m_hwCCBlitAccel = vInfo->blit_hw_CC;
267  m_hwToHwAlphaBlitAccel = vInfo->blit_hw_A;
268  m_swToHwBlitAccel = vInfo->blit_sw;
269  m_swToHwCCBlistAccel = vInfo->blit_sw_CC;
270  m_swToHwAlphaBlitAccel = vInfo->blit_sw_A;
271  m_BlitFillAccel = vInfo->blit_fill;
272  m_videoMem = vInfo->video_mem;
273  m_desktopWidth = vInfo->current_w;
274  m_desktopHeight = vInfo->current_h;
275  }
276 
277  ScreenMode DeviceCaps::getNearestScreenMode(uint16_t width, uint16_t height, uint16_t bpp, const std::string& renderer, bool fs) const {
278  ScreenMode mode;
279  bool foundMode = false;
280 
281  bool widthCheck = false;
282  bool heightCheck = false;
283  bool bppCheck = false;
284  bool rendCheck = false;
285  bool fsCheck = false;
286 
287 
288  for (uint32_t i = 0; i < m_screenModes.size(); i++) {
289  if (m_screenModes[i].getWidth() == width) {
290  widthCheck = true;
291  }
292  if (m_screenModes[i].getHeight() == height) {
293  heightCheck = true;
294  }
295  if (m_screenModes[i].getBPP() == bpp) {
296  bppCheck = true;
297  }
298  if (m_screenModes[i].isFullScreen() == fs) {
299  fsCheck = true;
300  }
301 
302  if ((m_screenModes[i].isOpenGL() && (renderer == "OpenGL" || renderer == "OpenGLe")) || (!m_screenModes[i].isOpenGL() && renderer == "SDL")){
303  rendCheck = true;
304  }
305 
306  //check for exact match
307  if (widthCheck && heightCheck && bppCheck && fsCheck && rendCheck) {
308  mode = m_screenModes[i];
309  foundMode = true;
310  break;
311  }
312 
313  //@note When the width and height to 0 that means that all
314  //resolutions are supported
315  if (m_screenModes[i].getWidth() == 0 && m_screenModes[i].getHeight() == 0 && bppCheck && fsCheck && rendCheck) {
316  mode = ScreenMode(width, height, bpp, m_screenModes[i].getSDLFlags());
317  foundMode = true;
318  break;
319  }
320 
321  //current screen bpp selected
322  if (widthCheck && heightCheck && bpp == 0 && fsCheck && rendCheck) {
323  mode = ScreenMode(width, height, bpp, m_screenModes[i].getSDLFlags());
324  foundMode = true;
325  break;
326  }
327 
328  if (m_screenModes[i].getWidth() == 0 && m_screenModes[i].getHeight() == 0 && bpp == 0 && fsCheck && rendCheck) {
329  mode = ScreenMode(width, height, bpp, m_screenModes[i].getSDLFlags());
330  foundMode = true;
331  break;
332  }
333 
334 
335  widthCheck = false;
336  heightCheck = false;
337  bppCheck = false;
338  rendCheck = false;
339  fsCheck = false;
340  }
341 
342  if (!foundMode) {
343  throw NotSupported("Could not find a maching screen mode for the values given!");
344  }
345 
346  return mode;
347  }
348 
349  int32_t DeviceCaps::getDesktopWidth() const {
350  return m_desktopWidth;
351  }
352 
354  return m_desktopHeight;
355  }
356 } //FIFE
bool m_swToHwBlitAccel
Definition: devicecaps.h:206
uint16_t m_bpp
Definition: devicecaps.h:109
static const uint32_t HW_WINDOWED_OPENGL
Definition: devicecaps.h:94
int32_t getDesktopHeight() const
Returns the height of the desktop resolution.
Definition: devicecaps.cpp:353
uint32_t getSDLFlags() const
Returns the SDL flags used when testing this mode.
Definition: devicecaps.h:74
static const uint32_t FULLSCREEN_SDL_DB_HW
Definition: devicecaps.h:104
std::vector< std::string > m_availableDrivers
Definition: devicecaps.h:199
uint32_t m_SDLFlags
Definition: devicecaps.h:110
std::string m_driverName
Definition: devicecaps.h:198
bool m_swToHwCCBlistAccel
Definition: devicecaps.h:207
uint16_t getBPP() const
Returns the number of bits per pixel this mode uses.
Definition: devicecaps.h:70
bool operator<(const ScreenMode &rhs) const
Definition: devicecaps.cpp:55
ScreenMode getNearestScreenMode(uint16_t width, uint16_t height, uint16_t bpp, const std::string &renderer, bool fs) const
Gets the nearest valid screen mode based on the arguments passed.
Definition: devicecaps.cpp:277
void fillAvailableDrivers()
Called in the constructor.
Definition: devicecaps.cpp:130
bool isFullScreen() const
True if this is a fullscreen mode.
Definition: devicecaps.h:78
ScreenMode()
Default Constructor.
Definition: devicecaps.cpp:40
static const uint32_t FULLSCREEN_SDL
Definition: devicecaps.h:102
int32_t m_desktopHeight
Definition: devicecaps.h:213
static const uint32_t HW_FULLSCREEN_OPENGL
Definition: devicecaps.h:96
uint16_t m_width
Definition: devicecaps.h:107
void reset()
Clears all information gathered for the device.
Definition: devicecaps.cpp:112
int32_t m_desktopWidth
Definition: devicecaps.h:212
uint16_t getHeight() const
Returns the height of the screen mode.
Definition: devicecaps.h:66
bool m_hwToHwAlphaBlitAccel
Definition: devicecaps.h:205
unsigned short uint16_t
Definition: core.h:39
uint16_t getWidth() const
Returns the width of the screen mode.
Definition: devicecaps.h:60
uint32_t m_videoMem
Definition: devicecaps.h:211
static const uint32_t WINDOWED_SDL_DB_HW
Definition: devicecaps.h:100
int32_t getDesktopWidth() const
Returns the width of the desktop resolution.
Definition: devicecaps.cpp:349
void fillDeviceCaps()
Should be called AFTER SDL_Init() has been called.
Definition: devicecaps.cpp:154
static const uint32_t WINDOWED_SDL
Definition: devicecaps.h:98
uint16_t m_height
Definition: devicecaps.h:108
unsigned int uint32_t
Definition: core.h:40
std::vector< ScreenMode > m_screenModes
Definition: devicecaps.h:197
bool m_swToHwAlphaBlitAccel
Definition: devicecaps.h:208
~DeviceCaps()
Destructor.
Definition: devicecaps.cpp:109
DeviceCaps()
Constructor.
Definition: devicecaps.cpp:90