⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hxflightarm.s

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 S
📖 第 1 页 / 共 5 页
字号:
	; 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 + -