Commit Graph

156 Commits

Author SHA1 Message Date
Adrià Franch 2036697758 fix(ajm): convert planar 16-bit MP3 output from FFmpeg
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-02 09:20:45 +02:00
asimplestray f2bfdd26f9 feat(shader): implement SOP1 saveexec/wrexec family 2026-10-02 00:22:41 +00:00
boykopovar 75434ee4ad
Merge pull request #240 from adriadam10/feat/pad-small
feat(libScePad): implement scePadGetHandle and the embedded mic vibration option
2026-10-01 22:00:55 +03:00
boykopovar 54c3f39680
Merge pull request #238 from adriadam10/feat/playgo-language-todo
feat(libScePlayGo): fix error codes, implement the language mask and to-do list
2026-10-01 21:58:12 +03:00
boykopovar ce6bd0c750
Merge pull request #233 from adriadam10/feat/fiber-context-size-check
feat(libSceFiber): implement context size checking and the thread frame pointer
2026-10-01 21:57:29 +03:00
boykopovar 171c9a97b2
Merge pull request #230 from asimplestray/feat/rt-miss-mode
feat(shader): add ray tracing miss fallback mode
2026-10-01 21:56:27 +03:00
boykopovar a360f162c6
Merge pull request #224 from adriadam10/feat/ces-cp1252
feat(libSceCesCs): convert single characters between CP1252 and UTF-8
2026-10-01 21:53:01 +03:00
boykopovar e0f7866205
Merge pull request #223 from adriadam10/feat/http2-ssl-stubs
feat(libSceSsl): implement CA certificate queries and sceHttp2AbortRequest
2026-10-01 21:52:19 +03:00
boykopovar 938b632784
Merge pull request #221 from adriadam10/feat/http-uri
feat(libSceHttp): implement URI parse, build and escape
2026-10-01 21:48:06 +03:00
boykopovar 01e1074efc
Merge pull request #219 from asimplestray/feat/shader-vop3-minmax16
feat(shader): implement VOP3 I16/U16 min/max/med3
2026-10-01 21:42:12 +03:00
Adrià Franch 621c8bea23 feat(libScePad): implement scePadGetHandle and the embedded mic vibration option
scePadOpen now records that the pad is open and scePadClose clears it;
scePadGetHandle returns the handle for a port scePadOpen accepts while
the pad is open, and DEVICE_NO_HANDLE otherwise. No embedded microphone
is emulated, so the option that weakens trigger vibration while it is
in use is accepted with no effect.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-01 19:57:32 +02:00
Adrià Franch 2b36dc2408 feat(libScePlayGo): implement the language mask and to-do list
The title is fully installed, so scePlayGoGetLanguageMask reports every
language. scePlayGoSetToDoList validates the handle, entries, chunk IDs
and loci; nothing is pending, so the list is not kept.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-01 19:50:33 +02:00
Adrià Franch 62530c9d5c feat(libSceFiber): implement context size checking and the thread frame pointer
sceFiberStartContextSizeCheck and sceFiberStopContextSizeCheck toggle a
mode in which new fibers get their context filled with a pattern, so
sceFiberGetInfo can report the unused stack margin.
sceFiberGetThreadFramePointerAddress returns the frame pointer of the
thread that called sceFiberRun.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-01 19:27:24 +02:00
asimplestray c3a740b3e6 feat(shader): add ray tracing miss fallback mode 2026-10-01 17:24:09 +00:00
Adrià Franch fb6580ae36 feat(libSceCesCs): convert single characters between CP1252 and UTF-8
sceCesRefersUcsProfileCp1252 returns the CP1252 profile, and
sceCesSbcToUtf8 / sceCesUtf8ToSbc convert one character in each
direction. The five bytes CP1252 leaves undefined map to the matching
C1 controls, so every byte round-trips. Malformed UTF-8 and code points
outside CP1252 return the library's error codes.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-01 18:41:25 +02:00
Adrià Franch c548cd25b7 feat(libSceSsl): implement CA certificate queries and sceHttp2AbortRequest
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>
2026-10-01 18:35:02 +02:00
Adrià Franch 0a8cc7f543 feat(libSceHttp): implement URI parse, build and escape
sceHttpUriParse, sceHttpUriBuild and sceHttpUriEscape work on strings
only and are implemented. sceHttpCreateRequestWithURL, sceHttpReadData,
sceHttpSetChunkedTransferEnabled and sceHttpCreateEpoll follow the
existing no-network behaviour.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-01 18:15:50 +02:00
asimplestray b15f6800dd feat(shader): implement VOP3 I16/U16 min/max/med3 2026-10-01 16:11:33 +00:00
julienlgy 0c4dace39e feat(libSceHmd): add a disconnected-headset HLE stub 2026-10-01 14:18:10 +02:00
boykopovar e57ee5120d
Merge pull request #206 from Praetorian0420/main
Implement network control and socket functionality improvements
2026-10-01 11:41:41 +03:00
boykopovar 33e11c7ea2
Merge pull request #203 from oneandonlydean/fix/libkernel-direct-memory-memfd
fix(libkernel): back direct memory with a memfd on Linux
2026-10-01 11:31:43 +03:00
boykopovar e4eaba6b2e
Merge pull request #198 from MichonGoddijn231849/fix/reserve-virtual-fixed
fix(libkernel): honour MAP_FIXED in sceKernelReserveVirtualRange and sceKernelMemoryPoolReserve
2026-10-01 11:28:18 +03:00
boykopovar 89570be51b
Merge pull request #191 from asimplestray/feat/shader-vopc-cmpx
feat(shader): implement VOPC I16/U16 cmpx compares
2026-10-01 10:52:25 +03:00
Praetorian0420 e3eeac4a81 Implement network control and socket functionality improvements
- Enhanced the network control library to check for host addresses and update connection states accordingly.
- Added support for socket operations including connect, listen, accept, send, and recv in the UDP and TCP socket implementations.
- Introduced error handling for various socket operations, ensuring proper feedback for unsupported actions.
- Created comprehensive tests for both TCP and UDP socket functionalities, validating the expected behavior of the network stack.
- Refactored existing code to improve clarity and maintainability, including the removal of unused functions and the addition of necessary error checks.
2026-09-30 23:29:01 -05:00
Dean Galvin d544596283 fix(libkernel): back direct memory with a memfd on Linux
std::tmpfile() places the shared direct memory backing in /tmp, so a
title's direct memory counts against that filesystem's size (a tmpfs is
half of RAM by default): once /tmp fills, touching a backing page raises
SIGBUS. memfd_create gives the same shared memory pages without a
filesystem or its size limit.
2026-10-01 16:06:42 +13:00
asimplestray 889af1d542 feat(shader): implement VOPC I16/U16 cmpx compares 2026-09-30 23:55:29 +00:00
asimplestray 4816e105ad fix(tests): match default convention of ApplicationHeapRealign 2026-09-30 23:55:00 +00:00
asimplestray b42db4b6f3 feat(libc): implement RaiseEv, catchReturnFromMain and reallocalign 2026-09-30 23:55:00 +00:00
Michon 1d806a4688 fix(libkernel): honour MAP_FIXED in sceKernelReserveVirtualRange and sceKernelMemoryPoolReserve
Both ignored the flags and the requested address and reserved wherever the arena
had room, so a title that reserves a fixed range (Marvel's Wolverine passes
0x400010, MAP_FIXED | MAP_NO_COALESCE) and then uses the address it asked for
touched memory it never reserved. A fixed reservation now lands at the address,
after checking the range is free; other reservations are placed as before.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-01 00:00:22 +02:00
boykopovar d7ab5e371e
Merge pull request #175 from Qznad/feat/decoder-png
feat(pngdec): implement the PNG decoder
2026-09-30 21:12:56 +03:00
boykopovar 95f34bed3d
Merge pull request #171 from asimplestray/feat/kernel-time-signal
feat(kernel): implement Sleep, sigprocmask and pthread finalize
2026-09-30 21:03:48 +03:00
boykopovar c3aed31639
Merge pull request #169 from asimplestray/feat/kernel-file-ops
feat(kernel): implement file metadata ops and address conversion
2026-09-30 21:03:08 +03:00
boykopovar ba1d32f450
Merge pull request #168 from asimplestray/feat/kernel-psem
feat(kernel): implement pthread semaphore lifecycle
2026-09-30 21:01:53 +03:00
boykopovar fe712e7b9e
Merge pull request #101 from asimplestray/feat/rt-miss-config
feat(shader): configurable ray tracing miss fallback
2026-09-30 20:40:33 +03:00
boykopovar 488e678aa8
Merge pull request #161 from asimplestray/feat/libc-lifecycle
feat(libc): implement cxa lifecycle aliases and init_env
2026-09-30 20:35:36 +03:00
asimplestray 976fa82054 feat(shader): configurable ray tracing miss fallback 2026-09-30 16:53:03 +00:00
asimplestray a4e755ccb1 feat(kernel): implement file metadata ops and address conversion 2026-09-30 16:51:37 +00:00
boykopovar f881e021a8
Merge pull request #160 from asimplestray/feat/libc-wide-io
feat(libc): implement fputwc, fputws and fscanf
2026-09-30 19:40:31 +03:00
Dean Galvin 48687eefab fix(contentexport): refuse init parameters without allocators or with reserved fields set
sceContentExportInit2 accepted any non-null parameter block. It now throws
when the malloc or free function is missing or a reserved field is not
zero. A test covers these refusals and the init and term order.
2026-09-30 18:35:36 +03:00
boykopovar 119a74952a
Merge pull request #126 from oneandonlydean/feat/systemservice-hdr-tone-map
feat(systemservice): report the SDR tone-map luminance
2026-09-30 18:12:00 +03:00
boykopovar 077d4a487f
Merge pull request #125 from oneandonlydean/feat/pthread-prio-inherit
feat(libkernel): accept priority-inheritance mutexes
2026-09-30 18:11:38 +03:00
boykopovar f952bbeeb7
Merge pull request #121 from oneandonlydean/feat/linux-guest-write-watch
feat(agc): track guest memory writes on Linux with async userfaultfd write protection
2026-09-30 18:10:48 +03:00
boykopovar 1e1f0562c6 refactor(videodec2): use shared ffmpeg-core submodule + remove black fallbacks 2026-09-30 17:41:49 +03:00
Pacuka a38ef6132f feat(videodec2): decode H.264 with FFmpeg
Adds libSceVideodec2. Access units (Annex B, or length-prefixed rewritten to
Annex B) are decoded by FFmpeg's H.264 decoder into the title's NV12 frame
buffers (256-byte pitch, chroma after the visible luma rows). Decode hands
out at most one picture per call, Flush drains the reordered ones, Reset
clears the decoder; timestamps and attached data travel with the picture.
FFmpeg is found through pkg-config and is optional: without it the decoders
return black pictures. guest_videodec2_tests checks the pictures of an
embedded stream against reference hashes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 17:30:58 +03:00
Dean Galvin d8c7c0ccdf feat(agc): track guest memory writes on Linux with async userfaultfd write protection
GuestMemory::CollectWrites was built on the Windows arena's MEM_WRITE_WATCH
and answered 0 on Linux, so every cached copy of guest memory (textures,
resident render targets, buffers, DCC key proofs) read as changed at every
check: resident targets were stored and re-uploaded at every refresh and
unit shadows stayed off. Astro Bot's intro ran at ~3 fps.

libc gains GuestWriteWatch, the Linux counterpart of GetWriteWatch. Every
guest mapping libkernel makes (MapAligned: fixed, hinted and aligned) is
registered with one userfaultfd in asynchronous write-protect mode
(UFFD_FEATURE_WP_ASYNC: the kernel lifts a page's protection on its first
write without a handler thread, for user and kernel-mode writes alike), and
PAGEMAP_SCAN with PM_SCAN_WP_MATCHING reports the pages written since the
last scan of a range and protects them again in one call. Unmap forgets
the range. Direct memory is mapped from shared backings over its
reservation and a fixed remap replaces the mapping, so both register the
new mapping afresh. The watch is per mapping: a write through one mapping
of shared physical pages is not seen at another, so physical pages mapped
at more than one address leave the watch in every mapping of them.

A registered mapping reads as written until a collect covers it. The watch
keeps that itself instead of relying on how the kernel classifies pages
never faulted in: Linux 6.17 reports a range without page tables as not
written and leaves it unprotected, 7.2 reports it as written. The first
collect of a fresh range reports it written and write-protects it with
UFFDIO_WRITEPROTECT, which puts markers on its unpopulated pages
(UFFD_FEATURE_WP_UNPOPULATED), so from then on only real writes report.

Fallback: the userfaultfd is opened with UFFD_USER_MODE_ONLY where
vm.unprivileged_userfaultfd restricts it, and a probe at startup checks the
mechanism on scratch pages (a populated and an unpopulated page written
after protection report exactly, untouched ones do not). Without it (kernel
older than 6.7, no userfaultfd permission, headers without PAGEMAP_SCAN, or
APS5_NO_WRITE_WATCH=1) the watch reports unavailable and the tracker stays
unwatched exactly as before: CollectWrites answers 0 and callers compare
bytes. A range with a page outside the registered mappings also answers 0,
and a protection or scan that fails reports its remaining pages as written
and answers 0.

The driver's tracker keeps its contract and generations. On Linux its
block stamps live in 4 GiB leaves over the user address space, made on
first stamp, instead of the arena's flat arrays; the collect memo now works
on both platforms. GuestMemory::WriteWatched and Watched replace the arena
queries in UnitShadowEnabled and ShadowDestinationFor, so unit shadows run
on Linux over watched memory and stay off everywhere else. The Windows
arena path is unchanged apart from going through the same stamp helpers.

Host imports: a driver may lift the write protection of imported pages
itself. amdgpu validates the userptr BO behind a VK_EXT_external_memory_host
import with a writable HMM fault on every submission after the pages were
protected again, so PAGEMAP_SCAN reports them as written with no CPU store,
and a resident display image read as written at every present (found by
Pacuka on an RX 6650 XT with RADV: the presented image went black). NVIDIA
pins the pages once at the import and stays exact from then on. A probe at
device setup decides per device: it maps and watches scratch pages, collects
them clean, imports them, collects, submits a GPU copy that reads the import,
waits, and collects again. Pages written after the submission mean imports
resolve write protection: every import from then on takes its range off the
watch (GuestMemory::Unwatch) before it is made, so Watched is false for it,
CollectWrites answers 0 and callers compare bytes; GPU writes to watched
memory keep their MarkWritten stamps. The result is logged once:
"[write-watch] host imports resolve write protection: yes/no". A probe that
cannot run takes the unwatch side. APS5_WRITE_WATCH_IMPORTS=watch|unwatch
overrides the probe (default probe; anything else throws), and
APS5_NO_WRITE_WATCH=1 still turns the watch off. On the RTX 4090 the probe
reads 0 of 4 pages written after the GPU read (4 after the import itself),
so imports stay watched there.

The import itself lifts the protection once where imports stay watched:
on the RTX 4090 the pinning at vkAllocateMemory reports every imported page
as written (4 of 4 in the probe), with no CPU store. Such a report would
read as a CPU write over any GPU results pending in the range and drop
them. So every import of a watched range is made inside an import window
(GuestMemory::ImportWatched), under the tracker lock: the range is
collected right before the import, so earlier CPU writes are stamped as
usual, and again right after it, and what the window reports is stamped
"maybe written". Readers without pending results see it as a change
(UnchangedSince fails, ChangedBlocks reports it), so caches re-upload or
compare. Decisions about pending GPU results read it as untracked:
ChangedBlocks reports BlockMaybeWritten apart from BlockWritten, and the
drop rule, the write-back's keep blocks, the alias checks, the unit
shadow's stale drop and the whole-image stale checks (through the new
WrittenSince, which also answers false for a range off the watch) store
the results instead of dropping them. A real CPU store racing an import
also races the pending GPU writes to the same memory, which has no
defined order on hardware either, so the GPU results winning is
acceptable. From the second collect on the range is protected again and
watched normally. A range the watch does not cover whole, or a collect of
the window that fails, is taken off the watch instead.

An unwatched import stays off the watch for the rest of its mapping: a
remap registers the range afresh, the import kept over it takes it off
again at the next reconcile, and a re-import after an unmap follows the
decision. Unwatch invalidates the collect memo, so a collect memoized
before the import answers 0. A range that leaves the watch while a storage
image holds a generation for it no longer reads as CPU-written:
ChangedBlocks now tells whether the range is watched, and the drop rule,
the write-back's keep blocks and the alias borrow treat an unwatched range
as untracked (stored, never dropped), as a generation of 0 is.

Tests: guest_memory checks the watch through libkernel mappings (a CPU
store, a read, a kernel write through read(), another thread, a memcpy
across pages, an mprotect cycle, a partial munmap and a fixed remap) and
over a fresh 2 MiB-aligned mapping without page tables, checks direct
memory (watched, an alias takes the shared pages off the watch in both
mappings, a fixed direct remap over flexible memory is watched afresh), and
names the failing line and the reported pages. The recorder tests allocate watched
memory on both platforms, so the UnchangedSince, key proof, close race and
unit shadow tests run on Linux, and the storage refresh test gains a
watched variant: results kept on the GPU reach a CPU reader, and a plain
CPU store into one unit with newer results pending is found by the watch
alone. The recorder tests now also run the real import probe, check the
decision with the result injected (unwatch: an import leaves the watch, a
memoized collect, a partly imported range and the unimported neighbour
answer as they should, MarkWritten stamps only watched memory, a remap and
a re-import after an unmap follow the decision; watch: the import stays
watched and stamped), and check that results pending when their memory
leaves the watch are stored rather than dropped. A further test imports the
memory of a storage image with results pending in watch mode: the
results survive the import window and reach guest memory, a cache
generation taken before the import sees a change, the window reads as
maybe written and not as a CPU store, and a CPU store after it reads as
one again. Unit shadows and the
watched storage refresh report themselves as not run when imports are
compared.
2026-10-01 00:08:08 +13:00
Qznad a0e2f88048 feat(pngdec): implement libScePngDec on the shared PNG decoder 2026-09-30 11:10:00 +01:00
boykopovar 5e08eb4cce perf(memory): skip redundant page scans in shared write tracking 2026-09-30 09:59:51 +03:00
boykopovar abb9c85266 fix(kernel): share direct memory mappings and track physical offsets 2026-09-30 09:59:51 +03:00
asimplestray c6d098d487 feat(kernel): implement Sleep, sigprocmask and pthread finalize 2026-09-29 23:40:48 +00:00
asimplestray 064006b617 feat(kernel): implement pthread semaphore lifecycle 2026-09-29 22:13:07 +00:00