📄 swline.cpp
字号:
/*
Copyright (c) 1995-2000 Microsoft Corporation. All rights reserved.
*/
#include "precomp.h"
SCODE GPE::EmulatedLine( GPELineParms *pParms )
{
int Bpp = EGPEFormatToBpp[pParms->pDst->Format()];
unsigned long baseMask = (2 << (Bpp-1) )-1;
int remainingPels;
unsigned char *Ptr;
unsigned char *newPtr;
int i;
long accum = (long)(pParms->dN) + pParms->llGamma;
long axstp = (long)(pParms->dN);
long dgstp = (long)(pParms->dN) - (long)(pParms->dM);
unsigned char rop2Mark = (unsigned char)(pParms->mix);
unsigned char rop2Space = (unsigned char)(pParms->mix >> 8);
unsigned char rop2;
unsigned long mask;
long stride = pParms->pDst->Stride();
unsigned long style = pParms->style;
int styleState = pParms->styleState;
DEBUGMSG(GPE_ZONE_LINE,(TEXT("GPE::EmulatedLine\r\n")));
DEBUGMSG(GPE_ZONE_LINE,(TEXT("Solid color 0x%08x\r\n"),pParms->solidColor));
DEBUGMSG(GPE_ZONE_LINE,(TEXT("Start X=%d,Y=%d\r\n"),pParms->xStart,pParms->yStart));
DEBUGMSG(GPE_ZONE_LINE,(TEXT("iDir:%d accum %d axstp %d dgstp %d\r\n"),
pParms->iDir,accum,axstp,dgstp));
DEBUGMSG(GPE_ZONE_LINE,(TEXT("Mix: %04x Bpp: %d\r\n"),pParms->mix,Bpp));
int MajorDPtr = 0;
int MinorDPtr = 0;
int MajorDPixel = 0;
int MinorDPixel = 0;
if( pParms->pDst->InVideoMemory() )
{
// If we have a pending blt and now attempt a software operation using
// video memory, the pipeline must be flushed.
WaitForNotBusy();
}
if( Bpp != 24 )
{
unsigned long pen[32];
unsigned long penMask[32];
int pixelsPerDWord = 32 / Bpp;
int subPixel;
unsigned long cache;
unsigned long D;
unsigned long P;
for( i=0; i<pixelsPerDWord; i++ )
{
int shift = i*Bpp; // Pixel 0 is in least significant byte
if( Bpp < 8 ) // Pixel 0 is in most significant bits of byte
shift^=(8-Bpp);
pen[i] = (pParms->solidColor & baseMask)<<shift;
penMask[i] = baseMask<<shift;
DEBUGMSG(GPE_ZONE_LINE,(TEXT("DWord Pixel %d pen: %08x penMask: %08x\r\n"),
i,pen[i],penMask[i]));
}
switch( pParms->iDir )
{
case 0: MajorDPixel = 1; MinorDPtr = stride; break;
case 1: MinorDPixel = 1; MajorDPtr = stride; break;
case 2: MinorDPixel = -1; MajorDPtr = stride; break;
case 3: MajorDPixel = -1; MinorDPtr = stride; break;
case 4: MajorDPixel = -1; MinorDPtr = -stride; break;
case 5: MinorDPixel = -1; MajorDPtr = -stride; break;
case 6: MinorDPixel = 1; MajorDPtr = -stride; break;
case 7: MajorDPixel = 1; MinorDPtr = -stride; break;
default:
DEBUGMSG(GPE_ZONE_ERROR,(TEXT("Invalid direction: %d\r\n"),pParms->iDir));
return E_INVALIDARG;
}
Ptr = ((unsigned char *)pParms->pDst->Buffer())
+ pParms->yStart * stride
+ (((pParms->xStart * Bpp) >> 5 ) << 2 );
subPixel = pParms->xStart % pixelsPerDWord;
cache = *(unsigned long *)Ptr;
for( remainingPels = pParms->cPels; remainingPels; remainingPels-- )
{
DEBUGMSG(GPE_ZONE_LINE,(TEXT("Remain:%d Ptr:%08x SubPix:%d cache:%08x\r\n"),
remainingPels,Ptr,subPixel,cache ));
D = cache;
P = pen[subPixel];
if( ( style >> ((styleState++) & 31 ) ) & 1 )
rop2 = rop2Space;
else
rop2 = rop2Mark;
switch( rop2 )
{
case 1: D = 0; break;
case 2: D = ~( P | D ); break;
case 3: D = ~P & D; break;
case 4: D = ~P; break;
case 5: D = P & ~D; break;
case 6: D = ~D; break;
case 7: D = P ^ D; break;
case 8: D = ~( P & D ); break;
case 9: D = P & D; break;
case 10: D = ~( P ^ D ); break;
case 11: D = D; break;
case 12: D = ~P | D; break;
case 13: D = P; break;
case 14: D = P | ~D; break;
case 15: D = P | D; break;
case 16: D = 0xffffffff; break;
default:
DEBUGMSG(GPE_ZONE_ERROR,(TEXT("Invalid rop2: %d\r\n"),rop2));
return E_INVALIDARG;
}
mask = penMask[subPixel];
cache = ( cache & ~mask ) | ( D & mask );
DEBUGMSG(GPE_ZONE_LINE,(TEXT("Result: P %08x, D %08x, mask %08x, cache %08x\r\n"),
P, D, mask, cache ));
if( remainingPels == 1 )
{
*(unsigned long *)Ptr = cache;
break;
}
newPtr = Ptr;
newPtr += MajorDPtr;
subPixel += MajorDPixel;
if( axstp ) // check for vertical/horizontal
{
if( accum < 0 )
{
DEBUGMSG(GPE_ZONE_LINE,(TEXT("Straight accum=%d axstp=%d\r\n"),accum,axstp));
accum += axstp;
}
else
{
DEBUGMSG(GPE_ZONE_LINE,(TEXT("Diagonal accum=%d dgstp=%d\r\n"),accum,dgstp));
newPtr += MinorDPtr;
subPixel += MinorDPixel;
accum += dgstp;
}
}
if( subPixel < 0 )
{
newPtr-=4;
subPixel += pixelsPerDWord;
}
else if( subPixel >= pixelsPerDWord )
{
newPtr+=4;
subPixel -= pixelsPerDWord;
}
if( newPtr != Ptr )
{
*(unsigned long *)Ptr = cache;
Ptr = newPtr;
cache = *(unsigned long *)Ptr;
}
}
}
else
{
unsigned char P0,P1,P2; // The pen (i.e. solid color), split into three bytes
// For 24bpp, we do brute force byte-by-byte accesses for each pixel
switch( pParms->iDir )
{
case 0: MajorDPtr = 3; MinorDPtr = stride; break;
case 1: MinorDPtr = 3; MajorDPtr = stride; break;
case 2: MinorDPtr = -3; MajorDPtr = stride; break;
case 3: MajorDPtr = -3; MinorDPtr = stride; break;
case 4: MajorDPtr = -3; MinorDPtr = -stride; break;
case 5: MinorDPtr = -3; MajorDPtr = -stride; break;
case 6: MinorDPtr = 3; MajorDPtr = -stride; break;
case 7: MajorDPtr = 3; MinorDPtr = -stride; break;
default:
DEBUGMSG(GPE_ZONE_ERROR,(TEXT("Invalid direction: %d\r\n"),pParms->iDir));
return E_INVALIDARG;
}
Ptr = ((unsigned char *)pParms->pDst->Buffer())
+ pParms->yStart * stride
+ pParms->xStart * 3;
P0 = ((unsigned char *)&(pParms->solidColor))[0];
P1 = ((unsigned char *)&(pParms->solidColor))[1];
P2 = ((unsigned char *)&(pParms->solidColor))[2];
for( remainingPels = pParms->cPels; remainingPels; remainingPels-- )
{
if( ( style >> ((styleState++) & 31 ) ) & 1 )
rop2 = rop2Space;
else
rop2 = rop2Mark;
switch( rop2 )
{
case 1: Ptr[0] = 0; Ptr[1] = 0; Ptr[2] = 0; break;
case 2: Ptr[0] = ~( P0 | Ptr[0] ); Ptr[1] = ~( P1 | Ptr[1] ); Ptr[2] = ~( P2 | Ptr[2] ); break;
case 3: Ptr[0] = ~P0 & Ptr[0]; Ptr[1] = ~P1 & Ptr[1]; Ptr[2] = ~P2 & Ptr[2]; break;
case 4: Ptr[0] = ~P0; Ptr[1] = ~P1; Ptr[2] = ~P2; break;
case 5: Ptr[0] = P0 & ~Ptr[0]; Ptr[1] = P1 & ~Ptr[1]; Ptr[2] = P2 & ~Ptr[2]; break;
case 6: Ptr[0] = ~Ptr[0]; Ptr[1] = ~Ptr[1]; Ptr[2] = ~Ptr[2]; break;
case 7: Ptr[0] = P0 ^ Ptr[0]; Ptr[1] = P1 ^ Ptr[1]; Ptr[2] = P2 ^ Ptr[2]; break;
case 8: Ptr[0] = ~( P0 & Ptr[0] ); Ptr[1] = ~( P1 & Ptr[1] ); Ptr[2] = ~( P2 & Ptr[2] ); break;
case 9: Ptr[0] = P0 & Ptr[0]; Ptr[1] = P1 & Ptr[1]; Ptr[2] = P2 & Ptr[2]; break;
case 10: Ptr[0] = ~( P0 ^ Ptr[0] ); Ptr[1] = ~( P1 ^ Ptr[1] ); Ptr[2] = ~( P2 ^ Ptr[2] ); break;
case 11: Ptr[0] = Ptr[0]; Ptr[1] = Ptr[1]; Ptr[2] = Ptr[2]; break;
case 12: Ptr[0] = ~P0 | Ptr[0]; Ptr[1] = ~P1 | Ptr[1]; Ptr[2] = ~P2 | Ptr[2]; break;
case 13: Ptr[0] = P0; Ptr[1] = P1; Ptr[2] = P2; break;
case 14: Ptr[0] = P0 | ~Ptr[0]; Ptr[1] = P1 | ~Ptr[1]; Ptr[2] = P2 | ~Ptr[2]; break;
case 15: Ptr[0] = P0 | Ptr[0]; Ptr[1] = P1 | Ptr[1]; Ptr[2] = P2 | Ptr[2]; break;
case 16: Ptr[0] = 0xff; Ptr[1] = 0xff; Ptr[2] = 0xff; break;
default:
DEBUGMSG(GPE_ZONE_ERROR,(TEXT("Invalid rop2: %d\r\n"),rop2));
return E_INVALIDARG;
}
Ptr += MajorDPtr;
if( axstp ) // check for vertical/horizontal
{
if( accum < 0 )
{
DEBUGMSG(GPE_ZONE_LINE,(TEXT("Straight accum=%d axstp=%d\r\n"),accum,axstp));
accum += axstp;
}
else
{
DEBUGMSG(GPE_ZONE_LINE,(TEXT("Diagonal accum=%d dgstp=%d\r\n"),accum,dgstp));
Ptr += MinorDPtr;
accum += dgstp;
}
}
}
}
return S_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -