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

  1. //-----------------------------------------------------------------------------
  2. // File: ddutil.cpp
  3. //
  4. // Desc: Routines for loading bitmap and palettes from resources
  5. //
  6. //
  7. // Copyright (c) 1995-1999 Microsoft Corporation. All rights reserved.
  8. //-----------------------------------------------------------------------------
  9.  
  10. #ifndef WIN32_LEAN_AND_MEAN
  11. #define WIN32_LEAN_AND_MEAN
  12. #endif
  13.  
  14. //-----------------------------------------------------------------------------
  15. // Include files
  16. //-----------------------------------------------------------------------------
  17. #include <windows.h>
  18. #include <windowsx.h>
  19. #include <ddraw.h>
  20. #include "ddutil.h"
  21.  
  22.  
  23.  
  24.  
  25. //-----------------------------------------------------------------------------
  26. // Name: DDLoadBitmap()
  27. // Desc: Create a DirectDrawSurface from a bitmap resource.
  28. //-----------------------------------------------------------------------------
  29. extern "C" IDirectDrawSurface7*
  30. DDLoadBitmap(IDirectDraw7 * pdd, LPCSTR szBitmap, int dx, int dy)
  31. {
  32.     HBITMAP                 hbm;
  33.     BITMAP                  bm;
  34.     DDSURFACEDESC2          ddsd;
  35.     IDirectDrawSurface7    *pdds;
  36.  
  37.     //
  38.     //  Try to load the bitmap as a resource, if that fails, try it as a file
  39.     //
  40.     hbm = (HBITMAP) LoadImage(GetModuleHandle(NULL), szBitmap, IMAGE_BITMAP, dx,
  41.                               dy, LR_CREATEDIBSECTION);
  42.     if (hbm == NULL)
  43.         hbm = (HBITMAP) LoadImage(NULL, szBitmap, IMAGE_BITMAP, dx, dy,
  44.                                   LR_LOADFROMFILE | LR_CREATEDIBSECTION);
  45.     if (hbm == NULL)
  46.         return NULL;
  47.     //
  48.     // Get size of the bitmap
  49.     //
  50.     GetObject(hbm, sizeof(bm), &bm);
  51.     //
  52.     // Create a DirectDrawSurface for this bitmap
  53.     //
  54.     ZeroMemory(&ddsd, sizeof(ddsd));
  55.     ddsd.dwSize = sizeof(ddsd);
  56.     ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
  57.     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
  58.     ddsd.dwWidth = bm.bmWidth;
  59.     ddsd.dwHeight = bm.bmHeight;
  60.     if (pdd->CreateSurface(&ddsd, &pdds, NULL) != DD_OK)
  61.         return NULL;
  62.     DDCopyBitmap(pdds, hbm, 0, 0, 0, 0);
  63.     DeleteObject(hbm);
  64.     return pdds;
  65. }
  66.  
  67.  
  68.  
  69.  
  70. //-----------------------------------------------------------------------------
  71. // Name: DDReLoadBitmap()
  72. // Desc: Load a bitmap from a file or resource into a directdraw surface.
  73. //       normaly used to re-load a surface after a restore.
  74. //-----------------------------------------------------------------------------
  75. HRESULT
  76. DDReLoadBitmap(IDirectDrawSurface7 * pdds, LPCSTR szBitmap)
  77. {
  78.     HBITMAP                 hbm;
  79.     HRESULT                 hr;
  80.  
  81.     //
  82.     //  Try to load the bitmap as a resource, if that fails, try it as a file
  83.     //
  84.     hbm = (HBITMAP) LoadImage(GetModuleHandle(NULL), szBitmap, IMAGE_BITMAP, 0,
  85.                               0, LR_CREATEDIBSECTION);
  86.     if (hbm == NULL)
  87.         hbm = (HBITMAP) LoadImage(NULL, szBitmap, IMAGE_BITMAP, 0, 0,
  88.                                   LR_LOADFROMFILE | LR_CREATEDIBSECTION);
  89.     if (hbm == NULL)
  90.     {
  91.         OutputDebugString("handle is null\n");
  92.         return E_FAIL;
  93.     }
  94.     hr = DDCopyBitmap(pdds, hbm, 0, 0, 0, 0);
  95.     if (hr != DD_OK)
  96.     {
  97.         OutputDebugString("ddcopybitmap failed\n");
  98.     }
  99.     DeleteObject(hbm);
  100.     return hr;
  101. }
  102.  
  103.  
  104.  
  105.  
  106. //-----------------------------------------------------------------------------
  107. // Name: DDCopyBitmap()
  108. // Desc: Draw a bitmap into a DirectDrawSurface
  109. //-----------------------------------------------------------------------------
  110. extern "C" HRESULT
  111. DDCopyBitmap(IDirectDrawSurface7 * pdds, HBITMAP hbm, int x, int y,
  112.              int dx, int dy)
  113. {
  114.     HDC                     hdcImage;
  115.     HDC                     hdc;
  116.     BITMAP                  bm;
  117.     DDSURFACEDESC2          ddsd;
  118.     HRESULT                 hr;
  119.  
  120.     if (hbm == NULL || pdds == NULL)
  121.         return E_FAIL;
  122.     //
  123.     // Make sure this surface is restored.
  124.     //
  125.     pdds->Restore();
  126.     //
  127.     // Select bitmap into a memoryDC so we can use it.
  128.     //
  129.     hdcImage = CreateCompatibleDC(NULL);
  130.     if (!hdcImage)
  131.         OutputDebugString("createcompatible dc failed\n");
  132.     SelectObject(hdcImage, hbm);
  133.     //
  134.     // Get size of the bitmap
  135.     //
  136.     GetObject(hbm, sizeof(bm), &bm);
  137.     dx = dx == 0 ? bm.bmWidth : dx;     // Use the passed size, unless zero
  138.     dy = dy == 0 ? bm.bmHeight : dy;
  139.     //
  140.     // Get size of surface.
  141.     //
  142.     ddsd.dwSize = sizeof(ddsd);
  143.     ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
  144.     pdds->GetSurfaceDesc(&ddsd);
  145.  
  146.     if ((hr = pdds->GetDC(&hdc)) == DD_OK)
  147.     {
  148.         StretchBlt(hdc, 0, 0, ddsd.dwWidth, ddsd.dwHeight, hdcImage, x, y,
  149.                    dx, dy, SRCCOPY);
  150.         pdds->ReleaseDC(hdc);
  151.     }
  152.     DeleteDC(hdcImage);
  153.     return hr;
  154. }
  155.  
  156.  
  157.  
  158.  
  159. //-----------------------------------------------------------------------------
  160. // Name: DDLoadPalette()
  161. // Desc: Create a DirectDraw palette object from a bitmap resource
  162. //       if the resource does not exist or NULL is passed create a
  163. //       default 332 palette.
  164. //-----------------------------------------------------------------------------
  165. extern "C" IDirectDrawPalette *
  166. DDLoadPalette(IDirectDraw7 * pdd, LPCSTR szBitmap)
  167. {
  168.     IDirectDrawPalette     *ddpal;
  169.     int                     i;
  170.     int                     n;
  171.     int                     fh;
  172.     HRSRC                   h;
  173.     LPBITMAPINFOHEADER      lpbi;
  174.     PALETTEENTRY            ape[256];
  175.     RGBQUAD                *prgb;
  176.  
  177.     //
  178.     // Build a 332 palette as the default.
  179.     //
  180.     for (i = 0; i < 256; i++)
  181.     {
  182.         ape[i].peRed = (BYTE) (((i >> 5) & 0x07) * 255 / 7);
  183.         ape[i].peGreen = (BYTE) (((i >> 2) & 0x07) * 255 / 7);
  184.         ape[i].peBlue = (BYTE) (((i >> 0) & 0x03) * 255 / 3);
  185.         ape[i].peFlags = (BYTE) 0;
  186.     }
  187.     //
  188.     // Get a pointer to the bitmap resource.
  189.     //
  190.     if (szBitmap && (h = FindResource(NULL, szBitmap, RT_BITMAP)))
  191.     {
  192.         lpbi = (LPBITMAPINFOHEADER) LockResource(LoadResource(NULL, h));
  193.         if (!lpbi)
  194.             OutputDebugString("lock resource failed\n");
  195.         prgb = (RGBQUAD *) ((BYTE *) lpbi + lpbi->biSize);
  196.         if (lpbi == NULL || lpbi->biSize < sizeof(BITMAPINFOHEADER))
  197.             n = 0;
  198.         else if (lpbi->biBitCount > 8)
  199.             n = 0;
  200.         else if (lpbi->biClrUsed == 0)
  201.             n = 1 << lpbi->biBitCount;
  202.         else
  203.             n = lpbi->biClrUsed;
  204.         //
  205.         //  A DIB color table has its colors stored BGR not RGB
  206.         //  so flip them around.
  207.         //
  208.         for (i = 0; i < n; i++)
  209.         {
  210.             ape[i].peRed = prgb[i].rgbRed;
  211.             ape[i].peGreen = prgb[i].rgbGreen;
  212.             ape[i].peBlue = prgb[i].rgbBlue;
  213.             ape[i].peFlags = 0;
  214.         }
  215.     }
  216.     else if (szBitmap && (fh = _lopen(szBitmap, OF_READ)) != -1)
  217.     {
  218.         BITMAPFILEHEADER        bf;
  219.         BITMAPINFOHEADER        bi;
  220.  
  221.         _lread(fh, &bf, sizeof(bf));
  222.         _lread(fh, &bi, sizeof(bi));
  223.         _lread(fh, ape, sizeof(ape));
  224.         _lclose(fh);
  225.         if (bi.biSize != sizeof(BITMAPINFOHEADER))
  226.             n = 0;
  227.         else if (bi.biBitCount > 8)
  228.             n = 0;
  229.         else if (bi.biClrUsed == 0)
  230.             n = 1 << bi.biBitCount;
  231.         else
  232.             n = bi.biClrUsed;
  233.         //
  234.         //  A DIB color table has its colors stored BGR not RGB
  235.         //  so flip them around.
  236.         //
  237.         for (i = 0; i < n; i++)
  238.         {
  239.             BYTE        r = ape[i].peRed;
  240.  
  241.             ape[i].peRed = ape[i].peBlue;
  242.             ape[i].peBlue = r;
  243.         }
  244.     }
  245.     pdd->CreatePalette(DDPCAPS_8BIT, ape, &ddpal, NULL);
  246.     return ddpal;
  247. }
  248.  
  249.  
  250.  
  251.  
  252. //-----------------------------------------------------------------------------
  253. // Name: DDColorMatch()
  254. // Desc: Convert a RGB color to a pysical color.
  255. //       We do this by leting GDI SetPixel() do the color matching
  256. //       then we lock the memory and see what it got mapped to.
  257. //-----------------------------------------------------------------------------
  258. extern "C" DWORD
  259. DDColorMatch(IDirectDrawSurface7 * pdds, COLORREF rgb)
  260. {
  261.     COLORREF                rgbT;
  262.     HDC                     hdc;
  263.     DWORD                   dw = CLR_INVALID;
  264.     DDSURFACEDESC2          ddsd;
  265.     HRESULT                 hres;
  266.  
  267.     //
  268.     //  Use GDI SetPixel to color match for us
  269.     //
  270.     if (rgb != CLR_INVALID && pdds->GetDC(&hdc) == DD_OK)
  271.     {
  272.         rgbT = GetPixel(hdc, 0, 0);     // Save current pixel value
  273.         SetPixel(hdc, 0, 0, rgb);       // Set our value
  274.         pdds->ReleaseDC(hdc);
  275.     }
  276.     //
  277.     // Now lock the surface so we can read back the converted color
  278.     //
  279.     ddsd.dwSize = sizeof(ddsd);
  280.     while ((hres = pdds->Lock(NULL, &ddsd, 0, NULL)) == DDERR_WASSTILLDRAWING)
  281.         ;
  282.     if (hres == DD_OK)
  283.     {
  284.         dw = *(DWORD *) ddsd.lpSurface;                 // Get DWORD
  285.         if (ddsd.ddpfPixelFormat.dwRGBBitCount < 32)
  286.             dw &= (1 << ddsd.ddpfPixelFormat.dwRGBBitCount) - 1;  // Mask it to bpp
  287.         pdds->Unlock(NULL);
  288.     }
  289.     //
  290.     //  Now put the color that was there back.
  291.     //
  292.     if (rgb != CLR_INVALID && pdds->GetDC(&hdc) == DD_OK)
  293.     {
  294.         SetPixel(hdc, 0, 0, rgbT);
  295.         pdds->ReleaseDC(hdc);
  296.     }
  297.     return dw;
  298. }
  299.  
  300.  
  301.  
  302.  
  303. //-----------------------------------------------------------------------------
  304. // Name: DDSetColorKey()
  305. // Desc: Set a color key for a surface, given a RGB.
  306. //       If you pass CLR_INVALID as the color key, the pixel
  307. //       in the upper-left corner will be used.
  308. //-----------------------------------------------------------------------------
  309. extern "C" HRESULT
  310. DDSetColorKey(IDirectDrawSurface7 * pdds, COLORREF rgb)
  311. {
  312.     DDCOLORKEY              ddck;
  313.  
  314.     ddck.dwColorSpaceLowValue = DDColorMatch(pdds, rgb);
  315.     ddck.dwColorSpaceHighValue = ddck.dwColorSpaceLowValue;
  316.     return pdds->SetColorKey(DDCKEY_SRCBLT, &ddck);
  317. }
  318.  
  319.  
  320.