home *** CD-ROM | disk | FTP | other *** search
/ The Net: Ultimate Internet Guide / WWLCD1.ISO / pc / directx2 / sdk / samples / donut / donut.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-28  |  10.6 KB  |  457 lines

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