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

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