mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 22:06:59 +01:00
Track pad port ownership and reject duplicate opens
This commit is contained in:
+112
-57
@@ -24,8 +24,12 @@ namespace Libs::Controller {
|
|||||||
|
|
||||||
LIB_NAME("Pad", "Pad");
|
LIB_NAME("Pad", "Pad");
|
||||||
|
|
||||||
constexpr int PAD_ERROR_INVALID_ARG = -2137915391; /* 0x80920001 */
|
constexpr int PAD_ERROR_INVALID_ARG = -2137915391; /* 0x80920001 */
|
||||||
constexpr int PAD_ERROR_INVALID_HANDLE = -2137915389; /* 0x80920003 */
|
constexpr int PAD_ERROR_INVALID_HANDLE = -2137915389; /* 0x80920003 */
|
||||||
|
constexpr int PAD_ERROR_ALREADY_OPENED = -2137915388; /* 0x80920004 */
|
||||||
|
constexpr int PAD_ERROR_NOT_INITIALIZED = -2137915387; /* 0x80920005 */
|
||||||
|
constexpr int PAD_ERROR_NO_HANDLE = -2137915384; /* 0x80920008 */
|
||||||
|
constexpr int PAD_HANDLE = 1;
|
||||||
|
|
||||||
constexpr uint32_t RUMBLE_DURATION_MS = 0xffff;
|
constexpr uint32_t RUMBLE_DURATION_MS = 0xffff;
|
||||||
constexpr uint32_t RELEASE_FLUSH_MS = 50;
|
constexpr uint32_t RELEASE_FLUSH_MS = 50;
|
||||||
@@ -107,6 +111,12 @@ public:
|
|||||||
|
|
||||||
KYTY_CLASS_NO_COPY(GameController);
|
KYTY_CLASS_NO_COPY(GameController);
|
||||||
|
|
||||||
|
int InitPort();
|
||||||
|
int OpenPort(int user_id, int type, int index);
|
||||||
|
int GetPortHandle(int user_id, int type, int index);
|
||||||
|
int ClosePort(int handle);
|
||||||
|
int CheckPortHandle(int handle);
|
||||||
|
|
||||||
void Connect(int id);
|
void Connect(int id);
|
||||||
void Disconnect(int id);
|
void Disconnect(int id);
|
||||||
void Button(int id, uint32_t button, bool down);
|
void Button(int id, uint32_t button, bool down);
|
||||||
@@ -131,6 +141,9 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr uint32_t STATES_MAX = 64;
|
static constexpr uint32_t STATES_MAX = 64;
|
||||||
|
enum class PortState { Uninitialized, Closed, Open };
|
||||||
|
|
||||||
|
int CheckPortHandleLocked(int handle) const;
|
||||||
|
|
||||||
void CheckActive();
|
void CheckActive();
|
||||||
void AddState();
|
void AddState();
|
||||||
@@ -140,6 +153,7 @@ private:
|
|||||||
void UpdateTriggerEffectState();
|
void UpdateTriggerEffectState();
|
||||||
|
|
||||||
Common::Mutex m_mutex;
|
Common::Mutex m_mutex;
|
||||||
|
PortState m_port_state = PortState::Uninitialized;
|
||||||
std::vector<int> m_connected_ids;
|
std::vector<int> m_connected_ids;
|
||||||
int m_active_id = -1;
|
int m_active_id = -1;
|
||||||
bool m_connected = false;
|
bool m_connected = false;
|
||||||
@@ -925,21 +939,71 @@ int GetActiveControllerId() {
|
|||||||
return g_controller != nullptr ? g_controller->GetActiveControllerId() : -1;
|
return g_controller != nullptr ? g_controller->GetActiveControllerId() : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int KYTY_SYSV_ABI PadInit() {
|
static bool PadOpenArgsAreValid(int user_id, int type, int index) {
|
||||||
PRINT_NAME();
|
// The host keyboard and gamepad feed one standard port for the configured user.
|
||||||
|
return user_id == Config::GetUserId() && type == 0 && index == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GameController::InitPort() {
|
||||||
|
Common::LockGuard lock(m_mutex);
|
||||||
|
if (m_port_state == PortState::Uninitialized) {
|
||||||
|
m_port_state = PortState::Closed;
|
||||||
|
}
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool PadOpenArgsAreValid(int user_id, int type, int index) {
|
int GameController::OpenPort(int user_id, int type, int index) {
|
||||||
constexpr int user_id_system = 0xff;
|
Common::LockGuard lock(m_mutex);
|
||||||
constexpr int port_type_standard = 0;
|
if (m_port_state == PortState::Uninitialized) {
|
||||||
constexpr int port_type_special = 2;
|
return PAD_ERROR_NOT_INITIALIZED;
|
||||||
constexpr int port_type_remote = 16;
|
}
|
||||||
const bool personal_port =
|
if (!PadOpenArgsAreValid(user_id, type, index)) {
|
||||||
user_id == Config::GetUserId() && (type == port_type_standard || type == port_type_special);
|
return PAD_ERROR_INVALID_ARG;
|
||||||
const bool system_remote_control = user_id == user_id_system && type == port_type_remote;
|
}
|
||||||
return index == 0 && (personal_port || system_remote_control);
|
if (m_port_state == PortState::Open) {
|
||||||
|
return PAD_ERROR_ALREADY_OPENED;
|
||||||
|
}
|
||||||
|
m_port_state = PortState::Open;
|
||||||
|
return PAD_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GameController::GetPortHandle(int user_id, int type, int index) {
|
||||||
|
Common::LockGuard lock(m_mutex);
|
||||||
|
if (m_port_state == PortState::Uninitialized) {
|
||||||
|
return PAD_ERROR_NOT_INITIALIZED;
|
||||||
|
}
|
||||||
|
return m_port_state == PortState::Open && PadOpenArgsAreValid(user_id, type, index) ? PAD_HANDLE
|
||||||
|
: PAD_ERROR_NO_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GameController::CheckPortHandleLocked(int handle) const {
|
||||||
|
if (m_port_state == PortState::Uninitialized) {
|
||||||
|
return PAD_ERROR_NOT_INITIALIZED;
|
||||||
|
}
|
||||||
|
return m_port_state == PortState::Open && handle == PAD_HANDLE ? OK : PAD_ERROR_INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GameController::CheckPortHandle(int handle) {
|
||||||
|
Common::LockGuard lock(m_mutex);
|
||||||
|
return CheckPortHandleLocked(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
int GameController::ClosePort(int handle) {
|
||||||
|
Common::LockGuard lock(m_mutex);
|
||||||
|
if (const auto error = CheckPortHandleLocked(handle); error != OK) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
m_port_state = PortState::Closed;
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PadCheckHandle(int handle) {
|
||||||
|
return g_controller->CheckPortHandle(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
int KYTY_SYSV_ABI PadInit() {
|
||||||
|
PRINT_NAME();
|
||||||
|
return g_controller->InitPort();
|
||||||
}
|
}
|
||||||
|
|
||||||
int KYTY_SYSV_ABI PadOpen(int user_id, int type, int index, const void* param) {
|
int KYTY_SYSV_ABI PadOpen(int user_id, int type, int index, const void* param) {
|
||||||
@@ -951,15 +1015,7 @@ int KYTY_SYSV_ABI PadOpen(int user_id, int type, int index, const void* param) {
|
|||||||
"\t param = 0x%016" PRIx64 "\n",
|
"\t param = 0x%016" PRIx64 "\n",
|
||||||
user_id, type, index, reinterpret_cast<uint64_t>(param));
|
user_id, type, index, reinterpret_cast<uint64_t>(param));
|
||||||
|
|
||||||
constexpr int pad_error_invalid_arg = -2137915391; /* 0x80920001 */
|
return g_controller->OpenPort(user_id, type, index);
|
||||||
|
|
||||||
if (!PadOpenArgsAreValid(user_id, type, index)) {
|
|
||||||
return pad_error_invalid_arg;
|
|
||||||
}
|
|
||||||
|
|
||||||
int handle = 1;
|
|
||||||
|
|
||||||
return handle;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int KYTY_SYSV_ABI PadGetHandle(int user_id, int type, int index) {
|
int KYTY_SYSV_ABI PadGetHandle(int user_id, int type, int index) {
|
||||||
@@ -970,20 +1026,20 @@ int KYTY_SYSV_ABI PadGetHandle(int user_id, int type, int index) {
|
|||||||
"\t index = %d\n",
|
"\t index = %d\n",
|
||||||
user_id, type, index);
|
user_id, type, index);
|
||||||
|
|
||||||
constexpr int pad_error_device_no_handle = -2137915384; /* 0x80920008 */
|
return g_controller->GetPortHandle(user_id, type, index);
|
||||||
|
}
|
||||||
|
|
||||||
if (!PadOpenArgsAreValid(user_id, type, index)) {
|
int KYTY_SYSV_ABI PadClose(int handle) {
|
||||||
return pad_error_device_no_handle;
|
PRINT_NAME();
|
||||||
}
|
LOGF("\t handle = %d\n", handle);
|
||||||
|
return g_controller->ClosePort(handle);
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int KYTY_SYSV_ABI PadSetMotionSensorState(int handle, bool enable) {
|
int KYTY_SYSV_ABI PadSetMotionSensorState(int handle, bool enable) {
|
||||||
PRINT_NAME();
|
PRINT_NAME();
|
||||||
|
|
||||||
if (handle != 1) {
|
if (const auto error = PadCheckHandle(handle); error != OK) {
|
||||||
return PAD_ERROR_INVALID_HANDLE;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOGF("\t enable = %s\n", (enable ? "true" : "false"));
|
LOGF("\t enable = %s\n", (enable ? "true" : "false"));
|
||||||
@@ -995,8 +1051,8 @@ int KYTY_SYSV_ABI PadSetMotionSensorState(int handle, bool enable) {
|
|||||||
int KYTY_SYSV_ABI PadSetAngularVelocityDeadbandState(int handle, bool enable) {
|
int KYTY_SYSV_ABI PadSetAngularVelocityDeadbandState(int handle, bool enable) {
|
||||||
PRINT_NAME();
|
PRINT_NAME();
|
||||||
|
|
||||||
if (handle != 1) {
|
if (const auto error = PadCheckHandle(handle); error != OK) {
|
||||||
return PAD_ERROR_INVALID_HANDLE;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOGF("\t enable = %s\n", (enable ? "true" : "false"));
|
LOGF("\t enable = %s\n", (enable ? "true" : "false"));
|
||||||
@@ -1007,8 +1063,8 @@ int KYTY_SYSV_ABI PadSetAngularVelocityDeadbandState(int handle, bool enable) {
|
|||||||
int KYTY_SYSV_ABI PadResetOrientation(int handle) {
|
int KYTY_SYSV_ABI PadResetOrientation(int handle) {
|
||||||
PRINT_NAME();
|
PRINT_NAME();
|
||||||
|
|
||||||
if (handle != 1) {
|
if (const auto error = PadCheckHandle(handle); error != OK) {
|
||||||
return PAD_ERROR_INVALID_HANDLE;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_controller->ResetOrientation();
|
g_controller->ResetOrientation();
|
||||||
@@ -1018,18 +1074,17 @@ int KYTY_SYSV_ABI PadResetOrientation(int handle) {
|
|||||||
int KYTY_SYSV_ABI PadGetControllerInformation(int handle, PadControllerInformation* info) {
|
int KYTY_SYSV_ABI PadGetControllerInformation(int handle, PadControllerInformation* info) {
|
||||||
PRINT_NAME();
|
PRINT_NAME();
|
||||||
|
|
||||||
int connected_count = 0;
|
if (const auto error = PadCheckHandle(handle); error != OK) {
|
||||||
bool connected = false;
|
return error;
|
||||||
|
|
||||||
g_controller->GetConnectionInfo(&connected, &connected_count);
|
|
||||||
|
|
||||||
if (handle != 1) {
|
|
||||||
return PAD_ERROR_INVALID_HANDLE;
|
|
||||||
}
|
}
|
||||||
if (info == nullptr) {
|
if (info == nullptr) {
|
||||||
return PAD_ERROR_INVALID_ARG;
|
return PAD_ERROR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int connected_count = 0;
|
||||||
|
bool connected = false;
|
||||||
|
g_controller->GetConnectionInfo(&connected, &connected_count);
|
||||||
|
|
||||||
std::memset(info, 0, sizeof(*info));
|
std::memset(info, 0, sizeof(*info));
|
||||||
|
|
||||||
info->touch_pixel_density = 44.86f;
|
info->touch_pixel_density = 44.86f;
|
||||||
@@ -1048,8 +1103,8 @@ int KYTY_SYSV_ABI PadGetControllerInformation(int handle, PadControllerInformati
|
|||||||
int KYTY_SYSV_ABI PadIsRemoteController(int handle, bool* is_remote) {
|
int KYTY_SYSV_ABI PadIsRemoteController(int handle, bool* is_remote) {
|
||||||
PRINT_NAME();
|
PRINT_NAME();
|
||||||
|
|
||||||
if (handle != 1) {
|
if (const auto error = PadCheckHandle(handle); error != OK) {
|
||||||
return PAD_ERROR_INVALID_HANDLE;
|
return error;
|
||||||
}
|
}
|
||||||
if (is_remote == nullptr) {
|
if (is_remote == nullptr) {
|
||||||
return PAD_ERROR_INVALID_ARG;
|
return PAD_ERROR_INVALID_ARG;
|
||||||
@@ -1062,8 +1117,8 @@ int KYTY_SYSV_ABI PadIsRemoteController(int handle, bool* is_remote) {
|
|||||||
int KYTY_SYSV_ABI PadReadState(int handle, PadData* data) {
|
int KYTY_SYSV_ABI PadReadState(int handle, PadData* data) {
|
||||||
PRINT_NAME();
|
PRINT_NAME();
|
||||||
|
|
||||||
if (handle != 1) {
|
if (const auto error = PadCheckHandle(handle); error != OK) {
|
||||||
return PAD_ERROR_INVALID_HANDLE;
|
return error;
|
||||||
}
|
}
|
||||||
if (data == nullptr) {
|
if (data == nullptr) {
|
||||||
return PAD_ERROR_INVALID_ARG;
|
return PAD_ERROR_INVALID_ARG;
|
||||||
@@ -1084,8 +1139,8 @@ int KYTY_SYSV_ABI PadRead(int handle, PadData* data, int num) {
|
|||||||
PRINT_NAME();
|
PRINT_NAME();
|
||||||
|
|
||||||
EXIT_NOT_IMPLEMENTED(num < 1 || num > 64);
|
EXIT_NOT_IMPLEMENTED(num < 1 || num > 64);
|
||||||
if (handle != 1) {
|
if (const auto error = PadCheckHandle(handle); error != OK) {
|
||||||
return PAD_ERROR_INVALID_HANDLE;
|
return error;
|
||||||
}
|
}
|
||||||
if (data == nullptr) {
|
if (data == nullptr) {
|
||||||
return PAD_ERROR_INVALID_ARG;
|
return PAD_ERROR_INVALID_ARG;
|
||||||
@@ -1116,8 +1171,8 @@ int KYTY_SYSV_ABI PadRead(int handle, PadData* data, int num) {
|
|||||||
int KYTY_SYSV_ABI PadSetVibration(int handle, const PadVibrationParam* param) {
|
int KYTY_SYSV_ABI PadSetVibration(int handle, const PadVibrationParam* param) {
|
||||||
PRINT_NAME();
|
PRINT_NAME();
|
||||||
|
|
||||||
if (handle != 1) {
|
if (const auto error = PadCheckHandle(handle); error != OK) {
|
||||||
return PAD_ERROR_INVALID_HANDLE;
|
return error;
|
||||||
}
|
}
|
||||||
if (param == nullptr) {
|
if (param == nullptr) {
|
||||||
return PAD_ERROR_INVALID_ARG;
|
return PAD_ERROR_INVALID_ARG;
|
||||||
@@ -1135,8 +1190,8 @@ int KYTY_SYSV_ABI PadSetVibration(int handle, const PadVibrationParam* param) {
|
|||||||
int KYTY_SYSV_ABI PadResetLightBar(int handle) {
|
int KYTY_SYSV_ABI PadResetLightBar(int handle) {
|
||||||
PRINT_NAME();
|
PRINT_NAME();
|
||||||
|
|
||||||
if (handle != 1) {
|
if (const auto error = PadCheckHandle(handle); error != OK) {
|
||||||
return PAD_ERROR_INVALID_HANDLE;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
@@ -1145,8 +1200,8 @@ int KYTY_SYSV_ABI PadResetLightBar(int handle) {
|
|||||||
int KYTY_SYSV_ABI PadSetLightBar(int handle, const PadLightBarParam* param) {
|
int KYTY_SYSV_ABI PadSetLightBar(int handle, const PadLightBarParam* param) {
|
||||||
PRINT_NAME();
|
PRINT_NAME();
|
||||||
|
|
||||||
if (handle != 1) {
|
if (const auto error = PadCheckHandle(handle); error != OK) {
|
||||||
return PAD_ERROR_INVALID_HANDLE;
|
return error;
|
||||||
}
|
}
|
||||||
if (param == nullptr) {
|
if (param == nullptr) {
|
||||||
return PAD_ERROR_INVALID_ARG;
|
return PAD_ERROR_INVALID_ARG;
|
||||||
@@ -1160,8 +1215,8 @@ int KYTY_SYSV_ABI PadSetLightBar(int handle, const PadLightBarParam* param) {
|
|||||||
int KYTY_SYSV_ABI PadSetTriggerEffect(int handle, const PadTriggerEffectParam* param) {
|
int KYTY_SYSV_ABI PadSetTriggerEffect(int handle, const PadTriggerEffectParam* param) {
|
||||||
PRINT_NAME();
|
PRINT_NAME();
|
||||||
|
|
||||||
if (handle != 1) {
|
if (const auto error = PadCheckHandle(handle); error != OK) {
|
||||||
return PAD_ERROR_INVALID_HANDLE;
|
return error;
|
||||||
}
|
}
|
||||||
if (param == nullptr) {
|
if (param == nullptr) {
|
||||||
return PAD_ERROR_INVALID_ARG;
|
return PAD_ERROR_INVALID_ARG;
|
||||||
@@ -1175,8 +1230,8 @@ int KYTY_SYSV_ABI PadGetTriggerEffectState(int handle, PadTriggerEffectStateInfo
|
|||||||
|
|
||||||
LOGF("\t handle = %d\n", handle);
|
LOGF("\t handle = %d\n", handle);
|
||||||
|
|
||||||
if (handle != 1) {
|
if (const auto error = PadCheckHandle(handle); error != OK) {
|
||||||
return PAD_ERROR_INVALID_HANDLE;
|
return error;
|
||||||
}
|
}
|
||||||
if (info == nullptr) {
|
if (info == nullptr) {
|
||||||
return PAD_ERROR_INVALID_ARG;
|
return PAD_ERROR_INVALID_ARG;
|
||||||
|
|||||||
@@ -81,9 +81,12 @@ enum class Setting { SpeakerVolume, VibrationIntensity, TriggerEffectIntensity }
|
|||||||
void CycleSetting(Setting setting);
|
void CycleSetting(Setting setting);
|
||||||
float GetSettingScale(Setting setting);
|
float GetSettingScale(Setting setting);
|
||||||
|
|
||||||
|
int PadCheckHandle(int handle);
|
||||||
|
|
||||||
int KYTY_SYSV_ABI PadInit();
|
int KYTY_SYSV_ABI PadInit();
|
||||||
int KYTY_SYSV_ABI PadOpen(int user_id, int type, int index, const void* param);
|
int KYTY_SYSV_ABI PadOpen(int user_id, int type, int index, const void* param);
|
||||||
int KYTY_SYSV_ABI PadGetHandle(int user_id, int type, int index);
|
int KYTY_SYSV_ABI PadGetHandle(int user_id, int type, int index);
|
||||||
|
int KYTY_SYSV_ABI PadClose(int handle);
|
||||||
int KYTY_SYSV_ABI PadSetMotionSensorState(int handle, bool enable);
|
int KYTY_SYSV_ABI PadSetMotionSensorState(int handle, bool enable);
|
||||||
int KYTY_SYSV_ABI PadSetAngularVelocityDeadbandState(int handle, bool enable);
|
int KYTY_SYSV_ABI PadSetAngularVelocityDeadbandState(int handle, bool enable);
|
||||||
int KYTY_SYSV_ABI PadResetOrientation(int handle);
|
int KYTY_SYSV_ABI PadResetOrientation(int handle);
|
||||||
|
|||||||
+10
-20
@@ -19,7 +19,7 @@ static int KYTY_SYSV_ABI PadSetVibrationMode(int handle, int mode) {
|
|||||||
"\t mode = %d\n",
|
"\t mode = %d\n",
|
||||||
handle, mode);
|
handle, mode);
|
||||||
|
|
||||||
return 0;
|
return Controller::PadCheckHandle(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int KYTY_SYSV_ABI PadSetVibrationTriggerEffectWeakWhileEmbeddedMicInUse(bool enabled) {
|
static int KYTY_SYSV_ABI PadSetVibrationTriggerEffectWeakWhileEmbeddedMicInUse(bool enabled) {
|
||||||
@@ -66,11 +66,10 @@ static int KYTY_SYSV_ABI
|
|||||||
PadDeviceClassGetExtendedInformation(int handle, PadDeviceClassExtendedInformation* info) {
|
PadDeviceClassGetExtendedInformation(int handle, PadDeviceClassExtendedInformation* info) {
|
||||||
PRINT_NAME();
|
PRINT_NAME();
|
||||||
|
|
||||||
constexpr int pad_error_invalid_handle = -2137915389; /* 0x80920003 */
|
constexpr int pad_error_invalid_arg = -2137915391; /* 0x80920001 */
|
||||||
constexpr int pad_error_invalid_arg = -2137915391; /* 0x80920001 */
|
|
||||||
|
|
||||||
if (handle != 1) {
|
if (const auto error = Controller::PadCheckHandle(handle); error != OK) {
|
||||||
return pad_error_invalid_handle;
|
return error;
|
||||||
}
|
}
|
||||||
if (info == nullptr) {
|
if (info == nullptr) {
|
||||||
return pad_error_invalid_arg;
|
return pad_error_invalid_arg;
|
||||||
@@ -85,16 +84,15 @@ static int KYTY_SYSV_ABI PadDeviceClassParseData(int handle, const Controller::P
|
|||||||
PadDeviceClassData* class_data) {
|
PadDeviceClassData* class_data) {
|
||||||
PRINT_NAME();
|
PRINT_NAME();
|
||||||
|
|
||||||
constexpr int pad_error_invalid_handle = -2137915389; /* 0x80920003 */
|
constexpr int pad_error_invalid_arg = -2137915391; /* 0x80920001 */
|
||||||
constexpr int pad_error_invalid_arg = -2137915391; /* 0x80920001 */
|
|
||||||
|
|
||||||
LOGF("\t handle = %d\n"
|
LOGF("\t handle = %d\n"
|
||||||
"\t data = 0x%016" PRIx64 "\n"
|
"\t data = 0x%016" PRIx64 "\n"
|
||||||
"\t class_data = 0x%016" PRIx64 "\n",
|
"\t class_data = 0x%016" PRIx64 "\n",
|
||||||
handle, reinterpret_cast<uint64_t>(data), reinterpret_cast<uint64_t>(class_data));
|
handle, reinterpret_cast<uint64_t>(data), reinterpret_cast<uint64_t>(class_data));
|
||||||
|
|
||||||
if (handle != 1) {
|
if (const auto error = Controller::PadCheckHandle(handle); error != OK) {
|
||||||
return pad_error_invalid_handle;
|
return error;
|
||||||
}
|
}
|
||||||
if (data == nullptr || class_data == nullptr) {
|
if (data == nullptr || class_data == nullptr) {
|
||||||
return pad_error_invalid_arg;
|
return pad_error_invalid_arg;
|
||||||
@@ -122,15 +120,7 @@ static int KYTY_SYSV_ABI PadSetTiltCorrectionState(int handle, bool enabled) {
|
|||||||
"\t enabled = %d\n",
|
"\t enabled = %d\n",
|
||||||
handle, enabled ? 1 : 0);
|
handle, enabled ? 1 : 0);
|
||||||
|
|
||||||
return 0;
|
return Controller::PadCheckHandle(handle);
|
||||||
}
|
|
||||||
|
|
||||||
static int KYTY_SYSV_ABI PadClose(int handle) {
|
|
||||||
PRINT_NAME();
|
|
||||||
|
|
||||||
LOGF("\t handle = %d\n", handle);
|
|
||||||
|
|
||||||
return OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// PPSA02385
|
// PPSA02385
|
||||||
@@ -154,7 +144,7 @@ static int KYTY_SYSV_ABI PadGetExtControllerInformationStub(int handle, void* in
|
|||||||
"\t info = 0x%016" PRIx64 "\n",
|
"\t info = 0x%016" PRIx64 "\n",
|
||||||
handle, reinterpret_cast<uint64_t>(info));
|
handle, reinterpret_cast<uint64_t>(info));
|
||||||
|
|
||||||
return OK;
|
return Controller::PadCheckHandle(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int KYTY_SYSV_ABI PadUnknownN3kSX62fgNo(uint64_t arg0, uint64_t arg1, uint64_t arg2,
|
static int KYTY_SYSV_ABI PadUnknownN3kSX62fgNo(uint64_t arg0, uint64_t arg1, uint64_t arg2,
|
||||||
@@ -197,7 +187,7 @@ LIB_DEFINE(InitPad_1) {
|
|||||||
LIB_FUNC("znaWI0gpuo8", Controller::PadGetTriggerEffectState);
|
LIB_FUNC("znaWI0gpuo8", Controller::PadGetTriggerEffectState);
|
||||||
LIB_FUNC("DscD1i9HX1w", Controller::PadResetLightBar);
|
LIB_FUNC("DscD1i9HX1w", Controller::PadResetLightBar);
|
||||||
LIB_FUNC("RR4novUEENY", Controller::PadSetLightBar);
|
LIB_FUNC("RR4novUEENY", Controller::PadSetLightBar);
|
||||||
LIB_FUNC("6ncge5+l5Qs", PadClose);
|
LIB_FUNC("6ncge5+l5Qs", Controller::PadClose);
|
||||||
LIB_FUNC("n3kSX62fgNo", PadUnknownN3kSX62fgNo);
|
LIB_FUNC("n3kSX62fgNo", PadUnknownN3kSX62fgNo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -110,6 +110,8 @@ struct Controller {
|
|||||||
now = 1000;
|
now = 1000;
|
||||||
haptics_handles_rumble = false;
|
haptics_handles_rumble = false;
|
||||||
Initialize();
|
Initialize();
|
||||||
|
Check(PadInit() == 0 && PadOpen(Config::GetUserId(), 0, 0, nullptr) == 1,
|
||||||
|
"the standard controller port did not open");
|
||||||
Connect(1);
|
Connect(1);
|
||||||
Check(GetSettingScale(Setting::SpeakerVolume) ==
|
Check(GetSettingScale(Setting::SpeakerVolume) ==
|
||||||
Config::GetControllerSpeakerVolume() / 50.0f &&
|
Config::GetControllerSpeakerVolume() / 50.0f &&
|
||||||
@@ -143,6 +145,54 @@ void SetRumble(uint8_t large, uint8_t small) {
|
|||||||
Check(PadSetVibration(1, ¶m) == 0, "vibration request failed");
|
Check(PadSetVibration(1, ¶m) == 0, "vibration request failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestPadPortOwnership() {
|
||||||
|
Initialize();
|
||||||
|
const int user = Config::GetUserId();
|
||||||
|
constexpr auto not_initialized = static_cast<int32_t>(0x80920005u);
|
||||||
|
constexpr auto already_opened = static_cast<int32_t>(0x80920004u);
|
||||||
|
constexpr auto invalid_handle = static_cast<int32_t>(0x80920003u);
|
||||||
|
constexpr auto no_handle = static_cast<int32_t>(0x80920008u);
|
||||||
|
PadData data {};
|
||||||
|
Check(PadOpen(user, 0, 0, nullptr) == not_initialized &&
|
||||||
|
PadGetHandle(user, 0, 0) == not_initialized &&
|
||||||
|
PadReadState(1, &data) == not_initialized,
|
||||||
|
"an uninitialized library exposed a controller port");
|
||||||
|
Check(PadInit() == 0 && PadGetHandle(user, 0, 0) == no_handle,
|
||||||
|
"initializing the library opened a controller port");
|
||||||
|
const int handle = PadOpen(user, 0, 0, nullptr);
|
||||||
|
Check(handle == 1 && PadInit() == 0 && PadGetHandle(user, 0, 0) == handle,
|
||||||
|
"reinitializing the library lost the open port");
|
||||||
|
for (int duplicate = 0; duplicate < 4; duplicate++) {
|
||||||
|
const int rejected = PadOpen(user, 0, 0, nullptr);
|
||||||
|
Check(rejected == already_opened,
|
||||||
|
"opening one pad five times exposed duplicate connected controllers");
|
||||||
|
Check(PadClose(rejected) == invalid_handle && PadGetHandle(user, 0, 0) == handle,
|
||||||
|
"closing a rejected duplicate released the original owner");
|
||||||
|
}
|
||||||
|
Check(PadGetHandle(user + 1, 0, 0) == no_handle &&
|
||||||
|
PadGetHandle(user, 2, 0) == no_handle && PadGetHandle(user, 0, 1) == no_handle,
|
||||||
|
"a different port tuple aliased the open standard pad");
|
||||||
|
SetButton(HOST_INPUT_CONTROLLER_ID, PAD_BUTTON_CROSS, true);
|
||||||
|
Check(PadReadState(handle, &data) == 0 && data.connected &&
|
||||||
|
data.buttons == PAD_BUTTON_CROSS,
|
||||||
|
"keyboard Cross did not reach the owned port");
|
||||||
|
SetButton(HOST_INPUT_CONTROLLER_ID, PAD_BUTTON_CROSS, false);
|
||||||
|
Connect(1);
|
||||||
|
SetButton(1, PAD_BUTTON_CROSS, true);
|
||||||
|
Check(PadReadState(handle, &data) == 0 && data.buttons == PAD_BUTTON_CROSS,
|
||||||
|
"the physical controller did not share the owned port");
|
||||||
|
Disconnect(1);
|
||||||
|
Check(PadGetHandle(user, 0, 0) == handle && PadOpen(user, 0, 0, nullptr) == already_opened,
|
||||||
|
"host disconnection released guest port ownership");
|
||||||
|
Check(PadClose(handle) == 0 && PadGetHandle(user, 0, 0) == no_handle &&
|
||||||
|
PadReadState(handle, &data) == invalid_handle &&
|
||||||
|
PadRead(handle, &data, 1) == invalid_handle && PadClose(handle) == invalid_handle,
|
||||||
|
"a closed port retained a usable handle");
|
||||||
|
Check(PadOpen(user, 0, 0, nullptr) == handle && PadReadState(handle, &data) == 0,
|
||||||
|
"a closed port could not reopen");
|
||||||
|
Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
void TestSettingCycles() {
|
void TestSettingCycles() {
|
||||||
Controller controller;
|
Controller controller;
|
||||||
for (auto setting:
|
for (auto setting:
|
||||||
@@ -503,6 +553,7 @@ void TestTriggerEffectState() {
|
|||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
Config::Initialize();
|
Config::Initialize();
|
||||||
|
TestPadPortOwnership();
|
||||||
TestSettingCycles();
|
TestSettingCycles();
|
||||||
TestGlobalControllerLevels();
|
TestGlobalControllerLevels();
|
||||||
// Each following test initializes another controller and requires strong defaults.
|
// Each following test initializes another controller and requires strong defaults.
|
||||||
|
|||||||
Reference in New Issue
Block a user