mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-08-04 15:19:47 +00:00
Overlays: Allow to play save data movies in save data list
This commit is contained in:
parent
2f8ed1a6bd
commit
1e0ba7e98d
35 changed files with 421 additions and 145 deletions
|
@ -546,6 +546,7 @@ target_sources(rpcs3_emu PRIVATE
|
||||||
RSX/Overlays/overlay_trophy_notification.cpp
|
RSX/Overlays/overlay_trophy_notification.cpp
|
||||||
RSX/Overlays/overlay_user_list_dialog.cpp
|
RSX/Overlays/overlay_user_list_dialog.cpp
|
||||||
RSX/Overlays/overlay_utils.cpp
|
RSX/Overlays/overlay_utils.cpp
|
||||||
|
RSX/Overlays/overlay_video.cpp
|
||||||
RSX/Overlays/Shaders/shader_loading_dialog.cpp
|
RSX/Overlays/Shaders/shader_loading_dialog.cpp
|
||||||
RSX/Overlays/Shaders/shader_loading_dialog_native.cpp
|
RSX/Overlays/Shaders/shader_loading_dialog_native.cpp
|
||||||
RSX/Program/CgBinaryFragmentProgram.cpp
|
RSX/Program/CgBinaryFragmentProgram.cpp
|
||||||
|
|
|
@ -307,7 +307,7 @@ static error_code select_and_delete(ppu_thread& ppu)
|
||||||
// Display a blocking Save Data List asynchronously in the GUI thread.
|
// Display a blocking Save Data List asynchronously in the GUI thread.
|
||||||
if (auto save_dialog = Emu.GetCallbacks().get_save_dialog())
|
if (auto save_dialog = Emu.GetCallbacks().get_save_dialog())
|
||||||
{
|
{
|
||||||
selected = save_dialog->ShowSaveDataList(save_entries, focused, SAVEDATA_OP_LIST_DELETE, vm::null, g_fxo->get<savedata_manager>().enable_overlay);
|
selected = save_dialog->ShowSaveDataList(base_dir, save_entries, focused, SAVEDATA_OP_LIST_DELETE, vm::null, g_fxo->get<savedata_manager>().enable_overlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reschedule after a blocking dialog returns
|
// Reschedule after a blocking dialog returns
|
||||||
|
@ -1183,7 +1183,7 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v
|
||||||
// Display a blocking Save Data List asynchronously in the GUI thread.
|
// Display a blocking Save Data List asynchronously in the GUI thread.
|
||||||
if (auto save_dialog = Emu.GetCallbacks().get_save_dialog())
|
if (auto save_dialog = Emu.GetCallbacks().get_save_dialog())
|
||||||
{
|
{
|
||||||
selected = save_dialog->ShowSaveDataList(save_entries, focused, operation, listSet, g_fxo->get<savedata_manager>().enable_overlay);
|
selected = save_dialog->ShowSaveDataList(base_dir, save_entries, focused, operation, listSet, g_fxo->get<savedata_manager>().enable_overlay);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -361,5 +361,5 @@ class SaveDialogBase
|
||||||
public:
|
public:
|
||||||
virtual ~SaveDialogBase();
|
virtual ~SaveDialogBase();
|
||||||
|
|
||||||
virtual s32 ShowSaveDataList(std::vector<SaveDataEntry>& save_entries, s32 focused, u32 op, vm::ptr<CellSaveDataListSet> listSet, bool enable_overlay) = 0;
|
virtual s32 ShowSaveDataList(const std::string& base_dir, std::vector<SaveDataEntry>& save_entries, s32 focused, u32 op, vm::ptr<CellSaveDataListSet> listSet, bool enable_overlay) = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -218,12 +218,12 @@ namespace gl
|
||||||
m_input_filter = gl::filter::linear;
|
m_input_filter = gl::filter::linear;
|
||||||
}
|
}
|
||||||
|
|
||||||
gl::texture_view* ui_overlay_renderer::load_simple_image(rsx::overlays::image_info* desc, bool temp_resource, u32 owner_uid)
|
gl::texture_view* ui_overlay_renderer::load_simple_image(rsx::overlays::image_info_base* desc, bool temp_resource, u32 owner_uid)
|
||||||
{
|
{
|
||||||
auto tex = std::make_unique<gl::texture>(GL_TEXTURE_2D, desc->w, desc->h, 1, 1, 1, GL_RGBA8, RSX_FORMAT_CLASS_COLOR);
|
auto tex = std::make_unique<gl::texture>(GL_TEXTURE_2D, desc->w, desc->h, 1, 1, 1, GL_RGBA8, RSX_FORMAT_CLASS_COLOR);
|
||||||
tex->copy_from(desc->get_data(), gl::texture::format::rgba, gl::texture::type::uint_8_8_8_8, {});
|
tex->copy_from(desc->get_data(), gl::texture::format::rgba, gl::texture::type::uint_8_8_8_8, {});
|
||||||
|
|
||||||
GLenum remap[] = { GL_RED, GL_ALPHA, GL_BLUE, GL_GREEN };
|
const GLenum remap[] = { GL_RED, GL_ALPHA, GL_BLUE, GL_GREEN };
|
||||||
auto view = std::make_unique<gl::texture_view>(tex.get(), remap);
|
auto view = std::make_unique<gl::texture_view>(tex.get(), remap);
|
||||||
|
|
||||||
auto result = view.get();
|
auto result = view.get();
|
||||||
|
@ -234,7 +234,7 @@ namespace gl
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
u64 key = reinterpret_cast<u64>(desc);
|
const u64 key = reinterpret_cast<u64>(desc);
|
||||||
temp_image_cache[key] = std::make_pair(owner_uid, std::move(tex));
|
temp_image_cache[key] = std::make_pair(owner_uid, std::move(tex));
|
||||||
temp_view_cache[key] = std::move(view);
|
temp_view_cache[key] = std::move(view);
|
||||||
}
|
}
|
||||||
|
@ -249,7 +249,7 @@ namespace gl
|
||||||
rsx::overlays::resource_config configuration;
|
rsx::overlays::resource_config configuration;
|
||||||
configuration.load_files();
|
configuration.load_files();
|
||||||
|
|
||||||
for (const auto &res : configuration.texture_raw_data)
|
for (const auto& res : configuration.texture_raw_data)
|
||||||
{
|
{
|
||||||
load_simple_image(res.get(), false, -1);
|
load_simple_image(res.get(), false, -1);
|
||||||
}
|
}
|
||||||
|
@ -318,13 +318,22 @@ namespace gl
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
gl::texture_view* ui_overlay_renderer::find_temp_image(rsx::overlays::image_info* desc, u32 owner_uid)
|
gl::texture_view* ui_overlay_renderer::find_temp_image(rsx::overlays::image_info_base* desc, u32 owner_uid)
|
||||||
{
|
{
|
||||||
auto key = reinterpret_cast<u64>(desc);
|
const bool dirty = std::exchange(desc->dirty, false);
|
||||||
|
const u64 key = reinterpret_cast<u64>(desc);
|
||||||
|
|
||||||
auto cached = temp_view_cache.find(key);
|
auto cached = temp_view_cache.find(key);
|
||||||
if (cached != temp_view_cache.end())
|
if (cached != temp_view_cache.end())
|
||||||
{
|
{
|
||||||
return cached->second.get();
|
gl::texture_view* view = cached->second.get();
|
||||||
|
|
||||||
|
if (dirty)
|
||||||
|
{
|
||||||
|
view->image()->copy_from(desc->get_data(), gl::texture::format::rgba, gl::texture::type::uint_8_8_8_8, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
return load_simple_image(desc, true, owner_uid);
|
return load_simple_image(desc, true, owner_uid);
|
||||||
|
@ -420,7 +429,7 @@ namespace gl
|
||||||
}
|
}
|
||||||
case rsx::overlays::image_resource_id::raw_image:
|
case rsx::overlays::image_resource_id::raw_image:
|
||||||
{
|
{
|
||||||
cmd_->bind_texture(31, GL_TEXTURE_2D, find_temp_image(static_cast<rsx::overlays::image_info*>(cmd.config.external_data_ref), ui.uid)->id());
|
cmd_->bind_texture(31, GL_TEXTURE_2D, find_temp_image(static_cast<rsx::overlays::image_info_base*>(cmd.config.external_data_ref), ui.uid)->id());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case rsx::overlays::image_resource_id::font_file:
|
case rsx::overlays::image_resource_id::font_file:
|
||||||
|
|
|
@ -75,7 +75,7 @@ namespace gl
|
||||||
|
|
||||||
ui_overlay_renderer();
|
ui_overlay_renderer();
|
||||||
|
|
||||||
gl::texture_view* load_simple_image(rsx::overlays::image_info* desc, bool temp_resource, u32 owner_uid);
|
gl::texture_view* load_simple_image(rsx::overlays::image_info_base* desc, bool temp_resource, u32 owner_uid);
|
||||||
|
|
||||||
void create();
|
void create();
|
||||||
void destroy();
|
void destroy();
|
||||||
|
@ -84,7 +84,7 @@ namespace gl
|
||||||
|
|
||||||
gl::texture_view* find_font(rsx::overlays::font* font);
|
gl::texture_view* find_font(rsx::overlays::font* font);
|
||||||
|
|
||||||
gl::texture_view* find_temp_image(rsx::overlays::image_info* desc, u32 owner_uid);
|
gl::texture_view* find_temp_image(rsx::overlays::image_info_base* desc, u32 owner_uid);
|
||||||
|
|
||||||
void set_primitive_type(rsx::overlays::primitive_type type);
|
void set_primitive_type(rsx::overlays::primitive_type type);
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ namespace rsx
|
||||||
{
|
{
|
||||||
update_value();
|
update_value();
|
||||||
|
|
||||||
if (!is_compiled)
|
if (!is_compiled())
|
||||||
{
|
{
|
||||||
const f32 col = m_last_value ? 1.0f : 0.3f;
|
const f32 col = m_last_value ? 1.0f : 0.3f;
|
||||||
const f32 bkg = m_last_value ? 0.3f : 1.0f;
|
const f32 bkg = m_last_value ? 0.3f : 1.0f;
|
||||||
|
|
|
@ -64,7 +64,7 @@ namespace rsx
|
||||||
if (const T new_value = m_setting->get(); new_value != m_last_value || initializing)
|
if (const T new_value = m_setting->get(); new_value != m_last_value || initializing)
|
||||||
{
|
{
|
||||||
m_last_value = new_value;
|
m_last_value = new_value;
|
||||||
is_compiled = false;
|
m_is_compiled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,7 @@ namespace rsx
|
||||||
{
|
{
|
||||||
this->update_value();
|
this->update_value();
|
||||||
|
|
||||||
if (!this->is_compiled)
|
if (!this->is_compiled())
|
||||||
{
|
{
|
||||||
const std::string value_text = Emu.GetCallbacks().get_localized_setting(home_menu_setting<T, cfg::_enum<T>>::m_setting, static_cast<u32>(this->m_last_value));
|
const std::string value_text = Emu.GetCallbacks().get_localized_setting(home_menu_setting<T, cfg::_enum<T>>::m_setting, static_cast<u32>(this->m_last_value));
|
||||||
m_dropdown.set_text(value_text);
|
m_dropdown.set_text(value_text);
|
||||||
|
@ -145,7 +145,7 @@ namespace rsx
|
||||||
{
|
{
|
||||||
this->update_value();
|
this->update_value();
|
||||||
|
|
||||||
if (!this->is_compiled)
|
if (!this->is_compiled())
|
||||||
{
|
{
|
||||||
const f64 percentage = std::clamp((this->m_last_value - static_cast<T>(m_minimum)) / std::fabs(m_maximum - m_minimum), 0.0, 1.0);
|
const f64 percentage = std::clamp((this->m_last_value - static_cast<T>(m_minimum)) / std::fabs(m_maximum - m_minimum), 0.0, 1.0);
|
||||||
m_slider.set_pos(m_slider.x, this->y + (this->h - m_slider.h) / 2);
|
m_slider.set_pos(m_slider.x, this->y + (this->h - m_slider.h) / 2);
|
||||||
|
|
|
@ -44,7 +44,7 @@ namespace rsx
|
||||||
|
|
||||||
compiled_resource& home_menu_message_box::get_compiled()
|
compiled_resource& home_menu_message_box::get_compiled()
|
||||||
{
|
{
|
||||||
if (!is_compiled)
|
if (!is_compiled())
|
||||||
{
|
{
|
||||||
compiled_resource& compiled = overlay_element::get_compiled();
|
compiled_resource& compiled = overlay_element::get_compiled();
|
||||||
compiled.add(m_label.get_compiled());
|
compiled.add(m_label.get_compiled());
|
||||||
|
|
|
@ -258,9 +258,9 @@ namespace rsx
|
||||||
|
|
||||||
compiled_resource& home_menu_page::get_compiled()
|
compiled_resource& home_menu_page::get_compiled()
|
||||||
{
|
{
|
||||||
if (!is_compiled || (m_message_box && !m_message_box->is_compiled))
|
if (!is_compiled() || (m_message_box && !m_message_box->is_compiled()))
|
||||||
{
|
{
|
||||||
is_compiled = false;
|
m_is_compiled = false;
|
||||||
|
|
||||||
if (home_menu_page* page = get_current_page(false))
|
if (home_menu_page* page = get_current_page(false))
|
||||||
{
|
{
|
||||||
|
@ -281,7 +281,7 @@ namespace rsx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is_compiled = true;
|
m_is_compiled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return compiled_resources;
|
return compiled_resources;
|
||||||
|
|
|
@ -58,7 +58,7 @@ namespace rsx
|
||||||
|
|
||||||
compiled_resource& animated_icon::get_compiled()
|
compiled_resource& animated_icon::get_compiled()
|
||||||
{
|
{
|
||||||
if (!is_compiled)
|
if (!is_compiled())
|
||||||
{
|
{
|
||||||
compiled_resources = image_view::get_compiled();
|
compiled_resources = image_view::get_compiled();
|
||||||
}
|
}
|
||||||
|
|
|
@ -302,7 +302,7 @@ namespace rsx
|
||||||
void overlay_element::refresh()
|
void overlay_element::refresh()
|
||||||
{
|
{
|
||||||
// Just invalidate for draw when get_compiled() is called
|
// Just invalidate for draw when get_compiled() is called
|
||||||
is_compiled = false;
|
m_is_compiled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void overlay_element::translate(s16 _x, s16 _y)
|
void overlay_element::translate(s16 _x, s16 _y)
|
||||||
|
@ -310,7 +310,7 @@ namespace rsx
|
||||||
x += _x;
|
x += _x;
|
||||||
y += _y;
|
y += _y;
|
||||||
|
|
||||||
is_compiled = false;
|
m_is_compiled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void overlay_element::scale(f32 _x, f32 _y, bool origin_scaling)
|
void overlay_element::scale(f32 _x, f32 _y, bool origin_scaling)
|
||||||
|
@ -324,7 +324,7 @@ namespace rsx
|
||||||
w = static_cast<u16>(_x * w);
|
w = static_cast<u16>(_x * w);
|
||||||
h = static_cast<u16>(_y * h);
|
h = static_cast<u16>(_y * h);
|
||||||
|
|
||||||
is_compiled = false;
|
m_is_compiled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void overlay_element::set_pos(s16 _x, s16 _y)
|
void overlay_element::set_pos(s16 _x, s16 _y)
|
||||||
|
@ -332,7 +332,7 @@ namespace rsx
|
||||||
x = _x;
|
x = _x;
|
||||||
y = _y;
|
y = _y;
|
||||||
|
|
||||||
is_compiled = false;
|
m_is_compiled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void overlay_element::set_size(u16 _w, u16 _h)
|
void overlay_element::set_size(u16 _w, u16 _h)
|
||||||
|
@ -340,7 +340,7 @@ namespace rsx
|
||||||
w = _w;
|
w = _w;
|
||||||
h = _h;
|
h = _h;
|
||||||
|
|
||||||
is_compiled = false;
|
m_is_compiled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void overlay_element::set_padding(u16 left, u16 right, u16 top, u16 bottom)
|
void overlay_element::set_padding(u16 left, u16 right, u16 top, u16 bottom)
|
||||||
|
@ -350,13 +350,13 @@ namespace rsx
|
||||||
padding_top = top;
|
padding_top = top;
|
||||||
padding_bottom = bottom;
|
padding_bottom = bottom;
|
||||||
|
|
||||||
is_compiled = false;
|
m_is_compiled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void overlay_element::set_padding(u16 padding)
|
void overlay_element::set_padding(u16 padding)
|
||||||
{
|
{
|
||||||
padding_left = padding_right = padding_top = padding_bottom = padding;
|
padding_left = padding_right = padding_top = padding_bottom = padding;
|
||||||
is_compiled = false;
|
m_is_compiled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Functions as a simple position offset. Top left corner is the anchor.
|
// NOTE: Functions as a simple position offset. Top left corner is the anchor.
|
||||||
|
@ -365,25 +365,36 @@ namespace rsx
|
||||||
margin_left = left;
|
margin_left = left;
|
||||||
margin_top = top;
|
margin_top = top;
|
||||||
|
|
||||||
is_compiled = false;
|
m_is_compiled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void overlay_element::set_margin(u16 margin)
|
void overlay_element::set_margin(u16 margin)
|
||||||
{
|
{
|
||||||
margin_left = margin_top = margin;
|
margin_left = margin_top = margin;
|
||||||
is_compiled = false;
|
m_is_compiled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void overlay_element::set_text(const std::string& text)
|
void overlay_element::set_text(const std::string& text)
|
||||||
{
|
{
|
||||||
this->text = utf8_to_u32string(text);
|
std::u32string new_text = utf8_to_u32string(text);
|
||||||
is_compiled = false;
|
const bool is_dirty = this->text != new_text;
|
||||||
|
this->text = std::move(new_text);
|
||||||
|
|
||||||
|
if (is_dirty)
|
||||||
|
{
|
||||||
|
m_is_compiled = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void overlay_element::set_unicode_text(const std::u32string& text)
|
void overlay_element::set_unicode_text(const std::u32string& text)
|
||||||
{
|
{
|
||||||
|
const bool is_dirty = this->text != text;
|
||||||
this->text = text;
|
this->text = text;
|
||||||
is_compiled = false;
|
|
||||||
|
if (is_dirty)
|
||||||
|
{
|
||||||
|
m_is_compiled = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void overlay_element::set_text(localized_string_id id)
|
void overlay_element::set_text(localized_string_id id)
|
||||||
|
@ -394,19 +405,19 @@ namespace rsx
|
||||||
void overlay_element::set_font(const char* font_name, u16 font_size)
|
void overlay_element::set_font(const char* font_name, u16 font_size)
|
||||||
{
|
{
|
||||||
font_ref = fontmgr::get(font_name, font_size);
|
font_ref = fontmgr::get(font_name, font_size);
|
||||||
is_compiled = false;
|
m_is_compiled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void overlay_element::align_text(text_align align)
|
void overlay_element::align_text(text_align align)
|
||||||
{
|
{
|
||||||
alignment = align;
|
alignment = align;
|
||||||
is_compiled = false;
|
m_is_compiled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void overlay_element::set_wrap_text(bool state)
|
void overlay_element::set_wrap_text(bool state)
|
||||||
{
|
{
|
||||||
wrap_text = state;
|
wrap_text = state;
|
||||||
is_compiled = false;
|
m_is_compiled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
font* overlay_element::get_font() const
|
font* overlay_element::get_font() const
|
||||||
|
@ -563,7 +574,7 @@ namespace rsx
|
||||||
|
|
||||||
compiled_resource& overlay_element::get_compiled()
|
compiled_resource& overlay_element::get_compiled()
|
||||||
{
|
{
|
||||||
if (!is_compiled)
|
if (!is_compiled())
|
||||||
{
|
{
|
||||||
compiled_resources.clear();
|
compiled_resources.clear();
|
||||||
|
|
||||||
|
@ -599,7 +610,7 @@ namespace rsx
|
||||||
compiled_resources.add(std::move(compiled_resources_temp), margin_left - horizontal_scroll_offset, margin_top - vertical_scroll_offset);
|
compiled_resources.add(std::move(compiled_resources_temp), margin_left - horizontal_scroll_offset, margin_top - vertical_scroll_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
is_compiled = true;
|
m_is_compiled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return compiled_resources;
|
return compiled_resources;
|
||||||
|
@ -664,7 +675,7 @@ namespace rsx
|
||||||
{
|
{
|
||||||
overlay_element::translate(_x, _y);
|
overlay_element::translate(_x, _y);
|
||||||
|
|
||||||
for (auto &itm : m_items)
|
for (auto& itm : m_items)
|
||||||
itm->translate(_x, _y);
|
itm->translate(_x, _y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -675,13 +686,23 @@ namespace rsx
|
||||||
translate(dx, dy);
|
translate(dx, dy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool layout_container::is_compiled()
|
||||||
|
{
|
||||||
|
if (m_is_compiled && std::any_of(m_items.cbegin(), m_items.cend(), [](const auto& item){ return item && !item->is_compiled(); }))
|
||||||
|
{
|
||||||
|
m_is_compiled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_is_compiled;
|
||||||
|
}
|
||||||
|
|
||||||
compiled_resource& layout_container::get_compiled()
|
compiled_resource& layout_container::get_compiled()
|
||||||
{
|
{
|
||||||
if (!is_compiled)
|
if (!is_compiled())
|
||||||
{
|
{
|
||||||
compiled_resource result = overlay_element::get_compiled();
|
compiled_resource result = overlay_element::get_compiled();
|
||||||
|
|
||||||
for (auto &itm : m_items)
|
for (auto& itm : m_items)
|
||||||
result.add(itm->get_compiled());
|
result.add(itm->get_compiled());
|
||||||
|
|
||||||
compiled_resources = result;
|
compiled_resources = result;
|
||||||
|
@ -716,7 +737,7 @@ namespace rsx
|
||||||
return m_items.back().get();
|
return m_items.back().get();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto result = item.get();
|
overlay_element* result = item.get();
|
||||||
m_items.insert(m_items.begin() + offset, std::move(item));
|
m_items.insert(m_items.begin() + offset, std::move(item));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -726,12 +747,12 @@ namespace rsx
|
||||||
if (scroll_offset_value == 0 && auto_resize)
|
if (scroll_offset_value == 0 && auto_resize)
|
||||||
return layout_container::get_compiled();
|
return layout_container::get_compiled();
|
||||||
|
|
||||||
if (!is_compiled)
|
if (!is_compiled())
|
||||||
{
|
{
|
||||||
compiled_resource result = overlay_element::get_compiled();
|
compiled_resource result = overlay_element::get_compiled();
|
||||||
const f32 global_y_offset = static_cast<f32>(-scroll_offset_value);
|
const f32 global_y_offset = static_cast<f32>(-scroll_offset_value);
|
||||||
|
|
||||||
for (auto &item : m_items)
|
for (auto& item : m_items)
|
||||||
{
|
{
|
||||||
if (!item)
|
if (!item)
|
||||||
{
|
{
|
||||||
|
@ -808,7 +829,7 @@ namespace rsx
|
||||||
if (scroll_offset_value == 0 && auto_resize)
|
if (scroll_offset_value == 0 && auto_resize)
|
||||||
return layout_container::get_compiled();
|
return layout_container::get_compiled();
|
||||||
|
|
||||||
if (!is_compiled)
|
if (!is_compiled())
|
||||||
{
|
{
|
||||||
compiled_resource result = overlay_element::get_compiled();
|
compiled_resource result = overlay_element::get_compiled();
|
||||||
const f32 global_x_offset = static_cast<f32>(-scroll_offset_value);
|
const f32 global_x_offset = static_cast<f32>(-scroll_offset_value);
|
||||||
|
@ -862,7 +883,7 @@ namespace rsx
|
||||||
|
|
||||||
compiled_resource& image_view::get_compiled()
|
compiled_resource& image_view::get_compiled()
|
||||||
{
|
{
|
||||||
if (!is_compiled)
|
if (!is_compiled())
|
||||||
{
|
{
|
||||||
auto& result = overlay_element::get_compiled();
|
auto& result = overlay_element::get_compiled();
|
||||||
auto& cmd_img = result.draw_commands.front();
|
auto& cmd_img = result.draw_commands.front();
|
||||||
|
@ -880,7 +901,7 @@ namespace rsx
|
||||||
verts[2] += vertex(padding_left, -padding_top, 0, 0);
|
verts[2] += vertex(padding_left, -padding_top, 0, 0);
|
||||||
verts[3] += vertex(-padding_right, -padding_top, 0, 0);
|
verts[3] += vertex(-padding_right, -padding_top, 0, 0);
|
||||||
|
|
||||||
is_compiled = true;
|
m_is_compiled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return compiled_resources;
|
return compiled_resources;
|
||||||
|
@ -892,7 +913,7 @@ namespace rsx
|
||||||
external_ref = nullptr;
|
external_ref = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void image_view::set_raw_image(image_info* raw_image)
|
void image_view::set_raw_image(image_info_base* raw_image)
|
||||||
{
|
{
|
||||||
image_resource_ref = image_resource_id::raw_image;
|
image_resource_ref = image_resource_id::raw_image;
|
||||||
external_ref = raw_image;
|
external_ref = raw_image;
|
||||||
|
@ -935,7 +956,7 @@ namespace rsx
|
||||||
|
|
||||||
compiled_resource& image_button::get_compiled()
|
compiled_resource& image_button::get_compiled()
|
||||||
{
|
{
|
||||||
if (!is_compiled)
|
if (!is_compiled())
|
||||||
{
|
{
|
||||||
auto& compiled = image_view::get_compiled();
|
auto& compiled = image_view::get_compiled();
|
||||||
for (auto& cmd : compiled.draw_commands)
|
for (auto& cmd : compiled.draw_commands)
|
||||||
|
@ -987,7 +1008,7 @@ namespace rsx
|
||||||
|
|
||||||
compiled_resource& rounded_rect::get_compiled()
|
compiled_resource& rounded_rect::get_compiled()
|
||||||
{
|
{
|
||||||
if (!is_compiled)
|
if (!is_compiled())
|
||||||
{
|
{
|
||||||
compiled_resources.clear();
|
compiled_resources.clear();
|
||||||
|
|
||||||
|
@ -1068,7 +1089,7 @@ namespace rsx
|
||||||
compiled_resources.add(std::move(compiled_resources_temp), margin_left, margin_top);
|
compiled_resources.add(std::move(compiled_resources_temp), margin_left, margin_top);
|
||||||
}
|
}
|
||||||
|
|
||||||
is_compiled = true;
|
m_is_compiled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return compiled_resources;
|
return compiled_resources;
|
||||||
|
|
|
@ -30,23 +30,29 @@ namespace rsx
|
||||||
triangle_fan = 4
|
triangle_fan = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
struct image_info
|
struct image_info_base
|
||||||
|
{
|
||||||
|
int w = 0, h = 0, channels = 0;
|
||||||
|
int bpp = 0;
|
||||||
|
bool dirty = false;
|
||||||
|
|
||||||
|
virtual const u8* get_data() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct image_info : public image_info_base
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
u8* data = nullptr;
|
u8* data = nullptr;
|
||||||
std::vector<u8> data_grey;
|
std::vector<u8> data_grey;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
int w = 0, h = 0, channels = 0;
|
|
||||||
int bpp = 0;
|
|
||||||
|
|
||||||
image_info(image_info&) = delete;
|
image_info(image_info&) = delete;
|
||||||
image_info(const std::string& filename, bool grayscaled = false);
|
image_info(const std::string& filename, bool grayscaled = false);
|
||||||
image_info(const std::vector<u8>& bytes, bool grayscaled = false);
|
image_info(const std::vector<u8>& bytes, bool grayscaled = false);
|
||||||
~image_info();
|
~image_info();
|
||||||
|
|
||||||
void load_data(const std::vector<u8>& bytes, bool grayscaled = false);
|
void load_data(const std::vector<u8>& bytes, bool grayscaled = false);
|
||||||
const u8* get_data() const { return channels == 4 ? data : data_grey.empty() ? nullptr : data_grey.data(); }
|
const u8* get_data() const override { return channels == 4 ? data : data_grey.empty() ? nullptr : data_grey.data(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct resource_config
|
struct resource_config
|
||||||
|
@ -165,7 +171,6 @@ namespace rsx
|
||||||
void set_sinus_offset(f32 sinus_modifier);
|
void set_sinus_offset(f32 sinus_modifier);
|
||||||
|
|
||||||
compiled_resource compiled_resources;
|
compiled_resource compiled_resources;
|
||||||
bool is_compiled = false;
|
|
||||||
|
|
||||||
bool visible = true;
|
bool visible = true;
|
||||||
|
|
||||||
|
@ -185,6 +190,7 @@ namespace rsx
|
||||||
virtual ~overlay_element() = default;
|
virtual ~overlay_element() = default;
|
||||||
|
|
||||||
virtual void refresh();
|
virtual void refresh();
|
||||||
|
virtual bool is_compiled() { return m_is_compiled; }
|
||||||
virtual void translate(s16 _x, s16 _y);
|
virtual void translate(s16 _x, s16 _y);
|
||||||
virtual void scale(f32 _x, f32 _y, bool origin_scaling);
|
virtual void scale(f32 _x, f32 _y, bool origin_scaling);
|
||||||
virtual void set_pos(s16 _x, s16 _y);
|
virtual void set_pos(s16 _x, s16 _y);
|
||||||
|
@ -204,6 +210,10 @@ namespace rsx
|
||||||
virtual std::vector<vertex> render_text(const char32_t* string, f32 x, f32 y);
|
virtual std::vector<vertex> render_text(const char32_t* string, f32 x, f32 y);
|
||||||
virtual compiled_resource& get_compiled();
|
virtual compiled_resource& get_compiled();
|
||||||
void measure_text(u16& width, u16& height, bool ignore_word_wrap = false) const;
|
void measure_text(u16& width, u16& height, bool ignore_word_wrap = false) const;
|
||||||
|
virtual void set_selected(bool selected) { static_cast<void>(selected); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool m_is_compiled = false; // Only use m_is_compiled as a getter in is_compiled() if possible
|
||||||
};
|
};
|
||||||
|
|
||||||
struct layout_container : public overlay_element
|
struct layout_container : public overlay_element
|
||||||
|
@ -221,6 +231,8 @@ namespace rsx
|
||||||
void translate(s16 _x, s16 _y) override;
|
void translate(s16 _x, s16 _y) override;
|
||||||
void set_pos(s16 _x, s16 _y) override;
|
void set_pos(s16 _x, s16 _y) override;
|
||||||
|
|
||||||
|
bool is_compiled() override;
|
||||||
|
|
||||||
compiled_resource& get_compiled() override;
|
compiled_resource& get_compiled() override;
|
||||||
|
|
||||||
virtual u16 get_scroll_offset_px() = 0;
|
virtual u16 get_scroll_offset_px() = 0;
|
||||||
|
@ -248,6 +260,7 @@ namespace rsx
|
||||||
compiled_resource& get_compiled() override
|
compiled_resource& get_compiled() override
|
||||||
{
|
{
|
||||||
// No draw
|
// No draw
|
||||||
|
m_is_compiled = true;
|
||||||
return compiled_resources;
|
return compiled_resources;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -263,7 +276,7 @@ namespace rsx
|
||||||
|
|
||||||
struct image_view : public overlay_element
|
struct image_view : public overlay_element
|
||||||
{
|
{
|
||||||
private:
|
protected:
|
||||||
u8 image_resource_ref = image_resource_id::none;
|
u8 image_resource_ref = image_resource_id::none;
|
||||||
void* external_ref = nullptr;
|
void* external_ref = nullptr;
|
||||||
|
|
||||||
|
@ -276,7 +289,7 @@ namespace rsx
|
||||||
compiled_resource& get_compiled() override;
|
compiled_resource& get_compiled() override;
|
||||||
|
|
||||||
void set_image_resource(u8 resource_id);
|
void set_image_resource(u8 resource_id);
|
||||||
void set_raw_image(image_info* raw_image);
|
void set_raw_image(image_info_base* raw_image);
|
||||||
void clear_image();
|
void clear_image();
|
||||||
void set_blur_strength(u8 strength);
|
void set_blur_strength(u8 strength);
|
||||||
};
|
};
|
||||||
|
|
|
@ -196,7 +196,7 @@ namespace rsx
|
||||||
|
|
||||||
compiled_resource& edit_text::get_compiled()
|
compiled_resource& edit_text::get_compiled()
|
||||||
{
|
{
|
||||||
if (!is_compiled)
|
if (!is_compiled())
|
||||||
{
|
{
|
||||||
auto renderer = get_font();
|
auto renderer = get_font();
|
||||||
const auto [caret_x, caret_y] = renderer->get_char_offset(text.c_str(), caret_position, clip_text ? w : -1, wrap_text);
|
const auto [caret_x, caret_y] = renderer->get_char_offset(text.c_str(), caret_position, clip_text ? w : -1, wrap_text);
|
||||||
|
@ -252,7 +252,7 @@ namespace rsx
|
||||||
cmd.config.clip_rect = {static_cast<f32>(x), static_cast<f32>(y), static_cast<f32>(x + w), static_cast<f32>(y + h)};
|
cmd.config.clip_rect = {static_cast<f32>(x), static_cast<f32>(y), static_cast<f32>(x + w), static_cast<f32>(y + h)};
|
||||||
}
|
}
|
||||||
|
|
||||||
is_compiled = true;
|
m_is_compiled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return compiled_resources;
|
return compiled_resources;
|
||||||
|
|
|
@ -91,6 +91,15 @@ namespace rsx
|
||||||
void list_view::update_selection()
|
void list_view::update_selection()
|
||||||
{
|
{
|
||||||
const overlay_element* current_element = get_selected_entry();
|
const overlay_element* current_element = get_selected_entry();
|
||||||
|
|
||||||
|
for (auto& item : m_items)
|
||||||
|
{
|
||||||
|
if (item)
|
||||||
|
{
|
||||||
|
item->set_selected(item.get() == current_element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!current_element)
|
if (!current_element)
|
||||||
{
|
{
|
||||||
return; // Ideally unreachable but it should still be possible to recover by user interaction.
|
return; // Ideally unreachable but it should still be possible to recover by user interaction.
|
||||||
|
@ -195,7 +204,7 @@ namespace rsx
|
||||||
m_cancel_btn->set_pos(x + 180, y + h + 20);
|
m_cancel_btn->set_pos(x + 180, y + h + 20);
|
||||||
|
|
||||||
m_cancel_only = cancel_only;
|
m_cancel_only = cancel_only;
|
||||||
is_compiled = false;
|
m_is_compiled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool list_view::get_cancel_only() const
|
bool list_view::get_cancel_only() const
|
||||||
|
@ -219,7 +228,7 @@ namespace rsx
|
||||||
|
|
||||||
compiled_resource& list_view::get_compiled()
|
compiled_resource& list_view::get_compiled()
|
||||||
{
|
{
|
||||||
if (!is_compiled)
|
if (!is_compiled())
|
||||||
{
|
{
|
||||||
auto& compiled = vertical_layout::get_compiled();
|
auto& compiled = vertical_layout::get_compiled();
|
||||||
compiled.add(m_highlight_box->get_compiled());
|
compiled.add(m_highlight_box->get_compiled());
|
||||||
|
|
|
@ -100,7 +100,7 @@ namespace rsx
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable caching
|
// Disable caching
|
||||||
is_compiled = false;
|
m_is_compiled = false;
|
||||||
|
|
||||||
compiled_resources = rounded_rect::get_compiled();
|
compiled_resources = rounded_rect::get_compiled();
|
||||||
compiled_resources.add(m_text.get_compiled());
|
compiled_resources.add(m_text.get_compiled());
|
||||||
|
|
|
@ -814,7 +814,7 @@ namespace rsx
|
||||||
|
|
||||||
compiled_resource& graph::get_compiled()
|
compiled_resource& graph::get_compiled()
|
||||||
{
|
{
|
||||||
if (is_compiled)
|
if (is_compiled())
|
||||||
{
|
{
|
||||||
return compiled_resources;
|
return compiled_resources;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ namespace rsx
|
||||||
void progress_bar::set_limit(f32 limit)
|
void progress_bar::set_limit(f32 limit)
|
||||||
{
|
{
|
||||||
m_limit = limit;
|
m_limit = limit;
|
||||||
is_compiled = false;
|
m_is_compiled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void progress_bar::set_value(f32 value)
|
void progress_bar::set_value(f32 value)
|
||||||
|
@ -32,7 +32,7 @@ namespace rsx
|
||||||
|
|
||||||
f32 indicator_width = (w * m_value) / m_limit;
|
f32 indicator_width = (w * m_value) / m_limit;
|
||||||
indicator.set_size(static_cast<u16>(indicator_width), h);
|
indicator.set_size(static_cast<u16>(indicator_width), h);
|
||||||
is_compiled = false;
|
m_is_compiled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void progress_bar::set_pos(s16 _x, s16 _y)
|
void progress_bar::set_pos(s16 _x, s16 _y)
|
||||||
|
@ -68,12 +68,12 @@ namespace rsx
|
||||||
text_view.set_size(w, text_h);
|
text_view.set_size(w, text_h);
|
||||||
|
|
||||||
set_pos(text_view.x, text_view.y);
|
set_pos(text_view.x, text_view.y);
|
||||||
is_compiled = false;
|
m_is_compiled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
compiled_resource& progress_bar::get_compiled()
|
compiled_resource& progress_bar::get_compiled()
|
||||||
{
|
{
|
||||||
if (!is_compiled)
|
if (!is_compiled())
|
||||||
{
|
{
|
||||||
auto& compiled = overlay_element::get_compiled();
|
auto& compiled = overlay_element::get_compiled();
|
||||||
compiled.add(text_view.get_compiled());
|
compiled.add(text_view.get_compiled());
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "overlay_save_dialog.h"
|
#include "overlay_save_dialog.h"
|
||||||
|
#include "overlay_video.h"
|
||||||
#include "Utilities/date_time.h"
|
#include "Utilities/date_time.h"
|
||||||
#include "Emu/System.h"
|
#include "Emu/System.h"
|
||||||
|
|
||||||
|
@ -7,26 +8,18 @@ namespace rsx
|
||||||
{
|
{
|
||||||
namespace overlays
|
namespace overlays
|
||||||
{
|
{
|
||||||
save_dialog::save_dialog_entry::save_dialog_entry(const std::string& text1, const std::string& text2, const std::string& text3, u8 resource_id, const std::vector<u8>& icon_buf)
|
save_dialog::save_dialog_entry::save_dialog_entry(const std::string& text1, const std::string& text2, const std::string& text3, u8 resource_id, const std::vector<u8>& icon_buf, const std::string& video_path)
|
||||||
{
|
{
|
||||||
std::unique_ptr<overlay_element> image = std::make_unique<image_view>();
|
std::unique_ptr<overlay_element> image = resource_id != image_resource_id::raw_image
|
||||||
|
? std::make_unique<video_view>(video_path, resource_id)
|
||||||
|
: !icon_buf.empty() ? std::make_unique<video_view>(video_path, icon_buf)
|
||||||
|
: std::make_unique<video_view>(video_path, resource_config::standard_image_resource::save); // Fallback
|
||||||
image->set_size(160, 110);
|
image->set_size(160, 110);
|
||||||
image->set_padding(36, 36, 11, 11); // Square image, 88x88
|
image->set_padding(36, 36, 11, 11); // Square image, 88x88
|
||||||
|
|
||||||
if (resource_id != image_resource_id::raw_image)
|
if (resource_id == image_resource_id::raw_image && !icon_buf.empty())
|
||||||
{
|
|
||||||
static_cast<image_view*>(image.get())->set_image_resource(resource_id);
|
|
||||||
}
|
|
||||||
else if (!icon_buf.empty())
|
|
||||||
{
|
{
|
||||||
image->set_padding(0, 0, 11, 11); // Half sized icon, 320x176->160x88
|
image->set_padding(0, 0, 11, 11); // Half sized icon, 320x176->160x88
|
||||||
icon_data = std::make_unique<image_info>(icon_buf);
|
|
||||||
static_cast<image_view*>(image.get())->set_raw_image(icon_data.get());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Fallback
|
|
||||||
static_cast<image_view*>(image.get())->set_image_resource(resource_config::standard_image_resource::save);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<overlay_element> text_stack = std::make_unique<vertical_layout>();
|
std::unique_ptr<overlay_element> text_stack = std::make_unique<vertical_layout>();
|
||||||
|
@ -74,10 +67,18 @@ namespace rsx
|
||||||
|
|
||||||
// Pack
|
// Pack
|
||||||
this->pack_padding = 15;
|
this->pack_padding = 15;
|
||||||
add_element(image);
|
m_image = add_element(image);
|
||||||
add_element(text_stack);
|
add_element(text_stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void save_dialog::save_dialog_entry::set_selected(bool selected)
|
||||||
|
{
|
||||||
|
if (m_image)
|
||||||
|
{
|
||||||
|
static_cast<video_view*>(m_image)->set_active(selected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
save_dialog::save_dialog()
|
save_dialog::save_dialog()
|
||||||
{
|
{
|
||||||
m_dim_background = std::make_unique<overlay_element>();
|
m_dim_background = std::make_unique<overlay_element>();
|
||||||
|
@ -197,7 +198,7 @@ namespace rsx
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 save_dialog::show(std::vector<SaveDataEntry>& save_entries, u32 focused, u32 op, vm::ptr<CellSaveDataListSet> listSet, bool enable_overlay)
|
s32 save_dialog::show(const std::string& base_dir, std::vector<SaveDataEntry>& save_entries, u32 focused, u32 op, vm::ptr<CellSaveDataListSet> listSet, bool enable_overlay)
|
||||||
{
|
{
|
||||||
rsx_log.notice("Showing native UI save_dialog (save_entries=%d, focused=%d, op=0x%x, listSet=*0x%x, enable_overlay=%d)", save_entries.size(), focused, op, listSet, enable_overlay);
|
rsx_log.notice("Showing native UI save_dialog (save_entries=%d, focused=%d, op=0x%x, listSet=*0x%x, enable_overlay=%d)", save_entries.size(), focused, op, listSet, enable_overlay);
|
||||||
|
|
||||||
|
@ -218,7 +219,7 @@ namespace rsx
|
||||||
{
|
{
|
||||||
const std::string date_and_size = fmt::format("%s %s", entry.date(), entry.data_size());
|
const std::string date_and_size = fmt::format("%s %s", entry.date(), entry.data_size());
|
||||||
std::unique_ptr<overlay_element> e;
|
std::unique_ptr<overlay_element> e;
|
||||||
e = std::make_unique<save_dialog_entry>(entry.subtitle, date_and_size, entry.details, image_resource_id::raw_image, entry.iconBuf);
|
e = std::make_unique<save_dialog_entry>(entry.subtitle, date_and_size, entry.details, image_resource_id::raw_image, entry.iconBuf, base_dir + entry.dirName + "/ICON1.PAM");
|
||||||
entries.emplace_back(std::move(e));
|
entries.emplace_back(std::move(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,7 +271,7 @@ namespace rsx
|
||||||
id = image_resource_id::raw_image;
|
id = image_resource_id::raw_image;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<overlay_element> new_stub = std::make_unique<save_dialog_entry>(title, get_localized_string(localized_string_id::CELL_SAVEDATA_NEW_SAVED_DATA_SUB_TITLE), "", id, icon);
|
std::unique_ptr<overlay_element> new_stub = std::make_unique<save_dialog_entry>(title, get_localized_string(localized_string_id::CELL_SAVEDATA_NEW_SAVED_DATA_SUB_TITLE), "", id, icon, "");
|
||||||
|
|
||||||
m_list->add_entry(new_stub);
|
m_list->add_entry(new_stub);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,11 +13,12 @@ namespace rsx
|
||||||
private:
|
private:
|
||||||
struct save_dialog_entry : horizontal_layout
|
struct save_dialog_entry : horizontal_layout
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
std::unique_ptr<image_info> icon_data;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
save_dialog_entry(const std::string& text1, const std::string& text2, const std::string& text3, u8 resource_id, const std::vector<u8>& icon_buf);
|
save_dialog_entry(const std::string& text1, const std::string& text2, const std::string& text3, u8 resource_id, const std::vector<u8>& icon_buf, const std::string& video_path);
|
||||||
|
void set_selected(bool selected) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
overlay_element* m_image = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<overlay_element> m_dim_background;
|
std::unique_ptr<overlay_element> m_dim_background;
|
||||||
|
@ -38,7 +39,7 @@ namespace rsx
|
||||||
|
|
||||||
compiled_resource get_compiled() override;
|
compiled_resource get_compiled() override;
|
||||||
|
|
||||||
s32 show(std::vector<SaveDataEntry>& save_entries, u32 focused, u32 op, vm::ptr<CellSaveDataListSet> listSet, bool enable_overlay);
|
s32 show(const std::string& base_dir, std::vector<SaveDataEntry>& save_entries, u32 focused, u32 op, vm::ptr<CellSaveDataListSet> listSet, bool enable_overlay);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
116
rpcs3/Emu/RSX/Overlays/overlay_video.cpp
Normal file
116
rpcs3/Emu/RSX/Overlays/overlay_video.cpp
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "overlay_video.h"
|
||||||
|
#include "Emu/System.h"
|
||||||
|
|
||||||
|
namespace rsx
|
||||||
|
{
|
||||||
|
namespace overlays
|
||||||
|
{
|
||||||
|
video_view::video_view(const std::string& video_path, const std::string& thumbnail_path)
|
||||||
|
{
|
||||||
|
init_video(video_path);
|
||||||
|
|
||||||
|
if (!thumbnail_path.empty())
|
||||||
|
{
|
||||||
|
m_thumbnail_info = std::make_unique<image_info>(thumbnail_path);
|
||||||
|
set_raw_image(m_thumbnail_info.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
video_view::video_view(const std::string& video_path, const std::vector<u8>& thumbnail_buf)
|
||||||
|
{
|
||||||
|
init_video(video_path);
|
||||||
|
|
||||||
|
if (!thumbnail_buf.empty())
|
||||||
|
{
|
||||||
|
m_thumbnail_info = std::make_unique<image_info>(thumbnail_buf);
|
||||||
|
set_raw_image(m_thumbnail_info.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
video_view::video_view(const std::string& video_path, u8 thumbnail_id)
|
||||||
|
: m_thumbnail_id(thumbnail_id)
|
||||||
|
{
|
||||||
|
init_video(video_path);
|
||||||
|
set_image_resource(thumbnail_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
video_view::~video_view()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void video_view::init_video(const std::string& video_path)
|
||||||
|
{
|
||||||
|
if (video_path.empty()) return;
|
||||||
|
|
||||||
|
m_video_source = Emu.GetCallbacks().make_video_source();
|
||||||
|
ensure(!!m_video_source);
|
||||||
|
|
||||||
|
m_video_source->set_update_callback([this]()
|
||||||
|
{
|
||||||
|
if (m_video_active)
|
||||||
|
{
|
||||||
|
m_is_compiled = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
m_video_source->set_video_path(video_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
void video_view::set_active(bool active)
|
||||||
|
{
|
||||||
|
if (m_video_source)
|
||||||
|
{
|
||||||
|
m_video_source->set_active(active);
|
||||||
|
m_video_active = active;
|
||||||
|
m_is_compiled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void video_view::update()
|
||||||
|
{
|
||||||
|
if (m_video_active && m_video_source && m_video_source->get_active())
|
||||||
|
{
|
||||||
|
if (!m_video_source->has_new())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_buffer_index = (m_buffer_index + 1) % m_video_info.size();
|
||||||
|
|
||||||
|
auto& info = m_video_info.at(m_buffer_index);
|
||||||
|
if (!info)
|
||||||
|
{
|
||||||
|
info = std::make_unique<video_info>();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_video_source->get_image(info->data, info->w, info->h, info->channels, info->bpp);
|
||||||
|
info->dirty = true;
|
||||||
|
|
||||||
|
set_raw_image(info.get());
|
||||||
|
m_is_compiled = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_thumbnail_info && m_thumbnail_info.get() != external_ref)
|
||||||
|
{
|
||||||
|
set_raw_image(m_thumbnail_info.get());
|
||||||
|
m_is_compiled = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_thumbnail_id != image_resource_id::none && m_thumbnail_id != image_resource_ref)
|
||||||
|
{
|
||||||
|
set_image_resource(m_thumbnail_id);
|
||||||
|
m_is_compiled = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
compiled_resource& video_view::get_compiled()
|
||||||
|
{
|
||||||
|
update();
|
||||||
|
|
||||||
|
return external_ref ? image_view::get_compiled() : overlay_element::get_compiled();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
40
rpcs3/Emu/RSX/Overlays/overlay_video.h
Normal file
40
rpcs3/Emu/RSX/Overlays/overlay_video.h
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "overlay_controls.h"
|
||||||
|
#include "util/video_source.h"
|
||||||
|
|
||||||
|
namespace rsx
|
||||||
|
{
|
||||||
|
namespace overlays
|
||||||
|
{
|
||||||
|
struct video_info : public image_info_base
|
||||||
|
{
|
||||||
|
std::vector<u8> data;
|
||||||
|
const u8* get_data() const override { return data.empty() ? nullptr : data.data(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
class video_view final : public image_view
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
video_view(const std::string& video_path, const std::string& thumbnail_path);
|
||||||
|
video_view(const std::string& video_path, const std::vector<u8>& thumbnail_buf);
|
||||||
|
video_view(const std::string& video_path, u8 thumbnail_id);
|
||||||
|
virtual ~video_view();
|
||||||
|
|
||||||
|
void set_active(bool active);
|
||||||
|
|
||||||
|
void update();
|
||||||
|
compiled_resource& get_compiled() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void init_video(const std::string& video_path);
|
||||||
|
|
||||||
|
usz m_buffer_index = 0;
|
||||||
|
std::array<std::unique_ptr<video_info>, 2> m_video_info; // double buffer
|
||||||
|
std::unique_ptr<video_source> m_video_source;
|
||||||
|
std::unique_ptr<image_info> m_thumbnail_info;
|
||||||
|
u8 m_thumbnail_id = image_resource_id::none;
|
||||||
|
bool m_video_active = false; // This is the expected state. The actual state is found in the video source.
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -386,22 +386,14 @@ namespace vk
|
||||||
VK_BLEND_OP_ADD, VK_BLEND_OP_ADD);
|
VK_BLEND_OP_ADD, VK_BLEND_OP_ADD);
|
||||||
}
|
}
|
||||||
|
|
||||||
vk::image_view* ui_overlay_renderer::upload_simple_texture(vk::render_device& dev, vk::command_buffer& cmd,
|
void ui_overlay_renderer::upload_simple_texture(vk::image* tex, vk::command_buffer& cmd,
|
||||||
vk::data_heap& upload_heap, u64 key, u32 w, u32 h, u32 layers, bool font, bool temp, const void* pixel_src, u32 owner_uid)
|
vk::data_heap& upload_heap, u32 w, u32 h, u32 layers, bool font, const void* pixel_src)
|
||||||
{
|
{
|
||||||
const VkFormat format = (font) ? VK_FORMAT_R8_UNORM : VK_FORMAT_B8G8R8A8_UNORM;
|
|
||||||
const u32 pitch = (font) ? w : w * 4;
|
const u32 pitch = (font) ? w : w * 4;
|
||||||
const u32 data_size = pitch * h * layers;
|
const u32 data_size = pitch * h * layers;
|
||||||
const auto offset = upload_heap.alloc<512>(data_size);
|
const auto offset = upload_heap.alloc<512>(data_size);
|
||||||
const auto addr = upload_heap.map(offset, data_size);
|
const auto addr = upload_heap.map(offset, data_size);
|
||||||
|
|
||||||
const VkImageSubresourceRange range = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, layers };
|
|
||||||
|
|
||||||
auto tex = std::make_unique<vk::image>(dev, dev.get_memory_mapping().device_local, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
|
||||||
VK_IMAGE_TYPE_2D, format, std::max(w, 1u), std::max(h, 1u), 1, 1, layers, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
|
|
||||||
VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
|
||||||
0, VMM_ALLOCATION_POOL_UNDEFINED);
|
|
||||||
|
|
||||||
if (pixel_src && data_size)
|
if (pixel_src && data_size)
|
||||||
std::memcpy(addr, pixel_src, data_size);
|
std::memcpy(addr, pixel_src, data_size);
|
||||||
else if (data_size)
|
else if (data_size)
|
||||||
|
@ -409,17 +401,31 @@ namespace vk
|
||||||
|
|
||||||
upload_heap.unmap();
|
upload_heap.unmap();
|
||||||
|
|
||||||
VkBufferImageCopy region;
|
const VkImageSubresourceRange range = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, layers };
|
||||||
region.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, layers };
|
VkBufferImageCopy region {
|
||||||
region.bufferOffset = offset;
|
.bufferOffset = offset,
|
||||||
region.bufferRowLength = w;
|
.bufferRowLength = w,
|
||||||
region.bufferImageHeight = h;
|
.bufferImageHeight = h,
|
||||||
region.imageOffset = {};
|
.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, layers },
|
||||||
region.imageExtent = { static_cast<u32>(w), static_cast<u32>(h), 1u };
|
.imageOffset = {},
|
||||||
|
.imageExtent = { static_cast<u32>(w), static_cast<u32>(h), 1u }
|
||||||
change_image_layout(cmd, tex.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, range);
|
};
|
||||||
|
change_image_layout(cmd, tex, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, range);
|
||||||
vkCmdCopyBufferToImage(cmd, upload_heap.heap->value, tex->value, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
vkCmdCopyBufferToImage(cmd, upload_heap.heap->value, tex->value, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
||||||
change_image_layout(cmd, tex.get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, range);
|
change_image_layout(cmd, tex, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, range);
|
||||||
|
}
|
||||||
|
|
||||||
|
vk::image_view* ui_overlay_renderer::upload_simple_texture(vk::render_device& dev, vk::command_buffer& cmd,
|
||||||
|
vk::data_heap& upload_heap, u64 key, u32 w, u32 h, u32 layers, bool font, bool temp, const void* pixel_src, u32 owner_uid)
|
||||||
|
{
|
||||||
|
const VkFormat format = (font) ? VK_FORMAT_R8_UNORM : VK_FORMAT_B8G8R8A8_UNORM;
|
||||||
|
|
||||||
|
auto tex = std::make_unique<vk::image>(dev, dev.get_memory_mapping().device_local, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||||
|
VK_IMAGE_TYPE_2D, format, std::max(w, 1u), std::max(h, 1u), 1, 1, layers, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
|
||||||
|
VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||||
|
0, VMM_ALLOCATION_POOL_UNDEFINED);
|
||||||
|
|
||||||
|
upload_simple_texture(tex.get(), cmd, upload_heap, w, h, layers, font, pixel_src);
|
||||||
|
|
||||||
auto view = std::make_unique<vk::image_view>(dev, tex.get());
|
auto view = std::make_unique<vk::image_view>(dev, tex.get());
|
||||||
|
|
||||||
|
@ -521,12 +527,23 @@ namespace vk
|
||||||
true, false, bytes.data(), -1);
|
true, false, bytes.data(), -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
vk::image_view* ui_overlay_renderer::find_temp_image(rsx::overlays::image_info* desc, vk::command_buffer& cmd, vk::data_heap& upload_heap, u32 owner_uid)
|
vk::image_view* ui_overlay_renderer::find_temp_image(rsx::overlays::image_info_base* desc, vk::command_buffer& cmd, vk::data_heap& upload_heap, u32 owner_uid)
|
||||||
{
|
{
|
||||||
u64 key = reinterpret_cast<u64>(desc);
|
const bool dirty = std::exchange(desc->dirty, false);
|
||||||
auto found = temp_view_cache.find(key);
|
const u64 key = reinterpret_cast<u64>(desc);
|
||||||
if (found != temp_view_cache.end())
|
|
||||||
return found->second.get();
|
auto cached = temp_view_cache.find(key);
|
||||||
|
if (cached != temp_view_cache.end())
|
||||||
|
{
|
||||||
|
vk::image_view* view = cached->second.get();
|
||||||
|
|
||||||
|
if (dirty)
|
||||||
|
{
|
||||||
|
upload_simple_texture(view->image(), cmd, upload_heap, desc->w, desc->h, 1, false, desc->get_data());
|
||||||
|
}
|
||||||
|
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
return upload_simple_texture(cmd.get_command_pool().get_owner(), cmd, upload_heap, key, desc->w, desc->h, 1,
|
return upload_simple_texture(cmd.get_command_pool().get_owner(), cmd, upload_heap, key, desc->w, desc->h, 1,
|
||||||
false, true, desc->get_data(), owner_uid);
|
false, true, desc->get_data(), owner_uid);
|
||||||
|
@ -693,7 +710,7 @@ namespace vk
|
||||||
: rsx::overlays::texture_sampling_mode::font3D;
|
: rsx::overlays::texture_sampling_mode::font3D;
|
||||||
break;
|
break;
|
||||||
case rsx::overlays::image_resource_id::raw_image:
|
case rsx::overlays::image_resource_id::raw_image:
|
||||||
src = find_temp_image(static_cast<rsx::overlays::image_info*>(command.config.external_data_ref), cmd, upload_heap, ui.uid);
|
src = find_temp_image(static_cast<rsx::overlays::image_info_base*>(command.config.external_data_ref), cmd, upload_heap, ui.uid);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
src = view_cache[command.config.texture_ref].get();
|
src = view_cache[command.config.texture_ref].get();
|
||||||
|
|
|
@ -154,6 +154,9 @@ namespace vk
|
||||||
|
|
||||||
ui_overlay_renderer();
|
ui_overlay_renderer();
|
||||||
|
|
||||||
|
void upload_simple_texture(vk::image* tex, vk::command_buffer& cmd,
|
||||||
|
vk::data_heap& upload_heap, u32 w, u32 h, u32 layers, bool font, const void* pixel_src);
|
||||||
|
|
||||||
vk::image_view* upload_simple_texture(vk::render_device& dev, vk::command_buffer& cmd,
|
vk::image_view* upload_simple_texture(vk::render_device& dev, vk::command_buffer& cmd,
|
||||||
vk::data_heap& upload_heap, u64 key, u32 w, u32 h, u32 layers, bool font, bool temp, const void* pixel_src, u32 owner_uid);
|
vk::data_heap& upload_heap, u64 key, u32 w, u32 h, u32 layers, bool font, bool temp, const void* pixel_src, u32 owner_uid);
|
||||||
|
|
||||||
|
@ -164,7 +167,7 @@ namespace vk
|
||||||
void remove_temp_resources(u32 key);
|
void remove_temp_resources(u32 key);
|
||||||
|
|
||||||
vk::image_view* find_font(rsx::overlays::font* font, vk::command_buffer& cmd, vk::data_heap& upload_heap);
|
vk::image_view* find_font(rsx::overlays::font* font, vk::command_buffer& cmd, vk::data_heap& upload_heap);
|
||||||
vk::image_view* find_temp_image(rsx::overlays::image_info* desc, vk::command_buffer& cmd, vk::data_heap& upload_heap, u32 owner_uid);
|
vk::image_view* find_temp_image(rsx::overlays::image_info_base* desc, vk::command_buffer& cmd, vk::data_heap& upload_heap, u32 owner_uid);
|
||||||
|
|
||||||
std::vector<VkPushConstantRange> get_push_constants() override;
|
std::vector<VkPushConstantRange> get_push_constants() override;
|
||||||
|
|
||||||
|
|
|
@ -111,6 +111,7 @@ struct EmuCallbacks
|
||||||
std::function<bool()> display_sleep_control_supported;
|
std::function<bool()> display_sleep_control_supported;
|
||||||
std::function<void(bool)> enable_display_sleep;
|
std::function<void(bool)> enable_display_sleep;
|
||||||
std::function<void()> check_microphone_permissions;
|
std::function<void()> check_microphone_permissions;
|
||||||
|
std::function<std::unique_ptr<class video_source>()> make_video_source;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace utils
|
namespace utils
|
||||||
|
|
|
@ -147,6 +147,7 @@
|
||||||
<ClCompile Include="Emu\RSX\Overlays\overlay_compile_notification.cpp" />
|
<ClCompile Include="Emu\RSX\Overlays\overlay_compile_notification.cpp" />
|
||||||
<ClCompile Include="Emu\RSX\Overlays\overlay_user_list_dialog.cpp" />
|
<ClCompile Include="Emu\RSX\Overlays\overlay_user_list_dialog.cpp" />
|
||||||
<ClCompile Include="Emu\RSX\Overlays\overlay_utils.cpp" />
|
<ClCompile Include="Emu\RSX\Overlays\overlay_utils.cpp" />
|
||||||
|
<ClCompile Include="Emu\RSX\Overlays\overlay_video.cpp" />
|
||||||
<ClCompile Include="Emu\RSX\Overlays\Shaders\shader_loading_dialog.cpp" />
|
<ClCompile Include="Emu\RSX\Overlays\Shaders\shader_loading_dialog.cpp" />
|
||||||
<ClCompile Include="Emu\RSX\Overlays\Shaders\shader_loading_dialog_native.cpp" />
|
<ClCompile Include="Emu\RSX\Overlays\Shaders\shader_loading_dialog_native.cpp" />
|
||||||
<ClCompile Include="Emu\RSX\Overlays\Trophies\overlay_trophy_list_dialog.cpp" />
|
<ClCompile Include="Emu\RSX\Overlays\Trophies\overlay_trophy_list_dialog.cpp" />
|
||||||
|
@ -682,6 +683,7 @@
|
||||||
<ClInclude Include="Emu\RSX\Overlays\overlay_manager.h" />
|
<ClInclude Include="Emu\RSX\Overlays\overlay_manager.h" />
|
||||||
<ClInclude Include="Emu\RSX\Overlays\overlay_media_list_dialog.h" />
|
<ClInclude Include="Emu\RSX\Overlays\overlay_media_list_dialog.h" />
|
||||||
<ClInclude Include="Emu\RSX\Overlays\overlay_progress_bar.hpp" />
|
<ClInclude Include="Emu\RSX\Overlays\overlay_progress_bar.hpp" />
|
||||||
|
<ClInclude Include="Emu\RSX\Overlays\overlay_video.h" />
|
||||||
<ClInclude Include="Emu\RSX\Overlays\Trophies\overlay_trophy_list_dialog.h" />
|
<ClInclude Include="Emu\RSX\Overlays\Trophies\overlay_trophy_list_dialog.h" />
|
||||||
<ClInclude Include="Emu\RSX\Program\FragmentProgramRegister.h" />
|
<ClInclude Include="Emu\RSX\Program\FragmentProgramRegister.h" />
|
||||||
<ClInclude Include="Emu\RSX\Program\GLSLTypes.h" />
|
<ClInclude Include="Emu\RSX\Program\GLSLTypes.h" />
|
||||||
|
|
|
@ -1354,6 +1354,9 @@
|
||||||
<ClCompile Include="Emu\RSX\Common\texture_cache_types.cpp">
|
<ClCompile Include="Emu\RSX\Common\texture_cache_types.cpp">
|
||||||
<Filter>Emu\GPU\RSX\Common</Filter>
|
<Filter>Emu\GPU\RSX\Common</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="Emu\RSX\Overlays\overlay_video.cpp">
|
||||||
|
<Filter>Emu\GPU\RSX\Overlays</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Crypto\aes.h">
|
<ClInclude Include="Crypto\aes.h">
|
||||||
|
@ -2719,6 +2722,9 @@
|
||||||
<ClInclude Include="util\video_source.h">
|
<ClInclude Include="util\video_source.h">
|
||||||
<Filter>Utilities</Filter>
|
<Filter>Utilities</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="Emu\RSX\Overlays\overlay_video.h">
|
||||||
|
<Filter>Emu\GPU\RSX\Overlays</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="Emu\RSX\Program\GLSLSnippets\GPUDeswizzle.glsl">
|
<None Include="Emu\RSX\Program\GLSLSnippets\GPUDeswizzle.glsl">
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "Emu/Cell/Modules/sceNpTrophy.h"
|
#include "Emu/Cell/Modules/sceNpTrophy.h"
|
||||||
#include "Emu/Io/Null/null_camera_handler.h"
|
#include "Emu/Io/Null/null_camera_handler.h"
|
||||||
#include "Emu/Io/Null/null_music_handler.h"
|
#include "Emu/Io/Null/null_music_handler.h"
|
||||||
|
#include "util/video_source.h"
|
||||||
|
|
||||||
#include <clocale>
|
#include <clocale>
|
||||||
|
|
||||||
|
@ -173,6 +174,8 @@ void headless_application::InitializeCallbacks()
|
||||||
|
|
||||||
callbacks.check_microphone_permissions = [](){};
|
callbacks.check_microphone_permissions = [](){};
|
||||||
|
|
||||||
|
callbacks.make_video_source = [](){ return nullptr; };
|
||||||
|
|
||||||
Emu.SetCallbacks(std::move(callbacks));
|
Emu.SetCallbacks(std::move(callbacks));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "Emu/vfs_config.h"
|
#include "Emu/vfs_config.h"
|
||||||
#include "util/init_mutex.hpp"
|
#include "util/init_mutex.hpp"
|
||||||
#include "util/console.h"
|
#include "util/console.h"
|
||||||
|
#include "qt_video_source.h"
|
||||||
#include "trophy_notification_helper.h"
|
#include "trophy_notification_helper.h"
|
||||||
#include "save_data_dialog.h"
|
#include "save_data_dialog.h"
|
||||||
#include "msg_dialog_frame.h"
|
#include "msg_dialog_frame.h"
|
||||||
|
@ -955,6 +956,8 @@ void gui_application::InitializeCallbacks()
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
callbacks.make_video_source = [](){ return std::make_unique<qt_video_source_wrapper>(); };
|
||||||
|
|
||||||
Emu.SetCallbacks(std::move(callbacks));
|
Emu.SetCallbacks(std::move(callbacks));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,9 +14,9 @@ qt_video_source::~qt_video_source()
|
||||||
stop_movie();
|
stop_movie();
|
||||||
}
|
}
|
||||||
|
|
||||||
void qt_video_source::set_video_path(const std::string& path)
|
void qt_video_source::set_video_path(const std::string& video_path)
|
||||||
{
|
{
|
||||||
m_video_path = QString::fromStdString(path);
|
m_video_path = QString::fromStdString(video_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void qt_video_source::set_active(bool active)
|
void qt_video_source::set_active(bool active)
|
||||||
|
@ -209,14 +209,14 @@ qt_video_source_wrapper::~qt_video_source_wrapper()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void qt_video_source_wrapper::set_video_path(const std::string& path)
|
void qt_video_source_wrapper::set_video_path(const std::string& video_path)
|
||||||
{
|
{
|
||||||
Emu.BlockingCallFromMainThread([this, &path]()
|
Emu.CallFromMainThread([this, path = video_path]()
|
||||||
{
|
{
|
||||||
m_qt_video_source = std::make_unique<qt_video_source>();
|
m_qt_video_source = std::make_unique<qt_video_source>();
|
||||||
m_qt_video_source->m_image_change_callback = [this](const QVideoFrame& frame)
|
m_qt_video_source->m_image_change_callback = [this](const QVideoFrame& frame)
|
||||||
{
|
{
|
||||||
std::lock_guard lock(m_qt_video_source->m_image_mutex);
|
std::unique_lock lock(m_qt_video_source->m_image_mutex);
|
||||||
|
|
||||||
if (m_qt_video_source->m_movie)
|
if (m_qt_video_source->m_movie)
|
||||||
{
|
{
|
||||||
|
@ -236,12 +236,30 @@ void qt_video_source_wrapper::set_video_path(const std::string& path)
|
||||||
{
|
{
|
||||||
m_qt_video_source->m_image.convertTo(QImage::Format_RGBA8888);
|
m_qt_video_source->m_image.convertTo(QImage::Format_RGBA8888);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lock.unlock();
|
||||||
|
|
||||||
|
notify_update();
|
||||||
};
|
};
|
||||||
m_qt_video_source->set_video_path(path);
|
m_qt_video_source->set_video_path(path);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void qt_video_source_wrapper::set_active(bool active)
|
||||||
|
{
|
||||||
|
Emu.CallFromMainThread([this, active]()
|
||||||
|
{
|
||||||
m_qt_video_source->set_active(true);
|
m_qt_video_source->set_active(true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool qt_video_source_wrapper::get_active() const
|
||||||
|
{
|
||||||
|
ensure(m_qt_video_source);
|
||||||
|
|
||||||
|
return m_qt_video_source->get_active();
|
||||||
|
}
|
||||||
|
|
||||||
void qt_video_source_wrapper::get_image(std::vector<u8>& data, int& w, int& h, int& ch, int& bpp)
|
void qt_video_source_wrapper::get_image(std::vector<u8>& data, int& w, int& h, int& ch, int& bpp)
|
||||||
{
|
{
|
||||||
ensure(m_qt_video_source);
|
ensure(m_qt_video_source);
|
||||||
|
|
|
@ -17,17 +17,14 @@ public:
|
||||||
qt_video_source();
|
qt_video_source();
|
||||||
virtual ~qt_video_source();
|
virtual ~qt_video_source();
|
||||||
|
|
||||||
void set_video_path(const std::string& path) override;
|
void set_video_path(const std::string& video_path) override;
|
||||||
const QString& video_path() const { return m_video_path; }
|
const QString& video_path() const { return m_video_path; }
|
||||||
|
|
||||||
void get_image(std::vector<u8>& data, int& w, int& h, int& ch, int& bpp) override;
|
void get_image(std::vector<u8>& data, int& w, int& h, int& ch, int& bpp) override;
|
||||||
bool has_new() const override { return m_has_new; }
|
bool has_new() const override { return m_has_new; }
|
||||||
|
|
||||||
virtual void set_active(bool active);
|
virtual void set_active(bool active);
|
||||||
[[nodiscard]] bool get_active() const
|
bool get_active() const override { return m_active; }
|
||||||
{
|
|
||||||
return m_active;
|
|
||||||
}
|
|
||||||
|
|
||||||
void start_movie();
|
void start_movie();
|
||||||
void stop_movie();
|
void stop_movie();
|
||||||
|
@ -67,9 +64,11 @@ public:
|
||||||
qt_video_source_wrapper() : video_source() {}
|
qt_video_source_wrapper() : video_source() {}
|
||||||
virtual ~qt_video_source_wrapper();
|
virtual ~qt_video_source_wrapper();
|
||||||
|
|
||||||
void set_video_path(const std::string& path) override;
|
void set_video_path(const std::string& video_path) override;
|
||||||
void get_image(std::vector<u8>& data, int& w, int& h, int& ch, int& bpp) override;
|
void set_active(bool active) override;
|
||||||
|
bool get_active() const override;
|
||||||
bool has_new() const override { return m_qt_video_source && m_qt_video_source->has_new(); }
|
bool has_new() const override { return m_qt_video_source && m_qt_video_source->has_new(); }
|
||||||
|
void get_image(std::vector<u8>& data, int& w, int& h, int& ch, int& bpp) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<qt_video_source> m_qt_video_source;
|
std::unique_ptr<qt_video_source> m_qt_video_source;
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
LOG_CHANNEL(cellSaveData);
|
LOG_CHANNEL(cellSaveData);
|
||||||
|
|
||||||
s32 save_data_dialog::ShowSaveDataList(std::vector<SaveDataEntry>& save_entries, s32 focused, u32 op, vm::ptr<CellSaveDataListSet> listSet, bool enable_overlay)
|
s32 save_data_dialog::ShowSaveDataList(const std::string& base_dir, std::vector<SaveDataEntry>& save_entries, s32 focused, u32 op, vm::ptr<CellSaveDataListSet> listSet, bool enable_overlay)
|
||||||
{
|
{
|
||||||
cellSaveData.notice("ShowSaveDataList(save_entries=%d, focused=%d, op=0x%x, listSet=*0x%x, enable_overlay=%d)", save_entries.size(), focused, op, listSet, enable_overlay);
|
cellSaveData.notice("ShowSaveDataList(save_entries=%d, focused=%d, op=0x%x, listSet=*0x%x, enable_overlay=%d)", save_entries.size(), focused, op, listSet, enable_overlay);
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ s32 save_data_dialog::ShowSaveDataList(std::vector<SaveDataEntry>& save_entries,
|
||||||
{
|
{
|
||||||
cellSaveData.notice("ShowSaveDataList: Showing native UI dialog");
|
cellSaveData.notice("ShowSaveDataList: Showing native UI dialog");
|
||||||
|
|
||||||
const s32 result = manager->create<rsx::overlays::save_dialog>()->show(save_entries, focused, op, listSet, enable_overlay);
|
const s32 result = manager->create<rsx::overlays::save_dialog>()->show(base_dir, save_entries, focused, op, listSet, enable_overlay);
|
||||||
if (result != rsx::overlays::user_interface::selection_code::error)
|
if (result != rsx::overlays::user_interface::selection_code::error)
|
||||||
{
|
{
|
||||||
cellSaveData.notice("ShowSaveDataList: Native UI dialog returned with selection %d", result);
|
cellSaveData.notice("ShowSaveDataList: Native UI dialog returned with selection %d", result);
|
||||||
|
|
|
@ -6,5 +6,5 @@
|
||||||
class save_data_dialog : public SaveDialogBase
|
class save_data_dialog : public SaveDialogBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
s32 ShowSaveDataList(std::vector<SaveDataEntry>& save_entries, s32 focused, u32 op, vm::ptr<CellSaveDataListSet> listSet, bool enable_overlay) override;
|
s32 ShowSaveDataList(const std::string& base_dir, std::vector<SaveDataEntry>& save_entries, s32 focused, u32 op, vm::ptr<CellSaveDataListSet> listSet, bool enable_overlay) override;
|
||||||
};
|
};
|
||||||
|
|
|
@ -586,7 +586,7 @@ void save_manager_dialog::OnEntriesRemove()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pop-up a small context-menu, being a replacement for save_data_manage_dialog
|
// Pop-up a small context-menu, being a replacement for save_data_manage_dialog
|
||||||
void save_manager_dialog::ShowContextMenu(const QPoint &pos)
|
void save_manager_dialog::ShowContextMenu(const QPoint& pos)
|
||||||
{
|
{
|
||||||
const int idx = m_list->currentRow();
|
const int idx = m_list->currentRow();
|
||||||
if (idx == -1)
|
if (idx == -1)
|
||||||
|
|
|
@ -42,7 +42,7 @@ private:
|
||||||
void Init();
|
void Init();
|
||||||
void UpdateList();
|
void UpdateList();
|
||||||
void UpdateIcons();
|
void UpdateIcons();
|
||||||
void ShowContextMenu(const QPoint &pos);
|
void ShowContextMenu(const QPoint& pos);
|
||||||
void WaitForRepaintThreads(bool abort);
|
void WaitForRepaintThreads(bool abort);
|
||||||
|
|
||||||
void closeEvent(QCloseEvent* event) override;
|
void closeEvent(QCloseEvent* event) override;
|
||||||
|
|
|
@ -1,20 +1,33 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "types.hpp"
|
#include "types.hpp"
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
class video_source
|
class video_source
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
video_source() {};
|
video_source() {};
|
||||||
virtual ~video_source() {};
|
virtual ~video_source() {};
|
||||||
virtual void set_video_path(const std::string& path) { static_cast<void>(path); }
|
virtual void set_video_path(const std::string& video_path) = 0;
|
||||||
virtual bool has_new() const { return false; };
|
virtual void set_active(bool active) = 0;
|
||||||
virtual void get_image(std::vector<u8>& data, int& w, int& h, int& ch, int& bpp)
|
virtual bool get_active() const = 0;
|
||||||
|
virtual bool has_new() const = 0;
|
||||||
|
virtual void get_image(std::vector<u8>& data, int& w, int& h, int& ch, int& bpp) = 0;
|
||||||
|
|
||||||
|
void set_update_callback(std::function<void()> callback)
|
||||||
{
|
{
|
||||||
static_cast<void>(data);
|
m_update_callback = callback;
|
||||||
static_cast<void>(w);
|
|
||||||
static_cast<void>(h);
|
|
||||||
static_cast<void>(ch);
|
|
||||||
static_cast<void>(bpp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void notify_update()
|
||||||
|
{
|
||||||
|
if (m_update_callback)
|
||||||
|
{
|
||||||
|
m_update_callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::function<void()> m_update_callback;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue