Example #1
0
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;
}
Example #2
0
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;
}
Example #3
0
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);
}
Example #4
0
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;
}
Example #5
0
//-----------------------------------------------------------------------------
// 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);
}
Example #7
0
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);
		}
	}
}