;;-*-Lisp-*- (in-package goal) ;; name: loader.gc ;; name in dgo: loader ;; dgos: GAME, ENGINE (defmethod inspect load-dir ((obj load-dir)) "Print all the stuff in a load-dir" (format #t "[~8x] ~A~%" obj (-> obj type)) (format #t "~Tlevel: ~A~%" (-> obj unknown)) (format #t "~Tallocated-length: ~D~%" (-> obj string-array allocated-length)) (format #t "~Tlength: ~D~%" (-> obj string-array length)) (dotimes (i (-> obj string-array length)) (format #t "~T [~D] ~S ~A (~D bytes)~%" i (-> obj string-array i) (-> obj data-array i) (mem-size (-> obj data-array i) #f 0)) ) obj ) (defmethod mem-usage load-dir ((obj load-dir) (arg0 memory-usage-block) (arg1 int)) "Get the memory usage data of a load-dir" (set! (-> arg0 length) (max 82 (-> arg0 length))) (set! (-> arg0 data 81 name) "array") (set! (-> arg0 data 81 count) (+ (-> arg0 data 81 count) 1)) (let ((v1-6 (asize-of obj))) (set! (-> arg0 data 81 used) (+ (-> arg0 data 81 used) v1-6)) (set! (-> arg0 data 81 total) (+ (-> arg0 data 81 total) (logand -16 (+ v1-6 15))) ) ) (set! (-> arg0 length) (max 82 (-> arg0 length))) (set! (-> arg0 data 81 name) "array") (set! (-> arg0 data 81 count) (-> arg0 data 81 count)) (let ((v1-15 (asize-of (-> obj string-array)))) (set! (-> arg0 data 81 used) (+ (-> arg0 data 81 used) v1-15)) (set! (-> arg0 data 81 total) (+ (-> arg0 data 81 total) (logand -16 (+ v1-15 15))) ) ) (set! (-> arg0 length) (max 82 (-> arg0 length))) (set! (-> arg0 data 81 name) "array") (set! (-> arg0 data 81 count) (-> arg0 data 81 count)) (let ((v1-24 (asize-of (-> obj data-array)))) (set! (-> arg0 data 81 used) (+ (-> arg0 data 81 used) v1-24)) (set! (-> arg0 data 81 total) (+ (-> arg0 data 81 total) (logand -16 (+ v1-24 15))) ) ) (dotimes (s3-0 (-> obj data-array length)) (mem-usage (-> obj data-array s3-0) arg0 arg1) ) (the-as load-dir #f) ) (defmethod load-to-heap-by-name load-dir-art-group ((obj load-dir-art-group) (art-name string) (do-reload symbol) (heap kheap) (version int)) "Load the art with the given name to the heap and return the art. Won't load a thing if it's already loaded, unless you set do-reload. This is intended for debug only." ;; see if we already have it. (let ((s5-0 (-> obj string-array))) (dotimes (s3-0 (-> s5-0 length)) (when (string= art-name (-> s5-0 s3-0)) (when do-reload ;; we have it, reload it if requested (let ((v1-4 (art-group-load-check art-name heap version))) (if v1-4 (set! (-> obj art-group-array s3-0) v1-4) ) ) ) (return (-> obj art-group-array s3-0)) ) ) ;; nope, we don't have it,add it to the list. (let ((v0-2 (art-group-load-check art-name heap version))) (when v0-2 (set! (-> s5-0 (-> s5-0 length)) art-name) (set! (-> obj art-group-array (-> s5-0 length)) v0-2) (+! (-> s5-0 length) 1) (+! (-> obj art-group-array length) 1) ) v0-2 ) ) ) (defmethod set-loaded-art load-dir-art-group ((obj load-dir-art-group) (arg0 art-group)) "Add some already loaded art to the load-dir." (let ((s4-0 (-> obj string-array))) (dotimes (s3-0 (-> s4-0 length)) (when (string= (-> arg0 name) (-> s4-0 s3-0)) (set! (-> obj art-group-array s3-0) arg0) (return (-> obj art-group-array s3-0)) ) ) (set! (-> s4-0 (-> s4-0 length)) (-> arg0 name)) (set! (-> obj art-group-array (-> s4-0 length)) arg0) (set! (-> s4-0 length) (+ (-> s4-0 length) 1)) ) (set! (-> obj art-group-array length) (+ (-> obj art-group-array length) 1)) arg0 ) (defun drawable-load ((arg0 drawable) (arg1 kheap)) "Load a drawable file. Unused." (cond ((type-type? (-> arg0 type) string) #|(with-sp (protect sp (if (< sp *stack-top*) (set! sp (&+ *kernel-sp* -1024)) )|# (let ((s5-1 (the-as drawable (loado (the-as string arg0) arg1)))) (if (and s5-1 (type-type? (-> s5-1 type) drawable)) (login s5-1) ) ) ;;)) ) ((type-type? (-> arg0 type) drawable) (login arg0) ) ) ) (defun art-load ((arg0 string) (arg1 kheap)) "Load an art file. Unused." #|(with-sp (protect sp (if (< sp *stack-top*) (set! sp (&+ *kernel-sp* -1024)) )|# (let ((s5-0 (the-as art (loado arg0 arg1)))) (if (type-type? (-> s5-0 type) art) (login s5-0) (the-as art #f) ) ) ;;)) ) (defun art-group-load-check ((arg0 string) (arg1 kheap) (arg2 int)) "Load and check an art-group file. this only runs if we're using debug memory." (when *debug-segment* #|(with-sp (protect sp (if (< sp *stack-top*) (set! sp (&+ *kernel-sp* -1024)) )|# (let ((s3-1 (the-as art-group (loado (make-file-name (file-kind art-group) arg0 arg2 #f) arg1)))) (cond ((not s3-1) (format 0 "ERROR: art-group ~A is not a valid file.~%" arg0) (the-as art-group #f) ) ((not (type-type? (-> s3-1 type) art-group)) (format 0 "ERROR: art-group ~A is not a art-group.~%" arg0) (the-as art-group #f) ) ((not (file-info-correct-version? (-> s3-1 info) (file-kind art-group) arg2)) ;; ^ prints a detailed error if it fails. ;;(format 0 "ERROR: art-group ~A is not the correct version.~%" arg0) (the-as art-group #f) ) (else (login s3-1) ) ) ) ;;)) ) ) (defmethod set-pending-file external-art-buffer ((obj external-art-buffer) (arg0 string) (arg1 int) (arg2 handle) (arg3 float)) "Request a new file to be loaded into this buffer." (set! (-> obj pending-load-file) arg0) (set! (-> obj pending-load-file-part) arg1) (set! (-> obj pending-load-file-owner) arg2) (set! (-> obj pending-load-file-priority) arg3) 0 ) (defmethod unlock! external-art-buffer ((obj external-art-buffer)) "Unlock this buffer." (declare (inline)) (set! (-> obj locked?) #f) #f ) (defmethod inactive? external-art-buffer ((obj external-art-buffer)) "Is this buffer inactive?" (declare (inline)) (!= (-> obj status) 'active) ) (defmethod file-status external-art-buffer ((obj external-art-buffer) (name string) (part int)) "Get the status of a file in the buffer. #f = file is not present." (when (and (name= (-> obj pending-load-file) name) (= (-> obj pending-load-file-part) part) ) ;; the file is at least wanting to load (if (and (name= (-> obj load-file) name) (= (-> obj load-file-part) part)) (-> obj status) ;; file is loaded or loading 'pending ;; file has not started loading yet. ) ) ) (defmethod link-art! art-group ((obj art-group)) "Links the elements of this art-group. This will put a reference to this joint animation in the level art group. Level art groups have slots for temporarily loaded joint animations." (when obj (countdown (s5-0 (-> obj length)) (let* ((art-elt (-> obj data s5-0)) (janim (if (and (nonzero? art-elt) (type-type? (-> art-elt type) art-joint-anim)) (the-as art-joint-anim art-elt) )) (success #f) ) (when janim ;; a countdown with a label right at the start (let ((s3-1 3)) (while (begin (label cfg-22) (nonzero? s3-1) ) ;; loop over levels, looking for the master art group for this joint animation. (+! s3-1 -1) (let ((janim-group (art-group-get-by-name (-> *level* level s3-1) (-> janim master-art-group-name)))) (when janim-group (cond ((and (< (-> janim master-art-group-index) (-> janim-group length)) ;; index is valid (not (-> janim-group data (-> janim master-art-group-index))) ;; doesn't already have it loaded ) ;; link! (set! (-> janim-group data (-> janim master-art-group-index)) janim) (set! success #t) ) (else ;; if the specified index is no good, just try looking for somewhere else. (countdown (a0-14 (-> janim-group length)) (when (not (-> janim-group data a0-14)) ;; found an empty one! (set! (-> janim-group data a0-14) janim) (set! success #t) (goto cfg-22) ) ) ) ) ) ) ) ) (if (not success) (format 0 "ERROR: ~A could not find a master slot to link for ~A.~%" (-> obj name) janim) ) ) ) ) ) obj ) (defmethod unlink-art! art-group ((obj art-group)) "Unlinks the elements of this art-group. This will undo the link-art! function." (when obj (countdown (s5-0 (-> obj length)) (let* ((art-elt (-> obj data s5-0)) (janim (if (and (nonzero? art-elt) (type-type? (-> art-elt type) art-joint-anim)) (the-as art-joint-anim art-elt) )) (success #f) ) (when janim (let ((s2-0 3)) (while (begin (label cfg-16) (nonzero? s2-0) ) (+! s2-0 -1) (let ((janim-group (art-group-get-by-name (-> *level* level s2-0) (-> janim master-art-group-name)))) (when janim-group (countdown (a0-5 (-> janim-group length)) (when (= janim (-> janim-group data a0-5)) (set! (-> janim-group data a0-5) #f) (set! success #t) (goto cfg-16) ) ) ) ) ) ) (if (not success) (format 0 "ERROR: ~A could not find a master slot to unlink for ~A.~%" (-> obj name) janim) ) ) ) ) ) 0 ) (defmethod link-file external-art-buffer ((obj external-art-buffer) (ag art-group)) "Link the art-group and set it to this buffer's art group." (when ag (link-art! ag) (set! (-> obj art-group) ag) ) ag ) (defmethod unlink-file external-art-buffer ((obj external-art-buffer) (ag art-group)) "Unlink the art-group and remove this buffer's art group." (when ag (unlink-art! ag) (set! (-> obj art-group) #f) ) 0 ) (defmethod update external-art-buffer ((obj external-art-buffer)) "Update this buffer." (when (or (not (name= (-> obj pending-load-file) (-> obj load-file))) (!= (-> obj pending-load-file-part) (-> obj load-file-part)) ) ;; we're loading a different file, or a different part of a file (unless (handle->process (-> obj pending-load-file-owner)) ;; nobody owns the loading file so we can discard it (set! (-> obj pending-load-file) #f) (set! (-> obj pending-load-file-part) -1) (set! (-> obj pending-load-file-owner) (the-as handle #f)) (set! (-> obj pending-load-file-priority) SPOOL_PRIORITY_LOWEST) ) (when (= (-> obj status) 'initialize) ;; we need to initialize the heap (let ((v1-11 (-> obj heap))) ;; Scary: this is a hard coded address that points to the kernel memory. ;; it turns out the kernel doesn't need this. So we can use it! (set! (-> v1-11 base) (the-as pointer (+ #x84000 (* #x3dc00 (-> obj index))))) (set! (-> v1-11 current) (-> v1-11 base)) (set! (-> v1-11 top-base) (&+ (-> v1-11 base) #x3dc00)) (set! (-> v1-11 top) (-> v1-11 top-base)) ) (set! (-> obj status) 'inactive) ;; heap is now allocated, but there is no data to use ) (cond ((-> obj load-file) ;; the buffer is working on a file (if (= (-> obj status) 'loading) ;; something else is already loading, cancel that because we want something else (str-load-cancel) ) ;; now nothing is loaded! (set! (-> obj load-file) #f) (set! (-> obj load-file-part) -1) (set! (-> obj load-file-owner) (the-as handle #f)) (set! (-> obj load-file-priority) SPOOL_PRIORITY_LOWEST) ;; on the next time through, we will set the actual load file. ) (else ;; we have officially chosen to load this file (set! (-> obj load-file) (-> obj pending-load-file)) (set! (-> obj load-file-part) (-> obj pending-load-file-part)) (set! (-> obj load-file-owner) (-> obj pending-load-file-owner)) (set! (-> obj load-file-priority) (-> obj pending-load-file-priority)) ) ) ) (label cfg-18) (cond ((-> obj load-file) ;; something is being worked on (case (-> obj status) (('active 'reserved) ;; file is loaded and usable (or reserved) ) (('error) ;; oops an error happened. make this buffer unusable now. (set! (-> obj status) 'inactive) (set! (-> obj load-file) #f) (set! (-> obj load-file-part) -1) (set! (-> obj load-file-owner) (the-as handle #f)) (set! (-> obj load-file-priority) SPOOL_PRIORITY_LOWEST) (set! (-> obj pending-load-file) #f) (set! (-> obj pending-load-file-part) -1) (set! (-> obj pending-load-file-owner) (the-as handle #f)) (set! (-> obj pending-load-file-priority) SPOOL_PRIORITY_LOWEST) (set! (-> obj art-group) #f) ) (('inactive) ;; no usable data here, fill the buffer (kheap-reset (-> obj heap)) (cond ((string= (-> obj load-file) "reserved") ;; we want to reserve this buffer for something (not loading an str file) (cond ((-> *art-control* reserve-buffer) (format 0 "ERROR: trying double reserve ~A when ~A is reserved~%" obj (-> *art-control* reserve-buffer)) ) (else (set! (-> obj status) 'reserved) (set! (-> *art-control* reserve-buffer) obj) ;; this buffer is reserved ) ) ) ((and (!= (-> *level* loading-level) (-> *level* level-default)) (< (meters 20) (-> obj load-file-priority)) ) ;; unused cond ) ((str-load (-> obj load-file) (-> obj load-file-part) (the pointer (align64 (-> obj heap current))) #x3fc00) ;; try to start load ;; load has started!! (set! (-> obj status) 'loading) ) ) ) (('loading) ;; loading... (case (str-load-status (&-> obj len)) (('error) ;; something went wrong. oh well. (set! (-> obj status) 'error) ) (('busy) ;; loading. we have nothing to do. ) (else ;; done!! ;; not sure it is a good idea to assume that this is a success... (set! (-> obj buf) (the pointer (align64 (-> obj heap current)))) (set! (-> obj status) 'loaded) (goto cfg-18) ;; go back and check status again! ) ) ) (('loaded) ;; file is loaded. link it and see if we're good (let ((a0-37 (-> obj buf))) (set! (-> obj art-group) (the-as art-group (link (the-as pointer a0-37) (-> obj load-file data) (-> obj len) (-> obj heap) 0))) ) (let ((s4-0 (-> obj art-group)) (s3-0 (-> obj load-file)) ) (cond ((not s4-0) (format 0 "ERROR: art-group ~A part ~D is not a valid file.~%" s3-0 (-> obj load-file-part)) (set! (-> obj status) 'error) ) ((not (type-type? (-> s4-0 type) art-group)) (format 0 "ERROR: art-group ~A part ~D is not a art-group.~%" s3-0 (-> obj load-file-part)) (set! (-> obj status) 'error) ) ((not (file-info-correct-version? (-> s4-0 info) (file-kind art-group) 0)) ;;(format 0 "ERROR: art-group ~A part ~D is the wrong version.~%" s3-0 (-> obj load-file-part)) (set! (-> obj status) 'error) ) (else (login s4-0) (set! (-> obj status) 'locked) ;; make file ready to be used ) ) ) ) (('locked) ;; this buffer is locked and needs to be unlocked before it can be used. ;; only one buffer can be active at a time. The other buffer is locked to prevent it from activating. (when (and (not (-> obj locked?)) (handle->process (-> obj load-file-owner))) ;; we want to be used, unlock this buffer and lock the other just in case. (link-file obj (-> obj art-group)) (set! (-> obj other locked?) #t) ;; prevent it from becoming active (set! (-> obj status) 'active) (goto cfg-18) ) ) ) ) (else ;; we want to get rid of the file! (case (-> obj status) (('initialize) ;; this was done earlier ) (('reserved) ;; this buffer is reserved (cond ((= (-> *art-control* reserve-buffer) obj) ;; yep it's this one! (set! (-> *art-control* reserve-buffer) #f) (set! (-> obj status) 'inactive) ) (else (format 0 "ERROR: trying tro free ~A when ~A is reserved~%" obj (-> *art-control* reserve-buffer)) ) ) ) (('active) ;; buffer is in use. not anymore! (unlink-file obj (-> obj art-group)) (let ((v1-70 (-> obj heap))) (set! (-> v1-70 current) (-> v1-70 base)) ) (set! (-> obj art-group) #f) (set! (-> obj status) 'inactive) ;; if the other is locked due to us, unlock it, then update it so it activates. (when (-> obj other locked?) (unlock! (-> obj other)) (update (-> obj other)) ) ) (else ;; some other scenario, just get rid of the whole thing. (let ((v1-79 (-> obj heap))) (set! (-> v1-79 current) (-> v1-79 base)) ) (set! (-> obj art-group) #f) (set! (-> obj status) 'inactive) ) ) ) ) 0 ) ;; start loading a spooled anim if we think one is about to be used, e.g. when approaching a fuel cell or npc ;; (some processes may want to wait for the stream to be preloaded, which won't happen with this disabled) (define *preload-spool-anims* #t) (defmethod file-status external-art-control ((obj external-art-control) (name string) (part int)) "Get the status of a file in this art control. #f = file not found" (dotimes (i 2) (awhen (file-status (-> obj buffer i) name part) (return it) ) ) #f ) (defmethod update external-art-control ((obj external-art-control) (debug-print symbol)) "Update this external-art-control. This validates the spool buffers, sorts the spools, advances str-play-queue, and does some other things. If debug-print, also prints some text to the display console" ;; if somebody wants a reserve buffer, they will set this to 1. (if (nonzero? (-> obj reserve-buffer-count)) (spool-push obj "reserved" 0 *dproc* (if (-> obj reserve-buffer) -110.0 -0.5) ) ) ;; frame-lock will get set to #t if something is assigned to this buffer in this update. (dotimes (v1-5 2) (set! (-> obj buffer v1-5 frame-lock) #f) ) ;; buffers assigned from this call to update (dotimes (v1-8 3) (set! (-> obj rec v1-8 buf2) #f) ) ;; update existing buffers from their recs (dotimes (s4-0 2) (let ((s3-0 (-> obj rec s4-0))) (when (-> s3-0 name) ;; iterate over the two buffers (dotimes (s2-0 2) (when (and (file-status (-> obj buffer s2-0) (-> s3-0 name) (-> s3-0 parts)) ;; this buffer holds the file for the rec (not (-> obj buffer s2-0 frame-lock)) ;; and nothing has frame-locked this buffer ) ;; so we frame lock it to prevent it from being kicked out (set! (-> obj buffer s2-0 frame-lock) #t) ;; remember what buffer (set! (-> s3-0 buf2) (-> obj buffer s2-0)) ;; update owner and priority. (set! (-> obj buffer s2-0 pending-load-file-owner) (-> s3-0 owner)) (set! (-> obj buffer s2-0 load-file-owner) (-> s3-0 owner)) (set! (-> obj buffer s2-0 pending-load-file-priority) (-> s3-0 priority)) (set! (-> obj buffer s2-0 load-file-priority) (-> s3-0 priority)) (goto cfg-24) ;; buffer found, move on. ) ) ) ) (label cfg-24) ) ;; preload recs ;; iterate over recs (dotimes (s4-1 2) (let ((s3-1 (-> obj rec s4-1))) ;; rec wants to load something, but doesn't have a buffer already (when (and (-> s3-1 name) (not (-> s3-1 buf2))) ;; skip if we aren't preloading, or have a positive priority. (if (and (not *preload-spool-anims*) (>= (-> s3-1 priority) 0.0)) ;; not in use, move on (goto cfg-46) ) ;; search for a buffer for preloading (dotimes (s2-1 2) ;; can't steal one that's already assigned (when (not (-> obj buffer s2-1 frame-lock)) ;; do the assignment! (set! (-> obj buffer s2-1 frame-lock) #t) (set-pending-file (-> obj buffer s2-1) (-> s3-1 name) (-> s3-1 parts) (-> s3-1 owner) (-> s3-1 priority)) (set! (-> s3-1 buf2) (-> obj buffer s2-1)) (goto cfg-46) ) ) ) ) (label cfg-46) ) ;; this part is a bit confusing, but I think it basically kicks out the lowest priority thing. (when (not (-> obj reserve-buffer)) (let ((s4-2 (-> obj rec 0 buf2))) ;; top priority buffer (if (and s4-2 (-> s4-2 locked?) (not (string= (-> s4-2 pending-load-file) "reserved")) (not (string= (-> s4-2 other pending-load-file) "reserved")) ) (set-pending-file (-> s4-2 other) (the-as string #f) -1 (the-as handle #f) SPOOL_PRIORITY_LOWEST) ) ) ) ;; update the buffers (dotimes (s4-3 2) (update (-> obj buffer s4-3)) ) ;; sort spool anims. (let ((s4-4 (the-as spool-anim #f))) (countdown (s3-2 3) (if (and (-> obj rec s3-2 name) (not (name= (-> obj rec s3-2 name) (-> obj active-stream))) ) (set! s4-4 (-> obj rec 0)) ) ) (if (and (-> obj preload-stream name) (or (not s4-4) (< (-> obj preload-stream priority) (-> s4-4 priority))) ) (set! s4-4 (-> obj preload-stream)) ) (cond (s4-4 (mem-copy! (&-> (-> obj last-preload-stream) type) (&-> s4-4 type) (size-of spool-anim)) (str-play-queue (-> s4-4 name)) ) (else (set! (-> obj last-preload-stream name) #f) (set! (-> obj last-preload-stream owner) (the-as handle #f)) ) ) ) (when (and debug-print *display-art-control*) (dotimes (s5-1 3) (format *stdcon* "rec ~d ~S ~D ~f ~A~%" s5-1 (-> obj rec s5-1 name) (-> obj rec s5-1 parts) (-> obj rec s5-1 priority) (handle->name (-> obj rec s5-1 owner))) ) (dotimes (s5-2 2) (format *stdcon* "buf ~d ~C ~S ~D ~A ~A~%" s5-2 (if (-> obj buffer s5-2 locked?) #\l #\\s) (-> obj buffer s5-2 pending-load-file) (-> obj buffer s5-2 pending-load-file-part) (-> obj buffer s5-2 status) (handle->name (-> obj buffer s5-2 pending-load-file-owner))) ) (format *stdcon* " a: ~S~%" (-> obj active-stream)) (format *stdcon* " p: ~S ~A~%" (-> obj preload-stream name) (handle->name (-> obj preload-stream owner))) (format *stdcon* " q: ~S ~A~%" (-> obj last-preload-stream name) (handle->name (-> obj last-preload-stream owner))) ) 0 ) (defmethod none-reserved? external-art-control ((obj external-art-control)) "are there any reserved buffers?" (declare (inline)) (zero? (-> obj reserve-buffer-count)) ) (defmethod reserve-alloc external-art-control ((obj external-art-control)) "Reserve a buffer!" (set! (-> obj reserve-buffer-count) 1) (if (-> obj reserve-buffer) (-> obj reserve-buffer heap) ) ) (defmethod reserve-free external-art-control ((obj external-art-control) (arg0 kheap)) "Free the reserved buffer!" (cond ((none-reserved? obj) (format 0 "ERROR: illegal attempt to free a buffer #x~X which had not been reserved (none reserved).~%" arg0) ) ((not (-> obj reserve-buffer)) (set! (-> obj reserve-buffer-count) 0) ) ((= (-> obj reserve-buffer heap) arg0) (set-pending-file (-> obj reserve-buffer) (the-as string #f) -1 (the-as handle #f) SPOOL_PRIORITY_LOWEST) (update (-> obj reserve-buffer)) (set! (-> obj reserve-buffer-count) 0) ) (else (format 0 "ERROR: illegal attempt to free a buffer #x~X which had not been reserved (buffer unknown).~%" arg0) ) ) 0 ) (defmethod clear-rec external-art-control ((obj external-art-control)) "Clears the recent spool anims from the art control." (cond ((!= *master-mode* 'game) (dotimes (s5-0 3) (when (name= (-> obj rec s5-0 name) "reserved") (case s5-0 ((0) (mem-copy! (&-> obj rec 0 type) (&-> obj rec 1 type) (size-of spool-anim)) (mem-copy! (&-> obj rec 1 type) (&-> obj rec 2 type) (size-of spool-anim)) ) ((1) (mem-copy! (&-> obj rec 1 type) (&-> obj rec 2 type) (size-of spool-anim)) ) ) (set! (-> obj rec 2 type) spool-anim) (set! (-> obj rec 2 name) #f) (set! (-> obj rec 2 priority) SPOOL_PRIORITY_LOWEST) (set! (-> obj rec 2 owner) (the-as handle #f)) ) ) ) (else (dotimes (v1-19 3) (set! (-> obj rec v1-19 type) spool-anim) (set! (-> obj rec v1-19 name) #f) (set! (-> obj rec v1-19 priority) SPOOL_PRIORITY_LOWEST) (set! (-> obj rec v1-19 owner) (the-as handle #f)) ) (set! (-> obj preload-stream type) spool-anim) (set! (-> obj preload-stream name) #f) (set! (-> obj preload-stream priority) SPOOL_PRIORITY_LOWEST) (set! (-> obj preload-stream owner) (the-as handle #f)) ) ) 0 ) (defmacro spool-calc-priority (priority proc) "Check the priority of a spool anim and recalculate it if needed. It will be the same as distance between target and the requesting process. priority = var that stores priority proc = a process to recalc from" `(when (and (= ,priority SPOOL_PRIORITY_RECALC) ,proc) (let ((target-trans (target-pos 0))) (set! ,priority (vector-vector-distance target-trans (-> (the-as process-drawable ,proc) root trans))) ) ) ) (defmethod try-preload-stream external-art-control ((obj external-art-control) (arg0 string) (arg1 int) (arg2 process) (arg3 float)) "Set a new stream to be preloaded, if appropriate." (spool-calc-priority arg3 arg2) (unless (and (-> obj preload-stream name) (>= arg3 (-> obj preload-stream priority)) ) (set! (-> obj preload-stream name) arg0) (set! (-> obj preload-stream parts) arg1) (set! (-> obj preload-stream priority) arg3) (set! (-> obj preload-stream owner) (process->handle arg2)) ) 0 ) (defmethod spool-push external-art-control ((obj external-art-control) (name string) (part int) (proc process) (priority float)) "Push a spool-anim to the spool array. There are only space for three, and only the three highest priority spool anims will be kept. (lowest priority = top)" (spool-calc-priority priority proc) ;; if this spool-anim already exists, pop it from the rec list (cond ((and (= part (-> obj rec 0 parts)) (name= name (-> obj rec 0 name))) (if (>= priority (-> obj rec 0 priority)) (return (the-as int #f)) ) ;; first spool. copy 1st <- 2nd and 2nd <- 3rd, 3rd will be wiped (mem-copy! (&-> obj rec 0 type) (&-> obj rec 1 type) (size-of spool-anim)) (mem-copy! (&-> obj rec 1 type) (&-> obj rec 2 type) (size-of spool-anim)) (set! (-> obj rec 2 name) #f) (set! (-> obj rec 2 owner) (the-as handle #f)) ) ((and (= part (-> obj rec 1 parts)) (name= name (-> obj rec 1 name))) (if (>= priority (-> obj rec 1 priority)) (return (the-as int #f)) ) ;; second spool. copy 2nd <- 3rd, 3rd will be wiped (mem-copy! (&-> obj rec 1 type) (&-> obj rec 2 type) (size-of spool-anim)) (set! (-> obj rec 2 name) #f) (set! (-> obj rec 2 owner) (the-as handle #f)) ) ((and (= part (-> obj rec 2 parts)) (name= name (-> obj rec 2 name))) (if (>= priority (-> obj rec 2 priority)) (return (the-as int #f)) ) ;; third spool. 3rd will be wiped (set! (-> obj rec 2 name) #f) (set! (-> obj rec 2 owner) (the-as handle #f)) ) ) ;; if it's top 3 priority, push this spool-anim to the rec list (cond ((< priority (-> obj rec 0 priority)) ;; 1st place! (mem-copy! (&-> obj rec 2 type) (&-> obj rec 1 type) (size-of spool-anim)) (mem-copy! (&-> obj rec 1 type) (&-> obj rec 0 type) (size-of spool-anim)) (set! (-> obj rec 0 name) name) (set! (-> obj rec 0 parts) part) (set! (-> obj rec 0 priority) priority) (set! (-> obj rec 0 owner) (process->handle proc)) ) ((< priority (-> obj rec 1 priority)) ;; 2nd place. (mem-copy! (&-> obj rec 2 type) (&-> obj rec 1 type) (size-of spool-anim)) (set! (-> obj rec 1 name) name) (set! (-> obj rec 1 parts) part) (set! (-> obj rec 1 priority) priority) (set! (-> obj rec 1 owner) (process->handle proc)) ) ((< priority (-> obj rec 2 priority)) ;; 3rd place... (set! (-> obj rec 2 name) name) (set! (-> obj rec 2 parts) part) (set! (-> obj rec 2 priority) priority) (set! (-> obj rec 2 owner) (process->handle proc)) ) ) 0 ) (defun-extern level-hint-surpress! none) ;; ? TODO (define-extern ja-channel-push! (function int int int :behavior process-drawable)) (define-extern ja-channel-set! (function int int :behavior process-drawable)) (define-extern joint-control-channel-group-eval! (function joint-control-channel art-joint-anim (function joint-control-channel float float float) int)) (define-extern joint-control-channel-group! (function joint-control-channel art-joint-anim (function joint-control-channel float float float) int)) (define-extern ja-aframe-num (function int float :behavior process-drawable)) ;; this function is modified to work without sound. (define *str-pos-hack* 0) (define *str-play-speed* 17) (define-extern ja-abort-spooled-anim (function spool-anim art-joint-anim int int :behavior process-drawable)) (defbehavior ja-play-spooled-anim process-drawable ((arg0 spool-anim) (arg1 art-joint-anim) (arg2 art-joint-anim) (arg3 (function process-drawable symbol))) (local-vars (v0-39 int) (spool-part int) (sv-24 float) (old-skel-status janim-status) (sv-32 int) (sv-40 int) (sv-48 int) (sv-56 int) (spool-sound sound-id) (sv-72 int) ) (set! *str-pos-hack* 0) (set! spool-part 0) (set! sv-24 -17.0) (set! old-skel-status (-> self skel status)) (set! sv-32 -2) (set! sv-40 0) (set! sv-48 0) (set! sv-56 0) (set! spool-sound (new-sound-id)) (backup-load-state-and-set-cmds *load-state* (-> arg0 command-list)) (set-setting! *setting-control* self 'spooling (the-as symbol (process->ppointer self)) 0.0 0) (logior! (-> self skel status) (janim-status inited drawn done)) (kill-current-level-hint '() '() 'die) (level-hint-surpress!) (copy-settings-from-target! *setting-control*) (when (or (handle->process (-> *art-control* spool-lock)) (!= *master-mode* 'game)) (cond (arg1 (when (!= (if (> (-> self skel active-channels) 0) (-> self skel root-channel 0 frame-group) ) arg1 ) (ja-channel-push! 1 15) (let ((s2-0 (-> self skel root-channel 0))) (joint-control-channel-group-eval! s2-0 arg1 num-func-identity) (set! (-> s2-0 frame-num) 0.0) ) ) ) (else (ja-channel-set! 0) ) ) (while (or (handle->process (-> *art-control* spool-lock)) (!= *master-mode* 'game)) (format #t "WARNING: ---------------------> loader stall on lock~%") (if (arg3 self) (goto cfg-88) ) (spool-push *art-control* (-> arg0 name) spool-part self -9.0) (suspend) (when arg1 (let ((a0-17 (-> self skel root-channel 0))) (set! (-> a0-17 param 0) 1.0) (joint-control-channel-group-eval! a0-17 (the-as art-joint-anim #f) num-func-loop!) ) ) ) ) (let ((v1-46 (process->ppointer self))) (set! (-> *art-control* spool-lock) (new 'static 'handle :process v1-46 :pid (-> (the-as process (-> v1-46 0)) pid)) ) ) (set! sv-48 (-> *display* base-frame-counter)) (while (< spool-part (-> arg0 parts)) (spool-push *art-control* (-> arg0 name) spool-part self -20.0) (update *art-control* #f) (spool-push *art-control* (-> arg0 name) spool-part self -20.0) (when (!= (file-status *art-control* (-> arg0 name) spool-part) 'active) (cond (arg1 (when (!= (if (> (-> self skel active-channels) 0) (-> self skel root-channel 0 frame-group) ) arg1 ) (ja-channel-set! 1) (let ((s2-2 (-> self skel root-channel 0))) (joint-control-channel-group-eval! s2-2 arg1 num-func-identity) (set! (-> s2-2 frame-num) 0.0) ) ) ) (else (ja-channel-set! 0) ) ) (while (!= (file-status *art-control* (-> arg0 name) spool-part) 'active) (if (arg3 self) (goto cfg-88) ) (spool-push *art-control* (-> arg0 name) spool-part self -20.0) (format #t "WARNING: ---------------------> loader stall on art ~S ~D~%" (-> arg0 name) spool-part) (suspend) (when arg1 (let ((a0-37 (-> self skel root-channel 0))) (set! (-> a0-37 param 0) 1.0) (joint-control-channel-group-eval! a0-37 (the-as art-joint-anim #f) num-func-loop!) ) ) ) ) (spool-push *art-control* (-> arg0 name) spool-part self -20.0) (let ((s2-4 (the-as art-joint-anim (lookup-art (-> self draw art-group) (-> arg0 name) art-joint-anim)))) (cond (s2-4 (ja-channel-set! 1) (let ((a0-42 (-> self skel root-channel 0))) (set! (-> a0-42 frame-group) s2-4) (set! (-> a0-42 param 0) (the float (+ (-> s2-4 data 0 length) -1))) (set! (-> a0-42 param 1) 1.0) (set! (-> a0-42 frame-num) 0.0) (joint-control-channel-group! a0-42 s2-4 num-func-seek!) ) (when (zero? spool-part) (str-play-async (-> arg0 name) spool-sound) ;; hack! ;;(set! *str-pos-hack* 0) ;; (set! (-> *art-control* active-stream) (-> arg0 name)) ) (let* ((f30-0 (* 0.05859375 (-> s2-4 speed))) (f28-0 (+ sv-24 (/ (the float (+ (-> s2-4 data 0 length) -1)) f30-0))) ) ;;(set! sv-72 (current-str-pos spool-sound)) (set! sv-72 *str-pos-hack*) (set! sv-40 (-> *display* base-frame-counter)) (until (>= (the float v0-39) f28-0) (+! *str-pos-hack* *str-play-speed*) (if (= (-> self skel root-channel 0) (-> self skel channel)) (logior! (-> self skel status) (janim-status spool)) ) (if (or (arg3 self) (and (<= sv-72 0) (>= (- (-> *display* base-frame-counter) sv-40) 1200)) (and (< 300 sv-56) (<= sv-72 0)) ) (goto cfg-88) ) (spool-push *art-control* (-> arg0 name) spool-part self -20.0) (if (< (+ spool-part 1) (-> arg0 parts)) (spool-push *art-control* (-> arg0 name) (+ spool-part 1) self -10.0) (logclear! (-> self skel status) (janim-status done)) ) (execute-commands-up-to *load-state* (ja-aframe-num 0)) (cond ((and (< sv-32 sv-72) #|(= (current-str-id) spool-sound)|#) (set! sv-56 (+ sv-56 (- (-> *display* base-frame-counter) (-> *display* old-base-frame-counter)))) (set! sv-40 (-> *display* base-frame-counter)) ) (else 0 ) ) (set! sv-32 sv-72) (set! sv-48 (-> *display* base-frame-counter)) (suspend) (let ((f0-14 (* (- (the float *str-pos-hack* #|(current-str-pos spool-sound)|#) sv-24) f30-0)) (a0-69 (-> self skel root-channel 0)) ) (set! (-> a0-69 param 0) (the float (+ (-> a0-69 frame-group data 0 length) -1))) (set! (-> a0-69 param 1) 1.0) (set! (-> a0-69 frame-num) f0-14) (joint-control-channel-group! a0-69 (the-as art-joint-anim #f) num-func-seek!) ) (set! v0-39 *str-pos-hack* #|(current-str-pos spool-sound)|#) (set! sv-72 v0-39) ) (set! sv-24 f28-0) ) (logclear! (-> self skel status) (janim-status spool)) ) (else (format 0 "ERROR: ~A in spool anim loop for ~A ~D, but not loaded.~" self (-> arg0 name) spool-part) (goto cfg-88) ) ) ) (set! spool-part (+ spool-part 1)) ) (set! spool-part (+ spool-part -1)) (label cfg-88) (ja-abort-spooled-anim arg0 arg2 spool-part) 0 ) (defbehavior ja-abort-spooled-anim process-drawable ((arg0 spool-anim) (arg1 art-joint-anim) (arg2 int)) "Abort a spooled animation." (restore-load-state-and-cleanup *load-state*) (str-play-stop (-> arg0 name)) (set! (-> *art-control* active-stream) #f) (logclear! (-> self skel status) (janim-status drawn done)) (if (zero? (logand (-> self skel status) (janim-status inited))) (logclear! (-> self skel status) (janim-status inited)) ) (clear-pending-settings-from-process *setting-control* self 'spooling) (cond ((and arg1 (>= arg2 0)) (ja-channel-push! 1 30) (set! (-> self skel root-channel 0 frame-group) arg1) (while (!= (-> self skel root-channel 0) (-> self skel channel)) (spool-push *art-control* (-> arg0 name) arg2 self -20.0) (suspend) ;; TODO macro (let ((a0-12 (-> self skel root-channel 0))) (set! (-> a0-12 param 0) (the float (+ (-> a0-12 frame-group data 0 length) -1))) (set! (-> a0-12 param 1) 1.0) (joint-control-channel-group-eval! a0-12 (the-as art-joint-anim #f) num-func-seek!) ) ) ) (else (ja-channel-set! 0) ) ) (set! (-> *art-control* spool-lock) (the-as handle #f)) 0 ) (if (zero? *art-control*) (set! *art-control* (new 'global 'external-art-control)) )