int DDInitWindowed(int width, int height, int bpp, HWND hwnd) { HRESULT ret; // create object and test for error if (DirectDrawCreate(NULL, &lpDD, NULL) != DD_OK) { return(0); } // set cooperation level to windowed mode normal if (lpDD->SetCooperativeLevel(hwnd, DDSCL_NORMAL) != DD_OK) { return(0); } // set globals screen_height = height; screen_width = width; screen_bpp = bpp; // Create the primary surface memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS; // all we need for windowed mode is access to the primary surface ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; // create the primary surface ret = lpDD->CreateSurface(&ddsd, &lpDDSPrimary, NULL); // create an offscreen and system mem back surface lpDDSBack = DDCreateSurface(width, height, NULL); lpDD->CreateClipper(0, &lpDDClipper, NULL); lpDDClipper->SetHWnd(0, hwnd); lpDDSPrimary->SetClipper(lpDDClipper); // clear out both primary and secondary surfaces DDFillSurface(lpDDSPrimary, 0); DDFillSurface(lpDDSBack, 0); DDGetRGB16(); return 1; }
PRBool nsWindowGfx::InitDDraw() { HRESULT hr; hr = DirectDrawCreate(NULL, &glpDD, NULL); NS_ENSURE_SUCCESS(hr, PR_FALSE); hr = glpDD->SetCooperativeLevel(NULL, DDSCL_NORMAL); NS_ENSURE_SUCCESS(hr, PR_FALSE); DDSURFACEDESC ddsd; memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS; ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat); ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; hr = glpDD->CreateSurface(&ddsd, &glpDDPrimary, NULL); NS_ENSURE_SUCCESS(hr, PR_FALSE); hr = glpDD->CreateClipper(0, &glpDDClipper, NULL); NS_ENSURE_SUCCESS(hr, PR_FALSE); hr = glpDDPrimary->SetClipper(glpDDClipper); NS_ENSURE_SUCCESS(hr, PR_FALSE); // We do not use the cairo ddraw surface for IMAGE_DDRAW16. Instead, we // use an 24bpp image surface, convert that to 565, then blit using ddraw. if (!IsRenderMode(gfxWindowsPlatform::RENDER_IMAGE_DDRAW16)) { gfxIntSize screen_size(GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)); gpDDSurf = new gfxDDrawSurface(glpDD, screen_size, gfxASurface::ImageFormatRGB24); if (!gpDDSurf) { /*XXX*/ fprintf(stderr, "couldn't create ddsurf\n"); return PR_FALSE; } } return PR_TRUE; }
bool CDirectDraw::SetDisplayMode( int pWidth, int pHeight, int pScale, char pDepth, int pRefreshRate, bool pWindowed, bool pDoubleBuffered) { if(pScale < 2) pScale = 2; static bool BLOCK = false; DDSURFACEDESC ddsd; PALETTEENTRY PaletteEntries [256]; if (BLOCK) return (false); BLOCK = true; if (pWindowed) pDoubleBuffered = false; if (pDepth == 0) pDepth = depth; if (lpDDSPrimary2 != NULL) { lpDDSPrimary2->Release(); lpDDSPrimary2 = NULL; } if (lpDDSOffScreen2 != NULL) { lpDDSOffScreen2->PageUnlock(0); lpDDSOffScreen2->Release(); lpDDSOffScreen2 = NULL; } if( lpDDPalette != NULL) { lpDDPalette->Release(); lpDDPalette = NULL; } lpDD->FlipToGDISurface(); if (pWindowed) { lpDD->RestoreDisplayMode(); ZeroMemory (&ddsd, sizeof (ddsd)); ddsd.dwSize = sizeof (ddsd); ddsd.dwFlags = DDSD_PIXELFORMAT; dErr = lpDD->GetDisplayMode (&ddsd); if (FAILED(dErr)) pDepth = 8; else { if (ddsd.ddpfPixelFormat.dwFlags&DDPF_RGB) pDepth = (char) ddsd.ddpfPixelFormat.dwRGBBitCount; else pDepth = 8; } if (pDepth == 8) dErr = lpDD->SetCooperativeLevel (GUI.hWnd, DDSCL_FULLSCREEN| DDSCL_EXCLUSIVE|DDSCL_ALLOWREBOOT); else dErr = lpDD->SetCooperativeLevel (GUI.hWnd, DDSCL_NORMAL|DDSCL_ALLOWREBOOT); } else { dErr = lpDD->SetCooperativeLevel (GUI.hWnd, DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN|DDSCL_ALLOWREBOOT); // XXX: TODO: use pRefreshRate! dErr = lpDD->SetDisplayMode (pWidth, pHeight, pDepth); } if (FAILED(dErr)) { BLOCK = false; return false; } ZeroMemory (&ddsd, sizeof (ddsd)); ddsd.dwSize = sizeof (ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; if(GUI.BilinearFilter) { ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY | (GUI.LocalVidMem ? DDSCAPS_LOCALVIDMEM : DDSCAPS_NONLOCALVIDMEM); } else { ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; } ddsd.dwWidth = SNES_WIDTH * pScale; ddsd.dwHeight = SNES_HEIGHT_EXTENDED * pScale; LPDIRECTDRAWSURFACE lpDDSOffScreen; if (FAILED(lpDD->CreateSurface (&ddsd, &lpDDSOffScreen, NULL))) { ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY | (GUI.LocalVidMem ? DDSCAPS_NONLOCALVIDMEM : DDSCAPS_LOCALVIDMEM); if(!GUI.BilinearFilter || FAILED(lpDD->CreateSurface (&ddsd, &lpDDSOffScreen, NULL))) { ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; if(!GUI.BilinearFilter || FAILED(lpDD->CreateSurface (&ddsd, &lpDDSOffScreen, NULL))) { BLOCK = false; return (false); } } } if (FAILED (lpDDSOffScreen->QueryInterface (IID_IDirectDrawSurface2, (void **)&lpDDSOffScreen2))) { lpDDSOffScreen->Release(); BLOCK = false; return (false); } lpDDSOffScreen2->PageLock(0); lpDDSOffScreen->Release(); ZeroMemory (&ddsd, sizeof (ddsd)); if (pDoubleBuffered) { ddsd.dwSize = sizeof( ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP; GUI.NumFlipFrames = 3; ddsd.dwBackBufferCount = 2; } else { GUI.NumFlipFrames = 1; ddsd.dwSize = sizeof (ddsd); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; } LPDIRECTDRAWSURFACE lpDDSPrimary; dErr = lpDD->CreateSurface (&ddsd, &lpDDSPrimary, NULL); if( FAILED(dErr) ) { if (pDoubleBuffered) { ddsd.dwBackBufferCount = 1; GUI.NumFlipFrames = 2; if (FAILED(dErr = lpDD->CreateSurface (&ddsd, &lpDDSPrimary, NULL))) { ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; pDoubleBuffered = false; GUI.NumFlipFrames = 1; dErr = lpDD->CreateSurface (&ddsd, &lpDDSPrimary, NULL); } } if (FAILED(dErr)) { BLOCK = false; lpDDSOffScreen2->PageUnlock(0); lpDDSOffScreen2->Release(); lpDDSOffScreen2 = NULL; return (false); } } ZeroMemory (&DDPixelFormat, sizeof (DDPixelFormat)); DDPixelFormat.dwSize = sizeof (DDPixelFormat); lpDDSPrimary->GetPixelFormat (&DDPixelFormat); clipped = true; if((!pWindowed && pDoubleBuffered) || FAILED(lpDDSPrimary->SetClipper( lpDDClipper))) clipped = false; if (FAILED (lpDDSPrimary->QueryInterface (IID_IDirectDrawSurface2, (void **)&lpDDSPrimary2))) { BLOCK = false; lpDDSPrimary->Release(); lpDDSPrimary = NULL; return (FALSE); } lpDDSPrimary->Release(); lpDDSPrimary = NULL; if((!pWindowed && pDoubleBuffered) || FAILED(lpDDSPrimary2->SetClipper( lpDDClipper))) clipped = false; if (pDepth == 8) { dErr = lpDD->CreatePalette (DDPCAPS_8BIT | DDPCAPS_ALLOW256, PaletteEntries, &lpDDPalette, NULL); if( FAILED(dErr)) { lpDDPalette = NULL; BLOCK = false; return false; } } depth = pDepth; height = pHeight; width = pWidth; doubleBuffered = pDoubleBuffered; BLOCK = false; return (true); }
BOOL _GameMode( HINSTANCE hInstance, int nCmdShow, int x, int y, int bpp ) { HRESULT result; WNDCLASS wc; DDSURFACEDESC ddsd; DDSCAPS ddscaps; LPDIRECTDRAW pdd; wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; wc.lpfnWndProc = WindowProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon( NULL, IDI_APPLICATION ); wc.hCursor = LoadCursor( NULL, IDC_ARROW ); wc.hbrBackground = GetStockBrush(BLACK_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = "EXAM3"; RegisterClass( &wc ); MainHwnd = CreateWindowEx ( 0, "EXAM3", NULL, WS_POPUP, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), NULL, NULL, hInstance, NULL ); if ( !MainHwnd ) return FALSE; SetFocus( MainHwnd ); ShowWindow( MainHwnd, nCmdShow ); UpdateWindow( MainHwnd ); ShowCursor( FALSE ); result = DirectDrawCreate( NULL, &pdd, NULL ); if ( result != DD_OK ) return Fail( MainHwnd ); result = pdd->QueryInterface(IID_IDirectDraw, (LPVOID *) &DirectOBJ); if ( result != DD_OK ) return Fail( MainHwnd ); gWidth=x; gHeight=y; // 윈도우 핸들의 협력 단계를 설정한다. if(gFullScreen){ result = DirectOBJ->SetCooperativeLevel( MainHwnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN ); if ( result != DD_OK ) return Fail( MainHwnd ); result = DirectOBJ->SetDisplayMode( x, y, bpp); if ( result != DD_OK ) return Fail( MainHwnd ); memset( &ddsd, 0, sizeof(ddsd) ); ddsd.dwSize = sizeof( ddsd ); ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; ddsd.dwBackBufferCount = 1; result = DirectOBJ -> CreateSurface( &ddsd, &RealScreen, NULL ); if ( result != DD_OK ) return Fail( MainHwnd ); memset( &ddscaps, 0, sizeof(ddscaps) ); ddscaps.dwCaps = DDSCAPS_BACKBUFFER; result = RealScreen -> GetAttachedSurface( &ddscaps, &BackScreen ); if ( result != DD_OK ) return Fail( MainHwnd ); } else{ result = DirectOBJ->SetCooperativeLevel( MainHwnd, DDSCL_NORMAL ); if ( result != DD_OK ) return Fail( MainHwnd ); memset( &ddsd, 0, sizeof(ddsd) ); ddsd.dwSize = sizeof( ddsd ); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; ddsd.dwBackBufferCount = 0; result = DirectOBJ -> CreateSurface( &ddsd, &RealScreen, NULL ); if(result != DD_OK) return Fail(MainHwnd); memset( &ddsd, 0, sizeof(ddsd) ); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; ddsd.dwWidth = x; ddsd.dwHeight = y; result = DirectOBJ->CreateSurface( &ddsd, &BackScreen, NULL ); if ( result != DD_OK ) return Fail( MainHwnd ); result = DirectOBJ->CreateClipper( 0, &ClipScreen, NULL); if ( result != DD_OK ) return Fail( MainHwnd ); result = ClipScreen->SetHWnd( 0, MainHwnd ); if ( result != DD_OK ) return Fail( MainHwnd ); result = RealScreen->SetClipper( ClipScreen ); if ( result != DD_OK ) return Fail( MainHwnd ); SetWindowPos(MainHwnd, NULL, 100, 100, x, y, SWP_NOZORDER | SWP_NOACTIVATE); } return TRUE; }
//----------------------------------------------------------------------------- // Name: InitGraphics() // Desc: //----------------------------------------------------------------------------- HRESULT InitGraphics() { DDCAPS ddcaps; HRESULT hr; DDSURFACEDESC ddsd; DDSCAPS ddscaps; // Create a window g_hwndMain = CreateWindowEx( WS_EX_APPWINDOW, TEXT("DuelClass"), TEXT("Duel"), WS_POPUP | WS_SYSMENU, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), NULL, NULL, g_hInst, NULL ); if( NULL == g_hwndMain ) return E_FAIL; UpdateWindow( g_hwndMain ); SetFocus( g_hwndMain ); // DDraw stuff begins here if( FAILED( hr = DirectDrawCreate( NULL, &g_pDD, NULL ) ) ) { ShowError(IDS_DDRAW_ERROR_DDC); return E_FAIL; } // Set access mode based on fullscreen/window if( g_bFullscreen ) { hr = g_pDD->SetCooperativeLevel( g_hwndMain, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN ); } else { hr = g_pDD->SetCooperativeLevel( g_hwndMain, DDSCL_NORMAL); } if( FAILED(hr) ) { ShowError(IDS_DDRAW_ERROR_SCL); return E_FAIL; } if( g_bFullscreen ) { // Set the mode to 640 by 480 by 8 if( FAILED( g_pDD->SetDisplayMode( 640, 480, 8 ) ) ) { ShowError(IDS_DDRAW_ERROR_SDM); return E_FAIL; } } else { RECT rcWork; RECT rc; DWORD dwStyle; // If we are still a WS_POPUP window we should convert to a // normal app window so we look like a windows app. dwStyle = GetWindowStyle(g_hwndMain); dwStyle &= ~WS_POPUP; dwStyle |= WS_OVERLAPPED | WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX; SetWindowLong( g_hwndMain, GWL_STYLE, dwStyle ); // Aet window size SetRect( &rc, 0, 0, MAX_DEFWIN_X, MAX_DEFWIN_Y ); AdjustWindowRectEx( &rc, GetWindowStyle(g_hwndMain), GetMenu(g_hwndMain) != NULL, GetWindowExStyle(g_hwndMain) ); SetWindowPos( g_hwndMain, NULL, 0, 0, rc.right-rc.left, rc.bottom-rc.top, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); SetWindowPos( g_hwndMain, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); // Make sure our window does not hang outside of the work area SystemParametersInfo( SPI_GETWORKAREA, 0, &rcWork, 0 ); GetWindowRect( g_hwndMain, &rc ); if( rc.left < rcWork.left ) rc.left = rcWork.left; if( rc.top < rcWork.top ) rc.top = rcWork.top; SetWindowPos( g_hwndMain, NULL, rc.left, rc.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE ); } // Check the color key hardware capabilities ddcaps.dwSize = sizeof( ddcaps ); memset( &ddsd, 0, sizeof( ddsd ) ); ddsd.dwSize = sizeof( ddsd ); if( g_bFullscreen ) { // Create surfaces ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; ddsd.dwBackBufferCount = 1; if( FAILED( hr = g_pDD->CreateSurface( &ddsd, &g_pddsFrontBuffer, NULL ) ) ) { ShowError(IDS_DDRAW_ERROR_CREATESURFACE); return E_FAIL; } // Get a pointer to the back buffer ddscaps.dwCaps = DDSCAPS_BACKBUFFER; if( FAILED( hr = g_pddsFrontBuffer->GetAttachedSurface( &ddscaps, &g_pddsBackBuffer ) ) ) { ShowError(IDS_DDRAW_ERROR_GAS); return E_FAIL; } } else { LPDIRECTDRAWCLIPPER pcClipper; // Window case, create the primary surface // and create a backbuffer in offscreen memory ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; if( FAILED( g_pDD->CreateSurface( &ddsd, &g_pddsFrontBuffer, NULL ) ) ) { ShowError(IDS_DDRAW_ERROR_CREATESURFACE); return E_FAIL; } ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; ddsd.dwWidth = MAX_DEFWIN_X; ddsd.dwHeight = MAX_DEFWIN_Y; if( FAILED( hr = g_pDD->CreateSurface( &ddsd, &g_pddsBackBuffer, NULL ) ) ) { ShowError(IDS_DDRAW_ERROR_CREATESURFACE); return E_FAIL; } if( FAILED( hr = g_pDD->CreateClipper( 0, &pcClipper, NULL) ) ) { ShowError(IDS_DDRAW_ERROR_CC); return E_FAIL; } if( FAILED( hr = pcClipper->SetHWnd( 0, g_hwndMain) ) ) { pcClipper->Release(); ShowError(IDS_DDRAW_ERROR_SH); return E_FAIL; } if( FAILED( hr = g_pddsFrontBuffer->SetClipper( pcClipper) ) ) { pcClipper->Release(); ShowError(IDS_DDRAW_ERROR_SC); return E_FAIL; } // Done with clipper pcClipper->Release(); } ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; ddsd.dwWidth = 320; ddsd.dwHeight = 128; for( DWORD i=0; i<4; i++ ) { if( FAILED( hr = g_pDD->CreateSurface( &ddsd, &g_pddsShip[i], NULL ) ) ) { ShowError(IDS_DDRAW_ERROR_CREATESURFACE); return E_FAIL; } } ddsd.dwHeight = 16; if( FAILED( hr = g_pDD->CreateSurface( &ddsd, &g_pddsNumbers, NULL ) ) ) { ShowError(IDS_DDRAW_ERROR_CREATESURFACE); return E_FAIL; } if( FAILED( RestoreSurfaces() ) ) { ShowError(IDS_DDRAW_ERROR_RS); return E_FAIL; } g_dwKeys = 0; ShowWindow( g_hwndMain, SW_SHOW); return S_OK; }
bool CDirectDraw::SetDisplayMode( int pWidth, int pHeight, int pScale, char pDepth, int pRefreshRate, bool pWindowed, bool pDoubleBuffered) { if(pScale < 2) pScale = 2; static bool BLOCK = false; DDSURFACEDESC ddsd; PALETTEENTRY PaletteEntries [256]; if (BLOCK) return (false); BLOCK = true; if (pWindowed) pDoubleBuffered = false; if (pDepth == 0) pDepth = Depth; if (lpDDSPrimary2 != NULL) { lpDDSPrimary2->Release(); lpDDSPrimary2 = NULL; } if (lpDDSOffScreen2 != NULL) { lpDDSOffScreen2->PageUnlock(0); lpDDSOffScreen2->Release(); lpDDSOffScreen2 = NULL; } if( lpDDPalette != NULL) { lpDDPalette->Release(); lpDDPalette = NULL; } lpDD->FlipToGDISurface(); if (pWindowed) { lpDD->RestoreDisplayMode(); SetWindowLong( GUI.hWnd, GWL_STYLE, WS_POPUPWINDOW|WS_CAPTION| WS_THICKFRAME|WS_VISIBLE|WS_MINIMIZEBOX|WS_MAXIMIZEBOX); // disabled because it messes up window maximization //if (!VOODOO_MODE) // SetWindowPos( GUI.hWnd, HWND_TOP, 0, 0, 0, 0, // SWP_DRAWFRAME|SWP_FRAMECHANGED|SWP_NOMOVE|SWP_NOSIZE); //else // SetWindowPos( GUI.hWnd, HWND_TOP, 0, 0, 0, 0, // SWP_FRAMECHANGED|SWP_NOMOVE|SWP_NOSIZE); ZeroMemory (&ddsd, sizeof (ddsd)); ddsd.dwSize = sizeof (ddsd); ddsd.dwFlags = DDSD_PIXELFORMAT; dErr = lpDD->GetDisplayMode (&ddsd); if (FAILED(dErr)) pDepth = 8; else { if (ddsd.ddpfPixelFormat.dwFlags&DDPF_RGB) pDepth = (char) ddsd.ddpfPixelFormat.dwRGBBitCount; else pDepth = 8; } if (pDepth == 8) dErr = lpDD->SetCooperativeLevel (GUI.hWnd, DDSCL_FULLSCREEN| DDSCL_EXCLUSIVE|DDSCL_ALLOWREBOOT); else dErr = lpDD->SetCooperativeLevel (GUI.hWnd, DDSCL_NORMAL|DDSCL_ALLOWREBOOT); } else { SetWindowLong (GUI.hWnd, GWL_STYLE, WS_POPUP|WS_VISIBLE); if (!VOODOO_MODE) { SetWindowPos (GUI.hWnd, HWND_TOP, 0, 0, 0, 0, SWP_DRAWFRAME|SWP_FRAMECHANGED|SWP_NOMOVE|SWP_NOSIZE); dErr = lpDD->SetCooperativeLevel (GUI.hWnd, DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN|DDSCL_ALLOWREBOOT); // XXX: TODO: use pRefreshRate! dErr = lpDD->SetDisplayMode (pWidth, pHeight, pDepth); } else { SetWindowPos (GUI.hWnd, HWND_TOP, 0, 0, 0, 0, SWP_FRAMECHANGED|SWP_NOMOVE|SWP_NOSIZE); dErr = lpDD->SetCooperativeLevel (GUI.hWnd, DDSCL_NORMAL|DDSCL_ALLOWREBOOT); } } if (FAILED(dErr)) { BLOCK = false; return false; } ZeroMemory (&ddsd, sizeof (ddsd)); ddsd.dwSize = sizeof (ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; if(GUI.ddrawUseVideoMemory) { ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY | (GUI.ddrawUseLocalVidMem ? DDSCAPS_LOCALVIDMEM : DDSCAPS_NONLOCALVIDMEM); } else { ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; } ddsd.dwWidth = SNES_WIDTH * pScale; ddsd.dwHeight = SNES_HEIGHT_EXTENDED * pScale; LPDIRECTDRAWSURFACE lpDDSOffScreen; if (FAILED(lpDD->CreateSurface (&ddsd, &lpDDSOffScreen, NULL))) { ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY | (GUI.ddrawUseLocalVidMem ? DDSCAPS_NONLOCALVIDMEM : DDSCAPS_LOCALVIDMEM); if(!GUI.ddrawUseVideoMemory || FAILED(lpDD->CreateSurface (&ddsd, &lpDDSOffScreen, NULL))) { ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; if(!GUI.ddrawUseVideoMemory || FAILED(lpDD->CreateSurface (&ddsd, &lpDDSOffScreen, NULL))) { BLOCK = false; return (false); } } } if (FAILED (lpDDSOffScreen->QueryInterface (IID_IDirectDrawSurface2, (void **)&lpDDSOffScreen2))) { lpDDSOffScreen->Release(); BLOCK = false; return (false); } lpDDSOffScreen2->PageLock(0); lpDDSOffScreen->Release(); ZeroMemory (&ddsd, sizeof (ddsd)); if (pDoubleBuffered) { ddsd.dwSize = sizeof( ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP; GUI.NumFlipFrames = 3; ddsd.dwBackBufferCount = 2; } else { GUI.NumFlipFrames = 1; ddsd.dwSize = sizeof (ddsd); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; } LPDIRECTDRAWSURFACE lpDDSPrimary; dErr = lpDD->CreateSurface (&ddsd, &lpDDSPrimary, NULL); if( FAILED(dErr) ) { if (pDoubleBuffered) { ddsd.dwBackBufferCount = 1; GUI.NumFlipFrames = 2; if (FAILED(dErr = lpDD->CreateSurface (&ddsd, &lpDDSPrimary, NULL))) { ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; pDoubleBuffered = false; GUI.NumFlipFrames = 1; dErr = lpDD->CreateSurface (&ddsd, &lpDDSPrimary, NULL); } } if (FAILED(dErr)) { BLOCK = false; lpDDSOffScreen2->PageUnlock(0); lpDDSOffScreen2->Release(); lpDDSOffScreen2 = NULL; return (false); } } ZeroMemory (&DDPixelFormat, sizeof (DDPixelFormat)); DDPixelFormat.dwSize = sizeof (DDPixelFormat); lpDDSPrimary->GetPixelFormat (&DDPixelFormat); Clipped = true; if((!pWindowed && pDoubleBuffered) || FAILED(lpDDSPrimary->SetClipper( lpDDClipper))) Clipped = false; if (FAILED (lpDDSPrimary->QueryInterface (IID_IDirectDrawSurface2, (void **)&lpDDSPrimary2))) { BLOCK = false; lpDDSPrimary->Release(); lpDDSPrimary = NULL; return (FALSE); } lpDDSPrimary->Release(); lpDDSPrimary = NULL; if((!pWindowed && pDoubleBuffered) || FAILED(lpDDSPrimary2->SetClipper( lpDDClipper))) Clipped = false; if (pDepth == 8) { dErr = lpDD->CreatePalette (DDPCAPS_8BIT | DDPCAPS_ALLOW256, PaletteEntries, &lpDDPalette, NULL); if( FAILED(dErr)) { lpDDPalette = NULL; BLOCK = false; return false; } } Depth = pDepth; Height = pHeight; Width = pWidth; DoubleBuffered = pDoubleBuffered; BLOCK = false; return (true); }
void dd_Window::flip_win() { RECT r; if(!bVisible) return; if(!img) return; //convert the image format if necessary if(DesktopBPP != vid_bpp) { image* temp = ImageAdapt(img, vid_bpp, DesktopBPP); memcpy((quad*)dx_win_bsd.lpSurface,temp->data,img->width*img->height*DesktopBPP/8); delete temp; } GetClientRect(hwnd, &r); int xres = img->width; int yres = img->height; //disable letterboxing if(0) { ClientToScreen(hwnd, (POINT *)&r); ClientToScreen(hwnd, (POINT *)&r + 1); dx_win_ps->Blt(&r, dx_win_bs, 0, 0, 0); return; } //----- //grump calculations int w = r.right - r.left; int h = r.bottom - r.top; //will contain w/h to render at int iw,ih; float ratio = (float)w / xres; float ph = ratio * (float)yres; if((int)ph>h) { ratio = (float)h / (float)yres; ih = h; iw = (int)(ratio * (float)xres); } else { ih = (int)ph; iw = w; } //create a client rectangle with the render destination properly set, possibly in the middle of the client area r.left += (w-iw)/2; r.top += (h-ih)/2; r.right = r.left + iw; r.bottom = r.top + ih; ClientToScreen(hwnd, (POINT *)&r); ClientToScreen(hwnd, (POINT *)&r + 1); //render the screen dx_win_ps->SetClipper(clipper); dx_win_ps->Blt(&r, dx_win_bs, 0, DDBLT_WAIT, 0); //draw black letterbox bars if(iw != w || ih != h) { RECT rClient; GetClientRect(hwnd, &rClient); ClientToScreen(hwnd, (POINT *)&rClient); ClientToScreen(hwnd, (POINT *)&rClient + 1); DDBLTFX ddbltfx; memset(&ddbltfx, 0, sizeof(DDBLTFX)); ddbltfx.dwSize = sizeof(DDBLTFX); ddbltfx.dwFillColor = 0; if(iw < w) { RECT rBlit; rBlit.left = rClient.left; rBlit.right = r.left; rBlit.top = r.top; rBlit.bottom = r.bottom; dx_win_ps->Blt(&rBlit, 0, 0, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx); rBlit.left = r.right; rBlit.right = rClient.right; dx_win_ps->Blt(&rBlit, 0, 0, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx); } else { RECT rBlit; rBlit.left = r.left; rBlit.right = r.right; rBlit.top = rClient.top; rBlit.bottom = r.top; dx_win_ps->Blt(&rBlit, 0, 0, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx); rBlit.top = r.bottom; rBlit.bottom = rClient.bottom; dx_win_ps->Blt(&rBlit, 0, 0, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx); } } }