mirror of
https://github.com/open-goal/jak-project.git
synced 2024-10-20 21:27:52 -04:00
b2052016e2
* time of day * goal code seems to work * stars at wrong spot * stars and sun work * debugging clouds * fix texture correction * sky works * cleanup, add profiler * clean up * final clean up * offline tests * missing include
792 lines
23 KiB
Common Lisp
792 lines
23 KiB
Common Lisp
;;-*-Lisp-*-
|
|
(in-package goal)
|
|
|
|
;; name: sparticle.gc
|
|
;; name in dgo: sparticle
|
|
;; dgos: GAME, ENGINE
|
|
|
|
|
|
;; This file contains the interface between sparticle and sprite as well as the actual particle updates.
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; basic methods
|
|
;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
(defmethod print sparticle-cpuinfo ((obj sparticle-cpuinfo))
|
|
(format #t "<sparticle-cpuinfo>~%")
|
|
(dotimes (s5-0 16)
|
|
(format #t "~D:~F~%" s5-0 (the-as float (-> obj data s5-0)))
|
|
)
|
|
(format #t "TIMER:~D~%" (-> obj timer))
|
|
(the-as sparticle-cpuinfo (format #t "FLAGS:~X~%" (-> obj flags)))
|
|
)
|
|
|
|
(defun sp-particle-copy! ((arg0 sparticle-cpuinfo) (arg1 sparticle-cpuinfo))
|
|
"copy some of the particle state."
|
|
(let ((v1-1 (-> arg1 sprite x-y-z-sx quad)))
|
|
(set! (-> arg0 sprite x-y-z-sx quad) v1-1)
|
|
)
|
|
(let ((v1-3 (-> arg1 sprite flag-rot-sy quad)))
|
|
(set! (-> arg0 sprite flag-rot-sy quad) v1-3)
|
|
)
|
|
(let ((v1-5 (-> arg1 sprite color quad)))
|
|
(set! (-> arg0 sprite color quad) v1-5)
|
|
)
|
|
(dotimes (v1-6 10)
|
|
(set! (-> arg0 adgif prims v1-6) (-> arg1 adgif prims v1-6))
|
|
)
|
|
(set! (-> arg0 vel-sxvel quad) (-> arg1 vel-sxvel quad))
|
|
(set! (-> arg0 rot-syvel quad) (-> arg1 rot-syvel quad))
|
|
(set! (-> arg0 fade quad) (-> arg1 fade quad))
|
|
(set! (-> arg0 acc quad) (-> arg1 acc quad))
|
|
(set! (-> arg0 friction) (-> arg1 friction))
|
|
(set! (-> arg0 timer) (-> arg1 timer))
|
|
(set! (-> arg0 flags) (-> arg1 flags))
|
|
(set! (-> arg0 user-float) (-> arg1 user-float))
|
|
(set! (-> arg0 func) (-> arg1 func))
|
|
(none)
|
|
)
|
|
|
|
(defmethod new sparticle-system
|
|
((allocation symbol)
|
|
(type-to-make type)
|
|
(arg0 int)
|
|
(arg1 int)
|
|
(arg2 symbol)
|
|
(arg3 pointer)
|
|
(arg4 (inline-array adgif-shader))
|
|
)
|
|
"allocate a particle system.
|
|
arg0: number of group0's
|
|
arg1: number of group1's
|
|
arg2: is 3d?
|
|
arg3: pointer to sprite allocations
|
|
arg4: pointer to adgif allocation"
|
|
(let ((gp-0 (object-new allocation type-to-make (the-as int (-> type-to-make size)))))
|
|
(let* ((v1-3 (/ (+ arg0 63) 64)) ;; num blocks
|
|
(a0-2 (/ (+ arg1 63) 64))
|
|
(a1-2 (* v1-3 64)) ;; length
|
|
(a2-2 (* a0-2 64))
|
|
(s2-1 (+ v1-3 a0-2)) ;; total blocks
|
|
(s5-1 (+ a1-2 a2-2)) ;; total length
|
|
)
|
|
(set! (-> gp-0 blocks 0) v1-3)
|
|
(set! (-> gp-0 length 0) a1-2)
|
|
(set! (-> gp-0 num-alloc 0) 0)
|
|
(set! (-> gp-0 blocks 1) a0-2)
|
|
(set! (-> gp-0 length 1) a2-2)
|
|
(set! (-> gp-0 num-alloc 1) 0)
|
|
(set! (-> gp-0 is-3d) arg2)
|
|
;; per block
|
|
(set! (-> gp-0 alloc-table) (the-as (pointer uint64) (malloc 'global (* s2-1 8))))
|
|
;; per particle
|
|
(set! (-> gp-0 cpuinfo-table) (the-as (inline-array sparticle-cpuinfo) (malloc 'global (* 144 s5-1))))
|
|
;; sprite data
|
|
(set! (-> gp-0 vecdata-table) arg3)
|
|
;; adgifs
|
|
(set! (-> gp-0 adgifdata-table) arg4)
|
|
(dotimes (v1-5 s2-1)
|
|
(set! (-> gp-0 alloc-table v1-5) (the-as uint -1))
|
|
)
|
|
(dotimes (s4-1 s5-1)
|
|
(set! (-> gp-0 cpuinfo-table s4-1 valid) #f)
|
|
;; link cpuinfos to sprite data
|
|
(set! (-> gp-0 cpuinfo-table s4-1 sprite)
|
|
(the-as sprite-vec-data-2d (&+ (-> gp-0 vecdata-table) (* 48 s4-1)))
|
|
)
|
|
;; and to adgif
|
|
(set! (-> gp-0 cpuinfo-table s4-1 adgif) (-> gp-0 adgifdata-table s4-1))
|
|
;; default init adgifs.
|
|
(adgif-shader<-texture-simple!
|
|
(-> gp-0 adgifdata-table s4-1)
|
|
(the-as texture #f)
|
|
)
|
|
(set! (-> gp-0 adgifdata-table s4-1 alpha)
|
|
(new 'static 'gs-miptbp :tbp1 #x48)
|
|
)
|
|
)
|
|
)
|
|
gp-0
|
|
)
|
|
)
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;
|
|
;; particle systems
|
|
;;;;;;;;;;;;;;;;;;;;
|
|
|
|
;; note: these constants must match the sizes of the sprite arrays.
|
|
|
|
(define *sp-particle-system-2d*
|
|
(new 'global 'sparticle-system 1920 128 #f (-> *sprite-array-2d* vec-data) (-> *sprite-array-2d* adgif-data))
|
|
)
|
|
|
|
(define *sp-particle-system-3d*
|
|
(new 'global 'sparticle-system 256 0 #t (-> *sprite-array-3d* vec-data) (-> *sprite-array-3d* adgif-data))
|
|
)
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;
|
|
;; alloc and block
|
|
;;;;;;;;;;;;;;;;;;;;
|
|
|
|
(defun sp-get-block-size ((arg0 sparticle-system) (arg1 int))
|
|
"get the index of the highest used block for the given group (0 or 1)"
|
|
(let ((v0-0 0))
|
|
(let ((v1-0 0)
|
|
(a2-0 (-> arg0 blocks 0))
|
|
)
|
|
(when (= arg1 1)
|
|
(set! v1-0 a2-0)
|
|
(set! a2-0 (-> arg0 blocks 1))
|
|
)
|
|
(dotimes (a1-3 a2-0)
|
|
(if (!= (-> arg0 alloc-table (+ v1-0 a1-3)) -1)
|
|
(set! v0-0 (+ a1-3 1))
|
|
)
|
|
)
|
|
)
|
|
v0-0
|
|
)
|
|
)
|
|
|
|
(defun sp-get-approx-alloc-size ((arg0 sparticle-system) (arg1 int))
|
|
"get approximately the amount of sprite memory used."
|
|
;; this is just (* 64 (sp-get-block-size arg0 arg1))
|
|
(let ((a3-0 arg1)
|
|
(v1-0 0)
|
|
)
|
|
(let ((a1-1 0)
|
|
(a2-0 (-> arg0 blocks 0))
|
|
)
|
|
(when (= a3-0 1)
|
|
(set! a1-1 a2-0)
|
|
(set! a2-0 (-> arg0 blocks 1))
|
|
)
|
|
(dotimes (a3-3 a2-0)
|
|
(if (!= (-> arg0 alloc-table (+ a1-1 a3-3)) -1)
|
|
(set! v1-0 (+ a3-3 1))
|
|
)
|
|
)
|
|
)
|
|
(* v1-0 64)
|
|
)
|
|
)
|
|
|
|
(defun sp-free-particle ((arg0 sparticle-system) (arg1 int) (arg2 sparticle-cpuinfo) (arg3 sprite-vec-data-2d))
|
|
"free a particle"
|
|
|
|
;; clear flags on our launch state.
|
|
(if (and (-> arg2 binding) (nonzero? (-> arg2 binding)))
|
|
(logclear! (-> arg2 binding flags)
|
|
(sp-launch-state-flags launcher-active particles-active)
|
|
)
|
|
)
|
|
|
|
;; clear the bit indicating that we're alive.
|
|
(let ((v1-6 (/ arg1 64))
|
|
(t0-4 (logand arg1 63))
|
|
)
|
|
(logior! (-> arg0 alloc-table v1-6) (ash 1 t0-4))
|
|
)
|
|
|
|
;; decrease alloc count for the appropriate group
|
|
(if (< arg1 (-> arg0 length 0))
|
|
(+! (-> arg0 num-alloc 0) -1)
|
|
(+! (-> arg0 num-alloc 1) -1)
|
|
)
|
|
(set! (-> arg2 valid) #f)
|
|
(set! (-> arg3 a) 0.0)
|
|
0
|
|
(none)
|
|
)
|
|
|
|
(defun sp-get-particle ((arg0 sparticle-system) (arg1 int) (arg2 sparticle-launch-state))
|
|
"alloc a particle"
|
|
(local-vars
|
|
(a2-3 int)
|
|
(a2-4 int)
|
|
(a2-5 int)
|
|
(a2-6 int)
|
|
(a2-7 int)
|
|
(a2-8 int)
|
|
(t1-16 int)
|
|
(t1-17 int)
|
|
(t1-18 int)
|
|
(t1-19 int)
|
|
(t1-20 int)
|
|
(t3-5 int)
|
|
)
|
|
(let ((v1-0 0)
|
|
(t0-0 (-> arg0 blocks 0))
|
|
(a3-0 0)
|
|
)
|
|
(when (= arg1 1)
|
|
(set! v1-0 t0-0)
|
|
(set! t0-0 (-> arg0 blocks 1))
|
|
)
|
|
|
|
;; this adds a moving offset to the allocation system. I'm not sure why.
|
|
(when arg2
|
|
(set! a3-0 (the-as int (-> arg2 randomize)))
|
|
(+! (-> arg2 randomize) 1)
|
|
(when (= (-> arg2 randomize) t0-0)
|
|
(set! (-> arg2 randomize) (the-as uint 0))
|
|
0
|
|
)
|
|
)
|
|
|
|
;; find the earliest free.
|
|
(dotimes (a2-1 t0-0)
|
|
(when (nonzero? (-> arg0 alloc-table (+ v1-0 a3-0)))
|
|
(let ((a2-2 0)
|
|
(t1-15 (-> arg0 alloc-table (+ v1-0 a3-0)))
|
|
(t0-4 (* (+ v1-0 a3-0) 64))
|
|
)
|
|
0
|
|
0
|
|
(let ((t2-4 (shl t1-15 32))
|
|
(t3-0 (+ a2-2 32))
|
|
)
|
|
(.movn t1-16 t2-4 t2-4 t1-15)
|
|
(.movz a2-3 t3-0 t2-4 a2-2)
|
|
)
|
|
(let ((t2-5 (shl t1-16 16))
|
|
(t3-1 (+ a2-3 16))
|
|
)
|
|
(.movn t1-17 t2-5 t2-5 t1-16)
|
|
(.movz a2-4 t3-1 t2-5 a2-3)
|
|
)
|
|
(let ((t2-6 (* t1-17 256))
|
|
(t3-2 (+ a2-4 8))
|
|
)
|
|
(.movn t1-18 t2-6 t2-6 t1-17)
|
|
(.movz a2-5 t3-2 t2-6 a2-4)
|
|
)
|
|
(let ((t2-7 (* t1-18 16))
|
|
(t3-3 (+ a2-5 4))
|
|
)
|
|
(.movn t1-19 t2-7 t2-7 t1-18)
|
|
(.movz a2-6 t3-3 t2-7 a2-5)
|
|
)
|
|
(let ((t2-8 (* t1-19 4))
|
|
(t3-4 (+ a2-6 2))
|
|
)
|
|
(.movn t1-20 t2-8 t2-8 t1-19)
|
|
(.movz a2-7 t3-4 t2-8 a2-6)
|
|
(let ((t1-21 (* t1-20 2))
|
|
(t2-9 (+ a2-7 1))
|
|
)
|
|
(.movn t3-5 t1-21 t1-21 t3-4)
|
|
(.movz a2-8 t2-9 t1-21 a2-7)
|
|
)
|
|
)
|
|
;; mark as allocated
|
|
(let ((t0-5 (+ t0-4 a2-8)))
|
|
(set! (-> arg0 alloc-table (+ v1-0 a3-0))
|
|
(logxor (-> arg0 alloc-table (+ v1-0 a3-0)) (the-as uint (ash 1 a2-8)))
|
|
)
|
|
;; update group's alloc count
|
|
(+! (-> arg0 num-alloc arg1) 1)
|
|
;; return it!
|
|
(let ((v1-9 (-> arg0 cpuinfo-table t0-5)))
|
|
(set! (-> v1-9 valid) #t)
|
|
(return v1-9)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
(+! a3-0 1)
|
|
(when (= a3-0 t0-0)
|
|
;; wrap
|
|
(set! a3-0 0)
|
|
)
|
|
)
|
|
)
|
|
|
|
(the-as sparticle-cpuinfo #f)
|
|
)
|
|
|
|
(defun sp-kill-particle ((arg0 sparticle-system) (arg1 sparticle-cpuinfo))
|
|
"kill the given particle"
|
|
(cond
|
|
;; modified to check the end of the spad too.
|
|
((in-scratchpad? arg1) ;;(>= (the-as int arg1) #x70000000) ;; TODO PC port
|
|
;; if in the sratchpad, just set the timer to 0.
|
|
(set! (-> arg1 timer) 0)
|
|
0
|
|
)
|
|
(else
|
|
(let ((a2-1 (/ (the-as int (- (the-as uint arg1) (the-as uint (-> arg0 cpuinfo-table 0)))) 144)))
|
|
(when (or (< a2-1 0) (>= a2-1 (+ (-> arg0 length 0) (-> arg0 length 1))))
|
|
;; invalid location for particle, error
|
|
(format 0 "Tried to release particle ~D~%" a2-1)
|
|
(return #f)
|
|
)
|
|
;; free it.
|
|
(sp-free-particle arg0 a2-1 arg1 (-> arg1 sprite))
|
|
)
|
|
)
|
|
)
|
|
#t
|
|
(none)
|
|
)
|
|
|
|
|
|
;;;;;;;;;;;;;;;;
|
|
;; effects
|
|
;;;;;;;;;;;;;;;;
|
|
|
|
(defun sp-orbiter ((arg0 sparticle-system) (arg1 sparticle-cpuinfo) (arg2 vector))
|
|
(let* ((f2-0 (-> arg1 omega))
|
|
(f0-0 (-> arg1 radius))
|
|
(f4-0 (-> arg1 vel-sxvel x))
|
|
(f24-0 (-> arg1 vel-sxvel y))
|
|
(f1-0 (-> arg1 vel-sxvel z))
|
|
(f3-0 (-> *sp-frame-time* y))
|
|
(f28-0 (+ f2-0 (* f4-0 f3-0)))
|
|
)
|
|
(set! (-> arg1 omega) f28-0)
|
|
(let ((f30-0 (+ f0-0 (* f1-0 f3-0))))
|
|
(set! (-> arg1 radius) f30-0)
|
|
(let ((f26-0 (sin f28-0))
|
|
(f28-1 (cos f28-0))
|
|
(f22-0 (sin (* 0.5 f24-0)))
|
|
(f0-5 (cos (* 0.5 f24-0)))
|
|
(a1-1 (new 'stack-no-clear 'vector))
|
|
(s4-0 (new 'stack-no-clear 'vector))
|
|
)
|
|
(let ((s3-0 (new 'stack-no-clear 'matrix)))
|
|
(set-vector! a1-1 (* f22-0 f28-1) 0.0 (* f22-0 f26-0) f0-5)
|
|
(quaternion*!
|
|
(-> arg1 rotvel3d)
|
|
(the-as quaternion a1-1)
|
|
(-> arg1 rotvel3d)
|
|
)
|
|
(quaternion-normalize! (-> arg1 rotvel3d))
|
|
(set-vector! s4-0 (* f26-0 f30-0) 0.0 (* f28-1 f30-0) 1.0)
|
|
(quaternion->matrix s3-0 (-> arg1 rotvel3d))
|
|
(vector-matrix*! s4-0 s4-0 s3-0)
|
|
)
|
|
(let ((v1-3 (the-as object (-> arg1 user-float))))
|
|
(set! (-> arg2 x) (+ (-> s4-0 x) (-> (the-as sprite-vec-data-2d v1-3) x)))
|
|
(set! (-> arg2 y) (+ (-> s4-0 y) (-> (the-as sprite-vec-data-2d v1-3) y)))
|
|
(set! (-> arg2 z) (+ (-> s4-0 z) (-> (the-as sprite-vec-data-2d v1-3) z)))
|
|
)
|
|
)
|
|
)
|
|
)
|
|
0
|
|
(none)
|
|
)
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;
|
|
;; particle update
|
|
;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
;; TODO sp-process-block-2d
|
|
;; TODO sp-process-block-3d
|
|
(define-extern sp-process-block-3d (function sparticle-system int int int int symbol none))
|
|
(set! sp-process-block-3d (the (function sparticle-system int int int int symbol none)
|
|
(__pc-get-mips2c "sp-process-block-3d")))
|
|
(define-extern sp-process-block-2d (function sparticle-system int int int int symbol none))
|
|
(set! sp-process-block-2d (the (function sparticle-system int int int int symbol none)
|
|
(__pc-get-mips2c "sp-process-block-2d")))
|
|
|
|
|
|
(defun sp-copy-to-spr ((arg0 int) (arg1 pointer) (arg2 int))
|
|
;; modified to use fake spad
|
|
(let ((a2-1 (/ (+ arg2 15) 16)))
|
|
(__mem-move (&+ (scratchpad-start) arg0) arg1 (the uint (* a2-1 16)))
|
|
;; (dma-send-to-spr-no-flush (the-as uint arg0) (the-as uint arg1) (the-as uint a2-1) #t)
|
|
)
|
|
0
|
|
(none)
|
|
)
|
|
|
|
(defun sp-copy-from-spr ((arg0 int) (arg1 pointer) (arg2 int))
|
|
;; modified to use fake spad.
|
|
(let ((a2-1 (/ (+ arg2 15) 16)))
|
|
(__mem-move arg1 (&+ (scratchpad-start) arg0) (the uint (* a2-1 16)))
|
|
;;(dma-send-from-spr-no-flush (the-as uint arg1) (the-as uint arg0) (the-as uint a2-1) #t)
|
|
)
|
|
0
|
|
(none)
|
|
)
|
|
|
|
;; TODO memcpy (unused)
|
|
|
|
(defun sp-process-block ((arg0 sparticle-system) (arg1 int) (arg2 sprite-array-2d) (arg3 int))
|
|
"update the given block of particles"
|
|
(local-vars
|
|
(sv-16 int)
|
|
(sv-32 int)
|
|
(sv-80 int)
|
|
(sv-96 int)
|
|
)
|
|
(let ((s3-0 16)
|
|
(s2-0 (* 144 arg3))
|
|
(s5-0 (* 48 arg3))
|
|
)
|
|
(set! sv-32 (* 80 arg3))
|
|
(let ((s1-0 (+ s3-0 s2-0)))
|
|
(set! sv-16 (+ s1-0 s5-0))
|
|
(sp-copy-to-spr s3-0 (the-as pointer (-> arg0 cpuinfo-table arg1)) s2-0)
|
|
(sp-copy-to-spr s1-0 (&+ (-> arg0 vecdata-table) (* 48 arg1)) s5-0)
|
|
(let ((t9-2 sp-copy-to-spr)
|
|
(a1-7 (-> arg0 adgifdata-table arg1))
|
|
)
|
|
(t9-2 sv-16 (the-as pointer a1-7) sv-32)
|
|
)
|
|
|
|
;; alternate to run without doing scratchpad (will change behavior of kill, but at least works for hud)
|
|
; (set! sv-80 (the-as int (-> arg0 cpuinfo-table arg1)))
|
|
; (set! sv-96 (the-as int (&+ (-> arg0 vecdata-table) (* 48 arg1))))
|
|
(set! sv-80 (+ (the int (scratchpad-start)) s3-0)) ;; spad
|
|
(set! sv-96 (+ (the int (scratchpad-start)) s1-0)) ;; spad
|
|
(cond
|
|
((-> arg0 is-3d)
|
|
(sp-process-block-3d arg0 sv-80 sv-96 arg1 arg3 (paused?))
|
|
)
|
|
(else
|
|
(sp-process-block-2d arg0 sv-80 sv-96 arg1 arg3 (paused?))
|
|
)
|
|
)
|
|
(sp-copy-from-spr s3-0 (the-as pointer (-> arg0 cpuinfo-table arg1)) s2-0)
|
|
(sp-copy-from-spr s1-0 (&+ (-> arg0 vecdata-table) (* 48 arg1)) s5-0)
|
|
)
|
|
)
|
|
0
|
|
(none)
|
|
)
|
|
|
|
(defun sp-process-particle-system ((arg0 sparticle-system) (arg1 int) (arg2 sprite-array-2d))
|
|
"update an entire particle system."
|
|
(let* ((v1-0 16)
|
|
(s1-0 (/ (- #x4000 v1-0) 272)) ;; offset in spad of vecdata, max sprite data in spad
|
|
(s3-0 0) ;; mem offset
|
|
(s4-0 (sp-get-approx-alloc-size arg0 arg1)) ;; remaining size.
|
|
)
|
|
;; group 1 starts after group 0
|
|
(if (= arg1 1)
|
|
(set! s3-0 (* (-> arg0 blocks 0) 64))
|
|
)
|
|
(set! (-> arg2 num-valid arg1) s4-0)
|
|
;; flush before processing
|
|
(flush-cache 0)
|
|
(while (>= s4-0 s1-0) ;; there are full blocks remaining...
|
|
(sp-process-block arg0 s3-0 arg2 s1-0) ;; process it
|
|
(set! s4-0 (- s4-0 s1-0))
|
|
(+! s3-0 s1-0) ;; next data
|
|
)
|
|
;; if there's anything leftover, don't forget that.
|
|
(if (> s4-0 0)
|
|
(sp-process-block arg0 s3-0 arg2 s4-0)
|
|
)
|
|
)
|
|
0
|
|
(none)
|
|
)
|
|
|
|
(define-perm *particles-flag* symbol #t)
|
|
|
|
(defun forall-particles-with-key-runner ((arg0 sparticle-launch-control) (arg1 (function sparticle-system sparticle-cpuinfo none)) (arg2 sparticle-system))
|
|
"call the given function on all particles with the given key (arg0)"
|
|
(local-vars (sv-16 int))
|
|
(let ((s3-0 (the-as object (-> arg2 cpuinfo-table 0)))
|
|
(s2-0 (&+ (-> arg2 vecdata-table) 0))
|
|
(s1-0 (+ (-> arg2 blocks 0) (-> arg2 blocks 1)))
|
|
)
|
|
(dotimes (s0-0 s1-0) ;; loop over blocks
|
|
(cond
|
|
((!= (-> arg2 alloc-table s0-0) -1) ;; block has something allocated.
|
|
(set! sv-16 0)
|
|
(while (< sv-16 64)
|
|
(if (and (-> (the-as sparticle-cpuinfo s3-0) valid) ;; is allocated
|
|
(= (-> (the-as sparticle-cpuinfo s3-0) key) arg0) ;; matches the key
|
|
)
|
|
(arg1 arg2 (the-as sparticle-cpuinfo s3-0)) ;; run the callback!
|
|
)
|
|
(set! s3-0 (-> (the-as (inline-array sparticle-cpuinfo) s3-0) 1)) ;; next cpu
|
|
(&+! s2-0 48) ;; next vec
|
|
(set! sv-16 (+ sv-16 1)) ;; next idx in block
|
|
)
|
|
)
|
|
(else
|
|
;; skip the whole block!
|
|
(set! s3-0 (-> (the-as (inline-array sparticle-cpuinfo) s3-0) 64))
|
|
(&+! s2-0 3072)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
0
|
|
(none)
|
|
)
|
|
|
|
(defun forall-particles-with-key ((arg0 sparticle-launch-control) (arg1 (function sparticle-system sparticle-cpuinfo none)) (arg2 symbol) (arg3 symbol))
|
|
"call the given function on all particles with the given key. arg2 is 2d, arg3 is 3d."
|
|
(if arg2
|
|
(forall-particles-with-key-runner arg0 arg1 *sp-particle-system-2d*)
|
|
)
|
|
(if arg3
|
|
(forall-particles-with-key-runner arg0 arg1 *sp-particle-system-3d*)
|
|
)
|
|
0
|
|
(none)
|
|
)
|
|
|
|
|
|
(defun sparticle-kill-it ((arg0 sparticle-system) (arg1 sparticle-cpuinfo))
|
|
"kill a particle without freeing it."
|
|
(set! (-> arg1 timer) 0) ;; advance timer to zero
|
|
(set! (-> arg1 func) (the-as basic 0)) ;; don't let the callback run and save the timer
|
|
(when (and (-> arg1 binding) (nonzero? (-> arg1 binding)))
|
|
;; kill the launcher too.
|
|
(logclear! (-> arg1 binding flags)
|
|
(sp-launch-state-flags launcher-active particles-active)
|
|
)
|
|
;; and forget it, I guess it could be unloaded
|
|
(set! (-> arg1 binding) #f)
|
|
)
|
|
0
|
|
(none)
|
|
)
|
|
|
|
(defun sparticle-kill-it-level0 ((arg0 sparticle-system) (arg1 sparticle-cpuinfo))
|
|
"kill all particles belonging to level 0"
|
|
(if (logtest? (-> arg1 flags) (sp-cpuinfo-flag level0))
|
|
(sparticle-kill-it arg0 arg1)
|
|
)
|
|
0
|
|
(none)
|
|
)
|
|
|
|
(defun sparticle-kill-it-level1 ((arg0 sparticle-system) (arg1 sparticle-cpuinfo))
|
|
"kill all particles belonging to level 1."
|
|
(if (logtest? (-> arg1 flags) (sp-cpuinfo-flag level1))
|
|
(sparticle-kill-it arg0 arg1)
|
|
)
|
|
0
|
|
(none)
|
|
)
|
|
|
|
(defun sparticle-60-to-50 ((arg0 sparticle-system) (arg1 sparticle-cpuinfo) (arg2 pointer))
|
|
"convert from 60hz to 50hz particles"
|
|
(let ((gp-0 (-> arg1 rotvel3d))
|
|
(s5-0 (new 'stack-no-clear 'quaternion))
|
|
)
|
|
(vector-angle<-quaternion! (the-as vector s5-0) gp-0)
|
|
(set! (-> s5-0 w) (* 12516.455 (-> s5-0 w)))
|
|
(quaternion-vector-angle! gp-0 (the-as vector s5-0) (-> s5-0 w))
|
|
)
|
|
0
|
|
(none)
|
|
)
|
|
|
|
(defun sparticle-50-to-60 ((arg0 sparticle-system) (arg1 sparticle-cpuinfo) (arg2 pointer))
|
|
"convert from 50hz to 60hz particles"
|
|
(let ((gp-0 (-> arg1 rotvel3d))
|
|
(s5-0 (new 'stack-no-clear 'quaternion))
|
|
)
|
|
(vector-angle<-quaternion! (the-as vector s5-0) gp-0)
|
|
(set! (-> s5-0 w) (* 8691.982 (-> s5-0 w)))
|
|
(quaternion-vector-angle! gp-0 (the-as vector s5-0) (-> s5-0 w))
|
|
)
|
|
0
|
|
(none)
|
|
)
|
|
|
|
(defun kill-all-particles-with-key ((arg0 sparticle-launch-control))
|
|
(forall-particles-with-key arg0 sparticle-kill-it #t #t)
|
|
0
|
|
(none)
|
|
)
|
|
|
|
|
|
(defun forall-particles-runner ((arg0 (function sparticle-system sparticle-cpuinfo pointer none)) (arg1 sparticle-system))
|
|
"run function on all particles in the system."
|
|
(let ((s4-0 (the-as object (-> arg1 cpuinfo-table 0)))
|
|
(s3-0 (&+ (-> arg1 vecdata-table) 0))
|
|
(s2-0 (+ (-> arg1 blocks 0) (-> arg1 blocks 1)))
|
|
)
|
|
(dotimes (s1-0 s2-0)
|
|
(cond
|
|
((!= (-> arg1 alloc-table s1-0) -1)
|
|
(dotimes (s0-0 64)
|
|
(if (-> (the-as sparticle-cpuinfo s4-0) valid)
|
|
(arg0 arg1 (the-as sparticle-cpuinfo s4-0) s3-0)
|
|
)
|
|
(set! s4-0 (+ (the-as uint s4-0) 144))
|
|
(&+! s3-0 48)
|
|
)
|
|
)
|
|
(else
|
|
(set! s4-0 (&+ (the-as pointer s4-0) 9216))
|
|
(&+! s3-0 3072)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
0
|
|
(none)
|
|
)
|
|
|
|
(defun forall-particles ((arg0 function) (arg1 symbol) (arg2 symbol))
|
|
"run function on all particles. arg1 for 2d, arg2 for 3d."
|
|
(if arg1
|
|
(forall-particles-runner
|
|
(the-as (function sparticle-system sparticle-cpuinfo pointer none) arg0)
|
|
*sp-particle-system-2d*
|
|
)
|
|
)
|
|
(if arg2
|
|
(forall-particles-runner
|
|
(the-as (function sparticle-system sparticle-cpuinfo pointer none) arg0)
|
|
*sp-particle-system-3d*
|
|
)
|
|
)
|
|
0
|
|
(none)
|
|
)
|
|
|
|
(defun kill-all-particles-in-level ((arg0 level))
|
|
"kill all particles belonging to the given level."
|
|
(forall-particles (if (zero? (-> arg0 index))
|
|
sparticle-kill-it-level0
|
|
sparticle-kill-it-level1
|
|
)
|
|
#t
|
|
#t
|
|
)
|
|
0
|
|
)
|
|
|
|
(defun all-particles-50-to-60 ()
|
|
(forall-particles-runner sparticle-50-to-60 *sp-particle-system-3d*)
|
|
(none)
|
|
)
|
|
|
|
(defun all-particles-60-to-50 ()
|
|
(forall-particles-runner sparticle-60-to-50 *sp-particle-system-3d*)
|
|
(none)
|
|
)
|
|
|
|
(defun set-particle-frame-time ((arg0 int))
|
|
(cond
|
|
((= arg0 5)
|
|
(set-vector!
|
|
*sp-frame-time*
|
|
0.00000000000000000000000000000000000001175495
|
|
5.0
|
|
1.0
|
|
1.0
|
|
)
|
|
)
|
|
((= arg0 6)
|
|
(set-vector!
|
|
*sp-frame-time*
|
|
0.000000000000000000000000000000000000011754952
|
|
6.0
|
|
1.2
|
|
1.2
|
|
)
|
|
)
|
|
((= arg0 10)
|
|
(set-vector!
|
|
*sp-frame-time*
|
|
0.000000000000000000000000000000000000011754958
|
|
10.0
|
|
2.0
|
|
2.0
|
|
)
|
|
)
|
|
((= arg0 12)
|
|
(set-vector!
|
|
*sp-frame-time*
|
|
0.00000000000000000000000000000000000001175496
|
|
12.0
|
|
2.4
|
|
2.4
|
|
)
|
|
)
|
|
)
|
|
0
|
|
(none)
|
|
)
|
|
|
|
(defun process-particles ()
|
|
"main particle system update."
|
|
(local-vars (v1-29 int) (gp-0 int))
|
|
(when *particles-flag*
|
|
0
|
|
0
|
|
;;(.mfc0 gp-0 Count)
|
|
(set! *sp-launcher-lock* #t)
|
|
;; start a profile frame.
|
|
(if *debug-segment*
|
|
(add-frame
|
|
(-> *display* frames (-> *display* on-screen) frame profile-bar 0)
|
|
'draw
|
|
(new 'static 'rgba :r #x40 :b #x40 :a #x80)
|
|
)
|
|
)
|
|
|
|
;; update timer
|
|
(let ((v1-14 (logand (the-as int (-> *sp-frame-time* x)) 255)))
|
|
(set! *particle-300hz-timer* (+ *particle-300hz-timer* v1-14))
|
|
(cond
|
|
(*sp-60-hz*
|
|
;; this is such a hack, but we can never get 6 or 12 in 50hz mode
|
|
(when (or (= v1-14 6) (= v1-14 12))
|
|
(set! *sp-60-hz* #f)
|
|
(all-particles-60-to-50)
|
|
)
|
|
)
|
|
(else
|
|
;; also a hack
|
|
(when (or (= v1-14 5) (= v1-14 10))
|
|
(set! *sp-60-hz* #t)
|
|
(all-particles-50-to-60)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
|
|
;; process the particles
|
|
(clear-sprite-aux-list)
|
|
(sp-process-particle-system *sp-particle-system-2d* 0 *sprite-array-2d*)
|
|
(sp-process-particle-system *sp-particle-system-2d* 1 *sprite-array-2d*)
|
|
(sp-process-particle-system *sp-particle-system-3d* 0 (the-as sprite-array-2d *sprite-array-3d*))
|
|
(if *debug-segment*
|
|
(add-frame
|
|
(-> *display* frames (-> *display* on-screen) frame profile-bar 0)
|
|
'draw
|
|
(new 'static 'rgba :r #x80 :g #x80 :b #xff :a #x80)
|
|
)
|
|
)
|
|
(set! *sp-launcher-lock* #f)
|
|
|
|
;; launch queued particles
|
|
(sp-clear-queue)
|
|
;;(.mfc0 v1-29 Count)
|
|
(let ((a2-5 (- v1-29 gp-0)))
|
|
(if *display-sprite-info*
|
|
(format
|
|
*stdcon*
|
|
"Particle time = ~D cycles for ~D 2D [~D warp] and ~D HUD and ~D 3D~%"
|
|
1234 ;;a2-5
|
|
(-> *sp-particle-system-2d* num-alloc 0)
|
|
(-> *sprite-aux-list* entry)
|
|
(-> *sp-particle-system-2d* num-alloc 1)
|
|
(-> *sp-particle-system-3d* num-alloc 0)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
0
|
|
(none)
|
|
)
|