home *** CD-ROM | disk | FTP | other *** search
/ Microsoft DirectX SDK 7.0 / Dx7.bin / DXF / samples / multimedia / ddraw / src / ddex2 / ddutil.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-07-14  |  9.9 KB  |  319 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 DDReLoadBitmap( IDirectDrawSurface7* pdds, LPCSTR szBitmap)
  76. {
  77.     HBITMAP                 hbm;
  78.     HRESULT                 hr;
  79.  
  80.     //
  81.     //  Try to load the bitmap as a resource, if that fails, try it as a file
  82.     //
  83.     hbm = (HBITMAP) LoadImage(GetModuleHandle(NULL), szBitmap, IMAGE_BITMAP, 0,
  84.                               0, LR_CREATEDIBSECTION);
  85.     if (hbm == NULL)
  86.         hbm = (HBITMAP) LoadImage(NULL, szBitmap, IMAGE_BITMAP, 0, 0,
  87.                                   LR_LOADFROMFILE | LR_CREATEDIBSECTION);
  88.     if (hbm == NULL)
  89.     {
  90.         OutputDebugString("handle is null\n");
  91.         return E_FAIL;
  92.     }
  93.     hr = DDCopyBitmap(pdds, hbm, 0, 0, 0, 0);
  94.     if (hr != DD_OK)
  95.     {
  96.         OutputDebugString("ddcopybitmap failed\n");
  97.     }
  98.     DeleteObject(hbm);
  99.     return hr;
  100. }
  101.  
  102.  
  103.  
  104.  
  105. //-----------------------------------------------------------------------------
  106. // Name: DDCopyBitmap()
  107. // Desc: Draw a bitmap into a DirectDrawSurface
  108. //-----------------------------------------------------------------------------
  109. extern "C" HRESULT
  110. DDCopyBitmap(IDirectDrawSurface7* pdds, HBITMAP hbm, int x, int y,
  111.              int dx, int dy)
  112. {
  113.     HDC                     hdcImage;
  114.     HDC                     hdc;
  115.     BITMAP                  bm;
  116.     DDSURFACEDESC2          ddsd;
  117.     HRESULT                 hr;
  118.  
  119.     if (hbm == NULL || pdds == NULL)
  120.         return E_FAIL;
  121.     //
  122.     // Make sure this surface is restored.
  123.     //
  124.     pdds->Restore();
  125.     //
  126.     // Select bitmap into a memoryDC so we can use it.
  127.     //
  128.     hdcImage = CreateCompatibleDC(NULL);
  129.     if (!hdcImage)
  130.         OutputDebugString("createcompatible dc failed\n");
  131.     SelectObject(hdcImage, hbm);
  132.     //
  133.     // Get size of the bitmap
  134.     //
  135.     GetObject(hbm, sizeof(bm), &bm);
  136.     dx = dx == 0 ? bm.bmWidth : dx;     // Use the passed size, unless zero
  137.     dy = dy == 0 ? bm.bmHeight : dy;
  138.     //
  139.     // Get size of surface.
  140.     //
  141.     ddsd.dwSize = sizeof(ddsd);
  142.     ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
  143.     pdds->GetSurfaceDesc(&ddsd);
  144.  
  145.     if ((hr = pdds->GetDC(&hdc)) == DD_OK)
  146.     {
  147.         StretchBlt(hdc, 0, 0, ddsd.dwWidth, ddsd.dwHeight, hdcImage, x, y,
  148.                    dx, dy, SRCCOPY);
  149.         pdds->ReleaseDC(hdc);
  150.     }
  151.     DeleteDC(hdcImage);
  152.     return hr;
  153. }
  154.  
  155.  
  156.  
  157.  
  158. //-----------------------------------------------------------------------------
  159. // Name: DDLoadPalette()
  160. // Desc: Create a DirectDraw palette object from a bitmap resource
  161. //       if the resource does not exist or NULL is passed create a
  162. //       default 332 palette.
  163. //-----------------------------------------------------------------------------
  164. extern "C" IDirectDrawPalette *
  165. DDLoadPalette(IDirectDraw7* pdd, LPCSTR szBitmap)
  166. {
  167.     IDirectDrawPalette     *ddpal;
  168.     int                     i;
  169.     int                     n;
  170.     int                     fh;
  171.     HRSRC                   h;
  172.     LPBITMAPINFOHEADER      lpbi;
  173.     PALETTEENTRY            ape[256];
  174.     RGBQUAD                *prgb;
  175.  
  176.     //
  177.     // Build a 332 palette as the default.
  178.     //
  179.     for (i = 0; i < 256; i++)
  180.     {
  181.         ape[i].peRed = (BYTE) (((i >> 5) & 0x07) * 255 / 7);
  182.         ape[i].peGreen = (BYTE) (((i >> 2) & 0x07) * 255 / 7);
  183.         ape[i].peBlue = (BYTE) (((i >> 0) & 0x03) * 255 / 3);
  184.         ape[i].peFlags = (BYTE) 0;
  185.     }
  186.     //
  187.     // Get a pointer to the bitmap resource.
  188.     //
  189.     if (szBitmap && (h = FindResource(NULL, szBitmap, RT_BITMAP)))
  190.     {
  191.         lpbi = (LPBITMAPINFOHEADER) LockResource(LoadResource(NULL, h));
  192.         if (!lpbi)
  193.             OutputDebugString("lock resource failed\n");
  194.         prgb = (RGBQUAD *) ((BYTE *) lpbi + lpbi->biSize);
  195.         if (lpbi == NULL || lpbi->biSize < sizeof(BITMAPINFOHEADER))
  196.             n = 0;
  197.         else if (lpbi->biBitCount > 8)
  198.             n = 0;
  199.         else if (lpbi->biClrUsed == 0)
  200.             n = 1 << lpbi->biBitCount;
  201.         else
  202.             n = lpbi->biClrUsed;
  203.         //
  204.         //  A DIB color table has its colors stored BGR not RGB
  205.         //  so flip them around.
  206.         //
  207.         for (i = 0; i < n; i++)
  208.         {
  209.             ape[i].peRed = prgb[i].rgbRed;
  210.             ape[i].peGreen = prgb[i].rgbGreen;
  211.             ape[i].peBlue = prgb[i].rgbBlue;
  212.             ape[i].peFlags = 0;
  213.         }
  214.     }
  215.     else if (szBitmap && (fh = _lopen(szBitmap, OF_READ)) != -1)
  216.     {
  217.         BITMAPFILEHEADER        bf;
  218.         BITMAPINFOHEADER        bi;
  219.  
  220.         _lread(fh, &bf, sizeof(bf));
  221.         _lread(fh, &bi, sizeof(bi));
  222.         _lread(fh, ape, sizeof(ape));
  223.         _lclose(fh);
  224.         if (bi.biSize != sizeof(BITMAPINFOHEADER))
  225.             n = 0;
  226.         else if (bi.biBitCount > 8)
  227.             n = 0;
  228.         else if (bi.biClrUsed == 0)
  229.             n = 1 << bi.biBitCount;
  230.         else
  231.             n = bi.biClrUsed;
  232.         //
  233.         //  A DIB color table has its colors stored BGR not RGB
  234.         //  so flip them around.
  235.         //
  236.         for (i = 0; i < n; i++)
  237.         {
  238.             BYTE        r = ape[i].peRed;
  239.  
  240.             ape[i].peRed = ape[i].peBlue;
  241.             ape[i].peBlue = r;
  242.         }
  243.     }
  244.     pdd->CreatePalette(DDPCAPS_8BIT, ape, &ddpal, NULL);
  245.     return ddpal;
  246. }
  247.  
  248.  
  249.  
  250.  
  251. //-----------------------------------------------------------------------------
  252. // Name: DDColorMatch()
  253. // Desc: Convert a RGB color to a pysical color.
  254. //       We do this by leting GDI SetPixel() do the color matching
  255. //       then we lock the memory and see what it got mapped to.
  256. //-----------------------------------------------------------------------------
  257. extern "C" DWORD
  258. DDColorMatch(IDirectDrawSurface7* pdds, COLORREF rgb)
  259. {
  260.     COLORREF                rgbT;
  261.     HDC                     hdc;
  262.     DWORD                   dw = CLR_INVALID;
  263.     DDSURFACEDESC2          ddsd;
  264.     HRESULT                 hres;
  265.  
  266.     //
  267.     //  Use GDI SetPixel to color match for us
  268.     //
  269.     if (rgb != CLR_INVALID && pdds->GetDC(&hdc) == DD_OK)
  270.     {
  271.         rgbT = GetPixel(hdc, 0, 0);     // Save current pixel value
  272.         SetPixel(hdc, 0, 0, rgb);       // Set our value
  273.         pdds->ReleaseDC(hdc);
  274.     }
  275.     //
  276.     // Now lock the surface so we can read back the converted color
  277.     //
  278.     ddsd.dwSize = sizeof(ddsd);
  279.     while ((hres = pdds->Lock(NULL, &ddsd, 0, NULL)) == DDERR_WASSTILLDRAWING)
  280.         ;
  281.     if (hres == DD_OK)
  282.     {
  283.         dw = *(DWORD *) ddsd.lpSurface;                 // Get DWORD
  284.         if (ddsd.ddpfPixelFormat.dwRGBBitCount < 32)
  285.             dw &= (1 << ddsd.ddpfPixelFormat.dwRGBBitCount) - 1;  // Mask it to bpp
  286.         pdds->Unlock(NULL);
  287.     }
  288.     //
  289.     //  Now put the color that was there back.
  290.     //
  291.     if (rgb != CLR_INVALID && pdds->GetDC(&hdc) == DD_OK)
  292.     {
  293.         SetPixel(hdc, 0, 0, rgbT);
  294.         pdds->ReleaseDC(hdc);
  295.     }
  296.     return dw;
  297. }
  298.  
  299.  
  300.  
  301.  
  302. //-----------------------------------------------------------------------------
  303. // Name: DDSetColorKey()
  304. // Desc: Set a color key for a surface, given a RGB.
  305. //       If you pass CLR_INVALID as the color key, the pixel
  306. //       in the upper-left corner will be used.
  307. //-----------------------------------------------------------------------------
  308. extern "C" HRESULT
  309. DDSetColorKey(IDirectDrawSurface7* pdds, COLORREF rgb)
  310. {
  311.     DDCOLORKEY              ddck;
  312.  
  313.     ddck.dwColorSpaceLowValue = DDColorMatch(pdds, rgb);
  314.     ddck.dwColorSpaceHighValue = ddck.dwColorSpaceLowValue;
  315.     return pdds->SetColorKey(DDCKEY_SRCBLT, &ddck);
  316. }
  317.  
  318.  
  319.