Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1378 lines
44 KiB

;-----------------------------------------------------------------------------
;
; This file contains x86 assembly attribute setup.
;
; Copyright (C) Microsoft Corporation, 1997.
;
; WARNING WARNING WARNING
; This assembly file generated from mas file.
; EDIT THE MAS FILE.
; I warned you.
; WARNING WARNING WARNING
;
;-----------------------------------------------------------------------------
include(`m4hdr.mh')dnl
.386p
.MODEL FLAT
INCLUDE offs_acp.inc
INCLUDE profile.inc
INCLUDE texdiff.inc
EXTERN @ComputeTableFog@8:NEAR
EXTERN _g_fOne:DWORD
.CODE
dnl
dnl d_CorrectAttr
dnl
dnl Generates code to compute the DX and DY steps, the
dnl corrected scaled initial value and the NC and CY steps.
dnl
dnl ebx is assumed to be the PSETUPCTX.
dnl $1 is the ATTRSET offset of the value being corrected.
dnl $2 is the name of the uncorrected initial value.
dnl $3 is the name of the DAttr20 value.
dnl $4 is the name of the DAttr10 value.
dnl $5 is the name of the scale to apply to the initial value before
dnl correction.
dnl
define(`d_CorrectAttr',
` fld DWORD PTR [ebx+SCTX_fNY10] ; NY10
fmul DWORD PTR $3 ; DXp
fld DWORD PTR [ebx+SCTX_fNY20] ; NY20 DXp
fmul DWORD PTR $4 ; DXn DXp
fld DWORD PTR [ebx+SCTX_fNX20] ; NX20 DXn DXp
fmul DWORD PTR $4 ; DYp DXn DXp
fxch st(2) ; DXp DXn DYp
fld DWORD PTR [ebx+SCTX_fNX10] ; NX10 DXp DXn DYp
fmul DWORD PTR $3 ; DYn DXp DXn DYp
fxch st(2) ; DXn DXp DYn DYp
fsubp st(1), st(0) ; DX DYn DYp
fld DWORD PTR $2 ; 0 DX DYn DYp
fmul DWORD PTR $5 ; 0 DX DYn DYp
fxch st(3) ; DYp DX DYn 0
fld DWORD PTR [ebx+SCTX_fDX] ; fDX DYp DX DYn 0
fmul st(0), st(2) ; cX DYp DX DYn 0
fxch st(3) ; DYn DYp DX cX 0
fsubp st(1), st(0) ; DY DX cX 0
fxch st(3) ; 0 DX cX DY
fld DWORD PTR [ebx+SCTX_fX20NC] ; iNC 0 DX cX DY
fmul st(0), st(2) ; XNC 0 DX cX DY
fxch st(3) ; cX 0 DX XNC DY
faddp st(1), st(0) ; c0X DX XNC DY
fld DWORD PTR [ebx+SCTX_fDY] ; fDY c0X DX XNC DY
fmul st(0), st(4) ; cY c0X DX XNC DY
fxch st(3) ; XNC c0X DX cY DY
fadd st(0), st(4) ; NC c0X DX cY DY
fxch st(1) ; c0X NC DX cY DY
fld DWORD PTR [ebx+SCTX_fX20CY] ; iCY c0X NC DX cY DY
fmul st(0), st(3) ; XCY c0X NC DX cY DY
fxch st(4) ; cY c0X NC DX XCY DY
faddp st(1), st(0) ; c0 NC DX XCY DY
fxch st(1) ; NC c0 DX XCY DY
fstp DWORD PTR [ebx+SCTX_DAttrNC+$1] ; c0 DX XCY DY
fxch st(1) ; DX c0 XCY DY
fstp DWORD PTR [ebx+SCTX_DAttrDX+$1] ; c0 XCY DY
fxch st(1) ; XCY c0 DY
fadd st(0), st(2) ; CY c0 DY
fxch st(1) ; c0 CY DY
fstp DWORD PTR [ebx+SCTX_Attr+$1] ; CY DY
fxch st(1) ; DY CY
fstp DWORD PTR [ebx+SCTX_DAttrDY+$1] ; CY
fstp DWORD PTR [ebx+SCTX_DAttrCY+$1] ;
')dnl
dnl
dnl d_NegateDeltas
dnl
dnl If X_DEC, negates the given list of deltas in DAttrDX.
dnl
dnl $1 is the name of the block for labels.
dnl Following arguments are ATTRSET offsets in the DAttrDX to process.
dnl
dnl Leaves uFlags in eax.
dnl
define(`d_NegateDeltaLoop',
` mov eax, [ebx+SCTX_DAttrDX+$1]
xor eax, 080000000h
mov [ebx+SCTX_DAttrDX+$1], eax
ifelse(eval($# > 1), `1', `d_NegateDeltaLoop(d_shift($@))')')dnl
dnl
define(`d_NegateDeltas',
` mov eax, [ebx+SCTX_uFlags]
test eax, TRIF_X_DEC
jz L_NDXDZ_$1
; X_DEC. Negate deltas.
d_NegateDeltaLoop(d_shift($@))dnl
mov eax, [ebx+SCTX_uFlags]
L_NDXDZ_$1:
')dnl
dnl
dnl d_CheckRpDeltas
dnl
dnl Checks given list of deltas against the given limit for
dnl setting of TRIF_RASTPRIM_OVERFLOW. The delta comparisons
dnl can be done in pure integer because the numbers involved are
dnl always positive.
dnl
dnl RASTPRIM filling is usually done in the non-overflow block so
dnl arbitrary processing can be done there by defining the d_CRPD_Post macro
dnl before invocation of this one.
dnl
dnl $1 is the name of the block for labels.
dnl $2 is the name of the limit.
dnl Following arguments are deltas offsets in the SETUPCTX to check.
dnl
dnl Relies on uFlags being in eax at the start. Leaves uFlags in eax.
dnl
define(`d_CheckRpDeltaLoop',
` mov eax, [ebx+$3]
and eax, 07fffffffh
cmp eax, $2
jge L_RPOD_$1
ifelse(eval($# > 3), `1',
`d_CheckRpDeltaLoop($1, $2, d_shift(d_shift(d_shift($@))))')')dnl
dnl
define(`d_CheckRpDeltas',
` test eax, TRIF_RASTPRIM_OVERFLOW
jnz L_RPOD_NoLoad_$1
d_CheckRpDeltaLoop($@)dnl
; No overflow. Do valid delta processing.
d_CRPD_Post(d_shift($@))
mov eax, [ebx+SCTX_uFlags]
jmp L_RP_Exit_$1
L_RPOD_$1:
; Overflow detected.
mov eax, [ebx+SCTX_uFlags]
L_RPOD_NoLoad_$1:
or eax, TRIF_RASTPRIM_OVERFLOW
mov [ebx+SCTX_uFlags], eax
L_RP_Exit_$1:
')dnl
dnl
dnl d_CheckFxDeltas
dnl
dnl Checks given list of deltas against the given limit for
dnl setting of TRIF_FIXED_OVERFLOW. The delta comparisons
dnl can be done in pure integer because the numbers involved are
dnl always positive.
dnl
dnl $1 is the name of the block for labels.
dnl $2 is the name of the limit.
dnl Following arguments are ATTRSET offsets in NC and CY to check.
dnl
define(`d_CheckFxDeltaLoop',
` mov eax, [ebx+SCTX_DAttrNC+$3]
and eax, 07fffffffh
cmp eax, $2
jge L_FXOD_$1
mov eax, [ebx+SCTX_DAttrCY+$3]
and eax, 07fffffffh
cmp eax, $2
jge L_FXOD_$1
ifelse(eval($# > 3), `1',
`d_CheckFxDeltaLoop($1, $2, d_shift(d_shift(d_shift($@))))')')dnl
dnl
define(`d_CheckFxDeltas',
`IFDEF STEP_FIXED
test eax, TRIF_FIXED_OVERFLOW
jnz L_FXOD_NoLoad_$1
d_CheckFxDeltaLoop($@)dnl
; No overflow.
jmp L_FX_Exit_$1
L_FXOD_$1:
; Overflow detected.
mov eax, [ebx+SCTX_uFlags]
L_FXOD_NoLoad_$1:
or eax, TRIF_FIXED_OVERFLOW
mov [ebx+SCTX_uFlags], eax
L_FX_Exit_$1:
ENDIF
')dnl
dnl
dnl d_ZSetup
dnl
dnl Does Z setup.
dnl
dnl $1 is the Z buffer depth.
dnl
define(`d_ZSetup',
` ;
; Slot a is used.
;
; Compute Z deltas.
fld DWORD PTR [edx+TL_dvSZ] ; Z2
fsub DWORD PTR [edi+TL_dvSZ] ; DZ20
fld DWORD PTR [ecx+TL_dvSZ] ; Z1 DZ20
fsub DWORD PTR [edi+TL_dvSZ] ; DZ10 DZ20
; Get initial Z and scale Z deltas.
mov eax, [edi+TL_dvSZ]
fxch st(1) ; DZ20 DZ10
fmul Z$1_SCALE ; DZ20 DZ10
fxch st(1) ; DZ10 DZ20
fmul Z$1_SCALE ; DZ10 DZ20
mov fVa0, eax
fxch st(1) ; DZ20 DZ10
fstp fDVa20 ; DZ10
fstp fDVa10 ;
d_CorrectAttr(`ATTRSET_fZ', `fVa0', `fDVa20', `fDVa10', Z$1_SCALE)dnl
d_NegateDeltas(Z$1, `ATTRSET_fZ')dnl
pushdef(`d_CRPD_Post',
` mov eax, [ebx+SCTX_pPrim]
fld DWORD PTR [ebx+SCTX_DAttrDX+ATTRSET_fZ]
fistp DWORD PTR [eax+RASTPRIM_iDZDX]
')dnl
d_CheckRpDeltas(Z$1, `C_Z_LIMIT', `SCTX_DAttrDX+ATTRSET_fZ')dnl
popdef(`d_CRPD_Post')dnl
d_CheckFxDeltas(Z$1, `C_Z_LIMIT', `ATTRSET_fZ')dnl
; Jump to next bead.
jmp DWORD PTR [ebx+SCTX_pfnTriSetupZEnd]
')dnl
dnl
dnl d_TexSetupStart
dnl
dnl Begins texture coordinate setup.
dnl
dnl iTex is the texcoord index, 0 ... 7.
dnl
define(`d_TexSetupStart',
` mov eax, iTex
mov ecx, DWORD PTR [esi+RS_WRAP0+eax * 4] ; Wrap flags
mov eax, ecx
and ecx, D3DWRAP_U
and eax, D3DWRAP_V
mov bWrapU, ecx
mov ecx, pV1
mov bWrapV, eax
')dnl
dnl
dnl d_TexSetupFinish
dnl
dnl Completes texture coordinate setup.
dnl
dnl iTex is the texcoord index, 0 ... 7.
dnl
define(`d_TexSetupFinish',
` mov ecx, iTex
d_CorrectAttr(ATTRSET_fUoW + ecx * 4, `fVa0', `fDVa20', `fDVa10', `TEX_SCALE')dnl
d_CorrectAttr(ATTRSET_fVoW + ecx * 4, `fVb0', `fDVb20', `fDVb10', `TEX_SCALE')dnl
d_NegateDeltas(Tex, ATTRSET_fUoW + ecx * 4, ATTRSET_fVoW + ecx * 4)dnl
pushdef(`d_CRPD_Post',
` mov eax, [ebx+SCTX_pPrim]
mov ecx, iTex
fld DWORD PTR [ebx+SCTX_DAttrDX+ATTRSET_fUoW + ecx * 4]
fistp DWORD PTR [eax+RASTPRIM_DUVoWDX + ecx * 8]
fld DWORD PTR [ebx+SCTX_DAttrDY+ATTRSET_fUoW + ecx * 4]
fistp DWORD PTR [eax+RASTPRIM_DUVoWDY + ecx * 8]
fld DWORD PTR [ebx+SCTX_DAttrDX+ATTRSET_fVoW + ecx * 4]
fistp DWORD PTR [eax+RASTPRIM_DUVoWDX + ecx * 8 + 4]
fld DWORD PTR [ebx+SCTX_DAttrDY+ATTRSET_fVoW + ecx * 4]
fistp DWORD PTR [eax+RASTPRIM_DUVoWDY + ecx * 8 + 4]
')dnl
d_CheckRpDeltas(Tex, `C_TEX_LIMIT',
SCTX_DAttrDX+ATTRSET_fUoW + ecx * 4,
SCTX_DAttrDY+ATTRSET_fUoW + ecx * 4,
SCTX_DAttrDX+ATTRSET_fVoW + ecx * 4,
SCTX_DAttrDY+ATTRSET_fVoW + ecx * 4)dnl
popdef(`d_CRPD_Post')dnl
d_CheckFxDeltas(Tex, `C_TEX_LIMIT', ATTRSET_fUoW + ecx * 4, ATTRSET_fVoW + ecx * 4)dnl
')dnl
dnl
dnl d_PerspTexDeltas
dnl
dnl Computes UoW,VoW texture deltas.
dnl
dnl
define(`d_PerspTexDeltas',
` ; Get UoW, VoW and scaled deltas.
mov eax, iTex
fld DWORD PTR [edi+TM_texCoord+eax*8] ; U
fmul DWORD PTR [edi+TL_dvRHW] ; UoW
fld DWORD PTR [edi+TM_texCoord+eax*8+4] ; V UoW
fmul DWORD PTR [edi+TL_dvRHW] ; VoW UoW
fxch st(1) ; UoW VoW
fstp fVa0 ; VoW
fstp fVb0 ;
; DU20.
TEXTURE_DIFF DWORD PTR [edx+TM_texCoord+eax*8], DWORD PTR [edi+TM_texCoord+eax*8], bWrapU, fTmp
mov eax, iTex
fadd DWORD PTR [edi+TM_texCoord+eax*8]
mov ecx, pV1
fmul DWORD PTR [edx+TL_dvRHW]
; DU10.
TEXTURE_DIFF DWORD PTR [ecx+TM_texCoord+eax*8], DWORD PTR [edi+TM_texCoord+eax*8], bWrapU, fTmp
fxch st(1)
mov ecx, pV1
; DU20.
fsub fVa0
fmul TEX_SCALE
fstp fDVa20
; DU10.
mov eax, iTex
fadd DWORD PTR [edi+TM_texCoord+eax*8]
fmul DWORD PTR [ecx+TL_dvRHW]
; DV20.
TEXTURE_DIFF DWORD PTR [edx+TM_texCoord+eax*8+4], DWORD PTR [edi+TM_texCoord+eax*8+4], bWrapV, fTmp
fxch st(1)
mov ecx, pV1
; DU10.
fsub fVa0
fmul TEX_SCALE
fstp fDVa10
; DV20.
mov eax, iTex
fadd DWORD PTR [edi+TM_texCoord+eax*8+4]
fmul DWORD PTR [edx+TL_dvRHW]
; DV10.
TEXTURE_DIFF DWORD PTR [ecx+TM_texCoord+eax*8+4], DWORD PTR [edi+TM_texCoord+eax*8+4], bWrapV, fTmp
fxch st(1)
mov ecx, pV1
; DV20.
fsub fVb0
fmul TEX_SCALE
fstp fDVb20
; Finish DV10.
mov eax, iTex
fadd DWORD PTR [edi+TM_texCoord+eax*8+4]
fmul DWORD PTR [ecx+TL_dvRHW]
fsub fVb0
fmul TEX_SCALE
fstp fDVb10
')dnl
dnl
dnl d_PerspTexSetup
dnl
dnl Produces perspective-correct texcoord setup code.
dnl
dnl $1 is the vertex U offset to use.
dnl $2 is the vertex V offset to use.
dnl $3 is the texcoord index, 1 or 2.
dnl
define(`d_PerspTexSetup',
` xor eax, eax
mov iTex, eax
LoopPerspTexSetup:
mov ecx, [ebx + SCTX_pCtx]
cmp eax, DWORD PTR [ecx + RCTX_cActTex]
jge DonePerspTexSetup
d_TexSetupStart()dnl
d_PerspTexDeltas()dnl
d_TexSetupFinish()dnl
mov eax, iTex
inc eax
mov iTex, eax
jmp LoopPerspTexSetup
DonePerspTexSetup:
')dnl
dnl
dnl d_AffineTexDeltas
dnl
dnl Computes U,V texture deltas.
dnl
dnl $1 is the vertex U offset to use.
dnl $2 is the vertex V offset to use.
dnl
define(`d_AffineTexDeltas',
` ; Get scaled deltas.
; Start DU20.
mov eax, iTex
mov eax, [edi+TM_texCoord+eax*8]
; Save U in fVa0
mov fVa0, eax
mov eax, iTex
TEXTURE_DIFF DWORD PTR [edx+TM_texCoord+eax*8], DWORD PTR [edi+TM_texCoord+eax*8], bWrapU, fTmp
fmul TEX_SCALE
mov ecx, pV1
fstp fDVa20
; DU10.
mov eax, iTex
TEXTURE_DIFF DWORD PTR [ecx+TM_texCoord+eax*8], DWORD PTR [edi+TM_texCoord+eax*8], bWrapU, fTmp
fmul TEX_SCALE
mov ecx, pV1
; Start DV20.
mov eax, iTex
mov eax, [edi+TM_texCoord+eax*8+4]
; Save V in fVb0
mov fVb0, eax
; DU10.
fstp fDVa10
; DV20.
mov eax, iTex
TEXTURE_DIFF DWORD PTR [edx+TM_texCoord+eax*8+4], DWORD PTR [edi+TM_texCoord+eax*8+4], bWrapV, fTmp
fmul TEX_SCALE
mov ecx, pV1
; DV20.
fstp fDVb20
; DV10.
mov eax, iTex
TEXTURE_DIFF DWORD PTR [ecx+TM_texCoord+eax*8+4], DWORD PTR [edi+TM_texCoord+eax*8+4], bWrapV, fTmp
fmul TEX_SCALE
mov ecx, pV1
fstp fDVb10
')dnl
dnl
dnl d_AffineTexSetup
dnl
dnl Produces affine-mapped texcoord setup code.
dnl
dnl $1 is the vertex U offset to use.
dnl $2 is the vertex V offset to use.
dnl $3 is the texcoord index, 1 or 2.
dnl
define(`d_AffineTexSetup',
` mov eax, 0
mov iTex, eax
LoopAffineTexSetup:
mov ecx, [ebx + SCTX_pCtx]
cmp eax, DWORD PTR [ecx + RCTX_cActTex]
je DoneAffineTexSetup
d_TexSetupStart()dnl
d_AffineTexDeltas()dnl
d_TexSetupFinish()dnl
mov eax, iTex
inc eax
mov iTex, eax
jmp LoopAffineTexSetup
DoneAffineTexSetup:
')dnl
dnl
dnl d_ColorDelta
dnl
dnl Produces color B - A code.
dnl
dnl $1 is the packed color address to use.
dnl $2 is the edge suffix, `2' or `1'.
dnl
define(`d_ColorDelta',
` ; A0 R0 G0 B0 sit at the end of the stack throughout.
mov eax, [$1]
mov ecx, eax
; B is in the correct shifted position.
and eax, 0ffh
mov fTmp, eax
fild fTmp ; B
; Shift G and store.
mov eax, ecx
shr eax, 8
and eax, 0ffh
mov fTmp, eax
fsub st(0), st(4) ; dB
fild fTmp ; G dB
; Shift R and store.
mov eax, ecx
shr eax, 16
and eax, 0ffh
mov fTmp, eax
fsub st(0), st(4) ; dG dB
fild fTmp ; R dG dB
; Shift A and store.
mov eax, ecx
shr eax, 24
mov fTmp, eax
fsub st(0), st(4) ; dR dG dB
fild fTmp ; A dR dG dB
; Scale deltas.
fxch st(3) ; dB dR dG A
fmul COLOR_SCALE ; dB dR dG A
fxch st(3) ; A dR dG dB
fsub st(0), st(4) ; dA dR dG dB
fxch st(2) ; dG dR dA dB
fmul COLOR_SCALE ; dG dR dA dB
fxch st(1) ; dR dG dA dB
fmul COLOR_SCALE ; dR dG dA dB
fxch st(2) ; dA dG dR dB
fmul COLOR_SCALE ; dA dG dR dB
fxch st(3) ; dB dG dR dA
fstp fDVa$2`'0 ; dG dR dA
fstp fDVb$2`'0 ; dR dA
fstp fDVc$2`'0 ; dA
fstp fDVd$2`'0 ;
')dnl
dnl
dnl d_SColorDelta
dnl
dnl Produces specular color B - A code.
dnl
dnl $1 is the packed color address to use.
dnl $2 is the edge suffix, `2' or `1'.
dnl
define(`d_SColorDelta',
` ; R0 G0 B0 sit at the end of the stack throughout.
mov eax, [$1]
mov ecx, eax
; B is in the correct shifted position.
and eax, 0ffh
mov fTmp, eax
fild fTmp ; B
; Shift G and store.
mov eax, ecx
shr eax, 8
and eax, 0ffh
mov fTmp, eax
fsub st(0), st(3) ; dB
fild fTmp ; G dB
; Shift R and store.
mov eax, ecx
shr eax, 16
and eax, 0ffh
mov fTmp, eax
fsub st(0), st(3) ; dG dB
fild fTmp ; R dG dB
; Scale deltas.
fxch st(2) ; dB dG R
fmul COLOR_SCALE ; dB dG R
fxch st(2) ; R dG dB
fsub st(0), st(3) ; dR dG dB
fxch st(1) ; dG dR dB
fmul COLOR_SCALE ; dG dR dB
fxch st(1) ; dR dG dB
fmul COLOR_SCALE ; dR dG dB
fxch st(2) ; dB dG dR
fstp fDVa$2`'0 ; dG dR
fstp fDVb$2`'0 ; dR
fstp fDVc$2`'0 ;
')dnl
dnl
dnl d_IdxColorDelta
dnl
dnl Produces indexed color B - A code.
dnl
dnl $1 is the packed color address to use.
dnl $2 is the edge suffix, `2' or `1'.
dnl
define(`d_IdxColorDelta',
` ; A0 Idx0 sit at the end of the stack throughout.
mov eax, [$1]
mov ecx, eax
; Mask off alpha.
and eax, 0ffffffh
add eax, 128
mov fTmp, eax
fild fTmp ; Idx
; Shift A and store.
shr ecx, 24
mov fTmp, ecx
fsub st(0), st(2) ; dIdx
fild fTmp ; A dIdx
; Scale deltas.
fxch st(1) ; dIdx A
fmul INDEX_COLOR_FIXED_SCALE ; dIdx A
fxch st(1) ; A dIdx
fsub st(0), st(2) ; dA dIdx
fxch st(1) ; dIdx dA
fstp fDVa$2`'0 ; dA
fmul INDEX_COLOR_SCALE ; dA
fstp fDVb$2`'0 ;
')dnl
dnl
dnl d_ColorSetup
dnl
dnl Produces color setup code.
dnl
dnl $1 is the vertex packed color offset to use.
dnl $2 is the color suffix, `' or `S'.
dnl
define(`d_ColorSetup',
` ; Get colors from pV0.
mov eax, [edi+$1]
mov ecx, eax
; B is in the correct shifted position.
and eax, 0ffh
mov fVa0, eax
fild fVa0 ; B
; Shift G and store.
mov eax, ecx
shr eax, 8
and eax, 0ffh
mov fVb0, eax
fild fVb0 ; G B
; Shift R and store.
mov eax, ecx
shr eax, 16
and eax, 0ffh
mov fVc0, eax
fild fVc0 ; R G B
ifelse($2, `',
` ; Shift A and store.
mov eax, ecx
shr eax, 24
mov fVd0, eax
fild fVd0 ; A R G B
')dnl
; Get colors from pV2 and subtract pV0.
d_$2ColorDelta(edx+$1, `2')dnl
; Get colors from pV1 and subtract pV0.
mov ecx, pV1
d_$2ColorDelta(ecx+$1, `1')dnl
mov ecx, pV1
; Store initial values.
ifelse($2, `',
` fxch st(3) ; B R G A
fstp fVa0 ; R G A
fxch st(1) ; G R A
fstp fVb0 ; R A
fstp fVc0 ; A
fstp fVd0 ;
',
` fxch st(2) ; B G R
fstp fVa0 ; G R
fstp fVb0 ; R
fstp fVc0 ;
')dnl
d_CorrectAttr(ATTRSET_fB$2, `fVa0', `fDVa20', `fDVa10', `COLOR_SCALE')dnl
d_CorrectAttr(ATTRSET_fG$2, `fVb0', `fDVb20', `fDVb10', `COLOR_SCALE')dnl
d_CorrectAttr(ATTRSET_fR$2, `fVc0', `fDVc20', `fDVc10', `COLOR_SCALE')dnl
ifelse($2, `',
`d_CorrectAttr(ATTRSET_fA$2, `fVd0', `fDVd20', `fDVd10', `COLOR_SCALE')dnl
d_NegateDeltas(Col$2, ATTRSET_fB$2, ATTRSET_fG$2,
ATTRSET_fR$2, ATTRSET_fA$2)dnl
pushdef(`d_CRPD_Post',
` mov eax, [ebx+SCTX_pPrim]
fld DWORD PTR [ebx+SCTX_DAttrDX+ATTRSET_fB$2]
fistp DWORD PTR [eax+RASTPRIM_iDB$2DX]
fld DWORD PTR [ebx+SCTX_DAttrDX+ATTRSET_fG$2]
fistp DWORD PTR [eax+RASTPRIM_iDG$2DX]
fld DWORD PTR [ebx+SCTX_DAttrDX+ATTRSET_fR$2]
fistp DWORD PTR [eax+RASTPRIM_iDR$2DX]
fld DWORD PTR [ebx+SCTX_DAttrDX+ATTRSET_fA$2]
fistp DWORD PTR [eax+RASTPRIM_iDA$2DX]
')dnl
d_CheckRpDeltas(Col$2, `C_COLOR_LIMIT',
SCTX_DAttrDX+ATTRSET_fB$2,
SCTX_DAttrDX+ATTRSET_fR$2,
SCTX_DAttrDX+ATTRSET_fG$2,
SCTX_DAttrDX+ATTRSET_fA$2)dnl
popdef(`d_CRPD_Post')dnl
d_CheckFxDeltas(Col$2, `C_COLOR_LIMIT',
ATTRSET_fB$2, ATTRSET_fG$2, ATTRSET_fR$2, ATTRSET_fA$2)',
`d_NegateDeltas(Col$2, ATTRSET_fB$2, ATTRSET_fG$2,
ATTRSET_fR$2)dnl
pushdef(`d_CRPD_Post',
` mov eax, [ebx+SCTX_pPrim]
fld DWORD PTR [ebx+SCTX_DAttrDX+ATTRSET_fB$2]
fistp DWORD PTR [eax+RASTPRIM_iDB$2DX]
fld DWORD PTR [ebx+SCTX_DAttrDX+ATTRSET_fG$2]
fistp DWORD PTR [eax+RASTPRIM_iDG$2DX]
fld DWORD PTR [ebx+SCTX_DAttrDX+ATTRSET_fR$2]
fistp DWORD PTR [eax+RASTPRIM_iDR$2DX]
')dnl
d_CheckRpDeltas(Col$2, `C_COLOR_LIMIT',
SCTX_DAttrDX+ATTRSET_fB$2,
SCTX_DAttrDX+ATTRSET_fR$2,
SCTX_DAttrDX+ATTRSET_fG$2)dnl
popdef(`d_CRPD_Post')dnl
d_CheckFxDeltas(Col$2, `C_COLOR_LIMIT',
ATTRSET_fB$2, ATTRSET_fG$2, ATTRSET_fR$2)')dnl
')dnl
;
; Locations of stack variables.
; Done as equates since setup functions don't have real stack frames.
;
; Generic storage slots for initial value and deltas.
fVa0 EQU DWORD PTR [ebp-4]
fDVa20 EQU DWORD PTR [ebp-8]
fDVa10 EQU DWORD PTR [ebp-12]
fVb0 EQU DWORD PTR [ebp-16]
fDVb20 EQU DWORD PTR [ebp-20]
fDVb10 EQU DWORD PTR [ebp-24]
fVc0 EQU DWORD PTR [ebp-28]
fDVc20 EQU DWORD PTR [ebp-32]
fDVc10 EQU DWORD PTR [ebp-36]
fVd0 EQU DWORD PTR [ebp-40]
fDVd20 EQU DWORD PTR [ebp-44]
fDVd10 EQU DWORD PTR [ebp-48]
fTmp EQU DWORD PTR [ebp-52]
bWrapU EQU DWORD PTR [ebp-56]
bWrapV EQU DWORD PTR [ebp-60]
iTex EQU DWORD PTR [ebp-64]
SETUP_LOCALS EQU 64
; Parameters
pV1 EQU DWORD PTR [ebp+20]
pV2 EQU DWORD PTR [ebp+24]
dnl d_DeclTriSetup
dnl
dnl Declare a PFN_SETUPATTR from its attribute name.
dnl
dnl $1 is the attribute name.
dnl
define(`d_DeclTriSetup',
`@TriSetup_$1@16 PROC SYSCALL PUBLIC
PROF_ENTRY
')dnl
define(`d_EndDeclTriSetup',
`@TriSetup_$1@16 ENDP
')dnl
dnl
;-----------------------------------------------------------------------------
;
; Setup_Start
;
; Establishes the stack frame for all setup routines, including
; preservation of registers and allocation of local storage space.
; Scales deltas by fOoDet.
; Puts pStpCtx in ebx, pV0 in edi, pV1 in ecx, pV2 in edx and
; pdwRenderState in esi.
; Jumps to first attribute setup bead.
;
;-----------------------------------------------------------------------------
d_DeclTriSetup(`Start')dnl
; Save registers.
push ebx
push esi
push edi
; Set frame after saving registers so saving more or fewer
; doesnt alter the locals.
push ebp
mov ebp, esp
; Allocate local storage space.
sub esp, SETUP_LOCALS
; Put pStpCtx in ebx.
mov ebx, ecx
; Put pV0 in edi, pV1 in ecx and pV2 in edx.
mov edi, edx
mov ecx, pV1
mov edx, pV2
; Fold normalization value into deltas.
fld DWORD PTR [ebx+SCTX_fDX10] ; DX10
fmul DWORD PTR [ebx+SCTX_fOoDet] ; NX10
fld DWORD PTR [ebx+SCTX_fDX20] ; DX20 NX10
fmul DWORD PTR [ebx+SCTX_fOoDet] ; NX20 NX10
mov eax, [ebx+SCTX_pCtx]
fld DWORD PTR [ebx+SCTX_fDY10] ; DY10 NX20 NX10
fmul DWORD PTR [ebx+SCTX_fOoDet] ; NY10 NX20 NX10
fld DWORD PTR [ebx+SCTX_fDY20] ; DY20 NY10 NX20 NX10
fmul DWORD PTR [ebx+SCTX_fOoDet] ; NY20 NY10 NX20 NX10
fxch st(3) ; NX10 NY10 NX20 NY20
fstp DWORD PTR [ebx+SCTX_fNX10] ; NY10 NX20 NY20
fxch st(1) ; NX20 NY10 NY20
fstp DWORD PTR [ebx+SCTX_fNX20] ; NY10 NY20
; Get pdwRenderState in esi.
; Now that pdwRenderState is an array of DWORD declared in the context,
; its address is the address of the context plus the offset
mov esi, eax
add esi, RCTX_pdwRenderState
fstp DWORD PTR [ebx+SCTX_fNY10] ; NY20
fstp DWORD PTR [ebx+SCTX_fNY20] ;
; Jump to first bead.
jmp DWORD PTR [ebx+SCTX_pfnTriSetupFirstAttr]
d_EndDeclTriSetup(`Start')dnl
;-----------------------------------------------------------------------------
;
; Setup_Z16
;
; Attribute setup for 16-bit Z.
;
;-----------------------------------------------------------------------------
d_DeclTriSetup(`Z16')dnl
d_ZSetup(`16')dnl
d_EndDeclTriSetup(`Z16')dnl
;-----------------------------------------------------------------------------
;
; Setup_Z32
;
; Attribute setup for 32-bit Z.
;
;-----------------------------------------------------------------------------
d_DeclTriSetup(`Z32')dnl
d_ZSetup(`32')dnl
d_EndDeclTriSetup(`Z32')dnl
;-----------------------------------------------------------------------------
;
; Setup_Persp_Tex
;
; Attribute setup for OoW and first texture coordinates.
; Coordinates are set up for perspective correction.
;
;-----------------------------------------------------------------------------
d_DeclTriSetup(`Persp_Tex')dnl
;
; Setup for OoW. Slot a is used.
;
; Compute OoW deltas.
fld DWORD PTR [edx+TL_dvRHW] ; OoW2
fsub DWORD PTR [edi+TL_dvRHW] ; DOoW20
fld DWORD PTR [ecx+TL_dvRHW] ; OoW1 DOoW20
fsub DWORD PTR [edi+TL_dvRHW] ; DOoW10 DOoW20
; Scale OoW deltas.
fxch st(1) ; DOoW20 DOoW10
fmul OOW_SCALE ; DOoW20 DOoW10
fxch st(1) ; DOoW10 DOoW20
fmul OOW_SCALE ; DOoW10 DOoW20
fxch st(1) ; DOoW20 DOoW10
fstp fDVa20 ; DOoW10
fstp fDVa10 ;
d_CorrectAttr(`ATTRSET_fOoW', `DWORD PTR [edi+TL_dvRHW]',
`fDVa20', `fDVa10', `OOW_SCALE')dnl
d_NegateDeltas(`OoW', `ATTRSET_fOoW')dnl
pushdef(`d_CRPD_Post',
` mov eax, [ebx+SCTX_pPrim]
fld DWORD PTR [ebx+SCTX_DAttrDX+ATTRSET_fOoW]
fistp DWORD PTR [eax+RASTPRIM_iDOoWDX]
fld DWORD PTR [ebx+SCTX_DAttrDY+ATTRSET_fOoW]
fistp DWORD PTR [eax+RASTPRIM_iDOoWDY]
')dnl
d_CheckRpDeltas(`OoW', `C_OOW_LIMIT',
`SCTX_DAttrDX+ATTRSET_fOoW',
`SCTX_DAttrDY+ATTRSET_fOoW')dnl
popdef(`d_CRPD_Post')dnl
d_CheckFxDeltas(`OoW', `C_OOW_LIMIT', `ATTRSET_fOoW')dnl
;
; Setup for tex. Slot a is used for U and b for V.
;
d_PerspTexSetup(`TL_dvTU', `TL_dvTV', `1')dnl
; Jump to next bead.
jmp DWORD PTR [ebx+SCTX_pfnTriSetupTexEnd]
d_EndDeclTriSetup(`Persp_Tex')dnl
;-----------------------------------------------------------------------------
;
; Setup_Affine_Tex
;
; Attribute setup for OoW and first texture coordinates.
; Coordinates are set up for affine mapping.
;
;-----------------------------------------------------------------------------
d_DeclTriSetup(`Affine_Tex')dnl
;
; Setup for OoW. Slot a is used.
;
mov eax, OOW_SCALE
mov [ebx+SCTX_Attr+ATTRSET_fOoW], eax
xor eax, eax
mov [ebx+SCTX_DAttrDX+ATTRSET_fOoW], eax
mov [ebx+SCTX_DAttrDY+ATTRSET_fOoW], eax
mov [ebx+SCTX_DAttrNC+ATTRSET_fOoW], eax
mov [ebx+SCTX_DAttrCY+ATTRSET_fOoW], eax
mov ecx, [ebx+SCTX_pPrim]
mov [ecx+RASTPRIM_iDOoWDX], eax
mov [ecx+RASTPRIM_iDOoWDY], eax
mov ecx, pV1
;
; Setup for tex. Slot a is used for U and b for V.
;
d_AffineTexSetup(`TL_dvTU', `TL_dvTV', `1')dnl
; Jump to next bead.
jmp DWORD PTR [ebx+SCTX_pfnTriSetupTexEnd]
d_EndDeclTriSetup(`Affine_Tex')dnl
;-----------------------------------------------------------------------------
;
; Setup_Diff
;
; Attribute setup for interpolated diffuse color.
;
;-----------------------------------------------------------------------------
d_DeclTriSetup(`Diff')dnl
;
; Slots a - d are B, G, R and A, respectively.
;
d_ColorSetup(`TL_dcColor', `')dnl
; Jump to next bead.
jmp DWORD PTR [ebx+SCTX_pfnTriSetupDiffEnd]
d_EndDeclTriSetup(`Diff')dnl
;-----------------------------------------------------------------------------
;
; Setup_DiffFlat
;
; Attribute setup for constant diffuse color.
;
;-----------------------------------------------------------------------------
d_DeclTriSetup(`DiffFlat')dnl
;
; Slots a - d are B, G, R and A, respectively.
;
; Get colors from first input vertex. Can't just use pV0
; because it may have changed due to vertex sorting.
mov eax, [ebx+SCTX_pFlatVtx]
mov eax, [eax+TL_dcColor]
mov ecx, eax
; G is in the correct shifted position.
and eax, 0ff00h
mov fVb0, eax
fild fVb0 ; G
; Shift B and store.
mov eax, ecx
shl eax, COLOR_SHIFT
and eax, 0ff00h
mov fVa0, eax
fild fVa0 ; B G
; Shift R and store.
mov eax, ecx
shr eax, (16 - COLOR_SHIFT)
and eax, 0ff00h
mov fVc0, eax
fild fVc0 ; R B G
; Shift A and store.
mov eax, ecx
shr eax, (24 - COLOR_SHIFT)
and eax, 0ff00h
mov fVd0, eax
fild fVd0 ; A R B G
fxch st(3) ; G R B A
fstp DWORD PTR [ebx+SCTX_Attr+ATTRSET_fG] ; R B A
fxch st(1) ; B R A
fstp DWORD PTR [ebx+SCTX_Attr+ATTRSET_fB] ; R A
fstp DWORD PTR [ebx+SCTX_Attr+ATTRSET_fR] ; A
fstp DWORD PTR [ebx+SCTX_Attr+ATTRSET_fA] ;
; Zero out all deltas.
xor eax, eax
mov ecx, [ebx+SCTX_pPrim]
mov [ebx+SCTX_DAttrDX+ATTRSET_fB], eax
mov [ebx+SCTX_DAttrDX+ATTRSET_fG], eax
mov [ebx+SCTX_DAttrDX+ATTRSET_fR], eax
mov [ebx+SCTX_DAttrDX+ATTRSET_fA], eax
mov [ebx+SCTX_DAttrDY+ATTRSET_fB], eax
mov [ebx+SCTX_DAttrDY+ATTRSET_fG], eax
mov [ebx+SCTX_DAttrDY+ATTRSET_fR], eax
mov [ebx+SCTX_DAttrDY+ATTRSET_fA], eax
mov [ebx+SCTX_DAttrNC+ATTRSET_fB], eax
mov [ebx+SCTX_DAttrNC+ATTRSET_fG], eax
mov [ebx+SCTX_DAttrNC+ATTRSET_fR], eax
mov [ebx+SCTX_DAttrNC+ATTRSET_fA], eax
mov [ebx+SCTX_DAttrCY+ATTRSET_fB], eax
mov [ebx+SCTX_DAttrCY+ATTRSET_fG], eax
mov [ebx+SCTX_DAttrCY+ATTRSET_fR], eax
mov [ebx+SCTX_DAttrCY+ATTRSET_fA], eax
; Fills both B and G.
mov [ecx+RASTPRIM_iDBDX], eax
; Fills both R and A.
mov [ecx+RASTPRIM_iDRDX], eax
mov ecx, pV1
; Jump to next bead.
jmp DWORD PTR [ebx+SCTX_pfnTriSetupDiffEnd]
d_EndDeclTriSetup(`DiffFlat')dnl
;-----------------------------------------------------------------------------
;
; Setup_DIdx
;
; Attribute setup for interpolated diffuse indexed color.
;
;-----------------------------------------------------------------------------
d_DeclTriSetup(`DIdx')dnl
;
; Slots a, b are Idx and A, respectively.
;
; Get values from pV0.
mov eax, [edi+TL_dcColor]
mov ecx, eax
; Mask off alpha.
and eax, 0ffffffh
add eax, 128
mov fVa0, eax
fild fVa0 ; Idx
; Shift A and store.
shr ecx, 24
mov fVb0, ecx
fild fVb0 ; A Idx
; Get colors from pV2 and subtract pV0.
d_IdxColorDelta(edx+TL_dcColor, `2')dnl
; Get colors from pV1 and subtract pV0.
mov ecx, pV1
d_IdxColorDelta(ecx+TL_dcColor, `1')dnl
mov ecx, pV1
; Store initial values.
fstp fVb0 ; Idx
fstp fVa0 ;
d_CorrectAttr(ATTRSET_fDIdx, `fVa0', `fDVa20', `fDVa10',
`INDEX_COLOR_FIXED_SCALE')dnl
d_CorrectAttr(ATTRSET_fDIdxA, `fVb0', `fDVb20', `fDVb10',
`INDEX_COLOR_SCALE')dnl
d_NegateDeltas(IdxCol, ATTRSET_fDIdx, ATTRSET_fDIdxA)dnl
pushdef(`d_CRPD_Post',
` mov eax, [ebx+SCTX_pPrim]
fld DWORD PTR [ebx+SCTX_DAttrDX+ATTRSET_fDIdx]
fistp DWORD PTR [eax+RASTPRIM_iDIdxDX]
fld DWORD PTR [ebx+SCTX_DAttrDX+ATTRSET_fDIdxA]
fistp DWORD PTR [eax+RASTPRIM_iDIdxADX]
')dnl
d_CheckRpDeltas(IdxCol, `C_INDEX_COLOR_LIMIT',
SCTX_DAttrDX+ATTRSET_fDIdx,
SCTX_DAttrDX+ATTRSET_fDIdxA)dnl
popdef(`d_CRPD_Post')dnl
d_CheckFxDeltas(IdxCol, `C_INDEX_COLOR_LIMIT',
ATTRSET_fDIdx, ATTRSET_fDIdxA)dnl
; Jump to next bead.
jmp DWORD PTR [ebx+SCTX_pfnTriSetupDiffEnd]
d_EndDeclTriSetup(`DIdx')dnl
;-----------------------------------------------------------------------------
;
; Setup_DIdxFlat
;
; Attribute setup for constant diffuse indexed color.
;
;-----------------------------------------------------------------------------
d_DeclTriSetup(`DIdxFlat')dnl
;
; Slots a, b are Idx and A, respectively.
;
; Get colors from first input vertex. Can't just use pV0
; because it may have changed due to vertex sorting.
mov eax, [ebx+SCTX_pFlatVtx]
mov eax, [eax+TL_dcColor]
mov ecx, eax
; Mask off alpha and shift.
shl eax, INDEX_COLOR_FIXED_SHIFT
; Should not be necessary to add .5 to Idx, since
; no floating point ops are done to it
mov fVa0, eax
fild fVa0 ; Idx
; Shift A and store.
shr ecx, (24 - INDEX_COLOR_SHIFT)
and ecx, 0ffffffh
mov fVb0, ecx
fild fVb0 ; A Idx
fxch st(1) ; Idx A
fstp DWORD PTR [ebx+SCTX_Attr+ATTRSET_fDIdx] ; A
fstp DWORD PTR [ebx+SCTX_Attr+ATTRSET_fDIdxA] ;
; Zero out all deltas.
xor eax, eax
mov ecx, [ebx+SCTX_pPrim]
mov [ebx+SCTX_DAttrDX+ATTRSET_fDIdx], eax
mov [ebx+SCTX_DAttrDX+ATTRSET_fDIdxA], eax
mov [ebx+SCTX_DAttrDY+ATTRSET_fDIdx], eax
mov [ebx+SCTX_DAttrDY+ATTRSET_fDIdxA], eax
mov [ebx+SCTX_DAttrNC+ATTRSET_fDIdx], eax
mov [ebx+SCTX_DAttrNC+ATTRSET_fDIdxA], eax
mov [ebx+SCTX_DAttrCY+ATTRSET_fDIdx], eax
mov [ebx+SCTX_DAttrCY+ATTRSET_fDIdxA], eax
mov [ecx+RASTPRIM_iDIdxDX], eax
mov [ecx+RASTPRIM_iDIdxADX], eax
mov ecx, pV1
; Jump to next bead.
jmp DWORD PTR [ebx+SCTX_pfnTriSetupDiffEnd]
d_EndDeclTriSetup(`DIdxFlat')dnl
;-----------------------------------------------------------------------------
;
; Setup_Spec
;
; Attribute setup for interpolated specular color.
;
;-----------------------------------------------------------------------------
d_DeclTriSetup(`Spec')dnl
;
; Slots a - c are B, G and R, respectively.
;
d_ColorSetup(`TL_dcSpecular', `S')dnl
; Jump to next bead.
jmp DWORD PTR [ebx+SCTX_pfnTriSetupSpecEnd]
d_EndDeclTriSetup(`Spec')dnl
;-----------------------------------------------------------------------------
;
; Setup_SpecFlat
;
; Attribute setup for constant specular color.
;
;-----------------------------------------------------------------------------
d_DeclTriSetup(`SpecFlat')dnl
;
; Slots a - c are B, G and R, respectively.
;
; Get colors from first input vertex. Can't just use pV0
; because it may have changed due to vertex sorting.
mov eax, [ebx+SCTX_pFlatVtx]
mov eax, [eax+TL_dcSpecular]
mov ecx, eax
; G is in the correct shifted position.
and eax, 0ff00h
mov fVb0, eax
fild fVb0 ; G
; Shift B and store.
mov eax, ecx
shl eax, 8
and eax, 0ff00h
mov fVa0, eax
fild fVa0 ; B G
; Shift R and store.
mov eax, ecx
shr eax, 8
and eax, 0ff00h
mov fVc0, eax
fild fVc0 ; R B G
fxch st(2) ; G B R
fstp DWORD PTR [ebx+SCTX_Attr+ATTRSET_fGS] ; B R
fstp DWORD PTR [ebx+SCTX_Attr+ATTRSET_fBS] ; R
fstp DWORD PTR [ebx+SCTX_Attr+ATTRSET_fRS] ;
; Zero out all deltas.
xor eax, eax
mov ecx, [ebx+SCTX_pPrim]
mov [ebx+SCTX_DAttrDX+ATTRSET_fBS], eax
mov [ebx+SCTX_DAttrDX+ATTRSET_fGS], eax
mov [ebx+SCTX_DAttrDX+ATTRSET_fRS], eax
mov [ebx+SCTX_DAttrDY+ATTRSET_fBS], eax
mov [ebx+SCTX_DAttrDY+ATTRSET_fGS], eax
mov [ebx+SCTX_DAttrDY+ATTRSET_fRS], eax
mov [ebx+SCTX_DAttrNC+ATTRSET_fBS], eax
mov [ebx+SCTX_DAttrNC+ATTRSET_fGS], eax
mov [ebx+SCTX_DAttrNC+ATTRSET_fRS], eax
mov [ebx+SCTX_DAttrCY+ATTRSET_fBS], eax
mov [ebx+SCTX_DAttrCY+ATTRSET_fGS], eax
mov [ebx+SCTX_DAttrCY+ATTRSET_fRS], eax
; Fills both B and G.
mov [ecx+RASTPRIM_iDBSDX], eax
; Fills both R and Fog. Fog will be set up later, if at all,
; so it's OK to trash it here.
mov [ecx+RASTPRIM_iDRSDX], eax
mov ecx, pV1
; Jump to next bead.
jmp DWORD PTR [ebx+SCTX_pfnTriSetupSpecEnd]
d_EndDeclTriSetup(`SpecFlat')dnl
;-----------------------------------------------------------------------------
;
; Setup_Fog
;
; Attribute setup for vertex fog.
;
;-----------------------------------------------------------------------------
d_DeclTriSetup(`Fog')dnl
;
; Slot a is used with some temporaries in b and c.
;
IFNDEF PWL_FOG
; Check for global-into-local fog. If global fog is on,
; compute the local fog values from table fog rather than
; from the vertex.
mov eax, [ebx+SCTX_uFlags]
test eax, PRIMSF_GLOBAL_FOG_USED
jz L_NormalLocalFog
;
; Compute table fog values for all three vertex Z values.
;
; pV1
push DWORD PTR [ecx+TL_dvSZ]
mov ecx, esi
call @ComputeTableFog@8
mov fVb0, eax
; pV0
push DWORD PTR [edi+TL_dvSZ]
mov ecx, esi
call @ComputeTableFog@8
; Keep V0 fog in fTmp so that we can write the FP value
; into fVa0.
mov fTmp, eax
; pV2
mov edx, pV2
push DWORD PTR [edx+TL_dvSZ]
mov ecx, esi
call @ComputeTableFog@8
mov fVc0, eax
; Restore pV1 and pV2.
mov ecx, pV1
mov edx, pV2
jmp L_ComputeFogDeltas
L_NormalLocalFog:
ENDIF
; Extract fog values from specular alpha and shift into position.
mov eax, [edi+TL_dcSpecular]
and eax, 0ff000000h
shr eax, 24 - FOG_SHIFT
; Keep V0 fog in fTmp so that we can write the FP value
; into fVa0.
mov fTmp, eax
mov eax, [ecx+TL_dcSpecular]
and eax, 0ff000000h
shr eax, 24 - FOG_SHIFT
mov fVb0, eax
mov eax, [edx+TL_dcSpecular]
and eax, 0ff000000h
shr eax, 24 - FOG_SHIFT
mov fVc0, eax
IFNDEF PWL_FOG
L_ComputeFogDeltas:
ENDIF
fild fTmp
; Compute fog deltas from shifted values in fVa?.
mov eax, fVc0
sub eax, fTmp
mov fDVa20, eax
fstp fVa0
fild fDVa20
mov eax, fVb0
sub eax, fTmp
mov fDVa10, eax
fstp fDVa20
fild fDVa10
fstp fDVa10
; fVa0 is already scaled so the scaling factor is given as 1.0.
; This is a little wasteful but it makes the above code simpler
; and more integer.
d_CorrectAttr(`ATTRSET_fFog', `fVa0', `fDVa20', `fDVa10', `_g_fOne')dnl
d_NegateDeltas(`Fog', `ATTRSET_fFog')dnl
pushdef(`d_CRPD_Post',
` ; Fog deltas are given per span rather than per primitive.
; Store local fog value in setup context so that it can be
; copied into the spans later.
fld DWORD PTR [ebx+SCTX_DAttrDX+ATTRSET_fFog]
fistp DWORD PTR [ebx+SCTX_iDLocalFogDX]
')dnl
d_CheckRpDeltas(`Fog', `C_FOG_LIMIT', `SCTX_DAttrDX+ATTRSET_fFog')dnl
popdef(`d_CRPD_Post')dnl
d_CheckFxDeltas(`Fog', `C_FOG_LIMIT', `ATTRSET_fFog')dnl
; Jump to next bead.
jmp DWORD PTR [ebx+SCTX_pfnTriSetupFogEnd]
d_EndDeclTriSetup(`Fog')dnl
;-----------------------------------------------------------------------------
;
; Setup_End
;
; Final bead. Restores stack and returns.
;
;-----------------------------------------------------------------------------
d_DeclTriSetup(`End')dnl
; Give up locals.
add esp, SETUP_LOCALS
; Restore registers.
pop ebp
pop edi
pop esi
pop ebx
ret 8
d_EndDeclTriSetup(`End')dnl
END