📄 directmanage.cpp
字号:
{
HRESULT ddrval;
m_ddsd.dwSize = sizeof(m_ddsd);
while( 1 )
{
ddrval = lpSur->Lock( NULL, &m_ddsd, DDLOCK_WAIT, NULL ); //锁定
if( ddrval == DD_OK )
{
break;
}
if( ddrval == DDERR_SURFACELOST )
{
ddrval = restoreAll();
if( ddrval != DD_OK ) return( false );
}
}
m_GraphBuffer = (WORD *)m_ddsd.lpSurface; //内存指针
m_GraphWidth = m_ddsd.dwWidth; //宽度
m_GraphHeight = m_ddsd.dwHeight; //高度
m_GraphPitch = m_ddsd.lPitch >> 1; //lPitch以Byte为单位计数的,
//GraphPitch以WORD为单位。所以GraphPitch = lPitch / 2;
return TRUE ;
}
//******************
//关闭缓冲区
BOOL CDirectManage::EndDraw(LPDIRECTDRAWSURFACE lpSur)
{
HRESULT ddrval;
ddrval = lpSur->Unlock( NULL ); //解锁
if( ddrval != DD_OK ) return( FALSE );
return TRUE;
}
//--------------------------------------------------------------//
//////////////////////////////////////////////////////////////////
//--------------------------------------------------------------//
//功能:以单色填充页面
//参数:目标表面,颜色
void CDirectManage::FillSurface(LPDIRECTDRAWSURFACE surf, DWORD color)
{
WORD color16=RGB16(color); //转化成16色
if( BeginDraw(surf) )
{
for( int i=0; i<m_GraphHeight; i++)
for(int j=0; j<m_GraphWidth; j++)
m_GraphBuffer[i*m_GraphPitch+j] = color16; //直接填充
EndDraw(surf);
}
}
//以单色填充页面
void CDirectManage::FillSurface(LPDIRECTDRAWSURFACE surf, WORD color)
{
if( BeginDraw(surf) )
{
for( int i=0; i<m_GraphHeight; i++)
for(int j=0; j<m_GraphWidth; j++)
m_GraphBuffer[i*m_GraphPitch+j] = color; //直接填充
EndDraw(surf);
}
}
//16位RGB换算
WORD CDirectManage::RGB16(WORD r, WORD g, WORD b)
{
//简单
if( m_bIs555 )
//rrrrr|ggggg|bbbbb 0xf8 = 11111000b
return ((r&0xf8)<<7) | ((g&0xf8)<<2) | ((b&0xf8)>>3);
else
//rrrrr|gggggg|bbbbb 0xfc = 11111100
return ((r&0xf8)<<8) | ((g&0xfc)<<3) | ((b&0xf8)>>3);
}
//24位转16位
WORD CDirectManage::RGB16(DWORD color)
{
WORD r,g,b;
//也比较简单
r=(WORD)(color>>16);
g=(WORD)(color>>8);
b=(WORD)color;
if( m_bIs555 )
return ((r&0xf8)<<7) | ((g&0xf8)<<2) | ((b&0xf8)>>3);
else
return ((r&0xf8)<<8) | ((g&0xfc)<<3) | ((b&0xf8)>>3);
}
//淡出(time=每一帧的时间)
void CDirectManage::ColorOut(LPDIRECTDRAWSURFACE dest, int time)
{
unsigned int alpha=2, oldtick, newtick;
WORD *lpSour, *lpDest, *lpBack;
if( theApp.m_iWindowMode != 0 ) //窗口
{
Blt(m_lpDDSSour, 0,0, m_lpDDSPrimary, theApp.m_rectWindow, false);
}
else
{
Blt(m_lpDDSSour, 0,0, m_lpDDSPrimary, theApp.m_RectScreen, false);
}
if( BeginDraw(m_lpDDSSour) )
{
lpSour=m_GraphBuffer;
EndDraw(m_lpDDSSour);
}
if( BeginDraw(dest) )
{
lpDest=m_GraphBuffer;
EndDraw(dest);
}
if( BeginDraw(m_lpDDSTemp) )
{
lpBack=m_GraphBuffer;
EndDraw(m_lpDDSTemp);
}
oldtick=timeGetTime();
for(int i=0; i<16; i++)
{
for(int j=0; j<theApp.m_iScreenWidth*theApp.m_iScreenHeight; j++)
{
//看看上面的函数对比一下
//这个是从屏幕逐渐变化到dest页面
lpBack[j]=Alpha_Pixel(lpDest[j], lpSour[j], alpha);
}
//延时
newtick=timeGetTime();
while( newtick-oldtick < (unsigned int)(time*i) )
{
newtick=timeGetTime();
}
//更新屏幕
_UpdateScreen(m_lpDDSTemp,theApp.m_RectScreen);
//自动跳桢
i=(newtick-oldtick)/time;
alpha=i*2+2;
if( i >= 15 ) //结束
{
alpha=31;
for(int j=0; j<theApp.m_iScreenWidth*theApp.m_iScreenHeight; j++)
{
lpBack[j]=Alpha_Pixel(lpDest[j], lpSour[j], alpha);
}
_UpdateScreen(m_lpDDSTemp,theApp.m_RectScreen);
break;
}
}
}
//*************************
//延时
void CDirectManage::Delay(long time)
{
static long old_clock, new_clock; //延时变量
new_clock=old_clock=timeGetTime();
MSG msg;
while( new_clock < old_clock + time )
{
if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
if (!GetMessage(&msg, NULL, 0, 0)) return;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else if(theApp.m_bIsActive)
{
new_clock=timeGetTime();
if( GetAsyncKeyState(VK_F4) ) //F4结束
{
return;
}
}
else WaitMessage(); //等待消息
}
}
//功能:更新到屏幕
//参数:目标表面,更新范围
void CDirectManage::_UpdateScreen(LPDIRECTDRAWSURFACE lpSurf, RECT DestRect)
{
if( theApp.m_iWindowMode==0 ) //全屏
{
Blt(m_lpDDSPrimary, 0, 0, lpSurf, DestRect, false);
}
else //窗口
{
m_lpDDSPrimary->Blt( &theApp.m_rectWindow, lpSurf, &DestRect, DDBLTFAST_NOCOLORKEY, 0);
}
}
//更新到屏幕或表面lpSurf
void CDirectManage::UpdateScreen(LPDIRECTDRAWSURFACE lpSurf, RECT DestRect)
{
}
//淡入(time=每一帧的时间)
void CDirectManage::ColorIn(int time, WORD Color)
{
unsigned int alpha=2, oldtick, newtick;
WORD *lpSurf, *lpTemp, BlackColor=Color;
//建立临时页面
LPDIRECTDRAWSURFACE Temp;
CreateBitmap(Temp, theApp.m_iScreenWidth, theApp.m_iScreenHeight);
//保存到临时页面
if( theApp.m_iWindowMode==0 ) //全屏
Blt(Temp, 0, 0, m_lpDDSPrimary, theApp.m_RectScreen, false);
else
Blt(Temp, 0, 0, m_lpDDSPrimary, theApp.m_rectWindow, false);
if( BeginDraw(m_lpDDSBack) )
{
lpSurf=m_GraphBuffer;
EndDraw(m_lpDDSBack);
}
if( BeginDraw(Temp) )
{
lpTemp=m_GraphBuffer;
EndDraw(Temp);
}
oldtick=timeGetTime(); //起始时间
for(int i=0; i<16; i++)
{
//把主表面的点和传近来的点进行alpha混合到lpDDSBack
for(int j=0; j<theApp.m_iScreenWidth*theApp.m_iScreenHeight; j++)
{
lpSurf[j]=Alpha_Pixel(BlackColor, lpTemp[j], alpha);
}
//延时
newtick=timeGetTime();
while( newtick-oldtick < (unsigned int)(time * i) )
{
newtick=timeGetTime();
}
//更新屏幕
_UpdateScreen(m_lpDDSBack,theApp.m_RectScreen);
//自动跳桢
i=(newtick-oldtick)/time;
//alpha增加
alpha=i*2+2;
if( i >= 15 ) //结束
{
alpha=31;
for(int j=0; j<theApp.m_iScreenWidth*theApp.m_iScreenHeight; j++)
{
lpSurf[j]=Alpha_Pixel(BlackColor, lpTemp[j], alpha);
}
_UpdateScreen(m_lpDDSBack,theApp.m_RectScreen);
break;
}
}
//释放
_RELEASE( Temp );
}
//****************************
//功能:两个点的ALPHA混合(0-31)
//参数:源点,目标点,ALPHA级别
//返回:混合后的点
WORD CDirectManage::Alpha_Pixel(WORD sour, WORD dest, int alpha)
{
//C++版 :看下面的汇编版的注释
m_rgbTemp = ((((sour<<16)|sour) & m_rgbMask ) * alpha +
(((dest<<16)|dest) & m_rgbMask ) * (32-alpha) ) >> 5;
m_rgbTemp = m_rgbTemp & m_rgbMask;
return (WORD)((m_rgbTemp>>16)|m_rgbTemp);
/*
//汇编版
int ialpha=32-alpha;
_asm{
movzx eax, sour //零扩展成32位
mov bx, ax //把sour放到bx中
sal eax, 16 //算术左移16位,低位填0
mov ax, bx //把sour放到ax中,现在的eax中放的是两个sour
and eax, rgbMask //与上rgbMask
mul alpha //乘上alpha值
mov esi, eax //保存到esi
movzx eax, dest //同样的方法
mov bx, ax
sal eax, 16
mov ax, bx
and eax, rgbMask
mul ialpha
add eax, esi //加上刚刚的值
shr eax, 5 //逻辑右移5位,高位填0
//rgbTemp = rgbTemp & rgbMask;
and eax, rgbMask //与上rgbMask
mov esi, eax //放到esi中
shr eax, 16 //逻辑右移动16位,高位填0
or eax, esi //或上esi
mov rgbTemp, eax //返回
}
return (WORD)rgbTemp;
*/
/*--------------------------------------------------------
多说点点,看看rgbMask的形式是什么:比如是655格式
00000|gggggg|00000|rrrrr|000000|bbbbb
5个0 六位的 5个0 |五位 |6个0 |五位
绿掩码 |红掩码 |蓝掩码
好了,看看是个什么结果
要是将他与一个数与的话,也只是保留grb位的数
如果把这个数右移动16位,再与原数或,再去掉高位的话
结果是什么呢?16位的rgb的值
明白了就好办多了。:)
那又是怎么做到alpha混合的呢?
主要是在那个乘法上面,注意先乘了一个alpha,然后有个右移5位
也就是除以32了。所以各个颜色成分的值算出来了也不会有越位,
各个颜色还是对齐了的。
然后就是上面说的那个了,还原成16位的颜色值
----------------------------------------------------------*/
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -