src/sgp/VObject_Blitters.cc
void Blt8BPPDataTo16BPPBufferTransShadowZNBObscuredClip(UINT16* pBuffer, UINT32 uiDestPitchBYTES, UINT16* pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect* clipregion, const UINT16* p16BPPPalette)
{
	UINT32 Unblitted, uiLineFlag;
	UINT8  *DestPtr, *ZPtr;
	UINT32 LineSkip;
	INT32  LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight, LSCount;
	INT32  ClipX1, ClipY1, ClipX2, ClipY2;

	// Assertions
	Assert( hSrcVObject != NULL );
	Assert( pBuffer != NULL );

	// Get Offsets from Index into structure
	ETRLEObject const& pTrav = hSrcVObject->SubregionProperties(usIndex);
	UINT32      const  usHeight = pTrav.usHeight;
	UINT32      const  usWidth  = pTrav.usWidth;

	// Add to start position of dest buffer
	INT32 const iTempX = iX + pTrav.sOffsetX;
	INT32 const iTempY = iY + pTrav.sOffsetY;

	if(clipregion==NULL)
	{
		ClipX1=ClippingRect.iLeft;
		ClipY1=ClippingRect.iTop;
		ClipX2=ClippingRect.iRight;
		ClipY2=ClippingRect.iBottom;
	}
	else
	{
		ClipX1=clipregion->iLeft;
		ClipY1=clipregion->iTop;
		ClipX2=clipregion->iRight;
		ClipY2=clipregion->iBottom;
	}

	// Calculate rows hanging off each side of the screen
	LeftSkip=__min(ClipX1 - MIN(ClipX1, iTempX), (INT32)usWidth);
	RightSkip=__min(MAX(ClipX2, (iTempX+(INT32)usWidth)) - ClipX2, (INT32)usWidth);
	TopSkip=__min(ClipY1 - __min(ClipY1, iTempY), (INT32)usHeight);
	BottomSkip=__min(__max(ClipY2, (iTempY+(INT32)usHeight)) - ClipY2, (INT32)usHeight);

	// calculate the remaining rows and columns to blit
	BlitLength=((INT32)usWidth-LeftSkip-RightSkip);
	BlitHeight=((INT32)usHeight-TopSkip-BottomSkip);

	// check if whole thing is clipped
	if((LeftSkip >=(INT32)usWidth) || (RightSkip >=(INT32)usWidth))
		return;

	// check if whole thing is clipped
	if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
		return;

	UINT8 const* SrcPtr = hSrcVObject->PixData(pTrav);
	DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
	ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
	LineSkip=(uiDestPitchBYTES-(BlitLength*2));

	uiLineFlag = (iTempY + TopSkip) & 1;

	UINT32 PxCount;

	while (TopSkip > 0)
	{
		for (;;)
		{
			PxCount = *SrcPtr++;
			if (PxCount & 0x80) continue;
			if (PxCount == 0) break;
			SrcPtr += PxCount;
		}
		TopSkip--;
	}

	do
	{
		for (LSCount = LeftSkip; LSCount > 0; LSCount -= PxCount)
		{
			PxCount = *SrcPtr++;
			if (PxCount & 0x80)
			{
				PxCount &= 0x7F;
				if (PxCount > static_cast<UINT32>(LSCount))
				{
					PxCount -= LSCount;
					LSCount = BlitLength;
					goto BlitTransparent;
				}
			}
			else
			{
				if (PxCount > static_cast<UINT32>(LSCount))
				{
					SrcPtr += LSCount;
					PxCount -= LSCount;
					LSCount = BlitLength;
					goto BlitNonTransLoop;
				}
				SrcPtr += PxCount;
			}
		}

		LSCount = BlitLength;
		while (LSCount > 0)
		{
			PxCount = *SrcPtr++;
			if (PxCount & 0x80)
			{
BlitTransparent: // skip transparent pixels
				PxCount &= 0x7F;
				if (PxCount > static_cast<UINT32>(LSCount)) PxCount = LSCount;
				LSCount -= PxCount;
				DestPtr += 2 * PxCount;
				ZPtr    += 2 * PxCount;
			}
			else
			{
BlitNonTransLoop: // blit non-transparent pixels
				if (PxCount > static_cast<UINT32>(LSCount))
				{
					Unblitted = PxCount - LSCount;
					PxCount = LSCount;
				}
				else
				{
					Unblitted = 0;
				}
				LSCount -= PxCount;

				do
				{
					UINT8 px = *SrcPtr++;

					if (px == 254)
					{
						if (*(UINT16*)ZPtr < usZValue)
						{
							*(UINT16*)DestPtr = ShadeTable[*(UINT16*)DestPtr];
						}
					}
					else
					{
						if (*(UINT16*)ZPtr <= usZValue ||
								uiLineFlag == (((uintptr_t)DestPtr & 2) != 0)) // XXX ugly, can be done better by just examining every other pixel
						{
							*(UINT16*)DestPtr = p16BPPPalette[px];
						}
					}
					DestPtr += 2;
					ZPtr += 2;
				}
				while (--PxCount > 0);
				SrcPtr += Unblitted;
			}
		}

		while (*SrcPtr++ != 0) {} // skip along until we hit and end-of-line marker
		DestPtr += LineSkip;
		ZPtr += LineSkip;
		uiLineFlag ^= 1;
	}
	while (--BlitHeight > 0);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferTransShadowZNBClip

	Blits an image into the destination buffer, using an ETRLE brush as a source, and a 16-bit
	buffer as a destination. As it is blitting, it checks the Z value of the ZBuffer, and if the
	pixel's Z level is below that of the current pixel, it is written on.
	The Z-buffer is 16 bit, and	must be the same dimensions (including Pitch) as the
	destination. Pixels with a value of	254 are shaded instead of blitted. The Z buffer is
	NOT updated.

**********************************************************************************************/
Blt8BPPDataTo16BPPBufferTransShadowZNBClip
Blits an image into the destination buffer, using an ETRLE brush as a source, and a 16-bit
buffer as a destination. As it is blitting, it checks the Z value of the ZBuffer, and if the
pixel's Z level is below that of the current pixel, it is written on.
The Z-buffer is 16 bit, and     must be the same dimensions (including Pitch) as the
destination. Pixels with a value of     254 are shaded instead of blitted. The Z buffer is
NOT updated.
Blt8BPPDataTo16BPPBufferTransShadowZNBClip Blits an image into the destination buffer using an ETRLE brush as a source and a 16 - bit buffer as a destination . As it is blitting it checks the Z value of the ZBuffer and if the pixel ' s Z level is below that of the current pixel it is written on . The Z - buffer is 16 bit and must be the same dimensions ( including Pitch ) as the destination . Pixels with a value of 254 are shaded instead of blitted . The Z buffer is NOT updated .
void Blt8BPPDataTo16BPPBufferTransShadowZNBObscuredClip(UINT16* pBuffer, UINT32 uiDestPitchBYTES, UINT16* pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect* clipregion, const UINT16* p16BPPPalette)
{
	UINT32 Unblitted, uiLineFlag;
	UINT8  *DestPtr, *ZPtr;
	UINT32 LineSkip;
	INT32  LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight, LSCount;
	INT32  ClipX1, ClipY1, ClipX2, ClipY2;
	Assert( hSrcVObject != NULL );
	Assert( pBuffer != NULL );
	ETRLEObject const& pTrav = hSrcVObject->SubregionProperties(usIndex);
	UINT32      const  usHeight = pTrav.usHeight;
	UINT32      const  usWidth  = pTrav.usWidth;
	INT32 const iTempX = iX + pTrav.sOffsetX;
	INT32 const iTempY = iY + pTrav.sOffsetY;
	if(clipregion==NULL)
	{
		ClipX1=ClippingRect.iLeft;
		ClipY1=ClippingRect.iTop;
		ClipX2=ClippingRect.iRight;
		ClipY2=ClippingRect.iBottom;
	}
	else
	{
		ClipX1=clipregion->iLeft;
		ClipY1=clipregion->iTop;
		ClipX2=clipregion->iRight;
		ClipY2=clipregion->iBottom;
	}
	LeftSkip=__min(ClipX1 - MIN(ClipX1, iTempX), (INT32)usWidth);
	RightSkip=__min(MAX(ClipX2, (iTempX+(INT32)usWidth)) - ClipX2, (INT32)usWidth);
	TopSkip=__min(ClipY1 - __min(ClipY1, iTempY), (INT32)usHeight);
	BottomSkip=__min(__max(ClipY2, (iTempY+(INT32)usHeight)) - ClipY2, (INT32)usHeight);
	BlitLength=((INT32)usWidth-LeftSkip-RightSkip);
	BlitHeight=((INT32)usHeight-TopSkip-BottomSkip);
	if((LeftSkip >=(INT32)usWidth) || (RightSkip >=(INT32)usWidth))
		return;
	if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
		return;
	UINT8 const* SrcPtr = hSrcVObject->PixData(pTrav);
	DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
	ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
	LineSkip=(uiDestPitchBYTES-(BlitLength*2));
	uiLineFlag = (iTempY + TopSkip) & 1;
	UINT32 PxCount;
	while (TopSkip > 0)
	{
		for (;;)
		{
			PxCount = *SrcPtr++;
			if (PxCount & 0x80) continue;
			if (PxCount == 0) break;
			SrcPtr += PxCount;
		}
		TopSkip--;
	}
	do
	{
		for (LSCount = LeftSkip; LSCount > 0; LSCount -= PxCount)
		{
			PxCount = *SrcPtr++;
			if (PxCount & 0x80)
			{
				PxCount &= 0x7F;
				if (PxCount > static_cast<UINT32>(LSCount))
				{
					PxCount -= LSCount;
					LSCount = BlitLength;
					goto BlitTransparent;
				}
			}
			else
			{
				if (PxCount > static_cast<UINT32>(LSCount))
				{
					SrcPtr += LSCount;
					PxCount -= LSCount;
					LSCount = BlitLength;
					goto BlitNonTransLoop;
				}
				SrcPtr += PxCount;
			}
		}
		LSCount = BlitLength;
		while (LSCount > 0)
		{
			PxCount = *SrcPtr++;
			if (PxCount & 0x80)
			{
BlitTransparent: 
				PxCount &= 0x7F;
				if (PxCount > static_cast<UINT32>(LSCount)) PxCount = LSCount;
				LSCount -= PxCount;
				DestPtr += 2 * PxCount;
				ZPtr    += 2 * PxCount;
			}
			else
			{
BlitNonTransLoop: 
				if (PxCount > static_cast<UINT32>(LSCount))
				{
					Unblitted = PxCount - LSCount;
					PxCount = LSCount;
				}
				else
				{
					Unblitted = 0;
				}
				LSCount -= PxCount;
				do
				{
					UINT8 px = *SrcPtr++;
					if (px == 254)
					{
						if (*(UINT16*)ZPtr < usZValue)
						{
							*(UINT16*)DestPtr = ShadeTable[*(UINT16*)DestPtr];
						}
					}
					else
					{
						if (*(UINT16*)ZPtr <= usZValue ||
								uiLineFlag == (((uintptr_t)DestPtr & 2) != 0)) 
						{
							*(UINT16*)DestPtr = p16BPPPalette[px];
						}
					}
					DestPtr += 2;
					ZPtr += 2;
				}
				while (--PxCount > 0);
				SrcPtr += Unblitted;
			}
		}
		while (*SrcPtr++ != 0) {} 
		DestPtr += LineSkip;
		ZPtr += LineSkip;
		uiLineFlag ^= 1;
	}
	while (--BlitHeight > 0);
}
void Blt8BPPDataTo16BPPBufferTransShadowZNBObscuredClip ( UINT16 * pBuffer , UINT32 uiDestPitchBYTES , UINT16 * pZBuffer , UINT16 usZValue , HVOBJECT hSrcVObject , INT32 iX , INT32 iY , UINT16 usIndex , SGPRect * clipregion , const UINT16 * p16BPPPalette ) { UINT32 Unblitted , uiLineFlag ; UINT8 * DestPtr , * ZPtr ; UINT32 LineSkip ; INT32 LeftSkip , RightSkip , TopSkip , BottomSkip , BlitLength , BlitHeight , LSCount ; INT32 ClipX1 , ClipY1 , ClipX2 , ClipY2 ; Assert ( hSrcVObject != NULL ) ; Assert ( pBuffer != NULL ) ; ETRLEObject const & pTrav = hSrcVObject -> SubregionProperties ( usIndex ) ; UINT32 const usHeight = pTrav . usHeight ; UINT32 const usWidth = pTrav . usWidth ; INT32 const iTempX = iX + pTrav . sOffsetX ; INT32 const iTempY = iY + pTrav . sOffsetY ; if ( clipregion == NULL ) { ClipX1 = ClippingRect . iLeft ; ClipY1 = ClippingRect . iTop ; ClipX2 = ClippingRect . iRight ; ClipY2 = ClippingRect . iBottom ; } else { ClipX1 = clipregion -> iLeft ; ClipY1 = clipregion -> iTop ; ClipX2 = clipregion -> iRight ; ClipY2 = clipregion -> iBottom ; } LeftSkip = __min ( ClipX1 - MIN ( ClipX1 , iTempX ) , ( INT32 ) usWidth ) ; RightSkip = __min ( MAX ( ClipX2 , ( iTempX + ( INT32 ) usWidth ) ) - ClipX2 , ( INT32 ) usWidth ) ; TopSkip = __min ( ClipY1 - __min ( ClipY1 , iTempY ) , ( INT32 ) usHeight ) ; BottomSkip = __min ( __max ( ClipY2 , ( iTempY + ( INT32 ) usHeight ) ) - ClipY2 , ( INT32 ) usHeight ) ; BlitLength = ( ( INT32 ) usWidth - LeftSkip - RightSkip ) ; BlitHeight = ( ( INT32 ) usHeight - TopSkip - BottomSkip ) ; if ( ( LeftSkip >= ( INT32 ) usWidth ) || ( RightSkip >= ( INT32 ) usWidth ) ) return ; if ( ( TopSkip >= ( INT32 ) usHeight ) || ( BottomSkip >= ( INT32 ) usHeight ) ) return ; UINT8 const * SrcPtr = hSrcVObject -> PixData ( pTrav ) ; DestPtr = ( UINT8 * ) pBuffer + ( uiDestPitchBYTES * ( iTempY + TopSkip ) ) + ( ( iTempX + LeftSkip ) * 2 ) ; ZPtr = ( UINT8 * ) pZBuffer + ( uiDestPitchBYTES * ( iTempY + TopSkip ) ) + ( ( iTempX + LeftSkip ) * 2 ) ; LineSkip = ( uiDestPitchBYTES - ( BlitLength * 2 ) ) ; uiLineFlag = ( iTempY + TopSkip ) & 1 ; UINT32 PxCount ; while ( TopSkip > 0 ) { for ( ; ; ) { PxCount = * SrcPtr ++ ; if ( PxCount & 0x80 ) continue ; if ( PxCount == 0 ) break ; SrcPtr += PxCount ; } TopSkip -- ; } do { for ( LSCount = LeftSkip ; LSCount > 0 ; LSCount -= PxCount ) { PxCount = * SrcPtr ++ ; if ( PxCount & 0x80 ) { PxCount &= 0x7F ; if ( PxCount > static_cast < UINT32 > ( LSCount ) ) { PxCount -= LSCount ; LSCount = BlitLength ; goto BlitTransparent ; } } else { if ( PxCount > static_cast < UINT32 > ( LSCount ) ) { SrcPtr += LSCount ; PxCount -= LSCount ; LSCount = BlitLength ; goto BlitNonTransLoop ; } SrcPtr += PxCount ; } } LSCount = BlitLength ; while ( LSCount > 0 ) { PxCount = * SrcPtr ++ ; if ( PxCount & 0x80 ) { BlitTransparent : PxCount &= 0x7F ; if ( PxCount > static_cast < UINT32 > ( LSCount ) ) PxCount = LSCount ; LSCount -= PxCount ; DestPtr += 2 * PxCount ; ZPtr += 2 * PxCount ; } else { BlitNonTransLoop : if ( PxCount > static_cast < UINT32 > ( LSCount ) ) { Unblitted = PxCount - LSCount ; PxCount = LSCount ; } else { Unblitted = 0 ; } LSCount -= PxCount ; do { UINT8 px = * SrcPtr ++ ; if ( px == 254 ) { if ( * ( UINT16 * ) ZPtr < usZValue ) { * ( UINT16 * ) DestPtr = ShadeTable [ * ( UINT16 * ) DestPtr ] ; } } else { if ( * ( UINT16 * ) ZPtr <= usZValue || uiLineFlag == ( ( ( uintptr_t ) DestPtr & 2 ) != 0 ) ) { * ( UINT16 * ) DestPtr = p16BPPPalette [ px ] ; } } DestPtr += 2 ; ZPtr += 2 ; } while ( -- PxCount > 0 ) ; SrcPtr += Unblitted ; } } while ( * SrcPtr ++ != 0 ) { } DestPtr += LineSkip ; ZPtr += LineSkip ; uiLineFlag ^= 1 ; } while ( -- BlitHeight > 0 ) ; }
Blt8BPPDataTo16BPPBufferTransShadowZNBClip
Blits an image into the destination buffer, using an ETRLE brush as a source, and a 16-bit
buffer as a destination.
Blt8BPPDataTo16BPPBufferTransShadowZNBClip Blits an image into the destination buffer using an ETRLE brush as a source and a 16 - bit buffer as a destination .
// Assertions // Get Offsets from Index into structure // Add to start position of dest buffer // Calculate rows hanging off each side of the screen // calculate the remaining rows and columns to blit // check if whole thing is clipped // check if whole thing is clipped // skip transparent pixels // blit non-transparent pixels // XXX ugly, can be done better by just examining every other pixel // skip along until we hit and end-of-line marker