Skip to content

Releases: EvilHumphrey/LegendCTL

LegendCTL v2.6.2

Choose a tag to compare

@github-actions github-actions released this 20 Jul 00:16

LegendCTL v2.6.2

Verification and localization release: profile Apply now checks its writes by read-back the way
Restore always has, and the app speaks Korean.

Apply now checks its writes by read-back

  • Applying a profile now reads back every readable value it writes and compares it against
    what was sent — the same post-apply verification Restore, Safe Import, and the inline deadzone
    flow already performed. Previously a profile Apply read-back-checked step size and lighting
    zones only; every other field's write was reported without a read-back check.
  • A per-field verification view. After any profile Apply, "Verification details" shows each
    field's write result and read-back outcome — matched, mismatched (with expected vs. observed),
    or could not verify. Write-only fields (like back-paddle bindings) can't be read back and are
    reported as sent, not verified.
  • The result line tells you which of three states you're in. All readable changes confirmed;
    some couldn't be verified (with the count); or a read-back mismatch — a mismatch is reported as
    fact, not softened. If the verification pass itself fails, the Apply now reports every written
    field as "could not verify" instead of showing an unqualified success — a write the app couldn't
    check is never presented as a confirmed one.
  • Counting honesty, checked adversarially. A field whose write failed is disclosed as a write
    failure — it is never counted among "written but couldn't be confirmed", and an Apply with any
    failed write never claims "all changes confirmed", even when a read-back happens to match a
    pre-existing value. (Three adversarial review rounds each caught and closed a distinct gap
    here before release.)
  • The trust surfaces state this scope consistently — the first-connect trust card, the
    About disclaimer, the Diagnostics trust panel, and the Trust Matrix "Applied changes" row all
    describe the same read-back behavior, in every shipped language. The "Applied changes" row still carries the muted
    "Verification policy" chip — it states the app's policy and is not per-apply evidence.

한국어 지원 — Korean UI

  • The full interface is now available in Korean (Settings → Language → 한국어): all 1,931
    interface strings, including every trust and verification surface. A native Korean reviewer
    confirmed the bounded core-terminology glossary (including the 프로필 form) — not a review of
    all 1,931 strings — and the trust-critical strings are byte-pinned by tests the same
    way the Simplified Chinese ones are, so their wording cannot drift silently.
  • The Korean UI font path explicitly registers the Hangul glyph ranges, and a real-render
    regression test guards sampled strings against missing-glyph (tofu) rendering.

Fixes

  • Startup crash with a VMware virtual machine active. Installed (windowed) builds could crash
    at startup while showing the VMware USB-passthrough notice, because the warning path wrote to a
    console stream that doesn't exist in windowed builds. Fixed with regression tests.
  • Diagnostics tabs no longer snap back to Status. Clicking a Diagnostics tab silently failed
    to record the selection (the UI library reports the selection differently in real use than the
    test double did), so the next refresh returned you to the Status tab — this is also why the
    first-run notice's "How to verify this" link landed on the wrong tab. Fixed app-wide, with a
    real-rendering regression test.

Same discipline

No new wrapper-written controller settings — the read-back verification only reads. No network
calls, nothing uploaded. Before publication, the asset-producing CI build passed the full
suite; the release build passed a real-hardware smoke including a Korean-locale pass and the
exact 한국어 language-picker label; and the release assets passed gh attestation verify.
The published assets carry GitHub build provenance you can verify with gh attestation verify.

LegendCTL is a standalone, unofficial configurator for the ZD Ultimate Legend — no official ZD app
required, local, no telemetry, no drivers, and honest about what it can and can't verify.

LegendCTL v2.6.1

Choose a tag to compare

@github-actions github-actions released this 17 Jul 21:35

LegendCTL v2.6.1

A point release focused on honesty wording and robustness on top of v2.6.0 — the Trust
Matrix now states exactly what a profile Apply does and doesn't read back, plus a wave of
under-the-hood hardening.

What's changed

  • The Trust Matrix "Applied changes" row is now labeled as policy, not evidence. It previously
    showed a green "Verified by read-back" chip no matter what — even before a controller was
    connected. It now carries a muted "Verification policy" chip and states the real, narrow
    scope: every write reports its outcome; the Restore, Safe Import and settled inline-deadzone
    flows run a final read-back comparison, and a profile Apply attempts read-back checks for step
    size and lighting zones only — successful writes to its other fields, including write-only
    ones like back-paddle bindings, are reported as sent, not verified. A write Windows reports as
    successful is not proof the controller stored the value.

  • Scoped wording on the other trust surfaces. The first-connect trust card, the Diagnostics
    trust panel, and the About screen's disclaimer now name the specific read-back paths — Restore,
    Safe Import, inline deadzone, and the attempted step-size/lighting checks — instead of implying
    every write is verified.

  • Simplified Chinese: localized support guides. The Firmware and Windows Stack support guides
    now render in Chinese for zh-CN users, matching the rest of the interface.

Robustness

  • HID read cancellation, hardened. Cancelling or recovering an in-flight read of the controller
    is now bounded and safe — a cancelled or stranded read can never be mistaken for a completed one,
    and a poisoned read handle is retired and reopened rather than reused.

  • Build self-verification. Release builds now carry a recorded manifest of the exact source
    files scanned at build time, and the in-app Trust Self-Check compares the shipped non-EXE payload
    files against it instead of reporting a clean result over nothing. The running EXE can't verify
    itself from inside — for that, the app points at the external gh attestation verify check.

Same discipline

No new wrapper-written controller settings, no network calls, nothing uploaded. Full suite green on
Python 3.13 / DearPyGui in the CI build that produced these assets, and the device-facing paths were
smoke-tested on real hardware before this cut. The release assets carry GitHub build provenance you
can verify with gh attestation verify.

LegendCTL is a standalone, unofficial configurator for the ZD Ultimate Legend — no official ZD app
required, local, no telemetry, no drivers.

LegendCTL v2.6.0

Choose a tag to compare

@github-actions github-actions released this 12 Jul 02:30

LegendCTL v2.6.0

This release is about making the app more honest about what it knows — a new provenance
surface, source labels on the values it shows, and a wave of trust-hardening fixes from an
independent adversarial review.

What's new

  • "What we know right now" provenance card (Diagnostics → Guidance). A live matrix that shows,
    for each fact about your controller — identity, firmware, active profile, settings, fingerprint —
    whether it was verified from the device, inferred locally, or unknown. It updates in place as you
    connect and disconnect, and it never claims a device read that didn't happen. (The card's
    "applied changes" row is a static statement of the app's verification policy — it is not
    per-apply evidence and does not track individual Applies.) A new "What we know now" link on Home
    and the Diagnostics status strip jumps you to it.

  • Firmware and active profile now populate — labeled by source. When the official ZD app's
    Controller Settings window is already open, LegendCTL can read four summary labels from it via
    Windows UI Automation and show them tagged "Official App UI". A value read this way can never
    render as "Verified from device" — the label is structural, not cosmetic. The right rail and Home
    now show the source alongside firmware and active profile, and keep a "(last read)" qualifier
    until a fresh read lands this connection.

  • Provenance in shared exports. Compatibility reports, share cards, and diagnostic bundles now
    label the firmware value's source (Official App UI / Controller Protocol / Manually entered /
    Not verified) instead of presenting it as a bare device-verified fact.

  • A shorter, honest first-run notice. The consent gate is now three factual lines plus the
    legal disclaimer, with a "How to verify this" link that opens the trust surfaces before you
    accept. It states plainly that settings are written when you act — via Apply, or the live controls
    that write immediately.

  • Simplified Chinese: localized settings choices. The Controller screen's vibration, trigger,
    and lighting choices now render in Chinese for zh-CN users, matching the rest of the interface.

Trust hardening (adversarial reviews, external and internal)

An independent external review of the public project and an internal multi-lens audit of this
release's changes found — and we fixed:

  • Restore-point contract made truthful. Safe Import now creates its checkpoint before it writes
    anything and aborts honestly if it can't; other changes that touch the device disclose when no
    restore point could be created rather than proceeding silently.
  • "Last applied" shows what was actually sent. When a controller can't confirm the 8-point
    sensitivity curve, LegendCTL applies the standard 3-point curve, says so in the result, and no
    longer records the richer curve as if it had been written.
  • Trust Self-Check fails closed. Its "no networking / no drivers" claims now require the scan to
    have actually run over real files; if it can't, it says so instead of reporting a clean result
    over nothing.
  • Durable local storage. Restore points, module records, and first-run data migration are now
    crash-safe: an interrupted write can never be mistaken for a completed one, and deleted data is
    never silently resurrected.

Same discipline

No new wrapper-written controller settings, no network calls, nothing uploaded. Full suite green on
Python 3.13 / DearPyGui in the CI build that produced these assets, and the device-facing paths were
smoke-tested on real hardware before this cut. The release assets carry GitHub build provenance you
can verify with gh attestation verify.

LegendCTL is a standalone, unofficial configurator for the ZD Ultimate Legend — no official ZD app
required, local, no telemetry, no drivers, and honest about what it can and can't verify.


Correction (2026-07-18): the provenance-card paragraph above originally listed "applied changes" among the facts shown as verified-from-device / inferred / unknown. That row states the app's verification policy and is not per-apply evidence; the wording now matches the corrected release notes in the repository.

LegendCTL v2.5.0

Choose a tag to compare

@github-actions github-actions released this 04 Jul 10:08

LegendCTL v2.5.0

A feature release built around knowing your hardware and finding your feet: LegendCTL now
collects a read-only model fingerprint of the connected controller (local-only, serial-free,
shared only if you paste it yourself), and the Home screen gains a "First steps" guide that
walks a new install from first read to first restore point — and gets out of the way once
you're set up.

  • Model fingerprint (read-only). The Trust Self-Check now shows a fingerprint of the
    connected device: VID/PID, HID usage page, report shape, interface inventory, and a SHA-256
    digest — the serial number is excluded by construction, and nothing is uploaded or written.
    The manual Compatibility Report includes the same fingerprint, so community reports can build
    a model corpus that makes future device support decisions evidence-based instead of guesswork.
    This is collection and honest display only: no gating, no behavior change, and the write
    paths are byte-for-byte the ones already shipped.
  • Home "First steps" guide. A fresh install now starts with a short guided card on Home:
    read your controller's settings, capture a restore point, know where the health check lives.
    The steps tick off live as you complete them — no navigating away and back — and once
    everything is done the card collapses to a single "First steps complete" row. Dismiss it and
    it stays dismissed across restarts.
  • Sharing surfaces hardened. The share-safe exports (Compatibility Report, Trust
    Self-Check) now escape angle brackets and backslashes too, so a crafted USB descriptor string
    can't smuggle formatting or HTML into a pasted GitHub issue.
  • Honesty around device swaps. The First steps card is scoped to the controller that earned
    it: plug in a different controller and the steps reflect that device, not its predecessor.
    The card also comes back correctly after a disconnect/reconnect on Home.
  • Chinese localization pass. A native-speaker review unified 35 drifted translations,
    fully translated the new fingerprint labels, and polished the First-steps wording; the legacy
    buttons screen's Back/Home labels are now properly localized. Regression-guarded so future
    drift gets caught.
  • Assorted hardening from an eight-lane pre-release review: partial fingerprint reads are
    retried rather than cached for the session, Win32 calls declare correct return types, and the
    test suite grew ordering-aware coverage for state that arrives after a screen builds.

No new wrapper-written controller settings, no network calls, nothing uploaded. Same release
discipline: full suite green on Python 3.13 / DearPyGui in the CI build that produced these
assets, and the fingerprint and First-steps
paths were smoke-tested on real hardware before this cut. This is also the first LegendCTL
release built and attested by CI — the release assets carry GitHub build provenance you can
verify with gh attestation verify.

LegendCTL is a standalone, unofficial configurator for the ZD Ultimate Legend — no official ZD
app required, local, no telemetry, no drivers, and honest about what it can and can't verify.

LegendCTL v2.4.1

Choose a tag to compare

@EvilHumphrey EvilHumphrey released this 03 Jul 07:03

LegendCTL v2.4.1

A fix release, and an honest self-correction: a reviewer's screenshot showed LegendCTL failing
to recognize his genuine ZD Ultimate Legend on Russian Windows — reads worked, but the app kept
him in the read-only "unrecognized controller" lane. The bug was ours, the report was exactly the
kind of evidence this project asks for, and v2.4.1 fixes it along with a batch of honesty
improvements around disconnects and partial reads.

  • Device recognition now works on every Windows language. Recognition used to parse the text
    output of a Windows system tool and keyed on its English field labels; on non-English Windows
    those labels are localized, so a real ZD Ultimate Legend fell back to the generic read-only
    XInput lane and writes stayed gated. Recognition now queries the Windows device API (SetupDi)
    directly — locale-independent by construction — and is regression-tested against Russian,
    German, and Chinese system configurations. If your controller was stuck "unrecognized" on a
    non-English system, this release is for you.
  • Unplugging is now visible immediately, everywhere. Disconnect used to be easy to miss: the
    header flipped while the screen you were on kept the last connected state until you navigated
    away. Now every built screen updates in place within a few seconds of the unplug, the activity
    feed logs "Controller disconnected.", and the stray "Detected …" line that could appear right
    after an unplug is gone.
  • Values that survive a disconnect say so. After an unplug, retained firmware and profile
    values are labeled "(last read)" instead of posing as live state — and if a different controller
    is plugged in, the retained values are cleared rather than attributed to the new device.
  • Partial reads are named, not silent. A settings read runs on a time budget; on a slow
    device the trailing fields (motion, back paddles, step size) could be skipped without a trace.
    The read status line now says how many fields were not read and suggests reading again.
  • Compatibility Report: firmware survives a disconnect. The report's firmware field now
    falls back to the last-read value when a live read isn't available, so a report generated
    after an unplug (or from a partially-read session) still pairs the model-level identity the
    report already carries (tail-redacted, never serials) with the firmware it was seen running.
  • A Home explainer text was corrected in both languages.

No new wrapper-written controller settings, no network calls, nothing uploaded — the write paths
are byte-for-byte the ones already shipped. Same release discipline: full suite green on
Python 3.12 / DearPyGui 2.3.1, and the recognition and disconnect paths were additionally
smoke-tested on real hardware (plug, read, apply, unplug, replug) before this cut.

LegendCTL is a standalone, unofficial configurator for the ZD Ultimate Legend — no official ZD
app required, local, no telemetry, no drivers, and honest about what it can and can't verify.

LegendCTL v2.4.0

Choose a tag to compare

@EvilHumphrey EvilHumphrey released this 02 Jul 22:50

LegendCTL v2.4.0

The same honest tool, with a layout that keeps the important state in view. v2.4.0 is about
context: on a wide window the app now shows a live context rail — device, connection,
firmware, active profile, pending changes, and the trust posture — beside a focused work column,
so you never lose track of what the app knows (and what it doesn't) while you work.

  • Adaptive context rail. Maximize the window (or widen it past ~1600px) and Home, Controller,
    Diagnostics, and Live Verify gain a right-hand rail with your device model, connection state,
    firmware, active profile, pending changes, and the standing trust line — plus one-click Read,
    Health Check, and Trust Self-Check. Narrow windows keep the familiar single-column layout; the
    rail only appears where it genuinely fits.
  • Home, reorganized around orientation. Home now leads with what LegendCTL is and what to do
    first: an orientation card (read first, verify live, then decide what to write), a compact
    device & profile status card, the trust front door, and a state-aware next step — connected and
    no-controller states each get honest, useful guidance.
  • Trust, one click from anywhere. The verify-it-yourself surfaces from v2.3.0 (Trust
    Self-Check, Compatibility Report, evidence card) are now front-door items: linked from Home,
    from the Diagnostics status tab, and from the context rail. A round of wording refinements also
    tightened several trust texts so each claim states exactly its scope — nothing broader, nothing
    vaguer.
  • Wider Live Verify workspace. On wide windows the live controller model gets a larger canvas
    and a proportionally scaled diagram — same behavior, same honest labels (it lights XInput
    output only, and says so).
  • Sticks first. Controller settings now open on the Sticks tab — the settings people
    actually come for — with the rest of the order unchanged in spirit: Buttons, Triggers,
    Vibration, Lighting, Motion, Profiles.
  • Launches as a normal window. The app no longer starts maximized; it opens as a regular
    centered window at its reference size (and sizes down to fit smaller displays). Maximize it
    whenever you want the rail layout.

Everything here is display/layout-only — no new wrapper-written controller settings, no network
calls, nothing uploaded, and the write paths are byte-for-byte the ones already shipped. Same
release discipline: full suite green on Python 3.12 / DearPyGui 2.3.1, including a real-window
layout budget check that now runs process-isolated for deterministic results.

LegendCTL is a standalone, unofficial configurator for the ZD Ultimate Legend — no official ZD
app required, local, no telemetry, no drivers, and honest about what it can and can't verify.

LegendCTL v2.3.0

Choose a tag to compare

@EvilHumphrey EvilHumphrey released this 30 Jun 22:37

LegendCTL v2.3.0

This release is about one idea: don't take our word for it — verify it yourself. LegendCTL
already claims to be local, driver-free, and honest about what it can and can't see; v2.3.0 turns
those claims into evidence you can check inside the app and share in a couple of clicks.

  • Trust Self-Check. A new Diagnostics panel that demonstrates the trust posture instead of
    just asserting it: it scans the shipped app for any networking code, confirms it installs no
    driver, virtual device, or background service, and shows where its local data lives — each row
    scoped honestly to "what this build does, this session," not a system-wide audit. One click
    copies the whole self-check as a shareable artifact.
  • Compatibility Report. An opt-in "Create Compatibility Report" flow that turns a local run
    into a share-safe, copy-pasteable packet — your controller variant, firmware, app version, and
    what you actually tested — aligned to the GitHub compatibility-report template, with a claim
    boundary that's clear it's self-reported evidence (not vendor certification, not a
    tournament/anti-cheat ruling). Paired with a new public compatibility matrix so reports
    accumulate into an honest, maintained ledger.
  • Shareable evidence card. Export a single self-contained page (HTML or Markdown) summarizing
    the trust posture, your device/config summary, the diagnostic-bundle privacy posture, and the
    claim boundary — screenshotable and pasteable, fully offline, with nothing uploaded.
  • Clearer live controller model. The Live Verify model's edge-lighting and labels were tidied
    for a cleaner read; behavior is unchanged — it still lights XInput output only, and says so.

Everything new here is opt-in, local, and display/export-only — no new wrapper-written controller
settings, no network calls, nothing uploaded. The diagnostic outputs scrub local paths and never
invent a claim the app can't back. Same release discipline: full suite green on Python 3.12 /
DearPyGui 2.3.1.

LegendCTL is a standalone, unofficial configurator for the ZD Ultimate Legend — no official ZD
app required, local, no telemetry, no drivers, and honest about what it can and can't verify.

LegendCTL v2.2.0

Choose a tag to compare

@EvilHumphrey EvilHumphrey released this 30 Jun 09:41

LegendCTL v2.2.0

This release makes the live controller view easier to understand — without pretending to know
more than XInput actually exposes — and lets you inspect a diagnostics bundle before you ever
share it.

The Live Verify model is redrawn and now offers three views — Front, Back, and Top — with a
side inspector you can drive by clicking a control on the model. As before, the live lights
reflect XInput output only: a remapped paddle and the button it's mapped to look identical,
and the UI says so rather than guessing.

  • Front / Back / Top controller views. The live model is redrawn closer to the real ZD
    Ultimate Legend, with smooth contours and three views you can switch between. The Top view
    shows the bumpers, triggers, and claws; the Back view shows the paddles. Live lights track
    XInput output, while source-only labels (paddles and claws) are marked as not-live, so
    nothing is implied that the device can't actually report.
  • Click the model to inspect a control. Selecting a control — on the model or in the list
    — opens an inspector with its identity, live output, and cached binding, plus an "Edit
    binding" link that jumps to the Buttons tab. Clicking a back paddle selects the paddle, not
    the button it happens to output.
  • On-device binding guide. A step-by-step guide explains how to assign or clear paddles
    and switch onboard profiles directly on the controller. It's clear about the boundary:
    LegendCTL can set a paddle from the Buttons tab, but it can't read paddle bindings back from
    the device — so press the paddle here to confirm the output.
  • Preview a diagnostics bundle before sharing. Exporting a diagnostics bundle now opens a
    preview that lists exactly what the archive contains and the privacy posture of each part,
    so you can inspect the scrubbed, local file before deciding to share it. Nothing is uploaded
    — the bundle is written to a folder you choose.
  • Safer shareable reports. Diagnostic text is scrubbed of local paths and written so
    special characters can't reformat the report when it's pasted elsewhere, and the open-folder
    action stays within a safe local target.

This update adds no new wrapper-written settings — the new surfaces are read-only displays plus
a local export preview. Same release discipline: full suite green on Python 3.12 /
DearPyGui 2.3.1.

LegendCTL is a standalone, unofficial configurator for the ZD Ultimate Legend — no official ZD
app required, local, no telemetry, no drivers, and honest about what it can and can't verify.

LegendCTL v2.1.0

Choose a tag to compare

@EvilHumphrey EvilHumphrey released this 29 Jun 04:26

LegendCTL v2.1.0

This release is about making your controller's real state visible — and honest about what
LegendCTL can and can't see.

The Buttons tab now shows your controller's actual current button bindings, read live from the
device, so you can see what's really remapped instead of a generic "unassigned". Where
LegendCTL genuinely can't read a value, it says so plainly rather than guessing.

  • See your real button bindings. The Buttons tab reads and displays the controller's
    current per-button mapping, and refreshes in place after you apply a remap in the app.
  • Honest paddle + profile display. Back paddles that LegendCTL can't read show
    "Not set in LegendCTL" — never a misleading "Unbound" — alongside a plain note on what
    it can and can't see. On-device profile slots are labeled Profile 1–4 (their names
    aren't readable over USB).
  • Back-paddle map. A new code-drawn diagram shows where each paddle (M1, M2, LM, RM, LK,
    RK) physically sits; selecting a paddle's row lights its spot. It's drawn from the official
    manual layout and labeled as a guide to your selection, not a device read.
  • Live controller visualizer. Live Verify now shows a code-drawn controller that lights up
    as you press buttons and triggers and tracks your sticks live — with an honest note that it
    reflects XInput output, not which physical control you pressed (a remapped paddle and its
    mapped button look the same to XInput).
  • Clearer "Profile: Not verified" status. A tooltip explains it's an informational
    active-slot indicator — your settings are unaffected — and how to confirm the slot.
  • Readable Device vs Profile. Settings now show human labels ("8000 Hz", "Not inverted",
    "Linear") instead of internal values, and the comparison defaults to showing only what
    changed.
  • Tidier Restore Points. Routine per-session auto-captures collapse behind a count with a
    one-click "Show all", so the meaningful safety captures stand out. Nothing is deleted —
    every restore point stays restorable.

This update adds no new wrapper-written settings — the new surfaces are read-only displays of
what's already on the device, and the bindings list never invents a button name for a mapping
kind LegendCTL doesn't model. Same release discipline: full suite green on Python 3.12 /
DearPyGui 2.3.1.

LegendCTL is a standalone, unofficial configurator for the ZD Ultimate Legend — no official ZD
app required, local, no telemetry, no drivers, and honest about what it can and can't verify.

LegendCTL v2.0.3

Choose a tag to compare

@EvilHumphrey EvilHumphrey released this 27 Jun 21:38

LegendCTL v2.0.3

LegendCTL gets its own look and a more forgiving live tester. The app accent is now the
LegendCTL blue, the About screen carries a radar mark drawn from the live deadzone visual,
and the in-app display name reads "LegendCTL" across the window title, status bar, About
panel, and first-run dialog.

The Live Verify tester now finds your controller on any XInput slot. It scans player slots
0–3, auto-selects the first connected pad and sticks to it, re-scans when a pad
disconnects, and adds an Auto / Player 1–4 override with a live "Active: Player N" readout.
On a multi-pad bench — common on a reviewer's desk — the ZD pad often enumerates as player
2–4, where the previous slot-0-only tester showed nothing.

Per-zone lighting now applies reliably. The apply path writes each lighting zone, reads it
back, and retries on a confirmed mismatch, fixing a silent-reject that could drop the
right-zone color on a profile apply.

This update adds no new wrapper-written settings: the lighting change makes an existing
write verify-and-retry, and the XInput change only widens which slot the read-only tester
reads. Same release discipline: full suite green on Python 3.12 / DearPyGui 2.3.1. A winget
manifest is included under packaging/winget/ for Windows Package Manager submission.

LegendCTL is a standalone, unofficial configurator for the ZD Ultimate Legend — no official
ZD app required.