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

;; name: bsp-h.gc
;; name in dgo: bsp-h
;; dgos: GAME

(declare-type bsp-header drawable)
(declare-type bsp-node structure)
(declare-type entity-camera entity)
(declare-type entity-nav-mesh structure)
(declare-type entity-race-mesh entity)
(declare-type city-level-info structure)

(define-extern inspect-bsp-tree (function bsp-header bsp-node none))
(define-extern map-bsp-tree (function (function bsp-node none) bsp-header bsp-node none))
(define-extern mem-usage-bsp-tree (function bsp-header bsp-node memory-usage-block int none))


(defenum texture-page-flag
  :type uint16
  :bitfield #t
  (alpha-enable 0)
  )

;; DECOMP BEGINS

(deftype bsp-node (structure)
  "A node in the 'BSP' tree. This is really a bounding volume tree, where each volume is an axis-aligned box, containing 2 child boxes.
This is used for precomputed visibility, based on the camera position. This is not used for collision."
  ((front          int16)
   (back           int16)
   (front-box-min  vector4b  :inline)
   (front-box-max  vector4b  :inline)
   (back-box-min   vector4b  :inline)
   (back-box-max   vector4b  :inline)
   )
  :pack-me
  )


(deftype bsp-header (drawable)
  "The bsp-header is really an entire level.
This probably started as a very simple structure, but now it is extremely complicated."
  ((info                     file-info                                  :overlay-at id)
   (all-visible-list         (pointer uint8))
   (visible-list-length      int16)
   (extra-vis-list-length    int16)
   (drawable-trees           drawable-tree-array)
   (pat                      pointer)
   (pat-length               int32)
   (texture-remap-table      (pointer uint64))
   (texture-remap-table-len  int32)
   (texture-ids              (pointer texture-id))
   (texture-page-count       int32)
   (unknown-basic            basic)
   (name                     symbol)
   (nickname                 symbol)
   (vis-info                 level-vis-info                     8)
   (actors                   drawable-inline-array-actor)
   (cameras                  (array entity-camera))
   (nodes                    (inline-array bsp-node))
   (level                    level)
   (current-leaf-idx         uint16)
   (texture-flags            texture-page-flag                  10)
   (cam-outside-bsp          uint8                                      :offset 152)
   (cam-using-back           uint8)
   (cam-box-idx              uint16)
   (ambients                 symbol)
   (subdivide-close          float                                      :offset 160)
   (subdivide-far            float)
   (race-meshes              (array entity-race-mesh))
   (actor-birth-order        (pointer uint32)                           :offset 172)
   (light-hash               light-hash)
   (nav-meshes               (array entity-nav-mesh))
   (actor-groups             (array actor-group))
   (region-trees             (array drawable-tree-region-prim)          :offset 188)
   (region-array             region-array)
   (collide-hash             collide-hash                               :offset 196)
   (wind-array               uint32                                     :offset 200)
   (wind-array-length        int32                                      :offset 204)
   (city-level-info          city-level-info                            :offset 208)
   (vis-spheres              vector-array                               :offset 216)
   (vis-spheres-length       uint32                                     :offset 248)
   (region-tree              drawable-tree-region-prim                  :offset 252)
   (tfrag-masks              texture-masks-array                        :offset 256)
   (tfrag-closest            (pointer float))
   (tfrag-mask-count         uint32                                     :overlay-at tfrag-closest)
   (shrub-masks              texture-masks-array)
   (shrub-closest            (pointer float))
   (shrub-mask-count         uint32                                     :overlay-at shrub-closest)
   (alpha-masks              texture-masks-array)
   (alpha-closest            (pointer float))
   (alpha-mask-count         uint32                                     :overlay-at alpha-closest)
   (water-masks              texture-masks-array)
   (water-closest            (pointer float))
   (water-mask-count         uint32                                     :overlay-at water-closest)
   (bsp-scale                vector                             :inline :offset 288)
   (bsp-offset               vector                             :inline)
   (hfrag-drawable           drawable                                   :offset 320)
   (end                      uint8                                      :offset 399)
   )
  (:methods
    (birth (_type_) none)
    (deactivate-entities (_type_) none)
    )
  )

(deftype game-level (basic)
  "Unused in Jak 1, 2, and 3!"
  ((master-bsp  basic)
   )
  )


(deftype view-frustum (structure)
  "A view frustum, expressed as corners.
This representation is not very useful, and is used in only one spot to generate camera planes
in a very inefficient way."
  ((hither-top-left      vector  :inline)
   (hither-top-right     vector  :inline)
   (hither-bottom-left   vector  :inline)
   (hither-bottom-right  vector  :inline)
   (yon-top-left         vector  :inline)
   (yon-top-right        vector  :inline)
   (yon-bottom-left      vector  :inline)
   (yon-bottom-right     vector  :inline)
   )
  )



;; WARN: Return type mismatch bsp-header vs none.
(defun-debug inspect-bsp-tree ((arg0 bsp-header) (arg1 bsp-node))
  "Attempt to print a bsp-tree, but it is actually broken since the jak 2 bsp format change"
  (cond
    ((zero? arg1)
     )
    (else
      (format #t "_#x~X________________~%" arg1)
      (inspect arg1)
      (let ((s4-0 *print-column*))
        (set! *print-column* (+ *print-column* 64))
        (if (> (-> arg1 front) 0)
            (inspect-bsp-tree arg0 (the-as bsp-node (-> arg1 front)))
            (format #t "_#x~X________________~%" arg1)
            )
        (if (> (-> arg1 back) 0)
            (inspect-bsp-tree arg0 (the-as bsp-node (-> arg1 back)))
            (format #t "_#x~X________________~%" arg1)
            )
        (set! *print-column* s4-0)
        )
      )
    )
  (none)
  )

;; WARN: Return type mismatch bsp-header vs none.
(defun map-bsp-tree ((arg0 (function bsp-node none)) (arg1 bsp-header) (arg2 bsp-node))
  "Attempt to call a function on all bsp-tree nodes, but it is actually broken since the jak 2 bsp format"
  (cond
    ((zero? arg2)
     )
    (else
      (if (> (-> arg2 front) 0)
          (map-bsp-tree arg0 arg1 (the-as bsp-node (-> arg2 front)))
          (arg0 arg2)
          )
      (if (> (-> arg2 back) 0)
          (map-bsp-tree arg0 arg1 (the-as bsp-node (-> arg2 back)))
          (arg0 arg2)
          )
      )
    )
  (none)
  )

(deftype collide-stats (structure)
  "Very strange collide stats type. It has been somewhat broken in all versions of the game.
The final stopwatch is cut off. For jak 3, I just fixed it."
  ((calls    uint32)
   (spheres  uint32)
   (nodes    uint32)
   (frags    uint32)
   (tris     uint32)
   (output   uint32)
   (junk     (pointer uint32)  24)
   )
  )
