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

;; name: scene.gc
;; name in dgo: scene
;; dgos: ENGINE, GAME

;; DECOMP BEGINS

(deftype scene-stage (process-hidden)
  ()
  )


(defmethod print ((this scene))
  (format #t "#<scene ~A ~A @ #x~X>" (-> this art-group) (-> this anim) this)
  this
  )

;; WARN: Return type mismatch spool-anim vs none.
(defmethod scene-method-15 ((this scene) (arg0 spool-anim))
  (set! (-> arg0 name) (-> this anim))
  (set! (-> arg0 anim-name) (-> this anim))
  (set! (-> arg0 parts) (-> this parts))
  (set! (-> arg0 command-list) (-> this command-list))
  (none)
  )

;; WARN: Return type mismatch basic vs continue-point.
(defun scene-decode-continue ((arg0 basic))
  (the-as continue-point (cond
                           ((not arg0)
                            (the-as basic #f)
                            )
                           ((= (-> arg0 type) continue-point)
                            arg0
                            )
                           ((= (-> arg0 type) string)
                            (get-continue-by-name *game-info* (the-as string arg0))
                            )
                           (else
                             (the-as basic #f)
                             )
                           )
          )
  )

(defmethod scene-actor-method-9 ((this scene-actor) (arg0 scene-player))
  (local-vars (s4-0 (pointer process)) (sv-96 process) (sv-112 process))
  (let ((s1-0 (if (-> this level)
                  (level-get *level* (-> this level))
                  (-> *level* default-level)
                  )
              )
        )
    (cond
      ((not s1-0)
       (-> *level* default-level)
       (set! s4-0 (the-as (pointer process) #f))
       (goto cfg-211)
       )
      ((= (-> s1-0 status) 'reserved)
       )
      ((!= (-> s1-0 status) 'active)
       (set! s4-0 (the-as (pointer process) #f))
       (goto cfg-211)
       )
      )
    (let* ((s4-1 (art-group-get-by-name *level* (-> this art-group) (the-as (pointer uint32) #f)))
           (s2-0 (if (type? s4-1 skeleton-group)
                     (the-as skeleton-group s4-1)
                     )
                 )
           (s0-0 (-> arg0 level))
           (s3-0
             (or (string= (-> this name) "jak-highres")
                 (string= (-> this name) "jak-highres-prison")
                 (string= (-> this name) "darkjak-highres")
                 )
             )
           )
      (set! (-> arg0 level) #f)
      (set! s4-0
            (when s2-0
              (let ((s1-1 (if (and (nonzero? (-> s1-0 entity)) (> (-> s1-0 entity length) 0))
                              (-> s1-0 entity data 0 entity)
                              (-> arg0 entity)
                              )
                          )
                    )
                (set! sv-96 (get-process *default-dead-pool* manipy #x4000))
                (set! s4-0 (when sv-96
                             (let ((t9-7 (method-of-type manipy activate)))
                               (t9-7 (the-as manipy sv-96) arg0 (-> this name) (the-as pointer #x70004000))
                               )
                             (run-now-in-process
                               sv-96
                               manipy-init
                               (-> arg0 root trans)
                               s1-1
                               s2-0
                               #f
                               (if (and s3-0 (logtest? (game-secrets big-head little-head) (-> *game-info* secrets)))
                                   1
                                   0
                                   )
                               )
                             (-> sv-96 ppointer)
                             )
                      )
                (set! (-> arg0 level) s0-0)
                (send-event (ppointer->process s4-0) 'anim-mode 'clone-anim)
                (send-event (ppointer->process s4-0) 'blend-shape #t)
                (send-event (ppointer->process s4-0) 'prefix (-> this prefix))
                (cond
                  ((zero? (-> this light-index))
                   (if (zero? (-> s2-0 light-index))
                       (send-event (ppointer->process s4-0) 'light-index 80)
                       )
                   )
                  (else
                    (send-event (ppointer->process s4-0) 'light-index (* (-> this light-index) 8))
                    )
                  )
                (if (nonzero? (-> this shadow-mask))
                    (send-event (ppointer->process s4-0) 'shadow-mask (* (-> this shadow-mask) 8))
                    )
                (if (nonzero? (-> this shadow-values))
                    (send-event (ppointer->process s4-0) 'shadow-values (* (-> this shadow-values) 8))
                    )
                (if (and s4-0 (not (logtest? (-> this flags) 1)) (nonzero? (-> (the-as process-drawable (-> s4-0 0)) draw)))
                    (logior! (-> (the-as process-drawable (-> s4-0 0)) draw status) (draw-control-status no-draw-bounds))
                    )
                (if (-> this shadow-volume-joint)
                    (send-event (ppointer->process s4-0) 'shadow-volume (-> this shadow-volume-joint) (-> this shadow-flags))
                    )
                (if (or (nonzero? (-> this draw-seg)) (nonzero? (-> this no-draw-seg)))
                    (send-event (ppointer->process s4-0) 'segment (* (-> this draw-seg) 8) (* (-> this no-draw-seg) 8))
                    )
                (when s3-0
                  (if (not (-> *setting-control* user-current beard))
                      (send-event (ppointer->process s4-0) 'segment 0 16)
                      )
                  (when (and s4-0 (nonzero? (-> (the-as scene-player (-> s4-0 0)) old-target-pos scale x)))
                    (cond
                      ((logtest? (game-secrets little-head) (-> *game-info* secrets))
                       (mode-set! (-> (the-as manipy (-> s4-0 0)) joint 0) (joint-mod-mode joint-set*))
                       (trs-set!
                         (-> (the-as manipy (-> s4-0 0)) joint 0)
                         (the-as vector #f)
                         (the-as quaternion #f)
                         (new 'static 'vector :x 0.4 :y 0.4 :z 0.4 :w 1.0)
                         )
                       )
                      ((logtest? (game-secrets big-head) (-> *game-info* secrets))
                       (mode-set! (-> (the-as manipy (-> s4-0 0)) joint 0) (joint-mod-mode joint-set*))
                       (trs-set!
                         (-> (the-as manipy (-> s4-0 0)) joint 0)
                         (the-as vector #f)
                         (the-as quaternion #f)
                         (new 'static 'vector :x 2.0 :y 2.0 :z 2.0 :w 1.0)
                         )
                       )
                      )
                    )
                  )
                (when (and s4-0 (logtest? (-> this flags) 2))
                  (set! sv-112 (get-process *default-dead-pool* manipy #x4000))
                  (let ((s0-1 (when sv-112
                                (let ((t9-24 (method-of-type manipy activate)))
                                  (t9-24 (the-as manipy sv-112) (ppointer->process s4-0) (-> this name) (the-as pointer #x70004000))
                                  )
                                (run-now-in-process sv-112 manipy-init (-> arg0 root trans) s1-1 s2-0 #f 0)
                                (-> sv-112 ppointer)
                                )
                              )
                        )
                    (send-event (ppointer->process s0-1) 'mirror #t)
                    (send-event (ppointer->process s0-1) 'anim-mode 'mirror)
                    (if (nonzero? (-> this light-index))
                        (send-event (ppointer->process s0-1) 'light-index (* (-> this light-index) 8))
                        )
                    (if (nonzero? (-> this shadow-mask))
                        (send-event (ppointer->process s0-1) 'shadow-mask (* (-> this shadow-mask) 8))
                        )
                    (if (nonzero? (-> this shadow-values))
                        (send-event (ppointer->process s0-1) 'shadow-values (* (-> this shadow-values) 8))
                        )
                    (if (and s0-1 (not (logtest? (-> this flags) 1)) (nonzero? (-> (the-as process-drawable (-> s0-1 0)) draw)))
                        (logior! (-> (the-as process-drawable (-> s0-1 0)) draw status) (draw-control-status no-draw-bounds))
                        )
                    (if (-> this shadow-volume-joint)
                        (send-event (ppointer->process s0-1) 'shadow-volume (-> this shadow-volume-joint) (-> this shadow-flags))
                        )
                    (if (or (nonzero? (-> this draw-seg)) (nonzero? (-> this no-draw-seg)))
                        (send-event (ppointer->process s0-1) 'segment (* (-> this draw-seg) 8) (* (-> this no-draw-seg) 8))
                        )
                    (when s3-0
                      (if (not (-> *setting-control* user-current beard))
                          (send-event (ppointer->process s0-1) 'segment 0 16)
                          )
                      )
                    )
                  )
                )
              (when (nonzero? (-> this camera))
                (cond
                  ((handle->process (-> arg0 camera))
                   (change-parent (handle->process (-> arg0 camera)) (ppointer->process s4-0))
                   (send-event (handle->process (-> arg0 camera)) 'target (ppointer->process s4-0))
                   (send-event (handle->process (-> arg0 camera)) 'joint (* (-> this camera) 8))
                   )
                  (else
                    (set! (-> arg0 camera) (ppointer->handle (process-spawn
                                                               othercam
                                                               (ppointer->process s4-0)
                                                               (-> this camera)
                                                               #t
                                                               'scene-player
                                                               :to (ppointer->process s4-0)
                                                               )
                                                             )
                          )
                    )
                  )
                )
              s4-0
              )
            )
      )
    )
  (label cfg-211)
  s4-0
  )

(defmethod deactivate ((this scene-player))
  "Make a process dead, clean it up, remove it from the active pool, and return to dead pool."
  (set! *scene-player* (the-as (pointer scene-player) #f))
  (kill-persister *setting-control* (the-as engine-pers 'blackout) 'bg-a-force)
  ((method-of-type process-drawable deactivate) this)
  (none)
  )

;; WARN: Return type mismatch process-drawable vs scene-player.
(defmethod relocate ((this scene-player) (offset int))
  (let ((v1-0 *kernel-context*))
    (set! (-> v1-0 relocating-process) this)
    (set! (-> v1-0 relocating-min) (the-as int (&-> this type)))
    (set! (-> v1-0 relocating-max)
          (the-as int (+ (+ (-> this allocated-length) -4 (-> process size)) (the-as int this)))
          )
    (set! (-> v1-0 relocating-offset) offset)
    )
  (let ((v1-2 (-> this scene-list)))
    (if (and (>= (the-as int v1-2) (-> *kernel-context* relocating-min))
             (< (the-as int v1-2) (-> *kernel-context* relocating-max))
             )
        (&+! (-> this scene-list) offset)
        )
    )
  (the-as scene-player ((method-of-type process-drawable relocate) this offset))
  )

(defmethod scene-player-method-25 ((this scene-player) (arg0 float))
  (local-vars (v1-11 symbol) (v1-40 symbol) (s0-0 object) (s0-1 object))
  (dotimes (s4-0 (-> this scene actor length))
    (let ((s3-0 (-> this scene actor s4-0)))
      (let* ((s2-0 (-> s3-0 draw-frames))
             (s1-0 (car s2-0))
             )
        (while (not (null? s2-0))
          (when (and (pair? s1-0)
                     (let ((a0-4 (car s1-0)))
                       (set! s0-0 (car (cdr s1-0)))
                       (or (= a0-4 'min) (>= arg0 (command-get-float a0-4 0.0)))
                       )
                     (or (= s0-0 'max) (< arg0 (command-get-float (car (cdr s1-0)) 0.0)))
                     )
            (set! v1-11 #t)
            (goto cfg-20)
            )
          (set! s2-0 (cdr s2-0))
          (set! s1-0 (car s2-0))
          )
        )
      (set! v1-11 #f)
      (label cfg-20)
      (cond
        (v1-11
          (if (not (handle->process (-> s3-0 process)))
              (set! (-> s3-0 process) (ppointer->handle (scene-actor-method-9 s3-0 this)))
              )
          (let ((s2-1 (handle->process (-> s3-0 process))))
            (when (and s2-1 (nonzero? (-> (the-as process-drawable s2-1) draw)))
              (let* ((s3-1 (-> s3-0 scissor-frames))
                     (s1-1 (car s3-1))
                     )
                (while (not (null? s3-1))
                  (when (and (pair? s1-1)
                             (let ((a0-20 (car s1-1)))
                               (set! s0-1 (car (cdr s1-1)))
                               (or (= a0-20 'min) (>= arg0 (command-get-float a0-20 0.0)))
                               )
                             (or (= s0-1 'max) (< arg0 (command-get-float (car (cdr s1-1)) 0.0)))
                             )
                    (set! v1-40 #t)
                    (goto cfg-59)
                    )
                  (set! s3-1 (cdr s3-1))
                  (set! s1-1 (car s3-1))
                  )
                )
              (set! v1-40 #f)
              (label cfg-59)
              (if v1-40
                  (logclear! (-> (the-as process-drawable s2-1) draw status) (draw-control-status force-vu1))
                  (logior! (-> (the-as process-drawable s2-1) draw status) (draw-control-status force-vu1))
                  )
              )
            )
          )
        ((handle->process (-> s3-0 process))
         (deactivate (handle->process (-> s3-0 process)))
         )
        )
      )
    )
  0
  (none)
  )

;; WARN: Return type mismatch basic vs scene.
(defun scene-lookup ((arg0 basic))
  "TODO - basic can be a string or a scene"
  (the-as
    scene
    (case (-> arg0 type)
      ((string)
       (let ((s5-0 (art-group-get-by-name *level* (the-as string arg0) (the-as (pointer uint32) #f))))
         (when (type? s5-0 scene)
           (let ((gp-0 (get-level-by-heap-ptr-and-status *level* (the-as pointer s5-0) 'active)))
             (when (and s5-0 gp-0)
               (let ((v1-5 (scene-decode-continue (-> s5-0 data 17))))
                 (when v1-5
                   (dotimes (a0-6 6)
                     (if (= (-> gp-0 name) (-> v1-5 want a0-6 name))
                         (goto cfg-15)
                         )
                     )
                   (format
                     0
                     "WARNING: can not find scene level ~A in continue ~A, dropping scene until after load~%"
                     (-> gp-0 name)
                     (-> v1-5 name)
                     )
                   (return (the-as scene #f))
                   )
                 )
               )
             )
           (label cfg-15)
           s5-0
           )
         )
       )
      ((scene)
       arg0
       )
      )
    )
  )

;; WARN: Return type mismatch basic vs scene.
(defmethod scene-player-method-24 ((this scene-player) (arg0 basic) (arg1 symbol))
  "TODO - arg1 can be string/scene"
  (when (= (-> arg0 type) string)
    (let ((v1-2 (scene-lookup arg0)))
      (if v1-2
          (set! arg0 v1-2)
          )
      )
    )
  (when (or (not arg0) (!= (-> arg0 type) scene))
    (format 0 "ERROR: SCENE: scene-player can not find scene ~A~%" arg0)
    (go process-drawable-art-error "scene-list format")
    )
  (when arg1
    (let ((s4-1 (get-level-by-heap-ptr-and-status *level* (the-as pointer arg0) 'active)))
      (scene-method-15 (the-as scene arg0) (-> this anim))
      (set! (-> this level) s4-1)
      )
    (set! (-> this scene) (the-as scene arg0))
    )
  (the-as scene arg0)
  )

(defmethod scene-player-method-23 ((this scene-player) (arg0 string) (arg1 symbol))
  (let ((gp-0 (scene-player-method-24 this arg0 #t)))
    (when (-> gp-0 peaceful)
      (let ((s3-0 *traffic-manager*))
        (send-event s3-0 'decrease-alert-level 0)
        (send-event s3-0 'restore-default-settings)
        )
      )
    (send-event *target* 'draw (-> gp-0 draw-target))
    (let ((s3-1 (entity-by-name (-> gp-0 entity))))
      (when (and (-> gp-0 entity) (not s3-1))
        (format 0 "ERROR: SCENE: scene ~A can not find entity ~A~%" (-> gp-0 name) (-> gp-0 entity))
        (go process-drawable-art-error (-> gp-0 entity))
        )
      (set! (-> this main-entity) (the-as entity-actor s3-1))
      (cond
        (s3-1
          (process-drawable-from-entity! this (-> this main-entity))
          (logclear! (-> this mask) (process-mask actor-pause))
          )
        (else
          (vector-reset! (-> this root trans))
          (quaternion-identity! (-> this root quat))
          )
        )
      )
    (let ((s3-2 (load-to-heap-by-name (-> *level* default-level art-group) (-> gp-0 art-group) #f global 0)))
      (when (not s3-2)
        (format 0 "ERROR: SCENE: scene ~A can not find art-group ~A~%" (-> gp-0 name) (-> gp-0 art-group))
        (go process-drawable-art-error (-> gp-0 art-group))
        )
      (set! (-> this draw art-group) s3-2)
      (countdown (v1-33 (-> s3-2 length))
        (when (-> s3-2 data v1-33)
          (cond
            ((= (-> s3-2 data v1-33 type) merc-ctrl)
             (set! (-> this draw mgeo) (the-as merc-ctrl (-> s3-2 data v1-33)))
             )
            ((= (-> s3-2 data v1-33 type) art-joint-geo)
             (set! (-> this draw jgeo) (the-as art-joint-geo (-> s3-2 data v1-33)))
             )
            )
          )
        )
      )
    (cond
      ((< (+ (-> this scene-index) 1) (-> this scene-list length))
       (let ((a0-34 (scene-player-method-24 this (-> this scene-list (+ (-> this scene-index) 1)) #f)))
         (cond
           (a0-34
             (scene-method-15 a0-34 (-> this next-anim))
             )
           (else
             (set! (-> this next-anim anim-name) (the-as basic 0))
             0
             )
           )
         )
       )
      (else
        (set! (-> this next-anim anim-name) (the-as basic 0))
        0
        )
      )
    (dotimes (s3-3 (-> gp-0 actor length))
      (let ((s2-0 (-> gp-0 actor s3-3)))
        (set! (-> s2-0 process) (the-as handle #f))
        (let ((s1-0 (if (-> s2-0 level)
                        (level-get *level* (-> s2-0 level))
                        (-> *level* default-level)
                        )
                    )
              (v1-55 (when level
                       (let ((s0-0 (art-group-get-by-name *level* (-> s2-0 art-group) (the-as (pointer uint32) #f))))
                         (if (type? s0-0 skeleton-group)
                             s0-0
                             )
                         )
                       )
                     )
              )
          (cond
            ((or (not s1-0) (not (or (= (-> s1-0 status) 'active) (= (-> s1-0 status) 'reserved))))
             (format
               0
               "ERROR: SCENE: scene actor ~A can not find an active level ~A~%"
               (-> s2-0 art-group)
               (-> s2-0 level)
               )
             )
            ((not v1-55)
             (format
               0
               "ERROR: SCENE: scene actor ~A can not find skeleton-group ~A~%"
               (-> s2-0 art-group)
               (-> s2-0 art-group)
               )
             )
            (else
              (load-to-heap-by-name (-> s1-0 art-group) (the-as string (-> v1-55 data 0)) #f global 0)
              )
            )
          )
        )
      )
    (process-entity-status! this (entity-perm-status no-kill) #t)
    (when arg1
      (set-setting! 'region-mode #f 0.0 0)
      (set-setting! 'process-mask 'set 0.0 (-> gp-0 mask-to-clear))
      (set-setting! 'sound-bank-load #f 0.0 0)
      (set-setting! 'movie (process->ppointer this) 0.0 0)
      (set-setting! 'movie-name (-> gp-0 name) 0.0 0)
      (set-setting!
        'music-volume
        'rel
        (if (>= (-> gp-0 music-volume) 0.0)
            (-> gp-0 music-volume)
            (-> *setting-control* user-current music-volume-movie)
            )
        0
        )
      (set-setting!
        'sfx-volume
        'rel
        (if (>= (-> gp-0 sfx-volume) 0.0)
            (-> gp-0 sfx-volume)
            (-> *setting-control* user-current sfx-movie-volume)
            )
        0
        )
      (set-setting!
        'ambient-volume
        'rel
        (if (>= (-> gp-0 ambient-volume) 0.0)
            (-> gp-0 ambient-volume)
            (-> *setting-control* user-current ambient-volume-move)
            )
        0
        )
      (if (nonzero? (the int (-> gp-0 music-delay)))
          (set-setting! 'sound-mode #f 0.0 2)
          )
      (set-setting! 'gem #f 0.0 0)
      (apply-settings *setting-control*)
      )
    )
  0
  (none)
  )

(deftype subtitle-work (structure)
  ((draw-tmpl  dma-gif-packet  :inline)
   (color0     vector4w        :inline)
   (color1     vector4w        :inline)
   )
  )


(define *subtitle-work*
  (new 'static 'subtitle-work
    :draw-tmpl (new 'static 'dma-gif-packet
      :dma-vif (new 'static 'dma-packet
        :dma (new 'static 'dma-tag :qwc #x6 :id (dma-tag-id cnt))
        :vif1 (new 'static 'vif-tag :imm #x6 :cmd (vif-cmd direct) :msk #x1)
        )
      :gif0 (new 'static 'gif-tag64
        :nloop #x1
        :eop #x1
        :pre #x1
        :prim (new 'static 'gs-prim :prim (gs-prim-type sprite) :tme #x1 :abe #x1 :fst #x1)
        :nreg #x5
        )
      :gif1 (new 'static 'gif-tag-regs
        :regs0 (gif-reg-id rgbaq)
        :regs1 (gif-reg-id uv)
        :regs2 (gif-reg-id xyz2)
        :regs3 (gif-reg-id uv)
        :regs4 (gif-reg-id xyz2)
        )
      )
    :color0 (new 'static 'vector4w :w #x80)
    :color1 (new 'static 'vector4w :x #x80 :y #x80 :z #x80 :w #x80)
    )
  )

;; og:preserve-this
(defun pc-upload-subtitle-texture ((dma-buf dma-buffer) (image-data pointer) (clut-data pointer) (width int) (height int) (tbp int) (cbp int))
  "Added PC-port function to send a mt4 texture."
  (pc-texture-anim-flag start-anim-array dma-buf)
  (pc-texture-anim-flag upload-generic-vram dma-buf :qwc 1)
  (let ((upload-record (the texture-anim-pc-upload (-> dma-buf base))))
    (set! (-> upload-record data) clut-data)
    (set! (-> upload-record width) 2)
    (set! (-> upload-record height) 8)
    (set! (-> upload-record dest) cbp)
    (set! (-> upload-record format) (gs-psm ct32))
    (set! (-> upload-record force-to-gpu) 0)
    )
  (&+! (-> dma-buf base) 16)

  (pc-texture-anim-flag upload-generic-vram dma-buf :qwc 1)
  (let ((upload-record (the texture-anim-pc-upload (-> dma-buf base))))
    (set! (-> upload-record data) image-data)
    (set! (-> upload-record width) width)
    (set! (-> upload-record height) height)
    (set! (-> upload-record dest) tbp)
    (set! (-> upload-record format) (gs-psm mt4))
    (set! (-> upload-record force-to-gpu) 1)
    )
  (&+! (-> dma-buf base) 16)
  (pc-texture-anim-flag finish-anim-array dma-buf)
  )

;; WARN: Return type mismatch pointer vs none.
(defun draw-subtitle-image ((arg0 subtitle-image) (arg1 font-context))
  (local-vars (sv-16 pointer) (sv-32 int))
  (let ((gp-0 (-> arg0 width))
        (s5-0 (-> arg0 height))
        )
    (let ((s4-0 (-> *display* frames (-> *display* on-screen) global-buf)))
      (set! sv-16 (-> s4-0 base))
      (unpack-comp-rle (the-as (pointer int8) sv-16) (the-as (pointer int8) (-> arg0 data)))
      (&+! (-> s4-0 base) (logand -16 (+ (shr (* gp-0 s5-0) 1) 15)))
      )
    (with-dma-buffer-add-bucket ((s3-0 (-> *display* frames (-> *display* on-screen) global-buf))
                                 (bucket-id subtitle)
                                 )
      ;; og:preserve-this
      ;; (upload-vram-data s3-0 0 (-> arg0 palette) 2 8)
      (let ((s0-0 20))
        (pc-upload-subtitle-texture
          s3-0  ;; dma-buf
          sv-16 ;; image data
          (-> arg0 palette) ;; clut data
          (the int (-> arg0 width))
          (the int (-> arg0 height))
          1 ;; tbp
          0 ;; cbp
          )
        ; (dma-buffer-add-gs-set s3-0
        ;                        (bitbltbuf (new 'static 'gs-bitbltbuf :dbp #x1 :dbw (shr gp-0 6) :dpsm s0-0))
        ;                        (trxpos (new 'static 'gs-trxpos))
        ;                        (trxreg (new 'static 'gs-trxreg :rrw gp-0 :rrh s5-0))
        ;                        (trxdir (new 'static 'gs-trxdir))
        ;                        )
        ; (let ((t9-2 dma-buffer-add-ref-texture)
        ;       (a0-13 s3-0)
        ;       (a2-8 gp-0)
        ;       (a3-1 s5-0)
        ;       (t0-1 s0-0)
        ;       )
        ;   (t9-2 a0-13 sv-16 (the-as int a2-8) (the-as int a3-1) (the-as gs-psm t0-1))
        ;   )
        (set! sv-32 (+ (log2 (the-as int (+ gp-0 -1))) 1))
        (let ((v1-17 (+ (log2 (the-as int (+ s5-0 -1))) 1)))
          (dma-buffer-add-gs-set s3-0
                                 (test-1 (new 'static 'gs-test :ate #x1 :afail #x3 :zte #x1 :ztst (gs-ztest always)))
                                 (alpha-1 (new 'static 'gs-alpha :b #x1 :d #x1))
                                 (tex0-1 (new 'static 'gs-tex0 :tbp0 #x1 :tcc #x1 :cld #x1 :psm s0-0 :th v1-17 :tw sv-32 :tbw (shr gp-0 6)))
                                 ;; og:preserve-this added texture filtering for PC port here:
                                 (tex1-1 (new 'static 'gs-tex1 :mmag 1 :mmin 1))
                                 (clamp-1 (new 'static 'gs-clamp :wms (gs-tex-wrap-mode clamp) :wmt (gs-tex-wrap-mode clamp)))
                                 (texflush 0)
                                 )
          )
        )
      (let* ((v1-28 (-> s3-0 base))
             (a2-23
               (+ (- 1793 (the-as int (shr (-> arg0 width) 1))) (the int (+ (-> arg1 origin x) (/ (-> arg1 width) 2))))
               )
             (a3-8 (+ (the int (-> arg1 origin y)) 1841))
             (a0-23 (+ a2-23 (-> arg0 width)))
             (a1-33 (+ a3-8 (-> arg0 height)))
             )
        ;; og:preserve-this
        (#when PC_PORT
          (when (not (-> *pc-settings* use-vis?))
            (let ((corrected-width (the int (* (-> *pc-settings* aspect-ratio-reciprocal) (-> arg0 width)))))
              (set! a2-23 (+ (- 1793 (the-as int (shr corrected-width 1))) (the int (+ (-> arg1 origin x) (* 0.5 (-> arg1 width))))))
              (set! a0-23 (+ a2-23 corrected-width))
              )
            )
          )
        (set! (-> (the-as (pointer uint128) v1-28) 0) (-> *subtitle-work* draw-tmpl dma-vif quad))
        (set! (-> (the-as (pointer uint128) v1-28) 1) (-> *subtitle-work* draw-tmpl quad 1))
        (set! (-> (the-as (pointer uint128) v1-28) 2) (-> *subtitle-work* color0 quad))
        (set-vector! (the-as vector4w (&+ v1-28 48)) 0 0 0 0)
        (set-vector! (the-as vector4w (&+ v1-28 64)) (the-as int (* a2-23 16)) (* a3-8 16) 0 0)
        (set-vector! (the-as vector4w (&+ v1-28 80)) (the-as int (* gp-0 16)) (the-as int (* s5-0 16)) 0 0)
        (set-vector! (the-as vector4w (&+ v1-28 96)) (the-as int (* a0-23 16)) (* a1-33 16) 0 0)
        )
      (&+! (-> s3-0 base) 112)
      (let* ((v1-32 (-> s3-0 base))
             (a1-38
               (+ (- 1792 (the-as int (shr (-> arg0 width) 1))) (the int (+ (-> arg1 origin x) (/ (-> arg1 width) 2))))
               )
             (a3-11 (+ (the int (-> arg1 origin y)) 1840))
             (a0-30 (+ a1-38 (-> arg0 width)))
             (a2-28 (+ a3-11 (-> arg0 height)))
             )
        ;; og:preserve-this
        (#when PC_PORT
          (when (not (-> *pc-settings* use-vis?))
            (let ((corrected-width (the int (* (-> *pc-settings* aspect-ratio-reciprocal) (-> arg0 width)))))
              (set! a1-38 (+ (- 1793 (the-as int (shr corrected-width 1))) (the int (+ (-> arg1 origin x) (* 0.5 (-> arg1 width))))))
              (set! a0-30 (+ a1-38 corrected-width))
              )
            )
          )
        (set! (-> (the-as (pointer uint128) v1-32) 0) (-> *subtitle-work* draw-tmpl dma-vif quad))
        (set! (-> (the-as (pointer uint128) v1-32) 1) (-> *subtitle-work* draw-tmpl quad 1))
        (set! (-> (the-as (pointer uint128) v1-32) 2) (-> *subtitle-work* color1 quad))
        (set-vector! (the-as vector4w (&+ v1-32 48)) 0 0 0 0)
        (set-vector! (the-as vector4w (&+ v1-32 64)) (the-as int (* a1-38 16)) (* a3-11 16) 0 0)
        (set-vector! (the-as vector4w (&+ v1-32 80)) (the-as int (* gp-0 16)) (the-as int (* s5-0 16)) 0 0)
        (set-vector! (the-as vector4w (&+ v1-32 96)) (the-as int (* a0-30 16)) (* a2-28 16) 0 0)
        )
      (&+! (-> s3-0 base) 112)
      (set-dirty-mask! (-> *level* default-level) 8 (the-as int (* gp-0 s5-0)) 256)
      )
    )
  (none)
  )

(defbehavior process-drawable-draw-subtitles process-drawable ()
  (when (and (nonzero? (-> self skel))
             (> (-> self skel active-channels) 0)
             (-> *setting-control* user-current subtitle)
             )
    (let ((v1-9 (-> self skel root-channel 0 frame-group)))
      (when v1-9
        ;; og:preserve-this send a movie-no-subtitle message so the pc subtitle system at least knows there's a movie playing
        (#when PC_PORT
            (if (= (-> self type) scene-player)
                (send-event (ppointer->process *subtitle2*) 'movie-no-subtitle (-> (the scene-player self) anim name) #f (ja-aframe-num 0))))
        (let ((gp-0 (res-lump-struct (-> v1-9 extra) 'subtitle-range (array subtitle-range))))
          (when gp-0
            (let ((f30-0 (ja-aframe-num 0))
                  (s5-0 (the-as int (-> *setting-control* user-current subtitle-language)))
                  )
              ;; og:preserve-this constant
              (if (and (= (the-as language-enum s5-0) (language-enum english)) (= (scf-get-territory) GAME_TERRITORY_SCEE))
                  (set! s5-0 7)
                  )
              (dotimes (s4-0 (-> gp-0 length))
                (let ((v1-16 (-> gp-0 s4-0)))
                  (when (and (>= f30-0 (-> v1-16 start-frame)) (< f30-0 (-> v1-16 end-frame)))
                    (let ((s3-0 (-> v1-16 message s5-0)))
                      (when (and s3-0 (nonzero? s3-0))
                        (let ((s2-0
                                (new 'stack 'font-context *font-default-matrix* 20 290 0.0 (font-color default) (font-flags shadow kerning))
                                )
                              )
                          (let ((v1-20 s2-0))
                            (set! (-> v1-20 width) (the float 465))
                            )
                          (let ((v1-21 s2-0))
                            (set! (-> v1-21 height) (the float 70))
                            )
                          (let ((v1-22 s2-0))
                            (set! (-> v1-22 scale) 0.5)
                            )
                          (set! (-> s2-0 flags) (font-flags shadow kerning middle large))
                          (case (-> s3-0 type)
                            ((string)
                             (when (= (-> *setting-control* user-default subtitle-language) (language-enum korean))
                               (set! s3-0 (convert-korean-text (the-as string s3-0)))
                               (let ((v1-27 s2-0))
                                 (set! (-> v1-27 scale) 0.6)
                                 )
                               )
                             (set! (-> s2-0 flags) (font-flags kerning middle middle-vert large))
                             (+! (-> s2-0 origin x) -1.0)
                             (+! (-> s2-0 origin y) -1.0)
                             (set! (-> s2-0 color) (font-color font-color-39))
                             (+! (-> s2-0 origin x) 1.0)
                             (+! (-> s2-0 origin y) 1.0)
                             (set! (-> s2-0 color) (font-color default))
                             (set! (-> s2-0 flags) (font-flags shadow kerning middle middle-vert large))
                             ;; og:preserve-this
                             (#if PC_PORT
                                  (if (or (!= (-> self type) scene-player)
                                          (not (send-event (ppointer->process *subtitle2*) 'movie (-> (the scene-player self) anim name) s3-0 f30-0)))
                                      (print-game-text (the-as string s3-0) s2-0 #f 44 (bucket-id subtitle)))

                                  (print-game-text (the-as string s3-0) s2-0 #f 44 (bucket-id subtitle)))
                             (gui-control-method-12
                               *gui-control*
                               self
                               (gui-channel subtitle)
                               (gui-action play)
                               "scene"
                               0
                               81920.0
                               (new 'static 'sound-id)
                               )
                             )
                            ((subtitle-image)
                             (draw-subtitle-image (the-as subtitle-image s3-0) s2-0)
                             )
                            (else
                              (if *debug-segment*
                                  (format *stdcon* "unknown message ~A~%" s3-0)
                                  )
                              )
                            )
                          )
                        )
                      )
                    )
                  )
                )
              )
            )
          )
        )
      )
    )
  0
  (none)
  )

(defstate wait (scene-player)
  :virtual #t
  :enter (behavior ((arg0 symbol))
    (set-time! (-> self state-time))
    (when (or (-> self scene) (-> self preload-continue))
      (let ((gp-0 (scene-decode-continue (the-as basic (if (-> self scene)
                                                           (-> self scene load-point-obj)
                                                           (-> self preload-continue)
                                                           )
                                                 )
                                         )
                  )
            )
        (when gp-0
          (when (-> self scene)
            (set-setting! 'borrow (-> self scene borrow) 0.0 0)
            (apply-settings *setting-control*)
            )
          (cond
            ((and *target*
                  (zero? (-> self scene-index))
                  (or (not (-> self scene)) (!= (level-status *level* (-> gp-0 vis-nick)) 'active))
                  )
             (send-event *target* 'continue gp-0)
             )
            (else
              (let ((a0-9 (lookup-level-info (-> gp-0 vis-nick))))
                (set! (-> *load-state* vis-nick) (if a0-9
                                                     (-> a0-9 name)
                                                     )
                      )
                )
              (dotimes (v1-23 6)
                (set! (-> *load-state* want v1-23 name) (-> gp-0 want v1-23 name))
                (set! (-> *load-state* want v1-23 display?) (-> gp-0 want v1-23 display?))
                (set! (-> *load-state* want v1-23 force-vis?) #f)
                (set! (-> *load-state* want v1-23 force-inside?) #f)
                )
              (update-task-masks 'event)
              )
            )
          )
        )
      )
    )
  :trans (behavior ()
    (if (and (-> self scene) (nonzero? (-> self anim anim-name)) (not (load-in-progress? *level*)))
        (gui-control-method-12
          *gui-control*
          self
          (gui-channel art-load)
          (gui-action queue)
          (-> self anim name)
          0
          -1.0
          (new 'static 'sound-id)
          )
        )
    (set! (-> *ACTOR-bank* birth-max) 1000)
    )
  :code (behavior ((arg0 symbol))
    (local-vars (v1-18 symbol) (v1-118 symbol))
    (when (and (-> self scene) (zero? (-> self scene wait-max-time)))
      (while *progress-process*
        (suspend)
        )
      (set-setting! 'allow-progress #f 0.0 0)
      (set-setting! 'bg-a-force 'abs 1.0 0)
      (apply-settings *setting-control*)
      )
    (if (or (not *target*) (or (focus-test? *target* grabbed)
                               (begin
                                 (dotimes (v1-17 6)
                                   (when (= (-> *load-state* want v1-17 name) (-> *target* current-level name))
                                     (set! v1-18 #f)
                                     (goto cfg-19)
                                     )
                                   )
                                 #t
                                 (set! v1-18 #t)
                                 (label cfg-19)
                                 (or v1-18 (not (-> self scene)))
                                 )
                               )
            )
        (set! arg0 #f)
        )
    (while (and arg0
                (or (focus-test? *target* in-air)
                    (and (-> *target* next-state) (= (-> *target* next-state name) 'target-flop-hit-ground))
                    )
                (-> self scene)
                (not (time-elapsed? (-> self state-time) (-> self scene wait-air-time)))
                )
      (suspend)
      )
    (suspend)
    (let ((s5-0 (current-time)))
      (when (and *target* (not (logtest? (-> *target* focus-status) (focus-status grabbed))))
        (label cfg-44)
        (when (not (process-grab? *target* #f))
          (suspend)
          (goto cfg-44)
          )
        )
      (process-entity-status! self (entity-perm-status no-kill) #t)
      ;; og:preserve-this
      ;; NOTE - for speedrunner mode, allows the game to continue
      ;; even if there is a dialogue in progress
      (until (not (or (-> *setting-control* user-current spooling)
                      (when (not (-> *pc-settings* speedrunner-mode?))
                        (or (-> *setting-control* user-current talking)
                            (-> *setting-control* user-current hint)
                            (-> *setting-control* user-current ambient)))))
        (set-setting! 'allow-progress #f 0.0 0)
        (apply-settings *setting-control*)
        (dotimes (s4-0 2)
          ;; og:preserve-this
          ;; NOTE - for speedrunner mode, allows the game to continue
          ;; even if there is a dialogue in progress
          (while (or (-> *setting-control* user-current spooling)
                     (when (not (-> *pc-settings* speedrunner-mode?))
                        (or (-> *setting-control* user-current talking)
                            (-> *setting-control* user-current hint)
                            (-> *setting-control* user-current ambient)))
                     (or (and (-> *setting-control* user-current movie)
                              (!= (-> *setting-control* user-current movie) (process->ppointer self))
                              )
                         *progress-process*
                         (!= (get-status *gui-control* (-> self gui-id)) 3)
                         )
                     )
            (suspend)
            )
          )
        (when arg0
          (while (and (-> self scene) (not (or (time-elapsed? s5-0 (-> self scene wait-ground-time))
                                               (time-elapsed? (-> self state-time) (-> self scene wait-max-time))
                                               )
                                           )
                      )
            (suspend)
            )
          )
        (remove-setting! 'movie)
        (remove-setting! 'sound-bank-load)
        (remove-setting! 'movie-name)
        (remove-setting! 'bg-a-force)
        (apply-settings *setting-control*)
        (set-blackout-frames (seconds 0.1))
        (suspend)
        (set-blackout-frames (seconds 0.1))
        (suspend)
        )
      )
    (send-event *target* 'trans 'save (-> self old-target-pos))
    (let ((gp-1 *load-state*))
      (when gp-1
        (dotimes (s5-1 2)
          (while (begin
                   (dotimes (s4-1 6)
                     (when (not (or (not (-> gp-1 want s4-1 name))
                                    (not (-> gp-1 want s4-1 display?))
                                    (= (level-status *level* (-> gp-1 want s4-1 name)) 'active)
                                    )
                                )
                       (set! v1-118 #t)
                       (goto cfg-109)
                       )
                     )
                   (set! v1-118 #f)
                   (label cfg-109)
                   v1-118
                   )
            (set-blackout-frames (seconds 0.1))
            (suspend)
            )
          (when (and (zero? s5-1) (< (-> self scene-index) (-> self scene-list length)))
            (scene-player-method-24 self (-> self scene-list (-> self scene-index)) #t)
            (when (-> self scene)
              (set-setting! 'borrow (-> self scene borrow) 0.0 0)
              (apply-settings *setting-control*)
              )
            )
          )
        )
      )
    (if (and *target* (focus-test? *target* in-head flut board pilot mech dark))
        (send-event *target* 'change-mode 'normal)
        )
    (when (< (-> self scene-index) (-> self scene-list length))
      (scene-player-method-24 self (-> self scene-list (-> self scene-index)) #t)
      (while (and (-> self scene)
                  (nonzero? (-> self anim anim-name))
                  (let ((v1-161 (file-status *art-control* (-> self anim name) 0)))
                    (or (not (or (= v1-161 'active) (= v1-161 'locked)))
                        (let* ((a1-26 (lookup-gui-connection-id
                                        *gui-control*
                                        (the-as string (-> self anim anim-name))
                                        (gui-channel none)
                                        (gui-action none)
                                        )
                                      )
                               (v1-167 (get-status *gui-control* a1-26))
                               )
                          (not (or (= v1-167 (gui-status ready)) (= v1-167 (gui-status active))))
                          )
                        )
                    )
                  )
        (set-blackout-frames (seconds 0.1))
        (suspend)
        )
      )
    (go-virtual play-anim)
    )
  )

(defstate release (scene-player)
  :virtual #t
  :code (behavior ()
    (when (= (-> *game-info* demo-state) 100)
      (logclear! (-> self mask) (process-mask pause progress))
      (set-blackout-frames (seconds 0.05))
      (set-setting! 'music-volume 'abs 0.0 0)
      (set-setting! 'sfx-volume 'abs 0.0 0)
      (set-setting! 'ambient-volume 'abs 0.0 0)
      (set-setting! 'allow-pause #f 0.0 0)
      (set-setting! 'allow-progress #f 0.0 0)
      (setup
        *screen-filter*
        (new 'static 'vector)
        (new 'static 'vector :w 128.0)
        (* 30.0 (seconds-per-frame))
        (bucket-id screen-filter)
        )
      (suspend-for (seconds 0.05)
        )
      (set! (-> *setting-control* user-current bg-a) 0.0)
      (remove-setting! 'movie)
      (remove-setting! 'movie-name)
      (while (or (-> *setting-control* user-current movie)
                 (not *target*)
                 (!= (-> *setting-control* user-current bg-a) 0.0)
                 )
        (suspend)
        )
      (set! (-> *game-info* blackout-time) 0)
      (set! (-> *game-info* demo-state) (the-as uint 1))
      (set! (-> *setting-control* user-current bg-a-force) 0.0)
      (set-setting! 'allow-progress #t 0.0 0)
      (remove-setting! 'process-mask)
      (apply-settings *setting-control*)
      (send-event *target* 'draw #t)
      (send-event *target* 'trans 'reset)
      (send-event *target* 'change-mode 'normal)
      (activate-progress *dproc* 'select-scene-special)
      (dotimes (gp-1 5)
        (suspend)
        )
      (disable *screen-filter*)
      (deactivate self)
      )
    ;; og:preserve-this there is a bug here. scene-index has already been advanced by this point, so we need to backtrack when checking things
    (when (< (#if PC_PORT (1- (-> self scene-index)) (-> self scene-index)) (+ (-> self scene-list length) -1))
      (set! (-> self scene-index) (+ (-> self scene-list length) -1))
      (scene-player-method-24 self (-> self scene-list (-> self scene-index)) #t)
      )
    (let ((gp-2 (or (not (-> self scene)) (-> self scene blackout-end))))
      (if gp-2
          (set-blackout-frames (seconds 0.1))
          )
      (send-event *target* 'draw #t)
      (send-event *target* 'trans 'reset)
      (suspend)
      (while (not (process-release? *target*))
        (suspend)
        (if gp-2
            (set-blackout-frames (seconds 0.1))
            )
        )
      (if gp-2
          (set-blackout-frames (seconds 0.1))
          )
      )
    (if (nonzero? (the int (-> self scene music-delay)))
        (persist-with-delay
          *setting-control*
          'music-delay
          (the-as time-frame (the int (-> self scene music-delay)))
          'sound-mode
          #f
          0.0
          2
          )
        )
    (cond
      ((and *target* (-> self scene) (-> self scene end-point-obj))
       (let ((gp-3 (scene-decode-continue (the-as basic (-> self scene end-point-obj)))))
         (when gp-3
           (set-continue! *game-info* gp-3 #f)
           (send-event *target* 'continue gp-3)
           )
         )
       )
      (else
        (send-event *target* 'trans 'restore (-> self old-target-pos))
        )
      )
    (if (and (-> self scene) (-> self scene save))
        (auto-save-user)
        )
    )
  )

(defstate play-anim (scene-player)
  :virtual #t
  :event (behavior ((proc process) (argc int) (message symbol) (block event-message-block))
    (case message
      (('abort)
       (set! (-> self aborted?) #t)
       (set-blackout-frames (seconds 0.2))
       (let ((a0-3 (-> self anim)))
         (when (and a0-3 (= (-> *setting-control* user-current spooling) (process->ppointer self)))
           (ja-abort-spooled-anim a0-3 (the-as art-joint-anim #f) -1)
           (ja-channel-set! 0)
           )
         )
       (go-virtual release)
       )
      )
    )
  :exit (behavior ()
    (while (-> self child)
      (deactivate (-> self child 0))
      )
    (kill-current-talker (the-as symbol '()) '(daxter voicebox message) 'exit)
    (set! (-> *setting-control* user-current bg-a) 0.0)
    (kill-persister *setting-control* (the-as engine-pers 'bg-a) 'bg-a)
    (kill-persister *setting-control* (the-as engine-pers 'bg-a-speed) 'bg-a-speed)
    (remove-setting! 'borrow)
    (remove-setting! 'gem)
    (apply-settings *setting-control*)
    )
  :trans (behavior ()
    (cond
      ((not (-> *setting-control* user-current spooling))
       (if (and (-> self scene) (nonzero? (-> self anim anim-name)))
           (gui-control-method-12
             *gui-control*
             self
             (gui-channel art-load)
             (gui-action queue)
             (-> self anim name)
             0
             -1.0
             (new 'static 'sound-id)
             )
           )
       )
      (else
        (if (and (-> self scene) (nonzero? (-> self next-anim anim-name)))
            (gui-control-method-12
              *gui-control*
              self
              (gui-channel art-load)
              (gui-action queue)
              (-> self next-anim name)
              0
              -1.0
              (new 'static 'sound-id)
              )
            )
        )
      )
    )
  :code (behavior ()
    (local-vars (a0-24 symbol))
    (if (and (= (-> *game-info* demo-state) 100) (-> self scene) (nonzero? (-> self scene scene-task)))
        (task-node-open! (the-as game-task-node (-> self scene scene-task)))
        )
    (dotimes (gp-0 2)
      (let ((v1-11 (-> *art-control* buffer gp-0)))
        (if (= (-> v1-11 status) 'active)
            (link-art! (-> v1-11 art-group))
            )
        )
      )
    (while (and (< (-> self scene-index) (-> self scene-list length)) (not (-> self aborted?)))
      (scene-player-method-23 self (the-as string (-> self scene-list (-> self scene-index))) #t)
      (set-blackout-frames (seconds 0.1))
      (suspend)
      (set-blackout-frames (seconds 0.1))
      (suspend)
      (scene-player-method-25 self 0.0)
      (set! (-> self cur-speed) 0.0)
      (set-time! (-> self scene-start-time))
      (ja-play-spooled-anim
        (-> self anim)
        (the-as art-joint-anim #f)
        (the-as art-joint-anim #f)
        (the-as
          (function process-drawable symbol)
          (if (-> self scene abort)
              (lambda :behavior scene-player () (when (cpad-pressed? 0 triangle)
                                                  (set! (-> self aborted?) #t)
                                                  (logclear! (-> *cpad-list* cpads 0 button0-abs 0) (pad-buttons triangle))
                                                  (logclear! (-> *cpad-list* cpads 0 button0-rel 0) (pad-buttons triangle))
                                                  #t
                                                  )
                                             )
              false-func
              )
          )
        )
      (while (-> self child)
        (deactivate (-> self child 0))
        )
      (+! (-> self scene-index) 1)
      (when (and (< (-> self scene-index) (-> self scene-list length)) (not (-> self aborted?)))
        (let ((v1-41 (scene-player-method-24 self (-> self scene-list (-> self scene-index)) #t)))
          (when v1-41
            (let ((a0-21 (scene-decode-continue (the-as basic (-> v1-41 load-point-obj)))))
              (set! a0-24 (when (and a0-21 (logtest? (-> a0-21 flags) (continue-flags scene-wait)))
                            (go-virtual wait a0-24)
                            a0-24
                            )
                    )
              )
            )
          )
        )
      )
    (if (and (-> self wait) *target* (focus-test? *target* grabbed))
        (go-virtual release)
        )
    )
  :post (behavior ()
    (when (-> self scene)
      (let ((gp-0 (-> self scene cut-list))
            (s5-0 (-> self skel root-channel 0 frame-group))
            )
        (when (not (or (null? gp-0) (not s5-0) (zero? s5-0)))
          (let ((v1-8 (the int (ja-frame-num 0)))
                (a0-2 (car gp-0))
                )
            (while (not (null? gp-0))
              (let ((f0-5 (/ (- (the float (/ (the-as int a0-2) 8)) (-> s5-0 artist-base)) (-> s5-0 artist-step))))
                (when (= v1-8 (if (= f0-5 (the float (the int f0-5)))
                                  (+ (the int f0-5) -1)
                                  (the int f0-5)
                                  )
                         )
                  (set! (-> self skel root-channel 0 frame-num) (the float (the int (-> self skel root-channel 0 frame-num))))
                  (set! (-> self pre-cut-frame) (the-as basic #t))
                  )
                )
              (set! gp-0 (cdr gp-0))
              (set! a0-2 (car gp-0))
              )
            )
          )
        )
      (if (-> self pre-cut-frame)
          (set! (-> self pre-cut-frame) #f)
          )
      )
    (when (and (-> self scene) (nonzero? (-> self skel active-channels)))
      (if (and (< (ja-aframe-num 0) 2.0) (logtest? (-> self skel status) (joint-control-status valid-spooled-frame)))
          (set-blackout-frames 0)
          )
      (scene-player-method-25 self (ja-aframe-num 0))
      (set! (-> self dma-max)
            (the-as uint (max
                           (the-as int (-> self dma-max))
                           (* (dma-buffer-length (-> *display* frames (-> *display* last-screen) global-buf)) 16)
                           )
                    )
            )
      (let ((gp-4 *display-scene-control*))
        (when (nonzero? gp-4)
          (if (logtest? gp-4 (scene-controls bounds-spheres))
              (debug-print-channels (-> self skel) (the-as symbol *stdcon*))
              )
          (if (logtest? gp-4 (scene-controls actors))
              (format *stdcon* "anim ~-30S " (-> self scene anim))
              )
          (if (logtest? gp-4 (scene-controls actor-marks))
              (format
                *stdcon*
                "dma ~DK / ~DK"
                (shr (* (dma-buffer-length (-> *display* frames (-> *display* last-screen) global-buf)) 16) 10)
                (shr (-> self dma-max) 10)
                )
              )
          (if (logtest? gp-4 (scene-controls actors actor-marks))
              (format *stdcon* "~%")
              )
          (when (logtest? gp-4 (scene-controls special-fma-spheres))
            (dotimes (s5-3 (-> self scene actor length))
              (let* ((s4-1 (handle->process (-> self scene actor s5-3 process)))
                     (v1-63 (if (type? s4-1 process-drawable)
                                (the-as process-drawable s4-1)
                                )
                            )
                     )
                (if (and v1-63 (nonzero? (-> v1-63 draw)))
                    (add-debug-sphere
                      #t
                      (bucket-id debug-no-zbuf1)
                      (-> v1-63 draw origin)
                      (-> v1-63 draw bounds w)
                      (new 'static 'rgba :b #xff :a #x80)
                      )
                    )
                )
              )
            )
          (when (logtest? gp-4 (scene-controls scene-controls-7))
            (dotimes (s5-4 (-> self scene actor length))
              (let* ((s4-2 (handle->process (-> self scene actor s5-4 process)))
                     (v1-79 (if (type? s4-2 process-drawable)
                                (the-as process-drawable s4-2)
                                )
                            )
                     )
                (if (and v1-79 (nonzero? (-> v1-79 draw)))
                    (format
                      *stdcon*
                      "~0K  ~-30S  ~S d:~4,,0m r:~4,,0m~1K~%"
                      (-> self scene actor s5-4 art-group)
                      (if (logtest? (-> v1-79 draw status) (draw-control-status on-screen))
                          "os"
                          "  "
                          )
                      (-> v1-79 draw distance)
                      (-> v1-79 draw bounds w)
                      )
                    )
                )
              )
            )
          (when (logtest? gp-4 (scene-controls scene-controls-8))
            (dotimes (gp-5 (-> self scene actor length))
              (let* ((s5-5 (handle->process (-> self scene actor gp-5 process)))
                     (v1-94 (if (type? s5-5 process-drawable)
                                (the-as process-drawable s5-5)
                                )
                            )
                     )
                (if (and v1-94 (nonzero? (-> v1-94 draw)))
                    (add-debug-text-3d
                      #t
                      (bucket-id debug-no-zbuf1)
                      (-> v1-94 name)
                      (-> v1-94 draw origin)
                      (font-color yellow)
                      (new 'static 'vector2h :data (new 'static 'array int16 2 0 8))
                      )
                    )
                )
              )
            )
          )
        )
      )
    (when (cpad-pressed? 0 square)
      (set! (-> *setting-control* user-default subtitle) (not (-> *setting-control* user-default subtitle)))
      (set-time! (-> self subtitle-change-time))
      )
    (when (and (not (time-elapsed? (-> self subtitle-change-time) (seconds 2)))
               (< (mod (- (current-time) (-> self subtitle-change-time)) 300) 210)
               )
      (let ((gp-6
              (new 'stack 'font-context *font-default-matrix* 36 60 0.0 (font-color default) (font-flags shadow kerning))
              )
            )
        (let ((v1-121 gp-6))
          (set! (-> v1-121 width) (the float 440))
          )
        (let ((v1-122 gp-6))
          (set! (-> v1-122 height) (the float 48))
          )
        (let ((v1-123 gp-6))
          (set! (-> v1-123 scale) 0.5)
          )
        (set! (-> gp-6 flags) (font-flags shadow kerning middle large))
        (print-game-text
          (lookup-text!
            *common-text*
            (if (-> *setting-control* user-default subtitle)
                (text-id scene-subtitles-enabled)
                (text-id scene-subtitles-disabled)
                )
            #f
            )
          gp-6
          #f
          44
          (bucket-id subtitle)
          )
        )
      )
    (process-drawable-draw-subtitles)
    (when (and (= *cheat-mode* 'debug) (-> self scene))
      (let ((gp-7
              (lookup-gui-connection *gui-control* self (gui-channel art-load) (-> self scene name) (new 'static 'sound-id))
              )
            )
        (when (!= *external-cam-mode* 'pad-0)
          (cond
            ((cpad-hold? 0 r1)
             (if (cpad-pressed? 0 circle)
                 (set-time! (-> self speed-press-time))
                 )
             (seek!
               (-> self speed-change-speed)
               8.0
               (* (lerp-scale 0.01 0.3 (the float (- (current-time) (-> self speed-press-time))) 0.0 300.0)
                  (-> self clock time-adjust-ratio)
                  )
               )
             )
            ((cpad-hold? 0 l1)
             (if (cpad-pressed? 0 square)
                 (set-time! (-> self speed-press-time))
                 )
             (seek!
               (-> self speed-change-speed)
               -8.0
               (* (lerp-scale 0.01 0.3 (the float (- (current-time) (-> self speed-press-time))) 0.0 300.0)
                  (-> self clock time-adjust-ratio)
                  )
               )
             )
            ((cpad-hold? 0 x)
             (when (cpad-pressed? 0 x)
               (set-time! (-> self speed-press-time))
               (cond
                 ((= (-> self cur-speed) 0.0)
                  (set! (-> self speed-change-speed) -1000.0)
                  )
                 (else
                   (set! (-> self targ-speed) 0.0)
                   (set! (-> self speed-change-speed) 0.0)
                   )
                 )
               )
             )
            (else
              (set! (-> self speed-change-speed) 0.0)
              )
            )
          )
        (cond
          ((= (-> self cur-speed) -1000.0)
           (format *stdcon* "scene paused~%")
           (when (!= (-> self targ-speed) -1000.0)
             (sound-continue (-> gp-7 id))
             (when *sound-player-enable*
               (let ((v1-186 (the-as sound-rpc-set-param (get-sound-buffer-entry))))
                 (set! (-> v1-186 command) (sound-command set-param))
                 (set! (-> v1-186 id) (-> gp-7 id))
                 (set! (-> v1-186 params pitch-mod) 0)
                 (set! (-> v1-186 params mask) (the-as uint 2))
                 (-> v1-186 id)
                 )
               )
             (set! (-> self targ-speed) 0.0)
             (set! (-> self cur-speed) 0.0)
             (set-time! (-> self speed-change-time))
             )
           )
          ((= (-> self speed-change-speed) -1000.0)
           (when (!= (-> self cur-speed) -1000.0)
             (set-time! (-> self speed-change-time))
             (set! (-> self targ-speed) -1000.0)
             (set! (-> self cur-speed) -1000.0)
             (sound-pause (-> gp-7 id))
             )
           )
          (else
            (set! (-> self targ-speed)
                  (fmax -10.0 (fmin 10.0 (+ (-> self targ-speed) (* (-> self speed-change-speed) (seconds-per-frame)))))
                  )
            (if (not (time-elapsed? (-> self speed-change-time) (seconds 3)))
                (format
                  *stdcon*
                  "id ~d speed ~f~%"
                  (if gp-7
                      (the-as int (-> gp-7 id))
                      0
                      )
                  (-> self targ-speed)
                  )
                )
            (when (and gp-7 (and (!= (-> self targ-speed) (-> self cur-speed))
                                 (< (-> self speed-change-time) (current-time))
                                 (time-elapsed? (-> self scene-start-time) (seconds 1))
                                 )
                       )
              (when *sound-player-enable*
                (let ((v1-211 (the-as sound-rpc-set-param (get-sound-buffer-entry))))
                  (set! (-> v1-211 command) (sound-command set-param))
                  (set! (-> v1-211 id) (-> gp-7 id))
                  (set! (-> v1-211 params pitch-mod) (the int (* 1524.0 (-> self targ-speed))))
                  (set! (-> v1-211 params mask) (the-as uint 2))
                  (-> v1-211 id)
                  )
                )
              (set! (-> self cur-speed) (-> self targ-speed))
              (set-time! (-> self speed-change-time))
              )
            )
          )
        )
      )
    )
  )

;; WARN: Return type mismatch object vs none.
;; WARN: Using new Jak 2 rtype-of
;; WARN: Using new Jak 2 rtype-of
;; WARN: Using new Jak 2 rtype-of
(defbehavior scene-player-init scene-player ((arg0 object) (arg1 symbol) (arg2 string))
  "`object` arg can be an `(array scene)`, `pair of scene` or a `scene`"
  (process-entity-set! self (the-as entity #f))
  ;; og:preserve-this changed from 512
  (stack-size-set! (-> self main-thread) 768)
  (set! (-> self root) (new 'process 'trsqv))
  (case (rtype-of arg0)
    ((array)
     (set! (-> self scene-list) (new 'process 'boxed-array scene (-> (the-as (array scene) arg0) length)))
     (dotimes (v1-7 (-> self scene-list length))
       (set! (-> self scene-list v1-7) (-> (the-as (array scene) arg0) v1-7))
       )
     )
    ((pair)
     (let ((s3-0 (method-of-type array new))
           (s2-0 'process)
           (s1-0 array)
           (s0-0 scene)
           (a0-14 arg0)
           )
       (set! (-> self scene-list)
             (the-as (array scene) (s3-0 s2-0 s1-0 s0-0 ((method-of-type (rtype-of a0-14) length) a0-14)))
             )
       )
     (dotimes (s3-1 (-> self scene-list length))
       (set! (-> self scene-list s3-1) (the-as scene (ref arg0 s3-1)))
       )
     )
    (else
      (set! (-> self scene-list) (new 'process 'boxed-array scene 1))
      (set! (-> self scene-list 0) (the-as scene arg0))
      )
    )
  (set! (-> self preload-continue) arg2)
  (set! (-> self camera) (the-as handle #f))
  (set! (-> self wait) arg1)
  (set! (-> self pre-cut-frame) #f)
  (set! (-> self aborted?) #f)
  (set! (-> self draw) (new 'process 'draw-control self #f))
  (set! (-> self skel) (new 'process 'joint-control 48))
  (set! (-> self anim) (new 'static 'spool-anim))
  (set! (-> self next-anim) (new 'static 'spool-anim))
  (dotimes (s4-1 (-> self scene-list length))
    (let ((v1-29 (scene-lookup (-> self scene-list s4-1))))
      (if v1-29
          (set! (-> self scene-list s4-1) v1-29)
          )
      )
    )
  (cond
    ((= (-> self scene-list (-> self scene-index) type) scene)
     (set! (-> self scene) (-> self scene-list (-> self scene-index)))
     (if (-> self scene)
         (scene-method-15 (-> self scene) (-> self anim))
         )
     )
    (else
      (set-blackout-frames (seconds 0.2))
      (set! (-> self scene) #f)
      )
    )
  (set! (-> self gui-id) (add-process
                           *gui-control*
                           self
                           (gui-channel movie)
                           (gui-action play)
                           (the-as string (cond
                                            ((= (rtype-of arg0) string)
                                             (empty)
                                             arg0
                                             )
                                            (else
                                              "movie"
                                              )
                                            )
                                   )
                           -99.0
                           0
                           )
        )
  (set! *scene-player* (the-as (pointer scene-player) (process->ppointer self)))
  (set! *display-entity-errors* #f)
  (set-setting! 'speech-control #f 0.0 0)
  (set-setting! 'allow-progress #f 0.0 0)
  (apply-settings *setting-control*)
  (go-virtual wait arg1)
  (none)
  )

(defmethod scene-method-16 ((this scene))
  (let ((v1-1 (-> *level* loading-level)))
    (if v1-1
        (set-loaded-art (-> v1-1 art-group) this)
        )
    )
  this
  )
