jak-project/goal_src/jak3/engine/level/region.gc
Hat Kid 93afb02cf4
decomp3: spawn target, add merc and particle buckets and some temporary hacks (#3445)
This includes all the collision stuff needed to spawn `target`,
decompiles the sparticle code and adds some of the PC hacks needed for
merc to run (it doesn't work quite right and looks bad, likely due to a
combination of code copied from Jak 2 and the time of day hacks).

There are a bunch of temporary hacks (see commits) in place to prevent
the game from crashing quite as much, but it is still extremely prone to
doing so due to lots of missing functions/potentially bad decomp.

---------

Co-authored-by: water <awaterford111445@gmail.com>
2024-04-05 00:07:39 -04:00

648 lines
22 KiB
Common Lisp

;;-*-Lisp-*-
(in-package goal)
;; name: region.gc
;; name in dgo: region
;; dgos: GAME
;; DECOMP BEGINS
;; WARN: Return type mismatch int vs drawable-region-prim.
(defmethod mem-usage ((this drawable-region-prim) (usage memory-usage-block) (flags int))
(set! (-> usage length) (max 51 (-> usage length)))
(set! (-> usage data 50 name) "region")
(+! (-> usage data 50 count) 1)
(let ((v1-6 (asize-of this)))
(+! (-> usage data 50 used) v1-6)
(+! (-> usage data 50 total) (logand -16 (+ v1-6 15)))
)
(mem-usage (-> this region) usage (logior flags 128))
(the-as drawable-region-prim 0)
)
;; WARN: Return type mismatch int vs drawable-inline-array-region-prim.
(defmethod mem-usage ((this drawable-inline-array-region-prim) (usage memory-usage-block) (flags int))
(set! (-> usage length) (max 1 (-> usage length)))
(set! (-> usage data 0 name) "drawable-group")
(+! (-> usage data 0 count) 1)
(let ((v1-5 32))
(+! (-> usage data 0 used) v1-5)
(+! (-> usage data 0 total) (logand -16 (+ v1-5 15)))
)
(dotimes (s3-0 (-> this length))
(mem-usage (-> this data s3-0) usage flags)
)
(the-as drawable-inline-array-region-prim 0)
)
(defmethod draw ((this drawable-tree-region-prim))
"Draw the drawable, and typically its children.
This usually means adding stuff to a list to be drawn later, rather than expensive drawing here."
0
(none)
)
(defmethod unpack-vis ((this drawable-tree-region-prim) (arg0 (pointer int8)) (arg1 (pointer int8)))
arg1
)
(defmethod collect-regions ((this drawable-region-prim) (arg0 sphere) (arg1 int) (arg2 region-prim-list))
"Fill the region-prim-list with regions that intersect the sphere."
(dotimes (s2-0 arg1)
(when (spheres-overlap? arg0 (the-as sphere (-> this bsphere)))
(set! (-> arg2 items (-> arg2 num-items)) this)
(+! (-> arg2 num-items) 1)
)
(&+! this 32)
)
0
(none)
)
(defmethod collect-regions ((this drawable-inline-array-region-prim) (arg0 sphere) (arg1 int) (arg2 region-prim-list))
"Fill the region-prim-list with regions that intersect the sphere."
(collect-regions (the-as drawable-region-prim (-> this data)) arg0 (-> this length) arg2)
0
(none)
)
(defmethod collect-regions ((this drawable-tree-region-prim) (arg0 sphere) (arg1 int) (arg2 region-prim-list))
"Fill the region-prim-list with regions that intersect the sphere."
(collect-regions (-> this data2 0) arg0 (-> this length) arg2)
0
(none)
)
(defmethod debug-draw-region ((this drawable-region-prim) (arg0 int))
(local-vars (sv-32 vector2h) (sv-36 vector))
(set! sv-32 (new 'stack 'vector2h))
(set! sv-36 (-> this bsphere))
(add-debug-x #t (bucket-id debug-no-zbuf1) sv-36 (new 'static 'rgba :r #xff :g #xff :a #x80))
(when (nonzero? (-> this region))
(let ((s5-0 add-debug-text-3d)
(s4-0 #t)
(s3-0 577)
)
(format (clear *temp-string*) "region-~D~%" (-> this region id))
(s5-0 s4-0 (the-as bucket-id s3-0) *temp-string* sv-36 (font-color white) sv-32)
)
(+! (-> sv-32 y) 8)
(let ((s5-1 (-> this region on-enter)))
(when s5-1
(let ((s4-1 add-debug-text-3d)
(s3-1 #t)
(s2-1 577)
)
(format (clear *temp-string*) "(on-enter ~S)" s5-1)
(s4-1 s3-1 (the-as bucket-id s2-1) *temp-string* sv-36 (font-color white) sv-32)
)
(+! (-> sv-32 y) 8)
)
)
(let ((s5-2 (-> this region on-inside)))
(when s5-2
(let ((s4-2 add-debug-text-3d)
(s3-2 #t)
(s2-2 577)
)
(format (clear *temp-string*) "(on-inside ~S)" s5-2)
(s4-2 s3-2 (the-as bucket-id s2-2) *temp-string* sv-36 (font-color white) sv-32)
)
(+! (-> sv-32 y) 8)
)
)
(let ((gp-1 (-> this region on-exit)))
(when gp-1
(let ((s5-3 add-debug-text-3d)
(s4-3 #t)
(s3-3 577)
)
(format (clear *temp-string*) "(on-exit ~S)" gp-1)
(s5-3 s4-3 (the-as bucket-id s3-3) *temp-string* sv-36 (font-color white) sv-32)
)
(+! (-> sv-32 y) 8)
)
)
)
0
(none)
)
(defmethod track-region ((this drawable-region-prim) (arg0 region-prim-area))
#f
)
(defmethod within-area? ((this drawable-region-prim) (arg0 region-prim-area))
"@returns Whether or not the object overlaps with the provided [[region-prim-area]]'s extent"
#f
)
(defmethod track-entered-region! ((this region-prim-area) (arg0 drawable-region-sphere))
(let ((v1-0 (-> this region-enter-count)))
(let ((a2-0 (-> arg0 region)))
(countdown (a3-0 v1-0)
(if (= (-> this region-enter-list a3-0) a2-0)
(return (the-as int #f))
)
)
(set! (-> this region-enter-list v1-0) a2-0)
)
(set! (-> this region-enter-prim-list v1-0) arg0)
(set! (-> this region-enter-count) (+ v1-0 1))
)
0
)
(defmethod track-exited-region! ((this region-prim-area) (arg0 drawable-region-sphere))
(let ((v1-0 (-> this region-exit-count)))
(let ((a2-0 (-> arg0 region)))
(countdown (a3-0 v1-0)
(if (= (-> this region-exit-list a3-0) a2-0)
(return (the-as int #f))
)
)
(set! (-> this region-exit-list v1-0) a2-0)
)
(set! (-> this region-exit-prim-list v1-0) arg0)
(set! (-> this region-exit-count) (+ v1-0 1))
)
0
)
(defmethod track-inside-region! ((this region-prim-area) (arg0 drawable-region-sphere))
(let ((v1-0 (-> this region-inside-count)))
(let ((a2-0 (-> arg0 region)))
(countdown (a3-0 v1-0)
(if (= (-> this region-inside-list a3-0) a2-0)
(return (the-as int #f))
)
)
(set! (-> this region-inside-list v1-0) a2-0)
)
(set! (-> this region-inside-prim-list v1-0) arg0)
(set! (-> this region-inside-count) (+ v1-0 1))
)
0
)
(defmethod track-start-region! ((this region-prim-area) (arg0 drawable-region-sphere))
(let ((v1-0 (-> this region-start-count)))
(let ((a2-0 (-> arg0 region)))
(countdown (a3-0 v1-0)
(if (= (-> this region-start-list a3-0) a2-0)
(return (the-as int #f))
)
)
(set! (-> this region-start-list v1-0) a2-0)
)
(set! (-> this region-start-prim-list v1-0) arg0)
(set! (-> this region-start-count) (+ v1-0 1))
)
0
)
(defmethod debug-draw-region ((this drawable-region-sphere) (arg0 int))
(let ((t9-0 (method-of-type drawable-region-prim debug-draw-region)))
(t9-0 this arg0)
)
(let ((a2-0 (-> this bsphere)))
(add-debug-sphere #t (bucket-id debug) a2-0 (-> this bsphere w) (new 'static 'rgba :r #xff :a #x80))
)
0
(none)
)
(defmethod track-region ((this drawable-region-sphere) (arg0 region-prim-area))
(-> this region)
(let ((s4-0 (-> this bsphere)))
(if (< 0.0 (ray-sphere-intersect (-> arg0 pos) (-> arg0 ray) s4-0 (-> s4-0 w)))
(track-entered-region! arg0 this)
)
(if (< 0.0 (ray-sphere-intersect (-> arg0 exit-pos) (-> arg0 exit-ray) s4-0 (-> s4-0 w)))
(track-exited-region! arg0 this)
)
(if (spheres-overlap? (the-as sphere (-> arg0 pos)) (the-as sphere s4-0))
(track-start-region! arg0 this)
)
(when (spheres-overlap? (the-as sphere (-> arg0 exit-pos)) (the-as sphere s4-0))
(track-inside-region! arg0 this)
#t
)
)
)
(defmethod within-area? ((this drawable-region-sphere) (arg0 region-prim-area))
"@returns Whether or not the object overlaps with the provided [[region-prim-area]]'s extent"
(spheres-overlap? (the-as sphere (-> arg0 pos)) (the-as sphere (-> this bsphere)))
)
(defmethod debug-draw-region ((this drawable-region-face) (arg0 int))
(when (zero? arg0)
(let ((t9-0 (method-of-type drawable-region-prim debug-draw-region)))
(t9-0 this arg0)
)
)
(let ((s5-0 (-> this bsphere)))
(add-debug-vector
#t
(bucket-id debug-no-zbuf1)
s5-0
(-> this data normal)
(meters 2)
(new 'static 'rgba :r #xff :g #xff :a #x80)
)
(add-debug-sphere #t (bucket-id debug) s5-0 (-> this bsphere w) (new 'static 'rgba :r #xff :a #x30))
)
;; (add-debug-bound
;; (bucket-id debug)
;; (-> this data points)
;; (the-as int (-> this data num-points))
;; (new 'static 'rgba :r #x80 :g #x80 :a #x40)
;; (new 'static 'rgba :r #x80 :a #x40)
;; 0
;; )
0
(none)
)
(defmethod track-region ((this drawable-region-face) (arg0 region-prim-area))
(local-vars (sv-48 vector) (sv-52 vector) (sv-56 (inline-array vector)))
(-> this region)
(let* ((s4-0 (-> this data))
(v1-1 (-> s4-0 normal))
(a0-3 (>= 0.0 (- (vector-dot (-> arg0 pos) v1-1) (-> v1-1 w))))
(s3-0 (>= 0.0 (- (vector-dot (-> arg0 exit-pos) v1-1) (-> v1-1 w))))
)
(when (!= a0-3 s3-0)
(when (nonzero? (-> s4-0 num-points))
(set! sv-48 (new 'stack-no-clear 'vector))
(set! sv-52 (new 'stack-no-clear 'vector))
(set! sv-56 (-> s4-0 points))
(ray-plane-intersect sv-48 sv-52 (-> arg0 pos) (-> arg0 ray) (-> sv-56 0) (-> sv-56 1) (-> sv-56 2))
(let ((s4-1 (-> s4-0 num-points))
(s2-0 0)
(s1-0 (vector-negate! (new 'stack-no-clear 'vector) sv-52))
)
(while (< (+ s2-0 2) (the-as int s4-1))
(if (or (point-in-triangle-cross
sv-48
sv-52
(-> (the-as (inline-array vector) sv-56) 0)
(-> (the-as (inline-array vector) sv-56) 1)
(-> (the-as (inline-array vector) sv-56) 2)
)
(point-in-triangle-cross
sv-48
s1-0
(-> (the-as (inline-array vector) sv-56) 0)
(-> (the-as (inline-array vector) sv-56) 1)
(-> (the-as (inline-array vector) sv-56) 2)
)
)
(goto cfg-17)
)
(+! s2-0 1)
(set! sv-56 (the-as (inline-array vector) (-> (the-as (inline-array vector) sv-56) 1)))
)
)
(set! s3-0 s3-0)
(goto cfg-20)
)
(label cfg-17)
(if s3-0
(track-entered-region! arg0 (the-as drawable-region-sphere this))
(track-exited-region! arg0 (the-as drawable-region-sphere this))
)
)
(label cfg-20)
s3-0
)
)
(defmethod debug-draw-region ((this drawable-region-volume) (arg0 int))
(let ((t9-0 (method-of-type drawable-region-prim debug-draw-region)))
(t9-0 this arg0)
)
(let* ((s5-0 (-> this faces length))
(s4-0 0)
(a0-3 (-> this faces data s4-0))
)
(while (< s4-0 s5-0)
(debug-draw-region a0-3 1)
(+! s4-0 1)
(set! a0-3 (-> this faces data s4-0))
)
)
0
(none)
)
(defmethod track-region ((this drawable-region-volume) (arg0 region-prim-area))
(if (within-area? this arg0)
(track-start-region! arg0 (the-as drawable-region-sphere this))
)
(let* ((s4-0 (-> this faces length))
(s3-0 0)
(a0-4 (-> this faces data s3-0))
)
(while (< s3-0 s4-0)
(if (not (track-region a0-4 arg0))
(return #f)
)
(+! s3-0 1)
(set! a0-4 (-> this faces data s3-0))
)
)
(track-inside-region! arg0 (the-as drawable-region-sphere this))
#t
)
(defmethod within-area? ((this drawable-region-volume) (arg0 region-prim-area))
"@returns Whether or not the object overlaps with the provided [[region-prim-area]]'s extent"
(let* ((v1-1 (-> this faces length))
(a2-0 0)
(a3-2 (-> this faces data a2-0))
)
(while (< a2-0 v1-1)
(let ((a3-4 (-> a3-2 data normal)))
(if (< 0.0 (- (vector-dot (-> arg0 pos) a3-4) (-> a3-4 w)))
(return #f)
)
)
(+! a2-0 1)
(set! a3-2 (-> this faces data a2-0))
)
)
#t
)
(defmethod drawable-tree-region-prim-method-17 ((this drawable-tree-region-prim) (arg0 vector))
;; og:preserve-this
(sphere<-vector+r! (the-as sphere (-> (scratchpad-object region-prim-area) pos)) arg0 0.0)
(let* ((s5-0 (-> this data2 (+ (-> this length) -1) length))
(s4-0 0)
(a0-8 (the-as object (+ (+ (* s4-0 32) 32) (the-as int (-> this data2 (+ (-> this length) -1))))))
)
(while (< s4-0 s5-0)
;; og:preserve-this
(if (within-area? (the-as drawable-region-prim a0-8) (scratchpad-object region-prim-area))
(return #t)
)
(+! s4-0 1)
(set! a0-8 (+ (+ (* s4-0 32) 32) (the-as int (-> this data2 (+ (-> this length) -1)))))
)
)
#f
)
;; WARN: Return type mismatch int vs symbol.
(defmethod point-in-region-debug! ((this region) (arg0 vector))
"Debug check to see if point is in region. This is not efficient, since it has to find the parent geometry of this region."
(local-vars (sv-16 int) (sv-32 int))
;; og:preserve-this
(sphere<-vector+r! (the-as sphere (-> (scratchpad-object region-prim-area) pos)) arg0 0.0)
(dotimes (s5-0 (-> *level* length))
(let ((s4-0 (-> *level* level s5-0)))
(when (= (-> s4-0 status) 'active)
(when (nonzero? (-> s4-0 bsp region-trees))
(let* ((s3-0 (-> s4-0 bsp region-trees length))
(s2-0 0)
(s1-0 (-> s4-0 bsp region-trees s2-0))
)
(while (< s2-0 s3-0)
(let ((s0-0 (-> s1-0 data2 (+ (-> s1-0 length) -1) length)))
(set! sv-16 0)
(set! sv-32 (+ (+ (* sv-16 32) 32) (the-as int (-> s1-0 data2 (+ (-> s1-0 length) -1)))))
(while (< sv-16 s0-0)
(if (and (= (-> (the-as drawable-region-prim sv-32) region) this)
(within-area?
(the-as drawable-region-prim sv-32)
;; og:preserve-this
(the-as region-prim-area (-> (scratchpad-object region-prim-area) region-prim-list))
)
)
(return (the-as symbol sv-32))
)
(set! sv-16 (+ sv-16 1))
(set! sv-32 (+ (+ (* sv-16 32) 32) (the-as int (-> s1-0 data2 (+ (-> s1-0 length) -1)))))
)
)
(+! s2-0 1)
(set! s1-0 (-> s4-0 bsp region-trees s2-0))
)
)
)
)
)
)
(the-as symbol #f)
)
(defmethod debug-print ((this drawable-tree-region-prim) (arg0 vector) (arg1 object))
;; og:preserve-this
(sphere<-vector+r! (the-as sphere (-> (scratchpad-object region-prim-area) pos)) arg0 0.0)
(let* ((s4-0 (-> this data2 (+ (-> this length) -1) length))
(s3-0 0)
(s2-0 (the-as object (+ (+ (* s3-0 32) 32) (the-as int (-> this data2 (+ (-> this length) -1))))))
)
(while (< s3-0 s4-0)
;; og:preserve-this
(if (within-area? (the-as drawable-region-prim s2-0) (scratchpad-object region-prim-area))
(format
arg1
" splitbox-~D ~A~%"
(-> (the-as drawable-region-prim s2-0) id)
(the-as drawable-region-prim s2-0)
)
)
(+! s3-0 1)
(set! s2-0 (+ (+ (* s3-0 32) 32) (the-as int (-> this data2 (+ (-> this length) -1)))))
)
)
0
(none)
)
(defun region-tree-execute ((arg0 symbol) (arg1 vector) (arg2 vector))
(local-vars (sv-32 vector))
(set! sv-32 (vector-average! (new 'stack-no-clear 'vector) arg1 arg2))
(set! (-> sv-32 w) (* 0.5 (vector-vector-distance arg1 arg2)))
;; og:preserve-this
(set! (-> (scratchpad-object region-prim-area) region-prim-list num-items) 0)
(set! (-> (scratchpad-object region-prim-area) region-enter-count) 0)
(set! (-> (scratchpad-object region-prim-area) region-exit-count) 0)
(set! (-> (scratchpad-object region-prim-area) region-inside-count) 0)
(set! (-> (scratchpad-object region-prim-area) region-start-count) 0)
(sphere<-vector+r! (the-as sphere (-> (scratchpad-object region-prim-area) pos)) arg1 0.0)
(sphere<-vector+r! (the-as sphere (-> (scratchpad-object region-prim-area) exit-pos)) arg2 0.0)
(vector-! (-> (scratchpad-object region-prim-area) ray) arg2 arg1)
(vector-! (-> (scratchpad-object region-prim-area) exit-ray) arg1 arg2)
(dotimes (s5-1 (-> *level* length))
(let ((v1-17 (-> *level* level s5-1)))
(when (= (-> v1-17 status) 'active)
(let ((s4-1 (-> v1-17 bsp region-trees)))
(when (nonzero? s4-1)
(let* ((s3-0 (-> s4-1 length))
(s2-0 0)
(a0-14 (-> s4-1 s2-0))
)
(while (< s2-0 s3-0)
(if (= (-> a0-14 name) arg0)
;; og:preserve-this
(collect-regions a0-14 (the-as sphere sv-32) 0 (-> (scratchpad-object region-prim-area) region-prim-list))
)
(+! s2-0 1)
(set! a0-14 (-> s4-1 s2-0))
)
)
)
)
)
)
)
;; og:preserve-this
(countdown (gp-1 (-> (scratchpad-object region-prim-area) region-prim-list num-items))
(track-region
(-> (scratchpad-object region-prim-area) region-prim-list items gp-1)
(the-as region-prim-area (-> (scratchpad-object region-prim-area) region-prim-list))
)
)
(let ((gp-2 (-> (scratchpad-object region-prim-area) region-enter-count)))
(while (begin (label cfg-22) (nonzero? gp-2))
(+! gp-2 -1)
(let* ((a2-5 (-> (scratchpad-object region-prim-area) region-enter-list gp-2))
(s5-2 (-> a2-5 on-enter))
)
(when s5-2
(countdown (v1-47 (-> (scratchpad-object region-prim-area) region-start-count))
(if (= a2-5 (-> (scratchpad-object region-prim-area) region-start-list v1-47))
(goto cfg-22)
)
)
(script-eval
s5-2
:key a2-5
:vector (-> (scratchpad-object region-prim-area) region-enter-prim-list gp-2 bsphere)
)
)
)
)
)
;; og:preserve-this
(let ((gp-3 (-> (scratchpad-object region-prim-area) region-exit-count)))
(while (begin (label cfg-31) (nonzero? gp-3))
(+! gp-3 -1)
(let* ((a2-6 (-> (scratchpad-object region-prim-area) region-exit-list gp-3))
(s5-3 (-> a2-6 on-exit))
)
(when s5-3
(countdown (v1-64 (-> (scratchpad-object region-prim-area) region-inside-count))
(if (= a2-6 (-> (scratchpad-object region-prim-area) region-inside-list v1-64))
(goto cfg-31)
)
)
(script-eval
s5-3
:key a2-6
:vector (-> (scratchpad-object region-prim-area) region-exit-prim-list gp-3 bsphere)
)
)
)
)
)
;; og:preserve-this
(countdown (gp-4 (-> (scratchpad-object region-prim-area) region-inside-count))
(let* ((a2-7 (-> (scratchpad-object region-prim-area) region-inside-list gp-4))
(s5-4 (-> a2-7 on-inside))
)
(if s5-4
(script-eval
s5-4
:key a2-7
:vector (-> (scratchpad-object region-prim-area) region-inside-prim-list gp-4 bsphere)
)
)
)
)
0
(none)
)
(defun region-execute ()
(set! (-> *level* camera-pos 1 quad) (-> *level* camera-pos 0 quad))
(set! (-> *level* camera-pos 0 quad) (-> (camera-pos) quad))
(set! (-> *level* target-pos 1 quad) (-> *level* target-pos 0 quad))
(set! (-> *level* target-pos 0 quad) (-> (target-pos 0) quad))
(when (and *execute-regions* (-> *setting-control* user-current region-mode) (not (paused?)))
(region-tree-execute 'camera (-> *level* camera-pos 1) (the-as vector (-> *level* camera-pos)))
(region-tree-execute 'target (-> *level* target-pos 1) (the-as vector (-> *level* target-pos)))
)
0
(none)
)
;; WARN: Return type mismatch int vs drawable-region-prim.
(defun region-prim-lookup-by-id ((arg0 int) (arg1 symbol) (arg2 int))
(let ((v1-0 -1))
(dotimes (a3-0 (-> *level* length))
(let ((t0-3 (-> *level* level a3-0)))
(when (= (-> t0-3 status) 'active)
(when (nonzero? (-> t0-3 bsp region-trees))
(let* ((t1-8 (-> t0-3 bsp region-trees length))
(t2-1 0)
(t3-2 (-> t0-3 bsp region-trees t2-1))
)
(while (< t2-1 t1-8)
(when (or (not arg1) (= (-> t3-2 name) arg1))
(let* ((t4-10 (-> t3-2 data2 (+ (-> t3-2 length) -1) length))
(t5-0 0)
(t6-2 (the-as object (+ (+ (* t5-0 32) 32) (the-as int (-> t3-2 data2 (+ (-> t3-2 length) -1))))))
)
(while (< t5-0 t4-10)
(when (= (-> (the-as drawable-region-prim t6-2) region id) arg0)
(+! v1-0 1)
(if (= v1-0 arg2)
(return (the-as drawable-region-prim t6-2))
)
)
(+! t5-0 1)
(set! t6-2 (+ (+ (* t5-0 32) 32) (the-as int (-> t3-2 data2 (+ (-> t3-2 length) -1)))))
)
)
)
(+! t2-1 1)
(set! t3-2 (-> t0-3 bsp region-trees t2-1))
)
)
)
)
)
)
)
(the-as drawable-region-prim #f)
)
(defun region-lookup-by-id ((arg0 int))
(dotimes (v1-0 (-> *level* length))
(let ((a1-3 (-> *level* level v1-0)))
(when (= (-> a1-3 status) 'active)
(when (nonzero? (-> a1-3 bsp region-array))
(let* ((a2-8 (-> a1-3 bsp region-array length))
(a3-1 0)
(t0-2 (-> a1-3 bsp region-array data a3-1))
)
(while (< a3-1 a2-8)
(if (= (-> t0-2 id) arg0)
(return t0-2)
)
(+! a3-1 1)
(set! t0-2 (-> a1-3 bsp region-array data a3-1))
)
)
)
)
)
)
(the-as region #f)
)