1

/**//*==========================================================================2
*3
* Copyright (C) 1995-1996 Microsoft Corporation. All Rights Reserved.4
*5
* File: ddutil.cpp6
* Content: Routines for loading bitmap and palettes from resources7
*8
***************************************************************************/9
#undef WIN32_LEAN_AND_MEAN10
#define WIN32_LEAN_AND_MEAN11
#include <windows.h>12
#include <windowsx.h>13
#include <ddraw.h>14
#include "ddutil.h"15

16

/**//*17
* DDLoadBitmap18
*19
* create a DirectDrawSurface from a bitmap resource.20
*21
*/22
extern "C" IDirectDrawSurface * DDLoadBitmap(IDirectDraw *pdd, LPCSTR szBitmap, int dx, int dy)23


{24
HBITMAP hbm;25
BITMAP bm;26
DDSURFACEDESC ddsd;27
IDirectDrawSurface *pdds;28

29
//30
// try to load the bitmap as a resource, if that fails, try it as a file31
//32
hbm = (HBITMAP)LoadImage(GetModuleHandle(NULL), szBitmap, IMAGE_BITMAP, dx, dy, LR_CREATEDIBSECTION);33

34
if (hbm == NULL)35
hbm = (HBITMAP)LoadImage(NULL, szBitmap, IMAGE_BITMAP, dx, dy, LR_LOADFROMFILE|LR_CREATEDIBSECTION);36

37
if (hbm == NULL)38
return NULL;39

40
//41
// get size of the bitmap42
//43
GetObject(hbm, sizeof(bm), &bm); // get size of bitmap44

45
//46
// create a DirectDrawSurface for this bitmap47
//48
ZeroMemory(&ddsd, sizeof(ddsd));49
ddsd.dwSize = sizeof(ddsd);50
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH;51
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;52
ddsd.dwWidth = bm.bmWidth;53
ddsd.dwHeight = bm.bmHeight;54

55
if (pdd->CreateSurface(&ddsd, &pdds, NULL) != DD_OK)56
return NULL;57

58
DDCopyBitmap(pdds, hbm, 0, 0, 0, 0);59

60
DeleteObject(hbm);61

62
return pdds;63
}64

65

/**//*66
* DDReLoadBitmap67
*68
* load a bitmap from a file or resource into a directdraw surface.69
* normaly used to re-load a surface after a restore.70
*71
*/72
HRESULT DDReLoadBitmap(IDirectDrawSurface *pdds, LPCSTR szBitmap)73


{74
HBITMAP hbm;75
HRESULT hr;76

77
//78
// try to load the bitmap as a resource, if that fails, try it as a file79
//80
hbm = (HBITMAP)LoadImage(GetModuleHandle(NULL), szBitmap, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);81

82
if (hbm == NULL)83
hbm = (HBITMAP)LoadImage(NULL, szBitmap, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION);84

85
if (hbm == NULL)86

{87
OutputDebugString("handle is null\n");88
return E_FAIL;89
}90

91
hr = DDCopyBitmap(pdds, hbm, 0, 0, 0, 0);92
if (hr != DD_OK)93

{94
OutputDebugString("ddcopybitmap failed\n");95
}96

97

98
DeleteObject(hbm);99
return hr;100
}101

102

/**//*103
* DDCopyBitmap104
*105
* draw a bitmap into a DirectDrawSurface106
*107
*/108
extern "C" HRESULT DDCopyBitmap(IDirectDrawSurface *pdds, HBITMAP hbm, int x, int y, int dx, int dy)109


{110
HDC hdcImage;111
HDC hdc;112
BITMAP bm;113
DDSURFACEDESC ddsd;114
HRESULT hr;115

116
if (hbm == NULL || pdds == NULL)117
return E_FAIL;118

119
//120
// make sure this surface is restored.121
//122
pdds->Restore();123

124
//125
// select bitmap into a memoryDC so we can use it.126
//127
hdcImage = CreateCompatibleDC(NULL);128
if (!hdcImage)129
OutputDebugString("createcompatible dc failed\n");130
SelectObject(hdcImage, hbm);131

132
//133
// get size of the bitmap134
//135
GetObject(hbm, sizeof(bm), &bm); // get size of bitmap136
dx = dx == 0 ? bm.bmWidth : dx; // use the passed size, unless zero137
dy = dy == 0 ? bm.bmHeight : dy;138

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, dx, dy, SRCCOPY);149
pdds->ReleaseDC(hdc);150
}151

152
DeleteDC(hdcImage);153

154
return hr;155
}156

157
//158
// DDLoadPalette159
//160
// Create a DirectDraw palette object from a bitmap resoure161
//162
// if the resource does not exist or NULL is passed create a163
// default 332 palette.164
//165
extern "C" IDirectDrawPalette * DDLoadPalette(IDirectDraw *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
//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

197
if (lpbi == NULL || lpbi->biSize < sizeof(BITMAPINFOHEADER))198
n = 0;199
else if (lpbi->biBitCount > 8)200
n = 0;201
else if (lpbi->biClrUsed == 0)202
n = 1 << lpbi->biBitCount;203
else204
n = lpbi->biClrUsed;205

206
//207
// a DIB color table has its colors stored BGR not RGB208
// so flip them around.209
//210
for(i=0; i<n; i++ )211

{212
ape[i].peRed = prgb[i].rgbRed;213
ape[i].peGreen = prgb[i].rgbGreen;214
ape[i].peBlue = prgb[i].rgbBlue;215
ape[i].peFlags = 0;216
}217
}218
else if (szBitmap && (fh = _lopen(szBitmap, OF_READ)) != -1)219

{220
BITMAPFILEHEADER bf;221
BITMAPINFOHEADER bi;222

223
_lread(fh, &bf, sizeof(bf));224
_lread(fh, &bi, sizeof(bi));225
_lread(fh, ape, sizeof(ape));226
_lclose(fh);227

228
if (bi.biSize != sizeof(BITMAPINFOHEADER))229
n = 0;230
else if (bi.biBitCount > 8)231
n = 0;232
else if (bi.biClrUsed == 0)233
n = 1 << bi.biBitCount;234
else235
n = bi.biClrUsed;236

237
//238
// a DIB color table has its colors stored BGR not RGB239
// so flip them around.240
//241
for(i=0; i<n; i++ )242

{243
BYTE r = ape[i].peRed;244
ape[i].peRed = ape[i].peBlue;245
ape[i].peBlue = r;246
}247
}248

249
pdd->CreatePalette(DDPCAPS_8BIT, ape, &ddpal, NULL);250

251
return ddpal;252
}253

254

/**//*255
* DDColorMatch256
*257
* convert a RGB color to a pysical color.258
*259
* we do this by leting GDI SetPixel() do the color matching260
* then we lock the memory and see what it got mapped to.261
*/262
//获得指定颜色所对应的调色板索引263
extern "C" DWORD DDColorMatch(IDirectDrawSurface *pdds, COLORREF rgb)264


{265
COLORREF rgbT;266
HDC hdc;267
DWORD dw = CLR_INVALID;268
DDSURFACEDESC ddsd;269
HRESULT hres;270

271
//272
// use GDI SetPixel to color match for us273
//274
if (rgb != CLR_INVALID && pdds->GetDC(&hdc) == DD_OK)275

{276
rgbT = GetPixel(hdc, 0, 0); // save current pixel value277
SetPixel(hdc, 0, 0, rgb); // set our value278
pdds->ReleaseDC(hdc);279
}280

281
//282
// now lock the surface so we can read back the converted color283
//284
ddsd.dwSize = sizeof(ddsd);285
while ((hres = pdds->Lock(NULL, &ddsd, 0, NULL)) == DDERR_WASSTILLDRAWING)286
;287

288
if (hres == DD_OK)289

{290
dw = *(DWORD *)ddsd.lpSurface; // get DWORD291
dw &= (1 << ddsd.ddpfPixelFormat.dwRGBBitCount)-1; // mask it to bpp292
pdds->Unlock(NULL);293
}294

295
//296
// now put the color that was there back.297
//298
if (rgb != CLR_INVALID && pdds->GetDC(&hdc) == DD_OK)299

{300
SetPixel(hdc, 0, 0, rgbT);301
pdds->ReleaseDC(hdc);302
}303

304
return dw;305
}306

307

/**//*308
* DDSetColorKey309
*310
* set a color key for a surface, given a RGB.311
* if you pass CLR_INVALID as the color key, the pixel312
* in the upper-left corner will be used.313
*/314
extern "C" HRESULT DDSetColorKey(IDirectDrawSurface *pdds, COLORREF rgb)315


{316
DDCOLORKEY ddck;317

318
ddck.dwColorSpaceLowValue = DDColorMatch(pdds, rgb);319
ddck.dwColorSpaceHighValue = ddck.dwColorSpaceLowValue;320
return pdds->SetColorKey(DDCKEY_SRCBLT, &ddck);321
}
浙公网安备 33010602011771号