mirror of
https://github.com/open-goal/jak-project
synced 2026-08-07 02:06:59 -04:00
7475e356b5
Adds a new "hires" sky texture animation that makes the sky use 512x512 textures instead of 128x128. The clouds have higher detail, are slightly more noisy, and are considerably less blocky. There is also a less noticeable "dot crawl" effect.  
433 lines
18 KiB
Common Lisp
433 lines
18 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))
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;;;; music player stuff
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
(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)))
|
|
)
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;;;; methods
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
(defmethod initialize pc-settings-jak2 ((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)
|
|
obj)
|
|
|
|
(defmethod set-game-setting! pc-settings-jak2 ((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 pc-settings-jak2 ((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! pc-settings-jak2 ((obj pc-settings-jak2) (lang language-enum))
|
|
(set! (-> *setting-control* user-default language) lang)
|
|
)
|
|
|
|
(defmethod get-game-language pc-settings-jak2 ((obj pc-settings-jak2))
|
|
(get-current-language)
|
|
)
|
|
|
|
|
|
(defmethod update pc-settings-jak2 ((obj pc-settings-jak2))
|
|
"Set the default misc settings"
|
|
|
|
((method-of-type pc-settings update) obj)
|
|
|
|
(set! *hires-sky* (-> obj hires-clouds?))
|
|
(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 pc-settings-jak2 ((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 - wrapping in `with-profiler` causes an error, fix it
|
|
(pc-discord-rpc-update info)
|
|
)
|
|
(none))
|
|
|
|
(defmethod update-speedrun pc-settings-jak2 ((obj pc-settings-jak2))
|
|
"update speedrun module"
|
|
(when (-> *pc-settings* speedrunner-mode?)
|
|
(speedrun-mode-update))
|
|
(none))
|
|
|
|
(defmethod update-video-hacks pc-settings-jak2 ((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? pc-settings-jak2 ((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 pc-settings-jak2 ((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 pc-settings-jak2 ((obj pc-settings-jak2))
|
|
"return the current closing speed modifier for airlocks"
|
|
(if (-> obj fast-airlock?)
|
|
(-> *pc-cheat-state* airlock-close-speed)
|
|
1.0))
|
|
|
|
(defmacro flava-unlocked? (flava)
|
|
"return #t if the specified flava is unlocked"
|
|
`(-> *pc-settings* flava-unlocked ,flava))
|
|
|
|
|
|
(defmethod update-cheats pc-settings-jak2 ((obj pc-settings-jak2))
|
|
"run cheats."
|
|
|
|
;; 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? (-> *pc-settings* cheats) turbo-board)
|
|
*target*
|
|
(focus-test? *target* board)
|
|
(case (-> *game-info* current-continue vis-nick)
|
|
(('ctysluma 'ctyslumb 'ctyslumc 'ctypal
|
|
'ctygena 'ctygenb 'ctygenc 'ctyport
|
|
'ctymarka 'ctymarkb 'ctyfarma 'ctyfarmb
|
|
'ctyinda 'ctyindb 'stadium) #t)
|
|
;; also allow in forest
|
|
(('forest) #t #|(not (task-node-open? (game-task-node forest-scouts-pegasus)))|#)))
|
|
(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))
|
|
|
|
;; run cheats end!!!
|
|
;;;;;;;;;;;;;;;;;;;;
|
|
|
|
0)
|
|
|
|
|
|
(defmethod update-music-log pc-settings-jak2 ((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 pc-settings-jak2 ((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*
|
|
(("jetboard-trick-text?") (set! (-> obj jetboard-trick-text?) (file-stream-read-symbol file)))
|
|
(("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)))
|
|
(("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))))
|
|
(("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))))
|
|
(("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))
|
|
)
|
|
)
|
|
)
|
|
0)
|
|
|
|
(defmethod handle-output-settings pc-settings-jak2 ((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 " (jetboard-trick-text? ~A)~%" (-> obj jetboard-trick-text?))
|
|
(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 " (hires-clouds? ~A)~%" (-> obj hires-clouds?))
|
|
(format file " (text-language ~D)~%" (-> obj text-language))
|
|
(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 " (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 ")~%")
|
|
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-zbuf1))
|
|
;; 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))
|
|
)
|
|
(draw-string-xy *pc-settings-built-sha*
|
|
buf
|
|
512 14
|
|
(font-color flat-yellow)
|
|
(font-flags right shadow kerning))))
|
|
|
|
|
|
|
|
(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 "~%"))
|
|
)
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;;;; 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))
|
|
|