;////////////////////////////////////////////////////////////////////////////////////////
;// Tristip twister with envmap
;// Copyright (c) 2004   emoon <daniel@collin.com>
;// Copyright (c) 2004   adresd <adresd_ps2dev@yahoo.com>
;// 
;// Licensed under the AFL v2.0. See the file LICENSE included with this
;// distribution for licensing terms.
;//
;// This is a distort per vertex according to distance from origin and
;// values passed in.. also performs envmapping
;//
;// Base version of code was supplied by emoon, mods by adresd.
;//
;// Note that this code is highly unoptimized, but might be useful to learn from or so.
;//

iScreenMatrix   = 0
iCameraMatrix   = 4
vfAngles        = 8
; vfAngles   x=Multiplier (for distance)  w=base lag rate
; only x should be altered to set effect.. w should be considered the limit

iGiftag         = 0
vfData          = 1



.global         g_PbVu1_Distort
.global         g_PbVu1_Distort_End
                
                .p2align 4  ; This aligns the following data to quadword alignment
                .vu

g_PbVu1_Distort:
                nop                             xtop        vi14
                                
                nop                             lq          vf28, iScreenMatrix+0(vi00)
                nop                             lq          vf29, iScreenMatrix+1(vi00)
                nop                             lq          vf30, iScreenMatrix+2(vi00)
                nop                             lq          vf31, iScreenMatrix+3(vi00)

                nop                             lq          vf24, iCameraMatrix+0(vi00)
                nop                             lq          vf25, iCameraMatrix+1(vi00)
                nop                             lq          vf26, iCameraMatrix+2(vi00)
                nop                             lq          vf27, iCameraMatrix+3(vi00)
                                                
                nop                             lq          vf22, vfAngles(vi00)    ; h,p,b,rate
                
                nop                             iaddiu      vi02, vi14, 246         ; 
                nop                             iaddiu      vi03, vi14, 246         ; xgkick adree
                nop                             iaddiu      vi01, vi14, vfData      ; coord adress
                
                nop                             lq.xyzw     vf06, iGiftag(vi14)     ; giftag
                nop                             sqi.xyzw    vf06, (vi02++)          ; store the giftag
                
                ;//////////////////////////////////////////////////////////////////////////////////
                ;// Get the lower part of the viftag to see how many coords we ill draw               
                nop                             iaddiu      vi05, vi00, 80
                
                
poly_loop:      
                nop                             lqi         vf05, (vi01++)          ; XYZ
                                                              
                ;//////////////////////////////////////////////////////////////////////////////////
                ;// Calculate distance to origo for the vertex 
                                
                mul        vf08,  vf05,  vf05   nop                     ; x*x , y*y, z*z ..
                addy.x     vf09x, vf08x, vf08y  nop                     ; x*x + y*y  
                addz.x     vf09x, vf08x, vf08z  loi 100.0               ; x*x + y*y + z*z
                addi.x     vf08x, vf00x, i      nop
                nop                             sqrt q, vf09x   ; sqrt(x*x + y*y + z*z)
                nop                             waitq
                addq.x     vf09x, vf00x, q      nop                     ; vf09x = distance
                mulw.x     vf09x, vf09x, vf22w  nop                     ; distance * lagrate
;//////////////////////////////
                 mulx.x     vf19x, vf09x, vf22x  nop               ; + x val (multiplier)
                ;//////////////////////////////////////////////////////////////////////////////////
                ;// Calc the rotation angles from the lagrate
                
                mulz.w      vf19, vf00, vf19z   nop                     ; copy angle from z to w
                addx.y      vf19, vf00, vf19x   loi 1.570796            ; copy angle from x to y                                     
                subi.xz     vf19, vf19, i       nop                     ; phase difference for sin as cos ( pi/2 )
                abs         vf19, vf19          nop                     ; mirror cos around zero
                maxw        vf20, vf00, vf00w   loi -0.159155           ; initialise all 1s                                                                             
                mulai       acc,  vf19, i       loi 12582912.0          ; scale so single cycle is range 0 to -1 ( *-1/2pi )                                   
                msubai      acc,  vf20, i       nop                     ; apply bias to remove fractional part
                maddai      acc,  vf20, i       loi -0.159155           ; remove bias to leave original int part                                    
                msubai      acc,  vf19, i       loi 0.5                 ; apply original number to leave fraction range only                                             
                msubi       vf19, vf20, i       nop                     ; ajust range: -0.5 to +0.5
                abs         vf19, vf19          loi 0.25                ; clamp: 0 to +0.5                                         
                subi        vf19, vf19, i       nop                     ; ajust range: -0.25 to +0.25
                mul         vf21, vf19, vf19    loi -76.574959          ; a^2
                muli        vf14, vf19, i       loi -41.341675          ; k4 a   
                muli        vf16, vf19, i       loi 81.602226           ; k2 a
                muli        vf15, vf19, i       nop                     ; k3 a
                mul         vf18, vf21, vf21    nop                     ; a^4
                mul         vf14, vf24, vf21    nop                     ; k4 a^3
                mula        acc,  vf16, vf21    loi 39.710659           ; + k2 a^3                                    
                muli        vf16, vf19, i       nop                     ; k5 a
                mul         vf17, vf18, vf18    nop                     ; a^8
                madda       acc,  vf14, vf18    nop                     ; + k4 a^7
                madda       acc,  vf15, vf18    loi 6.283185            ; + k3 a^5
                maddai      acc,  vf19, i       nop                     ; + k1 a
                madd        vf19, vf16, vf17    nop                     ; + k5 a^9

                ;//////////////////////////////////////////////////////////////////////////////////
                ;// Make unit matrix
                
                nop                             move vf13,vf00          ; row 3
                nop                             mr32 vf12,vf13          ; row 2
                nop                             mr32 vf11,vf12          ; row 1
                nop                             mr32 vf10,vf11          ; row 0        
                
                ;//////////////////////////////////////////////////////////////////////////////////
                ;// insert sin/cos here                

                addy.x  vf10x, vf00x, vf19y     loi -1.0                ; cos_angle, 0, 0, 0
                addx.z  vf10z, vf00z, vf19x     nop                     ; cos_angle, 0, sin_angle, 0
                muli.z  vf10z, vf10z, i         nop                     ; cos_angle, 0, -sin_angle, 0

                addx.x  vf12x, vf00x, vf19x     nop                     ; sin_angle, 0, 0, 0
                addy.z  vf12z, vf00z, vf19y     nop                     ; sin_angle, 0, cos_angle, 0
                                
                ;///////////////////////////////////////////////////////////////////////////////////
                ;// Calculate Local Matrix * CameraMatrix

                mulax     acc,  vf24, vf10      nop
                madday    acc,  vf25, vf10      nop
                maddaz    acc,  vf26, vf10      nop
                maddw     vf18, vf27, vf10      nop
                
                mulax     acc,  vf24, vf11      nop
                madday    acc,  vf25, vf11      nop
                maddaz    acc,  vf26, vf11      nop
                maddw     vf19, vf27, vf11      nop
                
                mulax     acc,  vf24, vf12      nop
                madday    acc,  vf25, vf12      nop
                maddaz    acc,  vf26, vf12      nop
                maddw     vf20, vf27, vf12      nop
                
                mulax     acc,  vf24, vf13      nop
                madday    acc,  vf25, vf13      nop
                maddaz    acc,  vf26, vf13      nop
                maddw     vf21, vf27, vf13      nop
                
                ;//////////////////////////////////////////////////////////////////////////////////
                ;// Calculate Screen * (Local * Camera)
                
                mulax     acc,  vf28, vf18      nop
                madday    acc,  vf29, vf18      nop
                maddaz    acc,  vf30, vf18      nop
                maddw     vf01, vf31, vf18      nop
                
                mulax     acc,  vf28, vf19      nop
                madday    acc,  vf29, vf19      nop
                maddaz    acc,  vf30, vf19      nop
                maddw     vf02, vf31, vf19      nop
                
                mulax     acc,  vf28, vf20      nop
                madday    acc,  vf29, vf20      nop
                maddaz    acc,  vf30, vf20      nop
                maddw     vf03, vf31, vf20      nop
                
                mulax     acc,  vf28, vf21      nop
                madday    acc,  vf29, vf21      nop
                maddaz    acc,  vf30, vf21      nop
                maddw     vf04, vf31, vf21      nop
                                
                ;//////////////////////////////////////////////////////////////////////////////////
                ;// Project vertex to screen space.
                                
                mulax     acc,  vf01, vf05x     nop                                 
                madday    acc,  vf02, vf05y     nop                                 
                maddaz    acc,  vf03, vf05z     nop                                 
                maddw     vf05, vf04, vf05w     nop                                 
                nop                             div         q, vf00w, vf05w     
                ; set color
                nop                             loi 150.0
                addi.xyzw vf01,vf00,I		nop
                ftoi0 vf01,vf01                 nop

                ;// Rotate normal
                nop                             lqi         vf02, (vi01++)          ; NORMAL
                mulax     acc,   vf18, vf02x    nop                                 
                madday    acc,   vf19, vf02y    nop                                 
                maddaz    acc,   vf20, vf02z    nop                                 
                maddw     vf02,  vf21, vf02w    loi         0.5 ;// 127.0
                ;// trunc if negative               
                muli      vf02,  vf02, i        nop
                addi.xy   vf02xy, vf02xy, i     waitq
    
                mulq        vf05, vf05, q       nop                                 
                ftoi4       vf05, vf05          nop                                 ; fixedpoint for gif
                mulq.xy   vf02xy, vf02xy, q     nop       
                addq.z    vf02z,  vf00z, q      nop        
                abs.xy    vf02xy, vf02xy        nop
                nop                             sqi         vf02, (vi02++)       ; ST
                nop                             sqi         vf01, (vi02++)       ; RGA
                nop                             sqi         vf05, (vi02++)       ; XYZ
                nop                             iaddi       vi05, vi05, -1          ; 
                nop                             nop                                 ;
                nop                             ibne        vi05, vi00, poly_loop   ; loop check
                nop                             nop
                nop                             xgkick      vi03
                nop[e]                          nop
                nop                             nop
                                
g_PbVu1_Distort_End: