opengl: better handling of the draw region setting (#2746)

This fixes screenshots and a bunch of weird scissoring bugs. Fixes #2630
and fixes #2631
This commit is contained in:
ManDude
2023-06-19 04:15:33 +01:00
committed by GitHub
parent a8a5f1e745
commit 572e63f4a9
16 changed files with 201 additions and 207 deletions
+97 -105
View File
@@ -701,6 +701,38 @@ void OpenGLRenderer::render(DmaFollower dma, const RenderOptions& settings) {
m_last_pmode_alp = settings.pmode_alp_register;
if (settings.save_screenshot) {
auto prof = m_profiler.root()->make_scoped_child("screenshot");
int read_buffer;
int x, y, w, h, fbo_id;
if (settings.internal_res_screenshot) {
Fbo* screenshot_src;
// can't screenshot from a multisampled buffer directly -
if (m_fbo_state.resources.resolve_buffer.valid) {
screenshot_src = &m_fbo_state.resources.resolve_buffer;
read_buffer = GL_COLOR_ATTACHMENT0;
} else {
screenshot_src = m_fbo_state.render_fbo;
read_buffer = GL_FRONT;
}
w = screenshot_src->width;
h = screenshot_src->height;
x = 0;
y = 0;
fbo_id = screenshot_src->fbo_id;
} else {
read_buffer = GL_FRONT;
w = settings.draw_region_width;
h = settings.draw_region_height;
x = m_render_state.draw_offset_x;
y = m_render_state.draw_offset_y;
fbo_id = 0; // window
}
finish_screenshot(settings.screenshot_path, w, h, x, y, fbo_id, read_buffer,
settings.quick_screenshot);
}
if (settings.draw_render_debug_window) {
auto prof = m_profiler.root()->make_scoped_child("render-window");
draw_renderer_selection_window();
@@ -751,22 +783,6 @@ void OpenGLRenderer::render(DmaFollower dma, const RenderOptions& settings) {
if (settings.draw_filters_window) {
m_filters_menu.draw_window();
}
if (settings.save_screenshot) {
Fbo* screenshot_src;
int read_buffer;
// can't screenshot from a multisampled buffer directly -
if (m_fbo_state.resources.resolve_buffer.valid) {
screenshot_src = &m_fbo_state.resources.resolve_buffer;
read_buffer = GL_COLOR_ATTACHMENT0;
} else {
screenshot_src = m_fbo_state.render_fbo;
read_buffer = GL_FRONT;
}
finish_screenshot(settings.screenshot_path, screenshot_src->width, screenshot_src->height, 0, 0,
screenshot_src->fbo_id, read_buffer, settings.quick_screenshot);
}
if (settings.gpu_sync) {
glFinish();
}
@@ -838,35 +854,24 @@ void OpenGLRenderer::setup_frame(const RenderOptions& settings) {
m_fbo_state.resources.render_buffer.clear();
m_fbo_state.resources.resolve_buffer.clear();
// first, see if we can just render straight to the display framebuffer.
// note: we always force a separate fbo on a screenshot so that it won't capture overlays.
// as an added bonus it also doesn't break the sprite distort buffer...
if (!settings.save_screenshot &&
window_fb.matches(settings.game_res_w, settings.game_res_h, settings.msaa_samples)) {
// it matches - no need for extra framebuffers.
lg::info("FBO Setup: rendering directly to window framebuffer");
m_fbo_state.render_fbo = &m_fbo_state.resources.window;
// NOTE: we will ALWAYS render the game to a separate framebuffer instead of directly to the
// window framebuffer.
// create a fbo to render to, with the desired settings
m_fbo_state.resources.render_buffer =
make_fbo(settings.game_res_w, settings.game_res_h, settings.msaa_samples, true);
m_fbo_state.render_fbo = &m_fbo_state.resources.render_buffer;
if (settings.msaa_samples != 1) {
lg::info("FBO Setup: using second temporary buffer: res: {}x{} {}x{}", window_fb.width,
window_fb.height, settings.game_res_w, settings.game_res_h);
// we'll need a temporary fbo to do the msaa resolve step
// non-multisampled, and doesn't need z/stencil
m_fbo_state.resources.resolve_buffer =
make_fbo(settings.game_res_w, settings.game_res_h, 1, false);
} else {
lg::info("FBO Setup: window didn't match: {} {}", window_fb.width, window_fb.height);
// create a fbo to render to, with the desired settings
m_fbo_state.resources.render_buffer =
make_fbo(settings.game_res_w, settings.game_res_h, settings.msaa_samples, true);
m_fbo_state.render_fbo = &m_fbo_state.resources.render_buffer;
bool msaa_matches = window_fb.multisample_count == settings.msaa_samples;
if (!msaa_matches) {
lg::info("FBO Setup: using second temporary buffer: res: {}x{} {}x{}", window_fb.width,
window_fb.height, settings.game_res_w, settings.game_res_h);
// we'll need a temporary fbo to do the msaa resolve step
// non-multisampled, and doesn't need z/stencil
m_fbo_state.resources.resolve_buffer =
make_fbo(settings.game_res_w, settings.game_res_h, 1, false);
} else {
lg::info("FBO Setup: not using second temporary buffer");
}
lg::info("FBO Setup: not using second temporary buffer");
}
}
@@ -874,15 +879,15 @@ void OpenGLRenderer::setup_frame(const RenderOptions& settings) {
fmt::format("Bad viewport size from game_res: {}x{}\n", settings.game_res_w,
settings.game_res_h));
if (!m_fbo_state.render_fbo->is_window) {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, m_fbo_state.resources.window.width, m_fbo_state.resources.window.height);
glClearColor(0.0, 0.0, 0.0, 0.0);
glClearDepth(0.0);
glDepthMask(GL_TRUE);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glDisable(GL_BLEND);
}
ASSERT_MSG(!m_fbo_state.render_fbo->is_window, "window fbo");
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, m_fbo_state.resources.window.width, m_fbo_state.resources.window.height);
glClearColor(0.0, 0.0, 0.0, 0.0);
glClearDepth(0.0);
glDepthMask(GL_TRUE);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glDisable(GL_BLEND);
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo_state.render_fbo->fbo_id);
glClearColor(0.0, 0.0, 0.0, 0.0);
@@ -914,20 +919,11 @@ void OpenGLRenderer::setup_frame(const RenderOptions& settings) {
m_render_state.draw_region_h = 240;
}
if (m_fbo_state.render_fbo->is_window) {
m_render_state.render_fb_x = m_render_state.draw_offset_x;
m_render_state.render_fb_y = m_render_state.draw_offset_y;
m_render_state.render_fb_w = m_render_state.draw_region_w;
m_render_state.render_fb_h = m_render_state.draw_region_h;
glViewport(m_render_state.draw_offset_x, m_render_state.draw_offset_y,
m_render_state.draw_region_w, m_render_state.draw_region_h);
} else {
m_render_state.render_fb_x = 0;
m_render_state.render_fb_y = 0;
m_render_state.render_fb_w = settings.game_res_w;
m_render_state.render_fb_h = settings.game_res_h;
glViewport(0, 0, settings.game_res_w, settings.game_res_h);
}
m_render_state.render_fb_x = 0;
m_render_state.render_fb_y = 0;
m_render_state.render_fb_w = settings.game_res_w;
m_render_state.render_fb_h = settings.game_res_h;
glViewport(0, 0, settings.game_res_w, settings.game_res_h);
}
void OpenGLRenderer::dispatch_buckets_jak1(DmaFollower dma,
@@ -1068,7 +1064,6 @@ void win_print_last_error(const std::string& msg) {
lg::error("[OpenGLRenderer] {} Win Err: {}", msg, lpMsgBuf);
}
HGLOBAL hClipboardData;
void copy_texture_to_clipboard(int width, int height, const std::vector<u32>& texture_data) {
std::vector<u32> data(texture_data);
@@ -1112,7 +1107,7 @@ void copy_texture_to_clipboard(int width, int height, const std::vector<u32>& te
}
// Create a global memory object to hold the image data
hClipboardData = GlobalAlloc(GMEM_MOVEABLE, sizeof(header) + image_size);
HGLOBAL hClipboardData = GlobalAlloc(GMEM_MOVEABLE, sizeof(header) + image_size);
if (hClipboardData == NULL) {
win_print_last_error("Failed to allocate memory for clipboard data.");
CloseClipboard();
@@ -1201,44 +1196,41 @@ void OpenGLRenderer::finish_screenshot(const std::string& output_name,
void OpenGLRenderer::do_pcrtc_effects(float alp,
SharedRenderState* render_state,
ScopedProfilerNode& prof) {
if (m_fbo_state.render_fbo->is_window) {
// nothing to do!
} else {
Fbo* window_blit_src = nullptr;
if (m_fbo_state.resources.resolve_buffer.valid) {
glBindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_state.render_fbo->fbo_id);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo_state.resources.resolve_buffer.fbo_id);
glBlitFramebuffer(0, // srcX0
0, // srcY0
m_fbo_state.render_fbo->width, // srcX1
m_fbo_state.render_fbo->height, // srcY1
0, // dstX0
0, // dstY0
m_fbo_state.resources.resolve_buffer.width, // dstX1
m_fbo_state.resources.resolve_buffer.height, // dstY1
GL_COLOR_BUFFER_BIT, // mask
GL_LINEAR // filter
);
window_blit_src = &m_fbo_state.resources.resolve_buffer;
} else {
window_blit_src = &m_fbo_state.resources.render_buffer;
}
glBindFramebuffer(GL_READ_FRAMEBUFFER, window_blit_src->fbo_id);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBlitFramebuffer(0, // srcX0
0, // srcY0
window_blit_src->width, // srcX1
window_blit_src->height, // srcY1
render_state->draw_offset_x, // dstX0
render_state->draw_offset_y, // dstY0
render_state->draw_offset_x + render_state->draw_region_w, // dstX1
render_state->draw_offset_y + render_state->draw_region_h, // dstY1
GL_COLOR_BUFFER_BIT, // mask
GL_LINEAR // filter
Fbo* window_blit_src = nullptr;
if (m_fbo_state.resources.resolve_buffer.valid) {
glBindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_state.render_fbo->fbo_id);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo_state.resources.resolve_buffer.fbo_id);
glBlitFramebuffer(0, // srcX0
0, // srcY0
m_fbo_state.render_fbo->width, // srcX1
m_fbo_state.render_fbo->height, // srcY1
0, // dstX0
0, // dstY0
m_fbo_state.resources.resolve_buffer.width, // dstX1
m_fbo_state.resources.resolve_buffer.height, // dstY1
GL_COLOR_BUFFER_BIT, // mask
GL_LINEAR // filter
);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
window_blit_src = &m_fbo_state.resources.resolve_buffer;
} else {
window_blit_src = &m_fbo_state.resources.render_buffer;
}
glBindFramebuffer(GL_READ_FRAMEBUFFER, window_blit_src->fbo_id);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBlitFramebuffer(0, // srcX0
0, // srcY0
window_blit_src->width, // srcX1
window_blit_src->height, // srcY1
render_state->draw_offset_x, // dstX0
render_state->draw_offset_y, // dstY0
render_state->draw_offset_x + render_state->draw_region_w, // dstX1
render_state->draw_offset_y + render_state->draw_region_h, // dstY1
GL_COLOR_BUFFER_BIT, // mask
GL_LINEAR // filter
);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
if (alp < 1) {
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
@@ -43,6 +43,7 @@ struct RenderOptions {
bool save_screenshot = false;
bool quick_screenshot = false;
bool internal_res_screenshot = false;
std::string screenshot_path;
float pmode_alp_register = 0.f;
+1 -2
View File
@@ -8,8 +8,7 @@ void Warp::draw_debug_window() {
}
void Warp::render(DmaFollower& dma, SharedRenderState* render_state, ScopedProfilerNode& prof) {
m_fb_copier.copy_now(render_state->render_fb_w, render_state->render_fb_h,
render_state->render_fb_x, render_state->render_fb_y,
m_fb_copier.copy_now(render_state->render_fb_w, render_state->render_fb_h, 0, 0,
render_state->render_fb);
render_state->texture_pool->move_existing_to_vram(m_warp_src_tex, m_tbp);
m_generic->render_in_mode(dma, render_state, prof, Generic2::Mode::WARP);
+10 -10
View File
@@ -197,16 +197,16 @@ void FramebufferCopier::copy_now(int render_fb_w,
glBindFramebuffer(GL_READ_FRAMEBUFFER, render_fb);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo);
glBlitFramebuffer(render_fb_x, // srcX0
render_fb_y, // srcY0
render_fb_x + render_fb_w, // srcX1
render_fb_y + render_fb_h, // srcY1
0, // dstX0
0, // dstY0
m_fbo_width, // dstX1
m_fbo_height, // dstY1
GL_COLOR_BUFFER_BIT, // mask
GL_NEAREST // filter
glBlitFramebuffer(0, // srcX0
0, // srcY0
render_fb_w, // srcX1
render_fb_h, // srcY1
0, // dstX0
0, // dstY0
m_fbo_width, // dstX1
m_fbo_height, // dstY1
GL_COLOR_BUFFER_BIT, // mask
GL_NEAREST // filter
);
glBindFramebuffer(GL_FRAMEBUFFER, render_fb);
@@ -188,9 +188,8 @@ GlowRenderer::GlowRenderer() {
GL_UNSIGNED_BYTE, nullptr);
glGenRenderbuffers(1, &m_ogl.probe_fbo_zbuf_rb);
glBindRenderbuffer(GL_RENDERBUFFER, m_ogl.probe_fbo_zbuf_rb);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, m_ogl.probe_fbo_w,
m_ogl.probe_fbo_h);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, m_ogl.probe_fbo_w, m_ogl.probe_fbo_h);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
m_ogl.probe_fbo_zbuf_rb);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
m_ogl.probe_fbo_rgba_tex, 0);
@@ -469,23 +468,23 @@ void GlowRenderer::blit_depth(SharedRenderState* render_state) {
glBindTexture(GL_TEXTURE_2D, 0);
glBindRenderbuffer(GL_RENDERBUFFER, m_ogl.probe_fbo_zbuf_rb);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, m_ogl.probe_fbo_w,
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, m_ogl.probe_fbo_w,
m_ogl.probe_fbo_h);
}
glBindFramebuffer(GL_READ_FRAMEBUFFER, render_state->render_fb);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_ogl.probe_fbo);
glBlitFramebuffer(render_state->render_fb_x, // srcX0
render_state->render_fb_y, // srcY0
render_state->render_fb_x + render_state->render_fb_w, // srcX1
render_state->render_fb_y + render_state->render_fb_h, // srcY1
0, // dstX0
0, // dstY0
m_ogl.probe_fbo_w, // dstX1
m_ogl.probe_fbo_h, // dstY1
GL_DEPTH_BUFFER_BIT, // mask
GL_NEAREST // filter
glBlitFramebuffer(0, // srcX0
0, // srcY0
render_state->render_fb_w, // srcX1
render_state->render_fb_h, // srcY1
0, // dstX0
0, // dstY0
m_ogl.probe_fbo_w, // dstX1
m_ogl.probe_fbo_h, // dstY1
GL_DEPTH_BUFFER_BIT, // mask
GL_NEAREST // filter
);
}
@@ -595,16 +595,16 @@ void Sprite3::distort_draw_common(SharedRenderState* render_state, ScopedProfile
glBindFramebuffer(GL_READ_FRAMEBUFFER, render_state->render_fb);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_distort_ogl.fbo);
glBlitFramebuffer(render_state->render_fb_x, // srcX0
render_state->render_fb_y, // srcY0
render_state->render_fb_x + render_state->render_fb_w, // srcX1
render_state->render_fb_y + render_state->render_fb_h, // srcY1
0, // dstX0
0, // dstY0
m_distort_ogl.fbo_width, // dstX1
m_distort_ogl.fbo_height, // dstY1
GL_COLOR_BUFFER_BIT, // mask
GL_NEAREST // filter
glBlitFramebuffer(0, // srcX0
0, // srcY0
render_state->render_fb_w, // srcX1
render_state->render_fb_h, // srcY1
0, // dstX0
0, // dstY0
m_distort_ogl.fbo_width, // dstX1
m_distort_ogl.fbo_height, // dstY1
GL_COLOR_BUFFER_BIT, // mask
GL_NEAREST // filter
);
glBindFramebuffer(GL_FRAMEBUFFER, render_state->render_fb);
+3 -3
View File
@@ -340,9 +340,8 @@ void render_game_frame(int game_width,
{
auto p = scoped_prof("wait-for-dma");
std::unique_lock<std::mutex> lock(g_gfx_data->dma_mutex);
// note: there's a timeout here. If the engine is messed up and not sending us frames,
// we still want to run the glfw loop.
got_chain = g_gfx_data->dma_cv.wait_for(lock, std::chrono::milliseconds(50),
// there's a timeout here, so imgui can still be responsive even if we don't render anything
got_chain = g_gfx_data->dma_cv.wait_for(lock, std::chrono::milliseconds(40),
[=] { return g_gfx_data->has_data_to_render; });
}
// render that chain.
@@ -364,6 +363,7 @@ void render_game_frame(int game_width,
options.draw_filters_window = g_gfx_data->debug_gui.should_draw_filters_menu();
options.save_screenshot = false;
options.quick_screenshot = false;
options.internal_res_screenshot = false;
options.gpu_sync = g_gfx_data->debug_gui.should_gl_finish();
if (take_screenshot) {
+2 -2
View File
@@ -69,8 +69,8 @@
;; crops excess aspect ratio at the top and bottom
;(set! (-> math-cam y-ratio) (* (1/ (-> *pc-settings* aspect-ratio)) (-> math-cam x-ratio)))
)
((-> *pc-settings* movie?)
;; this mess is just so that we can force the original 16x9 cropping during cutscenes.
((real-movie?)
;; force the original 16x9 cropping during cutscenes.
(if (<= (-> *pc-settings* aspect-ratio) ASPECT_16X9)
(set! (-> math-cam y-ratio) (* (1/ (-> *pc-settings* aspect-ratio)) (-> math-cam x-ratio)))
(begin
+1 -1
View File
@@ -54,7 +54,7 @@
(set! (-> *autosplit-info-jak1* citadel-num-scout-flies) (buzzer-count *game-info* (-> *level-task-data* (level-task-data-index citadel) task-info (-> *level-task-data* (level-task-data-index citadel) buzzer-task-index) task-id)))
;; loading/cutscene related flags
(set! (-> *autosplit-info-jak1* in-cutscene?) (-> *pc-settings* movie?))
(set! (-> *autosplit-info-jak1* in-cutscene?) (real-movie?))
;; need resolution flags
(autosplit-flag-task-complete! res-training-gimmie training-gimmie)
+36 -35
View File
@@ -68,7 +68,7 @@
;; if windowed mode, set the size properly
(when (= (-> obj display-mode) 'windowed)
;; TODO - this means the user can never have a window smaller than MIN_WIDTH/HEIGHT
(pc-set-window-size (max PC_MIN_WIDTH (-> obj win-width)) (max PC_MIN_HEIGHT (-> obj win-height))))))
(pc-set-window-size (max PC_MIN_WIDTH (-> obj window-width)) (max PC_MIN_HEIGHT (-> obj window-height))))))
0)
(defmethod set-size! pc-settings ((obj pc-settings) (width int) (height int) (call-handlers symbol))
@@ -76,10 +76,10 @@
(format 0 "Setting ~A size to ~D x ~D~%" (-> obj display-mode) width height)
(cond
((= 'windowed (-> obj display-mode))
(set! (-> obj win-width) width)
(set! (-> obj win-height) height)
(set! (-> obj window-width) width)
(set! (-> obj window-height) height)
(if call-handlers
(pc-set-window-size (max PC_MIN_WIDTH (-> obj win-width)) (max PC_MIN_HEIGHT (-> obj win-height))))
(pc-set-window-size (max PC_MIN_WIDTH (-> obj window-width)) (max PC_MIN_HEIGHT (-> obj window-height))))
)
(else
(set! (-> obj width) width)
@@ -151,7 +151,7 @@
(defmethod update-from-os pc-settings ((obj pc-settings))
"Update settings from the C kernel to GOAL."
(pc-get-window-size (&-> obj real-width) (&-> obj real-height))
(pc-get-window-size (&-> obj framebuffer-width) (&-> obj framebuffer-height))
(pc-get-window-scale (&-> obj dpi-x) (&-> obj dpi-y))
(when (-> obj use-vis?)
@@ -161,29 +161,29 @@
)
)
(unless (or (zero? (-> obj real-width)) (zero? (-> obj real-height)))
(let ((win-aspect (/ (the float (-> obj real-width)) (the float (-> obj real-height)))))
(unless (or (zero? (-> obj framebuffer-width)) (zero? (-> obj framebuffer-height)))
(let ((win-aspect (/ (the float (-> obj framebuffer-width)) (the float (-> obj framebuffer-height)))))
(cond
((and (not (-> obj use-vis?)) (-> obj aspect-ratio-auto?))
;; the window determines the resolution
(set-aspect-ratio! obj win-aspect)
(set! (-> obj lbox-width) (-> obj real-width))
(set! (-> obj lbox-height) (-> obj real-height))
(set! (-> obj framebuffer-scissor-width) (-> obj framebuffer-width))
(set! (-> obj framebuffer-scissor-height) (-> obj framebuffer-height))
)
((> win-aspect (-> obj aspect-ratio))
;; too wide
(set! (-> obj lbox-width) (the int (* (the float (-> obj real-height)) (-> obj aspect-ratio))))
(set! (-> obj lbox-height) (-> obj real-height))
(set! (-> obj framebuffer-scissor-width) (the int (* (the float (-> obj framebuffer-height)) (-> obj aspect-ratio))))
(set! (-> obj framebuffer-scissor-height) (-> obj framebuffer-height))
)
((< win-aspect (-> obj aspect-ratio))
;; too tall
(set! (-> obj lbox-width) (-> obj real-width))
(set! (-> obj lbox-height) (the int (/ (the float (-> obj real-width)) (-> obj aspect-ratio))))
(set! (-> obj framebuffer-scissor-width) (-> obj framebuffer-width))
(set! (-> obj framebuffer-scissor-height) (the int (/ (the float (-> obj framebuffer-width)) (-> obj aspect-ratio))))
)
(else
;; just right
(set! (-> obj lbox-width) (-> obj real-width))
(set! (-> obj lbox-height) (-> obj real-height))
(set! (-> obj framebuffer-scissor-width) (-> obj framebuffer-width))
(set! (-> obj framebuffer-scissor-height) (-> obj framebuffer-height))
)
)
))
@@ -197,10 +197,10 @@
;; TODO - move the below out of this function that runs every frame
(cond
((-> obj letterbox?)
(pc-set-letterbox (-> obj lbox-width) (-> obj lbox-height))
(pc-set-letterbox (-> obj framebuffer-scissor-width) (-> obj framebuffer-scissor-height))
)
(else
(pc-set-letterbox (-> obj real-width) (-> obj real-height))
(pc-set-letterbox (-> obj framebuffer-width) (-> obj framebuffer-height))
)
)
@@ -213,7 +213,7 @@
;; do game resolution
(if (= (-> obj display-mode) 'windowed)
(pc-set-game-resolution (-> obj real-width) (-> obj real-height))
(pc-set-game-resolution (-> obj framebuffer-scissor-width) (-> obj framebuffer-scissor-height))
(pc-set-game-resolution (-> obj width) (-> obj height)))
;; set msaa sample rate. if invalid, just reset to 2.
@@ -281,6 +281,10 @@
(+ (* (shr (logand bcd #xf0) 4) 10) (logand bcd #x0f))
)
(defun real-movie? ()
"are we in an actual cutscene and should letterbox the view?"
(and (nonzero? movie?) (movie?)))
(defmethod update pc-settings ((obj pc-settings))
"Update settings to/from PC kernel. Call this at the start of every frame.
This will update things like the aspect-ratio, which will be used for graphics code later."
@@ -288,8 +292,6 @@
(update-from-os obj)
(update-to-os obj)
(set! (-> obj movie?) (movie?))
(update-discord-rpc obj)
;; update auto-splitter info
@@ -350,8 +352,8 @@
(cond
((= (-> obj display-mode) 'windowed)
(if (-> obj letterbox?)
(-> obj lbox-width)
(-> obj real-width)))
(-> obj framebuffer-scissor-width)
(-> obj framebuffer-width)))
(else
(-> obj width))
)
@@ -362,8 +364,8 @@
(cond
((= (-> obj display-mode) 'windowed)
(if (-> obj letterbox?)
(-> obj lbox-height)
(-> obj real-height)))
(-> obj framebuffer-scissor-height)
(-> obj framebuffer-height)))
(else
(-> obj height))
)
@@ -375,16 +377,15 @@
"debug draw some things on-screen"
(when (-> obj debug?)
(format *stdcon* "fullscreen resolution: ~D x ~D~%" (-> obj width) (-> obj height))
(format *stdcon* "window size: ~D x ~D @ ~,,1f x ~,,1f~%" (-> obj window-width) (-> obj window-height) (-> obj dpi-x) (-> obj dpi-y))
(format *stdcon* "fb size: ~D x ~D (scissor: ~D x ~D)~%" (-> obj framebuffer-width) (-> obj framebuffer-height) (-> obj framebuffer-scissor-width) (-> obj framebuffer-scissor-height))
(format *stdcon* "aspect: ~,,3f/~,,3f auto? ~A vis? ~A lbox? ~A~%" (-> obj aspect-ratio) (/ (the float (-> obj framebuffer-width)) (the float (-> obj framebuffer-height))) (-> obj aspect-ratio-auto?) (-> obj use-vis?) (-> obj letterbox?))
(format *stdcon* "display-mode: ~A vsync? ~A~%" (-> obj display-mode) (-> obj vsync?))
(clear *pc-temp-string*)
(format *pc-temp-string* "game resolution: ~D x ~D~%" (-> obj width) (-> obj height))
(format *pc-temp-string* "window size: ~D x ~D (~,,1f x ~,,1f)~%" (-> obj real-width) (-> obj real-height) (-> obj dpi-x) (-> obj dpi-y))
(format *pc-temp-string* "target aspect: ~,,3f/~,,3f A: ~A/~A L: ~A~%" (-> obj aspect-ratio) (/ (the float (-> obj real-width)) (the float (-> obj real-height))) (-> obj aspect-ratio-auto?) (-> obj use-vis?) (-> obj letterbox?))
(format *pc-temp-string* "display-type: ~A ~A~%" (-> obj display-mode) (-> obj vsync?))
(draw-string-xy *pc-temp-string* buf 0 (- 224 (* 8 4)) (font-color default) (font-flags shadow kerning))
)
(when *display-actor-bank*
(draw-string-xy (string-format "Actor Bank: ~,,1m/~,,1m (~D)" (-> *ACTOR-bank* pause-dist) (-> *ACTOR-bank* birth-dist) (-> *ACTOR-bank* birth-max)) buf 512 (- 224 8) (font-color default) (font-flags shadow kerning right))
(draw-string-xy (string-format "Actor Bank: ~,,1m/~,,1m (~D)" (-> *ACTOR-bank* pause-dist) (-> *ACTOR-bank* birth-dist) (-> *ACTOR-bank* birth-max)) buf 512 0 (font-color default) (font-flags shadow kerning right))
)
)
@@ -619,7 +620,7 @@
;; restore the windowed mode resolution properly
(when (= (-> obj display-mode) 'windowed)
(pc-set-window-size (max PC_MIN_WIDTH (-> obj win-width)) (max PC_MIN_HEIGHT (-> obj win-height))))
(pc-set-window-size (max PC_MIN_WIDTH (-> obj window-width)) (max PC_MIN_HEIGHT (-> obj window-height))))
#t
)
@@ -630,8 +631,8 @@
(case-str *pc-temp-string*
(("fps") (set-frame-rate! obj (file-stream-read-int file) #t))
(("window-size")
(set! (-> obj win-width) (file-stream-read-int file))
(set! (-> obj win-height) (file-stream-read-int file))
(set! (-> obj window-width) (file-stream-read-int file))
(set! (-> obj window-height) (file-stream-read-int file))
)
(("game-size")
(set! (-> obj width) (file-stream-read-int file))
@@ -731,7 +732,7 @@
(-> obj aspect-custom-x) (-> obj aspect-custom-y)
(-> obj aspect-ratio-auto?))
(format file " (display-mode ~A)~%" (-> obj display-mode))
(format file " (window-size ~D ~D)~%" (-> obj win-width) (-> obj win-height))
(format file " (window-size ~D ~D)~%" (-> obj window-width) (-> obj window-height))
(format file " (game-size ~D ~D)~%" (-> obj width) (-> obj height))
(format file " (monitor ~D)~%" (-> obj monitor))
(format file " (letterbox ~A)~%" (-> obj letterbox?))
+16 -10
View File
@@ -139,14 +139,14 @@
(width int32)
(height int32)
;; window size. resolution = window size in windowed mode.
(win-width int32)
(win-height int32)
;; real window size from OS
(real-width int32)
(real-height int32)
;; letterboxed window size
(lbox-width int32)
(lbox-height int32)
(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.
@@ -165,7 +165,6 @@
(os symbol) ;; windows, linux, macos
(user symbol) ;; username. not system username, just debug thing.
(debug? symbol) ;; more debug stuff just in case.
(movie? symbol)
;; device settings
(ignore-controller-win-unfocused? symbol)
@@ -325,7 +324,6 @@
(set! (-> obj os) (pc-get-os))
(set! (-> obj user) #f)
(set! (-> obj debug?) #f)
(set! (-> obj movie?) #f)
(set! (-> obj font-scale) 1.0)
(set! (-> obj aspect-custom-x) 4)
(set! (-> obj aspect-custom-y) 3)
@@ -455,6 +453,11 @@
))
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; cheats
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(seval (define *pc-cheat-map*
'((#\a (circle triangle))
(#\b (square x))
@@ -540,3 +543,6 @@
(defun-extern real-movie? symbol)
+1 -1
View File
@@ -245,7 +245,7 @@
(set! (-> info deaths) (&-> *game-info* total-deaths))
(set! (-> info status) "Playing Jak and Daxter: The Precursor Legacy™")
(set! (-> info level) (symbol->string (-> (level-get-target-inside *level*) name))) ;; grab the name of level we're in
(set! (-> info cutscene?) (-> obj movie?))
(set! (-> info cutscene?) (real-movie?))
(set! (-> info ogreboss?) (aif (process-by-ename "ogreboss-1") (case (-> it next-state name) (
('ogreboss-die
'ogreboss-idle
+1 -1
View File
@@ -1411,7 +1411,7 @@
(local-vars (a0-96 int) (a0-98 int))
(with-pp
(when *slow-frame-rate*
(dotimes (v1-2 12800000)
(dotimes (v1-2 128000000) ;; was 12800000
(nop!)
(nop!)
(nop!)
@@ -2218,7 +2218,7 @@
;; PC port note : added this so we can see it during the code-hook
:post (behavior ()
(if *debug-segment*
(format *stdcon* "task-manager: alive in code-hook task ~A~%" (game-task->string (-> self node-info task)))
(format *stdcon* "task-manager: alive in code task ~A~%" (game-task->string (-> self node-info task)))
)
)
)
+1 -1
View File
@@ -76,7 +76,7 @@ renderers that want a single matrix.
;; crops excess aspect ratio at the top and bottom
;(set! (-> arg0 y-ratio) (* (1/ (-> *pc-settings* aspect-ratio)) (-> arg0 x-ratio)))
)
((-> *pc-settings* movie?)
((real-movie?)
;; this mess is just so that we can force the original 16x9 cropping during cutscenes.
(if (<= (-> *pc-settings* aspect-ratio) ASPECT_16X9)
(set! (-> arg0 y-ratio) (* (1/ (-> *pc-settings* aspect-ratio)) (-> arg0 x-ratio)))
+7 -11
View File
@@ -52,13 +52,9 @@
)
(defmethod update pc-settings-jak2 ((obj pc-settings-jak2))
"handle the text parsing input for the 'settings' group"
((method-of-type pc-settings update) obj)
(set! (-> obj movie?) (and (!= #f *scene-player*) (movie?)))
(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"
@@ -79,7 +75,7 @@
(else
(set! (-> info level) (aif (-> *load-state* vis-nick) (symbol->string it) "unknown")))
)
(set! (-> info cutscene?) (-> *pc-settings* movie?))
(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))
@@ -91,7 +87,7 @@
(defmethod update-speedrun pc-settings-jak2 ((obj pc-settings-jak2))
"update speedrun module"
(when (-> *pc-settings* speedrunner-mode?)
(speedrun-mode-update))
(speedrun-mode-update))
(none))
(defmethod update-video-hacks pc-settings-jak2 ((obj pc-settings-jak2))
@@ -161,9 +157,9 @@
(bucket-id debug-no-zbuf1))
(draw-string-xy *pc-settings-built-sha*
buf
0 10
512 14
(font-color flat-yellow)
(font-flags shadow kerning))))
(font-flags right shadow kerning))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; process pools