mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-12 04:35:56 +00:00
Merge 87701a5512
into 4f99f304e6
This commit is contained in:
commit
e57926ad36
39 changed files with 399 additions and 63 deletions
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -106,3 +106,6 @@
|
|||
[submodule "externals/libusb"]
|
||||
path = externals/libusb
|
||||
url = https://github.com/libusb/libusb-cmake.git
|
||||
[submodule "externals/json"]
|
||||
path = externals/json
|
||||
url = https://github.com/nlohmann/json.git
|
||||
|
|
|
@ -801,6 +801,8 @@ set(CORE src/core/aerolib/stubs.cpp
|
|||
src/core/thread.h
|
||||
src/core/tls.cpp
|
||||
src/core/tls.h
|
||||
src/core/user_account.cpp
|
||||
src/core/user_account.h
|
||||
)
|
||||
|
||||
if (ARCHITECTURE STREQUAL "x86_64")
|
||||
|
@ -1069,6 +1071,8 @@ set(QT_GUI src/qt_gui/about_dialog.cpp
|
|||
src/qt_gui/gui_settings.h
|
||||
src/qt_gui/settings.cpp
|
||||
src/qt_gui/settings.h
|
||||
src/qt_gui/user_management_dialog.cpp
|
||||
src/qt_gui/user_management_dialog.h
|
||||
src/qt_gui/sdl_event_wrapper.cpp
|
||||
src/qt_gui/sdl_event_wrapper.h
|
||||
${EMULATOR}
|
||||
|
@ -1112,7 +1116,7 @@ endif()
|
|||
create_target_directory_groups(shadps4)
|
||||
|
||||
target_link_libraries(shadps4 PRIVATE magic_enum::magic_enum fmt::fmt toml11::toml11 tsl::robin_map xbyak::xbyak Tracy::TracyClient RenderDoc::API FFmpeg::ffmpeg Dear_ImGui gcn half::half ZLIB::ZLIB PNG::PNG)
|
||||
target_link_libraries(shadps4 PRIVATE Boost::headers GPUOpen::VulkanMemoryAllocator LibAtrac9 sirit Vulkan::Headers xxHash::xxhash Zydis::Zydis glslang::glslang SDL3::SDL3 pugixml::pugixml stb::headers libusb::usb)
|
||||
target_link_libraries(shadps4 PRIVATE Boost::headers GPUOpen::VulkanMemoryAllocator LibAtrac9 sirit Vulkan::Headers xxHash::xxhash Zydis::Zydis glslang::glslang SDL3::SDL3 pugixml::pugixml stb::headers libusb::usb nlohmann_json::nlohmann_json)
|
||||
|
||||
target_compile_definitions(shadps4 PRIVATE IMGUI_USER_CONFIG="imgui/imgui_config.h")
|
||||
target_compile_definitions(Dear_ImGui PRIVATE IMGUI_USER_CONFIG="${PROJECT_SOURCE_DIR}/src/imgui/imgui_config.h")
|
||||
|
|
|
@ -57,6 +57,7 @@ path = [
|
|||
"src/images/refreshlist_icon.png",
|
||||
"src/images/settings_icon.png",
|
||||
"src/images/fullscreen_icon.png",
|
||||
"src/images/users_icon.png",
|
||||
"src/images/stop_icon.png",
|
||||
"src/images/utils_icon.png",
|
||||
"src/images/shadPS4.icns",
|
||||
|
|
4
externals/CMakeLists.txt
vendored
4
externals/CMakeLists.txt
vendored
|
@ -230,3 +230,7 @@ if (APPLE)
|
|||
add_subdirectory(MoltenVK)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#nlohmann json
|
||||
set(JSON_BuildTests OFF CACHE INTERNAL "")
|
||||
add_subdirectory(json)
|
1
externals/json
vendored
Submodule
1
externals/json
vendored
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 568b708fd46deeb23a959381393a7564f1586588
|
|
@ -75,6 +75,15 @@ static bool compatibilityData = false;
|
|||
static bool checkCompatibilityOnStartup = false;
|
||||
static std::string trophyKey;
|
||||
static bool isPSNSignedIn = false;
|
||||
std::string userid{"00000001"};
|
||||
std::string selectedUserid{"00000001"};
|
||||
|
||||
std::string getDefaultUserId() {
|
||||
return userid;
|
||||
}
|
||||
std::string getActiveUserId() {
|
||||
return selectedUserid;
|
||||
}
|
||||
|
||||
// Gui
|
||||
static bool load_game_size = true;
|
||||
|
|
|
@ -133,5 +133,7 @@ void setDefaultValues();
|
|||
|
||||
// todo: name and function location pending
|
||||
std::filesystem::path GetFoolproofKbmConfigFile(const std::string& game_id = "");
|
||||
std::string getDefaultUserId();
|
||||
std::string getActiveUserId();
|
||||
|
||||
}; // namespace Config
|
|
@ -137,6 +137,7 @@ static auto UserPaths = [] {
|
|||
create_path(PathType::PatchesDir, user_dir / PATCHES_DIR);
|
||||
create_path(PathType::MetaDataDir, user_dir / METADATA_DIR);
|
||||
create_path(PathType::CustomTrophy, user_dir / CUSTOM_TROPHY);
|
||||
create_path(PathType::HomeDir, user_dir / HOME_DIR);
|
||||
|
||||
std::ofstream notice_file(user_dir / CUSTOM_TROPHY / "Notice.txt");
|
||||
if (notice_file.is_open()) {
|
||||
|
|
|
@ -27,6 +27,7 @@ enum class PathType {
|
|||
PatchesDir, // Where patches are stored.
|
||||
MetaDataDir, // Where game metadata (e.g. trophies and menu backgrounds) is stored.
|
||||
CustomTrophy, // Where custom files for trophies are stored.
|
||||
HomeDir, // PS4 home directory
|
||||
};
|
||||
|
||||
constexpr auto PORTABLE_DIR = "user";
|
||||
|
@ -44,6 +45,7 @@ constexpr auto CHEATS_DIR = "cheats";
|
|||
constexpr auto PATCHES_DIR = "patches";
|
||||
constexpr auto METADATA_DIR = "game_data";
|
||||
constexpr auto CUSTOM_TROPHY = "custom_trophy";
|
||||
constexpr auto HOME_DIR = "home";
|
||||
|
||||
// Filenames
|
||||
constexpr auto LOG_FILE = "shad_log.txt";
|
||||
|
|
|
@ -29,10 +29,10 @@ s32 PS4_SYSV_ABI sceAudio3dAudioOutClose(const s32 handle) {
|
|||
return AudioOut::sceAudioOutClose(handle);
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI
|
||||
sceAudio3dAudioOutOpen(const OrbisAudio3dPortId port_id, const OrbisUserServiceUserId user_id,
|
||||
s32 type, const s32 index, const u32 len, const u32 freq,
|
||||
const AudioOut::OrbisAudioOutParamExtendedInformation param) {
|
||||
s32 PS4_SYSV_ABI sceAudio3dAudioOutOpen(
|
||||
const OrbisAudio3dPortId port_id, const Libraries::UserService::OrbisUserServiceUserId user_id,
|
||||
s32 type, const s32 index, const u32 len, const u32 freq,
|
||||
const AudioOut::OrbisAudioOutParamExtendedInformation param) {
|
||||
LOG_INFO(Lib_Audio3d,
|
||||
"called, port_id = {}, user_id = {}, type = {}, index = {}, len = {}, freq = {}",
|
||||
port_id, user_id, type, index, len, freq);
|
||||
|
@ -421,7 +421,7 @@ s32 PS4_SYSV_ABI sceAudio3dPortGetStatus() {
|
|||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortOpen(const OrbisUserServiceUserId user_id,
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortOpen(const Libraries::UserService::OrbisUserServiceUserId user_id,
|
||||
const OrbisAudio3dOpenParameters* parameters,
|
||||
OrbisAudio3dPortId* port_id) {
|
||||
LOG_INFO(Lib_Audio3d, "called, user_id = {}, parameters = {}, id = {}", user_id,
|
||||
|
|
|
@ -15,8 +15,6 @@ class SymbolsResolver;
|
|||
|
||||
namespace Libraries::Audio3d {
|
||||
|
||||
using OrbisUserServiceUserId = s32;
|
||||
|
||||
enum class OrbisAudio3dRate : u32 {
|
||||
ORBIS_AUDIO3D_RATE_48000 = 0,
|
||||
};
|
||||
|
@ -91,7 +89,8 @@ struct Audio3dState {
|
|||
};
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dAudioOutClose(s32 handle);
|
||||
s32 PS4_SYSV_ABI sceAudio3dAudioOutOpen(OrbisAudio3dPortId port_id, OrbisUserServiceUserId user_id,
|
||||
s32 PS4_SYSV_ABI sceAudio3dAudioOutOpen(OrbisAudio3dPortId port_id,
|
||||
Libraries::UserService::OrbisUserServiceUserId user_id,
|
||||
s32 type, s32 index, u32 len, u32 freq,
|
||||
AudioOut::OrbisAudioOutParamExtendedInformation param);
|
||||
s32 PS4_SYSV_ABI sceAudio3dAudioOutOutput(s32 handle, void* ptr);
|
||||
|
@ -127,7 +126,7 @@ s32 PS4_SYSV_ABI sceAudio3dPortGetQueueLevel(OrbisAudio3dPortId port_id, u32* qu
|
|||
u32* queue_available);
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortGetState();
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortGetStatus();
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortOpen(OrbisUserServiceUserId user_id,
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortOpen(Libraries::UserService::OrbisUserServiceUserId user_id,
|
||||
const OrbisAudio3dOpenParameters* parameters,
|
||||
OrbisAudio3dPortId* port_id);
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortPush(OrbisAudio3dPortId port_id, OrbisAudio3dBlocking blocking);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <core/libraries/system/userservice.h>
|
||||
#include "common/types.h"
|
||||
|
||||
namespace Core::Loader {
|
||||
|
@ -15,11 +16,11 @@ struct OrbisGameLiveStreamingStatus {
|
|||
bool isOnAir;
|
||||
u8 align[3];
|
||||
u32 spectatorCounts;
|
||||
s32 userId;
|
||||
Libraries::UserService::OrbisUserServiceUserId userId;
|
||||
u8 reserved[60];
|
||||
};
|
||||
struct OrbisGameLiveStreamingStatus2 {
|
||||
s32 userId;
|
||||
Libraries::UserService::OrbisUserServiceUserId userId;
|
||||
bool isOnAir;
|
||||
u8 align[3];
|
||||
u32 spectatorCounts;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <imgui.h>
|
||||
#include <magic_enum/magic_enum.hpp>
|
||||
|
||||
#include <core/libraries/system/userservice.h>
|
||||
#include "common/assert.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
|
@ -117,7 +118,7 @@ static ErrorDialogUi g_dialog_ui;
|
|||
struct Param {
|
||||
s32 size;
|
||||
s32 errorCode;
|
||||
OrbisUserServiceUserId userId;
|
||||
Libraries::UserService::OrbisUserServiceUserId userId;
|
||||
s32 _reserved;
|
||||
};
|
||||
|
||||
|
|
|
@ -11,8 +11,6 @@ class SymbolsResolver;
|
|||
}
|
||||
namespace Libraries::ErrorDialog {
|
||||
|
||||
using OrbisUserServiceUserId = s32;
|
||||
|
||||
struct Param;
|
||||
|
||||
CommonDialog::Error PS4_SYSV_ABI sceErrorDialogClose();
|
||||
|
|
|
@ -247,7 +247,7 @@ s32 PS4_SYSV_ABI sceImeGetPanelSize(const OrbisImeParam* param, u32* width, u32*
|
|||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceImeKeyboardClose(s32 userId) {
|
||||
s32 PS4_SYSV_ABI sceImeKeyboardClose(Libraries::UserService::OrbisUserServiceUserId userId) {
|
||||
LOG_INFO(Lib_Ime, "(STUBBED) called");
|
||||
|
||||
if (!g_keyboard_handler) {
|
||||
|
@ -268,7 +268,8 @@ int PS4_SYSV_ABI sceImeKeyboardGetResourceId() {
|
|||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceImeKeyboardOpen(s32 userId, const OrbisImeKeyboardParam* param) {
|
||||
s32 PS4_SYSV_ABI sceImeKeyboardOpen(Libraries::UserService::OrbisUserServiceUserId userId,
|
||||
const OrbisImeKeyboardParam* param) {
|
||||
LOG_INFO(Lib_Ime, "called");
|
||||
|
||||
if (!param) {
|
||||
|
|
|
@ -99,10 +99,11 @@ int PS4_SYSV_ABI sceImeFilterText();
|
|||
int PS4_SYSV_ABI sceImeForTestFunction();
|
||||
int PS4_SYSV_ABI sceImeGetPanelPositionAndForm();
|
||||
s32 PS4_SYSV_ABI sceImeGetPanelSize(const OrbisImeParam* param, u32* width, u32* height);
|
||||
s32 PS4_SYSV_ABI sceImeKeyboardClose(s32 userId);
|
||||
s32 PS4_SYSV_ABI sceImeKeyboardClose(Libraries::UserService::OrbisUserServiceUserId userId);
|
||||
int PS4_SYSV_ABI sceImeKeyboardGetInfo();
|
||||
int PS4_SYSV_ABI sceImeKeyboardGetResourceId();
|
||||
s32 PS4_SYSV_ABI sceImeKeyboardOpen(s32 userId, const OrbisImeKeyboardParam* param);
|
||||
s32 PS4_SYSV_ABI sceImeKeyboardOpen(Libraries::UserService::OrbisUserServiceUserId userId,
|
||||
const OrbisImeKeyboardParam* param);
|
||||
int PS4_SYSV_ABI sceImeKeyboardOpenInternal();
|
||||
int PS4_SYSV_ABI sceImeKeyboardSetMode();
|
||||
int PS4_SYSV_ABI sceImeKeyboardUpdate();
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <core/libraries/system/userservice.h>
|
||||
#include "common/types.h"
|
||||
#include "core/libraries/rtc/rtc.h"
|
||||
|
||||
|
@ -141,7 +142,7 @@ struct OrbisImeKeycode {
|
|||
};
|
||||
|
||||
struct OrbisImeKeyboardResourceIdArray {
|
||||
s32 userId;
|
||||
Libraries::UserService::OrbisUserServiceUserId userId;
|
||||
u32 resourceId[5];
|
||||
};
|
||||
|
||||
|
|
|
@ -924,7 +924,7 @@ int PS4_SYSV_ABI sceNpGetAccountCountry() {
|
|||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNpGetAccountCountryA(OrbisUserServiceUserId user_id,
|
||||
int PS4_SYSV_ABI sceNpGetAccountCountryA(Libraries::UserService::OrbisUserServiceUserId user_id,
|
||||
OrbisNpCountryCode* country_code) {
|
||||
LOG_INFO(Lib_NpManager, "(STUBBED) called, user_id = {}", user_id);
|
||||
if (country_code == nullptr) {
|
||||
|
@ -955,7 +955,8 @@ int PS4_SYSV_ABI sceNpGetAccountId(OrbisNpOnlineId* online_id, u64* account_id)
|
|||
return SIGNEDIN_STATUS;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNpGetAccountIdA(OrbisUserServiceUserId user_id, u64* account_id) {
|
||||
int PS4_SYSV_ABI sceNpGetAccountIdA(Libraries::UserService::OrbisUserServiceUserId user_id,
|
||||
u64* account_id) {
|
||||
LOG_DEBUG(Lib_NpManager, "user_id {}", user_id);
|
||||
if (account_id == nullptr) {
|
||||
return ORBIS_NP_ERROR_INVALID_ARGUMENT;
|
||||
|
@ -989,7 +990,8 @@ int PS4_SYSV_ABI sceNpGetGamePresenceStatusA() {
|
|||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNpGetNpId(OrbisUserServiceUserId user_id, OrbisNpId* np_id) {
|
||||
int PS4_SYSV_ABI sceNpGetNpId(Libraries::UserService::OrbisUserServiceUserId user_id,
|
||||
OrbisNpId* np_id) {
|
||||
LOG_DEBUG(Lib_NpManager, "user_id {}", user_id);
|
||||
if (np_id == nullptr) {
|
||||
return ORBIS_NP_ERROR_INVALID_ARGUMENT;
|
||||
|
@ -1004,7 +1006,8 @@ int PS4_SYSV_ABI sceNpGetNpReachabilityState() {
|
|||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNpGetOnlineId(OrbisUserServiceUserId user_id, OrbisNpOnlineId* online_id) {
|
||||
int PS4_SYSV_ABI sceNpGetOnlineId(Libraries::UserService::OrbisUserServiceUserId user_id,
|
||||
OrbisNpOnlineId* online_id) {
|
||||
LOG_DEBUG(Lib_NpManager, "user_id {}", user_id);
|
||||
if (online_id == nullptr) {
|
||||
return ORBIS_NP_ERROR_INVALID_ARGUMENT;
|
||||
|
@ -1024,7 +1027,8 @@ int PS4_SYSV_ABI sceNpGetParentalControlInfoA() {
|
|||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNpGetState(OrbisUserServiceUserId user_id, OrbisNpState* state) {
|
||||
int PS4_SYSV_ABI sceNpGetState(Libraries::UserService::OrbisUserServiceUserId user_id,
|
||||
OrbisNpState* state) {
|
||||
if (state == nullptr) {
|
||||
return ORBIS_NP_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
@ -1043,7 +1047,8 @@ int PS4_SYSV_ABI sceNpGetUserIdByOnlineId() {
|
|||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceNpHasSignedUp(OrbisUserServiceUserId user_id, bool* has_signed_up) {
|
||||
int PS4_SYSV_ABI sceNpHasSignedUp(Libraries::UserService::OrbisUserServiceUserId user_id,
|
||||
bool* has_signed_up) {
|
||||
LOG_DEBUG(Lib_NpManager, "called");
|
||||
if (has_signed_up == nullptr) {
|
||||
return ORBIS_NP_ERROR_INVALID_ARGUMENT;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <core/libraries/system/userservice.h>
|
||||
#include "common/types.h"
|
||||
|
||||
namespace Core::Loader {
|
||||
|
@ -18,8 +19,6 @@ using OrbisNpStateCallbackForNpToolkit = PS4_SYSV_ABI void (*)(s32 userId, Orbis
|
|||
|
||||
constexpr int ORBIS_NP_ONLINEID_MAX_LENGTH = 16;
|
||||
|
||||
using OrbisUserServiceUserId = s32;
|
||||
|
||||
struct OrbisNpOnlineId {
|
||||
char data[ORBIS_NP_ONLINEID_MAX_LENGTH];
|
||||
char term;
|
||||
|
@ -221,26 +220,31 @@ int PS4_SYSV_ABI sceNpCreateRequest();
|
|||
int PS4_SYSV_ABI sceNpDeleteRequest(int reqId);
|
||||
int PS4_SYSV_ABI sceNpGetAccountAge();
|
||||
int PS4_SYSV_ABI sceNpGetAccountCountry();
|
||||
int PS4_SYSV_ABI sceNpGetAccountCountryA(OrbisUserServiceUserId user_id,
|
||||
int PS4_SYSV_ABI sceNpGetAccountCountryA(Libraries::UserService::OrbisUserServiceUserId user_id,
|
||||
OrbisNpCountryCode* country_code);
|
||||
int PS4_SYSV_ABI sceNpGetAccountDateOfBirth();
|
||||
int PS4_SYSV_ABI sceNpGetAccountDateOfBirthA();
|
||||
int PS4_SYSV_ABI sceNpGetAccountId(OrbisNpOnlineId* online_id, u64* account_id);
|
||||
int PS4_SYSV_ABI sceNpGetAccountIdA(OrbisUserServiceUserId user_id, u64* account_id);
|
||||
int PS4_SYSV_ABI sceNpGetAccountIdA(Libraries::UserService::OrbisUserServiceUserId user_id,
|
||||
u64* account_id);
|
||||
int PS4_SYSV_ABI sceNpGetAccountLanguage();
|
||||
int PS4_SYSV_ABI sceNpGetAccountLanguage2();
|
||||
int PS4_SYSV_ABI sceNpGetAccountLanguageA();
|
||||
int PS4_SYSV_ABI sceNpGetGamePresenceStatus();
|
||||
int PS4_SYSV_ABI sceNpGetGamePresenceStatusA();
|
||||
int PS4_SYSV_ABI sceNpGetNpId(OrbisUserServiceUserId user_id, OrbisNpId* np_id);
|
||||
int PS4_SYSV_ABI sceNpGetNpId(Libraries::UserService::OrbisUserServiceUserId user_id,
|
||||
OrbisNpId* np_id);
|
||||
int PS4_SYSV_ABI sceNpGetNpReachabilityState();
|
||||
int PS4_SYSV_ABI sceNpGetOnlineId(OrbisUserServiceUserId user_id, OrbisNpOnlineId* online_id);
|
||||
int PS4_SYSV_ABI sceNpGetOnlineId(Libraries::UserService::OrbisUserServiceUserId user_id,
|
||||
OrbisNpOnlineId* online_id);
|
||||
int PS4_SYSV_ABI sceNpGetParentalControlInfo();
|
||||
int PS4_SYSV_ABI sceNpGetParentalControlInfoA();
|
||||
int PS4_SYSV_ABI sceNpGetState(OrbisUserServiceUserId user_id, OrbisNpState* state);
|
||||
int PS4_SYSV_ABI sceNpGetState(Libraries::UserService::OrbisUserServiceUserId user_id,
|
||||
OrbisNpState* state);
|
||||
int PS4_SYSV_ABI sceNpGetUserIdByAccountId();
|
||||
int PS4_SYSV_ABI sceNpGetUserIdByOnlineId();
|
||||
int PS4_SYSV_ABI sceNpHasSignedUp(OrbisUserServiceUserId user_id, bool* has_signed_up);
|
||||
int PS4_SYSV_ABI sceNpHasSignedUp(Libraries::UserService::OrbisUserServiceUserId user_id,
|
||||
bool* has_signed_up);
|
||||
int PS4_SYSV_ABI sceNpIdMapperAbortRequest();
|
||||
int PS4_SYSV_ABI sceNpIdMapperAccountIdToNpId();
|
||||
int PS4_SYSV_ABI sceNpIdMapperAccountIdToOnlineId();
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <unordered_map>
|
||||
#include <pugixml.hpp>
|
||||
|
||||
#include <core/libraries/system/userservice.h>
|
||||
#include "common/logging/log.h"
|
||||
#include "common/path_util.h"
|
||||
#include "common/slot_vector.h"
|
||||
|
@ -147,7 +148,8 @@ int PS4_SYSV_ABI sceNpTrophyConfigHasGroupFeature() {
|
|||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNpTrophyCreateContext(OrbisNpTrophyContext* context, int32_t user_id,
|
||||
s32 PS4_SYSV_ABI sceNpTrophyCreateContext(OrbisNpTrophyContext* context,
|
||||
Libraries::UserService::OrbisUserServiceUserId userId,
|
||||
uint32_t service_label, uint64_t options) {
|
||||
ASSERT(options == 0ull);
|
||||
if (!context) {
|
||||
|
@ -158,16 +160,16 @@ s32 PS4_SYSV_ABI sceNpTrophyCreateContext(OrbisNpTrophyContext* context, int32_t
|
|||
return ORBIS_NP_TROPHY_ERROR_CONTEXT_EXCEEDS_MAX;
|
||||
}
|
||||
|
||||
const auto& key = ContextKey{user_id, service_label};
|
||||
const auto& key = ContextKey{userId, service_label};
|
||||
if (contexts_internal.contains(key)) {
|
||||
return ORBIS_NP_TROPHY_ERROR_CONTEXT_ALREADY_EXISTS;
|
||||
}
|
||||
|
||||
const auto ctx_id = trophy_contexts.insert(user_id, service_label);
|
||||
const auto ctx_id = trophy_contexts.insert(userId, service_label);
|
||||
|
||||
*context = ctx_id.index + 1;
|
||||
contexts_internal[key].context_id = *context;
|
||||
LOG_INFO(Lib_NpTrophy, "New context = {}, user_id = {} service label = {}", *context, user_id,
|
||||
LOG_INFO(Lib_NpTrophy, "New context = {}, user_id = {} service label = {}", *context, userId,
|
||||
service_label);
|
||||
|
||||
return ORBIS_OK;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <core/libraries/system/userservice.h>
|
||||
#include "common/config.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/singleton.h"
|
||||
|
@ -156,7 +157,8 @@ int PS4_SYSV_ABI scePadGetFeatureReport() {
|
|||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI scePadGetHandle(s32 userId, s32 type, s32 index) {
|
||||
int PS4_SYSV_ABI scePadGetHandle(Libraries::UserService::OrbisUserServiceUserId userId, s32 type,
|
||||
s32 index) {
|
||||
if (userId == -1) {
|
||||
return ORBIS_PAD_ERROR_DEVICE_NO_HANDLE;
|
||||
}
|
||||
|
@ -249,7 +251,8 @@ int PS4_SYSV_ABI scePadMbusTerm() {
|
|||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI scePadOpen(s32 userId, s32 type, s32 index, const OrbisPadOpenParam* pParam) {
|
||||
int PS4_SYSV_ABI scePadOpen(Libraries::UserService::OrbisUserServiceUserId userId, s32 type,
|
||||
s32 index, const OrbisPadOpenParam* pParam) {
|
||||
if (userId == -1) {
|
||||
return ORBIS_PAD_ERROR_DEVICE_NO_HANDLE;
|
||||
}
|
||||
|
@ -265,8 +268,8 @@ int PS4_SYSV_ABI scePadOpen(s32 userId, s32 type, s32 index, const OrbisPadOpenP
|
|||
return 1; // dummy
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI scePadOpenExt(s32 userId, s32 type, s32 index,
|
||||
const OrbisPadOpenExtParam* pParam) {
|
||||
int PS4_SYSV_ABI scePadOpenExt(Libraries::UserService::OrbisUserServiceUserId userId, s32 type,
|
||||
s32 index, const OrbisPadOpenExtParam* pParam) {
|
||||
LOG_ERROR(Lib_Pad, "(STUBBED) called");
|
||||
if (Config::getUseSpecialPad()) {
|
||||
if (type != ORBIS_PAD_PORT_TYPE_SPECIAL)
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <core/libraries/system/userservice.h>
|
||||
#include "common/enum.h"
|
||||
#include "common/types.h"
|
||||
|
||||
|
@ -276,7 +277,8 @@ int PS4_SYSV_ABI scePadGetExtControllerInformation(s32 handle,
|
|||
OrbisPadExtendedControllerInformation* pInfo);
|
||||
int PS4_SYSV_ABI scePadGetExtensionUnitInfo();
|
||||
int PS4_SYSV_ABI scePadGetFeatureReport();
|
||||
int PS4_SYSV_ABI scePadGetHandle(s32 userId, s32 type, s32 index);
|
||||
int PS4_SYSV_ABI scePadGetHandle(Libraries::UserService::OrbisUserServiceUserId userId, s32 type,
|
||||
s32 index);
|
||||
int PS4_SYSV_ABI scePadGetIdleCount();
|
||||
int PS4_SYSV_ABI scePadGetInfo();
|
||||
int PS4_SYSV_ABI scePadGetInfoByPortType();
|
||||
|
@ -294,8 +296,10 @@ int PS4_SYSV_ABI scePadIsMoveReproductionModel();
|
|||
int PS4_SYSV_ABI scePadIsValidHandle();
|
||||
int PS4_SYSV_ABI scePadMbusInit();
|
||||
int PS4_SYSV_ABI scePadMbusTerm();
|
||||
int PS4_SYSV_ABI scePadOpen(s32 userId, s32 type, s32 index, const OrbisPadOpenParam* pParam);
|
||||
int PS4_SYSV_ABI scePadOpenExt(s32 userId, s32 type, s32 index, const OrbisPadOpenExtParam* pParam);
|
||||
int PS4_SYSV_ABI scePadOpen(Libraries::UserService::OrbisUserServiceUserId userId, s32 type,
|
||||
s32 index, const OrbisPadOpenParam* pParam);
|
||||
int PS4_SYSV_ABI scePadOpenExt(Libraries::UserService::OrbisUserServiceUserId userId, s32 type,
|
||||
s32 index, const OrbisPadOpenExtParam* pParam);
|
||||
int PS4_SYSV_ABI scePadOpenExt2();
|
||||
int PS4_SYSV_ABI scePadOutputReport();
|
||||
int PS4_SYSV_ABI scePadRead(s32 handle, OrbisPadData* pData, s32 num);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "remoteplay.h"
|
||||
|
||||
#include <core/libraries/system/userservice.h>
|
||||
#include "common/logging/log.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
#include "core/libraries/libs.h"
|
||||
|
@ -54,7 +55,8 @@ int PS4_SYSV_ABI sceRemoteplayGetConnectHistory() {
|
|||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceRemoteplayGetConnectionStatus(s32 userId, int* pStatus) {
|
||||
int PS4_SYSV_ABI sceRemoteplayGetConnectionStatus(
|
||||
Libraries::UserService::OrbisUserServiceUserId userId, int* pStatus) {
|
||||
*pStatus = ORBIS_REMOTEPLAY_CONNECTION_STATUS_DISCONNECT;
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <core/libraries/system/userservice.h>
|
||||
#include "common/types.h"
|
||||
|
||||
namespace Core::Loader {
|
||||
|
@ -24,7 +25,8 @@ int PS4_SYSV_ABI sceRemoteplayDisconnect();
|
|||
int PS4_SYSV_ABI sceRemoteplayGeneratePinCode();
|
||||
int PS4_SYSV_ABI sceRemoteplayGetApMode();
|
||||
int PS4_SYSV_ABI sceRemoteplayGetConnectHistory();
|
||||
int PS4_SYSV_ABI sceRemoteplayGetConnectionStatus(s32 userId, int* pStatus);
|
||||
int PS4_SYSV_ABI sceRemoteplayGetConnectionStatus(
|
||||
Libraries::UserService::OrbisUserServiceUserId userId, int* pStatus);
|
||||
int PS4_SYSV_ABI sceRemoteplayGetConnectUserId();
|
||||
int PS4_SYSV_ABI sceRemoteplayGetMbusDeviceInfo();
|
||||
int PS4_SYSV_ABI sceRemoteplayGetOperationStatus();
|
||||
|
|
|
@ -21,8 +21,8 @@ struct OrbisSharePlayConnectionInfo {
|
|||
int mode;
|
||||
Libraries::NpManager::OrbisNpOnlineId hostOnlineId;
|
||||
Libraries::NpManager::OrbisNpOnlineId visitorOnlineId;
|
||||
s32 hostUserId;
|
||||
s32 visitorUserId;
|
||||
Libraries::UserService::OrbisUserServiceUserId hostUserId;
|
||||
Libraries::UserService::OrbisUserServiceUserId visitorUserId;
|
||||
};
|
||||
|
||||
int PS4_SYSV_ABI sceSharePlayCrashDaemon();
|
||||
|
|
|
@ -490,7 +490,7 @@ int PS4_SYSV_ABI sceUserServiceGetImeRunCount() {
|
|||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceUserServiceGetInitialUser(int* user_id) {
|
||||
s32 PS4_SYSV_ABI sceUserServiceGetInitialUser(OrbisUserServiceUserId* user_id) {
|
||||
LOG_DEBUG(Lib_UserService, "called");
|
||||
if (user_id == nullptr) {
|
||||
LOG_ERROR(Lib_UserService, "user_id is null");
|
||||
|
@ -1041,7 +1041,8 @@ int PS4_SYSV_ABI sceUserServiceGetTraditionalChineseInputType() {
|
|||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceUserServiceGetUserColor(int user_id, OrbisUserServiceUserColor* color) {
|
||||
s32 PS4_SYSV_ABI sceUserServiceGetUserColor(OrbisUserServiceUserId user_id,
|
||||
OrbisUserServiceUserColor* color) {
|
||||
// TODO fix me better
|
||||
LOG_DEBUG(Lib_UserService, "called user_id = {}", user_id);
|
||||
if (color == nullptr) {
|
||||
|
@ -1067,7 +1068,8 @@ int PS4_SYSV_ABI sceUserServiceGetUserGroupNum() {
|
|||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceUserServiceGetUserName(int user_id, char* user_name, std::size_t size) {
|
||||
s32 PS4_SYSV_ABI sceUserServiceGetUserName(OrbisUserServiceUserId user_id, char* user_name,
|
||||
std::size_t size) {
|
||||
LOG_DEBUG(Lib_UserService, "called user_id = {} ,size = {} ", user_id, size);
|
||||
if (user_name == nullptr) {
|
||||
LOG_ERROR(Lib_UserService, "user_name is null");
|
||||
|
|
|
@ -151,7 +151,7 @@ int PS4_SYSV_ABI sceUserServiceGetImeLastUnit();
|
|||
int PS4_SYSV_ABI sceUserServiceGetImePointerMode();
|
||||
int PS4_SYSV_ABI sceUserServiceGetImePredictiveTextEnabled();
|
||||
int PS4_SYSV_ABI sceUserServiceGetImeRunCount();
|
||||
s32 PS4_SYSV_ABI sceUserServiceGetInitialUser(int* user_id);
|
||||
s32 PS4_SYSV_ABI sceUserServiceGetInitialUser(OrbisUserServiceUserId* user_id);
|
||||
int PS4_SYSV_ABI sceUserServiceGetIPDLeft();
|
||||
int PS4_SYSV_ABI sceUserServiceGetIPDRight();
|
||||
int PS4_SYSV_ABI sceUserServiceGetIsFakePlus();
|
||||
|
@ -258,11 +258,13 @@ int PS4_SYSV_ABI sceUserServiceGetTopMenuLimitItem();
|
|||
int PS4_SYSV_ABI sceUserServiceGetTopMenuNotificationFlag();
|
||||
int PS4_SYSV_ABI sceUserServiceGetTopMenuTutorialFlag();
|
||||
int PS4_SYSV_ABI sceUserServiceGetTraditionalChineseInputType();
|
||||
s32 PS4_SYSV_ABI sceUserServiceGetUserColor(int user_id, OrbisUserServiceUserColor* color);
|
||||
s32 PS4_SYSV_ABI sceUserServiceGetUserColor(OrbisUserServiceUserId user_id,
|
||||
OrbisUserServiceUserColor* color);
|
||||
int PS4_SYSV_ABI sceUserServiceGetUserGroupName();
|
||||
int PS4_SYSV_ABI sceUserServiceGetUserGroupNameList();
|
||||
int PS4_SYSV_ABI sceUserServiceGetUserGroupNum();
|
||||
s32 PS4_SYSV_ABI sceUserServiceGetUserName(int user_id, char* user_name, std::size_t size);
|
||||
s32 PS4_SYSV_ABI sceUserServiceGetUserName(OrbisUserServiceUserId user_id, char* user_name,
|
||||
std::size_t size);
|
||||
int PS4_SYSV_ABI sceUserServiceGetUserStatus();
|
||||
int PS4_SYSV_ABI sceUserServiceGetVibrationEnabled();
|
||||
int PS4_SYSV_ABI sceUserServiceGetVoiceRecognitionLastUsedOsk();
|
||||
|
|
|
@ -291,8 +291,8 @@ s32 PS4_SYSV_ABI sceVideoOutGetResolutionStatus(s32 handle, SceVideoOutResolutio
|
|||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceVideoOutOpen(SceUserServiceUserId userId, s32 busType, s32 index,
|
||||
const void* param) {
|
||||
s32 PS4_SYSV_ABI sceVideoOutOpen(Libraries::UserService::OrbisUserServiceUserId userId, s32 busType,
|
||||
s32 index, const void* param) {
|
||||
LOG_INFO(Lib_VideoOut, "called");
|
||||
ASSERT(busType == SCE_VIDEO_OUT_BUS_TYPE_MAIN);
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <core/libraries/system/userservice.h>
|
||||
#include "core/libraries/kernel/equeue.h"
|
||||
#include "core/libraries/videoout/buffer.h"
|
||||
|
||||
|
@ -12,8 +13,6 @@ class SymbolsResolver;
|
|||
|
||||
namespace Libraries::VideoOut {
|
||||
|
||||
using SceUserServiceUserId = s32; // TODO move it to proper place
|
||||
|
||||
// SceVideoOutBusType
|
||||
constexpr int SCE_VIDEO_OUT_BUS_TYPE_MAIN = 0; // Main output
|
||||
constexpr int SCE_VIDEO_OUT_BUS_TYPE_AUX_SOCIAL_SCREEN = 5; // Aux output for social
|
||||
|
@ -131,8 +130,8 @@ s32 PS4_SYSV_ABI sceVideoOutWaitVblank(s32 handle);
|
|||
s32 PS4_SYSV_ABI sceVideoOutSubmitFlip(s32 handle, s32 bufferIndex, s32 flipMode, s64 flipArg);
|
||||
s32 PS4_SYSV_ABI sceVideoOutGetFlipStatus(s32 handle, FlipStatus* status);
|
||||
s32 PS4_SYSV_ABI sceVideoOutGetResolutionStatus(s32 handle, SceVideoOutResolutionStatus* status);
|
||||
s32 PS4_SYSV_ABI sceVideoOutOpen(SceUserServiceUserId userId, s32 busType, s32 index,
|
||||
const void* param);
|
||||
s32 PS4_SYSV_ABI sceVideoOutOpen(Libraries::UserService::OrbisUserServiceUserId userId, s32 busType,
|
||||
s32 index, const void* param);
|
||||
s32 PS4_SYSV_ABI sceVideoOutClose(s32 handle);
|
||||
s32 PS4_SYSV_ABI sceVideoOutGetEventId(const Kernel::SceKernelEvent* ev);
|
||||
s32 PS4_SYSV_ABI sceVideoOutGetEventData(const Kernel::SceKernelEvent* ev, s64* data);
|
||||
|
|
72
src/core/user_account.cpp
Normal file
72
src/core/user_account.cpp
Normal file
|
@ -0,0 +1,72 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <filesystem>
|
||||
#include <common/io_file.h>
|
||||
#include <common/path_util.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "common/config.h"
|
||||
#include "user_account.h"
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
user_account::user_account(const std::string& user_id) {
|
||||
// Setting userId.
|
||||
m_user_id = user_id;
|
||||
|
||||
m_user_dir =
|
||||
Common::FS::GetUserPathString(Common::FS::PathType::HomeDir) + "/" + m_user_id + "/";
|
||||
|
||||
Common::FS::IOFile userfile(m_user_dir + "localuser.json", Common::FS::FileAccessMode::Read);
|
||||
if (userfile.IsOpen()) {
|
||||
nlohmann::json jsonfile;
|
||||
try {
|
||||
jsonfile = nlohmann::json::parse(userfile.ReadString(userfile.GetSize()));
|
||||
} catch (const nlohmann::json::parse_error& e) {
|
||||
// TODO error code
|
||||
}
|
||||
userfile.Close();
|
||||
m_username = jsonfile.value("username", "shadps4");
|
||||
if (m_username.length() > 16) // max of 16 chars allowed
|
||||
{
|
||||
m_username = m_username.substr(0, 16); // substring 16 only characters to display
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::map<u32, user_account> user_account::GetUserAccounts(const std::string& base_dir) {
|
||||
std::map<u32, user_account> user_list;
|
||||
for (const auto& entry : std::filesystem::directory_iterator(base_dir)) {
|
||||
if (entry.is_directory()) {
|
||||
std::string folder_name = entry.path().filename().string();
|
||||
const u32 key = check_user(folder_name);
|
||||
if (key == 0) {
|
||||
continue;
|
||||
}
|
||||
const std::filesystem::path account_file = entry.path() / "localuser.json";
|
||||
if (std::filesystem::exists(account_file)) {
|
||||
user_list.emplace(key, user_account(folder_name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return user_list;
|
||||
}
|
||||
|
||||
void user_account::createdDefaultUser() {
|
||||
const auto& default_user_dir =
|
||||
Common::FS::GetUserPath(Common::FS::PathType::HomeDir) / Config::getDefaultUserId();
|
||||
if (!std::filesystem::exists(default_user_dir)) {
|
||||
std::filesystem::create_directory(default_user_dir);
|
||||
Common::FS::IOFile userfile(default_user_dir / "localuser.json",
|
||||
Common::FS::FileAccessMode::Write);
|
||||
nlohmann::json jsonfile;
|
||||
|
||||
// Assign values
|
||||
jsonfile["username"] = "shadps4";
|
||||
|
||||
std::string jsonStr = jsonfile.dump(4);
|
||||
userfile.WriteString(jsonStr);
|
||||
userfile.Close();
|
||||
}
|
||||
}
|
40
src/core/user_account.h
Normal file
40
src/core/user_account.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
#include <charconv>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include "common/types.h"
|
||||
|
||||
class user_account {
|
||||
public:
|
||||
explicit user_account(const std::string& user_id = "00000001");
|
||||
|
||||
const std::string& GetUserId() const {
|
||||
return m_user_id;
|
||||
}
|
||||
const std::string& GetUserDir() const {
|
||||
return m_user_dir;
|
||||
}
|
||||
const std::string& GetUsername() const {
|
||||
return m_username;
|
||||
}
|
||||
|
||||
static std::map<u32, user_account> GetUserAccounts(const std::string& base_dir);
|
||||
static void createdDefaultUser();
|
||||
static u32 check_user(const std::string& user) {
|
||||
u32 id = 0;
|
||||
|
||||
if (user.size() == 8) {
|
||||
std::from_chars(&user.front(), &user.back() + 1, id);
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_user_id;
|
||||
std::string m_user_dir;
|
||||
std::string m_username;
|
||||
};
|
BIN
src/images/users_icon.png
Normal file
BIN
src/images/users_icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.6 KiB |
|
@ -7,6 +7,7 @@
|
|||
#include "system_error"
|
||||
#include "unordered_map"
|
||||
|
||||
#include <core/user_account.h>
|
||||
#include <fmt/core.h>
|
||||
#include "common/config.h"
|
||||
#include "common/memory_patcher.h"
|
||||
|
@ -27,6 +28,8 @@ int main(int argc, char* argv[]) {
|
|||
const auto user_dir = Common::FS::GetUserPath(Common::FS::PathType::UserDir);
|
||||
Config::load(user_dir / "config.toml");
|
||||
|
||||
user_account::createdDefaultUser();
|
||||
|
||||
bool has_game_argument = false;
|
||||
std::string game_path;
|
||||
std::vector<std::string> game_args{};
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "system_error"
|
||||
#include "unordered_map"
|
||||
|
||||
#include <core/user_account.h>
|
||||
#include "common/config.h"
|
||||
#include "common/memory_patcher.h"
|
||||
#include "core/file_sys/fs.h"
|
||||
|
@ -32,6 +33,8 @@ int main(int argc, char* argv[]) {
|
|||
const auto user_dir = Common::FS::GetUserPath(Common::FS::PathType::UserDir);
|
||||
Config::load(user_dir / "config.toml");
|
||||
|
||||
user_account::createdDefaultUser();
|
||||
|
||||
bool has_command_line_argument = argc > 1;
|
||||
bool show_gui = false, has_game_argument = false;
|
||||
std::string game_path;
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#ifdef ENABLE_DISCORD_RPC
|
||||
#include "common/discord_rpc_handler.h"
|
||||
#endif
|
||||
#include "user_management_dialog.h"
|
||||
|
||||
MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
|
||||
ui->setupUi(this);
|
||||
|
@ -438,6 +439,11 @@ void MainWindow::CreateConnects() {
|
|||
settingsDialog->exec();
|
||||
});
|
||||
|
||||
connect(ui->userManagement, &QAction::triggered, this, [this]() {
|
||||
user_manager_dialog user_manager(this);
|
||||
user_manager.exec();
|
||||
});
|
||||
|
||||
connect(ui->settingsButton, &QPushButton::clicked, this, [this]() {
|
||||
auto settingsDialog = new SettingsDialog(m_gui_settings, m_compat_info, this);
|
||||
|
||||
|
@ -1102,6 +1108,7 @@ void MainWindow::SetUiIcons(bool isWhite) {
|
|||
ui->menuGame_List_Mode->setIcon(RecolorIcon(ui->menuGame_List_Mode->icon(), isWhite));
|
||||
ui->trophyViewerAct->setIcon(RecolorIcon(ui->trophyViewerAct->icon(), isWhite));
|
||||
ui->configureAct->setIcon(RecolorIcon(ui->configureAct->icon(), isWhite));
|
||||
ui->userManagement->setIcon(RecolorIcon(ui->userManagement->icon(), isWhite));
|
||||
ui->addElfFolderAct->setIcon(RecolorIcon(ui->addElfFolderAct->icon(), isWhite));
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ public:
|
|||
#endif
|
||||
QAction* aboutAct;
|
||||
QAction* configureAct;
|
||||
QAction* userManagement;
|
||||
QAction* setThemeDark;
|
||||
QAction* setThemeLight;
|
||||
QAction* setThemeGreen;
|
||||
|
@ -155,6 +156,9 @@ public:
|
|||
configureAct = new QAction(MainWindow);
|
||||
configureAct->setObjectName("configureAct");
|
||||
configureAct->setIcon(QIcon(":images/settings_icon.png"));
|
||||
userManagement = new QAction(MainWindow);
|
||||
userManagement->setObjectName("userManagement");
|
||||
userManagement->setIcon(QIcon(":images/users_icon.png"));
|
||||
setThemeDark = new QAction(MainWindow);
|
||||
setThemeDark->setObjectName("setThemeDark");
|
||||
setThemeDark->setCheckable(true);
|
||||
|
@ -329,6 +333,7 @@ public:
|
|||
menuGame_List_Mode->addAction(setlistModeGridAct);
|
||||
menuGame_List_Mode->addAction(setlistElfAct);
|
||||
menuSettings->addAction(configureAct);
|
||||
menuSettings->addAction(userManagement);
|
||||
menuSettings->addAction(gameInstallPathAct);
|
||||
menuSettings->addAction(menuUtils->menuAction());
|
||||
menuUtils->addAction(downloadCheatsPatchesAct);
|
||||
|
@ -355,6 +360,8 @@ public:
|
|||
#endif
|
||||
aboutAct->setText(QCoreApplication::translate("MainWindow", "About shadPS4", nullptr));
|
||||
configureAct->setText(QCoreApplication::translate("MainWindow", "Configure...", nullptr));
|
||||
userManagement->setText(
|
||||
QCoreApplication::translate("MainWindow", "User Management", nullptr));
|
||||
#if QT_CONFIG(tooltip)
|
||||
#endif // QT_CONFIG(tooltip)
|
||||
menuRecent->setTitle(QCoreApplication::translate("MainWindow", "Recent Games", nullptr));
|
||||
|
|
126
src/qt_gui/user_management_dialog.cpp
Normal file
126
src/qt_gui/user_management_dialog.cpp
Normal file
|
@ -0,0 +1,126 @@
|
|||
#include "user_management_dialog.h"
|
||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <QDesktopServices>
|
||||
#include <QEvent>
|
||||
#include <QGuiApplication>
|
||||
#include <QHBoxLayout>
|
||||
#include <QHeaderView>
|
||||
#include <QInputDialog>
|
||||
#include <QKeyEvent>
|
||||
#include <QMenu>
|
||||
#include <QMessageBox>
|
||||
#include <QMouseEvent>
|
||||
#include <QPushButton>
|
||||
#include <QRegularExpressionValidator>
|
||||
#include <QScreen>
|
||||
#include <common/path_util.h>
|
||||
#include "common/config.h"
|
||||
#include "user_management_dialog.h"
|
||||
|
||||
user_manager_dialog::user_manager_dialog(QWidget* parent) : QDialog(parent) {
|
||||
setWindowTitle(tr("User Manager"));
|
||||
setMinimumSize(QSize(500, 400));
|
||||
setModal(true);
|
||||
|
||||
Init();
|
||||
}
|
||||
|
||||
void user_manager_dialog::Init() {
|
||||
// Table
|
||||
m_table = new QTableWidget(this);
|
||||
m_table->setSelectionMode(QAbstractItemView::SelectionMode::SingleSelection);
|
||||
m_table->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
m_table->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
m_table->setColumnCount(2);
|
||||
m_table->setCornerButtonEnabled(false);
|
||||
m_table->setAlternatingRowColors(true);
|
||||
m_table->setHorizontalHeaderLabels(QStringList() << tr("User ID") << tr("User Name"));
|
||||
m_table->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
|
||||
m_table->horizontalHeader()->setStretchLastSection(true);
|
||||
m_table->horizontalHeader()->setDefaultSectionSize(150);
|
||||
m_table->installEventFilter(this);
|
||||
|
||||
QPushButton* push_remove_user = new QPushButton(tr("&Delete User"), this);
|
||||
push_remove_user->setAutoDefault(false);
|
||||
|
||||
QPushButton* push_create_user = new QPushButton(tr("&Create User"), this);
|
||||
push_create_user->setAutoDefault(false);
|
||||
|
||||
QPushButton* push_edit_user = new QPushButton(tr("&Edit User"), this);
|
||||
push_edit_user->setAutoDefault(false);
|
||||
|
||||
QPushButton* push_close = new QPushButton(tr("&Close"), this);
|
||||
push_close->setAutoDefault(false);
|
||||
|
||||
// Button Layout
|
||||
QHBoxLayout* hbox_buttons = new QHBoxLayout();
|
||||
hbox_buttons->addWidget(push_create_user);
|
||||
hbox_buttons->addWidget(push_edit_user);
|
||||
hbox_buttons->addWidget(push_remove_user);
|
||||
hbox_buttons->addStretch();
|
||||
hbox_buttons->addWidget(push_close);
|
||||
|
||||
// Main Layout
|
||||
QVBoxLayout* vbox_main = new QVBoxLayout();
|
||||
vbox_main->setAlignment(Qt::AlignCenter);
|
||||
vbox_main->addWidget(m_table);
|
||||
vbox_main->addLayout(hbox_buttons);
|
||||
setLayout(vbox_main);
|
||||
|
||||
// get active user
|
||||
m_active_user = Config::getActiveUserId();
|
||||
RefreshTable();
|
||||
}
|
||||
void user_manager_dialog::RefreshTable() {
|
||||
|
||||
// For indicating logged-in user.
|
||||
QFont bold_font;
|
||||
bold_font.setBold(true);
|
||||
|
||||
m_user_list.clear();
|
||||
const auto& home_dir = Common::FS::GetUserPathString(Common::FS::PathType::HomeDir);
|
||||
m_user_list = user_account::GetUserAccounts(home_dir);
|
||||
|
||||
// Clear and then repopulate the table with the list gathered above.
|
||||
m_table->setRowCount(static_cast<int>(m_user_list.size()));
|
||||
|
||||
int row = 0;
|
||||
for (auto& [id, account] : m_user_list) {
|
||||
QTableWidgetItem* user_id_item =
|
||||
new QTableWidgetItem(QString::fromStdString(account.GetUserId()));
|
||||
user_id_item->setData(Qt::UserRole, id);
|
||||
user_id_item->setFlags(user_id_item->flags() & ~Qt::ItemIsEditable);
|
||||
m_table->setItem(row, 0, user_id_item);
|
||||
|
||||
QTableWidgetItem* username_item =
|
||||
new QTableWidgetItem(QString::fromStdString(account.GetUsername()));
|
||||
username_item->setData(Qt::UserRole, id);
|
||||
username_item->setFlags(username_item->flags() & ~Qt::ItemIsEditable);
|
||||
m_table->setItem(row, 1, username_item);
|
||||
|
||||
// make bold the user that is active
|
||||
if (m_active_user.starts_with(account.GetUserId())) {
|
||||
user_id_item->setFont(bold_font);
|
||||
username_item->setFont(bold_font);
|
||||
}
|
||||
++row;
|
||||
}
|
||||
|
||||
// GUI resizing
|
||||
m_table->horizontalHeader()->resizeSections(QHeaderView::ResizeToContents);
|
||||
m_table->verticalHeader()->resizeSections(QHeaderView::ResizeToContents);
|
||||
|
||||
const QSize table_size(m_table->verticalHeader()->width() +
|
||||
m_table->horizontalHeader()->length() + m_table->frameWidth() * 2,
|
||||
m_table->horizontalHeader()->height() +
|
||||
m_table->verticalHeader()->length() + m_table->frameWidth() * 2);
|
||||
|
||||
const QSize preferred_size =
|
||||
minimumSize().expandedTo(sizeHint() - m_table->sizeHint() + table_size).expandedTo(size());
|
||||
const QSize max_size(preferred_size.width(),
|
||||
static_cast<int>(QGuiApplication::primaryScreen()->size().height() * 0.6));
|
||||
|
||||
resize(preferred_size.boundedTo(max_size));
|
||||
}
|
23
src/qt_gui/user_management_dialog.h
Normal file
23
src/qt_gui/user_management_dialog.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
#include <QTableWidget>
|
||||
#include <core/user_account.h>
|
||||
|
||||
class user_manager_dialog : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit user_manager_dialog(QWidget* parent = nullptr);
|
||||
|
||||
private:
|
||||
void Init();
|
||||
void RefreshTable();
|
||||
|
||||
QTableWidget* m_table = nullptr;
|
||||
std::string m_active_user;
|
||||
std::map<u32, user_account> m_user_list;
|
||||
};
|
|
@ -37,6 +37,7 @@
|
|||
<file>images/fullscreen_icon.png</file>
|
||||
<file>images/refreshlist_icon.png</file>
|
||||
<file>images/favorite_icon.png</file>
|
||||
<file>images/trophy_icon.png</file>
|
||||
<file>images/trophy_icon.png</file>
|
||||
<file>images/users_icon.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue