📄 blt.cpp
字号:
// Not a pattern brush?
if( pBltParms->solidColor != -1 )
{
DEBUGMSG(CT69K_ZONE_BLTHI,(TEXT("CT69000::Blt - 0xAAF0\r\n")));
if (pBltParms->pMask->Format() == gpe1Bpp)
{
pBltParms->pBlt = FUNCNAME(BltText08);
}
else // Anti-aliased text (works only for FIXED_PALETTE == 1)
{
pBltParms->pBlt = FUNCNAME(BltAlphaText08);
}
return S_OK;
}
break;
default:
break;
}
DEBUGMSG(CT69K_ZONE_BLTHI,
(TEXT("CT69000::Blt - no 8 bit emulation found\r\n")));
}
else if ( pDst->Format() == gpe16Bpp &&
!((pBltParms->bltFlags & (BLT_TRANSPARENT | BLT_STRETCH)) ||
pBltParms->pLookup ||
pBltParms->pConvert )
)
{
switch (pBltParms->rop4)
{
case 0x0000: // BLACKNESS
DEBUGMSG(CT69K_ZONE_BLTHI,
(TEXT("CT69000::Blt(BltFill16) - BLACKNESS\r\n")));
pBltParms->solidColor = 0;
pBltParms->pBlt = FUNCNAME(BltFill16);
return S_OK;
case 0xFFFF: // WHITENESS
DEBUGMSG(CT69K_ZONE_BLTHI,
(TEXT("CT69000::Blt(BltFill16) - WHITENESS\r\n")));
pBltParms->solidColor = 0x00ffffff;
pBltParms->pBlt = FUNCNAME(BltFill16);
return S_OK;
case 0xF0F0: // PATCOPY
if( pBltParms->solidColor != -1 )
{
DEBUGMSG(CT69K_ZONE_BLTHI,
(TEXT("CT69000::Blt(BltFill16) - PATCOPY - solid brush\r\n")));
pBltParms->pBlt = FUNCNAME(BltFill16);
return S_OK;
}
break;
case 0xAAF0: // Special PATCOPY rop for text output -- fill where mask is set.
// Not a pattern brush?
if (pBltParms->solidColor != -1)
{
if (pBltParms->pMask->Format() == gpe1Bpp)
{
DEBUGMSG(CT69K_ZONE_BLTHI,
(TEXT("CT69000::Blt(BltText16) - 0xAAF0\r\n")));
pBltParms->pBlt = FUNCNAME(BltText16);
return S_OK;
}
else // Anti-aliased text
{
DEBUGMSG(CT69K_ZONE_BLTHI,
(TEXT("CT69000::Blt(BltAlphaText16) - 0xAAF0 alpha\r\n")));
pBltParms->pBlt = FUNCNAME(BltAlphaText16);
return S_OK;
}
}
break;
case 0xCCCC: // SRCCOPY
DEBUGMSG(CT69K_ZONE_BLTHI,
(TEXT("CT69000::Blt(BltSrcCopy1616) - SRCCOPY\r\n")));
pBltParms->pBlt = FUNCNAME(BltSrcCopy1616);
return S_OK;
case 0xEEEE: // SRCPAINT
DEBUGMSG(CT69K_ZONE_BLTHI,
(TEXT("CT69000::Blt(BltSrcPaint1616) - SRCPAINT\r\n")));
pBltParms->pBlt = FUNCNAME(BltSrcPaint1616);
return S_OK;
case 0x6666: // SRCINVERT
DEBUGMSG(CT69K_ZONE_BLTHI,
(TEXT("CT69000::Blt(BltSrcInvert1616) - SRCINVERT\r\n")));
pBltParms->pBlt = FUNCNAME(BltSrcInvert1616);
return S_OK;
case 0x8888: // SRCAND
DEBUGMSG(CT69K_ZONE_BLTHI,
(TEXT("CT69000::Blt(BltSrcAnd1616) - SRCAND\r\n")));
pBltParms->pBlt = FUNCNAME(BltSrcAnd1616);
return S_OK;
default:
;
}
DEBUGMSG(CT69K_ZONE_BLTHI,(TEXT("CT69000::Blt - no 16 bit emulation found\r\n")));
return S_OK;
}
DEBUGMSG(CT69K_ZONE_BLTLO,
(TEXT("CT69000::Blt - non standard blt - use gpe\r\n")));
return S_OK;
}
//-----------------------------------------------------------------------
//
// CT69000::BltComplete
//
// this function is called after a blit has been completed
//
//-----------------------------------------------------------------------
SCODE
CT69000::BltComplete(GPEBltParms *pBltParms)
{
DEBUGMSG(CT69K_ZONE_FUNCTION, (TEXT("CT69000::BltComplete\r\n")));
return S_OK;
}
//-----------------------------------------------------------------------
//
// CT69000::AcceleratedSrcCopyBlt
//
// this accelerated blit works for all blits with a source and a
// destination rect, e.g. SRCCOPY. The 69k supports all rops between
// SRC and DST.
//
//-----------------------------------------------------------------------
SCODE
CT69000::AcceleratedSrcCopyBlt(GPEBltParms *pBltParms)
{
DEBUGMSG(CT69K_ZONE_HW,
(TEXT("AcceleratedSrcCopyBlt Rop = 0x%4x\r\n"), pBltParms->rop4));
DBGBLTPARMS( CT69K_ZONE_HW, pBltParms);
//
// some handy shortcuts for pointers
//
RECTL *prclSrc=pBltParms->prclSrc;
RECTL *prclDst=pBltParms->prclDst;
GPESurf *pSrc=pBltParms->pSrc;
GPESurf *pDst=pBltParms->pDst;
ULONG ulSrcSpan=pSrc->Stride();
ULONG ulDstSpan=pDst->Stride();
ULONG ulSrcAddress=pSrc->OffsetInVideoMemory();
ULONG ulDstAddress=pDst->OffsetInVideoMemory();
ulSrcAddress += BYTESPERPIXEL(prclSrc->left)+
prclSrc->top*ulSrcSpan;
ulDstAddress += BYTESPERPIXEL(prclDst->left)+
prclDst->top*ulDstSpan;
ULONG ulCmd=(pBltParms->rop4 & 0xff);
//
// check if this is an overlapping blt
// on the same surface
//
if (pSrc==pDst)
{
ULONG ulDelta;
//
// if dest rect overlaps src rect on right side,
// start copy from right to left....
//
if (prclDst->left>prclSrc->left)
{
ulCmd |= 0x100;
ulDelta = BYTESPERPIXEL(prclSrc->right-prclSrc->left-1);
ulSrcAddress += ulDelta;
ulDstAddress += ulDelta;
}
//
// same for top/bottom rects
//
if (prclDst->top>prclSrc->top)
{
ulCmd |= 0x200;
ulDelta = (prclSrc->bottom-prclSrc->top-1)*ulSrcSpan;
ulSrcAddress += ulDelta;
ulDstAddress += ulDelta;
}
}
//
// wait before touching registers if engine was busy
//
if (BltEngineBusy())
WaitForNotBusy();
SetBR( 0, ulSrcSpan | (ulDstSpan << 16));
SetBR( 4, ulCmd);
SetBR( 6, ulSrcAddress);
SetBR( 7, ulDstAddress);
ULONG ulWidth=BYTESPERPIXEL(prclDst->right - prclDst->left);
ULONG ulHeight=prclDst->bottom - prclDst->top;
SetBR( 8, ulWidth | (ulHeight << 16));
return S_OK;
}
//-----------------------------------------------------------------------
//
// CT69000::AcceleratedTransparentSrcCopyBlt
//
// this accelerated blit works for all blits with a source and a
// destination rect and a color key.
//
//-----------------------------------------------------------------------
SCODE
CT69000::AcceleratedTransparentSrcCopyBlt(GPEBltParms *pBltParms)
{
DEBUGMSG(CT69K_ZONE_HW,
(TEXT("AcceleratedSrcCopyBlt Rop = 0x%4x\r\n"), pBltParms->rop4));
DBGBLTPARMS( CT69K_ZONE_HW, pBltParms);
//
// some handy shortcuts for pointers
//
RECTL *prclSrc=pBltParms->prclSrc;
RECTL *prclDst=pBltParms->prclDst;
GPESurf *pSrc=pBltParms->pSrc;
GPESurf *pDst=pBltParms->pDst;
ULONG ulSrcSpan=pSrc->Stride();
ULONG ulDstSpan=pDst->Stride();
ULONG ulSrcAddress=pSrc->OffsetInVideoMemory();
ULONG ulDstAddress=pDst->OffsetInVideoMemory();
DWORD dwKeyColor=pBltParms->solidColor;
ulSrcAddress += BYTESPERPIXEL(prclSrc->left)+
prclSrc->top*ulSrcSpan;
ulDstAddress += BYTESPERPIXEL(prclDst->left)+
prclDst->top*ulDstSpan;
ULONG ulCmd=(pBltParms->rop4 & 0xff);
//
// check if this is an overlapping blt
// on the same surface
//
if (pSrc==pDst)
{
ULONG ulDelta;
//
// if dest rect overlaps src rect on right side,
// start copy from right to left....
//
if (prclDst->left>prclSrc->left)
{
ulCmd |= 0x100;
ulDelta = BYTESPERPIXEL(prclSrc->right-prclSrc->left-1);
ulSrcAddress += ulDelta;
ulDstAddress += ulDelta;
}
//
// same for top/bottom rects
//
if (prclDst->top>prclSrc->top)
{
ulCmd |= 0x200;
ulDelta = (prclSrc->bottom-prclSrc->top-1)*ulSrcSpan;
ulSrcAddress += ulDelta;
ulDstAddress += ulDelta;
}
}
ulCmd |= (1 << 14); // enable transparency
//
// wait before touching registers if engine was busy
//
if (BltEngineBusy())
WaitForNotBusy();
SetKey( dwKeyColor);
SetBR( 0, ulSrcSpan | (ulDstSpan << 16));
SetBR( 4, ulCmd);
SetBR( 6, ulSrcAddress);
SetBR( 7, ulDstAddress);
ULONG ulWidth=BYTESPERPIXEL(prclDst->right - prclDst->left);
ULONG ulHeight=prclDst->bottom - prclDst->top;
SetBR( 8, ulWidth | (ulHeight << 16));
return S_OK;
}
//-----------------------------------------------------------------------
//
// CT69000::AcceleratedPatSrcDstBlt
//
// setup a blit between arbitrary source and dest. rects with a 8x8
// pattern as a brush
//
//-----------------------------------------------------------------------
SCODE
CT69000::AcceleratedPatSrcDstBlt(GPEBltParms *pBltParms)
{
DEBUGMSG(CT69K_ZONE_HW,
(TEXT("AcceleratedPatSrcDstBlt Rop = 0x%4x\r\n"), pBltParms->rop4));
DBGBLTPARMS( CT69K_ZONE_HW, pBltParms);
GPESurf *pBrush=pBltParms->pBrush;
POINTL *pptlBrush=pBltParms->pptlBrush;
//
// some handy shortcuts for pointers
//
RECTL *prclSrc=pBltParms->prclSrc;
RECTL *prclDst=pBltParms->prclDst;
GPESurf *pSrc=pBltParms->pSrc;
GPESurf *pDst=pBltParms->pDst;
ULONG ulSrcSpan=pSrc->Stride();
ULONG ulDstSpan=pDst->Stride();
ULONG ulSrcAddress=pSrc->OffsetInVideoMemory();
ULONG ulDstAddress=pDst->OffsetInVideoMemory();
ulSrcAddress += BYTESPERPIXEL(prclSrc->left)+
prclSrc->top*ulSrcSpan;
ulDstAddress += BYTESPERPIXEL(prclDst->left)+
prclDst->top*ulDstSpan;
ULONG ulCmd=(pBltParms->rop4 & 0xff);
if (pptlBrush!=NULL)
ulCmd |= (pptlBrush->y & 7) << 20;
//
// check if this is an overlapping blt
// on the same surface
//
if (pSrc==pDst)
{
ULONG ulDelta;
//
// do some more extensive checking if using patterns,
// since chip supports only top to bottom/ left to right
// pattern fills
//
if(!(prclDst->left>prclSrc->right ||
prclSrc->left>prclDst->right ||
prclDst->top>prclSrc->bottom ||
prclSrc->top>prclDst->bottom))
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -