Add a message overlay

This commit is contained in:
RipleyTom 2022-05-17 16:35:41 +02:00 committed by Megamouse
parent 3dc9a8b980
commit e68ffdbc81
11 changed files with 259 additions and 27 deletions

View file

@ -431,6 +431,7 @@ target_sources(rpcs3_emu PRIVATE
RSX/Overlays/overlay_fonts.cpp
RSX/Overlays/overlay_list_view.cpp
RSX/Overlays/overlay_media_list_dialog.cpp
RSX/Overlays/overlay_message.cpp
RSX/Overlays/overlay_message_dialog.cpp
RSX/Overlays/overlay_osk.cpp
RSX/Overlays/overlay_osk_panel.cpp

View file

@ -13,6 +13,7 @@
#include "Emu/NP/rpcn_config.h"
#include "Emu/NP/np_contexts.h"
#include "Emu/NP/np_helpers.h"
#include "Emu/RSX/Overlays/overlay_message.h"
#ifdef _WIN32
#include <winsock2.h>
@ -591,6 +592,7 @@ namespace np
if (auto state = rpcn->wait_for_connection(); state != rpcn::rpcn_state::failure_no_failure)
{
rsx::overlays::queue_message(rpcn::rpcn_state_to_localized_string_id(state));
rpcn_log.error("Connection to RPCN Failed!");
is_psn_active = false;
return;
@ -598,11 +600,14 @@ namespace np
if (auto state = rpcn->wait_for_authentified(); state != rpcn::rpcn_state::failure_no_failure)
{
rsx::overlays::queue_message(rpcn::rpcn_state_to_localized_string_id(state));
rpcn_log.error("RPCN login attempt failed!");
is_psn_active = false;
return;
}
rsx::overlays::queue_message(localized_string_id::RPCN_SUCCESS_LOGGED_ON);
string_to_online_name(rpcn->get_online_name(), &online_name);
string_to_avatar_url(rpcn->get_avatar_url(), &avatar_url);
public_ip_addr = rpcn->get_addr_sig();

View file

@ -49,6 +49,31 @@ std::vector<std::vector<u8>> get_rpcn_msgs();
namespace rpcn
{
localized_string_id rpcn_state_to_localized_string_id(rpcn::rpcn_state state)
{
switch (state)
{
case rpcn::rpcn_state::failure_no_failure: return localized_string_id::RPCN_NO_ERROR;
case rpcn::rpcn_state::failure_input: return localized_string_id::RPCN_ERROR_INVALID_INPUT;
case rpcn::rpcn_state::failure_wolfssl: return localized_string_id::RPCN_ERROR_WOLFSSL;
case rpcn::rpcn_state::failure_resolve: return localized_string_id::RPCN_ERROR_RESOLVE;
case rpcn::rpcn_state::failure_connect: return localized_string_id::RPCN_ERROR_CONNECT;
case rpcn::rpcn_state::failure_id: return localized_string_id::RPCN_ERROR_LOGIN_ERROR;
case rpcn::rpcn_state::failure_id_already_logged_in: return localized_string_id::RPCN_ERROR_ALREADY_LOGGED;
case rpcn::rpcn_state::failure_id_username: return localized_string_id::RPCN_ERROR_INVALID_LOGIN;
case rpcn::rpcn_state::failure_id_password: return localized_string_id::RPCN_ERROR_INVALID_PASSWORD;
case rpcn::rpcn_state::failure_id_token: return localized_string_id::RPCN_ERROR_INVALID_TOKEN;
case rpcn::rpcn_state::failure_protocol: return localized_string_id::RPCN_ERROR_INVALID_PROTOCOL_VERSION;
case rpcn::rpcn_state::failure_other: return localized_string_id::RPCN_ERROR_UNKNOWN;
default: return localized_string_id::INVALID;
}
}
std::string rpcn_state_to_string(rpcn::rpcn_state state)
{
return get_localized_string(rpcn_state_to_localized_string_id(state));
}
constexpr u32 RPCN_PROTOCOL_VERSION = 15;
constexpr usz RPCN_HEADER_SIZE = 13;
constexpr usz COMMUNICATION_ID_SIZE = 9;
@ -1592,7 +1617,7 @@ namespace rpcn
std::copy(service_id.begin(), service_id.end(), std::back_inserter(data));
data.push_back(0);
const le_t<u32> size = cookie.size();
std::copy(reinterpret_cast<const u8 *>(&size), reinterpret_cast<const u8 *>(&size) + sizeof(le_t<u32>), std::back_inserter(data));
std::copy(reinterpret_cast<const u8*>(&size), reinterpret_cast<const u8*>(&size) + sizeof(le_t<u32>), std::back_inserter(data));
std::copy(cookie.begin(), cookie.end(), std::back_inserter(data));
if (!forge_send(CommandType::RequestTicket, req_id, data))
@ -1620,7 +1645,7 @@ namespace rpcn
}
auto npids_vector = builder.CreateVector(davec);
//auto npids = builder.Create
// auto npids = builder.Create
auto fb_sendmessage = CreateSendMessageRequest(builder, nested_flatbuffer_vector, npids_vector);
builder.Finish(fb_sendmessage);

View file

@ -5,6 +5,7 @@
#include <thread>
#include <semaphore>
#include "Utilities/mutex.h"
#include "Emu/localized_string.h"
#include "util/asm.hpp"
@ -218,6 +219,9 @@ namespace rpcn
std::set<std::string> blocked;
};
localized_string_id rpcn_state_to_localized_string_id(rpcn::rpcn_state state);
std::string rpcn_state_to_string(rpcn::rpcn_state state);
class rpcn_client
{
private:

View file

@ -0,0 +1,108 @@
#include "stdafx.h"
#include "overlay_message.h"
#include "Emu/RSX/RSXThread.h"
namespace rsx
{
namespace overlays
{
message_item::message_item(localized_string_id msg_id)
{
m_expiration_time = get_system_time() + 5'000'000;
m_text.set_font("Arial", 16);
m_text.set_text(msg_id);
m_text.auto_resize();
m_text.back_color.a = 0.f;
m_fade_animation.current = color4f(1.f);
m_fade_animation.end = color4f(1.0f, 1.0f, 1.0f, 0.f);
m_fade_animation.duration = 2.f;
m_fade_animation.active = true;
}
u64 message_item::get_expiration() const
{
return m_expiration_time;
}
compiled_resource message_item::get_compiled()
{
if (!m_processed)
{
return {};
}
auto cr = m_text.get_compiled();
m_fade_animation.apply(cr);
return cr;
}
void message_item::update(usz index, u64 time)
{
if (m_cur_pos != index)
{
m_cur_pos = index;
m_text.set_pos(10, index * 18);
}
if ((m_expiration_time - time) < 2'000'000)
{
m_fade_animation.update(rsx::get_current_renderer()->vblank_count);
}
m_processed = true;
}
void message::update()
{
if (!visible)
{
return;
}
std::lock_guard lock(m_mutex_queue);
u64 cur_time = get_system_time();
while (!m_queue.empty() && m_queue.front().get_expiration() < cur_time)
{
m_queue.pop_front();
}
if (m_queue.empty())
{
visible = false;
return;
}
usz index = 0;
for (auto& item : m_queue)
{
item.update(index, cur_time);
index++;
}
}
compiled_resource message::get_compiled()
{
if (!visible)
{
return {};
}
std::lock_guard lock(m_mutex_queue);
compiled_resource cr{};
for (auto& item : m_queue)
{
cr.add(item.get_compiled());
}
return cr;
}
} // namespace overlays
} // namespace rsx

View file

@ -0,0 +1,75 @@
#pragma once
#include "overlays.h"
#include <deque>
namespace rsx
{
namespace overlays
{
class message_item
{
public:
message_item(localized_string_id msg_id);
void update(usz index, u64 time);
u64 get_expiration() const;
compiled_resource get_compiled();
private:
label m_text{};
animation_color_interpolate m_fade_animation;
u64 m_expiration_time = 0;
bool m_processed = false;
usz m_cur_pos = umax;
};
class message final : public user_interface
{
public:
void update() override;
compiled_resource get_compiled() override;
template <typename T>
void queue_message(T msg_id)
{
std::lock_guard lock(m_mutex_queue);
if constexpr (std::is_same_v<T, std::initializer_list<localized_string_id>>)
{
for (auto id : msg_id)
{
m_queue.emplace_back(id);
}
}
else
{
m_queue.emplace_back(msg_id);
}
visible = true;
}
private:
shared_mutex m_mutex_queue;
std::deque<message_item> m_queue;
};
template <typename T>
void queue_message(T msg_id)
{
if (auto manager = g_fxo->try_get<rsx::overlays::display_manager>())
{
auto msg_overlay = manager->get<rsx::overlays::message>();
if (!msg_overlay)
{
msg_overlay = std::make_shared<rsx::overlays::message>();
msg_overlay = manager->add(msg_overlay);
}
msg_overlay->queue_message(msg_id);
}
}
} // namespace overlays
} // namespace rsx

View file

@ -128,4 +128,18 @@ enum class localized_string_id
CELL_SAVEDATA_SAVE,
CELL_SAVEDATA_LOAD,
CELL_SAVEDATA_OVERWRITE,
RPCN_NO_ERROR,
RPCN_ERROR_INVALID_INPUT,
RPCN_ERROR_WOLFSSL,
RPCN_ERROR_RESOLVE,
RPCN_ERROR_CONNECT,
RPCN_ERROR_LOGIN_ERROR,
RPCN_ERROR_ALREADY_LOGGED,
RPCN_ERROR_INVALID_LOGIN,
RPCN_ERROR_INVALID_PASSWORD,
RPCN_ERROR_INVALID_TOKEN,
RPCN_ERROR_INVALID_PROTOCOL_VERSION,
RPCN_ERROR_UNKNOWN,
RPCN_SUCCESS_LOGGED_ON,
};