jak2: add frame rate option to graphics menu (#2962)

This PR adds a frame rate option to the graphics menu for some of the
most common refresh rates.

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

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



https://github.com/open-goal/jak-project/assets/6624576/ad4db24f-cd27-4237-a155-0db7008160f3
This commit is contained in:
Hat Kid 2023-09-09 16:59:00 +02:00 committed by GitHub
parent 0a7caf1d10
commit 572efbf9cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 141 additions and 9 deletions

View File

@ -7362,6 +7362,7 @@
(progress-lod-low #x128b)
(progress-lod-high #x128c)
(progress-credits #x128d)
(progress-frame-rate #x128e)
)
;; ---text-id-h:text-id

View File

@ -120,5 +120,6 @@
"128a": "Default",
"128b": "Low",
"128c": "High",
"128d": "Credits"
"128d": "Credits",
"128e": "Frame Rate (Experimental)"
}

View File

@ -550,6 +550,7 @@ void GlowRenderer::blit_depth(SharedRenderState* render_state) {
void GlowRenderer::draw_debug_window() {
ImGui::Checkbox("Show Probes", &m_debug.show_probes);
ImGui::Checkbox("Show Copy", &m_debug.show_probe_copies);
ImGui::Checkbox("Enable Glow Boost", &m_debug.enable_glow_boost);
ImGui::SliderFloat("Boost Glow", &m_debug.glow_boost, 0, 10);
ImGui::Text("Count: %d", m_debug.num_sprites);
}
@ -808,6 +809,10 @@ void GlowRenderer::draw_sprites(SharedRenderState* render_state, ScopedProfilerN
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
render_state->shaders[ShaderId::GLOW_DRAW].activate();
if (!m_debug.enable_glow_boost && Gfx::g_global_settings.target_fps > 60.0f) {
// on higher framerates, more glow sprites are drawn, so we scale the boost a bit
m_debug.glow_boost = 60.0f / Gfx::g_global_settings.target_fps;
}
glUniform1f(glGetUniformLocation(render_state->shaders[ShaderId::GLOW_DRAW].id(), "glow_boost"),
m_debug.glow_boost);

View File

@ -1,5 +1,6 @@
#pragma once
#include "game/graphics/gfx.h"
#include "game/graphics/opengl_renderer/sprite/sprite_common.h"
class GlowRenderer {
@ -27,6 +28,7 @@ class GlowRenderer {
struct {
bool show_probes = false;
bool show_probe_copies = false;
bool enable_glow_boost = false;
int num_sprites = 0;
float glow_boost = 1.f;
} m_debug;

View File

@ -34,6 +34,10 @@
(('pal)
(set! (-> obj time-factor) 6.0)
)
;; pc port note: added custom video mode for high fps
(('custom)
(set! (-> obj time-factor) (/ 300.0 (-> *pc-settings* target-fps)))
)
(else
(set! (-> obj time-factor) 5.0)
)

View File

@ -33,6 +33,10 @@ Will also set a bunch of common settings related to profiling and the camera to
(set! *video-mode* 1)
(sound-set-fps 50)
)
;; pc port note: added custom case
(('custom)
(sound-set-fps (-> *pc-settings* target-fps))
)
)
(set-time-ratios *display* (-> *display* dog-ratio))
(set! (-> *video-params* reset-video-mode) #t)

View File

@ -188,7 +188,8 @@
(if (not (-> self control danger-mode))
(target-danger-set! 'board-spin #f)
)
(+! (-> self board trotyv) (* (-> self board spin-control) (-> self clock seconds-per-frame)))
;; pc port note: patched for high fps
(+! (-> self board trotyv) (* (-> self board spin-control) (seconds-per-frame)))
(when (and (< (fabs f28-0) 1092266.6)
(< (fabs (-> self board spin-control)) 1092266.6)
(< (* 0.9 (fabs (-> self board flip-control))) (fabs f30-0))

View File

@ -919,7 +919,8 @@
)
(until (ja-done? 0)
(suspend)
(ja :num! (seek! max (/ (* (fmax 20480.0 (-> self control ctrl-xz-vel)) (-> self clock seconds-per-frame))
;; pc port note: patched for high fps
(ja :num! (seek! max (/ (* (fmax 20480.0 (-> self control ctrl-xz-vel)) (seconds-per-frame))
(/ (-> *TARGET-bank* run-up-cycle-dist) (-> *TARGET-bank* run-cycle-length))
)
)

View File

@ -690,6 +690,7 @@
(progress-lod-low #x128b)
(progress-lod-high #x128c)
(progress-credits #x128d)
(progress-frame-rate #x128e)
)
;; ---text-id

View File

@ -763,3 +763,11 @@
(defmacro current-time ()
`(-> PP clock frame-counter)
)
(defmacro seconds-per-frame ()
"Macro for assuming a 16.6 ms frame time at higher frame rates."
`(if (= (get-video-mode) 'custom)
0.016666668
(-> PP clock seconds-per-frame)
)
)

View File

@ -882,11 +882,16 @@
(set! (-> *pc-settings* lod-force-actor) 3)
))
)
;; (menu "Framerate"
;; (flag "60" 60 dm-frame-rate-pick-func)
;; (flag "100" 100 dm-frame-rate-pick-func)
;; (flag "150" 150 dm-frame-rate-pick-func)
;; )
(menu "Framerate"
(flag "30" 30 dm-frame-rate-pick-func)
(flag "50" 50 dm-frame-rate-pick-func)
(flag "60" 60 dm-frame-rate-pick-func)
(flag "75" 75 dm-frame-rate-pick-func)
(flag "120" 120 dm-frame-rate-pick-func)
(flag "144" 144 dm-frame-rate-pick-func)
(flag "165" 165 dm-frame-rate-pick-func)
(flag "240" 240 dm-frame-rate-pick-func)
)
(menu "MSAA"
(flag "Off" 1 dm-msaa-pick-func)
(flag "x2" 2 dm-msaa-pick-func)

View File

@ -18,6 +18,7 @@
(when category
(set! (-> *speedrun-info* category) category))
;; TODO - ensure any required settings are enabled
(set-frame-rate! *pc-settings* 60 #t)
(none)
)

View File

@ -2084,6 +2084,49 @@
(none)
)
(defmethod draw-option menu-frame-rate-option ((obj menu-frame-rate-option) (arg0 progress) (arg1 font-context) (arg2 int) (arg3 symbol))
(let ((alpha (* 2.0 (- 0.5 (-> arg0 menu-transition)))))
(set-scale! arg1 0.65)
(max! alpha 0.0)
(set! (-> arg1 alpha) alpha)
(set-flags! arg1 (font-flags kerning middle large))
(+! (-> arg1 origin y) 8.0)
(cond
(arg3
(set-color! arg1 (font-color progress-force-selected))
(draw-highlight (the int (+ -1.0 (-> arg1 origin y))) 42 alpha)
(print-game-text (lookup-text! *common-text* (-> obj name) #f) arg1 #f 44 (bucket-id progress))
(+! (-> arg1 origin y) 22.0)
(set-color! arg1 (font-color progress))
(set-scale! arg1 0.5)
(set-color! arg1 (font-color progress))
(+! (-> arg1 origin x) -25.0)
(print-game-text (string-format "~33L~C" 163) arg1 #f 44 (bucket-id progress))
(+! (-> arg1 origin x) 50.0)
(print-game-text (string-format "~33L~C" 161) arg1 #f 44 (bucket-id progress))
(+! (-> arg1 origin x) -25.0)
(set-color! arg1 (progress-selected 0))
(set-flags! arg1 (font-flags kerning middle large))
(print-game-text (string-format "~D" (-> *frame-rate-options* (-> *progress-state-pc* frame-rate-choice-index))) arg1 #f 44 (bucket-id progress))
)
(else
(if (= (-> arg0 option-index) arg2)
(draw-highlight (the int (-> arg1 origin y)) 21 alpha)
)
(set-scale! arg1 0.65)
(print-game-text (lookup-text! *common-text* (-> obj name) #f) arg1 #f 44 (bucket-id progress))
(set-scale! arg1 0.5)
(set-color! arg1 (font-color progress))
(+! (-> arg1 origin y) 22.0)
(set-flags! arg1 (font-flags kerning middle large))
(print-game-text (string-format "~D" (-> *frame-rate-options* (-> *progress-state-pc* frame-rate-choice-index))) arg1 #f 44 (bucket-id progress))
)
)
(when-not-drawn-decoration
(draw-decoration obj arg1 alpha (text-id progress-root-graphic-options) #f 0.95))
)
(none)
)

View File

@ -35,6 +35,9 @@
()
)
(deftype menu-frame-rate-option (menu-option)
()
)
(deftype menu-music-player-option (menu-option)
((last-move time-frame)

View File

@ -18,6 +18,8 @@
(aspect-ratio-choice-index int8)
(aspect-ratio-ratio-index int8)
(frame-rate-choice-index int8)
(music-player-track music-player-track-info)
(music-player-flava int8)
(music-player-selected symbol)
@ -60,6 +62,21 @@
(('borderless) (set! (-> *progress-state-pc* display-mode-choice-index) 2))
))
(defun set-progress-frame-rate-index ()
"Set the frame rate option index accordingly."
(case (-> *pc-settings* target-fps)
((30) (set! (-> *progress-state-pc* frame-rate-choice-index) 0))
((50) (set! (-> *progress-state-pc* frame-rate-choice-index) 1))
((60) (set! (-> *progress-state-pc* frame-rate-choice-index) 2))
((75) (set! (-> *progress-state-pc* frame-rate-choice-index) 3))
((120) (set! (-> *progress-state-pc* frame-rate-choice-index) 4))
((144) (set! (-> *progress-state-pc* frame-rate-choice-index) 5))
((165) (set! (-> *progress-state-pc* frame-rate-choice-index) 6))
((240) (set! (-> *progress-state-pc* frame-rate-choice-index) 7))
;; default to 60 fps
(else (set! (-> *progress-state-pc* frame-rate-choice-index) 2))
)
)
(defmethod init-defaults progress ((obj progress))
@ -136,7 +153,8 @@
;; set aspect ratio options
(set-progress-aspect-ratio-pc-index)
(set-progress-display-mode-index)
(set! (-> (the menu-on-off-option (-> *graphic-options-pc* options 2)) value-to-modify) (&-> *pc-settings* vsync?))
(set-progress-frame-rate-index)
(set! (-> (the menu-on-off-option (-> *graphic-options-pc* options 3)) value-to-modify) (&-> *pc-settings* vsync?))
(set! (-> *progress-state-pc* music-player-track) #f)
)
@ -505,6 +523,38 @@
0
)
(defmethod respond-progress menu-frame-rate-option ((obj menu-frame-rate-option) (arg0 progress) (arg1 symbol))
"Handle progress menu navigation logic."
(when arg1
(cond
((cpad-pressed? 0 triangle)
(set-progress-frame-rate-index))
((cpad-pressed? 0 confirm)
(sound-play "generic-beep")
(set-frame-rate! *pc-settings* (-> *frame-rate-options* (-> *progress-state-pc* frame-rate-choice-index)) #t)
)
(else
(let ((sound-beep? #f))
(when (cpad-pressed? 0 left l-analog-left)
(true! sound-beep?)
(min-max-wrap-around+! (-> *progress-state-pc* frame-rate-choice-index) -1 0 (1- (-> *frame-rate-options* length)))
(set-frame-rate! *pc-settings* (-> *frame-rate-options* (-> *progress-state-pc* frame-rate-choice-index)) #t)
)
(when (cpad-pressed? 0 right l-analog-right)
(true! sound-beep?)
(min-max-wrap-around+! (-> *progress-state-pc* frame-rate-choice-index) 1 0 (1- (-> *frame-rate-options* length)))
(set-frame-rate! *pc-settings* (-> *frame-rate-options* (-> *progress-state-pc* frame-rate-choice-index)) #t)
)
(if sound-beep?
(sound-play "generic-beep")
)
)
)
)
)
0
)
(defbehavior play-music-player progress ((info music-player-track-info) (flava int))
"play a music track using music player track info."

View File

@ -20,11 +20,13 @@
:options (new 'static 'boxed-array :type menu-option
(new 'static 'menu-display-mode-option :name (text-id progress-display-mode))
(new 'static 'menu-aspect-ratio-pc-option :name (text-id progress-aspect-ratio))
(new 'static 'menu-frame-rate-option :name (text-id progress-frame-rate))
(new 'static 'menu-on-off-vsync-option :name (text-id progress-vsync))
)
)
)
(define *frame-rate-options* (new 'static 'boxed-array :type int16 30 50 60 75 120 144 165 240))
(define *aspect-ratio-custom-options*
(new 'static 'menu-option-list