{"id":49809822,"url":"https://github.com/anpeaco/dcsboards","last_synced_at":"2026-05-13T00:01:42.842Z","repository":{"id":357450460,"uuid":"1235526463","full_name":"anpeaco/DCSBoards","owner":"anpeaco","description":"A Windows always-on-top overlay for DCS World that turns a pile of static checklist PNGs into a voice-controlled, kneeboard overlay.","archived":false,"fork":false,"pushed_at":"2026-05-12T21:29:47.000Z","size":11619,"stargazers_count":0,"open_issues_count":5,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-12T21:30:18.019Z","etag":null,"topics":["dcs","dcsworld","flight-simulator","kneeboard","overlay","piper-tts","tts"],"latest_commit_sha":null,"homepage":"https://github.com/anpeaco/DCSBoards","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/anpeaco.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-11T12:10:07.000Z","updated_at":"2026-05-12T21:07:12.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/anpeaco/DCSBoards","commit_stats":null,"previous_names":["anpeaco/dcsboards"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/anpeaco/DCSBoards","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anpeaco%2FDCSBoards","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anpeaco%2FDCSBoards/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anpeaco%2FDCSBoards/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anpeaco%2FDCSBoards/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/anpeaco","download_url":"https://codeload.github.com/anpeaco/DCSBoards/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anpeaco%2FDCSBoards/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32961785,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-12T23:30:32.555Z","status":"ssl_error","status_checked_at":"2026-05-12T23:30:18.191Z","response_time":102,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dcs","dcsworld","flight-simulator","kneeboard","overlay","piper-tts","tts"],"created_at":"2026-05-13T00:01:02.220Z","updated_at":"2026-05-13T00:01:42.820Z","avatar_url":"https://github.com/anpeaco.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# DCS Kneeboard\n\nA Windows always-on-top overlay for DCS World that turns a pile of static\nchecklist PNGs into a voice-controlled, kneeboard overlay. Push a HOTAS\nbutton, say *\"next page\"* or *\"what section\"*, and the overlay reads the\nmatching checklist item aloud — entirely offline.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/screenshots/overview-clean.png\" width=\"380\" alt=\"Kneeboard overlay showing an F-16C Maverick checklist page with the current step highlighted in yellow.\"\u003e\n\u003c/p\u003e\n\n## What it does\n\n- **Reads checklists aloud** with WinRT TTS, item by item, with auto-advance.\n- **Voice commands** via local Whisper (`base.en`) — say *\"next\"*, *\"next page\"*,\n  *\"restart section\"*, *\"what section\"*, *\"settings\"*, etc.\n- **Push-to-talk** or **hot-mic toggle** — bind to any HOTAS button.\n- **All input is bindable** — keyboard, gamepad, HOTAS (FreeJoy, Cougar, Warthog, …).\n- **Click-through mode** so the window doesn't steal focus while flying DCS.\n- **Hot-reload** of kneeboard sources when the sibling generator rebuilds them.\n- **Tabs** — generator output, raw image folders, and DCS's native\n  Saved Games kneeboards in one window.\n- **Per-aircraft pages** with `{aircraft}` placeholders resolved against the\n  current module.\n- **100% offline at runtime** — no cloud STT, no telemetry.\n\n## Screenshots\n\n### The overlay\n\nThe window is chromeless by default — just the page and the highlighted\nchecklist item. Chrome fades in as you hover the edges, then fades back\nout. All controls also have keyboard / HOTAS / voice bindings, so you\nrarely need the mouse.\n\n| Default state | Hover top → title bar |\n| :---: | :---: |\n| ![Overview](docs/screenshots/overview-clean.png) | ![Chrome top](docs/screenshots/chrome-top.png) |\n\n| Hover bottom → nav buttons | Hover left → tab strip |\n| :---: | :---: |\n| ![Chrome bottom](docs/screenshots/chrome-bottom.png) | ![Chrome tabs](docs/screenshots/chrome-tabs.png) |\n\n### Settings + voice help\n\n| Settings panel | Voice command help |\n| :---: | :---: |\n| ![Settings](docs/screenshots/settings.png) | ![Voice commands](docs/screenshots/voice-commands.png) |\n\nSettings lists every action and its current binding; click any row and\npress a key or HOTAS button to rebind it. Test-mode flashes the matched\nrow on press so you can identify which button does what without firing\nthe action.\n\nThe voice-commands panel is self-documenting — every phrase the router\nmatches is shown grouped by the action it triggers, generated from the\nsame rules table that does the matching.\n\n## Quick start\n\n```powershell\n# Default build (no STT — push-to-talk records audio but doesn't transcribe).\ncargo run\n```\n\nTo enable speech-to-text via Whisper, you need LLVM + CMake on the build\nhost (one-time setup):\n\n```powershell\n# 1. Install LLVM (provides libclang.dll for bindgen)\nwinget install --id LLVM.LLVM\n\n# 2. Install CMake (whisper.cpp build system)\nwinget install --id Kitware.CMake\n\n# 3. Restart your shell so PATH picks up the new tools.\n\n# 4. Download a Whisper GGML model (~148 MB)\nInvoke-WebRequest `\n  -Uri \"https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base.en.bin\" `\n  -OutFile \"models/ggml-base.en.bin\"\n\n# 5. Build with the feature flag (first build compiles whisper.cpp — slow,\n#    subsequent builds are fast).\ncargo run --features whisper-stt\n```\n\nThe app prints the chosen model path on startup. If no model is found, STT\nsilently disables and the rest of the app keeps working.\n\n## Voice commands (excerpt)\n\n| Action | Examples |\n| --- | --- |\n| Next item | \"next\", \"next item\", \"okay\", \"go\", \"done\" |\n| Previous item | \"back\", \"previous\", \"go back\" |\n| Next page | \"next page\", \"page down\" |\n| Previous page | \"previous page\", \"page up\" |\n| Next heading | \"next heading\", \"next section\" |\n| Restart section | \"restart section\", \"from the top\", \"start over\" |\n| Read current section | \"what section\", \"where am I\" |\n| Play / pause | \"play\", \"pause\", \"read\" |\n| Repeat | \"repeat\", \"again\", \"say again\" |\n| Hot mic toggle | \"hot mic\", \"open mic\" |\n| Read notes toggle | \"more info on / off\" |\n| Click-through toggle | \"click through\", \"pass through\" |\n| Open settings | \"settings\", \"open settings\" |\n| Open voice commands | \"voice commands\", \"what can I say\" |\n| Cancel | \"cancel\", \"stop\", \"never mind\" |\n\nFull list lives in `src/voice_router.rs`; the in-app **Voice Commands**\npanel is generated from the same table.\n\n## Architecture\n\n```\n┌──────────────────────────────────────────────────────┐\n│ Slint UI (page Image + highlight Rect + chrome)      │\n└────┬─────────────────────────────────────────────────┘\n     │\n     ▼ (Rust)\n┌─────────────────┐  ┌─────────────────┐  ┌─────────────┐\n│ ChecklistCtrl   │  │ Voice Router    │  │ TtsEngine   │\n│   nav state     │  │ transcript→Act  │  │  WinRtTts   │\n└────┬────────────┘  └────────┬────────┘  └──────┬──────┘\n     │                        ▲                  │\n     ▼                        │                  ▼\n┌─────────────────┐  ┌────────┴────────┐  ┌─────────────┐\n│ PageStore       │  │ SttEngine       │  │ AudioCapture│\n│  PNG + sidecar  │  │  WhisperStt     │◀─┤  cpal + VAD │\n│  hot-reload     │  │  worker thread  │  │ 16 kHz mono │\n└─────────────────┘  └─────────────────┘  └─────────────┘\n        ▲                   ▲                    ▲\n        │                   │                    │\n┌───────┴────────┐  ┌───────┴──────────┐  ┌──────┴──────┐\n│ kneeboards     │  │ models/          │  │ default mic │\n│ generator out  │  │ ggml-base.en.bin │  │             │\n│ (sibling repo) │  └──────────────────┘  └─────────────┘\n└────────────────┘\n```\n\nVoice events flow:\n\n1. Audio capture runs on a cpal callback thread, accumulating samples in a\n   shared buffer.\n2. While **push-to-talk** is held (or **hot mic** is latched), the buffer\n   fills. On release / on detected silence the chunk is downmixed + resampled\n   to 16 kHz mono.\n3. The PCM is shipped via mpsc to a dedicated whisper worker thread.\n4. The transcript comes back over another mpsc; a UI-thread Timer drains it\n   and feeds it to the voice router.\n5. Matched actions are dispatched through the same path as keyboard/HOTAS\n   triggers, so voice and physical input share identical behaviour.\n\n## Project layout\n\n```\nDCSBoards/\n  src/\n    main.rs              # Slint UI + AppState + dispatch\n    actions.rs           # Action enum (single source of truth)\n    voice_router.rs      # transcript → Action mapping\n    input/               # bindings + gilrs poller\n    audio/               # cpal capture + VAD + rubato resample\n    stt/                 # whisper-rs wrapper (feature-gated)\n    tts/ (in main)       # WinRT speech synth + pronunciation map\n    tabs.rs              # tab registry, manifest loader, lazy page decode\n    config.rs            # config.toml schema (aircraft, tabs)\n    settings.rs          # settings.toml schema (per-user state)\n    overlay.rs           # Win32 WS_EX_TRANSPARENT click-through\n    watcher.rs           # notify hot-reload\n  models/                # whisper GGML models (gitignored)\n  pages-sample/          # sample F-16C kneeboards for dev\n  ui/                    # (reserved for future .slint splits)\n  scripts/               # capture-screenshot.ps1, etc.\n  docs/screenshots/      # README assets\n  CLAUDE.md              # architecture notes for AI assistance\n  SPEC.md                # authoritative design doc\n```\n\n## Configuration\n\nTwo files; **edit by hand**, no in-app editor for these.\n\n**`config.toml`** — static project config: aircraft list, tab definitions.\nShared via git (this file is checked in for the sample setup).\n\n```toml\n[[aircraft]]\nid = \"F-16C_50\"\nlabel = \"F-16C Viper\"\n\n[[tabs]]\nid = \"checklists\"\nlabel = \"Generated Checklists\"\nicon = \"clipboard-list\"\nsource.kind = \"generator\"\nsource.path = \"C:/path/to/kneeboards/output/{aircraft}\"\n\n[[tabs]]\nid = \"dcs\"\nlabel = \"DCS Kneeboards\"\nicon = \"plane\"\nsource.kind = \"dcs_kneeboards\"   # resolves to %USERPROFILE%/Saved Games/DCS/Kneeboard/{aircraft}\n```\n\n**`settings.toml`** — per-user state: window position, audio device,\nbindings, behaviour toggles. Gitignored. Auto-created on first run; delete\nto reset.\n\n**`pronunciation.toml`** — TTS abbreviation overrides (`PWR → POWER`,\n`FLCS → Flickus`, etc). Reload with F5 without restarting.\n\n## Bindings + voice phrases\n\nEvery Action is bindable to:\n- a **keyboard combo** — fires while window has focus\n- a **gamepad / HOTAS button** via `gilrs` — fires regardless of focus\n- a **voice phrase** — fires when transcribed from STT\n\nBindings are recorded by clicking a row in Settings ▸ BINDINGS and pressing\nthe desired key / button. Last-writer-wins on conflicts.\n\n## Defaults\n\n| Action | Default trigger |\n| --- | --- |\n| Next item | `Space` |\n| Previous item | `Backspace` |\n| Play / pause | `R` |\n| Next heading | `H` |\n| Previous heading | `Shift+H` |\n| Page down / up | `PageDown` / `PageUp` |\n| Toggle click-through | `Ctrl+Alt+K` |\n| Toggle visibility | `Ctrl+Alt+V` |\n| Reload pronunciation | `F5` |\n| Cancel / close panels | `Esc` |\n| Push-to-talk | *unbound — bind to a HOTAS trigger* |\n| Hot mic toggle | *unbound* |\n\n## Related project — kneeboards generator\n\nThe static pages this overlay consumes are produced by a sibling Node.js +\nPuppeteer build at `C:\\Users\\anpea\\OneDrive\\Documents\\DevProjects\\kneeboards`.\nIt reads markdown checklists, renders them to PNG via headless Chromium,\nand emits a sidecar JSON file per page with the structured item model and\nper-item bounding boxes — the contract this overlay relies on.\n\nThe overlay does **not** parse markdown itself. The sidecar JSON schema\nis the formal boundary between the two repos.\n\n## Out of scope (v1)\n\nmacOS / Linux, cloud STT/TTS, multiplayer / telemetry, in-app checklist\nediting, touch UI, modifying DCS, signed installer.\n\nSee `SPEC.md` for the full design and `CLAUDE.md` for the working notes.\n\n## Status\n\nActive development. The overlay is functional end-to-end: page rendering,\nTTS readout, push-to-talk and continuous hot-mic STT, voice routing, hot\nreload, click-through, persistent bindings. M9 (signed installer + auto-\nupdater) is the remaining gap before public release.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanpeaco%2Fdcsboards","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fanpeaco%2Fdcsboards","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanpeaco%2Fdcsboards/lists"}