jak-project/goal_src/jak2/engine/level/bsp.gc

729 lines
28 KiB
Common Lisp

;;-*-Lisp-*-
(in-package goal)
;; name: bsp.gc
;; name in dgo: bsp
;; dgos: ENGINE, GAME
#|@file
The "bsp" is the main level data structure: the bsp-header contains references to all static level data.
The "bsp-tree" is a bsp used to associate camera positions with lists of visibible objects.
|#
;; DECOMP BEGINS
(defun-recursive mem-usage-bsp-tree none ((arg0 bsp-header) (arg1 bsp-node) (arg2 memory-usage-block) (arg3 int))
"Compute the memory usage of the bsp-tree part of a bsp-header"
(cond
((zero? arg1)
)
(else
(+! (-> arg2 data 60 count) 1)
(let ((v1-3 20))
(+! (-> arg2 data 60 used) v1-3)
(+! (-> arg2 data 60 total) v1-3)
)
(if (zero? (-> arg1 front-box-min w))
(mem-usage-bsp-tree arg0 (-> arg0 nodes (-> arg1 front)) arg2 arg3)
)
(when (zero? (-> arg1 back-box-min w))
(if (> (-> arg1 back) 0)
(mem-usage-bsp-tree arg0 (-> arg0 nodes (-> arg1 back)) arg2 arg3)
)
)
)
)
(none)
)
(defmethod mem-usage bsp-header ((obj bsp-header) (arg0 memory-usage-block) (arg1 int))
"Compute the memory usage of everything in a bsp-header.
This includes all the drawables."
(set! (-> arg0 work-bsp) obj)
(when (nonzero? (-> obj info))
(set! (-> arg0 length) (max 85 (-> arg0 length)))
(set! (-> arg0 data 84 name) "array")
(+! (-> arg0 data 84 count) 1)
(let ((v1-8 (asize-of (-> obj info))))
(+! (-> arg0 data 84 used) v1-8)
(+! (-> arg0 data 84 total) (logand -16 (+ v1-8 15)))
)
)
(if (nonzero? (-> obj drawable-trees))
(mem-usage (-> obj drawable-trees) arg0 arg1)
)
(if (nonzero? (-> obj collide-hash))
(mem-usage (-> obj collide-hash) arg0 arg1)
)
(set! (-> arg0 length) (max 65 (-> arg0 length)))
(set! (-> arg0 data 43 name) "entity")
(set! (-> arg0 data 44 name) "camera")
(set! (-> arg0 data 64 name) "pat")
(set! (-> arg0 data 60 name) "bsp-node")
(set! (-> arg0 length) (max 59 (-> arg0 length)))
(set! (-> arg0 data 58 name) "bsp-main")
(+! (-> arg0 data 58 count) 1)
(let ((v1-31 400))
(+! (-> arg0 data 58 used) v1-31)
(+! (-> arg0 data 58 total) (logand -16 (+ v1-31 15)))
)
(set! (-> arg0 length) (max 62 (-> arg0 length)))
(set! (-> arg0 data 61 name) "bsp-leaf-vis-self")
(+! (-> arg0 data 61 count) 1)
(let ((v1-40 (-> obj visible-list-length)))
(+! (-> arg0 data 61 used) v1-40)
(+! (-> arg0 data 61 total) (logand -16 (+ v1-40 15)))
)
(set! (-> arg0 length) (max 60 (-> arg0 length)))
(set! (-> arg0 data 59 name) "bsp-misc")
(+! (-> arg0 data 59 count) 1)
(let ((v1-50 (* (-> obj texture-remap-table-len) 8)))
(+! (-> arg0 data 59 used) v1-50)
(+! (-> arg0 data 59 total) (logand -16 (+ v1-50 15)))
)
(set! (-> arg0 length) (max 60 (-> arg0 length)))
(set! (-> arg0 data 59 name) "bsp-misc")
(+! (-> arg0 data 59 count) 1)
(let ((v1-60 (* (-> obj texture-page-count) 4)))
(+! (-> arg0 data 59 used) v1-60)
(+! (-> arg0 data 59 total) (logand -16 (+ v1-60 15)))
)
(when (nonzero? (-> obj unknown-basic))
(set! (-> arg0 length) (max 60 (-> arg0 length)))
(set! (-> arg0 data 59 name) "bsp-misc")
(+! (-> arg0 data 59 count) 1)
(let ((v1-72 (asize-of (-> obj unknown-basic))))
(+! (-> arg0 data 59 used) v1-72)
(+! (-> arg0 data 59 total) (logand -16 (+ v1-72 15)))
)
)
(when (nonzero? (-> obj actor-birth-order))
(set! (-> arg0 length) (max 60 (-> arg0 length)))
(set! (-> arg0 data 59 name) "bsp-misc")
(+! (-> arg0 data 59 count) 1)
(let ((v1-85 (* (-> obj actors length) 4)))
(+! (-> arg0 data 59 used) v1-85)
(+! (-> arg0 data 59 total) (logand -16 (+ v1-85 15)))
)
)
(+! (-> arg0 data 64 count) (-> obj pat-length))
(let ((v1-92 (* (-> obj pat-length) 4)))
(+! (-> arg0 data 64 used) v1-92)
(+! (-> arg0 data 64 total) (logand -16 (+ v1-92 15)))
)
(when (nonzero? (-> obj region-trees))
(let* ((s3-0 (-> obj region-trees length))
(s2-0 0)
(a0-39 (-> obj region-trees s2-0))
)
(while (< s2-0 s3-0)
(mem-usage a0-39 arg0 (logior arg1 128))
(+! s2-0 1)
(set! a0-39 (-> obj region-trees s2-0))
)
)
)
(let ((s3-1 (-> obj cameras)))
(when (nonzero? s3-1)
(dotimes (s2-1 (-> s3-1 length))
(mem-usage (-> s3-1 s2-1) arg0 (logior arg1 256))
)
)
)
(if (nonzero? (-> obj nodes))
(mem-usage-bsp-tree obj (-> obj nodes 0) arg0 arg1)
)
obj
)
(defmethod login bsp-header ((obj bsp-header))
"Log in a bsp-header.
Note that this version isn't typically used - instead level.gc does a special login that runs
over multiple frames."
(if (nonzero? (-> obj drawable-trees))
(login (-> obj drawable-trees))
)
(set! (-> obj level tfrag-gs-test)
(if (logtest? (-> obj texture-flags 0) (texture-page-flag alpha-enable))
(new 'static 'gs-test :ate #x1 :atst (gs-atest always) :zte #x1 :ztst (gs-ztest greater-equal))
(new 'static 'gs-test
:ate #x1
:atst (gs-atest greater-equal)
:aref #x26
:zte #x1
:ztst (gs-ztest greater-equal)
)
)
)
obj
)
(define *test-shrub* 0)
(defmethod draw bsp-header ((obj bsp-header) (arg0 bsp-header) (arg1 display-frame))
"Draw a bsp-header. Note that this mostly just adds drawable trees to a list which is later
used by the background system. So this is probably a bit of a leftover from when drawing was done
by iterating through all drawable-trees recursively."
(local-vars (a3-4 uint128) (a3-5 uint128))
(let ((s4-0 (-> obj level)))
(when (-> s4-0 render?)
;; setup for level drawing:
(set! *draw-index* (-> s4-0 draw-index)) ;; the index of level being drawn
(set! (-> *prototype-tie-work* mood) (-> s4-0 mood-context)) ;; the mood for TIE.
;; update tie/tfrag level of detail
(if *artist-use-menu-subdiv*
(update-subdivide-settings! *subdivide-settings* *math-camera* 7)
(update-subdivide-settings! *subdivide-settings* *math-camera* (-> s4-0 index))
)
;; upload visibility data to spr
(let ((a2-3 (/ (+ (-> obj visible-list-length) 15) 16)))
(__mem-move (-> (scratchpad-object terrain-context) work background vis-list) (-> s4-0 vis-bits) (the uint (* a2-3 16)))
; (dma-send-to-spr-no-flush
; (the-as uint (-> (the-as terrain-context #x70000000) work background vis-list))
; (the-as uint (-> s4-0 vis-bits))
; (the-as uint a2-3)
; #f
; )
)
;; debug option to flip visibility bits
(when *artist-flip-visible*
(let ((v1-15 (/ (+ (-> obj visible-list-length) 15) 16))
(a0-7 (-> (scratchpad-object terrain-context) work background vis-list))
(a1-5 (-> obj all-visible-list))
)
(dotimes (a2-4 v1-15)
(let ((a3-3 (-> (the-as (pointer uint128) (+ (the-as uint a0-7) (* a2-4 16))))))
(.pnor a3-4 a3-3 0)
)
(let ((t0-2 (-> (the-as (pointer uint128) (&+ a1-5 (* a2-4 16))))))
(.pand a3-5 a3-4 t0-2)
)
(set! (-> (the-as (pointer uint128) (+ (the-as uint a0-7) (* a2-4 16)))) a3-5)
)
)
)
;; load vf registers with camera matrices/planes - to be used by renderers
(let ((at-0 *math-camera*))
(with-vf (vf16 vf17 vf18 vf19 vf20 vf21 vf22 vf23 vf24 vf25 vf26 vf27 vf28 vf29 vf30 vf31)
:rw 'write
(.lvf vf16 (&-> at-0 plane 0 quad))
(.lvf vf17 (&-> at-0 plane 1 quad))
(.lvf vf18 (&-> at-0 plane 2 quad))
(.lvf vf19 (&-> at-0 plane 3 quad))
(.lvf vf20 (&-> at-0 shrub-mat vector 0 quad))
(.lvf vf21 (&-> at-0 shrub-mat vector 1 quad))
(.lvf vf22 (&-> at-0 shrub-mat vector 2 quad))
(.lvf vf23 (&-> at-0 shrub-mat trans quad))
(.lvf vf24 (&-> at-0 camera-rot vector 0 quad))
(.lvf vf25 (&-> at-0 camera-rot vector 1 quad))
(.lvf vf26 (&-> at-0 camera-rot vector 2 quad))
(.lvf vf27 (&-> at-0 camera-rot trans quad))
(.lvf vf28 (&-> at-0 camera-temp vector 0 quad))
(.lvf vf29 (&-> at-0 camera-temp vector 1 quad))
(.lvf vf30 (&-> at-0 camera-temp vector 2 quad))
(.lvf vf31 (&-> at-0 camera-temp trans quad))
)
)
;; execute the draw!
(when (nonzero? (-> obj drawable-trees))
(with-profiler 'bsp *profile-bsp-color*
(let ((a1-8 (-> obj drawable-trees)))
(draw a1-8 a1-8 arg1)
)
)
)
)
)
0
(none)
)
(defmethod debug-draw bsp-header ((obj bsp-header) (arg0 drawable) (arg1 display-frame))
"Set up and call debug-draw on a bsp-header and all its drawables.
The actual use of debug-draw is up to the drawables, but this is a useful place to do random
debug drawing."
(rlet ((vf16 :class vf)
(vf17 :class vf)
(vf18 :class vf)
(vf19 :class vf)
(vf20 :class vf)
(vf21 :class vf)
(vf22 :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)
)
(let ((v1-0 (-> obj level)))
(set! *draw-index* (-> v1-0 draw-index))
(set! (-> *prototype-tie-work* mood) (-> v1-0 mood-context))
(let ((a2-1 (/ (+ (-> obj visible-list-length) 15) 16)))
(__mem-move (-> (scratchpad-object terrain-context) work background vis-list) (-> v1-0 vis-bits) (the uint (* a2-1 16)))
; (dma-send-to-spr-no-flush
; (the-as uint (+ #x38a0 #x70000000))
; (the-as uint (-> v1-0 vis-bits))
; (the-as uint a2-1)
; #f
; )
)
)
(let ((at-0 *math-camera*))
(with-vf (vf16 vf17 vf18 vf19 vf20 vf21 vf22 vf23 vf24 vf25 vf26 vf27 vf28 vf29 vf30 vf31)
:rw 'write
(.lvf vf16 (&-> at-0 plane 0 quad))
(.lvf vf17 (&-> at-0 plane 1 quad))
(.lvf vf18 (&-> at-0 plane 2 quad))
(.lvf vf19 (&-> at-0 plane 3 quad))
(.lvf vf20 (&-> at-0 shrub-mat vector 0 quad))
(.lvf vf21 (&-> at-0 shrub-mat vector 1 quad))
(.lvf vf22 (&-> at-0 shrub-mat vector 2 quad))
(.lvf vf23 (&-> at-0 shrub-mat trans quad))
(.lvf vf24 (&-> at-0 camera-rot vector 0 quad))
(.lvf vf25 (&-> at-0 camera-rot vector 1 quad))
(.lvf vf26 (&-> at-0 camera-rot vector 2 quad))
(.lvf vf27 (&-> at-0 camera-rot trans quad))
(.lvf vf28 (&-> at-0 camera-temp vector 0 quad))
(.lvf vf29 (&-> at-0 camera-temp vector 1 quad))
(.lvf vf30 (&-> at-0 camera-temp vector 2 quad))
(.lvf vf31 (&-> at-0 camera-temp trans quad))
)
)
(when (nonzero? (-> obj drawable-trees))
(let ((a1-4 (-> obj drawable-trees)))
(debug-draw a1-4 a1-4 arg1)
)
)
0
(none)
)
)
(defmethod collect-stats bsp-header ((obj bsp-header))
"Set up and call collect-stats on a bsp-header.
This will run (moderately) expensive checks to count triangles, visibility, etc."
(rlet ((vf16 :class vf)
(vf17 :class vf)
(vf18 :class vf)
(vf19 :class vf)
(vf20 :class vf)
(vf21 :class vf)
(vf22 :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)
)
(let ((v1-0 (-> obj level))
(a2-0 (/ (+ (-> obj visible-list-length) 15) 16))
)
(__mem-move (-> (scratchpad-object terrain-context) work background vis-list) (-> v1-0 vis-bits) (the uint (* a2-0 16)))
; (dma-send-to-spr-no-flush
; (the-as uint (+ #x38a0 #x70000000))
; (the-as uint (-> v1-0 vis-bits))
; (the-as uint a2-0)
; #f
; )
)
(let ((at-0 *math-camera*))
(with-vf (vf16 vf17 vf18 vf19 vf20 vf21 vf22 vf23 vf24 vf25 vf26 vf27 vf28 vf29 vf30 vf31)
:rw 'write
(.lvf vf16 (&-> at-0 plane 0 quad))
(.lvf vf17 (&-> at-0 plane 1 quad))
(.lvf vf18 (&-> at-0 plane 2 quad))
(.lvf vf19 (&-> at-0 plane 3 quad))
(.lvf vf20 (&-> at-0 shrub-mat vector 0 quad))
(.lvf vf21 (&-> at-0 shrub-mat vector 1 quad))
(.lvf vf22 (&-> at-0 shrub-mat vector 2 quad))
(.lvf vf23 (&-> at-0 shrub-mat trans quad))
(.lvf vf24 (&-> at-0 camera-rot vector 0 quad))
(.lvf vf25 (&-> at-0 camera-rot vector 1 quad))
(.lvf vf26 (&-> at-0 camera-rot vector 2 quad))
(.lvf vf27 (&-> at-0 camera-rot trans quad))
(.lvf vf28 (&-> at-0 camera-temp vector 0 quad))
(.lvf vf29 (&-> at-0 camera-temp vector 1 quad))
(.lvf vf30 (&-> at-0 camera-temp vector 2 quad))
(.lvf vf31 (&-> at-0 camera-temp trans quad))
)
)
(if (nonzero? (-> obj drawable-trees))
(collect-stats (-> obj drawable-trees))
)
0
(none)
)
)
(defun bsp-camera-asm ((arg0 bsp-header) (arg1 vector))
"Determine which leaf node of the bsp we are in, and store this in the bsp-header."
(local-vars
(a2-1 object)
(cam-pos-i1 uint128)
(cam-pos-32 uint128)
(cam-pos-16 uint128)
(cam-pos-8 uint128)
(t0-5 uint)
(b-flag uint)
(f-flag int)
(front-max-compare uint128)
(back-max-compare uint128)
(front-min-compare uint128)
(back-min-compare uint128)
)
(rlet ((Q :class vf)
(vf0 :class vf)
(vf1 :class vf)
(vf2 :class vf)
(vf3 :class vf)
)
(init-vf0-vector)
(nop!)
;; unlike in jak 1, we use integers here, and each level has an offset/scale
(.lvf vf3 (&-> arg0 bsp-scale quad))
(let ((nodes (the-as object (-> arg0 nodes))))
;; apply scaling and offset.
(.lvf vf1 (&-> arg1 quad))
(.lvf vf2 (&-> arg0 bsp-offset quad))
(.sub.vf vf1 vf1 vf2 :mask #b111)
(.div.vf Q vf0 vf3 :fsf #b11 :ftf #b0)
(.wait.vf)
(.mul.vf vf1 vf1 Q :mask #b1)
(.div.vf Q vf0 vf3 :fsf #b11 :ftf #b1)
(.wait.vf)
(.mul.vf vf1 vf1 Q :mask #b10)
(.div.vf Q vf0 vf3 :fsf #b11 :ftf #b10)
(.wait.vf)
(.mul.vf vf1 vf1 Q :mask #b100)
(let ((a1-1 #xffffff)
(nidx (the-as uint 0))
)
(vftoi15.xyzw vf1 vf1) ;; convert scaled/offset to integer
(.mov cam-pos-i1 vf1)
;; pack to 8-byte integers
(.pw.sra cam-pos-32 cam-pos-i1 15)
(.ppach cam-pos-16 (the-as uint128 0) cam-pos-32)
(.ppacb cam-pos-8 (the-as uint128 0) (the-as int cam-pos-16))
(let ((cam-pos-8m (the-as uint128 (logand (the-as int cam-pos-8) a1-1))))
;; loop to go down the tree top
(label cfg-1)
(let ((node (the-as bsp-node (&+ (the-as pointer nodes) (+ (* nidx 16) (* nidx 4))))))
(nop!)
;; do comparisons
(let ((front-min (the-as uint128 (-> node front-box-min clr))))
(.pcgtb front-min-compare front-min cam-pos-8m)
(let ((front-max (the-as uint128 (-> node front-box-max clr))))
(.pcgtb front-max-compare front-max cam-pos-8m)
)
(let ((back-min (the-as uint128 (-> node back-box-min clr))))
(.pcgtb back-min-compare back-min cam-pos-8m)
(let ((back-max (the-as uint128 (-> node back-box-max clr))))
(.pcgtb back-max-compare back-max cam-pos-8m)
)
;; check comparisons
(let* ((front-idx (-> node front))
(not-f-min (lognot (the-as int front-min-compare)))
(not-b-min (lognot (the-as int back-min-compare)))
(t4-1 (logand not-f-min (the-as int front-max-compare)))
(t5-1 (logand not-b-min (the-as int back-max-compare)))
(f-in-box (logand t4-1 a1-1))
(b-in-box (logand t5-1 a1-1))
)
;; (.srl (the-as uint f-flag) (the-as uint front-min) 24)
(set! f-flag (logand #xffffffff (shr front-min 24)))
(let ((back-idx (the-as bsp-node (-> node back))))
(b! (= f-in-box a1-1) cfg-4 :delay
;(.srl b-flag (the-as int back-min) 24)
(set! b-flag (the uint (logand #xffffffff (shr back-min 24))))
)
(b! (= b-in-box a1-1) cfg-7 :delay (set! t0-5 (the-as uint 1)))
(b! #t cfg-11 :delay (set! (-> arg0 cam-outside-bsp) t0-5)) ;; outside of both, outside of bsp!
(label cfg-4)
(b! (zero? f-flag) cfg-1 :likely-delay (set! nidx (the uint front-idx)))
(let ((v1-1 nidx))
(set! (-> arg0 cam-using-back) (the-as uint 0)) ;; for whatever reason, store the side...
(b! #t cfg-10 :delay (set! a2-1 front-idx))
(label cfg-7)
(b! (zero? b-flag) cfg-1 :likely-delay (set! nidx (the uint back-idx)))
(set! v1-1 nidx)
(set! a2-1 back-idx)
(set! (-> arg0 cam-using-back) (the-as uint 1))
(label cfg-10)
(set! (-> arg0 current-leaf-idx) (the-as uint a2-1)) ;; store both leaf and thing before it.
(set! (-> arg0 cam-box-idx) (the-as uint v1-1))
)
)
)
)
)
)
)
)
)
(set! (-> arg0 cam-outside-bsp) (the-as uint 0)) ;; not outside of bsp if loop finished.
(label cfg-11)
0
(none)
)
)
(defmethod collect-regions bsp-header ((obj bsp-header) (arg0 sphere) (arg1 int) (arg2 region-prim-list))
"Recursively find all regions containing the sphere, add to region-prim-list"
(let ((s3-0 (-> obj region-trees)))
(dotimes (s2-0 (-> s3-0 length))
(collect-regions (-> s3-0 s2-0) arg0 arg1 arg2)
)
)
0
(none)
)
(defun print-collide-stats ()
"Display collide stats on screen."
(format *stdcon* "~0k~%count cycles instr icache dcache vu0/to/from~%")
(print-to-stream (-> *perf-stats* data 3) "collide" *stdcon*)
(print-to-stream (-> *perf-stats* data 4) "collide-list" *stdcon*)
(print-to-stream (-> *perf-stats* data 5) "collide-fill" *stdcon*)
(format *stdcon* "~0k---------------------------------------------------------------~%")
(format *stdcon* "~0kcalls = ~d~%" (-> *collide-stats* calls))
(format *stdcon* "~0kspheres = ~d~256hspheres/call = ~f~%"
(-> *collide-stats* spheres)
(/ (the float (-> *collide-stats* spheres)) (the float (-> *collide-stats* calls)))
)
(format *stdcon* "~0knodes = ~d~256hnodes/call = ~f~%"
(-> *collide-stats* nodes)
(/ (the float (-> *collide-stats* nodes)) (the float (-> *collide-stats* calls)))
)
(format *stdcon* "~0kfrags = ~d~256hfrags/call = ~f~%"
(-> *collide-stats* frags)
(/ (the float (-> *collide-stats* frags)) (the float (-> *collide-stats* calls)))
)
(format *stdcon* "~0ktris = ~d~256htris/frag = ~f~%"
(-> *collide-stats* tris)
(/ (the float (-> *collide-stats* tris)) (the float (-> *collide-stats* frags)))
)
(format *stdcon* "~0koutput = ~d~256houtput/call = ~f~%"
(-> *collide-stats* output)
(/ (the float (-> *collide-stats* output)) (the float (-> *collide-stats* calls)))
)
(format *stdcon* "~0k---------------------------------------------------------------~%")
(let ((gp-0 (stopwatch-elapsed-ticks (the-as stopwatch (&-> *collide-stats* pad0 1))))
(s4-0 (stopwatch-elapsed-ticks (the-as stopwatch (&-> *collide-stats* total-target 7))))
(s5-0 (stopwatch-elapsed-ticks (the-as stopwatch (&-> *collide-stats* target-cache-fill 7))))
)
(format *stdcon* "~0ktotal-target ~D~%" gp-0)
(format *stdcon* "~0ktarget-cache-fill ~D ~0,,2f%~%" s4-0 (/ (* 100.0 (the float s4-0)) (the float gp-0)))
(format *stdcon* "~0ktarget-ray-poly ~D ~0,,2f%~%" s5-0 (/ (* 100.0 (the float s5-0)) (the float gp-0)))
)
(set! (-> *collide-stats* calls) (the-as uint 0))
(set! (-> *collide-stats* spheres) (the-as uint 0))
(set! (-> *collide-stats* nodes) (the-as uint 0))
(set! (-> *collide-stats* frags) (the-as uint 0))
(set! (-> *collide-stats* tris) (the-as uint 0))
(set! (-> *collide-stats* output) (the-as uint 0))
(stopwatch-init (the-as stopwatch (&-> *collide-stats* pad0 1)))
(stopwatch-init (the-as stopwatch (&-> *collide-stats* total-target 7)))
(stopwatch-init (the-as stopwatch (&-> *collide-stats* target-cache-fill 7)))
0
(none)
)
(defun level-remap-texture ((arg0 texture-id))
"Remap a texture id."
(let ((v1-1 (-> *level* log-in-level-bsp)))
(when v1-1
(let* ((a3-0 (-> v1-1 texture-remap-table-len))
(v1-2 (the-as object (-> v1-1 texture-remap-table)))
(t0-0 (the-as (pointer uint64) v1-2))
(a1-1 (the-as uint #xfffffff8))
(a2-1 (logand (new 'static 'texture-id :index #xfff :page #xfff) arg0))
(a3-2 (the-as object (&+ t0-0 (* a3-0 8))))
)
(label cfg-2)
(b! (= v1-2 a3-2) cfg-8 :delay (nop!))
(let ((t0-3 (the-as object (logand (/ (+ (the-as int v1-2) (the-as int a3-2)) 2) a1-1))))
(let ((t1-1 (- (-> (the-as (pointer uint32) t0-3) 0) a2-1)))
(b! (zero? t1-1) cfg-7 :delay (nop!))
(b! (< (the-as int t1-1) 0) cfg-6 :delay (nop!))
)
(b! #t cfg-2 :delay (set! a3-2 (the-as (pointer uint64) t0-3)))
(label cfg-6)
(b! #t cfg-2 :delay (set! v1-2 (+ (the-as int t0-3) 8)))
(label cfg-7)
(set! arg0 (the-as texture-id (logior (-> (the-as (pointer uint32) t0-3) 1) 20)))
)
)
(label cfg-8)
0
)
)
(the-as texture-id arg0)
)
(defun build-masks ((arg0 bsp-header))
"Allocate texture masks as needed for a level."
(let ((v1-0 (-> arg0 drawable-trees))
(s2-0 (-> arg0 tfrag-mask-count))
(s3-0 (-> arg0 shrub-mask-count))
(s4-0 (-> arg0 alpha-mask-count))
(gp-0 (-> arg0 water-mask-count))
)
(when (zero? (+ s2-0 s3-0 s4-0 gp-0))
(dotimes (a0-5 (-> v1-0 length))
(let ((a1-2 (-> v1-0 trees a0-5)))
(cond
((= (-> a1-2 type) drawable-tree-tfrag)
(let* ((a2-5 (-> (the-as drawable-tree-tfrag a1-2) arrays (+ (-> (the-as drawable-tree-tfrag a1-2) length) -1)))
(a1-4 (-> a2-5 length))
(a2-6 (-> (the-as drawable-inline-array-tfrag a2-5) data))
)
(dotimes (a3-1 a1-4)
(set! (-> a2-6 0 texture-masks-index) s2-0)
(+! s2-0 1)
(set! a2-6 (the-as (inline-array tfragment) (-> a2-6 1)))
)
)
)
((= (-> a1-2 type) drawable-tree-tfrag-trans)
(let* ((a2-13
(-> (the-as drawable-tree-tfrag-trans a1-2) arrays (+ (-> (the-as drawable-tree-tfrag-trans a1-2) length) -1))
)
(a1-7 (-> a2-13 length))
(a2-14 (-> (the-as drawable-inline-array-tfrag a2-13) data))
)
(dotimes (a3-3 a1-7)
(set! (-> a2-14 0 texture-masks-index) s4-0)
(+! s4-0 1)
(set! a2-14 (the-as (inline-array tfragment) (-> a2-14 1)))
)
)
)
((= (-> a1-2 type) drawable-tree-tfrag-water)
(let* ((a2-21
(-> (the-as drawable-tree-tfrag-water a1-2) arrays (+ (-> (the-as drawable-tree-tfrag-water a1-2) length) -1))
)
(a1-10 (-> a2-21 length))
(a2-22 (-> (the-as drawable-inline-array-tfrag a2-21) data))
)
(dotimes (a3-5 a1-10)
(set! (-> a2-22 0 texture-masks-index) gp-0)
(+! gp-0 1)
(set! a2-22 (the-as (inline-array tfragment) (-> a2-22 1)))
)
)
)
((= (-> a1-2 type) drawable-tree-instance-tie)
(let* ((a1-13 (-> (the-as drawable-tree-instance-tie a1-2) prototypes prototype-array-tie))
(a2-26 (-> a1-13 length))
)
(dotimes (a3-7 a2-26)
(cond
((logtest? (-> a1-13 array-data a3-7 flags) (prototype-flags tpage-water))
(set! (-> a1-13 array-data a3-7 texture-masks-index) gp-0)
(+! gp-0 1)
)
((logtest? (-> a1-13 array-data a3-7 flags) (prototype-flags tpage-alpha))
(set! (-> a1-13 array-data a3-7 texture-masks-index) s4-0)
(+! s4-0 1)
)
(else
(set! (-> a1-13 array-data a3-7 texture-masks-index) s2-0)
(+! s2-0 1)
)
)
)
)
)
((= (-> a1-2 type) drawable-tree-instance-shrub)
(let* ((a2-30 (-> (the-as drawable-tree-instance-shrub a1-2) info prototype-inline-array-shrub))
(a1-16 (-> a2-30 length))
(a2-31 (-> a2-30 data))
)
(dotimes (a3-9 a1-16)
(set! (-> a2-31 0 texture-masks-index) s3-0)
(+! s3-0 1)
(set! a2-31 (the-as (inline-array prototype-bucket-shrub) (-> a2-31 1)))
)
)
)
)
)
)
)
(when (nonzero? s2-0)
(set! (-> arg0 tfrag-masks) (new 'loading-level 'texture-masks-array (the-as int s2-0)))
(set! (-> arg0 tfrag-mask-count) (the-as uint (malloc 'loading-level (the-as int (* s2-0 4)))))
(let ((v1-5 (-> arg0 tfrag-masks)))
(dotimes (a0-8 (the-as int s2-0))
(let ((a1-24 (-> v1-5 data a0-8)))
(dotimes (a2-34 3)
(set! (-> a1-24 data a2-34 mask quad) (the-as uint128 0))
)
)
)
)
)
(when (nonzero? s3-0)
(set! (-> arg0 shrub-masks) (new 'loading-level 'texture-masks-array (the-as int s3-0)))
(set! (-> arg0 shrub-mask-count) (the-as uint (malloc 'loading-level (the-as int (* s3-0 4)))))
(let ((v1-10 (-> arg0 shrub-masks)))
(dotimes (a0-11 (the-as int s3-0))
(let ((a1-32 (-> v1-10 data a0-11)))
(dotimes (a2-36 3)
(set! (-> a1-32 data a2-36 mask quad) (the-as uint128 0))
)
)
)
)
)
(when (nonzero? s4-0)
(set! (-> arg0 alpha-masks) (new 'loading-level 'texture-masks-array (the-as int s4-0)))
(set! (-> arg0 alpha-mask-count) (the-as uint (malloc 'loading-level (the-as int (* s4-0 4)))))
(let ((v1-15 (-> arg0 alpha-masks)))
(dotimes (a0-14 (the-as int s4-0))
(let ((a1-40 (-> v1-15 data a0-14)))
(dotimes (a2-38 3)
(set! (-> a1-40 data a2-38 mask quad) (the-as uint128 0))
)
)
)
)
)
(when (nonzero? gp-0)
(set! (-> arg0 water-masks) (new 'loading-level 'texture-masks-array (the-as int gp-0)))
(set! (-> arg0 water-mask-count) (the-as uint (malloc 'loading-level (the-as int (* gp-0 4)))))
(let ((v1-20 (-> arg0 water-masks)))
(dotimes (a0-17 (the-as int gp-0))
(let ((a1-48 (-> v1-20 data a0-17)))
(dotimes (a2-40 3)
(set! (-> a1-48 data a2-40 mask quad) (the-as uint128 0))
)
)
)
)
)
)
0
(none)
)