mirror of
https://github.com/OpenTrespasser/JurassicParkTrespasser.git
synced 2024-12-25 10:01:56 +00:00
1204 lines
34 KiB
Plaintext
1204 lines
34 KiB
Plaintext
|
/***********************************************************************************************
|
|||
|
*
|
|||
|
* Copyright <20> DreamWorks Interactive, 1997.
|
|||
|
*
|
|||
|
* Contents:
|
|||
|
* Specialized (non-template) versions of the DrawSubtriangle (terrain texture) function.
|
|||
|
* Optimized for the Pentium Processor
|
|||
|
*
|
|||
|
***********************************************************************************************
|
|||
|
*
|
|||
|
* $Log:: /JP2_PC/Source/Lib/Renderer/Primitives/P5/DrawSubTriangleTerrainEx.cpp $
|
|||
|
*
|
|||
|
* 15 98.08.13 4:26p Mmouni
|
|||
|
* Changes for VC++ 5.0sp3 compatibility.
|
|||
|
*
|
|||
|
* 14 98.01.22 3:15p Mmouni
|
|||
|
* Added support for 16-bit deep bump-maps.
|
|||
|
*
|
|||
|
* 13 97.11.25 7:03p Mmouni
|
|||
|
* Fixed problem with U carry being lost in inner loop of shadow primitives.
|
|||
|
*
|
|||
|
* 12 97.11.04 10:17p Mmouni
|
|||
|
* Fixed an error in the shadow from bump-map primitive.
|
|||
|
*
|
|||
|
* 11 97.10.22 7:11p Mmouni
|
|||
|
* Moved code that makes copies of edge values into assembly.
|
|||
|
*
|
|||
|
* 10 10/10/97 1:47p Mmouni
|
|||
|
* All inner loops are now left to right only, and optimized some.
|
|||
|
*
|
|||
|
* 9 10/01/97 7:17p Mmouni
|
|||
|
* Removed some more MOVZX instructions from the inner loops.
|
|||
|
*
|
|||
|
* 8 9/30/97 9:32p Mmouni
|
|||
|
* Got rid of MOVZX in inner loop.
|
|||
|
*
|
|||
|
* 7 9/15/97 2:10p Mmouni
|
|||
|
* Optimized inner loops (not final yet).
|
|||
|
*
|
|||
|
* 6 9/01/97 8:03p Rwyatt
|
|||
|
*
|
|||
|
* 5 97/08/19 16:15 Speter
|
|||
|
* (PKeet) Updated P5 and K6 shadow primitives.
|
|||
|
*
|
|||
|
* 4 8/17/97 12:21a Rwyatt
|
|||
|
* Moved terrain texture sadow primitives from DrawSubTriangleFlat
|
|||
|
*
|
|||
|
* 3 8/15/97 2:01a Rwyatt
|
|||
|
* Fixed 2 bugs related to 8 bit source textures
|
|||
|
*
|
|||
|
* 2 8/15/97 12:50a Rwyatt
|
|||
|
* Initial implementation of terrain textures, this code does not do multiple writes so may not
|
|||
|
* be efficient on a Pentium or K6
|
|||
|
*
|
|||
|
* 1 8/14/97 6:16p Rwyatt
|
|||
|
* Terrain texture primiteves initial implementation, Pentium
|
|||
|
*
|
|||
|
**********************************************************************************************/
|
|||
|
|
|||
|
#include "Common.hpp"
|
|||
|
|
|||
|
#include "Lib/View/Raster.hpp"
|
|||
|
#include "Lib/Renderer/Primitives/DrawTriangle.hpp"
|
|||
|
|
|||
|
//*********************************************************************************************
|
|||
|
|
|||
|
|
|||
|
//*****************************************************************************************
|
|||
|
//
|
|||
|
// Transparent, Linear, Terrain texture.
|
|||
|
//
|
|||
|
void DrawSubtriangle(TTexNoClutLinearTrans* pscan, CDrawPolygon<TTexNoClutLinearTrans>* pdtri)
|
|||
|
{
|
|||
|
typedef CDrawPolygon<TTexNoClutLinearTrans> TAccess;
|
|||
|
TTexNoClutLinearTrans* plinc = &pdtri->pedgeBase->lineIncrement;
|
|||
|
|
|||
|
_asm
|
|||
|
{
|
|||
|
push ebp
|
|||
|
mov edi,[plinc] // Pointer to scanline increment.
|
|||
|
|
|||
|
mov eax,[pscan] // Pointer to scanline.
|
|||
|
mov esi,[pdtri] // Pointer to polygon.
|
|||
|
|
|||
|
//
|
|||
|
// Copies of edge stepping values.
|
|||
|
//
|
|||
|
// fx_inc = pdtri->pedgeBase->lineIncrement.fxX;
|
|||
|
// fx_diff = pdtri->pedgeBase->lineIncrement.fxXDifference;
|
|||
|
// bf_u_inc = pdtri->pedgeBase->lineIncrement.indCoord.bfU;
|
|||
|
// w1d_v_inc = pdtri->pedgeBase->lineIncrement.indCoord.w1dV;
|
|||
|
// pscanGlbl = pscan;
|
|||
|
// pdtriGlbl = pdtri;
|
|||
|
//
|
|||
|
mov ebx,[edi]TTexNoClutLinearTrans.fxX
|
|||
|
mov ecx,[edi]TTexNoClutLinearTrans.fxXDifference
|
|||
|
|
|||
|
mov fx_inc,ebx
|
|||
|
mov fx_diff,ecx
|
|||
|
|
|||
|
mov ebx,[edi]TTexNoClutLinearTrans.indCoord.bfU.i4Int
|
|||
|
mov ecx,[edi]TTexNoClutLinearTrans.indCoord.bfU.u4Frac
|
|||
|
|
|||
|
mov bf_u_inc.i4Int,ebx
|
|||
|
mov bf_u_inc.u4Frac,ecx
|
|||
|
|
|||
|
mov ebx,[edi]TTexNoClutLinearTrans.indCoord.w1dV.bfxValue.i4Int
|
|||
|
mov ecx,[edi]TTexNoClutLinearTrans.indCoord.w1dV.bfxValue.u4Frac
|
|||
|
|
|||
|
mov w1d_v_inc.bfxValue.i4Int,ebx
|
|||
|
mov w1d_v_inc.bfxValue.u4Frac,ecx
|
|||
|
|
|||
|
mov pdtriTerTrans,esi
|
|||
|
mov pscanTerTrans,eax
|
|||
|
|
|||
|
mov ebx,[pvTextureBitmap]
|
|||
|
|
|||
|
lea ebp,LIN_TEXTURE_MODIFYB1
|
|||
|
mov [ebp - 4],ebx
|
|||
|
|
|||
|
mov ebp,[esi]CDrawPolygonBase.iY
|
|||
|
|
|||
|
// -------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Iterate through the scanlines that intersect the subtriangle.
|
|||
|
//
|
|||
|
// -------------------------------------------------------------------------
|
|||
|
|
|||
|
LIN_NEXT_SCAN_LINE:
|
|||
|
// check for odd scan lines here and skip if even
|
|||
|
and ebp,bEvenScanlinesOnly
|
|||
|
jnz INC_BASE_EDGE
|
|||
|
|
|||
|
mov ecx,[esi]TAccess.prasScreen
|
|||
|
|
|||
|
mov edi,[eax]TTexNoClutLinearTrans.fxX.i4Fx
|
|||
|
mov edx,[esi]CDrawPolygonBase.iLineStartIndex
|
|||
|
|
|||
|
mov ebx,edi
|
|||
|
|
|||
|
add ebx,[esi]CDrawPolygonBase.fxLineLength.i4Fx
|
|||
|
sar ebx,16
|
|||
|
|
|||
|
mov esi, [ecx]CRasterBase.pSurface
|
|||
|
|
|||
|
sar edi,16
|
|||
|
lea ecx,[edx+ebx]
|
|||
|
|
|||
|
sub edi,ebx
|
|||
|
jge INC_BASE_EDGE // no pixels
|
|||
|
|
|||
|
mov ebx,[eax]TTexNoClutLinearTrans.indCoord.bfU.u4Frac // UFrac
|
|||
|
mov edx,[eax]TTexNoClutLinearTrans.indCoord.w1dV.bfxValue.i4Int
|
|||
|
|
|||
|
lea esi, [esi + ecx*2]
|
|||
|
|
|||
|
add edx, [eax]TTexNoClutLinearTrans.indCoord.bfU.i4Int
|
|||
|
mov ecx,[eax]TTexNoClutLinearTrans.indCoord.w1dV.bfxValue.u4Frac // VFrac
|
|||
|
|
|||
|
and edx,[u4TextureTileMask]
|
|||
|
xor eax,eax
|
|||
|
|
|||
|
//------------------------------------------------------------------------------
|
|||
|
LIN_LOOP_B:
|
|||
|
mov al,byte ptr [0xDEADC0DE + edx]
|
|||
|
LIN_TEXTURE_MODIFYB1:
|
|||
|
add ecx,[w2dDeltaTex]CWalk2D.uVFrac
|
|||
|
sbb ebp,ebp
|
|||
|
test al,al
|
|||
|
jz short LIN_TRANSPARENT_B
|
|||
|
mov word ptr[esi + edi*2],ax
|
|||
|
LIN_TRANSPARENT_B:
|
|||
|
add ebx, [w2dDeltaTex]CWalk2D.uUFrac
|
|||
|
adc edx, [w2dDeltaTex + ebp*4 + 4]CWalk2D.iUVInt
|
|||
|
and edx,[u4TextureTileMask]
|
|||
|
inc edi
|
|||
|
jnz short LIN_LOOP_B
|
|||
|
|
|||
|
// -------------------------------------------------------------------------
|
|||
|
INC_BASE_EDGE:
|
|||
|
mov eax, pscanTerTrans
|
|||
|
mov edi, fx_inc
|
|||
|
|
|||
|
mov ebx,[eax]TTexNoClutLinearTrans.fxXDifference
|
|||
|
mov ecx,[eax]TTexNoClutLinearTrans.indCoord.bfU // bottom 32 bits
|
|||
|
add ebx,fx_diff
|
|||
|
mov edx,[eax+4]TTexNoClutLinearTrans.indCoord.bfU // top 32 bits
|
|||
|
add [eax]TTexNoClutLinearTrans.fxX, edi
|
|||
|
add ecx,DWORD PTR [bf_u_inc]
|
|||
|
mov edi, [eax]TTexNoClutLinearTrans.indCoord.w1dV.bfxValue.i4Int
|
|||
|
adc edx,DWORD PTR [bf_u_inc+4]
|
|||
|
mov esi, [eax]TTexNoClutLinearTrans.indCoord.w1dV.bfxValue.u4Frac
|
|||
|
// Add the integer portions together.
|
|||
|
add edi, w1d_v_inc.bfxValue.i4Int
|
|||
|
// Add the fractional portions together, and add an extra step value if a carry
|
|||
|
// results.
|
|||
|
add esi, w1d_v_inc.bfxValue.u4Frac
|
|||
|
jnc short SKIP_STEP_ADD1
|
|||
|
add edi, [eax]TTexNoClutLinearTrans.indCoord.w1dV.iOffsetPerLine
|
|||
|
SKIP_STEP_ADD1:
|
|||
|
|
|||
|
cmp ebx, 0x00010000
|
|||
|
jl short XDIFF_LESS
|
|||
|
// do this if greater than or equal
|
|||
|
|
|||
|
sub ebx, 0x00010000
|
|||
|
|
|||
|
add edi, w1dNegDV.bfxValue.i4Int
|
|||
|
|
|||
|
add ecx, DWORD PTR [bfNegDU]
|
|||
|
adc edx, DWORD PTR [bfNegDU+4]
|
|||
|
|
|||
|
add esi, w1dNegDV.bfxValue.u4Frac
|
|||
|
jnc short EDGE_DONE
|
|||
|
add edi, [eax]TTexNoClutLinearTrans.indCoord.w1dV.iOffsetPerLine
|
|||
|
jmp short EDGE_DONE
|
|||
|
|
|||
|
XDIFF_LESS:
|
|||
|
cmp ebx,0
|
|||
|
jge short EDGE_DONE
|
|||
|
// do this if less than 0
|
|||
|
|
|||
|
add ebx, 0x00010000
|
|||
|
add edi, w1dNegDV.bfxValue.i4Int
|
|||
|
add ecx, DWORD PTR [bfNegDU]
|
|||
|
adc edx, DWORD PTR [bfNegDU+4]
|
|||
|
add esi, w1dNegDV.bfxValue.u4Frac
|
|||
|
jnc short EDGE_DONE
|
|||
|
add edi, [eax]TTexNoClutLinearTrans.indCoord.w1dV.iOffsetPerLine
|
|||
|
|
|||
|
EDGE_DONE:
|
|||
|
// -------------------------------------------------------------------------
|
|||
|
// store all the working variables back to the original raster
|
|||
|
// and also interleave the co-ordinate update variables..
|
|||
|
mov [eax]TTexNoClutLinearTrans.indCoord.w1dV.bfxValue.u4Frac, esi
|
|||
|
mov esi,pdtriTerTrans
|
|||
|
mov [eax]TTexNoClutLinearTrans.indCoord.bfU, ecx
|
|||
|
mov [eax]TTexNoClutLinearTrans.indCoord.w1dV.bfxValue.i4Int, edi
|
|||
|
mov [eax]TTexNoClutLinearTrans.fxXDifference, ebx
|
|||
|
mov ecx,[esi]TAccess.prasScreen
|
|||
|
mov [eax]TTexNoClutLinearTrans.indCoord.bfU+4, edx
|
|||
|
mov edi,[esi]CDrawPolygonBase.fxDeltaLineLength.i4Fx
|
|||
|
mov ebp,[esi]CDrawPolygonBase.iY
|
|||
|
mov edx,[ecx]CRasterBase.iLinePixels
|
|||
|
add [esi]CDrawPolygonBase.fxLineLength.i4Fx, edi
|
|||
|
inc ebp
|
|||
|
add [esi]CDrawPolygonBase.iLineStartIndex, edx
|
|||
|
cmp ebp,[esi]CDrawPolygonBase.iYTo
|
|||
|
mov [esi]CDrawPolygonBase.iY, ebp
|
|||
|
jl LIN_NEXT_SCAN_LINE
|
|||
|
pop ebp
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//*****************************************************************************************
|
|||
|
//
|
|||
|
// Non-transparent, Linear, Terrain texture.
|
|||
|
//
|
|||
|
void DrawSubtriangle(TTexNoClutLinear* pscan, CDrawPolygon<TTexNoClutLinear>* pdtri)
|
|||
|
{
|
|||
|
typedef CDrawPolygon<TTexNoClutLinear> TAccess;
|
|||
|
TTexNoClutLinear* plinc = &pdtri->pedgeBase->lineIncrement;
|
|||
|
|
|||
|
_asm
|
|||
|
{
|
|||
|
push ebp
|
|||
|
mov edi,[plinc] // Pointer to scanline increment.
|
|||
|
|
|||
|
mov eax,[pscan] // Pointer to scanline.
|
|||
|
mov esi,[pdtri] // Pointer to polygon.
|
|||
|
|
|||
|
//
|
|||
|
// Copies of edge stepping values.
|
|||
|
//
|
|||
|
// fx_inc = pdtri->pedgeBase->lineIncrement.fxX;
|
|||
|
// fx_diff = pdtri->pedgeBase->lineIncrement.fxXDifference;
|
|||
|
// bf_u_inc = pdtri->pedgeBase->lineIncrement.indCoord.bfU;
|
|||
|
// w1d_v_inc = pdtri->pedgeBase->lineIncrement.indCoord.w1dV;
|
|||
|
// pscanGlbl = pscan;
|
|||
|
// pdtriGlbl = pdtri;
|
|||
|
//
|
|||
|
mov ebx,[edi]TTexNoClutLinear.fxX
|
|||
|
mov ecx,[edi]TTexNoClutLinear.fxXDifference
|
|||
|
|
|||
|
mov fx_inc,ebx
|
|||
|
mov fx_diff,ecx
|
|||
|
|
|||
|
mov ebx,[edi]TTexNoClutLinear.indCoord.bfU.i4Int
|
|||
|
mov ecx,[edi]TTexNoClutLinear.indCoord.bfU.u4Frac
|
|||
|
|
|||
|
mov bf_u_inc.i4Int,ebx
|
|||
|
mov bf_u_inc.u4Frac,ecx
|
|||
|
|
|||
|
mov ebx,[edi]TTexNoClutLinear.indCoord.w1dV.bfxValue.i4Int
|
|||
|
mov ecx,[edi]TTexNoClutLinear.indCoord.w1dV.bfxValue.u4Frac
|
|||
|
|
|||
|
mov w1d_v_inc.bfxValue.i4Int,ebx
|
|||
|
mov w1d_v_inc.bfxValue.u4Frac,ecx
|
|||
|
|
|||
|
mov pdtriTer,esi
|
|||
|
mov pscanTer,eax
|
|||
|
|
|||
|
mov ebx,[pvTextureBitmap]
|
|||
|
|
|||
|
lea ebp,LIN_TEXTURE_MODIFYB1
|
|||
|
mov [ebp - 4],ebx
|
|||
|
|
|||
|
mov ebp,[esi]CDrawPolygonBase.iY
|
|||
|
|
|||
|
// -------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Iterate through the scanlines that intersect the subtriangle.
|
|||
|
//
|
|||
|
// -------------------------------------------------------------------------
|
|||
|
|
|||
|
LIN_NEXT_SCAN_LINE:
|
|||
|
// check for odd scan lines here and skip if even
|
|||
|
and ebp,bEvenScanlinesOnly
|
|||
|
jnz INC_BASE_EDGE
|
|||
|
|
|||
|
mov ecx,[esi]TAccess.prasScreen
|
|||
|
|
|||
|
mov edi,[eax]TTexNoClutLinear.fxX.i4Fx
|
|||
|
mov edx,[esi]CDrawPolygonBase.iLineStartIndex
|
|||
|
|
|||
|
mov ebx,edi
|
|||
|
|
|||
|
add ebx,[esi]CDrawPolygonBase.fxLineLength.i4Fx
|
|||
|
sar ebx,16
|
|||
|
|
|||
|
mov esi, [ecx]CRasterBase.pSurface
|
|||
|
|
|||
|
sar edi,16
|
|||
|
lea ecx,[edx+ebx]
|
|||
|
|
|||
|
sub edi,ebx
|
|||
|
jge INC_BASE_EDGE // no pixels
|
|||
|
|
|||
|
mov ebx,[eax]TTexNoClutLinear.indCoord.bfU.u4Frac // UFrac
|
|||
|
mov edx,[eax]TTexNoClutLinear.indCoord.w1dV.bfxValue.i4Int
|
|||
|
|
|||
|
lea esi, [esi + ecx*2]
|
|||
|
|
|||
|
add edx, [eax]TTexNoClutLinear.indCoord.bfU.i4Int
|
|||
|
mov ecx,[eax]TTexNoClutLinear.indCoord.w1dV.bfxValue.u4Frac // VFrac
|
|||
|
and edx,[u4TextureTileMask]
|
|||
|
xor eax,eax
|
|||
|
|
|||
|
//------------------------------------------------------------------------------
|
|||
|
LIN_LOOP_B:
|
|||
|
mov al,byte ptr [0xDEADC0DE + edx]
|
|||
|
LIN_TEXTURE_MODIFYB1:
|
|||
|
add ecx,[w2dDeltaTex]CWalk2D.uVFrac
|
|||
|
|
|||
|
sbb ebp,ebp
|
|||
|
add ebx,[w2dDeltaTex]CWalk2D.uUFrac
|
|||
|
|
|||
|
adc edx,[w2dDeltaTex + ebp*4 + 4]CWalk2D.iUVInt
|
|||
|
|
|||
|
mov word ptr[esi + edi*2],ax
|
|||
|
|
|||
|
and edx,[u4TextureTileMask]
|
|||
|
|
|||
|
inc edi
|
|||
|
jnz short LIN_LOOP_B
|
|||
|
|
|||
|
// -------------------------------------------------------------------------
|
|||
|
INC_BASE_EDGE:
|
|||
|
mov eax,pscanTer
|
|||
|
mov edi,fx_inc
|
|||
|
|
|||
|
mov ebx,[eax]TTexNoClutLinear.fxXDifference
|
|||
|
mov ecx,[eax]TTexNoClutLinear.indCoord.bfU // bottom 32 bits
|
|||
|
add ebx,fx_diff
|
|||
|
mov edx,[eax+4]TTexNoClutLinear.indCoord.bfU // top 32 bits
|
|||
|
add [eax]TTexNoClutLinear.fxX, edi
|
|||
|
add ecx,DWORD PTR [bf_u_inc]
|
|||
|
mov edi, [eax]TTexNoClutLinear.indCoord.w1dV.bfxValue.i4Int
|
|||
|
adc edx,DWORD PTR [bf_u_inc+4]
|
|||
|
mov esi, [eax]TTexNoClutLinear.indCoord.w1dV.bfxValue.u4Frac
|
|||
|
// Add the integer portions together.
|
|||
|
add edi, w1d_v_inc.bfxValue.i4Int
|
|||
|
// Add the fractional portions together, and add an extra step value if a carry
|
|||
|
// results.
|
|||
|
add esi, w1d_v_inc.bfxValue.u4Frac
|
|||
|
jnc short SKIP_STEP_ADD1
|
|||
|
add edi, [eax]TTexNoClutLinear.indCoord.w1dV.iOffsetPerLine
|
|||
|
SKIP_STEP_ADD1:
|
|||
|
|
|||
|
cmp ebx, 0x00010000
|
|||
|
jl short XDIFF_LESS
|
|||
|
// do this if greater than or equal
|
|||
|
|
|||
|
sub ebx, 0x00010000
|
|||
|
|
|||
|
add edi, w1dNegDV.bfxValue.i4Int
|
|||
|
|
|||
|
add ecx, DWORD PTR [bfNegDU]
|
|||
|
adc edx, DWORD PTR [bfNegDU+4]
|
|||
|
|
|||
|
add esi, w1dNegDV.bfxValue.u4Frac
|
|||
|
jnc short EDGE_DONE
|
|||
|
add edi, [eax]TTexNoClutLinear.indCoord.w1dV.iOffsetPerLine
|
|||
|
jmp short EDGE_DONE
|
|||
|
|
|||
|
XDIFF_LESS:
|
|||
|
cmp ebx,0
|
|||
|
jge short EDGE_DONE
|
|||
|
// do this if less than 0
|
|||
|
|
|||
|
add ebx, 0x00010000
|
|||
|
add edi, w1dNegDV.bfxValue.i4Int
|
|||
|
add ecx, DWORD PTR [bfNegDU]
|
|||
|
adc edx, DWORD PTR [bfNegDU+4]
|
|||
|
add esi, w1dNegDV.bfxValue.u4Frac
|
|||
|
jnc short EDGE_DONE
|
|||
|
add edi, [eax]TTexNoClutLinear.indCoord.w1dV.iOffsetPerLine
|
|||
|
|
|||
|
EDGE_DONE:
|
|||
|
// -------------------------------------------------------------------------
|
|||
|
// store all the working variables back to the original raster
|
|||
|
// and also interleave the co-ordinate update variables..
|
|||
|
mov [eax]TTexNoClutLinear.indCoord.w1dV.bfxValue.u4Frac, esi
|
|||
|
mov esi,pdtriTer
|
|||
|
mov [eax]TTexNoClutLinear.indCoord.bfU, ecx
|
|||
|
mov [eax]TTexNoClutLinear.indCoord.w1dV.bfxValue.i4Int, edi
|
|||
|
mov [eax]TTexNoClutLinear.fxXDifference, ebx
|
|||
|
mov ecx,[esi]TAccess.prasScreen
|
|||
|
mov [eax]TTexNoClutLinear.indCoord.bfU+4, edx
|
|||
|
mov edi,[esi]CDrawPolygonBase.fxDeltaLineLength.i4Fx
|
|||
|
mov ebp,[esi]CDrawPolygonBase.iY
|
|||
|
mov edx,[ecx]CRasterBase.iLinePixels
|
|||
|
add [esi]CDrawPolygonBase.fxLineLength.i4Fx, edi
|
|||
|
inc ebp
|
|||
|
add [esi]CDrawPolygonBase.iLineStartIndex, edx
|
|||
|
cmp ebp,[esi]CDrawPolygonBase.iYTo
|
|||
|
mov [esi]CDrawPolygonBase.iY, ebp
|
|||
|
jl LIN_NEXT_SCAN_LINE
|
|||
|
pop ebp
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//*********************************************************************************************
|
|||
|
//
|
|||
|
// Draw shadow primitive.
|
|||
|
//
|
|||
|
void DrawSubtriangle(TShadow* pscan, CDrawPolygon<TShadow>* pdtri)
|
|||
|
{
|
|||
|
typedef CDrawPolygon<TShadow> TAccess;
|
|||
|
|
|||
|
// Local copies of edges stepping values.
|
|||
|
fx_inc = pdtri->pedgeBase->lineIncrement.fxX;
|
|||
|
fx_diff = pdtri->pedgeBase->lineIncrement.fxXDifference;
|
|||
|
|
|||
|
// put the shadow colour in the top byte of both words within a dword
|
|||
|
u4ShadowColour = (u1ShadowIntensity<<8) | (u1ShadowIntensity<<24);
|
|||
|
|
|||
|
_asm
|
|||
|
{
|
|||
|
mov edx,[pdtri]
|
|||
|
mov eax, [edx]CDrawPolygonBase.iY
|
|||
|
|
|||
|
mov edi,[edx]CDrawPolygonBase.iLineStartIndex
|
|||
|
mov ecx,[pscan]
|
|||
|
// edi, eax and edx are also set from the loop end
|
|||
|
|
|||
|
//--------------------------------------------------------------------------------------
|
|||
|
// scan line start
|
|||
|
NEXT_SCAN:
|
|||
|
and eax,[bEvenScanlinesOnly]
|
|||
|
jnz short SKIP_LOOP
|
|||
|
|
|||
|
mov ebx,[edx]TAccess.prasScreen
|
|||
|
mov esi,[ecx]TShadow.fxX.i4Fx
|
|||
|
|
|||
|
mov eax,esi
|
|||
|
|
|||
|
add eax,[edx]CDrawPolygonBase.fxLineLength.i4Fx
|
|||
|
|
|||
|
sar esi,16
|
|||
|
|
|||
|
sar eax,16
|
|||
|
|
|||
|
add edi,eax
|
|||
|
|
|||
|
sub esi,eax
|
|||
|
jge short SKIP_LOOP
|
|||
|
|
|||
|
//--------------------------------------------------------------------------------------
|
|||
|
// all scan lines are drawn the same way
|
|||
|
add edi,edi
|
|||
|
mov ecx,esi
|
|||
|
|
|||
|
add edi,[ebx]CRasterBase.pSurface
|
|||
|
|
|||
|
mov ebx,[u4ShadowColour]
|
|||
|
|
|||
|
add ecx,edi
|
|||
|
|
|||
|
and ecx,3
|
|||
|
jz short N_LOOP
|
|||
|
|
|||
|
//--------------------------------------------------------------------------------------
|
|||
|
// do a single WORD to dword align
|
|||
|
mov [edi + esi*2 + 1],bh
|
|||
|
|
|||
|
inc esi // we are now aligned to a DWORD
|
|||
|
jz short SKIP_LOOP // are we done?
|
|||
|
|
|||
|
//--------------------------------------------------------------------------------------
|
|||
|
// Main loop does 4 words at a time to avoid AGI
|
|||
|
N_LOOP:
|
|||
|
add esi,4
|
|||
|
jge short DONE_SCAN
|
|||
|
mov ecx,[edi + esi*2 - 8]
|
|||
|
mov edx,[edi + esi*2 - 4]
|
|||
|
and ecx,0x00ff00ff
|
|||
|
and edx,0x00ff00ff
|
|||
|
or ecx,ebx
|
|||
|
or edx,ebx
|
|||
|
mov [edi + esi*2 - 8],ecx
|
|||
|
mov [edi + esi*2 - 4],edx
|
|||
|
jmp short N_LOOP
|
|||
|
|
|||
|
DONE_SCAN:
|
|||
|
jz short TWO_DWORD_REMAIN
|
|||
|
sub esi,2
|
|||
|
jg short SINGLE_WORD_REMAIN
|
|||
|
|
|||
|
|
|||
|
//--------------------------------------------------------------------------------------
|
|||
|
// There is either 2 or 3 pixles left when we get to here
|
|||
|
mov edx,[edi + esi*2 - 4]
|
|||
|
and edx,0x00ff00ff
|
|||
|
or edx,ebx
|
|||
|
mov [edi + esi*2 - 4],edx
|
|||
|
inc esi
|
|||
|
jnz short SKIP_LOOP
|
|||
|
|
|||
|
//--------------------------------------------------------------------------------------
|
|||
|
// Do the single word that remains
|
|||
|
mov [edi + esi*2 - 2 + 1],bh
|
|||
|
jmp short SKIP_LOOP
|
|||
|
|
|||
|
|
|||
|
SINGLE_WORD_REMAIN:
|
|||
|
//--------------------------------------------------------------------------------------
|
|||
|
// do a single word to finish
|
|||
|
movzx ecx,word ptr [edi + esi*2 - 4]
|
|||
|
and ecx,0x00ff
|
|||
|
or ecx,ebx
|
|||
|
mov [edi + esi*2 - 4], cx
|
|||
|
jmp short SKIP_LOOP
|
|||
|
|
|||
|
//--------------------------------------------------------------------------------------
|
|||
|
// do 2 DWORDs to finish
|
|||
|
TWO_DWORD_REMAIN:
|
|||
|
mov ecx,[edi + esi*2 - 8]
|
|||
|
mov edx,[edi + esi*2 - 4]
|
|||
|
and ecx,0x00ff00ff
|
|||
|
and edx,0x00ff00ff
|
|||
|
or ecx,ebx
|
|||
|
or edx,ebx
|
|||
|
mov [edi + esi*2 - 8], ecx
|
|||
|
mov [edi + esi*2 - 4], edx
|
|||
|
|
|||
|
//--------------------------------------------------------------------------------------
|
|||
|
// Loop control an sub pixel correction for edges
|
|||
|
SKIP_LOOP:
|
|||
|
mov edx,pdtri
|
|||
|
mov ecx,pscan
|
|||
|
mov eax, fx_inc
|
|||
|
mov esi,[ecx]TShadow.fxXDifference
|
|||
|
add [ecx]TShadow.fxX,eax
|
|||
|
add esi, fx_diff
|
|||
|
mov ebx,[edx]TAccess.prasScreen
|
|||
|
|
|||
|
cmp esi, 1<<16
|
|||
|
jz short UFLOW
|
|||
|
|
|||
|
// greater than or equal to 1 is an overflow
|
|||
|
sub esi, 1<<16
|
|||
|
jmp short DONE_Y
|
|||
|
UFLOW:
|
|||
|
cmp esi, 0
|
|||
|
jge short DONE_Y
|
|||
|
add esi, 1<<16
|
|||
|
DONE_Y:
|
|||
|
// calc the new end point and line length
|
|||
|
mov [ecx]TShadow.fxXDifference, esi
|
|||
|
mov eax, [edx]CDrawPolygonBase.fxLineLength.i4Fx
|
|||
|
mov edi, [edx]CDrawPolygonBase.iLineStartIndex
|
|||
|
add eax, [edx]CDrawPolygonBase.fxDeltaLineLength.i4Fx
|
|||
|
add edi, [ebx]CRasterBase.iLinePixels
|
|||
|
mov [edx]CDrawPolygonBase.fxLineLength.i4Fx, eax
|
|||
|
|
|||
|
|
|||
|
mov eax, [edx]CDrawPolygonBase.iY
|
|||
|
mov esi, [edx]CDrawPolygonBase.iYTo
|
|||
|
inc eax
|
|||
|
mov [edx]CDrawPolygonBase.iLineStartIndex, edi
|
|||
|
mov [edx]CDrawPolygonBase.iY,eax
|
|||
|
cmp eax, esi
|
|||
|
jl short NEXT_SCAN
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//*********************************************************************************************
|
|||
|
//
|
|||
|
// Draw shadow transparent primitive, 8 bit source textures.
|
|||
|
//
|
|||
|
void DrawSubtriangle(TShadowTrans8* pscan, CDrawPolygon<TShadowTrans8>* pdtri)
|
|||
|
{
|
|||
|
typedef CDrawPolygon<TShadowTrans8> TAccess;
|
|||
|
TShadowTrans8* plinc = &pdtri->pedgeBase->lineIncrement;
|
|||
|
|
|||
|
_asm
|
|||
|
{
|
|||
|
push ebp
|
|||
|
mov edi,[plinc] // Pointer to scanline increment.
|
|||
|
|
|||
|
mov eax,[pscan] // Pointer to scanline.
|
|||
|
mov esi,[pdtri] // Pointer to polygon.
|
|||
|
|
|||
|
//
|
|||
|
// Copies of edge stepping values.
|
|||
|
//
|
|||
|
// fx_inc = pdtri->pedgeBase->lineIncrement.fxX;
|
|||
|
// fx_diff = pdtri->pedgeBase->lineIncrement.fxXDifference;
|
|||
|
// bf_u_inc = pdtri->pedgeBase->lineIncrement.indCoord.bfU;
|
|||
|
// w1d_v_inc = pdtri->pedgeBase->lineIncrement.indCoord.w1dV;
|
|||
|
// pscanGlbl = pscan;
|
|||
|
// pdtriGlbl = pdtri;
|
|||
|
//
|
|||
|
mov ebx,[edi]TShadowTrans8.fxX
|
|||
|
mov ecx,[edi]TShadowTrans8.fxXDifference
|
|||
|
|
|||
|
mov fx_inc,ebx
|
|||
|
mov fx_diff,ecx
|
|||
|
|
|||
|
mov ebx,[edi]TShadowTrans8.indCoord.bfU.i4Int
|
|||
|
mov ecx,[edi]TShadowTrans8.indCoord.bfU.u4Frac
|
|||
|
|
|||
|
mov bf_u_inc.i4Int,ebx
|
|||
|
mov bf_u_inc.u4Frac,ecx
|
|||
|
|
|||
|
mov ebx,[edi]TShadowTrans8.indCoord.w1dV.bfxValue.i4Int
|
|||
|
mov ecx,[edi]TShadowTrans8.indCoord.w1dV.bfxValue.u4Frac
|
|||
|
|
|||
|
mov w1d_v_inc.bfxValue.i4Int,ebx
|
|||
|
mov w1d_v_inc.bfxValue.u4Frac,ecx
|
|||
|
|
|||
|
mov pdtriShadow8,esi
|
|||
|
mov pscanShadow8,eax
|
|||
|
|
|||
|
mov ebx,[pvTextureBitmap]
|
|||
|
|
|||
|
lea ebp,LIN_TEXTURE_MODIFYB1
|
|||
|
mov [ebp - 4],ebx // Self modification.
|
|||
|
|
|||
|
mov ebp,[esi]CDrawPolygonBase.iY
|
|||
|
|
|||
|
// -------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Iterate through the scanlines that intersect the subtriangle.
|
|||
|
//
|
|||
|
// -------------------------------------------------------------------------
|
|||
|
|
|||
|
LIN_NEXT_SCAN_LINE:
|
|||
|
// check for odd scan lines here and skip if even
|
|||
|
and ebp,bEvenScanlinesOnly
|
|||
|
jnz INC_BASE_EDGE
|
|||
|
|
|||
|
mov ecx,[esi]TAccess.prasScreen
|
|||
|
|
|||
|
mov edi,[eax]TShadowTrans8.fxX.i4Fx
|
|||
|
mov edx,[esi]CDrawPolygonBase.iLineStartIndex
|
|||
|
|
|||
|
mov ebx,edi
|
|||
|
|
|||
|
add ebx,[esi]CDrawPolygonBase.fxLineLength.i4Fx
|
|||
|
sar ebx,16
|
|||
|
|
|||
|
mov esi,[ecx]CRasterBase.pSurface
|
|||
|
|
|||
|
sar edi,16
|
|||
|
lea ecx,[edx+ebx]
|
|||
|
|
|||
|
sub edi,ebx
|
|||
|
jge INC_BASE_EDGE // no pixels
|
|||
|
|
|||
|
mov ebx,[eax]TShadowTrans8.indCoord.bfU.u4Frac // UFrac
|
|||
|
mov edx,[eax]TShadowTrans8.indCoord.w1dV.bfxValue.i4Int // UInt
|
|||
|
|
|||
|
lea esi,[esi + ecx*2]
|
|||
|
mov ecx,[eax]TShadowTrans8.indCoord.bfU.i4Int
|
|||
|
|
|||
|
add edx,ecx // VInt
|
|||
|
mov ecx,[eax]TShadowTrans8.indCoord.w1dV.bfxValue.u4Frac // VFrac
|
|||
|
|
|||
|
mov ah,[u1ShadowIntensity] // Load shadow value
|
|||
|
|
|||
|
//------------------------------------------------------------------------------
|
|||
|
LIN_LOOP:
|
|||
|
and edx,[u4TextureTileMask] // Tiling mask
|
|||
|
add ecx,[w2dDeltaTex]CWalk2D.uVFrac // V step
|
|||
|
|
|||
|
sbb ebp,ebp // Carry from V step
|
|||
|
add ebx,[w2dDeltaTex]CWalk2D.uUFrac // U step
|
|||
|
|
|||
|
mov al,byte ptr [0xDEADC0DE + edx] // Byte of source texture
|
|||
|
LIN_TEXTURE_MODIFYB1:
|
|||
|
mov ebp,[w2dDeltaTex + ebp*4 + 4]CWalk2D.iUVInt // Lokup integer step
|
|||
|
|
|||
|
adc edx,ebp // Integer step
|
|||
|
test al,al // Test for transparency.
|
|||
|
|
|||
|
jz short TRANS
|
|||
|
|
|||
|
// insert the shadow colour into the destination raster
|
|||
|
mov byte ptr[esi + edi*2 + 1],ah
|
|||
|
|
|||
|
TRANS:
|
|||
|
inc edi
|
|||
|
jnz short LIN_LOOP
|
|||
|
|
|||
|
// -------------------------------------------------------------------------
|
|||
|
INC_BASE_EDGE:
|
|||
|
mov eax, pscanShadow8
|
|||
|
mov edi, fx_inc
|
|||
|
|
|||
|
mov ebx,[eax]TShadowTrans8.fxXDifference
|
|||
|
mov ecx,[eax]TShadowTrans8.indCoord.bfU // bottom 32 bits
|
|||
|
add ebx,fx_diff
|
|||
|
mov edx,[eax+4]TShadowTrans8.indCoord.bfU // top 32 bits
|
|||
|
add [eax]TShadowTrans8.fxX, edi
|
|||
|
add ecx,DWORD PTR [bf_u_inc]
|
|||
|
mov edi, [eax]TShadowTrans8.indCoord.w1dV.bfxValue.i4Int
|
|||
|
adc edx,DWORD PTR [bf_u_inc+4]
|
|||
|
mov esi, [eax]TShadowTrans8.indCoord.w1dV.bfxValue.u4Frac
|
|||
|
// Add the integer portions together.
|
|||
|
add edi, w1d_v_inc.bfxValue.i4Int
|
|||
|
// Add the fractional portions together, and add an extra step value if a carry
|
|||
|
// results.
|
|||
|
add esi, w1d_v_inc.bfxValue.u4Frac
|
|||
|
jnc short SKIP_STEP_ADD1
|
|||
|
add edi, [eax]TShadowTrans8.indCoord.w1dV.iOffsetPerLine
|
|||
|
SKIP_STEP_ADD1:
|
|||
|
|
|||
|
cmp ebx, 0x00010000
|
|||
|
jl short XDIFF_LESS
|
|||
|
// do this if greater than or equal
|
|||
|
|
|||
|
sub ebx, 0x00010000
|
|||
|
|
|||
|
add edi, w1dNegDV.bfxValue.i4Int
|
|||
|
|
|||
|
add ecx, DWORD PTR [bfNegDU]
|
|||
|
adc edx, DWORD PTR [bfNegDU+4]
|
|||
|
|
|||
|
add esi, w1dNegDV.bfxValue.u4Frac
|
|||
|
jnc short EDGE_DONE
|
|||
|
add edi, [eax]TShadowTrans8.indCoord.w1dV.iOffsetPerLine
|
|||
|
jmp short EDGE_DONE
|
|||
|
|
|||
|
XDIFF_LESS:
|
|||
|
cmp ebx,0
|
|||
|
jge short EDGE_DONE
|
|||
|
// do this if less than 0
|
|||
|
|
|||
|
add ebx, 0x00010000
|
|||
|
add edi, w1dNegDV.bfxValue.i4Int
|
|||
|
add ecx, DWORD PTR [bfNegDU]
|
|||
|
adc edx, DWORD PTR [bfNegDU+4]
|
|||
|
add esi, w1dNegDV.bfxValue.u4Frac
|
|||
|
jnc short EDGE_DONE
|
|||
|
add edi, [eax]TShadowTrans8.indCoord.w1dV.iOffsetPerLine
|
|||
|
|
|||
|
EDGE_DONE:
|
|||
|
// -------------------------------------------------------------------------
|
|||
|
// store all the working variables back to the original raster
|
|||
|
// and also interleave the co-ordinate update variables..
|
|||
|
mov [eax]TShadowTrans8.indCoord.w1dV.bfxValue.u4Frac, esi
|
|||
|
mov esi,pdtriShadow8
|
|||
|
mov [eax]TShadowTrans8.indCoord.bfU, ecx
|
|||
|
mov [eax]TShadowTrans8.indCoord.w1dV.bfxValue.i4Int, edi
|
|||
|
mov [eax]TShadowTrans8.fxXDifference, ebx
|
|||
|
mov ecx,[esi]TAccess.prasScreen
|
|||
|
mov [eax]TShadowTrans8.indCoord.bfU+4, edx
|
|||
|
mov edi,[esi]CDrawPolygonBase.fxDeltaLineLength.i4Fx
|
|||
|
mov ebp,[esi]CDrawPolygonBase.iY
|
|||
|
mov edx,[ecx]CRasterBase.iLinePixels
|
|||
|
add [esi]CDrawPolygonBase.fxLineLength.i4Fx, edi
|
|||
|
inc ebp
|
|||
|
add [esi]CDrawPolygonBase.iLineStartIndex, edx
|
|||
|
cmp ebp,[esi]CDrawPolygonBase.iYTo
|
|||
|
mov [esi]CDrawPolygonBase.iY, ebp
|
|||
|
jl LIN_NEXT_SCAN_LINE
|
|||
|
pop ebp
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
#if (iBUMPMAP_RESOLUTION == 16)
|
|||
|
|
|||
|
//*********************************************************************************************
|
|||
|
//
|
|||
|
// Draw shadow transparent primitive, 16 bit source textures (bumps)
|
|||
|
//
|
|||
|
void DrawSubtriangle(TShadowTrans32* pscan, CDrawPolygon<TShadowTrans32>* pdtri)
|
|||
|
{
|
|||
|
typedef CDrawPolygon<TShadowTrans32> TAccess;
|
|||
|
TShadowTrans32* plinc = &pdtri->pedgeBase->lineIncrement;
|
|||
|
|
|||
|
_asm
|
|||
|
{
|
|||
|
push ebp
|
|||
|
mov edi,[plinc] // Pointer to scanline increment.
|
|||
|
|
|||
|
mov eax,[pscan] // Pointer to scanline.
|
|||
|
mov esi,[pdtri] // Pointer to polygon.
|
|||
|
|
|||
|
//
|
|||
|
// Copies of edge stepping values.
|
|||
|
//
|
|||
|
// fx_inc = pdtri->pedgeBase->lineIncrement.fxX;
|
|||
|
// fx_diff = pdtri->pedgeBase->lineIncrement.fxXDifference;
|
|||
|
// bf_u_inc = pdtri->pedgeBase->lineIncrement.indCoord.bfU;
|
|||
|
// w1d_v_inc = pdtri->pedgeBase->lineIncrement.indCoord.w1dV;
|
|||
|
// pscanGlbl = pscan;
|
|||
|
// pdtriGlbl = pdtri;
|
|||
|
//
|
|||
|
mov ebx,[edi]TShadowTrans32.fxX
|
|||
|
mov ecx,[edi]TShadowTrans32.fxXDifference
|
|||
|
|
|||
|
mov fx_inc,ebx
|
|||
|
mov fx_diff,ecx
|
|||
|
|
|||
|
mov ebx,[edi]TShadowTrans32.indCoord.bfU.i4Int
|
|||
|
mov ecx,[edi]TShadowTrans32.indCoord.bfU.u4Frac
|
|||
|
|
|||
|
mov bf_u_inc.i4Int,ebx
|
|||
|
mov bf_u_inc.u4Frac,ecx
|
|||
|
|
|||
|
mov ebx,[edi]TShadowTrans32.indCoord.w1dV.bfxValue.i4Int
|
|||
|
mov ecx,[edi]TShadowTrans32.indCoord.w1dV.bfxValue.u4Frac
|
|||
|
|
|||
|
mov w1d_v_inc.bfxValue.i4Int,ebx
|
|||
|
mov w1d_v_inc.bfxValue.u4Frac,ecx
|
|||
|
|
|||
|
mov pdtriShadow32,esi
|
|||
|
mov ebx,[pvTextureBitmap]
|
|||
|
|
|||
|
mov pscanShadow32,eax
|
|||
|
add ebx,1 // Byte of bump-map that is color value.
|
|||
|
|
|||
|
lea ebp,LIN_TEXTURE_MODIFYB1
|
|||
|
mov [ebp - 4],ebx // Self modification.
|
|||
|
|
|||
|
mov ebp,[esi]CDrawPolygonBase.iY
|
|||
|
|
|||
|
// -------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Iterate through the scanlines that intersect the subtriangle.
|
|||
|
//
|
|||
|
// -------------------------------------------------------------------------
|
|||
|
|
|||
|
LIN_NEXT_SCAN_LINE:
|
|||
|
// check for odd scan lines here and skip if even
|
|||
|
and ebp,bEvenScanlinesOnly
|
|||
|
jnz INC_BASE_EDGE
|
|||
|
|
|||
|
mov ecx,[esi]TAccess.prasScreen
|
|||
|
|
|||
|
mov edi,[eax]TShadowTrans32.fxX.i4Fx
|
|||
|
mov edx,[esi]CDrawPolygonBase.iLineStartIndex
|
|||
|
|
|||
|
mov ebx,edi
|
|||
|
|
|||
|
add ebx,[esi]CDrawPolygonBase.fxLineLength.i4Fx
|
|||
|
sar ebx,16
|
|||
|
|
|||
|
mov esi, [ecx]CRasterBase.pSurface
|
|||
|
|
|||
|
sar edi,16
|
|||
|
lea ecx,[edx+ebx]
|
|||
|
|
|||
|
sub edi,ebx
|
|||
|
jge INC_BASE_EDGE // no pixels
|
|||
|
|
|||
|
mov ebx,[eax]TShadowTrans32.indCoord.bfU.u4Frac // UFrac
|
|||
|
mov edx,[eax]TShadowTrans32.indCoord.w1dV.bfxValue.i4Int // UInt
|
|||
|
|
|||
|
lea esi,[esi + ecx*2]
|
|||
|
mov ecx,[eax]TShadowTrans32.indCoord.bfU.i4Int
|
|||
|
|
|||
|
add edx,ecx // VInt
|
|||
|
mov ecx,[eax]TShadowTrans32.indCoord.w1dV.bfxValue.u4Frac // VFrac
|
|||
|
|
|||
|
mov ah,[u1ShadowIntensity] // Load shadow value
|
|||
|
|
|||
|
//------------------------------------------------------------------------------
|
|||
|
LIN_LOOP:
|
|||
|
and edx,[u4TextureTileMask] // Tiling mask
|
|||
|
add ecx,[w2dDeltaTex]CWalk2D.uVFrac // V step
|
|||
|
|
|||
|
sbb ebp,ebp // Carry from V step
|
|||
|
add ebx,[w2dDeltaTex]CWalk2D.uUFrac // U step
|
|||
|
|
|||
|
mov al,byte ptr [0xDEADC0DE + edx*2] // Byte of source texture
|
|||
|
LIN_TEXTURE_MODIFYB1:
|
|||
|
mov ebp,[w2dDeltaTex + ebp*4 + 4]CWalk2D.iUVInt // Lokup integer step
|
|||
|
|
|||
|
adc edx,ebp // Integer step
|
|||
|
test al,0xfc // Test for transparency.
|
|||
|
|
|||
|
jz short TRANS
|
|||
|
|
|||
|
// insert the shadow colour into the destination raster
|
|||
|
mov byte ptr[esi + edi*2 + 1],ah
|
|||
|
|
|||
|
TRANS:
|
|||
|
inc edi
|
|||
|
jnz short LIN_LOOP
|
|||
|
|
|||
|
// -------------------------------------------------------------------------
|
|||
|
INC_BASE_EDGE:
|
|||
|
mov eax, pscanShadow32
|
|||
|
mov edi, fx_inc
|
|||
|
|
|||
|
mov ebx,[eax]TShadowTrans32.fxXDifference
|
|||
|
mov ecx,[eax]TShadowTrans32.indCoord.bfU // bottom 32 bits
|
|||
|
add ebx,fx_diff
|
|||
|
mov edx,[eax+4]TShadowTrans32.indCoord.bfU // top 32 bits
|
|||
|
add [eax]TShadowTrans32.fxX, edi
|
|||
|
add ecx,DWORD PTR [bf_u_inc]
|
|||
|
mov edi, [eax]TShadowTrans32.indCoord.w1dV.bfxValue.i4Int
|
|||
|
adc edx,DWORD PTR [bf_u_inc+4]
|
|||
|
mov esi, [eax]TShadowTrans32.indCoord.w1dV.bfxValue.u4Frac
|
|||
|
// Add the integer portions together.
|
|||
|
add edi, w1d_v_inc.bfxValue.i4Int
|
|||
|
// Add the fractional portions together, and add an extra step value if a carry
|
|||
|
// results.
|
|||
|
add esi, w1d_v_inc.bfxValue.u4Frac
|
|||
|
jnc short SKIP_STEP_ADD1
|
|||
|
add edi, [eax]TShadowTrans32.indCoord.w1dV.iOffsetPerLine
|
|||
|
SKIP_STEP_ADD1:
|
|||
|
|
|||
|
cmp ebx, 0x00010000
|
|||
|
jl short XDIFF_LESS
|
|||
|
// do this if greater than or equal
|
|||
|
|
|||
|
sub ebx, 0x00010000
|
|||
|
|
|||
|
add edi, w1dNegDV.bfxValue.i4Int
|
|||
|
|
|||
|
add ecx, DWORD PTR [bfNegDU]
|
|||
|
adc edx, DWORD PTR [bfNegDU+4]
|
|||
|
|
|||
|
add esi, w1dNegDV.bfxValue.u4Frac
|
|||
|
jnc short EDGE_DONE
|
|||
|
add edi, [eax]TShadowTrans32.indCoord.w1dV.iOffsetPerLine
|
|||
|
jmp short EDGE_DONE
|
|||
|
|
|||
|
XDIFF_LESS:
|
|||
|
cmp ebx,0
|
|||
|
jge short EDGE_DONE
|
|||
|
// do this if less than 0
|
|||
|
|
|||
|
add ebx, 0x00010000
|
|||
|
add edi, w1dNegDV.bfxValue.i4Int
|
|||
|
add ecx, DWORD PTR [bfNegDU]
|
|||
|
adc edx, DWORD PTR [bfNegDU+4]
|
|||
|
add esi, w1dNegDV.bfxValue.u4Frac
|
|||
|
jnc short EDGE_DONE
|
|||
|
add edi, [eax]TShadowTrans32.indCoord.w1dV.iOffsetPerLine
|
|||
|
|
|||
|
EDGE_DONE:
|
|||
|
// -------------------------------------------------------------------------
|
|||
|
// store all the working variables back to the original raster
|
|||
|
// and also interleave the co-ordinate update variables..
|
|||
|
mov [eax]TShadowTrans32.indCoord.w1dV.bfxValue.u4Frac, esi
|
|||
|
mov esi,pdtriShadow32
|
|||
|
mov [eax]TShadowTrans32.indCoord.bfU, ecx
|
|||
|
mov [eax]TShadowTrans32.indCoord.w1dV.bfxValue.i4Int, edi
|
|||
|
mov [eax]TShadowTrans32.fxXDifference, ebx
|
|||
|
mov ecx,[esi]TAccess.prasScreen
|
|||
|
mov [eax]TShadowTrans32.indCoord.bfU+4, edx
|
|||
|
mov edi,[esi]CDrawPolygonBase.fxDeltaLineLength.i4Fx
|
|||
|
mov ebp,[esi]CDrawPolygonBase.iY
|
|||
|
mov edx,[ecx]CRasterBase.iLinePixels
|
|||
|
add [esi]CDrawPolygonBase.fxLineLength.i4Fx, edi
|
|||
|
inc ebp
|
|||
|
add [esi]CDrawPolygonBase.iLineStartIndex, edx
|
|||
|
cmp ebp,[esi]CDrawPolygonBase.iYTo
|
|||
|
mov [esi]CDrawPolygonBase.iY, ebp
|
|||
|
jl LIN_NEXT_SCAN_LINE
|
|||
|
pop ebp
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#elif (iBUMPMAP_RESOLUTION == 32) // if (iBUMPMAP_RESOLUTION == 16)
|
|||
|
|
|||
|
//*********************************************************************************************
|
|||
|
//
|
|||
|
// Draw shadow transparent primitive, 32 bit source textures (bumps)
|
|||
|
//
|
|||
|
void DrawSubtriangle(TShadowTrans32* pscan, CDrawPolygon<TShadowTrans32>* pdtri)
|
|||
|
{
|
|||
|
typedef CDrawPolygon<TShadowTrans32> TAccess;
|
|||
|
TShadowTrans32* plinc = &pdtri->pedgeBase->lineIncrement;
|
|||
|
|
|||
|
_asm
|
|||
|
{
|
|||
|
push ebp
|
|||
|
mov edi,[plinc] // Pointer to scanline increment.
|
|||
|
|
|||
|
mov eax,[pscan] // Pointer to scanline.
|
|||
|
mov esi,[pdtri] // Pointer to polygon.
|
|||
|
|
|||
|
//
|
|||
|
// Copies of edge stepping values.
|
|||
|
//
|
|||
|
// fx_inc = pdtri->pedgeBase->lineIncrement.fxX;
|
|||
|
// fx_diff = pdtri->pedgeBase->lineIncrement.fxXDifference;
|
|||
|
// bf_u_inc = pdtri->pedgeBase->lineIncrement.indCoord.bfU;
|
|||
|
// w1d_v_inc = pdtri->pedgeBase->lineIncrement.indCoord.w1dV;
|
|||
|
// pscanGlbl = pscan;
|
|||
|
// pdtriGlbl = pdtri;
|
|||
|
//
|
|||
|
mov ebx,[edi]TShadowTrans32.fxX
|
|||
|
mov ecx,[edi]TShadowTrans32.fxXDifference
|
|||
|
|
|||
|
mov fx_inc,ebx
|
|||
|
mov fx_diff,ecx
|
|||
|
|
|||
|
mov ebx,[edi]TShadowTrans32.indCoord.bfU.i4Int
|
|||
|
mov ecx,[edi]TShadowTrans32.indCoord.bfU.u4Frac
|
|||
|
|
|||
|
mov bf_u_inc.i4Int,ebx
|
|||
|
mov bf_u_inc.u4Frac,ecx
|
|||
|
|
|||
|
mov ebx,[edi]TShadowTrans32.indCoord.w1dV.bfxValue.i4Int
|
|||
|
mov ecx,[edi]TShadowTrans32.indCoord.w1dV.bfxValue.u4Frac
|
|||
|
|
|||
|
mov w1d_v_inc.bfxValue.i4Int,ebx
|
|||
|
mov w1d_v_inc.bfxValue.u4Frac,ecx
|
|||
|
|
|||
|
mov pdtriShadow32,esi
|
|||
|
mov ebx,[pvTextureBitmap]
|
|||
|
|
|||
|
mov pscanShadow32,eax
|
|||
|
add ebx,3 // Byte of bump-map that is color value.
|
|||
|
|
|||
|
lea ebp,LIN_TEXTURE_MODIFYB1
|
|||
|
mov [ebp - 4],ebx // Self modification.
|
|||
|
|
|||
|
mov ebp,[esi]CDrawPolygonBase.iY
|
|||
|
|
|||
|
// -------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Iterate through the scanlines that intersect the subtriangle.
|
|||
|
//
|
|||
|
// -------------------------------------------------------------------------
|
|||
|
|
|||
|
LIN_NEXT_SCAN_LINE:
|
|||
|
// check for odd scan lines here and skip if even
|
|||
|
and ebp,bEvenScanlinesOnly
|
|||
|
jnz INC_BASE_EDGE
|
|||
|
|
|||
|
mov ecx,[esi]TAccess.prasScreen
|
|||
|
|
|||
|
mov edi,[eax]TShadowTrans32.fxX.i4Fx
|
|||
|
mov edx,[esi]CDrawPolygonBase.iLineStartIndex
|
|||
|
|
|||
|
mov ebx,edi
|
|||
|
|
|||
|
add ebx,[esi]CDrawPolygonBase.fxLineLength.i4Fx
|
|||
|
sar ebx,16
|
|||
|
|
|||
|
mov esi, [ecx]CRasterBase.pSurface
|
|||
|
|
|||
|
sar edi,16
|
|||
|
lea ecx,[edx+ebx]
|
|||
|
|
|||
|
sub edi,ebx
|
|||
|
jge INC_BASE_EDGE // no pixels
|
|||
|
|
|||
|
mov ebx,[eax]TShadowTrans32.indCoord.bfU.u4Frac // UFrac
|
|||
|
mov edx,[eax]TShadowTrans32.indCoord.w1dV.bfxValue.i4Int // UInt
|
|||
|
|
|||
|
lea esi,[esi + ecx*2]
|
|||
|
mov ecx,[eax]TShadowTrans32.indCoord.bfU.i4Int
|
|||
|
|
|||
|
add edx,ecx // VInt
|
|||
|
mov ecx,[eax]TShadowTrans32.indCoord.w1dV.bfxValue.u4Frac // VFrac
|
|||
|
|
|||
|
mov ah,[u1ShadowIntensity] // Load shadow value
|
|||
|
|
|||
|
//------------------------------------------------------------------------------
|
|||
|
LIN_LOOP:
|
|||
|
and edx,[u4TextureTileMask] // Tiling mask
|
|||
|
add ecx,[w2dDeltaTex]CWalk2D.uVFrac // V step
|
|||
|
|
|||
|
sbb ebp,ebp // Carry from V step
|
|||
|
add ebx,[w2dDeltaTex]CWalk2D.uUFrac // U step
|
|||
|
|
|||
|
mov al,byte ptr [0xDEADC0DE + edx*4] // Byte of source texture
|
|||
|
LIN_TEXTURE_MODIFYB1:
|
|||
|
mov ebp,[w2dDeltaTex + ebp*4 + 4]CWalk2D.iUVInt // Lokup integer step
|
|||
|
|
|||
|
adc edx,ebp // Integer step
|
|||
|
test al,al // Test for transparency.
|
|||
|
|
|||
|
jz short TRANS
|
|||
|
|
|||
|
// insert the shadow colour into the destination raster
|
|||
|
mov byte ptr[esi + edi*2 + 1],ah
|
|||
|
|
|||
|
TRANS:
|
|||
|
inc edi
|
|||
|
jnz short LIN_LOOP
|
|||
|
|
|||
|
// -------------------------------------------------------------------------
|
|||
|
INC_BASE_EDGE:
|
|||
|
mov eax, pscanShadow32
|
|||
|
mov edi, fx_inc
|
|||
|
|
|||
|
mov ebx,[eax]TShadowTrans32.fxXDifference
|
|||
|
mov ecx,[eax]TShadowTrans32.indCoord.bfU // bottom 32 bits
|
|||
|
add ebx,fx_diff
|
|||
|
mov edx,[eax+4]TShadowTrans32.indCoord.bfU // top 32 bits
|
|||
|
add [eax]TShadowTrans32.fxX, edi
|
|||
|
add ecx,DWORD PTR [bf_u_inc]
|
|||
|
mov edi, [eax]TShadowTrans32.indCoord.w1dV.bfxValue.i4Int
|
|||
|
adc edx,DWORD PTR [bf_u_inc+4]
|
|||
|
mov esi, [eax]TShadowTrans32.indCoord.w1dV.bfxValue.u4Frac
|
|||
|
// Add the integer portions together.
|
|||
|
add edi, w1d_v_inc.bfxValue.i4Int
|
|||
|
// Add the fractional portions together, and add an extra step value if a carry
|
|||
|
// results.
|
|||
|
add esi, w1d_v_inc.bfxValue.u4Frac
|
|||
|
jnc short SKIP_STEP_ADD1
|
|||
|
add edi, [eax]TShadowTrans32.indCoord.w1dV.iOffsetPerLine
|
|||
|
SKIP_STEP_ADD1:
|
|||
|
|
|||
|
cmp ebx, 0x00010000
|
|||
|
jl short XDIFF_LESS
|
|||
|
// do this if greater than or equal
|
|||
|
|
|||
|
sub ebx, 0x00010000
|
|||
|
|
|||
|
add edi, w1dNegDV.bfxValue.i4Int
|
|||
|
|
|||
|
add ecx, DWORD PTR [bfNegDU]
|
|||
|
adc edx, DWORD PTR [bfNegDU+4]
|
|||
|
|
|||
|
add esi, w1dNegDV.bfxValue.u4Frac
|
|||
|
jnc short EDGE_DONE
|
|||
|
add edi, [eax]TShadowTrans32.indCoord.w1dV.iOffsetPerLine
|
|||
|
jmp short EDGE_DONE
|
|||
|
|
|||
|
XDIFF_LESS:
|
|||
|
cmp ebx,0
|
|||
|
jge short EDGE_DONE
|
|||
|
// do this if less than 0
|
|||
|
|
|||
|
add ebx, 0x00010000
|
|||
|
add edi, w1dNegDV.bfxValue.i4Int
|
|||
|
add ecx, DWORD PTR [bfNegDU]
|
|||
|
adc edx, DWORD PTR [bfNegDU+4]
|
|||
|
add esi, w1dNegDV.bfxValue.u4Frac
|
|||
|
jnc short EDGE_DONE
|
|||
|
add edi, [eax]TShadowTrans32.indCoord.w1dV.iOffsetPerLine
|
|||
|
|
|||
|
EDGE_DONE:
|
|||
|
// -------------------------------------------------------------------------
|
|||
|
// store all the working variables back to the original raster
|
|||
|
// and also interleave the co-ordinate update variables..
|
|||
|
mov [eax]TShadowTrans32.indCoord.w1dV.bfxValue.u4Frac, esi
|
|||
|
mov esi,pdtriShadow32
|
|||
|
mov [eax]TShadowTrans32.indCoord.bfU, ecx
|
|||
|
mov [eax]TShadowTrans32.indCoord.w1dV.bfxValue.i4Int, edi
|
|||
|
mov [eax]TShadowTrans32.fxXDifference, ebx
|
|||
|
mov ecx,[esi]TAccess.prasScreen
|
|||
|
mov [eax]TShadowTrans32.indCoord.bfU+4, edx
|
|||
|
mov edi,[esi]CDrawPolygonBase.fxDeltaLineLength.i4Fx
|
|||
|
mov ebp,[esi]CDrawPolygonBase.iY
|
|||
|
mov edx,[ecx]CRasterBase.iLinePixels
|
|||
|
add [esi]CDrawPolygonBase.fxLineLength.i4Fx, edi
|
|||
|
inc ebp
|
|||
|
add [esi]CDrawPolygonBase.iLineStartIndex, edx
|
|||
|
cmp ebp,[esi]CDrawPolygonBase.iYTo
|
|||
|
mov [esi]CDrawPolygonBase.iY, ebp
|
|||
|
jl LIN_NEXT_SCAN_LINE
|
|||
|
pop ebp
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#endif // elif (iBUMPMAP_RESOLUTION == 32)
|