jak-project/goal_src/engine/load/load-dgo.gc

134 lines
3.9 KiB
Common Lisp
Raw Normal View History

;;-*-Lisp-*-
2020-09-04 14:44:23 -04:00
(in-package goal)
;; name: load-dgo.gc
;; name in dgo: load-dgo
;; dgos: GAME, ENGINE
(deftype load-dgo-msg (structure)
((rsvd uint16 :offset-assert 0)
(result uint16 :offset-assert 2)
(b1 uint32 :offset-assert 4)
(b2 uint32 :offset-assert 8)
(bt uint32 :offset-assert 12)
;(name uint128 :offset-assert 16)
(name uint8 16 :offset-assert 16)
(address uint32 :offset 4)
)
:method-count-assert 9
:size-assert #x20
:flag-assert #x900000020
)
#|
struct RPC_Dgo_Cmd {
uint16_t rsvd;
uint16_t result;
uint32_t buffer1;
uint32_t buffer2;
uint32_t buffer_heap_top;
char name[16];
};
|#
(deftype load-chunk-msg (structure)
((rsvd uint16 :offset-assert 0)
(result uint16 :offset-assert 2)
(address pointer :offset-assert 4)
(section uint32 :offset-assert 8)
(maxlen uint32 :offset-assert 12)
(id uint32 :offset 4)
(basename uint8 48 :offset-assert 16)
)
:method-count-assert 9
:size-assert #x40
:flag-assert #x900000040
)
#|
struct RPC_Str_Cmd {
u16 rsvd; // 0, seems unused
u16 result; // 2, return code. see STR_RPC_RESULT_XXX
u32 ee_addr; // 4, GOAL address to load to.
s32 chunk_id; // 8, chunk ID for chunked file. Use -1 to load a non-chunked file, which gets the
// whole file.
u32 length; // 12, length that was actually loaded
char name[64]; // file name
};
|#
(deftype dgo-header (structure)
((length uint32 :offset-assert 0)
(rootname uint8 60 :offset-assert 4)
)
:method-count-assert 9
:size-assert #x40
:flag-assert #x900000040
)
#|
struct DgoHeader {
u32 object_count;
char name[60];
};
|#
(define-extern *load-dgo-rpc* rpc-buffer-pair)
(when (= 0 (the int *load-dgo-rpc*))
;; we need to allocate the rpc buffers
(set! *load-dgo-rpc* (new 'global 'rpc-buffer-pair (the uint 32) (the uint 1) 3)) ;; todo, constants
(define *load-str-rpc* (new 'global 'rpc-buffer-pair (the uint 64) (the uint 1) 4)) ;; todo, constants
(define *play-str-rpc* (new 'global 'rpc-buffer-pair (the uint 64) (the uint 2) 5))
(define *load-str-lock* '#f)
(define *que-str-lock* '#f)
(define *dgo-name* (new 'global 'string 64 (the string '#f)))
)
(defun str-load ((name string) (chunk-id int) (address pointer) (len int))
"Begin a streaming load if possible!
We must be able to grab the lock, and no streaming load in progress.
Return if we actually start the load."
;; call method 13
(when (or (check-busy *load-str-rpc*)
*load-str-lock*
)
(return-from #f '#f)
)
;; ok, we are good to start a load. begin by adding an element to the RPC buffer
(let ((cmd (the load-chunk-msg (add-element *load-str-rpc*))))
(set! (-> cmd result) 666)
(set! (-> cmd address) address)
(set! (-> cmd section) chunk-id)
(set! (-> cmd maxlen) len)
(charp<-string (-> cmd basename) name)
(call *load-str-rpc* (the uint 0) (the pointer cmd) (the uint 32))
(set! *load-str-lock* '#t)
(set! *que-str-lock* '#t)
'#t
)
)
(defun str-load-status ((length-out (pointer int32)))
"Check the status of the str load.
The 'busy status indicates it is still going
The 'error status indicates the load failed.
The 'complete status means the load is finished, and length-out contains the loaded length."
;; still going..
(if (check-busy *load-str-rpc*)
(return-from #f 'busy)
)
;; not busy, we can free the lock
(set! *load-str-lock* '#f)
(set! *que-str-lock* '#t)
;; grab the response
(let ((response (the load-chunk-msg (pop-last-received *load-str-rpc*))))
(if (= 1 (-> response result))
(return-from #f 'error)
)
;; no error!
(set! (-> length-out) (the int (-> response maxlen)))
'complete
)
)