From 4db04303215dd088def7a86ab4b542ffba633624 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Tue, 1 Sep 2026 23:53:29 +0200 Subject: [PATCH 1/4] big picture: don't jump to the last item when pressing down in the last row --- .../BigPicture/overlay_big_picture_game_grid.cpp | 16 +++++++++++++--- .../BigPicture/overlay_big_picture_game_grid.h | 3 +++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/rpcs3/Emu/RSX/Overlays/BigPicture/overlay_big_picture_game_grid.cpp b/rpcs3/Emu/RSX/Overlays/BigPicture/overlay_big_picture_game_grid.cpp index f95fcf1392c5..5432478ad1e9 100644 --- a/rpcs3/Emu/RSX/Overlays/BigPicture/overlay_big_picture_game_grid.cpp +++ b/rpcs3/Emu/RSX/Overlays/BigPicture/overlay_big_picture_game_grid.cpp @@ -267,6 +267,16 @@ namespace rsx refresh(); } + u16 big_picture_game_grid::column(s32 tile_index) const + { + return (tile_index < 0) ? 0 : (tile_index % m_columns); + } + + u16 big_picture_game_grid::row(s32 tile_index) const + { + return (tile_index < 0) ? 0 : (tile_index / m_columns); + } + page_navigation big_picture_game_grid::handle_button_press(pad_button button_press, bool is_auto_repeat, u64 auto_repeat_interval_ms) { if (m_loading) return page_navigation::stay; @@ -326,14 +336,14 @@ namespace rsx { case pad_button::dpad_left: case pad_button::ls_left: - if ((m_selected_index % m_columns) > 0) + if (column(m_selected_index) > 0) { select_tile(m_selected_index - 1); } break; case pad_button::dpad_right: case pad_button::ls_right: - if (((m_selected_index % m_columns) + 1) < m_columns && (m_selected_index + 1) < static_cast(m_tiles.size())) + if ((column(m_selected_index) + 1) < m_columns && (m_selected_index + 1) < static_cast(m_tiles.size())) { select_tile(m_selected_index + 1); } @@ -347,7 +357,7 @@ namespace rsx break; case pad_button::dpad_down: case pad_button::ls_down: - if (!m_tiles.empty()) + if (!m_tiles.empty() && row(m_selected_index) < row(static_cast(m_tiles.size()) - 1)) { select_tile(std::min(m_selected_index + m_columns, static_cast(m_tiles.size()) - 1)); } diff --git a/rpcs3/Emu/RSX/Overlays/BigPicture/overlay_big_picture_game_grid.h b/rpcs3/Emu/RSX/Overlays/BigPicture/overlay_big_picture_game_grid.h index 15d9e625c15c..6a95965a6dad 100644 --- a/rpcs3/Emu/RSX/Overlays/BigPicture/overlay_big_picture_game_grid.h +++ b/rpcs3/Emu/RSX/Overlays/BigPicture/overlay_big_picture_game_grid.h @@ -46,6 +46,9 @@ namespace rsx void finish_reload(std::vector>&& tiles); void select_tile(s32 index); + u16 column(s32 tile_index) const; + u16 row(s32 tile_index) const; + static constexpr u16 m_columns = 5; static constexpr u16 m_tile_size = 200; From f263474a360dbc4992556f3ceb2f9596363378dc Mon Sep 17 00:00:00 2001 From: Megamouse Date: Tue, 1 Sep 2026 23:58:24 +0200 Subject: [PATCH 2/4] big picture: increase auto repeat interval. It was way too fast. --- rpcs3/Emu/RSX/Overlays/BigPicture/overlay_big_picture.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpcs3/Emu/RSX/Overlays/BigPicture/overlay_big_picture.cpp b/rpcs3/Emu/RSX/Overlays/BigPicture/overlay_big_picture.cpp index 89f329d000ba..117478895a25 100644 --- a/rpcs3/Emu/RSX/Overlays/BigPicture/overlay_big_picture.cpp +++ b/rpcs3/Emu/RSX/Overlays/BigPicture/overlay_big_picture.cpp @@ -77,7 +77,7 @@ namespace rsx case pad_button::dpad_right: case pad_button::ls_left: case pad_button::ls_right: - m_auto_repeat_ms_interval = 10; + m_auto_repeat_ms_interval = 100; break; default: m_auto_repeat_ms_interval = m_auto_repeat_ms_interval_default; From ca5fca0974e482707f20fa4f0130c2ddf651ad75 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Wed, 2 Sep 2026 00:17:45 +0200 Subject: [PATCH 3/4] big picture: lock reload mutex at function entry --- .../RSX/Overlays/BigPicture/overlay_big_picture_game_grid.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rpcs3/Emu/RSX/Overlays/BigPicture/overlay_big_picture_game_grid.cpp b/rpcs3/Emu/RSX/Overlays/BigPicture/overlay_big_picture_game_grid.cpp index 5432478ad1e9..f1a1b565caa6 100644 --- a/rpcs3/Emu/RSX/Overlays/BigPicture/overlay_big_picture_game_grid.cpp +++ b/rpcs3/Emu/RSX/Overlays/BigPicture/overlay_big_picture_game_grid.cpp @@ -391,6 +391,8 @@ namespace rsx compiled_resource& big_picture_game_grid::get_compiled() { + std::lock_guard lock(m_reload_mutex); + if (!m_highlight->is_compiled() || (!m_tiles.empty() && m_grid && !m_grid->is_compiled()) || (m_details && m_details->is_visible())) @@ -411,8 +413,6 @@ namespace rsx return compiled_resources; } - std::lock_guard lock(m_reload_mutex); - if (m_tiles.empty()) { compiled_resources.add(m_placeholder_text->get_compiled()); From d51e0c810174fbabb7256d3985f228a74280b2d9 Mon Sep 17 00:00:00 2001 From: Megamouse Date: Wed, 2 Sep 2026 01:34:57 +0200 Subject: [PATCH 4/4] big picture: fix image/video aspect ratios --- .../overlay_big_picture_game_details.cpp | 2 + .../overlay_big_picture_game_grid.cpp | 1 + rpcs3/Emu/RSX/Overlays/overlay_controls.cpp | 64 +++++++++++++++++++ rpcs3/Emu/RSX/Overlays/overlay_controls.h | 16 ++++- .../Overlays/overlay_media_list_dialog.cpp | 21 +----- .../RSX/Overlays/overlay_message_dialog.cpp | 17 +---- rpcs3/Emu/RSX/Overlays/overlay_video.cpp | 6 ++ 7 files changed, 90 insertions(+), 37 deletions(-) diff --git a/rpcs3/Emu/RSX/Overlays/BigPicture/overlay_big_picture_game_details.cpp b/rpcs3/Emu/RSX/Overlays/BigPicture/overlay_big_picture_game_details.cpp index 74cabcd3d7c0..a50077f27354 100644 --- a/rpcs3/Emu/RSX/Overlays/BigPicture/overlay_big_picture_game_details.cpp +++ b/rpcs3/Emu/RSX/Overlays/BigPicture/overlay_big_picture_game_details.cpp @@ -82,10 +82,12 @@ namespace rsx if (icon_data) { + m_icon.set_keep_aspect_ratio(true); m_icon.set_raw_image(icon_data); } else { + m_icon.set_keep_aspect_ratio(false); m_icon.set_image_resource(resource_config::standard_image_resource::new_entry); } diff --git a/rpcs3/Emu/RSX/Overlays/BigPicture/overlay_big_picture_game_grid.cpp b/rpcs3/Emu/RSX/Overlays/BigPicture/overlay_big_picture_game_grid.cpp index f1a1b565caa6..1c1516ac2ba7 100644 --- a/rpcs3/Emu/RSX/Overlays/BigPicture/overlay_big_picture_game_grid.cpp +++ b/rpcs3/Emu/RSX/Overlays/BigPicture/overlay_big_picture_game_grid.cpp @@ -27,6 +27,7 @@ namespace rsx // The renderer's texture cache is keyed by this object's address, which can be reused by an // unrelated image after the old one is freed - force a re-upload instead of trusting the cache. m_icon_data->dirty = true; + static_cast(icon.get())->set_keep_aspect_ratio(true); static_cast(icon.get())->set_raw_image(m_icon_data.get()); } else diff --git a/rpcs3/Emu/RSX/Overlays/overlay_controls.cpp b/rpcs3/Emu/RSX/Overlays/overlay_controls.cpp index 4c36477c78ad..3280c253ef9a 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_controls.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlay_controls.cpp @@ -1041,6 +1041,59 @@ namespace rsx return result; } + void image_view::adjust_padding() + { + overlay_element::set_padding(m_original_padding_left, m_original_padding_right, m_original_padding_top, m_original_padding_bottom); + + if (!m_keep_aspect_ratio || !external_ref || external_ref->w <= 0 || external_ref->h <= 0) + { + return; + } + + // Adjust padding so that the image keeps its aspect ratio + + const u16 p_left = m_original_padding_left; + const u16 p_right = m_original_padding_right; + const u16 p_top = m_original_padding_top; + const u16 p_bottom = m_original_padding_bottom; + + const u16 target_width = w - (p_left + p_right); + const u16 target_height = h - (p_top + p_bottom); + const f32 target_ratio = target_width / static_cast(target_height); + const f32 image_ratio = external_ref->w / static_cast(external_ref->h); + + if (image_ratio > target_ratio) + { + const u16 new_padding = static_cast(target_height - target_width / image_ratio) / 2; + overlay_element::set_padding(p_left, p_right, p_top + new_padding, p_bottom + new_padding); + } + else if (image_ratio < target_ratio) + { + const u16 new_padding = static_cast(target_width - target_height * image_ratio) / 2; + overlay_element::set_padding(p_left + new_padding, p_right + new_padding, p_top, p_bottom); + } + } + + void image_view::set_padding(u16 left, u16 right, u16 top, u16 bottom) + { + m_original_padding_left = left; + m_original_padding_right = right; + m_original_padding_top = top; + m_original_padding_bottom = bottom; + + adjust_padding(); + } + + void image_view::set_padding(u16 padding) + { + m_original_padding_left = padding; + m_original_padding_right = padding; + m_original_padding_top = padding; + m_original_padding_bottom = padding; + + adjust_padding(); + } + compiled_resource& image_view::get_compiled() { if (is_compiled()) @@ -1086,6 +1139,8 @@ namespace rsx { image_resource_ref = image_resource_id::raw_image; external_ref = raw_image; + + adjust_padding(); } void image_view::clear_image() @@ -1099,6 +1154,15 @@ namespace rsx blur_strength = strength; } + void image_view::set_keep_aspect_ratio(bool enabled) + { + if (m_keep_aspect_ratio != enabled) + { + m_keep_aspect_ratio = enabled; + adjust_padding(); + } + } + image_button::image_button() { // Do not clip text to region extents diff --git a/rpcs3/Emu/RSX/Overlays/overlay_controls.h b/rpcs3/Emu/RSX/Overlays/overlay_controls.h index ecda383e8855..1afa0ff3b9c9 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_controls.h +++ b/rpcs3/Emu/RSX/Overlays/overlay_controls.h @@ -368,20 +368,34 @@ namespace rsx { protected: u8 image_resource_ref = image_resource_id::none; - const void* external_ref = nullptr; + const image_info_base* external_ref = nullptr; + + // Original padding of inherited class. Helps us to keep the image aspect ratio when padding is adjusted. + u16 m_original_padding_left = 0; + u16 m_original_padding_right = 0; + u16 m_original_padding_top = 0; + u16 m_original_padding_bottom = 0; + + bool m_keep_aspect_ratio = false; // Strength of blur effect u8 blur_strength = 0; + void adjust_padding(); + public: using overlay_element::overlay_element; + void set_padding(u16 left, u16 right, u16 top, u16 bottom) override; + void set_padding(u16 padding) override; + compiled_resource& get_compiled() override; void set_image_resource(u8 resource_id); void set_raw_image(const image_info_base* raw_image); void clear_image(); void set_blur_strength(u8 strength); + void set_keep_aspect_ratio(bool enabled); }; struct image_button : public image_view diff --git a/rpcs3/Emu/RSX/Overlays/overlay_media_list_dialog.cpp b/rpcs3/Emu/RSX/Overlays/overlay_media_list_dialog.cpp index 9cc5a5c1e344..e59f00252020 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_media_list_dialog.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlay_media_list_dialog.cpp @@ -55,27 +55,8 @@ namespace rsx if (fs::exists(entry.info.path)) { // Fit the new image into the available space - if (entry.info.width > 0 && entry.info.height > 0) - { - const u16 target_width = image->w - (image->padding_left + image->padding_right); - const u16 target_height = image->h - (image->padding_top + image->padding_bottom); - const f32 target_ratio = target_width / static_cast(target_height); - const f32 image_ratio = entry.info.width / static_cast(entry.info.height); - const f32 convert_ratio = image_ratio / target_ratio; - - if (convert_ratio > 1.0f) - { - const u16 new_padding = static_cast(target_height - target_height / convert_ratio) / 2; - image->set_padding(image->padding_left, image->padding_right, new_padding + image->padding_top, new_padding + image->padding_bottom); - } - else if (convert_ratio < 1.0f) - { - const u16 new_padding = static_cast(target_width - target_width * convert_ratio) / 2; - image->set_padding(image->padding_left + new_padding, image->padding_right + new_padding, image->padding_top, image->padding_bottom); - } - } - icon_data = std::make_unique(entry.info.path); + static_cast(image.get())->set_keep_aspect_ratio(true); static_cast(image.get())->set_raw_image(icon_data.get()); } else diff --git a/rpcs3/Emu/RSX/Overlays/overlay_message_dialog.cpp b/rpcs3/Emu/RSX/Overlays/overlay_message_dialog.cpp index a0be8ce5cf1c..7e5bea2fd9af 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_message_dialog.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlay_message_dialog.cpp @@ -391,25 +391,10 @@ namespace rsx background.back_color.a = 0.f; background_poster.set_size(virtual_width, virtual_height); + background_poster.set_keep_aspect_ratio(true); background_poster.set_raw_image(background_image.get()); background_poster.set_blur_strength(static_cast(background_blur_strength)); - ensure(background_image->w > 0); - ensure(background_image->h > 0); - ensure(background_poster.h > 0); - - // Set padding in order to keep the aspect ratio - if ((background_image->w / static_cast(background_image->h)) > (background_poster.w / static_cast(background_poster.h))) - { - const int padding = (background_poster.h - static_cast(background_image->h * (background_poster.w / static_cast(background_image->w)))) / 2; - background_poster.set_padding(0, 0, padding, padding); - } - else - { - const int padding = (background_poster.w - static_cast(background_image->w * (background_poster.h / static_cast(background_image->h)))) / 2; - background_poster.set_padding(padding, padding, 0, 0); - } - if (background_overlay_image && background_overlay_image->get_data()) { constexpr f32 reference_factor = 2.0f / 3.0f; diff --git a/rpcs3/Emu/RSX/Overlays/overlay_video.cpp b/rpcs3/Emu/RSX/Overlays/overlay_video.cpp index 34ea42f7c553..f9156115106f 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_video.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlay_video.cpp @@ -14,6 +14,7 @@ namespace rsx if (!thumbnail_path.empty()) { m_thumbnail_info = std::make_unique(thumbnail_path); + set_keep_aspect_ratio(true); set_raw_image(m_thumbnail_info.get()); } } @@ -25,6 +26,7 @@ namespace rsx if (!thumbnail_buf.empty()) { m_thumbnail_info = std::make_unique(thumbnail_buf); + set_keep_aspect_ratio(true); set_raw_image(m_thumbnail_info.get()); } } @@ -48,6 +50,7 @@ namespace rsx if (auto img = image_info::load_icon(info.icon_path, info.icon_in_archive ? info.path : "")) { m_thumbnail_info = std::move(img); + set_keep_aspect_ratio(true); set_raw_image(m_thumbnail_info.get()); } } @@ -102,6 +105,7 @@ namespace rsx m_video_source->get_image(info->data, info->w, info->h, info->channels, info->bpp); info->dirty = true; + set_keep_aspect_ratio(true); set_raw_image(info.get()); m_is_compiled = false; return; @@ -109,6 +113,7 @@ namespace rsx if (m_thumbnail_info && m_thumbnail_info.get() != external_ref) { + set_keep_aspect_ratio(true); set_raw_image(m_thumbnail_info.get()); m_is_compiled = false; return; @@ -116,6 +121,7 @@ namespace rsx if (m_thumbnail_id != image_resource_id::none && m_thumbnail_id != image_resource_ref) { + set_keep_aspect_ratio(false); set_image_resource(m_thumbnail_id); m_is_compiled = false; return;