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

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