mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-29 12:15:39 +00:00
229 lines
7.6 KiB
C++
229 lines
7.6 KiB
C++
#include "prx/libc/include/general/VabiMacros.hpp"
|
|
#include <cstdint>
|
|
#include <cstdlib>
|
|
#include <stdexcept>
|
|
|
|
extern "C" {
|
|
int APS5_VABI sceVrTrackerQueryMemory(const void*, void*);
|
|
int APS5_VABI sceVrTrackerInit(const void*);
|
|
int APS5_VABI sceVrTrackerTerm();
|
|
int APS5_VABI sceVrTrackerRegisterDevice(int, int);
|
|
int APS5_VABI sceVrTrackerRegisterDevice2(int, int);
|
|
int APS5_VABI sceVrTrackerRegisterDeviceInternal(int, int, int, int);
|
|
int APS5_VABI sceVrTrackerUnregisterDevice(int);
|
|
int APS5_VABI sceVrTrackerRecalibrate(const void*);
|
|
int APS5_VABI sceVrTrackerSetDurationUntilStatusNotTracking(int, std::uint32_t);
|
|
int APS5_VABI sceVrTrackerGpuWaitAndCpuProcess();
|
|
}
|
|
|
|
namespace {
|
|
|
|
constexpr int NotInit = static_cast<int>(0x81260801u);
|
|
constexpr int AlreadyInitialized = static_cast<int>(0x81260802u);
|
|
constexpr int DeviceNotRegistered = static_cast<int>(0x81260803u);
|
|
constexpr int DeviceAlreadyRegistered = static_cast<int>(0x81260804u);
|
|
constexpr int ArgumentInvalid = static_cast<int>(0x81260806u);
|
|
constexpr int NotExecuteGpuSubmit = static_cast<int>(0x81260815u);
|
|
constexpr std::uint32_t Untouched = 0xa5a5a5a5u;
|
|
constexpr int Hmd = 0;
|
|
constexpr int Pad = 1;
|
|
constexpr int Move = 2;
|
|
constexpr int Gun = 3;
|
|
|
|
struct Calibration {
|
|
std::uint32_t hmd, pad, move, gun;
|
|
std::uint32_t reserved[4];
|
|
};
|
|
|
|
struct QueryParam {
|
|
std::uint32_t size = sizeof(QueryParam);
|
|
std::uint32_t profile = 0;
|
|
std::uint32_t reserved[6]{};
|
|
Calibration calibration{};
|
|
};
|
|
|
|
struct QueryResult {
|
|
std::uint32_t words[16];
|
|
};
|
|
|
|
struct InitParam {
|
|
std::uint32_t size = sizeof(InitParam);
|
|
std::uint32_t profile = 0;
|
|
std::uint32_t executionMode = 0;
|
|
std::int32_t priorities[4]{};
|
|
std::int32_t reserved = 0;
|
|
std::uint64_t cpuMask = 0;
|
|
Calibration calibration{};
|
|
void* onion = nullptr;
|
|
std::uint32_t onionSize = 0x400000;
|
|
std::uint32_t onionAlignment = 0x10000;
|
|
void* garlic = nullptr;
|
|
std::uint32_t garlicSize = 0x3000000;
|
|
std::uint32_t garlicAlignment = 0x10000;
|
|
void* work = nullptr;
|
|
std::uint32_t workSize = 0x1000000;
|
|
std::uint32_t workAlignment = 0x10000;
|
|
std::int32_t pipe = 0;
|
|
std::int32_t queue = 0;
|
|
};
|
|
|
|
struct RecalibrateParam {
|
|
std::uint32_t size = sizeof(RecalibrateParam);
|
|
std::uint32_t deviceType = 0;
|
|
std::uint32_t calibrationType = 0;
|
|
std::uint32_t reserved[5]{};
|
|
};
|
|
|
|
std::uint8_t g_onion[16];
|
|
std::uint8_t g_garlic[16];
|
|
std::uint8_t g_work[16];
|
|
|
|
void Require(bool value) { if (!value) std::abort(); }
|
|
|
|
template <typename TFunction>
|
|
void RequireThrows(TFunction function) {
|
|
try { function(); } catch (const std::runtime_error&) { return; }
|
|
std::abort();
|
|
}
|
|
|
|
QueryResult FreshResult() {
|
|
QueryResult result;
|
|
for (auto& word : result.words) word = Untouched;
|
|
return result;
|
|
}
|
|
|
|
InitParam ValidInit() {
|
|
InitParam init;
|
|
init.onion = g_onion;
|
|
init.garlic = g_garlic;
|
|
init.work = g_work;
|
|
return init;
|
|
}
|
|
|
|
int Recalibrate(std::uint32_t deviceType, std::uint32_t size = sizeof(RecalibrateParam)) {
|
|
RecalibrateParam param;
|
|
param.size = size;
|
|
param.deviceType = deviceType;
|
|
return sceVrTrackerRecalibrate(¶m);
|
|
}
|
|
|
|
void CheckQueryMemory() {
|
|
QueryParam query;
|
|
auto result = FreshResult();
|
|
Require(sceVrTrackerQueryMemory(&query, &result) == 0);
|
|
Require(result.words[0] == Untouched);
|
|
Require(result.words[1] == 0x400000 && result.words[2] == 0x10000);
|
|
Require(result.words[3] == 0x3000000 && result.words[4] == 0x10000);
|
|
Require(result.words[5] == 0x1000000 && result.words[6] == 0x10000);
|
|
Require(result.words[7] == Untouched);
|
|
|
|
query.calibration.move = 1;
|
|
query.profile = 100;
|
|
Require(sceVrTrackerQueryMemory(&query, &result) == 0 && result.words[1] == 0x800000);
|
|
|
|
auto rejected = FreshResult();
|
|
QueryParam bad = query;
|
|
bad.profile = 1;
|
|
Require(sceVrTrackerQueryMemory(&bad, &rejected) == ArgumentInvalid);
|
|
bad = query;
|
|
bad.calibration.hmd = 1;
|
|
Require(sceVrTrackerQueryMemory(&bad, &rejected) == ArgumentInvalid);
|
|
bad = query;
|
|
bad.calibration.pad = 2;
|
|
Require(sceVrTrackerQueryMemory(&bad, &rejected) == ArgumentInvalid);
|
|
bad = query;
|
|
bad.size = sizeof(QueryParam) - 1;
|
|
Require(sceVrTrackerQueryMemory(&bad, &rejected) == ArgumentInvalid);
|
|
Require(sceVrTrackerQueryMemory(nullptr, &rejected) == ArgumentInvalid);
|
|
Require(sceVrTrackerQueryMemory(&query, nullptr) == ArgumentInvalid);
|
|
Require(rejected.words[1] == Untouched);
|
|
}
|
|
|
|
void CheckBeforeInit() {
|
|
Require(sceVrTrackerTerm() == NotInit);
|
|
Require(sceVrTrackerRegisterDevice(Pad, 5) == NotInit);
|
|
Require(sceVrTrackerUnregisterDevice(5) == NotInit);
|
|
Require(Recalibrate(Pad) == NotInit);
|
|
Require(sceVrTrackerSetDurationUntilStatusNotTracking(Pad, 10) == NotInit);
|
|
Require(sceVrTrackerGpuWaitAndCpuProcess() == NotInit);
|
|
}
|
|
|
|
void CheckInit() {
|
|
auto bad = ValidInit();
|
|
bad.size = sizeof(InitParam) - 8;
|
|
Require(sceVrTrackerInit(&bad) == ArgumentInvalid);
|
|
bad.size = 144;
|
|
RequireThrows([&] { sceVrTrackerInit(&bad); });
|
|
bad = ValidInit();
|
|
bad.calibration.move = 1;
|
|
Require(sceVrTrackerInit(&bad) == ArgumentInvalid);
|
|
bad.onionSize = 0x800000;
|
|
bad.pipe = 7;
|
|
Require(sceVrTrackerInit(&bad) == ArgumentInvalid);
|
|
bad.pipe = 0;
|
|
bad.queue = 8;
|
|
Require(sceVrTrackerInit(&bad) == ArgumentInvalid);
|
|
bad.queue = 0;
|
|
bad.work = nullptr;
|
|
Require(sceVrTrackerInit(&bad) == ArgumentInvalid);
|
|
bad.work = g_work;
|
|
bad.garlicAlignment = 0x1000;
|
|
Require(sceVrTrackerInit(&bad) == ArgumentInvalid);
|
|
Require(sceVrTrackerInit(nullptr) == ArgumentInvalid);
|
|
Require(sceVrTrackerTerm() == NotInit);
|
|
|
|
const auto init = ValidInit();
|
|
Require(sceVrTrackerInit(&init) == 0);
|
|
Require(sceVrTrackerInit(&init) == AlreadyInitialized);
|
|
Require(sceVrTrackerInit(nullptr) == AlreadyInitialized);
|
|
Require(sceVrTrackerGpuWaitAndCpuProcess() == NotExecuteGpuSubmit);
|
|
}
|
|
|
|
void CheckDevices() {
|
|
Require(sceVrTrackerRegisterDevice(Pad, 5) == 0);
|
|
Require(sceVrTrackerRegisterDevice(Pad, 6) == DeviceAlreadyRegistered);
|
|
Require(sceVrTrackerRegisterDevice2(Move, 7) == 0);
|
|
Require(sceVrTrackerRegisterDeviceInternal(Gun, 8, 5, 0) == ArgumentInvalid);
|
|
Require(sceVrTrackerRegisterDevice(4, 8) == ArgumentInvalid);
|
|
Require(sceVrTrackerRegisterDevice(-1, 8) == ArgumentInvalid);
|
|
Require(sceVrTrackerRegisterDevice(Hmd, 9) == 0);
|
|
|
|
Require(Recalibrate(Pad) == 0);
|
|
Require(Recalibrate(Move) == 0);
|
|
Require(Recalibrate(Hmd) == DeviceNotRegistered);
|
|
Require(Recalibrate(Gun) == DeviceNotRegistered);
|
|
Require(Recalibrate(4) == ArgumentInvalid);
|
|
Require(Recalibrate(Pad, sizeof(RecalibrateParam) + 4) == ArgumentInvalid);
|
|
Require(sceVrTrackerRecalibrate(nullptr) == ArgumentInvalid);
|
|
|
|
Require(sceVrTrackerSetDurationUntilStatusNotTracking(Gun, 10) == 0);
|
|
Require(sceVrTrackerSetDurationUntilStatusNotTracking(4, 10) == ArgumentInvalid);
|
|
|
|
Require(sceVrTrackerUnregisterDevice(5) == 0);
|
|
Require(sceVrTrackerUnregisterDevice(5) == ArgumentInvalid);
|
|
Require(sceVrTrackerUnregisterDevice(-1) == ArgumentInvalid);
|
|
Require(Recalibrate(Pad) == DeviceNotRegistered);
|
|
Require(sceVrTrackerRegisterDevice(Pad, 6) == 0);
|
|
Require(sceVrTrackerUnregisterDevice(9) == 0);
|
|
}
|
|
|
|
void CheckTerm() {
|
|
Require(sceVrTrackerTerm() == 0);
|
|
Require(sceVrTrackerTerm() == NotInit);
|
|
Require(sceVrTrackerRegisterDevice(Gun, 8) == NotInit);
|
|
const auto init = ValidInit();
|
|
Require(sceVrTrackerInit(&init) == 0);
|
|
Require(sceVrTrackerRegisterDevice(Move, 11) == DeviceAlreadyRegistered);
|
|
Require(sceVrTrackerTerm() == 0);
|
|
}
|
|
|
|
} // namespace
|
|
|
|
int main() {
|
|
CheckQueryMemory();
|
|
CheckBeforeInit();
|
|
CheckInit();
|
|
CheckDevices();
|
|
CheckTerm();
|
|
}
|