;;-*-Lisp-*- (in-package goal) (bundles "ENGINE.CGO" "GAME.CGO") (require "engine/math/quaternion-h.gc") (require "pc/pckernel-impl.gc") (require "engine/ps2/vu1-macros.gc") (require "engine/math/trigonometry.gc") (require "engine/math/transform-h.gc") ;;;;;;;;;;;;;;;;;;;;;; ;; math camera basics ;;;;;;;;;;;;;;;;;;;;;; ;; the math camera computes the perspective matrix, hvdf offset, and hmge scale. ;; multiplying a point by the perspective matrix, doing the persepctive divide, then adding hvdf offset gives you: ;; H : horizontal position (in GS coordinates) ;; V : vertical position (in GS coordinates) ;; D : depth (as a 24-bit integer for the z buffer) ;; F : fog ;; Multiplying by hmge then checking the clipping flags can be used to see if a point is outside the view frustum. ;; The "camera-temp" matrix is the perspective matrix multplied by the camera tranformation and is used ;; renderers that want a single matrix. ;;;;;;;;;;;;;;;;;;; ;; fog correction ;;;;;;;;;;;;;;;;;;; ;; The math-camera matrices are used to compute fogging values, which are a per-vertex uint8 that ;; tells the GS how "foggy" the color should be. This should be proportional to how far away the vertex ;; is. There is a scaling factor applied so the fog intensity isn't affected by the field of view angle. ;; DECOMP BEGINS ;; The fog-corrector stores a fog-end fog-start value that is corrected for the field of view. ;; the actual correction factor is computed in cam-update.gc (deftype fog-corrector (structure) ((fog-end float) (fog-start float))) (defun fog-corrector-setup ((corrector fog-corrector) (math-cam math-camera)) "Set the fog corrector based on the supplied math-camera" (set! (-> corrector fog-end) (* (-> math-cam fog-end) (-> math-cam fov-correction-factor))) (set! (-> corrector fog-start) (* (-> math-cam fog-start) (-> math-cam fov-correction-factor))) (none)) (define *math-camera-fog-correction* (new 'global 'fog-corrector)) (define-extern sprite-distorter-generate-tables (function none)) (defun update-math-camera ((math-cam math-camera) (video-mode symbol) (aspect symbol)) "Compute some one-time camera constants. These should only change when changing aspect ratio." ;; the x/y ratio are frustum slopes (set! (-> math-cam x-ratio) (tan (* 0.5 (-> math-cam fov)))) (if (= aspect 'aspect4x3) (set! (-> math-cam y-ratio) (* (1/ ASPECT_4X3) (-> math-cam x-ratio))) (set! (-> math-cam y-ratio) (* (1/ ASPECT_16X9) (-> math-cam x-ratio)))) (with-pc (cond ((-> *pc-settings* use-vis?) ;; using game vis, cannot allow seeing more of the view ;; crops excess aspect ratio at the top and bottom ;(set! (-> math-cam y-ratio) (* (1/ (-> *pc-settings* aspect-ratio)) (-> math-cam x-ratio))) ) ((real-movie?) ;; force the original 16x9 cropping during cutscenes. (if (<= (-> *pc-settings* aspect-ratio) ASPECT_16X9) (set! (-> math-cam y-ratio) (* (1/ (-> *pc-settings* aspect-ratio)) (-> math-cam x-ratio))) (begin (set! (-> math-cam y-ratio) (* (1/ ASPECT_16X9) (-> math-cam x-ratio))) (*! (-> math-cam x-ratio) (/ (-> *pc-settings* aspect-ratio) ASPECT_16X9))))) (else ;; not using game vis, allow *extended* aspect ratios ;; there is no vertical cropping, and you can see more of the sides (set! (-> math-cam y-ratio) (* (1/ ASPECT_4X3) (-> math-cam x-ratio))) ;; same cropping as 4x3 (*! (-> math-cam x-ratio) (/ (-> *pc-settings* aspect-ratio) ASPECT_4X3)) ;; extend fov! shows more on the sides. ))) ;; compute some culling constants. Not sure what these mean yet (let ((x-rat (-> math-cam x-ratio)) (y-rat (-> math-cam y-ratio)) (cull-info (-> math-cam cull-info))) (/ (+ 1.0 (* 4.0 x-rat x-rat)) (+ 1.0 (square x-rat))) (let ((y-thing (/ (+ 1.0 (* 4.0 y-rat y-rat)) (+ 1.0 (square y-rat))))) (set! (-> cull-info x-fact) (/ (+ 1.0 (* 4.0 x-rat x-rat)) (* x-rat (sqrtf (+ 1.0 (* 16.0 x-rat x-rat)))))) (set! (-> cull-info y-fact) (/ (+ 1.0 (* 4.0 y-rat y-rat)) (* y-rat (sqrtf (+ 1.0 (* 16.0 y-rat y-rat)))))) (set! (-> cull-info z-fact) (sqrtf (+ (* (+ -4.0 y-thing) (+ -4.0 y-thing) y-rat y-rat) (* (+ -1.0 y-thing) (+ -1.0 y-thing)))))) ;; radius of sphere containing camera origin and intersection of near plane and frustum (let* ((near-x (* x-rat (-> math-cam d))) (near-y (* y-rat (-> math-cam d))) (near-corner-dist-sqr (+ (* near-x near-x) (* near-y near-y))) (near-z (-> math-cam d))) (set! (-> cull-info cam-radius) (sqrtf (+ near-corner-dist-sqr (* near-z near-z))))) ;; frustum plane equations coefficients? (let* ((dx-rat-2 (* (-> math-cam d) (-> math-cam x-ratio))) (d-temp-2 (-> math-cam d)) (dx-rat-times-4 (* 4.0 dx-rat-2)) (d-temp-3 (-> math-cam d))) (let ((inverse-x-len (/ 1.0 (sqrtf (+ (square dx-rat-2) (square d-temp-2))))) (inverse-x-len-2 (/ 1.0 (sqrtf (+ (square dx-rat-times-4) (square d-temp-3)))))) (set! (-> cull-info xz-dir-ax) (* dx-rat-2 inverse-x-len)) (set! (-> cull-info xz-dir-az) (* d-temp-2 inverse-x-len)) (set! (-> cull-info xz-dir-bx) (* dx-rat-times-4 inverse-x-len-2)) (set! (-> cull-info xz-dir-bz) (* d-temp-3 inverse-x-len-2))) (set! (-> cull-info xz-cross-ab) (- (* dx-rat-2 d-temp-3) (* d-temp-2 dx-rat-times-4)))) (let* ((dy-rat (* (-> math-cam d) (-> math-cam y-ratio))) (d-temp-4 (-> math-cam d)) (dy-rat-times-4 (* 4.0 dy-rat)) (d-temp-5 (-> math-cam d))) (let ((inverse-y-len (/ 1.0 (sqrtf (+ (square dy-rat) (square d-temp-4))))) (inverse-y-len-2 (/ 1.0 (sqrtf (+ (square dy-rat-times-4) (square d-temp-5)))))) (set! (-> cull-info yz-dir-ay) (* dy-rat inverse-y-len)) (set! (-> cull-info yz-dir-az) (* d-temp-4 inverse-y-len)) (set! (-> cull-info yz-dir-by) (* dy-rat-times-4 inverse-y-len-2)) (set! (-> cull-info yz-dir-bz) (* d-temp-5 inverse-y-len-2))) (set! (-> cull-info yz-cross-ab) (- (* dy-rat d-temp-5) (* d-temp-4 dy-rat-times-4))))) ;; fog setup (fog-corrector-setup *math-camera-fog-correction* math-cam) ;; reset camera rotation (matrix-identity! (-> math-cam camera-rot)) ;;;;;;;;;;;;;; Perspective matrix setup ;; these min/max depths are the values we'd want to write to the 24-bit integer depth buffer (let ((min-depth 100.0) (max-depth 16760631.0) ;; almost 2^24. ) (let ((f0-21 16777115.0))) ;; unused. this is actually float closest to 2^24 ;; next, compute the fog slope d(8bit_integer_fog_value)/d(game_world_distance). ;; the final fog values we want are an 8-bit integer. ;; note that this is the fog at the near plane too. (let ((fog-slope (/ (* (-> math-cam d) (- (-> math-cam fog-min) (-> math-cam fog-max))) (- (-> *math-camera-fog-correction* fog-end) (-> *math-camera-fog-correction* fog-start)))) ;; this is half the range of the depth buffer. (depth-buffer-half-range (* -0.5 (- max-depth min-depth)))) ;; this is the slope to convert game world depths to depth buffer depths (let ((half-depth-buffer-slope (/ depth-buffer-half-range (* (-> math-cam d) (- (-> math-cam f) (-> math-cam d))))) (cam-fov-mult (-> math-cam fov-correction-factor))) ;; finally, build the actual matrix. ;; x/y are just the usual scaling (set! (-> math-cam perspective vector 0 x) (* cam-fov-mult (- (/ (-> math-cam x-pix) (* (-> math-cam x-ratio) (-> math-cam d)))))) (set! (-> math-cam perspective vector 1 y) (* cam-fov-mult (- (/ (-> math-cam y-pix) (* (-> math-cam y-ratio) (-> math-cam d)))))) ;; depth scaling (set! (-> math-cam perspective vector 2 z) (* cam-fov-mult (+ (-> math-cam f) (-> math-cam d)) half-depth-buffer-slope)) ;; depth to fog (set! (-> math-cam perspective vector 2 w) (* (/ cam-fov-mult (-> math-cam d)) fog-slope)) (set! (-> math-cam perspective vector 3 z) (* -2.0 half-depth-buffer-slope (-> math-cam f) (-> math-cam d) cam-fov-mult))) ;; hvdf = horizontal, vertical, depth, fog offsets to be applied after transform. (let ((hvdf-x 2048.0) (hvdf-y 2048.0) (hvdf-w (/ (- (* (-> *math-camera-fog-correction* fog-end) (-> math-cam fog-max)) (* (-> *math-camera-fog-correction* fog-start) (-> math-cam fog-min))) (- (-> *math-camera-fog-correction* fog-end) (-> *math-camera-fog-correction* fog-start))))) (let ((hvdf-z (* 0.5 (+ max-depth min-depth)))) (set! (-> math-cam hmge-scale x) (/ 1.0 (-> math-cam x-clip))) (set! (-> math-cam hmge-scale y) (/ 1.0 (-> math-cam y-clip))) (set! (-> math-cam hmge-scale z) (/ 1.0 depth-buffer-half-range)) (set! (-> math-cam hmge-scale w) (/ 1.0 fog-slope)) (set! (-> math-cam inv-hmge-scale x) (-> math-cam x-clip)) (set! (-> math-cam inv-hmge-scale y) (-> math-cam y-clip)) (set! (-> math-cam inv-hmge-scale z) depth-buffer-half-range) (set! (-> math-cam inv-hmge-scale w) fog-slope) (set! (-> math-cam hvdf-off x) hvdf-x) (set! (-> math-cam hvdf-off y) hvdf-y) (set! (-> math-cam hvdf-off z) hvdf-z) (set! (-> math-cam hvdf-off w) hvdf-w) (set! (-> math-cam guard x) (/ (-> math-cam x-clip) (-> math-cam x-pix))) (set! (-> math-cam guard y) (/ (-> math-cam y-clip) (-> math-cam y-pix))) (set! (-> math-cam guard z) 1.0) (set! (-> math-cam guard w) 1.0) (set! (-> math-cam isometric vector 3 z) (- 16777215.0 hvdf-z)) ;; og:preserve-this PC HACK! ;; for whatever reason, the font renderer ends up computing a depth #x1000000 instead of ;; #xffffffff, which overflows the 24-bit z buffer. ;; cheating this by 1 bit seems to fix it. (#when PC_PORT ;; #x4b002032 -> #x4b002031 (set! (-> math-cam isometric vector 3 z) (the-as float (1- (the-as int (-> math-cam isometric vector 3 z))))) ;; also do mirror game check here. (when (pc-cheats? (-> *pc-settings* cheats) mirror) (*! (-> math-cam perspective vector 0 x) -1.)))) (set! (-> math-cam isometric vector 3 w) fog-slope) ;; perspective matrix (let ((persp-xx (-> math-cam perspective vector 0 x)) (persp-yy (-> math-cam perspective vector 1 y)) (persp-x (* -1.9996 (-> math-cam perspective vector 0 x)))) (let ((sprite-row-0 (-> math-cam sprite-2d))) (set! (-> sprite-row-0 vector 0 x) persp-x) (set! (-> sprite-row-0 vector 0 y) 0.0) (set! (-> sprite-row-0 vector 0 z) 0.0) (set! (-> sprite-row-0 vector 0 w) 0.0)) (set-vector! (-> math-cam sprite-2d vector 1) 0.0 (- (* (/ persp-yy persp-xx) persp-x)) 0.0 0.0) (set-vector! (-> math-cam sprite-2d vector 2) 0.0 0.0 (- persp-x) 0.0) (set-vector! (-> math-cam sprite-2d vector 3) 0.0 0.0 (* 500000000.0 persp-x) (* 60.0 persp-x (-> math-cam pfog0)))) (set! (-> math-cam sprite-2d-hvdf quad) (-> math-cam hvdf-off quad)) (set! (-> math-cam sprite-2d-hvdf x) 2048.0) (set! (-> math-cam sprite-2d-hvdf y) 2048.0) (set! (-> math-cam sprite-2d-hvdf z) (-> math-cam hvdf-off z)) (set! (-> math-cam pfog0) fog-slope) (set! (-> math-cam pfog1) hvdf-w)))) ;; sets up some giftags, but they are totally wrong. ;; they use 32-bit variables to store 64-bit parts of the tag. 0 (make-u128 0 (shl #x301ec000 32)) (make-u128 0 (shl #x303ec000 32)) (let ((pfog (-> math-cam pfog0))) (let ((vis-gif-0 (-> math-cam vis-gifs))) (set! (-> vis-gif-0 0 fog0) (the-as uint pfog)) (set! (-> vis-gif-0 0 strip) (the-as uint #x301e4000)) (set! (-> vis-gif-0 0 regs) (the-as uint 1042)) (set! (-> vis-gif-0 0 fan) (the-as uint #x301ec000))) (let ((vis-gif-1 (&-> math-cam gifgr))) (set! (-> vis-gif-1 0) (the-as vis-gif-tag pfog)) (set! (-> vis-gif-1 1) (the-as vis-gif-tag (make-u128 0 (shl #x20164000 32)))) (set! (-> vis-gif-1 2) (the-as vis-gif-tag 65)) (set! (-> vis-gif-1 3) (the-as vis-gif-tag #x301ec000))) (let ((vis-gif-1-again (-> math-cam vis-gifs))) (set! (-> vis-gif-1-again 0 fog0) (the-as uint pfog)) (set! (-> vis-gif-1-again 0 strip) (the-as uint #x303e4000)) (set! (-> vis-gif-1-again 0 regs) (the-as uint 1042)) (set! (-> vis-gif-1-again 0 fan) (the-as uint #x303ec000))) (let ((vis-gif-1-again-again (-> math-cam vis-gifs))) (set! (-> vis-gif-1-again-again 0 fog0) (the-as uint pfog)) (set! (-> vis-gif-1-again-again 0 strip) (the-as uint #x303e4000)) (set! (-> vis-gif-1-again-again 0 regs) (the-as uint 1042)) (set! (-> vis-gif-1-again-again 0 fan) (the-as uint #x303ec000)))) ;; update sprite distort vectors (if (nonzero? sprite-distorter-generate-tables) (sprite-distorter-generate-tables)) math-cam) (defmethod new math-camera ((allocation symbol) (type-to-make type)) "Set up a new math-camera in NTSC mode." (let ((gp-0 (object-new allocation type-to-make (the-as int (-> type-to-make size))))) (set! (-> gp-0 d) 1024.0) (set! (-> gp-0 f) 40960000.0) (set! (-> gp-0 fov) 11650.845) (set! (-> gp-0 x-pix) 256.0) (set! (-> gp-0 x-clip) 1024.0) (set! (-> gp-0 y-pix) 112.0) (set! (-> gp-0 y-clip) 448.0) (set! (-> gp-0 fog-start) 40960.0) (set! (-> gp-0 fog-end) 819200.0) (set! (-> gp-0 fog-max) 255.0) (set! (-> gp-0 fog-min) 150.0) (matrix-identity! (-> gp-0 inv-camera-rot)) (matrix-identity! (-> gp-0 camera-rot)) (vector-reset! (-> gp-0 trans)) (set! (-> gp-0 isometric vector 0 x) 1.0) (set! (-> gp-0 isometric vector 1 y) 0.5) (set! (-> gp-0 isometric vector 2 z) -1.0) (set! (-> gp-0 reset) 1) (set! (-> gp-0 smooth-step) 0.0) (set! (-> gp-0 smooth-t) 0.0) (update-math-camera gp-0 'ntsc 'aspect4x3))) (define *math-camera* (new 'global 'math-camera)) (defun math-cam-start-smoothing ((arg0 float) (arg1 float)) "Unused camera smoothing" (set! (-> *math-camera* smooth-step) (/ 1.0 arg0)) (set! (-> *math-camera* smooth-t) arg1) (matrix->quaternion (-> *math-camera* inv-camera-rot-smooth-from) (-> *math-camera* inv-camera-rot-smooth))) (defun move-target-from-pad ((trans transform) (pad-idx int)) "Unused function to adjust trans based on inputs from the pad. This function must be extremely old because it takes a non-quaternion transform, and all target stuff uses quaternions." ;; local-trans is the translation in the camera frame. (let ((local-trans (new-stack-vector0))) ;; circle/square move camera relative x (left and right) (set! (-> local-trans x) (cond ((cpad-hold? pad-idx circle) -80.0) ((cpad-hold? pad-idx square) 80.0) (else 0.0))) ;; no way to move camera relative y (up/down) (set! (-> local-trans y) 0.0) ;; in and out movement (set! (-> local-trans z) (cond ((cpad-hold? pad-idx down) -80.0) ((cpad-hold? pad-idx up) 80.0) (else 0.0))) (set! (-> local-trans w) 1.0) ;; rotate this into world frame (let ((inv-cam-rot (new-stack-vector0)) (cam-rot-mat (new-stack-matrix0))) ;; unused. (vector-negate! inv-cam-rot (-> trans rot)) ;; convert rotation to rotation matrix. (matrix-rotate-zyx! cam-rot-mat (-> trans rot)) ;; and rotate the translation. (vector-matrix*! local-trans local-trans cam-rot-mat)) ;; and update the transform (vector+! (-> trans trans) (-> trans trans) local-trans)) ;; don't forget to fix w. (set! (-> trans trans w) 1.0) ;; global translation (if (cpad-hold? pad-idx r1) (+! (-> trans trans y) 80.0)) (if (cpad-hold? pad-idx r2) (+! (-> trans trans y) -80.0)) ;; rotation (don't allow camera roll) (if (cpad-hold? pad-idx x) (+! (-> trans rot x) 546.13336)) (if (cpad-hold? pad-idx triangle) (+! (-> trans rot x) -546.13336)) (if (cpad-hold? pad-idx left) (+! (-> trans rot y) 546.13336)) (if (cpad-hold? pad-idx right) (+! (-> trans rot y) -546.13336)) trans) (defun transform-point-vector! ((arg0 vector) (arg1 vector)) "Apply camera transformation to a point. Return true if it is visible or not. This returns the point in GS coords, but as float instead of int, so it's not really useful. See transform-point-qword! for more details" (rlet ((acc :class vf) (Q :class vf) (vf0 :class vf) (vf23 :class vf) (vf24 :class vf) (vf25 :class vf) (vf26 :class vf) (vf27 :class vf) (vf28 :class vf) (vf29 :class vf) (vf30 :class vf) (vf31 :class vf)) (init-vf0-vector) 0 (.lvf vf24 (&-> *math-camera* camera-temp vector 0 quad)) (.lvf vf25 (&-> *math-camera* camera-temp vector 1 quad)) (.lvf vf26 (&-> *math-camera* camera-temp vector 2 quad)) (.lvf vf27 (&-> *math-camera* camera-temp vector 3 quad)) (.lvf vf29 (&-> *math-camera* hmge-scale quad)) (.lvf vf30 (&-> *math-camera* hvdf-off quad)) (.lvf vf28 (&-> arg1 quad)) (.mul.x.vf acc vf24 vf28) (.add.mul.y.vf acc vf25 vf28 acc) (.add.mul.z.vf acc vf26 vf28 acc) (.add.mul.w.vf vf28 vf27 vf0 acc) (.add.w.vf vf23 vf0 vf0) (.mul.vf vf31 vf28 vf29) ;;(TODO.VCLIP vf31 vf31) (let ((clip (vu-clip vf31 0))) (.div.vf Q vf0 vf31 :fsf #b11 :ftf #b11) (.wait.vf) ;;(.cfc2.i v1-7 Clipping) (.mul.vf.xyz vf28 vf28 Q) (.mul.vf vf23 vf23 Q) (.add.vf vf28 vf28 vf30) (.max.x.vf.w vf28 vf28 vf0) (.svf (&-> arg0 quad) vf28) (zero? (logand clip 63))))) (defun transform-point-qword! ((arg0 vector4w) (arg1 vector)) "Apply camera transformation to point, returning fixed point 28.4 position that can be given to the GS directly." (rlet ((acc :class vf) (Q :class vf) (vf0 :class vf) (vf23 :class vf) (vf24 :class vf) (vf25 :class vf) (vf26 :class vf) (vf27 :class vf) (vf28 :class vf) (vf29 :class vf) (vf30 :class vf) (vf31 :class vf)) (init-vf0-vector) (let ((v1-0 0))) ;; this camera matrix has both the projection and camera translation/rotation (.lvf vf24 (&-> *math-camera* camera-temp vector 0 quad)) (.lvf vf25 (&-> *math-camera* camera-temp vector 1 quad)) (.lvf vf26 (&-> *math-camera* camera-temp vector 2 quad)) (.lvf vf27 (&-> *math-camera* camera-temp vector 3 quad)) ;; scaling (.lvf vf29 (&-> *math-camera* hmge-scale quad)) ;; offset (.lvf vf30 (&-> *math-camera* hvdf-off quad)) ;; input point (.lvf vf28 (&-> arg1 quad)) ;; matrix multiply, result in vf28 (.mul.x.vf acc vf24 vf28) (.add.mul.y.vf acc vf25 vf28 acc) (.add.mul.z.vf acc vf26 vf28 acc) (.add.mul.w.vf vf28 vf27 vf0 acc) (.add.w.vf vf23 vf0 vf0) ;; set w = 1.0 ;; apply hmge scaling. the result of this multiply sets clipping flags appropriately (.mul.vf vf31 vf28 vf29) ;; scale. ;;(TODO.VCLIP vf31 vf31) (let ((clip (vu-clip vf31 0))) ;; clip! ;; perspective divide (.div.vf Q vf0 vf31 :fsf #b11 :ftf #b11) (.wait.vf) ;;(.cfc2.i v1-7 Clipping) ;; perspective (.mul.vf.xyz vf28 vf28 Q) ;; compute scale factor (w was 1.0) (.mul.vf vf23 vf23 Q) ;; apply hvdf offsets (.add.vf vf28 vf28 vf30) ;; saturate fog (.max.x.vf.w vf28 vf28 vf0) ;; convert to GS fixed point (vftoi4.xyzw vf28 vf28) ;; store result! (.svf (&-> arg0 quad) vf28) ;; return result of clipping. (zero? (logand clip 63))))) (defun transform-point-vector-scale! ((arg0 vector) (arg1 vector)) "Similar to transform-point-qword! but returns the scale factor instead." (local-vars (v0-0 float)) (rlet ((acc :class vf) (Q :class vf) (vf0 :class vf) (vf23 :class vf) (vf24 :class vf) (vf25 :class vf) (vf26 :class vf) (vf27 :class vf) (vf28 :class vf) (vf29 :class vf) (vf30 :class vf) (vf31 :class vf)) (init-vf0-vector) (let ((v1-0 0))) (.lvf vf24 (&-> *math-camera* camera-temp vector 0 quad)) (.lvf vf25 (&-> *math-camera* camera-temp vector 1 quad)) (.lvf vf26 (&-> *math-camera* camera-temp vector 2 quad)) (.lvf vf27 (&-> *math-camera* camera-temp vector 3 quad)) (.lvf vf29 (&-> *math-camera* hmge-scale quad)) (.lvf vf30 (&-> *math-camera* hvdf-off quad)) (.lvf vf28 (&-> arg1 quad)) (.mul.x.vf acc vf24 vf28) (.add.mul.y.vf acc vf25 vf28 acc) (.add.mul.z.vf acc vf26 vf28 acc) (.add.mul.w.vf vf28 vf27 vf0 acc) (.add.w.vf vf23 vf0 vf0) (.mul.vf vf31 vf28 vf29) ;;(TODO.VCLIP vf31 vf31) clip result was unused (.div.vf Q vf0 vf31 :fsf #b11 :ftf #b11) (.wait.vf) ;;(.cfc2.i v1-7 Clipping) (.mul.vf.xyz vf28 vf28 Q) (.mul.vf vf23 vf23 Q) (.add.vf vf28 vf28 vf30) (.max.x.vf.w vf28 vf28 vf0) (.svf (&-> arg0 quad) vf28) ;;(let ((a0-2 (zero? (logand v1-7 63)))) ;; ) (.mov v0-0 vf23) v0-0)) (defun init-for-transform ((arg0 matrix)) "Sets up VU0 registers with camera info. This is probably a very old function and it's only used by jungle mirrors. It stashes some data in vector float registers that must be there before calling transform-float-point." (rlet ((vf1 :class vf) (vf17 :class vf) (vf18 :class vf) (vf19 :class vf) (vf2 :class vf) (vf23 :class vf) (vf24 :class vf) (vf25 :class vf) (vf26 :class vf) (vf27 :class vf) (vf28 :class vf) (vf29 :class vf) (vf3 :class vf) (vf4 :class vf) (vf6 :class vf) (vf7 :class vf) (vf8 :class vf) (vf9 :class vf)) (let ((gp-0 (new-stack-matrix0)) (s5-0 (new-stack-matrix0)) (s4-0 (new 'stack 'vector4s-3)) (s3-0 (new-stack-vector0)) (s2-0 (new 'stack 'vector4s-3))) (matrix*! s5-0 arg0 (-> *math-camera* camera-temp)) (matrix-3x3-inverse-transpose! gp-0 arg0) (let ((v1-3 s3-0)) (set! (-> v1-3 x) 0.4) (set! (-> v1-3 y) 0.4) (set! (-> v1-3 z) 0.4) (set! (-> v1-3 w) 1.0)) (let ((v1-4 (-> s4-0 data))) (set! (-> v1-4 0) 1.0) (set! (-> v1-4 1) 1.0) (set! (-> v1-4 2) 1.0) (set! (-> v1-4 3) 1.0)) (let ((v1-5 (&-> s4-0 data 4))) (set! (-> v1-5 0) 0.0) (set! (-> v1-5 1) 0.0) (set! (-> v1-5 2) 0.0) (set! (-> v1-5 3) 1.0)) (let ((v1-6 (&-> s4-0 data 8))) (set! (-> v1-6 0) 0.0) (set! (-> v1-6 1) 0.0) (set! (-> v1-6 2) 0.0) (set! (-> v1-6 3) 1.0)) (let ((v1-7 (-> s2-0 data))) (set! (-> v1-7 0) 1.0) (set! (-> v1-7 1) 0.0) (set! (-> v1-7 2) 0.0) (set! (-> v1-7 3) 1.0)) (let ((v1-8 (&-> s2-0 data 4))) (set! (-> v1-8 0) 0.0) (set! (-> v1-8 1) 1.0) (set! (-> v1-8 2) 0.0) (set! (-> v1-8 3) 1.0)) (let ((v1-9 (&-> s2-0 data 8))) (set! (-> v1-9 0) 0.0) (set! (-> v1-9 1) 0.0) (set! (-> v1-9 2) 1.0) (set! (-> v1-9 3) 1.0)) (.lvf vf7 (&-> *math-camera* hmge-scale quad)) (.lvf vf8 (&-> *math-camera* hvdf-off quad)) (.lvf vf9 (&-> *math-camera* giftex)) (let ((v1-13 255)) (.mov vf6 v1-13)) ;;(.mov v1-14 vf6) (.itof.vf vf6 vf6) (.svf (&-> *transform-regs* vf7) vf7) (.svf (&-> *transform-regs* vf8) vf8) (.svf (&-> *transform-regs* vf9) vf9) (.svf (&-> *transform-regs* vf6) vf6) (set! (-> *transform-regs* vf1) (-> s5-0 vector 0 quad)) (set! (-> *transform-regs* vf2) (-> s5-0 vector 1 quad)) (set! (-> *transform-regs* vf3) (-> s5-0 vector 2 quad)) (set! (-> *transform-regs* vf4) (-> s5-0 vector 3 quad)) (set! (-> *transform-regs* vf17) (-> gp-0 vector 0 quad)) (set! (-> *transform-regs* vf18) (-> gp-0 vector 1 quad)) (set! (-> *transform-regs* vf19) (-> gp-0 vector 2 quad)) (set! (-> *transform-regs* vf23) (-> s2-0 quad 0)) (set! (-> *transform-regs* vf24) (-> s2-0 quad 1)) (set! (-> *transform-regs* vf25) (-> s2-0 quad 2)) (set! (-> *transform-regs* vf27) (-> s4-0 quad 0)) (set! (-> *transform-regs* vf28) (-> s4-0 quad 1)) (set! (-> *transform-regs* vf29) (-> s4-0 quad 2)) (set! (-> *transform-regs* vf26) (-> s3-0 quad))) (none)))