From 68bddf80839e59f3a83237ac184c2160c5dc545f Mon Sep 17 00:00:00 2001 From: Niko Date: Wed, 14 Oct 2026 17:48:56 +0200 Subject: [PATCH] fix(libSceNpCommerce): open sceNpCommerceDialogOpen2 as prosper does Co-Authored-By: Claude Opus 5.5 --- core/libs/prx/libSceNpCommerce/Export.cpp | 4 +- core/libs/tests/GuestNpCommerceDialog.cpp | 79 +++++++++-------------- docs/dev/debt/libSceNpCommerce.md | 2 +- 3 files changed, 34 insertions(+), 51 deletions(-) diff --git a/core/libs/prx/libSceNpCommerce/Export.cpp b/core/libs/prx/libSceNpCommerce/Export.cpp index 75b66ad343..39fecd0fc0 100644 --- a/core/libs/prx/libSceNpCommerce/Export.cpp +++ b/core/libs/prx/libSceNpCommerce/Export.cpp @@ -79,9 +79,7 @@ int APS5_VABI sceNpCommerceSetPsStoreIconLayout(int layout) { return 0; } -int APS5_VABI sceNpCommerceDialogOpen2(const void* param) { - (void)param; - if (g_status == COMMON_DIALOG_STATUS_NONE) return COMMON_DIALOG_ERROR_NOT_INITIALIZED; +int APS5_VABI sceNpCommerceDialogOpen2(void) { g_status = COMMON_DIALOG_STATUS_FINISHED; return 0; } diff --git a/core/libs/tests/GuestNpCommerceDialog.cpp b/core/libs/tests/GuestNpCommerceDialog.cpp index d3ab0ee641..7b7239959f 100644 --- a/core/libs/tests/GuestNpCommerceDialog.cpp +++ b/core/libs/tests/GuestNpCommerceDialog.cpp @@ -2,78 +2,63 @@ #include #include +#include extern "C" { int APS5_VABI sceNpCommerceDialogInitialize(); int APS5_VABI sceNpCommerceDialogOpen(const void* param); +int APS5_VABI sceNpCommerceDialogOpen2(void); int APS5_VABI sceNpCommerceDialogUpdateStatus(void); int APS5_VABI sceNpCommerceDialogGetStatus(void); int APS5_VABI sceNpCommerceDialogGetResult(void* result); int APS5_VABI sceNpCommerceDialogClose(void); int APS5_VABI sceNpCommerceDialogTerminate(); -int APS5_VABI sceNpCommerceHidePsStoreIcon(void); -int APS5_VABI sceNpCommerceShowPsStoreIcon(int pos); -int APS5_VABI sceNpCommerceSetPsStoreIconLayout(int layout); -int APS5_VABI sceNpCommerceDialogOpen2(const void* param); } -static void Require(bool condition) { - if (!condition) { - std::abort(); - } +namespace { + +void Require(bool value) { if (!value) std::abort(); } + +constexpr int statusNone = 0; +constexpr int statusInitialized = 1; +constexpr int statusFinished = 3; +constexpr std::int32_t resultUserCanceled = 1; + +void RequireCanceledResult() { + std::uint8_t result[0x20]; + std::memset(result, 0x33, sizeof(result)); + Require(sceNpCommerceDialogGetResult(result) == 0); + std::int32_t value = 0; + std::memcpy(&value, result, sizeof(value)); + Require(value == resultUserCanceled); + Require(result[4] == 0); + Require(result[5] == 0x33); +} + } int main() { - constexpr int statusNone = 0; - constexpr int statusInitialized = 1; - constexpr int statusFinished = 3; - constexpr int resultUserCanceled = 1; - constexpr int errorNotInitialized = static_cast(0x80B80003u); - constexpr int errorAlreadyInitialized = static_cast(0x80B80004u); - constexpr int errorNotFinished = static_cast(0x80B80006u); - constexpr int errorArgNull = static_cast(0x80B80009u); - - struct DialogResult { - std::int32_t result; - std::uint8_t authorized; - }; - Require(sceNpCommerceDialogGetStatus() == statusNone); - Require(sceNpCommerceDialogUpdateStatus() == statusNone); - Require(sceNpCommerceDialogOpen(nullptr) == errorNotInitialized); - Require(sceNpCommerceDialogOpen2(nullptr) == errorNotInitialized); - Require(sceNpCommerceDialogClose() == errorNotInitialized); - - DialogResult dialogResult{}; - Require(sceNpCommerceDialogGetResult(&dialogResult) == errorNotFinished); - Require(sceNpCommerceDialogInitialize() == 0); - Require(sceNpCommerceDialogInitialize() == errorAlreadyInitialized); Require(sceNpCommerceDialogGetStatus() == statusInitialized); - Require(sceNpCommerceDialogOpen(nullptr) == errorArgNull); - Require(sceNpCommerceDialogOpen2(nullptr) == 0); - Require(sceNpCommerceDialogGetStatus() == statusFinished); + Require(sceNpCommerceDialogOpen2() == 0); Require(sceNpCommerceDialogUpdateStatus() == statusFinished); - - Require(sceNpCommerceDialogGetResult(nullptr) == errorArgNull); - Require(sceNpCommerceDialogGetResult(&dialogResult) == 0); - Require(dialogResult.result == resultUserCanceled); - Require(dialogResult.authorized == 0); + Require(sceNpCommerceDialogGetStatus() == statusFinished); + RequireCanceledResult(); Require(sceNpCommerceDialogClose() == 0); + Require(sceNpCommerceDialogGetStatus() == statusFinished); Require(sceNpCommerceDialogTerminate() == 0); Require(sceNpCommerceDialogGetStatus() == statusNone); - alignas(8) char param[16] = {}; + alignas(8) std::uint8_t param[0x40] = {}; Require(sceNpCommerceDialogInitialize() == 0); - Require(sceNpCommerceDialogOpen2(param) == 0); - Require(sceNpCommerceDialogGetStatus() == statusFinished); + Require(sceNpCommerceDialogOpen(param) == 0); + Require(sceNpCommerceDialogOpen2() == 0); + Require(sceNpCommerceDialogUpdateStatus() == statusFinished); + RequireCanceledResult(); Require(sceNpCommerceDialogTerminate() == 0); - - Require(sceNpCommerceHidePsStoreIcon() == 0); - Require(sceNpCommerceShowPsStoreIcon(0) == 0); - Require(sceNpCommerceSetPsStoreIconLayout(0) == 0); - + Require(sceNpCommerceDialogGetStatus() == statusNone); return 0; } diff --git a/docs/dev/debt/libSceNpCommerce.md b/docs/dev/debt/libSceNpCommerce.md index f3bd5b4eec..7a9d0ec642 100644 --- a/docs/dev/debt/libSceNpCommerce.md +++ b/docs/dev/debt/libSceNpCommerce.md @@ -6,4 +6,4 @@ ### Unknown function info -- [sceNpCommerceDialogOpen2](../../../core/libs/prx/libSceNpCommerce/Export.cpp) (libSceNpCommerce) - inferred signature follows `sceNpCommerceDialogOpen(const void*)`; accepts null or zero parameters and finishes as cancelled like the sibling call +- [sceNpCommerceDialogOpen2](../../../core/libs/prx/libSceNpCommerce/Export.cpp) (libSceNpCommerce) - declared without parameters; follows [prosper](https://github.com/mattias800/prosper/blob/73413cb445b0364bb49c4d2478e9ee1614b9f7d9/prosper/src/hle/np/np.cpp#L500-L504), which serves it with its `sceNpCommerceDialogOpen` handler: every argument is ignored, nothing is validated, it returns 0 and the dialog finishes at once, so `sceNpCommerceDialogGetResult` reports it cancelled. The parameters and the console's error results are unknown. Call of Duty: Black Ops (PPSA34501) calls it at Zombies > Online