If the guest-supplied thread pointer doesn't resolve to an XThread,
we previously returned STATUS_SUCCESS without setting the affinity
or writing previous_affinity_ptr, leaving callers believing the call
succeeded. Real NT kernel would crash on a bad pointer, but that's not
easy for us to replicate so return STATUS_INVALID_HANDLE instead and
log the pointer value so the condition is visible rather than silent.
Previous global TLS bitmap was shared across all processes. Now
per-process TLS bitmaps stored X_KPROCESS structures which should
better match Xbox360 architecture.
When a thread wakes from a kernel wait, the Xenon scheduler boosts its
effective priority by the increment passed to the signaling call
(KeSetEvent, KeReleaseSemaphore, KeReleaseMutant). The boost is clamped
to the per-thread max_dynamic_priority cap, respects the guest
boost_disabled flag, and is drained on the next quantum expiry.
Guest KTHREAD priority fields are now initialized from parent process
defaults, and the previously unknown fields involved have been renamed
to match their identified purpose.
And default ignore_thread_priorities to false.
Map Xenon's 0-31 priority range across all 5 host priority levels
instead of collapsing 0-17 into kNormal.
Use timer-driven quantum decay (~20ms period) matching Xenon's
60-quantum / 3-per-tick cycle to prevent starvation by gradually lowering
effective priority for non-real-time threads (< 18), piggybacking on the
existing 1ms timestamp timer.
Spinlock acquire now checks if the lock holder shares the same guest
CPU and yields more aggressively (Sleep(0)) when contending on the
same Xenon HW thread, which should better approximate real kernel's
implicit serialization.
Child threads without an explicit affinity mask now inherit the
parent's guest CPU assignment instead of round-robining, so the
spinlock check correctly identifies parent-child co-location.
Most non-Windows code paths use standard POSIX APIs (sockets, signals,
dlopen, threading) that work on any POSIX platform. Change Linux-specific
guards to !WIN32 or #else where the code is portable. Linux-specific
APIs (SIGRTMIN, Vulkan/X11, fontconfig/GTK) remain Linux-guarded.
std::ctype<char16_t> is a non-standard extension that's not available
on all platforms. Neither this nor the original technically match the
Windows kernel's fixed Unicode table approach and can produce different
results based on system locale.
Generate per-function CIE+FDE records and register them via
__register_frame so the C++ exception unwinder can propagate through
JIT frames. Replace setjmp/longjmp fiber reentry with throw/catch
on Linux to ensure destructors and RAII guards run during fiber
stack switches.
Removes the Windows-only BCrypt dependency from XeCryptBnQwNeRsaPubCrypt
and replaces it with a portable modular exponentiation implementation
using 64-bit arithmetic, enabling RSA signature verification on all
platforms. Adds Catch2 tests validating the implementation with a
2048-bit RSA key.
Some games persist BGM volume through their own save files but never
call XMPSetVolume. Add a TitlePatch system that intercepts NtReadFile/
NtWriteFile to apply game-specific logic as well as logic to identify
the memory location that the volume data is read into and monitor that
memory location for changes, updating XMP player volume if it changes
during gameplay.
Includes patches for known games with this issue:
Dead or Alive Xtreme 2 (544307D2), PGR4 (4D5307F9) and PGR3 (4D5307D1)