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

  1. /*==========================================================================
  2.  *
  3.  *  Copyright (C) 1995-1996 Microsoft Corporation. All Rights Reserved.
  4.  *
  5.  *  File:       donut.cpp
  6.  *
  7.  ***************************************************************************/
  8.  
  9. #define NAME "Stretch"
  10. #define TITLE "Stretch"
  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. #define SIZEX   64
  20. #define SIZEY   64
  21. char *szBitmap = "DONUT";
  22.  
  23. HWND            hwnd;
  24. DWORD           UpdateDelay = 13;
  25. HPALETTE        HPal = NULL;
  26.  
  27. LPDIRECTDRAW            lpDD;           // DirectDraw object
  28. LPDIRECTDRAWSURFACE     lpDDSPrimary;   // DirectDraw primary surface
  29. LPDIRECTDRAWSURFACE     lpDDSOne;       // Offscreen surface 1
  30. LPDIRECTDRAWCLIPPER     lpClipper;      // clipper for primary
  31. LPDIRECTDRAWPALETTE     lpDDPal;        // DirectDraw palette
  32. BOOL                    bActive;        // is application active?
  33.  
  34. /*
  35.  * restoreAll
  36.  *
  37.  * restore all lost objects
  38.  */
  39. BOOL restoreAll( void )
  40. {
  41.     return lpDDSPrimary->Restore() == DD_OK &&
  42.            lpDDSOne->Restore()     == DD_OK &&
  43.            DDReLoadBitmap(lpDDSOne, szBitmap) == DD_OK;
  44.  
  45. } /* restoreAll */
  46.  
  47. /*
  48.  * updateFrame
  49.  * 
  50.  * Decide what needs to be blitted next, wait for flip to complete,
  51.  * then flip the buffers.
  52.  */
  53. void updateFrame( void )
  54. {
  55.     static DWORD        lastTickCount = 0;
  56.     static int          currentFrame = 0;
  57.     static BOOL         haveBackground = FALSE;
  58.     DWORD               thisTickCount;
  59.     RECT                rcRect;
  60.     RECT                destRect;
  61.     HRESULT             ddrval;
  62.     POINT               pt;
  63.  
  64.     thisTickCount = GetTickCount();
  65.     if((thisTickCount - lastTickCount) <= UpdateDelay)
  66.     {
  67.         return;
  68.     }
  69.  
  70.     // Move to next frame;
  71.     lastTickCount = thisTickCount;
  72.     currentFrame++;
  73.     if(currentFrame > 59)
  74.     {
  75.         currentFrame = 0;
  76.     }
  77.  
  78.     // Blit the stuff for the next frame
  79.     rcRect.left   = currentFrame%10*64;
  80.     rcRect.top    = currentFrame/10*64;
  81.     rcRect.right  = currentFrame%10*64 + 64;
  82.     rcRect.bottom = currentFrame/10*64 + 64;
  83.  
  84.     GetClientRect( hwnd, &destRect );
  85.     if (destRect.right  < 128) destRect.right = 64;
  86.     if (destRect.bottom < 64)  destRect.bottom = 64;
  87.  
  88.     pt.x = pt.y = 0;
  89.     ClientToScreen( hwnd, &pt );
  90.     OffsetRect(&destRect, pt.x, pt.y);
  91.  
  92.     while( 1 )
  93.     {
  94.         ddrval = lpDDSPrimary->Blt( &destRect, lpDDSOne, &rcRect, 0, NULL );
  95.  
  96.         if( ddrval == DD_OK )
  97.         {
  98.             break;
  99.         }
  100.         if( ddrval == DDERR_SURFACELOST )
  101.         {
  102.             if(!restoreAll())
  103.             {
  104.                 return;
  105.             }
  106.         }
  107.         if( ddrval != DDERR_WASSTILLDRAWING )
  108.         {
  109.             return;
  110.         }
  111.     }
  112.     if(ddrval != DD_OK)
  113.     {
  114.         return;
  115.     }
  116. } /* updateFrame */
  117.  
  118.  
  119. /*
  120.  * finiObjects
  121.  *
  122.  * finished with all objects we use; release them
  123.  */
  124. static void finiObjects( void )
  125. {
  126.     if( lpDD != NULL )
  127.     {
  128.         if( lpDDSPrimary != NULL )
  129.         {
  130.             lpDDSPrimary->Release();
  131.             lpDDSPrimary = NULL;
  132.         }
  133.         if( lpDDSOne != NULL )
  134.         {
  135.             lpDDSOne->Release();
  136.             lpDDSOne = NULL;
  137.         }
  138.         if( lpDDPal != NULL )
  139.         {
  140.             lpDDPal->Release();
  141.             lpDDPal = NULL;
  142.         }
  143.         lpDD->Release();
  144.         lpDD = NULL;
  145.     }
  146. } /* finiObjects */
  147.  
  148. long FAR PASCAL WindowProc( HWND hWnd, UINT message, 
  149.                             WPARAM wParam, LPARAM lParam )
  150. {
  151.     RECT  rc;
  152.  
  153.     switch( message )
  154.     {
  155.     case WM_ACTIVATEAPP:
  156.         bActive = wParam;
  157.         break;
  158.  
  159.     case WM_PALETTECHANGED:
  160.         if ((HWND)wParam == hWnd)
  161.             break;
  162.         // fall through to WM_QUERYNEWPALETTE
  163.     case WM_QUERYNEWPALETTE:
  164.         // install our palette here
  165.         if (lpDDPal)
  166.         {
  167.             lpDDSPrimary->SetPalette(lpDDPal);
  168.         }
  169.         // reload the bitmap into the surface because the palette
  170.         // has changed..
  171.         DDReLoadBitmap(lpDDSOne, szBitmap);
  172.         break;
  173.  
  174.  
  175.     case WM_CREATE:
  176.         break;
  177.  
  178.     case WM_GETMINMAXINFO:
  179.         ((MINMAXINFO*)lParam)->ptMinTrackSize.x = SIZEX;
  180.         ((MINMAXINFO*)lParam)->ptMinTrackSize.y = SIZEY;
  181.         return 0;
  182.  
  183.     case WM_KEYDOWN:
  184.         switch( wParam )
  185.         {
  186.         case VK_ESCAPE:
  187.         case VK_F12:
  188.             PostMessage(hWnd, WM_CLOSE, 0, 0);
  189.             break;
  190.         }
  191.         break;
  192.  
  193.     case WM_DESTROY:
  194.         finiObjects();
  195.         PostQuitMessage( 0 );
  196.         break;
  197.  
  198.     case WM_COMMAND: 
  199.         switch(LOWORD(wParam))
  200.         {
  201.             case ID_ROTATION_STOP:          
  202.                 UpdateDelay = 0x7fffffff;
  203.                 break;
  204.             case ID_ROTATION_SLOW:          
  205.                 UpdateDelay = 200;
  206.                 break;
  207.             case ID_ROTATION_FAST:          
  208.                 UpdateDelay = 13;
  209.                 break;
  210.             case ID_FILE_EXIT:      
  211.                 PostMessage( hWnd, WM_CLOSE, 0, 0L );
  212.                 break;
  213.                     
  214.             case ID_SIZE_1X1: SetRect(&rc, 0, 0, SIZEX*1, SIZEY*1); goto size_me;
  215.             case ID_SIZE_2X1: SetRect(&rc, 0, 0, SIZEX*2, SIZEY*1); goto size_me;
  216.             case ID_SIZE_3X1: SetRect(&rc, 0, 0, SIZEX*3, SIZEY*1); goto size_me;
  217.             case ID_SIZE_1X2: SetRect(&rc, 0, 0, SIZEX*1, SIZEY*2); goto size_me;
  218.             case ID_SIZE_2X2: SetRect(&rc, 0, 0, SIZEX*2, SIZEY*2); goto size_me;
  219.             case ID_SIZE_3X2: SetRect(&rc, 0, 0, SIZEX*3, SIZEY*2); goto size_me;
  220.             case ID_SIZE_1X3: SetRect(&rc, 0, 0, SIZEX*1, SIZEY*3); goto size_me;
  221.             case ID_SIZE_2X3: SetRect(&rc, 0, 0, SIZEX*2, SIZEY*3); goto size_me;
  222.             case ID_SIZE_3X3: SetRect(&rc, 0, 0, SIZEX*3, SIZEY*3); goto size_me;
  223. size_me:
  224.                 AdjustWindowRectEx(&rc, GetWindowLong(hWnd, GWL_STYLE),
  225.                     GetMenu(hWnd) != NULL, GetWindowLong(hWnd, GWL_EXSTYLE));
  226.                 SetWindowPos(hWnd, NULL, 0, 0, rc.right-rc.left, rc.bottom-rc.top,
  227.                     SWP_NOZORDER|SWP_NOMOVE|SWP_NOACTIVATE);
  228.                 break;
  229.             } 
  230.             break;
  231.     }
  232.  
  233.     return DefWindowProc(hWnd, message, wParam, lParam);
  234.  
  235. } /* WindowProc */
  236.  
  237. /*
  238.  * This function is called if the initialization function fails
  239.  */
  240. BOOL initFail( HWND hwnd )
  241. {
  242.     finiObjects();
  243.     MessageBox( hwnd, "DirectDraw Init FAILED", TITLE, MB_OK );
  244.     DestroyWindow( hwnd );
  245.     return FALSE;
  246.  
  247. } /* initFail */
  248.  
  249. /*
  250.  * doInit - do work required for every instance of the application:
  251.  *                create the window, initialize data
  252.  */
  253. static BOOL doInit( HINSTANCE hInstance, int nCmdShow )
  254. {
  255.     WNDCLASS            wc;
  256.     DDSURFACEDESC       ddsd;
  257.     HRESULT             ddrval;
  258.  
  259.     /*
  260.      * set up and register window class
  261.      */
  262.     wc.style = CS_HREDRAW | CS_VREDRAW;
  263.     wc.lpfnWndProc = WindowProc;
  264.     wc.cbClsExtra = 0;
  265.     wc.cbWndExtra = 0;
  266.     wc.hInstance = hInstance;
  267.     wc.hIcon = LoadIcon( hInstance, IDI_APPLICATION );
  268.     wc.hCursor = LoadCursor( NULL, IDC_ARROW );
  269.     wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  270.     wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU);
  271.     wc.lpszClassName = NAME;
  272.     RegisterClass( &wc );
  273.     
  274.     /*
  275.      * create a window
  276.      */
  277.     hwnd = CreateWindowEx(
  278.         0,
  279.         NAME,
  280.         TITLE,
  281.         WS_OVERLAPPEDWINDOW,
  282.         CW_USEDEFAULT,
  283.         CW_USEDEFAULT,
  284.         128,
  285.         128,
  286.         NULL,
  287.         NULL,
  288.         hInstance,
  289.         NULL );
  290.  
  291.     if( !hwnd )
  292.     {
  293.         return FALSE;
  294.     }
  295.  
  296.     PostMessage(hwnd, WM_COMMAND, ID_SIZE_1X1, 0);
  297.  
  298.     ShowWindow( hwnd, nCmdShow );
  299.     UpdateWindow( hwnd );
  300.  
  301.     /*
  302.      * create the main DirectDraw object
  303.      */
  304.     ddrval = DirectDrawCreate( NULL, &lpDD, NULL );
  305.     if( ddrval != DD_OK )
  306.     {
  307.         return initFail(hwnd);
  308.     }
  309.     ddrval = lpDD->SetCooperativeLevel( hwnd, DDSCL_NORMAL );
  310.  
  311.     // Create the primary surface
  312.     ddsd.dwSize = sizeof( ddsd );
  313.     ddsd.dwFlags = DDSD_CAPS;
  314.     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
  315.  
  316.     ddrval = lpDD->CreateSurface( &ddsd, &lpDDSPrimary, NULL );
  317.     if( ddrval != DD_OK )
  318.     {
  319.         return initFail(hwnd);
  320.     }
  321.  
  322.     // create a clipper for the primary surface
  323.     ddrval = lpDD->CreateClipper( 0, &lpClipper, NULL );
  324.     if( ddrval != DD_OK )
  325.     {
  326.         return initFail(hwnd);
  327.     }
  328.     
  329.     ddrval = lpClipper->SetHWnd( 0, hwnd );
  330.     if( ddrval != DD_OK )
  331.     {
  332.         return initFail(hwnd);
  333.     }
  334.  
  335.     ddrval = lpDDSPrimary->SetClipper( lpClipper );
  336.     if( ddrval != DD_OK )
  337.     {
  338.         return initFail(hwnd);
  339.     }
  340.  
  341.     // load our palette
  342.     lpDDPal = DDLoadPalette(lpDD, szBitmap);
  343.  
  344.     // make sure to set the palette before loading bitmaps.
  345.     if (lpDDPal)
  346.         lpDDSPrimary->SetPalette(lpDDPal);
  347.  
  348.     // load our bitmap
  349.     lpDDSOne = DDLoadBitmap(lpDD, szBitmap, 0, 0);
  350.  
  351.     if( lpDDSOne == NULL )
  352.     {
  353.         return initFail(hwnd);
  354.     }
  355.  
  356.     return TRUE;
  357. } /* doInit */
  358.  
  359. /*
  360.  * WinMain - initialization, message loop
  361.  */
  362. int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
  363.                         LPSTR lpCmdLine, int nCmdShow)
  364. {
  365.     MSG         msg;
  366.  
  367.     if( !doInit( hInstance, nCmdShow ) )
  368.     {
  369.         return FALSE;
  370.     }
  371.  
  372.     while( 1 )
  373.     {
  374.         if( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )
  375.         {
  376.             if( !GetMessage( &msg, NULL, 0, 0 ) )
  377.                 return msg.wParam;
  378.             TranslateMessage(&msg); 
  379.             DispatchMessage(&msg);
  380.         }
  381.         else
  382.         {
  383.             updateFrame();
  384.         }
  385.     }
  386. } /* WinMain */
  387.