63 Commits
Author SHA1 Message Date
BlackBearReloaded a26ba78822 Version 01.005.000: game folders, a Cheats list, speed limit, MihawkGen frame generation, graphics fixes (#261) 2026-10-17 23:31:34 -04:00
BlackBearReloaded 23e0424149 Add a Speed limit to Settings > Performance and to each game 2026-10-17 15:39:15 -04:00
BlackBearReloaded 488dbd515d Add an Update notices switch to Settings > Diagnostics 2026-10-17 15:38:38 -04:00
BlackBearReloaded 71633561e9 Download a game into its own folder in roms with its update and DLC 2026-10-17 15:30:54 -04:00
BlackBearReloaded 97ba2b09c2 Read a game folder's own post-processing presets and effects 2026-10-17 14:48:58 -04:00
BlackBearReloaded 3a5c9e6b0b List a game's cheats on their own, apart from its mods 2026-10-17 14:48:50 -04:00
BlackBearReloaded 47cce6bb7f Read games from one folder per game in roms, with their update and DLC
* Read games from one folder per game in roms, with their update and DLC beside them

* Describe game folders in roms in the install docs
2026-10-17 14:35:16 -04:00
BlackBearReloaded 8f392248f7 Version 01.004.000: post-processing, wallpapers, more free memory, shader caches kept between starts (#235) 2026-10-16 21:50:42 -04:00
BlackBearReloaded f6c0543f8e Post-processing: Eden's ReShade FX presets in Settings > Video and per game (#234)
* Post-processing: Eden's ReShade FX presets in Settings > Video and in a game's own settings

* Launcher texts: the appearance, wallpaper and launcher texts in every language

* Post-processing in the README, the settings guide and the changelog: where presets and effects go
2026-10-16 21:33:35 -04:00
kasobos67 6527177816 Launcher pack updates from a feed, and a cached library for packs (#223) 2026-10-16 19:58:06 -04:00
Baws Deep 36d742454d Wallpapers: an image of your own behind the launcher (#225) 2026-10-16 19:03:38 -04:00
Baws DeepandClaude Opus 4.6 e2263cd741 Feat/slate theme (#220)
* Slate polish: warning popup, accent saved, setup card over the Library

Warnings no longer draw inline under whatever card is on screen:
say() with a warning puts them in a centered dismissible popup drawn
last. Any button press closes it and the action carries on, so a
still-failing action simply shows it again. "Saved ..." messages stay
inline as before.

The accent choice is carried by preferences() again, so saves no
longer erase "launcher": { "accent": ... }. Switching themes clears
the accent together with the save and restores both if that save
fails. preferences_check roundtrips "ice", keeps an empty accent
absent, and rejects "ICE" or path tricks.

The setup-required card leaves the bottom-left: on Slate (top_nav) it
draws last, centered over the Library's panel on Home and Library, and
not at all on Multiplayer, Settings or About. Canopy keeps its old
place. The panel's geometry moves to layout so the card and the panel
share one source.

Also: Color::rgb is constexpr; THEMES.md documents the theme fields.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Clear the warning card when a screen or dialog changes

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-10-16 13:31:17 -04:00
BlackBearReloaded 629c8bb976 More free memory: guest memory taken where a game writes it, and Compact memory (#221) 2026-10-16 12:45:43 -04:00
BlackBearReloaded 368294ee4b Prepare v1.003.000 release and contributor notes (#214) 2026-10-15 21:30:45 -04:00
kasobos67andBlackBearReloaded 05f79da2da Add custom launcher support (#197)
* ...

* ...

* Isolate recovery picker drawing state and validate shared HUD fields

---------

Co-authored-by: BlackBearReloaded <blackbearreloaded@protonmail.com>
2026-10-15 09:47:16 -04:00
Tiang-88andBlackBearReloaded f0bb66087e Console memory: a memory layout per game (#167)
* Console memory: a memory layout per game

A mod that keeps a block of memory of its own asks the guest kernel how much
the game has and reserves from the answer, so one that wants more than the
standard 4 GiB stops the game before its first picture. Every session was
pinned to 4 GiB with no way to ask for more; "memory_layout" in the settings
file, for every game or for one, now reaches the emulator before the guest's
memory block is taken.

* Console memory: the size in Settings > Performance

The larger memory was only a settings-file value, so a game with a mod that
wants more than 4 GiB had to be set by hand - and any change on the
Performance page re-saved that block of the file without it, taking the
hand-written value back out again. The page now has a Memory row after the
seven switches: Left and right move over 4, 6 and 8 GiB, and it writes the
same "memory_layout" key the file holds and reads it back, so the menu and
the file are one thing and nothing between the two has to be kept in order.
A game can still have its own in the file, which comes first. The row needs
no new text: "Memory" is the overlay's word for it already, and the sizes
are numbers.

---------

Co-authored-by: BlackBearReloaded <blackbearreloaded@protonmail.com>
2026-10-15 09:35:38 -04:00
Tiang-88andBlackBearReloaded 4bceda100e Say the game's own resolution in the overlay (#203)
* Say the game's own resolution in the overlay

The overlay so far told what was sent to the display; a game's own picture
was only to be found by guessing. Overlay options > Resolution puts the size
the guest renders at next to the backend, before the frame rate, so a game
that scales its picture down in heavy scenes shows it as it happens.

The size is taken where the frame is handed to the display, a cropped layer
counted as the part shown, as frame generation's own GuestExtent counts it.
It is a new bit at the end of the field mask, so a stored mask keeps meaning
what it did; the piece is off on a console that has one until it is switched.

* Validate overlay preferences against supported HUD bits

---------

Co-authored-by: BlackBearReloaded <blackbearreloaded@protonmail.com>
2026-10-15 09:32:03 -04:00
Rockiu0andClaude a302cde87a Four fixes to Eden's own source, applied when make prepare extracts it (#191)
tools/eden-patches/*.diff are applied in name order to the pinned Eden
tree, each once: a patch that reverses cleanly is already in. One that
neither reverses nor applies was changed after an earlier version went
in, and the files it touches come back from the pinned archive first.

- 01 fast file reads: read-only files are served from recently read
  1 MiB blocks. Each system call on the console's storage costs about the
  same whatever its size, so a game's small reads no longer pay it each.
  Writable files keep stdio's buffered view, which has their unflushed
  writes.
- 02 cache storage per title: a cache storage request with title id 0
  means the current process, as switchbrew documents for save data.
  Otherwise every game's cache storage was one shared folder, and two
  games of one series writing the same file names read each other's GPU
  shader caches.
- 03 bounded shader local memory: an out-of-bounds local memory load reads
  zero and a store is dropped, both through word 0. The PS5 faults on
  scratch accesses outside the allocation, which killed the process when a
  game indexed a local array with -1 after its intro.
- 04 CPU reads without reactive flushing: plain CPU reads of GPU-cached
  pages download GPU-written data only when reactive flushing is on, as
  with fastmem, where such reads never trap. Without fastmem every read
  otherwise took the rasterizer caches' locks, one 4 KiB page at a time.

docs/BUILDING.md says that the fork now patches these files.

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-15 09:31:37 -04:00
BlackBearReloadedandBawsDeep 2163a20034 Slate theme and accent colour presets (#199)
Co-authored-by: BawsDeep <bjornmaass@gmail.com>
2026-10-14 22:13:07 -04:00
BlackBearReloaded 6aa4487f00 v1.002.000 notes: the FPS overlay as a system monitor (#163) 2026-10-13 23:14:16 -04:00
BlackBearReloaded 1870130540 Version 01.002.000: more free memory, PS5 Pro memory mode, vibration strength (#160) 2026-10-13 20:33:38 -04:00
BlackBearReloaded c1c6c1a76d Settings > Controls > Vibration strength (#159) 2026-10-13 20:30:39 -04:00
BlackBearReloaded 81dd47c856 Changelog and README: thanks to the people whose work is in v1.001.000 (#146) 2026-10-13 00:08:29 -04:00
BlackBearReloaded e35e6d6f8e No game is named in the README, the guides, the comments or the preview's samples (#145) 2026-10-12 23:48:16 -04:00
BlackBearReloaded 03ba4462ff Docs: the README's guides and its changelog move to docs/ (#144) 2026-10-12 23:44:07 -04:00
BlackBearReloaded 7a8e463b0d CI: main is built every night, not after every merge (#143) 2026-10-12 23:37:48 -04:00
BlackBearReloaded a00fd76d5d CI: main is built after every merge and twice a week, so a release's build starts from its caches (#142) 2026-10-12 23:35:59 -04:00
BlackBearReloaded d7f2764f8e Version 01.001.000: a new launcher, performance and memory, PS5 OpenGL SDK 1.0.2 (#141) 2026-10-12 23:15:52 -04:00
BlackBearReloaded c2b50141fd Local wireless multiplayer through Eden rooms (#101)
* Validate Eden room packets and add offline interoperability checks

* Bound proxy decompression and receive queues

* Add asynchronous room controller and cancellable connections

* Wire room settings and lifecycle into the launcher

* Bound outgoing room queues and test stalled peers

* Own room receive callbacks per proxy socket

* Support proxy polling and release sockets between games

* Retain guest sockets across descriptor changes

* Record offline qualification and freeze fresh candidates

* Record room server and read-only console preflight evidence

* Show room members and reported games in a scrollable list

* Document Tailscale capabilities and verify room rejection recovery

* Record remaining hardware validation prerequisites

* Record successful room transport over Tailscale

* Record verified console deployment for operator testing

* Use a supported keyboard type for masked password entry

* Remember room passwords and report connection failures

* Report ENet handshake errors and packet counts

* Parse numeric room addresses before invoking the resolver

* Record operator-confirmed PS5 room connection

* Use the room virtual interface for guest wireless networking

* Compose room interfaces with the native getifaddrs adaptation

* Exercise LDN discovery and peer connection through a real room

* Record PS5 Mario Kart wireless lobby validation

* Record live LDN traffic, recovery and Tailscale component validation

* Prepare official desktop reference and correct room interface guidance

* Record public room connection and native DNS failure

* Show multiplayer connection status on home and settings

* Make external Tailscale qualification optional

* Invalidate network compiler cache for generated room headers

* Use the pinned Boost version in multiplayer host checks

* Show room server ping in the game overlay

* Record verified ping overlay deployment to PS5

* Respect detailed logging settings for multiplayer diagnostics

* Make the room socket non-blocking on the console so the member loop can send the join request

* Add public room browser beside private multiplayer connection

* Keep multiplayer destination choice selectable while connected

* Record local public browser validation and deferred console test

* Explain multiplayer connection failures in a persistent UI panel

* Define idle-only multiplayer validation on console .40

* Record console .40 public directory and private room validation

* Update public room notes for PR publication

* Keep the saved private room on public joins, save the private form as typed, and harden the public room list

* Translate the multiplayer and public room texts in all 29 languages
2026-10-11 01:02:48 -04:00
BlackBearReloaded 351057fac0 Eden at 67bada77, with the port adapted to it (#104)
* Eden at 67bada77

* Patches Eden now carries itself are removed; sparse tables follow its new vector

* Emitter header anchors for Eden 67bada77

* Memory checks use the JIT callback that takes a size

* Development hooks follow the JIT callbacks that take a size

* GPU lifecycle follows Eden 67bada77

* Frame generation log lines follow Eden 67bada77

* alloca for the effect compiler Eden now builds

* NSO segments, ZBIC ones too, are decoded in place

* The NSO loader check knows the ZBIC branch

* The producer check declares the shutdown the worker file now defines

* A thread's context guard and the slab lock stay spin locks

* The sparse vector's page constants do not depend on initialization order

* The exclusive monitor check uses the Boost that Eden now fetches
2026-10-10 20:10:55 -04:00
BlackBearReloaded dfda8026d4 Update Lapy helper with target lifetime fix (#94) 2026-10-10 14:31:52 -04:00
BlackBearReloaded 2beb1b538c Eden back at 5f142c79, and the source tree follows the pinned revision (#100) 2026-10-10 14:14:11 -04:00
BlackBearReloaded 7d9303a1ad One place for the app's data: no second set in the sandbox, and game files out of the app's folder (#92) 2026-10-10 12:37:04 -04:00
BlackBearReloaded 75dc3a8383 Update Eden, the Vulkan tools, Mesa and the Payload SDK (#90)
* Vulkan driver: the latest PS5_Vulkan tools, with the Mesa and Payload SDK they build

* RADV display adaptation for the newer Mesa: a set of framebuffers per output size

* Eden at 67bada77 (pins only; the port is adapted in the next commits)
2026-10-10 12:05:04 -04:00
BlackBearReloaded 26805fdd86 Publish the ccache snapshot from its own workflow 2026-10-10 11:18:03 -04:00
BlackBearReloaded fb4d6ac156 Keep a ccache snapshot in the build-cache release (#80) 2026-10-10 10:04:21 -04:00
Baws DeepandBlackBearReloaded 4d10d79108 Adding my nix-shell as a simple way to provide a full build enviorment. (#75)
* Add nixshell

Simple shell.nix to provide a full build enviorment.

* Update Building docs

Include nix-shell

* Update Nix shell recommendation wording

Removed the word 'recommended' from the Nix shell section.

* Building docs: keep the loading screen tool as it is on main

---------

Co-authored-by: BlackBearReloaded <blackbearreloaded@protonmail.com>
2026-10-10 01:05:53 -04:00
BlackBearReloaded 0fc954c2d2 The loading screen is a progress bar with the steps of a game's start (#73)
* The loading screen names the step a game's start is at

* The loading screen is a progress bar with the steps of the start

* Loading screen: the lettering is read in one place

* Loading screen: one small table per glyph

* Loading screen: smaller lettering tables
2026-10-09 23:19:49 -04:00
BlackBearReloaded 75562aaf30 Release workflow: build on the ubuntu-24.04 runner itself, without a container (#67)
* Pin the audio helper header as it is since its comment changed

* Release workflow: build on the ubuntu-24.04 runner itself, without a container

* Release workflow: Meson where the build scripts look for it
2026-10-09 18:28:21 -04:00
BlackBearReloaded 5f73c18fed No more .ffpfsc image: the build makes the ZIP and SHA256SUMS only; a tag's run adds its files to a release without a ZIP and never replaces a published one 2026-10-08 20:14:45 -04:00
BlackBearReloaded c2c9773db8 Attest the release ZIP's build provenance in the workflow 2026-10-08 19:57:18 -04:00
BlackBearReloaded 96211d4ff2 Download sources and save sync: all languages, and fixes from the review (#35)
* Download sources and save sync: the menu texts in all 29 languages

* Download sources and save sync: fixes after review
2026-10-08 19:39:47 -04:00
b489af4f08 RomM integration: browse, download and play games from your server (#21)
* Download sources: games on the network in the Library, downloaded when wanted

A download source is a server in the network that has Switch games. Its games are
listed in the Library beside the ones on the console, with the sources that have them.
A source says what it knows of a game: its title ID, its ids at metadata providers
(several at once) and whether its name comes from such metadata. The same game on
several sources is one title, and a game already on the console is not offered again:
by title ID, then a provider id both have, then the normalised name, else the file
name. Cross downloads a game and starts it once
it is there, asking first which source when several have it; Square puts it in a
download queue, which goes on in the background and after the app was reopened. Nothing
is streamed: a game runs from its file in roms/, its updates and DLC go to updates/. A
download is written to .remote-downloads/ in the game files folder and, once all of
the game's files are complete, moved into place (a cancel never touches roms/ or
updates/); a stopped one resumes where it was, its last 4 MB fetched again. A game
a source has can be deleted from the console in its settings: the game and all of its
updates and DLC go, its save data and settings stay. Settings > Downloads shows the
sources and the queue.

The sources are set up in config/remote/sources.json. Each entry names its backend's
"type": a backend implements the Source interface (headless/remote/source.h) and is made
in backends.cpp; remote.cpp, the launcher and EdenServices only know that interface.
This commit has no backend yet. remote/http.c is HTTP for the backends that need it,
linked into the update check's libcurl object.

Settings has one category more, so the preview walks one row further to Language.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Download sources: a RomM backend

"type": "romm" in sources.json is a RomM server (https://github.com/rommapp/romm), with
its address and a client API token, or a user name and password. Its Switch games come
from the game list's pages with each ROM's files; RomM's file categories say what is the
game and what are its updates and DLC (manuals, mods and the like stay on the server);
its ids at the metadata providers RomM matched, its title ID when the server has the keys,
and whether RomM identified it tell the game apart. A
file is downloaded by its own id (/api/roms/<file id>/files/content/<name>), the endpoint
RomM's feeds use, and goes on from where it was (Range). A current RomM is assumed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Download sources: tests and preview pictures

tools/check-remote.py builds the download sources (headless/remote) with their RomM
backend on the host and runs headless/remote_check.cpp against tools/romm-mock-server.py,
a stand-in for the parts of RomM's API the backend uses: sign-in, pages of games with
their files' categories, covers, downloads by file id with Range, a server that ignores
Range, a slow download to stop and cancel. It checks which game is which (title IDs,
provider ids, normalised names, file names), one source and two (a game of another
file name on the second one is the same title, the same game queued from one of them
only, a source of an unknown type, a source taken out of sources.json), going on after a stop with a spoilt end, a cancel that leaves the
player's own updates alone, a server that pages fewer games than asked for, two copies
of a game on one source, the cleaning of .remote-downloads/ and the kept queue. make test runs it; it is skipped without
libcurl's headers.

The launcher preview's sample services have two sources, Home and Office, one game on
both, and the preview draws the new screens (80-98): the Library with games on the
sources, the download dialog, choosing a source, a failed download, Settings >
Downloads, and deleting a game from the console.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Download sources: written by the console's FTP server, covers, speed and status

Written by the app itself, a download slowed the drive down as the file grew
(65 MB/s at first, 2 MB/s after 2 GB) and stopped the menu for seconds per
frame. From a payload the same drive keeps its speed, so the app now hands
the bytes to an FTP server running on the console (ftpsrv, etaHEN's, ...)
over loopback: REST to go on at a byte, STOR to write (headless/remote/ftp.h).
Downloads need such a server; without one they fail and say so. sources.json
may name its port ("ftp_port", 2121 by default) and a sign-in. File names
with a line break are refused, so a source cannot send the server commands.
When the server stops taking a file (a full drive), the download fails with
what it said ("No space left on device"); what was written stays in
.remote-downloads/ to go on from once there is room.

- Crash: the free-space check called statfs, which the SDK's libc.a has as
  a raw system call that ends a title. The check is left out on the console.
- Library: a game downloaded from a source is that source's game by the
  file name it came as, before the title IDs: a server's title ID can be
  another than the console reads from the file (Super Mario Galaxy 2 on the
  test server), and the game was then listed twice.
- Library: it reads all of the console's games again only when a source's
  list changed or a cover came, not after every reading of an unchanged
  list (that rewrote every cover and could make the menu flicker).
- Covers: Eden builds stb_image for JPEG only, and RomM's covers are PNG
  ("the cover of ... cannot be read"). metadata_bridge.cpp has a reader of
  its own for both, private to it.
- Speed: measured by the download thread, shown in the download dialog and
  in Settings > Downloads; the time left comes from it. Game files are not
  asked for compressed, and libcurl takes them in pieces of up to 1 MB.
- Menu: a cancel no longer deletes gigabytes while holding the queue's lock
  (the download thread does it, also while a game runs), and the menu asks
  for covers without touching the drive.
- Log: download sources write only what went wrong (on this console every
  line is a write to the drive the menu may wait for).
- Settings > Downloads: says when the lists asked for are in (a message
  gives way to the buttons after 4 s: with one source no row can be moved
  to, which takes it away elsewhere), shows the FTP server's port, and
  without a source shows an example with a RomM server. German added for
  the new texts.
- README: the FTP server is named where download sources are.
- Tests: tools/ftp-mock-server.py writes as ftpsrv does; check-remote runs
  every download through it, plus a download without an FTP server, a full
  drive and a file name with a line break.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Download sources: backends by what they can do, RomM's server part on its own

Groundwork for more uses of a backend than downloads (the save data of a
profile next): a backend's type now says what it can be used for, and what
all uses of a RomM server share is a part of its own.

- backends.h: Backends() lists each type with what it makes, one column per
  use (for now: `source`, a download source; nullptr when its servers have
  no games to download). MakeSource moved here from source.h and says when a
  type cannot be a download source. A new use is a column and a Make... of
  its own.
- romm/romm_client.h: Romm::Client, made from an entry of any config file
  (its errors name that file): the address, the sign-in, a JSON GET, a file
  into memory, the platform's id and the list of games. NormalUrl and
  ParsePage moved with it.
- romm/romm_source.cpp: the download source is what is left: the cover and
  the file download, on top of Romm::Client. Nothing changes for sources.json.
- remote_check: the table, and a RomM entry read for another file.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Download sources: review fixes

- A download cancelled and queued again before its transfer stopped goes
  on instead of being dropped with its files.
- A cancel that comes once the game is all in place leaves it done: the
  Library reads its list again.
- The covers' paths are taken while the lock is held: Start sets the
  paths again while a list thread may still fetch covers.
- Settings > Downloads: a row the queue no longer has (a download that
  finished meanwhile) is not drawn from past its end; trying a failed
  download again moves the rows with the queue.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Download sources: a download's contents checked as they come

RomM does not hash Switch files (they are in its NON_HASHABLE_PLATFORMS),
so a download could only be told whole by its size. Now each file is
checked while its bytes stream to the console's FTP server, as Eden's
integrity check checks a game, with no keys needed and without reading
the file again afterwards.

- remote/stream_check: reads the file's layout from the stream itself
  (an NSP's PFS0, an XCI's header, root HFS0 and secure HFS0) and hashes
  each NCA with OpenSSL's SHA-256 as its bytes go by, against the half of
  the SHA-256 it is named after. The first 1 MB is kept for headers asked
  for after their bytes went by. A gap, an unknown layout, a header that
  points past any file or a file that is no NSP or XCI leaves it
  unchecked, not damaged.
- remote: each file's bytes go to a StreamCheck on their way to FTP. A
  download that goes on from where it was reads what its file has so far
  from the drive first (the queue shows it as verifying, up to where it
  goes on); a server that sends the whole file anyway starts the check
  again. A damaged file is deleted and the download fails saying so, so
  trying again downloads it again. What the FTP server writes is not
  read back.
- Launcher: "Checking the game files 45%" in the download dialog,
  "Checking 45%" in the Library and Settings > Downloads, with the
  progress bar. German added; the preview's Orbit Postman goes on from
  40% and is shot while checking (83b). README.
- remote_check: synthetic NSPs and XCIs fed in pieces, overlapping,
  restarted, with gaps, spoilt, with headers of absurd sizes and as no
  NSP; check-remote links libcrypto and is skipped without its headers.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Save sync: save-sync.json, and a game's save data in step with RomM

Each player profile can keep its save data on a server, apart from the
download sources: another server, or another user of the same one. This
is the part without the menu: the config file, the store's interface,
RomM's store and the sync itself.

- save-sync.json (save_sync_config.h): the app writes an entry for every
  profile and keeps it in step with them (added, renamed, removed, in
  their order); the player fills one in over FTP with a server's "type",
  "url" and sign-in. What the player wrote stays; a file that is not JSON
  is left alone and nothing syncs. eden-save-sync-check.
- remote/save_store.h: a save store, a backend's interface of its own
  beside the download sources'; Backends() has a column for it.
- remote/save_archive.h: a game's save folder as one zip with the title's
  folder at its top, as Argosy packs Eden's, and RomM's content hash of
  it (MD5 of "<name>:<MD5>" lines by name, MD5 from OpenSSL), told from
  the folder. A folder that cannot be read whole fails instead of being
  taken as less. Unpacking takes JKSV's zips and Mac zips (without
  __MACOSX/ and .DS_Store), keeps a zip of one folder of the game's own,
  and refuses entries outside the folder. miniz is built into the app.
- remote/save_sync.h: SyncSaveData finds the game on the store and tells
  which side changed by the save data, not by the server's times: the
  console keeps the content hashes of both sides from when they were last
  in step (synced.json), bound to the server, the user and the store's
  game. One side changed: it uploads or downloads; both, or no record:
  the player chooses, so save data changed offline is never replaced
  unasked. Replaced save data goes to a backup folder first, the last
  three of a game kept.
- remote/romm/romm_saves.cpp: RomM's save sync, RomM 5.0.0 or newer
  (Romm::kMinimumVersion; an older server is refused at each sync). The
  console is registered once as a device of the user; a game's save data
  is in the slot "autosave" of the emulator "eden", as Argosy keeps it;
  the server's state is read from /api/saves (RomM 5.3's negotiate only
  for the session, as it pairs other emulators' save data with the
  console's). A refused upload (409) is a conflict.
- romm_client: requests with a JSON body, uploads as a form field and
  downloads to a file, all stopped when the sync is; a refusal (403)
  names both causes, a wrong sign-in or the token's missing scope.
- remote/http: POST and PUT with a JSON body or a file as a form field; a
  redirect sends a POST again with its body.
- remote_check: the zips, RomM's times and versions, save stores made
  from entries.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Save sync: synced before a game starts and after it ended

- Launcher: a dialog while a game's save data is synced before it
  starts; the game starts when it is done. Circle goes back without the
  game (the sync stops, nothing more changes). When the server cannot
  be reached: Play anyway, Try again or Back.
- After a game, once the menu is back, its save data goes up with a
  notice at the top right, and is tried again on later starts until it
  worked (pending.json). "auto": false stops those too.
- Changed on both sides: a dialog asks which one stays (Keep this
  console's, Take the server's, Change nothing), with when each was
  saved and the device of the server's.
- A server older than the save sync takes says so in a dialog to
  confirm, with both versions (before a game: play anyway or not; after
  one: Understood, or a notice when another game is about to start).
- The sync runs on a thread of its own in EdenServices; a game's title
  ID is read there, so the menu never waits for a scan of the games.
- arc() moves to widgets for the sync dialog's spinner.
- Preview A0-A7; German added; README: Save sync.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Save sync: profiles paired by a QR code

Setting a profile's save sync up needs no FTP and no typing.

- remote/pairing.h: a backend's pairing (as RFC 8628): a code and the
  address to approve it at, then polled until approved, denied or
  expired, stopped when it is cancelled. RomM's: /api/auth/device/init
  and /token, approved on the server's /pair/device signed in as the
  profile's user; RomM makes a device of the console with a client API
  token bound to it, which the save sync then is (no second device).
- save_sync_config.h: SetEntry links or unlinks a profile's entry, the
  player's own fields kept.
- Settings > Save sync: each profile with its server and user; Cross
  pairs it with one of the download sources' servers that can pair
  (asked first when several can; the source's "platform" kept), Square
  twice unlinks it. The pairing dialog shows a QR code of the approval
  page (Project Nayuki's QR Code generator library,
  third_party/qrcodegen, MIT), the code, the address, the steps and how
  long the code works.
- Preview B0-B6; German added; README.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Checks: the download sources and the save sync against RomM and ftpsrv in Docker

tools/check-romm.py [version ...] starts, for each RomM version, RomM
and MariaDB on a free port of localhost with a library of fake Switch
games (laid out as real NSPs and XCIs), and ftpsrv (the console's FTP
server, built for Linux from a pinned commit) on the host's network
(its passive mode needs it); makes an admin and a player with client
API tokens, sets a cover in RomM, scans the library over RomM's socket
(the scan task cannot be started over REST), and runs
headless/romm_live_check.cpp against it; then takes it all down. By
default it checks kMinimumVersion (5.0.0), 5.3.1, and 4.9.0, which has
to be refused. make test runs it after check-remote.py; without Docker
it is skipped, ROMM_CHECK=0 skips it too.

romm_live_check:
- Download sources: sign-ins, the list kept, a cover, what is no game, a
  game of 400 MB stopped part way and gone on with by Range (seen
  reading what it had from the drive first) and compared byte for byte,
  a spoilt end, an NSP and an XCI spoilt on the drive found damaged,
  updates and DLC, a cancel, leftovers, no FTP server, two sources on
  one server, sources removed or moved, the kept queue.
- Save sync: two consoles and a phone (Argosy's API calls): uploads, a
  save of 150 MB with 400 files, a device deleted in RomM, the versions
  kept, Argosy's and JKSV's zips, another emulator's and slot's save
  data, both sides changed in both orders, backups, a slot emptied in
  RomM, a token without scopes, a server that does not answer, an older
  RomM refused at each sync, and pairing approved, denied and cancelled.

check-remote.py keeps what needs no server and, against the stand-ins,
only what a real RomM and ftpsrv do not show on demand: capped pages, a
server that cannot resume, metadata ids and title IDs, another file
name on a second source, a full drive. romm-mock-server.py serves the
list and files only. docs/BUILDING.md says how to run it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Sample names in the checks and comments: invented ones

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: BlackBearReloaded <blackbearreloaded@protonmail.com>
2026-10-08 19:15:47 -04:00
v0ltfaultandClaude Fable 5.1 e3d6fead59 PS5 firmware 7.40: every game session ended at its first draw (#28)
* PS5 firmware 7.40: no mprotect on the macro path, lld 18 weak imports

On firmware 7.40 an app that is not jailbroken cannot mprotect(RX) memory, so
the GPU macro JIT's first compile ended every game session with xbyak's
"can't protect" (OpenGL then also reports the guest's 2010-0212 abort during
teardown). The CPU JIT is unaffected because it writes through a separate RW
alias. Run the few non-HLE macros through the interpreter on the PS5 build
instead: no executable memory on that path.

lld 18 exports undefined weak symbols from executables (lld 21+ no longer
does), and Mesa's entrypoint tables reference thousands of optional driver
entrypoints weakly, which the native packager then rejects. --no-dynamic-linker
is lld 18's switch for that; it is redundant on newer lld.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VCGd2KgMjDTQnfiHzJbrxx

* docs: firmware 7.40 report and ubuntu-24.04 build notes

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VCGd2KgMjDTQnfiHzJbrxx

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-08 12:37:20 -04:00
BlackBearReloaded 026851f5ac Release build: the cached driver comes with the SDK the final link uses 2026-10-07 22:42:00 -04:00
BlackBearReloaded 74bfc015e4 Release build: main is built by hand, pull requests and tags build by themselves 2026-10-07 22:18:07 -04:00
BlackBearReloaded f98e50069a Release build on a GitHub-hosted runner: main, pull requests and tags, ZIP checked and kept as an artifact 2026-10-07 21:38:46 -04:00
BlackBearReloaded c4b9c1ff93 Build workflow and link flags as before the forwarder change (#22) 2026-10-06 22:06:41 -04:00
Martin PhamandMartin Pham 264850746b Adding ROM Path argument to support forwarders (#13)
* params

* no message

* no message

---------

Co-authored-by: Martin Pham <i@mph.am>
2026-10-06 21:59:07 -04:00
BlackBearReloaded 10b16269e3 Lapy helper: SDK v0.42 and firmware 13.60 fix (#17) 2026-10-06 09:28:22 -04:00