Files
jak-project/goal_src/engine/anim/bones.gc
T
water111 4a0ac6c155 [graphics] first half of shadow renderer (#1246)
* start on dma stuff

* temp

* temp

* add shadow cpu
2022-03-22 21:42:37 -04:00

1525 lines
62 KiB
Common Lisp

;;-*-Lisp-*-
(in-package goal)
;; name: bones.gc
;; name in dgo: bones
;; dgos: GAME, ENGINE
;; Bones.
;; There are 4 main functions used by the outside world:
;; - bones-init. Call this before doing process-drawable DMA building.
;; - draw-bones. Call this once for each process-drawable during DMA building.
;; - bones-wrapup. Call this after all calls to draw-bones.
;; the above 3 functions are done separate for different levels.
;; - bones-mtx-calc-execute. Call this after all that.
;; It's more than just bones in here - submitting to merc is done from here.
(defglobalconstant USE_GENERIC #t)
;;;;;;;;;;;;;;;;;;
;; calc list
;;;;;;;;;;;;;;;;;;
(defenum bone-calc-flags
:type uint16
:bitfield #t
(bncfl00 0)
(bncfl01 1) ;; use identity matrix in bone matrix calc instead of cam rot (effectively screen-space bones?)
(bncfl02 2)
(bncfl03 3)
(bncfl04 4)
(bncfl05 5)
(bncfl06 6)
(bncfl07 7)
(bncfl08 8)
(bncfl09 9)
(bncfl10 10)
(bncfl11 11)
(bncfl12 12)
(bncfl13 13)
(bncfl14 14)
(bncfl15 15)
)
;; this type represents a "calculation" that will be performed at later time.
(deftype bone-calculation (structure)
((flags bone-calc-flags :offset-assert 0)
(num-bones uint16 :offset-assert 2)
(matrix-area (inline-array matrix) :offset-assert 4)
(joints (inline-array joint) :offset-assert 8)
(bones (inline-array bone) :offset-assert 12)
(ripple-scale float :offset-assert 16)
(ripple-y-scale float :offset-assert 20)
(ripple-normal-scale float :offset-assert 24)
(ripple-area (inline-array vector) :offset-assert 28)
(next bone-calculation :offset-assert 32)
(dummy-1 uint32 :offset-assert 36)
(dummy-2 uint32 :offset-assert 40)
(dummy-3 uint32 :offset-assert 44)
)
:method-count-assert 9
:size-assert #x30
:flag-assert #x900000030
)
;; linked list of bone-calculations.
;; you have to bring your own bone-calculations
(deftype bone-calculation-list (structure)
((first bone-calculation :offset-assert 0)
(next bone-calculation :offset-assert 4)
)
:method-count-assert 9
:size-assert #x8
:flag-assert #x900000008
)
;; the global calculation list.
(define *bone-calculation-list* (new 'global 'bone-calculation-list))
(defun bone-list-init ()
"Reset the bone list to have nothing."
(let ((v1-0 *bone-calculation-list*))
(set! (-> v1-0 first) (the-as bone-calculation 0))
(set! (-> v1-0 next) (the-as bone-calculation 0))
)
(none)
)
(bone-list-init)
;;;;;;;;;;;;;;;;;;
;; texscroll
;;;;;;;;;;;;;;;;;;
;; the "texture scroll" moves the texture. This is done by modifying the merc data.
;; list of all texture scroll effects.
(deftype texscroll-globals (structure)
((requests int32 :offset-assert 0)
(effects merc-effect 32 :offset-assert 4)
)
:method-count-assert 9
:size-assert #x84
:flag-assert #x900000084
)
(define *texscroll-globals* (new 'global 'texscroll-globals))
(defun texscroll-make-request ((arg0 merc-effect))
"Request that the given merc-effect have its texture scroll updated.
Note: only call this if you actually have a texture scroll effect!"
(let* ((v1-1 (-> *texscroll-globals* requests))
(a1-0 (-> arg0 extra-info))
(a1-1 (the-as mei-texture-scroll (+ (the-as uint a1-0) (* (-> a1-0 texture-scroll-offset) 16))))
)
(when (< v1-1 32)
(let* ((a3-1 (-> *display* integral-frame-counter))
(a2-3 (-> a1-1 time-factor))
(t0-2 (+ (ash 1 a2-3) -1))
)
(if (zero? (-> a1-1 scroll-dir))
(set! a3-1 (- a3-1))
)
(let ((a2-5 (ash (ash (logand a3-1 t0-2) (- 12 (the-as int (-> a1-1 st-int-scale)))) (- (the-as int a2-3)))))
(when (!= a2-5 (-> a1-1 cached-time))
(set! (-> a1-1 time-delta) (the-as uint (- a2-5 (the-as int (-> a1-1 cached-time)))))
(set! (-> a1-1 cached-time) (the-as uint a2-5))
(set! (-> *texscroll-globals* effects v1-1) arg0)
(+! (-> *texscroll-globals* requests) 1)
)
)
)
)
)
(none)
)
(defun texscroll-execute ()
"Do all requested texture scroll updates."
(dotimes (v1-0 (-> *texscroll-globals* requests))
(let* ((a2-0 (-> *texscroll-globals* effects v1-0))
(a0-2 (-> a2-0 frag-count))
(a1-1 (-> a2-0 extra-info))
(a1-2 (the-as mei-texture-scroll (+ (the-as uint a1-1) (* (-> a1-1 texture-scroll-offset) 16))))
(t1-0 (-> a2-0 frag-geo))
(a2-1 (-> a2-0 frag-ctrl))
)
(dotimes (a3-2 (the-as int a0-2))
(let ((t0-4 (&+ (the-as pointer t1-0) (logand (* (+ (-> a2-1 unsigned-four-count) 3) 4) #xfff0))))
(let ((t2-2 (+ (-> t1-0 header mat1-cnt) (-> t1-0 header mat2-cnt) (-> t1-0 header mat3-cnt))))
(the-as (pointer int8) (-> a1-2 time-delta))
(let* ((t1-3 (the-as (pointer int8) (&+ t0-4 9)))
(t2-4 (&+ t1-3 (* (the-as uint 12) t2-2)))
(t3-3 (-> a1-2 time-delta))
)
(nop!)
(label cfg-3)
(let ((t4-0 (-> t1-3 0)))
(nop!)
(nop!)
(nop!)
(let ((t4-1 (+ t4-0 t3-3)))
(set! t1-3 (&-> t1-3 12))
(b! (!= t1-3 t2-4) cfg-3 :delay (set! (-> t1-3 -12) t4-1))
)
)
)
)
(set! t1-0 (the-as
merc-fragment
(&+ (&+ t0-4 (logand (* (+ (-> a2-1 lump-four-count) 3) 4) #xfff0)) (* (-> a2-1 fp-qwc) 16))
)
)
)
(set! a2-1 (the-as merc-fragment-control (+ (the-as uint a2-1) (* (-> a2-1 mat-xfer-count) 2) 4)))
)
)
)
(set! (-> *texscroll-globals* requests) 0)
0
(none)
)
;;;;;;;;;;;;;;;;;;;;
;; Merc Submission
;;;;;;;;;;;;;;;;;;;;
;; when submitting to merc, we must provide some information to pick the appropriate rendering settings.
;; this information can't be precomputed and is done in bones.
;; per-effect information
(deftype merc-effect-bucket-info (structure)
((color-fade rgba :offset-assert 0)
(use-mercneric uint8 :offset-assert 4)
(ignore-alpha uint8 :offset-assert 5)
(pad0 uint8 :offset-assert 6)
(pad1 uint8 :offset-assert 7)
)
:pack-me
:method-count-assert 9
:size-assert #x8
:flag-assert #x900000008
)
;; information for everything being submitted.
(deftype merc-bucket-info (structure)
((light vu-lights :inline :offset-assert 0)
(needs-clip int32 :offset-assert 112)
(need-mercprime-if-merc int32 :offset-assert 116)
(must-use-mercneric-for-clip int32 :offset-assert 120)
(effect merc-effect-bucket-info 16 :inline :offset-assert 124)
)
:method-count-assert 9
:size-assert #xfc
:flag-assert #x9000000fc
)
(define *merc-bucket-info* (new 'global 'merc-bucket-info))
;; UNUSED.
(define *use-generic* #f)
;;;;;;;;;;;;;;;;
;; VU / DMA
;;;;;;;;;;;;;;;;
(define bones-vu0-block (new 'static 'vu-function #|:length 63 :qlength 32|#))
;; these changes only matter if transferring in _interleave_ mode.
(defun bones-set-sqwc ()
;; transfer 4, skip 1.
(#unless PC_PORT
(set! (-> (the-as dma-bank-control #x1000e000) sqwc) (new 'static 'dma-sqwc :sqwc #x1 :tqwc #x4))
)
(none)
)
(defun bones-reset-sqwc ()
;; transfer 1, skip 1
;; note: not sure what uses this mode??
(#unless PC_PORT
(set! (-> (the-as dma-bank-control #x1000e000) sqwc) (new 'static 'dma-sqwc :sqwc #x1 :tqwc #x1))
)
(none)
)
;; ?? used by generic merc
(define *merc-global-array* (new 'global 'merc-global-array))
(defun vu-lights<-light-group! ((arg0 vu-lights) (arg1 light-group))
"Convert a light-group to the VU format lights used by merc."
(local-vars (v1-0 uint128) (v1-1 uint128) (a2-1 uint128) (t0-1 uint128) (t1-1 uint128))
(rlet ((vf0 :class vf)
(vf10 :class vf)
(vf11 :class vf)
(vf4 :class vf)
(vf5 :class vf)
(vf6 :class vf)
(vf7 :class vf)
(vf8 :class vf)
(vf9 :class vf)
)
(init-vf0-vector)
(nop!)
(let ((a3-0 (the-as uint128 (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0))))
(nop!)
(let ((a2-0 (-> arg1 dir0 direction quad)))
(nop!)
(let ((t1-0 (-> arg1 dir1 direction quad)))
(nop!)
(.lvf vf4 (&-> arg1 dir0 color quad))
(.pextlw v1-0 t1-0 a2-0)
(let ((t0-0 (-> arg1 dir2 direction quad)))
(.pextuw a2-1 t1-0 a2-0)
(.lvf vf8 (&-> arg1 dir0 levels quad))
(.pextlw t1-1 a3-0 t0-0)
(.lvf vf5 (&-> arg1 dir1 color quad))
(.pextuw t0-1 a3-0 t0-0)
)
)
)
)
(.lvf vf9 (&-> arg1 dir1 levels quad))
(let ((a3-1 (make-u128 t1-1 v1-0)))
(.lvf vf6 (&-> arg1 dir2 color quad))
(.pcpyud v1-1 v1-0 t1-1)
(.lvf vf10 (&-> arg1 dir2 levels quad))
(let ((a2-2 (make-u128 (the-as int t0-1) a2-1)))
(.lvf vf7 (&-> arg1 ambi color quad))
(.mul.x.vf vf4 vf4 vf8)
(.lvf vf11 (&-> arg1 ambi levels quad))
(.mul.x.vf vf5 vf5 vf9)
(set! (-> arg0 direction 0 quad) (the-as uint128 a3-1))
(.mul.x.vf vf6 vf6 vf10)
(set! (-> arg0 direction 1 quad) v1-1)
(.mul.x.vf vf7 vf7 vf11)
(set! (-> arg0 direction 2 quad) (the-as uint128 a2-2))
)
)
(.min.x.vf vf4 vf0 vf0 :mask #b1000)
(nop!)
(.min.x.vf vf5 vf0 vf0 :mask #b1000)
(nop!)
(.min.x.vf vf6 vf0 vf0 :mask #b1000)
(nop!)
(.max.w.vf vf7 vf0 vf0 :mask #b1000)
(nop!)
(nop!)
(.svf (&-> arg0 color 0 quad) vf4)
(nop!)
(.svf (&-> arg0 color 1 quad) vf5)
(nop!)
(.svf (&-> arg0 color 2 quad) vf6)
(nop!)
(.svf (&-> arg0 ambient quad) vf7)
0
(none)
)
)
;;;;;;;;;;;;;;;;;;;;
;; BONE
;;;;;;;;;;;;;;;;;;;;
(defun bones-init ((arg0 dma-buffer) (arg1 dma-foreground-sink-group))
"Initialize the scratchpad and VU0 for bone work."
(scratchpad-object int)
(let ((a2-1 (the-as bone-memory (+ 16 (scratchpad-object int))))
(v1-2 (the-as bone-memory (+ 16 (scratchpad-object int))))
)
;; layout joints, bones, and outputs
(set! (-> a2-1 work layout joint 0) (the-as joint (+ 256 (scratchpad-object int))))
(set! (-> a2-1 work layout joint 1) (the-as joint (+ 4864 (scratchpad-object int))))
(set! (-> a2-1 work layout bone 0) (the-as bone (+ 1280 (scratchpad-object int))))
(set! (-> a2-1 work layout bone 1) (the-as bone (+ 5888 (scratchpad-object int))))
(set! (-> a2-1 work layout output 0) (the-as uint (+ 2816 (scratchpad-object int))))
(set! (-> a2-1 work layout output 1) (the-as uint (+ 7424 (scratchpad-object int))))
;; set up work
(set! (-> v1-2 work next-tag dma) (new 'static 'dma-tag :id (dma-tag-id next)))
(set! (-> v1-2 work next-tag vif0) (new 'static 'vif-tag :imm #x404 :cmd (vif-cmd stcycl)))
(set! (-> v1-2 work next-tag vif1) (new 'static 'vif-tag :imm #x404 :cmd (vif-cmd stcycl)))
(set! (-> v1-2 work dma-buf) arg0)
(set! (-> v1-2 work sink-group) arg1)
(set! (-> v1-2 work next-merc) (the-as dma-packet 0))
)
;; reset globals
(let ((v1-3 *merc-globals*))
(set! (-> v1-3 first) (the-as uint 0))
(set! (-> v1-3 next) (the-as (pointer uint32) 0))
)
;; upload bones program.
(#unless PC_PORT
(let ((gp-0 *vu0-dma-list*))
(let ((v1-4 gp-0))
(set! (-> v1-4 base) (-> v1-4 data))
(set! (-> v1-4 end) (&-> v1-4 data-buffer (-> v1-4 allocated-length)))
)
(dma-buffer-add-vu-function gp-0 bones-vu0-block 0)
(let* ((v1-5 gp-0)
(a0-6 (-> v1-5 base))
)
(set! (-> (the-as (pointer int64) a0-6)) #x70000000)
(set! (-> (the-as (pointer int64) a0-6) 1) 0)
(set! (-> v1-5 base) (&+ a0-6 16))
)
(.sync.l)
(dma-buffer-send-chain (the-as dma-bank-source #x10008000) gp-0)
)
)
;; we will use "run" in the shadow queue. Reset that (but don't increment yet, just in case we don't draw shadows)
(let ((gp-1 *shadow-queue*))
(if (>= (-> gp-1 cur-run) (the-as uint 15))
(format #t "Too many shadow-queues!!~%")
)
(let ((v1-13 (-> gp-1 run (-> gp-1 cur-run))))
(set! (-> v1-13 first) (the-as dma-packet 0))
(set! (-> v1-13 next) (the-as (pointer dma-packet) 0))
)
)
0
(none)
)
(defun draw-bones-mtx-calc ((arg0 bone-calculation) (arg1 int) (arg2 bone-calc-flags))
"Add the current work to the bone calculation list."
(let ((t2-0 (the-as bone-memory (+ 16 (scratchpad-object int))))
(v1-1 *bone-calculation-list*)
(a3-1 arg0)
)
;; grab active buffers
(let ((t0-0 (-> t2-0 work regs joint-ptr))
(t1-0 (-> t2-0 work regs bone-ptr))
(t2-1 (-> t2-0 work regs num-bones))
(t3-0 a3-1)
)
(set! (-> t3-0 flags) arg2)
(set! (-> t3-0 num-bones) t2-1)
(set! (-> t3-0 matrix-area) (the-as (inline-array matrix) arg1))
(set! (-> t3-0 joints) t0-0)
(set! (-> t3-0 bones) t1-0)
(set! (-> t3-0 next) (the-as bone-calculation 0))
)
;; splice into list
(if (nonzero? (-> v1-1 next))
(set! (-> v1-1 next next) a3-1)
)
(if (zero? (-> v1-1 first))
(set! (-> v1-1 first) a3-1)
)
(set! (-> v1-1 next) a3-1)
)
(the-as object (&+ arg0 48))
)
(def-mips2c bones-mtx-calc (function int pointer pointer int object none))
(defun bones-mtx-calc-execute ()
"Do all pending bone calculations"
(local-vars (v1-14 float))
(rlet ((vf1 :class vf)
(vf2 :class vf)
(vf25 :class vf)
(vf26 :class vf)
(vf27 :class vf)
(vf28 :class vf)
(vf29 :class vf)
(vf3 :class vf)
(vf30 :class vf)
(vf31 :class vf)
(vf4 :class vf)
(vf5 :class vf)
(vf6 :class vf)
(vf7 :class vf)
(vf8 :class vf)
)
(if *debug-segment*
(add-frame
(-> *display* frames (-> *display* on-screen) frame profile-bar 0)
'draw
(new 'static 'rgba :r #x40 :b #x40 :a #x80)
)
)
(let ((v1-8 (the-as bone-memory (+ 16 (scratchpad-object int)))))
(+ 16 #x70000000)
(set! (-> v1-8 work layout joint 0) (the-as joint (+ 256 (scratchpad-object int))))
(set! (-> v1-8 work layout joint 1) (the-as joint (+ 4864 (scratchpad-object int))))
(set! (-> v1-8 work layout bone 0) (the-as bone (+ 1280 (scratchpad-object int))))
(set! (-> v1-8 work layout bone 1) (the-as bone (+ 5888 (scratchpad-object int))))
(set! (-> v1-8 work layout output 0) (the-as uint (+ 2816 (scratchpad-object int))))
(set! (-> v1-8 work layout output 1) (the-as uint (+ 7424 (scratchpad-object int))))
)
(#unless PC_PORT (set! (-> (the-as dma-bank-control #x1000e000) sqwc) (new 'static 'dma-sqwc :sqwc #x1 :tqwc #x4)))
(let* ((v1-10 *bone-calculation-list*)
(gp-0 *identity-matrix*)
(s5-0 (-> *math-camera* camera-rot))
(s4-0 (-> v1-10 first))
)
(while (nonzero? s4-0)
(let ((v1-13 (if (logtest? (-> s4-0 flags) (bone-calc-flags bncfl01))
gp-0
s5-0
)
)
)
(.lvf vf28 (&-> v1-13 vector 0 quad))
(.lvf vf29 (&-> v1-13 vector 1 quad))
(.lvf vf30 (&-> v1-13 vector 2 quad))
(.lvf vf31 (&-> v1-13 vector 3 quad))
(.lvf vf25 (&-> v1-13 vector 0 quad))
(.lvf vf26 (&-> v1-13 vector 1 quad))
(.lvf vf27 (&-> v1-13 vector 2 quad))
(.mov v1-14 vf27)
;; hack??
(bones-mtx-calc
(the-as int (-> s4-0 matrix-area))
(the-as pointer (-> s4-0 joints))
(the-as pointer (-> s4-0 bones))
(the-as int (-> s4-0 num-bones))
v1-13 ;; hack, added
)
)
(when (logtest? (-> s4-0 flags) (bone-calc-flags bncfl00))
(let ((v1-18 (-> s4-0 matrix-area))
(a0-22 (-> s4-0 num-bones))
(f1-0 (-> s4-0 ripple-scale))
(f2-0 (-> s4-0 ripple-y-scale))
(f0-0 (-> s4-0 ripple-normal-scale))
(a1-9 (-> s4-0 ripple-area))
)
(let ((a2-2 f2-0))
(.mov vf1 a2-2)
)
(let ((a2-3 f1-0))
(.mov vf2 a2-3)
)
(let ((a2-4 f0-0))
(.mov vf3 a2-4)
)
(label cfg-8)
(.lvf vf5 (&-> v1-18 0 vector 1 quad))
(.lvf vf6 (&-> v1-18 0 vector 3 quad))
(.lvf vf7 (&-> v1-18 1 vector 0 quad))
(.lvf vf8 (&-> v1-18 1 vector 2 quad))
(.mul.x.vf vf4 vf5 vf2)
(.mul.x.vf vf5 vf5 vf1)
(let ((a3-1 (-> v1-18 0 vector 0 quad)))
(.mul.x.vf vf7 vf7 vf3)
(let ((a2-6 (-> v1-18 0 vector 2 quad)))
(.mul.x.vf vf8 vf8 vf3)
(set! (-> a1-9 0 quad) a3-1)
(let ((a3-2 (-> v1-18 1 vector 1 quad)))
(.sub.vf vf6 vf6 vf4)
(set! (-> a1-9 2 quad) a2-6)
(.svf (&-> a1-9 1 quad) vf5)
(set! (-> a1-9 5 quad) a3-2)
)
)
)
(+! a0-22 -1)
(.svf (&-> a1-9 4 quad) vf7)
;(.addiu v1-18 (the-as object v1-18) 128)
(&+! v1-18 128)
(.svf (&-> a1-9 3 quad) vf6)
;;(.addiu (the-as (inline-array vector) a1-9) a1-9 128)
(&+! a1-9 128)
(b! (nonzero? a0-22) cfg-8 :delay (.svf (&-> a1-9 -2 quad) vf8))
)
0
)
(set! s4-0 (-> s4-0 next))
)
)
(#unless PC_PORT (set! (-> (the-as dma-bank-control #x1000e000) sqwc) (new 'static 'dma-sqwc :sqwc #x1 :tqwc #x1)))
(bone-list-init)
(if *debug-segment*
(add-frame
(-> *display* frames (-> *display* on-screen) frame profile-bar 0)
'draw
(new 'static 'rgba :r #x7b :g #x7b :b #x7b :a #x80)
)
)
0
(none)
)
)
(defun bones-wrapup ()
(let ((v1-1 (the-as bone-memory (+ 16 (scratchpad-object int)))))
(when (nonzero? (-> v1-1 work next-merc))
;; only add if we actually drew with merc.
(let* ((a0-2 (-> v1-1 work dma-buf))
(a3-0 (-> a0-2 base))
)
(let ((a1-0 (the-as object (-> a0-2 base))))
(set! (-> (the-as dma-packet a1-0) dma) (new 'static 'dma-tag :id (dma-tag-id next)))
(set! (-> (the-as dma-packet a1-0) vif0) (new 'static 'vif-tag))
(set! (-> (the-as dma-packet a1-0) vif1) (new 'static 'vif-tag))
(set! (-> a0-2 base) (&+ (the-as pointer a1-0) 16))
)
(dma-bucket-insert-tag
(-> *display* frames (-> *display* on-screen) frame bucket-group)
(-> v1-1 work sink-group merc-sink bucket)
(the-as pointer (-> v1-1 work next-merc))
(the-as (pointer dma-tag) a3-0)
)
)
)
)
(none)
)
;;;;;;;;;;;;;;;
;; bone debug
;;;;;;;;;;;;;;;
(define *bones-first* #f)
(defun-debug dump-qword ((arg0 qword))
(let ((v1-0 arg0))
(format
0
"~8,'0X: ~8,'0X ~8,'0X ~8,'0X ~8,'0X~%"
v1-0
(-> v1-0 data 0)
(-> v1-0 data 1)
(-> v1-0 data 2)
(-> v1-0 data 3)
)
)
0
(none)
)
(defun-debug dump-mem ((arg0 pointer) (arg1 int))
(dotimes (s4-0 arg1)
(format
0
"~8,'0X: ~8,'0X ~8,'0X ~8,'0X ~8,'0X"
(&+ arg0 (* (* s4-0 4) 4))
(-> (the-as (pointer uint32) (&+ arg0 (* (* s4-0 4) 4))))
(-> (the-as (pointer uint32) (&+ arg0 (* (+ (* s4-0 4) 1) 4))))
(-> (the-as (pointer uint32) (&+ arg0 (* (+ (* s4-0 4) 2) 4))))
(-> (the-as (pointer uint32) (&+ arg0 (* (+ (* s4-0 4) 3) 4))))
)
(format
0
" ~F ~F ~F ~F ~%"
(-> (the-as (pointer uint32) (&+ arg0 (* (* s4-0 4) 4))))
(-> (the-as (pointer uint32) (&+ arg0 (* (+ (* s4-0 4) 1) 4))))
(-> (the-as (pointer uint32) (&+ arg0 (* (+ (* s4-0 4) 2) 4))))
(-> (the-as (pointer uint32) (&+ arg0 (* (+ (* s4-0 4) 3) 4))))
)
)
0
(none)
)
(defun-debug bones-debug ()
0
(none)
)
(defun-debug dump-bone-mem ()
(format 0 "== joints 0 ===========~%")
(dump-mem (the-as pointer (+ 256 #x70000000)) 64)
(format 0 "== bones 0 ============~%")
(dump-mem (the-as pointer (+ 1280 #x70000000)) 96)
(format 0 "== output 0 ===========~%")
(dump-mem (the-as pointer (+ 2816 #x70000000)) 128)
(format 0 "~%~%~%")
(format 0 "== joints 1 ===========~%")
(dump-mem (the-as pointer (+ 4864 #x70000000)) 64)
(format 0 "== bones 1 ============~%")
(dump-mem (the-as pointer (+ 5888 #x70000000)) 96)
(format 0 "== output 1 ===========~%")
(dump-mem (the-as pointer (+ 7424 #x70000000)) 128)
(format 0 "== dma-list ===========~%")
(dump-mem (the-as pointer (+ 256 #x70000000)) 90)
(format 0 "========================~%~%")
0
(none)
)
(define *default-shadow-settings* (new 'static 'shadow-settings
:shadow-dir
(new 'static 'vector :x -0.4226 :y -0.9063 :w 409600.0)
:bot-plane (new 'static 'plane :y 1.0 :w 37683.2)
:top-plane (new 'static 'plane :y 1.0 :w 4096.0)
:fade-dist 409600.0
)
)
(defun draw-bones-shadow ((arg0 draw-control) (arg1 pointer) (arg2 pointer))
;; (local-vars (ra-0 int))
;; the dma packet we'll use for shadow in the end.
(let* ((v1-0 (the-as dma-packet (&+ arg2 0)))
;; the shadow to draw
(t1-0 (-> arg0 shadow))
;; the shadow run to add to
(a3-4 (-> *shadow-queue* run (-> *shadow-queue* cur-run)))
;; the dma data to add to
(a2-1 (&+ arg2 16))
;; the distance of the thing we're drawing
(t4-0 (-> (scratchpad-object terrain-context) work foreground bone-mem work distance w))
;; the shadow packet we'll build here
(t0-2 (the-as shadow-dma-packet a2-1))
(t2-0 (-> t1-0 header num-joints))
(t3-0 (-> a3-4 next))
(t5-2 (if (-> arg0 shadow-ctrl)
(-> arg0 shadow-ctrl settings)
*default-shadow-settings*
)
)
(t6-0 (-> t5-2 flags))
)
(-> arg0 cur-lod)
(when (zero? (logand t6-0 2))
(if (< (-> t5-2 fade-dist) t4-0)
(set! t6-0 (logior t6-0 32))
)
)
(cond
((zero? (logand t6-0 32))
(let ((t2-1 (* t2-0 8))
(t4-4 (-> t1-0 total-size))
)
0
(set! (-> t0-2 tag dma) (new 'static 'dma-tag :qwc #x5 :id (dma-tag-id cnt)))
(set! (-> t0-2 tag vif0) (new 'static 'vif-tag))
(set! (-> t0-2 tag vif1) (new 'static 'vif-tag))
(if (nonzero? t3-0)
(set! (-> t3-0 0) (the-as dma-packet t0-2))
)
(if (zero? (-> a3-4 first))
(set! (-> a3-4 first) (the-as dma-packet t0-2))
)
(let ((t3-5 (&-> t0-2 tag vif1)))
(let ((t6-4 (the-as (inline-array vector) (-> t0-2 settings)))
(t7-3 (-> t5-2 center quad))
(t8-0 (-> t5-2 shadow-dir quad))
(t9-0 (-> t5-2 bot-plane quad))
(ra-0 (-> t5-2 top-plane quad))
)
;; (.lq ra-0 48 t5-2)
(let ((t5-3 (-> t5-2 fade-vec quad)))
(set! (-> t6-4 0 quad) t7-3)
(set! (-> t6-4 1 quad) t8-0)
(set! (-> t6-4 2 quad) t9-0)
(set! (-> t6-4 3 quad) ra-0)
(set! (-> t6-4 4 quad) t5-3)
)
)
(let ((a0-3
(the-as
vector
(+ (the-as uint (-> arg0 skeleton bones 0 transform vector 3))
(* (the-as uint 96) (-> arg0 shadow-joint-index))
)
)
)
)
(set! (-> t0-2 settings center x) (-> a0-3 x))
(set! (-> t0-2 settings center y) (-> a0-3 y))
(set! (-> t0-2 settings center z) (-> a0-3 z))
)
(set! (-> t0-2 geo-ref dma)
(new 'static 'dma-tag :id (dma-tag-id ref) :addr (the-as int (&-> t1-0 total-size)) :qwc t4-4)
)
(set! (-> t0-2 geo-ref vif0) (new 'static 'vif-tag))
(set! (-> t0-2 geo-ref vif1) (new 'static 'vif-tag))
(set! (-> t0-2 mtx-ref dma)
(new 'static 'dma-tag :id (dma-tag-id ref) :addr (the-as int (&+ arg1 256)) :qwc t2-1)
)
(set! (-> t0-2 mtx-ref vif0) (new 'static 'vif-tag))
(set! (-> t0-2 mtx-ref vif1) (new 'static 'vif-tag))
(set! (-> t0-2 end-tag dma) (new 'static 'dma-tag :id (dma-tag-id end)))
(set! (-> t0-2 end-tag vif0) (new 'static 'vif-tag))
(set! (-> t0-2 end-tag vif1) (new 'static 'vif-tag))
(let ((v0-0 (&+ a2-1 144)))
(set! (-> a3-4 next) (the-as (pointer dma-packet) t3-5))
(set! (-> v1-0 dma) (new 'static 'dma-tag :id (dma-tag-id next) :addr (the-as int v0-0)))
(set! (-> v1-0 vif0) (new 'static 'vif-tag))
(set! (-> v1-0 vif1) (new 'static 'vif-tag))
v0-0
)
)
)
)
(else
(the-as pointer v1-0)
)
)
)
)
;(def-mips2c draw-bones-generic-merc (function draw-control pointer pointer int pointer))
(defun draw-bones-generic-merc ((arg0 draw-control) (arg1 pointer) (arg2 pointer) (arg3 int))
"Add data for generic merc drawing to the dma buffer. Note that this data is not yet converted to the generic format,
so it is not linked into the chain. This data is linked to itself and can be found again by following the chain
in *merc-globals*, which, despite the name, only contains generic merc data."
(local-vars
(sv-16 generic-merc-ctrl)
(sv-32 merc-effect)
(sv-48 int)
(sv-64 merc-fragment)
(sv-80 merc-fragment-control)
(sv-96 uint)
(sv-112 int)
(sv-128 int)
(sv-144 generic-merc-ctrl)
)
(let ((gp-0 (the-as object (&+ arg2 0))))
(let ((s2-0 (-> arg0 lod-set lod (-> arg0 cur-lod) geo))
(s0-0 (-> *merc-globals* next))
)
(set! sv-144 (the-as generic-merc-ctrl (&+ arg2 16)))
(dotimes (s1-0 (the-as int (-> s2-0 header effect-count)))
(when (nonzero? (-> *merc-bucket-info* effect s1-0 use-mercneric))
(set! sv-16 sv-144)
(set! sv-32 (-> s2-0 effect s1-0))
(+! (-> *merc-global-stats* mercneric fragments) (-> sv-32 frag-count))
(+! (-> *merc-global-stats* mercneric tris) (-> sv-32 tri-count))
(+! (-> *merc-global-stats* mercneric dverts) (-> sv-32 dvert-count))
(when (nonzero? s0-0)
(set! (-> s0-0 0) (the-as uint sv-16))
sv-16
)
(when (zero? (-> *merc-globals* first))
(set! (-> *merc-globals* first) (the-as uint sv-16))
sv-16
)
(set! s0-0 (&-> sv-16 tag vif1))
(quad-copy! (the-as pointer (-> sv-16 lights)) (the-as pointer (-> *merc-bucket-info* light)) 7)
(quad-copy! (the-as pointer (-> sv-16 header)) (the-as pointer (-> s2-0 header)) 5)
(set! (-> sv-16 header envmap-tint) (the-as uint (-> *merc-bucket-info* effect s1-0 color-fade)))
(set! (-> sv-16 header needs-clip) (the-as uint (-> *merc-bucket-info* needs-clip)))
(set! (-> sv-16 header use-isometric) (the-as uint arg3))
(when (nonzero? arg3)
(set! (-> sv-16 header needs-clip) (the-as uint 0))
0
)
(set! (-> sv-16 header use-attached-shader) (the-as uint 0))
(set! (-> sv-16 header display-triangles) (the-as uint 1))
(set! (-> sv-16 header two-mat-count) (the-as uint 0))
(set! (-> sv-16 header shader-upload-count) (the-as uint (if (logtest? (-> sv-32 effect-bits) 2)
1
0
)
)
)
(when (nonzero? (-> arg0 death-timer))
(when (>= (the-as int (- (-> arg0 death-timer-org) (-> arg0 death-timer)))
(the-as int (-> arg0 death-draw-overlap))
)
(set! (-> sv-16 header display-triangles) (the-as uint 0))
0
)
(when (not (paused?))
(set! (-> sv-16 header two-mat-count) (-> arg0 death-vertex-skip))
(set! (-> sv-16 header death-effect) (-> arg0 death-effect))
(set! (-> sv-16 header two-mat-reuse-count)
(/ (* (-> arg0 death-vertex-skip) (- (-> arg0 death-timer-org) (-> arg0 death-timer)))
(-> arg0 death-timer-org)
)
)
)
)
(set! (-> sv-16 header query) (the-as basic 0))
(when (logtest? (-> sv-32 effect-bits) 4)
(when (-> arg0 ripple)
(if (-> arg0 ripple send-query)
(set! (-> sv-16 header query) (-> arg0 ripple query))
)
)
)
(quad-copy! (the-as pointer (-> sv-16 effect)) (the-as pointer sv-32) 2)
(set! sv-48 15)
(when (nonzero? (-> sv-32 extra-info))
(when (nonzero? (-> sv-32 extra-info shader-offset))
(set! (-> sv-16 header use-attached-shader) (the-as uint 1))
(quad-copy!
(the-as pointer (&+ sv-16 240))
(the-as pointer (+ (the-as uint (-> sv-32 extra-info)) (* (-> sv-32 extra-info shader-offset) 16)))
5
)
(set! sv-48 (+ sv-48 5))
sv-48
)
)
(set! (-> sv-16 tag dma) (new 'static 'dma-tag :id (dma-tag-id cnt) :qwc (+ sv-48 -1)))
(set! (-> sv-16 tag vif0) (the-as vif-tag sv-48))
(set! (-> sv-16 tag vif1) (new 'static 'vif-tag))
(set! sv-144 (the-as generic-merc-ctrl (+ (the-as uint sv-144) (* sv-48 16))))
sv-144
(set! sv-64 (-> sv-32 frag-geo))
(set! sv-80 (-> sv-32 frag-ctrl))
(set! sv-96 (-> sv-32 frag-count))
(set! sv-112 0)
(while (< sv-112 (the-as int sv-96))
(set! sv-128 (asize-of sv-80))
(let ((v1-104 (asize-of sv-64)))
;; (format 0 "~D TAG at #x~X merc size ~D bytes ~D qw~%" sv-112 sv-144 v1-104 (shr v1-104 4))
(set! (-> sv-144 tag dma)
(new 'static 'dma-tag :id (dma-tag-id ref) :addr (the-as int sv-64) :qwc (shr v1-104 4))
)
(set! (-> sv-144 tag vif0) (new 'static 'vif-tag))
(set! (-> sv-144 tag vif1) (new 'static 'vif-tag))
(when (nonzero? sv-112)
(set! (-> (the-as (pointer vif-tag) s0-0) 0) (the-as vif-tag sv-144))
(set! s0-0 (&-> sv-144 tag vif1))
)
(let ((a0-55 (the-as structure (-> sv-144 lights))))
(dotimes (a1-17 (the-as int (-> sv-80 mat-xfer-count)))
(let ((a3-2 (&+ arg1 (* (-> sv-80 mat-dest-data a1-17 matrix-number) 128))))
(set! (-> (the-as dma-packet a0-55) dma)
(new 'static 'dma-tag :qwc #x7 :id (dma-tag-id ref) :addr (the-as int a3-2))
)
; (let ((vec (the vector (+ (the-as int a3-2) 16))))
; (format 0 "#x~X #x~X mat ~D: ~f ~f ~f~%" a0-55 a3-2 a1-17 (-> vec x) (-> vec y) (-> vec z))
; )
)
(set! (-> (the-as dma-packet a0-55) vif0) (new 'static 'vif-tag))
(set! (-> (the-as dma-packet a0-55) vif1) (new 'static 'vif-tag))
(set! a0-55 (&+ (the-as dma-packet a0-55) 16))
)
(set! (-> (the-as dma-packet a0-55) dma) (new 'static 'dma-tag :id (dma-tag-id end)))
(set! (-> (the-as dma-packet a0-55) vif0) (new 'static 'vif-tag))
(set! (-> (the-as dma-packet a0-55) vif1) (new 'static 'vif-tag))
(set! sv-144 (the-as generic-merc-ctrl (&+ (the-as dma-packet a0-55) 16)))
)
(set! sv-80 (the-as merc-fragment-control (&+ (the-as pointer sv-80) sv-128)))
(set! sv-64 (the-as merc-fragment (&+ (the-as pointer sv-64) v1-104)))
)
sv-64
(set! sv-112 (+ sv-112 1))
)
)
)
(set! (-> *merc-globals* next) s0-0)
)
(set! (-> (the-as dma-packet gp-0) dma)
(new 'static 'dma-tag :id (dma-tag-id next) :addr (the-as int sv-144))
)
(set! (-> (the-as dma-packet gp-0) vif0) (new 'static 'vif-tag))
(set! (-> (the-as dma-packet gp-0) vif1) (new 'static 'vif-tag))
)
0
(the-as pointer sv-144)
)
;; draw-boes-merc
;; draw-bones-check-longest-edge
;; draw-bones-check-longest-edgei-asm
;; draw-bones
;; draw-bones-hud
(def-mips2c draw-bones-merc (function draw-control object object int int pointer))
(def-mips2c draw-bones-check-longest-edge-asm (function draw-control float symbol))
(defmacro store-qw (addr val)
`(set! (-> (the-as (pointer uint128) ,addr)) (the-as uint128 ,val))
)
(defmacro store-u32 (addr val)
`(set! (-> (the-as (pointer uint32) ,addr)) ,val)
)
(defun draw-bones ((arg0 draw-control) (dma-buf dma-buffer) (arg2 float))
"Main draw function for all bone-related renderers. Will set up merc, generic and shadow.
and also add the bones to the calculation list."
(local-vars (a0-16 int) (a0-17 int) (a0-62 int) (a2-10 int) (a2-12 int)
(used-merc int) (used-mercneric int) (effect-idx int) (sv-144 ripple-control))
(rlet ((vf1 :class vf) (vf2 :class vf) (vf3 :class vf) (vf4 :class vf) (vf5 :class vf) (vf6 :class vf)
(vf7 :class vf) (vf8 :class vf) (vf9 :class vf) (acc :class vf))
;; compute the number of bones. I believe this num-joints doesn't count align/prejoint/main, so each needs a bone
(let* ((num-bones (+ (-> arg0 mgeo num-joints) 3))
;; we'll use 128-bytes/bone.
(bone-data-size (* num-bones 128))
;; temp work
(spr-work (scratchpad-object terrain-context))
)
;;;;;;;;;;;;;;;;;;;;;;;;;
;; BONE CALC SETUP
;;;;;;;;;;;;;;;;;;;;;;;;;
;; next, grab some DMA data.
;; we'll also use this for storing bone calculation entries.
(let* ((dma-data-start (-> dma-buf base))
;; first qw is the tag, stash the bone-calc-entry right after that.
(bone-calc-entry (the-as bone-calculation (&+ dma-data-start 16)))
;; after that we'll use the space for storing bone matrices.
;; we won't calculate them now, but instead we'll tell the *bone-calculation-list* to put them here later.
(matrix-data (the-as object (&+ dma-data-start 64)))
)
;; align the matrix data to 64 bytes (we know it is at least 16 byte aligned)
(let ((a2-1 (logand (the-as int matrix-data) 48)))
(b! (zero? a2-1) cfg-2 :delay (nop!))
(set! matrix-data (&- (&+ (the-as pointer matrix-data) 64) (the-as uint a2-1)))
)
(label cfg-2)
;; start recording perf stats.
;; this just counts the stats for adding the calculation to the linked list.
;; which is really fast and not worth profiling.
;; I suspect the bone calculation originally was here,
;; but they moved it and forgot to move the performance counters too.
(reset! (-> *perf-stats* data (perf-stat-bucket bones)))
;; figure out where everything will be
(let ((a2-6 (the-as bone-regs (+ 240 (scratchpad-object int)))))
;; the joints are stored in the static art data
(set! (-> a2-6 joint-ptr) (the-as (inline-array joint) (-> arg0 jgeo data 0)))
;; the final bones output used by the rest of the engine is stored in
;; the process-drawable's skeleton
(set! (-> a2-6 bone-ptr) (-> arg0 skeleton bones))
(set! (-> a2-6 num-bones) (the-as uint num-bones))
)
;; Add the bone calculation to the list, to be done later.
;; this will write to both the "matrix data" and the bones array.
(let ((t0-2 matrix-data)
(t1-0 0)
(t4-0 (the-as bone-memory (+ 16 (scratchpad-object int))))
(a2-8 *bone-calculation-list*)
(a3-8 bone-calc-entry)
)
(let ((t2-0 (-> t4-0 work regs joint-ptr))
(t3-0 (-> t4-0 work regs bone-ptr))
(t4-1 (-> t4-0 work regs num-bones))
(t5-0 a3-8)
)
(set! (-> t5-0 flags) (the-as bone-calc-flags t1-0))
(set! (-> t5-0 num-bones) t4-1)
(set! (-> t5-0 matrix-area) (the-as (inline-array matrix) t0-2))
(set! (-> t5-0 joints) t2-0)
(set! (-> t5-0 bones) t3-0)
(set! (-> t5-0 next) (the-as bone-calculation 0))
)
(if (nonzero? (-> a2-8 next))
(set! (-> a2-8 next next) a3-8)
)
(if (zero? (-> a2-8 first))
(set! (-> a2-8 first) a3-8)
)
(set! (-> a2-8 next) a3-8)
)
(&+ bone-calc-entry 48)
;; end stat collection
(read! (-> *perf-stats* data (perf-stat-bucket bones)))
;; set up the dma buffer
(let ((s2-0 (the-as object (+ (the-as uint matrix-data) bone-data-size))))
(let ((a0-2 (shl (the-as int s2-0) 32)))
(set! (-> (the-as (pointer uint128) dma-data-start))
(logior (-> spr-work work foreground bone-mem work next-tag quad) a0-2)
)
;; NOTE: does this work correctly for the upper 64 bits??
)
;; only data-format 1 is supported.
(when (= (-> arg0 data-format) 1)
;; lights should be converted to a single vu-lights already, by the drawing code.
;; it stashes lights on the scratchpad. We'll load these here and transform them.
;; the result goes in the merc-bucke-info.
(let ((v1-6 (the-as vu-lights (+ 64 (scratchpad-object int))))
(a0-7 (-> *merc-bucket-info* light))
)
(let ((a1-8 (-> *math-camera* inv-camera-rot)))
(.lvf vf4 (&-> a1-8 vector 0 quad))
(.lvf vf5 (&-> a1-8 vector 1 quad))
(.lvf vf6 (&-> a1-8 vector 2 quad))
)
(.lvf vf1 (&-> v1-6 direction 0 quad))
(.lvf vf2 (&-> v1-6 direction 1 quad))
(.lvf vf3 (&-> v1-6 direction 2 quad))
;;(.vcallms 54)
;; TODO!
;mulax.xyzw ACC, vf01, vf04
(.mul.x.vf acc vf1 vf4)
;madday.xyzw ACC, vf02, vf04
(.add.mul.y.vf acc vf2 vf4 acc)
;maddz.xyzw vf07, vf03, vf04
(.add.mul.z.vf vf7 vf3 vf4 acc)
;mulax.xyzw ACC, vf01, vf05
(.mul.x.vf acc vf1 vf5)
;madday.xyzw ACC, vf02, vf05
(.add.mul.y.vf acc vf2 vf5 acc)
;maddz.xyzw vf08, vf03, vf05
(.add.mul.z.vf vf8 vf3 vf5 acc)
;mulax.xyzw ACC, vf01, vf06
(.mul.x.vf acc vf1 vf6)
;madday.xyzw ACC, vf02, vf06 :e
(.add.mul.y.vf acc vf2 vf6 acc)
;maddz.xyzw vf09, vf03, vf06
(.add.mul.z.vf vf9 vf3 vf6 acc)
(let ((a1-9 (-> v1-6 color 0 quad)))
(let ((a2-14 (-> v1-6 color 1 quad)))
(let ((a3-11 (-> v1-6 color 2 quad)))
(let ((v1-7 (-> v1-6 ambient quad)))
(set! (-> a0-7 color 0 quad) a1-9)
(set! (-> a0-7 color 1 quad) a2-14)
(set! (-> a0-7 color 2 quad) a3-11)
(set! (-> a0-7 ambient quad) v1-7)
)
)
)
)
(.svf (&-> a0-7 direction 0 quad) vf7)
(.svf (&-> a0-7 direction 1 quad) vf8)
(.svf (&-> a0-7 direction 2 quad) vf9)
(set! (-> a0-7 direction 1 w) (the-as float 0))
)
;; the drawable system's culling already knows if we need clipping or not,
;; we just trust it.
(set! (-> *merc-bucket-info* needs-clip)
(if (logtest? (-> arg0 status) (draw-status needs-clip))
1
0
)
)
;; Now, we need to decide on merc settings. Default to nothing.
(set! used-merc 0)
(set! used-mercneric 0)
(set! (-> *merc-bucket-info* need-mercprime-if-merc) 0)
(set! (-> *merc-bucket-info* must-use-mercneric-for-clip) 0)
(when (logtest? (-> arg0 status) (draw-status needs-clip))
;; we can either clip with "mercprime" (part of merc), or fall back to generic.
;; the generic approach always works, but is slower, so we try to use mercprime.
;; the user must provide a longest edge length, and we must pass an edge check (fails if close to camera)
(cond
((nonzero? (-> arg0 longest-edge))
;; TODO this makes close up things bad...
(if (draw-bones-check-longest-edge-asm arg0 arg2)
(set! (-> *merc-bucket-info* need-mercprime-if-merc) 1) ;; clip with mercprime!
(set! (-> *merc-bucket-info* must-use-mercneric-for-clip) 1) ;; failed, use generic
)
)
(else
(set! (-> *merc-bucket-info* must-use-mercneric-for-clip) 1) ;; no longest edge info, use generic.
)
)
)
;; grab the geometry at the appropriate level of detail.
(let ((geom (-> arg0 lod-set lod (-> arg0 cur-lod) geo)))
;; loop over effects, and set them up/pick renderers.
(set! effect-idx 0)
(while (< effect-idx (the-as int (-> geom header effect-count)))
;; try texture scroll
(when (logtest? (-> geom effect effect-idx effect-bits) 1)
(let* ((v1-35 (-> geom effect effect-idx extra-info))
(v1-36 (the-as mei-texture-scroll (+ (the-as uint v1-35) (* (-> v1-35 texture-scroll-offset) 16))))
)
(if (< arg2 (-> v1-36 max-dist))
;; just add to texscroll list.
(texscroll-make-request (-> geom effect effect-idx))
)
)
)
;; try ripple
(when (logtest? (-> geom effect effect-idx effect-bits) 4)
;; TODO.
(when (-> arg0 ripple)
(set! sv-144 (-> arg0 ripple))
(let* ((f1-4 (/ (- (-> sv-144 far-fade-dist) arg2) (- (-> sv-144 far-fade-dist) (-> sv-144 close-fade-dist))))
(f1-6 (fmax 0.0 (fmin 1.0 f1-4)))
(f0-4 f1-6)
(f30-0 (* f1-6 (-> sv-144 global-scale)))
)
(set! (-> sv-144 faded-scale) f30-0)
(let ((f1-9 (/ f30-0 (* 128.0 (-> geom header xyz-scale)))))
0
(set! a0-16 (* num-bones 128))
(let ((v1-56 #x20000000))
(set! a0-17 (+ a0-16 (the-as int s2-0)));(.addu a0-17 a0-16 s2-0)
(logand! a0-17 #xffffffff)
;(s.q! s2-0 v1-56)
(store-qw s2-0 v1-56)
)
(let ((v1-57 (+ a0-17 16)))
;(s.w! (+ s2-0 4) v1-57)
(store-u32 (&+ (the pointer s2-0) 4) v1-57)
)
(set! matrix-data (&+ (the pointer s2-0) 16))
(let ((v1-59 (-> *bone-calculation-list* next)))
(logior! (-> v1-59 flags) (bone-calc-flags bncfl00))
(set! (-> v1-59 ripple-scale) f30-0)
(set! (-> v1-59 ripple-y-scale) f1-9)
(set! (-> v1-59 ripple-normal-scale) (* f0-4 (-> sv-144 individual-normal-scale)))
(set! (-> v1-59 ripple-area) (the-as (inline-array vector) matrix-data))
)
)
(set! (-> dma-buf base) (the-as pointer (-> (the-as (pointer uint32) s2-0) 1)))
(set! s2-0 (-> dma-buf base))
(if (not (and (= f30-0 0.0) (= (-> sv-144 last-frame-scale) 0.0)))
(ripple-make-request (the-as ripple-wave (-> sv-144 waveform)) (-> geom effect effect-idx))
)
(set! (-> sv-144 last-frame-scale) f30-0)
)
)
)
(cond
((nonzero? (-> arg0 death-timer))
;; if using hte death effect, use mercneric always!
(set! (-> *merc-bucket-info* effect effect-idx use-mercneric) (the-as uint 1))
(set! used-mercneric 1)
used-mercneric
)
((nonzero? (-> geom effect effect-idx envmap-usage))
;; if we need envmap, set it up.
(let* ((v1-83 (-> geom effect effect-idx extra-info))
;; pointer to envmap tint data
(v1-84 (the-as structure (+ (the-as uint v1-83) (* (-> v1-83 envmap-tint-offset) 16))))
;; the envmap effect fades away at a certain distance
(f1-12 (-> (the-as mei-envmap-tint v1-84) fade0))
(f0-8 (-> (the-as mei-envmap-tint v1-84) fade1))
)
;; compute and saturate the envmap effect strength
(let ((f0-9 (+ (* f1-12 arg2) f0-8)))
(if (< 1.0 f0-9)
(set! f0-9 1.0)
)
(if (< f0-9 0.0)
(set! f0-9 0.0)
)
(cond
;; do envmap stuff if we are using generic anyway, or our strength is > 0.
((or (nonzero? (-> *merc-bucket-info* must-use-mercneric-for-clip)) (< 0.0 f0-9))
;; multiply colors by sun tint.
(let ((v1-85 (&-> (the-as merc-extra-info v1-84) dummy 4))
(a0-36 (the-as object (-> *merc-bucket-info* effect effect-idx)))
)
(let ((a1-16 (-> *time-of-day-context* current-sun env-color))
(f0-10 (* 0.0078125 f0-9))
)
(dotimes (a2-15 3)
(set! (-> (the-as (pointer int8) a0-36) a2-15)
(the int (* f0-10 (-> a1-16 data a2-15) (the float (-> v1-85 a2-15))))
)
)
)
(set! (-> (the-as (pointer uint8) a0-36) 3) (the-as uint 0))
)
;; env mapping, so use mercneric.
(set! (-> *merc-bucket-info* effect effect-idx use-mercneric) (the-as uint 1))
(set! used-mercneric 1)
used-mercneric
)
(else
;; no env map, don't use mercneric.
(set! (-> *merc-bucket-info* effect effect-idx use-mercneric) (the-as uint 0))
(set! (-> *merc-bucket-info* effect effect-idx ignore-alpha) (the-as uint 1))
(set! used-merc 1)
;; note sure what this is exactly...
(when (logtest? (-> geom effect effect-idx effect-bits) 2)
(let ((v1-102 (-> *merc-bucket-info* light)))
(set! (-> v1-102 direction 1 w) 0.000000000000000000000000000000000000011755039)
)
)
)
)
)
)
)
;; final two cases are for all other effects that don't matter generic/normal
;; here is a good place to force mercneric.
((nonzero? (-> *merc-bucket-info* must-use-mercneric-for-clip))
(set! (-> *merc-bucket-info* effect effect-idx use-mercneric) (the-as uint 1))
(set! used-mercneric 1)
used-mercneric
)
(else
(set! (-> *merc-bucket-info* effect effect-idx use-mercneric) (the-as uint 0))
(set! (-> *merc-bucket-info* effect effect-idx ignore-alpha) (the-as uint 0))
(set! used-merc 1)
used-merc
)
)
;; HACK just use merc if we aren't using generic.
(#unless USE_GENERIC
(when (logtest? *vu1-enable-user* (vu1-renderer-mask generic))
(unless (logtest? (-> arg0 status) (draw-status needs-clip))
;; no clip, but wants generic. Just use merc for now.
(set! (-> *merc-bucket-info* effect effect-idx use-mercneric) (the-as uint 0))
(set! used-merc 1)
)
(when (and (logtest? (-> arg0 status) (draw-status needs-clip)) ;; we need to clip
;;(nonzero? (-> arg0 longest-edge)) ;; we known the longest edge
;;(draw-bones-check-longest-edge-asm arg0 arg2) ;; it's ok to use percprime.
)
;; wants clip. in all cases, give to merc. this might give it to merc even if it fails the
;; long edge check, but it does ok
(set! (-> *merc-bucket-info* effect effect-idx use-mercneric) (the-as uint 0))
(set! (-> *merc-bucket-info* need-mercprime-if-merc) 1)
(set! used-merc 1)
)
)
)
(set! effect-idx (+ effect-idx 1))
) ;; end effect loop
;; draw generic!
;; note: this doesn't do the fully draw, there's some other stuff in process-drawable.gc to actually execute.
(#when USE_GENERIC
(when (nonzero? used-mercneric)
(when (logtest? *vu1-enable-user* (vu1-renderer-mask generic))
(set! (-> dma-buf base) (draw-bones-generic-merc arg0 (the pointer matrix-data) (the pointer s2-0) 0))
(set! s2-0 (-> dma-buf base))
)
)
)
;; draw shadow!
;; TODO
(when (-> arg0 shadow)
(when #t
(set! s2-0 (draw-bones-shadow arg0 (the pointer matrix-data) (the pointer s2-0)))
(set! (-> dma-buf base) (the-as pointer s2-0))
)
)
;; draw merc!
;;
(when (nonzero? used-merc)
(when (logtest? *vu1-enable-user* (vu1-renderer-mask merc))
(when (= (-> arg0 cur-lod) (-> arg0 lod-set max-lod))
(let ((f0-13 (- (-> arg0 lod-set lod (-> arg0 cur-lod) dist) arg2)))
(when (< f0-13 81920.0)
(when (zero? (logand (-> geom effect 0 effect-bits) 2))
(let* ((a1-25 (the int (* 0.0015625 f0-13)))
(v1-147 (min 128 (max 0 a1-25)))
(a0-56 (-> *merc-bucket-info* light))
)
(set! (-> a0-56 direction 1 w) 0.000000000000000000000000000000000000011755084)
(set! (-> a0-56 direction 2 w) (the-as float v1-147))
)
0
)
)
)
)
(if (nonzero? (-> *merc-bucket-info* need-mercprime-if-merc))
(set! (-> dma-buf base) (draw-bones-merc arg0 matrix-data s2-0 32 17))
(set! (-> dma-buf base) (draw-bones-merc arg0 matrix-data s2-0 35 20))
)
(set! s2-0 (-> dma-buf base))
)
)
) ;; end geom processing
;; advance death timer.
(when (nonzero? (-> arg0 death-timer))
(when (not (paused?))
(+! (-> arg0 death-timer) -1)
(if (>= (the-as uint 1) (-> arg0 death-timer))
(send-event (-> arg0 process) 'death-end arg0)
)
)
)
)
(let ((v1-164 (logand (the-as int s2-0) 48)))
0
(b! (zero? v1-164) cfg-83 :delay (set! a0-62 #x20000000))
;;(s.q! s2-0 a0-62)
(set! (-> (the (pointer uint128) s2-0) 0) (the uint128 a0-62))
(let ((a0-63 s2-0))
(set! s2-0 (+ (- (the-as int s2-0) v1-164) 64))
;;(s.w! (+ a0-63 4) (the-as int s2-0))
(set! (-> (the (pointer int32) (+ (the-as uint a0-63) 4))) (the-as int s2-0))
)
)
(label cfg-83)
(set! (-> dma-buf base) (the-as pointer (logand (the-as uint s2-0) (the-as uint #xfffffff))))
)
)
)
0
(none)
)
)
;; TODO
(defun draw-bones-hud ((arg0 draw-control) (arg1 dma-buffer))
(local-vars
(at-0 object)
(at-2 int)
(t2-10 vu-lights)
(t3-3 uint128)
(t3-4 uint128)
(t3-5 uint128)
(t3-6 uint128)
)
(let ((v1-0 arg0)
(gp-0 arg1)
)
;; (.lui at-0 28672)
(set! at-0 (scratchpad-object object))
(let* ((a3-0 (-> gp-0 base))
(a0-3 (+ (-> v1-0 mgeo num-joints) 3))
(a2-0 (the-as object (&+ a3-0 16)))
(a1-1 (&+ a3-0 64))
)
(let ((t0-1 (scratchpad-object bone-regs :offset 240)))
(set! (-> t0-1 joint-ptr) (the-as (inline-array joint) (-> v1-0 jgeo data 0)))
(set! (-> t0-1 bone-ptr) (-> v1-0 skeleton bones))
(set! (-> t0-1 num-bones) (the-as uint a0-3))
)
(let ((t2-0 a1-1)
(t3-0 2)
(t6-0 (scratchpad-object bone-memory :offset 16))
(t0-3 *bone-calculation-list*)
(t1-6 (the-as bone-calculation a2-0))
)
(let ((t4-0 (-> t6-0 work regs joint-ptr))
(t5-0 (-> t6-0 work regs bone-ptr))
(t6-1 (-> t6-0 work regs num-bones))
(t7-0 t1-6)
)
(set! (-> t7-0 flags) (the-as bone-calc-flags t3-0))
(set! (-> t7-0 num-bones) t6-1)
(set! (-> t7-0 matrix-area) (the-as (inline-array matrix) t2-0))
(set! (-> t7-0 joints) t4-0)
(set! (-> t7-0 bones) t5-0)
(set! (-> t7-0 next) (the-as bone-calculation 0))
)
(if (nonzero? (-> t0-3 next))
(set! (-> t0-3 next next) t1-6)
)
(if (zero? (-> t0-3 first))
(set! (-> t0-3 first) t1-6)
)
(set! (-> t0-3 next) t1-6)
)
(let ((a2-2 (the-as object (&+ (&+ (the-as pointer a2-0) 48) (* a0-3 128)))))
(set! (-> (the-as (pointer uint128) a3-0))
(logior (-> (the-as terrain-context at-0) work foreground generic-work saves envmap verts 4)
(shl (the-as int a2-2) 32)
)
)
(when (= (-> v1-0 data-format) 1)
(let ((a0-9 (-> v1-0 lod-set lod 0 geo)))
(dotimes (a3-2 (the-as int (-> a0-9 header effect-count)))
(cond
((nonzero? (-> a0-9 effect a3-2 envmap-usage))
(let* ((t1-7 (-> *merc-bucket-info* light))
(t2-9 (+ 64 (scratchpad-object int)))
(t0-10 7)
(t1-8 (the-as object t1-7))
)
(b! (< (+ t0-10 -4) 0) cfg-9 :delay (set! t2-10 (the-as vu-lights t2-9)))
(nop!)
(label cfg-8)
(let ((t6-2 (-> t2-10 direction 0 quad)))
(nop!)
(let ((t3-2 (-> t2-10 direction 1 quad)))
(+! t0-10 -4)
(let ((t4-1 (-> t2-10 direction 2 quad)))
(set! t1-8 (&+ (the-as pointer t1-8) 64))
(let ((t5-1 (-> t2-10 color 0 quad)))
(set! t2-10 (the-as vu-lights (-> t2-10 color 1)))
(store-qw (&+ (the-as pointer t1-8) -64) t6-2)
(let ((t6-3 (+ t0-10 -4)))
(store-qw (&+ (the-as pointer t1-8) -48) t3-2)
(nop!)
(store-qw (&+ (the-as pointer t1-8) -32) t4-1)
(b! (>= t6-3 0) cfg-8 :delay (store-qw (&+ (the-as pointer t1-8) -16) t5-1))
)
)
)
)
)
(label cfg-9)
(b! (zero? t0-10) cfg-14 :delay (set! t3-3 (-> t2-10 direction 0 quad)))
(let ((t2-11 (-> t2-10 direction 1))
(t1-9 (-> (the-as vu-lights t1-8) direction 1))
(t0-11 (+ t0-10 -1))
)
(store-qw (&+ t1-9 -16) t3-3)
(b! (zero? t0-11) cfg-14 :delay (set! t3-4 (-> t2-11 quad)))
(let ((t2-12 (&+ t2-11 16))
(t1-10 (&+ t1-9 16))
(t0-12 (+ t0-11 -1))
)
(store-qw (&+ t1-10 -16) t3-4)
(b! (zero? t0-12) cfg-14 :delay (set! t3-5 (-> t2-12 quad)))
(let ((t2-13 (&+ t2-12 16))
(t1-11 (&+ t1-10 16))
(t0-13 (+ t0-12 -1))
)
(store-qw (&+ t1-11 -16) t3-5)
(b! (zero? t0-13) cfg-14 :delay (set! t3-6 (-> t2-13 quad)))
(&+ t2-13 16)
(let ((t1-12 (&+ t1-11 16)))
(+ t0-13 -1)
(store-qw (&+ t1-12 -16) t3-6)
)
)
)
)
)
(label cfg-14)
0
(set! (-> *merc-bucket-info* effect a3-2 color-fade) (new 'static 'rgba :r #x80 :g #x80 :b #x80 :a #x80))
(set! (-> *merc-bucket-info* effect a3-2 use-mercneric) (the-as uint 1))
)
(else
(set! (-> *merc-bucket-info* effect a3-2 use-mercneric) (the-as uint 1))
)
)
)
)
(when (logtest? *vu1-enable-user* (vu1-renderer-mask generic))
(set! (-> gp-0 base) (draw-bones-generic-merc v1-0 a1-1 (the-as pointer a2-2) 1))
(set! a2-2 (-> gp-0 base))
)
)
(let ((a0-17 (logand (the-as int a2-2) 48)))
0
(b! (zero? a0-17) cfg-22 :delay (set! at-2 #x20000000))
(set! (-> (the-as (pointer int128) a2-2)) (the-as int128 at-2))
(let ((v1-2 (the-as pointer a2-2)))
(set! a2-2 (+ (&- (the-as pointer a2-2) (the-as uint a0-17)) 64))
(store-u32 (&+ v1-2 4) (the-as int a2-2))
)
)
(label cfg-22)
(set! (-> gp-0 base) (the-as pointer a2-2))
)
)
)
0
(none)
)
(define-extern draw-bones-hud (function draw-control dma-buffer none))