mirror of
https://github.com/open-goal/jak-project
synced 2026-06-05 11:19:05 -04:00
af6de539b5
In the original game, they had no choice but to use the memory card file as their method of persisting settings. We are not limited by such things. It's inconvenient to have to load your save-file when launching the game to initialize these settings to your liking, it's also confusing behaviour to even some players that have played the game heavily for over a decade. We can do better by globally saving these settings to the `pc-settings` file instead. Originally I only migrated the volume settings, then i figured it would be nice to also have play-hints and subtitles settings persisted. More could debatably be moved (language is a big one...) but these were the low hanging fruit. I also reduced the default volumes as that is something else that has come up a few times.
941 lines
41 KiB
Common Lisp
941 lines
41 KiB
Common Lisp
;;-*-Lisp-*-
|
|
(in-package goal)
|
|
|
|
#|
|
|
|
|
This file runs the game-specific version of the pckernel.
|
|
See pckernel-common.gc for the bulk of the pckernel.
|
|
|
|
|#
|
|
|
|
(define-extern get-active-mission-description (function discord-info string))
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;;;; pc cheats list
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
|
|
(deftype pc-cheat-info (basic)
|
|
((name text-id)
|
|
(unlock text-id)
|
|
(unlock-func symbol) ;; function symbol
|
|
(skill int) ;; skill points required. leave as 0 if you only want a custom unlock func
|
|
(flag pc-cheats)
|
|
(can-toggle symbol) ;; how it can be toggled
|
|
|
|
;; only show after this point in the story
|
|
(avail-after game-task-node)
|
|
(avail-after-hero game-task-node)
|
|
)
|
|
)
|
|
|
|
;;;;; pc cheat unlock functions
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
(defun pc-cheat-health-bars-unlock ()
|
|
"#t = cheat unlock requirements met. #f = locked"
|
|
(>= (get-count-for-enemy (-> *pc-settings* stats kill-stats) 'civilian) (-> *pc-cheat-state* kill-civvie-target)))
|
|
|
|
(defun pc-cheat-vehicle-health-bars-unlock ()
|
|
"#t = cheat unlock requirements met. #f = locked"
|
|
#f)
|
|
|
|
(defun pc-cheat-board-fast-unlock ()
|
|
"#t = cheat unlock requirements met. #f = locked"
|
|
(cond
|
|
;; haven't reached sewer valve task yet or not in sewers or at the start of sewers
|
|
((or (not (task-node-closed? (game-task-node sewer-board-introduction)))
|
|
(not (aif (level-get-target-inside *level*) (= (-> it name) 'sewer)))
|
|
(aif (get-continue-by-name *game-info* "sewer-start") (< (vector-vector-distance (target-pos 0) (-> it trans)) (meters 20))))
|
|
(set! (-> *pc-cheat-state* sewer-valve-on) #b000)
|
|
(set! (-> *pc-cheat-state* sewer-valve-start-time) 0)
|
|
(set! (-> *pc-cheat-state* sewer-valve-end-time) 0)
|
|
#f)
|
|
;; during sewer valve task
|
|
((not (task-node-closed? (game-task-node sewer-board-resolution)))
|
|
(set! (-> *pc-cheat-state* sewer-valve-end-time) (get-current-time))
|
|
(when (= (get-base-height *ocean-map*) -216498.17)
|
|
(set! (-> *pc-cheat-state* sewer-valve-start-time) (get-current-time))
|
|
)
|
|
|
|
;; no cheating!
|
|
(cond
|
|
((task-node-open? (game-task-node sewer-board-drain))
|
|
(aif (process-by-ename "sew-valve-6")
|
|
(if (and (= 'turn (-> it next-state name)) (= (-> *pc-cheat-state* sewer-valve-on) #b000))
|
|
(logior! (-> *pc-cheat-state* sewer-valve-on) #b001)))
|
|
(aif (process-by-ename "sew-valve-7")
|
|
(if (and (= 'turn (-> it next-state name)) (= (-> *pc-cheat-state* sewer-valve-on) #b001))
|
|
(logior! (-> *pc-cheat-state* sewer-valve-on) #b010)))
|
|
)
|
|
((and (task-node-closed? (game-task-node sewer-board-drain)) (= (-> *pc-cheat-state* sewer-valve-on) #b011))
|
|
(logior! (-> *pc-cheat-state* sewer-valve-on) #b100))
|
|
)
|
|
|
|
(when (and (= *cheat-mode* 'debug) (!= (-> *pc-cheat-state* sewer-valve-end-time) (-> *pc-cheat-state* sewer-valve-start-time)))
|
|
(format *stdcon* "sewer-valve time: ~0e/~D v: ~3B~%" (- (-> *pc-cheat-state* sewer-valve-end-time) (-> *pc-cheat-state* sewer-valve-start-time))
|
|
(-> *pc-cheat-state* sewer-valve-target-seconds)
|
|
(-> *pc-cheat-state* sewer-valve-on))
|
|
)
|
|
#f)
|
|
;; sewer valve task done!
|
|
(else
|
|
(let (
|
|
(time-taken (- (-> *pc-cheat-state* sewer-valve-end-time) (-> *pc-cheat-state* sewer-valve-start-time))))
|
|
|
|
(and (< 0 time-taken)
|
|
(< time-taken (seconds (-> *pc-cheat-state* sewer-valve-target-seconds)))
|
|
(= #b111 (-> *pc-cheat-state* sewer-valve-on)))
|
|
)
|
|
)
|
|
))
|
|
|
|
(defun pc-cheat-statistics-unlock ()
|
|
"#t = cheat unlock requirements met. #f = locked"
|
|
(killed-each-metalhead?))
|
|
|
|
(defun pc-cheat-suck-in-all-unlock ()
|
|
"#t = cheat unlock requirements met. #f = locked"
|
|
#f)
|
|
|
|
(defun pc-cheat-fast-travel-unlock ()
|
|
"#t = cheat unlock requirements met. #f = locked"
|
|
#f)
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;;;;; pc cheat unlock functions end
|
|
|
|
(defmacro static-pc-cheat-info (name flag can-toggle avail-after &key (skill 0) &key (unlock (null true-func)))
|
|
"helper for making a new static pc-cheat-info
|
|
unlock is a pair in format (unlock-text-id unlock-func) where unlock-func returns #t if the unlock requirement is met and #f otherwise
|
|
skill is the skill requirement. until the requirement is met (and avail-after is closed), it will show 'X required' in the menu
|
|
avail-after can be a single task-node or a pair of two, car is for normal game and cadr for hero mode"
|
|
`(new 'static 'pc-cheat-info :name (text-id ,name)
|
|
:unlock (text-id ,(car unlock))
|
|
:unlock-func (quote ,(cadr unlock))
|
|
:skill ,skill
|
|
:flag (pc-cheats ,flag)
|
|
:avail-after (game-task-node ,(if (pair? avail-after) (car avail-after) avail-after))
|
|
:avail-after-hero (game-task-node ,(if (pair? avail-after) (cadr avail-after) avail-after))
|
|
:can-toggle (quote ,can-toggle))
|
|
)
|
|
|
|
(defmacro def-pc-cheat-list (name &rest items)
|
|
"helper for making a list of pc cheats. see static-pc-cheat-info for parameters"
|
|
`(define ,name (new 'static 'boxed-array :type pc-cheat-info ,@(apply (lambda (x) `(static-pc-cheat-info ,@x)) items)))
|
|
)
|
|
|
|
;; the list of cheats
|
|
(def-pc-cheat-list *pc-cheats-list*
|
|
;; name cheat flag can-toggle avail-after
|
|
(progress-cheats-music-player music-player #f fortress-escape-introduction)
|
|
(progress-cheats-real-time-of-day real-time-of-day #t fortress-escape-resolution)
|
|
(progress-cheats-board-tricks board-tricks #t stadium-board1-gold)
|
|
(progress-cheats-health-bars health-bars #t palace-boss-resolution :unlock (progress-cheats-health-bars-unlock pc-cheat-health-bars-unlock))
|
|
;(progress-cheats-vehicle-health-bars vehicle-health-bars #t palace-boss-resolution :unlock (progress-cheats-vehicle-health-bars-unlock pc-cheat-vehicle-health-bars-unlock))
|
|
(progress-cheats-weather-bad weather-bad #t fortress-escape-resolution :skill 85)
|
|
(progress-cheats-weather-good weather-good #t fortress-escape-resolution :skill 85)
|
|
;(progress-cheats-suck-in-all suck-in-all #t forest-scouts-get-board :unlock (progress-cheats-suck-in-all-unlock pc-cheat-suck-in-all-unlock))
|
|
(progress-cheats-turbo-board turbo-board #t sewer-board-introduction :unlock (progress-cheats-turbo-board-unlock pc-cheat-board-fast-unlock))
|
|
;(progress-cheats-fast-travel fast-travel auto city-defend-stadium-introduction :unlock (progress-cheats-fast-travel-unlock pc-cheat-fast-travel-unlock))
|
|
;(progress-cheats-orb-tracker orb-tracker auto nest-boss-resolution)
|
|
(progress-cheats-no-textures no-textures #t nest-boss-resolution :skill 115)
|
|
(progress-cheats-vehicle-invuln vehicle-invuln #t nest-boss-resolution :skill 185)
|
|
;(progress-cheats-fast-movies fast-movies #t nest-boss-resolution :skill 200)
|
|
;(progress-cheats-slow-movies slow-movies #t nest-boss-resolution :skill 200)
|
|
;(progress-cheats-fast-speed fast-speed #t nest-boss-resolution :skill 250)
|
|
;(progress-cheats-slow-speed slow-speed #t nest-boss-resolution :skill 250)
|
|
;(progress-cheats-statistics statistics auto atoll-water-introduction :unlock (progress-cheats-statistics-unlock pc-cheat-statistics-unlock))
|
|
)
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;;;; music player list
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
(defenum music-player-flava
|
|
:bitfield #t :type uint8
|
|
(default)
|
|
(gun)
|
|
(board)
|
|
(mech)
|
|
(darkjak)
|
|
(pilot)
|
|
)
|
|
|
|
(deftype music-player-track-info (basic)
|
|
((text text-id)
|
|
(name symbol)
|
|
(mode int8)
|
|
(icon int16)
|
|
(flava music-player-flava)
|
|
(avail-after game-task-node)
|
|
)
|
|
)
|
|
|
|
(defmacro static-music-track-info (name &key text &key avail-after &key (mode 0) &key icon &key (flava ()))
|
|
`(new 'static 'music-player-track-info :text (text-id ,text) :name ,name :icon ,icon :avail-after (game-task-node ,avail-after) :mode ,mode :flava (music-player-flava ,@flava))
|
|
)
|
|
|
|
(define *music-player-tracks* (new 'static 'boxed-array :type music-player-track-info
|
|
(static-music-track-info 'city1 :mode 0 :icon 1 :text progress-music-player-city :avail-after fortress-escape-resolution :flava (gun board pilot))
|
|
(static-music-track-info 'city1 :mode 1 :icon 1 :text progress-music-player-city-battle :avail-after city-help-kid-resolution)
|
|
(static-music-track-info 'ruins :mode 0 :icon 4 :text progress-music-player-ruins :avail-after ruins-tower-resolution :flava (gun board mech darkjak))
|
|
(static-music-track-info 'atoll :mode 0 :icon 6 :text progress-music-player-atoll :avail-after atoll-water-resolution :flava (gun darkjak board))
|
|
(static-music-track-info 'sewer :mode 0 :icon 3 :text progress-music-player-sewer :avail-after fortress-dump-resolution :flava (gun board mech darkjak))
|
|
(static-music-track-info 'sewer :mode 1 :icon 3 :text progress-music-player-sewer-battle :avail-after fortress-dump-resolution)
|
|
(static-music-track-info 'danger11 :mode 0 :icon 3 :text progress-music-player-danger11 :avail-after fortress-dump-resolution)
|
|
(static-music-track-info 'atoll :mode 1 :icon 6 :text progress-music-player-atoll-battle :avail-after atoll-sig-resolution)
|
|
(static-music-track-info 'strip :mode 0 :icon 5 :text progress-music-player-strip :avail-after strip-rescue-resolution :flava (gun board mech darkjak))
|
|
(static-music-track-info 'mountain :mode 0 :icon 8 :text progress-music-player-mountain :avail-after mountain-collection-resolution :flava (gun board mech darkjak))
|
|
(static-music-track-info 'mountain :mode 1 :icon 8 :text progress-music-player-mountain-battle :avail-after mountain-collection-resolution)
|
|
(static-music-track-info 'palcab :mode 0 :icon 11 :text progress-music-player-palcab :avail-after palace-cable-resolution :flava (gun board darkjak))
|
|
(static-music-track-info 'forest :mode 0 :icon 9 :text progress-music-player-forest :avail-after forest-scouts-resolution :flava (gun board mech darkjak))
|
|
(static-music-track-info 'forest :mode 1 :icon 9 :text progress-music-player-forest-battle :avail-after forest-scouts-resolution)
|
|
(static-music-track-info 'danger9 :mode 0 :icon 1 :text progress-music-player-danger9 :avail-after city-intercept-tanker-resolution)
|
|
(static-music-track-info 'race :mode 0 :icon 2 :text progress-music-player-race :avail-after stadium-race-class3-resolution)
|
|
(static-music-track-info 'danger3 :mode 0 :icon 1 :text progress-music-player-danger3 :avail-after city-play-onin-game-resolution)
|
|
(static-music-track-info 'danger1 :mode 0 :icon 8 :text progress-music-player-battle :avail-after canyon-insert-items-resolution)
|
|
(static-music-track-info 'danger2 :mode 0 :icon 12 :text progress-music-player-danger2 :avail-after tomb-boss-door)
|
|
(static-music-track-info 'danger7 :mode 0 :icon 15 :text progress-music-player-danger7 :avail-after tomb-boss-resolution)
|
|
(static-music-track-info 'danger10 :mode 0 :icon 10 :text progress-music-player-danger10 :avail-after drill-mech-resolution)
|
|
(static-music-track-info 'palcab :mode 1 :icon 14 :text progress-music-player-palcab-battle :avail-after castle-boss-resolution)
|
|
(static-music-track-info 'danger6 :mode 0 :icon 14 :text progress-music-player-danger6 :avail-after castle-boss-resolution)
|
|
(static-music-track-info 'danger4 :mode 0 :icon 17 :text progress-music-player-danger4 :avail-after nest-boss-resolution)
|
|
))
|
|
|
|
;; automatically add the default flava to all tracks that had flavas marked
|
|
(dotimes (i (-> *music-player-tracks* length))
|
|
(if (nonzero? (-> *music-player-tracks* i flava))
|
|
(logior! (-> *music-player-tracks* i flava) (music-player-flava default)))
|
|
)
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;;;; fancy controller LED fader mechanics
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
(deftype led-fader-state (structure)
|
|
((enable? symbol)
|
|
(amount float)
|
|
(cur-color vector :inline)
|
|
(start-color vector :inline)
|
|
(end-color vector :inline)
|
|
)
|
|
(:methods
|
|
(enable (_type_ vector) int)
|
|
(update (_type_ float float) vector)
|
|
(disable (_type_) int)
|
|
)
|
|
)
|
|
|
|
(defmethod enable ((this led-fader-state) (start-from vector))
|
|
"begin transition."
|
|
|
|
(when (-> this enable?)
|
|
(disable this))
|
|
|
|
(vector-copy! (-> this start-color) start-from)
|
|
(set! (-> this amount) 0.0)
|
|
(true! (-> this enable?))
|
|
0)
|
|
|
|
(defmethod disable ((this led-fader-state))
|
|
"disable transition."
|
|
|
|
(set! (-> this amount) 0.0)
|
|
(update this 0.0 0.1)
|
|
(false! (-> this enable?))
|
|
0)
|
|
|
|
(defun vector3-lerp! ((dest vector) (a vector) (b vector) (alpha float))
|
|
"Linearly interpolate between two vectors. Alpha isn't clamped.
|
|
w will be set to what's in vector a."
|
|
(rlet ((vf0 :class vf)
|
|
(vf1 :class vf)
|
|
(vf2 :class vf)
|
|
(vf3 :class vf)
|
|
(vf4 :class vf)
|
|
)
|
|
(init-vf0-vector)
|
|
(.lvf vf1 (&-> a quad))
|
|
(.lvf vf2 (&-> b quad))
|
|
(.mov vf4 alpha)
|
|
(.add.x.vf vf3 vf1 vf0 :mask #b1000)
|
|
(.sub.vf vf2 vf2 vf1)
|
|
(.mul.x.vf vf2 vf2 vf4)
|
|
(.add.vf vf3 vf1 vf2 :mask #b111)
|
|
(.svf (&-> dest quad) vf3)
|
|
dest
|
|
)
|
|
)
|
|
|
|
(defun vector3-copy!! ((dest vector) (src vector))
|
|
"copy just the xyz fields of src into dest"
|
|
(rlet ((vf0 :class vf)
|
|
(dest-vf :class vf)
|
|
(src-vf :class vf))
|
|
(init-vf0-vector)
|
|
(.lvf dest-vf (&-> dest quad))
|
|
(.lvf src-vf (&-> src quad))
|
|
(.add.vf dest-vf vf0 src-vf :mask #b111)
|
|
(.svf (&-> dest quad) dest-vf)
|
|
dest
|
|
)
|
|
)
|
|
|
|
(defmethod update ((this led-fader-state) (to float) (duration float))
|
|
"disable transition."
|
|
|
|
(when (-> this enable?)
|
|
(seek! (-> this amount) to (/ (-> *target* clock seconds-per-frame) duration))
|
|
(vector4-lerp! (-> this cur-color) (-> this start-color) (-> this end-color) (-> this amount))
|
|
(if (and (= to 0.0) (= 0.0 (-> this amount)))
|
|
(false! (-> this enable?)))
|
|
)
|
|
(-> this cur-color))
|
|
|
|
|
|
;; global vars
|
|
(define *led-fader-state* (new 'static 'led-fader-state :enable? #f))
|
|
|
|
(define *led-darkjak-color* (static-vector 0.5 0.0 0.5 1.0))
|
|
(define *led-tomb-simon-off-color* (static-vector 0.0 0.0 0.0 1.0))
|
|
(define *led-tomb-simon-color* (static-vector 0.0 0.0 0.0 1.0))
|
|
(define *led-wanted-flash-color* (static-vector 1.0 0.0 0.0 1.0))
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;;;; methods
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
(defmethod initialize ((obj pc-settings-jak2))
|
|
"initial initialize method to be run after allocating"
|
|
(set! (-> obj music-unlocked) (new 'global 'bit-array (-> *music-player-tracks* length)))
|
|
((method-of-type pc-settings initialize) obj)
|
|
(set! (-> *setting-control* user-default sfx-volume) (-> obj memcard-volume-sfx))
|
|
(set! (-> *setting-control* user-default music-volume) (-> obj memcard-volume-music))
|
|
(set! (-> *setting-control* user-default dialog-volume) (-> obj memcard-volume-dialog))
|
|
(set! (-> *setting-control* user-default vibration) (-> obj memcard-vibration?))
|
|
obj)
|
|
|
|
(defmethod set-game-setting! ((obj pc-settings-jak2) (setting symbol) (value symbol))
|
|
(case setting
|
|
(('video-mode)
|
|
(set! (-> *setting-control* user-current video-mode) #f)
|
|
(set! (-> *setting-control* user-default video-mode) value)
|
|
)
|
|
(('aspect-ratio)
|
|
(set! (-> *setting-control* user-default aspect-ratio) value)
|
|
)
|
|
(else
|
|
(format #t "unknown setting ~A (~A) to set-game-setting!" setting value))
|
|
)
|
|
)
|
|
|
|
(defmethod get-game-setting ((obj pc-settings-jak2) (setting symbol))
|
|
(case setting
|
|
(('video-mode)
|
|
(-> *setting-control* user-default video-mode)
|
|
)
|
|
(('aspect-ratio)
|
|
(-> *setting-control* user-default aspect-ratio)
|
|
)
|
|
(else
|
|
(format #t "unknown setting ~A to get-game-setting" setting)
|
|
#f)
|
|
)
|
|
)
|
|
|
|
(defmethod set-game-language! ((obj pc-settings-jak2) (lang language-enum))
|
|
(set! (-> *setting-control* user-default language) lang)
|
|
)
|
|
|
|
(defmethod get-game-language ((obj pc-settings-jak2))
|
|
(get-current-language)
|
|
)
|
|
|
|
|
|
(defmethod update ((obj pc-settings-jak2))
|
|
"Set the default misc settings"
|
|
|
|
((method-of-type pc-settings update) obj)
|
|
|
|
(set! *hires-sky* (-> obj hires-clouds?))
|
|
|
|
(when (not (led-enabled? obj))
|
|
(disable *led-fader-state*)
|
|
)
|
|
|
|
(none))
|
|
|
|
|
|
(defun real-movie? ()
|
|
"are we in an actual cutscene and should letterbox the view?"
|
|
(and (!= #f *scene-player*) (nonzero? movie?) (movie?)))
|
|
|
|
(defmethod update-discord-rpc ((obj pc-settings-jak2))
|
|
"update discord rpc module"
|
|
(let ((info (new 'stack 'discord-info)))
|
|
(set! (-> info orb-count) (-> *game-info* skill-total))
|
|
(set! (-> info gem-count) (-> *game-info* gem-total))
|
|
(set! (-> info death-count) (-> *game-info* total-deaths))
|
|
(set! (-> info task) "unknown")
|
|
(set! (-> info status) (get-active-mission-description info))
|
|
;; grab the name of the level we're in
|
|
(cond
|
|
((or (aif (level-get *level* 'title) (= (-> it status) 'active))
|
|
(and *progress-process*
|
|
(= 'title (-> *progress-process* 0 state-stack 0))))
|
|
;; in title screen.
|
|
(set! (-> info level) (symbol->string 'title))
|
|
(set! (-> info status) "In title screen"))
|
|
(else
|
|
(set! (-> info level) (aif (-> *load-state* vis-nick) (symbol->string it) "unknown")))
|
|
)
|
|
(set! (-> info cutscene?) (real-movie?))
|
|
(set! (-> info time-of-day) (-> *time-of-day-context* time))
|
|
(set! (-> info percent-complete) (calculate-percentage *game-info*))
|
|
(set! (-> info focus-status) (if *target* (-> *target* focus-status) 0))
|
|
;; TODO - update to new with-profiler syntax
|
|
(pc-discord-rpc-update info)
|
|
)
|
|
(none))
|
|
|
|
(defmethod update-speedrun ((obj pc-settings-jak2))
|
|
"update speedrun module"
|
|
;; TODO - update to new with-profiler syntax
|
|
;; (with-profiler "speedrun-update"
|
|
(update! *speedrun-info*)
|
|
;;)
|
|
(none))
|
|
|
|
(defmethod update-video-hacks ((obj pc-settings-jak2))
|
|
"update the graphics hacks used for the progress menu. ugh."
|
|
|
|
(set! (-> (get-video-params) relative-x-scale) (-> obj aspect-ratio-reciprocal))
|
|
(set! (-> (get-video-params) relative-x-scale-reciprical) (-> obj aspect-ratio-scale))
|
|
)
|
|
|
|
|
|
(defmethod eligible-for-fast-elevator? ((obj pc-settings-jak2) (proc process))
|
|
"is this a valid process for a fast elevator?"
|
|
(and (-> obj fast-elevator?) (not (or (string= (-> proc name) "drill-lift-1")
|
|
(string= (-> proc name) "drill-lift-2"))))
|
|
)
|
|
|
|
(defmethod get-airlock-speed ((obj pc-settings-jak2))
|
|
"return the current speed modifier for airlocks"
|
|
(if (-> obj fast-airlock?)
|
|
(-> *pc-cheat-state* airlock-speed)
|
|
1.0))
|
|
|
|
(defmethod get-airlock-close-speed ((obj pc-settings-jak2))
|
|
"return the current closing speed modifier for airlocks"
|
|
(if (-> obj fast-airlock?)
|
|
(-> *pc-cheat-state* airlock-close-speed)
|
|
1.0))
|
|
|
|
|
|
(defmethod led-enabled? ((obj pc-settings-jak2))
|
|
"should the controller led be set?"
|
|
(or (-> obj controller-led-hp?)
|
|
(-> obj controller-led-status?)
|
|
))
|
|
|
|
(defmethod update-led ((obj pc-settings-jak2))
|
|
"set the controller led color by modifying the controller-led-color vector"
|
|
|
|
;; default color is just blue.
|
|
(set-vector-xyz! (-> obj controller-led-color) 0.0 0.0 1.0)
|
|
|
|
(when *target*
|
|
(let ((disable-fader? #t)
|
|
(simon-plat (the process #f)))
|
|
(when (-> obj controller-led-hp?)
|
|
;; flicker led according to hp. lower hp = faster and more intense flicker
|
|
(cond
|
|
((= (-> *target* fact health) 0.0)
|
|
;; dead. just set to minimum brightness.
|
|
(set! (-> obj controller-led-color a) (-> obj controller-led-min-brightness))
|
|
)
|
|
(else
|
|
(let ((flicker-speed (lerp-scale 2.0 0.0
|
|
(-> *target* fact health)
|
|
1.0 (-> *FACT-bank* health-max-default)))
|
|
(flicker-amp (lerp-scale (- 1.0 (-> obj controller-led-min-brightness)) (- 1.0 (-> obj controller-led-max-brightness))
|
|
(-> *target* fact health)
|
|
1.0 (-> *FACT-bank* health-max-default)))
|
|
)
|
|
(set! (-> obj controller-led-color a) (- 1.0 (* flicker-amp (/ (+ 1.0 (sin (* flicker-speed (degrees (current-time))))) 2.0))))
|
|
)
|
|
)
|
|
)
|
|
)
|
|
|
|
(when (-> obj controller-led-status?)
|
|
(set-vector-xyz! (-> obj controller-led-color) 1.0 1.0 1.0)
|
|
(cond
|
|
;; simon plat
|
|
((set! simon-plat (search-process-tree *active-pool*
|
|
(lambda ((proc process)) (and (= (-> proc type symbol) 'tomb-plat-simon)
|
|
(-> proc next-state)
|
|
(symbol-member? (-> proc next-state name) '(appear show-sequence idle))))))
|
|
(set! disable-fader? #f)
|
|
(case (-> simon-plat next-state name)
|
|
(('appear)
|
|
;; simon plats appearing - fade to black
|
|
(vector-copy! *led-tomb-simon-color* *led-tomb-simon-off-color*)
|
|
(vector-copy! (-> *led-fader-state* end-color) *led-tomb-simon-off-color*)
|
|
(if (not (-> *led-fader-state* enable?))
|
|
(enable *led-fader-state* (-> obj controller-led-color)))
|
|
)
|
|
(('show-sequence)
|
|
;; showing simon sequence - use only the flashing color
|
|
(vector-copy! (-> obj controller-led-color) *led-tomb-simon-color*)
|
|
;; set fader color to max, if it's not somehow.
|
|
(when (!= (-> *led-fader-state* amount) 1.0)
|
|
(set! (-> *led-fader-state* amount) 1.0))
|
|
)
|
|
(('idle)
|
|
;; playing simon sequence - simon blocks set end-color here
|
|
)
|
|
)
|
|
(update *led-fader-state* 1.0 2.0)
|
|
(unless (= (-> simon-plat next-state name) 'show-sequence)
|
|
(vector3-copy!! (-> obj controller-led-color) (-> *led-fader-state* cur-color)))
|
|
)
|
|
;; simon plat block
|
|
((set! simon-plat (search-process-tree *active-pool*
|
|
(lambda ((proc process)) (and (= (-> proc type symbol) 'tomb-simon-block)
|
|
(-> proc next-state)
|
|
(= (-> proc next-state name) 'dangerous)))))
|
|
;; simon plat mistake - fade to black (start color was set by simon block)
|
|
(set! disable-fader? #f)
|
|
(vector-copy! (-> *led-fader-state* end-color) *led-tomb-simon-off-color*)
|
|
(update *led-fader-state* 1.0 1.5)
|
|
(vector3-copy!! (-> obj controller-led-color) (-> *led-fader-state* cur-color))
|
|
)
|
|
|
|
;; gun
|
|
((and (nonzero? (-> *target* gun)) (focus-test? *target* gun))
|
|
(case (-> *target* gun gun-type)
|
|
(((pickup-type eco-yellow))
|
|
(set-vector-xyz! (-> obj controller-led-color) 1.0 0.75 0.125))
|
|
(((pickup-type eco-red))
|
|
(set-vector-xyz! (-> obj controller-led-color) 0.65 0.0 0.0))
|
|
(((pickup-type eco-blue))
|
|
(set-vector-xyz! (-> obj controller-led-color) 0.4375 0.8125 1.0))
|
|
(((pickup-type eco-dark))
|
|
(set-vector-xyz! (-> obj controller-led-color) 0.6875 0.6 0.78125))
|
|
)
|
|
)
|
|
|
|
;; darkjak
|
|
((and (nonzero? (-> *target* darkjak)) (focus-test? *target* dark))
|
|
(vector-copy! (-> *led-fader-state* end-color) *led-darkjak-color*)
|
|
(set! disable-fader? #f)
|
|
(if (not (-> *led-fader-state* enable?))
|
|
(enable *led-fader-state* (-> obj controller-led-color)))
|
|
(if (and (-> *target* next-state) (= (-> *target* next-state name) 'target-darkjak-get-off))
|
|
(update *led-fader-state* 0.0 0.75)
|
|
(update *led-fader-state* 1.0 0.3))
|
|
(vector3-copy!! (-> obj controller-led-color) (-> *led-fader-state* cur-color))
|
|
)
|
|
|
|
;; indax
|
|
((focus-test? *target* indax)
|
|
(set-vector-xyz! (-> obj controller-led-color) 1.0 0.5 0.0)
|
|
)
|
|
|
|
;; mech
|
|
((focus-test? *target* mech)
|
|
(set-vector-xyz! (-> obj controller-led-color) 1.0 1.0 0.0)
|
|
)
|
|
|
|
;; board
|
|
((focus-test? *target* board)
|
|
(set-vector-xyz! (-> obj controller-led-color) 0.0 1.0 1.0)
|
|
)
|
|
)
|
|
|
|
;; wanted flash
|
|
(awhen (the hud-map (process-by-name "hud-map" *active-pool*))
|
|
(when (not (hidden? it))
|
|
(let ((flash-amount (/ (+ (sin (degrees (-> it values 1 current))) 1.0) 2)))
|
|
(vector3-lerp! (-> obj controller-led-color) (-> obj controller-led-color) *led-wanted-flash-color* flash-amount)
|
|
))
|
|
)
|
|
)
|
|
(when disable-fader?
|
|
(disable *led-fader-state*))
|
|
))
|
|
#t)
|
|
|
|
(defmacro flava-unlocked? (flava)
|
|
"return #t if the specified flava is unlocked"
|
|
`(-> *pc-settings* flava-unlocked ,flava))
|
|
|
|
|
|
(defun inside-city? ()
|
|
"are we inside haven city?"
|
|
(symbol-member? (-> *game-info* current-continue vis-nick) ;; TODO get actual level we're in?
|
|
'(ctysluma ctyslumb ctyslumc
|
|
ctygena ctygenb ctygenc
|
|
ctymarka ctymarkb
|
|
ctyfarma ctyfarmb
|
|
ctyinda ctyindb
|
|
ctypal ctyport stadium)))
|
|
|
|
|
|
(defmethod update-cheats ((obj pc-settings-jak2))
|
|
"run cheats."
|
|
|
|
;; sync mirror mode cheat
|
|
(set! *PC-MIRROR-MODE-SET* (logtest? (-> *game-info* secrets) (game-secrets hflip-screen)))
|
|
|
|
;; run cheats here.
|
|
;;;;;;;;;;;;;;;;;;;
|
|
|
|
(when (pc-cheats? (-> obj cheats) real-time-of-day)
|
|
(let ((date (new 'stack-no-clear 'scf-time)))
|
|
(scf-get-time date)
|
|
(when (zero? (-> date stat))
|
|
(let* ((cur-time (-> *display* bg-clock frame-counter))
|
|
(day-len (seconds 1440)) ;; a full in-game day
|
|
(want-hour (bcd->dec (-> date hour)))
|
|
(want-minute (bcd->dec (-> date minute)))
|
|
(target-hour-frame (/ (the int (* (fsec 3600) want-hour)) 60))
|
|
(target-minute-frame (/ (the int (* (fsec 60) want-minute)) 60))
|
|
)
|
|
(set! (-> *display* bg-clock frame-counter) (+ (- cur-time (mod cur-time day-len)) day-len (+ target-hour-frame target-minute-frame)))
|
|
))
|
|
))
|
|
|
|
;; turbo jet board cheat
|
|
(cond
|
|
((and (pc-cheats? (-> obj cheats) turbo-board)
|
|
*target*
|
|
(focus-test? *target* board)
|
|
(inside-city?))
|
|
(set-setting! 'string-spline-max-move 'abs (* (-> *pc-cheat-state* turbo-board-speed) (meters 2)) 0)
|
|
(set-setting! 'string-spline-accel 'abs (* (-> *pc-cheat-state* turbo-board-speed) (meters 0.045)) 0)
|
|
(set-setting! 'string-spline-max-move-player 'abs (* (-> *pc-cheat-state* turbo-board-speed) (meters 1.5)) 0)
|
|
(set-setting! 'string-spline-accel-player 'abs (* (-> *pc-cheat-state* turbo-board-speed) (meters 0.035)) 0)
|
|
(set-cheat-state-flag! turbo-board)
|
|
)
|
|
(else
|
|
(remove-setting! 'string-spline-max-move)
|
|
(remove-setting! 'string-spline-accel)
|
|
(remove-setting! 'string-spline-max-move-player)
|
|
(remove-setting! 'string-spline-accel-player)
|
|
(clear-cheat-state-flag! turbo-board)
|
|
)
|
|
)
|
|
|
|
(pc-set-gfx-hack (pc-gfx-hack no-tex) (pc-cheats? (-> obj cheats) no-textures))
|
|
|
|
(if (or (logtest? (-> *game-info* secrets) (game-secrets hflip-screen))
|
|
*PC-MIRROR-MODE-SET*)
|
|
(sound-set-mirror-mode (sound-mirror-mode mirrored))
|
|
(sound-set-mirror-mode (sound-mirror-mode normal)))
|
|
|
|
;; run cheats end!!!
|
|
;;;;;;;;;;;;;;;;;;;;
|
|
|
|
;; check unlocked cheats
|
|
;;;;;;;;;;;;;;;;;;;;;;;;
|
|
(let ((old (-> *pc-settings* cheats))
|
|
(old-unlocked (-> *pc-settings* cheats-unlocked))
|
|
(old-purchased (-> *pc-settings* cheats-purchased))
|
|
(old-revealed (-> *pc-settings* cheats-revealed)))
|
|
|
|
(dotimes (i (-> *pc-cheats-list* length))
|
|
|
|
;; reveals cheats if they have been purchased, purchases cheats if they have been unlocked, unlocks cheats if they have been enabled.
|
|
;; the cheat process requires the steps to be filled in this order, see sequential checking below
|
|
(logior! (-> *pc-settings* cheats-revealed) (logior! (-> *pc-settings* cheats-purchased) (logior! (-> *pc-settings* cheats-unlocked) (-> *pc-settings* cheats))))
|
|
|
|
(let* ((cheat (-> *pc-cheats-list* i))
|
|
(cost (-> cheat skill))
|
|
(unlock-func (the (function symbol) (-> cheat unlock-func value))))
|
|
|
|
(when (if (logtest? (-> *game-info* secrets) (game-secrets hero-mode))
|
|
(task-node-closed? (-> cheat avail-after-hero))
|
|
(task-node-closed? (-> cheat avail-after)))
|
|
(logior! (-> obj cheats-revealed) (-> cheat flag))
|
|
|
|
(when (>= (-> *game-info* skill-total) cost)
|
|
(logior! (-> obj cheats-purchased) (-> cheat flag))
|
|
|
|
(when (or (zero? unlock-func)
|
|
(not unlock-func)
|
|
(unlock-func))
|
|
(logior! (-> obj cheats-unlocked) (-> cheat flag)))))
|
|
(case (-> cheat can-toggle)
|
|
((#f)
|
|
(when (logtest? (-> obj cheats-unlocked) (-> cheat flag))
|
|
(logior! (-> obj cheats) (-> cheat flag)))
|
|
)
|
|
)))
|
|
|
|
;; when speedrunning...the cheats are manually modified to facilitate the chosen category
|
|
;; don't persist these and don't spam the pc-settings saving routine every frame.
|
|
(when (and (not (-> *pc-settings* speedrunner-mode?))
|
|
(or (!= old (-> *pc-settings* cheats))
|
|
(!= old-unlocked (-> *pc-settings* cheats-unlocked))
|
|
(!= old-purchased (-> *pc-settings* cheats-purchased))
|
|
(!= old-revealed (-> *pc-settings* cheats-revealed))))
|
|
;; save pc-settings if we made new progress
|
|
(pc-settings-save)))
|
|
|
|
0)
|
|
|
|
|
|
(defmethod update-music-log ((obj pc-settings-jak2))
|
|
"update the music log"
|
|
|
|
(dotimes (i (-> *music-player-tracks* length))
|
|
(when (or (logtest? (-> *game-info* secrets) (game-secrets hero-mode))
|
|
(task-node-closed? (-> *music-player-tracks* i avail-after)))
|
|
(set-bit (-> obj music-unlocked) i)
|
|
)
|
|
)
|
|
|
|
(true! (-> obj flava-unlocked 0)) ;; default always unlocked
|
|
(if (task-node-closed? (game-task-node city-red-gun-training-resolution)) (true! (-> obj flava-unlocked 1))) ;; gun
|
|
(if (task-node-closed? (game-task-node forest-scouts-resolution)) (true! (-> obj flava-unlocked 2))) ;; board
|
|
(if (task-node-closed? (game-task-node ruins-mech-resolution)) (true! (-> obj flava-unlocked 3))) ;; mech
|
|
(if (task-node-closed? (game-task-node city-oracle-introduction)) (true! (-> obj flava-unlocked 4))) ;; darkjak
|
|
(if (task-node-closed? (game-task-node city-vehicle-training-resolution)) (true! (-> obj flava-unlocked 5))) ;; pilot
|
|
|
|
0)
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;;;; file I/O
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
(defun bit-array<-int64 ((arr bit-array) (start-offset int) (val int))
|
|
"starting from start-offset at arr, fill the next 64 bits of the array from an int64"
|
|
(let ((i start-offset)
|
|
(end-offset (min (+ start-offset 64) (-> arr length))))
|
|
(while (< i end-offset)
|
|
(if (nonzero? (logand val (ash 1 (- i start-offset))))
|
|
(set-bit arr i))
|
|
(1+! i)
|
|
)
|
|
val)
|
|
)
|
|
|
|
(defun int64<-bit-array ((arr bit-array) (start-offset int))
|
|
"starting from start-offset at arr, pack the next 64 bits into a single value and return it"
|
|
(let ((val 0)
|
|
(i start-offset)
|
|
(end-offset (min (+ start-offset 64) (-> arr length))))
|
|
(while (< i end-offset)
|
|
(if (get-bit arr i)
|
|
(logior! val (ash 1 (- i start-offset))))
|
|
(1+! i)
|
|
)
|
|
val)
|
|
)
|
|
|
|
(defmethod handle-input-settings ((obj pc-settings-jak2) (file file-stream))
|
|
"handle the text parsing input for the 'settings' group"
|
|
|
|
((method-of-type pc-settings handle-input-settings) obj file)
|
|
(case-str *pc-temp-string*
|
|
(("fast-airlock?") (set! (-> obj fast-airlock?) (file-stream-read-symbol file)))
|
|
(("fast-elevator?") (set! (-> obj fast-elevator?) (file-stream-read-symbol file)))
|
|
(("fast-progress?") (set! (-> obj fast-progress?) (file-stream-read-symbol file)))
|
|
(("smooth-minimap?") (set! (-> obj smooth-minimap?) (file-stream-read-symbol file)))
|
|
(("minimap-force-north") (set! (-> obj minimap-force-north) (file-stream-read-symbol file)))
|
|
(("hires-clouds?") (set! (-> obj hires-clouds?) (file-stream-read-symbol file)))
|
|
(("text-language") (set! (-> obj text-language) (the-as pc-language (file-stream-read-int file))))
|
|
(("controller-led-status?") (set! (-> obj controller-led-status?) (file-stream-read-symbol file)))
|
|
(("speedrunner-mode-custom-bind") (set! (-> obj speedrunner-mode-custom-bind) (file-stream-read-int file)))
|
|
(("cheats") (set! (-> obj cheats) (the-as pc-cheats (file-stream-read-int file))))
|
|
(("cheats-revealed") (set! (-> obj cheats-revealed) (the-as pc-cheats (file-stream-read-int file))))
|
|
(("cheats-purchased") (set! (-> obj cheats-purchased) (the-as pc-cheats (file-stream-read-int file))))
|
|
(("cheats-unlocked") (set! (-> obj cheats-unlocked) (the-as pc-cheats (file-stream-read-int file))))
|
|
(("cheats-backup") (file-stream-read-int file)) ;; TODO - Don't remove this, parsing code can't handle unexpected keys
|
|
(("memcard-subtitles?") (set! (-> obj memcard-subtitles?) (file-stream-read-symbol file)))
|
|
(("music-unlocked")
|
|
(dotimes (i (/ (align64 (-> obj music-unlocked length)) 64))
|
|
(bit-array<-int64 (-> obj music-unlocked) (* i 64) (file-stream-read-int file))
|
|
)
|
|
)
|
|
(("flava-unlocked")
|
|
(dotimes (i 6)
|
|
(set! (-> obj flava-unlocked i) (file-stream-read-symbol file))
|
|
)
|
|
)
|
|
(("stats")
|
|
(dosettings (file)
|
|
(case-str *pc-temp-string*
|
|
(("kill-stats")
|
|
(initialize (-> obj stats kill-stats))
|
|
(dosettings (file)
|
|
(let ((enemy-stats (alloc-slot (-> obj stats kill-stats) (string->symbol *pc-temp-string*))))
|
|
(dosettings (file)
|
|
(let ((source (string->kill-source *pc-temp-string*))
|
|
(amount (file-stream-read-int file)))
|
|
(when (!= source (kill-stats-source unknown))
|
|
(set! (-> enemy-stats sources source) amount)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
0)
|
|
|
|
(defmethod handle-output-settings ((obj pc-settings-jak2) (file file-stream))
|
|
"handle the text writing output for the 'settings' group"
|
|
|
|
((method-of-type pc-settings handle-output-settings) obj file)
|
|
(format file " (fast-airlock? ~A)~%" (-> obj fast-airlock?))
|
|
(format file " (fast-elevator? ~A)~%" (-> obj fast-elevator?))
|
|
(format file " (fast-progress? ~A)~%" (-> obj fast-progress?))
|
|
(format file " (smooth-minimap? ~A)~%" (-> obj smooth-minimap?))
|
|
(format file " (minimap-force-north ~A)~%" (-> obj minimap-force-north))
|
|
(format file " (hires-clouds? ~A)~%" (-> obj hires-clouds?))
|
|
(format file " (text-language ~D)~%" (-> obj text-language))
|
|
(format file " (controller-led-status? ~A)~%" (-> obj controller-led-status?))
|
|
(format file " (speedrunner-mode-custom-bind ~D)~%" (-> obj speedrunner-mode-custom-bind))
|
|
(format file " (cheats #x~x)~%" (-> obj cheats))
|
|
(format file " (cheats-revealed #x~x)~%" (-> obj cheats-revealed))
|
|
(format file " (cheats-purchased #x~x)~%" (-> obj cheats-purchased))
|
|
(format file " (cheats-unlocked #x~x)~%" (-> obj cheats-unlocked))
|
|
(format file " (memcard-subtitles? ~A)~%" (-> obj memcard-subtitles?))
|
|
|
|
(format file " (music-unlocked")
|
|
(dotimes (i (/ (align64 (-> obj music-unlocked length)) 64))
|
|
(format file " #x~x" (int64<-bit-array (-> obj music-unlocked) (* i 64)))
|
|
)
|
|
(format file ")~%")
|
|
|
|
(format file " (flava-unlocked")
|
|
(dotimes (i 6)
|
|
(format file " ~A" (-> obj flava-unlocked i))
|
|
)
|
|
(format file ")~%")
|
|
|
|
(format file " (stats~%")
|
|
(format file " (kill-stats~%")
|
|
(dotimes (i KILL_STATS_MAX_ENEMY_TYPES)
|
|
(when (-> obj stats kill-stats enemies i name)
|
|
(format file " (~A~%" (-> obj stats kill-stats enemies i name))
|
|
(dotimes (ii KILL_STATS_MAX_SOURCE)
|
|
(when (nonzero? (-> obj stats kill-stats enemies i sources ii))
|
|
(format file " (~A ~D)~%" (string->symbol (kill-source->string (the kill-stats-source ii))) (-> obj stats kill-stats enemies i sources ii))
|
|
))
|
|
(format file " )~%")
|
|
))
|
|
(format file " )~%")
|
|
(format file " )~%")
|
|
0)
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;;;; PC settings
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
(define-once *pc-settings* (new 'global 'pc-settings-jak2))
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;;;; other
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
|
|
(defun draw-build-revision ()
|
|
(with-dma-buffer-add-bucket ((buf (-> (current-frame) global-buf))
|
|
(bucket-id debug-no-zbuf2))
|
|
;; reset bucket settings prior to drawing - font won't do this for us, and
|
|
;; draw-raw-image can sometimes mess them up.
|
|
(dma-buffer-add-gs-set-flusha buf
|
|
(alpha-1 (new 'static 'gs-alpha :b #x1 :d #x1))
|
|
(tex1-1 (new 'static 'gs-tex1 :mmag #x1 :mmin #x1)))
|
|
(clear *pc-encoded-temp-string*)
|
|
(clear *temp-string*)
|
|
(format *temp-string* "<COLOR_WHITE>~S" *pc-settings-built-sha*)
|
|
(pc-encode-utf8-string *temp-string* *pc-encoded-temp-string*)
|
|
(let ((font-ctx (new 'stack 'font-context *font-default-matrix* 2 406 0.0 (font-color default) (font-flags shadow kerning large))))
|
|
(set! (-> font-ctx scale) 0.25)
|
|
(draw-string-adv *pc-encoded-temp-string* buf font-ctx))))
|
|
|
|
|
|
|
|
(defun print-level-types ((lev level))
|
|
"print the level-type linked list for a level"
|
|
(format #t "print-level-types for ~A~%" (-> lev nickname))
|
|
(let ((cur-type (-> lev level-type)))
|
|
(while (and cur-type (nonzero? cur-type) (= type (-> cur-type type)))
|
|
(format #t "~A~%" cur-type)
|
|
(set! cur-type (the type (-> cur-type method-table 8))))
|
|
(format #t "~%"))
|
|
)
|
|
|
|
|
|
(defun-debug pc-cheat->string ((cheat pc-cheats))
|
|
(doenum (name val pc-cheats)
|
|
(if (= cheat val)
|
|
(return name))
|
|
)
|
|
"*unknown*")
|
|
|
|
(defun-debug print-cheat-status (out)
|
|
(dotimes (i (-> *pc-cheats-list* length))
|
|
(let ((flag (-> *pc-cheats-list* i flag)))
|
|
(cond
|
|
((logtest? (-> *pc-settings* cheats) flag) (format out " ~20S(#x~6x): enabled~%" (pc-cheat->string flag) flag))
|
|
((logtest? (-> *pc-settings* cheats-unlocked) flag) (format out " ~20S(#x~6x): unlocked~%" (pc-cheat->string flag) flag))
|
|
((logtest? (-> *pc-settings* cheats-purchased) flag) (format out " ~20S(#x~6x): purchased~%" (pc-cheat->string flag) flag))
|
|
((logtest? (-> *pc-settings* cheats-revealed) flag) (format out " ~20S(#x~6x): revealed~%" (pc-cheat->string flag) flag))
|
|
(else (format out " ~20S(#x~6x): locked~%" (pc-cheat->string flag) flag))
|
|
)
|
|
))
|
|
out)
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;;;; process pools
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
;; the actor pool for PC processes! it has space for 4 processes, with 16K of space.
|
|
(define *pc-dead-pool* (new 'global 'dead-pool 4 (* 16 1024) "*pc-dead-pool*"))
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;;;; progress adjustments
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
(defconstant CENTER_X (/ 512 2))
|
|
|
|
(defun adjust-game-x-centered ((origin int) (x float))
|
|
"given an x position ranging from [0, 512) adjust for aspect ratio towards the origin point specified
|
|
such that it does not get stretched away with the framebuffer"
|
|
(+ origin (* (- x origin) (-> *pc-settings* aspect-ratio-reciprocal))))
|
|
|
|
(defmacro adjust-game-x (x)
|
|
`(adjust-game-x-centered CENTER_X ,x))
|
|
|
|
(defmacro adjust-game-x-int (x-float)
|
|
`(the int (adjust-game-x-centered CENTER_X (the float ,x-float))))
|