;;-*-Lisp-*-
(in-package goal)

;; name: aligner.gc
;; name in dgo: aligner
;; dgos: GAME

;; DECOMP BEGINS

;; ERROR: Unsupported inline assembly instruction kind - [lw ra, return-from-thread(s7)]
;; ERROR: Unsupported inline assembly instruction kind - [jr ra]
(defmethod compute-delta-align! ((this align-control))
  "Compute the change in align since the last time this was called."
  (local-vars (disable? symbol) (s7-0 none) (ra-0 int))
  (update-anim-data (-> this process skel))
  (let ((num-chans (-> this process skel active-channels)))
    (dotimes (chan-idx (the-as int num-chans))
      (let* ((chan (-> this process skel channel chan-idx))
             (frame-group (-> chan frame-group))
             )
        (case (-> chan command)
          (((joint-control-command stack) (joint-control-command stack1))
           )
          (else
            (when (!= (-> frame-group type) art-joint-anim)
              (go process-drawable-art-error "align joint-anim")
              ;; og:preserve-this
              (abandon-thread)
              ;; (.lw ra-0 return-from-thread s7-0)
              ;; (.jr ra-0)
              ;; (nop!)
              0
              )
            )
          )
        )
      )
    )
  (let* ((root-chan (-> this process skel root-channel 0))
         (root-frame-group (-> root-chan frame-group))
         (root-frame-num (-> root-chan frame-num))
         )
    (= (-> root-chan num-func) num-func-loop!)
    (cond
      ((or (not root-frame-group) (!= (-> this frame-group) root-frame-group))
       (set! disable? #t)
       )
      ((= (-> root-chan num-func) num-func-loop!)
       (set! disable? (< (* (-> root-chan param 0) (- root-frame-num (-> this frame-num))) 0.0))
       )
      (else
        (set! disable? (= root-frame-num 0.0))
        )
      )
    (if disable?
        (logior! (-> this flags) (align-flags disabled))
        (logclear! (-> this flags) (align-flags disabled))
        )
    (set! (-> this frame-group) root-frame-group)
    (set! (-> this frame-num) root-frame-num)
    )
  (mem-copy! (the-as pointer (-> this transform 1)) (the-as pointer (-> this transform)) 48)
  (quaternion-copy! (the-as quaternion (-> this transform 1 rot)) (-> this align quat))
  (vector-copy! (-> this transform 1 scale) (-> this align scale))
  (let* ((a2-5 (-> this matrix 1))
         (a3-0 (-> this matrix))
         (v1-21 (-> a3-0 0 rvec quad))
         (a0-19 (-> a3-0 0 uvec quad))
         (a1-13 (-> a3-0 0 fvec quad))
         (a3-1 (-> a3-0 0 trans quad))
         )
    (set! (-> a2-5 rvec quad) v1-21)
    (set! (-> a2-5 uvec quad) a0-19)
    (set! (-> a2-5 fvec quad) a1-13)
    (set! (-> a2-5 trans quad) a3-1)
    )
  (let ((s5-1 (-> this process node-list data 1)))
    (cspace<-matrix-no-push-joint! s5-1 (-> this process skel))
    (let* ((v1-25 (-> this matrix))
           (a3-2 (-> s5-1 bone transform))
           (a0-22 (-> a3-2 rvec quad))
           (a1-15 (-> a3-2 uvec quad))
           (a2-6 (-> a3-2 fvec quad))
           (a3-3 (-> a3-2 trans quad))
           )
      (set! (-> v1-25 0 rvec quad) a0-22)
      (set! (-> v1-25 0 uvec quad) a1-15)
      (set! (-> v1-25 0 fvec quad) a2-6)
      (set! (-> v1-25 0 trans quad) a3-3)
      )
    (vector*! (-> this transform 0 trans) (-> s5-1 bone transform trans) (-> this process root scale))
    )
  (vector-! (-> this delta trans) (-> this transform 0 trans) (-> this transform 1 trans))
  (set-vector!
    (-> this align scale)
    (vector-length (-> this matrix 0 rvec))
    (vector-length (-> this matrix 0 uvec))
    (vector-length (-> this matrix 0 fvec))
    1.0
    )
  (vector-! (-> this delta scale) (-> this align scale) (-> this transform 1 scale))
  (let ((a2-7 (matrix-inv-scale! (new 'stack-no-clear 'matrix) (-> this align scale))))
    (quaternion-normalize! (matrix->quaternion (-> this align quat) (matrix*! a2-7 (-> this matrix 0) a2-7)))
    )
  (let ((a1-27 (quaternion-inverse! (new 'stack-no-clear 'quaternion) (the-as quaternion (-> this transform 1 rot))))
        )
    (quaternion-normalize! (quaternion*! (-> this delta quat) a1-27 (-> this align quat)))
    )
  (-> this delta)
  )

;; WARN: Return type mismatch (inline-array transform) vs transform.
(defmethod first-transform ((this align-control))
  "Get the more recent align transform"
  (the-as transform (-> this transform))
  )

(defmethod second-transform ((this align-control))
  "Get the second most recent align trasnform"
  (-> this transform 1)
  )

(defmethod align! ((this align-control) (arg0 align-opts) (arg1 float) (arg2 float) (arg3 float))
  "Apply the alignment to the process-drawable."
  (when (not (logtest? (-> this flags) (align-flags disabled)))
    (let* ((a0-1 (-> this process))
           (t9-0 (method-of-object a0-1 apply-alignment))
           (v1-4 (-> this delta))
           (t1-0 (new 'stack-no-clear 'vector))
           )
      (set! (-> t1-0 x) arg1)
      (set! (-> t1-0 y) arg2)
      (set! (-> t1-0 z) arg3)
      (set! (-> t1-0 w) 1.0)
      (t9-0 a0-1 arg0 v1-4 t1-0)
      )
    )
  (-> this process root)
  )

(defmethod set-and-limit-velocity ((this trsqv) (arg0 int) (arg1 vector) (arg2 float))
  (with-pp
    (let ((a0-1 (-> this transv)))
      (when (logtest? arg0 4)
        (set! (-> a0-1 x) (-> arg1 x))
        (set! (-> a0-1 z) (-> arg1 z))
        (let* ((v1-2 arg1)
               (f0-8
                 (fmin
                   (* (sqrtf (+ (* (-> v1-2 x) (-> v1-2 x)) (* (-> v1-2 z) (-> v1-2 z)))) (-> pp clock frames-per-second))
                   arg2
                   )
                 )
               )
          (vector-xz-normalize! a0-1 f0-8)
          )
        )
      )
    this
    )
  )

(defmethod adjust-root-no-gravity! ((this align-control) (arg0 align-opts) (arg1 vector) (arg2 int) (arg3 float) (arg4 float))
  "Adjust the quat and transv of the process drawable to take into account the
   most recent change in align."
  (with-pp
    (when (not (logtest? (-> this flags) (align-flags disabled)))
      (let ((s5-0 (-> this delta)))
        (let ((a0-1 (-> this process root transv)))
          (if (logtest? arg0 (align-opts adjust-y-vel))
              (set! (-> a0-1 y) (* (-> s5-0 trans y) arg3 (-> pp clock frames-per-second)))
              )
          (when (logtest? arg0 (align-opts adjust-xz-vel))
            (set! (-> a0-1 x) (-> arg1 x))
            (set! (-> a0-1 z) (-> arg1 z))
            (let* ((v1-11 arg1)
                   (f0-9 (sqrtf (+ (* (-> v1-11 x) (-> v1-11 x)) (* (-> v1-11 z) (-> v1-11 z)))))
                   (v1-13 (-> s5-0 trans))
                   (f0-11 (* (fmin f0-9 (* (sqrtf (+ (* (-> v1-13 x) (-> v1-13 x)) (* (-> v1-13 z) (-> v1-13 z)))) arg4))
                             (-> pp clock frames-per-second)
                             )
                          )
                   (t9-0 vector-xz-normalize!)
                   )
              (set! (-> this last-speed) f0-11)
              (t9-0 a0-1 f0-11)
              )
            )
          )
        (if (logtest? arg0 (align-opts adjust-quat))
            (quaternion-normalize! (quaternion*! (-> this process root quat) (-> this process root quat) (-> s5-0 quat)))
            )
        )
      )
    (-> this process root)
    )
  )
