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

;; definition for function lookup-level-info
(defun lookup-level-info ((name symbol))
  (let* ((rest *level-load-list*)
         (current-sym (car rest))
         )
    (while (not (null? rest))
      (let ((info (the-as level-load-info (-> (the-as symbol current-sym) value))))
        (if (or (= name (-> info name)) (= name (-> info visname)) (= name (-> info nickname)))
            (return info)
            )
        )
      (set! rest (cdr rest))
      (set! current-sym (car rest))
      )
    )
  default-level
  )

;; definition for method 21 of type level-group
;; INFO: Return type mismatch object vs pair.
(defmethod load-command-get-index level-group ((obj level-group) (name symbol) (cmd-idx int))
  (let ((cmd-lst (-> (lookup-level-info name) alt-load-commands)))
    (while (nonzero? cmd-idx)
      (+! cmd-idx -1)
      (set! cmd-lst (cdr cmd-lst))
      (nop!)
      (nop!)
      (nop!)
      )
    (the-as pair (car cmd-lst))
    )
  )

;; definition for function remap-level-name
(defun remap-level-name ((arg0 level-load-info))
  (if (-> *level* vis?)
      (-> arg0 visname)
      (-> arg0 name)
      )
  )

;; definition for method 28 of type level
(defmethod art-group-get-by-name level ((obj level) (arg0 string))
  (countdown (s4-0 (-> obj art-group art-group-array length))
    (if (name= (-> obj art-group art-group-array s4-0 name) arg0)
        (return (-> obj art-group art-group-array s4-0))
        )
    )
  (the-as art-group #f)
  )

;; definition for method 13 of type level
(defmethod bsp-name level ((obj level))
  (if (and (!= (-> obj status) 'inactive) (-> obj bsp) (nonzero? (-> obj bsp name)))
      (-> obj bsp name)
      (-> obj name)
      )
  )

;; definition for function add-bsp-drawable
(defun add-bsp-drawable ((arg0 bsp-header) (arg1 level) (arg2 symbol) (arg3 display-frame))
  (draw arg0 arg0 arg3)
  (if (nonzero? *display-strip-lines*)
      (debug-draw arg0 arg0 arg3)
      )
  (none)
  )

;; definition for method 2 of type level
(defmethod print level ((obj level))
  (format #t "#<~A ~A ~S @ #x~X>" (-> obj type) (-> obj status) (-> obj name) obj)
  obj
  )

;; definition for method 7 of type bsp-header
;; INFO: Return type mismatch bsp-header vs none.
(defmethod relocate bsp-header ((obj bsp-header) (arg0 kheap) (arg1 (pointer uint8)))
  (let ((s5-0 (-> *level* loading-level)))
    (if s5-0
        (set! obj (cond
                    (obj
                      (cond
                        ((not (type-type? (-> obj type) bsp-header))
                         (format 0 "ERROR: level ~A is not a bsp-header.~%" (-> s5-0 name))
                         (the-as bsp-header #f)
                         )
                        ((not (file-info-correct-version? (-> obj info) (file-kind level-bt) 0))
                         (the-as bsp-header #f)
                         )
                        ((< 2048 (-> obj visible-list-length))
                         (format
                           0
                           "ERROR: level ~A visible-list-length ~d is greater than 2048 (16384 drawables).~%"
                           (-> s5-0 name)
                           (-> obj visible-list-length)
                           )
                         (the-as bsp-header #f)
                         )
                        (else
                          (set! (-> s5-0 bsp) obj)
                          (set! (-> obj level) s5-0)
                          obj
                          )
                        )
                      )
                    (else
                      (format 0 "ERROR: level ~A is not a valid file.~%" (-> s5-0 name))
                      (the-as bsp-header #f)
                      )
                    )
              )
        )
    )
  (none)
  )

;; definition for method 24 of type level
(defmethod load-required-packages level ((obj level))
  (when (not (or (not (-> obj bsp)) (= *kernel-boot-mode* 'debug-boot)))
    (if (not (null? (-> obj info packages)))
        (load-package "common" global)
        )
    )
  obj
  )

;; definition for method 26 of type level
;; INFO: Used lq/sq
(defmethod vis-clear level ((obj level))
  (countdown (v1-0 8)
    (nop!)
    (set! (-> obj vis-info v1-0) #f)
    )
  (dotimes (v1-3 128)
    (set! (-> (the-as (pointer int128) (&+ (-> obj vis-bits) (* v1-3 16)))) 0)
    )
  (set! (-> obj all-visible?) 'loading)
  0
  )

;; definition for method 20 of type level
;; INFO: Used lq/sq
(defmethod vis-load level ((obj level))
  (when (zero? (-> obj vis-info (-> obj vis-self-index) ramdisk))
    (let ((v1-10 (-> obj other vis-info (-> obj other vis-self-index))))
      (when (and v1-10 (nonzero? (-> v1-10 ramdisk)))
        (set! (-> v1-10 flags) (logand -1073741825 (-> v1-10 flags)))
        (set! (-> v1-10 ramdisk) (the-as uint 0))
        0
        )
      )
    (let ((s4-0 (make-file-name (file-kind vis) (the-as string (-> obj nickname)) 0 #f))
          (s3-0 (the-as ramdisk-rpc-fill (add-element *ramdisk-rpc*)))
          (s5-0 (+ *current-ramdisk-id* 1))
          )
      (set! *current-ramdisk-id* s5-0)
      (set! (-> s3-0 filename) (string->sound-name s4-0))
      (set! (-> s3-0 ee-id) s5-0)
      (call *ramdisk-rpc* (the-as uint 1) (the-as pointer 0) (the-as uint 0))
      (set! (-> obj vis-info (-> obj vis-self-index) ramdisk) (the-as uint s5-0))
      )
    )
  (-> obj vis-info (-> obj vis-self-index) ramdisk)
  )

;; definition for function load-vis-info
(defun load-vis-info ((arg0 symbol) (arg1 symbol))
  (dotimes (s4-0 (-> *level* length))
    (let ((s3-0 (-> *level* level s4-0)))
      (when (= (-> s3-0 status) 'active)
        (when (= arg0 (-> s3-0 nickname))
          (format 0 "Swapping in ~A VIS [dumping ~A]~%" arg0 arg1)
          (vis-load s3-0)
          )
        )
      )
    )
  0
  )

;; definition for method 25 of type level
(defmethod init-vis level ((obj level))
  (when (not (or (= (-> obj status) 'inactive) (not (-> obj bsp))))
    (set! (-> obj all-visible?) 'loading)
    (let ((s5-0 (-> obj bsp vis-info 0)))
      (cond
        ((and s5-0 (nonzero? s5-0) (valid? s5-0 level-vis-info #f #f 0))
         (set! (-> obj vis-info 0) s5-0)
         (set! (-> s5-0 current-vis-string) (the-as uint -1))
         (set! (-> s5-0 from-bsp) (-> obj bsp))
         (set! (-> s5-0 vis-bits) (-> obj vis-bits))
         (set! (-> s5-0 flags) (logand (the-as uint #xffffffff3fffffff) (-> s5-0 flags)))
         (set! (-> s5-0 flags) (logior #x20000000 (-> s5-0 flags)))
         (set! (-> s5-0 ramdisk) (the-as uint 0))
         (set! (-> s5-0 string-block) (the-as uint #f))
         (set! *vis-boot* #t)
         )
        (else
          (set! (-> obj vis-info 0) #f)
          )
        )
      )
    (dotimes (s5-1 6)
      (let* ((s3-0 (+ s5-1 1))
             (s4-0 (-> obj bsp vis-info s3-0))
             )
        (cond
          ((and s4-0 (nonzero? s4-0) (valid? s4-0 level-vis-info #f #f 0))
           (set! (-> obj vis-info s3-0) s4-0)
           (set! (-> s4-0 current-vis-string) (the-as uint -1))
           (set! (-> s4-0 from-bsp) #f)
           (set! (-> s4-0 vis-bits) (-> obj vis-bits))
           (set! (-> s4-0 flags) (logand (the-as uint #xffffffff1fffffff) (-> s4-0 flags)))
           (set! *vis-boot* #t)
           )
          (else
            (set! (-> obj vis-info s3-0) #f)
            )
          )
        )
      )
    )
  0
  )

;; definition for method 11 of type level-group
(defmethod level-get-for-use level-group ((obj level-group) (arg0 symbol) (arg1 symbol))
  (local-vars (s5-1 level))
  (alloc-levels! obj #f)
  (let* ((s3-0 (lookup-level-info arg0))
         (s2-0 (remap-level-name s3-0))
         )
    (let ((s1-0 (level-get obj s2-0)))
      (when s1-0
        (level-status-set! s1-0 arg1)
        (set! s5-1 s1-0)
        (goto cfg-10)
        )
      )
    (let ((a0-7 (level-get-most-disposable obj)))
      (set! s5-1 (if a0-7
                     (level-status-set! a0-7 'inactive)
                     a0-7
                     )
            )
      )
    (when (not level)
      (format 0 "ERROR: could not find a slot to load ~A into.~%" arg0)
      (set! s5-1 (the-as level #f))
      (goto cfg-10)
      )
    (set! (-> s5-1 info) s3-0)
    (set! (-> s5-1 name) arg0)
    (set! (-> s5-1 load-name) s2-0)
    )
  (set! (-> s5-1 mood) (the-as mood-context (-> s5-1 info mood value)))
  (set! (-> s5-1 mood-func) (the-as (function mood-context float int none) (-> s5-1 info mood-func value)))
  (set! (-> s5-1 display?) #f)
  (set! (-> s5-1 force-all-visible?) #f)
  (set! (-> s5-1 force-inside?) #f)
  (level-status-set! s5-1 'loading)
  (level-status-set! s5-1 arg1)
  (label cfg-10)
  s5-1
  )

;; definition for method 25 of type level-group
(defmethod level-status level-group ((obj level-group) (arg0 symbol))
  (let ((v1-1 (level-get *level* arg0)))
    (if v1-1
        (-> v1-1 status)
        )
    )
  )

;; definition for method 23 of type level
(defmethod level-status-set! level ((obj level) (arg0 symbol))
  (case arg0
    (('inactive)
     (-> obj status)
     (unload! obj)
     )
    (('loading)
     (case (-> obj status)
       (('inactive)
        (load-begin obj)
        )
       )
     )
    (('loading-bt)
     (case (-> obj status)
       (('loading)
        (set! (-> obj status) arg0)
        (load-continue obj)
        )
       )
     )
    (('loading-done)
     (case (-> obj status)
       (('loading-bt)
        (set! (-> obj status) arg0)
        )
       )
     )
    (('loaded)
     (case (-> obj status)
       (('loading-done)
        (login-begin obj)
        )
       (('alive 'active)
        (deactivate obj)
        )
       )
     )
    (('alive 'active)
     (when *dproc*
       (case (-> obj status)
         (('loaded)
          (birth obj)
          (level-status-set! obj arg0)
          )
         (('alive)
          (when (and *dproc* (= arg0 'active))
            (remove-by-param1 *background-draw-engine* (-> obj bsp))
            (add-connection *background-draw-engine* *dproc* add-bsp-drawable (-> obj bsp) obj #f)
            (dotimes (v1-40 9)
              (set! (-> obj closest-object v1-40) 0.0)
              (set! (-> obj texture-mask v1-40) (the-as uint 0))
              )
            (set! (-> obj level-distance) 0.0)
            (set! (-> obj status) 'active)
            )
          )
         )
       )
     )
    )
  obj
  )

;; definition for symbol *login-state*, type login-state
(define *login-state* (new 'global 'login-state))

;; definition for symbol *print-login*, type symbol
(define *print-login* #t)

;; definition for method 17 of type level
(defmethod load-continue level ((obj level))
  (local-vars (sv-16 symbol))
  (when (-> obj linking)
    (when (nonzero? (link-resume))
      (set! (-> obj linking) #f)
      (case (-> obj status)
        (('loading)
         (if (not (-> *texture-relocate-later* memcpy))
             (dgo-load-continue (logand -64 (&+ (-> obj heap current) 63)))
             )
         )
        (('loading-bt)
         (level-status-set! obj 'loading-done)
         (level-status-set! obj 'loaded)
         )
        )
      )
    (set! obj obj)
    (goto cfg-30)
    )
  (when (-> *texture-relocate-later* memcpy)
    (relocate-later)
    (dgo-load-continue (logand -64 (&+ (-> obj heap current) 63)))
    (set! obj obj)
    (goto cfg-30)
    )
  (case (-> obj status)
    (('loading)
     (set! sv-16 (the-as symbol #f))
     (let ((a0-15 (dgo-load-get-next (& sv-16))))
       (when a0-15
         (cond
           ((not sv-16)
            (cond
              ((dgo-load-link (the-as dgo-header a0-15) (-> obj heap) *print-login* #f)
               (if (not (-> *texture-relocate-later* memcpy))
                   (dgo-load-continue (logand -64 (&+ (-> obj heap current) 63)))
                   )
               )
              (else
                (set! (-> obj linking) #t)
                )
              )
            )
           (else
             (set! (-> obj heap top) (-> obj heap top-base))
             (level-status-set! obj 'loading-bt)
             )
           )
         )
       )
     )
    (('login)
     (level-update-after-load obj *login-state*)
     )
    (('loading-bt)
     (let ((a0-26 (logand -64 (&+ (-> obj heap current) 63))))
       (cond
         ((dgo-load-link (the-as dgo-header a0-26) (-> obj heap) *print-login* #t)
          (level-status-set! obj 'loading-done)
          (level-status-set! obj 'loaded)
          )
         (else
           (set! (-> obj linking) #t)
           )
         )
       )
     )
    )
  (label cfg-30)
  obj
  )

;; definition for method 18 of type level
(defmethod load-begin level ((obj level))
  (set! loading-level (-> obj heap))
  (set! (-> *level* loading-level) obj)
  (set! (-> *level* log-in-level-bsp) #f)
  (set! (-> obj nickname) #f)
  (set! (-> obj bsp) #f)
  (set! (-> obj entity) #f)
  (set! (-> obj ambient) #f)
  (set! (-> obj linking) #f)
  (vis-clear obj)
  (set! (-> obj status) 'loading)
  (set! (-> *texture-pool* allocate-func) texture-page-level-allocate)
  (if (= (-> obj load-name) (-> obj info visname))
      (format (clear *temp-string*) "~S" (-> obj info nickname))
      (format (clear *temp-string*) "~S" (-> obj name))
      )
  (set! (-> *temp-string* data 8) (the-as uint 0))
  (format *temp-string* ".DGO")
  (set! (-> obj heap top) (-> obj heap top-base))
  (let ((s4-0 (kmalloc (-> obj heap) #x200000 (kmalloc-flags align-64 top) "dgo-level-buf-2"))
        (s5-2 (kmalloc (-> obj heap) #x200000 (kmalloc-flags align-64 top) "dgo-level-buf-2"))
        )
    (set! (-> obj code-memory-start) (-> obj heap current))
    (format 0 "-----------> begin load ~A [~S]~%" (-> obj load-name) *temp-string*)
    (dgo-load-begin *temp-string* s5-2 s4-0 (logand -64 (&+ (-> obj heap current) 63)))
    )
  obj
  )

;; definition for method 19 of type level
(defmethod login-begin level ((obj level))
  (set! (-> *texture-pool* allocate-func) texture-page-default-allocate)
  (cond
    ((-> obj bsp)
     (set! (-> *level* log-in-level-bsp) (-> obj bsp))
     (login-level-textures *texture-pool* obj (-> obj bsp texture-page-count) (-> obj bsp texture-ids))
     (let ((v1-7 (-> obj bsp)))
       (when (nonzero? (-> v1-7 adgifs))
         (let ((s5-0 (-> v1-7 adgifs)))
           (dotimes (s4-0 (-> s5-0 length))
             (adgif-shader-login-no-remap (-> s5-0 data s4-0))
             )
           )
         )
       )
     (set! (-> *login-state* state) -1)
     (set! (-> *login-state* pos) (the-as uint 0))
     (set! (-> *login-state* elts) (the-as uint 0))
     (set! (-> obj status) 'login)
     )
    (else
      (level-status-set! obj 'inactive)
      (set! loading-level global)
      (set! (-> *level* loading-level) (-> *level* level-default))
      )
    )
  obj
  )

;; definition for function level-update-after-load
;; WARN: Found some very strange gotos. Check result carefully, this is not well tested.
;; INFO: Used lq/sq
;; ERROR: Unsupported inline assembly instruction kind - [mfc0 s5, Count]
;; ERROR: Unsupported inline assembly instruction kind - [mfc0 v1, Count]
;; ERROR: Unsupported inline assembly instruction kind - [mfc0 v1, Count]
(defun level-update-after-load ((loaded-level level) (level-login-state login-state))
  (local-vars (current-timer int) (v1-154 int) (initial-timer int) (sv-16 prototype-bucket-tie) (sv-32 int))
  0
  (let ((level-drawable-trees (-> loaded-level bsp drawable-trees)))
    0
    (.mfc0 initial-timer Count)
    (label cfg-1)
    0
    (.mfc0 current-timer Count)
    (let ((elapsed-timer (- current-timer initial-timer)))
      (when (< #x186a0 elapsed-timer)
        (set! loaded-level loaded-level)
        (goto cfg-78)
        )
      )
    (let ((current-login-pos (the-as int (-> level-login-state pos))))
      (when (= (-> level-login-state state) -1)
        (when (< current-login-pos (-> level-drawable-trees length))
          (let ((current-drawable (-> level-drawable-trees trees (the-as uint current-login-pos))))
            (cond
              ((= (-> current-drawable type) drawable-tree-tfrag)
               (dotimes (idx-in-drawable (-> current-drawable length))
                 (cond
                   ((= (-> current-drawable data idx-in-drawable type) drawable-inline-array-tfrag)
                    (set! (-> level-login-state elt (-> level-login-state elts)) (-> current-drawable data idx-in-drawable))
                    (+! (-> level-login-state elts) 1)
                    )
                   (else
                     (login (-> current-drawable data idx-in-drawable))
                     )
                   )
                 )
               )
              ((= (-> current-drawable type) drawable-tree-instance-tie)
               (set! (-> level-login-state elt (-> level-login-state elts)) current-drawable)
               (+! (-> level-login-state elts) 1)
               )
              (else
                (login current-drawable)
                )
              )
            )
          (+! (-> level-login-state pos) 1)
          (goto cfg-1)
          )
        (let ((v1-39 (- (the-as uint current-login-pos) (-> level-drawable-trees length))))
          (when (< (the-as int v1-39) (-> loaded-level art-group art-group-array length))
            (let ((s2-2 (-> loaded-level art-group art-group-array v1-39)))
              (login s2-2)
              (if (needs-link? s2-2)
                  (link-art! s2-2)
                  )
              )
            (+! (-> level-login-state pos) 1)
            (goto cfg-1)
            )
          )
        (set! (-> level-login-state pos) (the-as uint 0))
        (set! (-> level-login-state state) 0)
        (goto cfg-1)
        )
      (when (< (-> level-login-state state) (the-as int (-> level-login-state elts)))
        (let ((s1-1 (-> level-login-state elt (-> level-login-state state))))
          (cond
            ((= (-> s1-1 type) drawable-inline-array-tfrag)
             (cond
               ((< current-login-pos (-> (the-as drawable-inline-array-tfrag s1-1) length))
                (dotimes (s0-0 200)
                  (when (< current-login-pos (-> (the-as drawable-inline-array-tfrag s1-1) length))
                    (login (-> (the-as drawable-inline-array-tfrag s1-1) data (the-as uint current-login-pos)))
                    (set! current-login-pos (the-as int (+ (the-as uint current-login-pos) 1)))
                    )
                  )
                (set! (-> level-login-state pos) (the-as uint current-login-pos))
                )
               (else
                 (set! (-> level-login-state pos) (the-as uint 0))
                 (set! current-login-pos (+ (-> level-login-state state) 1))
                 (set! (-> level-login-state state) current-login-pos)
                 )
               )
             )
            ((= (-> s1-1 type) drawable-tree-instance-tie)
             (let ((s1-2 (-> (the-as drawable-tree-instance-tie s1-1) prototypes prototype-array-tie)))
               (when (< current-login-pos (-> s1-2 length))
                 (dotimes (s0-1 10)
                   (when (< current-login-pos (-> s1-2 length))
                     (set! sv-16 (-> s1-2 array-data (the-as uint current-login-pos)))
                     (set! sv-32 0)
                     (while (< sv-32 4)
                       (let ((a0-28 (-> sv-16 geometry-override sv-32)))
                         (if (nonzero? a0-28)
                             (login a0-28)
                             )
                         )
                       (set! sv-32 (+ sv-32 1))
                       )
                     (set! current-login-pos (the-as int (+ (the-as uint current-login-pos) 1)))
                     )
                   )
                 (set! (-> level-login-state pos) (the-as uint current-login-pos))
                 )
               (when (= (the-as uint current-login-pos) (-> s1-2 length))
                 (dotimes (s2-3 (-> s1-2 length))
                   (let ((s0-2 (-> s1-2 array-data s2-3 envmap-shader)))
                     (when (nonzero? s0-2)
                       (adgif-shader-login-no-remap s0-2)
                       (set! (-> s0-2 tex1) (new 'static 'gs-tex1 :mmag #x1 :mmin #x1))
                       (set! (-> s0-2 clamp) (new 'static 'gs-clamp :wms (gs-tex-wrap-mode clamp) :wmt (gs-tex-wrap-mode clamp)))
                       (set! (-> s0-2 alpha) (new 'static 'gs-alpha :b #x2 :c #x1 :d #x1))
                       (set! (-> s0-2 prims 1) (gs-reg64 tex0-1))
                       (set! (-> s0-2 prims 3) (gs-reg64 tex1-1))
                       (set! (-> s0-2 prims 5) (gs-reg64 miptbp1-1))
                       (set! (-> s0-2 clamp-reg) (gs-reg64 clamp-1))
                       (set! (-> s0-2 prims 9) (gs-reg64 alpha-1))
                       )
                     )
                   )
                 (set! (-> level-login-state pos) (the-as uint 0))
                 (+! (-> level-login-state state) 1)
                 )
               )
             )
            )
          )
        (goto cfg-1)
        )
      (when (= (-> level-login-state state) (-> level-login-state elts))
        (let ((v1-115 (-> loaded-level bsp)))
          (cond
            ((or (zero? (-> v1-115 actors)) (= (the-as uint current-login-pos) (-> v1-115 actors length)))
             (set! (-> level-login-state pos) (the-as uint 0))
             (+! (-> level-login-state state) 1)
             )
            (else
              (let ((a0-36 (-> v1-115 actors data (the-as uint current-login-pos) actor)))
                (entity-nav-login a0-36)
                )
              (+! (-> level-login-state pos) 1)
              )
            )
          )
        (goto cfg-1)
        )
      (when (zero? (the-as uint current-login-pos))
        (set! (-> level-login-state pos) (the-as uint 1))
        (set! loaded-level loaded-level)
        (goto cfg-78)
        )
      )
    )
  (set! (-> loaded-level nickname) (-> loaded-level bsp nickname))
  (if (nonzero? (-> loaded-level bsp nodes))
      (set! *time-of-day-effects* #t)
      (set! *time-of-day-effects* #f)
      )
  (let ((f0-0 (-> loaded-level bsp unk-data-4))
        (f1-0 (-> loaded-level bsp unk-data-5))
        )
    (when (and (= f0-0 0.0) (= f1-0 0.0))
      (set! f0-0 122880.0)
      (set! f1-0 286720.0)
      )
    (set! (-> *subdivide-settings* close (-> loaded-level index)) f0-0)
    (set! (-> *subdivide-settings* far (-> loaded-level index)) f1-0)
    (set! (-> *subdivide-settings* close 3) f0-0)
    (set! (-> *subdivide-settings* far 3) f1-0)
    )
  (init-vis loaded-level)
  (load-required-packages loaded-level)
  (set! (-> loaded-level status) 'loaded)
  (set! loading-level global)
  (set! (-> *level* loading-level) (-> *level* level-default))
  (set! (-> *level* log-in-level-bsp) #f)
  0
  (.mfc0 v1-154 Count)
  (- v1-154 initial-timer)
  (label cfg-78)
  loaded-level
  )

;; definition for method 22 of type level
(defmethod birth level ((obj level))
  (case (-> obj status)
    (('loaded)
     (let ((s5-0 loading-level)
           (s4-0 (-> *level* loading-level))
           (s3-1 (-> *level* log-in-level-bsp))
           )
       (set! loading-level (-> obj heap))
       (set! (-> *level* log-in-level-bsp) (-> obj bsp))
       (set! (-> *level* loading-level) obj)
       (birth (-> obj bsp))
       (set! (-> obj status) 'alive)
       (copy-perms-to-level! *game-info* obj)
       (send-event *camera* 'level-activate (-> obj name))
       (send-event *target* 'level-activate (-> obj name))
       (set! loading-level s5-0)
       (set! (-> *level* loading-level) s4-0)
       (set! (-> *level* log-in-level-bsp) s3-1)
       )
     )
    )
  obj
  )

;; definition for method 9 of type level
;; INFO: Used lq/sq
(defmethod deactivate level ((obj level))
  (case (-> obj status)
    (('active 'alive)
     (format 0 "----------- kill ~A (status ~A)~%" obj (-> obj status))
     (copy-perms-from-level! *game-info* obj)
     (send-event *camera* 'level-deactivate (-> obj name))
     (send-event *target* 'level-deactivate (-> obj name))
     (remove-by-param1 *background-draw-engine* (-> obj bsp))
     (deactivate-entities (-> obj bsp))
     (kill-all-particles-in-level obj)
     (set! (-> obj inside-sphere?) #f)
     (set! (-> obj inside-boxes?) #f)
     (set! (-> obj meta-inside?) #f)
     (set! (-> obj force-inside?) #f)
     (set! (-> obj status) 'loaded)
     (set! (-> obj all-visible?) 'loading)
     (dotimes (v1-19 128)
       (set! (-> (the-as (pointer int128) (&+ (-> obj vis-bits) (* v1-19 16)))) 0)
       )
     (countdown (v1-22 8)
       (let ((a0-14 (-> obj vis-info v1-22)))
         (if a0-14
             (set! (-> a0-14 current-vis-string) (the-as uint -1))
             )
         )
       )
     )
    )
  (if (= (-> *level* log-in-level-bsp) (-> obj bsp))
      (set! (-> *level* log-in-level-bsp) #f)
      )
  obj
  )

;; definition for method 12 of type level
(defmethod unload! level ((obj level))
  (deactivate obj)
  (when (!= (-> obj status) 'inactive)
    (when (or (= (-> obj status) 'loaded)
              (= (-> obj status) 'alive)
              (= (-> obj status) 'active)
              (= (-> obj status) 'login)
              )
      (dotimes (s5-0 (-> obj art-group art-group-array length))
        (let ((s4-0 (-> obj art-group art-group-array s5-0)))
          (if (needs-link? s4-0)
              (unlink-art! s4-0)
              )
          )
        )
      )
    (set! (-> obj bsp) #f)
    (set! (-> obj entity) #f)
    (set! (-> obj ambient) #f)
    (set! (-> obj status) 'inactive)
    (set! (-> obj art-group string-array length) 0)
    (set! (-> obj art-group art-group-array length) 0)
    (countdown (s5-1 (-> obj loaded-texture-page-count))
      (dotimes (v1-27 32)
        (when (= (-> obj loaded-texture-page s5-1) (-> *texture-pool* common-page v1-27))
          (set! (-> *texture-pool* common-page v1-27) (the-as texture-page 0))
          0
          )
        )
      (unload! *texture-pool* (-> obj loaded-texture-page s5-1))
      )
    (set! (-> obj loaded-texture-page-count) 0)
    (unlink-textures-in-heap! *texture-page-dir* (-> obj heap))
    (unlink-part-group-by-heap (-> obj heap))
    (dotimes (s5-2 2)
      (let ((v1-41 (-> *art-control* buffer s5-2 pending-load-file)))
        (if (and (>= (the-as int v1-41) (the-as int (-> obj heap base)))
                 (< (the-as int v1-41) (the-as int (-> obj heap top-base)))
                 )
            (set-pending-file (-> *art-control* buffer s5-2) (the-as string #f) -1 (the-as handle #f) 100000000.0)
            )
        )
      )
    (let* ((s5-3 (-> obj info packages)) (a0-29 (car s5-3))) (while (not (null? s5-3))
                                                               (case (rtype-of a0-29)
                                                                 ((symbol)
                                                                  (unload (symbol->string (the-as symbol a0-29)))
                                                                  )
                                                                 ((string)
                                                                  (unload (the-as string a0-29))
                                                                  )
                                                                 )
                                                               (set! s5-3 (cdr s5-3))
                                                               (set! a0-29 (car s5-3))
                                                               )
          )
    (vis-clear obj)
    (let ((v1-64 (-> obj heap)))
      (set! (-> v1-64 current) (-> v1-64 base))
      )
    (set! (-> obj code-memory-start) (the-as pointer 0))
    (set! (-> obj code-memory-end) (the-as pointer 0))
    (when (= (-> *level* loading-level) obj)
      (set! loading-level global)
      (set! (-> *level* loading-level) (-> *level* level-default))
      (set! (-> *level* log-in-level-bsp) #f)
      )
    )
  obj
  )

;; definition for method 10 of type level
;; ERROR: Unsupported inline assembly instruction kind - [addiu a0, a0, 56]
(defmethod is-object-visible? level ((obj level) (arg0 int))
  (local-vars (a0-1 int) (a0-3 int))
  (let ((v1-0 (-> obj vis-bits)))
    (shift-arith-right-32 a0-1 arg0 3)
    (let ((v1-2 (-> (the-as (pointer int8) (+ a0-1 (the-as int v1-0))))))
      (let ((a0-2 (logand arg0 7)))
        (.addiu a0-3 a0-2 56)
        )
      (< (shl v1-2 a0-3) 0)
      )
    )
  )

;; definition for method 15 of type level
;; INFO: Return type mismatch object vs symbol.
(defmethod point-in-boxes? level ((obj level) (arg0 vector))
  (the-as symbol (cond
                   ((or (not (-> obj bsp)) (zero? (-> obj bsp boxes)))
                    #f
                    )
                   ((-> obj force-inside?)
                    #t
                    )
                   (else
                     (let* ((a0-1 (-> obj bsp boxes))
                            (v1-5 (-> a0-1 data))
                            )
                       (countdown (a0-2 (-> a0-1 length))
                         (if (and (>= (-> arg0 x) (-> v1-5 0 min x))
                                  (>= (-> arg0 y) (-> v1-5 0 min y))
                                  (>= (-> arg0 z) (-> v1-5 0 min z))
                                  (< (-> arg0 x) (-> v1-5 0 max x))
                                  (< (-> arg0 y) (-> v1-5 0 max y))
                                  (< (-> arg0 z) (-> v1-5 0 max z))
                                  )
                             (return (the-as symbol #t))
                             )
                         (set! v1-5 (the-as (inline-array box8s) (-> v1-5 1)))
                         )
                       )
                     #f
                     )
                   )
          )
  )

;; definition for method 27 of type level
;; INFO: Return type mismatch int vs none.
(defmethod debug-print-splitbox level ((obj level) (arg0 vector) (arg1 string))
  (cond
    ((or (not (-> obj bsp)) (zero? (-> obj bsp boxes)) (zero? (-> obj bsp split-box-indices)))
     )
    (else
      (let* ((s3-0 (-> obj bsp boxes))
             (s2-0 (the-as object (-> s3-0 data)))
             )
        (dotimes (s1-0 (-> s3-0 length))
          (if (and (>= (-> arg0 x) (-> (the-as (inline-array box8s) s2-0) 0 min x))
                   (>= (-> arg0 y) (-> (the-as (inline-array box8s) s2-0) 0 min y))
                   (>= (-> arg0 z) (-> (the-as (inline-array box8s) s2-0) 0 min z))
                   (< (-> arg0 x) (-> (the-as (inline-array box8s) s2-0) 0 max x))
                   (< (-> arg0 y) (-> (the-as (inline-array box8s) s2-0) 0 max y))
                   (< (-> arg0 z) (-> (the-as (inline-array box8s) s2-0) 0 max z))
                   )
              (format arg1 "    splitbox-~D~%" (-> obj bsp split-box-indices s1-0))
              )
          (set! s2-0 (-> (the-as (inline-array box8s) s2-0) 1))
          )
        )
      )
    )
  0
  (none)
  )

;; definition for method 8 of type level
(defmethod mem-usage level ((obj level) (arg0 memory-usage-block) (arg1 int))
  (when (= (-> obj status) 'active)
    (set! (-> arg0 length) (max 65 (-> arg0 length)))
    (set! (-> arg0 data 64 name) "entity-links")
    (+! (-> arg0 data 64 count) (-> obj entity length))
    (let ((v1-8 (asize-of (-> obj entity))))
      (+! (-> arg0 data 64 used) v1-8)
      (+! (-> arg0 data 64 total) (logand -16 (+ v1-8 15)))
      )
    (set! (-> arg0 length) (max 65 (-> arg0 length)))
    (set! (-> arg0 data 64 name) "ambient-links")
    (+! (-> arg0 data 64 count) (-> obj ambient length))
    (let ((v1-18 (asize-of (-> obj ambient))))
      (+! (-> arg0 data 64 used) v1-18)
      (+! (-> arg0 data 64 total) (logand -16 (+ v1-18 15)))
      )
    (mem-usage (-> obj art-group) arg0 arg1)
    (set! (-> arg0 length) (max 64 (-> arg0 length)))
    (set! (-> arg0 data 63 name) "level-code")
    (+! (-> arg0 data 63 count) 1)
    (let ((v1-30 (&- (-> obj code-memory-end) (the-as uint (-> obj code-memory-start)))))
      (+! (-> arg0 data 63 used) v1-30)
      (+! (-> arg0 data 63 total) (logand -16 (+ v1-30 15)))
      )
    (countdown (s3-0 (-> obj loaded-texture-page-count))
      (mem-usage (-> obj loaded-texture-page s3-0) arg0 arg1)
      )
    (countdown (s3-1 8)
      (let ((s2-0 (-> obj vis-info s3-1)))
        (when s2-0
          (cond
            ((zero? s3-1)
             (set! (-> arg0 length) (max 60 (-> arg0 length)))
             (set! (-> arg0 data 59 name) "bsp-leaf-vis-self")
             (+! (-> arg0 data 59 count) 1)
             (let ((v1-50 (asize-of s2-0)))
               (+! (-> arg0 data 59 used) v1-50)
               (+! (-> arg0 data 59 total) (logand -16 (+ v1-50 15)))
               )
             )
            (else
              (set! (-> arg0 length) (max 61 (-> arg0 length)))
              (set! (-> arg0 data 60 name) "bsp-leaf-vis-adj")
              (+! (-> arg0 data 60 count) 1)
              (let ((v1-61 (+ (asize-of s2-0) (-> s2-0 allocated-length))))
                (+! (-> arg0 data 60 used) v1-61)
                (+! (-> arg0 data 60 total) (logand -16 (+ v1-61 15)))
                )
              )
            )
          )
        )
      )
    (mem-usage (-> obj bsp) arg0 arg1)
    )
  obj
  )

;; definition for method 18 of type level-group
(defmethod alloc-levels! level-group ((obj level-group) (arg0 symbol))
  (when (zero? (-> *level* level0 heap base))
    (when (nmember "game" *kernel-packages*)
      (set! *kernel-packages* (cons "art" *kernel-packages*))
      (set! *kernel-packages* (cons "common" *kernel-packages*))
      )
    (load-package "art" global)
    (if arg0
        (load-package "common" global)
        )
    (let ((s5-1 (if arg0
                    #xa2c000
                    #x1900000
                    )
                )
          )
      (dotimes (s4-0 2)
        (let ((s3-0 (-> obj level s4-0 heap)))
          (set! (-> s3-0 base) (malloc 'global s5-1))
          (set! (-> s3-0 current) (-> s3-0 base))
          (set! (-> s3-0 top-base) (&+ (-> s3-0 base) s5-1))
          (set! (-> s3-0 top) (-> s3-0 top-base))
          )
        )
      )
    )
  0
  )

;; definition for method 10 of type level-group
(defmethod level-get-with-status level-group ((obj level-group) (arg0 symbol))
  (dotimes (v1-0 (-> obj length))
    (if (= (-> obj level v1-0 status) arg0)
        (return (-> obj level v1-0))
        )
    )
  (the-as level #f)
  )

;; definition for method 26 of type level-group
(defmethod level-get-most-disposable level-group ((obj level-group))
  (dotimes (v1-0 (-> obj length))
    (case (-> obj level v1-0 status)
      (('inactive)
       (return (-> obj level v1-0))
       )
      )
    )
  (dotimes (v1-6 (-> obj length))
    (case (-> obj level v1-6 status)
      (('loading 'loading-bt)
       (return (-> obj level v1-6))
       )
      )
    )
  (dotimes (v1-12 (-> obj length))
    (case (-> obj level v1-12 status)
      (('loaded)
       (return (-> obj level v1-12))
       )
      )
    )
  (let ((v0-0 (the-as level #f)))
    (dotimes (v1-18 (-> obj length))
      (case (-> obj level v1-18 status)
        (('active)
         (if (and (not (-> obj level v1-18 inside-boxes?))
                  (or (not v0-0) (< (-> obj level v1-18 info priority) (-> v0-0 info priority)))
                  )
             (set! v0-0 (-> obj level v1-18))
             )
         )
        )
      )
    v0-0
    )
  )

;; definition for method 9 of type level-group
(defmethod level-get level-group ((obj level-group) (arg0 symbol))
  (dotimes (v1-0 (-> obj length))
    (if (and (!= (-> obj level v1-0 status) 'inactive)
             (or (= (-> obj level v1-0 name) arg0) (= (-> obj level v1-0 load-name) arg0))
             )
        (return (-> obj level v1-0))
        )
    )
  (the-as level #f)
  )

;; definition for method 20 of type level-group
(defmethod art-group-get-by-name level-group ((obj level-group) (arg0 string))
  (countdown (s4-0 3)
    (let ((s3-0 (-> obj level s4-0)))
      (countdown (s2-0 (-> s3-0 art-group art-group-array length))
        (if (name= (-> s3-0 art-group art-group-array s2-0 name) arg0)
            (return (-> s3-0 art-group art-group-array s2-0))
            )
        )
      )
    )
  (the-as art-group #f)
  )

;; definition for method 12 of type level-group
(defmethod activate-levels! level-group ((obj level-group))
  (dotimes (s5-0 (-> obj length))
    (level-status-set! (-> obj level s5-0) 'active)
    )
  0
  )

;; definition for method 17 of type level-group
(defmethod level-get-target-inside level-group ((obj level-group))
  (let ((s5-0 (target-pos 0)))
    (let ((v1-2 (-> *game-info* current-continue level)))
      (dotimes (a0-2 (-> obj length))
        (let ((a1-3 (-> obj level a0-2)))
          (when (= (-> a1-3 status) 'active)
            (if (= (-> a1-3 name) v1-2)
                (return a1-3)
                )
            )
          )
        )
      )
    (let ((s4-0 (the-as level #f)))
      (let ((f30-0 0.0))
        (dotimes (s3-0 (-> obj length))
          (let ((s2-0 (-> obj level s3-0)))
            (when (= (-> s2-0 status) 'active)
              (let ((f0-0 (vector-vector-distance (-> s2-0 bsp bsphere) s5-0)))
                (if (and (-> s2-0 inside-boxes?) (or (not s4-0) (< f0-0 f30-0)))
                    (set! s4-0 s2-0)
                    )
                )
              )
            )
          )
        )
      (if s4-0
          (return s4-0)
          )
      )
    )
  (dotimes (v1-20 (-> obj length))
    (let ((a0-8 (-> obj level v1-20)))
      (when (= (-> a0-8 status) 'active)
        (if (-> a0-8 meta-inside?)
            (return a0-8)
            )
        )
      )
    )
  (let ((v0-1 (the-as level #f)))
    (let ((f0-1 0.0))
      (dotimes (v1-23 (-> obj length))
        (let ((a0-13 (-> obj level v1-23)))
          (when (= (-> a0-13 status) 'active)
            (if (or (not v0-1) (< (-> a0-13 level-distance) f0-1))
                (set! v0-1 a0-13)
                )
            )
          )
        )
      )
    v0-1
    )
  )

;; definition for method 19 of type level-group
(defmethod load-commands-set! level-group ((obj level-group) (arg0 pair))
  (set! (-> obj load-commands) arg0)
  arg0
  )

;; definition for method 8 of type level-group
(defmethod mem-usage level-group ((obj level-group) (arg0 memory-usage-block) (arg1 int))
  (dotimes (s3-0 (-> obj length))
    (mem-usage (-> obj level s3-0) arg0 arg1)
    )
  obj
  )

;; definition for function bg
(defun bg ((arg0 symbol))
  (set! *cheat-mode* (if *debug-segment*
                         'debug
                         #f
                         )
        )
  (let ((v1-2 (lookup-level-info arg0)))
    (cond
      ((= (-> v1-2 visname) arg0)
       (set! (-> *level* vis?) #t)
       (set! arg0 (-> v1-2 name))
       )
      (else
        (set! (-> *level* vis?) #f)
        (set! (-> *kernel-context* low-memory-message) #f)
        )
      )
    (let* ((s5-0 (-> v1-2 run-packages))
           (a0-8 (car s5-0))
           )
      (while (not (null? s5-0))
        (case (rtype-of a0-8)
          ((symbol)
           (load-package (symbol->string (the-as symbol a0-8)) global)
           )
          ((string)
           (load-package (the-as string a0-8) global)
           )
          )
        (set! s5-0 (cdr s5-0))
        (set! a0-8 (car s5-0))
        )
      )
    )
  (let ((gp-1 (level-get-for-use *level* arg0 'active)))
    (while (and gp-1
                (or (= (-> gp-1 status) 'loading) (= (-> gp-1 status) 'loading-bt) (= (-> gp-1 status) 'login))
                (not *dproc*)
                )
      (load-continue gp-1)
      )
    (vis-load gp-1)
    (set! (-> *load-state* vis-nick) (if (-> *level* vis?)
                                         (-> gp-1 nickname)
                                         #f
                                         )
          )
    (set! (-> *load-state* want 0 name) (-> gp-1 name))
    (set! (-> *load-state* want 0 display?) 'display)
    (set! (-> *load-state* want 0 force-vis?) #f)
    (set! (-> *load-state* want 0 force-inside?) #f)
    (set! (-> *load-state* want 1 name) #f)
    (set! (-> *load-state* want 1 display?) #f)
    (set! (-> *load-state* want 1 force-inside?) #f)
    (if (-> gp-1 info continues)
        (set-continue! *game-info* (the-as basic (car (-> gp-1 info continues))))
        )
    )
  (activate-levels! *level*)
  (set! *print-login* #f)
  0
  )

;; definition for function play
(defun play ((arg0 symbol) (arg1 symbol))
  (let* ((v1-0 *kernel-boot-message*)
         (s5-0 (cond
                 ((= v1-0 'play)
                  (if *debug-segment*
                      'village1
                      'title
                      )
                  )
                 (else
                   'demo
                   )
                 )
               )
         )
    (stop 'play)
    (set! (-> *level* vis?) arg0)
    (set! (-> *level* want-level) #f)
    (set! (-> *level* border?) #t)
    (set! (-> *setting-control* default border-mode) #t)
    (set! (-> *level* play?) #t)
    (alloc-levels! *level* #t)
    (set! *display-profile* #f)
    (set! *cheat-mode* (if *debug-segment*
                           'debug
                           #f
                           )
          )
    (set! *time-of-day-fast* #f)
    (load-commands-set! *level* '())
    (when *time-of-day-proc*
      (set! (-> *time-of-day-proc* 0 time-ratio) 300.0)
      (set! (-> *time-of-day-proc* 0 hour) 7)
      )
    (set-blackout-frames (seconds 0.02))
    (when (not *dproc*)
      (reset! *load-state*)
      (let ((s4-1 (level-get-for-use *level* s5-0 'active)))
        (load-state-want-levels s5-0 #f)
        (load-state-want-display-level s5-0 'display)
        (load-state-want-vis (-> (lookup-level-info s5-0) nickname))
        (while (and s4-1 (or (= (-> s4-1 status) 'loading) (= (-> s4-1 status) 'loading-bt) (= (-> s4-1 status) 'login)))
          (set-blackout-frames (seconds 0.02))
          (load-continue s4-1)
          )
        )
      )
    (set! *print-login* #f)
    (level-status-set! (level-get *level* s5-0) 'active)
    )
  (on #t)
  (if arg1
      (initialize! *game-info* 'game (the-as game-save #f) (the-as string #f))
      )
  0
  )

;; definition for function update-sound-banks
(defun update-sound-banks ()
  (if (nonzero? (rpc-busy? 1))
      (return 0)
      )
  (let ((gp-0 #f)
        (s5-0 #f)
        )
    (dotimes (s4-0 (-> *level* length))
      (let ((v1-5 (-> *level* level s4-0)))
        (when (= (-> v1-5 status) 'active)
          (let* ((s3-0 (-> v1-5 info sound-banks))
                 (t0-0 (the-as symbol (car s3-0)))
                 )
            (while (not (null? s3-0))
              (cond
                ((or (= gp-0 t0-0) (= s5-0 t0-0) (-> *setting-control* current movie))
                 )
                ((not gp-0)
                 (set! gp-0 t0-0)
                 )
                ((not s5-0)
                 (set! s5-0 t0-0)
                 )
                (else
                  (format 0 "ERROR: Soundbanks ~A, ~A and ~A all required~%" gp-0 s5-0 t0-0)
                  )
                )
              (set! s3-0 (cdr s3-0))
              (set! t0-0 (the-as symbol (car s3-0)))
              )
            )
          )
        )
      )
    (when (and gp-0 (!= gp-0 *sound-bank-1*) (!= gp-0 *sound-bank-2*))
      (when (not *sound-bank-1*)
        (format 0 "Load soundbank ~A~%" gp-0)
        (sound-bank-load (string->sound-name (symbol->string gp-0)))
        (set! *sound-bank-1* gp-0)
        (return 0)
        )
      (when (not *sound-bank-2*)
        (format 0 "Load soundbank ~A~%" gp-0)
        (sound-bank-load (string->sound-name (symbol->string gp-0)))
        (set! *sound-bank-2* gp-0)
        (return 0)
        )
      (when (!= *sound-bank-1* s5-0)
        (format 0 "Unload soundbank ~A~%" *sound-bank-1*)
        (sound-bank-unload (string->sound-name (symbol->string *sound-bank-1*)))
        (set! *sound-bank-1* #f)
        (return 0)
        )
      (when (!= *sound-bank-2* s5-0)
        (format 0 "Unload soundbank ~A~%" *sound-bank-2*)
        (sound-bank-unload (string->sound-name (symbol->string *sound-bank-2*)))
        (set! *sound-bank-2* #f)
        (return 0)
        )
      )
    (when (and s5-0 (!= s5-0 *sound-bank-1*) (!= s5-0 *sound-bank-2*))
      (when (not *sound-bank-1*)
        (format 0 "Load soundbank ~A~%" s5-0)
        (sound-bank-load (string->sound-name (symbol->string s5-0)))
        (set! *sound-bank-1* s5-0)
        (return 0)
        )
      (when (not *sound-bank-2*)
        (format 0 "Load soundbank ~A~%" s5-0)
        (sound-bank-load (string->sound-name (symbol->string s5-0)))
        (set! *sound-bank-2* s5-0)
        (return 0)
        )
      (when (!= *sound-bank-1* gp-0)
        (format 0 "Unload soundbank ~A~%" *sound-bank-1*)
        (sound-bank-unload (string->sound-name (symbol->string *sound-bank-1*)))
        (set! *sound-bank-1* #f)
        (return 0)
        )
      (when (!= *sound-bank-2* gp-0)
        (format 0 "Unload soundbank ~A~%" *sound-bank-2*)
        (sound-bank-unload (string->sound-name (symbol->string *sound-bank-2*)))
        (set! *sound-bank-2* #f)
        (return 0)
        )
      )
    )
  0
  )

;; definition for method 10 of type load-state
(defmethod update! load-state ((obj load-state))
  (update-sound-banks)
  (let ((v1-0 #f))
    (dotimes (s5-0 2)
      (let ((s4-0 (-> *level* level s5-0)))
        (when (!= (-> s4-0 status) 'inactive)
          (let ((a0-6 #f))
            (dotimes (a1-2 2)
              (if (= (-> s4-0 name) (-> obj want a1-2 name))
                  (set! a0-6 #t)
                  )
              )
            (when (not a0-6)
              (format 0 "Discarding level ~A~%" (-> s4-0 name))
              (level-status-set! s4-0 'inactive)
              (set! v1-0 #t)
              )
            )
          )
        )
      )
    (let ((s5-1 #f))
      (if (and (= (-> *level* level0 status) 'inactive) (= (-> *level* level1 status) 'inactive))
          (set! s5-1 #t)
          )
      (if v1-0
          (return 0)
          )
      (let ((a0-20 #f)
            (v1-5 #f)
            )
        (when (-> obj want 0 name)
          (set! a0-20 #t)
          (dotimes (a1-12 3)
            (let ((a2-9 (-> *level* level a1-12)))
              (if (and (!= (-> a2-9 status) 'inactive) (= (-> a2-9 name) (-> obj want 0 name)))
                  (set! a0-20 #f)
                  )
              )
            )
          )
        (when (-> obj want 1 name)
          (set! v1-5 #t)
          (dotimes (a1-17 3)
            (let ((a2-17 (-> *level* level a1-17)))
              (if (and (!= (-> a2-17 status) 'inactive) (= (-> a2-17 name) (-> obj want 1 name)))
                  (set! v1-5 #f)
                  )
              )
            )
          )
        (let ((s4-1 -1))
          (cond
            ((and a0-20 v1-5)
             (set! s4-1 0)
             (if (and (-> obj want 1 display?) (not (-> obj want 0 display?)))
                 (set! s4-1 1)
                 )
             )
            (a0-20
              (set! s4-1 0)
              )
            (v1-5
              (set! s4-1 1)
              )
            )
          (when (!= s4-1 -1)
            (when (or s5-1 (not (check-busy *load-dgo-rpc*)))
              (format 0 "Adding level ~A~%" (-> obj want s4-1 name))
              (let ((s3-0 (level-get-for-use *level* (-> obj want s4-1 name) 'loaded)))
                (when (and s5-1 (-> obj want s4-1 display?))
                  (format 0 "Waiting for level to load~%")
                  (while (or (= (-> s3-0 status) 'loading) (= (-> s3-0 status) 'loading-bt) (= (-> s3-0 status) 'login))
                    (load-continue s3-0)
                    )
                  )
                )
              )
            )
          )
        )
      )
    )
  (dotimes (s5-2 2)
    (when (-> obj want s5-2 name)
      (dotimes (s4-2 3)
        (let ((s3-1 (-> *level* level s4-2)))
          (when (!= (-> s3-1 status) 'inactive)
            (when (= (-> s3-1 name) (-> obj want s5-2 name))
              (when (!= (-> s3-1 display?) (-> obj want s5-2 display?))
                (cond
                  ((not (-> s3-1 display?))
                   (cond
                     ((or (= (-> s3-1 status) 'loaded) (= (-> s3-1 status) 'active))
                      (format 0 "Displaying level ~A [~A]~%" (-> obj want s5-2 name) (-> obj want s5-2 display?))
                      (level-get-for-use *level* (-> s3-1 info name) 'active)
                      (set! (-> s3-1 display?) (-> obj want s5-2 display?))
                      )
                     (else
                       (if (and (-> s3-1 info wait-for-load) (!= (-> obj want s5-2 display?) 'display-no-wait))
                           (send-event *target* 'loading)
                           )
                       (if (= *cheat-mode* 'debug)
                           (format *stdcon* "display on for ~A but level is loading~%" (-> obj want s5-2 name))
                           )
                       )
                     )
                   )
                  ((not (-> obj want s5-2 display?))
                   (set! (-> s3-1 display?) #f)
                   (format 0 "Turning level ~A off~%" (-> s3-1 name))
                   (deactivate s3-1)
                   )
                  (else
                    (format 0 "Setting level ~A display command to ~A~%" (-> obj want s5-2 name) (-> obj want s5-2 display?))
                    (set! (-> s3-1 display?) (-> obj want s5-2 display?))
                    )
                  )
                )
              (when (!= (-> s3-1 force-all-visible?) (-> obj want s5-2 force-vis?))
                (set! (-> s3-1 force-all-visible?) (-> obj want s5-2 force-vis?))
                (format 0 "Setting force-all-visible?[~A] to ~A~%" (-> obj want s5-2 name) (-> obj want s5-2 force-vis?))
                )
              (when (!= (-> s3-1 force-inside?) (-> obj want s5-2 force-inside?))
                (set! (-> s3-1 force-inside?) (-> obj want s5-2 force-inside?))
                (format 0 "Setting force-inside?[~A] to ~A~%" (-> obj want s5-2 name) (-> obj want s5-2 force-inside?))
                )
              )
            )
          )
        )
      )
    )
  (let ((s5-3 #f))
    (dotimes (v1-121 (-> *level* length))
      (let ((a0-55 (-> *level* level v1-121)))
        (when (= (-> a0-55 status) 'active)
          (if (nonzero? (-> a0-55 vis-info (-> a0-55 vis-self-index) ramdisk))
              (set! s5-3 (-> a0-55 nickname))
              )
          )
        )
      )
    (when (and (!= s5-3 (-> obj vis-nick)) (-> *level* vis?))
      (when (-> obj vis-nick)
        (dotimes (s4-3 (-> *level* length))
          (let ((v1-133 (-> *level* level s4-3)))
            (when (= (-> v1-133 status) 'active)
              (if (and (= (-> v1-133 nickname) (-> obj vis-nick)) (-> v1-133 inside-boxes?))
                  (load-vis-info (-> obj vis-nick) s5-3)
                  )
              )
            )
          )
        )
      )
    )
  0
  )

;; definition for method 16 of type level-group
(defmethod level-update level-group ((obj level-group))
  (camera-pos)
  (new 'static 'boxed-array :type symbol :length 0 :allocated-length 2)
  (update *setting-control*)
  (update *art-control* #t)
  (clear-rec *art-control*)
  (dotimes (s5-0 2)
    (load-continue (-> obj level s5-0))
    )
  (dotimes (s5-1 (-> obj length))
    (let ((s4-0 (-> obj level s5-1)))
      (when (= (-> s4-0 status) 'active)
        (set! (-> s4-0 inside-boxes?) (point-in-boxes? s4-0 (-> *math-camera* trans)))
        (set! (-> s4-0 inside-sphere?) (>= (-> s4-0 bsp bsphere w) (-> s4-0 level-distance)))
        (if (-> s4-0 inside-boxes?)
            (set! (-> s4-0 meta-inside?) #t)
            )
        )
      )
    )
  (update! *load-state*)
  (dotimes (s5-2 (-> obj length))
    (let ((s4-1 (-> obj level s5-2)))
      (when (= (-> s4-1 status) 'active)
        (if (and (-> s4-1 inside-boxes?) (not (-> s4-1 other inside-boxes?)))
            (set! (-> s4-1 other meta-inside?) #f)
            )
        (when (and (null? (-> obj load-commands))
                   (= (-> s4-1 nickname) (-> *load-state* vis-nick))
                   (!= (-> s4-1 name) (-> *game-info* current-continue level))
                   (-> *level* border?)
                   )
          (let ((s3-0 (the-as continue-point (car (-> s4-1 info continues)))))
            (let* ((s2-0 (target-pos 0))
                   (s4-2 (-> s4-1 info continues))
                   (s1-0 (the-as continue-point (car s4-2)))
                   )
              (while (not (null? s4-2))
                (if (and (< (vector-vector-distance s2-0 (-> s1-0 trans)) (vector-vector-distance s2-0 (-> s3-0 trans)))
                         (zero? (-> s1-0 flags))
                         )
                    (set! s3-0 s1-0)
                    )
                (set! s4-2 (cdr s4-2))
                (set! s1-0 (the-as continue-point (car s4-2)))
                )
              )
            (set-continue! *game-info* s3-0)
            )
          )
        )
      )
    )
  (dotimes (v1-67 (-> obj length))
    (let ((a0-26 (-> obj level v1-67)))
      (when (= (-> a0-26 status) 'active)
        (set! (-> a0-26 vis-self-index) 0)
        (set! (-> a0-26 vis-adj-index) 7)
        (when (= (-> a0-26 other status) 'active)
          (dotimes (a1-10 8)
            (if (and (-> a0-26 vis-info a1-10) (= (-> a0-26 vis-info a1-10 from-level) (-> a0-26 other load-name)))
                (set! (-> a0-26 vis-adj-index) a1-10)
                )
            )
          )
        )
      )
    )
  (when *display-level-border*
    (dotimes (s5-3 (-> obj length))
      (let ((s4-3 (-> obj level s5-3)))
        (when (= (-> s4-3 status) 'active)
          (let ((s3-1 (-> s4-3 bsp current-bsp-back-flags)))
            (dotimes (s2-1 6)
              (when (and (logtest? s3-1 3) (-> s4-3 vis-info (+ s2-1 1)))
                (let ((v1-88 (lookup-level-info (-> s4-3 vis-info (+ s2-1 1) from-level))))
                  (format
                    *stdcon*
                    "  ~A -> ~A: load: ~A  display: ~A~%"
                    (-> s4-3 name)
                    (-> v1-88 name)
                    (logtest? s3-1 1)
                    (logtest? s3-1 2)
                    )
                  )
                )
              (set! s3-1 (shr s3-1 2))
              )
            )
          )
        )
      )
    )
  (dotimes (s5-4 (-> obj length))
    (let ((s4-4 (-> obj level s5-4)))
      (when (= (-> s4-4 status) 'active)
        (when (and (= (-> s4-4 nickname) (-> *load-state* vis-nick)) (not (-> s4-4 inside-boxes?)))
          (if (and (= *cheat-mode* 'debug) (-> s4-4 other inside-boxes?))
              (format *stdcon* "~3LForcing outside of ~A [bad split boxes]~%~0L" (-> s4-4 other name))
              )
          (set! (-> s4-4 other inside-boxes?) #f)
          )
        )
      )
    )
  (cond
    ((not (or (-> obj level0 inside-boxes?) (-> obj level1 inside-boxes?)))
     (when (or (-> obj level0 vis-info 0) (-> obj level1 vis-info 0))
       (if (= *cheat-mode* 'debug)
           (format *stdcon* "~3Loutside of bsp~%~0L")
           )
       )
     )
    (else
      (dotimes (v1-125 (-> obj length))
        (let ((a0-44 (-> obj level v1-125)))
          (when (= (-> a0-44 status) 'active)
            (dotimes (a1-17 8)
              (let ((a2-18 (-> a0-44 vis-info a1-17)))
                (when a2-18
                  (set! (-> a2-18 flags) (logand (the-as uint #xffffffff7fffffff) (-> a2-18 flags)))
                  (cond
                    ((= a1-17 (-> a0-44 vis-self-index))
                     (set! (-> a2-18 from-bsp) (-> a0-44 bsp))
                     )
                    ((= a1-17 (-> a0-44 vis-adj-index))
                     (set! (-> a2-18 from-bsp) (-> a0-44 other bsp))
                     )
                    (else
                      (set! (-> a2-18 from-bsp) #f)
                      )
                    )
                  )
                )
              )
            (cond
              ((= (-> a0-44 display?) 'display-self)
               (let ((a0-46 (-> a0-44 vis-info (-> a0-44 vis-self-index))))
                 (if a0-46
                     (set! (-> a0-46 flags) (the-as uint (logior (shl #x8000 16) (-> a0-46 flags))))
                     )
                 )
               )
              ((and (-> a0-44 inside-boxes?) (not (-> a0-44 other inside-boxes?)))
               (let ((a0-48 (-> a0-44 vis-info (-> a0-44 vis-self-index))))
                 (if a0-48
                     (set! (-> a0-48 flags) (the-as uint (logior (shl #x8000 16) (-> a0-48 flags))))
                     )
                 )
               )
              ((-> a0-44 other inside-boxes?)
               (let ((a0-50 (-> a0-44 vis-info (-> a0-44 vis-adj-index))))
                 (if a0-50
                     (set! (-> a0-50 flags) (the-as uint (logior (shl #x8000 16) (-> a0-50 flags))))
                     )
                 )
               )
              )
            )
          )
        )
      )
    )
  (when (or *display-level-border* *display-texture-download* *display-split-box-info*)
    (when *display-level-border*
      (format
        *stdcon*
        "  want: ~A ~A/~A   ~A ~A/~A~%"
        (-> *load-state* want 0 name)
        (-> *load-state* want 0 display?)
        (-> *load-state* want 0 force-vis?)
        (-> *load-state* want 1 name)
        (-> *load-state* want 1 display?)
        (-> *load-state* want 1 force-vis?)
        )
      (let ((t9-16 format)
            (a0-53 *stdcon*)
            (a1-49 "  nick ~A cur ~S  cont ~A~%~%")
            (a2-24 (-> *load-state* vis-nick))
            (v1-142 (and *target* (-> *target* current-level name)))
            )
        (t9-16
          a0-53
          a1-49
          a2-24
          (if v1-142
              (symbol->string (the-as symbol v1-142))
              )
          (-> *game-info* current-continue name)
          )
        )
      )
    (dotimes (s5-5 (-> obj length))
      (let ((s4-5 (-> obj level s5-5)))
        (when (= (-> s4-5 status) 'active)
          (format
            *stdcon*
            "~A: ~S ~A~%"
            (-> s4-5 name)
            (if (point-in-boxes? s4-5 (-> *math-camera* trans))
                "inside"
                )
            (-> s4-5 display?)
            )
          (when *display-texture-download*
            (format *stdcon* "  tfrag: ~8,,0m     " (-> s4-5 closest-object 0))
            (format *stdcon* "  shrub: ~8,,0m     " (-> s4-5 closest-object 2))
            (format *stdcon* "  alpha: ~8,,0m  #x~8X~%" (-> s4-5 closest-object 3) (-> s4-5 texture-mask 8))
            (format *stdcon* "    tie: ~8,,0m     " (-> s4-5 closest-object 5))
            (format *stdcon* "  fg-tf: ~8,,0m     " (-> s4-5 closest-object 6))
            (format *stdcon* "  fg-pr: ~8,,0m  #x~8X~%" (-> s4-5 closest-object 7) (-> s4-5 texture-mask 7))
            (format
              *stdcon*
              "  tf: ~8D  pr: ~8D  sh: ~8D  al: ~8D  wa: ~8D~%~1K"
              (-> s4-5 upload-size 0)
              (-> s4-5 upload-size 1)
              (-> s4-5 upload-size 2)
              (-> s4-5 upload-size 3)
              (-> s4-5 upload-size 4)
              )
            )
          (if *display-split-box-info*
              (debug-print-splitbox s4-5 (-> *math-camera* trans) *stdcon*)
              )
          )
        )
      )
    )
  0
  )

;; definition (debug) for function show-level
(defun-debug show-level ((arg0 symbol))
  (set! (-> *setting-control* default border-mode) #t)
  (load-state-want-levels (-> (level-get-target-inside *level*) name) arg0)
  (load-state-want-display-level arg0 'display)
  0
  )

;; failed to figure out what this is:
(when (zero? (-> *level* level0 art-group))
  (let ((gp-0 *level*))
    (set! (-> gp-0 vis?) #f)
    (set! (-> gp-0 loading-level) (-> gp-0 level-default))
    (set! (-> gp-0 level0 art-group) (new 'global 'load-dir-art-group 50 (-> gp-0 level0)))
    (set! (-> gp-0 level0 foreground-draw-engine 0) (new 'global 'engine 'draw 280))
    (set! (-> gp-0 level0 foreground-draw-engine 1) (new 'global 'engine 'draw 280))
    (set! (-> gp-0 level0 foreground-draw-engine 2) (new 'global 'engine 'draw 16))
    (set! (-> gp-0 level1 art-group) (new 'global 'load-dir-art-group 50 (-> gp-0 level1)))
    (set! (-> gp-0 level1 foreground-draw-engine 0) (new 'global 'engine 'draw 280))
    (set! (-> gp-0 level1 foreground-draw-engine 1) (new 'global 'engine 'draw 280))
    (set! (-> gp-0 level1 foreground-draw-engine 2) (new 'global 'engine 'draw 16))
    (set! (-> gp-0 level-default art-group) (new 'global 'load-dir-art-group 50 (-> gp-0 level1)))
    (set! (-> gp-0 level-default foreground-draw-engine 0) (new 'global 'engine 'draw 280))
    (set! (-> gp-0 level-default foreground-draw-engine 1) (new 'global 'engine 'draw 10))
    (set! (-> gp-0 level0 other) (-> gp-0 level1))
    (set! (-> gp-0 level1 other) (-> gp-0 level0))
    (set! (-> gp-0 level-default other) #f)
    (dotimes (s5-0 2)
      (let ((s4-0 (-> gp-0 level s5-0)))
        (set! (-> s4-0 vis-bits) (malloc 'global 2048))
        (vis-clear s4-0)
        )
      )
    (dotimes (v1-36 3)
      (let ((a0-50 (-> gp-0 level v1-36)))
        (set! (-> a0-50 linking) #f)
        (dotimes (a1-46 3)
          (set! (-> a0-50 foreground-sink-group a1-46 level) a0-50)
          )
        )
      )
    )
  )
