Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cellSaveData: Add autosave indicator #15720

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions rpcs3/Emu/Cell/Modules/cellSaveData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "Emu/Cell/PPUModule.h"
#include "Emu/Cell/Modules/cellSysutil.h"
#include "Emu/Cell/Modules/cellUserInfo.h"
#include "Emu/RSX/Overlays/overlay_message.h"

#include "cellSaveData.h"
#include "cellMsgDialog.h"
Expand Down Expand Up @@ -1750,6 +1751,48 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v

fileGet->excSize = 0;

// show indicator for automatic save or auto load interactions if the game requests it (statSet->indicator)
const bool show_auto_indicator = operation <= SAVEDATA_OP_LIST_AUTO_LOAD && statSet && statSet->indicator;

if (show_auto_indicator)
{
auto msg_text = localized_string_id::INVALID;
if (operation == SAVEDATA_OP_AUTO_SAVE || operation == SAVEDATA_OP_LIST_AUTO_SAVE)
{
msg_text = localized_string_id::CELL_SAVEDATA_AUTOSAVE;
}
else if (operation == SAVEDATA_OP_AUTO_LOAD || operation == SAVEDATA_OP_LIST_AUTO_LOAD)
{
msg_text = localized_string_id::CELL_SAVEDATA_AUTOLOAD;
}

u32 indicator_pos = (statSet->indicator->dispPosition & 0x0F);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
u32 indicator_pos = (statSet->indicator->dispPosition & 0x0F);
const u32 indicator_pos = (statSet->indicator->dispPosition & 0x0F);


auto msg_location = rsx::overlays::message_pin_location::top;
switch (indicator_pos)
{
case CELL_SAVEDATA_INDICATORPOS_UPPER_LEFT:
msg_location = rsx::overlays::message_pin_location::top;
break;
case CELL_SAVEDATA_INDICATORPOS_LOWER_LEFT:
msg_location = rsx::overlays::message_pin_location::bottom;
break;
case CELL_SAVEDATA_INDICATORPOS_UPPER_RIGHT:
msg_location = rsx::overlays::message_pin_location::top_right;
break;
case CELL_SAVEDATA_INDICATORPOS_LOWER_RIGHT:
msg_location = rsx::overlays::message_pin_location::bottom_right;
break;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing default


// TODO: Blinking variants

// RPCS3 saves basically instantaneously so there's not much point in showing auto indicator
// WHILE saving is in progress. Instead we show the indicator for 3 seconds to let the user
// know when the game autosaves.
rsx::overlays::queue_message(msg_text, 3'000'000, {}, msg_location);
}

error_code savedata_result = CELL_OK;

u64 delay_save_until = 0;
Expand Down Expand Up @@ -2098,6 +2141,11 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v
fs::remove_all(old_path);
}

if (show_auto_indicator)
{
// auto indicator should be hidden here if save/load throttling is added
}

if (savedata_result + 0u == CELL_SAVEDATA_ERROR_CBRESULT)
{
return display_callback_result_error_message(ppu, *result, errDialog);
Expand Down
40 changes: 34 additions & 6 deletions rpcs3/Emu/RSX/Overlays/overlay_message.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,12 @@ namespace rsx
return compiled_resources;
}

void message_item::update(usz index, u64 timestamp_us, s16 y_offset)
void message_item::update(usz index, u64 timestamp_us, s16 x_offset, s16 y_offset)
{
if (m_cur_pos != index)
{
m_cur_pos = index;
set_pos(10, y_offset);
set_pos(x_offset, y_offset);
}

if (!m_processed)
Expand Down Expand Up @@ -198,18 +198,29 @@ namespace rsx
// Render reversed list. Oldest entries are furthest from the border
constexpr u16 spacing = 4;
s16 y_offset = 8;
s16 x_offset = 10;
usz index = 0;
for (auto it = vis_set.rbegin(); it != vis_set.rend(); ++it, ++index)
{
if (origin == message_pin_location::top) [[ likely ]]
{
it->update(index, cur_time, y_offset);
it->update(index, cur_time, x_offset, y_offset);
y_offset += (spacing + it->h);
}
else
else if (origin == message_pin_location::bottom)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use a switch

{
y_offset += (spacing + it->h);
it->update(index, cur_time, x_offset, virtual_height - y_offset);
}
else if (origin == message_pin_location::top_right)
{
it->update(index, cur_time, virtual_width - x_offset - it->w, y_offset);
y_offset += (spacing + it->h);
it->update(index, cur_time, virtual_height - y_offset);
}
else if (origin == message_pin_location::bottom_right)
{
y_offset += (spacing + it->h);
it->update(index, cur_time, virtual_width - x_offset - it->w, virtual_height - y_offset);
}
}
}
Expand All @@ -225,8 +236,11 @@ namespace rsx

update_queue(m_visible_items_top, m_ready_queue_top, message_pin_location::top);
update_queue(m_visible_items_bottom, m_ready_queue_bottom, message_pin_location::bottom);
update_queue(m_visible_items_top_right, m_ready_queue_top_right, message_pin_location::top_right);
update_queue(m_visible_items_bottom_right, m_ready_queue_bottom_right, message_pin_location::bottom_right);

visible = !m_visible_items_top.empty() || !m_visible_items_bottom.empty();
visible = !m_visible_items_top.empty() || !m_visible_items_bottom.empty() ||
!m_visible_items_top_right.empty() || !m_visible_items_bottom_right.empty();
}

compiled_resource message::get_compiled()
Expand All @@ -250,6 +264,16 @@ namespace rsx
cr.add(item.get_compiled());
}

for (auto& item : m_visible_items_top_right)
{
cr.add(item.get_compiled());
}

for (auto& item : m_visible_items_bottom_right)
{
cr.add(item.get_compiled());
}

return cr;
}

Expand Down Expand Up @@ -287,6 +311,10 @@ namespace rsx
return check_list(m_ready_queue_top) || check_list(m_visible_items_top);
case message_pin_location::bottom:
return check_list(m_ready_queue_bottom) || check_list(m_visible_items_bottom);
case message_pin_location::top_right:
return check_list(m_ready_queue_top_right) || check_list(m_visible_items_top_right);
case message_pin_location::bottom_right:
return check_list(m_ready_queue_bottom_right) || check_list(m_visible_items_bottom_right);
}

return false;
Expand Down
34 changes: 27 additions & 7 deletions rpcs3/Emu/RSX/Overlays/overlay_message.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,17 @@ namespace rsx
enum class message_pin_location
{
top,
bottom
bottom,
top_right,
bottom_right
};

class message_item : public rounded_rect
{
public:
template <typename T>
message_item(T msg_id, u64 expiration, std::shared_ptr<atomic_t<u32>> refs, std::shared_ptr<overlay_element> icon = {});
void update(usz index, u64 timestamp_us, s16 y_offset);
void update(usz index, u64 timestamp_us, s16 x_offset, s16 y_offset);
void set_pos(s16 _x, s16 _y) override;

void reset_expiration();
Expand Down Expand Up @@ -61,23 +63,37 @@ namespace rsx
{
std::lock_guard lock(m_mutex_queue);

auto& queue = location == message_pin_location::top
? m_ready_queue_top
: m_ready_queue_bottom;
auto* queue = &m_ready_queue_top;

switch (location)
{
case message_pin_location::top:
queue = &m_ready_queue_top;
break;
case message_pin_location::bottom:
queue = &m_ready_queue_bottom;
break;
case message_pin_location::top_right:
queue = &m_ready_queue_top_right;
break;
case message_pin_location::bottom_right:
queue = &m_ready_queue_bottom_right;
break;
}

if constexpr (std::is_same_v<T, std::initializer_list<localized_string_id>>)
{
for (auto id : msg_id)
{
if (!message_exists(location, id, allow_refresh))
{
queue.emplace_back(id, expiration, refs, icon);
queue->emplace_back(id, expiration, refs, icon);
}
}
}
else if (!message_exists(location, msg_id, allow_refresh))
{
queue.emplace_back(msg_id, expiration, std::move(refs), icon);
queue->emplace_back(msg_id, expiration, std::move(refs), icon);
}

visible = true;
Expand All @@ -91,10 +107,14 @@ namespace rsx
// Top and bottom enqueued sets
std::deque<message_item> m_ready_queue_top;
std::deque<message_item> m_ready_queue_bottom;
std::deque<message_item> m_ready_queue_top_right;
std::deque<message_item> m_ready_queue_bottom_right;

// Top and bottom visible sets
std::deque<message_item> m_visible_items_top;
std::deque<message_item> m_visible_items_bottom;
std::deque<message_item> m_visible_items_top_right;
std::deque<message_item> m_visible_items_bottom_right;

void update_queue(std::deque<message_item>& vis_set, std::deque<message_item>& ready_set, message_pin_location origin);

Expand Down
2 changes: 2 additions & 0 deletions rpcs3/Emu/localized_string_id.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ enum class localized_string_id
CELL_SAVEDATA_SAVE,
CELL_SAVEDATA_LOAD,
CELL_SAVEDATA_OVERWRITE,
CELL_SAVEDATA_AUTOSAVE,
CELL_SAVEDATA_AUTOLOAD,

CELL_CROSS_CONTROLLER_MSG,
CELL_CROSS_CONTROLLER_FW_MSG,
Expand Down
2 changes: 2 additions & 0 deletions rpcs3/rpcs3qt/localized_emu.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@ class localized_emu : public QObject
case localized_string_id::CELL_SAVEDATA_DELETE: return tr("Delete this data?\n\n%0", "Savedata entry info").arg(std::forward<Args>(args)...);
case localized_string_id::CELL_SAVEDATA_LOAD: return tr("Load this data?\n\n%0", "Savedata entry info").arg(std::forward<Args>(args)...);
case localized_string_id::CELL_SAVEDATA_OVERWRITE: return tr("Do you want to overwrite the saved data?\n\n%0", "Savedata entry info").arg(std::forward<Args>(args)...);
case localized_string_id::CELL_SAVEDATA_AUTOSAVE: return tr("Saving...");
case localized_string_id::CELL_SAVEDATA_AUTOLOAD: return tr("Loading...");
case localized_string_id::CELL_CROSS_CONTROLLER_MSG: return tr("Start [%0] on the PS Vita system.\nIf you have not installed [%0], go to [Remote Play] on the PS Vita system and start [Cross-Controller] from the LiveArea™ screen.", "Cross-Controller message").arg(std::forward<Args>(args)...);
case localized_string_id::CELL_CROSS_CONTROLLER_FW_MSG: return tr("If your system software version on the PS Vita system is earlier than 1.80, you must update the system software to the latest version.", "Cross-Controller firmware message");
case localized_string_id::CELL_NP_RECVMESSAGE_DIALOG_TITLE: return tr("Select Message", "RECVMESSAGE_DIALOG");
Expand Down