📄 ddutil.cpp
字号:
//-----------------------------------------------------------------------------
// File: ddutil.cpp
// Desc: 由SDK提供的装入位图和调色板函数
// Copyright (c) 1995-1998 Microsoft Corporation. All rights reserved.
// 无心柳:对其进行部分修改和扩充
//-----------------------------------------------------------------------------
#include "stdafx.h"
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
//-----------------------------------------------------------------------------
// 包含文件
//-----------------------------------------------------------------------------
#include <windows.h>
#include <windowsx.h>
#include <ddraw.h>
#include "ddutil.h"
#define MAX(x, y) ((x)>(y)? (x) : (y))
#pragma pack (push)
#pragma pack (1)
struct TGAFILEHEADER{
BYTE bIDLength; //附加信息长度
BYTE bPalType; //调色板信息(不支持)
BYTE bImageType; //图象类型(只支持 2,10)
WORD wPalIndex; //调色板第一个索引值
WORD wPalLength; //调色板索引数
BYTE bPalBits; //一个调色板单位位数(15,16,24,32)
WORD wLeft; //图象左端坐标(基本不用)
WORD wBottom; //图象底端坐标(基本不用)
WORD wWidth; //图象宽度
WORD wHeight; //图象高度
BYTE bBits; //一个象素位数
BYTE bAlphaBits:4; //Alpha位数
BYTE bReserved:1; //保留,必须为0
BYTE bTopDown:1; //为1表示从上到下(只支持从下到上)
BYTE bInterleaving:2; //隔行(一般为0)
};
#pragma pack (pop)
//-----------------------------------------------------------------------------
// Name: DDLoadBitmap()
// Desc: Create a DirectDrawSurface from a bitmap resource.
//-----------------------------------------------------------------------------
extern "C" IDirectDrawSurface7 *
DDLoadBitmap(IDirectDraw7 * pdd, LPCSTR szBitmap, int dx, int dy)
{
HBITMAP hbm;
BITMAP bm;
DDSURFACEDESC2 ddsd;
IDirectDrawSurface7 *pdds;
//
// Try to load the bitmap as a resource, if that fails, try it as a file
//
hbm = (HBITMAP) LoadImage(GetModuleHandle(NULL), szBitmap, IMAGE_BITMAP, dx,
dy, LR_CREATEDIBSECTION);
if (hbm == NULL)
hbm = (HBITMAP) LoadImage(NULL, szBitmap, IMAGE_BITMAP, dx, dy,
LR_LOADFROMFILE | LR_CREATEDIBSECTION);
if (hbm == NULL)
return NULL;
//
// Get size of the bitmap
//
GetObject(hbm, sizeof(bm), &bm);
//增加检测页面格式的代码,指定只能读入8位色(256)的位图
/*if(bm.bmBitsPixel!=8)
{
Msg("%s位图格式不是256色",szBitmap);
DeleteObject(hbm);
return NULL;
}*/
//
// 为这个位图创建页面
//
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
//如果仅指定在系统内存中创建就会失败
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
ddsd.dwWidth = bm.bmWidth;
ddsd.dwHeight = bm.bmHeight;
//增加部分结束
HRESULT hr=pdd->CreateSurface(&ddsd, &pdds, NULL);
if ( hr!= DD_OK)
{
DeleteObject(hbm);
return NULL;
}
DDCopyBitmap(pdds, hbm, 0, 0, 0, 0);
DeleteObject(hbm);
return pdds;
}
//-----------------------------------------------------------------------------
// Name: DDLoadTGA()
// Desc: Create a DirectDrawSurface from a TGA image resource.
//-----------------------------------------------------------------------------
extern "C"
IDirectDrawSurface7 *DDLoadTGA(IDirectDraw7 *pdd, LPCSTR szTGA, unsigned char **ppAlpha)
{
FILE *fp;
if ((fp=fopen(szTGA, "rb")) == NULL)
return NULL;
fseek(fp, 0, SEEK_END);
long len = ftell(fp); //get the file length
rewind(fp);
unsigned char *tgadata = new unsigned char[len];
if (!tgadata)
return NULL;
fread(tgadata, 1, len, fp);
fclose(fp);
//Decode:
DWORD dataptr;
int i,j,width,height;
TGAFILEHEADER *head=(TGAFILEHEADER *)tgadata;
if ((head->bImageType!=2 && head->bImageType!=10)
|| head->bBits!=32 || head->bInterleaving!=0 || head->bTopDown!=0)
{
delete []tgadata;
return NULL;
}
//创建图面
LPDIRECTDRAWSURFACE7 lpSurface;
DDSURFACEDESC2 desc;
ZeroMemory(&desc, sizeof(desc));
desc.dwSize = sizeof(desc);
desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
//如果仅指定在系统内存中创建就会失败
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
desc.dwWidth = head->wWidth;
desc.dwHeight = head->wHeight;
HRESULT ddval = pdd->CreateSurface(&desc, &lpSurface, NULL);
if (FAILED(ddval))
{
delete []tgadata;
return NULL;
}
memset (&desc, 0, sizeof(DDSURFACEDESC2));
desc.dwSize = sizeof(DDSURFACEDESC2);
ddval = lpSurface->Lock(NULL, &desc, DDLOCK_WAIT, NULL);
if (FAILED(ddval))
{
lpSurface->Release();
delete []tgadata;
return NULL;
}
//获取当前显示器颜色数
HDC hdc = ::GetDC(NULL);
long lColorBit = GetDeviceCaps(hdc, BITSPIXEL);
void *pSur = desc.lpSurface;
long lPitch = desc.lPitch;
//解索图面,由于图面是在系统内存,所以现在解索并不会出错
lpSurface->Unlock(NULL);
width = head->wWidth;
height = head->wHeight;
BOOL bNeedAlpha;
unsigned char *pAlpha = NULL;
if (ppAlpha)
{
bNeedAlpha = TRUE;
pAlpha = new unsigned char[desc.dwWidth*desc.dwHeight];
*ppAlpha = pAlpha;
pAlpha += (height-1) * width;
}
else
bNeedAlpha = FALSE;
switch (lColorBit)
{
case 8:
pSur = ((BYTE*)pSur) + (height-1) * lPitch;
break;
case 16:
lPitch >>= 1;
pSur = ((WORD*)pSur) + (height-1) * lPitch;
break;
case 32:
lPitch >>= 2;
pSur = ((DWORD*)pSur) + (height-1) * lPitch;
break;
}
dataptr=(DWORD)tgadata+sizeof(TGAFILEHEADER)+head->bIDLength;
if (head->bImageType==2) {
// 不压缩
for (i=height-1;i>=0;i--)
{
for (j=0;j<width;j++) {
BYTE red,green,blue,alpha;
blue=*(BYTE*)dataptr++;
green=*(BYTE*)dataptr++;
red=*(BYTE*)dataptr++;
alpha=*(BYTE*)dataptr++;
switch (lColorBit)
{
case 8:
((BYTE*)pSur)[j] = (BYTE)DDColorMatch(lpSurface, RGB(red, green, blue));
break;
case 16:
((WORD*)pSur)[j] = (WORD)DDColorMatch(lpSurface, RGB(red, green, blue));
break;
case 32:
((DWORD*)pSur)[j] = (DWORD)DDColorMatch(lpSurface, RGB(red, green, blue));
break;
}
if (bNeedAlpha)
{
alpha=MAX(MAX(MAX(red,green),blue),alpha);
pAlpha[j]=alpha;
}
}
if (bNeedAlpha)
pAlpha -= width;
switch (lColorBit)
{
case 8:
pSur = (BYTE*)pSur - lPitch;
break;
case 16:
pSur = (WORD*)pSur - lPitch;
break;
case 32:
pSur = (DWORD*) - lPitch;
break;
}
}
}
else
{
// RLE 压缩
int run=0,raw=0;
void *runpixel;
switch (lColorBit)
{
case 8:
runpixel = new BYTE;
break;
case 16:
runpixel = new WORD;
break;
case 32:
runpixel = new DWORD;
break;
}
BYTE runalpha;
BYTE red,green,blue,alpha;
for (i=height-1;i>=0;i--)
{
for (j=0;j<width;)
{
if (run>0)
{
switch (lColorBit)
{
case 8:
((BYTE*)pSur)[j] = *(BYTE*)runpixel;
break;
case 16:
((WORD*)pSur)[j] = *(WORD*)runpixel;
break;
case 32:
((DWORD*)pSur)[j] = *(DWORD*)runpixel;
break;
}
if (bNeedAlpha)
pAlpha[j]=runalpha;
--run;
++j;
}
else if (raw>0) {
blue=*(BYTE*)dataptr++;
green=*(BYTE*)dataptr++;
red=*(BYTE*)dataptr++;
alpha=*(BYTE*)dataptr++;
switch (lColorBit)
{
case 8:
((BYTE*)pSur)[j] = (BYTE)DDColorMatch(lpSurface, RGB(red, green, blue));
break;
case 16:
((WORD*)pSur)[j] = (WORD)DDColorMatch(lpSurface, RGB(red, green, blue));
break;
case 32:
((DWORD*)pSur)[j] = (DWORD)DDColorMatch(lpSurface, RGB(red, green, blue));
break;
}
if (bNeedAlpha)
{
alpha=MAX(MAX(MAX(red,green),blue),alpha);
pAlpha[j]=alpha;
}
--raw;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -