mirror of
https://github.com/open-goal/jak-project.git
synced 2024-10-20 21:27:52 -04:00
6e8b0e57c7
Also fixes a minor issue where the JP sound bank wouldn't work (Jak 1). Fixes #2793
524 lines
17 KiB
Common Lisp
524 lines
17 KiB
Common Lisp
;;-*-Lisp-*-
|
|
(in-package goal)
|
|
|
|
#|
|
|
|
|
This file contains code that we need for the PC port of the game specifically.
|
|
It should be included as part of the game engine package (engine.cgo).
|
|
|
|
This file contains various types and functions to store PC-specific information
|
|
and also to communicate between the game (GOAL) and the operating system.
|
|
This way we can poll, change and display information about the system the game
|
|
is running on, such as:
|
|
- display devices and their settings, such as fullscreen, DPI, refresh rate, etc.
|
|
- audio devices and their settings, such as audio latency, channel number, etc.
|
|
- graphics devices and their settings, such as resolution, FPS, anisotropy, shaders, etc.
|
|
- input devices and their settings, such as controllers, keyboards, mice, etc.
|
|
- information about the game window (position, size)
|
|
- PC-specific goodies, enhancements, fixes and settings.
|
|
- whatever else.
|
|
|
|
If you do not want to include these PC things, you should exclude it from the build system.
|
|
|
|
|#
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;;;; constants
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
(deftype pckernel-version (int64)
|
|
((build int16 :offset 0)
|
|
(revision int16 :offset 16)
|
|
(minor int16 :offset 32)
|
|
(major int16 :offset 48)
|
|
)
|
|
)
|
|
|
|
(defmacro static-pckernel-version (major minor rev build)
|
|
`(new 'static 'pckernel-version :major ,major :minor ,minor :revision ,rev :build ,build))
|
|
(defconstant PC_KERNEL_INVALID_VERSION (static-pckernel-version #xffff #xffff #xffff #xffff))
|
|
;; version: invalid
|
|
(defconstant PC_KERNEL_VERSION PC_KERNEL_INVALID_VERSION)
|
|
(defconstant PC_KERNEL_VER_MAJOR (-> PC_KERNEL_VERSION major))
|
|
(defconstant PC_KERNEL_VER_MINOR (-> PC_KERNEL_VERSION minor))
|
|
(defconstant PC_KERNEL_VER_REVISION (-> PC_KERNEL_VERSION revision))
|
|
(defconstant PC_KERNEL_VER_BUILD (-> PC_KERNEL_VERSION build))
|
|
|
|
(defun-extern get-pckernel-version pckernel-version)
|
|
|
|
|
|
(defconstant PS2_VOICE_AMOUNT 48)
|
|
(defconstant PC_VOICE_AMOUNT 256)
|
|
|
|
(defconstant ASPECT_4X3 (/ 4.0 3.0))
|
|
(defconstant ASPECT_16X9 (/ 16.0 9.0))
|
|
(defconstant ASPECT_16X9_SCALE (/ ASPECT_16X9 ASPECT_4X3))
|
|
(defconstant PC_BASE_WIDTH 640)
|
|
(defconstant PC_BASE_HEIGHT 480)
|
|
(defconstant PC_MIN_WIDTH 320)
|
|
(defconstant PC_MIN_HEIGHT 240)
|
|
(defconstant PC_DEFAULT_MSAA 2)
|
|
|
|
|
|
;; how many entries the music log has. the game only has 21 tracks but let's have more space for no reason.
|
|
(defconstant PC_MUSIC_LOG_LENGTH 30)
|
|
;; how many entries the spool anim log has. only 164 are used in-game.
|
|
(defconstant PC_SPOOL_LOG_LENGTH 170)
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;;;; types and enums
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
|
|
;; graphics renderers
|
|
(defenum pc-gfx-renderer
|
|
:type uint8
|
|
(software)
|
|
(opengl)
|
|
(vulkan)
|
|
(direct3d)
|
|
)
|
|
|
|
|
|
(defmacro pc-cheats? (obj &rest cheats)
|
|
`(logtest? ,obj (pc-cheats ,@cheats)))
|
|
|
|
;; music log info
|
|
(deftype pc-music-log-entry (structure)
|
|
((name symbol)
|
|
(flava-mask int32)
|
|
)
|
|
:pack-me
|
|
)
|
|
|
|
;; bingo integration. placeholder for now.
|
|
(deftype pc-bingo-info (structure)
|
|
()
|
|
:pack-me
|
|
)
|
|
|
|
|
|
;; All of the configuration for the PC port in GOAL. Access things from here!
|
|
;; Includes some methods to change parameters.
|
|
(deftype pc-settings (basic)
|
|
((version pckernel-version) ;; version of this settings
|
|
|
|
;; "generic" graphics settings
|
|
(target-fps int16) ;; the target framerate of the game
|
|
;; game resolution?
|
|
(width int32)
|
|
(height int32)
|
|
;; window size. resolution = window size in windowed mode.
|
|
(window-width int32)
|
|
(window-height int32)
|
|
;; reported window framebuffer size from OS
|
|
(framebuffer-width int32)
|
|
(framebuffer-height int32)
|
|
;; the region to draw in that framebuffer. rest is cleared to black.
|
|
(framebuffer-scissor-width int32)
|
|
(framebuffer-scissor-height int32)
|
|
(dpi-x float) ;; DPI width scale
|
|
(dpi-y float) ;; DPI height scale
|
|
(aspect-ratio-auto? symbol) ;; if on, aspect ratio is calculated automatically based on game display size.
|
|
(aspect-ratio float) ;; the desired aspect ratio. set auto to off and then this to 4/3 to force 4x3 aspect.
|
|
(aspect-ratio-scale float) ;; aspect ratio compared to 4x3
|
|
(aspect-ratio-reciprocal float) ;; reciprocal of that
|
|
(aspect-custom-x int)
|
|
(aspect-custom-y int)
|
|
(display-mode symbol) ;; display mode. can be windowed, fullscreen or borderless
|
|
(letterbox? symbol) ;; letterbox. #f = stretched
|
|
(vsync? symbol) ;; vsync.
|
|
(font-scale float) ;; font scaling.
|
|
(monitor int32) ;; index of which monitor to use when fullscreen or borderless
|
|
|
|
;; debug settings
|
|
(os symbol) ;; windows, linux, macos
|
|
(user symbol) ;; username. not system username, just debug thing.
|
|
(debug? symbol) ;; more debug stuff just in case.
|
|
|
|
;; device settings
|
|
(ignore-controller-win-unfocused? symbol)
|
|
(controller-hp-led? symbol)
|
|
(controller-eco-led? symbol)
|
|
(controller-heat-led? symbol)
|
|
(controller-led-brightness float)
|
|
(controller-led-min-brightness float)
|
|
(controller-led-max-brightness float)
|
|
(controller-led-color rgbaf :inline)
|
|
(stick-deadzone float) ;; analog stick deadzone. 0-1
|
|
(keyboard-enabled? symbol)
|
|
(mouse-enabled? symbol)
|
|
(mouse-camera? symbol)
|
|
(mouse-xsens float)
|
|
(mouse-ysens float)
|
|
(mouse-movement? symbol)
|
|
(auto-hide-cursor? symbol)
|
|
|
|
;; audio settings
|
|
(audio-latency-ms int16) ;; audio latency in milliseconds
|
|
(audio-pan-override float) ;; audio pan modifier
|
|
(audio-volume-override float) ;; audio volume modifier
|
|
(audio-channel-nb int16) ;; audio channel amount. will be 48 on PS2 mode.
|
|
|
|
;; graphics settings
|
|
(gfx-renderer pc-gfx-renderer) ;; the renderer to use
|
|
(gfx-resolution float) ;; for supersampling
|
|
(gfx-anisotropy float) ;; for anisotropy
|
|
(gfx-msaa int32) ;; for MSAA
|
|
|
|
;; ps2 settings
|
|
(ps2-read-speed? symbol) ;; emulate DVD loads
|
|
(ps2-parts? symbol) ;; if off, increase particle cap
|
|
(ps2-music? symbol) ;; if off, use .wav files stored somewhere
|
|
(ps2-se? symbol) ;; if off, use adjusted sound effects
|
|
(ps2-hints? symbol) ;; if off, enables extra game hints
|
|
|
|
;; lod settings
|
|
(ps2-lod-dist? symbol) ;; use original lod distances
|
|
(force-envmap? symbol) ;; dont use envmap fading (force max).
|
|
(shrub-dist-mod float) ;; shrub render distance modifier
|
|
(lod-dist-mod float) ;; non-shrub lod distance modifier
|
|
(lod-force-tfrag int8) ;; tfrag lod tier override. 0 = highest detail
|
|
(lod-force-tie int8) ;; tie lod tier override
|
|
(lod-force-ocean int8) ;; ocean lod tier override
|
|
(lod-force-actor int8) ;; merc lod tier override
|
|
|
|
;; misc settings
|
|
(ps2-actor-vis? symbol) ;; skips vis check for actor entity if disabled
|
|
(use-vis? symbol) ;; if off, don't use vis trees. this MUST be off for custom (non-cropping) aspect ratios.
|
|
(hinttitles? symbol) ;; if on, non-cutscene subtitles will show up
|
|
(subtitle-speaker? symbol) ;; #f (force off), #t (force on), auto (on for offscreen)
|
|
(first-camera-h-inverted? symbol) ;; first-person horizontal camera inverted
|
|
(first-camera-v-inverted? symbol) ;; first-person vertical camera inverted
|
|
(third-camera-h-inverted? symbol) ;; third-person horizontal camera inverted
|
|
(third-camera-v-inverted? symbol) ;; third-person vertical camera inverted
|
|
(music-fadeout? symbol) ;; music fadeout toggle.
|
|
(music-fadein? symbol) ;; music fadein toggle.
|
|
|
|
(territory int16)
|
|
|
|
(bingo pc-bingo-info :inline) ;; bingo integration. does nothing for now.
|
|
|
|
(discord-rpc? symbol) ;; enable discord rich presence integration
|
|
(speedrunner-mode? symbol) ;; enable speedrunner mode
|
|
|
|
(flava-hack int64)
|
|
|
|
;; TODO - save/restore original settings (language/sound/etc)
|
|
)
|
|
|
|
(:methods
|
|
(new (symbol type) _type_)
|
|
(initialize (_type_) _type_)
|
|
(update (_type_) none)
|
|
(update-from-os (_type_) none)
|
|
(update-to-os (_type_) none)
|
|
(update-discord-rpc (_type_) none)
|
|
(update-speedrun (_type_) none)
|
|
(update-video-hacks (_type_) object)
|
|
(reset (_type_ symbol) int)
|
|
(reset-audio (_type_ symbol) int)
|
|
(reset-input (_type_ symbol symbol) int)
|
|
(reset-gfx (_type_ symbol) int)
|
|
(reset-ps2 (_type_ symbol) int)
|
|
(reset-misc (_type_ symbol) int)
|
|
(reset-camera (_type_ symbol) int)
|
|
(reset-extra (_type_ symbol) int)
|
|
(print-debug-misc (_type_) object)
|
|
(draw (_type_ dma-buffer) object)
|
|
(draw-memory (_type_ dma-buffer) symbol)
|
|
(set-display-mode! (_type_ symbol symbol) int)
|
|
(set-size! (_type_ int int symbol) none)
|
|
(set-aspect! (_type_ int int) none)
|
|
(set-aspect-ratio! (_type_ float) none)
|
|
(set-frame-rate! (_type_ int symbol) int)
|
|
(set-monitor! (_type_ int) none)
|
|
(set-game-setting! (_type_ symbol symbol) object)
|
|
(get-game-setting (_type_ symbol) symbol)
|
|
(set-game-language! (_type_ language-enum) language-enum)
|
|
(get-game-language (_type_) language-enum)
|
|
(get-current-game-width (_type_) int)
|
|
(get-current-game-height (_type_) int)
|
|
(read-from-file (_type_ string) symbol)
|
|
(write-to-file (_type_ string) symbol)
|
|
(handle-input-settings (_type_ file-stream) object)
|
|
(handle-output-settings (_type_ file-stream) object)
|
|
(led-enabled? (_type_) symbol)
|
|
(update-led (_type_) symbol)
|
|
(update-cheats (_type_) int)
|
|
(update-music-log (_type_) int)
|
|
(add-to-music-log (_type_ symbol int) int)
|
|
(commit-to-file (_type_) none)
|
|
(load-settings (_type_) int)
|
|
(set-ignore-controller-in-bg! (_type_ symbol) none)
|
|
(set-enable-keyboard! (_type_ symbol) none)
|
|
(update-mouse-controls! (_type_) none)
|
|
)
|
|
)
|
|
|
|
(defconstant PC_TEMP_STRING_LEN 1024)
|
|
(define *pc-temp-string* (new 'global 'string PC_TEMP_STRING_LEN (the string #f)))
|
|
|
|
(define *pc-temp-string-1* (new 'global 'string 2048 (the string #f)))
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;;;; debug settings
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
(define *display-actor-bank* #f)
|
|
(define *display-pad-debug* #f)
|
|
(define *display-heap-status* #f)
|
|
(define *display-actor-counts* #f)
|
|
(define *display-text-box* #f)
|
|
(define *display-sha* *debug-segment*)
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;;;; resets
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
(defmethod reset pc-settings ((obj pc-settings) (call-handlers symbol))
|
|
"Reset everything back to default settings
|
|
|
|
If call-handlers = #t then events will be sent to the runtime kernel to update OS settings
|
|
such as window size, etc.
|
|
If you just want to set the settings and handle the fields yourself later, set call-handlers to #f
|
|
such as if you're setting the initial values right before reading the settings file that changes them."
|
|
|
|
(format 0 "pc settings reset~%")
|
|
|
|
(set! (-> obj version) (get-pckernel-version))
|
|
|
|
(set! (-> obj os) (pc-get-os))
|
|
(set! (-> obj user) #f)
|
|
(set! (-> obj debug?) #f)
|
|
(set! (-> obj font-scale) 1.0)
|
|
(set! (-> obj aspect-custom-x) 4)
|
|
(set! (-> obj aspect-custom-y) 3)
|
|
(set! (-> obj discord-rpc?) #t)
|
|
(set! (-> obj speedrunner-mode?) #f)
|
|
|
|
(reset-gfx obj call-handlers)
|
|
(reset-audio obj call-handlers)
|
|
(reset-input obj 'all call-handlers)
|
|
(reset-ps2 obj call-handlers)
|
|
(reset-misc obj call-handlers)
|
|
(reset-extra obj call-handlers)
|
|
|
|
0)
|
|
|
|
|
|
(defmethod reset-gfx pc-settings ((obj pc-settings) (call-handlers symbol))
|
|
"Set the default graphics settings"
|
|
|
|
;; temporarily "set" to windowed so we can change window size
|
|
;; we set our actual target display mode later.
|
|
(set! (-> obj display-mode) 'windowed)
|
|
(set-size! obj PC_BASE_WIDTH PC_BASE_HEIGHT #f)
|
|
|
|
(set-aspect! obj 4 3)
|
|
(set-frame-rate! obj 60 call-handlers)
|
|
|
|
(set! (-> obj use-vis?) #f)
|
|
(set! (-> obj aspect-ratio-auto?) #t)
|
|
(set! (-> obj vsync?) #t)
|
|
(set! (-> obj letterbox?) #t)
|
|
|
|
;; get screen size and set to borderless at screen res (if retail)
|
|
(pc-get-active-display-size (&-> obj width) (&-> obj height))
|
|
(if (not *debug-segment*)
|
|
(set-display-mode! obj 'borderless call-handlers))
|
|
(set! (-> obj gfx-msaa) PC_DEFAULT_MSAA) ;; default msaa
|
|
0)
|
|
|
|
(defmethod reset-audio pc-settings ((obj pc-settings) (call-handlers symbol))
|
|
"Set the default audio settings"
|
|
|
|
(set! (-> obj audio-latency-ms) 80)
|
|
(set! (-> obj audio-pan-override) 0.0)
|
|
(set! (-> obj audio-volume-override) 1.0)
|
|
(set! (-> obj audio-channel-nb) PS2_VOICE_AMOUNT)
|
|
|
|
(set! (-> obj music-fadeout?) #t)
|
|
(set! (-> obj music-fadein?) #t)
|
|
0)
|
|
|
|
(defmethod reset-input pc-settings ((obj pc-settings) (device symbol) (call-handlers symbol))
|
|
"Set the default input settings"
|
|
|
|
(when (or (= device 'all) (= device 'controller))
|
|
(set! (-> obj ignore-controller-win-unfocused?) #f)
|
|
(set! (-> obj controller-hp-led?) #t)
|
|
(set! (-> obj controller-eco-led?) #t)
|
|
(set! (-> obj controller-heat-led?) #t)
|
|
(set! (-> obj stick-deadzone) 0.3)
|
|
(set! (-> obj controller-led-brightness) 1.0)
|
|
(set! (-> obj controller-led-min-brightness) 0.25)
|
|
(set! (-> obj controller-led-max-brightness) 1.0)
|
|
)
|
|
|
|
(when (or (= device 'all) (= device 'input))
|
|
(set! (-> obj keyboard-enabled?) #t)
|
|
(set! (-> obj mouse-enabled?) #f)
|
|
(set! (-> obj auto-hide-cursor?) #t)
|
|
)
|
|
|
|
(when (or (= device 'all) (= device 'mouse))
|
|
(set! (-> obj mouse-camera?) #f)
|
|
(set! (-> obj mouse-xsens) -15.0)
|
|
(set! (-> obj mouse-ysens) 10.0)
|
|
(set! (-> obj mouse-movement?) #f)
|
|
)
|
|
0)
|
|
|
|
(defmethod reset-ps2 pc-settings ((obj pc-settings) (call-handlers symbol))
|
|
"Set the default ps2 settings"
|
|
|
|
(set! (-> obj ps2-read-speed?) #f)
|
|
(set! (-> obj ps2-parts?) #f)
|
|
(set! (-> obj ps2-music?) #t)
|
|
(set! (-> obj ps2-se?) #t)
|
|
(set! (-> obj ps2-hints?) #t)
|
|
|
|
(set! (-> obj ps2-lod-dist?) #f)
|
|
(set! (-> obj force-envmap?) #t)
|
|
(set! (-> obj shrub-dist-mod) 1.0)
|
|
(set! (-> obj lod-dist-mod) 1.0)
|
|
(set! (-> obj lod-force-tfrag) 0)
|
|
(set! (-> obj lod-force-tie) 0)
|
|
(set! (-> obj lod-force-ocean) 0)
|
|
(set! (-> obj lod-force-actor) 0)
|
|
0)
|
|
|
|
(defmethod reset-misc pc-settings ((obj pc-settings) (call-handlers symbol))
|
|
"Set the default misc settings"
|
|
|
|
(set! (-> obj ps2-actor-vis?) #t)
|
|
(set! (-> obj hinttitles?) #t)
|
|
(set! (-> obj subtitle-speaker?) 'auto)
|
|
(reset-camera obj call-handlers)
|
|
|
|
(set! (-> obj territory) *default-territory*)
|
|
0)
|
|
|
|
(defmethod reset-camera pc-settings ((obj pc-settings) (call-handlers symbol))
|
|
"Set the original game's camera controls"
|
|
|
|
(set! (-> obj first-camera-h-inverted?) #f) ;; first-person horizontal is NOT inverted in original game
|
|
(set! (-> obj first-camera-v-inverted?) #t) ;; first-person vertical IS inverted in original game
|
|
(set! (-> obj third-camera-h-inverted?) #t) ;; third person horizontal IS inverted in original game
|
|
(set! (-> obj third-camera-v-inverted?) #t) ;; third-person vertical IS inverted in original game
|
|
0)
|
|
|
|
(defmethod reset-extra pc-settings ((obj pc-settings) (call-handlers symbol))
|
|
"Set the default goodies settings"
|
|
|
|
0)
|
|
|
|
(defmacro with-pc (&rest body)
|
|
"encapsulates the code around PC-specific checks"
|
|
`(#when PC_PORT (when (and *pc-settings*)
|
|
,@body
|
|
))
|
|
)
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;;;; cheats
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
(seval (define *pc-cheat-map*
|
|
'((#\a (circle triangle))
|
|
(#\b (square x))
|
|
(#\c (circle))
|
|
(#\d (down))
|
|
(#\e (right right))
|
|
;; #\f
|
|
;; #\g
|
|
;; #\h
|
|
(#\i (up))
|
|
;; #\j
|
|
(#\k (circle))
|
|
(#\l (left))
|
|
(#\m (triangle))
|
|
(#\n (up up))
|
|
(#\o (square))
|
|
(#\p (square circle))
|
|
;; #\q
|
|
(#\r (right))
|
|
(#\s (down down))
|
|
(#\t (triangle))
|
|
(#\u (up))
|
|
(#\v (down))
|
|
(#\w (left left))
|
|
(#\x (x))
|
|
(#\y (triangle))
|
|
(#\z (x x))
|
|
))
|
|
)
|
|
|
|
(desfun pc-cheat-encode (word extra)
|
|
"turn a cheat word into input names."
|
|
(let ((out '())
|
|
(word-str (symbol->string word)))
|
|
|
|
(dotimes (i (string-length word-str))
|
|
(let ((char-to-inputs (assoc (string-ref word-str i) *pc-cheat-map*)))
|
|
(if (not char-to-inputs)
|
|
(ferror "bad input for pc cheat name: {}" (string-ref word-str i))
|
|
(dolist (button (cadr char-to-inputs))
|
|
(set! out (cons (car button) out))
|
|
))
|
|
))
|
|
|
|
(dolist (ex extra)
|
|
(set! out (cons (car ex) out)))
|
|
|
|
out)
|
|
)
|
|
|
|
(defmacro pc-check-cheat-code (cheat-var pad-idx input &key (extra ()) &rest body)
|
|
"execute body when a cheat code made up of sequential inputs has been inputted"
|
|
|
|
(let ((buttons (pc-cheat-encode input extra)))
|
|
`(when (nonzero? (cpad-pressed ,pad-idx)) ;; only check when some button has been pressed
|
|
(case ,cheat-var
|
|
,@(apply-i
|
|
(lambda (x i)
|
|
`((,i)
|
|
(if (cpad-pressed? ,pad-idx ,x)
|
|
,(if (< i (- (length buttons) 1))
|
|
`(1+! ,cheat-var)
|
|
|
|
`(begin
|
|
(cond
|
|
((-> *pc-settings* speedrunner-mode?)
|
|
(sound-play "cursor-options"))
|
|
(else
|
|
,@body)
|
|
)
|
|
(set! ,cheat-var 0)
|
|
)
|
|
)
|
|
|
|
(set! ,cheat-var 0)
|
|
)
|
|
)
|
|
)
|
|
buttons)
|
|
)
|
|
)
|
|
))
|
|
|
|
|
|
|
|
(defun-extern real-movie? symbol)
|
|
|
|
|