sceNpTrophyUnlockTrophy inserted the id into the in-memory set and then saved the
state file. A save that threw (the state directory or the rename failed) left the
trophy unlocked in memory but not on disk, so a retry answered
TROPHY_ALREADY_UNLOCKED and the unlock was lost at the next start. The new set is
now built on a copy, written, and only then installed.
SaveState also never looked at the stream after writing, so a failed write (for
example a full disk) was ignored and the truncated temporary file was renamed over
the good state file. It now flushes, checks the stream, removes the partial
temporary file and throws.
With an NP title id in place, a PS4 Pro (firmware 10.71) answers 0x80551607
from sceNpTrophyRegisterContext through an aborted handle, ahead of the
missing trophy package (0x80551626 through a live handle). The earlier
measurement stopped at the NP title id lookup on both handles.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
On a PS4 Pro (firmware 10.71) sceNpTrophyGetTrophyUnlockState and
sceNpTrophyGetGameIcon answer 0x80551607 through an aborted handle, ahead of
the not-registered check, and aborting the handle again answers 0.
sceNpTrophyAbortHandle now records the abort, the calls that use the handle
answer NP_TROPHY_ERROR_ABORT, and destroying the handle clears it.
sceNpTrophyRegisterContext keeps its answer, as measured without a trophy
package.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Both measured PS4 titles (CUSA04865, CUSA12435) import it. On a PS4 Pro
with firmware 10.71 a live handle answers 0 and an unknown handle
0x80551608 (INVALID_HANDLE); the library has no asynchronous request to
abort, so the call only validates the handle.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
NpTrophy reads the trophy count and icons from the title's trophy
package (names are encrypted and stay not implemented), PS4 v1 save data
calls wrap the native v2/v3 ones, and NpWebApi library contexts, handles
and push event filters work offline (service filters fail without a
signed-in user). libSceAjm is built from the libSceAjm.native sources
for PS4 titles. Limbo's (CUSA01664) remaining PS4 imports, including the
synchronous PS4 TUS calls and the Facebook dialog calls next to the
existing libraries, are exported as not implemented.