00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "LampBasic.h"
00026 #include "Graphics/DeviceSelector/DesktopGraphicsDeviceSelector.h"
00027 #include "Graphics/System/LampGraphics.h"
00028 #include "Graphics/System/GraphicsDeviceSettings.h"
00029 #include "Graphics/Enumeration/GraphicsDeviceEnumeration.h"
00030
00031 namespace Lamp{
00032
00033
00034
00035 DesktopGraphicsDeviceSelector::DesktopGraphicsDeviceSelector(){
00036 }
00037
00038
00039 DesktopGraphicsDeviceSelector::~DesktopGraphicsDeviceSelector(){
00040 }
00041
00042
00043 bool DesktopGraphicsDeviceSelector::findBestWindowedMode(
00044 HWND windowHandle, bool requireHAL, bool requireREF){
00045 Direct3D* direct3D = LampGraphics::getDirect3D();
00046 GraphicsDeviceEnumeration* enumeration =
00047 GraphicsDeviceEnumeration::getInstance();
00048
00049 GraphicsAdapterInformation* bestAdapter = NULL;
00050 GraphicsDeviceInformation* bestDevice = NULL;
00051 GraphicsDeviceComboInformation* bestDeviceCombo = NULL;
00052
00053 D3DDISPLAYMODE primaryDesktopDisplayMode;
00054 direct3D->GetAdapterDisplayMode(0, &primaryDesktopDisplayMode);
00055
00056 bool foundBestDevice = false;
00057
00058 int adapterCount = enumeration->getAdapterCount();
00059 for(int i = 0; i < adapterCount; i++){
00060 GraphicsAdapterInformation* adapter = enumeration->getAdapter(i);
00061
00062 int deviceCount = adapter->getDeviceCount();
00063 for(int j = 0; j < deviceCount; j++){
00064 GraphicsDeviceInformation* device = adapter->getDevice(j);
00065
00066 if(requireHAL && (device->getDeviceType() != D3DDEVTYPE_HAL)){
00067 continue;
00068 }
00069
00070 if(requireREF && (device->getDeviceType() != D3DDEVTYPE_REF)){
00071 continue;
00072 }
00073
00074 int deviceComboCount = device->getDeviceComboCount();
00075 for(int k = 0; k < deviceComboCount; k++){
00076 GraphicsDeviceComboInformation* combo =
00077 device->getDeviceCombo(k);
00078
00079 if(!combo->isWindowed()){ continue; }
00080
00081 if(combo->getAdapterFormat() !=
00082 primaryDesktopDisplayMode.Format){ continue; }
00083
00084 bool matchedBackBuffer =
00085 (combo->getAdapterFormat() == combo->getBackBufferFormat());
00086 if(
00087 (bestDeviceCombo == NULL) ||
00088
00089 ((bestDeviceCombo->getDeviceType() != D3DDEVTYPE_HAL) &&
00090 (combo->getDeviceType() == D3DDEVTYPE_HAL)) ||
00091
00092 ((bestDeviceCombo->getDeviceType() == D3DDEVTYPE_HAL) &&
00093 matchedBackBuffer)
00094 ){
00095 bestAdapter = adapter;
00096 bestDevice = device;
00097 bestDeviceCombo = combo;
00098
00099 if((device->getDeviceType() == D3DDEVTYPE_HAL) &&
00100 matchedBackBuffer){
00101 foundBestDevice = true;
00102 break;
00103 }
00104 }
00105 }
00106 if(foundBestDevice){ break; }
00107 }
00108 if(foundBestDevice){ break; }
00109 }
00110
00111 if(bestDeviceCombo == NULL){ return false; }
00112
00113
00114 buildWindowModeSettings(windowHandle, primaryDesktopDisplayMode,
00115 bestAdapter, bestDevice, bestDeviceCombo);
00116 return true;
00117 }
00118
00119
00120 bool DesktopGraphicsDeviceSelector::findBestFullscreenMode(
00121 HWND windowHandle, bool requireHAL, bool requireREF){
00122 Direct3D* direct3D = LampGraphics::getDirect3D();
00123 GraphicsDeviceEnumeration* enumeration =
00124 GraphicsDeviceEnumeration::getInstance();
00125
00126 GraphicsAdapterInformation* bestAdapter = NULL;
00127 GraphicsDeviceInformation* bestDevice = NULL;
00128 GraphicsDeviceComboInformation* bestDeviceCombo = NULL;
00129
00130
00131 D3DDISPLAYMODE bestDesktopDisplayMode;
00132
00133 bool foundBestDevice = false;
00134
00135 int adapterCount = enumeration->getAdapterCount();
00136 for(int i = 0; i < adapterCount; i++){
00137 GraphicsAdapterInformation* adapter = enumeration->getAdapter(i);
00138
00139 D3DDISPLAYMODE desktopDisplayMode;
00140 direct3D->GetAdapterDisplayMode(
00141 adapter->getAdapterOrdinal(), &desktopDisplayMode);
00142
00143 int deviceCount = adapter->getDeviceCount();
00144 for(int j = 0; j < deviceCount; j++){
00145 GraphicsDeviceInformation* device = adapter->getDevice(j);
00146
00147 if(requireHAL && (device->getDeviceType() != D3DDEVTYPE_HAL)){
00148 continue;
00149 }
00150
00151 if(requireREF && (device->getDeviceType() != D3DDEVTYPE_REF)){
00152 continue;
00153 }
00154
00155 int deviceComboCount = device->getDeviceComboCount();
00156 for(int k = 0; k < deviceComboCount; k++){
00157 GraphicsDeviceComboInformation* combo =
00158 device->getDeviceCombo(k);
00159
00160 if(combo->isWindowed()){ continue; }
00161
00162 bool matchedDesktop =
00163 (combo->getAdapterFormat() == desktopDisplayMode.Format);
00164
00165 bool matchedBackBuffer =
00166 (combo->getAdapterFormat() == combo->getBackBufferFormat());
00167
00168 if(
00169 (bestDeviceCombo == NULL) ||
00170
00171 ((bestDeviceCombo->getDeviceType() != D3DDEVTYPE_HAL) &&
00172 (combo->getDeviceType() == D3DDEVTYPE_HAL)) ||
00173
00174 ((bestDeviceCombo->getDeviceType() == D3DDEVTYPE_HAL) &&
00175 (bestDeviceCombo->getAdapterFormat() !=
00176 desktopDisplayMode.Format) && matchedDesktop) ||
00177
00178 ((bestDeviceCombo->getDeviceType() == D3DDEVTYPE_HAL) &&
00179 matchedDesktop && matchedBackBuffer)
00180 ){
00181
00182 bestDesktopDisplayMode = desktopDisplayMode;
00183 bestAdapter = adapter;
00184 bestDevice = device;
00185 bestDeviceCombo = combo;
00186
00187 if((device->getDeviceType() == D3DDEVTYPE_HAL) &&
00188 matchedDesktop && matchedBackBuffer){
00189 foundBestDevice = true;
00190 break;
00191 }
00192 }
00193 }
00194 if(foundBestDevice){ break; }
00195 }
00196 if(foundBestDevice){ break; }
00197 }
00198
00199 if(bestDeviceCombo == NULL){ return false; }
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236 RECT windowRect;
00237 ::GetClientRect(windowHandle, &windowRect);
00238 DimensionI windowSize(windowRect.right - windowRect.left,
00239 windowRect.bottom - windowRect.top);
00240 D3DDISPLAYMODE bestDisplayMode;
00241 bestDisplayMode.Width = 0;
00242 bestDisplayMode.Height = 0;
00243 bestDisplayMode.Format = D3DFMT_UNKNOWN;
00244 bestDisplayMode.RefreshRate = 0;
00245 int displayModeCount = bestAdapter->getDisplayModeCount();
00246 for(int i = 0; i < displayModeCount; i++){
00247 D3DDISPLAYMODE displayMode = bestAdapter->getDisplayMode(i);
00248
00249 if(bestDeviceCombo->getAdapterFormat() != displayMode.Format){
00250 continue;
00251 }
00252
00253 if(bestDisplayMode.Width == 0){
00254 bestDisplayMode = displayMode;
00255 continue;
00256 }
00257
00258 int newWidthDist = Math::abs((int)(
00259 (int)windowSize.width - (int)displayMode.Width));
00260 int bestWidthDist = Math::abs((int)(
00261 (int)windowSize.width - (int)bestDisplayMode.Width));
00262 if(newWidthDist > bestWidthDist){ continue; }
00263
00264 if(newWidthDist != bestWidthDist){
00265 bestDisplayMode = displayMode;
00266 continue;
00267 }
00268
00269 int newHeightDist = Math::abs((int)(
00270 (int)windowSize.height - (int)displayMode.Height));
00271 int bestHeightDist = Math::abs((int)(
00272 (int)windowSize.height - (int)bestDisplayMode.Height));
00273 if(newHeightDist > bestHeightDist){ continue; }
00274
00275 if(newHeightDist != bestHeightDist){
00276 bestDisplayMode = displayMode;
00277 continue;
00278 }
00279
00280 int newRefreshDist = Math::abs((int)(
00281 (int)bestDesktopDisplayMode.RefreshRate -
00282 (int)displayMode.RefreshRate));
00283 int bestRefreshDist = Math::abs((int)(
00284 (int)bestDesktopDisplayMode.RefreshRate -
00285 (int)bestDisplayMode.RefreshRate));
00286 if(newRefreshDist > bestRefreshDist){ continue; }
00287
00288 bestDisplayMode = displayMode;
00289 }
00290
00291
00292 buildFullscreenModeSettings(
00293 bestDisplayMode, bestAdapter, bestDevice, bestDeviceCombo);
00294 return true;
00295 }
00296
00297 }
00298