diff --git a/rpcs3/Emu/Cell/Modules/cellSaveData.cpp b/rpcs3/Emu/Cell/Modules/cellSaveData.cpp index ad38c68683a2..57e9e4262cef 100644 --- a/rpcs3/Emu/Cell/Modules/cellSaveData.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSaveData.cpp @@ -126,7 +126,7 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version, listGet->dirListNum++; // number of directories in list // PSF parameters - const auto& psf = psf::load_object(fs::file(base_dir + entry.name + "/PARAM.SFO")); + const psf::registry psf = psf::load_object(fs::file(base_dir + entry.name + "/PARAM.SFO")); if (psf.empty()) { @@ -150,14 +150,8 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version, save_entry2.atime = entry.atime; save_entry2.mtime = entry.mtime; save_entry2.ctime = entry.ctime; - if (fs::is_file(base_dir + entry.name + "/ICON0.PNG")) - { - fs::file icon = fs::file(base_dir + entry.name + "/ICON0.PNG"); - u64 iconSize = icon.size(); - std::vector iconData; - icon.read(iconData, iconSize); - save_entry2.iconBuf = iconData; - } + if (fs::file icon{base_dir + entry.name + "/ICON0.PNG"}) + save_entry2.iconBuf = icon.to_vector(); save_entry2.isNew = false; save_entries.emplace_back(save_entry2); } @@ -477,7 +471,7 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version, std::string dir_path = base_dir + save_entry.dirName + "/"; std::string sfo_path = dir_path + "PARAM.SFO"; - auto&& psf = psf::load_object(fs::file(sfo_path)); + psf::registry psf = psf::load_object(fs::file(sfo_path)); // Get save stats { diff --git a/rpcs3/Emu/Cell/Modules/cellSaveData.h b/rpcs3/Emu/Cell/Modules/cellSaveData.h index 5793feb7a592..a1cebdbca784 100644 --- a/rpcs3/Emu/Cell/Modules/cellSaveData.h +++ b/rpcs3/Emu/Cell/Modules/cellSaveData.h @@ -94,6 +94,12 @@ enum CELL_SAVEDATA_RECREATE_MASK = 0xffff, }; +// CellSaveDataListNewData::iconPosition +enum : u32 +{ + CELL_SAVEDATA_ICONPOS_HEAD = 0, + CELL_SAVEDATA_ICONPOS_TAIL = 1, +}; // Datatypes struct CellSaveDataSetList diff --git a/rpcs3/Emu/RSX/overlays.h b/rpcs3/Emu/RSX/overlays.h index a17e13ee51ef..00d7bb7a18d4 100644 --- a/rpcs3/Emu/RSX/overlays.h +++ b/rpcs3/Emu/RSX/overlays.h @@ -332,15 +332,16 @@ namespace rsx return result; } - s32 show(std::vector& save_entries, u32 op, vm::ptr /*listSet*/) + s32 show(std::vector& save_entries, u32 op, vm::ptr listSet) { - std::vector null_icon; - auto num_actual_saves = save_entries.size(); + std::vector icon; + std::vector> entries; - for (auto &entry : save_entries) + for (auto& entry : save_entries) { - std::unique_ptr e = std::make_unique(entry.title.c_str(), (entry.subtitle + " - " + entry.details).c_str(), image_resource_id::raw_image, entry.iconBuf); - m_list->add_entry(e); + std::unique_ptr e; + e = std::make_unique(entry.title.c_str(), (entry.subtitle + " - " + entry.details).c_str(), image_resource_id::raw_image, entry.iconBuf); + entries.emplace_back(std::move(e)); } if (op >= 8) @@ -353,11 +354,57 @@ namespace rsx } else { - m_description->text = "Create Save"; - std::unique_ptr new_stub = std::make_unique("Create New", "Select to create a new entry", resource_config::standard_image_resource::new_entry, null_icon); + m_description->text = "Save"; + } + + const bool newpos_head = listSet->newData && listSet->newData->iconPosition == CELL_SAVEDATA_ICONPOS_HEAD; + + if (!newpos_head) + { + for (auto& entry : entries) + { + m_list->add_entry(entry); + } + } + + if (listSet->newData) + { + std::unique_ptr new_stub; + + const char* title = "Create New"; + + int id = resource_config::standard_image_resource::new_entry; + + if (auto picon = +listSet->newData->icon) + { + title = picon->title.get_ptr(); + + if (picon->iconBuf && picon->iconBufSize && picon->iconBufSize <= 225280) + { + const auto iconBuf = static_cast(picon->iconBuf.get_ptr()); + const auto iconEnd = iconBuf + picon->iconBufSize; + icon.assign(iconBuf, iconEnd); + } + } + + if (!icon.empty()) + { + id = image_resource_id::raw_image; + } + + new_stub = std::make_unique(title, "Select to create a new entry", id, icon); + m_list->add_entry(new_stub); } + if (newpos_head) + { + for (auto& entry : entries) + { + m_list->add_entry(entry); + } + } + if (!m_list->m_items.size()) { m_no_saves_text = std::make_unique