Ddutil.cpp
上传用户:semy2100
上传日期:2013-01-22
资源大小:3633k
文件大小:8k
源码类别:

射击游戏

开发平台:

Visual C++

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