feat(libSceHmd2): add PS VR2 modules that report the runtime as unavailable

sceHmd2Initialize fails, so titles skip their VR set-up; the other libSceHmd2 and libSceVrTracker2 exports throw.
This commit is contained in:
Gjon Gojcevic 2026-10-07 19:58:01 -04:00
parent df16c4c256
commit a988b8b1d0
5 changed files with 192 additions and 0 deletions

View File

@ -0,0 +1,15 @@
add_library(libSceHmd2 SHARED EXCLUDE_FROM_ALL Export.cpp)
target_include_directories(libSceHmd2 PRIVATE ${LIBS_INCLUDE_DIR})
configure_windows_unwind(libSceHmd2)
if(BUILD_TESTING)
add_test_executable(guest_hmd2_tests ${LIBS_INCLUDE_DIR}/tests/GuestHmd2.cpp)
target_include_directories(guest_hmd2_tests PRIVATE ${LIBS_INCLUDE_DIR})
target_link_libraries(guest_hmd2_tests PRIVATE libSceHmd2 libc)
configure_windows_unwind(guest_hmd2_tests)
add_test(NAME guest_hmd2 COMMAND guest_hmd2_tests)
if(WIN32)
set_tests_properties(guest_hmd2 PROPERTIES ENVIRONMENT_MODIFICATION
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libSceHmd2>")
endif()
endif()

View File

@ -0,0 +1,99 @@
#include <cstdint>
#include <cstddef>
#include "SceTypes.hpp"
#include "prx/libc/include/General.hpp"
namespace {
constexpr std::int32_t SCE_HMD2_ERROR_UNSUPPORTED_FEATURE = static_cast<std::int32_t>(0x81110016);
}
extern "C" {
std::int32_t APS5_VABI sceHmd2Initialize(const void* param) {
(void)param;
return SCE_HMD2_ERROR_UNSUPPORTED_FEATURE;
}
int APS5_VABI sceHmd2Close() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
int APS5_VABI sceHmd2GazeGetResultForFoveatedRendering() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
int APS5_VABI sceHmd2GetDeviceInformation() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
int APS5_VABI sceHmd2GetFieldOfViewWithoutHandle() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
int APS5_VABI sceHmd2Open() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
int APS5_VABI sceHmd2ReprojectionBeginFrame() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
int APS5_VABI sceHmd2ReprojectionDisableVrMode() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
int APS5_VABI sceHmd2ReprojectionEnableVrMode() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
int APS5_VABI sceHmd2ReprojectionGetPredictedDisplayTime() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
int APS5_VABI sceHmd2ReprojectionInitialize() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
int APS5_VABI sceHmd2ReprojectionQueryBufferSizeAlign() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
int APS5_VABI sceHmd2ReprojectionQueryDisplayBufferSizeAlign() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
int APS5_VABI sceHmd2ReprojectionSetAllowPositionalReprojection() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
int APS5_VABI sceHmd2ReprojectionSetParamWithBuffer() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
int APS5_VABI sceHmd2ReprojectionSetRenderConfig() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
int APS5_VABI sceHmd2SetVibration() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
}

View File

@ -0,0 +1,38 @@
#include <cstdint>
#include <cstddef>
#include "SceTypes.hpp"
#include "prx/libc/include/General.hpp"
extern "C" {
int APS5_VABI sceVrTracker2GetResult() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
int APS5_VABI sceVrTracker2Initialize() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
int APS5_VABI sceVrTracker2QueryMemory() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
int APS5_VABI sceVrTracker2RegisterDevice() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
int APS5_VABI sceVrTracker2SetCoordinateSystem() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
int APS5_VABI sceVrTracker2UnregisterDevice() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
}

View File

@ -0,0 +1,37 @@
#include "prx/libc/include/general/VabiMacros.hpp"
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <stdexcept>
extern "C" {
std::int32_t APS5_VABI sceHmd2Initialize(const void* param);
int APS5_VABI sceHmd2Open();
}
namespace {
void Require(bool condition, const char* message) {
if (!condition) {
std::fprintf(stderr, "HMD2: %s\n", message);
std::abort();
}
}
}
int main() {
const std::uint8_t param[16]{};
Require(sceHmd2Initialize(param) == static_cast<std::int32_t>(0x81110016), "initialization did not report the unsupported feature");
Require(sceHmd2Initialize(nullptr) == static_cast<std::int32_t>(0x81110016), "initialization without a param did not report the unsupported feature");
bool threw = false;
try {
sceHmd2Open();
} catch (const std::runtime_error&) {
threw = true;
}
Require(threw, "open after failed initialization did not throw");
std::puts("HMD2 tests passed");
return 0;
}

View File

@ -17,6 +17,7 @@ Throughout the project, every function at every stage either **does exactly what
- [libSceErrorDialog](../../core/libs/prx/libSceErrorDialog/Export.cpp) - the error dialog runs the state machine but shows nothing; the error code passed to `sceErrorDialogOpen` is only logged
- [libSceLoginDialog](../../core/libs/prx/libSceLoginDialog/Export.cpp) - the login dialog runs the common-dialog state machine but shows nothing and reports the user as having cancelled
- [libSceHmd](../../core/libs/prx/libSceHmd/Export.cpp) implements only the disconnected-headset path: initialization succeeds, device queries report `NotDetected`, and opening a device returns `DeviceDisconnected`. Headset support, tracking, rendering and additional HMD exports are not implemented; SDK-level ABI compatibility and in-game behaviour remain unverified.
- [libSceHmd2](../../core/libs/prx/libSceHmd2/Export.cpp) has no PS VR2 runtime: `sceHmd2Initialize` fails, and every other export it has (and every [libSceVrTracker2](../../core/libs/prx/libSceVrTracker2/Export.cpp) export) throws. PPSA01317 skips its whole VR set-up when initialization fails
- [libSceAudioPropagation](../../core/libs/prx/libSceAudioPropagation/Export.cpp) implements only the no-acoustic-propagation path: the system keeps a 16-byte header in the title's CPU memory (no GPU memory), rooms, portals, sources and materials are tracked handles, attributes are validated and have no effect, no rays are requested and sources report no audio paths. Ray results, path calculation and audio paths are accepted only when empty and throw otherwise; `sceAudioPropagationSourceRender` writes silence (zeroes) to each source's output buffer for the given size, without a dry signal. Objects still alive when their system is destroyed become unusable, and their later destroy or unregister is a no-op: PPSA21567 releases its reference-counted room, portal and source owners just before `sceAudioPropagationSystemDestroy`, so the order for every object is not proven. Occlusion, reflections and reverb from level geometry are absent; in-game behaviour remains unverified.
- [libSceNpCommerce](../../core/libs/prx/libSceNpCommerce/Export.cpp) - the PS Store icon show/hide calls and `sceNpCommerceSetPsStoreIconLayout` do nothing
- [libSceSystemService](../../core/libs/prx/libSceSystemService/Export.cpp) - `sceSystemServicePowerTick`, `sceSystemServiceReportAbnormalTermination`, `sceSystemServiceDisableMusicPlayer` and `sceSystemServiceReenableMusicPlayer` return success and do nothing: the host has no auto power-off timer to reset, no system crash reporter to notify and no system music player to pause or resume
@ -32,6 +33,8 @@ Throughout the project, every function at every stage either **does exactly what
### Unknown function info
- [sceHmd2Initialize](../../core/libs/prx/libSceHmd2/Export.cpp) (libSceHmd2) - the error the console returns when the PS VR2 runtime is unavailable is unknown; it returns libSceHmd's `UNSUPPORTED_FEATURE` (0x81110016). PPSA01317 passes a pointer to 16 zeroed bytes and only tests the result for non-zero
- PPSA01317 imports declared without parameters, signatures unknown: the remaining [libSceHmd2](../../core/libs/prx/libSceHmd2/Export.cpp) and [libSceVrTracker2](../../core/libs/prx/libSceVrTracker2/Export.cpp) exports. Names from the aerolib NID list
- PPSA01341 imports declared without parameters, signatures unknown: [sceAgcSetSemaphoreMemory](../../core/libs/prx/libSceAgc/Unimplemented.cpp), [sceAgcDriverRegisterMultipleResources](../../core/libs/prx/libSceAgcDriver/Unimplemented.cpp). Names from the shadPS4 aerolib NID list
- [sceAppContentDownloadDataGetAvailableSpaceKb](../../core/libs/prx/libSceAppContent/Export.cpp) (libSceAppContent) - a title whose `param.json` declares `downloadDataSize` 0 gets 0 KB and OK; the console's behaviour for a title without a download data area is unverified (it may return an error instead). KytyPS5 does not special-case it, and shadPS4 stubs 1048576 KB
- [7CxI50-xlCk, pMxXhNozUX8](../../core/libs/prx/libSceNpPartner001/Export.cpp) (libSceNpPartner001) - unknown names and signatures, imported by PPSA23566; declared without parameters