#bindings #virtual #hid #gamedev #input

stickup

A modular input device abstraction layer with HID and virtual device support

4 releases

new 0.2.0 May 16, 2025
0.1.6 May 16, 2025

#408 in Game dev

Download history 53/week @ 2025-05-09

53 downloads per month

Custom license

19KB
287 lines

StickUp

๐Ÿš€ Launch Note (v0.1.4)
StickUp just quietly launched and already hit over 120 downloads in the first few hours โ€” huge thanks to everyone checking it out!
If youโ€™re using it for sim gear, custom controllers, or input visualization, Iโ€™d love to hear from you.
Feedback, questions, or contributions? โ†’ belegrade@belegrades.gg

Crates.io Downloads Join the Discord Buy Me a Coffee Follow on X


๐Ÿ” Security Note

The name stickup was previously used in 2023 for a malicious crate which has since been removed from crates.io. (I wasn't aware of this at the time of publishing.)

This version โ€” authored by Belegrade Studio โ€” is a clean and fully rewritten project, unrelated to the original.

  • โœ… No build.rs
  • โœ… No network activity
  • โœ… 100% open and auditable

Transparency and trust matter. You're welcome to inspect the source or reach out directly.


StickUp is a modular, high-performance input abstraction layer for Rust applications.
It handles physical and virtual devices with precision, persistence, and simplicity.

Created by Belegrade Studio. Part of the CelerisTech suite.


โœจ Features

  • ๐Ÿ”Œ Plug-and-play device management (hidapi + virtual devices)
  • ๐ŸŽฎ Clean Device trait: axis + button abstraction
  • ๐Ÿง  Persistent device identity โ€” robust rebinding & hotplugging
  • ๐Ÿ“‹ Snapshot state or stream real-time InputEvents
  • ๐Ÿ”ง Flexible BindingProfile system to map inputs to actions
  • โš™๏ธ Feature flags (hid, virtual) to tailor backend support
  • ๐Ÿ’ก Minimal dependencies. Built for tools, overlays, engines, and more.

๐Ÿ“ฆ Installation

stickup = { version = "0.1.4", features = ["hid", "virtual"] }

๐Ÿš€ Quick Start

use stickup::DeviceManager;

fn main() {
    let mut manager = DeviceManager::new();
    let snapshot = manager.snapshot();

    for (id, state) in snapshot.iter() {
        println!("Device: {}", id);
        for (axis, value) in &state.axes {
            println!("  Axis {} = {}", axis, value);
        }
        for (button, pressed) in &state.buttons {
            println!("  Button {} is {}", button, if *pressed { "pressed" } else { "released" });
        }
    }
}

๐Ÿงฌ Device Identity

StickUp assigns a stable fingerprint to each device based on its hardware signature:

vendor_id:product_id:serial_number
# Example: 044f:0402:ABCD1234

If the device provides a serial number, this ID is persistent across USB ports, reboots, and sessions โ€” perfect for rebindings, multi-device setups, and simulators.


๐Ÿ” Examples

Run with cargo run --example <name>:

  • poll: Print a snapshot of all connected device states
  • virtual_demo: Feed manual input into a simulated device

๐Ÿ› ๏ธ Optional Features

  • hid (enabled by default): HID device support
  • virtual: Simulated input devices

๐Ÿงญ Philosophy

StickUp isnโ€™t just about input. Itโ€™s about clarity, intentional systems, and persistent presence.
Built for tools that know what they're listening to.


๐Ÿ“œ License

Licensed under the Pact of the Amaranth Rite. See LICENSE for terms.
Inspired by the MIT license, with deeper philosophical roots.

This crate uses hidapi, licensed under MIT or Apache-2.0.


๐Ÿ’ฌ Connect

Dependencies

~1โ€“12MB
~92K SLoC