//----------------------------------------------------------------------------- // Name: ToggleFullScreen() // Desc: Called when user toggles between fullscreen mode and windowed mode //----------------------------------------------------------------------------- HRESULT CDXGraphicsContext::DoToggleFullscreen() { // Need device change if going windowed and the current device // can only be fullscreen m_bReady = false; // Toggle the windowed state m_bWindowed = !m_bWindowed; // Prepare window for windowed/fullscreen change AdjustWindowForChange(); Lock(); m_pd3dDevice->Reset( &m_d3dpp ); CRender::GetRender()->CleanUp(); CleanUp(); m_pD3D = Direct3DCreate9( D3D_SDK_VERSION ); if( m_pD3D == NULL ) { TRACE0("Error to create m_pD3D"); Unlock(); return DisplayD3DErrorMsg( D3DAPPERR_NODIRECT3D, MSGERR_APPMUSTEXIT ); } InitializeD3D(); Unlock(); CRender::g_pRender->SetViewport(0, 0, windowSetting.uViWidth, windowSetting.uViHeight, 0x3FF); // When moving from fullscreen to windowed mode, it is important to // adjust the window size after resetting the device rather than // beforehand to ensure that you get the window size you want. For // example, when switching from 640x480 fullscreen to windowed with // a 1000x600 window on a 1024x768 desktop, it is impossible to set // the window size to 1000x600 until after the display mode has // changed to 1024x768, because windows cannot be larger than the // desktop. if( m_bWindowed ) { SetWindowLong(m_hWnd, GWL_STYLE, WS_OVERLAPPEDWINDOW); SetWindowPos( m_hWnd, HWND_NOTOPMOST, m_rcWindowBounds.left, m_rcWindowBounds.top, ( m_rcWindowBounds.right - m_rcWindowBounds.left ), ( m_rcWindowBounds.bottom - m_rcWindowBounds.top ), SWP_SHOWWINDOW ); } m_bReady = true; return S_OK; }
//----------------------------------------------------------------------------- // Name: Initialize3DEnvironment() // Desc: Usually this function is not overridden. Here's what this function does: // - Sets the windowed flag to be either windowed or fullscreen // - Sets parameters for z-buffer depth and back buffer // - Creates the D3D device // - Sets the window position (if windowed, that is) // - Makes some determinations as to the abilites of the driver (HAL, etc) // - Sets up some cursor stuff // - Calls InitDeviceObjects() // - Calls RestoreDeviceObjects() // - If all goes well, m_bActive is set to TRUE, and the function returns // - Otherwise, initialization is reattempted using the reference device //----------------------------------------------------------------------------- HRESULT CMyD3DApplication::Initialize3DEnvironment() { HRESULT hr; D3DAdapterInfo* pAdapterInfo = m_d3dSettings.PAdapterInfo(); D3DDeviceInfo* pDeviceInfo = m_d3dSettings.PDeviceInfo(); m_bWindowed = m_d3dSettings.IsWindowed; // Prepare window for possible windowed/fullscreen change AdjustWindowForChange(); // Set up the presentation parameters BuildPresentParamsFromSettings(); if( pDeviceInfo->Caps.PrimitiveMiscCaps & D3DPMISCCAPS_NULLREFERENCE ) { // Warn user about null ref device that can't render anything DisplayErrorMsg( D3DAPPERR_NULLREFDEVICE, 0 ); } DWORD behaviorFlags; if (m_d3dSettings.GetVertexProcessingType() == SOFTWARE_VP) behaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING; else if (m_d3dSettings.GetVertexProcessingType() == MIXED_VP) behaviorFlags = D3DCREATE_MIXED_VERTEXPROCESSING; else if (m_d3dSettings.GetVertexProcessingType() == HARDWARE_VP) behaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING; else if (m_d3dSettings.GetVertexProcessingType() == PURE_HARDWARE_VP) behaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE; else behaviorFlags = 0; // TODO: throw exception // Add multithreaded flag if requested by app if( m_bCreateMultithreadDevice ) behaviorFlags |= D3DCREATE_MULTITHREADED; // Create the device hr = m_pD3D->CreateDevice( m_d3dSettings.AdapterOrdinal(), pDeviceInfo->DevType, m_hWndFocus, behaviorFlags, &m_d3dpp, &m_pd3dDevice ); if( SUCCEEDED(hr) ) { // When moving from fullscreen to windowed mode, it is important to // adjust the window size after recreating the device rather than // beforehand to ensure that you get the window size you want. For // example, when switching from 640x480 fullscreen to windowed with // a 1000x600 window on a 1024x768 desktop, it is impossible to set // the window size to 1000x600 until after the display mode has // changed to 1024x768, because windows cannot be larger than the // desktop. if( m_bWindowed ) { SetWindowPos( m_hWnd, HWND_NOTOPMOST, m_rcWindowBounds.left, m_rcWindowBounds.top, ( m_rcWindowBounds.right - m_rcWindowBounds.left ), ( m_rcWindowBounds.bottom - m_rcWindowBounds.top ), SWP_HIDEWINDOW ); } // Store device Caps m_pd3dDevice->GetDeviceCaps( &m_d3dCaps ); m_dwCreateFlags = behaviorFlags; // Store device description if( pDeviceInfo->DevType == D3DDEVTYPE_REF ) lstrcpy( m_strDeviceStats, TEXT("REF") ); else if( pDeviceInfo->DevType == D3DDEVTYPE_HAL ) lstrcpy( m_strDeviceStats, TEXT("HAL") ); else if( pDeviceInfo->DevType == D3DDEVTYPE_SW ) lstrcpy( m_strDeviceStats, TEXT("SW") ); if( behaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING && behaviorFlags & D3DCREATE_PUREDEVICE ) { if( pDeviceInfo->DevType == D3DDEVTYPE_HAL ) lstrcat( m_strDeviceStats, TEXT(" (pure hw vp)") ); else lstrcat( m_strDeviceStats, TEXT(" (simulated pure hw vp)") ); } else if( behaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING ) { if( pDeviceInfo->DevType == D3DDEVTYPE_HAL ) lstrcat( m_strDeviceStats, TEXT(" (hw vp)") ); else lstrcat( m_strDeviceStats, TEXT(" (simulated hw vp)") ); } else if( behaviorFlags & D3DCREATE_MIXED_VERTEXPROCESSING ) { if( pDeviceInfo->DevType == D3DDEVTYPE_HAL ) lstrcat( m_strDeviceStats, TEXT(" (mixed vp)") ); else lstrcat( m_strDeviceStats, TEXT(" (simulated mixed vp)") ); } else if( behaviorFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING ) { lstrcat( m_strDeviceStats, TEXT(" (sw vp)") ); } if( pDeviceInfo->DevType == D3DDEVTYPE_HAL ) { // Be sure not to overflow m_strDeviceStats when appending the adapter // description, since it can be long. Note that the adapter description // is initially CHAR and must be converted to TCHAR. lstrcat( m_strDeviceStats, TEXT(": ") ); const int cchDesc = sizeof(pAdapterInfo->AdapterIdentifier.Description); TCHAR szDescription[cchDesc]; DXUtil_ConvertAnsiStringToGenericCch( szDescription, pAdapterInfo->AdapterIdentifier.Description, cchDesc ); int maxAppend = sizeof(m_strDeviceStats) / sizeof(TCHAR) - lstrlen( m_strDeviceStats ) - 1; _tcsncat( m_strDeviceStats, szDescription, maxAppend ); } // Store render target surface desc LPDIRECT3DSURFACE9 pBackBuffer = NULL; m_pd3dDevice->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer ); pBackBuffer->GetDesc( &m_d3dsdBackBuffer ); pBackBuffer->Release(); // Set up the fullscreen cursor if( m_bShowCursorWhenFullscreen && !m_bWindowed ) { HCURSOR hCursor; #ifdef _WIN64 hCursor = (HCURSOR)GetClassLongPtr( m_hWnd, GCLP_HCURSOR ); #else hCursor = (HCURSOR)ULongToHandle( GetClassLong( m_hWnd, GCL_HCURSOR ) ); #endif D3DUtil_SetDeviceCursor( m_pd3dDevice, hCursor, true ); m_pd3dDevice->ShowCursor( true ); } // Confine cursor to fullscreen window if( m_bClipCursorWhenFullscreen ) { if (!m_bWindowed ) { RECT rcWindow; GetWindowRect( m_hWnd, &rcWindow ); ClipCursor( &rcWindow ); } else { ClipCursor( NULL ); } } // Initialize the app's device-dependent objects hr = InitDeviceObjects(); if( FAILED(hr) ) { DeleteDeviceObjects(); } else { m_bDeviceObjectsInited = true; hr = RestoreDeviceObjects(); if( FAILED(hr) ) { InvalidateDeviceObjects(); } else { m_bDeviceObjectsRestored = true; return S_OK; } } // Cleanup before we try again Cleanup3DEnvironment(); } // If that failed, fall back to the reference rasterizer if( hr != D3DAPPERR_MEDIANOTFOUND && hr != HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND ) && pDeviceInfo->DevType == D3DDEVTYPE_HAL ) { if (FindBestWindowedMode(false, true)) { m_bWindowed = true; AdjustWindowForChange(); // Make sure main window isn't topmost, so error message is visible SetWindowPos( m_hWnd, HWND_NOTOPMOST, m_rcWindowBounds.left, m_rcWindowBounds.top, ( m_rcWindowBounds.right - m_rcWindowBounds.left ), ( m_rcWindowBounds.bottom - m_rcWindowBounds.top ), SWP_SHOWWINDOW ); // Let the user know we are switching from HAL to the reference rasterizer DisplayErrorMsg( hr, MSGWARN_SWITCHEDTOREF ); hr = Initialize3DEnvironment(); } } return hr; }
HRESULT CDXGraphicsContext::InitializeD3D() { // Prepare window for possible windowed/fullscreen change AdjustWindowForChange(); windowSetting.statusBarHeightToUse = 0; windowSetting.toolbarHeightToUse = 0; // Set up the presentation parameters //Clear out our presentation struct for use ZeroMemory( &m_d3dpp, sizeof(m_d3dpp) ); m_d3dpp.Windowed = m_bWindowed; m_d3dpp.BackBufferCount = 1; m_d3dpp.EnableAutoDepthStencil = TRUE; /*m_bUseDepthBuffer;*/ m_d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8; m_d3dpp.hDeviceWindow = m_hWnd; m_d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; m_d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; m_FSAAIsEnabled = false; if (options.DirectXAntiAliasingValue != 0 && m_maxFSAA > 0) { m_d3dpp.MultiSampleType = (D3DMULTISAMPLE_TYPE)(D3DMULTISAMPLE_NONE + min(m_maxFSAA, (int)options.DirectXAntiAliasingValue)); m_FSAAIsEnabled = true; //TRACE1("Start with FSAA=%d X", pDeviceInfo->MultiSampleType-D3DMULTISAMPLE_NONE); } if( currentRomOptions.N64FrameBufferEmuType != FRM_BUF_NONE && m_FSAAIsEnabled ) { m_FSAAIsEnabled = false; m_d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; m_d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; TRACE0("FSAA is turned off in order to use BackBuffer emulation"); SetWindowText(g_GraphicsInfo.hStatusBar, "FSAA is turned off in order to use BackBuffer emulation"); } if( !m_FSAAIsEnabled ) m_d3dpp.SwapEffect = m_bWindowed ? D3DSWAPEFFECT_COPY : D3DSWAPEFFECT_FLIP; // Always use COPY for window mode else m_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; // Anti-Aliasing mode windowSetting.uDisplayWidth = m_bWindowed ? windowSetting.uWindowDisplayWidth : windowSetting.uFullScreenDisplayWidth; windowSetting.uDisplayHeight = m_bWindowed ? windowSetting.uWindowDisplayHeight : windowSetting.uFullScreenDisplayHeight; m_d3dpp.FullScreen_RefreshRateInHz = m_bWindowed ? 0 : windowSetting.uFullScreenRefreshRate; if (m_d3dpp.FullScreen_RefreshRateInHz > m_displayMode.RefreshRate && !m_bWindowed) { m_d3dpp.FullScreen_RefreshRateInHz = m_displayMode.RefreshRate; windowSetting.uFullScreenRefreshRate = m_displayMode.RefreshRate; } m_d3dpp.BackBufferWidth = m_bWindowed ? 0 : windowSetting.uDisplayWidth; m_d3dpp.BackBufferHeight = m_bWindowed ? 0 : windowSetting.uDisplayHeight; // Create the device if(!SUCCEEDED(m_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, &m_d3dpp, &m_pd3dDevice ))) { if(!SUCCEEDED(m_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &m_d3dpp, &m_pd3dDevice ))) { MsgInfo("Failed to initialize Direct3D"); return E_FAIL; } } if(m_pd3dDevice ) { g_pD3DDev = m_pd3dDevice; gD3DDevWrapper.SetD3DDev(m_pd3dDevice); // Store device Caps m_pd3dDevice->GetDeviceCaps( &m_d3dCaps ); if( m_bWindowed ) { SetWindowPos( m_hWnd, HWND_NOTOPMOST, m_rcWindowBounds.left, m_rcWindowBounds.top, ( m_rcWindowBounds.right - m_rcWindowBounds.left ), ( m_rcWindowBounds.bottom - m_rcWindowBounds.top ), SWP_SHOWWINDOW ); } // Store render target surface desc LPDIRECT3DSURFACE9 pBackBuffer; m_pd3dDevice->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer ); pBackBuffer->GetDesc( &m_d3dsdBackBuffer ); pBackBuffer->Release(); if ( CRender::IsAvailable() ) { CRender::GetRender()->InitDeviceObjects(); } m_bActive = true; return S_OK; } else { if( status.ToToggleFullScreen || !m_bWindowed ) SetWindowText(g_GraphicsInfo.hStatusBar,"Can not initialize DX9, check your Direct settings"); else MsgInfo("Can not initialize DX9, check your Direct settings"); } return E_FAIL; }