.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 //}}}