Files
source/Standard Gaming Platform/vobject_blitters.cpp
T

20233 lines
448 KiB
C++

#ifdef JA2_PRECOMPILED_HEADERS
#include "JA2 SGP ALL.H"
#elif defined( WIZ8_PRECOMPILED_HEADERS )
#include "WIZ8 SGP ALL.H"
#else
#include "DirectDraw Calls.h"
#include <stdio.h>
#include "debug.h"
#if defined( JA2 ) || defined( UTIL )
#include "video.h" // JA2
#else
#include "video2.h" // Wiz8
#endif
#include "himage.h"
#include "vobject.h"
#include "wcheck.h"
#include "vobject.h"
#include "vobject_blitters.h"
#include "shading.h"
#include "sgp_logger.h"
#endif
#include <map>
std::map<UINT32,ClipRectangle> g_SurfaceRectangle;
static UINT8 g_AlphaTimesValueCache[256][256];
static const unsigned short maxChar = 0xff;
unsigned short blendWithAlpha(unsigned int rgb565New, unsigned int rgb565Old, unsigned int alpha)
{
unsigned short value = 0;
float alphaF;
unsigned short oldR, oldG, oldB, newR, newG, newB, outR, outG, outB;
unsigned short alphaC = (unsigned short)alpha;
__asm {
xor ebx, ebx
xor ecx, ecx
mov ecx, rgb565Old
xor eax, eax
xor edx, edx
mov ax, cx
shr ax, 11
xor ah, ah
mov oldR, ax
xor edx, edx
mov ax, cx
and ax, 0x7e0
shr ax, 5
xor ah, ah
mov oldG, ax
xor edx, edx
mov ax, cx
and ax, 0x1f
xor ah, ah
mov oldB, ax
xor ebx, ebx
xor ecx, ecx
mov ecx, rgb565New
xor eax, eax
xor edx, edx
mov ax, cx
shr ax, 11
xor ah, ah
mov newR, ax
xor edx, edx
mov ax, cx
and ax, 0x7e0
shr ax, 5
xor ah, ah
mov newG, ax
xor edx, edx
mov ax, cx
and ax, 0x1f
xor ah, ah
mov newB, ax
fld1
fild alphaC
fild maxChar
fdiv
fst alphaF
fsub
fild oldR
fmul
fild newR
fld alphaF
fmul
fadd
fistp outR
fld1
fild alphaC
fild maxChar
fdiv
fst alphaF
fsub
fild oldG
fmul
fild newG
fld alphaF
fmul
fadd
fistp outG
fld1
fild alphaC
fild maxChar
fdiv
fst alphaF
fsub
fild oldB
fmul
fild newB
fld alphaF
fmul
fadd
fistp outB
xor eax, eax
xor ebx, ebx
mov ax, outB
mov bx, outG
shl bx, 5
add eax, ebx
mov bx, outR
shl bx, 11
add eax, ebx
mov value, ax
}
return value;
}
class InitAlphaTimesValueCache
{
public:
InitAlphaTimesValueCache()
{
for(unsigned int alpha = 0; alpha < 256; alpha++)
{
for(unsigned int val = 0; val < 256; val++)
{
// it can't get any simpler than that
g_AlphaTimesValueCache[alpha][val] = (UINT8)( ((double)alpha/255.0) * val );
}
}
}
};
static InitAlphaTimesValueCache s_InitAlphaCache;
BOOLEAN Blt32BPPTo16BPPTrans(UINT16 *pDest, UINT32 uiDestPitch, UINT32 *pSrc, UINT32 uiSrcPitch, INT32 iDestXPos, INT32 iDestYPos, INT32 iSrcXPos, INT32 iSrcYPos, UINT32 uiWidth, UINT32 uiHeight)
{
UINT32 *pSrcPtr;
UINT16 *pDestPtr;
UINT32 uiLineSkipDest, uiLineSkipSrc;
Assert(pDest!=NULL);
Assert(pSrc!=NULL);
pSrcPtr = (UINT32 *)((UINT8 *)pSrc+(iSrcYPos*uiSrcPitch)+(iSrcXPos*4));
uiLineSkipSrc = uiSrcPitch-(uiWidth*4);
pDestPtr = (UINT16 *)((UINT8 *)pDest+(iDestYPos*uiDestPitch)+(iDestXPos*2));
uiLineSkipDest = uiDestPitch-(uiWidth*2);
UINT8 alpha, dst_channel, src_channel;
UINT8 red, green, blue;
do
{
UINT32 w = uiWidth;
do
{
// a
alpha = (UINT8)((0xFF000000 & *pSrcPtr) >> 24);
//alpha = 255;
if(alpha > 0)
{
// r
dst_channel = (UINT8)((0x1F & *pDestPtr) << 3);
src_channel = (UINT8)((0xFF & *pSrcPtr) );
red = (UINT8)( g_AlphaTimesValueCache[255-alpha][dst_channel] + g_AlphaTimesValueCache[alpha][src_channel] );
//red = (UINT8)( g_AlphaTimesValueCache[alpha][src_channel] );
// g
dst_channel = (UINT8)((0x7E0 & *pDestPtr) >> 3);
src_channel = (UINT8)((0xFF00 & *pSrcPtr) >> 8);
green = (UINT8)( g_AlphaTimesValueCache[255-alpha][dst_channel] + g_AlphaTimesValueCache[alpha][src_channel] );
//green = (UINT8)( g_AlphaTimesValueCache[alpha][src_channel] );
// b
dst_channel = (UINT8)((0xF800 & *pDestPtr) >> 8);
src_channel = (UINT8)((0xFF0000 & *pSrcPtr) >> 16);
blue = (UINT8)( g_AlphaTimesValueCache[255-alpha][dst_channel] + g_AlphaTimesValueCache[alpha][src_channel] );
//blue = (UINT8)( g_AlphaTimesValueCache[alpha][src_channel] );
UINT32 newcolor = FROMRGB(red,green,blue);
*pDestPtr = Get16BPPColor(newcolor);
}
pSrcPtr++;
pDestPtr++;
}
while (--w != 0);
pSrcPtr = (UINT32*)((UINT8*)pSrcPtr + uiLineSkipSrc);
pDestPtr = (UINT16*)((UINT8*)pDestPtr + uiLineSkipDest);
}
while (--uiHeight != 0);
return ( TRUE );
}
BOOLEAN Blt32BPPTo16BPPTransShadow(UINT16 *pDst, UINT32 uiDstPitch, UINT32 *pSrc, UINT32 uiSrcPitch, INT32 iDstXPos, INT32 iDstYPos, INT32 iSrcXPos, INT32 iSrcYPos, UINT32 uiWidth, UINT32 uiHeight)
{
UINT32 *pSrcPtr;
UINT16 *pDstPtr;
UINT32 uiLineSkipDst, uiLineSkipSrc;
Assert(pDst!=NULL);
Assert(pSrc!=NULL);
pSrcPtr = (UINT32*)((UINT8*)pSrc + (iSrcYPos * uiSrcPitch) + (iSrcXPos * 4));
uiLineSkipSrc = uiSrcPitch-(uiWidth*4);
pDstPtr = (UINT16*)((UINT8*)pDst + (iDstYPos * uiDstPitch) + (iDstXPos * 2));
uiLineSkipDst = uiDstPitch-(uiWidth*2);
UINT8 alpha, dst_channel, src_channel;
UINT8 red, green, blue;
UINT16 tmpVal;
UINT32 newcolor;
do
{
UINT32 w = uiWidth;
do
{
// a
alpha = (UINT8)((0xFF000000 & *pSrcPtr) >> 24);
//alpha = 255;
if(alpha > 0)
{
#if 1
// the darker shade
tmpVal = ShadeTable[*pDstPtr];
// r
dst_channel = (UINT8)((0x1F & *pDstPtr) << 3);
//src_channel = (UINT8)((0xFF & tmpVal) );
src_channel = (UINT8)((0x1F & tmpVal) << 3);
red = (UINT8)( g_AlphaTimesValueCache[255-alpha][dst_channel] + g_AlphaTimesValueCache[alpha][src_channel] );
// g
dst_channel = (UINT8)((0x7E0 & *pDstPtr) >> 3);
//src_channel = (UINT8)((0xFF00 & tmpVal) >> 8);
src_channel = (UINT8)((0x7E0 & tmpVal) >> 3);
green = (UINT8)( g_AlphaTimesValueCache[255-alpha][dst_channel] + g_AlphaTimesValueCache[alpha][src_channel] );
// b
dst_channel = (UINT8)((0xF800 & *pDstPtr) >> 8);
//src_channel = (UINT8)((0xFF0000 & tmpVal) >> 16);
src_channel = (UINT8)((0xF800 & tmpVal) >> 8);
blue = (UINT8)( g_AlphaTimesValueCache[255-alpha][dst_channel] + g_AlphaTimesValueCache[alpha][src_channel] );
newcolor = FROMRGB(red,green,blue);
*pDstPtr = Get16BPPColor(newcolor);
#else
*pDstPtr = ShadeTable[*pDstPtr];
#endif
}
pSrcPtr++;
pDstPtr++;
}
while (--w != 0);
pSrcPtr = (UINT32*)((UINT8*)pSrcPtr + uiLineSkipSrc);
pDstPtr = (UINT16*)((UINT8*)pDstPtr + uiLineSkipDst);
}
while (--uiHeight != 0);
return ( TRUE );
}
/* Here are bliting functions. If you dont know what kind of functions they are so :
* correct me if im wrong they copy array of bits from src image to dest image
* maby we can get ride this includes above? we dont need theme here i thinks so
* any questions? joker
*/
/* ClipingRect was declared here with static initializer
* We need to change that and initialize it in run-time
* any questions? joker
*/
SGPRect ClippingRect;
UINT32 guiTranslucentMask=0x3def; //0x7bef; // mask for halving 5,6,5
// GLOBALS for pre-calculating skip values
INT32 gLeftSkip, gRightSkip, gTopSkip, gBottomSkip;
BOOLEAN gfUsePreCalcSkips = FALSE;
//*Experimental**********************************************************************
/**********************************************************************************************
Blt16BPPDataTo16BPPBufferTransZClip
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
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.
**********************************************************************************************/
BOOLEAN Blt16BPPDataTo16BPPBufferTransZClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion)
{
UINT16 *p16BPPPalette;
UINT32 uiOffset;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, 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
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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(TRUE);
// check if whole thing is clipped
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
return(TRUE);
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
p16BPPPalette = hSrcVObject->pShadeCurrent;
LineSkip=(uiDestPitchBYTES-(BlitLength*2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
cmp TopSkip, 0 // check for nothing clipped on top
je LeftSkipSetup
TopSkipLoop: // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
add esi, ecx
jmp TopSkipLoop
TSEndLine:
dec TopSkip
jnz TopSkipLoop
LeftSkipSetup:
mov Unblitted, 0
mov eax, LeftSkip
mov LSCount, eax
or eax, eax
jz BlitLineSetup
LeftSkipLoop:
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, LSCount
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, LSCount // skip partial run, jump into normal loop for rest
add esi, LSCount // skip partial run, jump into normal loop for rest
sub ecx, LSCount
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2:
add esi, ecx // skip whole run, and start blit with new run
add esi, ecx // skip whole run, and start blit with new run
jmp BlitLineSetup
LSSkip1:
add esi, ecx // skip whole run, continue skipping
add esi, ecx // skip whole run, continue skipping
sub LSCount, ecx
jmp LeftSkipLoop
LSTrans:
and ecx, 07fH
cmp ecx, LSCount
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, LSCount // skip partial run, jump into normal loop for rest
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitTransparent
LSTrans1:
sub LSCount, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup: // Does any actual blitting (trans/non) for the line
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
BlitDispatch:
cmp LSCount, 0 // Check to see if we're done blitting
je RightSkipLoop
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
BlitNonTransLoop: // blit non-transparent pixels
cmp ecx, LSCount
jbe BNTrans1
sub ecx, LSCount
mov Unblitted, ecx
mov ecx, LSCount
BNTrans1:
sub LSCount, ecx
BlitNTL1:
mov ax, [ebx]
cmp ax, usZValue
ja BlitNTL2
mov ax, usZValue
mov [ebx], ax
xor eax, eax
mov ax, [esi]
mov [edi], ax
BlitNTL2:
add esi, 2
add edi, 2
add ebx, 2
dec cl
jnz BlitNTL1
//BlitLineEnd:
add esi, Unblitted
add esi, Unblitted
jmp BlitDispatch
BlitTransparent: // skip transparent pixels
and ecx, 07fH
cmp ecx, LSCount
jbe BTrans1
mov ecx, LSCount
BTrans1:
sub LSCount, ecx
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
RightSkipLoop: // skip along until we hit and end-of-line marker
xor eax, eax
RSLoop1:
mov al, [esi]
inc esi
or al, al
js RSLoop1
jz RSEnd
add esi, eax
add esi, eax
jmp RSLoop1
RSEnd:
dec BlitHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
jmp LeftSkipSetup
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt16BPPDataTo16BPPBufferTransparentClip
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
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.
**********************************************************************************************/
BOOLEAN Blt16BPPDataTo16BPPBufferTransparentClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion)
{
//UINT16 *p16BPPPalette;
//UINT32 uiOffset;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr;
UINT32 LineSkip;
//ETRLEObject *pTrav;
INT32 iTempX, iTempY, LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight, LSCount;
INT32 ClipX1, ClipY1, ClipX2, ClipY2;
SixteenBPPObjectInfo * p16BPPObject;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
p16BPPObject=&(hSrcVObject->p16BPPObject[usIndex]);
// Get Offsets from Index into structure
usHeight = p16BPPObject->usHeight;
usWidth = p16BPPObject->usWidth;
// Add to start position of dest buffer
iTempX = iX + p16BPPObject->sOffsetX;
iTempY = iY + p16BPPObject->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;
}
if ( gfUsePreCalcSkips )
{
LeftSkip= gLeftSkip;
RightSkip= gRightSkip;
TopSkip= gTopSkip;
BottomSkip= gBottomSkip;
gfUsePreCalcSkips = FALSE;
}
else
{
// 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(TRUE);
// check if whole thing is clipped
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
return(TRUE);
SrcPtr= (UINT8 *)p16BPPObject->p16BPPData;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
LineSkip=(uiDestPitchBYTES-(BlitLength*2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
// mov edx, p16BPPPalette
xor eax, eax
// mov ebx, ZPtr
xor ecx, ecx
cmp TopSkip, 0 // check for nothing clipped on top
je LeftSkipSetup
TopSkipLoop: // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
add esi, ecx
jmp TopSkipLoop
TSEndLine:
dec TopSkip
jnz TopSkipLoop
LeftSkipSetup:
mov Unblitted, 0
mov eax, LeftSkip
mov LSCount, eax
or eax, eax
jz BlitLineSetup
LeftSkipLoop:
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, LSCount
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, LSCount // skip partial run, jump into normal loop for rest
add esi, LSCount // skip partial run, jump into normal loop for rest
sub ecx, LSCount
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2:
add esi, ecx // skip whole run, and start blit with new run
add esi, ecx // skip whole run, and start blit with new run
jmp BlitLineSetup
LSSkip1:
add esi, ecx // skip whole run, continue skipping
add esi, ecx // skip whole run, continue skipping
sub LSCount, ecx
jmp LeftSkipLoop
LSTrans:
and ecx, 07fH
cmp ecx, LSCount
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, LSCount // skip partial run, jump into normal loop for rest
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitTransparent
LSTrans1:
sub LSCount, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup: // Does any actual blitting (trans/non) for the line
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
BlitDispatch:
cmp LSCount, 0 // Check to see if we're done blitting
je RightSkipLoop
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
BlitNonTransLoop: // blit non-transparent pixels
cmp ecx, LSCount
jbe BNTrans1
sub ecx, LSCount
mov Unblitted, ecx
mov ecx, LSCount
BNTrans1:
sub LSCount, ecx
//BlitNTL1:
rep movsw
//BlitNTL2:
//BlitLineEnd:
add esi, Unblitted
add esi, Unblitted
jmp BlitDispatch
BlitTransparent: // skip transparent pixels
and ecx, 07fH
cmp ecx, LSCount
jbe BTrans1
mov ecx, LSCount
BTrans1:
sub LSCount, ecx
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
RightSkipLoop: // skip along until we hit and end-of-line marker
xor eax, eax
RSLoop1:
mov al, [esi]
inc esi
or al, al
js RSLoop1
jz RSEnd
add esi, eax
add esi, eax
jmp RSLoop1
RSEnd:
dec BlitHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
jmp LeftSkipSetup
BlitDone:
}
return(TRUE);
}
/***********************************************************************************/
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferTransZNBClipTranslucent
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 ("Translucents").
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferTransZNBClipTranslucent( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion)
{
UINT16 *p16BPPPalette;
UINT32 uiOffset, uiLineFlag;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, 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
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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(TRUE);
// check if whole thing is clipped
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
return(TRUE);
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
p16BPPPalette = hSrcVObject->pShadeCurrent;
LineSkip=(uiDestPitchBYTES-(BlitLength*2));
uiLineFlag=(iTempY&1);
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
cmp TopSkip, 0 // check for nothing clipped on top
je LeftSkipSetup
TopSkipLoop: // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
jmp TopSkipLoop
TSEndLine:
dec TopSkip
jnz TopSkipLoop
LeftSkipSetup:
mov Unblitted, 0
mov eax, LeftSkip
mov LSCount, eax
or eax, eax
jz BlitLineSetup
LeftSkipLoop:
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, LSCount
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, LSCount // skip partial run, jump into normal loop for rest
sub ecx, LSCount
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2:
add esi, ecx // skip whole run, and start blit with new run
jmp BlitLineSetup
LSSkip1:
add esi, ecx // skip whole run, continue skipping
sub LSCount, ecx
jmp LeftSkipLoop
LSTrans:
and ecx, 07fH
cmp ecx, LSCount
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, LSCount // skip partial run, jump into normal loop for rest
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitTransparent
LSTrans1:
sub LSCount, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup: // Does any actual blitting (trans/non) for the line
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
BlitDispatch:
cmp LSCount, 0 // Check to see if we're done blitting
je RightSkipLoop
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
BlitNonTransLoop: // blit non-transparent pixels
cmp ecx, LSCount
jbe BNTrans1
sub ecx, LSCount
mov Unblitted, ecx
mov ecx, LSCount
BNTrans1:
sub LSCount, ecx
BlitNTL1:
mov ax, [ebx]
cmp ax, usZValue
ja BlitNTL2
xor eax, eax
mov edx, p16BPPPalette
mov al, [esi]
mov ax, [edx+eax*2]
shr eax, 1
and eax, [guiTranslucentMask]
xor edx, edx
mov dx, [edi]
shr edx, 1
and edx, [guiTranslucentMask]
add eax, edx
mov [edi], ax
BlitNTL2:
inc esi
add edi, 2
add ebx, 2
dec cl
jnz BlitNTL1
//BlitLineEnd:
add esi, Unblitted
jmp BlitDispatch
BlitTransparent: // skip transparent pixels
and ecx, 07fH
cmp ecx, LSCount
jbe BTrans1
mov ecx, LSCount
BTrans1:
sub LSCount, ecx
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
RightSkipLoop: // skip along until we hit and end-of-line marker
RSLoop1:
mov al, [esi]
inc esi
or al, al
jnz RSLoop1
dec BlitHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
jmp LeftSkipSetup
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferTransZTranslucent
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
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 ("Translucents").
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferTransZTranslucent( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex )
{
UINT32 usHeight, usWidth, uiOffset, LineSkip;
INT32 iTempX, iTempY;
UINT16 *p16BPPPalette;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 uiLineFlag;
ETRLEObject *pTrav;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
p16BPPPalette = hSrcVObject->pShadeCurrent;
LineSkip=(uiDestPitchBYTES-(usWidth*2));
uiLineFlag=(iTempY&1);
__asm {
mov esi, SrcPtr
mov edi, DestPtr
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
// mov edx, p16BPPPalette
BlitDispatch:
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
BlitNTL4:
mov ax, [ebx]
cmp ax, usZValue
ja BlitNTL5
mov ax, usZValue
mov [ebx], ax
xor eax, eax
mov edx, p16BPPPalette
mov al, [esi]
mov ax, [edx+eax*2]
shr eax, 1
and eax, guiTranslucentMask
xor edx, edx
mov dx, [edi]
shr edx, 1
and edx, guiTranslucentMask
add eax, edx
mov [edi], ax
BlitNTL5:
inc esi
add edi, 2
add ebx, 2
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
BlitDoneLine:
dec usHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
xor uiLineFlag, 1
jmp BlitDispatch
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferTransZClipTranslucent
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
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 ("Translucents").
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferTransZClipTranslucent( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion)
{
UINT16 *p16BPPPalette;
UINT32 uiOffset, uiLineFlag;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, 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
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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(TRUE);
// check if whole thing is clipped
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
return(TRUE);
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
p16BPPPalette = hSrcVObject->pShadeCurrent;
LineSkip=(uiDestPitchBYTES-(BlitLength*2));
uiLineFlag=(iTempY&1);
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
cmp TopSkip, 0 // check for nothing clipped on top
je LeftSkipSetup
TopSkipLoop: // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
jmp TopSkipLoop
TSEndLine:
dec TopSkip
jnz TopSkipLoop
LeftSkipSetup:
mov Unblitted, 0
mov eax, LeftSkip
mov LSCount, eax
or eax, eax
jz BlitLineSetup
LeftSkipLoop:
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, LSCount
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, LSCount // skip partial run, jump into normal loop for rest
sub ecx, LSCount
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2:
add esi, ecx // skip whole run, and start blit with new run
jmp BlitLineSetup
LSSkip1:
add esi, ecx // skip whole run, continue skipping
sub LSCount, ecx
jmp LeftSkipLoop
LSTrans:
and ecx, 07fH
cmp ecx, LSCount
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, LSCount // skip partial run, jump into normal loop for rest
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitTransparent
LSTrans1:
sub LSCount, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup: // Does any actual blitting (trans/non) for the line
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
BlitDispatch:
cmp LSCount, 0 // Check to see if we're done blitting
je RightSkipLoop
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
BlitNonTransLoop: // blit non-transparent pixels
cmp ecx, LSCount
jbe BNTrans1
sub ecx, LSCount
mov Unblitted, ecx
mov ecx, LSCount
BNTrans1:
sub LSCount, ecx
BlitNTL1:
mov ax, [ebx]
cmp ax, usZValue
ja BlitNTL2
mov ax, usZValue
mov [ebx], ax
xor eax, eax
mov edx, p16BPPPalette
mov al, [esi]
mov ax, [edx+eax*2]
xor edx, edx
shr eax, 1
mov dx, [edi]
and eax, [guiTranslucentMask]
shr edx, 1
and edx, [guiTranslucentMask]
add eax, edx
mov [edi], ax
BlitNTL2:
inc esi
add edi, 2
add ebx, 2
dec cl
jnz BlitNTL1
//BlitLineEnd:
add esi, Unblitted
jmp BlitDispatch
BlitTransparent: // skip transparent pixels
and ecx, 07fH
cmp ecx, LSCount
jbe BTrans1
mov ecx, LSCount
BTrans1:
sub LSCount, ecx
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
RightSkipLoop: // skip along until we hit and end-of-line marker
RSLoop1:
mov al, [esi]
inc esi
or al, al
jnz RSLoop1
xor uiLineFlag, 1
dec BlitHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
jmp LeftSkipSetup
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferTransZNBTranslucent
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 ("Translucents").
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferTransZNBTranslucent( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex )
{
UINT32 usHeight, usWidth, uiOffset, LineSkip;
INT32 iTempX, iTempY;
UINT16 *p16BPPPalette;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 uiLineFlag;
ETRLEObject *pTrav;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
p16BPPPalette = hSrcVObject->pShadeCurrent;
LineSkip=(uiDestPitchBYTES-(usWidth*2));
uiLineFlag=(iTempY&1);
__asm {
mov esi, SrcPtr
mov edi, DestPtr
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
mov edx, p16BPPPalette
BlitDispatch:
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
BlitNTL4:
mov ax, [ebx]
cmp ax, usZValue
ja BlitNTL5
xor edx, edx
xor eax, eax
mov edx, p16BPPPalette
mov al, [esi]
mov ax, [edx+eax*2]
shr eax, 1
mov dx, [edi]
and eax, [guiTranslucentMask]
shr edx, 1
and edx, [guiTranslucentMask]
add eax, edx
mov [edi], ax
BlitNTL5:
inc esi
add edi, 2
add ebx, 2
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
BlitDoneLine:
dec usHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
xor uiLineFlag, 1
jmp BlitDispatch
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo8BPPBufferTransZIncClip
Used for large brushes (larger vertically than a single tile). Increments the Z
value by Z_SUBLAYERS for every WORLD_TILE_Y lines of pixels blitted.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo8BPPBufferTransZIncClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion)
{
UINT32 uiOffset;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip, LineSkipZ;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight, LSCount;
INT32 ClipX1, ClipY1, ClipX2, ClipY2;
UINT8 *pPal8BPP;
UINT16 usZLevel, usZLinesToGo;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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(TRUE);
// check if whole thing is clipped
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
return(TRUE);
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip));
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*2*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
pPal8BPP = hSrcVObject->pShade8;
LineSkip=(uiDestPitchBYTES-(BlitLength));
LineSkipZ=LineSkip*2;
usZLevel=usZValue;
// usZLinesToGo=WORLD_TILE_Y;
__asm {
mov esi, SrcPtr
mov edi, DestPtr
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
mov edx, pPal8BPP
cmp TopSkip, 0 // check for nothing clipped on top
je LeftSkipSetup
TopSkipLoop: // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
jmp TopSkipLoop
TSEndLine:
dec TopSkip
jnz TopSkipLoop
LeftSkipSetup:
mov Unblitted, 0
mov eax, LeftSkip
mov LSCount, eax
or eax, eax
jz BlitLineSetup
LeftSkipLoop:
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, LSCount
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, LSCount // skip partial run, jump into normal loop for rest
sub ecx, LSCount
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2:
add esi, ecx // skip whole run, and start blit with new run
jmp BlitLineSetup
LSSkip1:
add esi, ecx // skip whole run, continue skipping
sub LSCount, ecx
jmp LeftSkipLoop
LSTrans:
and ecx, 07fH
cmp ecx, LSCount
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, LSCount // skip partial run, jump into normal loop for rest
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitTransparent
LSTrans1:
sub LSCount, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup: // Does any actual blitting (trans/non) for the line
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
BlitDispatch:
cmp LSCount, 0 // Check to see if we're done blitting
je RightSkipLoop
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
BlitNonTransLoop: // blit non-transparent pixels
cmp ecx, LSCount
jbe BNTrans1
sub ecx, LSCount
mov Unblitted, ecx
mov ecx, LSCount
BNTrans1:
sub LSCount, ecx
BlitNTL1:
mov ax, [ebx]
cmp ax, usZLevel
ja BlitNTL2
mov ax, usZLevel
mov [ebx], ax
xor eax, eax
mov al, [esi]
mov al, [edx+eax]
mov [edi], al
BlitNTL2:
inc esi
inc edi
add ebx, 2
dec cl
jnz BlitNTL1
//BlitLineEnd:
add esi, Unblitted
jmp BlitDispatch
BlitTransparent: // skip transparent pixels
and ecx, 07fH
cmp ecx, LSCount
jbe BTrans1
mov ecx, LSCount
BTrans1:
sub LSCount, ecx
add edi, ecx
// shl ecx, 1
add ecx, ecx
add ebx, ecx
jmp BlitDispatch
RightSkipLoop: // skip along until we hit and end-of-line marker
RSLoop1:
mov al, [esi]
inc esi
or al, al
jnz RSLoop1
// check for incrementing of z level
dec usZLinesToGo
jnz RSLoop2
// mov ax, usZLevel
// add ax, Z_SUBLEVELS
// mov usZLevel, ax
// mov ax, WORLD_TILE_Y
// mov usZLinesToGo, ax
RSLoop2:
dec BlitHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkipZ
jmp LeftSkipSetup
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
InitZBuffer
Allocates and initializes a Z buffer for use with the Z buffer blitters. Doesn't really do
much except allocate a chunk of memory, and zero it.
**********************************************************************************************/
UINT16 *InitZBuffer(UINT32 uiPitch, UINT32 uiHeight)
{
UINT16 *pBuffer;
/*
* ClippingRect was declared first with SCREEN_WIDTH and HEIGHT but now they are not
* constant so i will initialize it here
* any questions? joker
*/
ClippingRect.iLeft = 0;
ClippingRect.iTop = 0;
ClippingRect.iRight = SCREEN_WIDTH;
ClippingRect.iBottom = SCREEN_HEIGHT;
if((pBuffer = (UINT16 *) MemAlloc(uiPitch*uiHeight))==NULL)
return(NULL);
BYTE* data = (BYTE*)pBuffer;
SurfaceData::SetApplicationData(data);
g_SurfaceRectangle[SurfaceData::GetSurfaceID(data)].SetRect(ClippingRect);
memset(pBuffer, 0, (uiPitch*uiHeight));
return(pBuffer);
}
/**********************************************************************************************
ShutdownZBuffer
Frees up the memory allocated for the Z buffer.
**********************************************************************************************/
BOOLEAN ShutdownZBuffer(UINT16 *pBuffer)
{
SurfaceData::ReleaseApplicationData((BYTE*)pBuffer);
MemFree(pBuffer);
return(TRUE);
}
BOOLEAN BlitZRect(UINT16 *pZBuffer, UINT32 uiPitch, INT16 sLeft, INT16 sTop, INT16 sRight, INT16 sBottom, UINT16 usZValue)
{
INT16 sLeftClip, sTopClip, sRightClip, sBottomClip;
UINT8 *pZPtr;
UINT32 uiLineSkip, usWidth, usHeight;
sLeftClip=__max(ClippingRect.iLeft, sLeft);
sRightClip=__min(ClippingRect.iRight, sRight);
sTopClip=__max(ClippingRect.iTop, sTop);
sBottomClip=__min(ClippingRect.iBottom, sBottom);
usHeight=sBottomClip-sTopClip;
usWidth=sRightClip-sLeftClip;
pZPtr=(UINT8 *)pZBuffer+(sTopClip*uiPitch)+(sLeftClip*2);
uiLineSkip=(uiPitch-(usWidth*2));
if((usHeight==0) || (usWidth==0))
return(FALSE);
__asm {
mov edi, pZPtr
xor eax, eax
mov ax, usZValue
mov ebx, usWidth
mov edx, usHeight
BZR1:
mov ecx, ebx
rep stosw
add edi, uiLineSkip
dec edx
jnz BZR1
}
return(TRUE);
}
//*****************************************************************************
//** 8 Bit Blitters
//**
//*****************************************************************************
/**********************************************************************************************
Blt8BPPDataTo8BPPBuffer
Blits an image into the destination buffer, using an ETRLE brush as a source, and a 16-bit
buffer as a destination.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo8BPPBuffer( UINT8 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex )
{
static UINT32 uiOffset;
static UINT32 usHeight, usWidth;
static UINT8 *SrcPtr, *DestPtr;
static UINT32 LineSkip;
static ETRLEObject *pTrav;
static INT32 iTempX, iTempY;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX);
LineSkip=(uiDestPitchBYTES-(usWidth));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
xor eax, eax
xor ebx, ebx
xor ecx, ecx
BlitDispatch:
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
clc
rcr cl, 1
jnc BlitNTL2
movsb
BlitNTL2:
clc
rcr cl, 1
jnc BlitNTL3
movsw
BlitNTL3:
or cl, cl
jz BlitDispatch
xor ebx, ebx
//BlitNTL4:
rep movsd
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
xor al, al
rep stosb
jmp BlitDispatch
BlitDoneLine:
dec usHeight
jz BlitDone
add edi, LineSkip
jmp BlitDispatch
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo8BPPBufferMonoShadow
Uses a bitmap an 8BPP template for blitting. Anywhere a 1 appears in the bitmap, a shadow
is blitted to the destination (a black pixel). Any other value above zero is considered a
forground color, and zero is background. If the parameter for the background color is zero,
transparency is used for the background.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo8BPPBufferMonoShadow( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, UINT8 ubForeground, UINT8 ubBackground)
{
UINT32 uiOffset;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip, LineSkipZ;
ETRLEObject *pTrav;
INT32 iTempX, iTempY;
UINT8 *pPal8BPP;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*2*iTempY) + (iTempX*2);
LineSkip=(uiDestPitchBYTES-(usWidth));
LineSkipZ=LineSkip*2;
pPal8BPP=hSrcVObject->pShade8;
__asm {
mov esi, SrcPtr
mov edi, DestPtr
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
mov edx, pPal8BPP
BlitDispatch:
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
BlitNTL4:
mov al, [esi]
cmp al, 1
jne BlitNTL6
xor al, al
mov [edi], al
jmp BlitNTL5
BlitNTL6:
or al, al
jz BlitNTL7
mov al, ubForeground
mov [edi], al
jmp BlitNTL5
BlitNTL7:
cmp ubBackground, 0
je BlitNTL5
mov al, ubBackground
mov [edi], al
BlitNTL5:
inc esi
inc edi
add ebx, 2
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
mov al, ubBackground
or al, al
jz BlitTrans1
rep stosb
jmp BlitDispatch
BlitTrans1:
add edi, ecx
jmp BlitDispatch
BlitDoneLine:
dec usHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkipZ
jmp BlitDispatch
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo8BPPBufferMonoShadowClip
Uses a bitmap an 8BPP template for blitting. Anywhere a 1 appears in the bitmap, a shadow
is blitted to the destination (a black pixel). Any other value above zero is considered a
forground color, and zero is background. If the parameter for the background color is zero,
transparency is used for the background.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo8BPPBufferMonoShadowClip( UINT8 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion, UINT8 ubForeground, UINT8 ubBackground)
{
UINT32 uiOffset;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr;
UINT32 LineSkip, LineSkipZ;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight, LSCount;
INT32 ClipX1, ClipY1, ClipX2, ClipY2;
UINT8 *pPal8BPP;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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(TRUE);
// check if whole thing is clipped
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
return(TRUE);
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip));
LineSkip=(uiDestPitchBYTES-(BlitLength));
LineSkipZ=LineSkip*2;
pPal8BPP=hSrcVObject->pShade8;
__asm {
mov esi, SrcPtr
mov edi, DestPtr
xor eax, eax
xor ecx, ecx
mov edx, pPal8BPP
cmp TopSkip, 0 // check for nothing clipped on top
je LeftSkipSetup
TopSkipLoop: // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
jmp TopSkipLoop
TSEndLine:
dec TopSkip
jnz TopSkipLoop
LeftSkipSetup:
mov Unblitted, 0
mov eax, LeftSkip
mov LSCount, eax
or eax, eax
jz BlitLineSetup
LeftSkipLoop:
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, LSCount
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, LSCount // skip partial run, jump into normal loop for rest
sub ecx, LSCount
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2:
add esi, ecx // skip whole run, and start blit with new run
jmp BlitLineSetup
LSSkip1:
add esi, ecx // skip whole run, continue skipping
sub LSCount, ecx
jmp LeftSkipLoop
LSTrans:
and ecx, 07fH
cmp ecx, LSCount
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, LSCount // skip partial run, jump into normal loop for rest
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitTransparent
LSTrans1:
sub LSCount, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup: // Does any actual blitting (trans/non) for the line
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
BlitDispatch:
cmp LSCount, 0 // Check to see if we're done blitting
je RightSkipLoop
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
BlitNonTransLoop: // blit non-transparent pixels
cmp ecx, LSCount
jbe BNTrans1
sub ecx, LSCount
mov Unblitted, ecx
mov ecx, LSCount
BNTrans1:
sub LSCount, ecx
BlitNTL1:
xor eax, eax
mov al, [esi]
cmp al, 1
jne BlitNTL3
// write shadow pixel
xor al, al
mov [edi], al
jmp BlitNTL2
BlitNTL3:
or al, al
jz BlitNTL4
// write foreground pixel
mov al, ubForeground
mov [edi], al
jmp BlitNTL2
BlitNTL4:
cmp ubBackground, 0
je BlitNTL2
//write background pixel
mov al, ubBackground
mov [edi], al
BlitNTL2:
inc esi
inc edi
dec cl
jnz BlitNTL1
//BlitLineEnd:
add esi, Unblitted
jmp BlitDispatch
BlitTransparent: // skip transparent pixels
and ecx, 07fH
cmp ecx, LSCount
jbe BTrans1
mov ecx, LSCount
BTrans1:
sub LSCount, ecx
mov al, ubBackground
or al, al
jz BTrans2
rep stosb
jmp BlitDispatch
BTrans2:
add edi, ecx
jmp BlitDispatch
RightSkipLoop: // skip along until we hit and end-of-line marker
RSLoop1:
mov al, [esi]
inc esi
or al, al
jnz RSLoop1
dec BlitHeight
jz BlitDone
add edi, LineSkip
jmp LeftSkipSetup
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo8BPPBufferTransZPixelate
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
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.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo8BPPBufferTransZPixelate( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex )
{
UINT32 uiOffset;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip, LineSkipZ;
ETRLEObject *pTrav;
INT32 iTempX, iTempY;
UINT32 uiLineFlag;
UINT8 *pPal8BPP;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*2*iTempY) + (iTempX*2);
pPal8BPP = hSrcVObject->pShade8;
LineSkip=(uiDestPitchBYTES-(usWidth));
LineSkipZ=LineSkip*2;
uiLineFlag=(iTempY&1);
__asm {
mov esi, SrcPtr
mov edi, DestPtr
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
mov edx, pPal8BPP
BlitDispatch:
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
BlitNTL4:
test uiLineFlag, 1
jz BlitNTL6
test edi, 2
jz BlitNTL5
jmp BlitNTL7
BlitNTL6:
test edi, 2
jnz BlitNTL5
BlitNTL7:
mov ax, [ebx]
cmp ax, usZValue
ja BlitNTL5
mov ax, usZValue
mov [ebx], ax
mov al, [esi]
mov al, [edx+eax]
mov [edi], al
BlitNTL5:
inc esi
inc edi
add ebx, 2
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
add edi, ecx
// shl ecx, 1
add ecx, ecx
add ebx, ecx
jmp BlitDispatch
BlitDoneLine:
dec usHeight
jz BlitDone
xor uiLineFlag, 1
add edi, LineSkip
add ebx, LineSkipZ
jmp BlitDispatch
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo8BPPBufferTransZNBPixelate
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 value is
not updated, for any non-transparent pixels. The Z-buffer is 16 bit, and
must be the same dimensions as the destination.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo8BPPBufferTransZNBPixelate( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex )
{
UINT32 uiOffset;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip, LineSkipZ;
ETRLEObject *pTrav;
INT32 iTempX, iTempY;
UINT32 uiLineFlag;
UINT8 *pPal8BPP;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*2*iTempY) + (iTempX*2);
pPal8BPP = hSrcVObject->pShade8;
LineSkip=(uiDestPitchBYTES-(usWidth));
LineSkipZ=LineSkip*2;
uiLineFlag=(iTempY&1);
__asm {
mov esi, SrcPtr
mov edi, DestPtr
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
mov edx, pPal8BPP
BlitDispatch:
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
BlitNTL4:
test uiLineFlag, 1
jz BlitNTL6
test edi, 2
jz BlitNTL5
jmp BlitNTL7
BlitNTL6:
test edi, 2
jnz BlitNTL5
BlitNTL7:
mov ax, [ebx]
cmp ax, usZValue
ja BlitNTL5
mov al, [esi]
mov al, [edx+eax]
mov [edi], al
BlitNTL5:
inc esi
inc edi
add ebx, 2
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
add edi, ecx
// shl ecx, 1
add ecx, ecx
add ebx, ecx
jmp BlitDispatch
BlitDoneLine:
dec usHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkipZ
jmp BlitDispatch
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo8BPPBufferTransZClipPixelate
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
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.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo8BPPBufferTransZClipPixelate( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion)
{
UINT32 uiOffset;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip, LineSkipZ;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight, LSCount;
INT32 ClipX1, ClipY1, ClipX2, ClipY2;
UINT32 uiLineFlag;
UINT8 *pPal8BPP;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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(TRUE);
// check if whole thing is clipped
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
return(TRUE);
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip));
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*2*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
pPal8BPP = hSrcVObject->pShade8;
LineSkip=(uiDestPitchBYTES-(BlitLength));
LineSkipZ=LineSkip*2;
uiLineFlag=(iTempY&1);
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, pPal8BPP
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
cmp TopSkip, 0 // check for nothing clipped on top
je LeftSkipSetup
TopSkipLoop: // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
jmp TopSkipLoop
TSEndLine:
dec TopSkip
jnz TopSkipLoop
LeftSkipSetup:
mov Unblitted, 0
mov eax, LeftSkip
mov LSCount, eax
or eax, eax
jz BlitLineSetup
LeftSkipLoop:
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, LSCount
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, LSCount // skip partial run, jump into normal loop for rest
sub ecx, LSCount
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2:
add esi, ecx // skip whole run, and start blit with new run
jmp BlitLineSetup
LSSkip1:
add esi, ecx // skip whole run, continue skipping
sub LSCount, ecx
jmp LeftSkipLoop
LSTrans:
and ecx, 07fH
cmp ecx, LSCount
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, LSCount // skip partial run, jump into normal loop for rest
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitTransparent
LSTrans1:
sub LSCount, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup: // Does any actual blitting (trans/non) for the line
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
BlitDispatch:
cmp LSCount, 0 // Check to see if we're done blitting
je RightSkipLoop
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
BlitNonTransLoop: // blit non-transparent pixels
cmp ecx, LSCount
jbe BNTrans1
sub ecx, LSCount
mov Unblitted, ecx
mov ecx, LSCount
BNTrans1:
sub LSCount, ecx
BlitNTL1:
test uiLineFlag, 1
jz BlitNTL6
test edi, 2
jz BlitNTL2
jmp BlitNTL7
BlitNTL6:
test edi, 2
jnz BlitNTL2
BlitNTL7:
mov ax, [ebx]
cmp ax, usZValue
ja BlitNTL2
mov ax, usZValue
mov [ebx], ax
xor eax, eax
mov al, [esi]
mov al, [edx+eax]
mov [edi], al
BlitNTL2:
inc esi
inc edi
add ebx, 2
dec cl
jnz BlitNTL1
//BlitLineEnd:
add esi, Unblitted
jmp BlitDispatch
BlitTransparent: // skip transparent pixels
and ecx, 07fH
cmp ecx, LSCount
jbe BTrans1
mov ecx, LSCount
BTrans1:
sub LSCount, ecx
add edi, ecx
// shl ecx, 1
add ecx, ecx
add ebx, ecx
jmp BlitDispatch
RightSkipLoop: // skip along until we hit and end-of-line marker
RSLoop1:
mov al, [esi]
inc esi
or al, al
jnz RSLoop1
dec BlitHeight
jz BlitDone
xor uiLineFlag, 1
add edi, LineSkip
add ebx, LineSkipZ
jmp LeftSkipSetup
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo8BPPBufferTransZNBClipPixelate
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 value is
not updated, for any non-transparent pixels. The Z-buffer is 16 bit, and must be the same
dimensions as the destination.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo8BPPBufferTransZNBClipPixelate( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion)
{
UINT32 uiOffset;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip, LineSkipZ;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight, LSCount;
INT32 ClipX1, ClipY1, ClipX2, ClipY2;
UINT32 uiLineFlag;
UINT8 *pPal8BPP;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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(TRUE);
// check if whole thing is clipped
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
return(TRUE);
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip));
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*2*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
pPal8BPP=hSrcVObject->pShade8;
LineSkip=(uiDestPitchBYTES-(BlitLength));
LineSkipZ=LineSkip*2;
uiLineFlag=(iTempY&1);
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, pPal8BPP
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
cmp TopSkip, 0 // check for nothing clipped on top
je LeftSkipSetup
TopSkipLoop: // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
jmp TopSkipLoop
TSEndLine:
dec TopSkip
jnz TopSkipLoop
LeftSkipSetup:
mov Unblitted, 0
mov eax, LeftSkip
mov LSCount, eax
or eax, eax
jz BlitLineSetup
LeftSkipLoop:
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, LSCount
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, LSCount // skip partial run, jump into normal loop for rest
sub ecx, LSCount
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2:
add esi, ecx // skip whole run, and start blit with new run
jmp BlitLineSetup
LSSkip1:
add esi, ecx // skip whole run, continue skipping
sub LSCount, ecx
jmp LeftSkipLoop
LSTrans:
and ecx, 07fH
cmp ecx, LSCount
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, LSCount // skip partial run, jump into normal loop for rest
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitTransparent
LSTrans1:
sub LSCount, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup: // Does any actual blitting (trans/non) for the line
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
BlitDispatch:
cmp LSCount, 0 // Check to see if we're done blitting
je RightSkipLoop
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
BlitNonTransLoop: // blit non-transparent pixels
cmp ecx, LSCount
jbe BNTrans1
sub ecx, LSCount
mov Unblitted, ecx
mov ecx, LSCount
BNTrans1:
sub LSCount, ecx
BlitNTL1:
test uiLineFlag, 1
jz BlitNTL6
test edi, 2
jz BlitNTL2
jmp BlitNTL7
BlitNTL6:
test edi, 2
jnz BlitNTL2
BlitNTL7:
mov ax, [ebx]
cmp ax, usZValue
ja BlitNTL2
xor eax, eax
mov al, [esi]
mov al, [edx+eax]
mov [edi], al
BlitNTL2:
inc esi
inc edi
add ebx, 2
dec cl
jnz BlitNTL1
//BlitLineEnd:
add esi, Unblitted
jmp BlitDispatch
BlitTransparent: // skip transparent pixels
and ecx, 07fH
cmp ecx, LSCount
jbe BTrans1
mov ecx, LSCount
BTrans1:
sub LSCount, ecx
add edi, ecx
// shl ecx, 1
add ecx, ecx
add ebx, ecx
jmp BlitDispatch
RightSkipLoop: // skip along until we hit and end-of-line marker
RSLoop1:
mov al, [esi]
inc esi
or al, al
jnz RSLoop1
dec BlitHeight
jz BlitDone
xor uiLineFlag, 1
add edi, LineSkip
add ebx, LineSkipZ
jmp LeftSkipSetup
BlitDone:
}
return(TRUE);
}
/******************************************************************************
Blt8BPPDataTo8BPPBufferTransparentClip
Blits an image into the destination buffer, using an ETRLE brush as a source, and a 16-bit
buffer as a destination. Clips the brush.
*******************************************************************************/
BOOLEAN Blt8BPPDataTo8BPPBufferTransparentClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion)
{
UINT32 uiOffset;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight;
INT32 ClipX1, ClipY1, ClipX2, ClipY2;
UINT8 *pPal8BPP;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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(TRUE);
// check if whole thing is clipped
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
return(TRUE);
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip));
LineSkip=(uiDestPitchBYTES-(BlitLength));
pPal8BPP=hSrcVObject->pShade8;
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, pPal8BPP
// mov edx, pointer to shade table here
xor eax, eax
mov ebx, TopSkip
xor ecx, ecx
or ebx, ebx // check for nothing clipped on top
jz LeftSkipSetup
TopSkipLoop: // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
jmp TopSkipLoop
TSEndLine:
dec ebx
jnz TopSkipLoop
LeftSkipSetup:
mov Unblitted, 0
mov ebx, LeftSkip // check for nothing clipped on the left
or ebx, ebx
jz BlitLineSetup
LeftSkipLoop:
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, ebx
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, ebx // skip partial run, jump into normal loop for rest
sub ecx, ebx
mov ebx, BlitLength
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2:
add esi, ecx // skip whole run, and start blit with new run
jmp BlitLineSetup
LSSkip1:
add esi, ecx // skip whole run, continue skipping
sub ebx, ecx
jmp LeftSkipLoop
LSTrans:
and ecx, 07fH
cmp ecx, ebx
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, ebx // skip partial run, jump into normal loop for rest
mov ebx, BlitLength
mov Unblitted, 0
jmp BlitTransparent
LSTrans1:
sub ebx, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup: // Does any actual blitting (trans/non) for the line
mov ebx, BlitLength
mov Unblitted, 0
BlitDispatch:
or ebx, ebx // Check to see if we're done blitting
jz RightSkipLoop
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
BlitNonTransLoop: // blit non-transparent pixels
cmp ecx, ebx
jbe BNTrans1
sub ecx, ebx
mov Unblitted, ecx
mov ecx, ebx
BNTrans1:
sub ebx, ecx
clc
rcr cl, 1
jnc BlitNTL2
mov al, [esi]
mov al, [edx+eax]
mov [edi], al
inc esi
inc edi
BlitNTL2:
clc
rcr cl, 1
jnc BlitNTL3
mov al, [esi]
mov al, [edx+eax]
mov [edi], al
mov al, [esi+1]
mov al, [edx+eax]
mov [edi+1], al
add esi, 2
add edi, 2
BlitNTL3:
or cl, cl
jz BlitLineEnd
BlitNTL4:
mov al, [esi]
mov al, [edx+eax]
mov [edi], al
mov al, [esi+1]
mov al, [edx+eax]
mov [edi+1], al
mov al, [esi+2]
mov al, [edx+eax]
mov [edi+2], al
mov al, [esi+3]
mov al, [edx+eax]
mov [edi+3], al
add esi, 4
add edi, 4
dec cl
jnz BlitNTL4
BlitLineEnd:
add esi, Unblitted
jmp BlitDispatch
BlitTransparent: // skip transparent pixels
and ecx, 07fH
cmp ecx, ebx
jbe BTrans1
mov ecx, ebx
BTrans1:
sub ebx, ecx
add edi, ecx
jmp BlitDispatch
RightSkipLoop: // skip along until we hit and end-of-line marker
RSLoop1:
mov al, [esi]
inc esi
or al, al
jnz RSLoop1
dec BlitHeight
jz BlitDone
add edi, LineSkip
jmp LeftSkipSetup
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo8BPPBufferTransparent
Blits an image into the destination buffer, using an ETRLE brush as a source, and a 16-bit
buffer as a destination.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo8BPPBufferTransparent( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex )
{
UINT32 uiOffset;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr, *pPal8BPP;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX);
LineSkip=(uiDestPitchBYTES-(usWidth));
pPal8BPP=hSrcVObject->pShade8;
__asm {
mov esi, SrcPtr
mov edi, DestPtr
xor eax, eax
xor ebx, ebx
xor ecx, ecx
mov edx, pPal8BPP
BlitDispatch:
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
clc
rcr cl, 1
jnc BlitNTL2
// movsb
mov al, [esi]
mov al, [edx+eax]
mov [edi], al
inc esi
inc edi
BlitNTL2:
clc
rcr cl, 1
jnc BlitNTL3
// movsw
mov al, [esi]
mov al, [edx+eax]
mov [edi], al
mov al, [esi+1]
mov al, [edx+eax]
mov [edi+1], al
add esi, 2
add edi, 2
BlitNTL3:
or cl, cl
jz BlitDispatch
BlitNTL4:
// rep movsd
mov al, [esi]
mov al, [edx+eax]
mov [edi], al
mov al, [esi+1]
mov al, [edx+eax]
mov [edi+1], al
mov al, [esi+2]
mov al, [edx+eax]
mov [edi+2], al
mov al, [esi+3]
mov al, [edx+eax]
mov [edi+3], al
add esi, 4
add edi, 4
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
add edi, ecx
jmp BlitDispatch
BlitDoneLine:
dec usHeight
jz BlitDone
add edi, LineSkip
jmp BlitDispatch
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo8BPPBufferTransZ
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
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.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo8BPPBufferTransZ( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex )
{
UINT32 uiOffset;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip, LineSkipZ, uiZComp;
ETRLEObject *pTrav;
INT32 iTempX, iTempY;
UINT8 *pPal8BPP;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*2*iTempY) + (iTempX*2);
pPal8BPP = hSrcVObject->pShade8;
LineSkip=(uiDestPitchBYTES-(usWidth));
LineSkipZ=LineSkip*2;
uiZComp=(UINT32)usZValue;
__asm {
mov esi, SrcPtr
mov edi, DestPtr
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
mov edx, pPal8BPP
BlitDispatch:
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
clc
rcr cl, 1
jnc BlitNTL2
// do a byte
mov ax, [ebx]
cmp eax, uiZComp
ja BlitNTL4
mov eax, uiZComp
mov [ebx], ax
xor eax, eax
mov al, [esi]
mov al, [edx+eax]
mov [edi], al
BlitNTL4:
inc esi
inc ebx
inc edi
inc ebx
// do a word
BlitNTL2:
clc
rcr cl, 1
jnc BlitNTL6
// word - first pixel
mov ax, [ebx]
cmp eax, uiZComp
ja BlitNTL3
mov eax, uiZComp
mov [ebx], ax
xor eax, eax
mov al, [esi]
mov al, [edx+eax]
mov [edi], al
// word - second
BlitNTL3:
mov ax, [ebx+2]
cmp eax, uiZComp
ja BlitNTL12
mov eax, uiZComp
mov [ebx+2], ax
xor eax, eax
mov al, [esi+1]
mov al, [edx+eax]
mov [edi+1], al
BlitNTL12:
inc esi
inc edi
inc esi
inc edi
add ebx, 4
// do a dword
BlitNTL6:
or cl, cl
jz BlitDispatch
BlitNTL7:
// dword - first pixel
mov ax, [ebx]
cmp eax, uiZComp
ja BlitNTL8
mov eax, uiZComp
mov [ebx], ax
xor eax, eax
mov al, [esi]
mov al, [edx+eax]
mov [edi], al
// dword - second
BlitNTL8:
mov ax, [ebx+2]
cmp eax, uiZComp
ja BlitNTL9
mov eax, uiZComp
mov [ebx+2], ax
xor eax, eax
mov al, [esi+1]
mov al, [edx+eax]
mov [edi+1], al
BlitNTL9:
// dword - third pixel
mov ax, [ebx+4]
cmp eax, uiZComp
ja BlitNTL10
mov eax, uiZComp
mov [ebx+4], ax
xor eax, eax
mov al, [esi+2]
mov al, [edx+eax]
mov [edi+2], al
// dword - fourth
BlitNTL10:
mov ax, [ebx+6]
cmp eax, uiZComp
ja BlitNTL11
mov eax, uiZComp
mov [ebx+6], ax
xor eax, eax
mov al, [esi+3]
mov al, [edx+eax]
mov [edi+3], al
BlitNTL11:
add esi, 4
add edi, 4
add ebx, 8
dec cl
jnz BlitNTL7
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
add edi, ecx
// shl ecx, 1
add ecx, ecx
add ebx, ecx
jmp BlitDispatch
BlitDoneLine:
dec usHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkipZ
jmp BlitDispatch
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo8BPPBufferTransZNB
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 value is
not updated, for any non-transparent pixels. The Z-buffer is 16 bit, and
must be the same dimensions as the destination.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo8BPPBufferTransZNB( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex )
{
UINT32 uiOffset;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip, LineSkipZ;
ETRLEObject *pTrav;
INT32 iTempX, iTempY;
UINT8 *pPal8BPP;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*2*iTempY) + (iTempX*2);
pPal8BPP = hSrcVObject->pShade8;
LineSkip=(uiDestPitchBYTES-(usWidth));
LineSkipZ=LineSkip*2;
__asm {
mov esi, SrcPtr
mov edi, DestPtr
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
mov edx, pPal8BPP
BlitDispatch:
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
xor eax, eax
BlitNTL4:
mov ax, [ebx]
cmp ax, usZValue
ja BlitNTL5
xor ah, ah
mov al, [esi]
mov al, [edx+eax]
mov [edi], al
BlitNTL5:
inc esi
inc edi
add ebx, 2
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
add edi, ecx
// shl ecx, 1
add ecx, ecx
add ebx, ecx
jmp BlitDispatch
BlitDoneLine:
dec usHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkipZ
jmp BlitDispatch
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo8BPPBufferTransZNBColor
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 value is
not updated, for any non-transparent pixels. The Z-buffer is 16 bit, and
must be the same dimensions as the destination. Any pixels that fail the Z test
are written to with the specified color.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo8BPPBufferTransZNBColor( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, UINT8 ubColor)
{
UINT32 uiOffset;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip, LineSkipZ;
ETRLEObject *pTrav;
INT32 iTempX, iTempY;
UINT8 *pPal8BPP;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*2*iTempY) + (iTempX*2);
pPal8BPP = hSrcVObject->pShade8;
LineSkip=(uiDestPitchBYTES-(usWidth));
LineSkipZ=LineSkip*2;
__asm {
mov esi, SrcPtr
mov edi, DestPtr
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
mov edx, pPal8BPP
BlitDispatch:
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
xor eax, eax
BlitNTL4:
mov ax, [ebx]
cmp ax, usZValue
ja BlitNTL5
xor ah, ah
mov al, [esi]
mov al, [edx+eax]
mov [edi], al
jmp BlitNTL6
BlitNTL5:
xor ah, ah
mov al, ubColor
mov al, [edx+eax]
mov [edi], al
BlitNTL6:
inc esi
inc edi
add ebx, 2
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
add edi, ecx
// shl ecx, 1
add ecx, ecx
add ebx, ecx
jmp BlitDispatch
BlitDoneLine:
dec usHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkipZ
jmp BlitDispatch
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo8BPPBufferTransZClip
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
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.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo8BPPBufferTransZClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion)
{
UINT32 uiOffset;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip, LineSkipZ;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight, LSCount;
INT32 ClipX1, ClipY1, ClipX2, ClipY2;
UINT8 *pPal8BPP;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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(TRUE);
// check if whole thing is clipped
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
return(TRUE);
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip));
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*2*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
pPal8BPP = hSrcVObject->pShade8;
LineSkip=(uiDestPitchBYTES-(BlitLength));
LineSkipZ=LineSkip*2;
__asm {
mov esi, SrcPtr
mov edi, DestPtr
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
mov edx, pPal8BPP
cmp TopSkip, 0 // check for nothing clipped on top
je LeftSkipSetup
TopSkipLoop: // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
jmp TopSkipLoop
TSEndLine:
dec TopSkip
jnz TopSkipLoop
LeftSkipSetup:
mov Unblitted, 0
mov eax, LeftSkip
mov LSCount, eax
or eax, eax
jz BlitLineSetup
LeftSkipLoop:
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, LSCount
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, LSCount // skip partial run, jump into normal loop for rest
sub ecx, LSCount
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2:
add esi, ecx // skip whole run, and start blit with new run
jmp BlitLineSetup
LSSkip1:
add esi, ecx // skip whole run, continue skipping
sub LSCount, ecx
jmp LeftSkipLoop
LSTrans:
and ecx, 07fH
cmp ecx, LSCount
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, LSCount // skip partial run, jump into normal loop for rest
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitTransparent
LSTrans1:
sub LSCount, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup: // Does any actual blitting (trans/non) for the line
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
BlitDispatch:
cmp LSCount, 0 // Check to see if we're done blitting
je RightSkipLoop
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
BlitNonTransLoop: // blit non-transparent pixels
cmp ecx, LSCount
jbe BNTrans1
sub ecx, LSCount
mov Unblitted, ecx
mov ecx, LSCount
BNTrans1:
sub LSCount, ecx
BlitNTL1:
mov ax, [ebx]
cmp ax, usZValue
ja BlitNTL2
mov ax, usZValue
mov [ebx], ax
xor eax, eax
mov al, [esi]
mov al, [edx+eax]
mov [edi], al
BlitNTL2:
inc esi
inc edi
add ebx, 2
dec cl
jnz BlitNTL1
//BlitLineEnd:
add esi, Unblitted
jmp BlitDispatch
BlitTransparent: // skip transparent pixels
and ecx, 07fH
cmp ecx, LSCount
jbe BTrans1
mov ecx, LSCount
BTrans1:
sub LSCount, ecx
add edi, ecx
// shl ecx, 1
add ecx, ecx
add ebx, ecx
jmp BlitDispatch
RightSkipLoop: // skip along until we hit and end-of-line marker
RSLoop1:
mov al, [esi]
inc esi
or al, al
jnz RSLoop1
dec BlitHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkipZ
jmp LeftSkipSetup
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo8BPPBufferTransZNBClip
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 value is
not updated, for any non-transparent pixels. The Z-buffer is 16 bit, and must be the same
dimensions as the destination.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo8BPPBufferTransZNBClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion)
{
UINT32 uiOffset;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip, LineSkipZ;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight, LSCount;
INT32 ClipX1, ClipY1, ClipX2, ClipY2;
UINT8 *pPal8BPP;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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(TRUE);
// check if whole thing is clipped
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
return(TRUE);
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip));
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*2*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
pPal8BPP = hSrcVObject->pShade8;
LineSkip=(uiDestPitchBYTES-(BlitLength));
LineSkipZ=LineSkip*2;
__asm {
mov esi, SrcPtr
mov edi, DestPtr
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
mov edx, pPal8BPP
cmp TopSkip, 0 // check for nothing clipped on top
je LeftSkipSetup
TopSkipLoop: // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
jmp TopSkipLoop
TSEndLine:
dec TopSkip
jnz TopSkipLoop
LeftSkipSetup:
mov Unblitted, 0
mov eax, LeftSkip
mov LSCount, eax
or eax, eax
jz BlitLineSetup
LeftSkipLoop:
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, LSCount
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, LSCount // skip partial run, jump into normal loop for rest
sub ecx, LSCount
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2:
add esi, ecx // skip whole run, and start blit with new run
jmp BlitLineSetup
LSSkip1:
add esi, ecx // skip whole run, continue skipping
sub LSCount, ecx
jmp LeftSkipLoop
LSTrans:
and ecx, 07fH
cmp ecx, LSCount
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, LSCount // skip partial run, jump into normal loop for rest
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitTransparent
LSTrans1:
sub LSCount, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup: // Does any actual blitting (trans/non) for the line
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
BlitDispatch:
cmp LSCount, 0 // Check to see if we're done blitting
je RightSkipLoop
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
BlitNonTransLoop: // blit non-transparent pixels
cmp ecx, LSCount
jbe BNTrans1
sub ecx, LSCount
mov Unblitted, ecx
mov ecx, LSCount
BNTrans1:
sub LSCount, ecx
BlitNTL1:
mov ax, [ebx]
cmp ax, usZValue
ja BlitNTL2
xor eax, eax
mov al, [esi]
mov al, [edx+eax]
mov [edi], al
BlitNTL2:
inc esi
inc edi
add ebx, 2
dec cl
jnz BlitNTL1
//BlitLineEnd:
add esi, Unblitted
jmp BlitDispatch
BlitTransparent: // skip transparent pixels
and ecx, 07fH
cmp ecx, LSCount
jbe BTrans1
mov ecx, LSCount
BTrans1:
sub LSCount, ecx
add edi, ecx
// shl ecx, 1
add ecx, ecx
add ebx, ecx
jmp BlitDispatch
RightSkipLoop: // skip along until we hit and end-of-line marker
RSLoop1:
mov al, [esi]
inc esi
or al, al
jnz RSLoop1
dec BlitHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkipZ
jmp LeftSkipSetup
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo8BPPBufferTransZNBClipColor
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 value is
not updated, for any non-transparent pixels. The Z-buffer is 16 bit, and must be the same
dimensions as the destination.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo8BPPBufferTransZNBClipColor( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion, UINT8 ubColor)
{
UINT32 uiOffset;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip, LineSkipZ;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight, LSCount;
INT32 ClipX1, ClipY1, ClipX2, ClipY2;
UINT8 *pPal8BPP;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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(TRUE);
// check if whole thing is clipped
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
return(TRUE);
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip));
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*2*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
pPal8BPP = hSrcVObject->pShade8;
LineSkip=(uiDestPitchBYTES-(BlitLength));
LineSkipZ=LineSkip*2;
__asm {
mov esi, SrcPtr
mov edi, DestPtr
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
mov edx, pPal8BPP
cmp TopSkip, 0 // check for nothing clipped on top
je LeftSkipSetup
TopSkipLoop: // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
jmp TopSkipLoop
TSEndLine:
dec TopSkip
jnz TopSkipLoop
LeftSkipSetup:
mov Unblitted, 0
mov eax, LeftSkip
mov LSCount, eax
or eax, eax
jz BlitLineSetup
LeftSkipLoop:
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, LSCount
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, LSCount // skip partial run, jump into normal loop for rest
sub ecx, LSCount
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2:
add esi, ecx // skip whole run, and start blit with new run
jmp BlitLineSetup
LSSkip1:
add esi, ecx // skip whole run, continue skipping
sub LSCount, ecx
jmp LeftSkipLoop
LSTrans:
and ecx, 07fH
cmp ecx, LSCount
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, LSCount // skip partial run, jump into normal loop for rest
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitTransparent
LSTrans1:
sub LSCount, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup: // Does any actual blitting (trans/non) for the line
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
BlitDispatch:
cmp LSCount, 0 // Check to see if we're done blitting
je RightSkipLoop
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
BlitNonTransLoop: // blit non-transparent pixels
cmp ecx, LSCount
jbe BNTrans1
sub ecx, LSCount
mov Unblitted, ecx
mov ecx, LSCount
BNTrans1:
sub LSCount, ecx
xor eax, eax
BlitNTL1:
mov ax, [ebx]
cmp ax, usZValue
ja BlitNTL2
xor ah, ah
mov al, [esi]
mov al, [edx+eax]
mov [edi], al
jmp BlitNTL3
BlitNTL2:
xor ah, ah
mov al, ubColor
mov al, [edx+eax]
mov [edi], al
BlitNTL3:
inc esi
inc edi
add ebx, 2
dec cl
jnz BlitNTL1
//BlitLineEnd:
add esi, Unblitted
jmp BlitDispatch
BlitTransparent: // skip transparent pixels
and ecx, 07fH
cmp ecx, LSCount
jbe BTrans1
mov ecx, LSCount
BTrans1:
sub LSCount, ecx
add edi, ecx
// shl ecx, 1
add ecx, ecx
add ebx, ecx
jmp BlitDispatch
RightSkipLoop: // skip along until we hit and end-of-line marker
RSLoop1:
mov al, [esi]
inc esi
or al, al
jnz RSLoop1
dec BlitHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkipZ
jmp LeftSkipSetup
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo8BPPBufferShadowZ
Creates a shadow using a brush, but modifies the destination buffer only if the current
Z level is equal to higher than what's in the Z buffer at that pixel location. It
updates the Z buffer with the new Z level.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo8BPPBufferShadowZ( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex )
{
UINT32 uiOffset;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip, LineSkipZ;
ETRLEObject *pTrav;
INT32 iTempX, iTempY;
UINT8 *pPal8BPP;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*2*iTempY) + (iTempX*2);
pPal8BPP = hSrcVObject->pShade8;
LineSkip=(uiDestPitchBYTES-(usWidth));
LineSkipZ=LineSkip*2;
__asm {
mov esi, SrcPtr
mov edi, DestPtr
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
mov edx, pPal8BPP
BlitDispatch:
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
BlitNTL4:
mov ax, [ebx]
cmp ax, usZValue
jae BlitNTL5
mov ax, usZValue
mov [ebx], ax
xor eax, eax
mov al, [edi]
mov al, [edx+eax]
mov [edi], al
BlitNTL5:
inc esi
inc edi
add ebx, 2
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
add edi, ecx
// shl ecx, 1
add ecx, ecx
add ebx, ecx
jmp BlitDispatch
BlitDoneLine:
dec usHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkipZ
jmp BlitDispatch
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo8BPPBufferShadowZNB
Creates a shadow using a brush, but modifies the destination buffer only if the current
Z level is equal to higher than what's in the Z buffer at that pixel location.
The Z buffer is NOT updated with the new information.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo8BPPBufferShadowZNB( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex )
{
UINT32 uiOffset;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip, LineSkipZ;
ETRLEObject *pTrav;
INT32 iTempX, iTempY;
UINT8 *pPal8BPP;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*2*iTempY) + (iTempX*2);
pPal8BPP = hSrcVObject->pShade8;
LineSkip=(uiDestPitchBYTES-(usWidth));
LineSkipZ=LineSkip*2;
__asm {
mov esi, SrcPtr
mov edi, DestPtr
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
mov edx, pPal8BPP
BlitDispatch:
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
BlitNTL4:
mov ax, [ebx]
cmp ax, usZValue
jae BlitNTL5
xor eax, eax
mov al, [edi]
mov al, [edx+eax]
mov [edi], al
BlitNTL5:
inc esi
inc edi
add ebx, 2
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
add edi, ecx
// shl ecx, 1
add ecx, ecx
add ebx, ecx
jmp BlitDispatch
BlitDoneLine:
dec usHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkipZ
jmp BlitDispatch
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo8BPPBufferShadowZClip
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 value is
updated, for any non-transparent pixels. The Z-buffer is 16 bit, and
must be the same dimensions as the destination.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo8BPPBufferShadowZClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion)
{
UINT32 uiOffset;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip, LineSkipZ;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight, LSCount;
INT32 ClipX1, ClipY1, ClipX2, ClipY2;
UINT8 *pPal8BPP;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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(TRUE);
// check if whole thing is clipped
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
return(TRUE);
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip));
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*2*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
pPal8BPP = hSrcVObject->pShade8;
LineSkip=(uiDestPitchBYTES-(BlitLength));
LineSkipZ=LineSkip*2;
__asm {
mov esi, SrcPtr
mov edi, DestPtr
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
mov edx, pPal8BPP
cmp TopSkip, 0 // check for nothing clipped on top
je LeftSkipSetup
TopSkipLoop: // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
jmp TopSkipLoop
TSEndLine:
dec TopSkip
jnz TopSkipLoop
LeftSkipSetup:
mov Unblitted, 0
mov eax, LeftSkip
mov LSCount, eax
or eax, eax
jz BlitLineSetup
LeftSkipLoop:
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, LSCount
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, LSCount // skip partial run, jump into normal loop for rest
sub ecx, LSCount
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2:
add esi, ecx // skip whole run, and start blit with new run
jmp BlitLineSetup
LSSkip1:
add esi, ecx // skip whole run, continue skipping
sub LSCount, ecx
jmp LeftSkipLoop
LSTrans:
and ecx, 07fH
cmp ecx, LSCount
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, LSCount // skip partial run, jump into normal loop for rest
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitTransparent
LSTrans1:
sub LSCount, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup: // Does any actual blitting (trans/non) for the line
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
BlitDispatch:
cmp LSCount, 0 // Check to see if we're done blitting
je RightSkipLoop
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
BlitNonTransLoop: // blit non-transparent pixels
cmp ecx, LSCount
jbe BNTrans1
sub ecx, LSCount
mov Unblitted, ecx
mov ecx, LSCount
BNTrans1:
sub LSCount, ecx
BlitNTL1:
mov ax, [ebx]
cmp ax, usZValue
jae BlitNTL2
mov ax, usZValue
mov [ebx], ax
xor eax, eax
mov al, [edi]
mov al, [edx+eax]
mov [edi], al
BlitNTL2:
inc esi
inc edi
add ebx, 2
dec cl
jnz BlitNTL1
//BlitLineEnd:
add esi, Unblitted
jmp BlitDispatch
BlitTransparent: // skip transparent pixels
and ecx, 07fH
cmp ecx, LSCount
jbe BTrans1
mov ecx, LSCount
BTrans1:
sub LSCount, ecx
add edi, ecx
// shl ecx, 1
add ecx, ecx
add ebx, ecx
jmp BlitDispatch
RightSkipLoop: // skip along until we hit and end-of-line marker
RSLoop1:
mov al, [esi]
inc esi
or al, al
jnz RSLoop1
dec BlitHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkipZ
jmp LeftSkipSetup
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo8BPPBufferShadowZNBClip
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 value is
NOT updated, for any non-transparent pixels. The Z-buffer is 16 bit, and
must be the same dimensions as the destination.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo8BPPBufferShadowZNBClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion)
{
UINT32 uiOffset;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip, LineSkipZ;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight, LSCount;
INT32 ClipX1, ClipY1, ClipX2, ClipY2;
UINT8 *pPal8BPP;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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(TRUE);
// check if whole thing is clipped
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
return(TRUE);
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip));
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*2*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
pPal8BPP = hSrcVObject->pShade8;
LineSkip=(uiDestPitchBYTES-(BlitLength));
LineSkipZ=LineSkip*2;
__asm {
mov esi, SrcPtr
mov edi, DestPtr
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
mov edx, pPal8BPP
cmp TopSkip, 0 // check for nothing clipped on top
je LeftSkipSetup
TopSkipLoop: // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
jmp TopSkipLoop
TSEndLine:
dec TopSkip
jnz TopSkipLoop
LeftSkipSetup:
mov Unblitted, 0
mov eax, LeftSkip
mov LSCount, eax
or eax, eax
jz BlitLineSetup
LeftSkipLoop:
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, LSCount
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, LSCount // skip partial run, jump into normal loop for rest
sub ecx, LSCount
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2:
add esi, ecx // skip whole run, and start blit with new run
jmp BlitLineSetup
LSSkip1:
add esi, ecx // skip whole run, continue skipping
sub LSCount, ecx
jmp LeftSkipLoop
LSTrans:
and ecx, 07fH
cmp ecx, LSCount
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, LSCount // skip partial run, jump into normal loop for rest
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitTransparent
LSTrans1:
sub LSCount, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup: // Does any actual blitting (trans/non) for the line
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
BlitDispatch:
cmp LSCount, 0 // Check to see if we're done blitting
je RightSkipLoop
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
BlitNonTransLoop: // blit non-transparent pixels
cmp ecx, LSCount
jbe BNTrans1
sub ecx, LSCount
mov Unblitted, ecx
mov ecx, LSCount
BNTrans1:
sub LSCount, ecx
BlitNTL1:
mov ax, [ebx]
cmp ax, usZValue
jae BlitNTL2
xor eax, eax
mov al, [edi]
mov al, [edx+eax]
mov [edi], al
BlitNTL2:
inc esi
inc edi
add ebx, 2
dec cl
jnz BlitNTL1
//BlitLineEnd:
add esi, Unblitted
jmp BlitDispatch
BlitTransparent: // skip transparent pixels
and ecx, 07fH
cmp ecx, LSCount
jbe BTrans1
mov ecx, LSCount
BTrans1:
sub LSCount, ecx
add edi, ecx
// shl ecx, 1
add ecx, ecx
add ebx, ecx
jmp BlitDispatch
RightSkipLoop: // skip along until we hit and end-of-line marker
RSLoop1:
mov al, [esi]
inc esi
or al, al
jnz RSLoop1
dec BlitHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkipZ
jmp LeftSkipSetup
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo8BPPBufferTransShadowZ
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
updated to the current value, for any non-transparent pixels. If the source pixel is 254,
it is considered a shadow, and the destination buffer is darkened rather than blitted on.
The Z-buffer is 16 bit, and must be the same dimensions (including Pitch) as the destination.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo8BPPBufferTransShadowZ( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, UINT16 *p16BPPPalette )
{
UINT32 uiOffset;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip, LineSkipZ;
ETRLEObject *pTrav;
INT32 iTempX, iTempY;
UINT8 *pPal8BPP;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*2*iTempY) + (iTempX*2);
LineSkip=(uiDestPitchBYTES-(usWidth));
LineSkipZ=LineSkip*2;
pPal8BPP=hSrcVObject->pShade8;
__asm {
mov esi, SrcPtr
mov edi, DestPtr
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
mov edx, pPal8BPP
BlitDispatch:
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
BlitNTL4:
mov ax, [ebx]
cmp ax, usZValue
jae BlitNTL5
mov ax, usZValue
mov [ebx], ax
xor eax, eax
mov al, [esi]
cmp al, 254
jne BlitNTL6
mov al, [edi]
// mov al, ColorTable[eax] *********************************************
mov [edi], al
jmp BlitNTL5
BlitNTL6:
mov al, [edx+eax]
mov [edi], al
BlitNTL5:
inc esi
inc edi
add ebx, 2
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
add edi, ecx
// shl ecx, 1
add ecx, ecx
add ebx, ecx
jmp BlitDispatch
BlitDoneLine:
dec usHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkipZ
jmp BlitDispatch
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo8BPPBufferTransShadowZNB
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, for any non-transparent pixels. If the source pixel is 254,
it is considered a shadow, and the destination buffer is darkened rather than blitted on.
The Z-buffer is 16 bit, and must be the same dimensions (including Pitch) as the destination.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo8BPPBufferTransShadowZNB( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, UINT16 *p16BPPPalette )
{
UINT32 uiOffset;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip, LineSkipZ;
ETRLEObject *pTrav;
INT32 iTempX, iTempY;
UINT8 *pPal8BPP;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*2*iTempY) + (iTempX*2);
LineSkip=(uiDestPitchBYTES-(usWidth));
LineSkipZ=LineSkip*2;
pPal8BPP=hSrcVObject->pShade8;
__asm {
mov esi, SrcPtr
mov edi, DestPtr
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
mov edx, pPal8BPP
BlitDispatch:
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
BlitNTL4:
mov ax, [ebx]
cmp ax, usZValue
jae BlitNTL5
xor eax, eax
mov al, [esi]
cmp al, 254
jne BlitNTL6
// mov al, [edi]
// mov al, ColorTable[eax] *********************************************
// mov [edi], al
jmp BlitNTL5
BlitNTL6:
mov al, [edx+eax]
mov [edi], al
BlitNTL5:
inc esi
inc edi
add ebx, 2
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
add edi, ecx
// shl ecx, 1
add ecx, ecx
add ebx, ecx
jmp BlitDispatch
BlitDoneLine:
dec usHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkipZ
jmp BlitDispatch
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo8BPPBufferTransShadowZClip
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
updated to the current value, for any non-transparent pixels. The Z-buffer is 16 bit, and
must be the same dimensions as the destination. Pixels with a value of
254 are shaded instead of blitted.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo8BPPBufferTransShadowZClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion, UINT16 *p16BPPPalette )
{
UINT32 uiOffset;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip, LineSkipZ;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight, LSCount;
INT32 ClipX1, ClipY1, ClipX2, ClipY2;
UINT8 *pPal8BPP;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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(TRUE);
// check if whole thing is clipped
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
return(TRUE);
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip));
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*2*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
LineSkip=(uiDestPitchBYTES-(BlitLength));
LineSkipZ=LineSkip*2;
pPal8BPP=hSrcVObject->pShade8;
__asm {
mov esi, SrcPtr
mov edi, DestPtr
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
mov edx, pPal8BPP
cmp TopSkip, 0 // check for nothing clipped on top
je LeftSkipSetup
TopSkipLoop: // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
jmp TopSkipLoop
TSEndLine:
dec TopSkip
jnz TopSkipLoop
LeftSkipSetup:
mov Unblitted, 0
mov eax, LeftSkip
mov LSCount, eax
or eax, eax
jz BlitLineSetup
LeftSkipLoop:
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, LSCount
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, LSCount // skip partial run, jump into normal loop for rest
sub ecx, LSCount
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2:
add esi, ecx // skip whole run, and start blit with new run
jmp BlitLineSetup
LSSkip1:
add esi, ecx // skip whole run, continue skipping
sub LSCount, ecx
jmp LeftSkipLoop
LSTrans:
and ecx, 07fH
cmp ecx, LSCount
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, LSCount // skip partial run, jump into normal loop for rest
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitTransparent
LSTrans1:
sub LSCount, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup: // Does any actual blitting (trans/non) for the line
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
BlitDispatch:
cmp LSCount, 0 // Check to see if we're done blitting
je RightSkipLoop
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
BlitNonTransLoop: // blit non-transparent pixels
cmp ecx, LSCount
jbe BNTrans1
sub ecx, LSCount
mov Unblitted, ecx
mov ecx, LSCount
BNTrans1:
sub LSCount, ecx
BlitNTL1:
mov ax, [ebx]
cmp ax, usZValue
jae BlitNTL2
mov ax, usZValue
mov [ebx], ax
xor eax, eax
mov al, [esi]
cmp al, 254
jne BlitNTL3
mov al, [edi]
// mov ax, ColorTable[eax] ************************************************
mov [edi], al
jmp BlitNTL2
BlitNTL3:
mov al, [edx+eax]
mov [edi], al
BlitNTL2:
inc esi
inc edi
add ebx, 2
dec cl
jnz BlitNTL1
//BlitLineEnd:
add esi, Unblitted
jmp BlitDispatch
BlitTransparent: // skip transparent pixels
and ecx, 07fH
cmp ecx, LSCount
jbe BTrans1
mov ecx, LSCount
BTrans1:
sub LSCount, ecx
add edi, ecx
// shl ecx, 1
add ecx, ecx
add ebx, ecx
jmp BlitDispatch
RightSkipLoop: // skip along until we hit and end-of-line marker
RSLoop1:
mov al, [esi]
inc esi
or al, al
jnz RSLoop1
dec BlitHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkipZ
jmp LeftSkipSetup
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo8BPPBufferTransShadowZNBClip
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, for any non-transparent pixels. The Z-buffer is 16 bit, and
must be the same dimensions as the destination. Pixels with a value of
254 are shaded instead of blitted.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo8BPPBufferTransShadowZNBClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion, UINT16 *p16BPPPalette )
{
UINT32 uiOffset;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip, LineSkipZ;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight, LSCount;
INT32 ClipX1, ClipY1, ClipX2, ClipY2;
UINT8 *pPal8BPP;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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(TRUE);
// check if whole thing is clipped
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
return(TRUE);
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip));
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*2*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
LineSkip=(uiDestPitchBYTES-(BlitLength));
LineSkipZ=LineSkip*2;
pPal8BPP=hSrcVObject->pShade8;
__asm {
mov esi, SrcPtr
mov edi, DestPtr
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
mov edx, pPal8BPP
cmp TopSkip, 0 // check for nothing clipped on top
je LeftSkipSetup
TopSkipLoop: // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
jmp TopSkipLoop
TSEndLine:
dec TopSkip
jnz TopSkipLoop
LeftSkipSetup:
mov Unblitted, 0
mov eax, LeftSkip
mov LSCount, eax
or eax, eax
jz BlitLineSetup
LeftSkipLoop:
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, LSCount
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, LSCount // skip partial run, jump into normal loop for rest
sub ecx, LSCount
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2:
add esi, ecx // skip whole run, and start blit with new run
jmp BlitLineSetup
LSSkip1:
add esi, ecx // skip whole run, continue skipping
sub LSCount, ecx
jmp LeftSkipLoop
LSTrans:
and ecx, 07fH
cmp ecx, LSCount
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, LSCount // skip partial run, jump into normal loop for rest
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitTransparent
LSTrans1:
sub LSCount, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup: // Does any actual blitting (trans/non) for the line
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
BlitDispatch:
cmp LSCount, 0 // Check to see if we're done blitting
je RightSkipLoop
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
BlitNonTransLoop: // blit non-transparent pixels
cmp ecx, LSCount
jbe BNTrans1
sub ecx, LSCount
mov Unblitted, ecx
mov ecx, LSCount
BNTrans1:
sub LSCount, ecx
BlitNTL1:
mov ax, [ebx]
cmp ax, usZValue
jae BlitNTL2
xor eax, eax
mov al, [esi]
cmp al, 254
jne BlitNTL3
// mov al, [edi]
// mov ax, ColorTable[eax] ************************************************
// mov [edi], al
jmp BlitNTL2
BlitNTL3:
mov al, [edx+eax]
mov [edi], al
BlitNTL2:
inc esi
inc edi
add ebx, 2
dec cl
jnz BlitNTL1
//BlitLineEnd:
add esi, Unblitted
jmp BlitDispatch
BlitTransparent: // skip transparent pixels
and ecx, 07fH
cmp ecx, LSCount
jbe BTrans1
mov ecx, LSCount
BTrans1:
sub LSCount, ecx
add edi, ecx
// shl ecx, 1
add ecx, ecx
add ebx, ecx
jmp BlitDispatch
RightSkipLoop: // skip along until we hit and end-of-line marker
RSLoop1:
mov al, [esi]
inc esi
or al, al
jnz RSLoop1
dec BlitHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkipZ
jmp LeftSkipSetup
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo8BPPBufferShadow
Modifies the destination buffer. Darkens the destination pixels by 25%, using the source
image as a mask. Any Non-zero index pixels are used to darken destination pixels.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo8BPPBufferShadow( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex)
{
UINT8 *pPal8BPP;
UINT32 uiOffset;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX);
pPal8BPP = hSrcVObject->pShade8;
LineSkip=(uiDestPitchBYTES-(usWidth));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
xor eax, eax
mov ebx, usHeight
xor ecx, ecx
mov edx, OFFSET ShadeTable
BlitDispatch:
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
xor eax, eax
add esi, ecx
clc
rcr cl, 1
jnc BlitNTL2
mov ax, [edi]
mov ax, [edx+eax*2]
mov [edi], ax
add edi, 2
BlitNTL2:
clc
rcr cl, 1
jnc BlitNTL3
mov ax, [edi]
mov ax, [edx+eax*2]
mov [edi], ax
mov ax, [edi+2]
mov ax, [edx+eax*2]
mov [edi+2], ax
add edi, 4
BlitNTL3:
or cl, cl
jz BlitDispatch
BlitNTL4:
mov ax, [edi]
mov ax, [edx+eax*2]
mov [edi], ax
mov ax, [edi+2]
mov ax, [edx+eax*2]
mov [edi+2], ax
mov ax, [edi+4]
mov ax, [edx+eax*2]
mov [edi+4], ax
mov ax, [edi+6]
mov ax, [edx+eax*2]
mov [edi+6], ax
add edi, 8
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
// shl ecx, 1
add ecx, ecx
add edi, ecx
jmp BlitDispatch
BlitDoneLine:
dec ebx
jz BlitDone
add edi, LineSkip
jmp BlitDispatch
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo8BPPBufferShadowClip
Modifies the destination buffer. Darkens the destination pixels by 25%, using the source
image as a mask. Any Non-zero index pixels are used to darken destination pixels. Blitter
clips brush if it doesn't fit on the viewport.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo8BPPBufferShadowClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion)
{
UINT8 *pPal8BPP;
UINT32 uiOffset;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight;
INT32 ClipX1, ClipY1, ClipX2, ClipY2;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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);
// whole thing is clipped
if((LeftSkip >=(INT32)usWidth) || (RightSkip >=(INT32)usWidth))
return(TRUE);
// whole thing is clipped
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
return(TRUE);
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip));
pPal8BPP = hSrcVObject->pShade8;
LineSkip=(uiDestPitchBYTES-(BlitLength));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, pPal8BPP
xor eax, eax
mov ebx, TopSkip
xor ecx, ecx
or ebx, ebx // check for nothing clipped on top
jz LeftSkipSetup
TopSkipLoop: // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
jmp TopSkipLoop
TSEndLine:
dec ebx
jnz TopSkipLoop
LeftSkipSetup:
mov Unblitted, 0
mov ebx, LeftSkip // check for nothing clipped on the left
or ebx, ebx
jz BlitLineSetup
LeftSkipLoop:
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, ebx
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, ebx // skip partial run, jump into normal loop for rest
sub ecx, ebx
mov ebx, BlitLength
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2:
add esi, ecx // skip whole run, and start blit with new run
jmp BlitLineSetup
LSSkip1:
add esi, ecx // skip whole run, continue skipping
sub ebx, ecx
jmp LeftSkipLoop
LSTrans:
and ecx, 07fH
cmp ecx, ebx
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, ebx // skip partial run, jump into normal loop for rest
mov ebx, BlitLength
jmp BlitTransparent
LSTrans1:
sub ebx, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup: // Does any actual blitting (trans/non) for the line
mov ebx, BlitLength
mov Unblitted, 0
BlitDispatch:
or ebx, ebx // Check to see if we're done blitting
jz RightSkipLoop
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
BlitNonTransLoop:
cmp ecx, ebx
jbe BNTrans1
sub ecx, ebx
mov Unblitted, ecx
mov ecx, ebx
BNTrans1:
sub ebx, ecx
clc
rcr cl, 1
jnc BlitNTL2
mov ax, [edi]
mov ax, [edx+eax]
mov [edi], ax
inc esi
add edi, 2
BlitNTL2:
clc
rcr cl, 1
jnc BlitNTL3
mov ax, [edi]
mov ax, [edx+eax]
mov [edi], ax
mov ax, [edi+2]
mov ax, [edx+eax]
mov [edi+2], ax
add esi, 2
add edi, 4
BlitNTL3:
or cl, cl
jz BlitLineEnd
BlitNTL4:
mov ax, [edi]
mov ax, [edx+eax]
mov [edi], ax
mov ax, [edi+2]
mov ax, [edx+eax]
mov [edi+2], ax
mov ax, [edi+4]
mov ax, [edx+eax]
mov [edi+4], ax
mov ax, [edi+6]
mov ax, [edx+eax]
mov [edi+6], ax
add esi, 4
add edi, 8
dec cl
jnz BlitNTL4
BlitLineEnd:
add esi, Unblitted
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
cmp ecx, ebx
jbe BTrans1
mov ecx, ebx
BTrans1:
sub ebx, ecx
// shl ecx, 1
add ecx, ecx
add edi, ecx
jmp BlitDispatch
RightSkipLoop:
RSLoop1:
mov al, [esi]
inc esi
or al, al
jnz RSLoop1
dec BlitHeight
jz BlitDone
add edi, LineSkip
jmp LeftSkipSetup
BlitDone:
}
return(TRUE);
}
//*****************************************************************************
//** 16 Bit Blitters
//**
//*****************************************************************************
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferMonoShadowClip
Uses a bitmap an 8BPP template for blitting. Anywhere a 1 appears in the bitmap, a shadow
is blitted to the destination (a black pixel). Any other value above zero is considered a
forground color, and zero is background. If the parameter for the background color is zero,
transparency is used for the background.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferMonoShadowClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion, UINT16 usForeground, UINT16 usBackground, UINT16 usShadow )
{
UINT32 uiOffset;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, 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
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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(TRUE);
// check if whole thing is clipped
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
return(TRUE);
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
LineSkip=(uiDestPitchBYTES-(BlitLength*2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
xor eax, eax
xor ecx, ecx
cmp TopSkip, 0 // check for nothing clipped on top
je LeftSkipSetup
TopSkipLoop: // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
jmp TopSkipLoop
TSEndLine:
dec TopSkip
jnz TopSkipLoop
LeftSkipSetup:
mov Unblitted, 0
mov eax, LeftSkip
mov LSCount, eax
or eax, eax
jz BlitLineSetup
LeftSkipLoop:
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, LSCount
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, LSCount // skip partial run, jump into normal loop for rest
sub ecx, LSCount
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2:
add esi, ecx // skip whole run, and start blit with new run
jmp BlitLineSetup
LSSkip1:
add esi, ecx // skip whole run, continue skipping
sub LSCount, ecx
jmp LeftSkipLoop
LSTrans:
and ecx, 07fH
cmp ecx, LSCount
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, LSCount // skip partial run, jump into normal loop for rest
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitTransparent
LSTrans1:
sub LSCount, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup: // Does any actual blitting (trans/non) for the line
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
BlitDispatch:
cmp LSCount, 0 // Check to see if we're done blitting
je RightSkipLoop
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
BlitNonTransLoop: // blit non-transparent pixels
cmp ecx, LSCount
jbe BNTrans1
sub ecx, LSCount
mov Unblitted, ecx
mov ecx, LSCount
BNTrans1:
sub LSCount, ecx
BlitNTL1:
xor eax, eax
mov al, [esi]
cmp al, 1
jne BlitNTL3
// write shadow pixel
mov ax, usShadow
// only write if not zero
cmp ax, 0
je BlitNTL2
mov [edi], ax
jmp BlitNTL2
BlitNTL3:
or al, al
jz BlitNTL4
// write foreground pixel
mov ax, usForeground
mov [edi], ax
jmp BlitNTL2
BlitNTL4:
cmp usBackground, 0
je BlitNTL2
mov ax, usBackground
mov [edi], ax
BlitNTL2:
inc esi
add edi, 2
dec cl
jnz BlitNTL1
//BlitLineEnd:
add esi, Unblitted
jmp BlitDispatch
BlitTransparent: // skip transparent pixels
and ecx, 07fH
cmp ecx, LSCount
jbe BTrans1
mov ecx, LSCount
BTrans1:
sub LSCount, ecx
mov ax, usBackground
or ax, ax
jz BTrans2
rep stosw
jmp BlitDispatch
BTrans2:
// shl ecx, 1
add ecx, ecx
add edi, ecx
jmp BlitDispatch
RightSkipLoop: // skip along until we hit and end-of-line marker
RSLoop1:
mov al, [esi]
inc esi
or al, al
jnz RSLoop1
dec BlitHeight
jz BlitDone
add edi, LineSkip
jmp LeftSkipSetup
BlitDone:
}
return(TRUE);
}
extern void WriteMessageToFile( const STR16 pString );
/**********************************************************************************************
Blt16BPPTo16BPP
Copies a rect of 16 bit data from a video buffer to a buffer position of the brush
in the data area, for later blitting. Used to copy background information for mercs
etc. to their unblit buffer, for later reblitting. Does NOT clip.
**********************************************************************************************/
BOOLEAN Blt16BPPTo16BPP(UINT16 *pDest, UINT32 uiDestPitch, UINT16 *pSrc, UINT32 uiSrcPitch, INT32 iDestXPos, INT32 iDestYPos, INT32 iSrcXPos, INT32 iSrcYPos, UINT32 uiWidth, UINT32 uiHeight)
{
UINT16 *pSrcPtr, *pDestPtr;
UINT32 uiLineSkipDest, uiLineSkipSrc;
Assert(pDest!=NULL);
Assert(pSrc!=NULL);
try
{
UINT32 surfID = SurfaceData::GetSurfaceID((BYTE*)pDest);
ClipRectangle::ClipType ct;
if( (ct=g_SurfaceRectangle[surfID].Clip(iDestXPos, iDestYPos,uiWidth, uiHeight)) != ClipRectangle::NoClip )
{
#if _DEBUG
WriteMessageToFile(L"Trying to render to outside of destination surface");
#endif
if(ct == ClipRectangle::FullClip)
{
return false;
}
}
surfID = SurfaceData::GetSurfaceID((BYTE*)pSrc);
if( surfID && (ct=g_SurfaceRectangle[surfID].Clip(iSrcXPos, iSrcYPos,uiWidth, uiHeight)) != ClipRectangle::NoClip )
{
#if _DEBUG
WriteMessageToFile(L"Trying to render from outside of surface surface");
#endif
if(ct == ClipRectangle::FullClip)
{
return false;
}
}
}
catch(std::exception& ex)
{
SGP_ERROR(ex.what());
return false;
}
pSrcPtr=(UINT16 *)((UINT8 *)pSrc+(iSrcYPos*uiSrcPitch)+(iSrcXPos*2));
pDestPtr=(UINT16 *)((UINT8 *)pDest+(iDestYPos*uiDestPitch)+(iDestXPos*2));
uiLineSkipDest=uiDestPitch-(uiWidth*2);
uiLineSkipSrc=uiSrcPitch-(uiWidth*2);
__asm {
mov esi, pSrcPtr
mov edi, pDestPtr
mov ebx, uiHeight
cld
mov ecx, uiWidth
test ecx, 1
jz BlitDwords
BlitNewLine:
mov ecx, uiWidth
shr ecx, 1
movsw
//BlitNL2:
rep movsd
add edi, uiLineSkipDest
add esi, uiLineSkipSrc
dec ebx
jnz BlitNewLine
jmp BlitDone
BlitDwords:
mov ecx, uiWidth
shr ecx, 1
rep movsd
add edi, uiLineSkipDest
add esi, uiLineSkipSrc
dec ebx
jnz BlitDwords
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt16BPPTo16BPPTrans
Copies a rect of 16 bit data from a video buffer to a buffer position of the brush
in the data area, for later blitting. Used to copy background information for mercs
etc. to their unblit buffer, for later reblitting. Does NOT clip. Transparent color is
not copied.
**********************************************************************************************/
BOOLEAN Blt16BPPTo16BPPTrans(UINT16 *pDest, UINT32 uiDestPitch, UINT16 *pSrc, UINT32 uiSrcPitch, INT32 iDestXPos, INT32 iDestYPos, INT32 iSrcXPos, INT32 iSrcYPos, UINT32 uiWidth, UINT32 uiHeight, UINT16 usTrans)
{
UINT16 *pSrcPtr, *pDestPtr;
UINT32 uiLineSkipDest, uiLineSkipSrc;
Assert(pDest!=NULL);
Assert(pSrc!=NULL);
pSrcPtr = (UINT16*)((UINT8 *)pSrc+(iSrcYPos*uiSrcPitch)+(iSrcXPos*2));
pDestPtr = (UINT16*)((UINT8 *)pDest+(iDestYPos*uiDestPitch)+(iDestXPos*2));
uiLineSkipDest = uiDestPitch - (uiWidth*2);
uiLineSkipSrc = uiSrcPitch - (uiWidth*2);
#if 1
do
{
UINT32 w = uiWidth;
do
{
if (*pSrcPtr != usTrans) *pDestPtr = *pSrcPtr;
pSrcPtr++;
pDestPtr++;
}
while (--w != 0);
pSrcPtr = (UINT16*)((UINT8*)pSrcPtr + uiLineSkipSrc);
pDestPtr = (UINT16*)((UINT8*)pDestPtr + uiLineSkipDest);
}
while (--uiHeight != 0);
#else
__asm {
mov esi, pSrcPtr
mov edi, pDestPtr
mov ebx, uiHeight
mov dx, usTrans
BlitNewLine:
mov ecx, uiWidth
Blit2:
mov ax, [esi]
cmp ax, dx
je Blit3
mov [edi], ax
Blit3:
add esi, 2
add edi, 2
dec ecx
jnz Blit2
add edi, uiLineSkipDest
add esi, uiLineSkipSrc
dec ebx
jnz BlitNewLine
}
#endif
return(TRUE);
}
BOOLEAN Blt16BPPTo16BPPTransShadow(UINT16 *pDest, UINT32 uiDestPitch, UINT16 *pSrc, UINT32 uiSrcPitch, INT32 iDestXPos, INT32 iDestYPos, INT32 iSrcXPos, INT32 iSrcYPos, UINT32 uiWidth, UINT32 uiHeight, UINT16 usTrans)
{
UINT16 *pSrcPtr, *pDestPtr;
UINT32 uiLineSkipDest, uiLineSkipSrc;
Assert(pDest != NULL);
Assert(pSrc != NULL);
pSrcPtr = (UINT16*)((UINT8 *)pSrc + (iSrcYPos * uiSrcPitch) + (iSrcXPos * 2));
pDestPtr = (UINT16*)((UINT8 *)pDest + (iDestYPos * uiDestPitch) + (iDestXPos * 2));
uiLineSkipDest = uiDestPitch - (uiWidth * 2);
uiLineSkipSrc = uiSrcPitch - (uiWidth * 2);
#if 1
do
{
UINT32 w = uiWidth;
do
{
if (*pSrcPtr != usTrans)
{
*pDestPtr = ShadeTable[*pDestPtr];
}
pSrcPtr++;
pDestPtr++;
}
while (--w != 0);
pSrcPtr = (UINT16*)((UINT8*)pSrcPtr + uiLineSkipSrc);
pDestPtr = (UINT16*)((UINT8*)pDestPtr + uiLineSkipDest);
}
while (--uiHeight != 0);
#endif
return TRUE;
}
/**********************************************************************************************
Blt16BPPTo16BPPMirror
Copies a rect of 16 bit data from a video buffer to a buffer position of the brush
in the data area, for later blitting. Used to copy background information for mercs
etc. to their unblit buffer, for later reblitting. Does NOT clip.
**********************************************************************************************/
BOOLEAN Blt16BPPTo16BPPMirror(UINT16 *pDest, UINT32 uiDestPitch, UINT16 *pSrc, UINT32 uiSrcPitch, INT32 iDestXPos, INT32 iDestYPos, INT32 iSrcXPos, INT32 iSrcYPos, UINT32 uiWidth, UINT32 uiHeight)
{
UINT16 *pSrcPtr, *pDestPtr;
UINT32 uiLineSkipDest, uiLineSkipSrc;
INT32 RightSkip, LeftSkip, TopSkip, BottomSkip, BlitLength, BlitHeight;
INT32 iTempX, iTempY, ClipX1, ClipY1, ClipX2, ClipY2;
SGPRect *clipregion=NULL;
Assert(pDest!=NULL);
Assert(pSrc!=NULL);
// Add to start position of dest buffer
iTempX = iDestXPos;
iTempY = iDestYPos;
if(clipregion==NULL)
{
ClipX1= ClippingRect.iLeft; //0; it was changed, why??? joker//;
ClipY1= ClippingRect.iTop; //0; //;
ClipX2= ClippingRect.iRight; //SCREEN_WIDTH; //;
ClipY2= ClippingRect.iBottom; //SCREEN_HEIGHT; //;
}
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)uiWidth);
RightSkip=__min(__max(ClipX2, (iTempX+(INT32)uiWidth)) - ClipX2, (INT32)uiWidth);
TopSkip=__min(ClipY1 - __min(ClipY1, iTempY), (INT32)uiHeight);
BottomSkip=__min(__max(ClipY2, (iTempY+(INT32)uiHeight)) - ClipY2, (INT32)uiHeight);
iTempX=__max(ClipX1, iDestXPos);
iTempY=__max(ClipY1, iDestYPos);
// calculate the remaining rows and columns to blit
BlitLength=((INT32)uiWidth-LeftSkip-RightSkip);
BlitHeight=((INT32)uiHeight-TopSkip-BottomSkip);
// check if whole thing is clipped
if((LeftSkip >=(INT32)uiWidth) || (RightSkip >=(INT32)uiWidth))
return(TRUE);
// check if whole thing is clipped
if((TopSkip >=(INT32)uiHeight) || (BottomSkip >=(INT32)uiHeight))
return(TRUE);
pSrcPtr=(UINT16 *)((UINT8 *)pSrc+(TopSkip*uiSrcPitch)+(RightSkip*2));
pDestPtr=(UINT16 *)((UINT8 *)pDest+(iTempY*uiDestPitch)+(iTempX*2)+((BlitLength-1)*2));
uiLineSkipDest=uiDestPitch;//+((BlitLength-1)*2);
uiLineSkipSrc=uiSrcPitch-(BlitLength*2);
__asm {
mov esi, pSrcPtr
mov edi, pDestPtr
mov ebx, BlitHeight
BlitNewLine:
mov ecx, BlitLength
//add edi, ecx
//add edi, ecx
BlitNTL2:
mov ax, [esi]
mov [edi], ax
inc esi
dec edi
inc esi
dec edi
dec ecx
jnz BlitNTL2
add edi, BlitLength
add esi, uiLineSkipSrc
add edi, BlitLength
add edi, uiLineSkipDest
dec ebx
jnz BlitNewLine
}
return(TRUE);
}
/***********************************************************************************************
Blt8BPPTo8BPP
Copies a rect of an 8 bit data from a video buffer to a buffer position of the brush
in the data area, for later blitting. Used to copy background information for mercs
etc. to their unblit buffer, for later reblitting. Does NOT clip.
**********************************************************************************************/
BOOLEAN Blt8BPPTo8BPP(UINT8 *pDest, UINT32 uiDestPitch, UINT8 *pSrc, UINT32 uiSrcPitch, INT32 iDestXPos, INT32 iDestYPos, INT32 iSrcXPos, INT32 iSrcYPos, UINT32 uiWidth, UINT32 uiHeight)
{
UINT8 *pSrcPtr, *pDestPtr;
UINT32 uiLineSkipDest, uiLineSkipSrc;
Assert(pDest!=NULL);
Assert(pSrc!=NULL);
pSrcPtr=pSrc+(iSrcYPos*uiSrcPitch)+(iSrcXPos);
pDestPtr=pDest+(iDestYPos*uiDestPitch)+(iDestXPos);
uiLineSkipDest=uiDestPitch-(uiWidth);
uiLineSkipSrc=uiSrcPitch-(uiWidth);
__asm {
mov esi, pSrcPtr
mov edi, pDestPtr
mov ebx, uiHeight
cld
BlitNewLine:
mov ecx, uiWidth
clc
rcr ecx, 1
jnc Blit2
movsb
Blit2:
clc
rcr ecx, 1
jnc Blit3
movsw
Blit3:
or ecx, ecx
jz BlitLineDone
rep movsd
BlitLineDone:
add edi, uiLineSkipDest
add esi, uiLineSkipSrc
dec ebx
jnz BlitNewLine
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferTransZPixelate
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
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").
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferTransZPixelate( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex )
{
UINT32 usHeight, usWidth, uiOffset, LineSkip;
INT32 iTempX, iTempY;
UINT16 *p16BPPPalette;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 uiLineFlag;
ETRLEObject *pTrav;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
p16BPPPalette = hSrcVObject->pShadeCurrent;
LineSkip=(uiDestPitchBYTES-(usWidth*2));
uiLineFlag=(iTempY&1);
__asm {
mov esi, SrcPtr
mov edi, DestPtr
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
mov edx, p16BPPPalette
BlitDispatch:
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
BlitNTL4:
test uiLineFlag, 1
jz BlitNTL6
test edi, 2
jz BlitNTL5
jmp BlitNTL7
BlitNTL6:
test edi, 2
jnz BlitNTL5
BlitNTL7:
mov ax, [ebx]
cmp ax, usZValue
ja BlitNTL5
mov ax, usZValue
mov [ebx], ax
xor eax, eax
mov al, [esi]
mov ax, [edx+eax*2]
mov [edi], ax
BlitNTL5:
inc esi
add edi, 2
add ebx, 2
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
BlitDoneLine:
dec usHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
xor uiLineFlag, 1
jmp BlitDispatch
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferTransZPixelateObscured
// OK LIKE NORMAL PIXELATE BUT ONLY PIXELATES STUFF BELOW Z level
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
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").
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferTransZPixelateObscured( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex )
{
UINT32 usHeight, usWidth, uiOffset, LineSkip;
INT32 iTempX, iTempY;
UINT16 *p16BPPPalette;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 uiLineFlag;
ETRLEObject *pTrav;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
p16BPPPalette = hSrcVObject->pShadeCurrent;
LineSkip=(uiDestPitchBYTES-(usWidth*2));
uiLineFlag=(iTempY&1);
__asm {
mov esi, SrcPtr
mov edi, DestPtr
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
mov edx, p16BPPPalette
BlitDispatch:
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
BlitNTL4:
// TEST FOR Z FIRST!
mov ax, [ebx]
cmp ax, usZValue
jae BlitNTL8
// Write it NOW!
jmp BlitNTL7
BlitNTL8:
test uiLineFlag, 1
jz BlitNTL6
test edi, 2
jz BlitNTL5
jmp BlitNTL9
BlitNTL6:
test edi, 2
jnz BlitNTL5
BlitNTL7:
// Write normal z value
mov ax, usZValue
mov [ebx], ax
//jmp BlitNTL10
BlitNTL9:
// Write no z
//mov ax, 32767
//mov [ebx], ax
//BlitNTL10:
xor eax, eax
mov al, [esi]
mov ax, [edx+eax*2]
mov [edi], ax
BlitNTL5:
inc esi
add edi, 2
add ebx, 2
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
BlitDoneLine:
dec usHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
xor uiLineFlag, 1
jmp BlitDispatch
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferTransZClipPixelate
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
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").
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferTransZClipPixelate( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion)
{
UINT16 *p16BPPPalette;
UINT32 uiOffset, uiLineFlag;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, 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
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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(TRUE);
// check if whole thing is clipped
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
return(TRUE);
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
p16BPPPalette = hSrcVObject->pShadeCurrent;
LineSkip=(uiDestPitchBYTES-(BlitLength*2));
uiLineFlag=(iTempY&1);
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
cmp TopSkip, 0 // check for nothing clipped on top
je LeftSkipSetup
TopSkipLoop: // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
jmp TopSkipLoop
TSEndLine:
dec TopSkip
jnz TopSkipLoop
LeftSkipSetup:
mov Unblitted, 0
mov eax, LeftSkip
mov LSCount, eax
or eax, eax
jz BlitLineSetup
LeftSkipLoop:
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, LSCount
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, LSCount // skip partial run, jump into normal loop for rest
sub ecx, LSCount
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2:
add esi, ecx // skip whole run, and start blit with new run
jmp BlitLineSetup
LSSkip1:
add esi, ecx // skip whole run, continue skipping
sub LSCount, ecx
jmp LeftSkipLoop
LSTrans:
and ecx, 07fH
cmp ecx, LSCount
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, LSCount // skip partial run, jump into normal loop for rest
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitTransparent
LSTrans1:
sub LSCount, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup: // Does any actual blitting (trans/non) for the line
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
BlitDispatch:
cmp LSCount, 0 // Check to see if we're done blitting
je RightSkipLoop
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
BlitNonTransLoop: // blit non-transparent pixels
cmp ecx, LSCount
jbe BNTrans1
sub ecx, LSCount
mov Unblitted, ecx
mov ecx, LSCount
BNTrans1:
sub LSCount, ecx
BlitNTL1:
test uiLineFlag, 1
jz BlitNTL6
test edi, 2
jz BlitNTL2
jmp BlitNTL7
BlitNTL6:
test edi, 2
jnz BlitNTL2
BlitNTL7:
mov ax, [ebx]
cmp ax, usZValue
ja BlitNTL2
mov ax, usZValue
mov [ebx], ax
xor eax, eax
mov al, [esi]
mov ax, [edx+eax*2]
mov [edi], ax
BlitNTL2:
inc esi
add edi, 2
add ebx, 2
dec cl
jnz BlitNTL1
//BlitLineEnd:
add esi, Unblitted
jmp BlitDispatch
BlitTransparent: // skip transparent pixels
and ecx, 07fH
cmp ecx, LSCount
jbe BTrans1
mov ecx, LSCount
BTrans1:
sub LSCount, ecx
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
RightSkipLoop: // skip along until we hit and end-of-line marker
RSLoop1:
mov al, [esi]
inc esi
or al, al
jnz RSLoop1
xor uiLineFlag, 1
dec BlitHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
jmp LeftSkipSetup
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferTransZNBPixelate
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").
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferTransZNBPixelate( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex )
{
UINT32 usHeight, usWidth, uiOffset, LineSkip;
INT32 iTempX, iTempY;
UINT16 *p16BPPPalette;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 uiLineFlag;
ETRLEObject *pTrav;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
p16BPPPalette = hSrcVObject->pShadeCurrent;
LineSkip=(uiDestPitchBYTES-(usWidth*2));
uiLineFlag=(iTempY&1);
__asm {
mov esi, SrcPtr
mov edi, DestPtr
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
mov edx, p16BPPPalette
BlitDispatch:
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
BlitNTL4:
test uiLineFlag, 1
jz BlitNTL6
test edi, 2
jz BlitNTL5
jmp BlitNTL7
BlitNTL6:
test edi, 2
jnz BlitNTL5
BlitNTL7:
mov ax, [ebx]
cmp ax, usZValue
ja BlitNTL5
// ATE: DONOT WRITE Z VALUE
//mov ax, usZValue
//mov [ebx], ax
xor eax, eax
mov al, [esi]
mov ax, [edx+eax*2]
mov [edi], ax
BlitNTL5:
inc esi
add edi, 2
add ebx, 2
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
BlitDoneLine:
dec usHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
xor uiLineFlag, 1
jmp BlitDispatch
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferTransZNBClipPixelate
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").
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferTransZNBClipPixelate( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion)
{
UINT16 *p16BPPPalette;
UINT32 uiOffset, uiLineFlag;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, 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
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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(TRUE);
// check if whole thing is clipped
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
return(TRUE);
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
p16BPPPalette = hSrcVObject->pShadeCurrent;
LineSkip=(uiDestPitchBYTES-(BlitLength*2));
uiLineFlag=(iTempY&1);
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
cmp TopSkip, 0 // check for nothing clipped on top
je LeftSkipSetup
TopSkipLoop: // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
jmp TopSkipLoop
TSEndLine:
dec TopSkip
jnz TopSkipLoop
LeftSkipSetup:
mov Unblitted, 0
mov eax, LeftSkip
mov LSCount, eax
or eax, eax
jz BlitLineSetup
LeftSkipLoop:
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, LSCount
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, LSCount // skip partial run, jump into normal loop for rest
sub ecx, LSCount
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2:
add esi, ecx // skip whole run, and start blit with new run
jmp BlitLineSetup
LSSkip1:
add esi, ecx // skip whole run, continue skipping
sub LSCount, ecx
jmp LeftSkipLoop
LSTrans:
and ecx, 07fH
cmp ecx, LSCount
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, LSCount // skip partial run, jump into normal loop for rest
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitTransparent
LSTrans1:
sub LSCount, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup: // Does any actual blitting (trans/non) for the line
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
BlitDispatch:
cmp LSCount, 0 // Check to see if we're done blitting
je RightSkipLoop
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
BlitNonTransLoop: // blit non-transparent pixels
cmp ecx, LSCount
jbe BNTrans1
sub ecx, LSCount
mov Unblitted, ecx
mov ecx, LSCount
BNTrans1:
sub LSCount, ecx
BlitNTL1:
test uiLineFlag, 1
jz BlitNTL6
test edi, 2
jz BlitNTL2
jmp BlitNTL7
BlitNTL6:
test edi, 2
jnz BlitNTL2
BlitNTL7:
mov ax, [ebx]
cmp ax, usZValue
ja BlitNTL2
//mov ax, usZValue
//mov [ebx], ax
xor eax, eax
mov al, [esi]
mov ax, [edx+eax*2]
mov [edi], ax
BlitNTL2:
inc esi
add edi, 2
add ebx, 2
dec cl
jnz BlitNTL1
//BlitLineEnd:
add esi, Unblitted
jmp BlitDispatch
BlitTransparent: // skip transparent pixels
and ecx, 07fH
cmp ecx, LSCount
jbe BTrans1
mov ecx, LSCount
BTrans1:
sub LSCount, ecx
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
RightSkipLoop: // skip along until we hit and end-of-line marker
RSLoop1:
mov al, [esi]
inc esi
or al, al
jnz RSLoop1
xor uiLineFlag, 1
dec BlitHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
jmp LeftSkipSetup
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferTransZ
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
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.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferTransZ( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex )
{
UINT16 *p16BPPPalette;
UINT32 uiOffset;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
p16BPPPalette = hSrcVObject->pShadeCurrent;
LineSkip=(uiDestPitchBYTES-(usWidth*2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
BlitDispatch:
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
xor eax, eax
BlitNTL4:
mov ax, usZValue
cmp ax, [ebx]
jb BlitNTL5
mov [ebx], ax
xor ah, ah
mov al, [esi]
mov ax, [edx+eax*2]
mov [edi], ax
BlitNTL5:
inc esi
inc edi
inc ebx
inc edi
inc ebx
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
BlitDoneLine:
dec usHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
jmp BlitDispatch
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferTransZNB
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 value is
NOT updated by this version. The Z-buffer is 16 bit, and must be the same dimensions
(including Pitch) as the destination.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferTransZNB( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex )
{
UINT16 *p16BPPPalette;
UINT32 uiOffset;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
p16BPPPalette = hSrcVObject->pShadeCurrent;
LineSkip=(uiDestPitchBYTES-(usWidth*2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
BlitDispatch:
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
xor eax, eax
BlitNTL4:
mov ax, [ebx]
cmp ax, usZValue
ja BlitNTL5
xor ah, ah
mov al, [esi]
mov ax, [edx+eax*2]
mov [edi], ax
BlitNTL5:
inc esi
inc edi
inc ebx
inc edi
inc ebx
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
BlitDoneLine:
dec usHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
jmp BlitDispatch
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferTransZNBColor
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 value is
NOT updated by this version. The Z-buffer is 16 bit, and must be the same dimensions
(including Pitch) as the destination. Any pixels that fail the Z test, are written
to with the specified color value.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferTransZNBColor( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, UINT16 usColor)
{
UINT16 *p16BPPPalette;
UINT32 uiOffset;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
p16BPPPalette = hSrcVObject->pShadeCurrent;
LineSkip=(uiDestPitchBYTES-(usWidth*2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
BlitDispatch:
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
xor eax, eax
BlitNTL4:
mov ax, [ebx]
cmp ax, usZValue
ja BlitNTL5
xor ah, ah
mov al, [esi]
mov ax, [edx+eax*2]
mov [edi], ax
jmp BlitNTL6
BlitNTL5:
mov ax, usColor
mov [edi], ax
BlitNTL6:
inc esi
inc edi
inc ebx
inc edi
inc ebx
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
BlitDoneLine:
dec usHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
jmp BlitDispatch
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferTransShadow
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
updated to the current value, for any non-transparent pixels. If the source pixel is 254,
it is considered a shadow, and the destination buffer is darkened rather than blitted on.
The Z-buffer is 16 bit, and must be the same dimensions (including Pitch) as the destination.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadow(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, UINT16 *p16BPPPalette, BOOLEAN fIgnoreShadows)
{
UINT32 uiOffset;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
LineSkip=(uiDestPitchBYTES-(usWidth*2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
xor ecx, ecx
BlitDispatch:
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
BlitNTL4:
xor eax, eax
mov al, [esi]
cmp al, 254
jne BlitNTL6
mov al, fIgnoreShadows
cmp al, 0
jne BlitNTL5
mov ax, [edi]
mov ax, ShadeTable[eax*2]
mov [edi], ax
jmp BlitNTL5
BlitNTL6:
mov ax, [edx+eax*2]
mov [edi], ax
BlitNTL5:
inc esi
add edi, 2
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
// shl ecx, 1
add ecx, ecx
add edi, ecx
jmp BlitDispatch
BlitDoneLine:
dec usHeight
jz BlitDone
add edi, LineSkip
jmp BlitDispatch
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferTransShadow
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
updated to the current value, for any non-transparent pixels. If the source pixel is 254,
it is considered a shadow, and the destination buffer is darkened rather than blitted on.
The Z-buffer is 16 bit, and must be the same dimensions (including Pitch) as the destination.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadowAlpha(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, HVOBJECT hAlphaVObject, INT32 iX, INT32 iY, UINT16 usIndex, UINT16 *p16BPPPalette, BOOLEAN fIgnoreShadows)
{
UINT32 uiOffset;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr, *AlphaPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY;
// Assertions
Assert(hSrcVObject != NULL);
Assert(hAlphaVObject != NULL);
Assert(pBuffer != NULL);
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[usIndex]);
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF(iTempX >= 0);
CHECKF(iTempY >= 0);
SrcPtr = (UINT8 *)hSrcVObject->pPixData + uiOffset;
AlphaPtr = (UINT8 *)hAlphaVObject->pPixData + (hAlphaVObject->pETRLEObject[usIndex]).uiDataOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX * 2);
LineSkip = (uiDestPitchBYTES - (usWidth * 2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
xor ecx, ecx
BlitDispatch :
mov cl, [esi]
inc esi
push esi
mov esi, AlphaPtr
inc esi
mov AlphaPtr, esi
pop esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
BlitNTL4 :
xor eax, eax
mov al, [esi]
cmp al, 254
jne BlitNTL6
mov al, fIgnoreShadows
cmp al, 0
jne BlitNTL5
mov ax, [edi]
mov ax, ShadeTable[eax * 2]
mov[edi], ax
jmp BlitNTL5
BlitNTL6 :
mov ax, [edx + eax * 2]
push edx
push ecx
push ebx
push esi
mov esi, AlphaPtr
xor ebx, ebx
mov bl, [esi]
pop esi
push ebx
push[edi]
push eax
call blendWithAlpha
add esp, 12
pop ebx
pop ecx
pop edx
mov[edi], ax
BlitNTL5 :
inc esi
push esi
mov esi, AlphaPtr
inc esi
mov AlphaPtr, esi
pop esi
add edi, 2
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent :
and ecx, 07fH
// shl ecx, 1
add ecx, ecx
add edi, ecx
jmp BlitDispatch
BlitDoneLine :
dec usHeight
jz BlitDone
add edi, LineSkip
jmp BlitDispatch
BlitDone :
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferTransShadowZ
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
updated to the current value, for any non-transparent pixels. If the source pixel is 254,
it is considered a shadow, and the destination buffer is darkened rather than blitted on.
The Z-buffer is 16 bit, and must be the same dimensions (including Pitch) as the destination.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadowZAlpha(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, HVOBJECT hAlphaVObject, INT32 iX, INT32 iY, UINT16 usIndex, UINT16 *p16BPPPalette, BOOLEAN fIgnoreShadows)
{
UINT32 uiOffset;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr, *ZPtr, *AlphaPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY;
// Assertions
Assert(hSrcVObject != NULL);
Assert(hAlphaVObject != NULL);
Assert(pBuffer != NULL);
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[usIndex]);
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF(iTempX >= 0);
CHECKF(iTempY >= 0);
SrcPtr = (UINT8 *)hSrcVObject->pPixData + uiOffset;
AlphaPtr = (UINT8 *)hAlphaVObject->pPixData + (hAlphaVObject->pETRLEObject[usIndex]).uiDataOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX * 2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*iTempY) + (iTempX * 2);
LineSkip = (uiDestPitchBYTES - (usWidth * 2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
BlitDispatch :
mov cl, [esi]
inc esi
push esi
mov esi, AlphaPtr
inc esi
mov AlphaPtr, esi
pop esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
BlitNTL4 :
mov ax, [ebx]
cmp ax, usZValue
jae BlitNTL5
mov ax, usZValue
mov[ebx], ax
xor eax, eax
mov al, [esi]
cmp al, 254
jne BlitNTL6
mov al, fIgnoreShadows
cmp al, 0
jne BlitNTL5
mov ax, [edi]
mov ax, ShadeTable[eax * 2]
mov[edi], ax
jmp BlitNTL5
BlitNTL6 :
mov ax, [edx + eax * 2]
push edx
push ecx
push ebx
push esi
mov esi, AlphaPtr
xor ebx, ebx
mov bl, [esi]
pop esi
push ebx
push[edi]
push eax
call blendWithAlpha
add esp, 12
pop ebx
pop ecx
pop edx
mov[edi], ax
BlitNTL5 :
inc esi
push esi
mov esi, AlphaPtr
inc esi
mov AlphaPtr, esi
pop esi
add edi, 2
add ebx, 2
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent :
and ecx, 07fH
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
BlitDoneLine :
dec usHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
jmp BlitDispatch
BlitDone :
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferTransShadowZ
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
updated to the current value, for any non-transparent pixels. If the source pixel is 254,
it is considered a shadow, and the destination buffer is darkened rather than blitted on.
The Z-buffer is 16 bit, and must be the same dimensions (including Pitch) as the destination.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadowZ(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, UINT16 *p16BPPPalette, BOOLEAN fIgnoreShadows)
{
UINT32 uiOffset;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
LineSkip=(uiDestPitchBYTES-(usWidth*2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
BlitDispatch:
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
BlitNTL4:
mov ax, [ebx]
cmp ax, usZValue
jae BlitNTL5
mov ax, usZValue
mov [ebx], ax
xor eax, eax
mov al, [esi]
cmp al, 254
jne BlitNTL6
mov al, fIgnoreShadows
cmp al, 0
jne BlitNTL5
mov ax, [edi]
mov ax, ShadeTable[eax*2]
mov [edi], ax
jmp BlitNTL5
BlitNTL6:
mov ax, [edx+eax*2]
mov [edi], ax
BlitNTL5:
inc esi
add edi, 2
add ebx, 2
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
BlitDoneLine:
dec usHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
jmp BlitDispatch
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferTransShadowZNB
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 value is NOT
updated. If the source pixel is 254, it is considered a shadow, and the destination
buffer is darkened rather than blitted on. The Z-buffer is 16 bit, and must be the same
dimensions (including Pitch) as the destination.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadowZNB(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, UINT16 *p16BPPPalette, BOOLEAN fIgnoreShadows)
{
UINT32 uiOffset;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
LineSkip=(uiDestPitchBYTES-(usWidth*2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
BlitDispatch:
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
BlitNTL4:
mov ax, [ebx]
cmp ax, usZValue
ja BlitNTL5
xor eax, eax
mov al, [esi]
cmp al, 254
jne BlitNTL6
mov ax, [ebx]
cmp ax, usZValue
jae BlitNTL5
mov al, fIgnoreShadows
cmp al, 0
jne BlitNTL5
mov ax, [edi]
mov ax, ShadeTable[eax*2]
mov [edi], ax
jmp BlitNTL5
BlitNTL6:
mov ax, [edx+eax*2]
mov [edi], ax
BlitNTL5:
inc esi
add edi, 2
add ebx, 2
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
BlitDoneLine:
dec usHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
jmp BlitDispatch
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferTransShadowZNB
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 value is NOT
updated. If the source pixel is 254, it is considered a shadow, and the destination
buffer is darkened rather than blitted on. The Z-buffer is 16 bit, and must be the same
dimensions (including Pitch) as the destination.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadowZNBAlpha(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, HVOBJECT hAlphaVObject, INT32 iX, INT32 iY, UINT16 usIndex, UINT16 *p16BPPPalette, BOOLEAN fIgnoreShadows)
{
UINT32 uiOffset;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr, *ZPtr, *AlphaPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY;
// Assertions
Assert(hSrcVObject != NULL);
Assert(hAlphaVObject != NULL);
Assert(pBuffer != NULL);
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[usIndex]);
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF(iTempX >= 0);
CHECKF(iTempY >= 0);
SrcPtr = (UINT8 *)hSrcVObject->pPixData + uiOffset;
AlphaPtr = (UINT8 *)hAlphaVObject->pPixData + (hAlphaVObject->pETRLEObject[usIndex]).uiDataOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX * 2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*iTempY) + (iTempX * 2);
LineSkip = (uiDestPitchBYTES - (usWidth * 2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
BlitDispatch :
mov cl, [esi]
inc esi
push esi
mov esi, AlphaPtr
inc esi
mov AlphaPtr, esi
pop esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
BlitNTL4 :
mov ax, [ebx]
cmp ax, usZValue
ja BlitNTL5
xor eax, eax
mov al, [esi]
cmp al, 254
jne BlitNTL6
mov ax, [ebx]
cmp ax, usZValue
jae BlitNTL5
mov al, fIgnoreShadows
cmp al, 0
jne BlitNTL5
mov ax, [edi]
mov ax, ShadeTable[eax * 2]
mov[edi], ax
jmp BlitNTL5
BlitNTL6 :
mov ax, [edx + eax * 2]
push edx
push ecx
push ebx
push esi
mov esi, AlphaPtr
xor ebx, ebx
mov bl, [esi]
pop esi
push ebx
push[edi]
push eax
call blendWithAlpha
add esp, 12
pop ebx
pop ecx
pop edx
mov[edi], ax
BlitNTL5 :
inc esi
push esi
mov esi, AlphaPtr
inc esi
mov AlphaPtr, esi
pop esi
add edi, 2
add ebx, 2
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent :
and ecx, 07fH
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
BlitDoneLine :
dec usHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
jmp BlitDispatch
BlitDone :
}
return(TRUE);
}
#if 0
BlitNTL4:
// TEST FOR Z FIRST!
mov ax, [ebx]
cmp ax, usZValue
ja BlitNTL8
// Write it NOW!
jmp BlitNTL7
BlitNTL8:
test uiLineFlag, 1
jz BlitNTL6
test edi, 2
jz BlitNTL5
jmp BlitNTL9
BlitNTL6:
test edi, 2
jnz BlitNTL5
BlitNTL7:
// Write normal z value
mov ax, usZValue
mov [ebx], ax
jmp BlitNTL10
BlitNTL9:
// Write high z
mov ax, 32767
mov [ebx], ax
BlitNTL10:
xor eax, eax
mov al, [esi]
mov ax, [edx+eax*2]
mov [edi], ax
#endif
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferTransShadowZNBObscured
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 value is NOT
updated. If the source pixel is 254, it is considered a shadow, and the destination
buffer is darkened rather than blitted on. The Z-buffer is 16 bit, and must be the same
dimensions (including Pitch) as the destination.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadowZNBObscured(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, UINT16 *p16BPPPalette, BOOLEAN fIgnoreShadows)
{
UINT32 uiOffset;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY;
UINT32 uiLineFlag;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
LineSkip=(uiDestPitchBYTES-(usWidth*2));
uiLineFlag=(iTempY&1);
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
BlitDispatch:
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
BlitNTL4:
mov ax, [ebx]
cmp ax, usZValue
ja BlitNTL8
xor eax, eax
mov al, [esi]
cmp al, 254
jne BlitNTL6
mov ax, [ebx]
cmp ax, usZValue
jae BlitNTL5
mov al, fIgnoreShadows
cmp al, 0
jne BlitNTL5
mov ax, [edi]
mov ax, ShadeTable[eax*2]
mov [edi], ax
jmp BlitNTL5
BlitNTL8:
xor eax, eax
mov al, [esi]
cmp al, 254
je BlitNTL5
test uiLineFlag, 1
jz BlitNTL9
test edi, 2
jz BlitNTL5
jmp BlitNTL6
BlitNTL9:
test edi, 2
jnz BlitNTL5
BlitNTL6:
xor eax, eax
mov al, [esi]
mov ax, [edx+eax*2]
mov [edi], ax
BlitNTL5:
inc esi
add edi, 2
add ebx, 2
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
BlitDoneLine:
dec usHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
xor uiLineFlag, 1
jmp BlitDispatch
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferTransShadowZNBObscured
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 value is NOT
updated. If the source pixel is 254, it is considered a shadow, and the destination
buffer is darkened rather than blitted on. The Z-buffer is 16 bit, and must be the same
dimensions (including Pitch) as the destination.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadowZNBObscuredTest(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, UINT16 *p16BPPPalette, BOOLEAN fIgnoreShadows)
{
UINT32 uiOffset;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY;
UINT32 uiLineFlag;
// Assertions
Assert(hSrcVObject != NULL);
Assert(pBuffer != NULL);
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[usIndex]);
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF(iTempX >= 0);
CHECKF(iTempY >= 0);
SrcPtr = (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX * 2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*iTempY) + (iTempX * 2);
LineSkip = (uiDestPitchBYTES - (usWidth * 2));
uiLineFlag = (iTempY & 1);
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
BlitDispatch :
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
BlitNTL4 :
mov ax, [ebx]
cmp ax, usZValue
ja BlitNTL8
xor eax, eax
mov al, [esi]
cmp al, 254
jne BlitNTL6
mov ax, [ebx]
cmp ax, usZValue
jae BlitNTL5
mov al, fIgnoreShadows
cmp al, 0
jne BlitNTL5
mov ax, [edi]
mov ax, ShadeTable[eax * 2]
mov[edi], ax
jmp BlitNTL5
BlitNTL8 :
xor eax, eax
mov al, [esi]
cmp al, 254
je BlitNTL5
test uiLineFlag, 1
jz BlitNTL9
test edi, 2
jz BlitNTL5
jmp BlitNTL6
BlitNTL9 :
test edi, 2
jnz BlitNTL5
BlitNTL6 :
xor eax, eax
mov al, [esi]
mov ax, [edx + eax * 2]
push edx
push ecx
push ebx
push 0x0000007f
push[edi]
push eax
call blendWithAlpha
add esp, 12
pop ebx
pop ecx
pop edx
mov[edi], ax
BlitNTL5 :
inc esi
add edi, 2
add ebx, 2
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent :
and ecx, 07fH
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
BlitDoneLine :
dec usHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
xor uiLineFlag, 1
jmp BlitDispatch
BlitDone :
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferTransShadowZNBObscured
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 value is NOT
updated. If the source pixel is 254, it is considered a shadow, and the destination
buffer is darkened rather than blitted on. The Z-buffer is 16 bit, and must be the same
dimensions (including Pitch) as the destination.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadowZNBObscuredAlpha(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, HVOBJECT hAlphaVObject, INT32 iX, INT32 iY, UINT16 usIndex, UINT16 *p16BPPPalette, BOOLEAN fIgnoreShadows)
{
UINT32 uiOffset;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr, *ZPtr, *AlphaPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY;
UINT32 uiLineFlag;
// Assertions
Assert(hSrcVObject != NULL);
Assert(hAlphaVObject != NULL);
Assert(pBuffer != NULL);
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[usIndex]);
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF(iTempX >= 0);
CHECKF(iTempY >= 0);
SrcPtr = (UINT8 *)hSrcVObject->pPixData + uiOffset;
AlphaPtr = (UINT8 *)hAlphaVObject->pPixData + (hAlphaVObject->pETRLEObject[usIndex]).uiDataOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX * 2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*iTempY) + (iTempX * 2);
LineSkip = (uiDestPitchBYTES - (usWidth * 2));
uiLineFlag = (iTempY & 1);
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
BlitDispatch :
mov cl, [esi]
inc esi
push esi
mov esi, AlphaPtr
inc esi
mov AlphaPtr, esi
pop esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
BlitNTL4 :
mov ax, [ebx]
cmp ax, usZValue
ja BlitNTL8
xor eax, eax
mov al, [esi]
cmp al, 254
jne BlitNTL6
mov ax, [ebx]
cmp ax, usZValue
jae BlitNTL5
mov al, fIgnoreShadows
cmp al, 0
jne BlitNTL5
mov ax, [edi]
mov ax, ShadeTable[eax * 2]
mov[edi], ax
jmp BlitNTL5
BlitNTL8 :
xor eax, eax
mov al, [esi]
cmp al, 254
je BlitNTL5
test uiLineFlag, 1
jz BlitNTL9
test edi, 2
jz BlitNTL5
jmp BlitNTL6
BlitNTL9 :
test edi, 2
jnz BlitNTL5
BlitNTL6 :
xor eax, eax
mov al, [esi]
mov ax, [edx + eax * 2]
push edx
push ecx
push ebx
push esi
mov esi, AlphaPtr
xor ebx, ebx
mov bl, [esi]
pop esi
push ebx
push[edi]
push eax
call blendWithAlpha
add esp, 12
pop ebx
pop ecx
pop edx
mov[edi], ax
BlitNTL5 :
inc esi
push esi
mov esi, AlphaPtr
inc esi
mov AlphaPtr, esi
pop esi
add edi, 2
add ebx, 2
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent :
and ecx, 07fH
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
BlitDoneLine :
dec usHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
xor uiLineFlag, 1
jmp BlitDispatch
BlitDone :
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferTransShadowZClip
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
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. Pixels with a value of
254 are shaded instead of blitted.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadowZClip(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion, UINT16 *p16BPPPalette, BOOLEAN fIgnoreShadows)
{
UINT32 uiOffset;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, 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
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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(TRUE);
// check if whole thing is clipped
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
return(TRUE);
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
LineSkip=(uiDestPitchBYTES-(BlitLength*2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
cmp TopSkip, 0 // check for nothing clipped on top
je LeftSkipSetup
TopSkipLoop: // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
jmp TopSkipLoop
TSEndLine:
dec TopSkip
jnz TopSkipLoop
LeftSkipSetup:
mov Unblitted, 0
mov eax, LeftSkip
mov LSCount, eax
or eax, eax
jz BlitLineSetup
LeftSkipLoop:
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, LSCount
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, LSCount // skip partial run, jump into normal loop for rest
sub ecx, LSCount
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2:
add esi, ecx // skip whole run, and start blit with new run
jmp BlitLineSetup
LSSkip1:
add esi, ecx // skip whole run, continue skipping
sub LSCount, ecx
jmp LeftSkipLoop
LSTrans:
and ecx, 07fH
cmp ecx, LSCount
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, LSCount // skip partial run, jump into normal loop for rest
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitTransparent
LSTrans1:
sub LSCount, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup: // Does any actual blitting (trans/non) for the line
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
BlitDispatch:
cmp LSCount, 0 // Check to see if we're done blitting
je RightSkipLoop
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
BlitNonTransLoop: // blit non-transparent pixels
cmp ecx, LSCount
jbe BNTrans1
sub ecx, LSCount
mov Unblitted, ecx
mov ecx, LSCount
BNTrans1:
sub LSCount, ecx
BlitNTL1:
mov ax, [ebx]
cmp ax, usZValue
jae BlitNTL2
mov ax, usZValue
mov [ebx], ax
xor eax, eax
mov al, [esi]
cmp al, 254
jne BlitNTL3
mov al, fIgnoreShadows
cmp al, 0
jne BlitNTL2
mov ax, [edi]
mov ax, ShadeTable[eax*2]
mov [edi], ax
jmp BlitNTL2
BlitNTL3:
mov ax, [edx+eax*2]
mov [edi], ax
BlitNTL2:
inc esi
add edi, 2
add ebx, 2
dec cl
jnz BlitNTL1
//BlitLineEnd:
add esi, Unblitted
jmp BlitDispatch
BlitTransparent: // skip transparent pixels
and ecx, 07fH
cmp ecx, LSCount
jbe BTrans1
mov ecx, LSCount
BTrans1:
sub LSCount, ecx
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
RightSkipLoop: // skip along until we hit and end-of-line marker
RSLoop1:
mov al, [esi]
inc esi
or al, al
jnz RSLoop1
dec BlitHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
jmp LeftSkipSetup
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferTransShadowZClip
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
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. Pixels with a value of
254 are shaded instead of blitted.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadowZClipAlpha(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, HVOBJECT hAlphaVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion, UINT16 *p16BPPPalette, BOOLEAN fIgnoreShadows)
{
UINT32 uiOffset;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr, *ZPtr, *AlphaPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight, LSCount;
INT32 ClipX1, ClipY1, ClipX2, ClipY2;
// Assertions
Assert(hSrcVObject != NULL);
Assert(hAlphaVObject != NULL);
Assert(pBuffer != NULL);
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[usIndex]);
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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(TRUE);
// check if whole thing is clipped
if ((TopSkip >= (INT32)usHeight) || (BottomSkip >= (INT32)usHeight))
return(TRUE);
SrcPtr = (UINT8 *)hSrcVObject->pPixData + uiOffset;
AlphaPtr = (UINT8 *)hAlphaVObject->pPixData + (hAlphaVObject->pETRLEObject[usIndex]).uiDataOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY + TopSkip)) + ((iTempX + LeftSkip) * 2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*(iTempY + TopSkip)) + ((iTempX + LeftSkip) * 2);
LineSkip = (uiDestPitchBYTES - (BlitLength * 2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
cmp TopSkip, 0 // check for nothing clipped on top
je LeftSkipSetup
TopSkipLoop : // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
push esi
mov esi, AlphaPtr
add esi, ecx
mov AlphaPtr, esi
pop esi
jmp TopSkipLoop
TSEndLine :
dec TopSkip
jnz TopSkipLoop
LeftSkipSetup :
mov Unblitted, 0
mov eax, LeftSkip
mov LSCount, eax
or eax, eax
jz BlitLineSetup
LeftSkipLoop :
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, LSCount
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, LSCount // skip partial run, jump into normal loop for rest
push esi
mov esi, AlphaPtr
add esi, LSCount
mov AlphaPtr, esi
pop esi
sub ecx, LSCount
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2 :
add esi, ecx // skip whole run, and start blit with new run
push esi
mov esi, AlphaPtr
add esi, ecx
mov AlphaPtr, esi
pop esi
jmp BlitLineSetup
LSSkip1 :
add esi, ecx // skip whole run, continue skipping
push esi
mov esi, AlphaPtr
add esi, ecx
mov AlphaPtr, esi
pop esi
sub LSCount, ecx
jmp LeftSkipLoop
LSTrans :
and ecx, 07fH
cmp ecx, LSCount
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, LSCount // skip partial run, jump into normal loop for rest
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitTransparent
LSTrans1 :
sub LSCount, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup : // Does any actual blitting (trans/non) for the line
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
BlitDispatch :
cmp LSCount, 0 // Check to see if we're done blitting
je RightSkipLoop
mov cl, [esi]
inc esi
push esi
mov esi, AlphaPtr
inc esi
mov AlphaPtr, esi
pop esi
or cl, cl
js BlitTransparent
BlitNonTransLoop : // blit non-transparent pixels
cmp ecx, LSCount
jbe BNTrans1
sub ecx, LSCount
mov Unblitted, ecx
mov ecx, LSCount
BNTrans1 :
sub LSCount, ecx
BlitNTL1 :
mov ax, [ebx]
cmp ax, usZValue
jae BlitNTL2
mov ax, usZValue
mov[ebx], ax
xor eax, eax
mov al, [esi]
cmp al, 254
jne BlitNTL3
mov al, fIgnoreShadows
cmp al, 0
jne BlitNTL2
mov ax, [edi]
mov ax, ShadeTable[eax * 2]
mov[edi], ax
jmp BlitNTL2
BlitNTL3 :
mov ax, [edx + eax * 2]
push edx
push ecx
push ebx
push esi
mov esi, AlphaPtr
xor ebx, ebx
mov bl, [esi]
pop esi
push ebx
push[edi]
push eax
call blendWithAlpha
add esp, 12
pop ebx
pop ecx
pop edx
mov[edi], ax
BlitNTL2 :
inc esi
push esi
mov esi, AlphaPtr
inc esi
mov AlphaPtr, esi
pop esi
add edi, 2
add ebx, 2
dec cl
jnz BlitNTL1
//BlitLineEnd:
add esi, Unblitted
push esi
mov esi, AlphaPtr
add esi, Unblitted
mov AlphaPtr, esi
pop esi
jmp BlitDispatch
BlitTransparent : // skip transparent pixels
and ecx, 07fH
cmp ecx, LSCount
jbe BTrans1
mov ecx, LSCount
BTrans1 :
sub LSCount, ecx
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
RightSkipLoop : // skip along until we hit and end-of-line marker
RSLoop1:
mov al, [esi]
inc esi
push esi
mov esi, AlphaPtr
inc esi
mov AlphaPtr, esi
pop esi
or al, al
jnz RSLoop1
dec BlitHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
jmp LeftSkipSetup
BlitDone :
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferTransShadowClip
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
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. Pixels with a value of
254 are shaded instead of blitted.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadowClip(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion, UINT16 *p16BPPPalette, BOOLEAN fIgnoreShadows)
{
UINT32 uiOffset;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, 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
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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(TRUE);
// check if whole thing is clipped
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
return(TRUE);
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
LineSkip=(uiDestPitchBYTES-(BlitLength*2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
xor ecx, ecx
cmp TopSkip, 0 // check for nothing clipped on top
je LeftSkipSetup
TopSkipLoop: // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
jmp TopSkipLoop
TSEndLine:
dec TopSkip
jnz TopSkipLoop
LeftSkipSetup:
mov Unblitted, 0
mov eax, LeftSkip
mov LSCount, eax
or eax, eax
jz BlitLineSetup
LeftSkipLoop:
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, LSCount
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, LSCount // skip partial run, jump into normal loop for rest
sub ecx, LSCount
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2:
add esi, ecx // skip whole run, and start blit with new run
jmp BlitLineSetup
LSSkip1:
add esi, ecx // skip whole run, continue skipping
sub LSCount, ecx
jmp LeftSkipLoop
LSTrans:
and ecx, 07fH
cmp ecx, LSCount
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, LSCount // skip partial run, jump into normal loop for rest
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitTransparent
LSTrans1:
sub LSCount, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup: // Does any actual blitting (trans/non) for the line
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
BlitDispatch:
cmp LSCount, 0 // Check to see if we're done blitting
je RightSkipLoop
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
BlitNonTransLoop: // blit non-transparent pixels
cmp ecx, LSCount
jbe BNTrans1
sub ecx, LSCount
mov Unblitted, ecx
mov ecx, LSCount
BNTrans1:
sub LSCount, ecx
BlitNTL1:
xor eax, eax
mov al, [esi]
cmp al, 254
jne BlitNTL3
mov al, fIgnoreShadows
cmp al, 0
jne BlitNTL2
mov ax, [edi]
mov ax, ShadeTable[eax*2]
mov [edi], ax
jmp BlitNTL2
BlitNTL3:
mov ax, [edx+eax*2]
mov [edi], ax
BlitNTL2:
inc esi
add edi, 2
dec cl
jnz BlitNTL1
//BlitLineEnd:
add esi, Unblitted
jmp BlitDispatch
BlitTransparent: // skip transparent pixels
and ecx, 07fH
cmp ecx, LSCount
jbe BTrans1
mov ecx, LSCount
BTrans1:
sub LSCount, ecx
// shl ecx, 1
add ecx, ecx
add edi, ecx
jmp BlitDispatch
RightSkipLoop: // skip along until we hit and end-of-line marker
RSLoop1:
mov al, [esi]
inc esi
or al, al
jnz RSLoop1
dec BlitHeight
jz BlitDone
add edi, LineSkip
jmp LeftSkipSetup
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferTransShadowClip
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
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. Pixels with a value of
254 are shaded instead of blitted.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadowClipAlpha(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, HVOBJECT hAlphaVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion, UINT16 *p16BPPPalette, BOOLEAN fIgnoreShadows)
{
UINT32 uiOffset;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr, *AlphaPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight, LSCount;
INT32 ClipX1, ClipY1, ClipX2, ClipY2;
// Assertions
Assert(hSrcVObject != NULL);
Assert(hAlphaVObject != NULL);
Assert(pBuffer != NULL);
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[usIndex]);
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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(TRUE);
// check if whole thing is clipped
if ((TopSkip >= (INT32)usHeight) || (BottomSkip >= (INT32)usHeight))
return(TRUE);
SrcPtr = (UINT8 *)hSrcVObject->pPixData + uiOffset;
AlphaPtr = (UINT8 *)hAlphaVObject->pPixData + (hAlphaVObject->pETRLEObject[usIndex]).uiDataOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY + TopSkip)) + ((iTempX + LeftSkip) * 2);
LineSkip = (uiDestPitchBYTES - (BlitLength * 2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
xor ecx, ecx
cmp TopSkip, 0 // check for nothing clipped on top
je LeftSkipSetup
TopSkipLoop : // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
push esi
mov esi, AlphaPtr
inc esi
mov AlphaPtr, esi
pop esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
push esi
mov esi, AlphaPtr
add esi, ecx
mov AlphaPtr, esi
pop esi
jmp TopSkipLoop
TSEndLine :
dec TopSkip
jnz TopSkipLoop
LeftSkipSetup :
mov Unblitted, 0
mov eax, LeftSkip
mov LSCount, eax
or eax, eax
jz BlitLineSetup
LeftSkipLoop :
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, LSCount
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, LSCount // skip partial run, jump into normal loop for rest
push esi
mov esi, AlphaPtr
add esi, LSCount
mov AlphaPtr, esi
pop esi
sub ecx, LSCount
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2 :
add esi, ecx // skip whole run, and start blit with new run
push esi
mov esi, AlphaPtr
add esi, ecx
mov AlphaPtr, esi
pop esi
jmp BlitLineSetup
LSSkip1 :
add esi, ecx // skip whole run, continue skipping
push esi
mov esi, AlphaPtr
add esi, ecx
mov AlphaPtr, esi
pop esi
sub LSCount, ecx
jmp LeftSkipLoop
LSTrans :
and ecx, 07fH
cmp ecx, LSCount
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, LSCount // skip partial run, jump into normal loop for rest
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitTransparent
LSTrans1 :
sub LSCount, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup : // Does any actual blitting (trans/non) for the line
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
BlitDispatch :
cmp LSCount, 0 // Check to see if we're done blitting
je RightSkipLoop
mov cl, [esi]
inc esi
push esi
mov esi, AlphaPtr
inc esi
mov AlphaPtr, esi
pop esi
or cl, cl
js BlitTransparent
BlitNonTransLoop : // blit non-transparent pixels
cmp ecx, LSCount
jbe BNTrans1
sub ecx, LSCount
mov Unblitted, ecx
mov ecx, LSCount
BNTrans1 :
sub LSCount, ecx
BlitNTL1 :
xor eax, eax
mov al, [esi]
cmp al, 254
jne BlitNTL3
mov al, fIgnoreShadows
cmp al, 0
jne BlitNTL2
mov ax, [edi]
mov ax, ShadeTable[eax * 2]
mov[edi], ax
jmp BlitNTL2
BlitNTL3 :
mov ax, [edx + eax * 2]
push edx
push ecx
push ebx
push esi
mov esi, AlphaPtr
xor ebx, ebx
mov bl, [esi]
pop esi
push ebx
push[edi]
push eax
call blendWithAlpha
add esp, 12
pop ebx
pop ecx
pop edx
mov[edi], ax
BlitNTL2 :
inc esi
push esi
mov esi, AlphaPtr
inc esi
mov AlphaPtr, esi
pop esi
add edi, 2
dec cl
jnz BlitNTL1
//BlitLineEnd:
add esi, Unblitted
push esi
mov esi, AlphaPtr
add esi, Unblitted
mov AlphaPtr, esi
pop esi
jmp BlitDispatch
BlitTransparent : // skip transparent pixels
and ecx, 07fH
cmp ecx, LSCount
jbe BTrans1
mov ecx, LSCount
BTrans1 :
sub LSCount, ecx
// shl ecx, 1
add ecx, ecx
add edi, ecx
jmp BlitDispatch
RightSkipLoop : // skip along until we hit and end-of-line marker
RSLoop1:
mov al, [esi]
inc esi
push esi
mov esi, AlphaPtr
inc esi
mov AlphaPtr, esi
pop esi
or al, al
jnz RSLoop1
dec BlitHeight
jz BlitDone
add edi, LineSkip
jmp LeftSkipSetup
BlitDone :
}
return(TRUE);
}
/**********************************************************************************************
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.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadowZNBClip(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion, UINT16 *p16BPPPalette, BOOLEAN fIgnoreShadows)
{
UINT32 uiOffset;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, 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
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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(TRUE);
// check if whole thing is clipped
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
return(TRUE);
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
LineSkip=(uiDestPitchBYTES-(BlitLength*2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
cmp TopSkip, 0 // check for nothing clipped on top
je LeftSkipSetup
TopSkipLoop: // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
jmp TopSkipLoop
TSEndLine:
dec TopSkip
jnz TopSkipLoop
LeftSkipSetup:
mov Unblitted, 0
mov eax, LeftSkip
mov LSCount, eax
or eax, eax
jz BlitLineSetup
LeftSkipLoop:
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, LSCount
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, LSCount // skip partial run, jump into normal loop for rest
sub ecx, LSCount
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2:
add esi, ecx // skip whole run, and start blit with new run
jmp BlitLineSetup
LSSkip1:
add esi, ecx // skip whole run, continue skipping
sub LSCount, ecx
jmp LeftSkipLoop
LSTrans:
and ecx, 07fH
cmp ecx, LSCount
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, LSCount // skip partial run, jump into normal loop for rest
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitTransparent
LSTrans1:
sub LSCount, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup: // Does any actual blitting (trans/non) for the line
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
BlitDispatch:
cmp LSCount, 0 // Check to see if we're done blitting
je RightSkipLoop
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
BlitNonTransLoop: // blit non-transparent pixels
cmp ecx, LSCount
jbe BNTrans1
sub ecx, LSCount
mov Unblitted, ecx
mov ecx, LSCount
BNTrans1:
sub LSCount, ecx
BlitNTL1:
mov ax, [ebx]
cmp ax, usZValue
ja BlitNTL2
xor eax, eax
mov al, [esi]
cmp al, 254
jne BlitNTL3
mov ax, [ebx]
cmp ax, usZValue
jae BlitNTL2
mov al, fIgnoreShadows
cmp al, 0
jne BlitNTL2
mov ax, [edi]
mov ax, ShadeTable[eax*2]
mov [edi], ax
jmp BlitNTL2
BlitNTL3:
mov ax, [edx+eax*2]
mov [edi], ax
BlitNTL2:
inc esi
add edi, 2
add ebx, 2
dec cl
jnz BlitNTL1
//BlitLineEnd:
add esi, Unblitted
jmp BlitDispatch
BlitTransparent: // skip transparent pixels
and ecx, 07fH
cmp ecx, LSCount
jbe BTrans1
mov ecx, LSCount
BTrans1:
sub LSCount, ecx
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
RightSkipLoop: // skip along until we hit and end-of-line marker
RSLoop1:
mov al, [esi]
inc esi
or al, al
jnz RSLoop1
dec BlitHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
jmp LeftSkipSetup
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
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.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadowZNBClipAlpha(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, HVOBJECT hAlphaVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion, UINT16 *p16BPPPalette, BOOLEAN fIgnoreShadows)
{
UINT32 uiOffset;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr, *ZPtr, *AlphaPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight, LSCount;
INT32 ClipX1, ClipY1, ClipX2, ClipY2;
// Assertions
Assert(hSrcVObject != NULL);
Assert(hAlphaVObject != NULL);
Assert(pBuffer != NULL);
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[usIndex]);
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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(TRUE);
// check if whole thing is clipped
if ((TopSkip >= (INT32)usHeight) || (BottomSkip >= (INT32)usHeight))
return(TRUE);
SrcPtr = (UINT8 *)hSrcVObject->pPixData + uiOffset;
AlphaPtr = (UINT8 *)hAlphaVObject->pPixData + (hAlphaVObject->pETRLEObject[usIndex]).uiDataOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY + TopSkip)) + ((iTempX + LeftSkip) * 2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*(iTempY + TopSkip)) + ((iTempX + LeftSkip) * 2);
LineSkip = (uiDestPitchBYTES - (BlitLength * 2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
cmp TopSkip, 0 // check for nothing clipped on top
je LeftSkipSetup
TopSkipLoop : // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
push esi
mov esi, AlphaPtr
inc esi
mov AlphaPtr, esi
pop esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
push esi
mov esi, AlphaPtr
add esi, ecx
mov AlphaPtr, esi
pop esi
jmp TopSkipLoop
TSEndLine :
dec TopSkip
jnz TopSkipLoop
LeftSkipSetup :
mov Unblitted, 0
mov eax, LeftSkip
mov LSCount, eax
or eax, eax
jz BlitLineSetup
LeftSkipLoop :
mov cl, [esi]
push esi
mov esi, AlphaPtr
inc esi
mov AlphaPtr, esi
pop esi
inc esi
or cl, cl
js LSTrans
cmp ecx, LSCount
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, LSCount // skip partial run, jump into normal loop for rest
push esi
mov esi, AlphaPtr
add esi, LSCount
mov AlphaPtr, esi
pop esi
sub ecx, LSCount
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2 :
add esi, ecx // skip whole run, and start blit with new run
push esi
mov esi, AlphaPtr
add esi, ecx
mov AlphaPtr, esi
pop esi
jmp BlitLineSetup
LSSkip1 :
add esi, ecx // skip whole run, continue skipping
push esi
mov esi, AlphaPtr
add esi, ecx
mov AlphaPtr, esi
pop esi
sub LSCount, ecx
jmp LeftSkipLoop
LSTrans :
and ecx, 07fH
cmp ecx, LSCount
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, LSCount // skip partial run, jump into normal loop for rest
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitTransparent
LSTrans1 :
sub LSCount, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup : // Does any actual blitting (trans/non) for the line
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
BlitDispatch :
cmp LSCount, 0 // Check to see if we're done blitting
je RightSkipLoop
mov cl, [esi]
inc esi
push esi
mov esi, AlphaPtr
inc esi
mov AlphaPtr, esi
pop esi
or cl, cl
js BlitTransparent
BlitNonTransLoop : // blit non-transparent pixels
cmp ecx, LSCount
jbe BNTrans1
sub ecx, LSCount
mov Unblitted, ecx
mov ecx, LSCount
BNTrans1 :
sub LSCount, ecx
BlitNTL1 :
mov ax, [ebx]
cmp ax, usZValue
ja BlitNTL2
xor eax, eax
mov al, [esi]
cmp al, 254
jne BlitNTL3
mov ax, [ebx]
cmp ax, usZValue
jae BlitNTL2
mov al, fIgnoreShadows
cmp al, 0
jne BlitNTL2
mov ax, [edi]
mov ax, ShadeTable[eax * 2]
mov[edi], ax
jmp BlitNTL2
BlitNTL3 :
mov ax, [edx + eax * 2]
push edx
push ecx
push ebx
push esi
mov esi, AlphaPtr
xor ebx, ebx
mov bl, [esi]
pop esi
push ebx
push[edi]
push eax
call blendWithAlpha
add esp, 12
pop ebx
pop ecx
pop edx
mov[edi], ax
BlitNTL2 :
inc esi
push esi
mov esi, AlphaPtr
inc esi
mov AlphaPtr, esi
pop esi
add edi, 2
add ebx, 2
dec cl
jnz BlitNTL1
//BlitLineEnd:
add esi, Unblitted
push esi
mov esi, AlphaPtr
add esi, Unblitted
mov AlphaPtr, esi
pop esi
jmp BlitDispatch
BlitTransparent : // skip transparent pixels
and ecx, 07fH
cmp ecx, LSCount
jbe BTrans1
mov ecx, LSCount
BTrans1 :
sub LSCount, ecx
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
RightSkipLoop : // skip along until we hit and end-of-line marker
RSLoop1:
mov al, [esi]
inc esi
push esi
mov esi, AlphaPtr
inc esi
mov AlphaPtr, esi
pop esi
or al, al
jnz RSLoop1
dec BlitHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
jmp LeftSkipSetup
BlitDone :
}
return(TRUE);
}
/**********************************************************************************************
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.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadowZNBObscuredClip(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion, UINT16 *p16BPPPalette, BOOLEAN fIgnoreShadows)
{
UINT32 uiOffset;
UINT32 usHeight, usWidth, Unblitted, uiLineFlag;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, 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
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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(TRUE);
// check if whole thing is clipped
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
return(TRUE);
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
LineSkip=(uiDestPitchBYTES-(BlitLength*2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
cmp TopSkip, 0 // check for nothing clipped on top
je LeftSkipSetup
TopSkipLoop: // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
jmp TopSkipLoop
TSEndLine:
xor uiLineFlag, 1
dec TopSkip
jnz TopSkipLoop
LeftSkipSetup:
mov Unblitted, 0
mov eax, LeftSkip
mov LSCount, eax
or eax, eax
jz BlitLineSetup
LeftSkipLoop:
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, LSCount
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, LSCount // skip partial run, jump into normal loop for rest
sub ecx, LSCount
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2:
add esi, ecx // skip whole run, and start blit with new run
jmp BlitLineSetup
LSSkip1:
add esi, ecx // skip whole run, continue skipping
sub LSCount, ecx
jmp LeftSkipLoop
LSTrans:
and ecx, 07fH
cmp ecx, LSCount
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, LSCount // skip partial run, jump into normal loop for rest
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitTransparent
LSTrans1:
sub LSCount, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup: // Does any actual blitting (trans/non) for the line
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
BlitDispatch:
cmp LSCount, 0 // Check to see if we're done blitting
je RightSkipLoop
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
BlitNonTransLoop: // blit non-transparent pixels
cmp ecx, LSCount
jbe BNTrans1
sub ecx, LSCount
mov Unblitted, ecx
mov ecx, LSCount
BNTrans1:
sub LSCount, ecx
BlitNTL1:
mov ax, [ebx]
cmp ax, usZValue
ja BlitPixellate
xor eax, eax
mov al, [esi]
cmp al, 254
jne BlitNTL3
mov ax, [ebx]
cmp ax, usZValue
jae BlitNTL2
mov al, fIgnoreShadows
cmp al, 0
jne BlitNTL2
mov ax, [edi]
mov ax, ShadeTable[eax*2]
mov [edi], ax
jmp BlitNTL2
BlitPixellate:
xor eax, eax
mov al, [esi]
cmp al, 254
je BlitNTL2
test uiLineFlag, 1
jz BlitNTL9
test edi, 2
jz BlitNTL2
jmp BlitNTL3
BlitNTL9:
test edi, 2
jnz BlitNTL2
BlitNTL3:
xor eax, eax
mov al, [esi]
mov ax, [edx+eax*2]
mov [edi], ax
BlitNTL2:
inc esi
add edi, 2
add ebx, 2
dec cl
jnz BlitNTL1
//BlitLineEnd:
add esi, Unblitted
jmp BlitDispatch
BlitTransparent: // skip transparent pixels
and ecx, 07fH
cmp ecx, LSCount
jbe BTrans1
mov ecx, LSCount
BTrans1:
sub LSCount, ecx
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
RightSkipLoop: // skip along until we hit and end-of-line marker
RSLoop1:
mov al, [esi]
inc esi
or al, al
jnz RSLoop1
xor uiLineFlag, 1
dec BlitHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
jmp LeftSkipSetup
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
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.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadowZNBObscuredClipAlpha(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, HVOBJECT hAlphaVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion, UINT16 *p16BPPPalette, BOOLEAN fIgnoreShadows)
{
UINT32 uiOffset;
UINT32 usHeight, usWidth, Unblitted, uiLineFlag;
UINT8 *SrcPtr, *DestPtr, *ZPtr, *AlphaPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight, LSCount;
INT32 ClipX1, ClipY1, ClipX2, ClipY2;
// Assertions
Assert(hSrcVObject != NULL);
Assert(hAlphaVObject != NULL);
Assert(pBuffer != NULL);
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[usIndex]);
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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(TRUE);
// check if whole thing is clipped
if ((TopSkip >= (INT32)usHeight) || (BottomSkip >= (INT32)usHeight))
return(TRUE);
SrcPtr = (UINT8 *)hSrcVObject->pPixData + uiOffset;
AlphaPtr = (UINT8 *)hAlphaVObject->pPixData + (hAlphaVObject->pETRLEObject[usIndex]).uiDataOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY + TopSkip)) + ((iTempX + LeftSkip) * 2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*(iTempY + TopSkip)) + ((iTempX + LeftSkip) * 2);
LineSkip = (uiDestPitchBYTES - (BlitLength * 2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
cmp TopSkip, 0 // check for nothing clipped on top
je LeftSkipSetup
TopSkipLoop : // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
push esi
mov esi, AlphaPtr
inc esi
mov AlphaPtr, esi
pop esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
push esi
mov esi, AlphaPtr
add esi, ecx
mov AlphaPtr, esi
pop esi
jmp TopSkipLoop
TSEndLine :
xor uiLineFlag, 1
dec TopSkip
jnz TopSkipLoop
LeftSkipSetup :
mov Unblitted, 0
mov eax, LeftSkip
mov LSCount, eax
or eax, eax
jz BlitLineSetup
LeftSkipLoop :
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, LSCount
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, LSCount // skip partial run, jump into normal loop for rest
push esi
mov esi, AlphaPtr
add esi, LSCount
mov AlphaPtr, esi
pop esi
sub ecx, LSCount
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2 :
add esi, ecx // skip whole run, and start blit with new run
push esi
mov esi, AlphaPtr
add esi, ecx
mov AlphaPtr, esi
pop esi
jmp BlitLineSetup
LSSkip1 :
add esi, ecx // skip whole run, continue skipping
push esi
mov esi, AlphaPtr
add esi, ecx
mov AlphaPtr, esi
pop esi
sub LSCount, ecx
jmp LeftSkipLoop
LSTrans :
and ecx, 07fH
cmp ecx, LSCount
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, LSCount // skip partial run, jump into normal loop for rest
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitTransparent
LSTrans1 :
sub LSCount, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup : // Does any actual blitting (trans/non) for the line
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
BlitDispatch :
cmp LSCount, 0 // Check to see if we're done blitting
je RightSkipLoop
mov cl, [esi]
inc esi
push esi
mov esi, AlphaPtr
inc esi
mov AlphaPtr, esi
pop esi
or cl, cl
js BlitTransparent
BlitNonTransLoop : // blit non-transparent pixels
cmp ecx, LSCount
jbe BNTrans1
sub ecx, LSCount
mov Unblitted, ecx
mov ecx, LSCount
BNTrans1 :
sub LSCount, ecx
BlitNTL1 :
mov ax, [ebx]
cmp ax, usZValue
ja BlitPixellate
xor eax, eax
mov al, [esi]
cmp al, 254
jne BlitNTL3
mov ax, [ebx]
cmp ax, usZValue
jae BlitNTL2
mov al, fIgnoreShadows
cmp al, 0
jne BlitNTL2
mov ax, [edi]
mov ax, ShadeTable[eax * 2]
mov[edi], ax
jmp BlitNTL2
BlitPixellate :
xor eax, eax
mov al, [esi]
cmp al, 254
je BlitNTL2
test uiLineFlag, 1
jz BlitNTL9
test edi, 2
jz BlitNTL2
jmp BlitNTL3
BlitNTL9 :
test edi, 2
jnz BlitNTL2
BlitNTL3 :
xor eax, eax
mov al, [esi]
mov ax, [edx + eax * 2]
push edx
push ecx
push ebx
push esi
mov esi, AlphaPtr
xor ebx, ebx
mov bl, [esi]
pop esi
push ebx
push[edi]
push eax
call blendWithAlpha
add esp, 12
pop ebx
pop ecx
pop edx
mov[edi], ax
BlitNTL2 :
inc esi
push esi
mov esi, AlphaPtr
inc esi
mov AlphaPtr, esi
pop esi
add edi, 2
add ebx, 2
dec cl
jnz BlitNTL1
//BlitLineEnd:
add esi, Unblitted
push esi
mov esi, AlphaPtr
add esi, Unblitted
mov AlphaPtr, esi
pop esi
jmp BlitDispatch
BlitTransparent : // skip transparent pixels
and ecx, 07fH
cmp ecx, LSCount
jbe BTrans1
mov ecx, LSCount
BTrans1 :
sub LSCount, ecx
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
RightSkipLoop : // skip along until we hit and end-of-line marker
RSLoop1:
mov al, [esi]
inc esi
push esi
mov esi, AlphaPtr
inc esi
mov AlphaPtr, esi
pop esi
or al, al
jnz RSLoop1
xor uiLineFlag, 1
dec BlitHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
jmp LeftSkipSetup
BlitDone :
}
return(TRUE);
}
/**********************************************************************************************
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 OR EQUAL! 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.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferTransShadowBelowOrEqualZNBClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion, UINT16 *p16BPPPalette )
{
UINT32 uiOffset;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, 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
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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(TRUE);
// check if whole thing is clipped
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
return(TRUE);
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
LineSkip=(uiDestPitchBYTES-(BlitLength*2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
cmp TopSkip, 0 // check for nothing clipped on top
je LeftSkipSetup
TopSkipLoop: // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
jmp TopSkipLoop
TSEndLine:
dec TopSkip
jnz TopSkipLoop
LeftSkipSetup:
mov Unblitted, 0
mov eax, LeftSkip
mov LSCount, eax
or eax, eax
jz BlitLineSetup
LeftSkipLoop:
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, LSCount
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, LSCount // skip partial run, jump into normal loop for rest
sub ecx, LSCount
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2:
add esi, ecx // skip whole run, and start blit with new run
jmp BlitLineSetup
LSSkip1:
add esi, ecx // skip whole run, continue skipping
sub LSCount, ecx
jmp LeftSkipLoop
LSTrans:
and ecx, 07fH
cmp ecx, LSCount
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, LSCount // skip partial run, jump into normal loop for rest
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitTransparent
LSTrans1:
sub LSCount, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup: // Does any actual blitting (trans/non) for the line
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
BlitDispatch:
cmp LSCount, 0 // Check to see if we're done blitting
je RightSkipLoop
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
BlitNonTransLoop: // blit non-transparent pixels
cmp ecx, LSCount
jbe BNTrans1
sub ecx, LSCount
mov Unblitted, ecx
mov ecx, LSCount
BNTrans1:
sub LSCount, ecx
BlitNTL1:
mov ax, [ebx]
cmp ax, usZValue
ja BlitNTL2
xor eax, eax
mov al, [esi]
cmp al, 254
jne BlitNTL3
mov ax, [ebx]
cmp ax, usZValue
jae BlitNTL2
mov ax, [edi]
mov ax, ShadeTable[eax*2]
mov [edi], ax
jmp BlitNTL2
BlitNTL3:
mov ax, [edx+eax*2]
mov [edi], ax
BlitNTL2:
inc esi
add edi, 2
add ebx, 2
dec cl
jnz BlitNTL1
//BlitLineEnd:
add esi, Unblitted
jmp BlitDispatch
BlitTransparent: // skip transparent pixels
and ecx, 07fH
cmp ecx, LSCount
jbe BTrans1
mov ecx, LSCount
BTrans1:
sub LSCount, ecx
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
RightSkipLoop: // skip along until we hit and end-of-line marker
RSLoop1:
mov al, [esi]
inc esi
or al, al
jnz RSLoop1
dec BlitHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
jmp LeftSkipSetup
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferShadowZ
Creates a shadow using a brush, but modifies the destination buffer only if the current
Z level is equal to higher than what's in the Z buffer at that pixel location. It
updates the Z buffer with the new Z level.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferShadowZ( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex )
{
UINT16 *p16BPPPalette;
UINT32 uiOffset;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
p16BPPPalette = hSrcVObject->pShadeCurrent;
LineSkip=(uiDestPitchBYTES-(usWidth*2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, OFFSET ShadeTable
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
BlitDispatch:
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
BlitNTL4:
mov ax, [ebx]
cmp ax, usZValue
jae BlitNTL5
xor eax, eax
mov ax, [edi]
mov ax, [edx+eax*2]
mov [edi], ax
mov ax, usZValue
mov [ebx], ax
BlitNTL5:
inc esi
add edi, 2
add ebx, 2
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
BlitDoneLine:
dec usHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
jmp BlitDispatch
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferShadowZClip
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
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.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferShadowZClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion)
{
UINT16 *p16BPPPalette;
UINT32 uiOffset;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, 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
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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(TRUE);
// check if whole thing is clipped
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
return(TRUE);
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
p16BPPPalette = hSrcVObject->pShadeCurrent;
LineSkip=(uiDestPitchBYTES-(BlitLength*2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, OFFSET ShadeTable
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
cmp TopSkip, 0 // check for nothing clipped on top
je LeftSkipSetup
TopSkipLoop: // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
jmp TopSkipLoop
TSEndLine:
dec TopSkip
jnz TopSkipLoop
LeftSkipSetup:
mov Unblitted, 0
mov eax, LeftSkip
mov LSCount, eax
or eax, eax
jz BlitLineSetup
LeftSkipLoop:
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, LSCount
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, LSCount // skip partial run, jump into normal loop for rest
sub ecx, LSCount
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2:
add esi, ecx // skip whole run, and start blit with new run
jmp BlitLineSetup
LSSkip1:
add esi, ecx // skip whole run, continue skipping
sub LSCount, ecx
jmp LeftSkipLoop
LSTrans:
and ecx, 07fH
cmp ecx, LSCount
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, LSCount // skip partial run, jump into normal loop for rest
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitTransparent
LSTrans1:
sub LSCount, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup: // Does any actual blitting (trans/non) for the line
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
BlitDispatch:
cmp LSCount, 0 // Check to see if we're done blitting
je RightSkipLoop
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
BlitNonTransLoop: // blit non-transparent pixels
cmp ecx, LSCount
jbe BNTrans1
sub ecx, LSCount
mov Unblitted, ecx
mov ecx, LSCount
BNTrans1:
sub LSCount, ecx
BlitNTL1:
mov ax, [ebx]
cmp ax, usZValue
jae BlitNTL2
mov ax, usZValue
mov [ebx], ax
xor eax, eax
mov ax, [edi]
mov ax, [edx+eax*2]
mov [edi], ax
BlitNTL2:
inc esi
add edi, 2
add ebx, 2
dec cl
jnz BlitNTL1
//BlitLineEnd:
add esi, Unblitted
jmp BlitDispatch
BlitTransparent: // skip transparent pixels
and ecx, 07fH
cmp ecx, LSCount
jbe BTrans1
mov ecx, LSCount
BTrans1:
sub LSCount, ecx
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
RightSkipLoop: // skip along until we hit and end-of-line marker
RSLoop1:
mov al, [esi]
inc esi
or al, al
jnz RSLoop1
dec BlitHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
jmp LeftSkipSetup
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferShadowZNB
Creates a shadow using a brush, but modifies the destination buffer only if the current
Z level is equal to higher than what's in the Z buffer at that pixel location. It does
NOT update the Z buffer with the new Z value.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferShadowZNB( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex )
{
UINT16 *p16BPPPalette;
UINT32 uiOffset;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
p16BPPPalette = hSrcVObject->pShadeCurrent;
LineSkip=(uiDestPitchBYTES-(usWidth*2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, OFFSET ShadeTable
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
BlitDispatch:
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
BlitNTL4:
mov ax, [ebx]
cmp ax, usZValue
jae BlitNTL5
xor eax, eax
mov ax, [edi]
mov ax, [edx+eax*2]
mov [edi], ax
BlitNTL5:
inc esi
add edi, 2
add ebx, 2
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
BlitDoneLine:
dec usHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
jmp BlitDispatch
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferShadowZNBClip
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 value is
not updated, for any non-transparent pixels. The Z-buffer is 16 bit, and must be the
same dimensions (including Pitch) as the destination.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferShadowZNBClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion)
{
UINT16 *p16BPPPalette;
UINT32 uiOffset;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, 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
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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(TRUE);
// check if whole thing is clipped
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
return(TRUE);
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
p16BPPPalette = hSrcVObject->pShadeCurrent;
LineSkip=(uiDestPitchBYTES-(BlitLength*2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, OFFSET ShadeTable
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
cmp TopSkip, 0 // check for nothing clipped on top
je LeftSkipSetup
TopSkipLoop: // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
jmp TopSkipLoop
TSEndLine:
dec TopSkip
jnz TopSkipLoop
LeftSkipSetup:
mov Unblitted, 0
mov eax, LeftSkip
mov LSCount, eax
or eax, eax
jz BlitLineSetup
LeftSkipLoop:
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, LSCount
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, LSCount // skip partial run, jump into normal loop for rest
sub ecx, LSCount
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2:
add esi, ecx // skip whole run, and start blit with new run
jmp BlitLineSetup
LSSkip1:
add esi, ecx // skip whole run, continue skipping
sub LSCount, ecx
jmp LeftSkipLoop
LSTrans:
and ecx, 07fH
cmp ecx, LSCount
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, LSCount // skip partial run, jump into normal loop for rest
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitTransparent
LSTrans1:
sub LSCount, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup: // Does any actual blitting (trans/non) for the line
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
BlitDispatch:
cmp LSCount, 0 // Check to see if we're done blitting
je RightSkipLoop
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
BlitNonTransLoop: // blit non-transparent pixels
cmp ecx, LSCount
jbe BNTrans1
sub ecx, LSCount
mov Unblitted, ecx
mov ecx, LSCount
BNTrans1:
sub LSCount, ecx
BlitNTL1:
mov ax, [ebx]
cmp ax, usZValue
jae BlitNTL2
xor eax, eax
mov ax, [edi]
mov ax, [edx+eax*2]
mov [edi], ax
BlitNTL2:
inc esi
add edi, 2
add ebx, 2
dec cl
jnz BlitNTL1
//BlitLineEnd:
add esi, Unblitted
jmp BlitDispatch
BlitTransparent: // skip transparent pixels
and ecx, 07fH
cmp ecx, LSCount
jbe BTrans1
mov ecx, LSCount
BTrans1:
sub LSCount, ecx
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
RightSkipLoop: // skip along until we hit and end-of-line marker
RSLoop1:
mov al, [esi]
inc esi
or al, al
jnz RSLoop1
dec BlitHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
jmp LeftSkipSetup
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferTransZClip
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
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.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferTransZClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion)
{
UINT16 *p16BPPPalette;
UINT32 uiOffset;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, 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
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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(TRUE);
// check if whole thing is clipped
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
return(TRUE);
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
p16BPPPalette = hSrcVObject->pShadeCurrent;
LineSkip=(uiDestPitchBYTES-(BlitLength*2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
cmp TopSkip, 0 // check for nothing clipped on top
je LeftSkipSetup
TopSkipLoop: // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
jmp TopSkipLoop
TSEndLine:
dec TopSkip
jnz TopSkipLoop
LeftSkipSetup:
mov Unblitted, 0
mov eax, LeftSkip
mov LSCount, eax
or eax, eax
jz BlitLineSetup
LeftSkipLoop:
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, LSCount
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, LSCount // skip partial run, jump into normal loop for rest
sub ecx, LSCount
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2:
add esi, ecx // skip whole run, and start blit with new run
jmp BlitLineSetup
LSSkip1:
add esi, ecx // skip whole run, continue skipping
sub LSCount, ecx
jmp LeftSkipLoop
LSTrans:
and ecx, 07fH
cmp ecx, LSCount
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, LSCount // skip partial run, jump into normal loop for rest
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitTransparent
LSTrans1:
sub LSCount, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup: // Does any actual blitting (trans/non) for the line
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
BlitDispatch:
cmp LSCount, 0 // Check to see if we're done blitting
je RightSkipLoop
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
BlitNonTransLoop: // blit non-transparent pixels
cmp ecx, LSCount
jbe BNTrans1
sub ecx, LSCount
mov Unblitted, ecx
mov ecx, LSCount
BNTrans1:
sub LSCount, ecx
BlitNTL1:
mov ax, [ebx]
cmp ax, usZValue
ja BlitNTL2
mov ax, usZValue
mov [ebx], ax
xor eax, eax
mov al, [esi]
mov ax, [edx+eax*2]
mov [edi], ax
BlitNTL2:
inc esi
add edi, 2
add ebx, 2
dec cl
jnz BlitNTL1
//BlitLineEnd:
add esi, Unblitted
jmp BlitDispatch
BlitTransparent: // skip transparent pixels
and ecx, 07fH
cmp ecx, LSCount
jbe BTrans1
mov ecx, LSCount
BTrans1:
sub LSCount, ecx
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
RightSkipLoop: // skip along until we hit and end-of-line marker
RSLoop1:
mov al, [esi]
inc esi
or al, al
jnz RSLoop1
dec BlitHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
jmp LeftSkipSetup
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferTransZNBClip
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 value is NOT
updated in this version. The Z-buffer is 16 bit, and must be the same dimensions (including Pitch) as the destination.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferTransZNBClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion)
{
UINT16 *p16BPPPalette;
UINT32 uiOffset;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, 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
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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(TRUE);
// check if whole thing is clipped
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
return(TRUE);
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
p16BPPPalette = hSrcVObject->pShadeCurrent;
LineSkip=(uiDestPitchBYTES-(BlitLength*2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
cmp TopSkip, 0 // check for nothing clipped on top
je LeftSkipSetup
TopSkipLoop: // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
jmp TopSkipLoop
TSEndLine:
dec TopSkip
jnz TopSkipLoop
LeftSkipSetup:
mov Unblitted, 0
mov eax, LeftSkip
mov LSCount, eax
or eax, eax
jz BlitLineSetup
LeftSkipLoop:
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, LSCount
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, LSCount // skip partial run, jump into normal loop for rest
sub ecx, LSCount
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2:
add esi, ecx // skip whole run, and start blit with new run
jmp BlitLineSetup
LSSkip1:
add esi, ecx // skip whole run, continue skipping
sub LSCount, ecx
jmp LeftSkipLoop
LSTrans:
and ecx, 07fH
cmp ecx, LSCount
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, LSCount // skip partial run, jump into normal loop for rest
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitTransparent
LSTrans1:
sub LSCount, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup: // Does any actual blitting (trans/non) for the line
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
BlitDispatch:
cmp LSCount, 0 // Check to see if we're done blitting
je RightSkipLoop
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
BlitNonTransLoop: // blit non-transparent pixels
cmp ecx, LSCount
jbe BNTrans1
sub ecx, LSCount
mov Unblitted, ecx
mov ecx, LSCount
BNTrans1:
sub LSCount, ecx
BlitNTL1:
mov ax, [ebx]
cmp ax, usZValue
ja BlitNTL2
xor eax, eax
mov al, [esi]
mov ax, [edx+eax*2]
mov [edi], ax
BlitNTL2:
inc esi
add edi, 2
add ebx, 2
dec cl
jnz BlitNTL1
//BlitLineEnd:
add esi, Unblitted
jmp BlitDispatch
BlitTransparent: // skip transparent pixels
and ecx, 07fH
cmp ecx, LSCount
jbe BTrans1
mov ecx, LSCount
BTrans1:
sub LSCount, ecx
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
RightSkipLoop: // skip along until we hit and end-of-line marker
RSLoop1:
mov al, [esi]
inc esi
or al, al
jnz RSLoop1
dec BlitHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
jmp LeftSkipSetup
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferTransZNBClipColor
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 value is NOT
updated in this version. The Z-buffer is 16 bit, and must be the same dimensions (including
Pitch) as the destination. Any pixels that fail the Z test are written to with the
specified pixel value.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferTransZNBClipColor( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion, UINT16 usColor)
{
UINT16 *p16BPPPalette;
UINT32 uiOffset;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, 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
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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(TRUE);
// check if whole thing is clipped
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
return(TRUE);
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
p16BPPPalette = hSrcVObject->pShadeCurrent;
LineSkip=(uiDestPitchBYTES-(BlitLength*2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
cmp TopSkip, 0 // check for nothing clipped on top
je LeftSkipSetup
TopSkipLoop: // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
jmp TopSkipLoop
TSEndLine:
dec TopSkip
jnz TopSkipLoop
LeftSkipSetup:
mov Unblitted, 0
mov eax, LeftSkip
mov LSCount, eax
or eax, eax
jz BlitLineSetup
LeftSkipLoop:
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, LSCount
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, LSCount // skip partial run, jump into normal loop for rest
sub ecx, LSCount
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2:
add esi, ecx // skip whole run, and start blit with new run
jmp BlitLineSetup
LSSkip1:
add esi, ecx // skip whole run, continue skipping
sub LSCount, ecx
jmp LeftSkipLoop
LSTrans:
and ecx, 07fH
cmp ecx, LSCount
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, LSCount // skip partial run, jump into normal loop for rest
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitTransparent
LSTrans1:
sub LSCount, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup: // Does any actual blitting (trans/non) for the line
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
BlitDispatch:
cmp LSCount, 0 // Check to see if we're done blitting
je RightSkipLoop
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
BlitNonTransLoop: // blit non-transparent pixels
cmp ecx, LSCount
jbe BNTrans1
sub ecx, LSCount
mov Unblitted, ecx
mov ecx, LSCount
BNTrans1:
sub LSCount, ecx
xor eax, eax
BlitNTL1:
mov ax, [ebx]
cmp ax, usZValue
ja BlitNTL2
xor ah, ah
mov al, [esi]
mov ax, [edx+eax*2]
mov [edi], ax
jmp BlitNTL3
BlitNTL2:
mov ax, usColor
mov [edi], ax
BlitNTL3:
inc esi
inc edi
inc ebx
inc edi
inc ebx
dec cl
jnz BlitNTL1
//BlitLineEnd:
add esi, Unblitted
jmp BlitDispatch
BlitTransparent: // skip transparent pixels
and ecx, 07fH
cmp ecx, LSCount
jbe BTrans1
mov ecx, LSCount
BTrans1:
sub LSCount, ecx
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
RightSkipLoop: // skip along until we hit and end-of-line marker
RSLoop1:
mov al, [esi]
inc esi
or al, al
jnz RSLoop1
dec BlitHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
jmp LeftSkipSetup
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataSubTo16BPPBuffer
Blits a subrect from a flat 8 bit surface to a 16-bit buffer.
**********************************************************************************************/
BOOLEAN Blt8BPPDataSubTo16BPPBuffer( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVSURFACE hSrcVSurface, UINT8 *pSrcBuffer, UINT32 uiSrcPitch, INT32 iX, INT32 iY, SGPRect *pRect)
{
UINT16 *p16BPPPalette;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr;
UINT32 LineSkip, LeftSkip, RightSkip, TopSkip, BlitLength, SrcSkip, BlitHeight;
INT32 iTempX, iTempY;
// Assertions
Assert( hSrcVSurface != NULL );
Assert( pSrcBuffer != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
usHeight = (UINT32)hSrcVSurface->usHeight;
usWidth = (UINT32)hSrcVSurface->usWidth;
// Add to start position of dest buffer
iTempX = iX;
iTempY = iY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
LeftSkip=pRect->iLeft;
RightSkip=usWidth-pRect->iRight;
TopSkip=pRect->iTop*uiSrcPitch;
BlitLength=pRect->iRight-pRect->iLeft;
BlitHeight=pRect->iBottom-pRect->iTop;
SrcSkip=uiSrcPitch-BlitLength;
SrcPtr= (UINT8 *)(pSrcBuffer+TopSkip+LeftSkip);
DestPtr = ((UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2));
p16BPPPalette = hSrcVSurface->p16BPPPalette;
LineSkip=(uiDestPitchBYTES-(BlitLength*2));
__asm {
mov esi, SrcPtr // pointer to current line start address in source
mov edi, DestPtr // pointer to current line start address in destination
mov ebx, BlitHeight // line counter (goes top to bottom)
mov edx, p16BPPPalette // conversion table
sub eax, eax
sub ecx, ecx
NewRow:
mov ecx, BlitLength // pixels to blit count
BlitLoop:
mov al, [esi]
xor ah, ah
shl eax, 1 // make it into a word index
mov ax, [edx+eax] // get 16-bit version of 8-bit pixel
mov [edi], ax // store it in destination buffer
inc edi
inc esi
inc edi
dec ecx
jnz BlitLoop
add esi, SrcSkip // move line pointers down one line
add edi, LineSkip
dec ebx // check line counter
jnz NewRow // done blitting, exit
//DoneBlit: // finished blit
}
return( TRUE );
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBuffer
Blits from a flat surface to a 16-bit buffer.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBuffer( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVSURFACE hSrcVSurface, UINT8 *pSrcBuffer, INT32 iX, INT32 iY)
{
UINT16 *p16BPPPalette;
// UINT32 uiOffset;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr;
UINT32 LineSkip;
// ETRLEObject *pTrav;
INT32 iTempX, iTempY;
UINT32 rows;
// Assertions
Assert( hSrcVSurface != NULL );
Assert( pSrcBuffer != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
usHeight = (UINT32)hSrcVSurface->usHeight;
usWidth = (UINT32)hSrcVSurface->usWidth;
// Add to start position of dest buffer
iTempX = iX;
iTempY = iY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)pSrcBuffer;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
p16BPPPalette = hSrcVSurface->p16BPPPalette;
LineSkip=(uiDestPitchBYTES-(usWidth*2));
__asm {
mov esi, SrcPtr // pointer to current line start address in source
mov edi, DestPtr // pointer to current line start address in destination
mov ecx, usHeight // line counter (goes top to bottom)
mov rows, ecx
mov edx, p16BPPPalette
sub eax, eax
sub ecx, ecx
mov ebx, usWidth // column counter (goes right to left)
dec ebx
ReadMask:
test usWidth, 1
jz BlitWord
xor eax, eax // clear out the top 24 bits
mov al, [esi+ebx]
shl eax, 1 // make it into a word index
mov ax, [edx+eax] // get 16-bit version of 8-bit pixel
mov [edi+ebx*2], ax // store it in destination buffer
dec ebx
js DoneRow
BlitWord:
test usWidth, 2
jz SetupDwords
mov ax, [esi+ebx-1]
mov cl, ah
sub ah, ah
and ecx, 0ffH
shl eax, 1
shl ecx, 1
mov ax, [edx+eax]
mov cx, [edx+ecx]
shl ecx, 16
mov cx, ax
mov [edi+ebx*2-2], ecx
sub ebx, 2
js DoneRow
SetupDwords:
BlitDwords:
mov ax, [esi+ebx-1]
mov cl, ah
sub ah, ah
and ecx, 0ffH
shl eax, 1
shl ecx, 1
mov ax, [edx+eax]
mov cx, [edx+ecx]
shl ecx, 16
mov cx, ax
mov [edi+ebx*2-2], ecx
mov ax, [esi+ebx-3]
mov cl, ah
sub ah, ah
and ecx, 0ffH
shl eax, 1
shl ecx, 1
mov ax, [edx+eax]
mov cx, [edx+ecx]
shl ecx, 16
mov cx, ax
mov [edi+ebx*2-6], ecx
sub ebx, 4 // decrement column counter
jns BlitDwords // loop until one line is done
DoneRow:
dec rows // check line counter
jz DoneBlit // done blitting, exit
add esi, usWidth // move line pointers down one line
add edi, uiDestPitchBYTES
mov ebx, usWidth // column counter (goes right to left)
dec ebx
jmp ReadMask
DoneBlit: // finished blit
}
return( TRUE );
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferHalf
Blits from a flat surface to a 16-bit buffer, dividing the source image into
exactly half the size.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferHalf( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVSURFACE hSrcVSurface, UINT8 *pSrcBuffer, UINT32 uiSrcPitch, INT32 iX, INT32 iY)
{
UINT16 *p16BPPPalette;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr;
UINT32 LineSkip;
INT32 iTempX, iTempY;
UINT32 uiSrcSkip;
// Assertions
Assert( hSrcVSurface != NULL );
Assert( pSrcBuffer != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
usHeight = (UINT32)hSrcVSurface->usHeight;
usWidth = (UINT32)hSrcVSurface->usWidth;
// Add to start position of dest buffer
iTempX = iX;
iTempY = iY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)pSrcBuffer;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
p16BPPPalette = hSrcVSurface->p16BPPPalette;
LineSkip=(uiDestPitchBYTES-(usWidth&0xfffffffe));
uiSrcSkip=(uiSrcPitch*2)-(usWidth&0xfffffffe);
__asm {
mov esi, SrcPtr // pointer to current line start address in source
mov edi, DestPtr // pointer to current line start address in destination
mov ebx, usHeight // line counter (goes top to bottom)
shr ebx, 1 // half the rows
mov edx, p16BPPPalette
xor eax, eax
BlitSetup:
mov ecx, usWidth
shr ecx, 1 // divide the width by 2
ReadMask:
mov al, [esi]
xor ah, ah
inc esi // skip one source byte
inc esi
shl eax, 1 // make it into a word index
mov ax, [edx+eax] // get 16-bit version of 8-bit pixel
mov [edi], ax // store it in destination buffer
inc edi // next pixel
inc edi
dec ecx
jnz ReadMask
//DoneRow:
add esi, uiSrcSkip // move source pointer down one line
add edi, LineSkip
dec ebx // check line counter
jnz BlitSetup // done blitting, exit
//DoneBlit: // finished blit
}
return( TRUE );
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferHalfRect
Blits from a flat surface to a 16-bit buffer, dividing the source image into
exactly half the size, from a sub-region.
- Source rect is in source units.
- In order to make sure the same pixels are skipped, always align the top and
left coordinates to the same factor of two.
- A rect specifying an odd number of pixels will divide out to an even
number of pixels blitted to the destination.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferHalfRect( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVSURFACE hSrcVSurface, UINT8 *pSrcBuffer, UINT32 uiSrcPitch, INT32 iX, INT32 iY, SGPRect *pRect)
{
UINT16 *p16BPPPalette;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr;
UINT32 LineSkip;
INT32 iTempX, iTempY;
UINT32 uiSrcSkip;
// Assertions
Assert( hSrcVSurface != NULL );
Assert( pSrcBuffer != NULL );
Assert( pBuffer != NULL );
Assert( pRect != NULL );
// Get Offsets from Index into structure
usWidth = (UINT32)(pRect->iRight-pRect->iLeft);
usHeight = (UINT32)(pRect->iBottom-pRect->iTop);
// Add to start position of dest buffer
iTempX = iX;
iTempY = iY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
CHECKF( usWidth > 0 );
CHECKF( usHeight > 0 );
CHECKF( usHeight <= hSrcVSurface->usHeight);
CHECKF( usWidth <= hSrcVSurface->usWidth);
SrcPtr = (UINT8 *)pSrcBuffer + (uiSrcPitch*pRect->iTop) + (pRect->iLeft);
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
p16BPPPalette = hSrcVSurface->p16BPPPalette;
LineSkip = (uiDestPitchBYTES-(usWidth&0xfffffffe));
uiSrcSkip = (uiSrcPitch*2)-(usWidth&0xfffffffe);
__asm {
mov esi, SrcPtr // pointer to current line start address in source
mov edi, DestPtr // pointer to current line start address in destination
mov ebx, usHeight // line counter (goes top to bottom)
shr ebx, 1 // half the rows
mov edx, p16BPPPalette
xor eax, eax
BlitSetup:
mov ecx, usWidth
shr ecx, 1 // divide the width by 2
ReadMask:
mov al, [esi]
xor ah, ah
inc esi // skip one source byte
inc esi
shl eax, 1 // make it into a word index
mov ax, [edx+eax] // get 16-bit version of 8-bit pixel
mov [edi], ax // store it in destination buffer
inc edi // next pixel
inc edi
dec ecx
jnz ReadMask
//DoneRow:
add esi, uiSrcSkip // move source pointer down one line
add edi, LineSkip
dec ebx // check line counter
jnz BlitSetup // done blitting, exit
//DoneBlit: // finished blit
}
return( TRUE );
}
/****************************INCOMPLETE***********************************************/
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferMask
Blits an image into the destination buffer, using an ETRLE brush as a source, another ETRLE
for a mask, and a 16-bit buffer as a destination.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferMask(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, HVOBJECT hMaskObject, INT32 iMOX, INT32 iMOY, UINT16 usMask)
{
UINT16 *p16BPPPalette;
UINT32 uiOffset;
UINT32 uiMOffset;
UINT32 usHeight, usWidth;
UINT32 usMHeight, usMWidth;
UINT8 *SrcPtr, *DestPtr, *MaskPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[usIndex]);
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Get Offsets from Index into structure for mask
pTrav = &(hMaskObject->pETRLEObject[usMask]);
usMHeight = (UINT32)pTrav->usHeight;
usMWidth = (UINT32)pTrav->usWidth;
uiMOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
MaskPtr= (UINT8 *)hMaskObject->pPixData + uiMOffset + (iMOY*usMWidth) + iMOX;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
p16BPPPalette = hSrcVObject->pShadeCurrent;
LineSkip=(uiDestPitchBYTES-(usWidth*2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
xor ebx, ebx
xor ecx, ecx
BlitDispatch:
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
clc
rcr cl, 1
jnc BlitNTL2
mov bl, [esi]
mov ax, [edx+ebx*2]
mov [edi], ax
inc esi
add edi, 2
BlitNTL2:
clc
rcr cl, 1
jnc BlitNTL3
mov bl, [esi]
mov ax, [edx+ebx*2]
mov [edi], ax
mov bl, [esi+1]
mov ax, [edx+ebx*2]
mov [edi+2], ax
add esi, 2
add edi, 4
BlitNTL3:
or cl, cl
jz BlitDispatch
xor ebx, ebx
BlitNTL4:
mov bl, [esi]
mov ax, [edx+ebx*2]
mov [edi], ax
mov bl, [esi+1]
mov ax, [edx+ebx*2]
mov [edi+2], ax
mov bl, [esi+2]
mov ax, [edx+ebx*2]
mov [edi+4], ax
mov bl, [esi+3]
mov ax, [edx+ebx*2]
mov [edi+6], ax
add esi, 4
add edi, 8
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
// shl ecx, 1
add ecx, ecx
add edi, ecx
jmp BlitDispatch
BlitDoneLine:
dec usHeight
jz BlitDone
add edi, LineSkip
jmp BlitDispatch
BlitDone:
}
return(TRUE);
}
void SetClippingRect(SGPRect *clip)
{
Assert(clip!=NULL);
Assert(clip->iLeft < clip->iRight);
Assert(clip->iTop < clip->iBottom);
memcpy(&ClippingRect, clip, sizeof(SGPRect));
}
void GetClippingRect(SGPRect *clip)
{
Assert(clip!=NULL);
memcpy(clip, &ClippingRect, sizeof(SGPRect));
}
/**********************************************************************************************
Blt16BPPBufferPixelateRectWithColor
Given an 8x8 pattern and a color, pixelates an area by repeatedly "applying the color" to pixels whereever there
is a non-zero value in the pattern.
KM: Added Nov. 23, 1998
This is all the code that I moved from Blt16BPPBufferPixelateRect().
This function now takes a color field (which previously was
always black. The 3rd assembler line in this function:
mov ax, usColor // color of pixel
used to be:
xor eax, eax // color of pixel (black or 0)
This was the only internal modification I made other than adding the usColor argument.
*********************************************************************************************/
BOOLEAN Blt16BPPBufferPixelateRectWithColor(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, SGPRect *area, UINT8 Pattern[8][8], UINT16 usColor )
{
INT32 width, height;
UINT32 LineSkip;
UINT16 *DestPtr;
INT32 iLeft, iTop, iRight, iBottom;
// Assertions
Assert( pBuffer != NULL );
Assert( Pattern != NULL );
iLeft=__max(ClippingRect.iLeft, area->iLeft);
iTop=__max(ClippingRect.iTop, area->iTop);
iRight=__min(ClippingRect.iRight-1, area->iRight);
iBottom=__min(ClippingRect.iBottom-1, area->iBottom);
DestPtr=(pBuffer+(iTop*(uiDestPitchBYTES/2))+iLeft);
width=iRight-iLeft+1;
height=iBottom-iTop+1;
LineSkip=(uiDestPitchBYTES-(width*2));
CHECKF(width >=1);
CHECKF(height >=1);
__asm {
mov esi, Pattern // Pointer to pixel pattern
mov edi, DestPtr // Pointer to top left of rect area
mov ax, usColor // color of pixel
xor ebx, ebx // pattern column index
xor edx, edx // pattern row index
BlitNewLine:
mov ecx, width
BlitLine:
cmp [esi+ebx], 0
je BlitLine2
mov [edi], ax
BlitLine2:
add edi, 2
inc ebx
and ebx, 07H
or ebx, edx
dec ecx
jnz BlitLine
add edi, LineSkip
xor ebx, ebx
add edx, 08H
and edx, 38H
dec height
jnz BlitNewLine
}
return(TRUE);
}
//KM: Modified Nov. 23, 1998
//Original prototype (this function) didn't have a color field. I've added the color field to
//Blt16BPPBufferPixelateRectWithColor(), moved the previous implementation of this function there, and added
//the modification to allow a specific color.
BOOLEAN Blt16BPPBufferPixelateRect(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, SGPRect *area, UINT8 Pattern[8][8] )
{
return Blt16BPPBufferPixelateRectWithColor( pBuffer, uiDestPitchBYTES, area, Pattern, 0 );
}
/**********************************************************************************************
Blt16BPPBufferHatchRect
A wrapper for Blt16BPPBufferPixelateRect(), it automatically sends a hatch pattern to it
of the specified color
*********************************************************************************************/
BOOLEAN Blt16BPPBufferHatchRectWithColor(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, SGPRect *area, UINT16 usColor )
{
UINT8 Pattern[8][8] =
{
1,0,1,0,1,0,1,0,
0,1,0,1,0,1,0,1,
1,0,1,0,1,0,1,0,
0,1,0,1,0,1,0,1,
1,0,1,0,1,0,1,0,
0,1,0,1,0,1,0,1,
1,0,1,0,1,0,1,0,
0,1,0,1,0,1,0,1
};
return Blt16BPPBufferPixelateRectWithColor( pBuffer, uiDestPitchBYTES, area, Pattern, usColor );
}
//Uses black hatch color
BOOLEAN Blt16BPPBufferHatchRect(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, SGPRect *area )
{
UINT8 Pattern[8][8] =
{
1,0,1,0,1,0,1,0,
0,1,0,1,0,1,0,1,
1,0,1,0,1,0,1,0,
0,1,0,1,0,1,0,1,
1,0,1,0,1,0,1,0,
0,1,0,1,0,1,0,1,
1,0,1,0,1,0,1,0,
0,1,0,1,0,1,0,1
};
return Blt16BPPBufferPixelateRectWithColor( pBuffer, uiDestPitchBYTES, area, Pattern, 0 );
}
BOOLEAN Blt16BPPBufferLooseHatchRectWithColor(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, SGPRect *area, UINT16 usColor )
{
UINT8 Pattern[8][8] =
{
1,0,0,0,1,0,0,0,
0,0,0,0,0,0,0,0,
0,0,1,0,0,0,1,0,
0,0,0,0,0,0,0,0,
1,0,0,0,1,0,0,0,
0,0,0,0,0,0,0,0,
0,0,1,0,0,0,1,0,
0,0,0,0,0,0,0,0,
};
return Blt16BPPBufferPixelateRectWithColor( pBuffer, uiDestPitchBYTES, area, Pattern, usColor );
}
BOOLEAN Blt16BPPBufferLooseHatchRect(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, SGPRect *area )
{
UINT8 Pattern[8][8] =
{
1,0,0,0,1,0,0,0,
0,0,0,0,0,0,0,0,
0,0,1,0,0,0,1,0,
0,0,0,0,0,0,0,0,
1,0,0,0,1,0,0,0,
0,0,0,0,0,0,0,0,
0,0,1,0,0,0,1,0,
0,0,0,0,0,0,0,0,
};
return Blt16BPPBufferPixelateRectWithColor( pBuffer, uiDestPitchBYTES, area, Pattern, 0 );
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferShadow
Modifies the destination buffer. Darkens the destination pixels by 25%, using the source
image as a mask. Any Non-zero index pixels are used to darken destination pixels.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferShadow( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex)
{
UINT16 *p16BPPPalette;
UINT32 uiOffset;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
p16BPPPalette = hSrcVObject->pShadeCurrent;
LineSkip=(uiDestPitchBYTES-(usWidth*2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
xor eax, eax
mov ebx, usHeight
xor ecx, ecx
mov edx, OFFSET ShadeTable
BlitDispatch:
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
xor eax, eax
add esi, ecx
clc
rcr cl, 1
jnc BlitNTL2
mov ax, [edi]
mov ax, [edx+eax*2]
mov [edi], ax
add edi, 2
BlitNTL2:
clc
rcr cl, 1
jnc BlitNTL3
mov ax, [edi]
mov ax, [edx+eax*2]
mov [edi], ax
mov ax, [edi+2]
mov ax, [edx+eax*2]
mov [edi+2], ax
add edi, 4
BlitNTL3:
or cl, cl
jz BlitDispatch
BlitNTL4:
mov ax, [edi]
mov ax, [edx+eax*2]
mov [edi], ax
mov ax, [edi+2]
mov ax, [edx+eax*2]
mov [edi+2], ax
mov ax, [edi+4]
mov ax, [edx+eax*2]
mov [edi+4], ax
mov ax, [edi+6]
mov ax, [edx+eax*2]
mov [edi+6], ax
add edi, 8
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
// shl ecx, 1
add ecx, ecx
add edi, ecx
jmp BlitDispatch
BlitDoneLine:
dec ebx
jz BlitDone
add edi, LineSkip
jmp BlitDispatch
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferTransparent
Blits an image into the destination buffer, using an ETRLE brush as a source, and a 16-bit
buffer as a destination.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferTransparent( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex )
{
UINT16 *p16BPPPalette;
UINT32 uiOffset;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
p16BPPPalette = hSrcVObject->pShadeCurrent;
LineSkip=(uiDestPitchBYTES-(usWidth*2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
xor ebx, ebx
xor ecx, ecx
BlitDispatch:
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
clc
rcr cl, 1
jnc BlitNTL2
mov bl, [esi]
mov ax, [edx+ebx*2]
mov [edi], ax
inc esi
add edi, 2
BlitNTL2:
clc
rcr cl, 1
jnc BlitNTL3
mov bl, [esi]
mov ax, [edx+ebx*2]
mov [edi], ax
mov bl, [esi+1]
mov ax, [edx+ebx*2]
mov [edi+2], ax
add esi, 2
add edi, 4
BlitNTL3:
or cl, cl
jz BlitDispatch
xor ebx, ebx
BlitNTL4:
mov bl, [esi]
mov ax, [edx+ebx*2]
mov [edi], ax
mov bl, [esi+1]
mov ax, [edx+ebx*2]
mov [edi+2], ax
mov bl, [esi+2]
mov ax, [edx+ebx*2]
mov [edi+4], ax
mov bl, [esi+3]
mov ax, [edx+ebx*2]
mov [edi+6], ax
add esi, 4
add edi, 8
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
// shl ecx, 1
add ecx, ecx
add edi, ecx
jmp BlitDispatch
BlitDoneLine:
dec usHeight
jz BlitDone
add edi, LineSkip
jmp BlitDispatch
BlitDone:
}
return(TRUE);
}
//*****************************************************************************************
// Blt8BPPDataTo16BPPBufferTransMirror
//
// Blits an 8bpp ETRLE to a 16-bit buffer, mirroring the image, with transparency.
//
// Returns BOOLEAN - TRUE if successful
//
// UINT16 *pBuffer - 16bpp Destination buffer
// UINT32 uiDestPitchBYTES - Destination pitch in bytes
// HVOBJECT hSrcVObject - Source VOBJECT handle
// INT32 iX - X-location of blit
// INT32 iY - Y-location of blit
// UINT16 usIndex - VOBJECT image index to blit from
//
// Created: 7/28/99 Derek Beland
//*****************************************************************************************
BOOLEAN Blt8BPPDataTo16BPPBufferTransMirror( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex )
{
UINT16 *p16BPPPalette;
UINT32 uiOffset;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr;
UINT32 uiDestSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
// iTempX = iX + pTrav->sOffsetX;
iTempX = iX + usWidth - pTrav->sOffsetX-1;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
p16BPPPalette = hSrcVObject->pShadeCurrent;
uiDestSkip=(uiDestPitchBYTES+(usWidth*2));
__asm {
// esi = pointer to source data
// edi = pointer to destination buffer
// eax = 16bpp pixel
// ebx = 8bpp pixel
// ecx = repeat count
// edx = pointer to 8->16bpp conversion table
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
xor ebx, ebx
xor ecx, ecx
BlitDispatch:
// pick up a new byte
mov cl, [esi]
inc esi
or cl, cl
// if bit 7 is set, the run is transparent
js BlitTransparent
// if the byte is zero, it marks the end of current line
jz BlitDoneLine
//BlitNonTransLoop:
// else we have a normal run of non-transparent bytes
// blit one byte of the count
clc
rcr cl, 1
jnc BlitNTL2
mov bl, [esi]
mov ax, [edx+ebx*2]
mov [edi], ax
inc esi
sub edi, 2
// blit one word of the count
BlitNTL2:
clc
rcr cl, 1
jnc BlitNTL3
mov bl, [esi]
mov ax, [edx+ebx*2]
mov [edi], ax
mov bl, [esi+1]
mov ax, [edx+ebx*2]
mov [edi-2], ax
add esi, 2
sub edi, 4
// blit the rest four at a time (unrolled loop)
BlitNTL3:
or cl, cl
jz BlitDispatch
xor ebx, ebx
BlitNTL4:
mov bl, [esi]
mov ax, [edx+ebx*2]
mov [edi], ax
mov bl, [esi+1]
mov ax, [edx+ebx*2]
mov [edi-2], ax
mov bl, [esi+2]
mov ax, [edx+ebx*2]
mov [edi-4], ax
mov bl, [esi+3]
mov ax, [edx+ebx*2]
mov [edi-6], ax
add esi, 4
sub edi, 8
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
// shl ecx, 1
add ecx, ecx
sub edi, ecx
jmp BlitDispatch
BlitDoneLine:
dec usHeight
jz BlitDone
add edi, uiDestSkip
jmp BlitDispatch
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferTransparentClip
Blits an image into the destination buffer, using an ETRLE brush as a source, and a 16-bit
buffer as a destination. Clips the brush.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferTransparentClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion)
{
UINT16 *p16BPPPalette;
UINT32 uiOffset;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight;
INT32 ClipX1, ClipY1, ClipX2, ClipY2;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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(TRUE);
// check if whole thing is clipped
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
return(TRUE);
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
p16BPPPalette = hSrcVObject->pShadeCurrent;
LineSkip=(uiDestPitchBYTES-(BlitLength*2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
mov ebx, TopSkip
xor ecx, ecx
or ebx, ebx // check for nothing clipped on top
jz LeftSkipSetup
TopSkipLoop: // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
jmp TopSkipLoop
TSEndLine:
dec ebx
jnz TopSkipLoop
LeftSkipSetup:
mov Unblitted, 0
mov ebx, LeftSkip // check for nothing clipped on the left
or ebx, ebx
jz BlitLineSetup
LeftSkipLoop:
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, ebx
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, ebx // skip partial run, jump into normal loop for rest
sub ecx, ebx
mov ebx, BlitLength
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2:
add esi, ecx // skip whole run, and start blit with new run
jmp BlitLineSetup
LSSkip1:
add esi, ecx // skip whole run, continue skipping
sub ebx, ecx
jmp LeftSkipLoop
LSTrans:
and ecx, 07fH
cmp ecx, ebx
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, ebx // skip partial run, jump into normal loop for rest
mov ebx, BlitLength
mov Unblitted, 0
jmp BlitTransparent
LSTrans1:
sub ebx, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup: // Does any actual blitting (trans/non) for the line
mov ebx, BlitLength
mov Unblitted, 0
BlitDispatch:
or ebx, ebx // Check to see if we're done blitting
jz RightSkipLoop
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
BlitNonTransLoop: // blit non-transparent pixels
cmp ecx, ebx
jbe BNTrans1
sub ecx, ebx
mov Unblitted, ecx
mov ecx, ebx
BNTrans1:
sub ebx, ecx
clc
rcr cl, 1
jnc BlitNTL2
xor eax, eax
mov al, [esi]
mov ax, [edx+eax*2]
mov [edi], ax
inc esi
add edi, 2
BlitNTL2:
clc
rcr cl, 1
jnc BlitNTL3
xor eax, eax
mov al, [esi]
mov ax, [edx+eax*2]
mov [edi], ax
xor eax, eax
mov al, [esi+1]
mov ax, [edx+eax*2]
mov [edi+2], ax
add esi, 2
add edi, 4
BlitNTL3:
or cl, cl
jz BlitLineEnd
BlitNTL4:
xor eax, eax
mov al, [esi]
mov ax, [edx+eax*2]
mov [edi], ax
xor eax, eax
mov al, [esi+1]
mov ax, [edx+eax*2]
mov [edi+2], ax
xor eax, eax
mov al, [esi+2]
mov ax, [edx+eax*2]
mov [edi+4], ax
xor eax, eax
mov al, [esi+3]
mov ax, [edx+eax*2]
mov [edi+6], ax
add esi, 4
add edi, 8
dec cl
jnz BlitNTL4
BlitLineEnd:
add esi, Unblitted
jmp BlitDispatch
BlitTransparent: // skip transparent pixels
and ecx, 07fH
cmp ecx, ebx
jbe BTrans1
mov ecx, ebx
BTrans1:
sub ebx, ecx
// shl ecx, 1
add ecx, ecx
add edi, ecx
jmp BlitDispatch
RightSkipLoop: // skip along until we hit and end-of-line marker
RSLoop1:
mov al, [esi]
inc esi
or al, al
jnz RSLoop1
dec BlitHeight
jz BlitDone
add edi, LineSkip
jmp LeftSkipSetup
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
BltIsClipped
Determines whether a given blit will need clipping or not. Returns TRUE/FALSE.
**********************************************************************************************/
BOOLEAN BltIsClipped(HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion )
{
UINT32 usHeight, usWidth;
ETRLEObject *pTrav;
INT32 iTempX, iTempY;
INT32 ClipX1, ClipY1, ClipX2, ClipY2;
// Assertions
Assert( hSrcVObject != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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
if(__min(ClipX1 - min(ClipX1, iTempX), (INT32)usWidth))
return(TRUE);
if(__min(max(ClipX2, (iTempX+(INT32)usWidth)) - ClipX2, (INT32)usWidth))
return(TRUE);
if(__min(ClipY1 - __min(ClipY1, iTempY), (INT32)usHeight))
return(TRUE);
if(__min(__max(ClipY2, (iTempY+(INT32)usHeight)) - ClipY2, (INT32)usHeight))
return(TRUE);
return(FALSE);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferShadowClip
Modifies the destination buffer. Darkens the destination pixels by 25%, using the source
image as a mask. Any Non-zero index pixels are used to darken destination pixels. Blitter
clips brush if it doesn't fit on the viewport.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferShadowClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion)
{
UINT16 *p16BPPPalette;
UINT32 uiOffset;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight;
INT32 ClipX1, ClipY1, ClipX2, ClipY2;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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);
// whole thing is clipped
if((LeftSkip >=(INT32)usWidth) || (RightSkip >=(INT32)usWidth))
return(TRUE);
// whole thing is clipped
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
return(TRUE);
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
p16BPPPalette = hSrcVObject->pShadeCurrent;
LineSkip=(uiDestPitchBYTES-(BlitLength*2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, OFFSET ShadeTable
xor eax, eax
mov ebx, TopSkip
xor ecx, ecx
or ebx, ebx // check for nothing clipped on top
jz LeftSkipSetup
TopSkipLoop: // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
jmp TopSkipLoop
TSEndLine:
dec ebx
jnz TopSkipLoop
LeftSkipSetup:
mov Unblitted, 0
mov ebx, LeftSkip // check for nothing clipped on the left
or ebx, ebx
jz BlitLineSetup
LeftSkipLoop:
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, ebx
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, ebx // skip partial run, jump into normal loop for rest
sub ecx, ebx
mov ebx, BlitLength
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2:
add esi, ecx // skip whole run, and start blit with new run
jmp BlitLineSetup
LSSkip1:
add esi, ecx // skip whole run, continue skipping
sub ebx, ecx
jmp LeftSkipLoop
LSTrans:
and ecx, 07fH
cmp ecx, ebx
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, ebx // skip partial run, jump into normal loop for rest
mov ebx, BlitLength
jmp BlitTransparent
LSTrans1:
sub ebx, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup: // Does any actual blitting (trans/non) for the line
mov ebx, BlitLength
mov Unblitted, 0
BlitDispatch:
or ebx, ebx // Check to see if we're done blitting
jz RightSkipLoop
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
BlitNonTransLoop:
cmp ecx, ebx
jbe BNTrans1
sub ecx, ebx
mov Unblitted, ecx
mov ecx, ebx
BNTrans1:
sub ebx, ecx
clc
rcr cl, 1
jnc BlitNTL2
mov ax, [edi]
mov ax, [edx+eax*2]
mov [edi], ax
inc esi
add edi, 2
BlitNTL2:
clc
rcr cl, 1
jnc BlitNTL3
mov ax, [edi]
mov ax, [edx+eax*2]
mov [edi], ax
mov ax, [edi+2]
mov ax, [edx+eax*2]
mov [edi+2], ax
add esi, 2
add edi, 4
BlitNTL3:
or cl, cl
jz BlitLineEnd
BlitNTL4:
mov ax, [edi]
mov ax, [edx+eax*2]
mov [edi], ax
mov ax, [edi+2]
mov ax, [edx+eax*2]
mov [edi+2], ax
mov ax, [edi+4]
mov ax, [edx+eax*2]
mov [edi+4], ax
mov ax, [edi+6]
mov ax, [edx+eax*2]
mov [edi+6], ax
add esi, 4
add edi, 8
dec cl
jnz BlitNTL4
BlitLineEnd:
add esi, Unblitted
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
cmp ecx, ebx
jbe BTrans1
mov ecx, ebx
BTrans1:
sub ebx, ecx
// shl ecx, 1
add ecx, ecx
add edi, ecx
jmp BlitDispatch
RightSkipLoop:
RSLoop1:
mov al, [esi]
inc esi
or al, al
jnz RSLoop1
dec BlitHeight
jz BlitDone
add edi, LineSkip
jmp LeftSkipSetup
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt16BPPBufferShadowRect
Darkens a rectangular area by 25%. This blitter is used by ShadowVideoObjectRect.
pBuffer Pointer to a 16BPP buffer
uiDestPitchBytes Pitch of the destination surface
area An SGPRect, the area to darken
*********************************************************************************************/
BOOLEAN Blt16BPPBufferShadowRect(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, SGPRect *area)
{
INT32 width, height;
UINT32 LineSkip;
UINT16 *DestPtr;
// Assertions
Assert( pBuffer != NULL );
// Clipping
if( area->iLeft < ClippingRect.iLeft )
area->iLeft = ClippingRect.iLeft;
if( area->iTop < ClippingRect.iTop )
area->iTop = ClippingRect.iTop;
if( area->iRight >= ClippingRect.iRight )
area->iRight = ClippingRect.iRight - 1;
if( area->iBottom >= ClippingRect.iBottom )
area->iBottom = ClippingRect.iBottom - 1;
//CHECKF(area->iLeft >= ClippingRect.iLeft );
//CHECKF(area->iTop >= ClippingRect.iTop );
//CHECKF(area->iRight <= ClippingRect.iRight );
//CHECKF(area->iBottom <= ClippingRect.iBottom );
DestPtr=(pBuffer+(area->iTop*(uiDestPitchBYTES/2))+area->iLeft);
width=area->iRight-area->iLeft+1;
height=area->iBottom-area->iTop+1;
LineSkip=(uiDestPitchBYTES-(width*2));
CHECKF(width >=1);
CHECKF(height >=1);
__asm {
mov esi, OFFSET ShadeTable
mov edi, DestPtr
xor eax, eax
mov ebx, LineSkip
mov edx, height
BlitNewLine:
mov ecx, width
BlitLine:
mov ax, [edi]
mov ax, [esi+eax*2]
mov [edi], ax
add edi, 2
dec ecx
jnz BlitLine
add edi, ebx
dec edx
jnz BlitNewLine
}
return(TRUE);
}
/**********************************************************************************************
Blt16BPPBufferShadowRect
Darkens a rectangular area by 25%. This blitter is used by ShadowVideoObjectRect.
pBuffer Pointer to a 16BPP buffer
uiDestPitchBytes Pitch of the destination surface
area An SGPRect, the area to darken
*********************************************************************************************/
BOOLEAN Blt16BPPBufferShadowRectAlternateTable(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, SGPRect *area)
{
INT32 width, height;
UINT32 LineSkip;
UINT16 *DestPtr;
// Assertions
Assert( pBuffer != NULL );
// Clipping
if( area->iLeft < ClippingRect.iLeft )
area->iLeft = ClippingRect.iLeft;
if( area->iTop < ClippingRect.iTop )
area->iTop = ClippingRect.iTop;
if( area->iRight >= ClippingRect.iRight )
area->iRight = ClippingRect.iRight - 1;
if( area->iBottom >= ClippingRect.iBottom )
area->iBottom = ClippingRect.iBottom - 1;
//CHECKF(area->iLeft >= ClippingRect.iLeft );
//CHECKF(area->iTop >= ClippingRect.iTop );
//CHECKF(area->iRight <= ClippingRect.iRight );
//CHECKF(area->iBottom <= ClippingRect.iBottom );
DestPtr=(pBuffer+(area->iTop*(uiDestPitchBYTES/2))+area->iLeft);
width=area->iRight-area->iLeft+1;
height=area->iBottom-area->iTop+1;
LineSkip=(uiDestPitchBYTES-(width*2));
CHECKF(width >=1);
CHECKF(height >=1);
__asm {
mov esi, OFFSET IntensityTable
mov edi, DestPtr
xor eax, eax
mov ebx, LineSkip
mov edx, height
BlitNewLine:
mov ecx, width
BlitLine:
mov ax, [edi]
mov ax, [esi+eax*2]
mov [edi], ax
add edi, 2
dec ecx
jnz BlitLine
add edi, ebx
dec edx
jnz BlitNewLine
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferMonoShadow
Uses a bitmap an 8BPP template for blitting. Anywhere a 1 appears in the bitmap, a shadow
is blitted to the destination (a black pixel). Any other value above zero is considered a
forground color, and zero is background. If the parameter for the background color is zero,
transparency is used for the background.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferMonoShadow( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, UINT16 usForeground, UINT16 usBackground)
{
UINT16 *p16BPPPalette;
UINT32 uiOffset;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
p16BPPPalette = hSrcVObject->pShadeCurrent;
LineSkip=(uiDestPitchBYTES-(usWidth*2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
xor ebx, ebx
xor ecx, ecx
BlitDispatch:
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
xor ebx, ebx
BlitNTL4:
mov bl, [esi]
cmp bl, 1
jb BlitNTL5
// write a black shadow
xor ax, ax
mov [edi], ax
inc esi
add edi, 2
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitNTL5:
or bl, bl
jz BlitNTL6
mov ax, usForeground
mov [edi], ax
inc esi
add edi, 2
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitNTL6:
cmp usBackground, 0
je BlitNTL7
mov ax, usBackground
mov [edi], ax
BlitNTL7:
inc esi
add edi, 2
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
mov ax, usBackground
or ax, ax
jz BTrans1
rep stosw
jmp BlitDispatch
BTrans1:
// shl ecx, 1
add ecx, ecx
add edi, ecx
jmp BlitDispatch
BlitDoneLine:
dec usHeight
jz BlitDone
add edi, LineSkip
jmp BlitDispatch
BlitDone:
}
return(TRUE);
}
/*
BOOLEAN Blt8BPPDataTo16BPPBufferFullTransparent( HVOBJECT hDestVObject, HVOBJECT hSrcVObject, UINT16 usX, UINT16 usY, SGPRect *srcRect )
{
UINT32 uiSrcStart, uiDestStart, uiNumLines, uiLineSize;
// UINT32 rows, cols;
UINT8 *pSrc; //, *pSrcTemp;
UINT16 *pDest; //*pDestTemp,
UINT32 uiSrcPitch, uiDestPitch;
UINT16 *p16BPPPalette;
UINT16 usEffectiveSrcWidth;
UINT16 usEffectiveDestWidth;
UINT16 us16BPPSrcTransColor;
UINT16 us16BPPDestTransColor;
// UINT16 us16BPPValue;
UINT32 count;
UINT8 maskcolor;
// Assertions
Assert( hSrcVObject != NULL );
Assert( hDestVObject != NULL );
// Validations
CHECKF( usX >= 0 );
CHECKF( usY >= 0 );
CHECKF( srcRect->iRight > srcRect->iLeft );
CHECKF( srcRect->iBottom > srcRect->iTop );
p16BPPPalette = hSrcVObject->p16BPPPalette;
CHECKF( p16BPPPalette != NULL );
// Lock Data
pSrc = LockVideoObjectBuffer( hSrcVObject, &uiSrcPitch );
// Effective width ( in PIXELS ) is Pitch ( in bytes ) converted to pitch ( IN PIXELS )
usEffectiveSrcWidth = (UINT16)( uiSrcPitch / ( hSrcVObject->ubBitDepth / 8 ) );
pDest = (UINT16*)LockVideoObjectBuffer( hDestVObject, &uiDestPitch );
// Effective width ( in PIXELS ) is Pitch ( in bytes ) converted to pitch ( IN PIXELS )
usEffectiveDestWidth = (UINT16)( uiDestPitch / ( hDestVObject->ubBitDepth / 8 ) );
// Determine memcopy coordinates
uiSrcStart = srcRect->iTop * usEffectiveSrcWidth + srcRect->iLeft;
uiDestStart = usY * usEffectiveDestWidth + usX;
uiNumLines = ( srcRect->iBottom - srcRect->iTop );
uiLineSize = ( srcRect->iRight - srcRect->iLeft );
CHECKF( hDestVObject->usWidth >= uiLineSize );
CHECKF( hDestVObject->usHeight >= uiNumLines );
// Find 16 BPP transparent color
us16BPPSrcTransColor = Get16BPPColor( hSrcVObject->TransparentColor );
for(count=0; (count < 256) && (p16BPPPalette[count]!=us16BPPSrcTransColor); count++);
if(count==256)
{
DebugMsg(TOPIC_VIDEOOBJECT, DBG_LEVEL_2, String( "Transparency color does not exist in palette table for source object" ));
maskcolor=0;
}
else
maskcolor=(UINT8)count;
us16BPPDestTransColor = Get16BPPColor( hDestVObject->TransparentColor );
// Convert to Pixel specification
pDest = pDest + uiDestStart;
pSrc = pSrc + uiSrcStart;
__asm {
mov esi, pSrc // pointer to current line start address in source
mov edi, pDest // pointer to current line start address in destination
mov ecx, uiNumLines // line counter (goes top to bottom)
mov edx, p16BPPPalette
mov ebx, uiLineSize // column counter (goes right to left)
dec ebx
ReadMask:
mov ax, [edi+ebx*2]
cmp ax, us16BPPDestTransColor
je NextColumn
xor eax, eax // clear out the top 24 bits
mov al, [esi+ebx]
cmp al, maskcolor
je NextColumn
shl eax, 1 // make it into a word index
mov ax, [edx+eax] // get 16-bit version of 8-bit pixel
mov [edi+ebx*2], ax
NextColumn:
dec ebx // decrement column counter
jns ReadMask // loop until one line is done
dec ecx // check line counter
jz DoneBlit // done blitting, exit
add esi, uiSrcPitch // move line pointers down one line
add edi, uiDestPitch
mov ebx, uiLineSize // column counter (goes right to left)
dec ebx
jmp ReadMask // back into blitting on next line
DoneBlit: // finished blit
}
ReleaseVideoObjectBuffer( hSrcVObject );
ReleaseVideoObjectBuffer( hDestVObject );
return( TRUE );
} */
// UTILITY FUNCTIONS FOR BLITTING
/*
BOOLEAN ClipReleatedSrcAndDestRectangles( HVOBJECT hDestVObject, HVOBJECT hSrcVObject, RECT *DestRect, RECT *SrcRect )
{
Assert( hDestVObject != NULL );
Assert( hSrcVObject != NULL );
// Check for invalid start positions and clip by ignoring blit
if ( DestRect->iLeft >= hDestVObject->usWidth || DestRect->iTop >= hDestVObject->usHeight )
{
return( FALSE );
}
if ( SrcRect->iLeft >= hSrcVObject->usWidth || SrcRect->iTop >= hSrcVObject->usHeight )
{
return( FALSE );
}
// For overruns
// Clip destination rectangles
if ( DestRect->iRight > hDestVObject->usWidth )
{
// Both have to be modified or by default streching occurs
DestRect->iRight = hDestVObject->usWidth;
SrcRect->iRight = SrcRect->iLeft + ( DestRect->iRight - DestRect->iLeft );
}
if ( DestRect->iBottom > hDestVObject->usHeight )
{
// Both have to be modified or by default streching occurs
DestRect->iBottom = hDestVObject->usHeight;
SrcRect->iBottom = SrcRect->iTop + ( DestRect->iBottom - DestRect->iTop );
}
// Clip src rectangles
if ( SrcRect->iRight > hSrcVObject->usWidth )
{
// Both have to be modified or by default streching occurs
SrcRect->iRight = hSrcVObject->usWidth;
DestRect->iRight = DestRect->iLeft + ( SrcRect->iRight - SrcRect->iLeft );
}
if ( SrcRect->iBottom > hSrcVObject->usHeight )
{
// Both have to be modified or by default streching occurs
SrcRect->iBottom = hSrcVObject->usHeight;
DestRect->iBottom = DestRect->iTop + ( SrcRect->iBottom - SrcRect->iTop );
}
// For underruns
// Clip destination rectangles
if ( DestRect->iLeft < 0 )
{
// Both have to be modified or by default streching occurs
DestRect->iLeft = 0;
SrcRect->iLeft = SrcRect->iRight - ( DestRect->iRight - DestRect->iLeft );
}
if ( DestRect->iTop < 0 )
{
// Both have to be modified or by default streching occurs
DestRect->iTop = 0;
SrcRect->iTop = SrcRect->iBottom - ( DestRect->iBottom - DestRect->iTop );
}
// Clip src rectangles
if ( SrcRect->iLeft < 0 )
{
// Both have to be modified or by default streching occurs
SrcRect->iLeft = 0;
DestRect->iLeft = DestRect->iRight - ( SrcRect->iRight - SrcRect->iLeft );
}
if ( SrcRect->iTop < 0 )
{
// Both have to be modified or by default streching occurs
SrcRect->iTop = 0;
DestRect->iTop = DestRect->iBottom - ( SrcRect->iBottom - SrcRect->iTop );
}
return( TRUE );
}
BOOLEAN FillSurface( HVOBJECT hDestVObject, blt_fx *pBltFx )
{
DDBLTFX BlitterFX;
Assert( hDestVObject != NULL );
CHECKF( pBltFx != NULL );
BlitterFX.dwSize = sizeof( DDBLTFX );
BlitterFX.dwFillColor = pBltFx->ColorFill;
DDBltSurface( (LPDIRECTDRAWSURFACE2)hDestVObject->pSurfaceData, NULL, NULL, NULL, DDBLT_COLORFILL, &BlitterFX );
if ( hDestVObject->fFlags & VOBJECT_VIDEO_MEM_USAGE && !hDestVObject->fFlags & VOBJECT_RESERVED_SURFACE )
{
UpdateBackupSurface( hDestVObject );
}
return( TRUE );
}
BOOLEAN FillSurfaceRect( HVOBJECT hDestVObject, blt_fx *pBltFx )
{
DDBLTFX BlitterFX;
Assert( hDestVObject != NULL );
CHECKF( pBltFx != NULL );
BlitterFX.dwSize = sizeof( DDBLTFX );
BlitterFX.dwFillColor = pBltFx->ColorFill;
DDBltSurface( (LPDIRECTDRAWSURFACE2)hDestVObject->pSurfaceData, (LPRECT)&(pBltFx->FillRect), NULL, NULL, DDBLT_COLORFILL, &BlitterFX );
if ( hDestVObject->fFlags & VOBJECT_VIDEO_MEM_USAGE && !hDestVObject->fFlags & VOBJECT_RESERVED_SURFACE )
{
UpdateBackupSurface( hDestVObject );
}
return( TRUE );
}
BOOLEAN BltVObjectUsingDD( HVOBJECT hDestVObject, HVOBJECT hSrcVObject, UINT32 fBltFlags, INT32 iDestX, INT32 iDestY, RECT *SrcRect )
{
UINT32 uiDDFlags;
RECT DestRect;
// Blit using the correct blitter
if ( fBltFlags & VO_BLT_FAST )
{
// Validations
CHECKF( iDestX >= 0 );
CHECKF( iDestY >= 0 );
// Default flags
uiDDFlags = 0;
// Convert flags into DD flags, ( for transparency use, etc )
if ( fBltFlags & VO_BLT_USECOLORKEY )
{
uiDDFlags != DDBLTFAST_SRCCOLORKEY;
}
// Convert flags into DD flags, ( for transparency use, etc )
if ( fBltFlags & VO_BLT_USEDESTCOLORKEY )
{
uiDDFlags != DDBLTFAST_DESTCOLORKEY;
}
if ( uiDDFlags == 0 )
{
// Default here is no colorkey
uiDDFlags = DDBLTFAST_NOCOLORKEY;
}
DDBltFastSurface( (LPDIRECTDRAWSURFACE2)hDestVObject->pSurfaceData, iDestX, iDestY, (LPDIRECTDRAWSURFACE2)hSrcVObject->pSurfaceData, SrcRect, uiDDFlags );
}
else
{
// Normal, specialized blit for clipping, etc
// Default flags
uiDDFlags = DDBLT_WAIT;
// Convert flags into DD flags, ( for transparency use, etc )
if ( fBltFlags & VO_BLT_USECOLORKEY )
{
uiDDFlags |= DDBLT_KEYSRC;
}
// Setup dest rectangle
DestRect.top = (int)iDestY;
DestRect.left = (int)iDestX;
DestRect.bottom = (int)iDestY + ( SrcRect->iBottom - SrcRect->iTop );
DestRect.right = (int)iDestX + ( SrcRect->iRight - SrcRect->iLeft );
// Do Clipping of rectangles
if ( !ClipReleatedSrcAndDestRectangles( hDestVObject, hSrcVObject, &DestRect, SrcRect ) )
{
// Returns false because dest start is > dest size
return( TRUE );
}
DDBltSurface( (LPDIRECTDRAWSURFACE2)hDestVObject->pSurfaceData, &DestRect, (LPDIRECTDRAWSURFACE2)hSrcVObject->pSurfaceData,
SrcRect, uiDDFlags, NULL );
}
// Update backup surface with new data
if ( hDestVObject->fFlags & VOBJECT_VIDEO_MEM_USAGE && !hDestVObject->fFlags & VOBJECT_RESERVED_SURFACE )
{
UpdateBackupSurface( hDestVObject );
}
return( TRUE );
}
// Blt to backup buffer
BOOLEAN UpdateBackupSurface( HVOBJECT hVObject )
{
RECT aRect;
// Assertions
Assert( hVObject != NULL );
// Validations
CHECKF( hVObject->pSavedSurfaceData != NULL );
aRect.top = (int)0;
aRect.left = (int)0;
aRect.bottom = (int)hVObject->usHeight;
aRect.right = (int)hVObject->usWidth;
// Copy all contents into backup buffer
DDBltFastSurface( (LPDIRECTDRAWSURFACE2)hVObject->pSurfaceData, 0, 0, (LPDIRECTDRAWSURFACE2)hVObject->pSavedSurfaceData, &aRect, DDBLTFAST_NOCOLORKEY );
return( TRUE );
}
*/
BOOLEAN FillRect8BPP(UINT8 *pBuffer, UINT32 uiDestPitchBYTES, INT32 x1, INT32 y1, INT32 x2, INT32 y2, UINT8 color)
{
INT32 x1real, y1real, x2real, y2real;
UINT32 linelength, lines, lineskip;
UINT8 *startoffset;
// check parameters
Assert(pBuffer!=NULL);
Assert(uiDestPitchBYTES > 0);
Assert(x2 > x1);
Assert(y2 > y1);
// clip edges of rect if hanging off screen
x1real=__max(0, x1);
x2real=__min(639, x2);
y1real=__max(0, y1);
y2real=__min(479, y2);
startoffset=pBuffer+(y1real*uiDestPitchBYTES)+x1real;
lines=y2real-y1real+1;
linelength=x2real-x1real+1;
lineskip=uiDestPitchBYTES-linelength;
__asm {
mov edi, startoffset
mov al, color
mov ah, al
shl eax, 16
mov al, color
mov ah, al
mov edx, lines
mov ebx, linelength
// edi = destination pointer
// eax = dword of color value
// ebx = line length
// ecx = column counter
// edx = row counter
LineLoop:
mov ecx, ebx
clc
rcr ecx, 1
jnc FL2
mov [edi], al
inc edi
FL2:
clc
rcr ecx, 1
jnc FL3
mov [edi], ax
add edi, 2
FL3:
or ecx, ecx
jz FillLineEnd
rep stosd
FillLineEnd:
add edi, lineskip
dec edx
jnz LineLoop
}
return(TRUE);
}
BOOLEAN FillRect16BPP(UINT16 *pBuffer, UINT32 uiDestPitchBYTES, INT32 x1, INT32 y1, INT32 x2, INT32 y2, UINT16 color)
{
INT32 x1real, y1real, x2real, y2real;
UINT32 linelength, lines, lineskip;
UINT16 *startoffset;
// check parameters
Assert(pBuffer!=NULL);
Assert(uiDestPitchBYTES > 0);
Assert(x2 > x1);
Assert(y2 > y1);
// clip edges of rect if hanging off screen
x1real=__max(0, x1);
x2real=__min(639, x2);
y1real=__max(0, y1);
y2real=__min(479, y2);
startoffset=pBuffer+(y1real*uiDestPitchBYTES/2)+x1real;
lines=y2real-y1real+1;
linelength=x2real-x1real+1;
lineskip=uiDestPitchBYTES-(linelength*2);
__asm {
mov edi, startoffset
mov ax, color
shl eax, 16
mov ax, color
mov edx, lines
mov ebx, linelength
// edi = destination pointer
// eax = dword of color value
// ebx = line length
// ecx = column counter
// edx = row counter
LineLoop:
mov ecx, ebx
clc
rcr ecx, 1
jnc FL2
mov [edi], ax
add edi, 2
FL2:
or ecx, ecx
jz FillLineEnd
rep stosd
FillLineEnd:
add edi, lineskip
dec edx
jnz LineLoop
}
return(TRUE);
}
/**********************************************************************************************
BltIsClippedOrOffScreen
Determines whether a given blit will need clipping or not. Returns TRUE/FALSE.
**********************************************************************************************/
CHAR8 BltIsClippedOrOffScreen( HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion )
{
UINT32 usHeight, usWidth;
ETRLEObject *pTrav;
INT32 iTempX, iTempY;
INT32 ClipX1, ClipY1, ClipX2, ClipY2;
// Assertions
Assert( hSrcVObject != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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
gLeftSkip=__min(ClipX1 - min(ClipX1, iTempX), (INT32)usWidth);
gRightSkip=__min(max(ClipX2, (iTempX+(INT32)usWidth)) - ClipX2, (INT32)usWidth);
gTopSkip=__min(ClipY1 - __min(ClipY1, iTempY), (INT32)usHeight);
gBottomSkip=__min(__max(ClipY2, (iTempY+(INT32)usHeight)) - ClipY2, (INT32)usHeight);
gfUsePreCalcSkips = TRUE;
// check if whole thing is clipped
if((gLeftSkip >=(INT32)usWidth) || (gRightSkip >=(INT32)usWidth))
return(-1 );
// check if whole thing is clipped
if((gTopSkip >=(INT32)usHeight) || (gBottomSkip >=(INT32)usHeight))
return(-1 );
if ( gLeftSkip )
return( TRUE );
if ( gRightSkip )
return( TRUE );
if ( gTopSkip )
return( TRUE );
if ( gBottomSkip )
return( TRUE );
return(FALSE);
}
// Blt8BPPDataTo16BPPBufferOutline
// ATE New blitter for rendering a differrent color for value 254. Can be transparent if fDoOutline is FALSE
BOOLEAN Blt8BPPDataTo16BPPBufferOutline( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, INT16 s16BPPColor, BOOLEAN fDoOutline )
{
UINT32 uiOffset;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY;
UINT16 *p16BPPPalette;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
LineSkip=(uiDestPitchBYTES-(usWidth*2));
p16BPPPalette = hSrcVObject->pShadeCurrent;
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
xor ecx, ecx
BlitDispatch:
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
BlitNTL4:
xor eax, eax
mov al, [esi]
cmp al, 254
jne BlitNTL6
// DO OUTLINE
// ONLY IF WE WANT IT!
mov al, fDoOutline;
cmp al, 1
jne BlitNTL5
mov ax, s16BPPColor
mov [edi], ax
jmp BlitNTL5
BlitNTL6:
mov ax, [edx+eax*2]
mov [edi], ax
BlitNTL5:
inc esi
add edi, 2
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
// shl ecx, 1
add ecx, ecx
add edi, ecx
jmp BlitDispatch
BlitDoneLine:
dec usHeight
jz BlitDone
add edi, LineSkip
jmp BlitDispatch
BlitDone:
}
return(TRUE);
}
// ATE New blitter for rendering a differrent color for value 254. Can be transparent if fDoOutline is FALSE
BOOLEAN Blt8BPPDataTo16BPPBufferOutlineClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, INT16 s16BPPColor, BOOLEAN fDoOutline, SGPRect *clipregion )
{
UINT32 uiOffset;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight, LSCount;
INT32 ClipX1, ClipY1, ClipX2, ClipY2;
UINT16 *p16BPPPalette;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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(TRUE);
// check if whole thing is clipped
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
return(TRUE);
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
LineSkip=(uiDestPitchBYTES-(BlitLength*2));
p16BPPPalette = hSrcVObject->pShadeCurrent;
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
xor ecx, ecx
cmp TopSkip, 0 // check for nothing clipped on top
je LeftSkipSetup
TopSkipLoop: // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
jmp TopSkipLoop
TSEndLine:
dec TopSkip
jnz TopSkipLoop
LeftSkipSetup:
mov Unblitted, 0
mov eax, LeftSkip
mov LSCount, eax
or eax, eax
jz BlitLineSetup
LeftSkipLoop:
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, LSCount
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, LSCount // skip partial run, jump into normal loop for rest
sub ecx, LSCount
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2:
add esi, ecx // skip whole run, and start blit with new run
jmp BlitLineSetup
LSSkip1:
add esi, ecx // skip whole run, continue skipping
sub LSCount, ecx
jmp LeftSkipLoop
LSTrans:
and ecx, 07fH
cmp ecx, LSCount
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, LSCount // skip partial run, jump into normal loop for rest
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitTransparent
LSTrans1:
sub LSCount, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup: // Does any actual blitting (trans/non) for the line
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
BlitDispatch:
cmp LSCount, 0 // Check to see if we're done blitting
je RightSkipLoop
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
BlitNonTransLoop: // blit non-transparent pixels
cmp ecx, LSCount
jbe BNTrans1
sub ecx, LSCount
mov Unblitted, ecx
mov ecx, LSCount
BNTrans1:
sub LSCount, ecx
BlitNTL1:
xor eax, eax
mov al, [esi]
cmp al, 254
jne BlitNTL3
// DO OUTLINE
// ONLY IF WE WANT IT!
mov al, fDoOutline;
cmp al, 1
jne BlitNTL2
mov ax, s16BPPColor
mov [edi], ax
jmp BlitNTL2
BlitNTL3:
mov ax, [edx+eax*2]
mov [edi], ax
BlitNTL2:
inc esi
add edi, 2
dec cl
jnz BlitNTL1
//BlitLineEnd:
add esi, Unblitted
jmp BlitDispatch
BlitTransparent: // skip transparent pixels
and ecx, 07fH
cmp ecx, LSCount
jbe BTrans1
mov ecx, LSCount
BTrans1:
sub LSCount, ecx
// shl ecx, 1
add ecx, ecx
add edi, ecx
jmp BlitDispatch
RightSkipLoop: // skip along until we hit and end-of-line marker
RSLoop1:
mov al, [esi]
inc esi
or al, al
jnz RSLoop1
dec BlitHeight
jz BlitDone
add edi, LineSkip
jmp LeftSkipSetup
BlitDone:
}
return(TRUE);
}
BOOLEAN Blt8BPPDataTo16BPPBufferOutlineZClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, INT16 s16BPPColor, BOOLEAN fDoOutline, SGPRect *clipregion )
{
UINT32 uiOffset;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight, LSCount;
INT32 ClipX1, ClipY1, ClipX2, ClipY2;
UINT16 *p16BPPPalette;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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(TRUE);
// check if whole thing is clipped
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
return(TRUE);
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
LineSkip=(uiDestPitchBYTES-(BlitLength*2));
p16BPPPalette = hSrcVObject->pShadeCurrent;
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
cmp TopSkip, 0 // check for nothing clipped on top
je LeftSkipSetup
TopSkipLoop: // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
jmp TopSkipLoop
TSEndLine:
dec TopSkip
jnz TopSkipLoop
LeftSkipSetup:
mov Unblitted, 0
mov eax, LeftSkip
mov LSCount, eax
or eax, eax
jz BlitLineSetup
LeftSkipLoop:
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, LSCount
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, LSCount // skip partial run, jump into normal loop for rest
sub ecx, LSCount
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2:
add esi, ecx // skip whole run, and start blit with new run
jmp BlitLineSetup
LSSkip1:
add esi, ecx // skip whole run, continue skipping
sub LSCount, ecx
jmp LeftSkipLoop
LSTrans:
and ecx, 07fH
cmp ecx, LSCount
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, LSCount // skip partial run, jump into normal loop for rest
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitTransparent
LSTrans1:
sub LSCount, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup: // Does any actual blitting (trans/non) for the line
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
BlitDispatch:
cmp LSCount, 0 // Check to see if we're done blitting
je RightSkipLoop
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
BlitNonTransLoop: // blit non-transparent pixels
cmp ecx, LSCount
jbe BNTrans1
sub ecx, LSCount
mov Unblitted, ecx
mov ecx, LSCount
BNTrans1:
sub LSCount, ecx
BlitNTL1:
mov ax, usZValue
cmp ax, [ebx]
jb BlitNTL2
// CHECK FOR OUTLINE...
mov al, [esi]
cmp al, 254
jne BlitNTL3
// DO OUTLINE
// ONLY IF WE WANT IT!
mov al, fDoOutline;
cmp al, 1
jne BlitNTL2
mov ax, s16BPPColor
mov [edi], ax
jmp BlitNTL2
BlitNTL3:
//Write to z-buffer
mov [ebx], ax
xor eax, eax
mov al, [esi]
mov ax, [edx+eax*2]
mov [edi], ax
BlitNTL2:
inc esi
add edi, 2
inc ebx
inc ebx
dec cl
jnz BlitNTL1
//BlitLineEnd:
add esi, Unblitted
jmp BlitDispatch
BlitTransparent: // skip transparent pixels
and ecx, 07fH
cmp ecx, LSCount
jbe BTrans1
mov ecx, LSCount
BTrans1:
sub LSCount, ecx
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
RightSkipLoop: // skip along until we hit and end-of-line marker
RSLoop1:
mov al, [esi]
inc esi
or al, al
jnz RSLoop1
dec BlitHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
jmp LeftSkipSetup
BlitDone:
}
return(TRUE);
}
BOOLEAN Blt8BPPDataTo16BPPBufferOutlineZPixelateObscuredClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, INT16 s16BPPColor, BOOLEAN fDoOutline, SGPRect *clipregion )
{
UINT32 uiOffset;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight, LSCount;
INT32 ClipX1, ClipY1, ClipX2, ClipY2;
UINT16 *p16BPPPalette;
UINT32 uiLineFlag;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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(TRUE);
// check if whole thing is clipped
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
return(TRUE);
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
LineSkip=(uiDestPitchBYTES-(BlitLength*2));
p16BPPPalette = hSrcVObject->pShadeCurrent;
uiLineFlag=(iTempY&1);
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
cmp TopSkip, 0 // check for nothing clipped on top
je LeftSkipSetup
TopSkipLoop: // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
jmp TopSkipLoop
TSEndLine:
dec TopSkip
jnz TopSkipLoop
LeftSkipSetup:
mov Unblitted, 0
mov eax, LeftSkip
mov LSCount, eax
or eax, eax
jz BlitLineSetup
LeftSkipLoop:
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, LSCount
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, LSCount // skip partial run, jump into normal loop for rest
sub ecx, LSCount
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2:
add esi, ecx // skip whole run, and start blit with new run
jmp BlitLineSetup
LSSkip1:
add esi, ecx // skip whole run, continue skipping
sub LSCount, ecx
jmp LeftSkipLoop
LSTrans:
and ecx, 07fH
cmp ecx, LSCount
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, LSCount // skip partial run, jump into normal loop for rest
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitTransparent
LSTrans1:
sub LSCount, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup: // Does any actual blitting (trans/non) for the line
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
BlitDispatch:
cmp LSCount, 0 // Check to see if we're done blitting
je RightSkipLoop
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
BlitNonTransLoop: // blit non-transparent pixels
cmp ecx, LSCount
jbe BNTrans1
sub ecx, LSCount
mov Unblitted, ecx
mov ecx, LSCount
BNTrans1:
sub LSCount, ecx
BlitNTL1:
mov ax, usZValue
cmp ax, [ebx]
jb BlitNTL8
// Write it now!
jmp BlitNTL7
BlitNTL8:
test uiLineFlag, 1
jz BlitNTL6
test edi, 2
jz BlitNTL2
jmp BlitNTL9
BlitNTL6:
test edi, 2
jnz BlitNTL2
BlitNTL7:
mov [ebx], ax
BlitNTL9:
// CHECK FOR OUTLINE...
mov al, [esi]
cmp al, 254
jne BlitNTL3
// DO OUTLINE
// ONLY IF WE WANT IT!
mov al, fDoOutline;
cmp al, 1
jne BlitNTL2
mov ax, s16BPPColor
mov [edi], ax
jmp BlitNTL2
BlitNTL3:
//Write to z-buffer
mov [ebx], ax
xor eax, eax
mov al, [esi]
mov ax, [edx+eax*2]
mov [edi], ax
BlitNTL2:
inc esi
add edi, 2
inc ebx
inc ebx
dec cl
jnz BlitNTL1
//BlitLineEnd:
add esi, Unblitted
jmp BlitDispatch
BlitTransparent: // skip transparent pixels
and ecx, 07fH
cmp ecx, LSCount
jbe BTrans1
mov ecx, LSCount
BTrans1:
sub LSCount, ecx
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
RightSkipLoop: // skip along until we hit and end-of-line marker
RSLoop1:
mov al, [esi]
inc esi
or al, al
jnz RSLoop1
dec BlitHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
xor uiLineFlag, 1
jmp LeftSkipSetup
BlitDone:
}
return(TRUE);
}
BOOLEAN Blt8BPPDataTo16BPPBufferOutlineShadow( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex )
{
UINT32 uiOffset;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY;
UINT16 *p16BPPPalette;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
LineSkip=(uiDestPitchBYTES-(usWidth*2));
p16BPPPalette = hSrcVObject->pShadeCurrent;
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
xor ecx, ecx
BlitDispatch:
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
BlitNTL4:
xor eax, eax
mov al, [esi]
cmp al, 254
je BlitNTL5
mov ax, [edi]
mov ax, ShadeTable[eax*2]
mov [edi], ax
BlitNTL5:
inc esi
add edi, 2
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
// shl ecx, 1
add ecx, ecx
add edi, ecx
jmp BlitDispatch
BlitDoneLine:
dec usHeight
jz BlitDone
add edi, LineSkip
jmp BlitDispatch
BlitDone:
}
return(TRUE);
}
BOOLEAN Blt8BPPDataTo16BPPBufferOutlineShadowClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion )
{
UINT16 *p16BPPPalette;
UINT32 uiOffset;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight;
INT32 ClipX1, ClipY1, ClipX2, ClipY2;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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);
// whole thing is clipped
if((LeftSkip >=(INT32)usWidth) || (RightSkip >=(INT32)usWidth))
return(TRUE);
// whole thing is clipped
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
return(TRUE);
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
p16BPPPalette = hSrcVObject->pShadeCurrent;
LineSkip=(uiDestPitchBYTES-(BlitLength*2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, OFFSET ShadeTable
xor eax, eax
mov ebx, TopSkip
xor ecx, ecx
or ebx, ebx // check for nothing clipped on top
jz LeftSkipSetup
TopSkipLoop: // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
or cl, cl
js TopSkipLoop
jz TSEndLine
// Check for outline as well
mov cl, [esi]
cmp cl, 254
je TopSkipLoop
//
add esi, ecx
jmp TopSkipLoop
TSEndLine:
dec ebx
jnz TopSkipLoop
LeftSkipSetup:
mov Unblitted, 0
mov ebx, LeftSkip // check for nothing clipped on the left
or ebx, ebx
jz BlitLineSetup
LeftSkipLoop:
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, ebx
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, ebx // skip partial run, jump into normal loop for rest
sub ecx, ebx
mov ebx, BlitLength
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2:
add esi, ecx // skip whole run, and start blit with new run
jmp BlitLineSetup
LSSkip1:
add esi, ecx // skip whole run, continue skipping
sub ebx, ecx
jmp LeftSkipLoop
LSTrans:
and ecx, 07fH
cmp ecx, ebx
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, ebx // skip partial run, jump into normal loop for rest
mov ebx, BlitLength
jmp BlitTransparent
LSTrans1:
sub ebx, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup: // Does any actual blitting (trans/non) for the line
mov ebx, BlitLength
mov Unblitted, 0
BlitDispatch:
or ebx, ebx // Check to see if we're done blitting
jz RightSkipLoop
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
BlitNonTransLoop:
cmp ecx, ebx
jbe BNTrans1
sub ecx, ebx
mov Unblitted, ecx
mov ecx, ebx
BNTrans1:
sub ebx, ecx
clc
rcr cl, 1
jnc BlitNTL2
mov ax, [edi]
mov ax, [edx+eax*2]
mov [edi], ax
inc esi
add edi, 2
BlitNTL2:
clc
rcr cl, 1
jnc BlitNTL3
mov ax, [edi]
mov ax, [edx+eax*2]
mov [edi], ax
mov ax, [edi+2]
mov ax, [edx+eax*2]
mov [edi+2], ax
add esi, 2
add edi, 4
BlitNTL3:
or cl, cl
jz BlitLineEnd
BlitNTL4:
mov ax, [edi]
mov ax, [edx+eax*2]
mov [edi], ax
mov ax, [edi+2]
mov ax, [edx+eax*2]
mov [edi+2], ax
mov ax, [edi+4]
mov ax, [edx+eax*2]
mov [edi+4], ax
mov ax, [edi+6]
mov ax, [edx+eax*2]
mov [edi+6], ax
add esi, 4
add edi, 8
dec cl
jnz BlitNTL4
BlitLineEnd:
add esi, Unblitted
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
cmp ecx, ebx
jbe BTrans1
mov ecx, ebx
BTrans1:
sub ebx, ecx
// shl ecx, 1
add ecx, ecx
add edi, ecx
jmp BlitDispatch
RightSkipLoop:
RSLoop1:
mov al, [esi]
inc esi
or al, al
jnz RSLoop1
dec BlitHeight
jz BlitDone
add edi, LineSkip
jmp LeftSkipSetup
BlitDone:
}
return(TRUE);
}
BOOLEAN Blt8BPPDataTo16BPPBufferOutlineZ( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, INT16 s16BPPColor, BOOLEAN fDoOutline )
{
UINT16 *p16BPPPalette;
UINT32 uiOffset;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
p16BPPPalette = hSrcVObject->pShadeCurrent;
LineSkip=(uiDestPitchBYTES-(usWidth*2));
// Compressed sequence consist of multiple subsequences of transparent and non - transparent bytes(SirTech have transparent color as zero).
// Every subsequence on transparent bytes is replaced by one byte with highest bit set to 1. Lower 7 bits hold number of transparent bytes.
// If sequence of transparent bytes is longer than 127, then new byte for transparent bytes encoding used and so on.
// One service byte used before subsequence of non - transparent bytes. Its highest bit is set to 0.
// Lower 7 bits hold number of non - transparent byte in subsequence.
// If non - transparent bytes subsequence exceeds 127, new service byte is used and so on.
// Every row has zero byte on its end.
__asm {
mov esi, SrcPtr // Load source pixel data to ESI, starting at the place SrcPtr is pointing to.
mov edi, DestPtr // Load destination buffer to EDI, starting at the place DestPtr is pointing to.
mov edx, p16BPPPalette // Load 16 bit palette to EDX
xor eax, eax // Zero EAX
mov ebx, ZPtr // Load zbuffer to EBX
xor ecx, ecx
BlitDispatch:
mov cl, [esi] // Read a byte from source and load it to CL. CL is the least signifigant byte of CX, which is the least significant word of ECX
inc esi // Go forward one byte in source data
or cl, cl
js BlitTransparent // if highest bit is 1 -> we have transparent pixels
jz BlitDoneLine // Zero means end of a row
//BlitNonTransLoop:
xor eax, eax
BlitNTL4:
// Do not draw pixel if its z value is less than Z-buffer
mov ax, usZValue // Move Z value we want to compare to, to EAX
cmp ax, [ebx] // Compare against the Z-buffer
jb BlitNTL5
// CHECK FOR OUTLINE, BLIT DIFFERENTLY IF WE WANT IT TO!
mov al, [esi] // Load byte from source into AL
cmp al, 254
jne BlitNTL6
// DO OUTLINE
// ONLY IF WE WANT IT!
mov al, fDoOutline; // Load BOOLEAN fDoOutline to AL
cmp al, 1 // Check if it's TRUE
jne BlitNTL5 // Jump if FALSE
mov ax, s16BPPColor // Load s16BPPColor value to AX
mov [edi], ax // Load color to destination
jmp BlitNTL5
BlitNTL6:
//Donot write to z-buffer
mov [ebx], ax // Original comment says to not write to zBuffer. This writes gibberish there so is most likely wrong.
xor ah, ah
mov al, [esi] // Load byte from source into AL
mov ax, [edx+eax*2] // Load value from address EDX+EAX*2. EDX holds the 16 bit palette.
mov [edi], ax // Load AX value into destination buffer, ie. color the destination pixel
BlitNTL5:
inc esi // Move a byte forward in source data
inc edi // Move a byte forward in destination data. This is duplicated below so we move two bytes forward in destination data due to it being 16 bit.
inc ebx // Same thing with Z-buffer.
inc edi
inc ebx
dec cl
jnz BlitNTL4
jmp BlitDispatch // Jump to the next blit operation
BlitTransparent:
and ecx, 07fH
// shl ecx, 1
add ecx, ecx
add edi, ecx // Add value in ECX to destination buffer
add ebx, ecx // Add value in ECX to Z-buffer
jmp BlitDispatch
BlitDoneLine:
dec usHeight // Decrement Height by 1. We're going through the blitting source data from the top, one row at a time
jz BlitDone // If Height is 0, we're done blitting.
add edi, LineSkip // Skip the rest of the current destination line, so we start at the correct spot for the next line blit.
add ebx, LineSkip // Same for Z-buffer.
jmp BlitDispatch // Jump to the next blit operation
BlitDone:
}
return(TRUE);
}
BOOLEAN Blt8BPPDataTo16BPPBufferOutlineZPixelateObscured( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, INT16 s16BPPColor, BOOLEAN fDoOutline )
{
UINT16 *p16BPPPalette;
UINT32 uiOffset;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY;
UINT32 uiLineFlag;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
p16BPPPalette = hSrcVObject->pShadeCurrent;
LineSkip=(uiDestPitchBYTES-(usWidth*2));
uiLineFlag=(iTempY&1);
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
BlitDispatch:
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
xor eax, eax
BlitNTL4:
mov ax, usZValue
cmp ax, [ebx]
jbe BlitNTL8
// Write it now!
jmp BlitNTL7
BlitNTL8:
test uiLineFlag, 1
jz BlitNTL6
test edi, 2
jz BlitNTL5
jmp BlitNTL9
BlitNTL6:
test edi, 2
jnz BlitNTL5
BlitNTL7:
mov [ebx], ax
BlitNTL9:
// CHECK FOR OUTLINE, BLIT DIFFERENTLY IF WE WANT IT TO!
mov al, [esi]
cmp al, 254
jne BlitNTL12
// DO OUTLINE
// ONLY IF WE WANT IT!
mov al, fDoOutline;
cmp al, 1
jne BlitNTL5
mov ax, s16BPPColor
mov [edi], ax
jmp BlitNTL5
BlitNTL12:
xor ah, ah
mov al, [esi]
mov ax, [edx+eax*2]
mov [edi], ax
BlitNTL5:
inc esi
inc edi
inc ebx
inc edi
inc ebx
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
BlitDoneLine:
dec usHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
xor uiLineFlag, 1
jmp BlitDispatch
BlitDone:
}
return(TRUE);
}
// This is the same as above, but DONOT WRITE to Z!
BOOLEAN Blt8BPPDataTo16BPPBufferOutlineZNB( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, INT16 s16BPPColor, BOOLEAN fDoOutline )
{
UINT16 *p16BPPPalette;
UINT32 uiOffset;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
p16BPPPalette = hSrcVObject->pShadeCurrent;
LineSkip=(uiDestPitchBYTES-(usWidth*2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
BlitDispatch:
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
xor eax, eax
BlitNTL4:
mov ax, usZValue
cmp ax, [ebx]
jb BlitNTL5
// CHECK FOR OUTLINE, BLIT DIFFERENTLY IF WE WANT IT TO!
mov al, [esi]
cmp al, 254
jne BlitNTL6
// DO OUTLINE
// ONLY IF WE WANT IT!
mov al, fDoOutline;
cmp al, 1
jne BlitNTL5
mov ax, s16BPPColor
mov [edi], ax
jmp BlitNTL5
BlitNTL6:
//Donot write to z-buffer
//mov [ebx], ax
xor ah, ah
mov al, [esi]
mov ax, [edx+eax*2]
mov [edi], ax
BlitNTL5:
inc esi
inc edi
inc ebx
inc edi
inc ebx
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
BlitDoneLine:
dec usHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
jmp BlitDispatch
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferIntensityZ
Creates a shadow using a brush, but modifies the destination buffer only if the current
Z level is equal to higher than what's in the Z buffer at that pixel location. It
updates the Z buffer with the new Z level.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferIntensityZ( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex )
{
UINT16 *p16BPPPalette;
UINT32 uiOffset;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
p16BPPPalette = hSrcVObject->pShadeCurrent;
LineSkip=(uiDestPitchBYTES-(usWidth*2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, OFFSET IntensityTable
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
BlitDispatch:
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
BlitNTL4:
mov ax, [ebx]
cmp ax, usZValue
jae BlitNTL5
xor eax, eax
mov ax, [edi]
mov ax, [edx+eax*2]
mov [edi], ax
mov ax, usZValue
mov [ebx], ax
BlitNTL5:
inc esi
add edi, 2
add ebx, 2
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
BlitDoneLine:
dec usHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
jmp BlitDispatch
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferIntensityZClip
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
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.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferIntensityZClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion)
{
UINT16 *p16BPPPalette;
UINT32 uiOffset;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, 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
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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(TRUE);
// check if whole thing is clipped
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
return(TRUE);
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
p16BPPPalette = hSrcVObject->pShadeCurrent;
LineSkip=(uiDestPitchBYTES-(BlitLength*2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, OFFSET IntensityTable
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
cmp TopSkip, 0 // check for nothing clipped on top
je LeftSkipSetup
TopSkipLoop: // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
jmp TopSkipLoop
TSEndLine:
dec TopSkip
jnz TopSkipLoop
LeftSkipSetup:
mov Unblitted, 0
mov eax, LeftSkip
mov LSCount, eax
or eax, eax
jz BlitLineSetup
LeftSkipLoop:
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, LSCount
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, LSCount // skip partial run, jump into normal loop for rest
sub ecx, LSCount
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2:
add esi, ecx // skip whole run, and start blit with new run
jmp BlitLineSetup
LSSkip1:
add esi, ecx // skip whole run, continue skipping
sub LSCount, ecx
jmp LeftSkipLoop
LSTrans:
and ecx, 07fH
cmp ecx, LSCount
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, LSCount // skip partial run, jump into normal loop for rest
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitTransparent
LSTrans1:
sub LSCount, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup: // Does any actual blitting (trans/non) for the line
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
BlitDispatch:
cmp LSCount, 0 // Check to see if we're done blitting
je RightSkipLoop
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
BlitNonTransLoop: // blit non-transparent pixels
cmp ecx, LSCount
jbe BNTrans1
sub ecx, LSCount
mov Unblitted, ecx
mov ecx, LSCount
BNTrans1:
sub LSCount, ecx
BlitNTL1:
mov ax, [ebx]
cmp ax, usZValue
jae BlitNTL2
mov ax, usZValue
mov [ebx], ax
xor eax, eax
mov ax, [edi]
mov ax, [edx+eax*2]
mov [edi], ax
BlitNTL2:
inc esi
add edi, 2
add ebx, 2
dec cl
jnz BlitNTL1
//BlitLineEnd:
add esi, Unblitted
jmp BlitDispatch
BlitTransparent: // skip transparent pixels
and ecx, 07fH
cmp ecx, LSCount
jbe BTrans1
mov ecx, LSCount
BTrans1:
sub LSCount, ecx
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
RightSkipLoop: // skip along until we hit and end-of-line marker
RSLoop1:
mov al, [esi]
inc esi
or al, al
jnz RSLoop1
dec BlitHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
jmp LeftSkipSetup
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferIntensityZNB
Creates a shadow using a brush, but modifies the destination buffer only if the current
Z level is equal to higher than what's in the Z buffer at that pixel location. It does
NOT update the Z buffer with the new Z value.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferIntensityZNB( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex )
{
UINT16 *p16BPPPalette;
UINT32 uiOffset;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
p16BPPPalette = hSrcVObject->pShadeCurrent;
LineSkip=(uiDestPitchBYTES-(usWidth*2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, OFFSET IntensityTable
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
BlitDispatch:
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
BlitNTL4:
mov ax, [ebx]
cmp ax, usZValue
jae BlitNTL5
xor eax, eax
mov ax, [edi]
mov ax, [edx+eax*2]
mov [edi], ax
BlitNTL5:
inc esi
add edi, 2
add ebx, 2
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
BlitDoneLine:
dec usHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
jmp BlitDispatch
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferIntensityZNBClip
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 value is
not updated, for any non-transparent pixels. The Z-buffer is 16 bit, and must be the
same dimensions (including Pitch) as the destination.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferIntensityZNBClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion)
{
UINT16 *p16BPPPalette;
UINT32 uiOffset;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, 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
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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(TRUE);
// check if whole thing is clipped
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
return(TRUE);
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
p16BPPPalette = hSrcVObject->pShadeCurrent;
LineSkip=(uiDestPitchBYTES-(BlitLength*2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, OFFSET IntensityTable
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
cmp TopSkip, 0 // check for nothing clipped on top
je LeftSkipSetup
TopSkipLoop: // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
jmp TopSkipLoop
TSEndLine:
dec TopSkip
jnz TopSkipLoop
LeftSkipSetup:
mov Unblitted, 0
mov eax, LeftSkip
mov LSCount, eax
or eax, eax
jz BlitLineSetup
LeftSkipLoop:
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, LSCount
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, LSCount // skip partial run, jump into normal loop for rest
sub ecx, LSCount
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2:
add esi, ecx // skip whole run, and start blit with new run
jmp BlitLineSetup
LSSkip1:
add esi, ecx // skip whole run, continue skipping
sub LSCount, ecx
jmp LeftSkipLoop
LSTrans:
and ecx, 07fH
cmp ecx, LSCount
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, LSCount // skip partial run, jump into normal loop for rest
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitTransparent
LSTrans1:
sub LSCount, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup: // Does any actual blitting (trans/non) for the line
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
BlitDispatch:
cmp LSCount, 0 // Check to see if we're done blitting
je RightSkipLoop
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
BlitNonTransLoop: // blit non-transparent pixels
cmp ecx, LSCount
jbe BNTrans1
sub ecx, LSCount
mov Unblitted, ecx
mov ecx, LSCount
BNTrans1:
sub LSCount, ecx
BlitNTL1:
mov ax, [ebx]
cmp ax, usZValue
jae BlitNTL2
xor eax, eax
mov ax, [edi]
mov ax, [edx+eax*2]
mov [edi], ax
BlitNTL2:
inc esi
add edi, 2
add ebx, 2
dec cl
jnz BlitNTL1
//BlitLineEnd:
add esi, Unblitted
jmp BlitDispatch
BlitTransparent: // skip transparent pixels
and ecx, 07fH
cmp ecx, LSCount
jbe BTrans1
mov ecx, LSCount
BTrans1:
sub LSCount, ecx
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
RightSkipLoop: // skip along until we hit and end-of-line marker
RSLoop1:
mov al, [esi]
inc esi
or al, al
jnz RSLoop1
dec BlitHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
jmp LeftSkipSetup
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferIntensityClip
Modifies the destination buffer. Darkens the destination pixels by 25%, using the source
image as a mask. Any Non-zero index pixels are used to darken destination pixels. Blitter
clips brush if it doesn't fit on the viewport.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferIntensityClip( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion)
{
UINT16 *p16BPPPalette;
UINT32 uiOffset;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, LeftSkip, RightSkip, TopSkip, BottomSkip, BlitLength, BlitHeight;
INT32 ClipX1, ClipY1, ClipX2, ClipY2;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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);
// whole thing is clipped
if((LeftSkip >=(INT32)usWidth) || (RightSkip >=(INT32)usWidth))
return(TRUE);
// whole thing is clipped
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
return(TRUE);
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
p16BPPPalette = hSrcVObject->pShadeCurrent;
LineSkip=(uiDestPitchBYTES-(BlitLength*2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, OFFSET IntensityTable
xor eax, eax
mov ebx, TopSkip
xor ecx, ecx
or ebx, ebx // check for nothing clipped on top
jz LeftSkipSetup
TopSkipLoop: // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
jmp TopSkipLoop
TSEndLine:
dec ebx
jnz TopSkipLoop
LeftSkipSetup:
mov Unblitted, 0
mov ebx, LeftSkip // check for nothing clipped on the left
or ebx, ebx
jz BlitLineSetup
LeftSkipLoop:
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, ebx
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, ebx // skip partial run, jump into normal loop for rest
sub ecx, ebx
mov ebx, BlitLength
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2:
add esi, ecx // skip whole run, and start blit with new run
jmp BlitLineSetup
LSSkip1:
add esi, ecx // skip whole run, continue skipping
sub ebx, ecx
jmp LeftSkipLoop
LSTrans:
and ecx, 07fH
cmp ecx, ebx
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, ebx // skip partial run, jump into normal loop for rest
mov ebx, BlitLength
jmp BlitTransparent
LSTrans1:
sub ebx, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup: // Does any actual blitting (trans/non) for the line
mov ebx, BlitLength
mov Unblitted, 0
BlitDispatch:
or ebx, ebx // Check to see if we're done blitting
jz RightSkipLoop
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
BlitNonTransLoop:
cmp ecx, ebx
jbe BNTrans1
sub ecx, ebx
mov Unblitted, ecx
mov ecx, ebx
BNTrans1:
sub ebx, ecx
clc
rcr cl, 1
jnc BlitNTL2
mov ax, [edi]
mov ax, [edx+eax*2]
mov [edi], ax
inc esi
add edi, 2
BlitNTL2:
clc
rcr cl, 1
jnc BlitNTL3
mov ax, [edi]
mov ax, [edx+eax*2]
mov [edi], ax
mov ax, [edi+2]
mov ax, [edx+eax*2]
mov [edi+2], ax
add esi, 2
add edi, 4
BlitNTL3:
or cl, cl
jz BlitLineEnd
BlitNTL4:
mov ax, [edi]
mov ax, [edx+eax*2]
mov [edi], ax
mov ax, [edi+2]
mov ax, [edx+eax*2]
mov [edi+2], ax
mov ax, [edi+4]
mov ax, [edx+eax*2]
mov [edi+4], ax
mov ax, [edi+6]
mov ax, [edx+eax*2]
mov [edi+6], ax
add esi, 4
add edi, 8
dec cl
jnz BlitNTL4
BlitLineEnd:
add esi, Unblitted
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
cmp ecx, ebx
jbe BTrans1
mov ecx, ebx
BTrans1:
sub ebx, ecx
// shl ecx, 1
add ecx, ecx
add edi, ecx
jmp BlitDispatch
RightSkipLoop:
RSLoop1:
mov al, [esi]
inc esi
or al, al
jnz RSLoop1
dec BlitHeight
jz BlitDone
add edi, LineSkip
jmp LeftSkipSetup
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
Blt8BPPDataTo16BPPBufferIntensity
Modifies the destination buffer. Darkens the destination pixels by 25%, using the source
image as a mask. Any Non-zero index pixels are used to darken destination pixels.
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferIntensity( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex)
{
UINT16 *p16BPPPalette;
UINT32 uiOffset;
UINT32 usHeight, usWidth;
UINT8 *SrcPtr, *DestPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY;
// Assertions
Assert( hSrcVObject != NULL );
Assert( pBuffer != NULL );
// Get Offsets from Index into structure
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
iTempY = iY + pTrav->sOffsetY;
// Validations
CHECKF( iTempX >= 0 );
CHECKF( iTempY >= 0 );
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*iTempY) + (iTempX*2);
p16BPPPalette = hSrcVObject->pShadeCurrent;
LineSkip=(uiDestPitchBYTES-(usWidth*2));
__asm {
mov esi, SrcPtr
mov edi, DestPtr
xor eax, eax
mov ebx, usHeight
xor ecx, ecx
mov edx, OFFSET IntensityTable
BlitDispatch:
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
jz BlitDoneLine
//BlitNonTransLoop:
xor eax, eax
add esi, ecx
clc
rcr cl, 1
jnc BlitNTL2
mov ax, [edi]
mov ax, [edx+eax*2]
mov [edi], ax
add edi, 2
BlitNTL2:
clc
rcr cl, 1
jnc BlitNTL3
mov ax, [edi]
mov ax, [edx+eax*2]
mov [edi], ax
mov ax, [edi+2]
mov ax, [edx+eax*2]
mov [edi+2], ax
add edi, 4
BlitNTL3:
or cl, cl
jz BlitDispatch
BlitNTL4:
mov ax, [edi]
mov ax, [edx+eax*2]
mov [edi], ax
mov ax, [edi+2]
mov ax, [edx+eax*2]
mov [edi+2], ax
mov ax, [edi+4]
mov ax, [edx+eax*2]
mov [edi+4], ax
mov ax, [edi+6]
mov ax, [edx+eax*2]
mov [edi+6], ax
add edi, 8
dec cl
jnz BlitNTL4
jmp BlitDispatch
BlitTransparent:
and ecx, 07fH
// shl ecx, 1
add ecx, ecx
add edi, ecx
jmp BlitDispatch
BlitDoneLine:
dec ebx
jz BlitDone
add edi, LineSkip
jmp BlitDispatch
BlitDone:
}
return(TRUE);
}
/**********************************************************************************************
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").
**********************************************************************************************/
BOOLEAN Blt8BPPDataTo16BPPBufferTransZClipPixelateObscured( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, UINT16 *pZBuffer, UINT16 usZValue, HVOBJECT hSrcVObject, INT32 iX, INT32 iY, UINT16 usIndex, SGPRect *clipregion)
{
UINT16 *p16BPPPalette;
UINT32 uiOffset, uiLineFlag;
UINT32 usHeight, usWidth, Unblitted;
UINT8 *SrcPtr, *DestPtr, *ZPtr;
UINT32 LineSkip;
ETRLEObject *pTrav;
INT32 iTempX, iTempY, 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
pTrav = &(hSrcVObject->pETRLEObject[ usIndex ] );
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
uiOffset = pTrav->uiDataOffset;
// Add to start position of dest buffer
iTempX = iX + pTrav->sOffsetX;
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(TRUE);
// check if whole thing is clipped
if((TopSkip >=(INT32)usHeight) || (BottomSkip >=(INT32)usHeight))
return(TRUE);
SrcPtr= (UINT8 *)hSrcVObject->pPixData + uiOffset;
DestPtr = (UINT8 *)pBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
ZPtr = (UINT8 *)pZBuffer + (uiDestPitchBYTES*(iTempY+TopSkip)) + ((iTempX+LeftSkip)*2);
p16BPPPalette = hSrcVObject->pShadeCurrent;
LineSkip=(uiDestPitchBYTES-(BlitLength*2));
uiLineFlag=(iTempY&1);
__asm {
mov esi, SrcPtr
mov edi, DestPtr
mov edx, p16BPPPalette
xor eax, eax
mov ebx, ZPtr
xor ecx, ecx
cmp TopSkip, 0 // check for nothing clipped on top
je LeftSkipSetup
TopSkipLoop: // Skips the number of lines clipped at the top
mov cl, [esi]
inc esi
or cl, cl
js TopSkipLoop
jz TSEndLine
add esi, ecx
jmp TopSkipLoop
TSEndLine:
xor uiLineFlag, 1
dec TopSkip
jnz TopSkipLoop
LeftSkipSetup:
mov Unblitted, 0
mov eax, LeftSkip
mov LSCount, eax
or eax, eax
jz BlitLineSetup
LeftSkipLoop:
mov cl, [esi]
inc esi
or cl, cl
js LSTrans
cmp ecx, LSCount
je LSSkip2 // if equal, skip whole, and start blit with new run
jb LSSkip1 // if less, skip whole thing
add esi, LSCount // skip partial run, jump into normal loop for rest
sub ecx, LSCount
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitNonTransLoop
LSSkip2:
add esi, ecx // skip whole run, and start blit with new run
jmp BlitLineSetup
LSSkip1:
add esi, ecx // skip whole run, continue skipping
sub LSCount, ecx
jmp LeftSkipLoop
LSTrans:
and ecx, 07fH
cmp ecx, LSCount
je BlitLineSetup // if equal, skip whole, and start blit with new run
jb LSTrans1 // if less, skip whole thing
sub ecx, LSCount // skip partial run, jump into normal loop for rest
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
jmp BlitTransparent
LSTrans1:
sub LSCount, ecx // skip whole run, continue skipping
jmp LeftSkipLoop
BlitLineSetup: // Does any actual blitting (trans/non) for the line
mov eax, BlitLength
mov LSCount, eax
mov Unblitted, 0
BlitDispatch:
cmp LSCount, 0 // Check to see if we're done blitting
je RightSkipLoop
mov cl, [esi]
inc esi
or cl, cl
js BlitTransparent
BlitNonTransLoop: // blit non-transparent pixels
cmp ecx, LSCount
jbe BNTrans1
sub ecx, LSCount
mov Unblitted, ecx
mov ecx, LSCount
BNTrans1:
sub LSCount, ecx
BlitNTL1:
// OK, DO CHECK FOR Z FIRST!
mov ax, [ebx]
cmp ax, usZValue
jae BlitNTL8
// ONLY WRITE DATA IF WE REALLY SHOULD
mov ax, usZValue
mov [ebx], ax
jmp BlitNTL7
BlitNTL8:
test uiLineFlag, 1
jz BlitNTL6
test edi, 2
jz BlitNTL2
jmp BlitNTL7
BlitNTL6:
test edi, 2
jnz BlitNTL2
BlitNTL7:
xor eax, eax
mov al, [esi]
mov ax, [edx+eax*2]
mov [edi], ax
BlitNTL2:
inc esi
add edi, 2
add ebx, 2
dec cl
jnz BlitNTL1
//BlitLineEnd:
add esi, Unblitted
jmp BlitDispatch
BlitTransparent: // skip transparent pixels
and ecx, 07fH
cmp ecx, LSCount
jbe BTrans1
mov ecx, LSCount
BTrans1:
sub LSCount, ecx
// shl ecx, 1
add ecx, ecx
add edi, ecx
add ebx, ecx
jmp BlitDispatch
RightSkipLoop: // skip along until we hit and end-of-line marker
RSLoop1:
mov al, [esi]
inc esi
or al, al
jnz RSLoop1
xor uiLineFlag, 1
dec BlitHeight
jz BlitDone
add edi, LineSkip
add ebx, LineSkip
jmp LeftSkipSetup
BlitDone:
}
return(TRUE);
}