home *** CD-ROM | disk | FTP | other *** search
/ NEXT Generation 27 / NEXT27.iso / pc / demos / emperor / dx3.exe / SDK / SAMPLES / DDEX4 / DDEX4.CPP < prev    next >
C/C++ Source or Header  |  1996-08-28  |  10KB  |  406 lines

  1. /*==========================================================================
  2.  *
  3.  *  Copyright (C) 1995-1996 Microsoft Corporation. All Rights Reserved.
  4.  *
  5.  *  File:       ddex4.cpp
  6.  *  Content:    Direct Draw example program 4.  Adds functionality to 
  7.  *              example program 3.  Creates a flipping surface and loads
  8.  *              a bitmap image into an offscreen surface.  Uses BltFast to
  9.  *              copy portions of the offscreen surface to the back buffer
  10.  *              to generate an animation.  Illustrates watching return
  11.  *              code from BltFast to prevent image tearing.  This program
  12.  *              requires 1.2 Meg of video ram.
  13.  *
  14.  ***************************************************************************/
  15.  
  16. #define NAME "DDExample4"
  17. #define TITLE "Direct Draw Example 4"
  18.  
  19. #define WIN32_LEAN_AND_MEAN
  20. #include <windows.h>
  21. #include <windowsx.h>
  22. #include <ddraw.h>
  23. #include "resource.h"
  24. #include "ddutil.h"
  25.  
  26. char szBitmap[] = "ALL";
  27.  
  28. LPDIRECTDRAW            lpDD;           // DirectDraw object
  29. LPDIRECTDRAWSURFACE     lpDDSPrimary;   // DirectDraw primary surface
  30. LPDIRECTDRAWSURFACE     lpDDSBack;      // DirectDraw back surface
  31. LPDIRECTDRAWSURFACE     lpDDSOne;       // Offscreen surface 1
  32. LPDIRECTDRAWPALETTE     lpDDPal;        // DirectDraw palette
  33. BOOL                    bActive;        // is application active?
  34.  
  35. /*
  36.  * restoreAll
  37.  *
  38.  * restore all lost objects
  39.  */
  40. HRESULT restoreAll( void )
  41. {
  42.     HRESULT     ddrval;
  43.  
  44.     ddrval = lpDDSPrimary->Restore();
  45.     if( ddrval == DD_OK )
  46.     {
  47.         ddrval = lpDDSOne->Restore();
  48.         if( ddrval == DD_OK )
  49.         {
  50.             DDReLoadBitmap(lpDDSOne, szBitmap);
  51.         }
  52.     }
  53.     return ddrval;
  54.  
  55. } /* restoreAll */
  56.  
  57. /*
  58.  * updateFrame
  59.  * 
  60.  * Decide what needs to be blitted next, wait for flip to complete,
  61.  * then flip the buffers.
  62.  */
  63. void updateFrame( void )
  64. {
  65.     static DWORD        lastTickCount[3] = {0,0,0};
  66.     static int          currentFrame[3] = {0,0,0};
  67.     DWORD               thisTickCount;
  68.     RECT                rcRect;
  69.     DWORD               delay[3] = {50, 78, 13};
  70.     int                 i;
  71.     int                 xpos[3] = {288, 190, 416};
  72.     int                 ypos[3] = {128, 300, 256};
  73.     HRESULT             ddrval;
  74.  
  75.     // Decide which frame will be blitted next
  76.     thisTickCount = GetTickCount();
  77.     for(i=0; i<3; i++)
  78.     {
  79.         if((thisTickCount - lastTickCount[i]) > delay[i])
  80.         {
  81.             // Move to next frame;
  82.             lastTickCount[i] = thisTickCount;
  83.             currentFrame[i]++;
  84.             if(currentFrame[i] > 59)
  85.             {
  86.                 currentFrame[i] = 0;
  87.             }
  88.         }
  89.     }
  90.  
  91.     // Blit the stuff for the next frame
  92.     rcRect.left = 0;
  93.     rcRect.top = 0;
  94.     rcRect.right = 640;
  95.     rcRect.bottom = 480;
  96.     while( 1 )
  97.     {
  98.         ddrval = lpDDSBack->BltFast( 0, 0, lpDDSOne,
  99.             &rcRect, DDBLTFAST_NOCOLORKEY );
  100.  
  101.         if( ddrval == DD_OK )
  102.         {
  103.             break;
  104.         }
  105.         if( ddrval == DDERR_SURFACELOST )
  106.         {
  107.             ddrval = restoreAll();
  108.             if( ddrval != DD_OK )
  109.             {
  110.                 return;
  111.             }
  112.         }
  113.         if( ddrval != DDERR_WASSTILLDRAWING )
  114.         {
  115.             return;
  116.         }
  117.     }
  118.     if(ddrval != DD_OK)
  119.     {
  120.         return;
  121.     }
  122.  
  123.     for( i=0; i<3; i++ )
  124.     {
  125.         rcRect.left   = currentFrame[i]%10*64;
  126.         rcRect.top    = currentFrame[i]/10*64 + 480;
  127.         rcRect.right  = currentFrame[i]%10*64 + 64;
  128.         rcRect.bottom = currentFrame[i]/10*64 + 64 + 480;
  129.  
  130.         while( 1 )
  131.         {
  132.             ddrval = lpDDSBack->BltFast( xpos[i], ypos[i], lpDDSOne,
  133.                                  &rcRect, DDBLTFAST_SRCCOLORKEY );
  134.             if( ddrval == DD_OK )
  135.             {
  136.                 break;
  137.             }
  138.             if( ddrval == DDERR_SURFACELOST )
  139.             {
  140.                 ddrval = restoreAll();
  141.                 if( ddrval != DD_OK )
  142.                 {
  143.                     return;
  144.                 }
  145.             }
  146.             if( ddrval != DDERR_WASSTILLDRAWING )
  147.             {
  148.                 return;
  149.             }
  150.         }
  151.     }
  152.  
  153.     // Flip the surfaces
  154.     while( 1 )
  155.     {
  156.         ddrval = lpDDSPrimary->Flip( NULL, 0 );
  157.         if( ddrval == DD_OK )
  158.         {
  159.             break;
  160.         }
  161.         if( ddrval == DDERR_SURFACELOST )
  162.         {
  163.             ddrval = restoreAll();
  164.             if( ddrval != DD_OK )
  165.             {
  166.                 break;
  167.             }
  168.         }
  169.         if( ddrval != DDERR_WASSTILLDRAWING )
  170.         {
  171.             break;
  172.         }
  173.     }
  174.  
  175. } /* updateFrame */
  176.  
  177.  
  178. /*
  179.  * finiObjects
  180.  *
  181.  * finished with all objects we use; release them
  182.  */
  183. static void finiObjects( void )
  184. {
  185.     if( lpDD != NULL )
  186.     {
  187.         if( lpDDSPrimary != NULL )
  188.         {
  189.             lpDDSPrimary->Release();
  190.             lpDDSPrimary = NULL;
  191.         }
  192.         if( lpDDSOne != NULL )
  193.         {
  194.             lpDDSOne->Release();
  195.             lpDDSOne = NULL;
  196.         }
  197.         if( lpDDPal != NULL )
  198.         {
  199.             lpDDPal->Release();
  200.             lpDDPal = NULL;
  201.         }
  202.         lpDD->Release();
  203.         lpDD = NULL;
  204.     }
  205. } /* finiObjects */
  206.  
  207. long FAR PASCAL WindowProc( HWND hWnd, UINT message, 
  208.                             WPARAM wParam, LPARAM lParam )
  209. {
  210.     switch( message )
  211.     {
  212.     case WM_ACTIVATEAPP:
  213.         bActive = wParam;
  214.         break;
  215.  
  216.     case WM_SETCURSOR:
  217.         SetCursor(NULL);
  218.         return TRUE;
  219.  
  220.     case WM_CREATE:
  221.         break;
  222.  
  223.     case WM_KEYDOWN:
  224.         switch( wParam )
  225.         {
  226.         case VK_ESCAPE:
  227.         case VK_F12:
  228.             PostMessage(hWnd, WM_CLOSE, 0, 0);
  229.             break;
  230.         }
  231.         break;
  232.  
  233.     case WM_DESTROY:
  234.         finiObjects();
  235.         PostQuitMessage( 0 );
  236.         break;
  237.     }
  238.  
  239.     return DefWindowProc(hWnd, message, wParam, lParam);
  240.  
  241. } /* WindowProc */
  242.  
  243. /*
  244.  * This function is called if the initialization function fails
  245.  */
  246. BOOL initFail( HWND hwnd )
  247. {
  248.     finiObjects();
  249.     MessageBox( hwnd, "DirectDraw Init FAILED", TITLE, MB_OK );
  250.     DestroyWindow( hwnd );
  251.     return FALSE;
  252.  
  253. } /* initFail */
  254.  
  255. /*
  256.  * doInit - do work required for every instance of the application:
  257.  *                create the window, initialize data
  258.  */
  259. static BOOL doInit( HINSTANCE hInstance, int nCmdShow )
  260. {
  261.     HWND                hwnd;
  262.     WNDCLASS            wc;
  263.     DDSURFACEDESC       ddsd;
  264.     DDSCAPS             ddscaps;
  265.     HRESULT             ddrval;
  266.  
  267.     /*
  268.      * set up and register window class
  269.      */
  270.     wc.style = CS_HREDRAW | CS_VREDRAW;
  271.     wc.lpfnWndProc = WindowProc;
  272.     wc.cbClsExtra = 0;
  273.     wc.cbWndExtra = 0;
  274.     wc.hInstance = hInstance;
  275.     wc.hIcon = LoadIcon( hInstance, IDI_APPLICATION );
  276.     wc.hCursor = LoadCursor( NULL, IDC_ARROW );
  277.     wc.hbrBackground = GetStockBrush(BLACK_BRUSH);
  278.     wc.lpszMenuName = NAME;
  279.     wc.lpszClassName = NAME;
  280.     RegisterClass( &wc );
  281.     
  282.     /*
  283.      * create a window
  284.      */
  285.     hwnd = CreateWindowEx(
  286.         0,
  287.         NAME,
  288.         TITLE,
  289.         WS_POPUP,
  290.         0,
  291.         0,
  292.         GetSystemMetrics(SM_CXSCREEN),
  293.         GetSystemMetrics(SM_CYSCREEN),
  294.         NULL,
  295.         NULL,
  296.         hInstance,
  297.         NULL );
  298.  
  299.     if( !hwnd )
  300.     {
  301.         return FALSE;
  302.     }
  303.  
  304.     ShowWindow( hwnd, nCmdShow );
  305.     UpdateWindow( hwnd );
  306.  
  307.     /*
  308.      * create the main DirectDraw object
  309.      */
  310.     ddrval = DirectDrawCreate( NULL, &lpDD, NULL );
  311.     if( ddrval != DD_OK )
  312.     {
  313.         return initFail(hwnd);
  314.     }
  315.  
  316.     // Get exclusive mode
  317.     ddrval = lpDD->SetCooperativeLevel( hwnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN );
  318.     if( ddrval != DD_OK )
  319.     {
  320.         return initFail(hwnd);
  321.     }
  322.  
  323.     // Set the video mode to 640x480x8
  324.     ddrval = lpDD->SetDisplayMode( 640, 480, 8);
  325.     if( ddrval != DD_OK )
  326.     {
  327.         return initFail(hwnd);
  328.     }
  329.  
  330.     // Create the primary surface with 1 back buffer
  331.     ddsd.dwSize = sizeof( ddsd );
  332.     ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
  333.     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE |
  334.                           DDSCAPS_FLIP |
  335.                           DDSCAPS_COMPLEX;
  336.     ddsd.dwBackBufferCount = 1;
  337.     ddrval = lpDD->CreateSurface( &ddsd, &lpDDSPrimary, NULL );
  338.     if( ddrval != DD_OK )
  339.     {
  340.         return initFail(hwnd);
  341.     }
  342.  
  343.     ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
  344.     ddrval = lpDDSPrimary->GetAttachedSurface(&ddscaps, &lpDDSBack);
  345.     if( ddrval != DD_OK )
  346.     {
  347.         return initFail(hwnd);
  348.     }
  349.  
  350.     // create and set the palette
  351.     lpDDPal = DDLoadPalette(lpDD, szBitmap);
  352.  
  353.     if (lpDDPal)
  354.         lpDDSPrimary->SetPalette(lpDDPal);
  355.  
  356.     // Create the offscreen surface, by loading our bitmap.
  357.     lpDDSOne = DDLoadBitmap(lpDD, szBitmap, 0, 0);
  358.  
  359.     if( lpDDSOne == NULL )
  360.     {
  361.         return initFail(hwnd);
  362.     }
  363.  
  364.     // Set the color key for this bitmap (black)
  365.     DDSetColorKey(lpDDSOne, RGB(0,0,0));
  366.  
  367.     return TRUE;
  368. } /* doInit */
  369.  
  370. /*
  371.  * WinMain - initialization, message loop
  372.  */
  373. int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
  374.                         LPSTR lpCmdLine, int nCmdShow)
  375. {
  376.     MSG         msg;
  377.  
  378.     lpCmdLine = lpCmdLine;
  379.     hPrevInstance = hPrevInstance;
  380.  
  381.     if( !doInit( hInstance, nCmdShow ) )
  382.     {
  383.         return FALSE;
  384.     }
  385.  
  386.     while( 1 )
  387.     {
  388.         if( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )
  389.         {
  390.             if( !GetMessage( &msg, NULL, 0, 0 ) )
  391.                 return msg.wParam;
  392.             TranslateMessage(&msg); 
  393.             DispatchMessage(&msg);
  394.         }
  395.         else if( bActive )
  396.         {
  397.             updateFrame();
  398.         }
  399.         else
  400.         {
  401.             // make sure we go to sleep if we have nothing else to do
  402.             WaitMessage();
  403.         }
  404.     }
  405. } /* WinMain */
  406.