src/sgp/VObject_Blitters.cc
void Blt8BPPDataTo16BPPBufferTransZClipPixelateObscured( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion)
{
	UINT32 uiLineFlag;
	UINT32 Unblitted;
	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);
	UINT16 const* const p16BPPPalette = hSrcVObject->CurrentShade();
	LineSkip=(uiDestPitchBYTES-(BlitLength*2));
	uiLineFlag=(iTempY&1);

	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
				{
					if (*(UINT16*)ZPtr < usZValue)
					{
						*(UINT16*)ZPtr = usZValue;
					}
					else
					{
						if (uiLineFlag != (((uintptr_t)DestPtr & 2) != 0)) continue;
					}
					*(UINT16*)DestPtr = p16BPPPalette[*SrcPtr];
				}
				while (SrcPtr++, DestPtr += 2, ZPtr += 2, --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);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferTransZClipPixelateObscured

	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, and the Z value is
	NOT updated to the current value,	for any non-transparent pixels. The Z-buffer is 16 bit, and
	must be the same dimensions (including Pitch) as the destination.

	Blits every second pixel ("pixelates").

**********************************************************************************************/
Blt8BPPDataTo16BPPBufferTransZClipPixelateObscured
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, and the Z value is
NOT updated to the current value,       for any non-transparent pixels. The Z-buffer is 16 bit, and
must be the same dimensions (including Pitch) as the destination.

Blits every second pixel ("pixelates").
Blt8BPPDataTo16BPPBufferTransZClipPixelateObscured 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 and the Z value is NOT updated to the current value for any non - transparent pixels . The Z - buffer is 16 bit and must be the same dimensions ( including Pitch ) as the destination . Blits every second pixel ( " pixelates " ) .
void Blt8BPPDataTo16BPPBufferTransZClipPixelateObscured( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion)
{
	UINT32 uiLineFlag;
	UINT32 Unblitted;
	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);
	UINT16 const* const p16BPPPalette = hSrcVObject->CurrentShade();
	LineSkip=(uiDestPitchBYTES-(BlitLength*2));
	uiLineFlag=(iTempY&1);
	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
				{
					if (*(UINT16*)ZPtr < usZValue)
					{
						*(UINT16*)ZPtr = usZValue;
					}
					else
					{
						if (uiLineFlag != (((uintptr_t)DestPtr & 2) != 0)) continue;
					}
					*(UINT16*)DestPtr = p16BPPPalette[*SrcPtr];
				}
				while (SrcPtr++, DestPtr += 2, ZPtr += 2, --PxCount > 0);
				SrcPtr += Unblitted;
			}
		}
		while (*SrcPtr++ != 0) {} 
		DestPtr += LineSkip;
		ZPtr += LineSkip;
		uiLineFlag ^= 1;
	}
	while (--BlitHeight > 0);
}
void Blt8BPPDataTo16BPPBufferTransZClipPixelateObscured ( UINT16 * pBuffer , UINT32 uiDestPitchBYTES , UINT16 * pZBuffer , UINT16 usZValue , HVOBJECT hSrcVObject , INT32 iX , INT32 iY , UINT16 usIndex , SGPRect * clipregion ) { UINT32 uiLineFlag ; UINT32 Unblitted ; 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 ) ; UINT16 const * const p16BPPPalette = hSrcVObject -> CurrentShade ( ) ; LineSkip = ( uiDestPitchBYTES - ( BlitLength * 2 ) ) ; uiLineFlag = ( iTempY & 1 ) ; 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 { if ( * ( UINT16 * ) ZPtr < usZValue ) { * ( UINT16 * ) ZPtr = usZValue ; } else { if ( uiLineFlag != ( ( ( uintptr_t ) DestPtr & 2 ) != 0 ) ) continue ; } * ( UINT16 * ) DestPtr = p16BPPPalette [ * SrcPtr ] ; } while ( SrcPtr ++ , DestPtr += 2 , ZPtr += 2 , -- PxCount > 0 ) ; SrcPtr += Unblitted ; } } while ( * SrcPtr ++ != 0 ) { } DestPtr += LineSkip ; ZPtr += LineSkip ; uiLineFlag ^= 1 ; } while ( -- BlitHeight > 0 ) ; }
Blt8BPPDataTo16BPPBufferTransZClipPixelateObscured
Blits an image into the destination buffer, using an ETRLE brush as a source, and a 16-bit
buffer as a destination.
Blt8BPPDataTo16BPPBufferTransZClipPixelateObscured 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 // skip along until we hit and end-of-line marker