📄 hxflightarm.s
字号:
; wcgr0 = 16 wcgr1 = 12 wcgr2 = 8 wcgr3 = 32
; ---------------------------------------------------------------------- --
; calculate distance squared
wzero wr15
tmia wr15, r2, r2 ;
tmia wr15, r3, r3 ;
tmia wr15, r4, r4 ;
; CLZ on Dsquared
; if lz >= 16, fall through (Q16.16 path)
; if lz < 16, use 32.32 path
textrmsw r5, wr15, #1 ; grab top bits
clz r8, r5 ; CLZ on 32. value
cmp r8, #16
bgt DSQR16_16
DSQR32_32
; Grab the 32.0 value to get DSqr, then get a 0.32 value for InvD.
; we have the leading zeroes, and the 32 bits from the top of the 32.32 DSqr.
; To get to Fat Float, we need to shift right by CLZ - 8 bits
rsbs r8, r8, #8 ; prep exponent for mantissa shift
movge r7, r5, asr r8 ; shift mantissa right (if exp was pos)
rsblt r7, r8, #0
movlt r7, r5, lsl r7 ; shift mantissa left (if exp was neg)
add r8, r8, #23 ; shift exponent
; r5 = DSqr Q32
; r7 = DSqr mantissa FF
; r8 = DSqr Exponent FF
HXF_INVSQRT r7, r8, r6, r9, r10
; r5 = DSqr Q32
; r7 = InvD mantissa FF
; r8 = InvD exponent FF
; Convert to .32
mov r6, #9
adds r8, r6, r8
; mantisa
movgt r7, r7, lsl r8
rsblt r8, r8, #0
movlt r7, r7, lsr r8
; *************
; Compute VL
; Normalize the vector
wzero wr6
wzero wr7
wzero wr8
; Normalize VL * InvD
; *************
; Compute VL - Normalize the vector
tmia wr6, r2, r7 ; VL.x = InvD * X - r2 Free
mov r9, #34 ; Setup for the Shift convert 16.48 to 2.14
tmia wr7, r3, r7 ; VL.y = InvD * Y - r3 Free
tinsrw wr15, r9, #0 ; Setup for the Shift convert 16.48 to 2.14
tmia wr8, r4, r7 ; VL.z = InvD * Z - r4, r7 Free
wsrad wr6, wr6, wr15 ; Convert to 16 bits 2.14
wsrad wr7, wr7, wr15
wsrad wr8, wr8, wr15
; Pack up VL into wr8
wunpckilh wr6, wr6, wr8
wunpckilh wr7, wr7, wr14
wunpckilh wr8, wr6, wr7
; *************
; Calculate Attenuation
;
; 1
; -----------------------
; kC + DSqr(kL*InvD + kQ)
;
; ---------------------------------------------------------------------- --
; Register Map -
; ---------------------------------------------------------------------- --
; r0 = pState r4 = r8 = r12 = pOutVtx
; r1 = flags r5 = DSqr r9 = r13 = sp
; r2 = Att Const r6 = r10 = r14 = link
; r3 = Att Linear r7 = InvD r11 = pLight r15 = pc
; ---------------------------------------------------------------------- --
; wr0 = out diff(D) wr4 = wr8 = VL wr12 = 0xFFFF0000
; wr1 = out spec(S) wr5 = wr9 = Att wr13 =
; wr2 = vtx Norm(N) wr6 = wr10 = wr14 = Zero
; wr3 = vtx Diff(vD)wr7 = wr11 = 0x04040404wr15 =
; wcgr0 = 16 wcgr1 = 12 wcgr2 = 8 wcgr3 = 32
; ---------------------------------------------------------------------- --
ldr r2, [r11, #HXFLIGHT_OFFSET_ATTENUATIONLINEAR]
wldrw wr10, [r11, #HXFLIGHT_OFFSET_ATTENUATIONCONSTANT]
wldrw wr15, [r11, #HXFLIGHT_OFFSET_ATTENUATIONQUADRATIC]
; if Linear Att < 0 then att is disabled.
cmp r2, #0
movlt r2, #0x80000000
movlt r10, #0
blt SET_ATT
; 3-31-04 -- Att cannot be negative in OGL - Att constants tested to be >0
; DSqr == x^2+y^2+z^2 -> Must be positive - Sum of squares
; InvD = 1/sqrt(dSqr) -> Sqrt must be Positive
; att = (kL * InvD) + kQ
wslldg wr15, wr15, wcgr3 ; Convert KQ to 64bit
tmia wr15, r7, r2 ; (kL:r2 * InvD:r7) + kQ:wr15
textrmsw r6, wr15, #1 ;
; att = kC + (Dsqr*att)
tmia wr10, r5, r6 ; (DSqr:r5 * Att:r6) + kC:wr10
textrmsw r6, wr10, #0
; check for divide by zero - Skip this light (Infinite contribution)
cmp r6, #0 ; if(att == 0)
beq NEXT_LIGHT
; Normalize Manitssa
clz r5, r6
mov r4, r6, lsl r5
b ATT_RESULT
DSQR16_16
wsradg wr15, wr15, wcgr0 ; normalization of DSqr
textrmsw r5, wr15, #0 ; r2 = lv.x
cmp r5, #0 ; FIXME Add Delta
ble NEXT_LIGHT ; Light is on the vertex -- Skip the rest of the whacky math.
; Negative value is indicitive of an overflow. So get out.
; Negative values will cause AccVals on the InvSqrt.
; *************
; Calculate InvD - inverse sqrt of DSqr
mov r7, r5
HXF_INVSQRTFX r7, r8, r6, r9, r10
; *************
; Compute VL
; Normalize the vector
wzero wr6
wzero wr7
wzero wr8
; Normalize VL * InvD
; *************
; Compute VL - Normalize the vector
tmia wr6, r2, r7 ; VL.x = InvD * X - r2 Free
mov r9, #18 ; Setup for the Shift convert 32.32 to 2.14
tmia wr7, r3, r7 ; VL.y = InvD * Y - r3 Free
tinsrw wr15, r9, #0 ; Setup for the Shift convert 32.32 to 2.14
tmia wr8, r4, r7 ; VL.z = InvD * Z - r4, r7 Free
wsrad wr6, wr6, wr15 ; Convert to 16 bits 2.14
wsrad wr7, wr7, wr15
wsrad wr8, wr8, wr15
; Pack up VL into wr8
wunpckilh wr6, wr6, wr8
wunpckilh wr7, wr7, wr14
wunpckilh wr8, wr6, wr7
; *************
; Calculate Attenuation
;
; 1
; -----------------------
; kC + DSqr(kL*InvD + kQ)
;
; ---------------------------------------------------------------------- --
; Register Map -
; ---------------------------------------------------------------------- --
; r0 = pState r4 = r8 = r12 = pOutVtx
; r1 = flags r5 = DSqr r9 = r13 = sp
; r2 = Att Const r6 = r10 = r14 = link
; r3 = Att Linear r7 = InvD r11 = pLight r15 = pc
; ---------------------------------------------------------------------- --
; wr0 = out diff(D) wr4 = wr8 = VL wr12 = 0xFFFF0000
; wr1 = out spec(S) wr5 = wr9 = Att wr13 =
; wr2 = vtx Norm(N) wr6 = wr10 = wr14 = Zero
; wr3 = vtx Diff(vD)wr7 = wr11 = 0x04040404wr15 =
; wcgr0 = 16 wcgr1 = 12 wcgr2 = 8 wcgr3 = 32
; ---------------------------------------------------------------------- --
ldr r2, [r11, #HXFLIGHT_OFFSET_ATTENUATIONLINEAR]
wldrw wr10, [r11, #HXFLIGHT_OFFSET_ATTENUATIONCONSTANT]
wldrw wr15, [r11, #HXFLIGHT_OFFSET_ATTENUATIONQUADRATIC]
; if Linear Att < 0 then att is disabled.
cmp r2, #0
movlt r2, #0x80000000
movlt r10, #0
blt SET_ATT
; 3-31-04 -- Att cannot be negative in OGL - Att constants tested to be >0
; DSqr == x^2+y^2+z^2 -> Must be positive - Sum of squares
; InvD = 1/sqrt(dSqr) -> Sqrt must be Positive
; att = (kL * InvD) + kQ
wslldg wr15, wr15, wcgr0 ; Convert KQ to 64bit
tmia wr15, r7, r2 ; (kL:r2 * InvD:r7) + kQ:wr15
wslldg wr10, wr10, wcgr0 ; Convert KC to 64bit
wsradg wr15, wr15, wcgr0 ; Convert ATT to 32 bit fixed
textrmsw r6, wr15, #0 ;
; att = kC + (Dsqr*att)
tmia wr10, r5, r6 ; (DSqr:r5 * Att:r6) + kC:wr10
wsradg wr10, wr10, wcgr0 ; Convert ATT to 32 bit fixed
textrmsw r6, wr10, #0
; check for divide by zero - Skip this light (Infinite contribution)
cmp r6, #0 ; if(att == 0)
beq NEXT_LIGHT
; Normalize Manitssa
clz r5, r6
mov r4, r6, lsl r5
ATT_RESULT
; compute result exponent
rsb r5, r5, #15
rsb r10, r5, #0
; Convert Inverse - 8 bit divide
mov r2, #0
mov r3, #0x80000000
HXF_ONEBITDIVIDE 31, r3, r4, r2 ; 1
HXF_ONEBITDIVIDE 30, r3, r4, r2 ; 2
HXF_ONEBITDIVIDE 29, r3, r4, r2 ; 3
HXF_ONEBITDIVIDE 28, r3, r4, r2 ; 4
HXF_ONEBITDIVIDE 27, r3, r4, r2 ; 5
HXF_ONEBITDIVIDE 26, r3, r4, r2 ; 6
HXF_ONEBITDIVIDE 25, r3, r4, r2 ; 7
HXF_ONEBITDIVIDE 24, r3, r4, r2 ; 8
HXF_ONEBITDIVIDE 23, r3, r4, r2 ; 9
HXF_ONEBITDIVIDE 22, r3, r4, r2 ; 10
HXF_ONEBITDIVIDE 21, r3, r4, r2 ; 11
HXF_ONEBITDIVIDE 20, r3, r4, r2 ; 12
HXF_ONEBITDIVIDE 19, r3, r4, r2 ; 13
HXF_ONEBITDIVIDE 18, r3, r4, r2 ; 14
HXF_ONEBITDIVIDE 17, r3, r4, r2 ; 15
HXF_ONEBITDIVIDE 16, r3, r4, r2 ; 16
; Mantissa r2
; Exponent r10
; Check for Zero Attenuation
cmp r2, #0
beq NEXT_LIGHT
SET_ATT
; Ensure normalization
clz r3, r2
mov r2, r2, lsl r3
sub r10, r10, r3
; convert mantissa to 16 bit
mov r2, r2, lsr #16 ; convert mantissa to 0.16
add r10, r10, #1 ; convert exponent from 1.15 to 0.16
; Compute Shift
cmp r10, #0 ; if exponent is < 0 then just shift the exponent in to position
rsblt r10, r10, #0
movlt r2, r2, lsr r10
movlt r10, #0 ; clamp exp to 0
rsb r10, r10, #16
tinsrw wr10, r10, #0; store exp
; Compute mantissa
tbcsth wr9, r2 ; Store Attenuation in the proper wMMX Register
mov pc, lr
ENDP
|SpotEffect| PROC
; ---------------------------------------------------------------------- --
; Register Map - Compute Spot effect
; ---------------------------------------------------------------------- --
; r0 = pState r4 = r8 = r12 = pOutVtx
; r1 = flags r5 = r9 = r13 = sp
; r2 = r6 = r10 = r14 = link
; r3 = r7 = r11 = pLight r15 = pc
; ---------------------------------------------------------------------- --
; wr0 = out diff(D) wr4 = wr8 = VL wr12 = 0xFFFF0000
; wr1 = out spec(S) wr5 = wr9 = Att(0.16) wr13 =
; wr2 = vtx Norm(N) wr6 = wr10 = wr14 = Zero
; wr3 = vtx Diff(vD)wr7 = wr11 = 0x04040404wr15 =
; wcgr0 = 16 wcgr1 = 12 wcgr2 = 8 wcgr3 = 32
; ---------------------------------------------------------------------- --
mov r10, lr
ldrd r6, [r11, #HXFLIGHT_OFFSET_SPOTCUTOFF]
wldrd wr13, [r11, #HXFLIGHT_OFFSET_DIRECTION]
; Compute LV vector
wsubhss wr7, wr14, wr8 ; Make VL to LV
wmacsz wr13, wr13, wr7 ; Compute 4.28 spoteffect
textrmsw r2, wr13, #0
mov r2, r2, asr #12 ; convert spoteffect to 16.16
cmp r2, r6 ; test if we are in the spot range also catch <=0
blt NEXT_LIGHT ; we are out side the spot range no more for this light
; -------------------------------------------
cmp r7, #HFX_ONE
ble NO_SPOTPOWER
cmp r2, #HFX_ONE
bge NO_SPOTPOWER
stmfd sp!, {r0, r1, r3}
mov r0, r2
mov r1, r7 ;
bl Pow
mov r2, r0 ; check if we the spot effect valid
ldmfd sp!, {r0, r1, r3}
NO_SPOTPOWER
; -------------------------------------------
; Clamp 0-1
cmp r2, #0
ble NEXT_LIGHT ; Zero Spot effect bail
cmp r2, #HFX_ONE ; Don't bother if Spot Saturates
movge pc, r10
; factor spot effect into attenuation
tbcsth wr15, r2
wmulum wr9, wr9, wr15 ;Combine Att and Spot effect
mov pc, r10
ENDP
;** ************************************************************************ **
; Name: LightSpecular
; Description: Compute Light Specular Contribution
; ---------------------------------------------------------------------- --
; Register Map - Light Preamble
; ---------------------------------------------------------------------- --
; r0 = pState r4 = r8 = r12 = pOutVtx
; r1 = Flags r5 = r9 = r13 = sp
; r2 = r6 = r10 = (link) r14 = link
; r3 = r7 = r11 = pLight r15 = pc
; ---------------------------------------------------------------------- --
; wr0 = out diff(D) wr4 = wr8 = VL wr12 = 0xFFFF0000
; wr1 = out spec(S) wr5 = wr9 = Att(0.16) wr13 =
; wr2 = vtx Norm(N) wr6 = wr10 = Att Shift wr14 = Zero
; wr3 = vtx Diff(vD)wr7 = wr11 = 0x04040404wr15 =
; wcgr0 = 16 wcgr1 = 12 wcgr2 = 8 wcgr3 = 32
; ---------------------------------------------------------------------- --
;** ************************************************************************ **
|LightSpecular| PROC
mov r10, lr ; preserve lr
; Compute S
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -