mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
Obsolete and doesn't work * Remove gbPixelDepth * Remove 8-bit to 8-bit blitters * FileNameForBPP now only calls strcopy
14886 lines
333 KiB
C++
14886 lines
333 KiB
C++
#include "DirectDraw Calls.h"
|
|
#include <stdio.h>
|
|
#include "debug.h"
|
|
#include "video.h" // JA2
|
|
#include "himage.h"
|
|
#include "vobject.h"
|
|
#include "wcheck.h"
|
|
#include "vobject.h"
|
|
#include "vobject_blitters.h"
|
|
#include "shading.h"
|
|
#include "sgp_logger.h"
|
|
|
|
#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)
|
|
{
|
|
// 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);
|
|
}
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**********************************************************************************************
|
|
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);
|
|
}
|
|
|
|
|
|
|
|
|
|
//*****************************************************************************
|
|
//** 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);
|
|
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);
|
|
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);
|
|
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);
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**********************************************************************************************
|
|
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 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);
|
|
|
|
}
|