Skip to content

feat(libScePlayReady): implement the version, init-params and buffer-init calls - #13624

Merged
adriadam10 merged 2 commits into
boykopovar:mainfrom
BunnyFl:feat/libsceplayready-version-and-init-params
Oct 31, 2026
Merged

adriadam10 merged 2 commits into
boykopovar:mainfrom
BunnyFl:feat/libsceplayready-version-and-init-params

Conversation

@BunnyFl

@BunnyFl BunnyFl commented Oct 30, 2026

Copy link
Copy Markdown
Contributor

What

On main, 49 of the 50 libScePlayReady exports throw (scePlayReadyMemGetStats returns 0x80004001), and the debt file lists those 49 as having no known prototype. This implements six that need no PlayReady state, following firmware 13.42's libScePlayReady.sprx (read from disassembly and run natively, not measured on a console; see Tested), and gives them their prototypes:

Export Firmware 13.42
void sceBufferInit(void* buffer) clears the first 0x18 bytes; does nothing for null
int scePlayReadyBufferInit(void* buffer) clears the first 0x18 bytes and returns 0; 0x80070057 for null
void scePlayReadyApiInitializeInitParams(void* params), void scePlayReadyInitializeInitParams(void* params) clear the first 0x138 bytes, then write 0x50524459 and 1 as the first two 32-bit words; do nothing for null
int scePlayReadyApiVersion(uint32_t index, uint64_t* version) index 0 writes {2, 5, 0, 1788}, index 1 writes {1, 3, 3, 2021111201} (32 bytes), returns 0; 0x80070057 for any other index or a null version, with nothing written
const char* scePlayReadyApiVersionString(uint32_t index) returns one static 32-byte buffer holding the same numbers as "%lu.%lu.%lu.%lu" (2.5.0.1788, 1.3.3.2021111201); for any other index the whole buffer is cleared and returned

Both calls that take an index read only its low 32 bits (cmp $0x1,%edi). The version string keeps the firmware's buffer: the firmware does not clear it before a valid index and writes the text through libc snprintf, so with snprintf behaving as standard C (it was modelled, not run, in the firmware run below) the text and its terminator are the only bytes written, and after 1.3.3.2021111201 a call for index 0 leaves 11201 after the new terminator. Here the text is built with std::to_chars rather than the host snprintf, because unsigned long (%lu) is 32 bits on Windows and the values are 64-bit.

scePlayReadyApiIsStarted and scePlayReadyReset are left throwing: their answers depend on the state that scePlayReadyApiStart and scePlayReadyInitialize set, and those are not implemented. In the debt file the six names leave the "no credible prototypes" entry, which is split into three entries to stay under 1000 characters (its text is unchanged), and a new entry records where they come from, that the meaning of the cleared fields is unknown (so they take void*), and that the version string is a single static buffer, as in the firmware.

Tested

Windows 11, WinLibs GCC 15.2, Release. No title was run.

Checklist

  • Based on current main; no other open PR implements the same functions
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw (NotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file
  • No notes, investigation .md files or images added to the repository (attach them to this PR)
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none
  • Fixes: none
  • Unblocks: none
  • GPUs tested: n/a
  • AI-assisted: yes

🤖 Generated with Claude Code

BunnyFl and others added 2 commits October 30, 2026 20:39
…init calls

Follow firmware 13.42's libScePlayReady.sprx for sceBufferInit,
scePlayReadyBufferInit, scePlayReadyApiInitializeInitParams,
scePlayReadyInitializeInitParams, scePlayReadyApiVersion and
scePlayReadyApiVersionString, and give them their prototypes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…000 characters

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

Progress report (5a75b4a → 3b0bccc)

📈 System libraries: 26.51% (+0.02%, +6 implemented functions)

✅ 6 implemented
Library Name
libScePlayReady sceBufferInit
libScePlayReady scePlayReadyApiInitializeInitParams
libScePlayReady scePlayReadyApiVersion
libScePlayReady scePlayReadyApiVersionString
libScePlayReady scePlayReadyBufferInit
libScePlayReady scePlayReadyInitializeInitParams

Changed libraries (implemented exports)

Library Before After Change
libScePlayReady 1/50 (2.00%) 7/50 (14.00%) +12.00%

@github-actions

github-actions Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.

Pull request Shared files not compared
PR 5021 core/libs/CMakeLists.txt
PR 7275 core/libs/CMakeLists.txt
PR 7622 core/libs/CMakeLists.txt
PR 8650 core/libs/CMakeLists.txt
PR 9156 core/libs/CMakeLists.txt
PR 9293 core/libs/CMakeLists.txt
PR 9297 core/libs/CMakeLists.txt
PR 9302 core/libs/CMakeLists.txt
PR 9383 core/libs/CMakeLists.txt
PR 9933 core/libs/CMakeLists.txt
PR 12642 core/libs/CMakeLists.txt
PR 12928 core/libs/CMakeLists.txt
PR 13253 core/libs/CMakeLists.txt
PR 13256 core/libs/CMakeLists.txt

@JJenkx

JJenkx commented Oct 30, 2026

Copy link
Copy Markdown
Contributor

Windows run of this head (3b0bccc206), merged onto main 5a75b4a119 (clean merge, local only). Windows 11 Enterprise 10.0.22621, Ryzen 9 5950X, WinLibs GCC 15.2.0 UCRT r7, Ninja, Release, BUILD_TESTING=ON, ANYPS5_ENABLE_SPIRV_TOOLS=ON, no Vulkan driver visible.

  • This PR: guest_playready passes 3 of 3 (ctest --repeat until-fail:3).
  • Negative control: not possible. With this PR's source files (core/libs/prx/libScePlayReady/Export.cpp, core/libs/prx/libScePlayReady/include/Api.hpp) put back to main's version, the build fails against the rest of the PR, so there is no source-only control.

AI-assisted: yes (Claude Code).

@MarcZX10 MarcZX10 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed — looks good

I approve head 3b0bccc20699338ffd461c12d021490fa4583b1f: the six accessor-free initialization/version calls are implemented consistently with their declared signatures, and I found no blocking source issue.

What I ran

Reviewed exact head 3b0bccc20699338ffd461c12d021490fa4583b1f against PR base 5a75b4a119e2c92f8e0881944bd006c0b2bf9751; its merge preview against current main 73ffb45110da8a9960267124941316bc006998ea was clean. The implementation and test files are identical to tested commit 579ed87e0db7277b8fa3c5e37dc2792853fa21eb; the only later change is the debt-file split. The relevant PlayReady source and test files have no changes on current main since the reported test base 16345cad6a692bc37e682150f11c7ab635788941. Environment: Linux x86-64, Python 3.11.2. No local build or CTest was run.

python3 tools/pr_precheck.py --repo boykopovar/AnyPS5 --pr 13624
git diff --stat 579ed87e0db7277b8fa3c5e37dc2792853fa21eb...3b0bccc20699338ffd461c12d021490fa4583b1f
git diff --name-only 16345cad6a692bc37e682150f11c7ab635788941...73ffb45110da8a9960267124941316bc006998ea -- core/libs/prx/libScePlayReady core/libs/tests/GuestPlayReady.cpp core/libs/CMakeLists.txt
gh pr checks 13624 --repo boykopovar/AnyPS5

Results

Check Result
Diff, conventions, dependency/merge preview Passed.
Export declaration/definition audit Passed; no findings.
Hosted Windows build Passed on the reviewed head.
Hosted Linux and specialized jobs Skipped.
PlayReady CTest and seven negative controls Author reports 3/3 relevant tests passed and each mutation failed the new test on commit 579ed87e0db7277b8fa3c5e37dc2792853fa21eb; I did not independently run them.
Firmware behavior Author reports native calls against firmware 13.42; no console measurement is claimed, and I did not independently verify the disassembly or run.
Relevant unedited output

python3 tools/pr_precheck.py --repo boykopovar/AnyPS5 --pr 13624:

Head unchanged at completion: True
Base unchanged at completion: True
diff_check: passed
conventions_and_pr_template: passed
live_dependency_and_mergeability_check: passed

gh pr checks 13624 --repo boykopovar/AnyPS5:

windows	pass	7m44s
conventions	pass	22s
intake	pass	21s
labels	pass	5s
eligibility	pass	7s
library-portability	pass	1m51s
report	pass	59s
linux	skipping	0
register-context	skipping	0
relinker	skipping	0
relinker-asan	skipping	0
write-watch	skipping	0

Sources

Not verified

I did not run the C++ tests, negative controls, firmware calls, or console behavior locally. Linux full-build and specialized hosted jobs were skipped.

@blawesom blawesom left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified 3b0bccc on Linux x86-64 (GCC 16.2.1, CachyOS kernel 6.2.10, Release, BUILD_TESTING=ON)

  • Built in an isolated worktree at the PR head (fresh build dir, Ninja): guest_playready_tests and guest_firmware_constant_returns_tests build clean.
  • ctest -R '^guest_playready$|^guest_firmware_constant_returns$' -V: 2/2 passed. guest_playready repeated 5x: 5/5 passed.
  • ctest -R 'public_headers' --parallel 8: 65/65 passed. ctest -R 'playready': only guest_playready exists in the family; passed. nid_verneed passed after building nid_patcher (initial failure was only the unbuilt dependency in my fresh dir, not a PR regression).
  • tools/check_conventions.py --base origin/main at the head: all checks passed.
  • Diff vs base 16345cad6a is exactly the 5 files shown; no code comments (only // namespace ends); Conventional Commit subjects; remaining 43 unimplemented exports still go through NotImplemented_nid_no_patch.
  • Test coverage of all six exports is thorough: exact cleared ranges (0x18, 0x138) with two fill bytes and untouched tails, magic/version words, null arguments, both version indices plus rejected 2/3/0x80000000/0xFFFFFFFF with nothing written, shared 32-byte string buffer, leftover tail and cleared buffer for unknown indices.
  • Version values ({2,5,0,1788} and {1,3,3,2021111201}) come from firmware 13.42's libScePlayReady.sprx read from disassembly and run natively — the PR body and the debt entry both state this and explicitly note it was not measured on a console, and the debt doc correctly documents the shared mutable string buffer and its consequences.
  • PR checklist complete and consistent with what I ran (AI-assisted: yes; GPUs: n/a; no title run — none needed for these stateless calls).

Not run: firmware SPRX comparison or a console run (no title/console here); Windows build (author covered WinLibs GCC 15.2).

@adriadam10 adriadam10 self-assigned this Oct 31, 2026
@adriadam10
adriadam10 merged commit 93d9b78 into boykopovar:main Oct 31, 2026
12 checks passed
@adriadam10

Copy link
Copy Markdown
Collaborator

Checked the six implementations against the diff (cleared sizes 0x18/0x138, init-params words, index and null rejection, static version buffer), the debt entries and the new guest_playready test (it pins cleared vs untouched bytes, which the throwing stubs cannot produce). Conventions, Windows and library-portability are green, and @JJenkx (Windows), @blawesom (Linux) and @MarcZX10 confirmed it; merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants