;;-*-Lisp-*-
(in-package goal)

;; name: loader-h.gc
;; name in dgo: loader-h
;; dgos: ENGINE, GAME

;; TODO: document this stuff when doing loader.gc

(declare-type spool-anim basic)
(declare-type art-joint-anim art-element)
(declare-type external-art-buffer basic)
(declare-type process-drawable process)
(define-extern external-art-buffer-init (function external-art-buffer int))
(define-extern ja-abort-spooled-anim (function spool-anim art-joint-anim int int :behavior process-drawable))
(declare-type art basic)
(declare-type art-group art)
(define-extern *stack-top* pointer)

;; DECOMP BEGINS

;; load-dir is an array of references to loaded things.
;; it's used to handle art groups that are loaded as part of a level load.
(deftype load-dir (basic)
  ((lev           level)
   (string-array  (array string))
   (data-array    (array basic))
   )
  (:methods
    (new (symbol type int level) _type_)
    (load-to-heap-by-name (_type_ string symbol kheap int) art-group)
    (set-loaded-art (_type_ art-group) art-group)
    )
  )

;; specialization of load-dir for art-groups specificially.
(deftype load-dir-art-group (load-dir)
  ((art-group-array  (array art-group)  :overlay-at data-array)
   )
  (:methods
    (new (symbol type int level) _type_)
    )
  )

(defmethod new load-dir ((allocation symbol) (type-to-make type) (arg0 int) (arg1 level))
  "Allocate a new load-dir that can hold arg0 items, for the given level."
  (let ((s4-0 (object-new allocation type-to-make (the-as int (-> type-to-make size)))))
    (set! (-> s4-0 lev) arg1)
    (set! (-> s4-0 string-array)
          (the-as (array string) ((method-of-type array new) allocation array string arg0))
          )
    (set! (-> s4-0 string-array length) 0)
    (set! (-> s4-0 data-array) (the-as (array basic) ((method-of-type array new) allocation array basic arg0)))
    (set! (-> s4-0 data-array length) 0)
    s4-0
    )
  )

(defmethod new load-dir-art-group ((allocation symbol) (type-to-make type) (arg0 int) (arg1 level))
  "Allocate a new load-dir-art-group that can hold arg0 art-groups, for the given level."
  (let ((v0-0 ((method-of-type load-dir new) allocation type-to-make arg0 arg1)))
    (set! (-> v0-0 data-array content-type) art-group)
    (the-as load-dir-art-group v0-0)
    )
  )

;; an external-art-buffer is a buffer that streamed files use.
(deftype external-art-buffer (basic)
  ((index                       int32)
   (other                       external-art-buffer)
   (status                      symbol)
   (locked?                     symbol)
   (login?                      symbol)
   (frame-lock                  symbol)
   (init-heap                   (function external-art-buffer object))
   (heap                        kheap   :inline)
   (pending-load-file           string)
   (pending-load-file-part      int32)
   (pending-load-file-owner     handle)
   (pending-load-file-priority  float)
   (load-file                   string)
   (load-file-part              int32)
   (load-file-owner             handle)
   (load-file-priority          float)
   (buf                         pointer)
   (len                         int32)
   (art-group                   art-group)
   (art-data                    uint32  :overlay-at art-group)
   )
  (:methods
    (new (symbol type int function symbol) _type_)
    (set-pending-file (_type_ string int handle float) int)
    (update (_type_) int)
    (inactive? (_type_) symbol)
    (file-status (_type_ string int) symbol)
    (link-file (_type_ art-group) art-group)
    (unlink-file (_type_ art-group) int)
    (unlock! (_type_) int)
    )
  )


(defmethod new external-art-buffer ((allocation symbol) (type-to-make type) (arg0 int) (arg1 function) (arg2 symbol))
  "Allocate a new external-art-buffer"
  (let ((v0-0 (object-new allocation type-to-make (the-as int (-> type-to-make size)))))
    (set! (-> v0-0 index) arg0)
    (set! (-> v0-0 init-heap) (the-as (function external-art-buffer object) arg1))
    (set! (-> v0-0 login?) arg2)
    (set! (-> v0-0 load-file) #f)
    (set! (-> v0-0 load-file-part) -1)
    (set! (-> v0-0 load-file-owner) (the-as handle #f))
    (set! (-> v0-0 load-file-priority) 100000000.0)
    (set! (-> v0-0 pending-load-file) #f)
    (set! (-> v0-0 pending-load-file-part) -1)
    (set! (-> v0-0 pending-load-file-owner) (the-as handle #f))
    (set! (-> v0-0 pending-load-file-priority) 100000000.0)
    (set! (-> v0-0 art-group) #f)
    (set! (-> v0-0 status) 'initialize)
    (set! (-> v0-0 locked?) #f)
    (set! (-> v0-0 other) #f)
    v0-0
    )
  )

;; a spool-anim is metadata for an animation that will be loaded in chunks to a pair of external-art-buffers
(deftype spool-anim (basic)
  ((name          string               :offset  16)
   (anim-name     basic)
   (buffer        external-art-buffer  :overlay-at anim-name)
   (parts         int32)
   (hint-id       int32                :overlay-at parts)
   (priority      float)
   (owner         handle)
   (command-list  pair)
   )
  )

;; the external-art-control manages loading chunks from spool-anims to external-art-buffer.
(deftype external-art-control (basic)
  ((buffer                    external-art-buffer  2)
   (rec                       spool-anim           3 :inline)
   (spool-lock                handle)
   (reserve-buffer            external-art-buffer)
   (reserve-buffer-count      int16)
   (dma-reserve-buffer-count  int16)
   (active-stream             string)
   (queue-stream              (array spool-anim))
   (frame-mask                uint32)
   (dma-reserve-heap          kheap                :inline)
   )
  (:methods
    (new (symbol type) _type_)
    (update (_type_ symbol) int)
    (clear-rec (_type_) int)
    (spool-push (_type_ string int process float) int)
    (file-status (_type_ string int) symbol)
    (reserve-alloc (_type_) kheap)
    (reserve-free (_type_ kheap) int)
    (none-reserved? (_type_) symbol)
    )
  )


(defmethod new external-art-control ((allocation symbol) (type-to-make type))
  (let ((gp-0 (object-new allocation type-to-make (the-as int (-> type-to-make size)))))
    (dotimes (s4-0 2)
      (set! (-> gp-0 buffer s4-0)
            ((method-of-type external-art-buffer new) allocation external-art-buffer s4-0 external-art-buffer-init #t)
            )
      )
    (set! (-> gp-0 buffer 0 other) (-> gp-0 buffer 1))
    (set! (-> gp-0 buffer 1 other) (-> gp-0 buffer 0))
    (dotimes (v1-9 3)
      (set! (-> gp-0 rec v1-9 name) #f)
      (set! (-> gp-0 rec v1-9 priority) 100000000.0)
      (set! (-> gp-0 rec v1-9 owner) (the-as handle #f))
      )
    (set! (-> gp-0 spool-lock) (the-as handle #f))
    (set! (-> gp-0 reserve-buffer) #f)
    (set! (-> gp-0 active-stream) #f)
    (set! (-> gp-0 queue-stream) (new 'global 'boxed-array spool-anim 4))
    (dotimes (s5-1 (-> gp-0 queue-stream allocated-length))
      (set! (-> gp-0 queue-stream s5-1) (new 'global 'spool-anim))
      )
    (set! (-> gp-0 queue-stream length) 0)
    gp-0
    )
  )

(deftype subtitle-range (basic)
  ((start-frame  float)
   (end-frame    float)
   (message      basic  8)
   )
  )


(deftype subtitle-image (basic)
  ((width    uint16)
   (height   uint16)
   (palette  rgba   16 :offset  16)
   (data     uint8  :dynamic)
   )
  )


(define-extern *art-control* external-art-control)




