The texture hash, the CRC32 helpers, Adler-32 and the Ector hash are C;
the texture hash picks CRC32 or MurmurHash3 once with a branch instead
of calling through a function pointer each time, CPUDetect still
deciding which. The hashes are bit for bit the old ones, so cached and
saved hashes stay valid.
Of it, the backends read the EFB scale, now passed as the backbuffer
scale; GLContext::Create tested for libretro, its only context; and
the controller interface kept a render window that is always null. The
video backends' Initialize, InitBackendInfo and PopulateBackendInfo,
Core::Init, EmuThread and StartEmuThread, BootCore and the controller
interface lose the parameter; PrepareWindow, ChangeWindow, the window
change refresh and the Vulkan instance's surface extensions go, as
nothing presents but the frontend.
The projection is the game's, turned only by the VR camera. Savestates
keep the free look camera's place: written as one at rest, and read past
whichever kind a state holds. The hotkey manager and the controller setup
that alone started it are gone too.
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.
SHA1, HMAC, hex dumps, PNG loading, file search, DHCP options, HTTP
posts and DirectIOFile reads and writes take pointer plus size; callers
pass their buffers straight through. Contains.h is gone; lookups are
plain loops. File search and FAT FST sorting are in-place heap sorts;
min/max/clamp/copy/fill become ternaries, memcpy and memset. Watch
string import and export had no callers and are removed.
- 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.
In dual core the CPU thread called into the frontend while the
frontend's own loop was running: every button and axis read went to
input_cb from SI polling, each field's audio went to the batch
callback, and rumble went to the rumble interface.
retro_run now reads every input of the libretro devices once, right
after poll_cb, and emulation reads those values. Rumble the emulation
asks for is kept until the end of retro_run, which hands it over
together with the audio the frame produced.
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.
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.
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().
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.
Common::Event is an atomic flag with a retro_eventcount to park on, so
Set takes no lock and makes no syscall while nobody waits. BlockingLoop
loses both of its mutexes: waiters park on an eventcount and re-check
IsDone(), so any number may wait at once, and Prepare hands setup to
the one thread that moves the loop out of the stopped state.
The thread helpers name, yield and sleep through rthreads and
retro_timers; the unused affinity and SwitchCurrentThread helpers go.
The core runs only inside a libretro frontend. The Qt frontend and its
submodule go, together with what only it used: the Qt DBus screensaver
inhibit, the JIT's single-block erase, the string translator hook, the
Qt translation catalogs and Transifex config, the desktop packaging
(NSIS, RPM, Flatpak) and the autoupdate overview.
The core takes its input from the libretro frontend and never builds the
SDL controller backend. The SDL submodule, the backend, its config entries
and the SDL hints and version bits of the Qt frontend go.
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.
SDL 3 has more misc buttons for "additional controller buttons" (e.g. left/right trigger clicks on a GameCube controller, or for the second touchpad click on the Steam Controller) which use these additional named Misc buttons. Taken from [SDL_GamepadButton](https://wiki.libsdl.org/SDL3/SDL_GamepadButton)
Previously we would vibrate for 100 ms on every vibration, which was
especially annoying if a game was doing a bunch of vibrations that were
supposed to be much shorter than that. Now we tell Android to vibrate
for 10 s, then cancel the vibration as soon as the game turns the
vibration off.
This fixes https://bugs.dolphin-emu.org/issues/14076. The issue report
more or less already says it all, but to provide a shorter summary:
We were fetching a list of vibrator IDs, but instead of passing the
vibrator ID to the vibrator manager, we passed the index of the ID in
the list. This happened to work fine on many devices, including all
devices that use DolphinVibratorManagerCompat, due to the only Vibrator
having both an index and ID of 0. But on some devices, it failed due to
the ID of the Vibrator being 1.
This fix makes us correctly pass the ID to the vibrator manager. We
still use indices in controller INI files, both for compatibility with
the controller mappings shipped with Dolphin (which use index 0) and for
backwards compatibility with older controller INI files.
Accomplished using `run-clang-tidy` with `performance-move-const-arg,performance-unnecessary-value-param,modernize-pass-by-value`.
Changed arguments to const references, removed them where inappropriate (e.g. sink parameters). Same with std::move.
Manually reviewed each change to make sure that it makes sense, and do something more appropriate if possible.
Previously, when an input device was connected or disconnected, we would
recreate all devices. This commit makes it so we only touch the relevant
device instead. This matters because recreating a device causes us to
drop all held buttons for that device. Due to Android only delivering
inputs as events, we're unable to poll for currently held buttons when
recreating a device.
This recently became a problem for users of Ayn devices due to a
firmware update. Every now and then, something about the display
viewports changes, triggering an update to an input device that I assume
is a touch input device. This input device isn't something users
normally map in Dolphin's controller settings, but it changing was
causing Dolphin to drop all held buttons for the device's built-in
gamepad as well as any other connected gamepads.
Yellow squiggly lines begone!
Done automatically on .cpp files through `run-clang-tidy`, with manual corrections to the mistakes.
If an import is directly used, but is technically unnecessary since it's recursively imported by something else, it is *not* removed.
The tool doesn't touch .h files, so I did some of them by hand while fixing errors due to old recursive imports.
Not everything is removed, but the cleanup should be substantial enough.
Because this done on Linux, code that isn't used on it is mostly untouched.
(Hopefully no open PR is depending on these imports...)