#include "prx/libSceMove/include/Api.hpp" #include "ProcessParametersFixture.hpp" #include "prx/libc/include/general/VabiMacros.hpp" #include #include #include #include #include #include namespace { void Require(bool value) { if (!value) std::abort(); } constexpr int kOk = 0; constexpr int kNoControllerConnected = 1; constexpr int kNotInit = static_cast(0x80EE0001); constexpr int kAlreadyInit = static_cast(0x80EE0002); constexpr int kInvalidArg = static_cast(0x80EE0003); constexpr int kInvalidHandle = static_cast(0x80EE0004); constexpr int kAlreadyOpened = static_cast(0x80EE0007); constexpr std::int32_t kUserId = 0x10000000; constexpr std::int32_t kFirstHandle = 0x30B0100; constexpr std::int32_t kHandleStep = 0x100; constexpr std::uint8_t kFill = 0x5A; constexpr std::uint32_t kLastSdkAllowingNullData = 0x03ffffff; constexpr std::uint32_t kFirstSdkRequiringData = 0x04000000; alignas(16) std::array process{}; void InstallProcessParameters() { const std::uint64_t size = process.size(); const std::uint32_t magic = 0x4942524f; std::memcpy(process.data(), &size, sizeof(size)); std::memcpy(process.data() + 8, &magic, sizeof(magic)); Require(ProcessParametersFixture::Install(process.data(), process.size())); } void SetCompiledSdkVersion(std::uint32_t version) { std::memcpy(process.data() + 0x10, &version, sizeof(version)); } struct Buffer { std::uint8_t bytes[128]; Buffer() { std::memset(bytes, kFill, sizeof(bytes)); } bool Untouched() const { for (std::uint8_t byte : bytes) { if (byte != kFill) return false; } return true; } }; template bool Throws(TCall call) { try { call(); } catch (const std::runtime_error&) { return true; } return false; } void RequireNotInit(std::int32_t handle) { Buffer buffer; std::int32_t count = -7; Require(sceMoveOpen(kUserId, 0, 0) == kNotInit); Require(sceMoveClose(handle) == kNotInit); Require(sceMoveGetDeviceInfo(handle, buffer.bytes) == kNotInit); Require(sceMoveGetExtensionPortInfo(handle, buffer.bytes) == kNotInit); Require(sceMoveReadStateLatest(handle, buffer.bytes) == kNotInit); Require(sceMoveReadStateRecent(handle, 0, buffer.bytes, &count) == kNotInit); SetCompiledSdkVersion(kLastSdkAllowingNullData); Require(sceMoveReadStateRecent(handle, 0, nullptr, &count) == kNotInit); SetCompiledSdkVersion(kFirstSdkRequiringData); Require(sceMoveSetVibration(handle, 0xFF) == kNotInit); Require(sceMoveSetLightSphere(handle, 0xFF, 0, 0) == kNotInit); Require(sceMoveResetLightSphere(handle) == kNotInit); Require(sceMoveTerm() == kNotInit); Require(buffer.Untouched()); Require(count == -7); } void RequireUnknownHandle(std::int32_t handle) { Buffer buffer; std::int32_t count = -7; Require(sceMoveClose(handle) == kInvalidHandle); Require(sceMoveGetDeviceInfo(handle, buffer.bytes) == kInvalidHandle); Require(sceMoveGetExtensionPortInfo(handle, buffer.bytes) == kInvalidHandle); Require(sceMoveReadStateLatest(handle, buffer.bytes) == kInvalidHandle); Require(sceMoveReadStateRecent(handle, 0, buffer.bytes, &count) == kInvalidHandle); Require(sceMoveSetVibration(handle, 0xFF) == kInvalidHandle); Require(sceMoveSetLightSphere(handle, 0xFF, 0, 0) == kInvalidHandle); Require(sceMoveResetLightSphere(handle) == kInvalidHandle); Require(sceMoveGetDeviceInfo(handle, nullptr) == kInvalidArg); Require(sceMoveGetExtensionPortInfo(handle, nullptr) == kInvalidArg); Require(sceMoveReadStateLatest(handle, nullptr) == kInvalidArg); Require(sceMoveReadStateRecent(handle, -1, buffer.bytes, &count) == kInvalidArg); Require(sceMoveReadStateRecent(handle, 0, buffer.bytes, nullptr) == kInvalidArg); Require(buffer.Untouched()); Require(count == -7); } } int main() { InstallProcessParameters(); SetCompiledSdkVersion(kFirstSdkRequiringData); RequireNotInit(kFirstHandle); Require(sceMoveInit() == kOk); Require(sceMoveInit() == kAlreadyInit); RequireUnknownHandle(0); RequireUnknownHandle(-1); RequireUnknownHandle(kFirstHandle); const std::int32_t first = sceMoveOpen(kUserId, 0, 0); const std::int32_t second = sceMoveOpen(kUserId, 0, 1); Require(first == kFirstHandle); Require(second == kFirstHandle + kHandleStep); Require(sceMoveOpen(kUserId, 0, 0) == kAlreadyOpened); Require(sceMoveOpen(kUserId, 0, 1) == kAlreadyOpened); Require(Throws([] { sceMoveOpen(kUserId + 1, 0, 2); })); Require(sceMoveGetDeviceInfo(first, nullptr) == kInvalidArg); Require(sceMoveGetExtensionPortInfo(first, nullptr) == kInvalidArg); Require(sceMoveReadStateLatest(first, nullptr) == kInvalidArg); Buffer buffer; std::int32_t count = -7; Require(sceMoveReadStateRecent(first, -1, buffer.bytes, &count) == kInvalidArg); Require(sceMoveReadStateRecent(first, 0, nullptr, &count) == kInvalidArg); Require(sceMoveReadStateRecent(first, 0, buffer.bytes, nullptr) == kInvalidArg); SetCompiledSdkVersion(kLastSdkAllowingNullData); Require(sceMoveReadStateRecent(first, 0, nullptr, &count) == kNoControllerConnected); Require(sceMoveReadStateRecent(first, -1, nullptr, &count) == kInvalidArg); Require(sceMoveReadStateRecent(first, 0, nullptr, nullptr) == kInvalidArg); Require(sceMoveReadStateRecent(first + 1, 0, nullptr, &count) == kInvalidHandle); Require(count == -7); SetCompiledSdkVersion(kFirstSdkRequiringData); Require(sceMoveReadStateRecent(first, 0, nullptr, &count) == kInvalidArg); Require(sceMoveGetDeviceInfo(first, buffer.bytes) == kNoControllerConnected); Require(sceMoveGetExtensionPortInfo(first, buffer.bytes) == kNoControllerConnected); Require(sceMoveReadStateLatest(first, buffer.bytes) == kNoControllerConnected); Require(sceMoveReadStateRecent(first, 0, buffer.bytes, &count) == kNoControllerConnected); Require(buffer.Untouched()); Require(count == -7); Require(sceMoveSetVibration(first, 0xFF) == kNoControllerConnected); Require(sceMoveSetLightSphere(first, 0, 0xFF, 0) == kNoControllerConnected); Require(sceMoveResetLightSphere(first) == kOk); Require(sceMoveClose(first) == kOk); RequireUnknownHandle(first); const std::int32_t reopened = sceMoveOpen(kUserId, 0, 0); Require(reopened == kFirstHandle + 2 * kHandleStep); Require(sceMoveClose(reopened) == kOk); Require(sceMoveSetVibration(second, 0) == kNoControllerConnected); Require(sceMoveTerm() == kOk); RequireNotInit(second); Require(sceMoveInit() == kOk); RequireUnknownHandle(second); const std::int32_t third = sceMoveOpen(kUserId, 0, 0); Require(third == kFirstHandle + 3 * kHandleStep); Require(sceMoveClose(third) == kOk); Require(sceMoveTerm() == kOk); }