From 40f108547126a3402d2285fe7e3353f0afddb24d Mon Sep 17 00:00:00 2001 From: historia Date: Sun, 6 Sep 2026 13:35:35 -0400 Subject: initial commit --- README.md | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 README.md (limited to 'README.md') diff --git a/README.md b/README.md new file mode 100644 index 0000000..0094eb1 --- /dev/null +++ b/README.md @@ -0,0 +1,95 @@ +# vrising-cam + +Hold **Q / E** to rotate the camera in V Rising on Linux, by emulating the +game's "Rotate camera" gesture: holding the right mouse button while streaming +relative mouse motion. The emulation happens at the kernel level (uinput), so +it works the same on X11 and Wayland — verified on KDE Plasma Wayland with the +game running through plain Steam/Proton. + +Single-file, no services: the first run creates a `.venv` next to the script, +installs `evdev`, and re-executes itself inside it. The script only acts while +its process is running; `Ctrl+C` to stop, and the emulated right mouse button +is always released on exit (including on SIGTERM and crashes, via `atexit`). + +## Usage + +``` +./vrising-cam.py # hold Q = rotate left, hold E = rotate right +``` + +While running, the process watches your keyboard's `/dev/input/event*` nodes +for Q / E, presses the emulated right mouse button for as long as either key +is held, and emits relative X motion at a continuous rate. + +### Options + +| Flag | Meaning | +| --- | --- | +| `--speed N` | rotation speed in relative X units per second (default `2000`) | +| `--tick-ms N` | milliseconds between motion ticks (default `1.0`; lower = smoother, higher = lighter) | +| `--ease SECONDS` | ramp speed up over `SECONDS` on press and decay on release (`0` = off; try `0.15`) | +| `--invert` | swap the rotation direction of Q and E | +| `-v`, `--verbose` | log key presses/releases, RMB injection, measured motion rate | +| `--test-rmb [SECONDS]` | self-test: hold the injected RMB for `SECONDS` (default 3) and read events back from the kernel; no keyboard needed | +| `--check` | show detected keyboards, uinput and grab status, then exit | + +### Tuning the feel + +- **Smoothness** comes from the fractional accumulator: ticks deliver 0–1 unit + each at a fine cadence, so motion is progress-continuous instead of pulsing. + The default 1 ms tick keeps bursts at 0–1 unit practically throughout; bulge + the interval (e.g. `--tick-ms 50`) for a lighter pipeline if you ever need to. +- **Speed**: `--speed 1000` is a slow orbit; `3000+` is a fast spin. Because + motion is rate-continuous, `--speed` directly maps to how fast the camera + rotates. +- **Ease**: `--ease 0.15` gives short smoothstep accel after pressing and a + linear decay on key release (the emulated RMB stays held during the decay, + then releases). `--ease 0` (default) is instant — some people prefer that. + The previous caveat applies while tap-spinning: easing shapes hold-and-drag + feel, not button clicks. +- Q held together with E cancels out (no motion) but keeps the RMB hold. + +### CPU cost + +Idle the loop wakes 4×/s via `select`. While rotating, it wakes once per tick +(1000/s at the default 1 ms) plus one kernel write per emitted event — well +under 1% of one core on any modern machine. + +## Setup on Arch (KDE Wayland / X11 alike) + +1. Make `/dev/uinput` writable: + + ``` + echo 'KERNEL=="uinput", MODE="0660", GROUP="input", TAG+="uaccess"' | sudo tee /etc/udev/rules.d/70-vrising-cam.rules + sudo udevadm control --reload-rules && sudo udevadm trigger + sudo usermod -aG input $USER # log out and back in + ``` +2. Ensure the `uinput` module loads at boot: + + ``` + sudo modprobe uinput + echo uinput | sudo tee /etc/modules-load.d/uinput.conf + ``` +3. Run `./vrising-cam.py --check` — it should print `READY`: + `/dev/uinput` openable, your keyboards listed exposing Q+E, and no + "exclusively grabbed" warnings. + +## Troubleshooting + +- **No camera rotation at all** → run with `-v`: hold Q and watch for + `key: Q press` lines. No lines while rotating means some other process + exclusively grabbed your keyboard (`EVIOCGRAB`; remappers like + keyd/kanata/kmonad do this) — the script warns about that with `--check` + and `-v`. +- **Keys detected but desktop/game shows nothing** → run the self-test + `./vrising-cam.py --test-rmb`: if `kernel read-back: OK` still shows no + reaction on the desktop, get `sudo libinput debug-events` + (`sudo pacman -S libinput-tools` on current Arch) and watch for + `BTN_RIGHT` lines while the test runs. +- **Stop quickly** → `Ctrl+C` (or `kill`, also emulated) — the emulated RMB + is released in the `finally`/`atexit` path. + +## Files + +- `vrising-cam.py` — the whole program (single file by design) +- `.venv/` — auto-created next to the script on first run (git-ignored) -- cgit v1.2.3