zaparoo-update
Rust and QML update UI package for Zaparoo Frontend hosts.
Package layout
The root package keeps the public zaparoo-update crate name and only contains
the frontend-facing facade API. It never includes or compiles
private/zaparoo-update-impl/.
The implementation source lives in private/zaparoo-update-impl/ as a separate
private crate. Local runtime builders compile that crate into binary/QML
artifacts, and the public facade plus runtime crates consume those artifacts in
the same shape production consumers use.
Runtime packages are scaffolded under runtime/. They contain only package
metadata and an artifacts/ layout for compiled shared libraries/QML plugin
files; they must not contain the private implementation source.
Current runtime package crates:
zaparoo-update-runtime-linux-armv7zaparoo-update-runtime-linux-x86_64zaparoo-update-runtime-windows-x86_64
Publish runtime crates before publishing the root facade crate. The root crate declares runtime crates as target-specific dependencies, so Cargo package verification for the facade expects the matching runtime package to be available from the registry for each published target.
With the private implementation source or binary runtime present, the crate
provides the Zaparoo.Update.Native CXX-Qt singletons plus packaged QML/CMake
assets for embedding the update screens into a host frontend. Hosts must
provide the documented QML host APIs, including Zaparoo.Update.Host and
Zaparoo.Theme.Sizing.
Host integration entrypoints
- Rust: call
zaparoo_update::init_runtime(tokio_handle)before showing the update QML. - QML: embed
Zaparoo.Update.UpdateScreenand provide the host modulesZaparoo.Update.HostandZaparoo.Theme. - CMake: include
cmake/ZaparooUpdate.cmakeand callzaparoo_update_add_qml_module()from the host build.
See examples/minimal-frontend for a small host with one Update button,
screensaver handling, CRT preview aliases, and launchers for mock and real
Downloader runs.
Local run entrypoints
Run these from the package root (../zaparoo-update) unless noted otherwise.
Mock Downloader UI run
Builds local desktop runtime artifacts, builds the desktop minimal frontend
against those artifacts, and runs it against ./mock-downloader.py. Useful for
UI work without touching real Downloader files.
CRT preview aliases are accepted:
Real Downloader local run
Builds the desktop minimal frontend and runs it against a local
../Downloader_MiSTer checkout. It creates ./.local_drv/, copies
../Downloader_MiSTer/downloader.ini there on first run, and points Downloader
at that directory for install state, downloaded files, and logs. This mirrors
Downloader's ./src/debug.py local_run setup.
Override paths when needed:
./.local_drv/ is git-ignored.
Local dylib runtime targets
These targets build dynamic runtime artifacts from the private source tree for
desktop development. They are non-default and write to build/ by default.
dylib-local-linux is intended to run on a Linux host. dylib-local-win is
intended to run on a Windows host with Rust, CMake, Ninja, and Qt available in
the environment. The default outputs are:
build/runtime-local-dylib/linux/artifacts
build/runtime-local-dylib/windows/artifacts
Common overrides:
Run the production-like frontend from WSL
This stages ../zaparoo-frontend under build/frontend-wsl-prod/, stages this
package as a facade-only zaparoo-update dependency, configures a Release
frontend build with ZAPAROO_DEV=OFF, and runs it against the platform
zaparoo-update-runtime-* crate resolved through Cargo/CMake.
The staged checkout is reused by default so Cargo/CMake incremental outputs are
kept between runs. Use --fresh-stage when you need to copy fresh changes from
../zaparoo-frontend or restage this facade package from scratch.
By default the script starts the frontend mock core and uses this repo's mock downloader so it can run locally in WSL. To keep the core endpoint untouched or use a local Downloader_MiSTer checkout:
Useful local checks:
MiSTer ARM32 entrypoints
Build the production frontend with this package
Builds ../zaparoo-frontend through its ARMv7/MiSTer Dockerfile while staging
this checkout as the zaparoo-update dependency. The default mode stages the
public facade files plus the runtime crate manifests/artifacts needed by Cargo,
while keeping private/ out of the Docker build context. That mode requires the
ARMv7 runtime crate artifacts to be populated first.
To explicitly build local ARMv7 runtime artifacts from the private source tree and then build the frontend through the facade-only context:
Deploy the production-like frontend to MiSTer
This runs the same facade/runtime-crate build as
./build-frontend-armv7.sh --build-local-runtime, then copies
build/frontend-mister-prod/output/frontend to
/media/fat/zaparoo/frontend and lets MiSTer_Zaparoo respawn it. Use
--build-only to stop before SSH deployment, or --skip-build to deploy an
already built binary.
This deploy helper defaults to the local MiSTer toolchain image and stable
staged Docker contexts under build/frontend-mister-prod/stage/, so repeated
runs can reuse Docker/Cargo build state. Use --fresh-stage to restage those
contexts, or --official-toolchain to use the GHCR toolchain image instead.
That path is intentionally non-default. It writes generated files into
runtime/zaparoo-update-runtime-linux-armv7/artifacts/.
Build minimal frontend for MiSTer
Uses the local Docker toolchain image
zaparoo/qt6-arm32-mister:<version> and writes:
examples/minimal-frontend/output/minimal_update_frontend
Deploy and run minimal frontend on MiSTer
Reads MISTER_IP and optional MISTER_PW from ./.env, deploys to
/tmp/zaparoo-update-minimal, stops the normal frontend wrapper while the
example runs, and starts the wrapper again on exit when available.
Common options:
By default deploy leaves the current MiSTer framebuffer/video mode unchanged.
Use --crt and --apply-vmode only when explicitly testing the CRT/native
writer path.
Direct mock stream entrypoint
Emits a DLP1 LTSV update stream for development and tests. The minimal mock
launcher wires this up automatically, so most UI work should use
run-mock.sh instead.
Event stream recording and playback
These debug hooks are inactive unless the env vars are explicitly set.
RECORD_EVENTS=/tmp/events.ltsv
PLAY_EVENTS=/tmp/events.ltsv
RECORD_EVENTS writes the raw update event stream to the target file, creating
or truncating it for each run. PLAY_EVENTS reads that stream back instead of
starting the downloader.