⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 swline.cpp

📁 See Hanoi.cpp for the implementation of this cla
💻 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 + -