36 Commits
Author SHA1 Message Date
LibretroAdmin 73c3c0baee Remove Movie (TAS input recording/playback)
Nothing in the core starts a recording or a playback, so a movie is
never active. Each call site keeps its no-movie path: no determinism
toggle, the real clock for the RTC, the configured memory cards, no
pad/Wiimote input mirroring into display strings on every poll. The
state keeps the movie counters' bytes, written as zeroes, so existing
savestates still load.
2026-11-07 15:12:31 +01:00
LibretroAdmin 5e7772c97e Follow-ups to the LIBRETRO ifdef removal
D3D11 sets logic op support from the device again (off on UWP) and
always reports object names: the UWP check's else had swallowed the
object-name line and logic op was never on. The Android input backend
is no longer created, so its source, include and CIFACE_USE_ANDROID go.
Core.h declarations indented with spaces like the rest of the file.
2026-11-07 14:55:52 +01:00
LibretroAdmin 6e9be4ba64 Common: drop the Gekko assembler, nothing in the core calls it 2026-11-07 13:37:22 +01:00
LibretroAdmin 734ceaa90c GBA: ROM, BIOS and saves through the frontend's VFS
The GBA core's files open as an mGBA VFile over a libretro-common
filestream (GBAVFile.c). A read-only map of a mapped file lends the
mapping itself, so the ROM and the BIOS are read where they lie; a save
is mapped into a buffer of its own and written back when mGBA syncs it.
A ROM in an archive or a zip is read or inflated straight into the
memory file mGBA maps, with no buffer in between.

The state and save import/export, e-Reader card queueing, ROM info and
forced disconnect entry points nothing calls are gone.
2026-11-07 06:27:34 +01:00
LibretroAdmin 4d9402dd6e Texture hashes through libretro-common's xxh64
TextureInfo hashes textures and palettes with libretro-common's
xxh64(), the same value XXH64() gives, so dumped and custom texture
names stay as they are. The pipeline hash helpers nothing calls are
gone, and with them Externals/xxhash.
2026-11-07 06:12:53 +01:00
LibretroAdmin 6fe348ec38 Vulkan: device memory from a heap of its own, in C
VKHeap.c takes large blocks from the driver and hands out offsets in
them: the lowest free span that fits, spans kept sorted so a free is a
binary search and a merge. The handle is a small struct kept by value,
so nothing is allocated per allocation. Host-visible blocks are mapped
once and stay mapped; stream buffers and staging buffers write straight
into the memory the GPU reads. Buffers and linear images keep to blocks
of their own, apart from optimal images. What the driver requires or
prefers dedicated, and anything of half a block or more, gets memory of
its own sized to fit. Host blocks are 16 MiB, device blocks 64 MiB, and
neither more than an eighth of its driver heap; one empty block of each
kind is kept and the rest go back to the driver.

The Vulkan Memory Allocator is gone, and with it the memory budget
extension only it used.
2026-11-07 06:06:08 +01:00
LibretroAdmin 5c90c84330 DiscIO: drop NANDImporter
Nothing the core builds imports a NAND backup; only the Android
frontend's WiiUtils, which is not part of the libretro build, called it.
2026-11-07 04:24:25 +01:00
LibretroAdmin 2323f96cf4 File I/O: one path, libretro-common's filestream and VFS
Every file the core touches goes through libretro-common's filestream,
path and dirent layers, taken from RetroArch: vfs_hybrid opens local
paths with libretro-common's own implementation and hands URI paths
(and, on Android, anything a local open cannot reach) to the
frontend's VFS. File::IOFile and File::DirectIOFile sit on RFILE, and
FileUtil, FileSearch and the directory walks on path_stat, path_mkdir
and retro_opendir. Dolphin's fopen, POSIX and Win32 file code,
std::filesystem and std::fstream are gone, with the dual VFS paths and
the core option that chose between them.

Files opened for reading alone are memory-mapped where the platform
can: reads copy straight out of the page cache, DirectIOFile's offset
reads on one mapped object are thread safe, and GetMappedPtr(), View()
and Prefetch() lend and warm without a copy. Text files are read a
line at a time through File::LineReader, lent from the mapping or a
window refilled a block at a time, never a byte at a time; JSON is
parsed straight from the mapping. Ini files and the cheat file are
built in memory and written once, an ini only when it changed and
then atomically.
2026-11-07 03:27:01 +01:00
LibretroAdmin c265e74c05 Software renderer: pictures handed to the frontend in memory, no GL
The software and null renderers run without a hardware context. They
come up at the end of retro_load_game, where a frontend with a context
would call context_reset, and go down with the rest at unload.

The software renderer's picture goes to video_refresh straight from its
XFB texture, in one pass into XRGB8888 order, into a buffer that grows
only with the picture: no GL texture upload, no draw, no window of its
own. The GPU thread's g_gfx is the backend's own from the start.
2026-11-07 02:05:40 +01:00
LibretroAdmin a390228b51 GL: no contexts of the core's own, the frontend's libretro GL context alone
The OpenGL renderer draws on the context the frontend hands over
through libretro GL, and the core makes no context of its own: the
platform context code goes, EGL, EGLX11, EGL for Android, WGL, AGL,
BGL and the GLX window, with the shared contexts made for the shader
compiler's threads, and GLContext::Create makes the libretro context
alone. Programs are compiled on the frontend's context, so the OpenGL
backend reports no background compiling and its shader compiler runs
no threads; the shared-context compiler, its glFinish and VAO rebinds
and the driver bug that switched it off go with it. Android no longer
links libEGL.
2026-11-07 01:36:34 +01:00
LibretroAdmin 919e8c5181 Video: the frontend's frame targets in place of swap chains
The frontend owns the window and presents, so the D3D11, D3D12 and
Vulkan backends draw their picture into a FrameOutput, a render target
the frontend reads where it is, rather than a swap chain. D3D11 hands
over one texture at pixel shader slot 0. D3D12 negotiates version 2 of
its interface and keeps one texture per sync index, handed over with
the fence its picture completes on, falling back to set_texture on
version 1. Vulkan keeps one image per sync index and hands it over with
set_image, so the fake swap chain and the WSI calls hooked under it are
gone, and the device may come without a surface. The outputs are RGBA8
and report that format to the presenter.

The DXGI and Vulkan swap chains, the backends' standalone device
creation and exclusive fullscreen are removed.
2026-11-06 19:11:38 +01:00
LibretroAdmin aeb0819e40 D3D, D3D12: vertex, pixel and compute stages to bytecode with rslc
The vendored rslc compiles the generators' GLSL straight to DXBC of the
feature level's shader model, so these stages no longer go through HLSL
and the runtime compiler. The geometry stage is written in HLSL and is
still compiled by D3DCompile.
2026-11-06 17:17:12 +01:00
LibretroAdmin f073fc9448 Remove glslang and SPIRV-Cross
Every backend compiles its shaders through rslc now: the two submodules,
VideoCommon/Spirv.cpp and their build go.
2026-11-06 14:12:01 +01:00
LibretroAdmin 275126d933 Build glslang and Spirv.cpp only where Metal needs them
Vulkan and D3D compile through rslc, so glslang only serves Metal's path
through SPIRV-Cross. It and VideoCommon/Spirv.cpp are built with
SPIRV-Cross on Apple platforms and nowhere else.
2026-11-06 04:34:35 +01:00
LibretroAdmin e3e2f2a230 Vulkan: compile the shaders with rslc instead of glslang
Vendors rslc from RetroArch's libretro-common (gfx/shaders, built with
RSLC_EXTENDED) and has the Vulkan backend hand every vertex, geometry
and pixel stage to it for SPIR-V: no glslang on that path, no global
lock, any number of compiles in parallel. D3D and Metal still go
through glslang and SPIRV-Cross until rslc writes their code.

A stage rslc refuses is logged and written, with the error, to the
dump directory as bad_<stage>_Vulkan_<n>.txt.

rslc has no compute stage, storage buffers, atomics or subgroup
operations yet, so for now the backend does not offer what needs them:
GPU texture decoding (decoding stays on the CPU), the bounding box,
the dynamic vertex loader and the vertex-shader line and point
expansion (the geometry shader expands them).
2026-11-06 01:50:24 +01:00
LibretroAdmin 53238c0a06 VideoCommon, backends, input, DiscIO: std::atomic -> retro_atomic
- CommandProcessor: the FIFO registers shared by the CPU and GPU
  threads are retro_atomic words, read and written through LoadReg and
  StoreReg; MMIO's LowPart/HighPart take those words.
- Fifo: the video buffer write and seen pointers, the sync ticks and
  the stop request.
- PerfQueryBase: the query count and results sit behind base-class
  helpers that every backend (Metal too) uses instead of touching the
  atomics.
- Custom assets: the loader's memory delta and an asset's last load
  time are 64-bit words; Present's swap flag is an int.
- D3D's input layout, Vulkan's waiting_for_submit.
- InputCommon: a NumericSetting's value and the Wiimote and Android
  rumble levels are kept as their bits in a 64-bit word; the
  ControllerInterface flags, counter and aspect ratio are int words.
- CachedBlob's fill position and stop flag.

UICommon/GameFileCache is deleted: only the Android app's game list
used it, and that is not part of the core.
2026-11-06 00:19:39 +01:00
LibretroAdmin d3b454d48b Common: make the lock-free maps C89
AtomicHashMap.h was a pair of C++ templates. Common/AtomicMap.{h,c}
replaces it with the same structure in C89, keyed by bytes: each key's
node is pushed at its bucket's head with a CAS and stays until the map
is freed.

- atomic_slot_map: one atomic pointer slot per key, for the OGL
  pipeline programs (keyed by the PipelineProgramKey bytes) and the
  D3D state cache (keyed by each state's hex word).
- atomic_value_map: values that begin with a quiesce_node_t, published
  whole and freed once no reader is inside, for the asset library's
  id-to-files and path-to-id maps (keyed by the string's bytes).

The OGL program cache's reference count and shader id counter move to
retro_atomic too, and PipelineProgramKeyHash goes with the template
that used it.
2026-11-06 00:19:39 +01:00
LibretroAdmin f38b307112 Audio: hand the frontend each field as the hardware made it
The mixer, its granule queues, fades, time stretching and resampling,
the sound stream, the frontend audio callback modes and frame time
callback, Dolby Pro Logic II decoding, audio dumping and the
FreeSurround library are removed.

AudioCommon/FieldAudio.c (C89) is the AI's output. The DSP's DMA
samples go straight into the current field's buffer at the DMA rate,
only byte-swapped. Disc streaming is added in place on top of them and
converted only when its rate differs from the DMA rate, as the AI does
when it mixes the two. The frontend is told the DMA rate, and told
again if a game switches it; it does any other resampling itself.

The remotes' speakers, the Skylanders portal and connected GBAs are
mixed in place too while they play, each converted from its own rate:
a remote's samples as its ADPCM decoder produces them, the portal's
straight from the request, and a GBA's read by mGBA straight into a
lock-free ring that the CPU thread mixes from at the field's end.

Each field end seals the buffer, its length the emulated time since the
last one at the output rate, and retro_run hands every sealed field to
the batch callback straight from that buffer: one video frame and one
consecutive run of samples per run, with no queue or copy in between.

Save state version 193, as the audio interface no longer carries mixer
state.
2026-11-05 23:34:32 +01:00
LibretroAdmin a2404c6e43 Remove the on-screen messages and the ImGui overlay
Nothing is drawn over the game any more. The OSD message queue, the
ImGui overlay that drew it (with the shader-compile progress window and
the statistics, projection and scissor windows), and the imgui and implot
libraries are removed from the build.

Core::DisplayMessage now writes to the log, and the former OSD calls
go through it. Shader compilation no longer presents frames outside
retro_run while it waits.

Deleted with it: the "OSD enabled" core option, the OSD, FPS, speed,
graph, statistics and internal-resolution display settings, and the
ImGui shaders and texture conversion.
2026-11-05 23:34:25 +01:00
LibretroAdmin c478df9181 Measure elapsed time by retro_run, not the host clock
FrameClock also sums frame lengths at the refresh rate the core reports,
and the core-wide Clock (CommonTypes.h) reads that sum. Everything that
measured elapsed time now follows the frontend: it advances a frame at a
time and stands still while the frontend pauses. That covers input
expression timers, cursor and gyro integration, Wiimote-as-device
timeouts, the DSU client, VR controller velocity, Free Look, IOS socket
timeouts, the BBA TCP timers, custom asset load times, OSD message
lifetimes, Common::Timer and the Dolphin IOS device's elapsed time.
Local steady_clock aliases are removed so nothing bypasses it.

Calendar reads stay: the RTC's starting date, file and log timestamps,
and generated file names still take the host's date and time.

Deleted: SteadyAwakeClock, the debugger's unused CodeTrace, and the
host-time diagnostics in IOS request handling and DVDThread.
2026-11-05 22:05:07 +01:00
LibretroAdmin 1e2dbf6616 Remove all sleeping and wall-clock pacing from the core
retro_run runs one video frame and the frontend paces it, so the core no
longer paces itself:

- The speed limiter is gone: CoreTiming::Throttle and its host-time
  targets, VI skip, the presenter's presentation-time wait,
  PrecisionTimer, PerformanceMetrics/PerformanceTracker, and the
  emulation speed, precision timing, rush/smooth presentation and VI
  skip settings and core options. The Dolphin IOS device reports 100%
  and ignores speed limits a guest asks for.
- Common/FrameClock.c (C89) counts retro_run calls. Background threads
  that acted every so many milliseconds wait for a number of frames
  instead: real-Wiimote pool upkeep, scanning, write tests and
  reconnect retries, USB scanning, the USB Gecko and GBA link
  listeners, the BBA read thread, memory card flushing and the WC24
  scheduler. Shutdown wakes every waiter.
- Waits that polled or timed out now block until signalled: dual-core
  boot, PauseAndLock in the GPU loop, CPU thread jobs, shader
  compilation progress, BlockingLoop and ParallelFor setup and
  teardown.
- Bluetooth passthrough submits transfers straight to libusb; the
  output worker and its timed sleep are deleted, HCI command timeouts
  count emulated time, and blocking firmware commands wait for the
  adapter's events.
- Real Wiimote reports go out when produced; delayed ones carry a
  frame number.
- Common::Flag sits on retro_atomic.
- Deleted: SleepCurrentThread, YieldCPU, Common::SleepUntil,
  Event::WaitFor, BlockingLoop::WaitYield, timer resolution changes,
  the play-time tracker, Host_YieldToUI, FrameTiming::ThrottleFrame
  leftovers and the never-used DO_WAIT_FOR_WIIMOTES mode.
2026-11-05 22:05:03 +01:00
LibretroAdmin 2e6ddc0424 Common: rewrite CallGate in C89
call_gate_t is the same counters as before, zero-filled when open.
The gates a thread is inside are now a list of call_gate_frame_t on
the callers' own stacks, linked through an rthreads TLS key, instead of
a thread_local array: no nesting limit and nothing to free per thread.
The TLS key and the shared eventcount are made on first use and
published with a CAS, so racing threads never wait on each other.

Builds rthreads with HAVE_THREAD_STORAGE for the TLS key.
2026-11-05 22:04:57 +01:00
LibretroAdmin f7d5095739 Core, InputCommon, VideoCommon: remove the remaining locks
Every std::mutex, lock_guard, unique_lock, scoped_lock,
condition_variable, call_once and semaphore left in Source/Core is
replaced by a lock-free design:

- Input: the device list, control bindings, stick calibration and
  default device are published snapshots read under a quiesce; a
  rebind requested while another thread is rebinding is handed to
  that thread instead of waited for.
- WiimoteReal: the pool thread owns the slots and runs commands from
  an MPSC queue; the active Wiimotes are atomic slots.
- EXI/SI/IOS devices: socket and packet traffic goes through SPSC
  rings or MPSC handoffs owned by one thread; USB scanning publishes
  its device list, and libusb transfers drain through a CallGate.
- Memory cards: the flush thread applies change records queued by
  the CPU thread.
- Custom assets: loads are scheduled as a published batch with an
  atomic cursor, results come back over an MPSC stack, and busy
  assets are skipped and retried.
- D3D state and GL program caches use insert-only atomic maps
  (Common/AtomicHashMap.h).
- Logging appends with O_APPEND / FILE_APPEND_DATA; FatFs reports
  busy instead of waiting; per-socket WSAStartup/WSACleanup.

Deleted as unused by the libretro core: the profiler, the FIFO
recorder, the volume verifier, the touch InputOverrider and the
GameCube adapter's libusb path.
2026-11-05 20:11:31 +01:00
LibretroAdmin 68c8ee8851 Common: lock-free Config, cached Info values and HookableEvent
Two small primitives carry it:

Quiesce (C89) frees read-mostly shared data without locks.  Readers
bracket an access with quiesce_enter/exit; a writer swaps in a new
pointer and retires the old one, and whichever thread sees the reader
count reach zero frees it.  Nobody waits, and a reader that retires
something from inside, such as a callback removing itself, only defers
the free.

CallGate lets a callback be unregistered while other threads may be
calling it.  Calls enter and leave the gate with one seq_cst add each;
closing it shuts out new calls and returns once the ones on other
threads have left, parking on an eventcount meanwhile, so the owner can
free what the callback captured.  A callback closing its own gate does
not wait on itself.

Config: the layers are a fixed array of published pointers indexed by
LayerType instead of a map under a shared_mutex, and the change
callbacks a fixed array of slots claimed by CAS instead of a vector
under a recursive_mutex.  Readers, OnConfigChanged among them, walk
them under the quiesce; RemoveConfigChangedCallback closes the
callback's gate, so as before nothing it captured is used once it
returns.

Info's cached value drops its spin mutex.  A value of four bytes or
less shares one 64-bit word with its config version, so Config::Get
reads it with a single load and updates it with a CAS; a wider one is a
published copy freed through the quiesce.  Common/Mutex.h had no other
user and is removed.

HookableEvent publishes its listeners as an immutable array, replaced
whole on register and unregister, so Trigger takes no lock.  A hook
registered from inside a callback is first called by the next Trigger;
destroying a hook while another thread runs its callback waits for that
call, as before.

Checked with a stress harness under TSan and ASan/UBSan: three readers
against two writers retiring 400000 objects, and hooks registered and
destroyed 20000 times against two threads triggering.
2026-11-05 20:11:24 +01:00
LibretroAdmin d452125b02 Remove the achievements code and the unit tests
None of it is built.  USE_RETRO_ACHIEVEMENTS is never defined, since a
libretro frontend runs achievements itself; what stays is the stub
AchievementManager the rest of the core already compiled against.
Source/UnitTests has had no build since the core moved to
Makefile.common.

They also held a good share of the remaining std::mutex users, which
the following commits take out of the code that is built.
2026-11-05 20:11:20 +01:00
LibretroAdmin 472dc5ae3f Remove user post-processing shaders and graphics-mod custom shaders
Both fed user-written GLSL to the backends at runtime, which the move to
bytecode emitted straight from the shader generators leaves no compiler
for. The frontend's own shader pipeline covers post-processing.

The presentation pass keeps a plain copy and the built-in correction
shader for output resampling, colour space and gamma correction and HDR
scaling, now compiled in rather than loaded from Sys/Shaders. The
graphics-mod system keeps its draw, EFB, projection and texture actions;
custom pipelines, materials, shader, mesh and sampler assets, the custom
constant buffers in every backend and the two mods built on them are
gone, along with the shader generators' custom-shader hooks.
2026-11-05 15:57:56 +01:00
LibretroAdmin 767c898df8 Move every thread onto rthreads and add a lock-free parallel_for
No std::thread, std::async, std::future or std::promise is left. Each
thread is an sthread with a plain entry point: Common::ThreadEntry<&C::F>
turns a member function into one, Common::JoinThread joins and clears a
handle, and Common::StartDetachedThread covers the fire-and-forget users.

Common/ParallelFor.{h,c} (C89) runs fn(ctx, i) for i in [0, count) on a
persistent pool of one worker per extra core plus the caller. Jobs are
claimed with an atomic counter, workers park on an eventcount between
batches, and the batch hand-off is a seq_cst users/active pair, so there
is no lock anywhere. A caller that finds the pool busy runs its batch
serially instead of waiting. retro_deinit joins the pool.

- VolumeWii::HashGroup spawned 64 threads per 2 MiB group and
  EncryptGroup another one per core; both are now parallel_for batches
  on the pool. The H1/H2 tail is a few small hashes and runs inline.
- VolumeVerifier spawned up to five std::async threads per chunk; the
  chunk's tasks now go to one persistent worker that fans them out with
  parallel_for, still overlapping the next read. The Redump lookup is an
  sthread joined in Finish or the destructor.
- The dual-core "GPU thread" in Core only set a thread_local on itself
  and exited, since the frontend runs the GPU loop. It is gone, along
  with the non-libretro branches of Core.cpp.
- The emu thread is started through Core::StartEmuThread.
- CPU core counts come from cpu_features_get_core_amount().
2026-11-05 13:00:34 +01:00
LibretroAdmin 8c7aa58f6b Remove UPnP, the unused host input backends, disc conversion and DolphinTool
None of these run in the core: UPnP served NetPlay; the DInput, XInput,
WGInput, Win32, Quartz, Xlib, evdev and Pipes input backends are never
enabled, since input comes from libretro; and disc conversion, with its
multithreaded compressor, was only reached from DolphinTool. The WIA,
RVZ and GCZ readers stay.
2026-11-05 13:00:29 +01:00
LibretroAdmin e4aed234da Remove NetPlay
The core never creates a NetPlay client or server; only the standalone
frontends did. Drop NetPlay with what only it used: the traversal
client, ENet, the QoS session, the NetPlay config layer and settings,
the chat and golf overlays, the netplay index, the save sync plumbing
in BootSessionData and WiiRoot, the disc sync hashes, and the Android
app's netplay feature and JNI bindings.
2026-11-05 13:00:19 +01:00
LibretroAdmin a27ceb33f8 Vendor libretro-common's rthreads, eventcount, SPSC queues and atomics
From RetroArch's libretro-common: rthreads, retro_eventcount,
retro_spsc, retro_waitable_spsc, mpsc_stack and retro_atomic, with the
units they need (features_cpu, rtime, compat_strl), built as their own
library group.
2026-11-05 13:00:15 +01:00
LibretroAdmin 1b8dfea3d0 Remove the audio backends and the SoundStream abstraction
The core only ever outputs through libretro, so drop the ALSA, cubeb,
null, OpenAL, OpenSL ES, PulseAudio and WASAPI streams, the backend
selection, and the vendored cubeb and OpenAL. SoundStream is now one
non-virtual class, implemented by the libretro output in
DolphinLibretro/Audio.cpp.

Also drop the settings only the backends read (backend, volume, mute,
mute on disabled speed limit, latency, WASAPI device) and the volume
and mute helpers. The mute-on-fast-forward toggle never had an effect,
as the libretro stream ignored volume changes.

The GameCube microphone, Wii Speak and Logitech mic keep their libretro
microphone path; the unbuilt cubeb capture path and its Windows COM
worker thread go.

Dolby Pro Logic II decoding (SurroundDecoder, FreeSurround) stays.
2026-11-05 05:38:09 +01:00
LibretroAdmin 74999e2082 Remove analytics
Drop DolphinAnalytics and Common/Analytics along with every game-quirk,
game-start, performance-sample and GPU-bug-override report, the
Main.Analytics settings, and the Android opt-in dialog, settings
entries, JNI hooks and session-timestamp tracking that only fed it.
DriverDetails loses its to_string helpers and stored driver name,
which only built the bug-override report.
2026-11-05 04:48:00 +01:00
LibretroAdmin c39e70854d Remove Discord Rich Presence, X11Utils and DolphinNoGUI
Discord presence was already disabled in the core (Host callbacks were
stubs and Boot turned it off); drop UICommon's DiscordPresence, the
vendored discord-rpc, its settings and the Host_UpdateDiscord* hooks.
The DolphinDevice Discord IOCTLs now answer IPC_EACCES, as Dolphin does
with presence disabled.

X11Utils was only used by DolphinNoGUI, a standalone frontend, so both
go.
2026-11-05 04:47:56 +01:00
LibretroAdmin dc7d0c21a0 Remove the updaters
UpdaterCommon, WinUpdater, MacUpdater and UICommon's AutoUpdate only
served the standalone Dolphin frontends; RetroArch updates the core.
Also drop the AutoUpdate settings, the update-track build string and
the u32 WindowsRegistry::ReadValue instantiation only WinUpdater used.
2026-11-05 04:47:53 +01:00
LibretroAdmin 057a10b834 Remove the CMake build
The static Makefile is the only build. GitLab CI and the GitHub workflows
build with it, with the same lanes and toolchains; the MSVC workflow and
the CMake-only macOS universal-binary script go, as nothing builds them.
The Readme describes the Makefile build.
2026-11-05 03:13:53 +01:00
LibretroAdmin 6e35fc179b Add a static Makefile for the libretro core
Builds parallel_gamecubewii_libretro for every lane .gitlab-ci.yml covers:
unix (Linux x86_64/aarch64), webos, win64 (MinGW-w64), osx (x86_64/arm64,
CROSS_COMPILE), ios-arm64, tvos-arm64, android-arm64 and android-x86_64.
The source lists and per-library flags follow what the CMake LIBRETRO=ON
build links into the core, without the units only the standalone frontends
use. The per-platform configure results for curl, libusb, libiconv and mGBA
are checked in under Externals/<library>/makefile; the remaining generated
files are produced by the Makefile under obj/gen.

The Android input backend's JNI entry points belong to the Android app and
are left out of the core, which links with --no-undefined everywhere.

The Windows code builds against MinGW-w64 headers older than 12.0 as well:
D3D12 includes d3d12sdklayers.h explicitly, and the constants, declarations
and const-correct pointer types those headers lack for D3D12, device
notifications, the Wii Remote Bluetooth path, the IOS IP stack and thread
naming are provided locally.
2026-11-04 23:49:57 +01:00