📄 instsurfwithddraw.cpp
字号:
//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 + -