;;-*-Lisp-*-
(in-package goal)
(bundles "ENGINE.CGO" "GAME.CGO")
(require "engine/gfx/hw/display.gc")
(require "engine/gfx/foreground/bones-h.gc")
(require "engine/gfx/mood/time-of-day-h.gc")
(require "engine/gfx/shadow/shadow-vu1-h.gc")
(require "engine/collide/collide-mesh-h.gc")
(require "engine/gfx/generic/generic-h.gc")
(require "engine/collide/pat-h.gc")

;; DECOMP BEGINS

(defmethod asize-of ((obj shadow-geo))
  (the-as int (-> obj total-size)))

(defmethod mem-usage ((obj shadow-geo) (arg0 memory-usage-block) (arg1 int))
  (set! (-> arg0 length) (max 108 (-> arg0 length)))
  (set! (-> arg0 data 107 name) "shadow-geo")
  (+! (-> arg0 data 107 count) 1)
  (let ((v1-5 (-> obj total-size)))
    (+! (-> arg0 data 107 used) v1-5)
    (+! (-> arg0 data 107 total) (logand -16 (+ v1-5 15))))
  obj)

(define *shadow-data*
  (new 'static
       'shadow-data
       :texoffset
       (new 'static 'vector :x 256.5 :y 112.5)
       :texscale
       (new 'static 'vector :x 0.001953125 :y 0.00390625)
       :clrs
       (new 'static
            'inline-array
            vector
            2
            (new 'static 'vector :x (the-as float #x80) :w (the-as float #x82))
            (new 'static 'vector :y (the-as float #x80) :w (the-as float #x7f)))
       :dma-unpack-template
       (new 'static
            'dma-packet
            :dma
            (new 'static 'dma-tag :id (dma-tag-id cnt))
            :vif0
            (new 'static 'vif-tag :cmd (vif-cmd flusha) :msk #x1)
            :vif1
            (new 'static 'vif-tag :cmd (vif-cmd unpack-v4-32)))
       :dma-cnt
       (new 'static 'dma-tag :id (dma-tag-id cnt))
       :vif-unpack-v4-8
       (new 'static 'vif-tag :cmd (vif-cmd unpack-v4-8))))

(defun shadow-dma-init ((arg0 dma-buffer))
  (let* ((v1-0 *display*)
         (a1-2 (-> v1-0 frames (-> v1-0 on-screen) draw frame1 fbp)))
    (* a1-2 32)
    (let ((t3-0 512)
          (t2-0 (-> *video-parms* screen-sy))
          (a2-0 1792)
          (a3-0 (-> *video-parms* screen-miny)))
      2304
      (let ((t0-0 (-> *video-parms* screen-maxy))
            (t1-0 (/ t3-0 32))
            (t5-0 (* a3-0 16))
            (v1-11 (-> arg0 base)))
        (let* ((t4-0 arg0)
               (t6-0 (the-as object (-> t4-0 base))))
          (set! (-> (the-as dma-packet t6-0) dma) (new 'static 'dma-tag :id (dma-tag-id cnt)))
          (set! (-> (the-as dma-packet t6-0) vif0) (new 'static 'vif-tag))
          (set! (-> (the-as dma-packet t6-0) vif1) (new 'static 'vif-tag :cmd (vif-cmd direct) :msk #x1))
          (set! (-> t4-0 base) (&+ (the-as pointer t6-0) 16)))
        (let* ((t4-1 arg0)
               (t6-2 (the-as object (-> t4-1 base))))
          (set! (-> (the-as gs-gif-tag t6-2) tag) (new 'static 'gif-tag64 :nloop #xa :eop #x1 :nreg #x1))
          (set! (-> (the-as gs-gif-tag t6-2) regs) (new 'static 'gif-tag-regs :regs0 (gif-reg-id a+d)))
          (set! (-> t4-1 base) (&+ (the-as pointer t6-2) 16)))
        (let ((t4-2 (-> arg0 base)))
          (set! (-> (the-as (pointer gs-reg) t4-2) 8) (gs-reg texflush))
          (set! (-> (the-as (pointer gs-reg) t4-2) 24) (gs-reg test-1))
          (set! (-> (the-as (pointer gs-test) t4-2) 2)
                (new 'static 'gs-test :ate #x1 :atst (gs-atest always) :zte #x1 :ztst (gs-ztest always)))
          (set! (-> (the-as (pointer gs-reg) t4-2) 40) (gs-reg alpha-1))
          (set! (-> (the-as (pointer gs-alpha) t4-2) 4) (new 'static 'gs-alpha :b #x1 :d #x1))
          (set! (-> (the-as (pointer gs-reg) t4-2) 56) (gs-reg frame-1))
          (set! (-> (the-as (pointer gs-frame) t4-2) 6) (new 'static 'gs-frame :fbw #x8 :fbmsk #xffffff :fbp a1-2))
          (set! (-> (the-as (pointer gs-reg) t4-2) 72) (gs-reg zbuf-1))
          (set! (-> (the-as (pointer gs-zbuf) t4-2) 8) (new 'static 'gs-zbuf :zbp #x1c0 :psm (gs-psm ct24) :zmsk #x1))
          (set! (-> (the-as (pointer gs-reg) t4-2) 88) (gs-reg xyoffset-1))
          (set! (-> (the-as (pointer gs-xy-offset) t4-2) 10) (new 'static 'gs-xy-offset :ofx (* a2-0 16) :ofy t5-0))
          (set! (-> (the-as (pointer gs-reg) t4-2) 104) (gs-reg tex0-1))
          (set! (-> (the-as (pointer gs-tex0) t4-2) 12) (new 'static 'gs-tex0 :tbw #x8 :tw #x9 :th #x8 :tcc #x1 :tbp0 (* a1-2 32)))
          (set! (-> (the-as (pointer gs-reg) t4-2) 120) (gs-reg tex1-1))
          (set! (-> (the-as (pointer gs-tex1) t4-2) 14) (new 'static 'gs-tex1))
          (set! (-> (the-as (pointer gs-reg) t4-2) 136) (gs-reg miptbp1-1))
          (set! (-> (the-as (pointer gs-miptbp) t4-2) 16) (new 'static 'gs-miptbp))
          (set! (-> (the-as (pointer gs-reg) t4-2) 152) (gs-reg clamp-1))
          (set! (-> (the-as (pointer gs-clamp) t4-2) 18)
                (new 'static
                     'gs-clamp
                     :wms (gs-tex-wrap-mode region-clamp)
                     :wmt (gs-tex-wrap-mode region-clamp)
                     :maxv
                     (+ t2-0 -1)
                     :maxu
                     (+ t3-0 -1))))
        (&+! (-> arg0 base) 160)
        (let* ((t2-7 arg0)
               (t3-5 (the-as object (-> t2-7 base))))
          (set! (-> (the-as gs-gif-tag t3-5) tag) (new 'static 'gif-tag64 :nloop #x1 :eop #x1 :flg (gif-flag reg-list) :nreg #x2))
          (set! (-> (the-as gs-gif-tag t3-5) regs) (new 'static 'gif-tag-regs :regs1 (gif-reg-id rgbaq)))
          (set! (-> t2-7 base) (&+ (the-as pointer t3-5) 16)))
        (let* ((t2-8 arg0)
               (t3-7 (-> t2-8 base)))
          (set! (-> (the-as (pointer gs-prim) t3-7) 0) (new 'static 'gs-prim :prim (gs-prim-type sprite)))
          (set! (-> (the-as (pointer gs-rgbaq) t3-7) 1) (new 'static 'gs-rgbaq :a #x60))
          (set! (-> t2-8 base) (&+ t3-7 16)))
        (let* ((t2-9 arg0)
               (t3-9 (the-as object (-> t2-9 base))))
          (set! (-> (the-as gs-gif-tag t3-9) tag) (new 'static 'gif-tag64 :eop #x1 :flg (gif-flag reg-list) :nreg #x2 :nloop t1-0))
          (set! (-> (the-as gs-gif-tag t3-9) regs) (new 'static 'gif-tag-regs :regs0 (gif-reg-id xyz2) :regs1 (gif-reg-id xyz2)))
          (set! (-> t2-9 base) (&+ (the-as pointer t3-9) 16)))
        (let ((t2-10 0))
          (dotimes (t3-11 t1-0)
            (let* ((t4-10 arg0)
                   (t5-12 (-> t4-10 base)))
              (set! (-> (the-as (pointer gs-xyzf) t5-12) 0) (new 'static 'gs-xyzf :z #x1ffff :y (* a3-0 16) :x (* (+ a2-0 t2-10) 16)))
              (set! (-> (the-as (pointer gs-xyzf) t5-12) 1)
                    (new 'static 'gs-xyzf :z #x1ffff :y (* t0-0 16) :x (* (+ t2-10 32 a2-0) 16)))
              (set! (-> t4-10 base) (&+ t5-12 16)))
            (+! t2-10 32)))
        (let* ((a2-3 arg0)
               (a3-1 (the-as object (-> a2-3 base))))
          (set! (-> (the-as gs-gif-tag a3-1) tag) (new 'static 'gif-tag64 :nloop #x4 :eop #x1 :nreg #x1))
          (set! (-> (the-as gs-gif-tag a3-1) regs) (new 'static 'gif-tag-regs :regs0 (gif-reg-id a+d)))
          (set! (-> a2-3 base) (&+ (the-as pointer a3-1) 16)))
        (cond
          (*shadow-debug*
           (let* ((a2-5 arg0)
                  (a3-3 (-> a2-5 base)))
             (set! (-> (the-as (pointer gs-test) a3-3) 0)
                   (new 'static 'gs-test :ate #x1 :atst (gs-atest always) :zte #x1 :ztst (gs-ztest greater-equal)))
             (set! (-> (the-as (pointer gs-reg64) a3-3) 1) (gs-reg64 test-1))
             (set! (-> (the-as (pointer gs-zbuf) a3-3) 2) (new 'static 'gs-zbuf :zbp #x1c0 :psm (gs-psm ct24)))
             (set! (-> (the-as (pointer gs-reg64) a3-3) 3) (gs-reg64 zbuf-1))
             (set! (-> (the-as (pointer gs-frame) a3-3) 4) (new 'static 'gs-frame :fbw #x8 :fbp a1-2))
             (set! (-> (the-as (pointer gs-reg64) a3-3) 5) (gs-reg64 frame-1))
             (set! (-> (the-as (pointer uint64) a3-3) 6) (the-as uint 0))
             (set! (-> (the-as (pointer gs-reg64) a3-3) 7) (gs-reg64 texflush))
             (set! (-> a2-5 base) (&+ a3-3 64))))
          (else
           (let* ((a2-6 arg0)
                  (a3-4 (-> a2-6 base)))
             (set! (-> (the-as (pointer gs-test) a3-4) 0)
                   (new 'static 'gs-test :ate #x1 :atst (gs-atest always) :zte #x1 :ztst (gs-ztest greater-equal)))
             (set! (-> (the-as (pointer gs-reg64) a3-4) 1) (gs-reg64 test-1))
             (set! (-> (the-as (pointer gs-zbuf) a3-4) 2) (new 'static 'gs-zbuf :zbp #x1c0 :psm (gs-psm ct24) :zmsk #x1))
             (set! (-> (the-as (pointer gs-reg64) a3-4) 3) (gs-reg64 zbuf-1))
             (set! (-> (the-as (pointer gs-frame) a3-4) 4) (new 'static 'gs-frame :fbw #x8 :fbmsk #xffffff :fbp a1-2))
             (set! (-> (the-as (pointer gs-reg64) a3-4) 5) (gs-reg64 frame-1))
             (set! (-> (the-as (pointer uint64) a3-4) 6) (the-as uint 0))
             (set! (-> (the-as (pointer gs-reg64) a3-4) 7) (gs-reg64 texflush))
             (set! (-> a2-6 base) (&+ a3-4 64)))))
        (let ((a2-10 (/ (the-as int (+ (- -16 (the-as int v1-11)) (the-as int (-> arg0 base)))) 16)))
          (cond
            ((nonzero? a2-10)
             (logior! (-> (the-as (pointer uint64) v1-11) 0) (shr (shl a2-10 48) 48))
             (logior! (-> (the-as (pointer uint64) v1-11) 1) (shl (shr (shl a2-10 48) 48) 32)))
            (else (set! (-> arg0 base) v1-11)))))))
  (none))

(defun shadow-dma-end ((arg0 dma-buffer))
  (local-vars (t9-2 int) (ra-0 int) (ra-1 int) (ra-2 int))
  (let* ((v1-0 *display*)
         (v1-5 (-> v1-0 frames (-> v1-0 on-screen) draw frame1 fbp)))
    (* v1-5 32)
    (let ((a2-0 512)
          (a3-0 (-> *video-parms* screen-sy))
          (a1-5 1792)
          (t0-1 (-> *video-parms* screen-miny)))
      2304
      (-> *video-parms* screen-maxy)
      (let ((t1-3 (/ a2-0 32))
            (a2-3 (+ (* *oddeven* 8) (* t0-1 16))))
        (let* ((t2-1 arg0)
               (t3-0 (the-as object (-> t2-1 base))))
          (set! (-> (the-as dma-packet t3-0) dma) (new 'static 'dma-tag :qwc #x5 :id (dma-tag-id cnt)))
          (set! (-> (the-as dma-packet t3-0) vif0) (new 'static 'vif-tag :cmd (vif-cmd flusha) :msk #x1))
          (set! (-> (the-as dma-packet t3-0) vif1) (new 'static 'vif-tag :imm #x5 :cmd (vif-cmd direct) :msk #x1))
          (set! (-> t2-1 base) (&+ (the-as pointer t3-0) 16)))
        (let* ((t2-2 arg0)
               (t3-2 (the-as object (-> t2-2 base))))
          (set! (-> (the-as gs-gif-tag t3-2) tag) (new 'static 'gif-tag64 :nloop #x1 :eop #x1 :nreg #x4))
          (set! (-> (the-as gs-gif-tag t3-2) regs)
                (new 'static
                     'gif-tag-regs
                     :regs0 (gif-reg-id a+d)
                     :regs1 (gif-reg-id a+d)
                     :regs2 (gif-reg-id a+d)
                     :regs3 (gif-reg-id a+d)
                     :regs4 (gif-reg-id a+d)
                     :regs5 (gif-reg-id a+d)
                     :regs6 (gif-reg-id a+d)
                     :regs7 (gif-reg-id a+d)
                     :regs8 (gif-reg-id a+d)
                     :regs9 (gif-reg-id a+d)
                     :regs10 (gif-reg-id a+d)
                     :regs11 (gif-reg-id a+d)
                     :regs12 (gif-reg-id a+d)
                     :regs13 (gif-reg-id a+d)
                     :regs14 (gif-reg-id a+d)
                     :regs15 (gif-reg-id a+d)))
          (set! (-> t2-2 base) (&+ (the-as pointer t3-2) 16)))
        (let* ((t2-3 arg0)
               (t3-4 (-> t2-3 base)))
          (set! (-> (the-as (pointer uint64) t3-4) 0) (the-as uint 0))
          (set! (-> (the-as (pointer gs-reg64) t3-4) 1) (gs-reg64 texflush))
          (set! (-> (the-as (pointer gs-test) t3-4) 2)
                (new 'static 'gs-test :ate #x1 :atst (gs-atest not-equal) :aref #x60 :zte #x1 :ztst (gs-ztest always)))
          (set! (-> (the-as (pointer gs-reg64) t3-4) 3) (gs-reg64 test-1))
          (set! (-> (the-as (pointer gs-frame) t3-4) 4) (new 'static 'gs-frame :fbw #x8 :fbp v1-5))
          (set! (-> (the-as (pointer gs-reg64) t3-4) 5) (gs-reg64 frame-1))
          (set! (-> (the-as (pointer uint64) t3-4) 6) (the-as uint 0))
          (set! (-> (the-as (pointer gs-reg64) t3-4) 7) (gs-reg64 texflush))
          (set! (-> t2-3 base) (&+ t3-4 64)))
        (let ((t2-4 (-> arg0 base)))
          (let* ((t3-6 arg0)
                 (t4-13 (the-as object (-> t3-6 base))))
            (set! (-> (the-as dma-packet t4-13) dma) (new 'static 'dma-tag :id (dma-tag-id cnt)))
            (set! (-> (the-as dma-packet t4-13) vif0) (new 'static 'vif-tag :cmd (vif-cmd flusha) :msk #x1))
            (set! (-> (the-as dma-packet t4-13) vif1) (new 'static 'vif-tag :cmd (vif-cmd direct) :msk #x1))
            (set! (-> t3-6 base) (&+ (the-as pointer t4-13) 16)))
          (let* ((t4-15 (the-as uint #x3f80000080404040))
                 (t3-8 (-> *time-of-day-context* current-shadow-color))
                 (t5-14 (the-as gs-rgbaq
                                (logior (logand (logior (logand (logior (logand t4-15 -256) (shr (shl (the int (* 128.0 (-> t3-8 x))) 56) 56)) -65281)
                                                        (shr (shl (the int (* 128.0 (-> t3-8 y))) 56) 48))
                                                -16711681)
                                        (shr (shl (the int (* 128.0 (-> t3-8 z))) 56) 40))))
                 (t3-12 arg0)
                 (t4-21 (the-as object (-> t3-12 base))))
            (set! (-> (the-as gs-gif-tag t4-21) tag) (new 'static 'gif-tag64 :nloop #x1 :flg (gif-flag reg-list) :nreg #x2))
            (set! (-> (the-as gs-gif-tag t4-21) regs) (new 'static 'gif-tag-regs :regs1 (gif-reg-id rgbaq)))
            (set! (-> (the-as (pointer gs-prim) t4-21) 2) (new 'static 'gs-prim :prim (gs-prim-type sprite) :tme #x1 :abe #x1))
            (set! (-> (the-as (pointer gs-rgbaq) t4-21) 3) t5-14)
            (set! (-> (the-as (inline-array gs-gif-tag) t4-21) 2 tag)
                  (new 'static 'gif-tag64 :eop #x1 :flg (gif-flag reg-list) :nreg #x4 :nloop t1-3))
            (set! (-> (the-as (inline-array gs-gif-tag) t4-21) 2 regs)
                  (new 'static
                       'gif-tag-regs
                       :regs0 (gif-reg-id st)
                       :regs1 (gif-reg-id xyz2)
                       :regs2 (gif-reg-id st)
                       :regs3 (gif-reg-id xyz2)))
            (set! (-> t3-12 base) (&+ (the-as pointer t4-21) 48)))
          (let ((t3-13 0)
                (t4-23 0))
            (dotimes (t5-18 t1-3)
              (let ((t8-0 t3-13))
                (+! t3-13 32)
                (let* ((t6-5 arg0)
                       (t7-0 (-> t6-5 base)))
                  (let ((t9-1 (shl (the-as int (* 0.00390625 (+ 0.5 (the float (the-as int t4-23))))) 32)))
                    (let ((f0-12 (* 0.001953125 (+ 0.5 (the float t8-0))))) (.mov ra-0 f0-12))
                    ;;(.dsll32 ra-1 ra-0 0)
                    (set! ra-1 (shl ra-0 32))
                    ;;(.dsrl32 ra-2 ra-1 0)
                    (set! ra-2 (shr ra-1 32))
                    ;(.or t9-2 t9-1 ra-2)
                    (set! t9-2 (logior t9-1 ra-2)))
                  (set! (-> (the-as (pointer int64) t7-0)) t9-2)
                  (set! (-> (the-as (pointer gs-xyzf) t7-0) 1)
                        (new 'static 'gs-xyzf :z #x1ffff :y (* (+ t0-1 t4-23) 16) :x (* (+ a1-5 t8-0) 16)))
                  (set! (-> (the-as (pointer gs-st) t7-0) 2)
                        (new 'static 'gs-st :s (* 0.001953125 (+ 0.5 (the float t3-13))) :t (* 0.00390625 (+ 0.5 (the float a3-0)))))
                  (set! (-> (the-as (pointer gs-xyzf) t7-0) 3)
                        (new 'static 'gs-xyzf :z #x1ffff :y (* (+ t0-1 a3-0) 16) :x (* (+ a1-5 t3-13) 16)))
                  (set! (-> t6-5 base) (&+ t7-0 32))))))
          (let ((t0-5 (/ (the-as int (+ (- -16 (the-as int t2-4)) (the-as int (-> arg0 base)))) 16)))
            (cond
              ((nonzero? t0-5)
               (logior! (-> (the-as (pointer uint64) t2-4)) (shr (shl t0-5 48) 48))
               (logior! (-> (the-as (pointer uint64) t2-4) 1) (shl (shr (shl t0-5 48) 48) 32)))
              (else (set! (-> arg0 base) t2-4)))))
        (let* ((a3-3 arg0)
               (t0-11 (the-as object (-> a3-3 base))))
          (set! (-> (the-as dma-packet t0-11) dma) (new 'static 'dma-tag :qwc #x7 :id (dma-tag-id cnt)))
          (set! (-> (the-as dma-packet t0-11) vif0) (new 'static 'vif-tag))
          (set! (-> (the-as dma-packet t0-11) vif1) (new 'static 'vif-tag :imm #x7 :cmd (vif-cmd direct) :msk #x1))
          (set! (-> a3-3 base) (&+ (the-as pointer t0-11) 16)))
        (let* ((a3-4 arg0)
               (t0-13 (the-as object (-> a3-4 base))))
          (set! (-> (the-as gs-gif-tag t0-13) tag) (new 'static 'gif-tag64 :nloop #x1 :eop #x1 :nreg #x6))
          (set! (-> (the-as gs-gif-tag t0-13) regs)
                (new 'static
                     'gif-tag-regs
                     :regs0 (gif-reg-id a+d)
                     :regs1 (gif-reg-id a+d)
                     :regs2 (gif-reg-id a+d)
                     :regs3 (gif-reg-id a+d)
                     :regs4 (gif-reg-id a+d)
                     :regs5 (gif-reg-id a+d)
                     :regs6 (gif-reg-id a+d)
                     :regs7 (gif-reg-id a+d)
                     :regs8 (gif-reg-id a+d)
                     :regs9 (gif-reg-id a+d)
                     :regs10 (gif-reg-id a+d)
                     :regs11 (gif-reg-id a+d)
                     :regs12 (gif-reg-id a+d)
                     :regs13 (gif-reg-id a+d)
                     :regs14 (gif-reg-id a+d)
                     :regs15 (gif-reg-id a+d)))
          (set! (-> a3-4 base) (&+ (the-as pointer t0-13) 16)))
        (let* ((a3-5 arg0)
               (t0-15 (-> a3-5 base)))
          (set! (-> (the-as (pointer gs-test) t0-15) 0)
                (new 'static 'gs-test :atst (gs-atest not-equal) :zte #x1 :ztst (gs-ztest greater-equal)))
          (set! (-> (the-as (pointer gs-reg64) t0-15) 1) (gs-reg64 test-1))
          (set! (-> (the-as (pointer gs-xy-offset) t0-15) 2) (new 'static 'gs-xy-offset :ofx (* a1-5 16) :ofy a2-3))
          (set! (-> (the-as (pointer gs-reg64) t0-15) 3) (gs-reg64 xyoffset-1))
          (set! (-> (the-as (pointer gs-alpha) t0-15) 4) (new 'static 'gs-alpha :b #x1 :d #x1))
          (set! (-> (the-as (pointer gs-reg64) t0-15) 5) (gs-reg64 alpha-1))
          (set! (-> (the-as (pointer gs-frame) t0-15) 6) (new 'static 'gs-frame :fbw #x8 :fbp v1-5))
          (set! (-> (the-as (pointer gs-reg64) t0-15) 7) (gs-reg64 frame-1))
          (set! (-> (the-as (pointer gs-zbuf) t0-15) 8) (new 'static 'gs-zbuf :zbp #x1c0 :psm (gs-psm ct24)))
          (set! (-> (the-as (pointer gs-reg64) t0-15) 9) (gs-reg64 zbuf-1))
          (set! (-> (the-as (pointer uint64) t0-15) 10) (the-as uint 0))
          (set! (-> (the-as (pointer gs-reg64) t0-15) 11) (gs-reg64 texflush))
          (set! (-> a3-5 base) (&+ t0-15 96))))))
  (none))

(deftype shadow-stats (structure)
  ((num-single-tris  uint32 :offset-assert 0)
   (num-double-tris  uint32 :offset-assert 4)
   (num-single-edges uint32 :offset-assert 8)
   (num-double-edges uint32 :offset-assert 12))
  :method-count-assert 9
  :size-assert #x10
  :flag-assert #x900000010)

(deftype shadow-dcache (structure)
  ((vtx-table              uint32 :offset-assert 0)
   (single-edge-table      uint32 :offset-assert 4)
   (double-edge-table      uint32 :offset-assert 8)
   (double-tri-table       uint32 :offset-assert 12)
   (dcache-top             uint32 :offset-assert 16)
   (num-facing-single-tris uint32 :offset-assert 20)
   (num-single-edges       uint32 :offset-assert 24)
   (num-double-edges       uint32 :offset-assert 28)
   (single-tri-list        uint32 :offset-assert 32)
   (single-edge-list       uint32 :offset-assert 36)
   (double-edge-list       uint32 :offset-assert 40)
   (ptr-dual-verts         uint32 :offset-assert 44)
   (stats                  shadow-stats :inline :offset-assert 48)
   (center                 vector :inline :offset-assert 64)
   (plane                  vector :inline :offset-assert 80)
   (top-plane              vector :inline :offset-assert 96)
   (near-plane             vector :inline :offset-assert 112)
   (light-dir              vector :inline :offset-assert 128)
   (vtx-min                vector :inline :offset-assert 144)
   (data                   uint8 :dynamic :offset-assert 160))
  :method-count-assert 9
  :size-assert #xa0
  :flag-assert #x9000000a0)

(define shadow-vu0-block
  (new 'static
       'vu-function
       #| :length 88 :qlength 44 |#
       ))

(def-mips2c shadow-xform-verts function)

(def-mips2c shadow-execute (function shadow-dma-packet pointer pointer))

(defun shadow-vu0-upload ()
  (#unless PC_PORT
    (let ((gp-0 *vu0-dma-list*))
      (let ((v1-0 gp-0))
        (set! (-> v1-0 base) (-> v1-0 data))
        (set! (-> v1-0 end) (&-> v1-0 data-buffer (-> v1-0 allocated-length))))
      (dma-buffer-add-vu-function gp-0 shadow-vu0-block 0)
      (let* ((v1-1 gp-0)
             (a0-5 (-> v1-1 base)))
        (set! (-> (the-as (pointer int64) a0-5)) #x70000000)
        (s.d! (+ a0-5 8) 0)
        (set! (-> v1-1 base) (&+ a0-5 16)))
      (.sync.l)
      (dma-buffer-send-chain (the-as dma-bank-source #x10008000) gp-0)))
  0
  (none))

(defun shadow-execute-all ((arg0 dma-buffer) (arg1 shadow-queue))
  (if *debug-segment*
    (add-frame (-> *display* frames (-> *display* on-screen) frame profile-bar 0)
               'draw
               (new 'static 'rgba :r #x40 :b #x40 :a #x80)))
  (when (logtest? (vu1-renderer-mask shadow) *vu1-enable-user*)
    (when (> (-> arg1 cur-run) 0)
      (let ((v1-12 #f))
        (dotimes (a0-6 (the-as int (-> arg1 cur-run)))
          (if (nonzero? (-> arg1 run a0-6 first)) (set! v1-12 #t)))
        (when v1-12
          (shadow-vu0-upload)
          (let* ((s4-0 (-> *display* frames (-> *display* on-screen) frame global-buf))
                 (s5-0 (-> s4-0 base)))
            (shadow-vu1-init-buffer s4-0)
            (flush-cache 0)
            (let ((v1-17 (the-as shadow-dcache *gsf-buffer*)))
              (set! (-> v1-17 stats num-single-tris) (the-as uint 0))
              (set! (-> v1-17 stats num-double-tris) (the-as uint 0))
              (set! (-> v1-17 stats num-single-edges) (the-as uint 0))
              (set! (-> v1-17 stats num-double-edges) (the-as uint 0)))
            0
            (shadow-dma-init s4-0)
            (dotimes (s3-0 (the-as int (-> arg1 cur-run)))
              (let ((v1-21 (-> arg1 run s3-0)))
                (if (nonzero? (-> v1-21 first))
                  (set! (-> s4-0 base) (shadow-execute (the-as shadow-dma-packet (-> v1-21 first)) (-> s4-0 base))))))
            (shadow-dma-end s4-0)
            (let ((a3-0 (-> s4-0 base)))
              (let ((v1-25 (the-as object (-> s4-0 base))))
                (set! (-> (the-as dma-packet v1-25) dma) (new 'static 'dma-tag :id (dma-tag-id next)))
                (set! (-> (the-as dma-packet v1-25) vif0) (new 'static 'vif-tag))
                (set! (-> (the-as dma-packet v1-25) vif1) (new 'static 'vif-tag))
                (set! (-> s4-0 base) (&+ (the-as pointer v1-25) 16)))
              (dma-bucket-insert-tag (-> *display* frames (-> *display* on-screen) frame bucket-group)
                                     (bucket-id shadow)
                                     s5-0
                                     (the-as (pointer dma-tag) a3-0))))))
      (when #f
        (let ((gp-1 (the-as structure *gsf-buffer*)))
          (format *stdcon* "#single tris : ~4d~%" (-> (the-as shadow-dcache gp-1) stats num-single-tris))
          (format *stdcon* "#double tris : ~4d~%" (-> (the-as shadow-dcache gp-1) stats num-double-tris))
          (format *stdcon* "#single edges: ~4d~%" (-> (the-as shadow-dcache gp-1) stats num-single-edges))
          (format *stdcon* "#double edges: ~4d~%" (-> (the-as shadow-dcache gp-1) stats num-double-edges))))))
  (if *debug-segment*
    (add-frame (-> *display* frames (-> *display* on-screen) frame profile-bar 0)
               'draw
               (new 'static 'rgba :r #x40 :g #x42 :b #xe0 :a #x80)))
  0
  (none))

(defmethod update-direction-from-time-of-day ((obj shadow-control))
  (let ((v1-1 (-> *time-of-day-context* current-shadow)))
    (set! (-> obj settings shadow-dir x) (-> v1-1 x))
    (set! (-> obj settings shadow-dir y) (-> v1-1 y))
    (set! (-> obj settings shadow-dir z) (-> v1-1 z)))
  0
  (none))

(defmethod collide-to-find-planes ((obj shadow-control) (arg0 vector) (arg1 float) (arg2 float) (arg3 float))
  (with-pp
    (let ((s4-0 (new 'stack-no-clear 'collide-tri-result))
          (v1-0 (new 'stack-no-clear 'vector))
          (a2-1 (new 'stack-no-clear 'vector)))
      (set! (-> v1-0 quad) (-> arg0 quad))
      (set! (-> v1-0 y) (+ 4096.0 (-> v1-0 y)))
      (set-vector! a2-1 0.0 (- arg3) 0.0 1.0)
      (cond
        ((>= (fill-and-probe-using-line-sphere *collide-cache*
                                               v1-0
                                               a2-1
                                               8192.0
                                               (collide-kind background)
                                               pp
                                               s4-0
                                               (new 'static 'pat-surface :noentity #x1))
             0.0)
         (let ((v1-2 obj)) (logclear! (-> v1-2 settings flags) (shadow-flags disable-draw)))
         0
         (let ((v1-4 obj)) (set! (-> v1-4 settings bot-plane w) (- (+ (-> s4-0 intersect y) arg1))))
         0
         (set! (-> obj settings top-plane w) (- (+ (-> s4-0 intersect y) arg2)))
         0)
        (else (let ((v1-7 obj)) (logior! (-> v1-7 settings flags) (shadow-flags disable-draw))) 0)))
    0
    (none)))
