A filter_type naming a subset of the PNG filters used only the first
filter of the mask, because stb's writer is either fully adaptive or
forced to one filter. Decoder::Png::Encode now takes the set of allowed
filter types, filters the rows and writes the chunks itself, and keeps
stb for deflate only. Output for the all-filters and single-filter
cases is unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SHA1RNDS4/NEXTE/MSG1/MSG2 with a memory source made `--to-intel` fail
the whole relink. The stub now spills a scratch xmm, loads the operand
into it with the unaligned load already used for SHA-256 and runs the
register-form lowering. The SHA1RNDS4 immediate is read after the SIB
byte and displacement. RIP-relative operands still fail: the stub runs
at a different address.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Return the kerning between two character codes at the render scale of
the font, the one set by sceFontSetupRenderScalePixel and
sceFontSetupRenderScalePoint, and fail with NOT_BOUND_RENDERER when no
renderer is bound. sceFontGetKerning keeps its behaviour and shares the
FreeType lookup.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The WriteAddressFromCounter_04_00 measure checks only the address and the
counter pair measure only the address and an even start, as in ampr_emu.
TechnicalDebt records that AMPR commands are larger than the console
records, which affects titles that pad with Nop to an exact offset, and
that the at-start flag of the 04_00 writes is ignored.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
s_setreg_b32 has no effect, so a read of the MODE round fields after it
wrote another mode still reports round to nearest even, the rounding the
recompiled code uses. The refused HW_ID test row is named as hardware
register 4, which has no name on gfx10.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sceAgcSetPacketPredication sets or clears the predicate bit of a type-3
packet header, and sceAgcSetRangePredication does so for every type-3
packet between two addresses, skipping type-2 fillers. The z-pass, bool
and disable predication size queries return the size of the
SET_PREDICATION packet sceAgcDcbSetPredication writes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
As in ampr_emu, a counter pair starts at an even counter, and the write
commands take a non-null, 8-byte aligned address; others return EINVAL.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sceAmprCommandBufferWaitOnAddress took (address, reference, mask,
compare) and WaitOnCounter (counter, reference, compare), and both read
the compare value as WAIT_REG_MEM (0 always, 1 <, 2 <=, 3 ==, ...).
ampr_emu, which replaces libSceAmpr for retail titles on the console,
has (address, reference, compare, flush) and (counter, reference,
compare, flush) with the SCE compare values (0 ==, 1 > unsigned,
2 < unsigned, 3 !=), so waits were decoded as other comparisons and
could block forever or pass early.
WriteAddressFromCounterPairOnCompletion takes one counter index, not
two, and WriteKernelEventQueueOnCompletion an int id and no user data.
Counter indices above 127, compare values above 3, flush values above 1
and misaligned wait addresses return EINVAL, as in ampr_emu.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Read the MPEG audio frame header and report the frame size, channel
count, samples per channel, bitrate and sample rate. The signature,
the result layout and the rate tables follow shadPS4's reimplementation
of the PS4 library. Requesting the original file length throws: that
lookup is not implemented.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ds_add/sub/rsub/inc/dec_u64, ds_min/max_i64/u64, ds_and/or/xor/mskor_b64,
ds_cmpst_b64/f64, ds_min/max_f64, their _rtn forms and ds_wrxchg_rtn_b64
threw in the decoder.
LDS is a 32-bit workgroup array, so the two dwords are read and written
under a lock dword placed after the guest LDS, which is cleared with a
workgroup barrier at entry. The lock is acquired and released in the same
loop iteration, so lanes of one subgroup cannot deadlock on it. Stages
whose LDS is a function variable update it directly. 64-bit GDS atomics
throw.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds the dialog to the silent-stubs list in docs/dev/TechnicalDebt.md, since it finishes without
showing anything. sceErrorDialogOpen now logs the error code and user id from the parameter
(offsets 4 and 8), like libSceMsgDialog logs its message, so an error a title would have shown
the player stays visible instead of disappearing.
sceAmprCommandBufferPushMarker, PushMarkerWithColor, PopMarker, SetMarker
and SetMarkerWithColor record a marker command, and the matching
sceAmprMeasureCommandSize functions return its size. The APR executor
skips markers, as it does a nop.
Signatures follow the ampr_emu reimplementation of libSceAmpr.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The mix level is a linear gain on the pad speaker port, 32768 being 0 dB.
A pad speaker port opens at 11626 (-9 dB). An unknown handle, a port of
another type and a level above 0 dB return the AudioOut error codes; a
negative level throws, as its effect is unknown.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Two diagrams in docs/dev/ARCHITECTURE.md: how the relinker and the NID-patched system libraries produce a native program, and the graphics path from command buffers through the shader recompiler to Vulkan. README only gains a link.
Co-Authored-By: Claude <noreply@anthropic.com>
Any other field or value throws. The existing s_setreg_b32 no-op is
recorded under Functional technical debt instead of silent stubs.
Co-Authored-By: Claude <noreply@anthropic.com>
s_cmovk_i32 writes the sign-extended 16-bit immediate when SCC is set.
s_version is a no-op marker. s_setreg_imm32_b32 takes its value from a
literal dword and is ignored like s_setreg_b32; both are now listed as
silent stubs in TechnicalDebt.
Co-Authored-By: Claude <noreply@anthropic.com>
sceAudioPropagationSourceRender takes the system, an array of RenderInfo
descriptors and their count: PPSA21564 and PPSA21567 pass one RenderInfo
{0x010107d6, 0x30} per call, with the source handle at +0x10, its output
buffer at +0x18, the buffer size in bytes at +0x20 and the word 2 at
+0x28, once per audio grain for each propagated source.
Without acoustic propagation a source contributes nothing, so each
output buffer is zeroed for its size. Every RenderInfo is checked first
(descriptor, a live source of this system, a non-empty output), and a
count of 0 or a format word other than 2 throws, as neither has been
observed.
RSQRTPS and RCPPS are approximations whose low bits differ between Intel
and AMD. Intel returns 0x3F7FF000 for 1/sqrt(1.0), and two Newton-Raphson
steps on it settle on 0.99999994 instead of 1.0. PPSA21564 renormalises
its spring quaternions that way: an identity quaternion keeps w at
0.99999994 with a zero axis, its axis-angle conversion then normalises the
zero axis into NaNs, and the NaN bone poses reach keyframed physics bodies.
A NaN body later moves to an invalid broadphase cell and the game crashes
a few seconds into its hub level.
--to-intel now replaces the VEX.128 register forms with an out-of-line stub
that computes 1/sqrt(x) with SQRTPS and DIVPS (1/x with DIVPS), keeping
the upper half of the destination cleared and the scratch register intact.
A site with no room for the jump, including one followed by a branch
target or a RIP-relative instruction, keeps the native instruction and is
reported as kept instead of failing the relink.
The 22 exports used by PPSA21567 take the call shapes recovered from its
call sites (#481): destroys take the system and the object, attribute
setters take a count, SourceCreate takes only an output handle,
UnregisterMaterial only the material.
The system lives in the title's CPU memory (16-byte header, no GPU memory)
and its handle is that address; rooms, portals, sources and materials are
counter handles. Attributes are validated and have no effect; no rays are
requested and sources report no audio paths. Non-empty ray results, path
calculation and audio paths throw, SourceRender stays unimplemented, and
invalid input throws because no error code is known. Objects left when
their system is destroyed become unusable; their later destroy or
unregister is a no-op.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SHA1RNDS4, SHA1NEXTE, SHA1MSG1 and SHA1MSG2 passed through --to-intel
unchanged, so a relinked title that executes them faults on Intel CPUs
without SHA-NI. Their register forms are now lowered out of line with
SSE2 only through the shared stub builder; short sites share stubs via
MatchSequence. Memory forms fail the relink with the file offset, as for
SHA-256.
Co-Authored-By: Claude <noreply@anthropic.com>
Replace the decoder-less AvPlayer with a player that demuxes MP4 sources
with FFmpeg (opened by path or through the title's file replacement),
decodes H.264 and AAC on their own threads, and hands out NV12 frames and
interleaved 16-bit PCM in buffers from the title's allocators, presented
on a media clock that audio drives when it is enabled.
Both libSceAvPlayer and libSceAvPlayer.native are built from the same
sources and link the shared ffmpeg target. The struct size checks stay,
next to the types in SceTypes.hpp. ChangeStream and GetStreamInfoEx are
implemented; Init without allocators, StartEx, SetAvailableBandwidth,
SetLogCallback and negative trick speeds succeed as before and are listed
in TechnicalDebt. HLS sources throw.
guest_avplayer plays an embedded 6 KB MP4 (H.264 plus two AAC tracks).
pthread_barrier_init threw for any non-null attributes object, and no
function could create one. Add pthread_barrierattr_init, _destroy,
_getpshared and _setpshared after FreeBSD libthr, and let
pthread_barrier_init take the object.
PTHREAD_PROCESS_SHARED still throws in pthread_barrierattr_setpshared:
FreeBSD 9.0 rejects it and 11.0 accepts it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sceKernelSyncOnAddressWait parks the calling thread while the 32-bit word
at the address still holds the expected value, until
sceKernelSyncOnAddressWake releases it or the timeout expires.
sceKernelSyncOnAddressWake releases up to the requested number of threads
parked on the address, in arrival order.
The libc.prx bundled with SDK 9 titles imports both for its once
primitive, so those titles stopped at load with an unresolved import.
# Conflicts:
# docs/dev/TechnicalDebt.md
libkernel did not export sceKernelMapNamedFlexibleMemoryInternal, which
the libc bundled with SDK 9 titles imports. It now forwards to
sceKernelMapNamedFlexibleMemory: the mapping counts against the flexible
budget, gets the range name and is released by sceKernelMunmap. Older
libc builds call the public function at the same sites with the same
arguments and result handling.
The known callers pass flag 0x8000, whose meaning is unknown. It is
still rejected as an unsupported mapping flag and is recorded in
TechnicalDebt.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
and throws for any non-zero word after it. Its layout matches shadPS4's
ServiceThreadParams instead: an unknown first word (16), a set-priority flag
and a priority (256..767), a set-affinity flag and a 64-bit CPU mask at
offset 16. PPSA21564 passes 16, 1, 0x100, 1 and 0x1FFF, so it stops at
startup on main.
sceVideoOutOpen now validates each field and reads the mask only when its
flag is set, so a 16-byte param with both flags clear still works. The
priority and affinity are not applied, since the present and vblank threads
are host threads; this and the unknown first word are listed in the
technical debt.
scePngEncQueryMemorySize, scePngEncCreate, scePngEncEncode and
scePngEncDelete encode R8G8B8A8 and B8G8R8A8 images with a pitch into
RGB or RGBA PNGs using the shared encoder in core/Decoder/Png.
Decoder::Png::Encode takes optional compression level and filter
options so the encode parameters are honoured.
Co-Authored-By: Claude <noreply@anthropic.com>
All six exports are implemented: MP3 and AAC (ADTS or raw blocks) are
decoded with the bundled FFmpeg and ATRAC9 with LibAtrac9, one unit per
call, into interleaved S16 or float PCM, with the libSceAudiodec
validation and error codes. libSceAudiodec.native is built from the same
sources.
Co-Authored-By: Claude <noreply@anthropic.com>
Sign-in, web browser and player dialogs finish cancelled; the message dialog finishes at once;
NpAuth, entitlement consumption, reachability, account age and the NpUtility bandwidth test
report signed out; sceKernelMtypeprotect changes the protection (the memory type has no host
equivalent); the APR ForEach resolvers resolve every path and report each failure in its own
result entry. vswprintf's stub is dropped in favor of the existing wide-formatter
implementation, which already covers it on every platform.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Keyboard input follows libSceMouse: the video out event loop forwards SDL
key and focus events, whose scancodes are USB HID usages, and the library
keeps the pressed keys, modifiers and lock LEDs in a 16-entry history for
sceKeyboardRead and a snapshot for sceKeyboardReadState.
sceKeyboardGetKey2Char translates the 101-key arrangement; the 106-key
one throws and is listed as technical debt.
KeyboardData holds 16 key codes (96 bytes), not 6.
Co-Authored-By: Claude <noreply@anthropic.com>
sceSslGetCaCerts reports that no CA certificates are available and
sceSslFreeCaCerts clears the structure, in line with the library's
no-network behaviour. sceHttp2AbortRequest succeeds like
sceHttpAbortRequest. sceSslClose and sceSslGetSerialNumber keep throwing
and are listed as unknown signatures.
Co-Authored-By: Claude <noreply@anthropic.com>
In 64-bit mode a REX prefix only takes effect when it immediately
precedes the opcode; a REX followed by a legacy prefix or another REX is
ignored. The instruction decoder, the rewriter's reference classifier,
DecodedInstruction and the SSE4a, SHA-256 and CLZERO operand decoders
read legacy prefixes and then at most one REX. `48 F3 0F 2B 00`
(MOVNTSS) was therefore scanned as `[48 F3][0F 2B 00]` and kept, and
`48 67 0F 01 FC` lost its address-size prefix.
All of them now accept REX bytes among the prefixes and keep only one
that directly precedes the opcode. The converter's guard against
prefix-only fragments is removed, since the decoder no longer produces
them, and the TechnicalDebt entry describing the split is dropped.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Lower CLZERO out of line instead of failing the relink: the 64-byte line
containing rAX (EAX with 67h) is cleared with four MOVNTDQ stores of
zero, the same non-temporal, weakly ordered store. The line address is
masked in xmm0 so RFLAGS stays untouched; xmm0 and rcx are spilled below
the red zone. Short sites share stubs through MatchSequence. CLZERO with
LOCK, an FS/GS override, a 66/F2/F3 prefix or longer than 15 bytes fails
the relink.
The decoder splits a REX followed by another prefix into a separate
instruction, which would hide a prefix that changes what CLZERO or the
next instruction does. The converter now fails the relink when such a
prefix-only fragment directly precedes an AMD-only instruction or would
be moved into a stub as a trailing instruction.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Replace MONITORX with a NOP and MWAITX with PAUSE in place, padded with
NOPs to the original length, instead of failing the relink. MWAITX may
return before its timer or a store to the monitored line, and without an
armed monitor it does not wait, so callers already re-check their
condition; the replacement takes that path every time.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Lower SHA256RNDS2, SHA256MSG1 and SHA256MSG2 (register forms) out of line
with legacy SSE2 instructions only, so relinked code no longer needs
SHA-NI. Consecutive short SHA-256 and SSE4a sites share one stub. The
SSE4a stub builder moves to StubBodyBuilder for reuse; IsShaNi now also
recognises SHA256RNDS2 (0F 38 CB). Memory operand forms fail the relink.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
feat: export the AMPR command buffer waits and writes, sceAgcFuseShaderHalves, sceAgcSetSubmitMode, sceNpSessionSignalingCreateContext and sceNetEpollAbort
Lower INSERTQ xmm1, xmm2 (F2 0F 79) out of line with SSE2 only instead of
failing the --to-intel relink. Length and index are read from bits 69:64
and 77:72 of the source; dst[127:64] is zeroed as on hardware.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>