mirror of
https://github.com/open-goal/jak-project
synced 2026-08-10 19:17:55 -04:00
c162c66118
This PR does two main things: 1. Work through the main low-hanging fruit issues in the formatter keeping it from feeling mature and usable 2. Iterate and prove that point by formatting all of the Jak 1 code base. **This has removed around 100K lines in total.** - The decompiler will now format it's results for jak 1 to keep things from drifting back to where they were. This is controlled by a new config flag `format_code`. How am I confident this hasn't broken anything?: - I compiled the entire project and stored it's `out/jak1/obj` files separately - I then recompiled the project after formatting and wrote a script that md5's each file and compares it (`compare-compilation-outputs.py` - The results (eventually) were the same:  > This proves that the only difference before and after is non-critical whitespace for all code/macros that is actually in use. I'm still aware of improvements that could be made to the formatter, as well as general optimization of it's performance. But in general these are for rare or non-critical situations in my opinion and I'll work through them before doing Jak 2. The vast majority looks great and is working properly at this point. Those known issues are the following if you are curious: 
481 lines
20 KiB
Common Lisp
481 lines
20 KiB
Common Lisp
;;-*-Lisp-*-
|
|
(in-package goal)
|
|
(bundles "ENGINE.CGO" "GAME.CGO")
|
|
(require "engine/gfx/hw/display.gc")
|
|
(require "engine/gfx/sprite/sparticle/sparticle-launcher.gc")
|
|
|
|
;; This file contains the interface between sparticle and sprite as well as the actual particle updates.
|
|
|
|
;; DECOMP BEGINS
|
|
|
|
(defmethod print ((this sparticle-cpuinfo))
|
|
(format #t "<sparticle-cpuinfo>~%")
|
|
(dotimes (s5-0 16)
|
|
(format #t "~D:~F~%" s5-0 (the-as float (-> this data s5-0))))
|
|
(format #t "TIMER:~D~%" (-> this timer))
|
|
(the-as sparticle-cpuinfo (format #t "FLAGS:~X~%" (-> this flags))))
|
|
|
|
(defun sp-particle-copy! ((arg0 sparticle-cpuinfo) (arg1 sparticle-cpuinfo))
|
|
(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"
|
|
(#when PC_BIG_MEMORY
|
|
(*! arg0 SPRITE_MAX_AMOUNT_MULT)
|
|
; (*! arg1 SPRITE_MAX_AMOUNT_MULT)
|
|
)
|
|
(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 uint64 (bit per-sprite)
|
|
(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)
|
|
;; fill alloc-table with 1's
|
|
(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-alpha :b #x2 :d #x1))))
|
|
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"
|
|
;; og:preserve-this
|
|
;; pc port note : this function originally attempted to find a free sparticle by picking a "random"
|
|
;; (actually incremental) starting block and going from there. we disable that completely for pc
|
|
;; because it is actually detrimental since we may alloc sparticles spread over way too many blocks
|
|
;; which can have a negative impact on our performance.
|
|
(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)))
|
|
(dotimes (blk t0-0)
|
|
(when (nonzero? (-> arg0 alloc-table (+ v1-0 a3-0)))
|
|
(dotimes (bit 64)
|
|
(when (nonzero? (logand (ash 1 bit) (-> arg0 alloc-table (+ v1-0 a3-0))))
|
|
(logxor! (-> arg0 alloc-table (+ v1-0 a3-0)) (ash 1 bit))
|
|
(+! (-> arg0 num-alloc arg1) 1)
|
|
(let ((v1-9 (-> arg0 cpuinfo-table (+ bit (* (+ v1-0 a3-0) 64))))) (set! (-> v1-9 valid) #t) (return v1-9)))))
|
|
(+! a3-0 1)
|
|
(if (= a3-0 t0-0) (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
|
|
;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
(def-mips2c sp-process-block-2d (function sparticle-system int int int int symbol none))
|
|
|
|
(def-mips2c sp-process-block-3d (function sparticle-system int int int int symbol none))
|
|
|
|
(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 ((scaled-seconds int))
|
|
"Adjusts particle frame time based on the frame-rate (scaled-seconds). Note: This used to be a case statement and has been rewritten as a more generic formula"
|
|
(set-vector! *sp-frame-time*
|
|
(the-as float (logior #x800000 scaled-seconds))
|
|
(the float scaled-seconds)
|
|
(* 0.2 scaled-seconds)
|
|
(* 0.2 scaled-seconds))
|
|
(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* (when (or (= v1-14 6) (= v1-14 12)) (set! *sp-60-hz* #f) (all-particles-60-to-50)))
|
|
(else (when (or (= v1-14 5) (= v1-14 10)) (set! *sp-60-hz* #t) (all-particles-50-to-60)))))
|
|
;; process the particles
|
|
;; og:preserve-this made this not run when paused, since aux sprites wont get added.
|
|
(unless (paused?)
|
|
(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~%"
|
|
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))
|