when osu sound i guess

feat: held keys

ptr.pet 7d4e376a db9a0090

verified
Changed files
+59 -17
src
+59 -17
src/main.rs
··· 1 1 #![windows_subsystem = "windows"] 2 2 3 - use std::sync::mpsc; 3 + use std::collections::HashSet; 4 4 use std::{collections::HashMap, time::Duration}; 5 5 6 - use device_query::{DeviceEvents, DeviceEventsHandler, Keycode}; 6 + use device_query::{DeviceState, Keycode}; 7 7 use quad_snd::{AudioContext, Sound}; 8 8 9 9 fn main() { ··· 25 25 let sound = sounds.get(name).unwrap(); 26 26 sound.play(&ctx, Default::default()); 27 27 }; 28 + let play_sound_for_key = |key: Keycode| match key { 29 + Keycode::CapsLock => play_sound("caps"), 30 + Keycode::Delete | Keycode::Backspace => play_sound("delete"), 31 + Keycode::Up | Keycode::Down | Keycode::Left | Keycode::Right => play_sound("movement"), 32 + _ => { 33 + let no = fastrand::u8(1..=4); 34 + play_sound(&format!("press-{no}")); 35 + } 36 + }; 28 37 29 - let (tx, rx) = mpsc::channel(); 38 + let state = DeviceState::new(); 39 + let mut previously_held_keys = HashSet::<Keycode>::new(); 40 + let mut key_press_times = HashMap::<Keycode, std::time::Instant>::new(); 41 + let mut last_sound_time = std::time::Instant::now(); 30 42 31 - let query = DeviceEventsHandler::new(Duration::from_millis(10)).expect("already running"); 32 - let _guard = query.on_key_down(move |key| { 33 - tx.send(*key).expect("tx"); 34 - }); 43 + let initial_delay = Duration::from_millis(500); // Wait 500ms before starting to repeat 44 + let repeat_interval = Duration::from_millis(50); // Then repeat every 50ms 35 45 36 46 loop { 37 - if let Ok(key) = rx.recv() { 38 - match key { 39 - Keycode::CapsLock => play_sound("caps"), 40 - Keycode::Delete | Keycode::Backspace => play_sound("delete"), 41 - Keycode::Up | Keycode::Down | Keycode::Left | Keycode::Right => { 42 - play_sound("movement") 47 + let currently_held_keys: HashSet<Keycode> = state.query_keymap().into_iter().collect(); 48 + 49 + // Track when keys were first pressed 50 + for key in &currently_held_keys { 51 + if !previously_held_keys.contains(key) { 52 + // Key just pressed, record the time and play initial sound 53 + key_press_times.insert(*key, std::time::Instant::now()); 54 + play_sound_for_key(*key); 55 + } 56 + } 57 + 58 + // Remove timing info for released keys 59 + key_press_times.retain(|key, _| currently_held_keys.contains(key)); 60 + 61 + // Play repeating sounds every 50ms, but only after initial delay 62 + if last_sound_time.elapsed() >= repeat_interval { 63 + let now = std::time::Instant::now(); 64 + for key in &currently_held_keys { 65 + if matches!( 66 + key, 67 + Keycode::LShift 68 + | Keycode::RShift 69 + | Keycode::LControl 70 + | Keycode::RControl 71 + | Keycode::RAlt 72 + | Keycode::LAlt 73 + | Keycode::RMeta 74 + | Keycode::LMeta 75 + | Keycode::CapsLock 76 + ) { 77 + continue; 43 78 } 44 - _ => { 45 - let no = fastrand::u8(1..=4); 46 - play_sound(&format!("press-{no}")); 79 + if let Some(press_time) = key_press_times.get(key) { 80 + // Only repeat if key has been held longer than initial delay 81 + if now.duration_since(*press_time) >= initial_delay { 82 + play_sound_for_key(*key); 83 + } 47 84 } 48 85 } 86 + last_sound_time = now; 49 87 } 50 - println!("handling new event"); 88 + 89 + previously_held_keys = currently_held_keys; 90 + 91 + // Buffer inputs at lower interval (5ms) 92 + std::thread::sleep(Duration::from_millis(5)); 51 93 } 52 94 }