mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-06-09 20:23:14 +00:00
Rewrite Save Data & Impl Save Data Dialog (#824)
* core: Rewrite PSF parser & add encoder add .sfo hex pattern to /scripts * core/fs: allow to mount path as read-only * common: Add CString wrapper to handle native null-terminated strings * SaveData: rewrite to implement full functionality * mock value for SYSTEM_VER * SavaData: backup features * SavaData: SaveDataMemory features * imgui Ref-counted textures - has a background thread to decode textures * imgui: rework gamepad navigation * PSF: fixed psf not using enum class for PSFEntryFmt (was a standard old ugly enum) - Add null check to CString when itself is used in a nullable field * SaveDataDialog implementation - Fix Mounting/Unmounting check of SaveInstance
This commit is contained in:
parent
077f8981a7
commit
0f4bcd8c83
51 changed files with 4919 additions and 1134 deletions
|
@ -39,11 +39,6 @@ Error PS4_SYSV_ABI sceMsgDialogGetResult(DialogResult* result) {
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <thread>
|
||||
|
||||
#include <imgui.h>
|
||||
#include "common/assert.h"
|
||||
#include "imgui/imgui_std.h"
|
||||
|
@ -31,18 +33,6 @@ struct {
|
|||
};
|
||||
static_assert(std::size(user_button_texts) == static_cast<int>(ButtonType::TWO_BUTTONS) + 1);
|
||||
|
||||
static void DrawCenteredText(const char* text) {
|
||||
const auto ws = GetWindowSize();
|
||||
const auto text_size = CalcTextSize(text, nullptr, false, ws.x - 40.0f);
|
||||
PushTextWrapPos(ws.x - 30.0f);
|
||||
SetCursorPos({
|
||||
(ws.x - text_size.x) / 2.0f,
|
||||
(ws.y - text_size.y) / 2.0f - 50.0f,
|
||||
});
|
||||
Text("%s", text);
|
||||
PopTextWrapPos();
|
||||
}
|
||||
|
||||
MsgDialogState::MsgDialogState(const OrbisParam& param) {
|
||||
this->mode = param.mode;
|
||||
switch (mode) {
|
||||
|
@ -81,11 +71,29 @@ MsgDialogState::MsgDialogState(const OrbisParam& param) {
|
|||
}
|
||||
}
|
||||
|
||||
MsgDialogState::MsgDialogState(UserState mode) {
|
||||
this->mode = MsgDialogMode::USER_MSG;
|
||||
this->state = mode;
|
||||
}
|
||||
|
||||
MsgDialogState::MsgDialogState(ProgressState mode) {
|
||||
this->mode = MsgDialogMode::PROGRESS_BAR;
|
||||
this->state = mode;
|
||||
}
|
||||
|
||||
MsgDialogState::MsgDialogState(SystemState mode) {
|
||||
this->mode = MsgDialogMode::SYSTEM_MSG;
|
||||
this->state = mode;
|
||||
}
|
||||
|
||||
void MsgDialogUi::DrawUser() {
|
||||
const auto& [button_type, msg, btn_param1, btn_param2] =
|
||||
state->GetState<MsgDialogState::UserState>();
|
||||
const auto ws = GetWindowSize();
|
||||
DrawCenteredText(msg.c_str());
|
||||
if (!msg.empty()) {
|
||||
DrawCenteredText(&msg.front(), &msg.back() + 1,
|
||||
GetContentRegionAvail() - ImVec2{0.0f, 15.0f + BUTTON_SIZE.y});
|
||||
}
|
||||
ASSERT(button_type <= ButtonType::TWO_BUTTONS);
|
||||
auto [count, text1, text2] = user_button_texts[static_cast<u32>(button_type)];
|
||||
if (count == 0xFF) { // TWO_BUTTONS -> User defined message
|
||||
|
@ -115,7 +123,7 @@ void MsgDialogUi::DrawUser() {
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (first_render && !focus_first) {
|
||||
if ((first_render || IsKeyPressed(ImGuiKey_GamepadFaceRight)) && !focus_first) {
|
||||
SetItemCurrentNavFocus();
|
||||
}
|
||||
PopID();
|
||||
|
@ -125,7 +133,7 @@ void MsgDialogUi::DrawUser() {
|
|||
if (Button(text1, BUTTON_SIZE)) {
|
||||
Finish(ButtonId::BUTTON1);
|
||||
}
|
||||
if (first_render && focus_first) {
|
||||
if ((first_render || IsKeyPressed(ImGuiKey_GamepadFaceRight)) && focus_first) {
|
||||
SetItemCurrentNavFocus();
|
||||
}
|
||||
PopID();
|
||||
|
@ -249,11 +257,13 @@ void MsgDialogUi::Draw() {
|
|||
|
||||
CentralizeWindow();
|
||||
SetNextWindowSize(window_size);
|
||||
SetNextWindowFocus();
|
||||
SetNextWindowCollapsed(false);
|
||||
if (first_render || !io.NavActive) {
|
||||
SetNextWindowFocus();
|
||||
}
|
||||
KeepNavHighlight();
|
||||
// Hack to allow every dialog to have a unique window
|
||||
if (Begin("Message Dialog##MessageDialog", nullptr, ImGuiWindowFlags_NoSavedSettings)) {
|
||||
if (Begin("Message Dialog##MessageDialog", nullptr,
|
||||
ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoSavedSettings)) {
|
||||
switch (state->GetMode()) {
|
||||
case MsgDialogMode::USER_MSG:
|
||||
DrawUser();
|
||||
|
@ -269,4 +279,16 @@ void MsgDialogUi::Draw() {
|
|||
End();
|
||||
|
||||
first_render = false;
|
||||
}
|
||||
}
|
||||
|
||||
DialogResult Libraries::MsgDialog::ShowMsgDialog(MsgDialogState state, bool block) {
|
||||
DialogResult result{};
|
||||
Status status = Status::RUNNING;
|
||||
MsgDialogUi dialog(&state, &status, &result);
|
||||
if (block) {
|
||||
while (status == Status::RUNNING) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <variant>
|
||||
|
||||
#include "common/fixed_value.h"
|
||||
|
@ -129,6 +130,11 @@ private:
|
|||
|
||||
public:
|
||||
explicit MsgDialogState(const OrbisParam& param);
|
||||
|
||||
explicit MsgDialogState(UserState mode);
|
||||
explicit MsgDialogState(ProgressState mode);
|
||||
explicit MsgDialogState(SystemState mode);
|
||||
|
||||
MsgDialogState() = default;
|
||||
|
||||
[[nodiscard]] OrbisUserServiceUserId GetUserId() const {
|
||||
|
@ -165,13 +171,11 @@ public:
|
|||
|
||||
void Finish(ButtonId buttonId, CommonDialog::Result r = CommonDialog::Result::OK);
|
||||
|
||||
void SetProgressBarValue(u32 value, bool increment);
|
||||
|
||||
void Draw() override;
|
||||
|
||||
bool ShouldGrabGamepad() override {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// Utility function to show a message dialog
|
||||
// !!! This function can block !!!
|
||||
DialogResult ShowMsgDialog(MsgDialogState state, bool block = true);
|
||||
|
||||
}; // namespace Libraries::MsgDialog
|
|
@ -1,84 +0,0 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
#include "core/libraries/libs.h"
|
||||
#include "core/libraries/system/savedatadialog.h"
|
||||
|
||||
namespace Libraries::SaveDataDialog {
|
||||
|
||||
int PS4_SYSV_ABI sceSaveDataDialogClose() {
|
||||
LOG_ERROR(Lib_SaveDataDialog, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceSaveDataDialogGetResult() {
|
||||
LOG_ERROR(Lib_SaveDataDialog, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceSaveDataDialogGetStatus() {
|
||||
LOG_ERROR(Lib_SaveDataDialog, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceSaveDataDialogInitialize() {
|
||||
LOG_ERROR(Lib_SaveDataDialog, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceSaveDataDialogIsReadyToDisplay() {
|
||||
LOG_ERROR(Lib_SaveDataDialog, "(STUBBED) called");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceSaveDataDialogOpen() {
|
||||
LOG_ERROR(Lib_SaveDataDialog, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceSaveDataDialogProgressBarInc() {
|
||||
LOG_ERROR(Lib_SaveDataDialog, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceSaveDataDialogProgressBarSetValue() {
|
||||
LOG_ERROR(Lib_SaveDataDialog, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceSaveDataDialogTerminate() {
|
||||
LOG_ERROR(Lib_SaveDataDialog, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceSaveDataDialogUpdateStatus() {
|
||||
LOG_ERROR(Lib_SaveDataDialog, "(STUBBED) called");
|
||||
return 3; // SCE_COMMON_DIALOG_STATUS_FINISHED
|
||||
}
|
||||
|
||||
void RegisterlibSceSaveDataDialog(Core::Loader::SymbolsResolver* sym) {
|
||||
LIB_FUNCTION("fH46Lag88XY", "libSceSaveDataDialog", 1, "libSceSaveDataDialog", 1, 1,
|
||||
sceSaveDataDialogClose);
|
||||
LIB_FUNCTION("yEiJ-qqr6Cg", "libSceSaveDataDialog", 1, "libSceSaveDataDialog", 1, 1,
|
||||
sceSaveDataDialogGetResult);
|
||||
LIB_FUNCTION("ERKzksauAJA", "libSceSaveDataDialog", 1, "libSceSaveDataDialog", 1, 1,
|
||||
sceSaveDataDialogGetStatus);
|
||||
LIB_FUNCTION("s9e3+YpRnzw", "libSceSaveDataDialog", 1, "libSceSaveDataDialog", 1, 1,
|
||||
sceSaveDataDialogInitialize);
|
||||
LIB_FUNCTION("en7gNVnh878", "libSceSaveDataDialog", 1, "libSceSaveDataDialog", 1, 1,
|
||||
sceSaveDataDialogIsReadyToDisplay);
|
||||
LIB_FUNCTION("4tPhsP6FpDI", "libSceSaveDataDialog", 1, "libSceSaveDataDialog", 1, 1,
|
||||
sceSaveDataDialogOpen);
|
||||
LIB_FUNCTION("V-uEeFKARJU", "libSceSaveDataDialog", 1, "libSceSaveDataDialog", 1, 1,
|
||||
sceSaveDataDialogProgressBarInc);
|
||||
LIB_FUNCTION("hay1CfTmLyA", "libSceSaveDataDialog", 1, "libSceSaveDataDialog", 1, 1,
|
||||
sceSaveDataDialogProgressBarSetValue);
|
||||
LIB_FUNCTION("YuH2FA7azqQ", "libSceSaveDataDialog", 1, "libSceSaveDataDialog", 1, 1,
|
||||
sceSaveDataDialogTerminate);
|
||||
LIB_FUNCTION("KK3Bdg1RWK0", "libSceSaveDataDialog", 1, "libSceSaveDataDialog", 1, 1,
|
||||
sceSaveDataDialogUpdateStatus);
|
||||
};
|
||||
|
||||
} // namespace Libraries::SaveDataDialog
|
|
@ -1,26 +0,0 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/types.h"
|
||||
|
||||
namespace Core::Loader {
|
||||
class SymbolsResolver;
|
||||
}
|
||||
|
||||
namespace Libraries::SaveDataDialog {
|
||||
|
||||
int PS4_SYSV_ABI sceSaveDataDialogClose();
|
||||
int PS4_SYSV_ABI sceSaveDataDialogGetResult();
|
||||
int PS4_SYSV_ABI sceSaveDataDialogGetStatus();
|
||||
int PS4_SYSV_ABI sceSaveDataDialogInitialize();
|
||||
int PS4_SYSV_ABI sceSaveDataDialogIsReadyToDisplay();
|
||||
int PS4_SYSV_ABI sceSaveDataDialogOpen();
|
||||
int PS4_SYSV_ABI sceSaveDataDialogProgressBarInc();
|
||||
int PS4_SYSV_ABI sceSaveDataDialogProgressBarSetValue();
|
||||
int PS4_SYSV_ABI sceSaveDataDialogTerminate();
|
||||
int PS4_SYSV_ABI sceSaveDataDialogUpdateStatus();
|
||||
|
||||
void RegisterlibSceSaveDataDialog(Core::Loader::SymbolsResolver* sym);
|
||||
} // namespace Libraries::SaveDataDialog
|
Loading…
Add table
Add a link
Reference in a new issue