⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ddutil.cpp

📁 RPG四大编辑器:场景/道具/角色/地图四大编辑器源代码 vc++ 6.0
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//-----------------------------------------------------------------------------
// 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 + -