/*********************************************************************************************** * * Copyright © 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* pdtri) { typedef CDrawPolygon 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* pdtri) { typedef CDrawPolygon 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* pdtri) { typedef CDrawPolygon 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* pdtri) { typedef CDrawPolygon 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* pdtri) { typedef CDrawPolygon 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* pdtri) { typedef CDrawPolygon 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)