mirror of
https://github.com/open-goal/jak-project
synced 2026-07-01 20:20:35 -04:00
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:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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?))
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -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)))
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user