📄 directdraw.cpp
字号:
void CDirectDraw::GetDisplayMode( DWORD& dwWidth, DWORD& dwHeight, DWORD& dwDepth, DWORD& dwRate )
{
dwWidth = m_dwDisplayWidth;
dwHeight = m_dwDisplayHeight;
dwDepth = m_dwDisplayDepth;
dwRate = m_dwDisplayRate;
}
BOOL CDirectDraw::GetDisplayMode( INT no, DWORD& dwWidth, DWORD& dwHeight, DWORD& dwDepth, DWORD& dwRate )
{
if( m_DisplayModes.size() < no )
return FALSE;
dwWidth = m_DisplayModes[no].dwWidth;
dwHeight = m_DisplayModes[no].dwHeight;
dwDepth = m_DisplayModes[no].dwDepth;
dwRate = m_DisplayModes[no].dwRate;
return TRUE;
}
INT CDirectDraw::GetMatchDisplayMode( DWORD dwWidth, DWORD dwHeight, DWORD dwDepth, DWORD dwRate )
{
for( int i = 0; i < m_DisplayModes.size(); i++ ) {
if( m_DisplayModes[i].dwWidth == dwWidth
|| m_DisplayModes[i].dwHeight == dwHeight
|| m_DisplayModes[i].dwDepth == dwDepth
|| m_DisplayModes[i].dwRate == dwRate )
return i;
}
return -1;
}
BOOL CDirectDraw::IsNowDisplayMode( DWORD dwWidth, DWORD dwHeight, DWORD dwDepth, DWORD dwRate )
{
if( m_dwDisplayWidth == dwWidth && m_dwDisplayHeight == dwHeight
&& m_dwDisplayDepth == dwDepth && m_dwDisplayRate == dwRate )
return TRUE;
return FALSE;
}
// 價僢僩埵抲偺庢摼
void CDirectDraw::GetBitMask( DWORD val, int& shift, int& bits )
{
shift = 0;
while( !(val & (1<<shift)) && (shift<32) ) {
shift++;
}
bits = 32;
while( !(val & (1<<(bits-1))) && (bits>0) ) {
bits--;
}
bits = bits - shift;
}
static float PalConvTbl[][3] = {
1.00f, 1.00f, 1.00f,
1.00f, 0.80f, 0.73f,
0.73f, 1.00f, 0.70f,
0.76f, 0.78f, 0.58f,
0.86f, 0.80f, 1.00f,
0.83f, 0.68f, 0.85f,
0.67f, 0.77f, 0.83f,
0.68f, 0.68f, 0.68f,
// 1.00f, 1.00f, 1.00f,
};
// 僷儗僢僩僥乕僽儖偺寁嶼
BOOL CDirectDraw::CalcPaletteTable()
{
INT i, j;
if( !m_lpDD || !m_lpDDPrimary )
return FALSE;
DDSURFACEDESC2 ddsd;
ZEROMEMORY( &ddsd, sizeof(DDSURFACEDESC2) );
ddsd.dwSize = sizeof(DDSURFACEDESC2);
ddsd.dwFlags = DDSD_PIXELFORMAT;
if( m_lpDDPrimary->GetSurfaceDesc(&ddsd) != DD_OK )
throw "CDirectDraw:GetSurfaceDesc error";
INT Rbit, Gbit, Bbit;
INT Rsft, Gsft, Bsft;
if( ddsd.ddpfPixelFormat.dwRGBBitCount != 8 ) {
GetBitMask( ddsd.ddpfPixelFormat.dwRBitMask, Rsft, Rbit );
GetBitMask( ddsd.ddpfPixelFormat.dwGBitMask, Gsft, Gbit );
GetBitMask( ddsd.ddpfPixelFormat.dwBBitMask, Bsft, Bbit );
}
for( j = 0; j < 8; j++ ) {
for( i = 0; i < 64; i++ ) {
DWORD Rn, Gn, Bn;
DWORD Rs, Gs, Bs;
// Normal
Rn = (DWORD)(PalConvTbl[j][0]*m_PaletteBuf[i].r);
Gn = (DWORD)(PalConvTbl[j][1]*m_PaletteBuf[i].g);
Bn = (DWORD)(PalConvTbl[j][2]*m_PaletteBuf[i].b);
// Scanline
Rs = (DWORD)(PalConvTbl[j][0]*m_PaletteBuf[i].r*m_nScanlineColor/100.0f);
Gs = (DWORD)(PalConvTbl[j][1]*m_PaletteBuf[i].g*m_nScanlineColor/100.0f);
Bs = (DWORD)(PalConvTbl[j][2]*m_PaletteBuf[i].b*m_nScanlineColor/100.0f);
m_cpPalette[j][i+0x00].rgbRed = (BYTE)Rn;
m_cpPalette[j][i+0x00].rgbGreen = (BYTE)Gn;
m_cpPalette[j][i+0x00].rgbBlue = (BYTE)Bn;
m_cpPalette[j][i+0x40].rgbRed = (BYTE)Rs;
m_cpPalette[j][i+0x40].rgbGreen = (BYTE)Gs;
m_cpPalette[j][i+0x40].rgbBlue = (BYTE)Bs;
m_cnPalette[j][i] = ((Rn>>(8-Rbit))<<Rsft)|((Gn>>(8-Gbit))<<Gsft)|((Bn>>(8-Bbit))<<Bsft);
m_csPalette[j][i] = ((Rs>>(8-Rbit))<<Rsft)|((Gs>>(8-Gbit))<<Gsft)|((Bs>>(8-Bbit))<<Bsft);
// RGB555
if( Rsft > Bsft ) {
// RGB555->RGB888偺帪
m_cfPalette[j][i] = ((Rn>>(8-5))<<10)|((Gn>>(8-5))<<5)|((Bn>>(8-5))<<0);
} else {
// BGR555->BGR888偺帪
m_cfPalette[j][i] = ((Rn>>(8-5))<<0)|((Gn>>(8-5))<<5)|((Bn>>(8-5))<<10);
}
// Monochrome
Rn = (DWORD)(m_PaletteBuf[i&0x30].r);
Gn = (DWORD)(m_PaletteBuf[i&0x30].g);
Bn = (DWORD)(m_PaletteBuf[i&0x30].b);
Rn =
Gn =
Bn = (DWORD)(0.299f * Rn + 0.587f * Gn + 0.114f * Bn);
Rn = (DWORD)(PalConvTbl[j][0]*Rn);
Gn = (DWORD)(PalConvTbl[j][1]*Gn);
Bn = (DWORD)(PalConvTbl[j][2]*Bn);
if( Rn > 0xFF ) Rs = 0xFF;
if( Gn > 0xFF ) Gs = 0xFF;
if( Bn > 0xFF ) Bs = 0xFF;
// Scanline
Rs = (DWORD)(m_PaletteBuf[i&0x30].r*m_nScanlineColor/100.0f);
Gs = (DWORD)(m_PaletteBuf[i&0x30].g*m_nScanlineColor/100.0f);
Bs = (DWORD)(m_PaletteBuf[i&0x30].b*m_nScanlineColor/100.0f);
Rs =
Gs =
Bs = (DWORD)(0.299f * Rs + 0.587f * Gs + 0.114f * Bs);
Rs = (DWORD)(PalConvTbl[j][0]*Rs);
Gs = (DWORD)(PalConvTbl[j][1]*Gs);
Bs = (DWORD)(PalConvTbl[j][2]*Bs);
if( Rs > 0xFF ) Rs = 0xFF;
if( Gs > 0xFF ) Gs = 0xFF;
if( Bs > 0xFF ) Bs = 0xFF;
m_mpPalette[j][i+0x00].rgbRed = (BYTE)Rn;
m_mpPalette[j][i+0x00].rgbGreen = (BYTE)Gn;
m_mpPalette[j][i+0x00].rgbBlue = (BYTE)Bn;
m_mpPalette[j][i+0x40].rgbRed = (BYTE)Rs;
m_mpPalette[j][i+0x40].rgbGreen = (BYTE)Gs;
m_mpPalette[j][i+0x40].rgbBlue = (BYTE)Bs;
m_mnPalette[j][i] = ((Rn>>(8-Rbit))<<Rsft)|((Gn>>(8-Gbit))<<Gsft)|((Bn>>(8-Bbit))<<Bsft);
m_msPalette[j][i] = ((Rs>>(8-Rbit))<<Rsft)|((Gs>>(8-Gbit))<<Gsft)|((Bs>>(8-Bbit))<<Bsft);
// RGB555
if( Rsft > Bsft ) {
// RGB555->RGB888偺帪
m_mfPalette[j][i] = ((Rn>>(8-5))<<10)|((Gn>>(8-5))<<5)|((Bn>>(8-5))<<0);
} else {
// BGR555->BGR888偺帪
m_mfPalette[j][i] = ((Rn>>(8-5))<<0)|((Gn>>(8-5))<<5)|((Bn>>(8-5))<<10);
}
}
}
// 嵞昤夋偺堊
m_bDeltaUpdate = TRUE;
return TRUE;
}
// 僷儗僢僩僥乕僽儖偺愝掕
void CDirectDraw::SetPaletteTable( LPBYTE pal )
{
if( pal )
memcpy( m_PaletteBuf, pal, sizeof(m_PaletteBuf) );
else
memcpy( m_PaletteBuf, m_PalDefault, sizeof(m_PaletteBuf) );
CalcPaletteTable();
m_bPaletteUpdate = TRUE;
}
// 僷儗僢僩僥乕僽儖偺愝掕
void CDirectDraw::SetPaletteTable( RGBQUAD* rgb )
{
for( INT i = 0; i < 64; i++ ) {
m_PaletteBuf[i].r = rgb[i].rgbRed;
m_PaletteBuf[i].g = rgb[i].rgbGreen;
m_PaletteBuf[i].b = rgb[i].rgbBlue;
}
CalcPaletteTable();
m_bPaletteUpdate = TRUE;
}
// 僷儗僢僩僥乕僽儖偺庢摼
void CDirectDraw::GetPaletteTable( RGBQUAD* rgb )
{
for( INT i = 0; i < 64; i++ ) {
rgb[i].rgbRed = m_PaletteBuf[i].r;
rgb[i].rgbGreen = m_PaletteBuf[i].g;
rgb[i].rgbBlue = m_PaletteBuf[i].b;
rgb[i].rgbReserved = 0;
}
}
// 僷儗僢僩僼傽僀儖偺峏怴
void CDirectDraw::SetPaletteFile( LPCTSTR fname )
{
// 僷儗僢僩僼傽僀儖偺峏怴
if( strlen( fname ) > 0 ) {
FILE *fp;
if( (fp = ::fopen( fname, "rb" )) ) {
BYTE palbuf[192];
// 僒僀僘暘撉傒崬傒
if( ::fread( palbuf, 192, 1, fp ) == 1 ) {
// 僷儗僢僩偺曄峏偲寁嶼
SetPaletteTable( palbuf );
} else {
// 撉傒偒傟側偐偭偨帪偼僨僼僅儖僩
SetPaletteTable( (LPBYTE)NULL );
}
FCLOSE(fp);
} else {
// 奐偗側偐偭偨帪偼僨僼僅儖僩
SetPaletteTable( (LPBYTE)NULL );
}
} else {
// 柤慜偑柍偄帪偼僨僼僅儖僩
SetPaletteTable( (LPBYTE)NULL );
}
}
// 僼儖僗僋儕乕儞儌乕僪偱偺GDI僂僀儞僪僂昞帵愝掕
BOOL CDirectDraw::SetFullScreenGDI( BOOL bMode )
{
// 擮偺堊僠僃僢僋
if( !m_lpDD || !m_lpDDPrimary )
return FALSE;
if( m_bScreenMode ) {
if( !m_bGDI ) {
if( bMode ) {
RELEASE( m_lpDDClipper ); // 堦墳
if( m_lpDD->CreateClipper(0, &m_lpDDClipper, NULL) == DD_OK ) {
m_lpDDClipper->SetHWnd( 0, m_hWnd );
m_lpDDPrimary->SetClipper( m_lpDDClipper );
if( m_lpDD->FlipToGDISurface() == DD_OK ) {
m_bGDI = TRUE;
} else {
RELEASE( m_lpDDClipper );
return FALSE;
}
}
}
} else {
if( !bMode ) {
RELEASE( m_lpDDClipper );
m_bGDI = FALSE;
}
}
}
return TRUE;
}
void CDirectDraw::RealizePalette()
{
if( !m_lpDD || !m_lpDDPrimary )
return;
if( !m_bScreenMode ) {
DDSURFACEDESC2 ddsd;
ZEROMEMORY( &ddsd, sizeof(DDSURFACEDESC2) );
ddsd.dwSize = sizeof(DDSURFACEDESC2);
m_lpDDPrimary->GetSurfaceDesc(&ddsd);
if( ddsd.ddpfPixelFormat.dwRGBBitCount == 8 ) {
HDC hdc;
hdc = ::GetDC( m_hWnd );
::SelectPalette( hdc, m_hPalette, FALSE );
::RealizePalette( hdc );
::ReleaseDC( m_hWnd, hdc );
m_bPaletteUpdate = TRUE;
}
}
}
// 昤夋(Windows儊僢僙乕僕梡)
void CDirectDraw::OnScreenDraw()
{
if( !m_bScreenMode ) {
// Window mode
Blt();
Flip();
} else {
// Fullscreen mode
if( m_bGDI ) {
Blt();
Flip();
}
}
}
void CDirectDraw::SetPaletteMode( INT nMode, BOOL bMono )
{
if( (m_nPaletteMode != nMode) || (m_bMonoMode != bMono) ) {
m_bPaletteUpdate = TRUE;
}
m_nPaletteMode = nMode;
m_bMonoMode = bMono;
}
// 昞帵拞偺僷儗僢僩僥乕僽儖偺庢摼
void CDirectDraw::GetPaletteData( RGBQUAD* rgb )
{
INT i;
if( !m_bMonoMode ) {
for( i = 0; i < 64; i++ ) {
rgb[i ] = m_cpPalette[m_nPaletteMode][i];
rgb[i+0x40] = m_mpPalette[m_nPaletteMode][i];
}
} else {
for( i = 0; i < 64; i++ ) {
rgb[i ] = m_mpPalette[m_nPaletteMode][i];
rgb[i+0x40] = m_mpPalette[m_nPaletteMode][i];
}
}
}
void CDirectDraw::Blt()
{
INT i;
DDSURFACEDESC2 ddsd;
if( !m_lpDD || !m_lpDDPrimary )
return;
// ScreenMode changing?
if( m_bChangeMode )
return;
// Surface lost check & restore
if( !RestoreSurface() )
return;
ZEROMEMORY( &ddsd, sizeof(DDSURFACEDESC2) );
ddsd.dwSize = sizeof(DDSURFACEDESC2);
if( m_lpDDPrimary->GetSurfaceDesc(&ddsd) != DD_OK )
return;
// Palette copy
if( ddsd.ddpfPixelFormat.dwRGBBitCount == 8 ) {
if( !(m_LineColormode[1]&0x80) ) {
for( i = 0; i < 128; i++ ) {
m_logPalette.pe[i+0x40].peRed = m_cpPalette[m_nPaletteMode][i].rgbRed;
m_logPalette.pe[i+0x40].peGreen = m_cpPalette[m_nPaletteMode][i].rgbGreen;
m_logPalette.pe[i+0x40].peBlue = m_cpPalette[m_nPaletteMode][i].rgbBlue;
}
} else {
for( i = 0; i < 128; i++ ) {
m_logPalette.pe[i+0x40].peRed = m_mpPalette[m_nPaletteMode][i].rgbRed;
m_logPalette.pe[i+0x40].peGreen = m_mpPalette[m_nPaletteMode][i].rgbGreen;
m_logPalette.pe[i+0x40].peBlue = m_mpPalette[m_nPaletteMode][i].rgbBlue;
}
}
if( !m_bScreenMode ) {
::AnimatePalette( m_hPalette, 0, 256, m_logPalette.pe );
}
}
// Size calculate
BOOL bDoubleWidth = FALSE;
BOOL bDoubleHeight = FALSE;
RECT rcW;
rcW.left = 0;
rcW.top = 0;
rcW.right = SCREEN_WIDTH;
rcW.bottom = SCREEN_HEIGHT;
if( m_bDoubleSize || (m_nBltFilter && IsMMX()) ) {
rcW.right *= 2;
rcW.bottom *= 2;
bDoubleWidth = TRUE;
bDoubleHeight = TRUE;
} else if( m_bScanlineMode ) {
rcW.bottom *= 2;
bDoubleHeight = TRUE;
}
// Render function
BLTFUNC* bltfunc;
if( !m_nBltFilter || !IsMMX() ) {
if( !m_bDoubleSize ) {
if( !m_bScanlineMode ) {
bltfunc = NormalBltTable;
} else {
bltfunc = ScanlineBltTable;
}
} else {
if( !m_bScanlineMode ) {
bltfunc = DoubleBltTable;
} else {
bltfunc = DoubleScanlineBltTable;
}
}
} else {
switch( m_nBltFilter ) {
case BLTFILTER_2XSAI:
bltfunc = nx2xSaIBltTable;
break;
case BLTFILTER_SUPER2XSAI:
bltfunc = nxSuper2xSaIBltTable;
break;
case BLTFILTER_SUPEREAGLE:
bltfunc = nxSuperEagleBltTable;
break;
case BLTFILTER_SCALE2X:
bltfunc = nxScale2xBltTable;
break;
default:
break;
}
}
BOOL bFilter = FALSE;
LPBYTE lpRdr = m_lpRender+8;
ZEROMEMORY( &ddsd, sizeof(DDSURFACEDESC2) );
ddsd.dwSize = sizeof(DDSURFACEDESC2);
if( m_bForceWrite ) {
// 懡抜儗儞僟儕儞僌柍偟
if( m_lpDDRender->Lock( NULL, &ddsd, 0, NULL ) == DD_OK ) {
switch( ddsd.ddpfPixelFormat.dwRGBBitCount ) {
case 8:
(this->*bltfunc[0])( lpRdr, &m_lpRenderDelta[DELTA_WIDTH*2*sizeof(DWORD)], ddsd, TRUE );
break;
case 16:
(this->*bltfunc[1])( lpRdr, &m_lpRenderDelta[DELTA_WIDTH*2*sizeof(DWORD)], ddsd, TRUE );
break;
case 24:
(this->*bltfunc[2])( lpRdr, &m_lpRenderDelta[DELTA_WIDTH*2*sizeof(DWORD)], ddsd, TRUE );
break;
case 32:
(this->*bltfunc[3])( lpRdr, &m_lpRenderDelta[DELTA_WIDTH*2*sizeof(DWORD)], ddsd, TRUE );
break;
default:
break;
}
m_lpDDRender->Unlock( NULL );
m_bDeltaUpdate = FALSE;
}
} else {
if( m_lpDDRender2->Lock( NULL, &ddsd, 0, NULL ) == DD_OK ) {
switch( ddsd.ddpfPixelFormat.dwRGBBitCount ) {
case 8:
(this->*bltfunc[0])( lpRdr, &m_lpRenderDelta[DELTA_WIDTH*2*sizeof(DWORD)], ddsd, m_bDeltaUpdate );
break;
case 16:
(this->*bltfunc[1])( lpRdr, &m_lpRenderDelta[DELTA_WIDTH*2*sizeof(DWORD)], ddsd, m_bDeltaUpdate );
break;
case 24:
(this->*bltfunc[2])( lpRdr, &m_lpRenderDelta[DELTA_WIDTH*2*sizeof(DWORD)], ddsd, m_bDeltaUpdate );
break;
case 32:
(this->*bltfunc[3])( lpRdr, &m_lpRenderDelta[DELTA_WIDTH*2*sizeof(DWORD)], ddsd, m_bDeltaUpdate );
break;
default:
break;
}
m_lpDDRender2->Unlock( NULL );
m_bDeltaUpdate = FALSE;
m_lpDDRender->Blt( &rcW, m_lpDDRender2, &rcW, 0, NULL );
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -