zaparoo-update 0.1.0

Facade crate for the Zaparoo update UI/runtime integration
Documentation
zaparoo-update-0.1.0 has been yanked.

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-armv7
  • zaparoo-update-runtime-linux-x86_64
  • zaparoo-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.UpdateScreen and provide the host modules Zaparoo.Update.Host and Zaparoo.Theme.
  • CMake: include cmake/ZaparooUpdate.cmake and call zaparoo_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

./examples/minimal-frontend/run-mock.sh

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:

./examples/minimal-frontend/run-mock.sh --crt ntsc-320b
./examples/minimal-frontend/run-mock.sh --resolution pal-640

Real Downloader local run

./examples/minimal-frontend/run-real-downloader.sh

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:

./examples/minimal-frontend/run-real-downloader.sh --downloader-root ../Downloader_MiSTer
./examples/minimal-frontend/run-real-downloader.sh --local-dir ./.local_drv

./.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.

make dylib-local-linux
make dylib-local-win

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:

make dylib-local-linux BUILD_PROFILE=debug
make dylib-local-linux OUTPUT_DIR=/tmp/zaparoo-update-runtime

Run the production-like frontend from WSL

./run-frontend-wsl-prod.sh

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:

./run-frontend-wsl-prod.sh --real-core
./run-frontend-wsl-prod.sh --real-downloader ../Downloader_MiSTer

Useful local checks:

./run-frontend-wsl-prod.sh --build-only
./run-frontend-wsl-prod.sh --fresh-stage --build-only
./run-frontend-wsl-prod.sh --play-events /tmp/events.ltsv
./run-frontend-wsl-prod.sh --record-events /tmp/events.ltsv

MiSTer ARM32 entrypoints

Build the production frontend with this package

./build-frontend-armv7.sh

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:

./build-frontend-armv7.sh --build-local-runtime

Deploy the production-like frontend to MiSTer

./deploy-frontend-mister-prod.sh

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

./examples/minimal-frontend/build-arm32.sh

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

./examples/minimal-frontend/deploy-mister.sh

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:

./examples/minimal-frontend/deploy-mister.sh --skip-build
./examples/minimal-frontend/deploy-mister.sh --no-run
./examples/minimal-frontend/deploy-mister.sh --crt ntsc-320b --apply-vmode

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

./mock-downloader.py

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 ./examples/minimal-frontend/run-real-downloader.sh
PLAY_EVENTS=/tmp/events.ltsv ./examples/minimal-frontend/run-mock.sh

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.