Files
ManDude 0212aa10c9 [decomp] better handling of animation code and art files (#1352)
* update refs

* [decompiler] read and process art groups

* finish decompiler art group selection & detect in `ja-group?`

* make art stuff work on offline tests!

* [decompiler] detect `ja-group!` (primitive)

* corrections.

* more

* use new feature on skel groups!

* find `loop!` as well

* fully fledged `ja` macro & decomp + `loop` detect

* fancy fixed point printing!

* update source

* `:num! max` (i knew i should've done this)

* Update jak1_ntsc_black_label.jsonc

* hi imports

* make compiling the game work

* fix `defskelgroup`

* clang

* update refs

* fix chan

* fix seek and finalboss

* fix tests

* delete unused function

* track let rewrite stats

* reorder `rewrite_let`

* Update .gitattributes

* fix bug with `:num! max`

* Update robotboss-part.gc

* Update goal-lib.gc

* document `ja`

* get rid of pc fixes thing

* use std::abs
2022-05-20 02:30:14 +01:00

1380 lines
49 KiB
Common Lisp

;;-*-Lisp-*-
(in-package goal)
;; name: process-drawable.gc
;; name in dgo: process-drawable
;; dgos: GAME, ENGINE
;; DECOMP BEGINS
(defun cspace-by-name ((arg0 process-drawable) (arg1 string))
(let* ((s4-0 (-> arg0 node-list length))
(s3-0 0)
(s2-0 (-> arg0 node-list data s3-0))
)
(while (< s3-0 s4-0)
(if (and (-> s2-0 joint) (name= (-> s2-0 joint name) arg1))
(return s2-0)
)
(+! s3-0 1)
(set! s2-0 (-> arg0 node-list data s3-0))
)
)
(the-as cspace #f)
)
(defun cspace-index-by-name ((arg0 process-drawable) (arg1 string))
(let* ((s4-0 0)
(s3-0 (-> arg0 node-list length))
(s2-0 0)
(v1-3 (-> arg0 node-list data s2-0))
)
(while (< s2-0 s3-0)
(if (and (-> v1-3 joint) (name= (-> v1-3 joint name) arg1))
(return s4-0)
)
(+! s4-0 1)
(+! s2-0 1)
(set! v1-3 (-> arg0 node-list data s2-0))
)
)
-1
)
(defun vector<-cspace! ((arg0 vector) (arg1 cspace))
(rlet ((Q :class vf)
(vf0 :class vf)
(vf2 :class vf)
)
(init-vf0-vector)
(.lvf vf2 (&-> (-> arg1 bone) transform vector 3 quad))
(.div.vf Q vf0 vf2 :fsf #b11 :ftf #b11)
;; ADDED
;; there's a bug in swamp-blimp where they vector<-cspace!
;; on some default-initialized-to-zero bones
;; we have to return 0s for this to avoid NaNs getting everywhere.
(let ((temp (new-stack-vector0)))
(.svf (&-> temp quad) vf2)
(when (= (-> temp w) 0.0)
(set-vector! arg0 0. 0. 0. 1.)
(return arg0)
)
)
(.wait.vf)
(.mul.vf vf2 vf2 Q :mask #b111)
(.nop.vf)
(.nop.vf)
(.mov.vf vf2 vf0 :mask #b1000)
(.svf (&-> arg0 quad) vf2)
arg0
)
)
(defun vector<-cspace+vector! ((arg0 vector) (arg1 cspace) (arg2 vector))
(vector-matrix*! arg0 arg2 (-> arg1 bone transform))
)
(defun-debug cspace-children ((arg0 process-drawable) (arg1 int))
(let ((a3-0 '()))
(countdown (s4-0 (-> arg0 node-list length))
(if (= (-> arg0 node-list data s4-0 parent) arg1)
(set! a3-0 (cons (-> arg0 node-list data s4-0) a3-0))
)
)
a3-0
)
)
;; ERROR: function was not converted to expressions. Cannot decompile.
(defmethod new draw-control ((allocation symbol) (type-to-make type) (arg0 process) (arg1 art-joint-geo))
(let ((v0-0 (object-new allocation type-to-make (the-as int (-> type-to-make size)))))
(set! (-> v0-0 jgeo) arg1)
(set! (-> v0-0 process) arg0)
v0-0
)
)
(defmethod lod-set! draw-control ((obj draw-control) (arg0 int))
(let ((v1-1 (max 0 (min arg0 (-> obj lod-set max-lod)))))
(set! (-> obj desired-lod) v1-1)
(when (!= (-> obj cur-lod) v1-1)
(set! (-> obj mgeo) (-> obj lod-set lod v1-1 geo))
(set! (-> obj cur-lod) v1-1)
)
)
0
(none)
)
(defmethod lods-assign! draw-control ((obj draw-control) (arg0 lod-set))
(mem-copy! (the-as pointer (-> obj lod-set)) (the-as pointer arg0) 33)
(let ((a1-2 (min (-> obj cur-lod) (-> obj lod-set max-lod))))
(set! (-> obj cur-lod) -1)
(lod-set! obj a1-2)
)
0
(none)
)
(defmethod setup-lods! lod-set ((obj lod-set) (arg0 skeleton-group) (arg1 art-group) (arg2 entity))
(local-vars (sv-16 res-tag))
(let ((s4-0 arg0)
(s5-0 arg1)
)
(let ((v1-0 (-> s5-0 length))
(s3-0 (-> s4-0 max-lod))
)
(set! (-> obj max-lod) s3-0)
(dotimes (a0-1 (+ s3-0 1))
(when (or (>= (-> s4-0 mgeo a0-1) v1-0) (begin
(set! arg0 (the-as skeleton-group (-> s5-0 data (-> s4-0 mgeo a0-1))))
(!= (-> (the-as art-element arg0) type) merc-ctrl)
)
)
(set! obj (the-as lod-set #f))
(goto cfg-16)
)
(set! (-> obj lod a0-1 geo) (the-as merc-ctrl arg0))
(set! (-> obj lod a0-1 dist) (-> s4-0 lod-dist a0-1))
)
(if (= (-> obj lod s3-0 dist) 4095996000.0)
(set! (-> obj lod s3-0 dist) (res-lump-float arg2 'vis-dist :default 4095996000.0))
)
)
(let ((v1-13 (-> s5-0 data (-> s4-0 jgeo))))
(set! sv-16 (new 'static 'res-tag))
(let ((v1-14 (res-lump-data (-> v1-13 extra) 'lod-dist pointer :tag-ptr (& sv-16))))
(when v1-14
(dotimes (a0-6 (the-as int (-> sv-16 elt-count)))
(set! (-> obj lod a0-6 dist) (-> (the-as (pointer float) (&+ v1-14 (* a0-6 4)))))
)
)
)
)
)
(label cfg-16)
obj
)
(define *default-skel-template* '((align root #f) (prejoint root cspace<-parented-matrix-joint!)))
(defbehavior make-nodes-from-jg process-drawable ((arg0 art-joint-geo) (arg1 pair) (arg2 symbol))
(let ((gp-0 ((method-of-type cspace-array new) arg2 cspace-array (+ (-> arg0 length) 1))))
(let ((v0-1 ((method-of-type skeleton new) arg2 skeleton (+ (-> arg0 length) 1))))
(set! (-> self draw skeleton) v0-1)
(let ((s4-1 v0-1))
(when (or (zero? gp-0) (zero? s4-1))
(go process-drawable-art-error "memory")
(set! gp-0 (the-as cspace-array #f))
(goto cfg-16)
)
(let ((v1-10 ((method-of-type cspace dummy-9) (the-as cspace (-> gp-0 data)) #f)))
(set! (-> v1-10 bone) (the-as bone (-> s4-1 bones)))
(let ((a0-6 (-> gp-0 data)))
(set! (-> a0-6 0 param0) cspace<-transformq!)
(set! (-> a0-6 0 param1) (the-as basic (-> self root trans)))
)
(set! (-> v1-10 bone cache bone-matrix) (the-as uint 0))
)
0
(let ((v1-14 (dummy-9 (-> gp-0 data 1) #f)))
(set! (-> v1-14 joint) (-> arg0 data 0))
(set! (-> v1-14 bone) (-> s4-1 bones 1))
(set! (-> v1-14 parent) (the-as cspace (-> gp-0 data)))
(set! (-> v1-14 bone cache bone-matrix) (the-as uint 128))
)
(let ((v1-17 (dummy-9 (-> gp-0 data 2) #f)))
(set! (-> v1-17 joint) (-> arg0 data 1))
(set! (-> v1-17 bone) (-> s4-1 bones 2))
(set! (-> v1-17 parent) (the-as cspace (-> gp-0 data)))
(let ((a1-9 v1-17))
(set! (-> a1-9 param0) cspace<-parented-matrix-joint!)
(set! (-> a1-9 param1) self)
)
(set! (-> v1-17 bone cache bone-matrix) (the-as uint 256))
)
(let ((s3-0 3))
(while (< s3-0 (-> gp-0 length))
(let* ((s1-0 (-> arg0 data (+ s3-0 -1)))
(s2-0 (if (-> s1-0 parent)
(+ (-> s1-0 parent number) 1)
0
)
)
(v1-29 (dummy-9 (-> gp-0 data s3-0) #f))
)
(set! (-> v1-29 joint) s1-0)
(set! (-> v1-29 bone) (-> s4-1 bones s3-0))
(set! (-> v1-29 parent) (-> gp-0 data s2-0))
(set! (-> v1-29 bone cache bone-matrix) (the-as uint (* s3-0 128)))
(set! (-> v1-29 bone cache parent-matrix) (the-as uint (* s2-0 128)))
)
(+! s3-0 1)
)
)
)
)
(add-connection
(-> (if (-> self entity)
(-> self entity extra level)
(-> *level* level-default)
)
foreground-draw-engine
(-> self draw sink-group merc-sink foreground-texture-page)
)
self
add-process-drawable
self
(-> self draw)
#f
)
(label cfg-16)
gp-0
)
)
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
;; WARN: Unsupported inline assembly instruction kind - [cache dxwbin a2, 0]
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
;; WARN: Unsupported inline assembly instruction kind - [cache dxwbin a2, 1]
;; WARN: Unsupported inline assembly instruction kind - [sync.l]
(defun fill-skeleton-cache ((arg0 process-drawable))
(let ((v1-0 (-> arg0 node-list))
(a0-2 (-> arg0 draw skeleton))
)
(dotimes (a1-0 (-> v1-0 length))
(let ((a3-0 (-> v1-0 data a1-0))
(a2-3 (the-as bone-cache (+ (the-as uint (the-as bone-cache (-> a0-2 bones 0 cache))) (* 96 a1-0))))
)
(set! (-> a2-3 bone-matrix) (the-as uint (* a1-0 128)))
(set! (-> a2-3 frame) (the-as uint 0))
(let ((t0-3 0))
(if (and (-> a3-0 parent) (-> a3-0 parent joint))
(set! t0-3 (-> a3-0 parent joint number))
)
(set! (-> a2-3 parent-matrix) (the-as uint (* (+ t0-3 1) 128)))
)
(.sync.l)
;(.cache dxwbin a2-3 0)
(.sync.l)
;(.cache dxwbin a2-3 1)
)
(.sync.l)
0
)
)
0
)
(defun execute-math-engine ()
(#when PC_PORT
(with-dma-buffer-add-bucket ((debug-buf (-> (current-frame) global-buf))
(bucket-id debug-no-zbuf))
(when (-> *pc-settings* display-actor-counts)
(draw-string-xy (string-format "M: ~D/~D A: ~D" (-> *matrix-engine* length) MATRIX_ENGINE_AMOUNT (process-count *active-pool*)) debug-buf 8 (- 224 18) (font-color default) (font-flags shadow kerning))
)
)
)
(let ((gp-0 *matrix-engine*))
(countdown (s5-0 (-> gp-0 length))
(let ((a0-1 (handle->process (-> gp-0 s5-0))))
(if a0-1
(do-joint-math! (the-as process-drawable a0-1))
)
)
)
(set! (-> gp-0 length) 0)
)
0
0
)
(define-extern draw-joint-spheres (function process-drawable symbol))
(defun-debug draw-bone-lines ((obj process-drawable))
"Added in PC port to debug bones"
(dotimes (i (-> obj node-list length))
(let ((parent (-> obj node-list data i parent)))
(when (and parent (nonzero? parent) (-> parent joint) (-> parent parent))
(let ((child (vector<-cspace! (new-stack-vector0) (-> obj node-list data i)))
)
(add-debug-line #t (bucket-id debug) child (vector<-cspace! (new-stack-vector0) parent) (new 'static 'rgba :g #xff :a #x40) #f (the rgba -1))
)
)
)
)
)
(defmethod do-joint-math! process-drawable ((obj process-drawable))
(cond
((logtest? (-> obj draw status) (draw-status hidden no-anim))
)
((zero? (-> obj skel))
(matrix<-transformq+trans!
(the-as matrix (-> obj draw skeleton bones 3))
(the-as transformq (-> obj root trans))
(-> obj draw skeleton bones 0 transform vector 3)
)
(set! (-> obj draw origin quad) (-> obj draw skeleton bones 3 transform vector 3 quad))
)
(else
(let ((s5-0 (-> obj draw mgeo num-joints)))
(let ((s4-0 (+ s5-0 2)))
(+ s4-0 1)
((-> obj skel generate-frame-function)
(the-as (inline-array vector) (+ 2416 (the-as int (the-as terrain-context (scratchpad-object int)))))
s4-0
obj
)
(if (-> obj skel prebind-function)
((-> obj skel prebind-function) (the-as pointer (+ 2416 (scratchpad-object int))) s4-0 obj)
)
)
(dotimes (s4-1 1)
(let* ((v1-25 (-> obj node-list data s4-1))
(t9-3 (-> v1-25 param0))
)
(if t9-3
((the-as (function cspace basic basic int) t9-3) v1-25 (-> v1-25 param1) (-> v1-25 param2))
)
)
)
(dotimes (s4-2 2)
(let* ((a0-15 (-> obj node-list data (+ s4-2 1)))
(a1-5 (+ (* s4-2 64) 2416 (scratchpad-object int)))
(t9-4 (-> a0-15 param0))
)
(if t9-4
((the-as (function cspace pointer none) t9-4) a0-15 (the-as pointer a1-5))
)
)
)
(let ((s4-3 3))
(dotimes (s3-0 s5-0)
(let ((a0-17 (-> obj node-list data (+ s3-0 s4-3)))
(a1-7 (+ (* 48 s3-0) 2544 (scratchpad-object int)))
)
(if (-> a0-17 param0)
((the-as (function cspace matrix none) (-> a0-17 param0)) a0-17 (the-as matrix a1-7))
(cspace<-parented-transformq-joint! a0-17 (the-as transformq a1-7))
)
)
)
)
)
(if (-> obj skel postbind-function)
((-> obj skel postbind-function) obj)
)
(let ((v1-54 (-> obj draw origin-joint-index)))
(if (zero? v1-54)
(set! (-> obj draw origin quad)
(-> (the-as
(pointer uint128)
(+ (the-as uint (-> obj draw skeleton bones 0 transform vector 3)) (* (the-as uint 96) v1-54))
)
)
)
(vector<-cspace! (-> obj draw origin) (-> obj node-list data v1-54))
)
)
)
)
; (draw-bone-lines obj)
;; (draw-joint-spheres obj)
0
(none)
)
(defmethod cleanup-for-death process-drawable ((obj process-drawable))
(if (type-type? (-> obj root type) collide-shape)
(clear-collide-with-as (the-as collide-shape (-> obj root)))
)
(if (nonzero? (-> obj skel))
(ja-channel-set! 0)
)
(process-entity-status! obj (entity-perm-status dead) #t)
(none)
)
(defun draw-joint-spheres ((arg0 process-drawable))
(dotimes (s5-0 (-> arg0 node-list length))
(let ((a2-0 (vector<-cspace! (new-stack-vector0) (-> arg0 node-list data s5-0))))
(add-debug-sphere #t (bucket-id debug) a2-0 819.2 (new 'static 'rgba :g #xff :a #x40))
;;(add-debug-text-sphere #t (bucket-id debug) a2-0 819.2 (the string (-> arg0 node-list data s5-0 joint name)) (new 'static 'rgba :g #xff :a #x40))
)
)
#f
)
(defmethod deactivate process-drawable ((obj process-drawable))
(if (nonzero? (-> obj part))
(kill-and-free-particles (-> obj part))
)
(if (nonzero? (-> obj sound))
(stop! (-> obj sound))
)
((method-of-type process deactivate) obj)
(none)
)
(defstate process-drawable-art-error (process-drawable)
:code
(behavior ((arg0 string))
(logior! (-> self entity extra perm status) (entity-perm-status bit-1))
(while #t
(when *display-entity-errors*
(let ((s5-0 add-debug-text-3d)
(s4-0 #t)
(s3-0 68)
)
(format (clear *temp-string*) "~2j~s art error for ~s" arg0 (-> self name))
(s5-0
s4-0
(the-as bucket-id s3-0)
*temp-string*
(-> self root trans)
(font-color orange-red)
(the-as vector2h #f)
)
)
)
(suspend)
)
(none)
)
)
(define-extern ja-post (function none :behavior process-drawable))
(define-extern anim-loop (function none :behavior process-drawable))
(defstate process-drawable-idle (process-drawable)
:code
anim-loop
:post
ja-post
)
;; WARN: Stack slot offset 20 signed mismatch
;; WARN: Stack slot offset 20 signed mismatch
;; WARN: Stack slot offset 20 signed mismatch
(defmethod initialize-skeleton process-drawable ((obj process-drawable) (arg0 skeleton-group) (arg1 pair))
(local-vars (s3-0 draw-control) (sv-16 art-element) (sv-20 int))
(let ((s1-0 (cond
((= (-> arg0 texture-level) 2)
(-> *level* level-default)
)
((-> obj entity)
(-> obj entity extra level)
)
(else
(-> *level* level-default)
)
)
)
)
(let ((s4-0 (load-to-heap-by-name
(-> s1-0 art-group)
(-> arg0 art-group-name)
#f
global
(-> arg0 version)
)
)
)
(when (or (zero? s4-0) (or (not s4-0) (!= (-> s4-0 type) art-group)))
(go process-drawable-art-error "art-group")
(set! s3-0 (the-as draw-control #f))
(goto cfg-59)
)
(set! sv-16 (-> s4-0 data (-> arg0 jgeo)))
(set! sv-20 (-> s4-0 length))
(when (or (>= (-> arg0 jgeo) sv-20) (!= (-> sv-16 type) art-joint-geo))
(go process-drawable-art-error "joint-geo")
(set! s3-0 (the-as draw-control #f))
(goto cfg-59)
)
(let ((v0-3 (new 'process 'draw-control obj (the-as art-joint-geo sv-16))))
(set! (-> obj draw) v0-3)
(set! s3-0 v0-3)
)
(let ((v1-26 s3-0))
(set! (-> v1-26 status) (draw-status no-skeleton-update))
(set! (-> v1-26 art-group) s4-0)
(set! (-> v1-26 jgeo) (the-as art-joint-geo sv-16))
(set! (-> v1-26 force-lod) -1)
(set! (-> v1-26 cur-lod) -1)
(set! (-> v1-26 shadow) #f)
(set! (-> v1-26 shadow-ctrl) #f)
(set! (-> v1-26 data-format) (the-as uint 1))
(set! (-> v1-26 color-mult quad) (-> (new 'static 'vector :x 1.0 :y 1.0 :z 1.0 :w 1.0) quad))
(set! (-> v1-26 color-emissive quad) (-> (new 'static 'vector) quad))
(set! (-> v1-26 level-index) (the-as uint (-> (if (-> obj entity)
(-> obj entity extra level)
(-> *level* level-default)
)
index
)
)
)
(set! (-> v1-26 longest-edge) (-> arg0 longest-edge))
(set! (-> v1-26 ripple) #f)
)
(set! (-> s3-0 bounds quad) (-> arg0 bounds quad))
(let ((v1-28 (-> arg0 shadow)))
(when (and (> v1-28 0) (< v1-28 sv-20))
(let ((s0-0 (-> s4-0 data v1-28))
(v1-32 (res-lump-value (-> obj entity) 'options uint128))
)
(if (and (zero? (logand #x20000 v1-32)) (= (-> s0-0 type) shadow-geo))
(set! (-> s3-0 shadow) (the-as shadow-geo s0-0))
)
)
)
)
(if (not (setup-lods! (-> s3-0 lod-set) arg0 s4-0 (-> obj entity)))
(go process-drawable-art-error "mesh")
)
(let ((v1-43 (res-lump-value (-> sv-16 extra) 'texture-bucket int :default (the-as uint128 1))))
(let ((a0-39 (if (= (-> arg0 texture-level) 2)
2
(-> s1-0 index)
)
)
)
(if (= (the-as uint v1-43) 4)
(set! v1-43 2)
)
(if (= a0-39 2)
(set! v1-43 (-> arg0 sort))
)
)
(set! (-> s3-0 sink-group) (-> s1-0 foreground-sink-group v1-43))
)
(set! (-> s3-0 dma-add-func) (the-as (function process-drawable draw-control symbol object none) nothing))
(set! (-> obj node-list) (make-nodes-from-jg (the-as art-joint-geo sv-16) arg1 'process))
(set! (-> s3-0 dma-add-func) dma-add-process-drawable)
(set! (-> s3-0 shadow-mask) (res-lump-value (-> obj entity) 'shadow-mask uint))
(set! (-> s3-0 light-index) (res-lump-value (-> obj entity) 'light-index uint))
(lod-set! s3-0 0)
(let ((a2-10 (res-lump-value (-> sv-16 extra) 'joint-channel int :default (the-as uint128 6))))
(cond
((> a2-10 0)
(logior! (-> s3-0 status) (draw-status has-joint-channels))
(let ((v0-13 (new 'process 'joint-control a2-10)))
(set! (-> obj skel) v0-13)
(let ((s2-1 v0-13))
(cond
((>= (-> arg0 janim) 0)
(when (or (>= (-> arg0 janim) sv-20) (!= (-> s4-0 data (-> arg0 janim) type) art-joint-anim))
(go process-drawable-art-error "initial joint-anim")
(set! s3-0 (the-as draw-control #f))
(goto cfg-59)
)
(ja-channel-set! 1)
(let ((s1-1 (-> obj skel root-channel 0)))
(joint-control-channel-group-eval!
s1-1
(the-as art-joint-anim (-> s4-0 data (-> arg0 janim)))
num-func-identity
)
(set! (-> s1-1 frame-num) 0.0)
)
)
(else
(ja-channel-set! 0)
)
)
(set! (-> s2-1 effect) (new 'process 'effect-control obj))
)
)
)
(else
(set! (-> s3-0 skeleton bones 0 transform vector 3 quad) (-> (the-as vector (get-property-struct
(-> sv-16 extra)
'trans-offset
'interp
-1000000000.0
*null-vector*
(the-as (pointer res-tag) #f)
*res-static-buf*
)
)
quad
)
)
)
)
)
)
)
(let ((gp-1 (the-as collide-shape (-> (the-as collide-shape obj) dir-targ x))))
(if (and gp-1 (nonzero? gp-1) (type-type? (-> gp-1 type) collide-shape))
(find-collision-meshes gp-1)
)
)
(label cfg-59)
(none)
)
(defmethod initialize-skeleton-by-name process-drawable ((obj process-drawable) (arg0 string) (arg1 object))
(let ((s3-0 string->symbol))
(format (clear *temp-string*) "*~S-sg*" arg0)
(let ((s3-1 (-> (s3-0 *temp-string*) value)))
(if (and (nonzero? s3-1) (valid? s3-1 skeleton-group #f #f 0))
(initialize-skeleton obj (the-as skeleton-group s3-1) (the-as pair arg1))
(go process-drawable-art-error arg0)
)
)
)
obj
)
(defmethod apply-alignment process-drawable ((obj process-drawable) (arg0 int) (arg1 transformq) (arg2 vector))
(when (logtest? arg0 7)
(let* ((body-T-world (quaternion->matrix (new 'stack-no-clear 'matrix) (-> obj root quat)))
(world-T-body (matrix-transpose! (new 'stack-no-clear 'matrix) body-T-world))
(grav-rt-body (vector-matrix*! (new 'stack-no-clear 'vector) (-> *standard-dynamics* gravity) world-T-body))
(vel-rt-body (vector-matrix*! (new 'stack-no-clear 'vector) (-> obj root transv) world-T-body))
)
(if (logtest? arg0 2048)
(set-vector! grav-rt-body 0.0 0.0 0.0 1.0)
)
(when (logtest? arg0 1)
(set! (-> vel-rt-body x) (+ (* (-> arg1 trans x) (-> arg2 x) (-> *display* frames-per-second))
(* (-> grav-rt-body x) (-> *display* seconds-per-frame))
)
)
(if (zero? (logand arg0 12))
(set! (-> vel-rt-body z) 0.0)
)
)
(if (and (logtest? arg0 2) (not (and (logtest? arg0 4096) (= (-> arg1 trans y) 0.0))))
(set! (-> vel-rt-body y) (+ (* (-> arg1 trans y) (-> arg2 y) (-> *display* frames-per-second))
(* (-> grav-rt-body y) (-> *display* seconds-per-frame))
)
)
)
(when (logtest? arg0 4)
(set! (-> vel-rt-body z) (+ (* (-> arg1 trans z) (-> arg2 z) (-> *display* frames-per-second))
(* (-> grav-rt-body z) (-> *display* seconds-per-frame))
)
)
(if (zero? (logand arg0 9))
(set! (-> vel-rt-body x) 0.0)
)
)
(vector-matrix*! (-> obj root transv) vel-rt-body body-T-world)
)
)
(if (logtest? arg0 16)
(quaternion-normalize! (quaternion*! (-> obj root quat) (-> obj root quat) (-> arg1 quat)))
)
(the-as collide-shape (-> obj root))
)
(defbehavior ja-done? process-drawable ((arg0 int))
(let ((v1-2 (-> self skel root-channel arg0)))
(cond
((zero? (-> self skel active-channels))
#t
)
((= (-> v1-2 num-func) num-func-seek!)
(= (-> v1-2 frame-num) (-> v1-2 param 0))
)
(else
#t
)
)
)
)
(defbehavior ja-min? process-drawable ((arg0 int))
(= (-> self skel root-channel arg0 frame-num) 0.0)
)
(defbehavior ja-max? process-drawable ((arg0 int))
(let ((v1-2 (-> self skel root-channel arg0)))
(>= (-> v1-2 frame-num) (the float (+ (-> v1-2 frame-group data 0 length) -1)))
)
)
(defmacro ja-group (&key (chan 0))
"get the frame group for self. default channel is 0, the base channel. returns #f if no frame group."
`(if (> (-> self skel active-channels) ,chan)
(-> self skel root-channel ,chan frame-group))
)
(defmacro ja-group? (group &key (chan 0))
"is self in this frame group on this channel? default is channel 0, which is the base channel."
`(= (ja-group) ,group)
)
(defbehavior ja-num-frames process-drawable ((arg0 int))
(+ (-> self skel root-channel arg0 frame-group data 0 length) -1)
)
(defbehavior ja-frame-num process-drawable ((arg0 int))
(-> self skel root-channel arg0 frame-num)
)
(defbehavior ja-aframe-num process-drawable ((arg0 int))
(let* ((a0-2 (-> self skel root-channel arg0))
(v1-2 (-> a0-2 frame-group))
)
(+ (* (-> a0-2 frame-num) (-> v1-2 artist-step)) (if (and v1-2 (nonzero? v1-2))
(-> v1-2 artist-base)
0.0
)
)
)
)
(defbehavior ja-aframe process-drawable ((arg0 float) (arg1 int))
(let ((v1-3 (-> self skel root-channel arg1 frame-group)))
(/ (- arg0 (if (and v1-3 (nonzero? v1-3))
(-> v1-3 artist-base)
0.0
)
)
(if v1-3
(-> v1-3 artist-step)
1.0
)
)
)
)
(defbehavior ja-speed process-drawable ((arg0 int))
(-> self skel root-channel arg0 frame-group speed)
)
(defbehavior ja-step process-drawable ((arg0 int))
(-> self skel root-channel arg0 frame-group artist-step)
)
(defbehavior ja-channel-set! process-drawable ((arg0 int))
(set! (-> self skel active-channels) arg0)
(set! (-> self skel root-channel) (-> self skel channel))
(set! (-> self skel blend-index) -1)
(set! (-> self skel root-channel 0 frame-group) #f)
(dotimes (v1-6 arg0)
(set! (-> self skel root-channel v1-6 eval-time) (the-as uint (-> *display* base-frame-counter)))
(set! (-> self skel root-channel v1-6 group-sub-index) v1-6)
(set! (-> self skel root-channel v1-6 command) (if (zero? v1-6)
'push
'blend
)
)
(set! (-> self skel root-channel v1-6 frame-interp) 0.0)
(set! (-> self skel root-channel v1-6 frame-num) 0.0)
(set! (-> self skel root-channel v1-6 frame-group) #f)
(set! (-> self skel root-channel v1-6 num-func) num-func-none)
(set! (-> self skel root-channel v1-6 group-size) arg0)
)
arg0
)
(defbehavior ja-channel-push! process-drawable ((arg0 int) (arg1 time-frame))
(cond
((or (zero? (-> self skel active-channels))
(zero? arg1)
(when (>= (+ (-> self skel active-channels) arg0) (-> self skel allocated-length))
(format
0
"WARNING: ~A could not do (ja-channel-push ~D) because it has ~D/~D channels.~%"
self
arg0
(-> self skel active-channels)
(-> self skel allocated-length)
)
#t
)
)
(ja-channel-set! arg0)
)
(else
(when (not (-> self skel root-channel 0 frame-group))
(set! (-> self skel active-channels)
(/ (&- (the-as pointer (-> self skel root-channel)) (the-as uint (the-as pointer (-> self skel channel)))) 48)
)
(if (zero? (-> self skel active-channels))
(return (ja-channel-set! arg0))
)
)
(set! (-> self skel root-channel)
(the-as (inline-array joint-control-channel) (-> self skel channel (-> self skel active-channels)))
)
(set! (-> self skel active-channels) (+ arg0 1 (-> self skel active-channels)))
(dotimes (v1-26 arg0)
(set! (-> self skel root-channel v1-26 eval-time) (the-as uint (-> *display* base-frame-counter)))
(set! (-> self skel root-channel v1-26 group-sub-index) v1-26)
(set! (-> self skel root-channel v1-26 command) (if (zero? v1-26)
'push
'blend
)
)
(set! (-> self skel root-channel v1-26 frame-interp) 0.0)
(set! (-> self skel root-channel v1-26 frame-num) 0.0)
(set! (-> self skel root-channel v1-26 frame-group) #f)
(set! (-> self skel root-channel v1-26 num-func) num-func-none)
(set! (-> self skel root-channel v1-26 group-size) arg0)
)
(let ((v1-31 (-> self skel root-channel arg0)))
(set! (-> v1-31 eval-time) (the-as uint (-> *display* base-frame-counter)))
(set! (-> v1-31 group-sub-index) arg0)
(set! (-> self skel blend-index) (+ (-> self skel active-channels) -1))
(set! (-> v1-31 frame-interp) 0.0)
(set! (-> v1-31 frame-num) 0.0)
(set! (-> v1-31 frame-group) #f)
(set! (-> v1-31 group-size) arg0)
(set! (-> v1-31 param 0) (/ 5.0 (+ 5.0 (the float arg1))))
(set! (-> v1-31 num-func) num-func-blend-in!)
(cond
((= arg0 1)
(set! (-> v1-31 command) 'stack1)
(set! (-> self skel root-channel 0 command) 'push1)
)
(else
(set! (-> v1-31 command) 'stack)
)
)
)
arg0
)
)
)
(defbehavior joint-control-reset! process-drawable ((arg0 joint-control) (arg1 joint-control-channel))
(let* ((v1-2 (the-as joint-control-channel (&- (the-as pointer arg1) (the-as uint (* 48 (-> arg1 group-size))))))
(s5-0 (/ (&- (the-as pointer v1-2) (the-as uint (the-as pointer (-> arg0 channel)))) 48))
(s4-0 (/ (&- (the-as pointer arg1) (the-as uint v1-2)) 48))
)
(when (> s5-0 0)
(if (= (-> v1-2 command) 'push1)
(set! (-> v1-2 command) 'push)
)
(if (= (-> arg0 root-channel) v1-2)
(set! (-> arg0 root-channel) (-> arg0 channel))
(set! (-> arg0 root-channel)
(the-as (inline-array joint-control-channel) (-> arg0 root-channel (- (+ s5-0 1))))
)
)
(qmem-copy<-!
(the-as pointer (-> arg0 channel))
(the-as pointer v1-2)
(* 48 (- (-> arg0 active-channels) s5-0))
)
(qmem-copy<-!
(the-as pointer (-> arg0 channel s4-0))
(the-as pointer (+ (the-as uint (-> arg0 channel 1)) (* 48 s4-0)))
(* 48 (+ (- (- -1 s5-0) s4-0) (-> arg0 active-channels)))
)
(set! (-> arg0 active-channels) (- (-> arg0 active-channels) (+ s5-0 1)))
)
)
(none)
)
(defbehavior ja-group-size process-drawable ()
(if (< (the-as int (-> self skel root-channel))
(the-as int (-> self skel channel (-> self skel active-channels)))
)
(-> self skel root-channel 0 group-size)
0
)
)
(defmacro ja (&key (chan 0)
&key (group! #f)
&key (num! #f)
&key (param0 #f)
&key (param1 #f)
&key (num-func #f)
&key (frame-num #f)
&key (frame-interp #f)
&key (dist #f)
&key (eval? #t)
)
"set various joint anim parameters for self and eval them.
you can use this for playing animations!
chan = the channel to modify. defaults to 0 (base channel). this is usually what you want.
group! = when not #f, set this as the new frame-group. defaults to #f
num! = set the frame playback function. this is what determines what frame an animation is at. funcs below.
#f = no func will be set, and there wont be a frame eval.
num-func = sets the num-func field for the channel. this lets you change the function with eval'ing.
param0 = 1st parameter for the playback function. ONLY USE THESE WITH num-func !!
param1 = 2nd parameter for the playback function. ONLY USE THESE WITH num-func !!
frame-num = set the frame-num field.
frame-interp = set the frame-interp field.
dist = set the dist field.
available num! functions:
- (+!) = advance anim.
- (-!) = reverse anim.
- (identity num) = play 'num' frame.
- (seek! target speed) = animate towards frame target at a speed.
speed is optional and defaults to 1.0 when not provided.
target is optional and defaults to the last frame of the animation.
if you want to set the speed, you therefore must also set the target.
target can be max (no quote), which is just the same as the default value.
- (loop! speed) = loop animation at a speed. default speed is 1.0 when not provided.
- (chan channel) = copy frame from another channel.
- min = the start of the animation.
- max = the end of the animation.
"
(let* ((num-args (if (pair? num!) (cdr num!) '()))
(num! (if (pair? num!) (car num!) num!))
(nf (cond
((or (eq? num! 'identity)
(eq? num! 'min)
(eq? num! 'max)
)
'num-func-identity)
((eq? num! 'none) 'num-func-none)
((eq? num! '+!) 'num-func-+!)
((eq? num! '-!) 'num-func--!)
((eq? num! 'seek!) 'num-func-seek!)
((eq? num! 'loop!) 'num-func-loop!)
((eq? num! 'blend-in!) 'num-func-blend-in!)
((eq? num! 'chan) 'num-func-chan)
))
(p0 (if param0 param0
(cond
((eq? num! 'chan) `(the float ,(car num-args)))
((eq? num! '+!) (if (null? num-args) 1.0 (car num-args)))
((eq? num! '-!) (if (null? num-args) 1.0 (car num-args)))
((eq? num! 'loop!) (if (null? num-args) 1.0 (if (eq? 'max (car num-args))
(if group!
`(the float (1- (-> (the art-joint-anim ,group!) data 0 length)))
`(the float (1- (-> ja-ch frame-group data 0 length)))
)
(car num-args))))
((eq? num! 'seek!) (if (or (null? num-args) (eq? (car num-args) 'max))
(if group!
`(the float (1- (-> (the art-joint-anim ,group!) data 0 length)))
`(the float (1- (-> ja-ch frame-group data 0 length)))
)
(car num-args)))
)))
(p1 (if param1 param1
(cond
((eq? num! 'seek!) (if (or (null? num-args) (null? (cdr num-args))) 1.0 (cadr num-args)))
)))
(frame-num (if (eq? 'max frame-num) (if group!
`(the float (1- (-> (the art-joint-anim ,group!) data 0 length)))
`(the float (1- (-> ja-ch frame-group data 0 length)))
)
frame-num))
(frame-group (if (or p0 p1 frame-num (not nf)) group! #f))
)
`(let ((ja-ch (-> self skel root-channel ,chan)))
,(if frame-interp `(set! (-> ja-ch frame-interp) ,frame-interp) `(none))
,(if dist `(set! (-> ja-ch dist) ,dist) `(none))
,(if frame-group `(set! (-> ja-ch frame-group) (the art-joint-anim ,frame-group)) `(none))
,(if p0 `(set! (-> ja-ch param 0) ,p0) `(none))
,(if p1 `(set! (-> ja-ch param 1) ,p1) `(none))
,(if num-func `(set! (-> ja-ch num-func) ,num-func) `(none))
,(if frame-num `(set! (-> ja-ch frame-num) ,frame-num) `(none))
,(if nf
`(,(if eval? 'joint-control-channel-group-eval! 'joint-control-channel-group!)
ja-ch (the art-joint-anim ,group!) ,nf)
`(none))
,(cond
((eq? num! 'min) `(set! (-> ja-ch frame-num) 0.0))
((eq? num! 'max) (if group!
`(set! (-> ja-ch frame-num) (the float (1- (-> (the art-joint-anim ,group!) data 0 length))))
`(set! (-> ja-ch frame-num) (the float (1- (-> ja-ch frame-group data 0 length))))
))
((eq? num! 'identity) `(set! (-> ja-ch frame-num) ,(car num-args)))
(#t `(none))
)
))
)
(defmacro ja-no-eval (&key (chan 0)
&key (group! #f)
&key (num! #f)
&key (param0 #f)
&key (param1 #f)
&key (num-func #f)
&key (frame-num #f)
&key (frame-interp #f)
&key (dist #f)
)
`(ja :eval? #f :chan ,chan :group! ,group! :num! ,num! :param0 ,param0 :param1 ,param1 :num-func ,num-func :frame-num ,frame-num :frame-interp ,frame-interp :dist ,dist)
)
(defbehavior ja-eval process-drawable ()
(let ((gp-0 (-> self skel root-channel 0))
(s5-0 (-> self skel channel (-> self skel active-channels)))
(s4-0 (-> *display* base-frame-counter))
)
(while (< (the-as int gp-0) (the-as int s5-0))
(case (-> gp-0 command)
(('stack 'stack1)
)
(else
(if (!= (-> gp-0 eval-time) s4-0)
(joint-control-channel-eval gp-0)
)
)
)
(&+! gp-0 48)
)
)
0
)
(defbehavior ja-blend-eval process-drawable ()
(let ((gp-0 (-> self skel root-channel))
(s5-0 (the-as joint-control-channel (-> self skel channel)))
(s4-0 (-> *display* base-frame-counter))
)
(when (and (nonzero? (-> self skel active-channels)) (!= gp-0 s5-0))
(while (< (the-as int s5-0) (the-as int gp-0))
(case (-> s5-0 command)
(('stack 'stack1)
)
(else
(if (!= (-> s5-0 eval-time) s4-0)
(joint-control-channel-eval s5-0)
)
)
)
(&+! s5-0 48)
)
)
)
0
)
;; WARN: Unsupported inline assembly instruction kind - [lw ra, return-from-thread(s7)]
;; WARN: Unsupported inline assembly instruction kind - [jr ra]
(defmethod evaluate-joint-control process-drawable ((obj process-drawable))
(local-vars (s7-0 none) (ra-0 int))
(let ((gp-0 (-> obj skel)))
(label cfg-1)
(let ((s4-0 (-> gp-0 active-channels)))
(b! (logtest? (-> obj draw status) (draw-status hidden)) cfg-27)
(let ((s3-0 0))
(b! #t cfg-13 :delay (nop!))
(label cfg-3)
(let ((s2-0 (-> gp-0 channel s3-0)))
(let ((v1-7 (-> s2-0 command)))
(b! (!= v1-7 'stack) cfg-6 :delay (nop!))
(joint-control-channel-eval s2-0)
(b! (!= s4-0 (-> gp-0 active-channels)) cfg-1 :delay (nop!))
(b! #t cfg-12 :delay (nop!))
(label cfg-6)
(b! (!= v1-7 'stack1) cfg-9 :delay (nop!))
)
(joint-control-channel-eval s2-0)
(b! (!= s4-0 (-> gp-0 active-channels)) cfg-1 :delay (nop!))
(set! (-> gp-0 channel (+ s3-0 -1) frame-interp) (-> s2-0 frame-interp))
(b! #t cfg-12 :delay (nop!))
(label cfg-9)
(let ((s1-0 (-> s2-0 frame-group)))
(let ((v1-16 art-joint-anim))
(b! (= (-> s1-0 type) v1-16) cfg-11)
)
(go process-drawable-art-error "joint-anim")
(format 0 "dummy-19 bad~%")
(break!)
(nop!)
0
(label cfg-11)
(set! (-> s2-0 frame-num) (fmax 0.0 (fmin (-> s2-0 frame-num) (the float (+ (-> s1-0 data 0 length) -1)))))
)
)
(label cfg-12)
(+! s3-0 1)
(label cfg-13)
(b! (< s3-0 s4-0) cfg-3)
)
(dotimes (v1-26 s4-0)
(set! (-> gp-0 channel v1-26 frame-interp) (fmax 0.0 (fmin 1.0 (-> gp-0 channel v1-26 frame-interp))))
)
(if (or (zero? s4-0) (not (-> gp-0 root-channel 0 frame-group)))
(logior! (-> obj draw status) (draw-status no-anim))
)
)
(if (logtest? (-> obj skel status) (janim-status blerc blerc-done))
(merc-blend-shape obj)
)
(if (logtest? (-> obj skel status) (janim-status eye-done eye))
(merc-eye-anim obj)
)
(label cfg-27)
(let ((a0-17 (-> gp-0 effect)))
(if a0-17
(TODO-RENAME-9 a0-17)
)
)
)
0
(none)
)
(defbehavior ja-post process-drawable ()
(when (nonzero? (-> self draw))
(let ((gp-1 (logtest? (-> self draw status) (draw-status no-skeleton-update))))
(logclear! (-> self draw status) (draw-status no-anim no-skeleton-update))
(when (nonzero? (-> self skel))
(evaluate-joint-control self)
(when (or (logtest? (-> self skel status) (janim-status inited)) gp-1)
(do-joint-math! self)
(if (and gp-1 (type-type? (-> self root type) collide-shape))
(update-transforms! (the-as collide-shape (-> self root)))
)
(return #f)
)
)
)
;; NOTE : added matrix-engine check for PC port
(if (< (-> *matrix-engine* length) MATRIX_ENGINE_AMOUNT)
(let ((v1-24 *matrix-engine*))
(set! (-> v1-24 (-> v1-24 length)) (process->handle self))
(+! (-> v1-24 length) 1)
)
)
)
0
(none)
)
(defmethod dummy-9 joint-control ((obj joint-control))
(cond
((< (the-as int (-> obj root-channel)) (the-as int (-> obj channel (-> obj active-channels))))
(let ((s5-0 (-> obj root-channel (-> obj root-channel 0 group-size)))
(s4-0 (the-as joint-control-channel (-> obj root-channel)))
(gp-0 (the-as (pointer float) (new 'stack-no-clear 'vector)))
)
(while (< (the-as int s4-0) (the-as int s5-0))
(case (-> s4-0 command)
(('push)
(set! (-> gp-0 0) (-> s4-0 dist))
(set! gp-0 (&-> gp-0 1))
)
(('blend 'push1)
(set! (-> gp-0 -1) (lerp (-> gp-0 -1) (-> s4-0 dist) (-> s4-0 frame-interp)))
)
(('stack)
(set! (-> gp-0 -2) (lerp (-> gp-0 -2) (-> gp-0 -1) (-> s4-0 frame-interp)))
(set! gp-0 (&-> gp-0 -1))
)
)
(&+! s4-0 48)
)
(-> gp-0 -1)
)
)
(else
0.0
)
)
)
(defbehavior anim-loop process-drawable ()
(logior! (-> self mask) (process-mask sleep-code))
(while #t
(nop!)
(suspend)
)
(none)
)
(defbehavior transform-post process-drawable ()
(ja-post)
(update-transforms! (the-as collide-shape (-> self root)))
0
)
(defbehavior rider-trans process-drawable ()
(detect-riders! (the-as collide-shape (-> self root)))
0
)
(defbehavior rider-post process-drawable ()
(ja-post)
(let ((gp-0 (the-as collide-shape (-> self root))))
(update-transforms! gp-0)
(pull-riders! gp-0)
(do-push-aways! gp-0)
)
0
)
(defbehavior pusher-post process-drawable ()
(ja-post)
(let ((gp-0 (the-as collide-shape (-> self root))))
(update-transforms! gp-0)
(do-push-aways! gp-0)
)
0
)
(defbehavior process-drawable-delay-player process-drawable ((arg0 time-frame))
(while (and *target*
(logtest? (-> *target* control unknown-surface00 flags) (surface-flags surf11))
(zero? (logand (-> *target* control status) (cshape-moving-flags onsurf)))
)
(suspend)
)
(set! (-> self state-time) (-> *display* base-frame-counter))
(process-grab? *target*)
(while (or (-> *setting-control* current talking)
(-> *setting-control* current spooling)
(-> *setting-control* current hint)
(-> *setting-control* current ambient)
)
(suspend)
)
(while (< (- (-> *display* base-frame-counter) (-> self state-time)) arg0)
(suspend)
)
(process-release? *target*)
(suspend)
0
)
(defbehavior process-drawable-fuel-cell-handler process-drawable ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
(case arg2
(('notify)
(case (-> arg3 param 0)
(('pickup)
(if (type-type? (-> arg0 type) fuel-cell)
(process-entity-status! self (entity-perm-status dead) #t)
)
)
)
)
)
(none)
)
;; WARN: Found some very strange gotos. Check result carefully, this is not well tested.
(defbehavior process-drawable-birth-fuel-cell process-drawable ((arg0 entity) (arg1 vector) (arg2 symbol))
(let ((v1-0 arg0)
(gp-0 (new 'stack-no-clear 'vector))
)
(if (not v1-0)
(set! v1-0 (-> self entity))
)
(if arg1
(set! (-> gp-0 quad) (-> arg1 quad))
(set! (-> gp-0 quad) (-> v1-0 extra trans quad))
)
(let ((s5-0 (-> v1-0 extra perm task))
(s4-0 (new 'static 'fact-info))
)
(set! (-> s4-0 options) (fact-options))
(if arg2
(set! (-> s4-0 options) (fact-options fop6))
)
(when (and (nonzero? s5-0) (not (task-complete? *game-info* s5-0)))
(label cfg-12)
(birth-pickup-at-point gp-0 (pickup-type fuel-cell) (the float s5-0) #f self s4-0)
(when (not (-> self child))
(suspend)
(goto cfg-12)
)
)
)
)
0
(none)
)
;; this part is debug only
(when *debug-segment*
(define *valid-con* (new 'debug 'string #x4000 (the-as string #f)))
)
(defun-debug process-drawable-valid? ((arg0 process-drawable))
(let ((s5-0 #t))
(clear *valid-con*)
(format *valid-con* "~%--- ~A -----------------------------~%" arg0)
(dotimes (s4-0 (-> arg0 node-list length))
(let ((s3-0 (-> arg0 node-list data s4-0)))
(when (-> s3-0 geo)
(cond
((valid? (-> s3-0 geo) drawable "cspace geo" #t *valid-con*)
)
(else
(format *valid-con* "ERROR: ~A has an invalid geo ~A~%" s3-0 (-> s3-0 geo))
(set! s5-0 #f)
)
)
)
)
)
(let ((s4-1 (-> arg0 skel active-channels)))
(when (< (-> arg0 skel allocated-length) s4-1)
(format
*valid-con*
"ERROR: ~~A has ~D joint channels, but only ~D are allowed~%"
arg0
s4-1
(-> arg0 skel allocated-length)
)
(set! s5-0 #f)
)
(dotimes (s3-1 s4-1)
(let ((s2-0 (-> arg0 skel channel s3-1)))
(case (-> s2-0 command)
(('stack 'stack1)
)
(else
(set! s5-0 (cond
((valid? (-> s2-0 frame-group) art-joint-anim "joint-control frame-group" #t *valid-con*)
(when (not (and (>= (the int (-> s2-0 frame-num)) 0)
(< (the int (-> s2-0 frame-num)) (-> s2-0 frame-group data 0 length))
)
)
(format
*valid-con*
"ERROR: ~`joint-control-channel`P #~D has an invalid frame-num ~F/~D [0-~D]~%"
s2-0
s3-1
(-> s2-0 frame-num)
(the int (-> s2-0 frame-num))
(+ (-> s2-0 frame-group data 0 length) -1)
)
(set! s5-0 #f)
)
s5-0
)
(else
(format
*valid-con*
"ERROR: ~`joint-control-channel`P #~D has an invalid frame-group ~A~%"
s2-0
s3-1
(-> s2-0 frame-group)
)
#f
)
)
)
)
)
)
)
)
(when (not s5-0)
(format *valid-con* "--------------------------------~%~%")
(format 0 "~S" *valid-con*)
)
s5-0
)
)