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/libraries/libs.h"
#include "core/libraries/pad/pad_errors.h"
#include "core/user_settings.h"
#include "input/controller.h"
#include "pad.h"
@ -266,8 +267,11 @@ int PS4_SYSV_ABI scePadOpen(Libraries::UserService::OrbisUserServiceUserId userI
if (!g_initialized) {
return ORBIS_PAD_ERROR_NOT_INITIALIZED;
}
if (userId == -1) {
return ORBIS_PAD_ERROR_DEVICE_NO_HANDLE;
if (userId < 0) {
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 (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)
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;
scePadResetLightBar(userId);
scePadResetOrientation(userId);
return userId; // TODO: userId shouldn't be used as the handle too
scePadResetLightBar(pad_handle);
scePadResetOrientation(pad_handle);
return pad_handle;
}
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;
bool connected = false;
std::vector<Input::State> states(64);
auto controller_id = GameControllers::GetControllerIndexFromUserID(handle);
auto controller_id = GameControllers::GetControllerIndexFromControllerID(handle);
if (!controller_id) {
return ORBIS_PAD_ERROR_INVALID_HANDLE;
}
@ -444,7 +454,7 @@ int PS4_SYSV_ABI scePadReadHistory() {
int PS4_SYSV_ABI scePadReadState(s32 handle, OrbisPadData* pData) {
LOG_TRACE(Lib_Pad, "handle: {}", handle);
auto controller_id = GameControllers::GetControllerIndexFromUserID(handle);
auto controller_id = GameControllers::GetControllerIndexFromControllerID(handle);
if (!controller_id) {
return ORBIS_PAD_ERROR_INVALID_HANDLE;
}
@ -465,7 +475,7 @@ int PS4_SYSV_ABI scePadReadStateExt() {
int PS4_SYSV_ABI scePadResetLightBar(s32 handle) {
LOG_INFO(Lib_Pad, "(DUMMY) called");
auto controller_id = GameControllers::GetControllerIndexFromUserID(handle);
auto controller_id = GameControllers::GetControllerIndexFromControllerID(handle);
if (!controller_id) {
return ORBIS_PAD_ERROR_INVALID_HANDLE;
}
@ -488,7 +498,7 @@ int PS4_SYSV_ABI scePadResetLightBarAllByPortType() {
int PS4_SYSV_ABI scePadResetOrientation(s32 handle) {
LOG_INFO(Lib_Pad, "scePadResetOrientation called handle = {}", handle);
auto controller_id = GameControllers::GetControllerIndexFromUserID(handle);
auto controller_id = GameControllers::GetControllerIndexFromControllerID(handle);
if (!controller_id) {
return ORBIS_PAD_ERROR_INVALID_HANDLE;
}
@ -545,7 +555,7 @@ int PS4_SYSV_ABI scePadSetLightBar(s32 handle, const OrbisPadLightBarParam* pPar
if (GameControllers::GetOverrideControllerColor()) {
return ORBIS_OK;
}
auto controller_id = GameControllers::GetControllerIndexFromUserID(handle);
auto controller_id = GameControllers::GetControllerIndexFromControllerID(handle);
if (!controller_id) {
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) {
auto controller_id = GameControllers::GetControllerIndexFromUserID(handle);
auto controller_id = GameControllers::GetControllerIndexFromControllerID(handle);
if (!controller_id) {
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_ID = 0x80920104;
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 {
int default_user_id = 1;
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(Users, default_user_id, user)
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Users, default_user_id, user, commit_hash)
class UserManager {
public:

View File

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

View File

@ -8,6 +8,7 @@
#include "common/logging/log.h"
#include "controller.h"
#include "core/emulator_settings.h"
#include "core/user_settings.h"
#include "core/libraries/kernel/time.h"
#include "core/libraries/pad/pad.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) {
if (user_id < 1 || user_id > 4)
auto const u = UserManagement.GetUserByID(user_id);
if (!u) {
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

View File

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