#include #include #include #include #include #include #include "SceTypes.hpp" #include "prx//libc/include/General.hpp" #include "prx/libScePad/include/Pad.hpp" #include "prx/libScePad/include/PadState.hpp" namespace { constexpr int PAD_ERROR_DEVICE_NOT_CONNECTED = static_cast(0x80920007); constexpr int PAD_ERROR_DEVICE_NO_HANDLE = static_cast(0x80920008); bool g_opened = false; bool ValidPort(int userId, int type, int index) { const bool personalPort = type == PAD_PORT_TYPE_STANDARD || type == PAD_PORT_TYPE_SPECIAL; const bool systemRemote = userId == PAD_USER_ID_SYSTEM && type == PAD_PORT_TYPE_REMOTE; return index == 0 && (personalPort || systemRemote); } } extern "C" { int APS5_VABI scePadClose_nid_postfix(int handle) { if (handle != PAD_HANDLE) { return PAD_ERROR_INVALID_HANDLE; } g_opened = false; return PAD_OK; } int APS5_VABI scePadDeviceClassGetExtendedInformation(int handle, PadDeviceClassExtendedInformation* info) { if (handle != PAD_HANDLE) return PAD_ERROR_INVALID_HANDLE; if (info == nullptr) return PAD_ERROR_INVALID_ARG; std::memset(info, 0, sizeof(*info)); info->deviceClass = PAD_DEVICE_CLASS_STANDARD; return PAD_OK; } int APS5_VABI scePadDeviceClassParseData(int handle, const PadData* data, PadDeviceClassData* class_data) { if (handle != PAD_HANDLE) return PAD_ERROR_INVALID_HANDLE; if (data == nullptr || class_data == nullptr) return PAD_ERROR_INVALID_ARG; std::memset(class_data, 0, sizeof(*class_data)); class_data->deviceClass = PAD_DEVICE_CLASS_STANDARD; class_data->dataValid = data->connected; return PAD_OK; } int APS5_VABI scePadGetControllerInformation(int handle, PadControllerInformation* info) { if (handle != PAD_HANDLE) { return PAD_ERROR_INVALID_HANDLE; } if (info == nullptr) { return PAD_ERROR_INVALID_ARG; } std::memset(info, 0, sizeof(*info)); info->touchPadInfo.pixelDensity = 44.86f; info->touchPadInfo.resolution.x = 1920; info->touchPadInfo.resolution.y = 943; info->stickInfo.deadZoneLeft = 2; info->stickInfo.deadZoneRight = 2; info->connectionType = PAD_CONNECTION_TYPE_LOCAL; info->connectedCount = 1; info->connected = true; info->deviceClass = PAD_DEVICE_CLASS_STANDARD; return PAD_OK; } int APS5_VABI scePadGetHandle(int user_id, int type, int index) { if (!g_opened || !ValidPort(user_id, type, index) || type == PAD_PORT_TYPE_SPECIAL) return PAD_ERROR_DEVICE_NO_HANDLE; return PAD_HANDLE; } int APS5_VABI scePadGetInfo_nid_postfix(PadInfo* info) { if (info == nullptr) return PAD_ERROR_INVALID_ARG; std::memset(info, 0, sizeof(*info)); info->maxConnectCount = 4; info->connectedCount[0] = 1; info->connectedCount[1] = 0; PadInfo::PadTypeInfo& slot = info->padTypeInfo[0]; slot.connectPort = 0; slot.status = 1; slot.deviceType = PAD_DEVICE_TYPE_DUAL_SENSE; slot.connectType = PAD_CONNECT_TYPE_BLUETOOTH; std::memcpy(slot.bluetoothMacAddress, PAD_BD_ADDRESS, sizeof(slot.bluetoothMacAddress)); return PAD_OK; } int APS5_VABI scePadGetTriggerEffectState(int handle, PadTriggerEffectStateInformation* info) { if (handle != PAD_HANDLE) return PAD_ERROR_INVALID_HANDLE; if (info == nullptr) return PAD_ERROR_INVALID_ARG; std::memset(info, 0, sizeof(*info)); return PAD_OK; } int APS5_VABI scePadGetExtControllerInformation(int handle, void* info) { if (handle != PAD_HANDLE) return PAD_ERROR_INVALID_HANDLE; if (info == nullptr) return PAD_ERROR_INVALID_ARG; std::memset(info, 0, 0x2c); PadControllerInformation* base = static_cast(info); base->touchPadInfo.pixelDensity = 44.86f; base->touchPadInfo.resolution.x = 1920; base->touchPadInfo.resolution.y = 943; base->stickInfo.deadZoneLeft = 2; base->stickInfo.deadZoneRight = 2; base->connectionType = PAD_CONNECTION_TYPE_LOCAL; base->connectedCount = 1; base->connected = true; base->deviceClass = PAD_DEVICE_CLASS_STANDARD; return PAD_OK; } int APS5_VABI scePadSetProcessPrivilege(int privilege) { (void)privilege; return PAD_OK; } int APS5_VABI scePadSetParticularMode(bool mode) { (void)mode; return PAD_OK; } int APS5_VABI scePadInit_nid_postfix(void) { Pad::Initialize(); return PAD_OK; } int APS5_VABI scePadOpen_nid_postfix(int userId, int type, int index, const void* param) { (void)param; if (!ValidPort(userId, type, index)) { return PAD_ERROR_INVALID_ARG; } if (type == PAD_PORT_TYPE_SPECIAL) return PAD_ERROR_DEVICE_NOT_CONNECTED; g_opened = true; return PAD_HANDLE; } int APS5_VABI scePadOpenExt(int userId, int type, int index, const void* param) { if (!ValidPort(userId, type, index) || param == nullptr) { return PAD_ERROR_INVALID_ARG; } if (type != PAD_PORT_TYPE_SPECIAL) NotImplemented_nid_no_patch(__func__); return PAD_ERROR_DEVICE_NOT_CONNECTED; } int APS5_VABI scePadReadExt() { NotImplemented_nid_no_patch(__func__); return 0; } int APS5_VABI scePadGetFeatureReport() { NotImplemented_nid_no_patch(__func__); return 0; } int APS5_VABI scePadSetFeatureReport() { NotImplemented_nid_no_patch(__func__); return 0; } int APS5_VABI scePadOutputReport() { NotImplemented_nid_no_patch(__func__); return 0; } int APS5_VABI scePadRead_nid_postfix(int handle, PadData* data, int num) { if (handle != PAD_HANDLE) return PAD_ERROR_INVALID_HANDLE; if (data == nullptr || num <= 0) APS5_INVALID_ARG_EX; return Pad::Read(data, num); } int APS5_VABI scePadReadState(int handle, PadData* data) { if (handle != PAD_HANDLE) return PAD_ERROR_INVALID_HANDLE; if (data == nullptr) APS5_INVALID_ARG_EX; *data = Pad::ReadState(); return 0; } int APS5_VABI scePadResetLightBar(int handle) { if (handle != PAD_HANDLE) return PAD_ERROR_INVALID_HANDLE; Pad::SetLightBar(false, 0, 0, 0); return PAD_OK; } int APS5_VABI scePadResetOrientation(int handle) { if (handle != PAD_HANDLE) return PAD_ERROR_INVALID_HANDLE; Pad::ResetOrientation(); return PAD_OK; } int APS5_VABI scePadSetAngularVelocityDeadbandState(int handle, bool enable) { if (handle != PAD_HANDLE) return PAD_ERROR_INVALID_HANDLE; if (enable) NotImplemented_nid_no_patch(__func__); return PAD_OK; } int APS5_VABI scePadSetLightBar(int handle, const PadLightBarParam* param) { if (handle != PAD_HANDLE) return PAD_ERROR_INVALID_HANDLE; if (param == nullptr) return PAD_ERROR_INVALID_ARG; Pad::SetLightBar(true, param->r, param->g, param->b); return PAD_OK; } int APS5_VABI scePadSetMotionSensorState(int handle, bool enable) { if (handle != PAD_HANDLE) return PAD_ERROR_INVALID_HANDLE; Pad::SetMotionEnabled(enable); return PAD_OK; } int APS5_VABI scePadSetTiltCorrectionState(int handle, bool enabled) { if (handle != PAD_HANDLE) return PAD_ERROR_INVALID_HANDLE; Pad::SetTiltCorrection(enabled); return PAD_OK; } int APS5_VABI scePadSetTriggerEffect(int handle, const void* param) { if (handle != PAD_HANDLE) return PAD_ERROR_INVALID_HANDLE; if (param == nullptr) return PAD_ERROR_INVALID_ARG; const std::uint8_t* bytes = static_cast(param); const std::uint8_t mask = bytes[0]; if ((mask & ~0x3u) != 0) { return PAD_ERROR_INVALID_ARG; } std::uint32_t mode[2] = {}; for (int trigger = 0; trigger < 2; ++trigger) std::memcpy(&mode[trigger], bytes + 8 + 56 * trigger, 4); if (mode[0] > 6 || mode[1] > 6) { return PAD_ERROR_INVALID_ARG; } for (int trigger = 0; trigger < 2; ++trigger) { if ((mask & (1u << trigger)) != 0) Pad::SetTriggerCommand(trigger, bytes + 8 + 56 * trigger); } return PAD_OK; } int APS5_VABI scePadSetVibration(int handle, const PadVibrationParam* param) { if (handle != PAD_HANDLE) return PAD_ERROR_INVALID_HANDLE; if (param == nullptr) return PAD_ERROR_INVALID_ARG; Pad::SetVibration(param->large_motor, param->small_motor); return PAD_OK; } int APS5_VABI scePadSetVibrationMode(int handle, int mode) { if (handle != PAD_HANDLE) return PAD_ERROR_INVALID_HANDLE; if (mode < 0 || mode > 3) return PAD_ERROR_INVALID_ARG; Pad::SetVibrationMode(mode); return PAD_OK; } int APS5_VABI scePadSetVibrationTriggerEffectWeakWhileEmbeddedMicInUse(bool enabled) { (void)enabled; return PAD_OK; } int APS5_VABI scePadVrControllerGetDeviceInformation() { NotImplemented_nid_no_patch(__func__); return 0; } int APS5_VABI scePadVrControllerRead() { NotImplemented_nid_no_patch(__func__); return 0; } int APS5_VABI scePadVrControllerGetTriggerEffectState() { NotImplemented_nid_no_patch(__func__); return 0; } int APS5_VABI scePadVrControllerReadState(int handle, void* state) { (void)handle; (void)state; NotImplemented_nid_no_patch(__func__); return 0; } int APS5_VABI scePadVrControllerSetTriggerEffect() { NotImplemented_nid_no_patch(__func__); return 0; } int APS5_VABI scePadVrControllerSetTriggerEffects() { NotImplemented_nid_no_patch(__func__); return 0; } int APS5_VABI scePadIsRemoteController(int handle, bool* remote) { if (handle != PAD_HANDLE) return PAD_ERROR_INVALID_HANDLE; if (remote == nullptr) return PAD_ERROR_INVALID_ARG; *remote = false; return 0; } int APS5_VABI scePadSetAngularVelocityBiasCorrectionState(int handle, bool enabled) { if (handle != PAD_HANDLE) return PAD_ERROR_INVALID_HANDLE; if (enabled) NotImplemented_nid_no_patch(__func__); return PAD_OK; } APS5_EXPORT("n3kSX62fgNo", scePadUnknown_n3kSX62fgNo); int APS5_VABI scePadUnknown_n3kSX62fgNo() { NotImplemented_nid_no_patch(__func__); return 0; } }