Files
jak-project/goal_src/jak2/pc/progress/progress-pc.gc
T
Hat Kid 572efbf9cb jak2: add frame rate option to graphics menu (#2962)
This PR adds a frame rate option to the graphics menu for some of the
most common refresh rates.

Jak 2 has much better support for variable frame rates than Jak 1 out of
the box, but there are still some edge cases, most prominently the fact
that sprites are still limited to the 300 tick system, which is most
noticeable on glow sprites. For this, I abused the glow boost debug
setting to scale the glow based on the frame rate.

While testing, I noticed two other cases that I have also patched,
there's likely to be many more that are yet to be found, but aside from
that, the game is playable as normal.



https://github.com/open-goal/jak-project/assets/6624576/ad4db24f-cd27-4237-a155-0db7008160f3
2023-09-09 10:59:00 -04:00

757 lines
27 KiB
Common Lisp

;;-*-Lisp-*-
(in-package goal)
#|
Additional PC port specific file for overriding/expanding the progress menu
This gives us more freedom to write code how we want.
|#
(deftype progress-global-state-pc (basic)
((decoration-draw-time uint64)
(display-mode-choice-index int8)
(aspect-ratio-choice-index int8)
(aspect-ratio-ratio-index int8)
(frame-rate-choice-index int8)
(music-player-track music-player-track-info)
(music-player-flava int8)
(music-player-selected symbol)
)
)
(define *progress-state-pc* (new 'static 'progress-global-state-pc :music-player-track #f))
(defmacro when-not-drawn-decoration (&rest body)
`(when (> (-> *display* real-clock integral-frame-counter) (-> *progress-state-pc* decoration-draw-time))
,@body
(set! (-> *progress-state-pc* decoration-draw-time) (-> *display* real-clock integral-frame-counter))))
(defun set-progress-aspect-ratio-pc-index ()
"set the progress aspect ratio option index accordingly"
(cond
((not (-> *pc-settings* use-vis?))
(if (-> *pc-settings* aspect-ratio-auto?)
(set! (-> *progress-state-pc* aspect-ratio-choice-index) 2)
(set! (-> *progress-state-pc* aspect-ratio-choice-index) 3))
)
(else
(case (get-aspect-ratio)
(('aspect16x9)
(set! (-> *progress-state-pc* aspect-ratio-choice-index) 1))
(else
(set! (-> *progress-state-pc* aspect-ratio-choice-index) 0)))
)
))
(defun set-progress-display-mode-index ()
"set the progress display mode option index accordingly"
(case (-> *pc-settings* display-mode)
(('windowed #f) (set! (-> *progress-state-pc* display-mode-choice-index) 0))
(('fullscreen) (set! (-> *progress-state-pc* display-mode-choice-index) 1))
(('borderless) (set! (-> *progress-state-pc* display-mode-choice-index) 2))
))
(defun set-progress-frame-rate-index ()
"Set the frame rate option index accordingly."
(case (-> *pc-settings* target-fps)
((30) (set! (-> *progress-state-pc* frame-rate-choice-index) 0))
((50) (set! (-> *progress-state-pc* frame-rate-choice-index) 1))
((60) (set! (-> *progress-state-pc* frame-rate-choice-index) 2))
((75) (set! (-> *progress-state-pc* frame-rate-choice-index) 3))
((120) (set! (-> *progress-state-pc* frame-rate-choice-index) 4))
((144) (set! (-> *progress-state-pc* frame-rate-choice-index) 5))
((165) (set! (-> *progress-state-pc* frame-rate-choice-index) 6))
((240) (set! (-> *progress-state-pc* frame-rate-choice-index) 7))
;; default to 60 fps
(else (set! (-> *progress-state-pc* frame-rate-choice-index) 2))
)
)
(defmethod init-defaults progress ((obj progress))
"Initialize default menu settings."
(set! (-> *progress-state* aspect-ratio-choice) (get-aspect-ratio))
(set! (-> *progress-state* video-mode-choice) (get-video-mode))
(set! (-> *progress-state* yes-no-choice) #f)
(set! (-> *progress-state* on-off-choice) #f)
(set! (-> *progress-state* color-flash-counter) 0)
(set! (-> *progress-state* game-options-item-selected) 0)
(set! (-> *progress-state* game-options-item-picked) #f)
(set! (-> *progress-state* game-options-vibrations) (-> *setting-control* user-default vibration))
(set! (-> *progress-state* game-options-subtitles) (-> *setting-control* user-default subtitle))
(set! (-> *progress-state* game-options-language-index)
(the-as int (-> *setting-control* user-default language))
)
(set! (-> *progress-state* game-options-subtitle-language-index)
(the-as int (-> *setting-control* user-default subtitle-language))
)
(set! (-> *progress-state* graphic-options-item-selected) 0)
(set! (-> *progress-state* graphic-options-item-picked) #f)
(set! (-> *progress-state* graphic-options-aspect-ratio) (get-aspect-ratio))
(set! (-> *progress-state* graphic-options-progressive-scan)
(-> *setting-control* user-default use-progressive-scan)
)
(set! (-> *progress-state* qr-options-item-selected) 0)
(set! (-> *progress-state* qr-options-item-picked) #f)
(set! (-> *progress-state* total-num-tasks) 0)
(set! (-> *progress-state* secrets-unlocked) #f)
(set! (-> *progress-state* clear-screen) #f)
(set! (-> obj sliding) 0.0)
(set! (-> obj sliding-height) 0.0)
(set! (-> obj sliding-off) 1.0)
(set! (-> obj scanlines-alpha) 0.0)
(set! (-> (the-as menu-on-off-game-vibrations-option (-> *game-options* options 0)) value-to-modify)
(&-> *setting-control* user-default vibration)
)
(set! (-> (the-as menu-on-off-game-subtitles-option (-> *game-options* options 1)) value-to-modify)
(&-> *setting-control* user-default subtitle)
)
(set! (-> (the-as menu-language-option (-> *game-options* options 2)) language-selection)
(-> *setting-control* user-current language)
)
(set! (-> (the-as menu-language-option (-> *game-options* options 2)) language-direction) #t)
(set! (-> (the-as menu-language-option (-> *game-options* options 2)) language-transition) #f)
(set! (-> (the-as menu-language-option (-> *game-options* options 2)) language-x-offset) 0)
(set! (-> (the-as menu-on-off-option (-> *game-options-japan* options 0)) value-to-modify)
(&-> *setting-control* user-default vibration)
)
(set! (-> (the-as menu-on-off-option (-> *game-options-demo* options 0)) value-to-modify)
(&-> *setting-control* user-default vibration)
)
(set! (-> (the-as menu-on-off-option (-> *graphic-options* options 2)) value-to-modify)
(&-> *setting-control* user-default use-progressive-scan)
)
(set! (-> (the-as menu-on-off-option (-> *graphic-title-options-pal* options 2)) value-to-modify)
(&-> *setting-control* user-default use-progressive-scan)
)
(set! (-> (the-as menu-slider-option (-> *sound-options* options 0)) value-to-modify)
(&-> *setting-control* user-default sfx-volume)
)
(set! (-> (the-as menu-slider-option (-> *sound-options* options 1)) value-to-modify)
(&-> *setting-control* user-default music-volume)
)
(set! (-> (the-as menu-slider-option (-> *sound-options* options 2)) value-to-modify)
(&-> *setting-control* user-default dialog-volume)
)
(set! (-> (the-as menu-missions-option (-> *missions-options* options 0)) task-line-index) 0)
(set-setting-by-param *setting-control* 'extra-bank '((force2 menu1)) 0 0)
;; PC STATE BEGIN
;; --------------
;; set aspect ratio options
(set-progress-aspect-ratio-pc-index)
(set-progress-display-mode-index)
(set-progress-frame-rate-index)
(set! (-> (the menu-on-off-option (-> *graphic-options-pc* options 3)) value-to-modify) (&-> *pc-settings* vsync?))
(set! (-> *progress-state-pc* music-player-track) #f)
)
(defmethod set-menu-options progress ((obj progress) (arg0 symbol))
"Set the menu options for the menu state specified by arg0."
(set! (-> obj current-options) #f)
(case arg0
(('go-away)
(go (method-of-object obj go-away))
)
(('main)
(set! (-> obj current-options) (cond
(*cheat-mode*
*main-options*
)
((= *kernel-boot-message* 'kiosk)
*main-kiosk-options*
)
((demo?)
*main-demo-options*
)
(else
*main-options*
)
)
)
)
(('game-options)
(set! (-> obj current-options)
(cond
((demo?)
(if (= (scf-get-territory) GAME_TERRITORY_SCEE)
*game-options*
*game-options-demo*
)
)
((and (= (scf-get-territory) GAME_TERRITORY_SCEI) (not (and (= *progress-cheat* 'language) (cpad-hold? 0 l2) (cpad-hold? 0 r2))))
*game-options*
)
(else
*game-options*
)
)
)
)
(('graphic-options)
(set! (-> obj current-options) *graphic-options-pc*)
)
(('sound-options)
(set! (-> obj current-options) *sound-options*)
)
(('select-load 'select-save)
(set! (-> obj current-options) *load-save-options*)
)
(('select-save-title)
(set! (-> obj current-options) *save-options-title*)
)
(('select-save-title-hero)
(logior! (-> *game-info* purchase-secrets) (game-secrets hero-mode))
(logior! (-> *game-info* secrets) (game-secrets hero-mode))
(set! (-> obj current-options) *save-options-title*)
)
(('loading 'saving 'creating 'formatting)
(set! (-> obj current-options) *loading-options*)
)
(('unformatted-card 'insufficient-space 'no-memory-card)
(set! (-> obj current-options) *insufficient-space-options*)
)
(('secrets-insufficient-space 'secrets-no-memory-card)
(set! (-> obj current-options) *secrets-insufficient-space-options*)
)
(('insert-card)
(set! (-> obj current-options) *insert-card-options*)
)
(('error-loading 'error-saving 'error-formatting 'error-creating)
(set! (-> obj current-options) *error-loading-options*)
)
(('error-auto-saving)
(set! (-> obj current-options) *error-auto-saving-options*)
)
(('card-removed)
(set! (-> obj current-options) *card-removed-options*)
)
(('error-disc-removed)
(set! (-> obj current-options) *error-disc-removed-options*)
)
(('error-reading)
(set! (-> obj current-options) *error-reading-options*)
)
(('icon-info)
(set! (-> obj current-options) *icon-info-options*)
)
(('format-card)
(set! (-> obj current-options) *format-card-options*)
)
(('already-exists)
(set! (-> obj current-options) *already-exists-options*)
)
(('create-game)
(set! (-> obj current-options) *create-game-options*)
)
(('video-mode-warning)
(set! (-> obj current-options) *video-mode-warning-options*)
)
(('video-mode-ok)
(set! (-> obj current-options) *video-mode-ok-options*)
)
(('progressive-mode-warning)
(set! (-> obj current-options) *progressive-mode-warning-options*)
)
(('progressive-mode-ok)
(set! (-> obj current-options) *progressive-mode-ok-options*)
)
(('quit)
(set! (-> obj current-options) *quit-options*)
)
(('title)
(set! (-> obj current-options) *title*)
)
(('title-options)
(set! (-> obj current-options) *options*)
)
(('select-start 'select-pre-start 'select-kiosk-start)
(set! (-> obj current-options) *select-start-options*)
(set! (-> (the-as menu-select-start-option (-> (the-as (array menu-option) (-> *select-start-options* options)) 0))
task-index
)
0
)
0
)
(('select-scene)
(set! (-> obj current-options) *select-scene-options*)
(set! (-> (the-as menu-select-scene-option (-> (the-as (array menu-option) (-> *select-scene-options* options)) 0))
task-index
)
0
)
0
)
(('select-scene-special)
(set! (-> *progress-state* starting-state) 'title)
(set! (-> obj state-pos) 0)
(let ((v1-67 (-> obj state-pos)))
(set! (-> obj state-stack v1-67) 'title)
(set! (-> obj option-index-stack v1-67) 3)
(let ((v1-68 (+ v1-67 1)))
(set! (-> obj state-stack v1-68) 'unlocked-secrets)
(set! (-> obj option-index-stack v1-68) (-> obj option-index))
(set! (-> obj state-pos) (+ v1-68 1))
)
)
(dotimes (s5-1 (-> obj state-pos))
(format
#t
"select-scene-special: ~S ~D~%"
(symbol->string (-> obj state-stack s5-1))
(-> obj option-index-stack s5-1)
)
)
(set! (-> obj current-options) *select-scene-options*)
)
(('bigmap)
(set! (-> obj current-options) *bigmap-options*)
)
(('missions)
(set! (-> *progress-state* missions-total-spacing) 0.0)
(set! (-> (the-as menu-missions-option (-> (the-as (array menu-option) (-> *missions-options* options)) 0))
task-line-index
)
0
)
(set! (-> obj current-options) *missions-options*)
)
(('highscores)
(set! (-> (the-as menu-highscores-option (-> (the-as (array menu-option) (-> *highscores-options* options)) 0))
page-index
)
0
)
(set! (-> (the-as menu-highscores-option (-> (the-as (array menu-option) (-> *highscores-options* options)) 0))
prev-page-index
)
0
)
(set! (-> obj current-options) *highscores-options*)
)
(('secret)
(set! (-> obj secret-buying) #f)
(set! (-> obj current-options) *secret-options*)
)
(('quit-restart)
(set! (-> obj current-options) *quit-restart-options*)
)
(('unlocked-secrets)
(set! (-> obj current-options) *unlocked-secrets*)
)
(('aspect-ratio-custom)
(set! (-> *progress-state-pc* aspect-ratio-ratio-index) 0)
(set! (-> obj current-options) *aspect-ratio-custom-options*)
)
(('music-player)
(set! (-> *progress-state-pc* music-player-selected) #f)
(set! (-> (the-as menu-music-player-option (-> *music-player-options* options 0)) excitement) 0)
(set! (-> obj current-options) *music-player-options*)
)
)
(when (= (-> obj current-options) #f)
(format #t "Didn't find new menu settings!!~%")
(pop-state obj)
)
0
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; CUSTOM MENU OPTIONS
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defmacro min-max-wrap-around+! (var inc minimum maximum)
`(set! ,var (min-max-wrap-around (+ ,var ,inc) ,minimum ,maximum)))
(defmethod respond-progress menu-aspect-ratio-pc-option ((obj menu-aspect-ratio-pc-option) (arg0 progress) (arg1 symbol))
"Handle progress menu navigation logic."
(when arg1
(cond
((cpad-pressed? 0 triangle)
(set-progress-aspect-ratio-pc-index))
((cpad-pressed? 0 confirm)
(sound-play "generic-beep")
(case (-> *progress-state-pc* aspect-ratio-choice-index)
((0)
(if (not (-> *pc-settings* use-vis?))
(set! (-> *setting-control* user-current aspect-ratio) #f))
(set! (-> *setting-control* user-default aspect-ratio) 'aspect4x3)
(true! (-> *pc-settings* use-vis?))
)
((1)
(if (not (-> *pc-settings* use-vis?))
(set! (-> *setting-control* user-current aspect-ratio) #f))
(set! (-> *setting-control* user-default aspect-ratio) 'aspect16x9)
(true! (-> *pc-settings* use-vis?))
)
((2)
(set! (-> *setting-control* user-default aspect-ratio) 'aspect4x3)
(true! (-> *pc-settings* aspect-ratio-auto?))
(false! (-> *pc-settings* use-vis?))
)
((3)
(cpad-clear! 0 confirm)
(push-and-set-state arg0 'aspect-ratio-custom)
)
)
)
(else
(let ((sound-beep? #f))
(when (cpad-pressed? 0 left l-analog-left)
(true! sound-beep?)
(min-max-wrap-around+! (-> *progress-state-pc* aspect-ratio-choice-index) -1 0 3))
(when (cpad-pressed? 0 right l-analog-right)
(true! sound-beep?)
(min-max-wrap-around+! (-> *progress-state-pc* aspect-ratio-choice-index) 1 0 3))
(if sound-beep?
(sound-play "generic-beep")))
)
)
)
0
)
(defmethod respond-progress menu-display-mode-option ((obj menu-display-mode-option) (arg0 progress) (arg1 symbol))
"Handle progress menu navigation logic."
(when arg1
(cond
((cpad-pressed? 0 triangle)
(set-progress-display-mode-index))
((cpad-pressed? 0 confirm)
(sound-play "generic-beep")
(case (-> *progress-state-pc* display-mode-choice-index)
((0) (set-display-mode! *pc-settings* 'windowed #t))
((1) (set-display-mode! *pc-settings* 'fullscreen #t))
((2) (set-display-mode! *pc-settings* 'borderless #t))
)
)
(else
(let ((sound-beep? #f))
(when (cpad-pressed? 0 left l-analog-left)
(true! sound-beep?)
(min-max-wrap-around+! (-> *progress-state-pc* display-mode-choice-index) -1 0 2))
(when (cpad-pressed? 0 right l-analog-right)
(true! sound-beep?)
(min-max-wrap-around+! (-> *progress-state-pc* display-mode-choice-index) 1 0 2))
(if sound-beep?
(sound-play "generic-beep")))
)
)
)
0
)
(defmethod respond-progress menu-aspect-ratio-custom-option ((obj menu-aspect-ratio-custom-option) (arg0 progress) (arg1 symbol))
"Handle progress menu navigation logic."
(let ((aspect-custom-val-ptr (case (-> *progress-state-pc* aspect-ratio-ratio-index)
((0)
(&-> *pc-settings* aspect-custom-x))
((1)
(&-> *pc-settings* aspect-custom-y))
(else
(&-> *pc-settings* aspect-custom-x))
)))
(cond
((cpad-pressed? 0 left l-analog-left)
(when (< 0 (-> *progress-state-pc* aspect-ratio-ratio-index))
(sound-play "roll-over")
(1-! (-> *progress-state-pc* aspect-ratio-ratio-index))
)
)
((cpad-pressed? 0 right l-analog-right)
(when (> 1 (-> *progress-state-pc* aspect-ratio-ratio-index))
(sound-play "roll-over")
(1+! (-> *progress-state-pc* aspect-ratio-ratio-index))
)
)
((cpad-pressed? 0 up l-analog-up)
(when (> 99 (-> aspect-custom-val-ptr))
(sound-play "roll-over")
(1+! (-> aspect-custom-val-ptr))
)
)
((cpad-pressed? 0 down l-analog-down)
(when (< 1 (-> aspect-custom-val-ptr))
(sound-play "roll-over")
(1-! (-> aspect-custom-val-ptr))
)
)
((cpad-pressed? 0 triangle)
(cpad-clear! 0 triangle)
(sound-play "generic-beep")
(pop-state arg0)
)
((cpad-pressed? 0 confirm)
(cpad-clear! 0 confirm)
(when (>= (/ (the float (-> *pc-settings* aspect-custom-x)) (the float (-> *pc-settings* aspect-custom-y))) (/ 4.0 3.0))
(set! (-> *setting-control* user-default aspect-ratio) 'aspect4x3)
(set-aspect! *pc-settings* (-> *pc-settings* aspect-custom-x) (-> *pc-settings* aspect-custom-y))
(sound-play "generic-beep")
(pop-state arg0)
)
)
))
0
)
(defmethod respond-progress menu-frame-rate-option ((obj menu-frame-rate-option) (arg0 progress) (arg1 symbol))
"Handle progress menu navigation logic."
(when arg1
(cond
((cpad-pressed? 0 triangle)
(set-progress-frame-rate-index))
((cpad-pressed? 0 confirm)
(sound-play "generic-beep")
(set-frame-rate! *pc-settings* (-> *frame-rate-options* (-> *progress-state-pc* frame-rate-choice-index)) #t)
)
(else
(let ((sound-beep? #f))
(when (cpad-pressed? 0 left l-analog-left)
(true! sound-beep?)
(min-max-wrap-around+! (-> *progress-state-pc* frame-rate-choice-index) -1 0 (1- (-> *frame-rate-options* length)))
(set-frame-rate! *pc-settings* (-> *frame-rate-options* (-> *progress-state-pc* frame-rate-choice-index)) #t)
)
(when (cpad-pressed? 0 right l-analog-right)
(true! sound-beep?)
(min-max-wrap-around+! (-> *progress-state-pc* frame-rate-choice-index) 1 0 (1- (-> *frame-rate-options* length)))
(set-frame-rate! *pc-settings* (-> *frame-rate-options* (-> *progress-state-pc* frame-rate-choice-index)) #t)
)
(if sound-beep?
(sound-play "generic-beep")
)
)
)
)
)
0
)
(defbehavior play-music-player progress ((info music-player-track-info) (flava int))
"play a music track using music player track info."
(set! (-> *progress-state-pc* music-player-track) info)
(set-setting! 'music (-> info name) 0.0 0)
(set-setting! 'sound-flava #f 999999.0 flava)
(set-setting! 'sound-mode #f 0.0 (-> info mode))
(apply-settings *setting-control*)
(sound-group-continue (sound-group music))
0)
(defbehavior stop-music-player progress ()
"play a music track using music player track info."
(remove-setting! 'music)
(remove-setting! 'sound-flava)
(remove-setting! 'sound-mode)
(sound-set-midi-reg 0 0)
(sound-set-midi-reg 2 0)
(sound-set-midi-reg 16 0)
(set! (-> *progress-state-pc* music-player-track) #f)
;(min! (-> *setting-control* user-current sound-excitement) 0.0)
(sound-set-midi-reg 16 (the int (* 100.0 (-> *setting-control* user-current sound-excitement))))
(set! (-> *setting-control* sound-excitement-change-time) (-> *display* base-clock frame-counter))
(apply-settings *setting-control*)
(sound-group-pause (sound-group music))
0)
(defun count-bits ((val int))
"return the number of bits set to 1."
(let ((bits 0))
(dotimes (i 64)
(if (logtest? val (ash 1 i))
(1+! bits))
)
bits)
)
(defun bit-on-offset ((bits int) (n int))
"return the bit offset of where the n'th bit that is set to 1 is"
(let ((bit-on-i 0))
(dotimes (i 64)
(if (logtest? bits (ash 1 i))
(if (= bit-on-i n)
(return i)
(1+! bit-on-i)))
))
-1)
(defmethod respond-progress menu-music-player-option ((obj menu-music-player-option) (arg0 progress) (arg1 symbol))
"Handle progress menu navigation logic."
(if (= 0.0 (-> obj max-scroll))
(set! (-> obj max-scroll) (+ -141.0 (* (-> *music-player-tracks* length) 23))))
;; control logic
(let ((scroll-sound? #f)
(track-max (1- (-> *music-player-tracks* length)))
(flava-max (1- (count-bits (the-as int (-> *music-player-tracks* (-> obj music-index) flava)))))
(old-excitement (-> obj excitement))
(play? #f))
;; excitement controls
(cond
((cpad-pressed? 0 right l-analog-right)
(seekl! (-> obj excitement) 3 1))
((cpad-pressed? 0 left l-analog-left)
(seekl! (-> obj excitement) 0 1))
)
(when (!= (-> obj excitement) old-excitement)
(sound-play "generic-beep")
(sound-set-midi-reg 16 (* 25 (-> obj excitement))) ;; play new excitement track
(unless (or (< (-> obj excitement) old-excitement) (process-by-name "sound-stinger" arg0))
(process-spawn-function process :to arg0 :name "sound-stinger"
(lambda :behavior process ((stinger int))
(let ((state-time (current-time)))
(format 0 "set stinger ~D~%" stinger)
(sound-set-midi-reg 0 stinger)
(until (>= (- (current-time) state-time) (seconds 0.5))
(suspend))
(sound-set-midi-reg 0 0)
)
)
(+ 9 (-> obj excitement)))
)
(unless (process-by-name "sound-excitement" arg0)
(process-spawn-function process :to arg0 :name "sound-excitement"
(lambda :behavior process ((excite-fade int))
(let ((state-time (current-time)))
(format 0 "set excitement fade ~D~%" (* 25 excite-fade))
(sound-set-midi-reg 2 (* 25 excite-fade)) ;; fade out old excitement track
(until (>= (- (current-time) state-time) (seconds 0.8))
(suspend))
)
)
old-excitement)
)
)
(cond
((or (cpad-pressed? 0 down l-analog-down)
(and (cpad-hold? 0 down l-analog-down) (>= (- (current-time) (-> obj last-move)) (seconds 0.2))))
(set! (-> obj last-move) (current-time))
(true! scroll-sound?)
(cond
((-> *progress-state-pc* music-player-selected)
(min-max-wrap-around+! (-> obj flava-index) 1 0 flava-max))
(else
(min-max-wrap-around+! (-> obj music-index) 1 0 track-max)
(if (= (-> obj music-index) 0)
(set! (-> obj current-scroll) 0.0)))
))
((or (cpad-pressed? 0 up l-analog-up)
(and (cpad-hold? 0 up l-analog-up) (>= (- (current-time) (-> obj last-move)) (seconds 0.2))))
(set! (-> obj last-move) (current-time))
(true! scroll-sound?)
(cond
((-> *progress-state-pc* music-player-selected)
(min-max-wrap-around+! (-> obj flava-index) -1 0 flava-max))
(else
(min-max-wrap-around+! (-> obj music-index) -1 0 track-max)
(if (= (-> obj music-index) track-max)
(set! (-> obj current-scroll) (-> obj max-scroll))))
))
((cpad-pressed? 0 confirm)
(cpad-clear! 0 confirm)
(sound-play "generic-beep")
(cond
;; track is locked. do nothing.
((not (get-bit (-> *pc-settings* music-unlocked) (-> obj music-index)))
)
;; we have a track with a submenu selected
((-> *progress-state-pc* music-player-selected)
(let ((flava (bit-on-offset (the-as int (-> *music-player-tracks* (-> obj music-index) flava)) (-> obj flava-index))))
(cond
((flava-unlocked? flava)
(set! (-> *progress-state-pc* music-player-flava) flava)
(true! play?)
;; exit submenu
(false! (-> *progress-state-pc* music-player-selected))
)
(else
;; do nothing.
)
)
)
)
;; we have a track with a submenu that's not open, open it
((nonzero? (-> *music-player-tracks* (-> obj music-index) flava))
;; same track that's currently playing, we can just reuse the flava position that's being used
;; otherwise use zero.
(if (= (-> *progress-state-pc* music-player-track) (-> *music-player-tracks* (-> obj music-index)))
(set! (-> obj flava-index) (count-bits (logand (1- (ash 1 (-> *progress-state-pc* music-player-flava))) (the-as int (-> *music-player-tracks* (-> obj music-index) flava)))))
(set! (-> obj flava-index) 0))
(true! (-> *progress-state-pc* music-player-selected)))
;; no submenu required, just play track.
(else
(set! (-> *progress-state-pc* music-player-flava) 0)
(true! play?))
)
(when play?
(play-music-player (-> *music-player-tracks* (-> obj music-index)) (-> *progress-state-pc* music-player-flava))
)
)
((cpad-pressed? 0 triangle)
(cpad-clear! 0 triangle)
(sound-play "generic-beep")
(cond
((-> *progress-state-pc* music-player-selected)
(false! (-> *progress-state-pc* music-player-selected)))
(else
(stop-music-player)
(pop-state arg0))
)
)
)
(when scroll-sound?
(sound-play "secrets-scroll"))
)
0
)
(defun hide-progress-screen ()
(when (and *progress-process* *progress-state* (!= (-> *progress-state* starting-state) 'title))
(stop-music-player)
(set-next-state (-> *progress-process* 0) 'go-away 0)
)
0
(none)
)