system/MsgDialog: types & basic text display

This commit is contained in:
Vinicius Rangel 2024-09-04 00:59:58 -03:00
parent 035cb3eeaa
commit 2e4eac3d19
No known key found for this signature in database
GPG key ID: A5B154D904B761D9
7 changed files with 329 additions and 137 deletions

View file

@ -325,6 +325,7 @@ set(COMMON src/common/logging/backend.cpp
src/common/error.cpp
src/common/error.h
src/common/scope_exit.h
src/common/fixed_value.h
src/common/func_traits.h
src/common/native_clock.cpp
src/common/native_clock.h
@ -563,6 +564,7 @@ set(VIDEO_CORE src/video_core/amdgpu/liverpool.cpp
set(IMGUI src/imgui/imgui_config.h
src/imgui/imgui_layer.h
src/imgui/imgui_std.h
src/imgui/layer/video_info.cpp
src/imgui/layer/video_info.h
src/imgui/renderer/imgui_core.cpp

35
src/common/fixed_value.h Normal file
View file

@ -0,0 +1,35 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
/**
* @brief A template class that encapsulates a fixed, compile-time constant value.
*
* @tparam T The type of the value.
* @tparam Value The fixed value of type T.
*
* This class provides a way to encapsulate a value that is constant and known at compile-time.
* The value is stored as a private member and cannot be changed. Any attempt to assign a new
* value to an object of this class will reset it to the fixed value.
*/
template <typename T, T Value>
class FixedValue {
T m_value{Value};
public:
constexpr FixedValue() = default;
constexpr explicit(false) operator T() const {
return m_value;
}
FixedValue& operator=(const T&) {
m_value = Value;
return *this;
}
FixedValue& operator=(T&&) noexcept {
m_value = {Value};
return *this;
}
};

View file

@ -8,6 +8,9 @@
namespace Libraries::CommonDialog {
bool g_isInitialized = false;
bool g_isUsed = false;
int PS4_SYSV_ABI _ZN3sce16CommonDialogUtil12getSelfAppIdEv() {
LOG_ERROR(Lib_CommonDlg, "(STUBBED) called");
return ORBIS_OK;
@ -83,14 +86,16 @@ int PS4_SYSV_ABI _ZTVN3sce16CommonDialogUtil6ClientE() {
return ORBIS_OK;
}
int PS4_SYSV_ABI sceCommonDialogInitialize() {
LOG_ERROR(Lib_CommonDlg, "(DUMMY) called");
return ORBIS_OK;
Error PS4_SYSV_ABI sceCommonDialogInitialize() {
if (g_isInitialized) {
return Error::ALREADY_SYSTEM_INITIALIZED;
}
g_isInitialized = true;
return Error::OK;
}
int PS4_SYSV_ABI sceCommonDialogIsUsed() {
LOG_ERROR(Lib_CommonDlg, "(STUBBED) called");
return ORBIS_OK;
bool PS4_SYSV_ABI sceCommonDialogIsUsed() {
return g_isUsed;
}
int PS4_SYSV_ABI Func_0FF577E4E8457883() {

View file

@ -11,9 +11,44 @@ class SymbolsResolver;
namespace Libraries::CommonDialog {
struct OrbisCommonDialogBaseParam {
enum class Status : u32 {
NONE = 0,
INITIALIZED = 1,
RUNNING = 2,
FINISHED = 3,
};
enum class Result : u32 {
OK = 0,
USER_CANCELED = 1,
};
enum class Error : u32 {
OK = 0,
NOT_SYSTEM_INITIALIZED = 0x80B80001,
ALREADY_SYSTEM_INITIALIZED = 0x80B80002,
NOT_INITIALIZED = 0x80B80003,
ALREADY_INITIALIZED = 0x80B80004,
NOT_FINISHED = 0x80B80005,
INVALID_STATE = 0x80B80006,
RESULT_NONE = 0x80B80007,
BUSY = 0x80B80008,
OUT_OF_MEMORY = 0x80B80009,
PARAM_INVALID = 0x80B8000A,
NOT_RUNNING = 0x80B8000B,
ALREADY_CLOSE = 0x80B8000C,
ARG_NULL = 0x80B8000D,
UNEXPECTED_FATAL = 0x80B8000E,
NOT_SUPPORTED = 0x80B8000F,
INHIBIT_SHAREPLAY_CLIENT = 0x80B80010,
};
extern bool g_isInitialized;
extern bool g_isUsed;
struct BaseParam {
std::size_t size;
u8 reserved[36];
std::array<u8, 36> reserved;
u32 magic;
};
@ -32,8 +67,8 @@ int PS4_SYSV_ABI _ZNK3sce16CommonDialogUtil6Client8getAppIdEv();
int PS4_SYSV_ABI _ZNK3sce16CommonDialogUtil6Client8isFinishEv();
int PS4_SYSV_ABI _ZNK3sce16CommonDialogUtil6Client9getResultEv();
int PS4_SYSV_ABI _ZTVN3sce16CommonDialogUtil6ClientE();
int PS4_SYSV_ABI sceCommonDialogInitialize();
int PS4_SYSV_ABI sceCommonDialogIsUsed();
Error PS4_SYSV_ABI sceCommonDialogInitialize();
bool PS4_SYSV_ABI sceCommonDialogIsUsed();
int PS4_SYSV_ABI Func_0FF577E4E8457883();
int PS4_SYSV_ABI Func_41716C2CE379416C();
int PS4_SYSV_ABI Func_483A427D8F6E0748();

View file

@ -1,54 +1,224 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <imgui.h>
#include <magic_enum.hpp>
#include "common/assert.h"
#include "common/logging/log.h"
#include "core/libraries/error_codes.h"
#include "core/libraries/libs.h"
#include "core/libraries/system/msgdialog.h"
#include <magic_enum.hpp>
#include "imgui/imgui_layer.h"
#include "imgui/imgui_std.h"
namespace Libraries::MsgDialog {
int PS4_SYSV_ABI sceMsgDialogClose() {
LOG_ERROR(Lib_MsgDlg, "(STUBBED) called");
return ORBIS_OK;
}
class MsgDialogGui;
int PS4_SYSV_ABI sceMsgDialogGetResult() {
LOG_ERROR(Lib_MsgDlg, "(STUBBED) called");
return ORBIS_OK;
}
using CommonDialog::Error;
using CommonDialog::Result;
using CommonDialog::Status;
int PS4_SYSV_ABI sceMsgDialogGetStatus() {
LOG_ERROR(Lib_MsgDlg, "(STUBBED) called");
return ORBIS_OK;
}
using OrbisUserServiceUserId = s32;
int PS4_SYSV_ABI sceMsgDialogInitialize() {
LOG_ERROR(Lib_MsgDlg, "(STUBBED) called");
return ORBIS_OK;
}
enum class MsgDialogMode : u32 {
USER_MSG = 1,
PROGRESS_BAR = 2,
SYSTEM_MSG = 3,
};
s32 PS4_SYSV_ABI sceMsgDialogOpen(const OrbisMsgDialogParam* param) {
LOG_ERROR(Lib_MsgDlg, "(STUBBED) called");
switch (param->mode) {
case ORBIS_MSG_DIALOG_MODE_USER_MSG:
LOG_INFO(Lib_MsgDlg, "sceMsgDialogOpen userMsg type = %s msg = %s",
magic_enum::enum_name(param->userMsgParam->buttonType), param->userMsgParam->msg);
break;
case ORBIS_MSG_DIALOG_MODE_PROGRESS_BAR:
LOG_INFO(Lib_MsgDlg, "sceMsgDialogOpen progressBar type = %s msg = %s",
magic_enum::enum_name(param->progBarParam->barType), param->progBarParam->msg);
break;
case ORBIS_MSG_DIALOG_MODE_SYSTEM_MSG:
LOG_INFO(Lib_MsgDlg, "sceMsgDialogOpen systemMsg type: %s",
magic_enum::enum_name(param->sysMsgParam->sysMsgType));
break;
default:
break;
enum class ButtonId : u32 {
INVALID = 0,
OK = 1,
YES = 1,
NO = 2,
BUTTON1 = 1,
BUTTON2 = 2,
};
enum class ButtonType : u32 {
OK = 0,
YESNO = 1,
NONE = 2,
OK_CANCEL = 3,
WAIT = 5,
WAIT_CANCEL = 6,
YESNO_FOCUS_NO = 7,
OK_CANCEL_FOCUS_CANCEL = 8,
TWO_BUTTONS = 9,
};
enum class ProgressBarType : u32 {
PERCENTAGE = 0,
PERCENTAGE_CANCEL = 1,
};
enum class SystemMessageType : u32 {
TRC_EMPTY_STORE = 0,
TRC_PSN_CHAT_RESTRICTION = 1,
TRC_PSN_UGC_RESTRICTION = 2,
CAMERA_NOT_CONNECTED = 4,
WARNING_PROFILE_PICTURE_AND_NAME_NOT_SHARED = 5,
};
struct ButtonsParam {
const char* msg1{};
const char* msg2{};
std::array<char, 32> reserved{};
};
struct UserMessageParam {
ButtonType buttonType{};
s32 : 32;
const char* msg{};
ButtonsParam* buttonsParam{};
std::array<char, 24> reserved{};
};
struct ProgressBarParam {
ProgressBarType barType{};
s32 : 32;
const char* msg{};
std::array<char, 64> reserved{};
};
struct SystemMessageParam {
SystemMessageType sysMsgType{};
std::array<char, 32> reserved{};
};
struct Param {
CommonDialog::BaseParam baseParam;
std::size_t size;
MsgDialogMode mode;
s32 : 32;
UserMessageParam* userMsgParam;
ProgressBarParam* progBarParam;
SystemMessageParam* sysMsgParam;
OrbisUserServiceUserId userId;
std::array<char, 40> reserved;
s32 : 32;
};
struct MsgDialogResult {
FixedValue<u32, 0> mode{};
Result result{};
ButtonId buttonId{};
std::array<char, 32> reserved{};
};
class MsgDialogGui final : public ImGui::Layer {
const Param* param{};
void DrawUser(const UserMessageParam& user_message_param) {
const auto ws = ImGui::GetWindowSize();
ImGui::SetCursorPosY(ws.y / 2.0f - 30.0f);
ImGui::BeginGroup();
ImGui::PushTextWrapPos(ws.x - 30.0f);
ImGui::SetCursorPosX(
(ws.x - ImGui::CalcTextSize(user_message_param.msg, nullptr, false, ws.x - 40.0f).x) /
2.0f);
ImGui::Text("%s", user_message_param.msg);
ImGui::PopTextWrapPos();
ImGui::EndGroup();
switch (user_message_param.buttonType) {}
}
return ORBIS_OK;
void DrawProgressBar(const ProgressBarParam& progress_bar_param) {}
void DrawSystemMessage(const SystemMessageParam& system_message_param) {}
public:
void Draw() override {
const auto& io = ImGui::GetIO();
const ImVec2 window_size{
std::min(io.DisplaySize.x, 500.0f),
std::min(io.DisplaySize.y, 300.0f),
};
ImGui::CentralizeWindow();
ImGui::SetNextWindowSize(window_size);
ImGui::Begin("##Message Dialog", nullptr, ImGuiWindowFlags_NoDecoration);
switch (param->mode) {
case MsgDialogMode::USER_MSG:
DrawUser(*param->userMsgParam);
break;
case MsgDialogMode::PROGRESS_BAR:
DrawProgressBar(*param->progBarParam);
break;
case MsgDialogMode::SYSTEM_MSG:
DrawSystemMessage(*param->sysMsgParam);
break;
}
ImGui::End();
}
bool ShouldGrabGamepad() override {
return true;
}
explicit MsgDialogGui(const Param* param = nullptr) : param(param) {}
} static g_msg_dialog_gui;
static auto g_status = Status::NONE;
static MsgDialogResult g_result{};
Error PS4_SYSV_ABI sceMsgDialogClose() {
if (g_status != Status::RUNNING) {
return Error::NOT_RUNNING;
}
g_status = Status::FINISHED;
ImGui::Layer::RemoveLayer(&g_msg_dialog_gui);
return Error::OK;
}
Error PS4_SYSV_ABI sceMsgDialogGetResult(MsgDialogResult* result) {
if (g_status != Status::FINISHED) {
return Error::NOT_FINISHED;
}
if (result == nullptr) {
return Error::ARG_NULL;
}
for (const auto v : result->reserved) {
if (v != 0) {
return Error::PARAM_INVALID;
}
}
*result = g_result;
return Error::OK;
}
CommonDialog::Status PS4_SYSV_ABI sceMsgDialogGetStatus() {
return g_status;
}
Error PS4_SYSV_ABI sceMsgDialogInitialize() {
if (!CommonDialog::g_isInitialized) {
return Error::NOT_SYSTEM_INITIALIZED;
}
if (g_status != Status::NONE) {
return Error::ALREADY_INITIALIZED;
}
if (CommonDialog::g_isUsed) {
return Error::BUSY;
}
g_status = Status::INITIALIZED;
CommonDialog::g_isUsed = true;
return Error::OK;
}
Error PS4_SYSV_ABI sceMsgDialogOpen(const Param* param) {
if (g_status != Status::INITIALIZED && g_status != Status::FINISHED) {
return Error::INVALID_STATE;
}
ASSERT(param->size == sizeof(Param));
ASSERT(param->baseParam.size == sizeof(CommonDialog::BaseParam));
g_status = Status::RUNNING;
g_msg_dialog_gui = MsgDialogGui(param);
ImGui::Layer::AddLayer(&g_msg_dialog_gui);
return Error::OK;
}
int PS4_SYSV_ABI sceMsgDialogProgressBarInc() {
@ -66,14 +236,20 @@ int PS4_SYSV_ABI sceMsgDialogProgressBarSetValue() {
return ORBIS_OK;
}
int PS4_SYSV_ABI sceMsgDialogTerminate() {
LOG_ERROR(Lib_MsgDlg, "(STUBBED) called");
return ORBIS_OK;
Error PS4_SYSV_ABI sceMsgDialogTerminate() {
if (g_status == Status::RUNNING) {
sceMsgDialogClose();
}
if (g_status == Status::NONE) {
return Error::NOT_INITIALIZED;
}
g_status = Status::NONE;
CommonDialog::g_isUsed = false;
return Error::OK;
}
int PS4_SYSV_ABI sceMsgDialogUpdateStatus() {
LOG_ERROR(Lib_MsgDlg, "(STUBBED) called");
return ORBIS_OK;
Status PS4_SYSV_ABI sceMsgDialogUpdateStatus() {
return g_status;
}
void RegisterlibSceMsgDialog(Core::Loader::SymbolsResolver* sym) {

View file

@ -3,6 +3,7 @@
#pragma once
#include "common/fixed_value.h"
#include "common/types.h"
#include "core/libraries/system/commondialog.h"
@ -12,95 +13,19 @@ class SymbolsResolver;
namespace Libraries::MsgDialog {
using OrbisUserServiceUserId = s32;
struct MsgDialogResult;
struct Param;
enum OrbisCommonDialogStatus {
ORBIS_COMMON_DIALOG_STATUS_NONE = 0,
ORBIS_COMMON_DIALOG_STATUS_INITIALIZED = 1,
ORBIS_COMMON_DIALOG_STATUS_RUNNING = 2,
ORBIS_COMMON_DIALOG_STATUS_FINISHED = 3
};
enum OrbisMsgDialogMode {
ORBIS_MSG_DIALOG_MODE_USER_MSG = 1,
ORBIS_MSG_DIALOG_MODE_PROGRESS_BAR = 2,
ORBIS_MSG_DIALOG_MODE_SYSTEM_MSG = 3,
};
enum OrbisMsgDialogButtonType {
ORBIS_MSG_DIALOG_BUTTON_TYPE_OK = 0,
ORBIS_MSG_DIALOG_BUTTON_TYPE_YESNO = 1,
ORBIS_MSG_DIALOG_BUTTON_TYPE_NONE = 2,
ORBIS_MSG_DIALOG_BUTTON_TYPE_OK_CANCEL = 3,
ORBIS_MSG_DIALOG_BUTTON_TYPE_WAIT = 5,
ORBIS_MSG_DIALOG_BUTTON_TYPE_WAIT_CANCEL = 6,
ORBIS_MSG_DIALOG_BUTTON_TYPE_YESNO_FOCUS_NO = 7,
ORBIS_MSG_DIALOG_BUTTON_TYPE_OK_CANCEL_FOCUS_CANCEL = 8,
ORBIS_MSG_DIALOG_BUTTON_TYPE_2BUTTONS = 9,
};
enum OrbisMsgDialogProgressBarType {
ORBIS_MSG_DIALOG_PROGRESSBAR_TYPE_PERCENTAGE = 0,
ORBIS_MSG_DIALOG_PROGRESSBAR_TYPE_PERCENTAGE_CANCEL = 1,
};
enum OrbisMsgDialogSystemMessageType {
ORBIS_MSG_DIALOG_SYSMSG_TYPE_TRC_EMPTY_STORE = 0,
ORBIS_MSG_DIALOG_SYSMSG_TYPE_TRC_PSN_CHAT_RESTRICTION = 1,
ORBIS_MSG_DIALOG_SYSMSG_TYPE_TRC_PSN_UGC_RESTRICTION = 2,
ORBIS_MSG_DIALOG_SYSMSG_TYPE_CAMERA_NOT_CONNECTED = 4,
ORBIS_MSG_DIALOG_SYSMSG_TYPE_WARNING_PROFILE_PICTURE_AND_NAME_NOT_SHARED = 5,
};
struct OrbisMsgDialogButtonsParam {
const char* msg1;
const char* msg2;
char reserved[32];
};
struct OrbisMsgDialogUserMessageParam {
OrbisMsgDialogButtonType buttonType;
s32 : 32;
const char* msg;
OrbisMsgDialogButtonsParam* buttonsParam;
char reserved[24];
};
struct OrbisMsgDialogProgressBarParam {
OrbisMsgDialogProgressBarType barType;
int32_t : 32;
const char* msg;
char reserved[64];
};
struct OrbisMsgDialogSystemMessageParam {
OrbisMsgDialogSystemMessageType sysMsgType;
char reserved[32];
};
struct OrbisMsgDialogParam {
CommonDialog::OrbisCommonDialogBaseParam baseParam;
std::size_t size;
OrbisMsgDialogMode mode;
s32 : 32;
OrbisMsgDialogUserMessageParam* userMsgParam;
OrbisMsgDialogProgressBarParam* progBarParam;
OrbisMsgDialogSystemMessageParam* sysMsgParam;
OrbisUserServiceUserId userId;
char reserved[40];
s32 : 32;
};
int PS4_SYSV_ABI sceMsgDialogClose();
int PS4_SYSV_ABI sceMsgDialogGetResult();
int PS4_SYSV_ABI sceMsgDialogGetStatus();
int PS4_SYSV_ABI sceMsgDialogInitialize();
s32 PS4_SYSV_ABI sceMsgDialogOpen(const OrbisMsgDialogParam* param);
CommonDialog::Error PS4_SYSV_ABI sceMsgDialogClose();
CommonDialog::Error PS4_SYSV_ABI sceMsgDialogGetResult(MsgDialogResult* result);
CommonDialog::Status PS4_SYSV_ABI sceMsgDialogGetStatus();
CommonDialog::Error PS4_SYSV_ABI sceMsgDialogInitialize();
CommonDialog::Error PS4_SYSV_ABI sceMsgDialogOpen(const Param* param);
int PS4_SYSV_ABI sceMsgDialogProgressBarInc();
int PS4_SYSV_ABI sceMsgDialogProgressBarSetMsg();
int PS4_SYSV_ABI sceMsgDialogProgressBarSetValue();
int PS4_SYSV_ABI sceMsgDialogTerminate();
int PS4_SYSV_ABI sceMsgDialogUpdateStatus();
CommonDialog::Error PS4_SYSV_ABI sceMsgDialogTerminate();
CommonDialog::Status PS4_SYSV_ABI sceMsgDialogUpdateStatus();
void RegisterlibSceMsgDialog(Core::Loader::SymbolsResolver* sym);
} // namespace Libraries::MsgDialog

14
src/imgui/imgui_std.h Normal file
View file

@ -0,0 +1,14 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <imgui.h>
namespace ImGui {
inline void CentralizeWindow() {
const auto display_size = GetIO().DisplaySize;
SetNextWindowPos(display_size / 2.0f, ImGuiCond_Always, {0.5f});
}
} // namespace ImGui