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

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