📄 hxflightarm.s
字号:
wsrad wr8, wr8, wr15
; *************
; Pack normal into wr2
wunpckilh wr6, wr6, wr8
wunpckilh wr7, wr7, wr14
wunpckilh wr2, wr6, wr7
b LOAD_NORMAL_RETURN
ENDP
;** ************************************************************************ **
; Name: LoadNormalize*NormalProc
; Description: Load normals into HNormal format in wr2
; ---------------------------------------------------------------------- --
; Register Map - Light Preamble
; ---------------------------------------------------------------------- --
; r0 = pState r4 = r8 = r12 = pOutVtx
; r1 = Flags r5 = r9 = r13 = sp
; r2 = r6 = Load Addr 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
; ---------------------------------------------------------------------- --
;** ************************************************************************ **
|HXFLoadNormalizeFIXEDNormalProc| PROC
ldr r2, [r6] ; load n.x
ldr r3, [r6, #4] ; load n.y
ldr r4, [r6, #8] ; load n.z
; unpack normal to Mantissa, exp repr
HXF_SIGNED_CLZ r6, r2
HXF_SIGNED_CLZ r7, r3
HXF_SIGNED_CLZ r8, r4
; Compute largest LZ count
cmp r6, r7
movgt r6, r7
cmp r6, r8
movgt r6, r8
; compute proper shift amount.
rsbs r6, r6, #8
add r5, r6, #7
rsblt r6, r6, #0
movlt r2, r2, lsl r6
movlt r3, r3, lsl r6
movlt r4, r4, lsl r6
movgt r2, r2, asr r6
movgt r3, r3, asr r6
movgt r4, r4, asr r6
b NormalizeNormal ;
ENDP
|HXFLoadNormalizeINT8NormalProc| PROC
ldrsb r2, [r6]
ldrsb r3, [r6, #1]
ldrsb r4, [r6, #2]
; unpack normal to Mantissa, exp repr
HXF_SIGNED_CLZ r6, r2
HXF_SIGNED_CLZ r7, r3
HXF_SIGNED_CLZ r8, r4
; Compute largest LZ count
cmp r6, r7
movgt r6, r7
cmp r6, r8
movgt r6, r8
; compute proper shift amount.
rsbs r6, r6, #8
add r5, r6, #15
rsblt r6, r6, #0
movlt r2, r2, lsl r6
movlt r3, r3, lsl r6
movlt r4, r4, lsl r6
movgt r2, r2, asr r6
movgt r3, r3, asr r6
movgt r4, r4, asr r6
b NormalizeNormal ;
ENDP
|HXFLoadNormalizeINT16NormalProc| PROC
ldrsh r2, [r6]
ldrsh r3, [r6, #2]
ldrsh r4, [r6, #4]
; unpack normal to Mantissa, exp repr
HXF_SIGNED_CLZ r6, r2
HXF_SIGNED_CLZ r7, r3
HXF_SIGNED_CLZ r8, r4
; Compute largest LZ count
cmp r6, r7
movgt r6, r7
cmp r6, r8
movgt r6, r8
; compute proper shift amount.
rsbs r6, r6, #8
add r5, r6, #8
rsblt r6, r6, #0
movlt r2, r2, lsl r6
movlt r3, r3, lsl r6
movlt r4, r4, lsl r6
movgt r2, r2, asr r6
movgt r3, r3, asr r6
movgt r4, r4, asr r6
b NormalizeNormal ;
ENDP
;** ************************************************************************ **
; Name: Load*DiffuseColor
; Description:
; ---------------------------------------------------------------------- --
; Register Map - Light Preamble
; ---------------------------------------------------------------------- --
; r0 = pState r4 = r8 = r12 =
; r1 = Flags r5 = Input Fmt r9 = r13 = sp
; r2 = r6 = Load Addr r10 = r14 = link
; r3 = r7 = Preserve 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 = 1 = wr15 =
; wcgr0 = 16 wcgr1 = 12 wcgr2 = 8 wcgr3 = 32
; ---------------------------------------------------------------------- --
;** ************************************************************************ **
|HXFLoadUINT8DiffuseColorProc| PROC
wldrw wr4, [r6] ; HXF_VF_UINT8
wunpckelub wr4, wr4
wsllhg wr3, wr4, wcgr2
wshufh wr3, wr3, #0xC6 ; ABGR(11 10 01 00) to ARGB (11 00 01 10)
b LOAD_DIFFUSE_RETURN
ENDP
|HXFLoadPACKEDDiffuseColorProc| PROC
wldrd wr3, [r6] ; HXF_VF_PACKED
b LOAD_DIFFUSE_RETURN
ENDP
|HXFLoadFIXEDDiffuseColorProc| PROC
wldrw wr15, [r6] ; r
wldrw wr13, [r6, #4] ; g
wldrw wr5, [r6, #8] ; b
wldrw wr4, [r6, #12] ; a
wslldg wr4, wr4, wcgr3 ;ar
wor wr4, wr4, wr15
wslldg wr13, wr13, wcgr3 ;gb
wor wr13, wr13, wr5
wmaxsw wr4, wr4, wr14 ;Clamp < 0 to 0
wmaxsw wr13, wr13, wr14
wpackwus wr3, wr13, wr4 ; Clamp >0x10000 to 0xFFFF
wmaxsw wr4, wr4, wr14 ;Clamp < 0 to 0
wmaxsw wr13, wr13, wr14
wpackwus wr3, wr13, wr4 ; Clamp >0x10000 to 0xFFFF
b LOAD_DIFFUSE_RETURN
ENDP
;** ************************************************************************ **
; Name: HXFLightVertex
; Description: Called only from the optimized Transform pipe(HXFTranformVertices)
; Uses a custom calling convention for this interface.
;
; NOTE: Color arithmetic Colors are treated as 16 bit quantities. Stored as unsigned 0.16 quantities
; ---------------------------------------------------------------------------
; D = Vertex Diffuse Accumulator
; S = Vertex Specular Accumulator
; N = Vertex Normal
; vD = Vertex Diffuse Color
; VL = Vertex Light Normal
; LN = VL dot N
; SX = normalize(LV(??) + EyeVector)
; SdotN= S dot N
; att = Attenuation value (4.12 format)
; ---------------------------------------------------------------------------
; Basic algorithm:
; 1. Load emissive
; 2. Load Vertex Ambient (va)
; 3. Load calc global ambient
; if Lights enabled NumLights != 0
; 4. Load Vertex Normal (N)
; 5. Load Vertex Diffuse (vd)
; 6. Load Vertex Specular (vs) if Specular Enable
; Iterate Lights
; 7. Load Light
; 8. Calculate Distance Sqr, and Inverse Distance (DSqr, InvD)
; 9. Calculate Vertex to Light Normal (VL)
; 10. Calculate Attenuation (att)
; 11. Spot Calculations
; a.
; 12. Load Light Ambient (la)
; 13. Calculate Light Ambient lAmbC = (va*la)
; 14. Calculate Light Effect LdotN = dotproduct(VL, N)
; 15. Load Light Diffuse (ld)
; 16. Calculate Light Diffuse term att * LdotN * (ld*vd) + lAmbC
; 17. Calculate Specular
; a. Compute S (VL + EyeVector)
; b. Compute SdotN = dotproduct(S, N)
;
; End Light Loop
; 18. Combine diffuse and specular (if not SEPERATE_SPECULAR)
; 19. store output color
;
; ---------------------------------------------------------------------------
; Input Arguments:
; ---------------------------------------------------------------------------
; r0 - HXFState* pState [must preserve]
; r1 - Flags [must preserve]
; r12 - out vertex pointer
; r13 - Stack Pointer
; r14(lr) - Return address
; Expects wcgr0 to be set to 16
; Expects wcgr1 to be set to 4
; Expects wcgr2 to be set to 8
; Expects wcgr3 to be set to 32
; Expects wr14 to be 0
; wr11-wr12 - [must preserved]
; Prototype in C: N/A
;** ************************************************************************ **
|HXFLightVertex| PROC
str lr, [r0, #HXFSTATE_OFFSET_STORAGE_LR] ; Store link register
; ---------------------------------------------------------------------- --
; Register Map - Light Preamble
; ---------------------------------------------------------------------- --
; r0 = pState r4 = r8 = r12 = pOutVtx
; r1 = flags r5 = r9 = r13 = sp
; r2 = r6 = r10 = r14 =
; 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
; ---------------------------------------------------------------------- --
wzero wr1 ; ensure specular is black to start with
; *************
; Load emissive color
wldrd wr0, [r0, #HXFSTATE_OFFSET_MATERIALEMISSIVE] ; set initial value to wr0
; *************
; AMBIENT COLOR
; ************* Vertex diffuse color
tst r1, #HXF_LM_COLOR_CONSTANT
wzero wr3
bne LOAD_DIFFUSE_RETURN
; Only load diffuse if it is not constant
ldrd r6, [r0, #HXFSTATE_OFFSET_PINDIFFUSE]
ldr r5, [r0, #HXFSTATE_OFFSET_LOADDIFFUSEPROC]
add r7, r6, r7 ; update the diffuse pointer
str r7, [r0, #HXFSTATE_OFFSET_PINDIFFUSE]
mov pc, r5 ; Branch to the diffuse load
LOAD_DIFFUSE_RETURN
; *************
; GLOBAL AMBIENT COLOR - Calc global ambient - accumulate into wr0
wldrd wr5, [r0, #HXFSTATE_OFFSET_MATERIALAMBIENT] ; Load global ambient color
tst r1, #HXF_LM_COLOR_CONSTANT
wmulumeq wr5, wr3, wr5 ; Compute global ambient * vertex Ambient
waddhus wr0, wr0, wr5 ; accumulate global ambient into diffuse
; -------------------------------------------------------------------------
; *************
; Setup for per light calculation
ldr r11, [r0, #HXFSTATE_OFFSET_PLIGHTS] ; Load Light Pointer
cmp r11, #0
beq STORE_COLORS ; no lights
; *************
; Load vertex normal
ldrd r6, [r0, #HXFSTATE_OFFSET_PINNORMAL]
ldr r5, [r0, #HXFSTATE_OFFSET_LOADNORMALPROC]
add r7, r6, r7 ; update the normal pointer
str r7, [r0, #HXFSTATE_OFFSET_PINNORMAL]
mov pc, r5 ; Branch to the Normal load
LOAD_NORMAL_RETURN
tst r1, #HXF_LIGHTING_INVERT_NORMALS
wsubhne wr2, wr14, wr2 ; Negate the normal direction
LIGHT_LOOP
; ---------------------------------------------------------------------- --
; Register Map - Loop Loop
; ---------------------------------------------------------------------- --
; r0 = pState r4 = r8 = r12 = pOutVtx
; r1 = flags r5 = r9 = r13 = sp
; r2 = r6 = r10 = r14 =
; 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
; ---------------------------------------------------------------------- --
; Call the light proc
ldr r10, [r11, #HXFLIGHT_OFFSET_PROC]
; FIXME Stall
mov pc, r10
NEXT_LIGHT ; *************
ldr r11, [r11, #HXFLIGHT_OFFSET_PNEXT]
cmp r11, #0 ; FIXME STALL
bne LIGHT_LOOP
STORE_COLORS; ************* Store the vertex colors
; ---------------------------------------------------------------------- --
; Register Map - Store Colors
; ---------------------------------------------------------------------- --
; r0 = pState r4 = r8 = r12 = pOutVtx
; r1 = flags r5 = r9 = r13 = sp
; r2 = r6 = r10 = r14 =
; r3 = r7 = r11 = r15 = pc
; ---------------------------------------------------------------------- --
; wr0 = out diff(D) wr4 = wr8 = wr12 = 0xFFFF0000
; wr1 = out spec(S) wr5 = wr9 = wr13 =
; wr2 = wr6 = wr10 = wr14 = Zero
; wr3 = wr7 = wr11 = 0x04040404wr15 =
; wcgr0 = 16 wcgr1 = 12 wcgr2 = 8 wcgr3 = 32
; ---------------------------------------------------------------------- --
ldr r2, [r0, #HXFSTATE_OFFSET_OUTDIFFUSEOFFSET]
; TBD add options for Seperate specular
waddhus wr0, wr0, wr1 ; Combine Specular and Diffuse
add r2, r12, r2 ; Compute the Diffuse offset
wsrlhg wr0, wr0, wcgr2
wpackhus wr0, wr0, wr14
wstrw wr0, [r2]
ldr pc, [r0, #HXFSTATE_OFFSET_STORAGE_LR] ; Store the link register
ENDP
;** ************************************************************************ **
END
;/* ************************************************************************ *\
;** ************************************************************************ **
;** EOF
;** ************************************************************************ **
;\* ************************************************************************ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -