From 0b5c6350aeba9547dfaad0899a477447564926e6 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Mon, 1 Mar 2021 00:00:49 +0100 Subject: [PATCH] cellScreenshot: fix overlay scaling (#9867) * cellScreenshot: fix overlay scaling --- rpcs3/Emu/RSX/GL/GLPresent.cpp | 4 ++-- rpcs3/rpcs3qt/gs_frame.cpp | 35 ++++++++++++++++++++++++++----- rpcs3/rpcs3qt/gui_application.cpp | 4 +--- 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/GLPresent.cpp b/rpcs3/Emu/RSX/GL/GLPresent.cpp index c7579ef0ef..bfd526dcd2 100644 --- a/rpcs3/Emu/RSX/GL/GLPresent.cpp +++ b/rpcs3/Emu/RSX/GL/GLPresent.cpp @@ -2,7 +2,7 @@ #include "GLGSRender.h" #include "Emu/Cell/Modules/cellVideoOut.h" -LOG_CHANNEL(screenshot); +LOG_CHANNEL(screenshot_log, "SCREENSHOT"); gl::texture* GLGSRender::get_present_source(gl::present_surface_info* info, const rsx::avconf* avconfig) { @@ -227,7 +227,7 @@ void GLGSRender::flip(const rsx::display_flip_info_t& info) glGetTextureImageEXT(image_to_flip, GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, sshot_frame.data()); if (GLenum err; (err = glGetError()) != GL_NO_ERROR) - screenshot.error("Failed to capture image: 0x%x", err); + screenshot_log.error("Failed to capture image: 0x%x", err); else m_frame->take_screenshot(std::move(sshot_frame), buffer_width, buffer_height, false); } diff --git a/rpcs3/rpcs3qt/gs_frame.cpp b/rpcs3/rpcs3qt/gs_frame.cpp index 4925c65d0b..b32be473b2 100644 --- a/rpcs3/rpcs3qt/gs_frame.cpp +++ b/rpcs3/rpcs3qt/gs_frame.cpp @@ -9,6 +9,7 @@ #include "Emu/system_config.h" #include "Emu/IdManager.h" #include "Emu/Cell/Modules/cellScreenshot.h" +#include "Emu/RSX/rsx_utils.h" #include #include @@ -442,6 +443,8 @@ void gs_frame::take_screenshot(const std::vector sshot_data, const u32 sshot std::thread( [sshot_width, sshot_height, is_bgra](const std::vector sshot_data) { + screenshot_log.notice("Taking screenshot (%dx%d)", sshot_width, sshot_height); + std::string screen_path = fs::get_config_dir() + "screenshots/"; if (!fs::create_dir(screen_path) && fs::g_tls_error != fs::error::exist) @@ -571,12 +574,34 @@ void gs_frame::take_screenshot(const std::vector sshot_data, const u32 sshot if (!overlay_img.load(qstr(cell_sshot_overlay_path))) { screenshot_log.error("Failed to read cell screenshot overlay '%s' : %s", cell_sshot_overlay_path, fs::g_tls_error); + return; } - // TODO: the overlay and its offset need to be scaled based on image size, resolution scaling and video resolution - else if (manager.overlay_offset_x < static_cast(sshot_width) - && manager.overlay_offset_y < static_cast(sshot_height) - && manager.overlay_offset_x + overlay_img.width() > 0 - && manager.overlay_offset_y + overlay_img.height() > 0) + + // Games choose the overlay file and the offset based on the current video resolution. + // We need to scale the overlay if our resolution scaling causes the image to have a different size. + const auto avconf = g_fxo->get(); + + // TODO: handle wacky PS3 resolutions (without resolution scaling) + if (avconf->resolution_x != sshot_width || avconf->resolution_y != sshot_height) + { + const int scale = rsx::get_resolution_scale_percent(); + const int x = (scale * manager.overlay_offset_x) / 100; + const int y = (scale * manager.overlay_offset_y) / 100; + const int width = (scale * overlay_img.width()) / 100; + const int height = (scale * overlay_img.height()) / 100; + + screenshot_log.notice("Scaling overlay from %dx%d at offset (%d,%d) to %dx%d at offset (%d,%d)", + overlay_img.width(), overlay_img.height(), manager.overlay_offset_x, manager.overlay_offset_y, width, height, x, y); + + manager.overlay_offset_x = x; + manager.overlay_offset_y = y; + overlay_img = overlay_img.scaled(QSize(width, height), Qt::AspectRatioMode::IgnoreAspectRatio, Qt::TransformationMode::SmoothTransformation); + } + + if (manager.overlay_offset_x < static_cast(sshot_width) && + manager.overlay_offset_y < static_cast(sshot_height) && + manager.overlay_offset_x + overlay_img.width() > 0 && + manager.overlay_offset_y + overlay_img.height() > 0) { QImage screenshot_img(rows[0], sshot_width, sshot_height, QImage::Format_RGBA8888); QPainter painter(&screenshot_img); diff --git a/rpcs3/rpcs3qt/gui_application.cpp b/rpcs3/rpcs3qt/gui_application.cpp index 6267aef655..ce85dfb65c 100644 --- a/rpcs3/rpcs3qt/gui_application.cpp +++ b/rpcs3/rpcs3qt/gui_application.cpp @@ -248,9 +248,7 @@ std::unique_ptr gui_application::get_gs_frame() { extern const std::unordered_map, value_hash> g_video_out_resolution_map; - const auto size = g_video_out_resolution_map.at(g_cfg.video.resolution); - int w = size.first; - int h = size.second; + auto [w, h] = g_video_out_resolution_map.at(g_cfg.video.resolution); if (m_gui_settings->GetValue(gui::gs_resize).toBool()) {