Files
jak-project/goal_src/jak2/pc/progress/progress-generic-draw-pc.gc
Alex a6c21a9814 Implement analog stick sensitivity setting, default it to 133% (#3919)
This is a simple multiplier to the gamepad axis input value received
from SDL events. Normally the values it provides cannot satisfy the
square range of the stick input. This is usually fine but it might play
differently with different controllers and compared to consoles,
especially considering the DualShock 1/2 have automatic calibration
which works in mysterious ways. The setting is there so any user can
adjust it for their controllers.

Saved to and loaded from the input-settings.json file.

133% matches PCSX2's default setting and is generally a good value to
map the square stick range within most modern(ish) controllers' circular
stick motion.

Progress menu option added to Jak 1 and 2. Setting can be changed from
50% all the way to 200%.

~~Renamed the analog deadzone options to stick deadzone since they don't
apply to the other analog buttons and only the (analog, yes) sticks.~~
2025-05-27 16:01:06 +01:00

633 lines
35 KiB
Common Lisp

;;-*-Lisp-*-
(in-package goal)
;;
(defglobalconstant DEBUG_PAGE_ROWS #f)
(defconstant FONT_SIZE_HEADER 0.6) ;; font size for the decoration text
(defconstant FONT_SIZE_OPTION 0.5) ;; font size for regular options
(defconstant FONT_SIZE_OPTION_EXTRA 0.35) ;; font size for option sub-text
(defconstant HIGHLIGHT_SIZE 18) ;; default highlight size for options
(defconstant HIGHLIGHT_SIZE_LARGE 33)
;;
(defun draw-page-border ((hud-bounds hud-box) (alpha float))
(let ((x-pos 70)
(y-pos 112)
(width 375)
(background-height 200))
(when (= (get-aspect-ratio) 'aspect16x9)
(set! x-pos 79)
(set! y-pos 86)
(set! width 356)
(set! background-height 255))
(#when PC_PORT
;; added for better widescreen handling
(when (not (-> *pc-settings* use-vis?))
(set! x-pos (the int (adjust-game-x (the float x-pos))))
(set! width (the int (* (-> *pc-settings* aspect-ratio-reciprocal) width)))))
(set-vector! (-> hud-bounds color) 64 128 128 (the int (* 128.0 alpha)))
;; Top Line
(set! (-> hud-bounds min x) (the float x-pos))
(set! (-> hud-bounds max x) (the float (+ x-pos width)))
(set! (-> hud-bounds min y) (the float y-pos))
(set! (-> hud-bounds max y) (the float y-pos))
(with-dma-buffer-add-bucket ((buffer-1 (-> *display* frames (-> *display* on-screen) global-buf))
(bucket-id progress))
((method-of-type hud-box draw-box-prim-only) hud-bounds buffer-1))
;; Bottom Line
(set! (-> hud-bounds min x) (the float x-pos))
(set! (-> hud-bounds max x) (the float (+ x-pos width)))
(set! (-> hud-bounds min y) (the float (+ y-pos background-height)))
(set! (-> hud-bounds max y) (the float (+ y-pos background-height)))
(with-dma-buffer-add-bucket ((buffer-2 (-> *display* frames (-> *display* on-screen) global-buf))
(bucket-id progress))
((method-of-type hud-box draw-box-prim-only) hud-bounds buffer-2)))
(none))
(defun draw-page-background ((alpha float))
(let ((x-pos 70)
(y-pos 112)
(width 375)
(background-height 200))
(when (= (get-aspect-ratio) 'aspect16x9)
(set! x-pos 79)
(set! y-pos 86)
(set! width 356)
(set! background-height 256))
(#when PC_PORT
;; added for better widescreen handling
(when (not (-> *pc-settings* use-vis?))
(set! x-pos (the int (adjust-game-x (the float x-pos))))
(set! width (the int (* (-> *pc-settings* aspect-ratio-reciprocal) width)))))
(with-dma-buffer-add-bucket ((buffer (-> *display* frames (-> *display* on-screen) global-buf))
(bucket-id particles))
(draw-sprite2d-xy buffer x-pos y-pos width background-height
(new 'static 'rgba :r #x40 :g #x40 :b #x40 :a (the int (* 64.0 alpha))))))
(none))
(defun draw-page-header ((font-ctx font-context) (text text-id))
(let ((x-pos 70)
(y-pos 82)
(width 375))
(when (= (get-aspect-ratio) 'aspect16x9)
(set! x-pos 79)
(set! y-pos 55)
(set! width 356))
(set-scale! font-ctx FONT_SIZE_HEADER)
(set! (-> font-ctx origin y) (the float y-pos))
(set-color! font-ctx (font-color progress))
(print-game-text (lookup-text! *common-text* text #f) font-ctx #f 44 (bucket-id progress)))
(none))
(defun draw-scrolling-page-up-down-arrows ((font-ctx font-context) (draw-up? symbol) (draw-down? symbol))
(let ((new-x-pos 250.0)
(new-y-pos-up 100)
(new-y-pos-down 211)
(new-scale 0.5)
(old-scale (-> font-ctx scale))
(old-x-pos (-> font-ctx origin x))
(old-y-pos (-> font-ctx origin y)))
(when (= (get-aspect-ratio) 'aspect16x9)
(set! new-x-pos 251.5)
(set! new-y-pos-up 75)
(set! new-y-pos-down 265))
(set! (-> font-ctx scale) new-scale)
(when draw-up?
(set! (-> font-ctx origin x) (the float new-x-pos))
(set! (-> font-ctx origin y) (the float new-y-pos-up))
(let ((print-text-fn print-game-text))
(format (clear *progress-generic-temp-string*) "~33L~C" 160)
(print-text-fn *progress-generic-temp-string* font-ctx #f 44 (bucket-id progress))))
(when draw-down?
(set! (-> font-ctx origin x) (the float new-x-pos))
(set! (-> font-ctx origin y) (the float (+ new-y-pos-up new-y-pos-down)))
(let ((print-text-fn-1 print-game-text))
(format (clear *progress-generic-temp-string*) "~33L~C" 162)
(print-text-fn-1 *progress-generic-temp-string* font-ctx #f 44 (bucket-id progress))))
(set! (-> font-ctx origin x) old-x-pos)
(set! (-> font-ctx origin y) old-y-pos)
(set! (-> font-ctx scale) old-scale))
(none))
;; The boundary info could be moved to the menu-option, every one of these is duplicate code
(defun begin-scissor-scrolling-page ((hud-bounds hud-box))
(cond
((= (get-aspect-ratio) 'aspect16x9)
(set! (-> hud-bounds min x) 19.0)
(set! (-> hud-bounds min y) 86.0)
(set! (-> hud-bounds max x) 494.0)
(set! (-> hud-bounds max y) 340.0))
(else
(set! (-> hud-bounds min x) 70.0)
(set! (-> hud-bounds min y) 112.0)
(set! (-> hud-bounds max x) 444.0)
(set! (-> hud-bounds max y) 312.0)))
(#when PC_PORT
(set! (-> hud-bounds min x) (the float (the int (adjust-game-x (-> hud-bounds min x)))))
(set! (-> hud-bounds max x) (the float (the int (adjust-game-x (-> hud-bounds max x))))))
(with-dma-buffer-add-bucket ((buffer (-> *display* frames (-> *display* on-screen) global-buf))
(bucket-id progress))
(setup-scissor hud-bounds buffer))
(none))
(defun end-scissor-scrolling-page ((hud-bounds hud-box) (arg1 float))
(with-dma-buffer-add-bucket ((buffer (-> *display* frames (-> *display* on-screen) global-buf))
(bucket-id progress)
)
(restore-scissor hud-bounds buffer))
(none))
(defun-debug draw-generic-page-row-line ((y-coord int))
(#when DEBUG_PAGE_ROWS
(with-dma-buffer-add-bucket ((buf (-> *display* frames (-> *display* on-screen) global-buf))
(bucket-id debug-no-zbuf2))
(draw-sprite2d-xy buf 0 y-coord 512 1 (static-rgba #xff #xff #xff #x40))))
0)
(defmethod draw-option ((obj menu-generic-scrolling-page) (progress progress) (font-ctx font-context) (arg3 int) (arg4 symbol))
(when (or (zero? (-> obj mounted?)) (not (-> obj mounted?)))
(on-mount! obj))
;; the list has a total of 200px of y-height
;; with 10px of margin at the top and bottom, that leaves 180 / 4 = 45px per item
;; it's the responsibility of each generic component to center itself within these 45px lines
(when (not (-> *progress-pc-generic-store* clear-screen?))
(let* ((font-alpha (fmax 0.0 (* 2.0 (- 0.5 (-> progress menu-transition)))))
(hud-bounds (new 'stack-no-clear 'hud-box))
(max-page-size (if (= (get-aspect-ratio) 'aspect16x9) 7 5))
(margin-top-bottom 0.0)
(line-height (/ (if (= (get-aspect-ratio) 'aspect16x9) 253.0 200.0) max-page-size)))
(set! (-> font-ctx alpha) font-alpha)
(set-color! font-ctx (font-color progress))
;; header
(draw-page-header font-ctx (-> obj name))
;; background borders
(draw-page-border (-> obj box 0) font-alpha)
;; background
(draw-page-background font-alpha)
(begin-scissor-scrolling-page hud-bounds)
(if (= (get-aspect-ratio) 'aspect16x9)
(set! (-> font-ctx origin y) (+ 86.0 margin-top-bottom))
(set! (-> font-ctx origin y) (+ 112.0 margin-top-bottom)))
;; do scrolling. if we notice we need to scroll too much, we just snap immediately instead of smoothly stepping.
(cond
((> (-> *progress-pc-generic-store* current-menu-scroll-index) (-> *progress-pc-generic-store* current-menu-hover-index))
(if (>= (abs (- (-> *progress-pc-generic-store* current-menu-scroll-index) (the float (-> *progress-pc-generic-store* current-menu-hover-index)))) 2.0)
(set! (-> *progress-pc-generic-store* current-menu-scroll-index) (the float (-> *progress-pc-generic-store* current-menu-hover-index)))
(seek-ease! (-> *progress-pc-generic-store* current-menu-scroll-index) (the float (-> *progress-pc-generic-store* current-menu-hover-index)) (* 0.125 (-> PP clock time-adjust-ratio)) 0.3 (* 0.00125 (-> PP clock time-adjust-ratio)))))
((< (+ (-> *progress-pc-generic-store* current-menu-scroll-index) (1- max-page-size)) (-> *progress-pc-generic-store* current-menu-hover-index))
(if (>= (abs (- (-> *progress-pc-generic-store* current-menu-scroll-index) (the float (- (-> *progress-pc-generic-store* current-menu-hover-index) (1- max-page-size))))) 2.0)
(set! (-> *progress-pc-generic-store* current-menu-scroll-index) (the float (- (-> *progress-pc-generic-store* current-menu-hover-index) (1- max-page-size))))
(seek-ease! (-> *progress-pc-generic-store* current-menu-scroll-index) (the float (- (-> *progress-pc-generic-store* current-menu-hover-index) (1- max-page-size))) (* 0.125 (-> PP clock time-adjust-ratio)) 0.3 (* 0.00125 (-> PP clock time-adjust-ratio)))))
)
;; render items
(let* ((start-index (the int (-> *progress-pc-generic-store* current-menu-scroll-index)))
;; we add 1 because the scroll effect will reveal 1 extra
(end-index (min (-> obj menu-options length) (+ start-index max-page-size 1))))
;; scroll adjust
(-! (-> font-ctx origin y) (* line-height (abs (- (-> *progress-pc-generic-store* current-menu-scroll-index) start-index))))
(while (< start-index end-index)
(let ((menu-option (-> obj menu-options start-index)))
(when (nonzero? menu-option)
;; save the y,x position as who knows where it will end up after the component finishes rendering
(let ((old-y-pos (-> font-ctx origin y))
(old-x-pos (-> font-ctx origin x)))
(draw-option menu-option progress font-ctx start-index
(= (-> obj selected-option-index) start-index))
;; move to the next line
(set! (-> font-ctx origin y) (+ old-y-pos line-height))
;; - debugging, draw the dividing lines to make centering new items easier
(draw-generic-page-row-line (the int (-> font-ctx origin y)))
(set! (-> font-ctx origin x) old-x-pos)
;; reset the font color
(set-color! font-ctx (font-color progress)))))
(+! start-index 1)))
;; end
(end-scissor-scrolling-page hud-bounds 1.0)
(set-flags! font-ctx (font-flags kerning large))
(let ((draw-up-arrow? (< 0 (-> *progress-pc-generic-store* current-menu-hover-index)))
(draw-down-arrow? (< (-> *progress-pc-generic-store* current-menu-hover-index) (1- (-> obj menu-options length)))))
(draw-scrolling-page-up-down-arrows font-ctx draw-up-arrow? draw-down-arrow?))))
(none))
(defun draw-generic-highlight ((y-pos int) (height int) (alpha float))
(let ((x-pos (if (= (get-aspect-ratio) 'aspect4x3)
70
50))
(width (if (= (get-aspect-ratio) 'aspect4x3)
374
500)))
(when (not (-> *pc-settings* use-vis?))
(set! x-pos (the int (adjust-game-x (the float x-pos))))
(set! width (the int (* (-> *pc-settings* aspect-ratio-reciprocal) width))))
(with-dma-buffer-add-bucket ((buffer (-> *display* frames (-> *display* on-screen) global-buf))
(bucket-id progress)
)
(draw-sprite2d-xy buffer x-pos y-pos width height
(new 'static 'rgba :r #x40 :g #x80 :b #x80 :a (the int (* 64.0 alpha)))))))
(defmethod draw-option ((obj menu-generic-boolean-option) (arg0 progress) (font-ctx font-context) (option-index int) (selected? symbol))
(when (not (-> obj mounted?))
(on-mount! obj))
(let ((alpha (* 2.0 (- 0.5 (-> arg0 menu-transition))))
(line-height 18.0))
(max! alpha 0.0)
(set! (-> font-ctx alpha) alpha)
(set-flags! font-ctx (font-flags kerning middle large))
(set-scale! font-ctx FONT_SIZE_OPTION)
(+! (-> font-ctx origin y) (if (= (get-aspect-ratio) 'aspect4x3) 7.0 5.0))
(cond
(selected?
(set-color! font-ctx (font-color progress-force-selected))
(draw-generic-highlight (the int (- (-> font-ctx origin y) 2.0)) HIGHLIGHT_SIZE_LARGE alpha)
(print-game-text (lookup-text! *common-text* (-> obj name) #f) font-ctx #f 44 (bucket-id progress))
(+! (-> font-ctx origin y) line-height)
(set! *progress-generic-temp-string* (clear *progress-generic-temp-string*))
(if (-> obj value)
(format *progress-generic-temp-string* "~33L~S~35L ~S" (lookup-text! *common-text* (-> obj truthy-text) #f) (lookup-text! *common-text* (-> obj falsey-text) #f))
(format *progress-generic-temp-string* "~35L~S ~33L~S~1L" (lookup-text! *common-text* (-> obj truthy-text) #f) (lookup-text! *common-text* (-> obj falsey-text) #f))))
;; hover case
(else
(cond
((and (nonzero? (-> obj should-disable?))
(!= (-> obj should-disable?) #f)
((-> obj should-disable?)))
(set-color! font-ctx (font-color progress-option-off))
(when (= option-index (-> *progress-pc-generic-store* current-menu-hover-index))
(draw-generic-highlight (the int (+ -2.0 (-> font-ctx origin y))) HIGHLIGHT_SIZE (* 0.5 alpha))))
((= option-index (-> *progress-pc-generic-store* current-menu-hover-index))
(set-color! font-ctx (progress-selected 0))
(draw-generic-highlight (the int (+ -2.0 (-> font-ctx origin y))) HIGHLIGHT_SIZE alpha))
(else
(set-color! font-ctx (font-color progress))))
(print-game-text (lookup-text! *common-text* (-> obj name) #f) font-ctx #f 44 (bucket-id progress))
(+! (-> font-ctx origin y) line-height)
(set! *progress-generic-temp-string* (clear *progress-generic-temp-string*))
(let ((actual-value (call-get-value-fn obj)))
(if actual-value
(format *progress-generic-temp-string* "~1L~S~35L ~S" (lookup-text! *common-text* (-> obj truthy-text) #f) (lookup-text! *common-text* (-> obj falsey-text) #f))
(format *progress-generic-temp-string* "~35L~S ~1L~S~1L" (lookup-text! *common-text* (-> obj truthy-text) #f) (lookup-text! *common-text* (-> obj falsey-text) #f))))))
(set-scale! font-ctx FONT_SIZE_OPTION_EXTRA)
(print-game-text *progress-generic-temp-string* font-ctx #f 44 (bucket-id progress)))
(none))
(defmethod draw-option ((obj menu-generic-carousel-option)
(progress progress)
(font-ctx font-context)
(option-index int)
(selected? symbol))
(when (not (-> obj mounted?))
(on-mount! obj))
(let ((alpha (fmax (* 2.0 (- 0.5 (-> progress menu-transition))) 0.0)))
(set! (-> font-ctx scale) 0.45)
(set! (-> font-ctx alpha) alpha)
(+! (-> font-ctx origin y) 5.0)
(set-flags! font-ctx (font-flags kerning middle large))
;; the item label
(cond
(selected?
(set! (-> font-ctx color) (font-color progress-force-selected))
(draw-generic-highlight (the int (- (-> font-ctx origin y) 2.0)) HIGHLIGHT_SIZE_LARGE alpha))
((and (nonzero? (-> obj should-disable?))
(!= (-> obj should-disable?) #f)
((-> obj should-disable?)))
(set-color! font-ctx (font-color progress-option-off))
(when (= option-index (-> *progress-pc-generic-store* current-menu-hover-index))
(draw-generic-highlight (the int (+ -2.0 (-> font-ctx origin y))) HIGHLIGHT_SIZE (* 0.5 alpha))))
((= option-index (-> *progress-pc-generic-store* current-menu-hover-index))
(set! (-> font-ctx color) (progress-selected 0))
(draw-generic-highlight (the int (- (-> font-ctx origin y) 2.0)) HIGHLIGHT_SIZE alpha)))
(print-game-text (lookup-text! *common-text* (-> obj name) #f) font-ctx #f 44 (bucket-id progress))
(+! (-> font-ctx origin y) 18.0)
(set! (-> font-ctx scale) 0.35)
(set! (-> font-ctx color) (font-color progress))
;; the value
(cond
((or (< (-> obj item-index) 0) (> (-> obj item-index) (num-items obj)))
(print-game-text (lookup-text! *common-text* (text-id progress-multiselect-no-items-found) #f) font-ctx #f 44 (bucket-id progress)))
((and selected? (>= (-> obj item-index) 0) (< (-> obj item-index) (num-items obj)))
(format (clear *progress-generic-temp-string*) "~33L~C ~S ~33L~C" 163 (get-item-label obj (-> obj item-index)) 161)
(print-game-text *progress-generic-temp-string* font-ctx #f 44 (bucket-id progress)))
(else
(let ((actual-index (call-get-item-index-fn obj)))
(print-game-text (get-item-label obj actual-index) font-ctx #f 44 (bucket-id progress))))))
(none))
(defun draw-generic-simple-string-option ((option menu-generic-option) (progress progress) (font-ctx font-context) (option-index int) (str string))
(let ((alpha (* 2.0 (- 0.5 (-> progress menu-transition))))
(line-height 23.0))
(max! alpha 0.0)
(set! (-> font-ctx alpha) alpha)
(set-flags! font-ctx (font-flags kerning middle large))
(set-scale! font-ctx FONT_SIZE_OPTION)
(+! (-> font-ctx origin y) (if (= (get-aspect-ratio) 'aspect4x3) 14.0 11.0))
(cond
((and (nonzero? (-> option should-disable?))
(!= (-> option should-disable?) #f)
((-> option should-disable?)))
(set-color! font-ctx (font-color progress-option-off))
(when (= option-index (-> *progress-pc-generic-store* current-menu-hover-index))
(draw-generic-highlight (the int (+ -2.0 (-> font-ctx origin y))) HIGHLIGHT_SIZE (* 0.5 alpha))))
((= option-index (-> *progress-pc-generic-store* current-menu-hover-index))
(set-color! font-ctx (progress-selected 0))
(draw-generic-highlight (the int (+ -2.0 (-> font-ctx origin y))) HIGHLIGHT_SIZE alpha))
(else
(set-color! font-ctx (font-color progress))))
(print-game-text str font-ctx #f 44 (bucket-id progress)))
(none))
(defmethod draw-option ((obj menu-generic-link-option) (progress progress) (font-ctx font-context) (option-index int) (selected? symbol))
(when (not (-> obj mounted?))
(on-mount! obj))
(draw-generic-simple-string-option obj progress font-ctx option-index (lookup-text! *common-text* (-> obj name) #f))
(none))
(defmethod draw-option ((obj menu-generic-button-option) (progress progress) (font-ctx font-context) (option-index int) (selected? symbol))
(when (not (-> obj mounted?))
(on-mount! obj))
(draw-generic-simple-string-option obj progress font-ctx option-index (lookup-text! *common-text* (-> obj name) #f))
(none))
(defmethod draw-option ((obj menu-generic-confirm-option) (progress progress) (font-ctx font-context) (option-index int) (selected? symbol))
(when (not (-> obj mounted?))
(on-mount! obj))
;; drawn different depending on whether or not the confirmation prompt is open
(cond
(selected?
;; TODO - this is duplicate code with the boolean option, but i ran out of arguments, make a struct or something later
(let ((alpha (* 2.0 (- 0.5 (-> progress menu-transition))))
(line-height 18.0))
(max! alpha 0.0)
(set! (-> font-ctx alpha) alpha)
(set-flags! font-ctx (font-flags kerning middle large))
(set-scale! font-ctx FONT_SIZE_OPTION)
(+! (-> font-ctx origin y) (if (= (get-aspect-ratio) 'aspect4x3) 7.0 5.0))
(cond
(selected?
(set-color! font-ctx (font-color progress-force-selected))
(draw-generic-highlight (the int (- (-> font-ctx origin y) 2.0)) HIGHLIGHT_SIZE_LARGE alpha)
(print-game-text (lookup-text! *common-text* (-> obj name) #f) font-ctx #f 44 (bucket-id progress))
(+! (-> font-ctx origin y) line-height)
(set! *progress-generic-temp-string* (clear *progress-generic-temp-string*))
(if (-> obj confirmed?)
(format *progress-generic-temp-string* "~33L~S~35L ~S" (lookup-text! *common-text* (text-id progress-yes) #f) (lookup-text! *common-text* (text-id progress-no) #f))
(format *progress-generic-temp-string* "~35L~S ~33L~S~1L" (lookup-text! *common-text* (text-id progress-yes) #f) (lookup-text! *common-text* (text-id progress-no) #f))))
;; hover case
(else
(cond
((and (nonzero? (-> obj should-disable?))
(!= (-> obj should-disable?) #f)
((-> obj should-disable?)))
(set-color! font-ctx (font-color progress-option-off))
(when (= option-index (-> *progress-pc-generic-store* current-menu-hover-index))
(draw-generic-highlight (the int (+ -1.0 (-> font-ctx origin y))) HIGHLIGHT_SIZE (* 0.5 alpha))))
((= option-index (-> *progress-pc-generic-store* current-menu-hover-index))
(set-color! font-ctx (progress-selected 0))
(draw-generic-highlight (the int (+ -1.0 (-> font-ctx origin y))) HIGHLIGHT_SIZE alpha))
(else
(set-color! font-ctx (font-color progress))))
(print-game-text (lookup-text! *common-text* (-> obj name) #f) font-ctx #f 44 (bucket-id progress))
(+! (-> font-ctx origin y) line-height)
(set! *progress-generic-temp-string* (clear *progress-generic-temp-string*))
(if (-> obj confirmed?)
(format *progress-generic-temp-string* "~1L~S~35L ~S" (lookup-text! *common-text* (text-id progress-yes) #f) (lookup-text! *common-text* (text-id progress-no) #f))
(format *progress-generic-temp-string* "~35L~S ~1L~S~1L" (lookup-text! *common-text* (text-id progress-yes) #f) (lookup-text! *common-text* (text-id progress-no) #f)))))
(set-scale! font-ctx FONT_SIZE_OPTION_EXTRA)
(print-game-text *progress-generic-temp-string* font-ctx #f 44 (bucket-id progress))))
(else
(draw-generic-simple-string-option obj progress font-ctx option-index (lookup-text! *common-text* (-> obj name) #f))))
(none))
(defmethod draw-option ((obj menu-generic-slider-option) (arg0 progress) (font-ctx font-context) (option-index int) (selected? symbol))
(when (not (-> obj mounted?))
(on-mount! obj))
(let ((alpha (max 0.0 (* 2.0 (- 0.5 (-> arg0 menu-transition)))))
(slider-value (if selected? (-> obj value) (call-get-value-fn obj))))
(set! (-> font-ctx alpha) alpha)
(set-scale! font-ctx FONT_SIZE_OPTION)
(+! (-> font-ctx origin y) 20.0)
(case (get-aspect-ratio)
(('aspect4x3))
(('aspect16x9)))
(set-flags! font-ctx (font-flags kerning middle large))
(cond
(selected?
(set-scale! font-ctx FONT_SIZE_OPTION_EXTRA)
(+! (-> font-ctx origin y) (if (= (get-aspect-ratio) 'aspect4x3) -15.0 -15.0))
(set-color! font-ctx (font-color progress-force-selected))
(draw-generic-highlight (the int (+ -2.0 (-> font-ctx origin y))) HIGHLIGHT_SIZE_LARGE alpha)
(if (= (-> obj show-decimal?) #t)
(print-game-text (string-format "~S: ~,,2f" (lookup-text! *common-text* (-> obj name) #f) slider-value) font-ctx #f 44 (bucket-id progress))
(print-game-text (string-format "~S: ~,,0f" (lookup-text! *common-text* (-> obj name) #f) slider-value) font-ctx #f 44 (bucket-id progress)))
(set! (-> obj bar-sprite tex) (lookup-texture-by-id (new 'static 'texture-id :index #xb :page #xc93)))
(set! (-> obj bar-sprite scale-x) 2.0)
(set! (-> obj bar-sprite scale-y) 0.5)
(let ((sprite-color-0 (-> obj bar-sprite color2)))
(set! (-> sprite-color-0 0) 128)
(set! (-> sprite-color-0 1) 128)
(set! (-> sprite-color-0 2) 128)
(set! (-> sprite-color-0 3) 128)
)
(set! (-> obj bar-sprite pos z) #x3fffff)
(set! (-> obj bar-sprite pos w) 0)
(set! (-> obj bar-cursor-sprite tex) (lookup-texture-by-id (new 'static 'texture-id :index #xc :page #xc93)))
(set! (-> obj bar-cursor-sprite scale-x) 0.2)
(set! (-> obj bar-cursor-sprite scale-y) 1.0)
(let ((sprite-color-1 (-> obj bar-cursor-sprite color2)))
(set! (-> sprite-color-1 0) 128)
(set! (-> sprite-color-1 1) 128)
(set! (-> sprite-color-1 2) 128)
(set! (-> sprite-color-1 3) 128)
)
(set! (-> obj bar-cursor-sprite pos z) #x3fffff)
(set! (-> obj bar-cursor-sprite pos w) 0)
;; bar
(set-hud-piece-position! (-> obj bar-sprite) (the int (adjust-game-x 135.0)) (+ (the int (-> font-ctx origin y)) (if (= (get-aspect-ratio) 'aspect4x3) 18 15)))
;; calculate the percentage of the bar based on the range
;; (actual + abs(range-min)) / (range-max + abs(range-min)) = percentage
(let* ((percentage (/ (+ slider-value (fabs (-> obj min-value)))
(+ (-> obj max-value) (fabs (-> obj min-value)))))
;; cursor (135 -> 365) = 230 pixels
(cursor-x-pos (adjust-game-x-int (+ 135 (* (if (= (get-aspect-ratio) 'aspect4x3) 230.0 231.0) percentage))))
(bar-remainder (- (adjust-game-x-int 365) cursor-x-pos)))
;; cursor position
(set-hud-piece-position! (-> obj bar-cursor-sprite) cursor-x-pos (+ (the int (-> font-ctx origin y)) (if (= (get-aspect-ratio) 'aspect4x3) 14 11)))
(with-dma-buffer-add-bucket ((buffer (-> *display* frames (-> *display* on-screen) global-buf))
(bucket-id progress))
(draw (-> obj bar-sprite) buffer (-> *level* default-level))
;; bar mask
;; TODO - bar remainder isnt correct on custom aspect ratios since those internally still return `aspect4x3` for (get-aspect-ratio), this is a larger issue though
;; perhaps just standardize menu size in general and ditch aspect ratio differences.
(draw-sprite2d-xy buffer (+ cursor-x-pos 10) (+ (the int (-> font-ctx origin y)) (if (= (get-aspect-ratio) 'aspect4x3) 23 20)) (+ bar-remainder (if (= (get-aspect-ratio) 'aspect4x3) 9 6)) 6
(new 'static 'rgba :r (the int (* 0.0 alpha slider-value))
:g (the int (* 0.0 alpha slider-value))
:b (the int (* 0.0 alpha slider-value))
:a (the int (* 128.0 alpha))))
(draw (-> obj bar-cursor-sprite) buffer (-> *level* default-level)))))
(else
(+! (-> font-ctx origin y) -8.0)
(cond
((and (nonzero? (-> obj should-disable?))
(!= (-> obj should-disable?) #f)
((-> obj should-disable?)))
(set-color! font-ctx (font-color progress-option-off))
(when (= option-index (-> *progress-pc-generic-store* current-menu-hover-index))
(draw-generic-highlight (the int (+ -1.0 (-> font-ctx origin y))) HIGHLIGHT_SIZE (* 0.5 alpha))))
((= option-index (-> *progress-pc-generic-store* current-menu-hover-index))
(set-color! font-ctx (progress-selected 0))
(draw-generic-highlight (the int (+ -2.0 (-> font-ctx origin y))) HIGHLIGHT_SIZE alpha))
(else
(set-color! font-ctx (font-color progress))))
(if (= (-> obj show-decimal?) #t)
(print-game-text (string-format "~S: ~,,2f" (lookup-text! *common-text* (-> obj name) #f) slider-value) font-ctx #f 44 (bucket-id progress))
(print-game-text (string-format "~S: ~,,0f" (lookup-text! *common-text* (-> obj name) #f) slider-value) font-ctx #f 44 (bucket-id progress)))))
)
(none))
(defmethod draw-option ((obj menu-generic-details-page) (progress progress) (font-ctx font-context) (option-index int) (selected? symbol))
(when (or (zero? (-> obj mounted?)) (not (-> obj mounted?)))
(on-mount! obj))
;; the list has a total of 200px of y-height
;; with 10px of margin at the top and bottom, that leaves 180 / 4 = 45px per item
;; it's the responsibility of each generic component to center itself within these 45px lines
(when (not (-> *progress-pc-generic-store* clear-screen?))
(let* ((font-alpha (fmax 0.0 (* 2.0 (- 0.5 (-> progress menu-transition)))))
(hud-bounds (new 'stack-no-clear 'hud-box))
(max-page-size (if (= (get-aspect-ratio) 'aspect16x9) 12 10))
(margin-top-bottom 0.0)
(line-height (/ (if (= (get-aspect-ratio) 'aspect16x9) 253.0 200.0) max-page-size)))
(set! (-> font-ctx alpha) font-alpha)
(set-color! font-ctx (font-color progress))
;; header
(draw-page-header font-ctx (-> obj name))
;; background borders
(draw-page-border (-> obj box 0) font-alpha)
;; background
(draw-page-background font-alpha)
(begin-scissor-scrolling-page hud-bounds)
(if (= (get-aspect-ratio) 'aspect16x9)
(set! (-> font-ctx origin y) (+ 86.0 margin-top-bottom))
(set! (-> font-ctx origin y) (+ 112.0 margin-top-bottom)))
;; render items
(let* ((entry-index (max 0 (* (/ (-> *progress-pc-generic-store* current-menu-hover-index) max-page-size) max-page-size)))
(end-index (min (-> obj entries length) (+ entry-index max-page-size))))
(while (< entry-index end-index)
(let ((entry (-> obj entries entry-index)))
(when (nonzero? entry)
;; save the y,x position as who knows where it will end up after the component finishes rendering
(let ((old-y-pos (-> font-ctx origin y))
(old-x-pos (-> font-ctx origin x)))
(draw-option entry progress font-ctx entry-index
(= (-> obj selected-entry-index) entry-index))
;; move to the next line
(set! (-> font-ctx origin y) (+ old-y-pos line-height))
;; - debugging, draw the dividing lines to make center new items easier
(draw-generic-page-row-line (the int (-> font-ctx origin y)))
(set! (-> font-ctx origin x) old-x-pos)
;; reset the font color
(set-color! font-ctx (font-color progress)))))
(+! entry-index 1)))
;; end
(end-scissor-scrolling-page hud-bounds 1.0)
(set-flags! font-ctx (font-flags kerning large))
(let* ((draw-up-arrow? (and (not (zero? (-> *progress-pc-generic-store* current-menu-hover-index)))
(>= (-> *progress-pc-generic-store* current-menu-hover-index) max-page-size)))
(last-page-remainder (mod (-> obj entries length) max-page-size))
(last-page-starting-index (if (zero? last-page-remainder)
(- (-> obj entries length) max-page-size)
(- (-> obj entries length) last-page-remainder)))
(draw-down-arrow? (and (> (-> obj entries length) max-page-size)
(< (-> *progress-pc-generic-store* current-menu-hover-index) last-page-starting-index))))
(draw-scrolling-page-up-down-arrows font-ctx draw-up-arrow? draw-down-arrow?))))
(none))
(defmethod draw-option ((obj menu-generic-details-keybind-entry) (progress progress) (font-ctx font-context) (option-index int) (selected? symbol))
(when (or (zero? (-> obj mounted?)) (not (-> obj mounted?)))
(on-mount! obj))
;; TODO - implement `should-disable?` if it's ever relevant (its not right now)
(let ((alpha (* 2.0 (- 0.5 (-> progress menu-transition))))
(line-height 23.0))
(max! alpha 0.0)
(set! (-> font-ctx alpha) alpha)
(set-scale! font-ctx 0.40)
(cond
((= option-index (-> *progress-pc-generic-store* current-menu-hover-index))
(set-color! font-ctx (progress-selected 0))
(draw-generic-highlight (the int (+ 2.0 (-> font-ctx origin y))) 18 alpha))
(else
(set-color! font-ctx (font-color progress))))
;; Print left aligned text
(set-flags! font-ctx (font-flags kerning middle-vert large))
(-! (-> font-ctx origin y) 1.0)
(when (= (get-aspect-ratio) 'aspect16x9)
(+! (-> font-ctx origin x) 5.0))
(print-game-text (get-keybind-string obj) font-ctx #f 44 (bucket-id progress))
;; Now print the right aligned text
(set! (-> font-ctx origin x) (the float (adjust-game-x (if (= (get-aspect-ratio) 'aspect16x9) 430.0 438.0))))
(+! (-> font-ctx origin y) 6.0)
(set-flags! font-ctx (font-flags kerning right large))
(let ((bind (pc-get-current-bind (-> obj bind-info) *pc-cpp-temp-string*)))
(cond
(selected?
(print-game-text (string-format "~S...(~Ds)" (lookup-text! *common-text* (text-id progress-keybinds-waiting-for-bind) #f)
(inc (/ (- (seconds 5) (- (current-time) (-> *progress-pc-generic-store* keybind-select-time))) TICKS_PER_SECOND)))
font-ctx #f 44 (bucket-id progress)))
((= bind #f)
(print-game-text (lookup-text! *common-text* (text-id progress-keybinds-unset) #f) font-ctx #f 44 (bucket-id progress)))
((string= *pc-cpp-temp-string* "unknown")
(print-game-text (lookup-text! *common-text* (text-id progress-unknown-option) #f) font-ctx #f 44 (bucket-id progress)))
(else
(print-game-text *pc-cpp-temp-string* font-ctx #f 44 (bucket-id progress))))))
(none))
(defmethod draw-option ((obj menu-generic-details-confirm-entry) (progress progress) (font-ctx font-context) (option-index int) (selected? symbol))
(when (or (zero? (-> obj mounted?)) (not (-> obj mounted?)))
(on-mount! obj))
;; TODO - implement `should-disable?` if it's ever relevant (its not right now)
(let ((alpha (* 2.0 (- 0.5 (-> progress menu-transition))))
(line-height 23.0))
(max! alpha 0.0)
(set! (-> font-ctx alpha) alpha)
(set-scale! font-ctx 0.40)
(cond
((= option-index (-> *progress-pc-generic-store* current-menu-hover-index))
(set-color! font-ctx (progress-selected 0))
(draw-generic-highlight (the int (+ 2.0 (-> font-ctx origin y))) 18 alpha))
(else
(set-color! font-ctx (font-color progress))))
;; Print left aligned text
(set-flags! font-ctx (font-flags kerning middle-vert large))
(-! (-> font-ctx origin y) 1.0)
(when (= (get-aspect-ratio) 'aspect16x9)
(+! (-> font-ctx origin x) 5.0))
(print-game-text (lookup-text! *common-text* (-> obj name) #f) font-ctx #f 44 (bucket-id progress))
(when selected?
;; Now print the right aligned text, if the option is selected
(set! (-> font-ctx origin x) (the float (adjust-game-x (if (= (get-aspect-ratio) 'aspect16x9) 430.0 438.0))))
(+! (-> font-ctx origin y) 6.0)
(set-flags! font-ctx (font-flags kerning right large))
(clear *progress-generic-temp-string*)
(if (-> obj confirmed?)
(format *progress-generic-temp-string* "~33L~S~35L ~S" (lookup-text! *common-text* (text-id progress-yes) #f) (lookup-text! *common-text* (text-id progress-no) #f))
(format *progress-generic-temp-string* "~35L~S ~33L~S~1L" (lookup-text! *common-text* (text-id progress-yes) #f) (lookup-text! *common-text* (text-id progress-no) #f)))
(print-game-text *progress-generic-temp-string* font-ctx #f 44 (bucket-id progress))))
(none))
(defmethod draw-option ((obj menu-generic-to-resolutions-option) (progress progress) (font-ctx font-context) (option-index int) (selected? symbol))
;; change the name depending on whether we're fullscreen or not
(cond
((and (= (-> obj name) (text-id progress-window-size)) (fullscreen?))
(set! (-> obj name) (text-id progress-game-res)))
((and (= (-> obj name) (text-id progress-game-res)) (not (fullscreen?)))
(set! (-> obj name) (text-id progress-window-size))))
(call-parent-method obj progress font-ctx option-index selected?))