feat(libSceNpGameIntent): export missing firmware game intent interfaces

This commit is contained in:
fogydes authored and Adrià Franch committed 2026-10-19 09:22:26 +02:00
1 parent fb0dc118f3
commit fa94b2cfc8
5 files changed
+119

No files matched your search

+10
View File
@@ -606,4 +606,14 @@ if(BUILD_TESTING)
set_tests_properties(guest_voice_chat PROPERTIES ENVIRONMENT_MODIFICATION
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libSceVoiceChat>")
endif()
add_test_executable(guest_np_game_intent_tests tests/GuestNpGameIntent.cpp)
target_include_directories(guest_np_game_intent_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(guest_np_game_intent_tests PRIVATE libSceNpGameIntent libc)
configure_windows_unwind(guest_np_game_intent_tests)
add_test(NAME guest_np_game_intent COMMAND guest_np_game_intent_tests)
if(WIN32)
set_tests_properties(guest_np_game_intent PROPERTIES ENVIRONMENT_MODIFICATION
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libSceNpGameIntent>")
endif()
endif()
+5
View File
@@ -1439,6 +1439,11 @@ struct NpGameIntentData {
std::uint8_t padding[7];
};
struct NpGameIntentInitParam {
std::size_t size;
std::uint8_t reserved[32];
};
struct NpGameIntentInfo {
std::size_t size;
std::int32_t user_id;
@@ -46,4 +46,31 @@ int APS5_VABI sceNpGameIntentTerminate(void) {
return 0;
}
int APS5_VABI sceNpGameIntentInitParamInit(NpGameIntentInitParam* param) {
if (param == nullptr) {
APS5_INVALID_ARG_EX;
}
std::memset(param, 0, sizeof(NpGameIntentInitParam));
param->size = sizeof(NpGameIntentInitParam);
return 0;
}
int APS5_VABI sceNpGameIntentInfoInit(NpGameIntentInfo* info) {
if (info == nullptr) {
APS5_INVALID_ARG_EX;
}
std::memset(info, 0, sizeof(NpGameIntentInfo));
info->size = sizeof(NpGameIntentInfo);
info->user_id = NpGameIntentUserIdInvalid;
return 0;
}
int APS5_VABI sceNpGameIntentVshInitialize(void) {
return 0;
}
int APS5_VABI sceNpGameIntentVshTerminate(void) {
return 0;
}
}
+67
View File
@@ -0,0 +1,67 @@
#include "SceTypes.hpp"
#include "prx/libc/include/general/VabiMacros.hpp"
#include <cstdio>
#include <cstdlib>
#include <stdexcept>
extern "C" {
int APS5_VABI sceNpGameIntentInitParamInit(NpGameIntentInitParam* param);
int APS5_VABI sceNpGameIntentInfoInit(NpGameIntentInfo* info);
int APS5_VABI sceNpGameIntentInitialize(const void* initParam);
int APS5_VABI sceNpGameIntentReceiveIntent(NpGameIntentInfo* intentInfo);
int APS5_VABI sceNpGameIntentGetPropertyValueString(const NpGameIntentData* intentData, const char* key, char* valueBuf, size_t bufSize);
int APS5_VABI sceNpGameIntentVshInitialize(void);
int APS5_VABI sceNpGameIntentVshTerminate(void);
int APS5_VABI sceNpGameIntentTerminate(void);
}
static void Require(bool value, const char* what) {
if (value) return;
std::printf("NpGameIntent: %s\n", what);
std::abort();
}
template <typename TError, typename TCall>
static bool Throws(TCall call) {
try {
call();
} catch (const TError&) {
return true;
}
return false;
}
int main() {
constexpr int kIntentNotFound = -2141898746;
constexpr int kValueNotFound = -2141898745;
Require(Throws<std::invalid_argument>([] { sceNpGameIntentInitParamInit(nullptr); }),
"null param init did not throw");
NpGameIntentInitParam initParam{};
Require(sceNpGameIntentInitParamInit(&initParam) == 0, "param init failed");
Require(initParam.size == sizeof(NpGameIntentInitParam), "param size mismatch");
Require(Throws<std::invalid_argument>([] { sceNpGameIntentInfoInit(nullptr); }),
"null info init did not throw");
NpGameIntentInfo info{};
Require(sceNpGameIntentInfoInit(&info) == 0, "info init failed");
Require(info.size == sizeof(NpGameIntentInfo), "info size mismatch");
Require(info.user_id == -1, "info user_id mismatch");
Require(sceNpGameIntentInitialize(&initParam) == 0, "initialization failed");
Require(sceNpGameIntentReceiveIntent(&info) == kIntentNotFound, "receive intent mismatch");
char buf[64]{};
Require(sceNpGameIntentGetPropertyValueString(&info.intent_data, "key", buf, sizeof(buf)) == kValueNotFound,
"get property value mismatch");
Require(sceNpGameIntentVshInitialize() == 0, "vsh init failed");
Require(sceNpGameIntentVshTerminate() == 0, "vsh terminate failed");
Require(sceNpGameIntentTerminate() == 0, "terminate failed");
std::puts("NpGameIntent tests passed");
return 0;
}
+10
View File
@@ -0,0 +1,10 @@
# libSceNpGameIntent technical debt
### Silent stubs
- [sceNpGameIntentVshInitialize, sceNpGameIntentVshTerminate](../../../core/libs/prx/libSceNpGameIntent/Export.cpp) (libSceNpGameIntent) - VSH initialization and termination return 0 without performing shell operations, matching `sceNpGameIntentInitialize` and `sceNpGameIntentTerminate`
### Unknown function info
- [sceNpGameIntentInitParamInit](../../../core/libs/prx/libSceNpGameIntent/Export.cpp) (libSceNpGameIntent) - struct layout matches [fpPS4](https://github.com/red-prig/fpPS4/blob/master/src/np/ps4_libscenpgameintent.pas#L17) `SceNpGameIntentInitParam`; setting `size`, zeroing reserved bytes, and throwing on null pointer follow Sony SDK `*ParamInit` conventions but are unverified on retail hardware
- [sceNpGameIntentInfoInit](../../../core/libs/prx/libSceNpGameIntent/Export.cpp) (libSceNpGameIntent) - struct layout matches [fpPS4](https://github.com/red-prig/fpPS4/blob/master/src/np/ps4_libscenpgameintent.pas#L28) `SceNpGameIntentInfo`; setting `size`, `user_id = -1`, zeroing fields, and throwing on null pointer match `sceNpGameIntentReceiveIntent` defaults but are unverified on retail hardware