;;-*-Lisp-*- (in-package goal) ;; name: history.gc ;; name in dgo: history ;; dgos: ENGINE, GAME (defenum collide-status :bitfield #t :type uint64 (on-surface 0) (on-ground 1) (touch-surface 2) (touch-wall 3) (touch-ceiling 4) (touch-actor 5) (on-special-surface 6) (touch-edge 7) (no-touch 8) (blocked 9) (on-water 10) (impact-surface 11) (touch-background 12) (stuck 13) (touch-ceiling-sticky 14) (glance 15) (probe-hit 16) ) (defenum history-channel :type uint8 (trans 0) (transv 1) (transv-in 2) (transv-out 3) (intersect 4) (local-normal 5) (surface-normal 6) (collide-status 7) (pat 8) (time 9) (friction 10)) ;; DECOMP BEGINS ;; this file is debug only (declare-file (debug)) (defun history-channel->string ((arg0 history-channel)) (case arg0 (((history-channel friction)) "friction" ) (((history-channel transv-out)) "transv-out" ) (((history-channel pat)) "pat" ) (((history-channel transv-in)) "transv-in" ) (((history-channel trans)) "trans" ) (((history-channel local-normal)) "local-normal" ) (((history-channel collide-status)) "collide-status" ) (((history-channel time)) "time" ) (((history-channel intersect)) "intersect" ) (((history-channel surface-normal)) "surface-normal" ) (((history-channel transv)) "transv" ) (else "*unknown*" ) ) ) (deftype history-elt (structure) ((record-tag-bytes uint8 4) (record-tag uint32 :overlay-at (-> record-tag-bytes 0)) (record-id uint16 :overlay-at (-> record-tag-bytes 0)) (owner uint8 :overlay-at (-> record-tag-bytes 2)) (channel history-channel) (timestamp time-frame) (origin vector :inline) (bytes uint8 16) (vector vector :inline :overlay-at (-> bytes 0)) (float float :overlay-at (-> bytes 0)) (collide-status collide-status :overlay-at (-> bytes 0)) (collide-reaction-flag uint32 :overlay-at (-> bytes 8)) (pat pat-surface :overlay-at (-> bytes 0)) ) ) (deftype history-iterator (basic) ((max-age uint32) (owner uint8) (proc process) (out object) (channel-mask uint64) (index int32) (done? symbol) ) (:methods (new (symbol type uint) _type_) (frame-counter-delta (_type_ history-elt) time-frame) (update-entries! (_type_) history-elt) (get-age (_type_ history-elt) float) ) ) (deftype history (basic) ((alloc-index int32) (allocated-length int32) (elts history-elt :inline :dynamic :offset 16) ) (:methods (new (symbol type int) _type_) (clear-record-tags! (_type_ history-channel uint uint) history-elt) (clear-history-entries! (_type_) none) ) ) (defmethod length ((this history)) (-> this allocated-length) ) ;; WARN: Return type mismatch uint vs int. (defmethod asize-of ((this history)) (the-as int (+ (-> this type size) (* 48 (-> this allocated-length)))) ) (defmethod new history ((allocation symbol) (type-to-make type) (arg0 int)) (let ((v0-0 (object-new allocation type-to-make (the-as int (+ (-> type-to-make size) (* 48 arg0)))))) (set! (-> v0-0 allocated-length) arg0) v0-0 ) ) (defmethod clear-history-entries! ((this history)) "Iterates through each [[history-elt]] in the `elt` dynamic array For each entry: - clear `timestamp` - clear `record-tag`" (set! (-> this alloc-index) 0) (countdown (v1-0 (-> this allocated-length)) (let ((a1-3 (-> this elts v1-0))) (set! (-> a1-3 record-tag) (the-as uint 0)) (set! (-> a1-3 timestamp) 0) ) 0 ) 0 (none) ) (define-perm *history* history (new 'debug 'history 4096)) (clear-history-entries! *history*) ;; WARN: new jak 2 until loop case, check carefully (defmethod clear-record-tags! ((this history) (arg0 history-channel) (arg1 uint) (arg2 uint)) "First grab the latest [[history-elt]] at `alloc-index` 1. update it's `channel`, `record-id` and `owner` from the provided args 2. - if it's `record-tag` is zero -- return it - otherwise, iterate through all `elts` until one is found that does not match it's `timestamp` - if not `0` out the `record-tag` for that elt and continue iteration" (let* ((t1-0 (-> this alloc-index)) (v1-0 (-> this elts)) (v0-0 (-> v1-0 t1-0)) ) (let ((t2-0 (-> v0-0 record-tag)) (t0-2 (-> v0-0 timestamp)) ) (set! (-> v0-0 channel) arg0) (set! (-> v0-0 record-id) arg1) (set! (-> v0-0 owner) arg2) (set! (-> v0-0 timestamp) (-> *display* base-clock frame-counter)) (let* ((a1-4 (-> this allocated-length)) (a2-2 (mod (+ t1-0 1) a1-4)) ) (set! (-> this alloc-index) a2-2) (when (nonzero? t2-0) (until #f (let ((a0-4 (-> v1-0 a2-2))) (if (!= t0-2 (-> a0-4 timestamp)) (return v0-0) ) (set! (-> a0-4 record-tag) (the-as uint 0)) ) (set! a2-2 (mod (+ a2-2 1) a1-4)) ) #f ) ) ) v0-0 ) ) (defmethod new history-iterator ((allocation symbol) (type-to-make type) (arg0 uint)) (let ((v0-0 (object-new allocation type-to-make (the-as int (-> type-to-make size))))) (set! (-> v0-0 max-age) arg0) (set! (-> v0-0 owner) (the-as uint 1)) (set! (-> v0-0 proc) #f) (set! (-> v0-0 out) *stdcon*) (set! (-> v0-0 channel-mask) (the-as uint -1)) (set! (-> v0-0 index) (-> *history* alloc-index)) (set! (-> v0-0 done?) #f) v0-0 ) ) (defmethod update-entries! ((this history-iterator)) "Iterate through each [[history-elt]] in [[*history*]] - If we hit the end set `done?` to true - If the `timestamp` on the elt, minus the current framecounter exceeds `max-age`, we are also done, return #f - However if we find an elt who's `owner` matches the iterator's, break out early returning that `elt`" (let ((v1-0 *history*) (a1-2 (-> *display* base-clock frame-counter)) ) (while (not (-> this done?)) (let ((a2-1 (+ (-> this index) -1))) (if (< a2-1 0) (set! a2-1 (+ (-> v1-0 allocated-length) -1)) ) (set! (-> this index) a2-1) (if (= a2-1 (-> v1-0 alloc-index)) (set! (-> this done?) #t) ) (let ((a2-5 (-> v1-0 elts a2-1))) (when (nonzero? (-> a2-5 record-tag)) (when (< (the-as time-frame (-> this max-age)) (- a1-2 (-> a2-5 timestamp))) (set! (-> this done?) #t) (return (the-as history-elt #f)) ) (if (= (-> a2-5 owner) (-> this owner)) (return a2-5) ) ) ) ) ) ) (the-as history-elt #f) ) (defmethod get-age ((this history-iterator) (arg0 history-elt)) "Get the age of a history element" (- 1.0 (fmin 1.0 (/ (the float (+ (- 1 (-> arg0 timestamp)) (-> *display* base-clock frame-counter))) (the float (+ (-> this max-age) 1)) ) ) ) ) (defmethod frame-counter-delta ((this history-iterator) (arg0 history-elt)) "Returns the difference between [[*display*]]'s `base-clock.frame-counter` and the elt's `timestamp`" (- (-> *display* base-clock frame-counter) (-> arg0 timestamp)) ) ;; WARN: new jak 2 until loop case, check carefully (defun history-print ((arg0 history-iterator)) (local-vars (sv-16 object) (sv-24 int) (sv-32 int) (sv-40 history-elt) (sv-48 time-frame) (sv-56 uint) (sv-64 collide-status) (sv-72 float) (sv-80 string) (sv-96 string) ) (set! sv-16 (-> arg0 out)) (set! sv-24 -1) (set! sv-32 0) (until #f (set! sv-40 (update-entries! arg0)) (if (not sv-40) (goto cfg-71) ) (when (logtest? (-> arg0 channel-mask) (ash 1 (-> sv-40 channel))) (set! sv-48 (frame-counter-delta arg0 sv-40)) (set! sv-56 (-> sv-40 record-id)) (cond ((!= sv-24 sv-48) (set! sv-24 (the-as int sv-48)) (set! sv-32 (the-as int sv-56)) (format sv-16 "~3D ~4X " sv-48 (-> sv-40 record-id)) ) ((!= sv-32 sv-56) (set! sv-32 (the-as int sv-56)) (format sv-16 " ~4X " (-> sv-40 record-id)) ) (else (format sv-16 " ") ) ) (let ((v1-22 (-> sv-40 channel))) (cond ((or (= v1-22 (history-channel trans)) (or (= v1-22 (history-channel transv)) (= v1-22 (history-channel transv-in)) (= v1-22 (history-channel transv-out)) (= v1-22 (history-channel intersect)) ) ) (format sv-16 "~-15S: ~14Mm ~14Mm ~14Mm~%" (history-channel->string (-> sv-40 channel)) (-> sv-40 vector x) (-> sv-40 vector y) (-> sv-40 vector z) ) ) ((or (= v1-22 (history-channel local-normal)) (= v1-22 (history-channel surface-normal))) (format sv-16 "~-15S: ~14f ~14f ~14f~%" (history-channel->string (-> sv-40 channel)) (-> sv-40 vector x) (-> sv-40 vector y) (-> sv-40 vector z) ) ) ((= v1-22 (history-channel pat)) (let* ((s2-0 (-> sv-40 vector x)) (s5-2 format) (s4-2 sv-16) (s3-2 "~-15S: #x~6X mode:~-8S material:~-10S event:~S~%") (s1-0 (history-channel->string (-> sv-40 channel))) (s0-0 s2-0) ) (set! sv-80 (pat-mode->string (the-as pat-surface s2-0))) (set! sv-96 (pat-material->string (the-as pat-surface s2-0))) (let ((t2-0 (pat-event->string (the-as pat-surface s2-0)))) (s5-2 s4-2 s3-2 s1-0 s0-0 sv-80 sv-96 t2-0) ) ) ) ((= v1-22 (history-channel collide-status)) (set! sv-64 (-> sv-40 collide-status)) (set! sv-72 (-> sv-40 vector z)) (format sv-16 "~-15S: #x~6X " (history-channel->string (-> sv-40 channel)) sv-64) (let ((s5-4 sv-64)) (if (= (logand s5-4 (collide-status touch-background)) (collide-status touch-background)) (format sv-16 "touch-background ") ) (if (= (logand s5-4 (collide-status on-special-surface)) (collide-status on-special-surface)) (format sv-16 "on-special-surface ") ) (if (= (logand s5-4 (collide-status touch-wall)) (collide-status touch-wall)) (format sv-16 "touch-wall ") ) (if (= (logand s5-4 (collide-status on-surface)) (collide-status on-surface)) (format sv-16 "on-surface ") ) (if (= (logand s5-4 (collide-status impact-surface)) (collide-status impact-surface)) (format sv-16 "impact-surface ") ) (if (= (logand s5-4 (collide-status touch-ceiling)) (collide-status touch-ceiling)) (format sv-16 "touch-ceiling ") ) (if (= (logand s5-4 (collide-status on-ground)) (collide-status on-ground)) (format sv-16 "on-ground ") ) (if (= (logand s5-4 (collide-status glance)) (collide-status glance)) (format sv-16 "glance ") ) (if (= (logand s5-4 (collide-status blocked)) (collide-status blocked)) (format sv-16 "blocked ") ) (if (= (logand s5-4 (collide-status touch-edge)) (collide-status touch-edge)) (format sv-16 "touch-edge ") ) (if (= (logand s5-4 (collide-status touch-ceiling-sticky)) (collide-status touch-ceiling-sticky)) (format sv-16 "touch-ceiling-sticky ") ) (if (= (logand s5-4 (collide-status on-water)) (collide-status on-water)) (format sv-16 "on-water ") ) (if (= (logand s5-4 (collide-status touch-actor)) (collide-status touch-actor)) (format sv-16 "touch-actor ") ) (if (= (logand (collide-status probe-hit) s5-4) (collide-status probe-hit)) (format sv-16 "probe-hit ") ) (if (= (logand s5-4 (collide-status stuck)) (collide-status stuck)) (format sv-16 "stuck ") ) (if (= (logand s5-4 (collide-status no-touch)) (collide-status no-touch)) (format sv-16 "no-touch ") ) (if (= (logand s5-4 (collide-status touch-surface)) (collide-status touch-surface)) (format sv-16 "touch-surface ") ) ) (format sv-16 " #x~6X~%" sv-72) ) ((= v1-22 (history-channel friction)) (let ((f30-0 (-> sv-40 vector x))) (format sv-16 "~-15S: ~f~%" (history-channel->string (-> sv-40 channel)) f30-0) ) ) ) ) ) ) #f (label cfg-71) 0 (none) ) ;; WARN: new jak 2 until loop case, check carefully (defun history-draw ((arg0 history-iterator)) (local-vars (sv-16 vector) (sv-20 vector) (sv-24 pat-surface)) (set! sv-16 (the-as vector #f)) (set! sv-20 (the-as vector #f)) (set! sv-24 (new 'static 'pat-surface)) (until #f (let ((s5-0 (update-entries! arg0))) (if (not s5-0) (goto cfg-34) ) (when (logtest? (-> arg0 channel-mask) (ash 1 (-> s5-0 channel))) (let* ((f0-0 (get-age arg0 s5-0)) (v1-8 (the int (lerp 4.0 128.0 f0-0))) ) (case (-> s5-0 channel) (((history-channel trans)) (if sv-16 (add-debug-line #t (bucket-id debug-no-zbuf1) sv-16 (-> s5-0 vector) (the-as rgba (logior #xffff00 (shl v1-8 24))) #f (the-as rgba -1) ) (add-debug-x #t (bucket-id debug-no-zbuf1) (-> s5-0 vector) (the-as rgba (logior #xffff00 (shl v1-8 24)))) ) (set! sv-16 (-> s5-0 vector)) ) (((history-channel intersect)) (if sv-20 (add-debug-line #t (bucket-id debug-no-zbuf1) sv-20 (-> s5-0 vector) (the-as rgba (logior #xffffff (shl v1-8 24))) #f (the-as rgba -1) ) (add-debug-x #t (bucket-id debug-no-zbuf1) (-> s5-0 vector) (the-as rgba (logior #xffffff (shl v1-8 24)))) ) (set! sv-20 (-> s5-0 vector)) ) (((history-channel transv)) (add-debug-vector #t (bucket-id debug-no-zbuf1) (-> s5-0 origin) (-> s5-0 vector) (meters 0.000024414063) (the-as rgba (logior (shl v1-8 24) #xff00)) ) ) (((history-channel transv-in)) (add-debug-vector #t (bucket-id debug-no-zbuf1) (-> s5-0 origin) (-> s5-0 vector) (meters 0.000024414063) (the-as rgba (logior #x408040 (shl v1-8 24))) ) ) (((history-channel transv-out)) (add-debug-vector #t (bucket-id debug-no-zbuf1) (-> s5-0 origin) (-> s5-0 vector) (meters 0.000024414063) (the-as rgba (logior #x404080 (shl v1-8 24))) ) ) (((history-channel local-normal) (history-channel surface-normal)) (let ((t1-7 (logand (the-as uint (-> *pat-mode-info* (-> sv-24 mode) hilite-color)) (the-as uint #xffffffff00ffffff)) ) ) (add-debug-vector #t (bucket-id debug-no-zbuf1) (-> s5-0 origin) (-> s5-0 vector) (meters 1) (the-as rgba (logior t1-7 (shl v1-8 24))) ) ) ) (((history-channel pat)) (set! sv-24 (the-as pat-surface (-> s5-0 vector x))) ) (((history-channel friction)) (let ((f0-3 (-> s5-0 vector x)) (a3-10 (new 'stack-no-clear 'vector)) ) (set-vector! a3-10 0.0 (* -8192.0 f0-3) 0.0 1.0) (add-debug-vector #t (bucket-id debug-no-zbuf1) (-> s5-0 origin) a3-10 (meters 0.00024414062) (the-as rgba (logior #xffffff (shl v1-8 24))) ) ) ) ) ) ) ) ) #f (label cfg-34) 0 (none) )