📄 hxftransformarm.s
字号:
wzero wr1 ; r.y = 0
tmia wr1, r4, r7 ; r.y += v1.x * M_12
ldrd r6, [r3, #32] ; Load M_31 & M_32
tmia wr0, r5, r8 ; r.x += v1.y * M_21
tmia wr1, r5, r9 ; r.y += v1.y * M_22
ldrd r8, [r3, #48] ; Load M_41 & M_42
tmia wr0, r10, r6 ; r.x += v1.z * M_31
tmia wr1, r10, r7 ; r.y += v1.z * M_32
tmia wr0, r11, r8 ; r.x += v1.w * M_41
tmia wr1, r11, r9 ; r.y += v1.w * M_42
wsradg wr0, wr0, wcgr0 ; Shift adjust r.x
wsradg wr1, wr1, wcgr0 ; Shift adjust r.y
; Store off coordinates r.s and r.t
wstrw wr0, [r2]
wstrw wr1, [r2, #4]
mov pc, lr
ENDP
;** ************************************************************************ **
; Name: HXFTransformVertices
; Description: This is the optimized vertex transform and light function.
; ---------------------------------------------------------------------------
; Basic Algorithm - See HXFTranformVertices_ref function in HXFTransform_Ref.c
; for a C implementation.
; Processing steps:
; 1. Load and convert input vertices
; 2. Transform vertices
; 3. Generate clip flags
; 4. Light the vertex
; 5. Process Texture coordintes
; 6. update the output pointer
; 7. Loop.
;
; Steps 1, 2, 3 all happen together as a chain of function calls
; the load and convert calls the Transfrom function which calls
; the clip flag
; Input Arguments: r0 - HXFState* pState
; Output Argument: None;
; r0 - HXFState Pointer - all called fuctions must preserve
; r1 - Flags - Must be preserved by all called functions
; r2 - r11 - Free use.. Some submasks apply see docs in function headers
; r12 - output vertex - loop counter
; r13(sp) - Stack Pointer
; r14(lr) - Free use except when functions are called useing bl -- you know
; who you are.
; r15(pc) - program counter
; wr0 - wr15 - Free use some
; wcgr0 - (16)Fixed point conversion shift value.
; wcgr1 - (12) Used in lighting for Conversion of Vector DotProducts(4.28) to Colors(0.16).
; wcgr2 - (8) Byte size shift amount for use in optimized transform work.
; wcgr3 - (32) Value for optimized transform work.
; wr14 - set to zero
; Prototype in C: void HXFTranformVertices(HXFState* pState);
;** ************************************************************************ **
|HXFTransformVertices| PROC
stmfd sp!, {r4-r11, r14}
; Set up a shifter amount in the wMMX control register.
mov r1, #16 ; shift value for 32.32 to 16.16 conversion
tmcr wcgr0, r1
mov r1, #12 ; shift value for 6.26 to 0.16 conversion
tmcr wcgr1, r1
mov r1, #8 ; Byte shifter value for use in applying exponent adjustments.
tmcr wcgr2, r1
mov r1, #32 ; shift value for working in wMMX doing transforms.
tmcr wcgr3, r1
mov r1, #4 ; We need to add 4 to each adjustment value before we use it to shift the division result.
tbcstb wr11, r1
wzero wr14
wzero wr12
mov r1, #0x10000
sub r1, r1, #1
mov r1, r1 lsl #16
tinsrw wr12, r1, #0
; ************************************************************************
; Loop Setup
; Initialize the counter
ldr r12, [r0, #HXFSTATE_OFFSET_POUTVERTICES]
ldr r1, [r0, #HXFSTATE_OFFSET_FLAGS]
; ************************************************************************
HTV_BEGIN_VERTEX
; ************************************************************************
; 1. Load and convert the position
; Loads input position in r2, r3, r4
; branches to TransformPosition
; 2. Transform the position
; Called directly by the load proc
; expects input position in r2, r3, r4
; generates screen position in r5, r6, r7, r8
; if clipping is enabled calls ClipFlags else returns
; 3. Generate clip flags if needed
; expects screen position in in r5, r6, r7, r8
; returns to this functions at HTV_TNL_RETURN
ldrd r6, [r0, #HXFSTATE_OFFSET_PINPOSITION] ; Load Position pointer and stride
ldr r5, [r0, #HXFSTATE_OFFSET_LOADPOSITIONPROC]
pld [r6, r7, lsl #2] ; prefetch 4 vertices ahead
add r7, r6, r7 ; update the input vertex position pointer
str r7, [r0, #HXFSTATE_OFFSET_PINPOSITION] ; update the input position pointer
ldr lr, =TransformPosition
mov pc, r5 ; branch to the position load proc
HTV_TNL_RETURN ; the transform functions always returns to this label
; ************************************************************************
; Register map - to END VERTEX LOOP
; r0 - pState
; r1 - Flags
; r12 - Output Vertex Pointer
; ************************************************************************
; 4. Perform Vertex Lighting
; positions are in r2-r4 - for use by lighter if it is called.
tst r1, #HXF_LIGHT_ENABLE ; if light flag is set
ldrne lr, =HTV_LIGHT_RETURN ;
bne HXFLightVertex ; Vertex lighting is enabled - do lighting calculations
; ************************************************************************
; 4.1 Diffuse Color
ldr r2, [r0, #HXFSTATE_OFFSET_OUTDIFFUSEOFFSET]
ldrd r6, [r0, #HXFSTATE_OFFSET_PINDIFFUSE] ; Load the input data pointer
ldr r5, [r0, #HXFSTATE_OFFSET_LOADDIFFUSEPROC]
add r2, r2, r12 ; Calculate the output offset - address to store the color
pld [r6, r7, lsl #2] ; prefetch 4 vertices ahead
add r7, r7, r6 ; calculate the updated address for the next iteration
str r7, [r0, #HXFSTATE_OFFSET_PINDIFFUSE] ; save the address
ldr lr, =HTV_DCC_RETURN
mov pc, r5
HTV_DCC_RETURN
; ************************************************************************
; 4.2. Specular
tst r1, #HXF_OUTPUT_SPECULAR
beq HTV_LIGHT_RETURN
ldr r2, [r0, #HXFSTATE_OFFSET_OUTSPECULAROFFSET]
ldrd r6, [r0, #HXFSTATE_OFFSET_PINSPECULAR] ; Load the input data pointer
ldr r5, [r0, #HXFSTATE_OFFSET_LOADSPECULARPROC]
add r2, r2, r12 ; Calculate the output offset - address to store the color
pld [r6, r7, lsl #2] ; prefetch 4 vertices ahead
add r7, r7, r6 ; calculate the updated address for the next iteration
str r7, [r0, #HXFSTATE_OFFSET_PINSPECULAR] ; save the address
ldr lr, =HTV_LIGHT_RETURN
mov pc, r5
HTV_LIGHT_RETURN
; ************************************************************************
; 5. Fogging
tst r1, #HXF_FOG_ENABLE
beq HTV_FOG_RETURN
ldr r5, [r0, #HXFSTATE_OFFSET_FOGPROC]
ldr r2, [r0, #HXFSTATE_OFFSET_OUTSPECULAROFFSET]
mov pc, r5
HTV_FOG_RETURN
; ************************************************************************
; 6. Tex Coordinate Handling
; ************************************************************************
; 6.1 Tex Coordinate 1
tst r1, #HXF_OUTPUT_TEX1
beq HTV_BEGIN_TEXTURE2 ; Do nothing if there is nothing to do!
ldr r2, [r0, #HXFSTATE_OFFSET_OUTTEX1OFFSET] ; Test if we have something to do.
ldrd r6, [r0, #HXFSTATE_OFFSET_PINTEXTURECOORDINATE1] ; Load texture 1 input data and stride into r6-r7.
ldr r5, [r0, #HXFSTATE_OFFSET_LOADTEX1PROC]
add r2, r2, r12 ; Calculate appropriate offset.
pld [r6, r7, lsl #2] ; prefetch 4 vertices ahead
add r7, r7, r6 ; Update the input pointer for the next iteration.
str r7, [r0, #HXFSTATE_OFFSET_PINTEXTURECOORDINATE1]
mov r9, #TEXTURE_MATRIX_1_OFFSET ; Load Tex Matrix Offset -- TBD Make more efficient
ldr lr, =HTV_BEGIN_TEXTURE2 ; set up the return address for both the copy and transform
mov pc, r5
HTV_BEGIN_TEXTURE2
; ************************************************************************
; 6.2 Tex Coordinate 2
tst r1, #HXF_OUTPUT_TEX2
beq HTV_END_TEXTURE2 ; Do nothing if there is nothing to do!
ldr r2, [r0, #HXFSTATE_OFFSET_OUTTEX2OFFSET] ; Test if we need to something.
ldrd r6, [r0, #HXFSTATE_OFFSET_PINTEXTURECOORDINATE2] ; Load texture 2 input data and stride into r6-r7.
ldr r5, [r0, #HXFSTATE_OFFSET_LOADTEX2PROC]
add r2, r2, r12 ; Calculate appropriate offset.
pld [r6, r7, lsl #2] ; prefetch 4 vertices ahead
add r7, r7, r6 ; Update the input pointer for the next iteration.
str r7, [r0, #HXFSTATE_OFFSET_PINTEXTURECOORDINATE2]
mov r9, #TEXTURE_MATRIX_2_OFFSET ; Load Tex Matrix Offset -- TBD Make more efficient
ldr lr, =HTV_END_TEXTURE2 ; set up the return address for both the copy and transform
mov pc, r5
HTV_END_TEXTURE2
; ************************************************************************
; 7. END VERTEX LOOP
; Update vertex pointer and check for end of loop
ldr r2, [r0, #HXFSTATE_OFFSET_OUTVERTEXSIZE]
ldr r4, [r0, #HXFSTATE_OFFSET_PENDOUTVERTEX]
add r12, r2, r12
cmp r12, r4
blt HTV_BEGIN_VERTEX
; ************************************************************************
; Clean up
; this code is only run at the tail of the loop so.
ldr r12, [r0, #HXFSTATE_OFFSET_NUMVERTICES]
ldr r2, [r0, #HXFSTATE_OFFSET_POUTCLIPFLAGS] ; Can't use macro because stride does not follow the pointer, stride is always 1
sub r2, r2, r12 ; reset the pointer - this is a byte array so the size is NumElements *1
str r2, [r0, #HXFSTATE_OFFSET_POUTCLIPFLAGS]
HTV_RESET_INPUTS
HXF_RESET_POINTER HXFSTATE_OFFSET_PINPOSITION, r2, r3, r11, r12
tst r1, #HXF_LIGHT_ENABLE ; test if lighting is enabled
beq HTV_RESTORE_NO_LIGHT ; if so we have more work to do...
HXF_RESET_POINTER HXFSTATE_OFFSET_PINNORMAL, r2, r3, r11, r12
; restore input diffuse
HXF_RESET_POINTER HXFSTATE_OFFSET_PINDIFFUSE, r2, r3, r11, r12
b HTV_RESTORE_TEXPOINTERS
HTV_RESTORE_NO_LIGHT
; restore input diffuse
HXF_RESET_POINTER HXFSTATE_OFFSET_PINDIFFUSE, r2, r3, r11, r12
HTV_RESTORE_TEXPOINTERS
HXF_RESET_POINTER HXFSTATE_OFFSET_PINTEXTURECOORDINATE1, r2, r3, r11, r12
HXF_RESET_POINTER HXFSTATE_OFFSET_PINTEXTURECOORDINATE2, r2, r3, r11, r12
; restore the registers and exit
ldmfd sp!, {r4-r11, pc}
ENDP
|HXFRelightVertices| PROC
stmfd sp!, {r4-r11, r14}
; Set up a shifter amount in the wMMX control register.
mov r1, #16 ; shift value for 32.32 to 16.16 conversion
tmcr wcgr0, r1
mov r1, #12 ; shift value for 6.26 to 0.16 conversion
tmcr wcgr1, r1
mov r1, #8 ; Byte shifter value for use in applying exponent adjustments.
tmcr wcgr2, r1
mov r1, #32 ; shift value for working in wMMX doing transforms.
tmcr wcgr3, r1
mov r1, #4 ; We need to add 4 to each adjustment value before we use it to shift the division result.
tbcstb wr11, r1
wzero wr14
wzero wr12
mov r1, #0x10000
sub r1, r1, #1
mov r1, r1 lsl #16
tinsrw wr12, r1, #0
; ************************************************************************
; Loop Setup
; Initialize the counter
ldr r12, [r0, #HXFSTATE_OFFSET_POUTVERTICES]
ldr r1, [r0, #HXFSTATE_OFFSET_FLAGS]
; ************************************************************************
HRLV_BEGIN_VERTEX
ldrd r6, [r0, #HXFSTATE_OFFSET_PINPOSITION] ; Load Position pointer and stride
ldr r5, [r0, #HXFSTATE_OFFSET_LOADPOSITIONPROC]
pld [r6, r7, lsl #2] ; prefetch 4 vertices ahead
add r7, r6, r7 ; update the input vertex position pointer
str r7, [r0, #HXFSTATE_OFFSET_PINPOSITION] ; update the input position pointer
ldr lr, =HRLV_TNL_RETURN
mov pc, r5 ; branch to the position load proc
HRLV_TNL_RETURN ; the transform functions always returns to this label
strd r2, [r0, #HXFSTATE_OFFSET_STORAGE_VTXPOSITION_X]
strd r4, [r0, #HXFSTATE_OFFSET_STORAGE_VTXPOSITION_Z]
; ************************************************************************
; Register map - to END VERTEX LOOP
; r0 - pState
; r1 - Flags
; r12 - Output Vertex Pointer
; ************************************************************************
; 4. Perform Vertex Lighting
bl HXFLightVertex ; Vertex lighting is enabled - do lighting calculations
; ************************************************************************
; 7. END VERTEX LOOP
; Update vertex pointer and check for end of loop
ldr r2, [r0, #HXFSTATE_OFFSET_OUTVERTEXSIZE]
ldr r4, [r0, #HXFSTATE_OFFSET_PENDOUTVERTEX]
add r12, r2, r12
cmp r12, r4
blt HRLV_BEGIN_VERTEX
; ************************************************************************
; Clean up
; this code is only run at the tail of the loop so.
ldr r12, [r0, #HXFSTATE_OFFSET_NUMVERTICES]
HRLV_RESET_INPUTS
HXF_RESET_POINTER HXFSTATE_OFFSET_PINPOSITION, r2, r3, r11, r12
HXF_RESET_POINTER HXFSTATE_OFFSET_PINNORMAL, r2, r3, r11, r12
HXF_RESET_POINTER HXFSTATE_OFFSET_PINDIFFUSE, r2, r3, r11, r12
; restore the registers and exit
ldmfd sp!, {r4-r11, pc}
ENDP
;** ************************************************************************ **
END
;/* ************************************************************************ *\
;** ************************************************************************ **
;** EOF
;** ************************************************************************ **
;\* ************************************************************************ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -