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
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
|