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

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

(define-extern ripple-find-height (function process-drawable int vector float))
(define-extern ripple-make-request (function ripple-wave merc-effect none))
(define-extern ripple-execute (function none))

;; DECOMP BEGINS

(deftype ripple-request (structure)
  ((waveform  ripple-wave)
   (effect    merc-effect)
   )
  :pack-me
  )


(deftype ripple-globals (structure)
  ((count     int32)
   (requests  ripple-request  16 :inline)
   )
  )


(define *ripple-globals* (new 'global 'ripple-globals))

(defun ripple-make-request ((arg0 ripple-wave) (arg1 merc-effect))
  (let ((v1-1 (-> *ripple-globals* count))
        (a2-1 (-> *ripple-globals* requests))
        (a3-0 0)
        )
    (when (< v1-1 16)
      (dotimes (t0-1 v1-1)
        (if (= arg1 (-> a2-1 t0-1 effect))
            (set! a3-0 1)
            )
        )
      (when (zero? a3-0)
        (set! (-> a2-1 v1-1 effect) arg1)
        (set! (-> a2-1 v1-1 waveform) arg0)
        (+! (-> *ripple-globals* count) 1)
        )
      )
    )
  0
  (none)
  )

(defun ripple-update-waveform-offs ((arg0 ripple-wave-set) (arg1 clock))
  (let ((f0-1 (the float (- (-> arg1 integral-frame-counter) (the-as int (-> arg0 frame-save))))))
    (when (!= f0-1 0.0)
      (dotimes (v1-3 (-> arg0 count))
        (let ((a2-4 (-> arg0 wave v1-3)))
          (+! (-> a2-4 offs) (* f0-1 (-> a2-4 delta)))
          (set! (-> a2-4 offs) (the float (logand (the int (-> a2-4 offs)) #xffff)))
          )
        )
      (set! (-> arg0 frame-save) (the-as uint (-> arg1 integral-frame-counter)))
      )
    )
  0
  (none)
  )

(def-mips2c ripple-execute-init (function none))

(def-mips2c ripple-create-wave-table (function ripple-wave-set int))

(def-mips2c ripple-apply-wave-table (function merc-effect symbol))

(defun ripple-execute ()
  (when (-> *ripple-globals* count)
    (ripple-execute-init)
    (let ((gp-0 0)
          (s5-0 (-> *ripple-globals* count))
          (s4-0 (-> *ripple-globals* requests))
          )
      (while (!= gp-0 s5-0)
        (when (-> s4-0 gp-0 waveform)
          (let ((s3-0 gp-0)
                (s2-0 (-> s4-0 gp-0 waveform))
                )
            (ripple-create-wave-table (the-as ripple-wave-set s2-0))
            (while (!= s3-0 s5-0)
              (when (= s2-0 (-> s4-0 s3-0 waveform))
                (ripple-apply-wave-table (-> s4-0 s3-0 effect))
                (set! (-> s4-0 s3-0 waveform) #f)
                )
              (+! s3-0 1)
              )
            )
          )
        (+! gp-0 1)
        )
      )
    (set! (-> *ripple-globals* count) 0)
    0
    )
  0
  (none)
  )

(def-mips2c ripple-matrix-scale (function merc-effect none))

;; WARN: Return type mismatch symbol vs none.
(defun-debug ripple-add-debug-sphere ((arg0 process-drawable) (arg1 vector) (arg2 float) (arg3 float))
  (let ((f30-0 (- (quaternion-y-angle (-> arg0 root quat))))
        (s5-0 (new-stack-vector0))
        )
    (let ((f28-0 (+ (-> arg1 x) (* arg2 (-> arg1 z))))
          (f26-0 (+ (-> arg1 y) (* arg3 (-> arg1 z))))
          )
      (set! (-> s5-0 x) (- (* f28-0 (cos f30-0)) (* f26-0 (sin f30-0))))
      (set! (-> s5-0 y) 0.0)
      (set! (-> s5-0 z) (+ (* f26-0 (cos f30-0)) (* f28-0 (sin f30-0))))
      )
    (set! (-> s5-0 w) 0.0)
    (vector+! s5-0 s5-0 (-> arg0 root trans))
    (add-debug-sphere #t (bucket-id debug) s5-0 (meters 0.5) (new 'static 'rgba :r #xff :g #xff :a #x80))
    )
  (none)
  )

(defun ripple-slow-add-sine-waves ((arg0 ripple-wave-set) (arg1 float) (arg2 float))
  (let ((f30-0 0.0))
    (dotimes (s3-0 (-> arg0 count))
      (let* ((v1-3 (-> arg0 wave s3-0))
             (f0-2 (+ (-> v1-3 offs) (* arg1 (-> v1-3 xmul)) (* arg2 (-> v1-3 zmul))))
             )
        (+! f30-0 (* (-> v1-3 scale) (cos f0-2)))
        )
      )
    (fmax -127.0 (fmin 127.0 f30-0))
    )
  )

(defun ripple-find-height ((arg0 process-drawable) (arg1 int) (arg2 vector))
  (local-vars (sv-16 draw-control) (sv-32 float) (sv-48 float))
  (let ((f30-0 (-> arg0 root trans y)))
    (set! sv-16 (-> arg0 draw))
    (if (or (zero? sv-16) (not (-> sv-16 ripple)))
        (return f30-0)
        )
    (let ((v1-11 (-> sv-16 lod-set lod (-> sv-16 cur-lod) geo effect)))
      (if (not (logtest? (-> v1-11 0 effect-bits) (effect-bits ripple)))
          (return f30-0)
          )
      (let* ((v1-12 (-> v1-11 0 extra-info))
             (s4-0 (the-as mei-ripple (+ (the-as uint v1-12) (* (-> v1-12 ripple-offset) 16))))
             (gp-0 (-> sv-16 ripple))
             (s5-0 (-> gp-0 waveform))
             )
        (if (not (-> gp-0 waveform))
            (return f30-0)
            )
        (if (not (-> s5-0 converted))
            (return f30-0)
            )
        (let* ((f28-0 (- (-> arg2 x) (-> arg0 root trans x)))
               (f26-0 (- (-> arg2 z) (-> arg0 root trans z)))
               (f22-0 (+ (quaternion-y-angle (-> arg0 root quat)) (-> s4-0 angle)))
               (f24-0 (cos f22-0))
               (f1-3 (sin f22-0))
               (f0-4 (- (* f28-0 f24-0) (* f26-0 f1-3)))
               (f1-5 (+ (* f26-0 f24-0) (* f28-0 f1-3)))
               (f2-3 (/ 1.0 (-> s4-0 grid-size)))
               (f28-1 (* f2-3 (- f0-4 (-> s4-0 x-base))))
               (f26-1 (* f2-3 (- f1-5 (-> s4-0 z-base))))
               )
          (ripple-update-waveform-offs s5-0 (-> *display* bg-clock))
          (let* ((f22-1 (the float (the int f28-1)))
                 (f24-1 (the float (the int f26-1)))
                 (f20-0 (ripple-slow-add-sine-waves s5-0 f22-1 f24-1))
                 )
            (set! sv-32 (ripple-slow-add-sine-waves s5-0 (+ 1.0 f22-1) f24-1))
            (set! sv-48 (ripple-slow-add-sine-waves s5-0 f22-1 (+ 1.0 f24-1)))
            (let* ((f1-6 (ripple-slow-add-sine-waves s5-0 (+ 1.0 f22-1) (+ 1.0 f24-1)))
                   (f0-22 (+ f20-0 (* (- f28-1 f22-1) (- sv-32 f20-0))))
                   (f1-9 (+ sv-48 (* (- f28-1 f22-1) (- f1-6 sv-48))))
                   (f1-12 (+ f0-22 (* (- f26-1 f24-1) (- f1-9 f0-22))))
                   (f0-23 (-> gp-0 faded-scale))
                   )
              (if (< f0-23 0.0)
                  (set! f0-23 (-> gp-0 global-scale))
                  )
              (+ f30-0 (* (/ f1-12 128) f0-23))
              )
            )
          )
        )
      )
    )
  )
