home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / graphics / directx / duel / gfx.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-15  |  15.1 KB  |  565 lines

  1. /*==========================================================================
  2.  *
  3.  *  Copyright (C) 1995-1997 Microsoft Corporation. All Rights Reserved.
  4.  *
  5.  *  File:       gfx.c
  6.  *  Content:    DirectDraw related code.
  7.  *
  8.  *
  9.  ***************************************************************************/
  10. #include "gfx.h"
  11. #include "input.h"
  12. #include "ddutil.h"
  13.  
  14. /*
  15.  * Externals
  16.  */
  17. extern BOOL             gbUseEmulation;     // user DDHEL or DDHAL ?
  18. extern BOOL                gbFullscreen;        // window or fullscreen mode ?
  19. extern HWND                ghWndMain;            // main window
  20. extern DWORD            gdwKeys;                
  21. extern int              gnProgramState;     // current state of program (rest, splash, active, etc.)
  22. extern RECT                grcWindow;          // client window rectangle
  23. extern BOOL                gbFullscreen;        // fullscreen or window mode ?
  24. extern HINSTANCE        ghinst;                // application instance handle
  25. extern TCHAR            gtszClassName[];    // Duel's class name
  26.  
  27.  
  28. /*
  29.  * Globals
  30.  */
  31. LPDIRECTDRAWSURFACE     glpFrontBuffer;            // primary surface
  32. LPDIRECTDRAWSURFACE     glpBackBuffer;            // back buffer for animation
  33. LPDIRECTDRAWSURFACE        glpSplash;                // splash screen
  34. LPDIRECTDRAWSURFACE     glpShip0;                // ship bitmaps
  35. LPDIRECTDRAWSURFACE     glpShip1;
  36. LPDIRECTDRAWSURFACE     glpShip2;
  37. LPDIRECTDRAWSURFACE     glpShip3;
  38. LPDIRECTDRAWSURFACE     glpNum;                    // Numbers bitmap
  39. LPDIRECTDRAW            glpDD;                    // DirectDraw interface
  40. LPDIRECTDRAWPALETTE     glpArtPalette=NULL;        // Game screen palette
  41. LPDIRECTDRAWPALETTE     glpSplashPalette=NULL;    // Splash screen palette
  42. LPDIRECTDRAWCLIPPER        glpClipper=NULL;        // Clipper for front buffer
  43. DWORD                   gdwFillColor;
  44. int                        gnGameBPP;                // primary surface bit depth
  45. #ifdef DEBUG
  46. BOOL                    gbHELBlt = FALSE;
  47. #endif
  48.  
  49. BOOL InitGraphics( void )
  50. {
  51.     DDCAPS          ddcaps;
  52.     HRESULT         ddrval;
  53.     DDSURFACEDESC   ddsd;
  54.     DDSCAPS         ddscaps;
  55.     TCHAR            tszTitle[MAX_WINDOWTITLE];
  56.  
  57.     LoadString(ghinst, IDS_DUEL_TITLE, tszTitle, MAX_WINDOWTITLE);
  58.  
  59.     // Create a window
  60.     ghWndMain = CreateWindowEx(
  61.         WS_EX_APPWINDOW,  // WS_EX_TOPMOST,
  62.         gtszClassName,
  63.         tszTitle,
  64.                      // don't show the window yet 
  65.         WS_POPUP |   // non-app window POPUP
  66.         WS_SYSMENU,  // so we get an icon in the tray
  67.         0,
  68.         0,
  69.         GetSystemMetrics(SM_CXSCREEN),
  70.         GetSystemMetrics(SM_CYSCREEN),
  71.         NULL,
  72.         NULL,
  73.         ghinst,
  74.         NULL );
  75.  
  76.     if( !ghWndMain )
  77.     {
  78.         return FALSE;
  79.     }
  80.  
  81.     UpdateWindow( ghWndMain );
  82.     SetFocus( ghWndMain );
  83.  
  84.     // ddraw stuff begins here
  85.     if( gbUseEmulation )
  86.         ddrval = DirectDrawCreate( (LPVOID) DDCREATE_EMULATIONONLY, &glpDD, NULL );
  87.     else
  88.         ddrval = DirectDrawCreate( NULL, &glpDD, NULL );
  89.  
  90.     if( ddrval != DD_OK )
  91.         return ShowError(IDS_DDRAW_ERROR_DDC);
  92.  
  93.     // set access mode based on fullscreen/window
  94.     if (gbFullscreen) 
  95.     {
  96.         ddrval = glpDD->lpVtbl->SetCooperativeLevel( glpDD, ghWndMain,
  97.                             DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN );
  98.     }
  99.     else
  100.     {
  101.         ddrval = glpDD->lpVtbl->SetCooperativeLevel( glpDD, ghWndMain,
  102.                             DDSCL_NORMAL);
  103.     }
  104.  
  105.     if( ddrval != DD_OK )
  106.         return ShowError(IDS_DDRAW_ERROR_SCL);
  107.  
  108.     if (gbFullscreen)
  109.     {
  110.         // set the mode to 640 by 480 by 8
  111.         ddrval = glpDD->lpVtbl->SetDisplayMode( glpDD, 640, 480, 8 );
  112.         
  113.         if( ddrval != DD_OK )
  114.             return ShowError(IDS_DDRAW_ERROR_SDM);
  115.     }
  116.     else
  117.     {
  118.         RECT rcWork;
  119.         RECT rc;
  120.         HDC hdc;
  121.         DWORD dwStyle;
  122.  
  123.         //
  124.         //  when in rome (I mean when in windows) we should use the
  125.         //  current mode
  126.         //
  127.         hdc = GetDC(NULL);
  128.         gnGameBPP = GetDeviceCaps(hdc, PLANES) * GetDeviceCaps(hdc, BITSPIXEL);
  129.         ReleaseDC(NULL, hdc);
  130.  
  131.         //
  132.         // if we are still a WS_POPUP window we should convert to a
  133.         // normal app window so we look like a windows app.
  134.         //
  135.         dwStyle = GetWindowStyle(ghWndMain);
  136.         dwStyle &= ~WS_POPUP;
  137.         dwStyle |= WS_OVERLAPPED | WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX;
  138.         SetWindowLong(ghWndMain, GWL_STYLE, dwStyle);
  139.  
  140.         // set window size
  141.         SetRect(&rc, 0, 0, MAX_DEFWIN_X, MAX_DEFWIN_Y);
  142.  
  143.         AdjustWindowRectEx(&rc,
  144.             GetWindowStyle(ghWndMain),
  145.             GetMenu(ghWndMain) != NULL,
  146.             GetWindowExStyle(ghWndMain));
  147.  
  148.         SetWindowPos(ghWndMain, NULL, 0, 0, rc.right-rc.left, rc.bottom-rc.top,
  149.             SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
  150.  
  151.         SetWindowPos(ghWndMain, HWND_NOTOPMOST, 0, 0, 0, 0,
  152.             SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
  153.  
  154.         //
  155.         //  make sure our window does not hang outside of the work area
  156.         //  this will make people who have the tray on the top or left
  157.         //  happy.
  158.         //
  159.         SystemParametersInfo(SPI_GETWORKAREA, 0, &rcWork, 0);
  160.         GetWindowRect(ghWndMain, &rc);
  161.         if (rc.left < rcWork.left) rc.left = rcWork.left;
  162.         if (rc.top  < rcWork.top)  rc.top  = rcWork.top;
  163.         SetWindowPos(ghWndMain, NULL, rc.left, rc.top, 0, 0,
  164.             SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
  165.     }
  166.  
  167.     // check the color key hardware capabilities
  168.     ddcaps.dwSize = sizeof( ddcaps );
  169.  
  170.     memset( &ddsd, 0, sizeof( ddsd ) );
  171.     ddsd.dwSize = sizeof( ddsd );
  172.  
  173.     if (gbFullscreen)
  174.     {
  175.         // Create surfaces
  176.         ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
  177.         ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE |
  178.                               DDSCAPS_FLIP |
  179.                               DDSCAPS_COMPLEX;
  180.         ddsd.dwBackBufferCount = 1;
  181.         ddrval = glpDD->lpVtbl->CreateSurface( glpDD, &ddsd, &glpFrontBuffer, NULL );
  182.         if( ddrval != DD_OK )
  183.             return ShowError(IDS_DDRAW_ERROR_CSFB);
  184.  
  185.         // get a pointer to the back buffer
  186.         ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
  187.         ddrval = glpFrontBuffer->lpVtbl->GetAttachedSurface(
  188.                     glpFrontBuffer,
  189.                     &ddscaps,
  190.                     &glpBackBuffer );
  191.         if( ddrval != DD_OK )
  192.             return ShowError(IDS_DDRAW_ERROR_GAS);
  193.     }
  194.     else
  195.     {
  196.         // window case, create the primary surface
  197.         // and create a backbuffer in offscreen memory
  198.         ddsd.dwFlags = DDSD_CAPS;
  199.         ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
  200.  
  201.         ddrval = glpDD->lpVtbl->CreateSurface( glpDD, &ddsd, &glpFrontBuffer, NULL );
  202.         if( ddrval != DD_OK )
  203.             return ShowError(IDS_DDRAW_ERROR_CSFB);
  204.  
  205.         ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;    
  206.         ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
  207.  
  208.         ddsd.dwWidth = MAX_DEFWIN_X;
  209.         ddsd.dwHeight = MAX_DEFWIN_Y;
  210.         ddrval = glpDD->lpVtbl->CreateSurface( glpDD, &ddsd, &glpBackBuffer, NULL );
  211.         if( ddrval != DD_OK )
  212.             return ShowError(IDS_DDRAW_ERROR_CSBB);
  213.  
  214.         ddrval = glpDD->lpVtbl->CreateClipper(glpDD, 0, &glpClipper, NULL);
  215.         if( ddrval != DD_OK )
  216.             return ShowError(IDS_DDRAW_ERROR_CC);
  217.  
  218.         ddrval = glpClipper->lpVtbl->SetHWnd(glpClipper, 0, ghWndMain);
  219.         if( ddrval != DD_OK )
  220.             return ShowError(IDS_DDRAW_ERROR_SH);
  221.  
  222.         ddrval = glpFrontBuffer->lpVtbl->SetClipper(glpFrontBuffer, glpClipper);
  223.         if( ddrval != DD_OK )
  224.             return ShowError(IDS_DDRAW_ERROR_SC);
  225.     }
  226.  
  227.     ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;    
  228.     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
  229. #ifdef DEBUG
  230.     if( gbHELBlt )
  231.         ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
  232. #endif
  233.  
  234.     ddsd.dwWidth = 320;
  235.     ddsd.dwHeight = 128;
  236.     ddrval = glpDD->lpVtbl->CreateSurface( glpDD, &ddsd, &glpShip0, NULL );
  237.     if( ddrval != DD_OK )
  238.     return ShowError(IDS_DDRAW_ERROR_CSS0);
  239.  
  240.     ddsd.dwWidth = 320;
  241.     ddsd.dwHeight = 128;
  242.     ddrval = glpDD->lpVtbl->CreateSurface( glpDD, &ddsd, &glpShip1, NULL );
  243.     if( ddrval != DD_OK )
  244.     return ShowError(IDS_DDRAW_ERROR_CSS1);
  245.  
  246.     ddsd.dwWidth = 320;
  247.     ddsd.dwHeight = 128;
  248.     ddrval = glpDD->lpVtbl->CreateSurface( glpDD, &ddsd, &glpShip2, NULL );
  249.     if( ddrval != DD_OK )
  250.     return ShowError(IDS_DDRAW_ERROR_CSS2);
  251.  
  252.     ddsd.dwWidth = 320;
  253.     ddsd.dwHeight = 128;
  254.     ddrval = glpDD->lpVtbl->CreateSurface( glpDD, &ddsd, &glpShip3, NULL );
  255.     if( ddrval != DD_OK )
  256.     return ShowError(IDS_DDRAW_ERROR_CSS3);
  257.  
  258.     ddsd.dwHeight = 16;
  259.     ddrval = glpDD->lpVtbl->CreateSurface( glpDD, &ddsd, &glpNum, NULL );
  260.     if( ddrval != DD_OK )
  261.     return ShowError(IDS_DDRAW_ERROR_CSN);
  262.  
  263.     if( !RestoreSurfaces() )
  264.         return ShowError(IDS_DDRAW_ERROR_RS);
  265.     
  266.     gdwKeys = 0;
  267.     ShowWindow(ghWndMain, SW_SHOW);
  268.     return TRUE;
  269. }
  270.  
  271. void CleanupGraphics(void)
  272. {
  273.     if( glpShip0 != NULL )
  274.     glpShip0->lpVtbl->Release( glpShip0 );
  275.     
  276.     if( glpShip1 != NULL )
  277.     glpShip1->lpVtbl->Release( glpShip1 );
  278.     
  279.     if( glpShip2 != NULL )
  280.     glpShip2->lpVtbl->Release( glpShip2 );
  281.     
  282.     if( glpShip3 != NULL )
  283.     glpShip3->lpVtbl->Release( glpShip3 );
  284.     
  285.     if( glpNum != NULL )
  286.     glpNum->lpVtbl->Release( glpNum );
  287.         
  288.     if (!gbFullscreen && glpClipper)
  289.     glpClipper->lpVtbl->Release( glpClipper );
  290.  
  291.     if( glpFrontBuffer != NULL )
  292.     glpFrontBuffer->lpVtbl->Release( glpFrontBuffer );
  293.     
  294.      if( glpArtPalette != NULL )
  295.     glpArtPalette->lpVtbl->Release( glpArtPalette );
  296.     
  297.     if( glpSplashPalette != NULL )
  298.     glpSplashPalette->lpVtbl->Release( glpSplashPalette );
  299.  
  300.    if( !gbFullscreen && (glpBackBuffer != NULL ))
  301.     glpBackBuffer->lpVtbl->Release( glpBackBuffer );
  302.  
  303.     if( glpDD != NULL )
  304.         glpDD->lpVtbl->Release( glpDD );
  305. }
  306.  
  307. void bltSplash( LPRECT rc)
  308. {
  309.     HRESULT     ddrval;
  310.     HBITMAP     hbm;
  311.  
  312.     if( ( glpFrontBuffer == NULL ) ||
  313.         ( glpSplashPalette == NULL ) ||
  314.     ( glpBackBuffer == NULL ) )
  315.     {
  316.         return;
  317.     }
  318.  
  319.     // set the palette before loading the splash screen
  320.     glpFrontBuffer->lpVtbl->SetPalette( glpFrontBuffer, glpSplashPalette );
  321.  
  322.     hbm = (HBITMAP)LoadImage( GetModuleHandle( NULL ), TEXT("SPLASH"), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION );
  323.     if ( NULL == hbm )
  324.     return;
  325.     
  326.     // if the surface is lost, DDCopyBitmap will fail and the surface will
  327.     // be restored below.
  328.     ddrval = DDCopyBitmap( glpBackBuffer, hbm, 0, 0, 0, 0 );
  329.  
  330.     DeleteObject( hbm );
  331.  
  332.     while( 1 )
  333.     {
  334.         if( NULL == rc)
  335.         {
  336.                 ddrval = glpFrontBuffer->lpVtbl->Blt( glpFrontBuffer, 
  337.                 &grcWindow, glpBackBuffer, NULL, DDBLT_WAIT, NULL);
  338.         }
  339.         else
  340.         {
  341.                 ddrval = glpFrontBuffer->lpVtbl->Blt( glpFrontBuffer, 
  342.                 &grcWindow, glpBackBuffer, rc, DDBLT_WAIT, NULL);
  343.         }
  344.  
  345.         if( ddrval == DD_OK )
  346.         return;
  347.         if( ddrval == DDERR_SURFACELOST )
  348.             if( !RestoreSurfaces() )
  349.                 return;
  350.         if( ddrval != DDERR_WASSTILLDRAWING )
  351.             return;
  352.     }
  353. }
  354.  
  355. void bltScore( char *num, int x, int y )
  356. {
  357.     char *c;
  358.     RECT    src;
  359.     int     i;
  360.  
  361.     for(c=num; *c != '\0'; c++)
  362.     {
  363.         i = *c - '0';
  364.         src.left = i*16;
  365.         src.top = 0;
  366.         src.right = src.left + 16;
  367.         src.bottom = src.top + 16;
  368.     bltObject( x, y, glpNum, &src, DDBLTFAST_SRCCOLORKEY );
  369.         x += 16;
  370.     }
  371. }
  372.  
  373. void bltObject( int x, int y, LPDIRECTDRAWSURFACE surf, LPRECT src, DWORD flags )
  374. {
  375.     HRESULT ddrval;
  376.  
  377.     while( 1 )
  378.     {
  379.         ddrval = glpBackBuffer->lpVtbl->BltFast( glpBackBuffer, x, y, surf, src, flags );
  380.         if( ddrval == DD_OK )
  381.         return;
  382.         if( ddrval == DDERR_SURFACELOST )
  383.             if( !RestoreSurfaces() )
  384.                 return;
  385.         if( ddrval != DDERR_WASSTILLDRAWING )
  386.             return;
  387.     }
  388. }
  389.  
  390. void EraseScreen( void )
  391. {
  392.     DDBLTFX     ddbltfx;
  393.     HRESULT     ddrval;
  394.  
  395.     // Erase the background
  396.     ddbltfx.dwSize = sizeof( ddbltfx );
  397.     ddbltfx.dwFillColor = gdwFillColor;
  398.     while( 1 )
  399.     {
  400.         ddrval = glpBackBuffer->lpVtbl->Blt( glpBackBuffer, NULL, NULL,
  401.                  NULL, DDBLT_COLORFILL, &ddbltfx );
  402.  
  403.         if( ddrval == DD_OK )
  404.         {
  405.             break;
  406.         }
  407.         if( ddrval == DDERR_SURFACELOST )
  408.         {
  409.             if( !RestoreSurfaces() )
  410.                 return;
  411.         }
  412.         if( ddrval != DDERR_WASSTILLDRAWING )
  413.         {
  414.             return;
  415.         }
  416.     }
  417. }
  418.  
  419. void FlipScreen( void )
  420. {
  421.     HRESULT     ddrval;
  422.  
  423.     // Flip the surfaces
  424.     if (gbFullscreen)
  425.     {
  426.         while( 1 )
  427.         {
  428.             ddrval = glpFrontBuffer->lpVtbl->Flip( glpFrontBuffer, NULL, 0 );
  429.             if( ddrval == DD_OK )
  430.             {
  431.                 break;
  432.             }
  433.             if( ddrval == DDERR_SURFACELOST )
  434.             {
  435.                 if( !RestoreSurfaces() )
  436.                 {
  437.                     return;
  438.                 }
  439.             }
  440.             if( ddrval != DDERR_WASSTILLDRAWING )
  441.             {
  442.                 break;
  443.             }
  444.         }
  445.     }
  446.     else
  447.     {
  448.         ddrval = IDirectDrawSurface_Blt(
  449.                     glpFrontBuffer,          // dest surface
  450.                     &grcWindow,              // dest rect
  451.                     glpBackBuffer,           // src surface
  452.                     NULL,                   // src rect (all of it)
  453.                     DDBLT_WAIT,
  454.                     NULL);
  455.     }
  456. }
  457.  
  458. BOOL RestoreSurfaces( void )
  459. {
  460.     HRESULT    ddrval;
  461.     HBITMAP     hbm;
  462.  
  463.     ddrval = glpFrontBuffer->lpVtbl->Restore(glpFrontBuffer);
  464.     if( ddrval != DD_OK )
  465.         return FALSE;
  466.     ddrval = glpBackBuffer->lpVtbl->Restore(glpBackBuffer);
  467.     if( ddrval != DD_OK )
  468.         return FALSE;
  469.     ddrval = glpShip0->lpVtbl->Restore(glpShip0);
  470.     if( ddrval != DD_OK )
  471.         return FALSE;
  472.     ddrval = glpShip1->lpVtbl->Restore(glpShip1);
  473.     if( ddrval != DD_OK )
  474.         return FALSE;
  475.     ddrval = glpShip2->lpVtbl->Restore(glpShip2);
  476.     if( ddrval != DD_OK )
  477.         return FALSE;
  478.     ddrval = glpShip3->lpVtbl->Restore(glpShip3);
  479.     if( ddrval != DD_OK )
  480.         return FALSE;
  481.     ddrval = glpNum->lpVtbl->Restore(glpNum);
  482.     if( ddrval != DD_OK )
  483.         return FALSE;
  484.  
  485.     // Create and set the palette for the splash bitmap
  486.     glpSplashPalette = DDLoadPalette( glpDD, TEXT("SPLASH") );
  487.     if( NULL == glpSplashPalette )
  488.     return FALSE;
  489.  
  490.     // Create and set the palette for the art bitmap
  491.     glpArtPalette = DDLoadPalette( glpDD, TEXT("Duel8") );
  492.     if( NULL == glpArtPalette )
  493.     return FALSE;
  494.  
  495.     // set the palette before loading the art
  496.     glpFrontBuffer->lpVtbl->SetPalette( glpFrontBuffer, glpArtPalette );
  497.  
  498.     hbm = (HBITMAP)LoadImage(GetModuleHandle(NULL), TEXT("Duel8"), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION );
  499.  
  500.     if( NULL == hbm )
  501.         return FALSE;
  502.  
  503.     ddrval = DDCopyBitmap( glpShip0, hbm, 0, 0, 320, 128 );
  504.     if( ddrval != DD_OK )
  505.     {
  506.         DeleteObject( hbm );
  507.     return FALSE;
  508.     }
  509.  
  510.     ddrval = DDCopyBitmap( glpShip1, hbm, 0, 128, 320, 128 );
  511.     if( ddrval != DD_OK )
  512.     {
  513.         DeleteObject( hbm );
  514.     return FALSE;
  515.     }
  516.  
  517.     ddrval = DDCopyBitmap( glpShip2, hbm, 0, 256, 320, 128 );
  518.     if( ddrval != DD_OK )
  519.     {
  520.         DeleteObject( hbm );
  521.     return FALSE;
  522.     }
  523.  
  524.     ddrval = DDCopyBitmap( glpShip3, hbm, 0, 384, 320, 128 );
  525.     if( ddrval != DD_OK )
  526.     {
  527.         DeleteObject( hbm );
  528.     return FALSE;
  529.     }
  530.  
  531.     ddrval = DDCopyBitmap( glpNum, hbm, 0, 512, 320, 16 );
  532.     if( ddrval != DD_OK )
  533.     {
  534.         DeleteObject( hbm );
  535.     return FALSE;
  536.     }
  537.  
  538.     DeleteObject( hbm );
  539.  
  540.     // set colorfill colors and color gdwKeys according to bitmap contents
  541.     gdwFillColor = DDColorMatch( glpShip0, CLR_INVALID );
  542.     
  543.     DDSetColorKey( glpShip0, CLR_INVALID );
  544.     DDSetColorKey( glpShip1, CLR_INVALID );
  545.     DDSetColorKey( glpShip2, CLR_INVALID );
  546.     DDSetColorKey( glpShip3, CLR_INVALID );
  547.     DDSetColorKey( glpNum, CLR_INVALID );
  548.  
  549.     return TRUE;
  550. }
  551.  
  552. void SetGamePalette(void)
  553. {
  554.     if (glpFrontBuffer)
  555.         glpFrontBuffer->lpVtbl->SetPalette( glpFrontBuffer, glpArtPalette );
  556. }
  557.  
  558. void FlipToGDI(void)
  559. {
  560.     if (glpDD) 
  561.         glpDD->lpVtbl->FlipToGDISurface( glpDD );
  562. }
  563.  
  564.  
  565.