Settings has a Knock actions screen with Knock twice and Knock thrice
side by side. Each lists four actions, and one press picks one: switch
passthrough, switch the style, show or hide SteamVR's performance graph,
or do nothing. The defaults stay the same, and the lists mark them with
(default).
config.json stores the actions under knock_actions, keyed by kind and
count, so each kind of knock can have its own actions and a new count
needs no format change. The screen sets every kind the same. The
performance graph is the SteamVR setting perfcheck.perfGraphInHMD. The
tour still teaches the default actions.
Development builds read commands appended to
~/.config/knockthru/test-commands: open or close the panel, click a
panel pixel, press a button by name, feed a knock or a double or triple
knock, and save the panel as a PNG. Releases leave it out:
build-arm64.sh adds it only with KNOCKTHRU_TEST_HOOK=1, and the release
workflow never sets that. The host build always has it, so CI compiles it.
On the Frame it drove calibration, the bug report and its recording,
the factory reset and tour, and an update from 1.0.1 to a local
1.0.2-test release through Install and Restart.
Nothing referenced it, and it read only uncompressed CSV files while the
recordings are gzipped. detector_test with KNOCKTHRU_TEST_VERBOSE=1 prints
every knock in a recording.
run() was one 721-line function whose 15 lambdas shared its locals. It is
now an App class in app.cpp with one method per job: slow checks, panel
clicks, knocks, background jobs, and drawing. The shared SteamVR helpers,
pose sampling, haptics, the bug report, and install commands move to
their own files. main.cpp keeps the command-line commands.
Behavior is unchanged. The order of steps in the main loop is the same,
except that a finished recording is collected after the knocks of that
loop instead of before.
The version defaults in CMakeLists.txt, build-arm64.sh, and package.mjs
say 1.0.0, and so do the README's manual install and build examples.
The README's update GIF goes from 1.0.0 to 1.1.0, not 0.1.0 to 0.2.0.
The Reset label is too small to win an entry in the 127-color GIF palette,
so it came out mustard. An extra solid frame of the error red, seen only
by palettegen, gives it its own entry.
All three GIFs share one knock timeline: first knock at 0.5 s, 0.3 s
between knocks, and the action 0.4 s after the last knock. The knock
kinds and timing loops are both 2.4 s, so they stay in step.
Knocks move on eased keyframes: a small pull back, a speed-up into the
contact, a slowing rebound, and a settle with a slight overshoot. The
controllers swing from the wrist, bursts fly out behind them, and the
controllers buzz after the action. In the hero, the panel cross-fades and
the captions fade out, then rise in.
The timing strip now runs in real time with 0.1 s ticks. Its dots pop in,
labels fade in, the wait bracket grows with the playhead, and the strip
fades out before it loops.
The FrameDrop button moves into the second install step.
cad_sprites.py now traces the CAD the same way as the logo: a flat light
shape, a gap between the controller head and grip, the controls cut out,
and a blue thumbstick. The headset gets a gap around the visor and its
two front cameras cut out. The trace steps come from the logo work.
The headset knock now shows the left controller tapping the left side of
the headset. The hero and dashboard images pick up the new panel icon.
The README says how to pause or remove KnockThru, and ends with a line
about who it is made for.
scripts/cad_sprites.py renders the left and right Steam Frame controllers
and the headset core module from Valve's STEP files into shaded sprites in
images/cad/, in the panel's colors. readme_media.py places these sprites
in the hero and knock kinds animations instead of hand-drawn shapes.
The CAD is CC BY-NC-SA 4.0, so the sprites and the two GIFs that use them
carry that license. THIRD_PARTY_NOTICES.md and the README credits say so.
The README now opens with an animation of the dashboard panel reacting
to knocks, then covers install, how to knock, the dashboard tab, and
troubleshooting in plain words. Settings, SSH calibration, commands,
manual install, and build move into collapsed sections at the bottom.
scripts/readme_media.py makes the images: the hero and dashboard images
come from the real panel code through panel_preview --readme, and the
knock kinds and timing animations are drawn with Pillow. ffmpeg writes
the GIFs.
scripts/install.sh downloads the latest release ZIP named in the FrameDrop
manifest, checks its SHA-256, unpacks it to ~/KnockThru, adds it to the Steam
library, and runs knockthru --install. The release workflow attaches it.
The report card's QR code now opens a page on the Frame, over the local
Wi-Fi, with the whole report. One button copies it and opens the
prefilled GitHub form, where it goes in the Report box. The page also
offers the report as a download. It needs a random token in the path and
stops when the card closes or after 15 minutes. SteamOS's firewall opens
TCP 1024 to 65535, and the kernel picks the port from that range.
Without a network, the QR code opens the GitHub form directly, as before.
Report in Settings opens a card with a QR code. A phone held up to a lens
scans it and opens the bug form in .github/ISSUE_TEMPLATE/bug.yml, with
the KnockThru version, SteamVR version, and passthrough status filled in.
The full report still goes to ~/knockthru-report.txt.
Vendors nayuki/QR-Code-generator (MIT) to encode the code.
--update installs the latest GitHub release over the running one and
restarts it. It reads the FrameDrop manifest, checks the ZIP's SHA-256,
and renames each new file over the old one. The resident app has the same
check and install behind CheckUpdate and InstallUpdate, for the panel.
--report writes ~/knockthru-report.txt with the KnockThru and SteamVR
versions, registration state, settings, and the end of both logs.
--uninstall --purge also deletes ~/.config/knockthru and SteamVR's
vrappconfig file for KnockThru.
A missing Room View button now throws DashboardChanged. The passthrough
tile then says a Steam update moved the button, and the log records the
SteamVR version once.
A knock that turns passthrough on plays Steam's switch-on sound, and one that
turns it off plays the switch-off sound, like the Room View switch in the
quick settings. The style switch and the panel settings do the same, and the
calibration buttons play Steam's button sound. KnockThru plays the files from
the Steam install with pw-play, so it ships no audio. Set "sounds" to false
to turn them off.
Pick a kind, learn the knock, record single knocks, adjust sensitivity
on a notched slider, and try a double knock before saving. The knock
animations port the README timing and draw controllers and the headset
traced from the CAD sprites. The slider's middle notch keeps the old
60 percent rule. The tuning comes in a later change.
The tab has a passthrough button, a translucent or opaque switch,
switches to pause knocks, pick knock kinds, and turn knocks off in the
running game, and a calibration screen with step-by-step progress.
The panel draws into an RGBA image with stb_truetype and Noto Sans, and
shows it through two Vulkan textures that take turns. SetOverlayRaw made
the panel flash on every update. Calibration moved into a Calibrator
class shared by the panel and --calibrate. Panel changes write to the
user config.json. SteamVR also gets an app icon.
A SteamVR overlay app for the Steam Frame. A double knock (controllers
together, a controller on a surface, or a tap on the headset) turns Room
View on or off. A triple knock switches translucent and opaque.
Includes the knock detector with replay tests on recorded poses, the
debug port client for the Room View button, per-game blocklist,
calibration, haptics, install and autostart, and FrameDrop packaging.