📄 swblt.cpp
字号:
unsigned long srcValue,
unsigned long brushValue,
unsigned char rop3,
unsigned char dstBitsPerPixel
)
{
if( dstBitsPerPixel > 24 )
{
// Break into two halves, otherwise the brushValue<<=2 below will overflow
return ProcessROP3(dstValue,srcValue,brushValue,rop3,16) |
( ProcessROP3(dstValue>>16,srcValue>>16,brushValue>>16,rop3,dstBitsPerPixel-16) << 16);
}
DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("Process rop3=%02x, numbits=%d, pattern=%04x, source=%04x, dest=%04x, "),
rop3,dstBitsPerPixel,brushValue,srcValue,dstValue ));
unsigned long result = 0;
unsigned long rsltBit = 1;
brushValue <<= 2;
srcValue <<= 1;
while( dstBitsPerPixel-- )
{
if( ( 1<< ( brushValue&4 | srcValue&2 | dstValue&1 ) ) & rop3 )
result |= rsltBit;
brushValue >>= 1;
srcValue >>= 1;
dstValue >>= 1;
rsltBit <<=1;
}
DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("resuult=%04x\r\n"), result));
return result;
}
#if defined (OSV_PPC) || ( defined (_WINCEOSVER) && (_WINCEOSVER >= 500))
#define FIX16_ONE 0x00010000
#define FIX16_MASK 0x0000FFFF
#define FIX16_SHIFT 16
SCODE
GPE::EmulatedBlt_Bilinear(
GPEBltParms *pParms
)
{
int width = pParms->prclDst->right - pParms->prclDst->left;
int height = pParms->prclDst->bottom - pParms->prclDst->top;
int dstMatters = ((( pParms->rop4 >> 1 ) ^ pParms->rop4 ) & 0x5555) != 0;
int srcWidth = pParms->prclSrc->right - pParms->prclSrc->left;
int srcHeight = pParms->prclSrc->bottom - pParms->prclSrc->top;
int dstXStartSkip = 0;
int dstYStartSkip = 0;
int srcXStartSkip = 0;
int srcYStartSkip = 0;
unsigned int xratio = srcWidth * FIX16_ONE / width;
unsigned int yratio = srcHeight * FIX16_ONE / height;
unsigned int xstep = (xratio - FIX16_ONE) >> 1;
unsigned int ystep = (yratio - FIX16_ONE) >> 1;
unsigned char rop3 = (unsigned char)pParms->rop4;
ystep &= FIX16_MASK;
xstep &= FIX16_MASK;
if (pParms->prclClip)
{
RECTL rclClipped = *pParms->prclDst;
if (rclClipped.left < pParms->prclClip->left)
{
rclClipped.left = pParms->prclClip->left;
}
if (rclClipped.top < pParms->prclClip->top)
{
rclClipped.top = pParms->prclClip->top;
}
if (rclClipped.bottom > pParms->prclClip->bottom)
{
rclClipped.bottom = pParms->prclClip->bottom;
}
if (rclClipped.right > pParms->prclClip->right)
{
rclClipped.right = pParms->prclClip->right;
}
// The clipped rect is empty.
if (rclClipped.right <= rclClipped.left
|| rclClipped.bottom <= rclClipped.top)
{
return S_OK;
}
dstXStartSkip = pParms->xPositive ? (rclClipped.left - pParms->prclDst->left) : (pParms->prclDst->right - rclClipped.right);
dstYStartSkip = pParms->yPositive ? (rclClipped.top - pParms->prclDst->top) : (pParms->prclDst->bottom - rclClipped.bottom);
width = rclClipped.right - rclClipped.left;
height = rclClipped.bottom - rclClipped.top;
}
int skipCount;
for (skipCount = dstXStartSkip; skipCount; skipCount--)
{
xstep += xratio;
srcXStartSkip += (xstep >> FIX16_SHIFT);
xstep &= FIX16_MASK;
}
for (skipCount = dstYStartSkip; skipCount; skipCount--)
{
ystep += yratio;
srcYStartSkip += (ystep >> FIX16_SHIFT);
ystep &= FIX16_MASK;
}
// The destination must be at least 16 bpp.
PixelIterator dst;
dst.Bpp = EGPEFormatToBpp[pParms->pDst->Format()];
if (pParms->yPositive)
{
dst.RowIncrement = pParms->pDst->Stride();
dst.RowPtr = (unsigned char*)pParms->pDst->Buffer() + pParms->pDst->Stride() * (pParms->prclDst->top + dstYStartSkip);
}
else
{
dst.RowIncrement = -pParms->pDst->Stride();
dst.RowPtr = (unsigned char*)pParms->pDst->Buffer() + pParms->pDst->Stride() * (pParms->prclDst->bottom - 1 - dstYStartSkip);
}
if (pParms->xPositive)
{
dst.BytesPerAccess = dst.Bpp/8;
dst.RowPtr += dst.BytesPerAccess * (pParms->prclDst->left + dstXStartSkip);
}
else
{
dst.BytesPerAccess = -dst.Bpp/8;
dst.RowPtr -= dst.BytesPerAccess * (pParms->prclDst->right - 1 - dstXStartSkip);
}
dst.Mask = (2 << (dst.Bpp - 1)) - 1;
dst.CacheState = 0; // so it is not marked as dirty
// Initialize the first source iterator (src0)
PixelIterator src0;
src0.InitPixelIterator(pParms->pSrc, pParms->xPositive, pParms->yPositive, pParms->prclSrc,
srcXStartSkip, srcYStartSkip-1);
// Initialize the second source iterator (src1)
PixelIterator src1;
src1.InitPixelIterator(pParms->pSrc, pParms->xPositive, pParms->yPositive, pParms->prclSrc,
srcXStartSkip, srcYStartSkip);
// Compensate for srcXStartSkip and srcYStartSkip.
srcHeight -= srcYStartSkip;
srcWidth -= srcXStartSkip;
// Force a read of the first row.
int ystepOverflow = 1;
for (int y = 0, SrcYPixels = 0; y < height; y++)
{
bool IsSrc0Valid;
bool IsSrc1Valid;
// Initialize the dst row pointer to the next line.
dst.Ptr = dst.RowPtr;
dst.RowPtr += dst.RowIncrement;
// Initialize u0 and u1
int u1 = ystep >> 8;
int u0 = 256 - u1;
// Check to see if we need to advance to the next row, or go back to
// the beginning of the current source row.
if (!ystepOverflow)
{
SrcYPixels--;
src0.RowPtr -= src0.RowIncrement;
src1.RowPtr -= src0.RowIncrement;
}
// Initialize the source row pointers to the next line.
src0.Ptr = src0.RowPtr;
src0.RowPtr += src0.RowIncrement;
src1.Ptr = src1.RowPtr;
src1.RowPtr += src1.RowIncrement;
if (SrcYPixels == 0)
{
IsSrc0Valid = false;
}
else
{
IsSrc0Valid = true;
}
if (SrcYPixels < srcHeight)
{
IsSrc1Valid = true;
}
else
{
IsSrc1Valid = false;
}
SrcYPixels++;
if (!src0.Is24Bit && IsSrc0Valid)
{
src0.Cache = *(UNALIGNED unsigned long *)src0.Ptr;
src0.CacheState = src0.CacheStateNewRow;
}
if (!src1.Is24Bit && IsSrc1Valid)
{
src1.Cache = *(UNALIGNED unsigned long *)src1.Ptr;
src1.CacheState = src1.CacheStateNewRow;
}
for (int x = 0, SrcXPixels = 0; x < width;)
{
// Save the old values of src0 and src1.
unsigned long OldSrc0Value = src0.Value;
unsigned long OldSrc1Value = src1.Value;
// Only increment the src0 and src1 pointers if we haven't hit the
// end of a row.
if (SrcXPixels < srcWidth)
{
SrcXPixels++;
// Get the next src0 pixel.
if (IsSrc0Valid)
{
if (src0.Is24Bit)
{
src0.Value = (*src0.Ptr) + (*(src0.Ptr+1) << 8) + (*(src0.Ptr+2) << 16);
src0.Ptr += src0.BytesPerAccess;
}
else
{
if (!(src0.CacheState & 0x00FF00))
{
src0.Ptr += src0.BytesPerAccess;
src0.CacheState = src0.CacheStateNewDWord;
src0.Cache = *(UNALIGNED unsigned long *)src0.Ptr;
}
src0.Value = src0.Cache >> ((src0.CacheState >> 16) ^ src0.MaskShiftXor);
src0.CacheState += src0.CacheStateIncrement;
}
src0.Value &= src0.Mask;
if (pParms->pLookup)
{
src0.Value = (pParms->pLookup)[src0.Value];
}
if (pParms->pConvert)
{
src0.Value = (pParms->pColorConverter->*(pParms->pConvert))(src0.Value);
}
}
// Get the next src1 pixel (if needed).
if (IsSrc1Valid)
{
if (src1.Is24Bit)
{
src1.Value = (*src1.Ptr) + (*(src1.Ptr+1) << 8) + (*(src1.Ptr+2) << 16);
src1.Ptr += src1.BytesPerAccess;
}
else
{
if (!(src1.CacheState & 0x00FF00))
{
src1.Ptr += src1.BytesPerAccess;
src1.CacheState = src1.CacheStateNewDWord;
src1.Cache = *(UNALIGNED unsigned long *)src1.Ptr;
}
src1.Value = src1.Cache >> ((src1.CacheState >> 16) ^ src1.MaskShiftXor);
src1.CacheState += src1.CacheStateIncrement;
}
src1.Value &= src1.Mask;
if (pParms->pLookup)
{
src1.Value = (pParms->pLookup)[src1.Value];
}
if (pParms->pConvert)
{
src1.Value = (pParms->pColorConverter->*(pParms->pConvert))(src1.Value);
}
}
else
{
src1.Value = src0.Value;
}
if (!IsSrc0Valid)
{
src0.Value = src1.Value;
}
}
// If this is the first pixel read set the old values to this pixel
if (SrcXPixels == 1)
{
OldSrc0Value = src0.Value;
OldSrc1Value = src1.Value;
}
// Combine the pixels according to this algorithm:
// s0 = OldSrc0Value * u0 + OldSrc1Value * u1;
// s1 = src0.Value * u0 + src1.Value * u1;
// SrcValue = s0 * v0 + s1 * v1;
unsigned long s0;
unsigned long s1;
if (OldSrc0Value == OldSrc1Value)
{
s0 = OldSrc0Value;
}
else
{
unsigned long A00aa00gg;
unsigned long A00rr00bb;
A00aa00gg = ((OldSrc0Value & g_BilinearMasks[3]) >> g_BilinearShifts[3]) << 16;
A00aa00gg |= (OldSrc0Value
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -