Files
CydandClaude Fable 5 db7745fcd0 sda4: commit the Glaze developer hard-drive dump
Un-ignored: the dev drive is the ground truth the restoration and
emulator work constantly reference (DPL3/LIBDPL + VRENDER i860 renderer
source, BT/RP live+dev game trees, VGL_LABS pod boot, scene/audio
content). Kept in-repo for the pod-owner community.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 19:41:15 -05:00

720 lines
17 KiB
ArmAsm

.align 8
.text
//{{{ register trace macro
//}}}
// void xform_light_project ( VERTEX *v1,
// int n_verts,
// int strip_shade,
// int front_face,
// VIEW *eye,
// LIGHTSOURCE *blondie,
// MATRIX quad_aligned_m,
// MATERIAL *m,
// int do_project_and_texture,
// float texscale,
// int pmesh )
//{{{ declare registers
//{{{ parameters
// parameters
//}}}
//{{{ local floats -- all registers used !
// local floats
// these must be double-aligned
// for transforming
//}}}
//{{{ local ints and pointers -- all registers used !
// local ints and pointers
//}}}
//}}}
//{{{ define offsets into some types
// fields in r28 structure
// fields in material structure
// fields in view structure
// fields in vertex structure
//}}}
// r17 guaranteed > 0
.globl _fn_xform_light_project
.align 8
//
//
_fn_xform_light_project::
//{{{ save volatiles
fst.d f2, -8(sp) // 1
fst.d f4, -16(sp) // 1
fst.d f6, -24(sp) // 1
st.l r15, -28(sp) // 2
st.l r14, -32(sp) // 2
st.l r13, -36(sp) // 2
st.l r12, -40(sp) // 2
st.l r11, -44(sp) // 2
st.l r10, -48(sp) // 2
st.l r9, -52(sp) // 2
st.l r8, -56(sp) // 2
adds -64, sp, sp // 1
fxfr f8 , r9 // 2
//}}}
//{{{ cache matrix
fld.q 0( r22 ), f4 // 2
fld.q 16( r22 ), f8 // 2
fld.q 32( r22 ), f12 // 2
fld.q 48( r22 ), f16 // 2
//}}}
//{{{ initialize state
//
// load various floating-point constants into spare integer registers
//
orh ha%.C00066, r0, r31 // 1
ld.l l%.C00066(r31), r14 // 2
orh ha%.C00067, r0, r31 // 1
ld.l l%.C00067(r31), r13 // 2
orh ha%.C00068, r0, r31 // 1
ld.l l%.C00068(r31), r15 // 2
orh ha%.C00069, r0, r31 // 1
ld.l l%.C00069(r31), r12 // 2
orh ha%_sub_pxl_correct, r0, r31 // 1
ld.l l%_sub_pxl_correct(r31), r10 // 2
ixfr r14 , f21 // 2
//
// r29 = r23 ->specular_table;
//
ld.l (11*4) ( r23 ), r29 // 2
//
// f2 = r20 ->screen_half_width;
// f3 = r20 ->screen_half_height;
// f20 = r20 ->zscale;
//
orh ha%.Czscale, r0, r31
fld.l l%.Czscale(r31), f30
fld.l ( (37*4) )( r20 ), f2 // 1
fld.l ( (39*4) )( r20 ), f3 // 1
fld.l ( (42*4) )( r20 ), f20 // 1
fmul.ss f20 , f30 , f20
//
// f7 = r20 ->d;
// f11 =1.0f;
// NB .C00066 must be 1.0f
//
fld.l ( (33*4) )( r20 ), f7 // 2
ixfr r14 , f11 // 2
//
// f15 = f2 *( r20 ->shift_x + 1.0f);
// f19 = f3 *( r20 ->shift_y + 1.0f);
//
fld.l ( (44*4) )( r20 ), f15 // 2
fld.l ( (45*4) )( r20 ), f19 // 2
fadd.ss f11 , f15 , f15 // 3
fadd.ss f11 , f19 , f19 // 3
fmul.ss f2 , f15 , f15 // 3
fmul.ss f3 , f19 , f19 // 1
//
// if ( r18 & strip_shade_coloured) {
// r26 = 0;
// r27 = 0;
// }
//
and 2, r18 , r0 // 1
bc .not_cooked // 3
mov r0, r26
mov r16 , r11 // 1
br .end_check
mov r0, r27
//
// else if ( r18 & strip_shade_smooth) {
// r26 = 1;
// r27 = 0;
// r11 = r16 ;
// }
//
.not_cooked::
and 1, r18 , r0 // 1
bc .not_smooth // 2
adds 0x1, r0, r26 // 1
mov r16 , r11 // 1
br .end_check // 2
mov r0, r27 // 1
//
// else {
// r26 = r17 -2;
// r27 = -1;
// r11 = r16 +1;
// }
//
.not_smooth::
adds -2, r17 , r26
adds -1, r0, r27
adds 56, r16 , r11
.end_check::
btne 0x0, r19 , .dont_tweak_factor // 3
ixfr r13 , f21
.dont_tweak_factor::
//}}}
//{{{ LOOP : transform point - CHECK FOR W-COORD == 0, and dont do it!
//
// f22 = r16 ->position[0];
// f22 = r16 ->position[1];
// f23 = r16 ->position[2];
//
// rx=( f22 * f4 )+( f23 * f8 )+( f24 * f12 )+tx;
// ry=( f22 * f5 )+( f23 * f9 )+( f24 * f13 )+ty;
// rz=( f22 * f6 )+( f23 * f10 )+( f24 * f14 )+tz;
//
// this can be optimized by about 5 ticks i think, NOTE use
// T as staging-post and all will be well, maybe use KR for f24 ?
//
//
// first fix nverts !!!
adds -1, r17 , r17
fld.d 0( r16 ), f22 // 4
.vertex_loop::
fld.d 48( r22 ), f16 // 2
fld.l 56( r22 ), f18 // 2
bte 0x0, r25 , .vertex_proceed
ld.l 12( r16 ), r31
and 1, r31, r0
bnc .vertex_proceed
// r16 ++;
// r11 ++;
//
// r26 += r27 ;
// r17 --;
adds 56 , r16 , r16
adds 56 , r11 , r11
adds r27 , r26 , r26
adds -1, r17 , r17 // carry set if nverts>1
bnc.t .vertex_loop
fld.d 0( r16 ), f22
br .xf_exit
nop
.vertex_proceed::
pfmul.ss f22 , f4 ,f0 // 1
pfmul.ss f23 , f8 ,f0 // 1
pfmul.ss f22 , f5 ,f0 // 1
fld.l 8( r16 ), f24 // 1
pfmul.ss f23 , f9 , f30 // 1
pfmul.ss f22 , f6 , f31 // 1
pfadd.ss f30 , f31 ,f0 // 1
pfmul.ss f23 , f10 , f30 // 1
pfmul.ss f24 , f12 , f31 // 1
pfadd.ss f30 , f31 ,f0 // 1
pfmul.ss f24 , f13 , f30 // 1
pfmul.ss f24 , f14 , f31 // 1
pfadd.ss f30 , f31 ,f0 // 1
m12apm.ss f0,f0,f0 // 1
m12apm.ss f0,f0,f0 // 1
m12apm.ss f0,f0,f0 // 1
r2ap1.ss f16 ,f0,f0 // 1
r2ap1.ss f17 ,f0,f0 // 1
r2ap1.ss f18 ,f0,f0 // 1
pfadd.ss f0,f0, f22 // 1
pfadd.ss f0,f0, f23 // 1
pfadd.ss f0,f0, f24 // 1
fst.l f24 , 12( r16 ) // uninverted z goes in W-slot
//}}}
//{{{ project point does the john rhoades sub-pixel correction
//
// f29 = f7 /rz;
//
and 0x1, r24 , r0
bc .dont_project
ixfr r15 , f30 // f30 = 2.0 // 1
frcp.ss f24 , f29 // f29 = first guess // 1
fmul.ss f24 , f29 , f31 // first guess * divisor // 3
fsub.ss f30 , f31 , f31 // 2.0 - (fg*d) // 3
fmul.ss f29 , f31 , f29 // 2nd guess // 3
fmul.ss f24 , f29 , f31 // g2*d // 3
fsub.ss f30 , f31 , f31 // 2.0 - g2*d // 3
fmul.ss f29 , f31 , f29 // 3rd guess, real 1/z // 3
ixfr r10 , f31 // put john rhoades into f31
fmul.ss f7 , f29 , f29 // 3rd guess, real 1/z // 3
//
// f22 =(rx* f2 * f29 )+ f15 ;
// f23 =(ry* f3 * f29 )+ f19 ;
// no longer f24 = f11 -( f20 * f29 );
//
// but
// f24 = f20 * f29 (where f24 =1 at near clip, 0 at infinity)
// and we z-buffer by newz > zbuf => keep
//
// NB we need to do the John Rhoades thing by adding on a BIG number then
// subtracting it again
//
pfmul.ss f20 , f29 , f0
pfmul.ss f22 , f2 , f0
pfmul.ss f23 , f3 , f0
mi2pt.ss f29 , f0, f24 // got real f24
mimt1s2.ss f0, f0, f0 // m-3 * f29
mimt1s2.ss f0, f0, f0 // m-3 * f29
pfmul.ss f0, f0, f0 // push f29 * f22 * f2 to m-3
i2p1.ss f15 , f0, f24 // and fire add
i2p1.ss f19 , f0, f0 // again
pfsub.ss f0, f31 , f0 // push -john rhoades into pipe
i2ap1.ss f31 , f0, f0 // add x to BIG
i2ap1.ss f31 , f0, f0 // add y to BIG
pfadd.ss f0, f0, f31 // f31 now -BIG
i2ap1.ss f31 , f0, f0 // subtract BIG from x
i2ap1.ss f31 , f0, f0 // subtract BIG from y
pfadd.ss f0, f0, f0 // x+BIG-BIG now in adder stage 3
pfadd.ss f0, f0, f22
pfadd.ss f0, f0, f23
// r16 ->position[0] = f22 ;
// r16 ->position[1] = f23 ;
// r16 ->position[2] = f24 ;
.dont_project::
fst.d f22 , 0( r16 )
.dont_texture::
fst.l f24 , 8( r16 ) // 1
//}}}
//{{{ r28 point
// if ( r26 ) {
bte 0x0, r26 , .dont_light // 1
.do_lighting::
// load surface normal of vertex to be lit up
fld.d ( (8*4) +0)( r11 ), f22
orh ha%_ambientR, r0, r31 // 1
mov r21 , r8
fld.l ( (8*4) +8)( r11 ), f24
or l%_ambientR, r31, r31 // 2
fld.d 0(r31), f16
fld.l 8(r31), f18
pfmul.ss f21 , f22 , f0
pfmul.ss f21 , f23 , f0
pfmul.ss f21 , f24 , f0
pfmul.ss f0, f0, f22
pfmul.ss f0, f0, f23
pfmul.ss f0, f0, f24
// for ( r8 = r21 ; r8 ; r8 = r8 ->next ) {
bte 0x0, r8 , .lighting_done
//
// need to compute
// f25 =( f22 * f26 ) + ( f23 * f27 ) + ( f24 * f28 );
//
fld.l ( (5*4) +0)( r8 ), f26
.next_bulb::
fld.l ( (5*4) +4)( r8 ), f27
fld.l ( (5*4) +8)( r8 ), f28
.align 8
pfmul.ss f22 , f26 , f0
pfmul.ss f23 , f27 , f0 // pipeline states AFTER this instruction
pfmul.ss f24 , f28 , f0 // nlz nly nlx ? ? ? ?
r2ap1.ss f0, f0, f0 // f22 . f26 into T
r2pt.ss f0, f0, f0 // adder 1 = f22 . f26 + f23 . f27
pfadd.ss f0, f0, f0 // adder 2
pfadd.ss f0, f0, f0 // adder 3
m12apm.ss f0, f0, f0 // add-3 + mul-3
pfadd.ss f0, f0, f0 //
pfadd.ss f0, f0, f0 //
pfadd.ss f0, f0, f25
pfgt.ss f25 , f0, f0
bnc .no_diffuse
fld.l ( (9*4) )( r8 ), f30
fld.l ( (9*4) +4)( r8 ), f31
fld.l ( (9*4) +8)( r8 ), f29
pfmul.ss f25 , f30 , f0
pfmul.ss f25 , f31 , f0
pfmul.ss f25 , f29 , f0
mr2p1.ss f16 , f0, f0
mr2p1.ss f17 , f0, f0
mr2p1.ss f18 , f0, f0
pfadd.ss f0, f0, f16
pfadd.ss f0, f0, f17
pfadd.ss f0, f0, f18
// indirect off r8 next field
.no_diffuse::
ld.l r0( r8 ), r8
xor r0, r8 , r0
bnc.t .next_bulb
fld.l ( (5*4) +0)( r8 ), f26
// f16 , f17 , f18 hold the accumulated r28 r g bs
// now multiply by surface colour
ixfr r12 , f25
fld.l ( (4) )( r23 ), f30
fld.l ( (4) +4)( r23 ), f31
fld.l ( (4) +8)( r23 ), f29
pfmul.ss f25 , f30 , f0
pfmul.ss f25 , f31 , f0
pfmul.ss f25 , f29 , f0
pfmul.ss f0, f0, f30
pfmul.ss f16 , f30 , f31
pfmul.ss f17 , f31 , f29
pfmul.ss f18 , f29 , f0
pfmul.ss f0, f0, f16
pfmul.ss f0, f0, f17
pfmul.ss f0, f0, f18
fst.l f16 , ( (8*4) )( r11 ) // 1
fst.l f17 , (4+ (8*4) )( r11 ) // 1
fst.l f18 , (8+ (8*4) )( r11 ) // 1
.dont_light::
.lighting_done::
//}}}
//{{{ loop tail
// r16 ++;
// r11 ++;
//
// r26 += r27 ;
// r17 --;
adds 56 , r16 , r16
adds 56 , r11 , r11
adds r27 , r26 , r26
adds -1, r17 , r17 // carry set if nverts>1
bnc.t .vertex_loop
fld.d 0( r16 ), f22
//}}}
//{{{ unsave volatiles, exit
.xf_exit::
adds 64, sp, sp
fld.d -8(sp), f2
fld.d -16(sp), f4
fld.d -24(sp), f6
ld.l -28(sp), r15
ld.l -32(sp), r14
ld.l -36(sp), r13
ld.l -40(sp), r12
ld.l -44(sp), r11
ld.l -48(sp), r10
ld.l -52(sp), r9
bri r1
ld.l -56(sp), r8
//}}}
//{{{ fn_inv (computes 1/z)
.align 8
.globl _fn_inv
.align 8
_fn_inv::
orh ha%.C00068, r0, r31
fld.l l%.C00068(r31), f12
frcp.ss f8 , f11 // f11 = first guess
fmul.ss f8 , f11 , f10 // first guess * divisor
fsub.ss f12 , f10 , f10 // 2.0 - (fg*d)
fmul.ss f11 , f10 , f11 // 2nd guess
fmul.ss f8 , f11 , f10 // g2*d
fsub.ss f12 , f10 , f10 // 2.0 - g2*d
bri r1
fmul.ss f10 , f11 , f8 // 3rd guess, real 1/z
//}}}
//{{{ constants and strings
.align 8
.globl _sub_pxl_correct
.C00066:
.long 0x3f800000 // 1.00000000E+00
.C00067:
.long 0xbf800000 // -1.00000000E+00
.C00068:
.long 0x40000000 // 2.00000000E+00
.C00069:
.long 0x43800000 // 256.00000000E+00
_sub_pxl_correct:
.long 0x00000000 // 0x49000000 // 5.24288000E+05
.Czscale: // (0)
.long 0x497fffff // 1.04857588E+06
// .long 0x49fffffe // 2.09715175E+06
.about_to_xform::
.string "about to xform"
.byte 0x0
.xformed::
.string "xformed"
.byte 0x0
.projected::
.string "projected"
.byte 0x0
//}}}
//{{{ quad matrices
.data
.globl _ambientR
.globl _ambientG
.globl _ambientB
_ambientR:
.long 0x3eb33333 // 3.49999994E-01
_ambientG:
.long 0x3eb33333 // 3.49999994E-01
_ambientB:
.long 0x3eb33333 // 3.49999994E-01
.align 16
_quad_f_matrix:: // (64)
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.align 16
_quad_b_matrix:: // (64)
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
//}}}