Improve save data dialog

Bug fix: don't display new data entry when not asked for
Use icon/title provided by the game for the new data entry
Display new data entry at the beginning of list when necessary
Minor cellSaveData cleanup
This commit is contained in:
Nekotekina 2018-04-02 14:27:38 +03:00
parent 0e74f2e340
commit da9baac842
3 changed files with 69 additions and 20 deletions

View File

@ -126,7 +126,7 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
listGet->dirListNum++; // number of directories in list listGet->dirListNum++; // number of directories in list
// PSF parameters // 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()) 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.atime = entry.atime;
save_entry2.mtime = entry.mtime; save_entry2.mtime = entry.mtime;
save_entry2.ctime = entry.ctime; save_entry2.ctime = entry.ctime;
if (fs::is_file(base_dir + entry.name + "/ICON0.PNG")) if (fs::file icon{base_dir + entry.name + "/ICON0.PNG"})
{ save_entry2.iconBuf = icon.to_vector<uchar>();
fs::file icon = fs::file(base_dir + entry.name + "/ICON0.PNG");
u64 iconSize = icon.size();
std::vector<uchar> iconData;
icon.read(iconData, iconSize);
save_entry2.iconBuf = iconData;
}
save_entry2.isNew = false; save_entry2.isNew = false;
save_entries.emplace_back(save_entry2); 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 dir_path = base_dir + save_entry.dirName + "/";
std::string sfo_path = dir_path + "PARAM.SFO"; 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 // Get save stats
{ {

View File

@ -94,6 +94,12 @@ enum
CELL_SAVEDATA_RECREATE_MASK = 0xffff, CELL_SAVEDATA_RECREATE_MASK = 0xffff,
}; };
// CellSaveDataListNewData::iconPosition
enum : u32
{
CELL_SAVEDATA_ICONPOS_HEAD = 0,
CELL_SAVEDATA_ICONPOS_TAIL = 1,
};
// Datatypes // Datatypes
struct CellSaveDataSetList struct CellSaveDataSetList

View File

@ -332,15 +332,16 @@ namespace rsx
return result; return result;
} }
s32 show(std::vector<SaveDataEntry>& save_entries, u32 op, vm::ptr<CellSaveDataListSet> /*listSet*/) s32 show(std::vector<SaveDataEntry>& save_entries, u32 op, vm::ptr<CellSaveDataListSet> listSet)
{ {
std::vector<u8> null_icon; std::vector<u8> icon;
auto num_actual_saves = save_entries.size(); std::vector<std::unique_ptr<overlay_element>> entries;
for (auto &entry : save_entries) for (auto& entry : save_entries)
{ {
std::unique_ptr<overlay_element> e = std::make_unique<save_dialog_entry>(entry.title.c_str(), (entry.subtitle + " - " + entry.details).c_str(), image_resource_id::raw_image, entry.iconBuf); std::unique_ptr<overlay_element> e;
m_list->add_entry(e); e = std::make_unique<save_dialog_entry>(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) if (op >= 8)
@ -353,11 +354,57 @@ namespace rsx
} }
else else
{ {
m_description->text = "Create Save"; m_description->text = "Save";
std::unique_ptr<overlay_element> new_stub = std::make_unique<save_dialog_entry>("Create New", "Select to create a new entry", resource_config::standard_image_resource::new_entry, null_icon); }
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<overlay_element> 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<u8*>(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<save_dialog_entry>(title, "Select to create a new entry", id, icon);
m_list->add_entry(new_stub); m_list->add_entry(new_stub);
} }
if (newpos_head)
{
for (auto& entry : entries)
{
m_list->add_entry(entry);
}
}
if (!m_list->m_items.size()) if (!m_list->m_items.size())
{ {
m_no_saves_text = std::make_unique<label>(); m_no_saves_text = std::make_unique<label>();
@ -367,7 +414,7 @@ namespace rsx
m_no_saves_text->set_size(m_list->w, 30); m_no_saves_text->set_size(m_list->w, 30);
m_no_saves_text->set_text("There is no saved data."); m_no_saves_text->set_text("There is no saved data.");
m_no_saves_text->back_color.a = 0; m_no_saves_text->back_color.a = 0;
m_no_saves = true; m_no_saves = true;
m_list->set_cancel_only(true); m_list->set_cancel_only(true);
} }
@ -377,8 +424,10 @@ namespace rsx
if (auto err = run_input_loop()) if (auto err = run_input_loop())
return err; return err;
if (return_code == num_actual_saves) if (return_code == entries.size() && !newpos_head)
return selection_code::new_save; return selection_code::new_save;
if (return_code >= 0 && newpos_head)
return return_code - 1;
return return_code; return return_code;
} }