From fdfe2204aa21c5b1a9cc3fecdc253f62a1586653 Mon Sep 17 00:00:00 2001 From: David Date: Tue, 13 Oct 2026 20:00:30 +0530 Subject: [PATCH] feat(libSceAppContent): implement sceAppContentAddcontEnqueueDownload The signature (uint32_t service label, const NpUnifiedEntitlementLabel*) follows SharpProspero Interop/AppContent/AppContent.cs (5dfdb4b0). dlc_emu dlc_content.cpp (fcf69b16) answers NOT_FOUND for a label that is not a known add-on and PARAMETER for a null label. No add-on content is ever installed here, as sceAppContentAddcontMount and sceAppContentGetAddcontInfo already model, so every non-null label answers NOT_FOUND and nothing is queued. dlc_emu's nonzero-padding check is left out, as sibling functions do not check it and no console source confirms it. Carried from @screamm with author attribution preserved. Co-Authored-By: Claude Opus 5.5 --- core/libs/prx/libSceAppContent/Export.cpp | 7 ++++--- core/libs/tests/GuestAppContent.cpp | 5 +++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/core/libs/prx/libSceAppContent/Export.cpp b/core/libs/prx/libSceAppContent/Export.cpp index d36481e95..5f56318a1 100644 --- a/core/libs/prx/libSceAppContent/Export.cpp +++ b/core/libs/prx/libSceAppContent/Export.cpp @@ -172,9 +172,10 @@ int APS5_VABI sceAppContentTemporaryDataUnmount(const AppContentMountPoint* moun } -int APS5_VABI sceAppContentAddcontEnqueueDownload(void) { - NotImplemented_nid_no_patch(__func__); - return 0; +int APS5_VABI sceAppContentAddcontEnqueueDownload(uint32_t service_label, const NpUnifiedEntitlementLabel* entitlement_label) { + (void)service_label; + if (!entitlement_label) return SCE_APP_CONTENT_ERROR_PARAMETER; + return SCE_APP_CONTENT_ERROR_NOT_FOUND; } int APS5_VABI sceAppContentGetAddcontDownloadProgress(void) { diff --git a/core/libs/tests/GuestAppContent.cpp b/core/libs/tests/GuestAppContent.cpp index 93154a94e..1f68eaec0 100644 --- a/core/libs/tests/GuestAppContent.cpp +++ b/core/libs/tests/GuestAppContent.cpp @@ -10,6 +10,7 @@ extern "C" { int APS5_VABI sceAppContentInitialize(const AppContentInitParam*, AppContentBootParam*); int APS5_VABI sceAppContentAddcontMount(uint32_t, const NpUnifiedEntitlementLabel*, AppContentMountPoint*); int APS5_VABI sceAppContentAddcontUnmount(const AppContentMountPoint*); +int APS5_VABI sceAppContentAddcontEnqueueDownload(uint32_t, const NpUnifiedEntitlementLabel*); int APS5_VABI sceAppContentTemporaryDataMount2(uint32_t, AppContentMountPoint*); int APS5_VABI sceAppContentTemporaryDataUnmount(const AppContentMountPoint*); int APS5_VABI sceAppContentTemporaryDataFormat(const AppContentMountPoint*); @@ -82,6 +83,10 @@ int main() { std::memcpy(mountPoint.data, "/addcont0", 10); Require(sceAppContentAddcontUnmount(&mountPoint) == ErrorNotFound); Require(sceAppContentAddcontUnmount(nullptr) == ErrorParameter); + Require(sceAppContentAddcontEnqueueDownload(0, &label) == ErrorNotFound); + Require(sceAppContentAddcontEnqueueDownload(7, &label) == ErrorNotFound); + Require(sceAppContentAddcontEnqueueDownload(0, nullptr) == ErrorParameter); + Require(sceAppContentAddcontMount(0, &label, &mountPoint) == ErrorNotFound); std::filesystem::create_directory(directory / "temp0"); { std::ofstream file(directory / "temp0" / "old.txt"); file << "previous run"; }