Fix scePadOpen error returns and decouple pad handles from user IDs

This commit is contained in:
kalaposfos13 2026-03-04 16:36:50 +01:00
parent a595661d98
commit 8f3e3c2a69
6 changed files with 45 additions and 15 deletions

View File

@ -6,6 +6,7 @@
#include "core/emulator_settings.h" #include "core/emulator_settings.h"
#include "core/libraries/libs.h" #include "core/libraries/libs.h"
#include "core/libraries/pad/pad_errors.h" #include "core/libraries/pad/pad_errors.h"
#include "core/user_settings.h"
#include "input/controller.h" #include "input/controller.h"
#include "pad.h" #include "pad.h"
@ -266,8 +267,11 @@ int PS4_SYSV_ABI scePadOpen(Libraries::UserService::OrbisUserServiceUserId userI
if (!g_initialized) { if (!g_initialized) {
return ORBIS_PAD_ERROR_NOT_INITIALIZED; return ORBIS_PAD_ERROR_NOT_INITIALIZED;
} }
if (userId == -1) { if (userId < 0) {
return ORBIS_PAD_ERROR_DEVICE_NO_HANDLE; return ORBIS_DEVICE_SERVICE_ERROR_INVALID_USER;
}
if (userId == Libraries::UserService::ORBIS_USER_SERVICE_USER_ID_SYSTEM) {
return ORBIS_DEVICE_SERVICE_ERROR_INVALID_USER;
} }
if (EmulatorSettings.IsUsingSpecialPad()) { if (EmulatorSettings.IsUsingSpecialPad()) {
if (type != ORBIS_PAD_PORT_TYPE_SPECIAL) if (type != ORBIS_PAD_PORT_TYPE_SPECIAL)
@ -276,11 +280,17 @@ int PS4_SYSV_ABI scePadOpen(Libraries::UserService::OrbisUserServiceUserId userI
if (type != ORBIS_PAD_PORT_TYPE_STANDARD && type != ORBIS_PAD_PORT_TYPE_REMOTE_CONTROL) if (type != ORBIS_PAD_PORT_TYPE_STANDARD && type != ORBIS_PAD_PORT_TYPE_REMOTE_CONTROL)
return ORBIS_PAD_ERROR_DEVICE_NOT_CONNECTED; return ORBIS_PAD_ERROR_DEVICE_NOT_CONNECTED;
} }
LOG_INFO(Lib_Pad, "(DUMMY) called user_id = {} type = {} index = {}", userId, type, index); auto u = UserManagement.GetUserByID(userId);
if (!u) {
return ORBIS_DEVICE_SERVICE_ERROR_USER_NOT_LOGIN;
}
s32 pad_handle = u->controller_port;
LOG_INFO(Lib_Pad, "(DUMMY) called user_id = {} type = {} index = {}, pad_handle = {}", userId,
type, index, pad_handle);
g_opened = true; g_opened = true;
scePadResetLightBar(userId); scePadResetLightBar(pad_handle);
scePadResetOrientation(userId); scePadResetOrientation(pad_handle);
return userId; // TODO: userId shouldn't be used as the handle too return pad_handle;
} }
int PS4_SYSV_ABI scePadOpenExt(Libraries::UserService::OrbisUserServiceUserId userId, s32 type, int PS4_SYSV_ABI scePadOpenExt(Libraries::UserService::OrbisUserServiceUserId userId, s32 type,
@ -411,7 +421,7 @@ int PS4_SYSV_ABI scePadRead(s32 handle, OrbisPadData* pData, s32 num) {
int connected_count = 0; int connected_count = 0;
bool connected = false; bool connected = false;
std::vector<Input::State> states(64); std::vector<Input::State> states(64);
auto controller_id = GameControllers::GetControllerIndexFromUserID(handle); auto controller_id = GameControllers::GetControllerIndexFromControllerID(handle);
if (!controller_id) { if (!controller_id) {
return ORBIS_PAD_ERROR_INVALID_HANDLE; return ORBIS_PAD_ERROR_INVALID_HANDLE;
} }
@ -444,7 +454,7 @@ int PS4_SYSV_ABI scePadReadHistory() {
int PS4_SYSV_ABI scePadReadState(s32 handle, OrbisPadData* pData) { int PS4_SYSV_ABI scePadReadState(s32 handle, OrbisPadData* pData) {
LOG_TRACE(Lib_Pad, "handle: {}", handle); LOG_TRACE(Lib_Pad, "handle: {}", handle);
auto controller_id = GameControllers::GetControllerIndexFromUserID(handle); auto controller_id = GameControllers::GetControllerIndexFromControllerID(handle);
if (!controller_id) { if (!controller_id) {
return ORBIS_PAD_ERROR_INVALID_HANDLE; return ORBIS_PAD_ERROR_INVALID_HANDLE;
} }
@ -465,7 +475,7 @@ int PS4_SYSV_ABI scePadReadStateExt() {
int PS4_SYSV_ABI scePadResetLightBar(s32 handle) { int PS4_SYSV_ABI scePadResetLightBar(s32 handle) {
LOG_INFO(Lib_Pad, "(DUMMY) called"); LOG_INFO(Lib_Pad, "(DUMMY) called");
auto controller_id = GameControllers::GetControllerIndexFromUserID(handle); auto controller_id = GameControllers::GetControllerIndexFromControllerID(handle);
if (!controller_id) { if (!controller_id) {
return ORBIS_PAD_ERROR_INVALID_HANDLE; return ORBIS_PAD_ERROR_INVALID_HANDLE;
} }
@ -488,7 +498,7 @@ int PS4_SYSV_ABI scePadResetLightBarAllByPortType() {
int PS4_SYSV_ABI scePadResetOrientation(s32 handle) { int PS4_SYSV_ABI scePadResetOrientation(s32 handle) {
LOG_INFO(Lib_Pad, "scePadResetOrientation called handle = {}", handle); LOG_INFO(Lib_Pad, "scePadResetOrientation called handle = {}", handle);
auto controller_id = GameControllers::GetControllerIndexFromUserID(handle); auto controller_id = GameControllers::GetControllerIndexFromControllerID(handle);
if (!controller_id) { if (!controller_id) {
return ORBIS_PAD_ERROR_INVALID_HANDLE; return ORBIS_PAD_ERROR_INVALID_HANDLE;
} }
@ -545,7 +555,7 @@ int PS4_SYSV_ABI scePadSetLightBar(s32 handle, const OrbisPadLightBarParam* pPar
if (GameControllers::GetOverrideControllerColor()) { if (GameControllers::GetOverrideControllerColor()) {
return ORBIS_OK; return ORBIS_OK;
} }
auto controller_id = GameControllers::GetControllerIndexFromUserID(handle); auto controller_id = GameControllers::GetControllerIndexFromControllerID(handle);
if (!controller_id) { if (!controller_id) {
return ORBIS_PAD_ERROR_INVALID_HANDLE; return ORBIS_PAD_ERROR_INVALID_HANDLE;
} }
@ -625,7 +635,7 @@ int PS4_SYSV_ABI scePadSetUserColor() {
} }
int PS4_SYSV_ABI scePadSetVibration(s32 handle, const OrbisPadVibrationParam* pParam) { int PS4_SYSV_ABI scePadSetVibration(s32 handle, const OrbisPadVibrationParam* pParam) {
auto controller_id = GameControllers::GetControllerIndexFromUserID(handle); auto controller_id = GameControllers::GetControllerIndexFromControllerID(handle);
if (!controller_id) { if (!controller_id) {
return ORBIS_PAD_ERROR_INVALID_HANDLE; return ORBIS_PAD_ERROR_INVALID_HANDLE;
} }

View File

@ -20,3 +20,6 @@ constexpr int ORBIS_PAD_ERROR_INVALID_BUFFER_LENGTH = 0x80920102;
constexpr int ORBIS_PAD_ERROR_INVALID_REPORT_LENGTH = 0x80920103; constexpr int ORBIS_PAD_ERROR_INVALID_REPORT_LENGTH = 0x80920103;
constexpr int ORBIS_PAD_ERROR_INVALID_REPORT_ID = 0x80920104; constexpr int ORBIS_PAD_ERROR_INVALID_REPORT_ID = 0x80920104;
constexpr int ORBIS_PAD_ERROR_SEND_AGAIN = 0x80920105; constexpr int ORBIS_PAD_ERROR_SEND_AGAIN = 0x80920105;
constexpr s32 ORBIS_DEVICE_SERVICE_ERROR_INVALID_USER = 0x809b0001;
constexpr s32 ORBIS_DEVICE_SERVICE_ERROR_USER_NOT_LOGIN = 0x809b0081;

View File

@ -18,9 +18,10 @@ struct User {
struct Users { struct Users {
int default_user_id = 1; int default_user_id = 1;
std::vector<User> user; std::vector<User> user;
std::string commit_hash{};
}; };
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(User, user_id, user_color, user_name, controller_port) NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(User, user_id, user_color, user_name, controller_port)
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Users, default_user_id, user) NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Users, default_user_id, user, commit_hash)
class UserManager { class UserManager {
public: public:

View File

@ -40,6 +40,7 @@ bool UserSettingsImpl::Save() const {
try { try {
json j; json j;
j["Users"] = m_userManager.GetUsers(); j["Users"] = m_userManager.GetUsers();
j["Users"]["commit_hash"] = std::string(Common::g_scm_rev);
std::ofstream out(path); std::ofstream out(path);
if (!out) { if (!out) {
@ -102,6 +103,10 @@ bool UserSettingsImpl::Load() {
m_userManager.GetUsers() = default_users; m_userManager.GetUsers() = default_users;
} }
if (m_userManager.GetUsers().commit_hash != Common::g_scm_rev) {
Save();
}
LOG_DEBUG(EmuSettings, "User settings loaded successfully"); LOG_DEBUG(EmuSettings, "User settings loaded successfully");
return true; return true;
} catch (const std::exception& e) { } catch (const std::exception& e) {

View File

@ -8,6 +8,7 @@
#include "common/logging/log.h" #include "common/logging/log.h"
#include "controller.h" #include "controller.h"
#include "core/emulator_settings.h" #include "core/emulator_settings.h"
#include "core/user_settings.h"
#include "core/libraries/kernel/time.h" #include "core/libraries/kernel/time.h"
#include "core/libraries/pad/pad.h" #include "core/libraries/pad/pad.h"
#include "core/libraries/system/userservice.h" #include "core/libraries/system/userservice.h"
@ -375,9 +376,18 @@ u8 GameControllers::GetGamepadIndexFromJoystickId(SDL_JoystickID id) {
} }
std::optional<u8> GameControllers::GetControllerIndexFromUserID(s32 user_id) { std::optional<u8> GameControllers::GetControllerIndexFromUserID(s32 user_id) {
if (user_id < 1 || user_id > 4) auto const u = UserManagement.GetUserByID(user_id);
if (!u) {
return std::nullopt; return std::nullopt;
return static_cast<u8>(user_id - 1); }
return u->controller_port - 1;
}
std::optional<u8> GameControllers::GetControllerIndexFromControllerID(s32 controller_id) {
if (controller_id < 1 || controller_id > 4) {
return std::nullopt;
}
return controller_id - 1;
} }
} // namespace Input } // namespace Input

View File

@ -258,6 +258,7 @@ public:
static void TryOpenSDLControllers(GameControllers& controllers); static void TryOpenSDLControllers(GameControllers& controllers);
static u8 GetGamepadIndexFromJoystickId(SDL_JoystickID id); static u8 GetGamepadIndexFromJoystickId(SDL_JoystickID id);
static std::optional<u8> GetControllerIndexFromUserID(s32 user_id); static std::optional<u8> GetControllerIndexFromUserID(s32 user_id);
static std::optional<u8> GetControllerIndexFromControllerID(s32 controller_id);
static void CalculateOrientation(Libraries::Pad::OrbisFVector3& acceleration, static void CalculateOrientation(Libraries::Pad::OrbisFVector3& acceleration,
Libraries::Pad::OrbisFVector3& angularVelocity, Libraries::Pad::OrbisFVector3& angularVelocity,