Ddutil.cpp
上传用户:sycq158
上传日期:2008-10-22
资源大小:15361k
文件大小:10k
源码类别:

游戏

开发平台:

Visual C++

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