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

📄 instsurfwithddraw.cpp

📁 跨平台2D引擎
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//instSurfWithDDraw.cpp
#ifndef INST_SURFWIDTHDDRAW_CPP
#define INST_SURFWIDTHDDRAW_CPP


#include "instSurfWithDDraw.h"
#include <instGdiFont.h>


namespace inst
{


IDirectDraw7 *CSurf::s_pddraw=null;
COLOR CSurf::s_DefaultColorKey=Rgb(0,0,0);
Bool CSurf::s_DefaultColorKeyEnabled=True;

HFONT CSurf::ToGdiFont(const IFont *font)
{
	if(!font)return NULL;

	if(CStr(L"inst::CGdiFont")==font->GetClass())return ((CGdiFont *)font->GetAddr())->GetHFont();

	LOGFONTW lf;
	ZeroMemory(&lf,sizeof(lf));

	memcpy(lf.lfFaceName,font->GetName().ReadW(),Min(LF_FACESIZE,font->GetName().GetLen()));
	lf.lfHeight		= font->GetHeight();
	lf.lfWeight		= (font->IsBold())?700:400;
	lf.lfItalic		= (font->IsItalic())?1:0;
	lf.lfUnderline	= (font->IsUnderline())?1:0;
	lf.lfCharSet	= font->GetCharSet();

	return ::CreateFontIndirectW(&lf);
}

void CSurf::SetDDraw(IDirectDraw7 *pddraw)
{
	if(!pddraw)return;
	s_pddraw=pddraw; //由于没有ReleaseDDraw之类的函数,所以不能增加引用计数!否则无法释放!
}

HBITMAP CSurf::LoadBmp(const CStr &path,POS *pw,POS *ph) //从rpgdiy抄的
{
	HBITMAP hBmp=null;
	if(!(hBmp=(HBITMAP)::LoadImageW(NULL,path.ReadW(),IMAGE_BITMAP,
		0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION)))return hBmp;
	BITMAP bm;
	::GetObject(hBmp,sizeof(bm),&bm);
	*pw=bm.bmWidth;
	*ph=bm.bmHeight;
	return hBmp;
}

inline void CSurf::TmpCreateSurface(POS w,POS h,Bool bSysMemOnly) //从rpgdiy抄的
{
	m_pdds=null;
	DDSURFACEDESC2 ddsd;
	ZeroMemory(&ddsd,sizeof(ddsd));
	ddsd.dwSize=sizeof(ddsd);
	ddsd.dwFlags=DDSD_WIDTH|DDSD_CAPS|DDSD_HEIGHT;
    ddsd.dwWidth=w;
    ddsd.dwHeight=h;
	if(!bSysMemOnly)
	{
		ddsd.ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN|DDSCAPS_VIDEOMEMORY;
		if(FAILED(s_pddraw->CreateSurface(&ddsd,&m_pdds,null)))
		{	//失败了,引用计数没有增加!
			ddsd.ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY;
			if(FAILED( s_pddraw->CreateSurface(&ddsd,&m_pdds,null) ))__asm int 3; //失败了,引用计数没有增加!
		}
	}
	else
	{
		ddsd.ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY;
		if(FAILED( s_pddraw->CreateSurface(&ddsd,&m_pdds,null) ))__asm int 3; //失败了,引用计数没有增加!
	}
	if(s_DefaultColorKeyEnabled)SetColorKey(s_DefaultColorKey);
}

CSurf::CSurf(IDirectDrawSurface7 *pdds)
{
	if(!s_pddraw)return;
	if(!(m_pdds=pdds))return;
	m_pdds->AddRef(); //注意这里要加引用计数!因为在析构函数会Release()
	if(s_DefaultColorKeyEnabled)SetColorKey(s_DefaultColorKey);
}

CSurf::CSurf(POS w,POS h,Bool bSysMemOnly)
{
	if(!s_pddraw)return;
	TmpCreateSurface(w,h,bSysMemOnly);
}

CSurf::CSurf(const CStr &path,POS w,POS h,Bool bSysMemOnly)
{
	if(!s_pddraw)return;
	POS *pw=new POS(0),*ph=new POS(0);
	HBITMAP hBmp=null;
	if(!(hBmp=LoadBmp(path,pw,ph)))return;
	POS tw=w?w:*pw;
	POS th=h?h:*ph;
	TmpCreateSurface(tw,th,bSysMemOnly);
	if(!m_pdds)return;
	HDC hdc,hDCImage;
	if(FAILED(m_pdds->GetDC(&hdc)))return;
	hDCImage=::CreateCompatibleDC(0);

	::SelectObject(hDCImage,hBmp);
	::BitBlt(hdc,0,0,(Int32)tw,(Int32)th,hDCImage,0,0,SRCCOPY);
	::DeleteDC(hDCImage);
	m_pdds->ReleaseDC(hdc);
}

CSurf::CSurf(const CStr &path,POS wsurf,POS hsurf,
			POS wbmp,POS hbmp,Bool bSysMemOnly)
{
	if(!s_pddraw)return;
	POS *pwbmp=new POS(0),*phbmp=new POS(0);
	HBITMAP hBmp=null;
	if(!(hBmp=LoadBmp(path,pwbmp,phbmp)))return;
	POS twbmp=wbmp?wbmp:*pwbmp;
	POS thbmp=hbmp?hbmp:*phbmp;
	TmpCreateSurface(wsurf,hsurf,bSysMemOnly);
	if(!m_pdds)return;
	HDC hdc,hDCImage;
	if(FAILED(m_pdds->GetDC(&hdc)))return;
	hDCImage=::CreateCompatibleDC(0);
	::SelectObject(hDCImage,hBmp);
	::StretchBlt(hdc,0,0,wsurf,hsurf,hDCImage,0,0,(Int32)twbmp,(Int32)thbmp,SRCCOPY);
	::DeleteDC(hDCImage);
	m_pdds->ReleaseDC(hdc);
}

CSurf::~CSurf()
{
	SafeRelease(m_pdds);
}

COLOR CSurf::GetColorKey()
{
	if(!m_pdds)return Rgb(0,0,0);

	DDCOLORKEY key;
	ZeroMemory(&key,sizeof(key));
	if(DD_OK!=(m_pdds->GetColorKey(DDCKEY_SRCBLT,&key)))return Rgb(0,0,0);
	if(key.dwColorSpaceLowValue==0)return Rgb(0,0,0);
	
	DDSURFACEDESC2 ddsd;
	ZeroMemory(&ddsd,sizeof(ddsd));
	ddsd.dwSize=sizeof(ddsd);
	UInt32 old;
	if(DD_OK!=(m_pdds->Lock(Null,&ddsd,DDLOCK_WAIT,Null)))return Rgb(0,0,0);
	old=*(UInt32*)ddsd.lpSurface;
	if(ddsd.ddpfPixelFormat.dwRGBBitCount=32)
	{
		*(UInt32*)ddsd.lpSurface = key.dwColorSpaceLowValue;
	}
	else
	{
		*(UInt32*)ddsd.lpSurface &= ~ ( ( 1 << ddsd.ddpfPixelFormat.dwRGBBitCount ) - 1 );
		*(UInt32*)ddsd.lpSurface |= ( key.dwColorSpaceLowValue ) & 1;
	//	*(UInt32*)ddsd.lpSurface |= ( 1 << ddsd.ddpfPixelFormat.dwRGBBitCount ) - 1 );
	//	*(UInt32*)ddsd.lpSurface &= ( key.dwColorSpaceLowValue ) & 1;
	}
	if(DD_OK!=(m_pdds->Unlock(Null)))return Rgb(0,0,0);

	HDC hdc;
	if(DD_OK!=(m_pdds->GetDC(&hdc)))return Rgb(0,0,0);
	COLOR ret=ToInstColor(::GetPixel(hdc,0,0));
	if(DD_OK!=(m_pdds->ReleaseDC(hdc)))return ret;

	if(DD_OK!=(m_pdds->Lock(Null,&ddsd,DDLOCK_WAIT,Null)))return ret;
	*(UInt32*)ddsd.lpSurface=old;
	m_pdds->Unlock(Null);
	return ret;
}

void CSurf::SetColorKey(COLOR key)
{
	if(!m_pdds)return;

	DDCOLORKEY tmp;
	ZeroMemory(&tmp,sizeof(tmp));
	tmp.dwColorSpaceHighValue=0;
	if(key==Rgb(0,0,0))
	{
		tmp.dwColorSpaceLowValue=0;
		m_pdds->SetColorKey(DDCKEY_SRCBLT,&tmp);
		return;
	}

	HDC hdc;
	if(DD_OK!=(m_pdds->GetDC(&hdc)))return;
	UInt32 old=::GetPixel(hdc,0,0);
	::SetPixel(hdc,0,0,ToGdiColor(key));
	if(DD_OK!=(m_pdds->ReleaseDC(hdc)))return;

	DDSURFACEDESC2 ddsd;
	ZeroMemory(&ddsd,sizeof(ddsd));
	ddsd.dwSize=sizeof(ddsd);
	if(DD_OK!=(m_pdds->Lock(Null,&ddsd,DDLOCK_WAIT,Null)))return;
	tmp.dwColorSpaceLowValue=*(UInt32*)ddsd.lpSurface;
	if(ddsd.ddpfPixelFormat.dwRGBBitCount<32)
		tmp.dwColorSpaceLowValue &= ( 1 << ddsd.ddpfPixelFormat.dwRGBBitCount ) - 1;
	if(DD_OK!=(m_pdds->Unlock(Null)))return;
	if(DD_OK!=(m_pdds->SetColorKey(DDCKEY_SRCBLT,&tmp)))return;
	
	if(DD_OK!=(m_pdds->GetDC(&hdc)))return;
	::SetPixel(hdc,0,0,old);
	m_pdds->ReleaseDC(hdc);
}

#define If if(
#define Then )
#define ExitSub return
#define Or ||
#define Left left
#define Top top
#define Right right
#define Bottom bottom
void CSurf::Blt(POS xdest,POS ydest,
		ISurf *surf,POS xsrc,POS ysrc,POS w,POS h,ALPHA alpha,Bool bHasColorKey)
{
	if(!surf)return;
	if(!m_pdds)return;

	if(surf->GetClass()!=this->GetClass())return; //不支持
	CSurf *pSurf = (CSurf*)surf->GetAddr();
	if(!(pSurf->m_pdds))return;

	if(m_pdds==pSurf->m_pdds)return;

	DDSURFACEDESC2 ddsd;
	ZeroMemory(&ddsd,sizeof(ddsd));
	ddsd.dwSize=sizeof(ddsd);
	m_pdds->GetSurfaceDesc(&ddsd);

	DDSURFACEDESC2 pSurf_ddsd;
	ZeroMemory(&pSurf_ddsd,sizeof(pSurf_ddsd));
	pSurf_ddsd.dwSize=sizeof(pSurf_ddsd);
	pSurf->m_pdds->GetSurfaceDesc(&pSurf_ddsd);

	RECT rc={xsrc,ysrc,xsrc+w,ysrc+h};
	POS xmax,ymax;
	xmax = ddsd.dwWidth;
	ymax = ddsd.dwHeight;
	
	If xdest > xmax Or ydest > ymax Then ExitSub;
	If xdest + rc.Right - rc.Left < 0 Or ydest + rc.Bottom - rc.Top < 0 Then ExitSub;
	If xdest < 0 Then {rc.Left = rc.Left - xdest; xdest = 0; }
	If xdest + rc.Right - rc.Left > xmax Then rc.Right = xmax - xdest + rc.Left;
	If ydest < 0 Then { rc.Top = rc.Top - ydest; ydest = 0; }
	If ydest + rc.Bottom - rc.Top > ymax Then rc.Bottom = ymax - ydest + rc.Top;
	
	If rc.Left < 0 Then { xdest = xdest - rc.Left; rc.Left = 0; }
	If rc.Top < 0 Then { ydest = ydest - rc.Top; rc.Top = 0; }
	If rc.Right > (Int32)pSurf_ddsd.dwWidth Then rc.Right = (Int32)pSurf_ddsd.dwWidth;
 	If rc.Bottom > (Int32)pSurf_ddsd.dwHeight Then rc.Bottom = (Int32)pSurf_ddsd.dwHeight;
	if(FAILED( m_pdds->BltFast( xdest, ydest, pSurf->m_pdds, &rc,
		(bHasColorKey?DDBLTFAST_SRCCOLORKEY:DDBLTFAST_NOCOLORKEY) | DDBLTFAST_WAIT ) ))__asm int 3;
}

void CSurf::BltRgn(POS xdest,POS ydest,POS rx,POS ry,POS rw,POS rh,
		ISurf *surf,POS xsrc,POS ysrc,POS w,POS h,ALPHA alpha,Bool bHasColorKey)
{
	if(!surf)return;
	if(!m_pdds)return;

	if(surf->GetClass()!=this->GetClass())return; //不支持
	CSurf *pSurf = (CSurf*)surf->GetAddr();
	if(!(pSurf->m_pdds))return;

	if(m_pdds==pSurf->m_pdds)return;

	DDSURFACEDESC2 ddsd;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -