home *** CD-ROM | disk | FTP | other *** search
/ Microsoft DirectX SDK 7.0 / Dx7.bin / DXF / samples / multimedia / ddraw / src / ddex4 / ddex4.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-07-14  |  12.6 KB  |  411 lines

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