📄 surface.cpp
字号:
// Surface.cpp: implementation of the CSurface class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Surface.h"
#include "EasyDraw.h"
#include "log.h"
#include <stdio.h>
#define ENABLE_TRACE
//#define SafeRelease(x) (if(x!=0) x->Release(); x=0)
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
Surface::Surface()
{
Init();
}
Surface::Surface( Surface &surf )
{
if(this!=&surf)
{
FreeSurface();
this->m_ColorKeyType=surf.m_ColorKeyType;
this->m_iHeight=surf.m_iHeight;
this->m_iWidth=surf.m_iWidth;
this->m_lpDDSurface=surf.m_lpDDSurface;
this->m_lpDDSurfaceCopy=surf.m_lpDDSurfaceCopy;
}
}
Surface::~Surface()
{
}
void Surface::Init()
{
m_ColorKeyType = DDBLTFAST_NOCOLORKEY;
m_lpDDSurface = NULL;
m_lpDDSurfaceCopy = NULL;
m_iWidth = 0;
m_iHeight = 0;
}
void Surface::FreeSurface()
{
if(m_lpDDSurface)
{
SafeRelease(m_lpDDSurface);
}
if(m_lpDDSurfaceCopy )
{
SafeRelease(m_lpDDSurfaceCopy);
}
m_ColorKeyType = DDBLTFAST_NOCOLORKEY;
m_iWidth = 0;
m_iHeight = 0;
}
bool Surface::GetWH( int *pWidth, int *pHeight )
{
DDSURFACEDESC2 ddsd;
ddsd.dwSize = sizeof( DDSURFACEDESC2 );
if ( m_lpDDSurface != NULL )
{
if ( m_lpDDSurface->GetSurfaceDesc( &ddsd ) != DD_OK )
return false;
}
else
return false;
if ( pWidth != NULL )
*pWidth = ddsd.dwWidth;
if ( pHeight != NULL )
*pHeight= ddsd.dwHeight;
return true;
}
//创建一个空页面
bool Surface::CreateNullSurface( int iw, int ih, bool isSysMemory, bool isColorKey, DWORD ColorKey )
{
FreeSurface();
HRESULT hr = CreateSurfaceHelp( GetEasyDrawPointer()->GetLPDD(),
&m_lpDDSurface, iw, ih,
isSysMemory, isColorKey, ColorKey );
if ( hr == DDERR_OUTOFVIDEOMEMORY )
{
isSysMemory = true;
}
return OnCreateSurface( isSysMemory, isColorKey );
}
bool Surface::CreateImageSurface( char *szFileName, bool isSysMemory, bool isColorKey, DWORD ColorKey )
{
if ( szFileName != NULL )
{
int len = strlen(szFileName);
char szNameEx[3];
strcpy( szNameEx, &szFileName[len-3] );
if ( strcmp( szNameEx, "BMP" ) == 0 || strcmp( szNameEx, "bmp" ) == 0 )
{
return CreateBmpSurface( szFileName, isSysMemory, isColorKey, ColorKey );
}
else
return false;
}
return false;
}
bool Surface::CreateBmpSurface( char *szFileName, bool isSysMemory, bool isColorKey, DWORD ColorKey )
{
FreeSurface();
LPDIRECTDRAW7 lpdd = GetEasyDrawPointer()->GetLPDD();
HRESULT hr = CreateSurfaceOfBmp( lpdd, &m_lpDDSurface, szFileName, isSysMemory, isColorKey, ColorKey );
if ( hr == DDERR_OUTOFVIDEOMEMORY )
isSysMemory = true;
return OnCreateSurface( isSysMemory, isColorKey );
}
bool Surface::OnCreateSurface( bool isSysMemory, bool isColorKey )
{
if ( m_lpDDSurface == NULL )
return false;
GetWH( &m_iWidth, &m_iHeight );
if ( isColorKey )
{
m_ColorKeyType = DDBLTFAST_SRCCOLORKEY;
}
if ( !isSysMemory )
return CreateCopySurface();
else
return true;
}
bool Surface::CreateCopySurface()
{
if ( m_lpDDSurface == NULL )
return false;
SafeRelease(m_lpDDSurfaceCopy);
CreateSurfaceHelp( GetEasyDrawPointer()->GetLPDD(), &m_lpDDSurfaceCopy, m_iWidth, m_iHeight, true, false, 0 );
if ( m_lpDDSurfaceCopy == NULL )
return false;
m_lpDDSurfaceCopy->BltFast( 0, 0, m_lpDDSurface, NULL, DDBLTFAST_NOCOLORKEY );
return true;
}
//绘制页面到后台缓冲区
void Surface::DrawSurface( int x, int y, RECT *pRect )
{
LPDIRECTDRAWSURFACE7 lpDDBack = GetEasyDrawPointer()->GetBackSurface();
if ( m_lpDDSurface != NULL )
{
lpDDBack->BltFast( x, y, m_lpDDSurface, pRect, m_ColorKeyType );
}
}
void Surface::DrawNight( int x, int y, RECT *pRect )
{
LPDIRECTDRAWSURFACE7 lpDDBack = GetEasyDrawPointer()->GetBackSurface();
if ( m_lpDDSurfaceCopy != NULL )
{
lpDDBack->BltFast( x, y, m_lpDDSurfaceCopy, pRect, m_ColorKeyType );
}
}
//剪裁绘制页面到后台缓冲区
void Surface::DrawAutoClip( int x, int y )
{
int iSW = GetEasyDrawPointer()->GetDeviceWidth();
int iSH = GetEasyDrawPointer()->GetDeviceHeight();
RECT rc;
rc.left = 0;
rc.top = 0;
rc.right= m_iWidth;
rc.bottom=m_iHeight;
if ( x + m_iWidth > iSW )
{
rc.right -= x + m_iWidth - iSW;
}
else if ( x < 0 )
{
rc.left -= x;
x = 0;
}
if ( y + m_iHeight > iSH )
{
rc.bottom -= y + m_iHeight - iSH;
}
else if ( y < 0 )
{
rc.top -= y;
y = 0;
}
LPDIRECTDRAWSURFACE7 lpDDBack = GetEasyDrawPointer()->GetBackSurface();
lpDDBack->BltFast( x, y, m_lpDDSurface, &rc, m_ColorKeyType );
}
//页面恢复
bool Surface::Restore()
{
if ( m_lpDDSurface == NULL )
return false;
HRESULT hr;
hr = m_lpDDSurface->IsLost();
if ( hr != DD_OK )
{
hr = m_lpDDSurface->Restore();
if ( hr != DD_OK )
return false;
}
if ( m_lpDDSurfaceCopy != NULL )
m_lpDDSurface->BltFast( 0, 0, m_lpDDSurfaceCopy, NULL, DDBLTFAST_NOCOLORKEY );
return true;
}
//从一个页面画到其他的页面
void Surface::BltTo( int destX, int destY, Surface *pDestSurf, RECT *rcSrc )
{
//目的页面不空且原页面不空
if ( pDestSurf->m_lpDDSurface != NULL && m_lpDDSurface != NULL )
{
pDestSurf->m_lpDDSurface->BltFast( destX, destY, m_lpDDSurface, rcSrc, m_ColorKeyType );
//拷贝页面绘制
if ( pDestSurf->m_lpDDSurfaceCopy != NULL )
pDestSurf->m_lpDDSurfaceCopy->BltFast( destX, destY, m_lpDDSurface, rcSrc, m_ColorKeyType );
}
}
//向页面上写字
void Surface::WriteText( const char *szText, int TextLen, int x, int y, DWORD Color )
{
if ( m_lpDDSurfaceCopy != NULL )
{
// DrawTextOnSurface( m_lpDDSurfaceCopy, szText, TextLen, x, y, Color );
Restore();
}
else if ( m_lpDDSurface != NULL )
{
// DrawTextOnSurface( m_lpDDSurface, szText, TextLen, x, y, Color );
}
}
void Surface::SetSurfaceColorKey( DWORD ColorKey )
{
if ( !m_lpDDSurface == NULL )
{
ColorKey = GetEasyDrawPointer()->ChangeColorKey( ColorKey );
SetColorKeyHelp( m_lpDDSurface, ColorKey );
m_ColorKeyType = DDBLTFAST_SRCCOLORKEY;
}
}
bool Surface::CopySurface( Surface * psurf )
{
if ( m_lpDDSurface == NULL )
return false;
SafeRelease(m_lpDDSurfaceCopy);
CreateSurfaceHelp( GetEasyDrawPointer()->GetLPDD(), &m_lpDDSurfaceCopy, m_iWidth, m_iHeight, true, false, 0 );
if ( m_lpDDSurfaceCopy == NULL )
return false;
m_lpDDSurfaceCopy->BltFast( 0, 0, m_lpDDSurface, NULL, DDBLTFAST_NOCOLORKEY );
return true;
}
bool Surface::CopySurfaceToBmp( char *szBmpName, RECT *pRect )
{
if ( m_lpDDSurface != NULL )
{
return CopySurfaceToBmp16( m_lpDDSurface, szBmpName, pRect, true );
}
else
return false;
}
void Surface::DrawAlphaMMX( int x, int y )
{
if ( m_lpDDSurface == NULL )
return;
RECT rc_src; //temp页面上要锁定的矩形区域
RECT rc; //temp页面上要blt的区域
RECT rc_dest; //目标页面上的矩形区域
rc_src.left = 0;
rc_src.top = 0;
rc_src.right= m_iWidth;
rc_src.bottom=m_iHeight;
rc = rc_src;
int iSW = GetEasyDrawPointer()->GetDeviceWidth();
int iSH = GetEasyDrawPointer()->GetDeviceHeight();
if ( x + m_iWidth > iSW )
rc.right -= x + m_iWidth - iSW;
if ( x < 0 )
{
rc.left -= x;
x = 0;
}
if ( y + m_iHeight > iSH )
rc.bottom -= y + m_iHeight - iSH;
if ( y < 0 )
{
rc.top -= y;
y = 0;
}
rc_dest.left = x;
rc_dest.top = y;
rc_dest.right= x + rc.right - rc.left;
rc_dest.bottom=y + rc.bottom- rc.top;
LPDIRECTDRAWSURFACE7 back, temp;
back = GetEasyDrawPointer()->GetBackSurface();
temp = GetEasyDrawPointer()->GetTempSurface();
//test
// char str[128];
// sprintf(str,"%d,%d,%d,%d",rc_dest.left,rc_dest.top,rc_dest.right,rc_dest.bottom);
// CODE_TRACE("surface.cpp",str);
//test end
//把后台页面的矩形拷贝到特效页面上
temp->BltFast( rc.left, rc.top, back, &rc_dest, DDBLTFAST_NOCOLORKEY );
//锁定特效页面
DDSURFACEDESC2 ddsd;
ddsd.dwSize = sizeof(ddsd);
if ( temp->Lock( &rc_src, &ddsd, DDLOCK_SURFACEMEMORYPTR, NULL ) != DD_OK ) return;
WORD *buf_temp = (WORD *)ddsd.lpSurface;
int pitch_temp = ddsd.lPitch;
//锁定内存页面
ddsd.dwSize = sizeof(ddsd);
if ( m_lpDDSurface->Lock( NULL, &ddsd, DDLOCK_READONLY, NULL ) != DD_OK )
{
temp->Unlock(0);
return;
}
WORD *buf_surf = (WORD *)ddsd.lpSurface;
ddsd.dwWidth *= 2;
int pitch_surf = ddsd.lPitch - ddsd.dwWidth;
pitch_temp -= ddsd.dwWidth;
__int64 _0x7befx4 = 0x7bef7bef7bef7bef;
__asm
{
mov edx, buf_temp; //edx 目标页面指针
mov ecx, buf_surf; //ecx 源页面指针
xor ebx, ebx;
_for_h_begin:
cmp ebx, ddsd.dwHeight;
jnb _for_h_end;
xor eax, eax;
_for_w_begin:
cmp eax, ddsd.dwWidth;
jnb _for_w_end;
movq mm0, [edx];
movq mm1, [ecx];
psrlw mm0, 1;
psrlw mm1, 1;
pand mm0, _0x7befx4;
pand mm1, _0x7befx4;
paddusw mm0, mm1; //注意要用paddusw无符号饱和压缩加法
movq [edx], mm0;
add edx, 8;
add ecx, 8;
add eax, 8;
jmp _for_w_begin;
_for_w_end:
inc ebx;
add edx, pitch_temp;
add ecx, pitch_surf;
jmp _for_h_begin;
_for_h_end:
emms;
}
m_lpDDSurface->Unlock(0);
temp->Unlock(0);
back->BltFast( x, y, temp, &rc, DDBLTFAST_NOCOLORKEY );
}
//////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////
void Surface::DrawAlphaShadow( int x, int y )
{
if ( m_lpDDSurface == NULL )
return;
RECT rc_src; //temp页面上要锁定的矩形区域
RECT rc; //temp页面上要blt的区域
RECT rc_dest; //目标页面上的矩形区域
rc_src.left = 0;
rc_src.top = 0;
rc_src.right= m_iWidth;
rc_src.bottom=m_iHeight;
rc = rc_src;
int iSW = GetEasyDrawPointer()->GetDeviceWidth();
int iSH = GetEasyDrawPointer()->GetDeviceHeight();
if ( x + m_iWidth > iSW )
rc.right -= x + m_iWidth - iSW;
if ( x < 0 )
{
rc.left -= x;
x = 0;
}
if ( y + m_iHeight > iSH )
rc.bottom -= y + m_iHeight - iSH;
if ( y < 0 )
{
rc.top -= y;
y = 0;
}
rc_dest.left = x;
rc_dest.top = y+m_iHeight/2;
rc_dest.right= x + 2*m_iWidth;
rc_dest.bottom=y + m_iHeight;
if ( rc_dest.right > iSW )
rc_dest.right -= (rc_dest.right - iSW);
if ( rc_dest.left < 0 )
{
rc_dest.left=0;
}
if ( rc_dest.bottom > iSH )
rc.bottom -= (rc_dest.bottom - iSH);
if ( rc_dest.top < 0 )
{
rc_dest.top=0;
}
LPDIRECTDRAWSURFACE7 back, temp;
back = GetEasyDrawPointer()->GetBackSurface();
temp = GetEasyDrawPointer()->GetTempSurface();
//把后台页面的矩形拷贝到特效页面上
temp->BltFast( rc.left, rc.top, back, &rc_dest, DDBLTFAST_NOCOLORKEY );
// DDBLTFX ddBltFx;
// ddBltFx.dwSize=sizeof(DDBLTFX);
// ddBltFx.dwFillPixel=0;
// ddBltFx.dwFillColor =0xffff;
// temp->Blt(NULL,NULL,NULL,DDBLT_WAIT|DDBLT_COLORFILL,&ddBltFx);
// DDCOLORKEY ddck;
// ddck.dwColorSpaceLowValue = 0xffff;
// ddck.dwColorSpaceHighValue = 0xffff;
// temp->SetColorKey( DDCKEY_SRCBLT, &ddck );
// m_lpDDSurfaceCopy->Blt(NULL,NULL,NULL,DDBLT_WAIT|DDBLT_COLORFILL,&ddBltFx);
// char str[32];
// sprintf(str,"%d %d %d %d",rc_dest.left,rc_dest.top,rc_dest.right,rc_dest.bottom);
// log::instance().dump("surface.cpp",str);
//锁定特效页面
DDSURFACEDESC2 ddsdtemp;
WORD *buf_temp;
int pitch_temp;
rc_src.left=0;
rc_src.right=rc_dest.right-rc_dest.left;
rc_src.top=0;
rc_src.bottom=rc_dest.bottom-rc_dest.top;
ddsdtemp.dwSize = sizeof(ddsdtemp);
if ( temp->Lock( &rc_src, &ddsdtemp, DDLOCK_SURFACEMEMORYPTR, NULL ) != DD_OK )
return;
buf_temp = (WORD *)ddsdtemp.lpSurface;
pitch_temp = ddsdtemp.lPitch;
ddsdtemp.lPitch=ddsdtemp.lPitch >> 1;
//锁定内存页面
DDSURFACEDESC2 ddsdsurf;
WORD *buf_surf;
ddsdsurf.dwSize = sizeof(ddsdsurf);
if ( m_lpDDSurface->Lock( NULL, &ddsdsurf, DDLOCK_READONLY, NULL ) != DD_OK )
{
temp->Unlock(0);
return;
}
ddsdsurf.lPitch=ddsdsurf.lPitch >> 1;
buf_surf = (WORD *)ddsdsurf.lpSurface;
WORD *buf = buf_temp;
__int64 _0x7befx4 = 0x7bef7bef7bef7bef;
WORD *data = buf_surf;
int Width=rc_dest.right-rc_dest.left;
WORD mask=0x7bef;
for(int i=m_iHeight/2;i>0;i--)
{
data =buf_surf;
buf = buf_temp;
int bujin=(2*i*m_iWidth)/m_iHeight;
buf+=bujin;
int kuandu=Width-bujin;
if(kuandu>m_iWidth)
{
kuandu=m_iWidth;
}
for(int x=0;x<kuandu;x++)
{
if((*data)!=0x0000)
// {
_asm
{
mov eax,buf;
mov bx,7befh;
mov cx,[eax]
shr cx,1;
and cx,bx;
mov [eax],cx;
}
// }
data++;
buf++;
}
buf_temp+=ddsdtemp.lPitch;
buf_surf+=ddsdsurf.lPitch;
buf_surf+=ddsdsurf.lPitch;
}
m_lpDDSurface->Unlock(0);
temp->Unlock(0);
back->BltFast( x, y+m_iHeight/2, temp, &rc_src, DDBLTFAST_NOCOLORKEY );
}
inline void BrightnessAndContrast1(int& red,int& green,int& blue,
int contrast,int brightness)
{
static int old_c = 0,old_b = 0;
static int extra_c = 0;
static float ratio = 0;
if( contrast!=old_c )
{
ratio = (float)contrast/100;
extra_c = -127*ratio;
old_c = contrast;
}
if( brightness!=old_b)
{
extra_c += brightness;
old_b = brightness;
}
red -= red*ratio + extra_c;
green -= green*ratio + extra_c;
blue -= blue*ratio + extra_c;
if(red>255) red=255;
if(green>255) green=255;
if(blue>255) blue=255;
if(red<0) red=0;
if(green<0) green=0;
if(blue<0) blue=0;
}
#define _MY16RGB565(r,g,b) ((b>>3) + ( (g>>2)<< 5 ) + ( (r>>3)<<11 ))
void Surface::CreateNight()
{
//锁定特效页面
DDSURFACEDESC2 ddsd;
//锁定内存页面
ddsd.dwSize = sizeof(ddsd);
if (this->m_lpDDSurfaceCopy->Lock( NULL, &ddsd, DDLOCK_READONLY, NULL ) != DD_OK )
{
this->m_lpDDSurfaceCopy->Unlock(0);
return;
}
WORD *buf_surf = (WORD *)ddsd.lpSurface;
ddsd.dwWidth *= 2;
int pitch_surf = ddsd.lPitch - ddsd.dwWidth;
int size=ddsd.lPitch>>1;
WORD *buffer=(USHORT *)ddsd.lpSurface;
for(int x=0;x<960;x++)
{
for(int y=0;y<640;y++)
{
int value = buffer[y*size+x];
int red = (value & 0x0000f800)>>8,
green= (value & 0x000007e0)>>3,
blue = (value & 0x0000001f)<<3;
BrightnessAndContrast1(red,green,blue,55,85);
buffer[y*size+x] = _MY16RGB565(red,green,blue);
}
}
this->m_lpDDSurfaceCopy->Unlock(0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -