Skip to content

Commit

Permalink
add pen support
Browse files Browse the repository at this point in the history
  • Loading branch information
callmeclover authored May 16, 2024
1 parent 18a2a61 commit 2a248d3
Show file tree
Hide file tree
Showing 5 changed files with 232 additions and 63 deletions.
17 changes: 14 additions & 3 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#[allow(unused_imports)]
use dialoguer::{theme::ColorfulTheme, Confirm};
use std::{fs, path::Path};
use toml::{de::Error, from_str, to_string_pretty};
Expand Down Expand Up @@ -147,9 +148,6 @@ pub async fn get_options(config: Config) -> Vec<(&'static str, usize)> {
if config.basic.use_keyboard {
options.push(("keyboard", 50));
}
if config.basic.use_controller && cfg!(feature = "advanced") {
options.push(("gamepad", 50));
}
if config.basic.do_screenshots {
options.push(("screenshot", 1));
}
Expand All @@ -168,5 +166,18 @@ pub async fn get_options(config: Config) -> Vec<(&'static str, usize)> {
}
}

#[cfg(feature = "advanced")]
{
if config.basic.use_controller {
options.push(("gamepad", 50));
}
if config.basic.use_pen {
options.push(("pen", 15));
}
if config.basic.use_touch {
options.push(("touch", 10));
}
}

options
}
136 changes: 90 additions & 46 deletions src/func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,51 +85,6 @@ fn keyboard(enigo: &mut Enigo, rng: &mut rand::rngs::ThreadRng) {
}
}

#[cfg(feature = "advanced")]
fn gamepad(gamepad: &mut GamepadInjector, rng: &mut rand::rngs::ThreadRng) {
let lists: Vec<(Vec<(&str, usize)>, usize)> = vec![
(GAMEPAD_BUTTONS.to_vec(), 5),
(GAMEPAD_MOVE.to_vec(), 3),
(GAMEPAD_SPECIAL.to_vec(), 1),
];
let index: WeightedIndex<usize> =
WeightedIndex::new(lists.iter().map(|item: &(Vec<(&str, usize)>, usize)| item.1)).unwrap();
let list: &Vec<(&str, usize)> = &lists[index.sample(rng)].0;
let index2: WeightedIndex<usize> =
WeightedIndex::new(list.iter().map(|item: &(&str, usize)| item.1)).unwrap();
let action = list[index2.sample(rng)].0;
match action {
"LeftThumbstickMove" => {
gamepad.update_left_thumbstick((rng.gen_range(-1.0..=1.0), rng.gen_range(-1.0..=1.0)));
gamepad.inject();
thread::sleep(Duration::from_millis(rng.gen_range(0..=5000)));
gamepad.update_left_thumbstick((0.0,0.0));
}
"RightThumbstickMove" => {
gamepad.update_right_thumbstick((rng.gen_range(-1.0..=1.0), rng.gen_range(-1.0..=1.0)));
gamepad.inject();
thread::sleep(Duration::from_millis(rng.gen_range(0..=5000)));
gamepad.update_right_thumbstick((0.0,0.0));
}
"LeftTrigger" => {
gamepad.update_left_trigger(rng.gen_range(0.0..=1.0));
gamepad.inject();
thread::sleep(Duration::from_millis(rng.gen_range(0..=5000)));
gamepad.update_left_trigger(0.0);
}
"RightTrigger" => {
gamepad.update_right_trigger(rng.gen_range(0.0..=1.0));
gamepad.inject();
thread::sleep(Duration::from_millis(rng.gen_range(0..=5000)));
gamepad.update_right_trigger(0.0);
}
_=>{
gamepad.toggle_button(action);
}
}
gamepad.inject();
}

fn mouse(enigo: &mut Enigo, rng: &mut rand::rngs::ThreadRng) {
let lists: Vec<(Vec<(&str, usize)>, usize)> = vec![
(MOUSE_MOVE.to_vec(), 5),
Expand Down Expand Up @@ -287,14 +242,102 @@ pub async fn main_logic(options: &[(&str, usize)], tts: &mut Tts, enigo: &mut En
}

#[cfg(feature = "advanced")]
pub async fn main_logic_adv(options: &[(&str, usize)], tts: &mut Tts, enigo: &mut Enigo, gamepadobj: &mut GamepadInjector) {
{
fn gamepad(gamepad: &mut GamepadInjector, rng: &mut rand::rngs::ThreadRng) {
let lists: Vec<(Vec<(&str, usize)>, usize)> = vec![
(GAMEPAD_BUTTONS.to_vec(), 5),
(GAMEPAD_MOVE.to_vec(), 3),
(GAMEPAD_SPECIAL.to_vec(), 1),
];
let index: WeightedIndex<usize> =
WeightedIndex::new(lists.iter().map(|item: &(Vec<(&str, usize)>, usize)| item.1)).unwrap();
let list: &Vec<(&str, usize)> = &lists[index.sample(rng)].0;
let index2: WeightedIndex<usize> =
WeightedIndex::new(list.iter().map(|item: &(&str, usize)| item.1)).unwrap();
let action = list[index2.sample(rng)].0;
match action {
"LeftThumbstickMove" => {
gamepad.update_left_thumbstick((rng.gen_range(-1.0..=1.0), rng.gen_range(-1.0..=1.0)));
gamepad.inject();
thread::sleep(Duration::from_millis(rng.gen_range(0..=5000)));
gamepad.update_left_thumbstick((0.0,0.0));
}
"RightThumbstickMove" => {
gamepad.update_right_thumbstick((rng.gen_range(-1.0..=1.0), rng.gen_range(-1.0..=1.0)));
gamepad.inject();
thread::sleep(Duration::from_millis(rng.gen_range(0..=5000)));
gamepad.update_right_thumbstick((0.0,0.0));
}
"LeftTrigger" => {
gamepad.update_left_trigger(rng.gen_range(0.0..=1.0));
gamepad.inject();
thread::sleep(Duration::from_millis(rng.gen_range(0..=5000)));
gamepad.update_left_trigger(0.0);
}
"RightTrigger" => {
gamepad.update_right_trigger(rng.gen_range(0.0..=1.0));
gamepad.inject();
thread::sleep(Duration::from_millis(rng.gen_range(0..=5000)));
gamepad.update_right_trigger(0.0);
}
_=>{
gamepad.toggle_button(action);
}
}
gamepad.inject();
}

fn pen(pen: &mut PenInjector, rng: &mut rand::rngs::ThreadRng) {
let lists: Vec<(Vec<(&str, usize)>, usize)> = vec![
(GAMEPAD_BUTTONS.to_vec(), 5),
(GAMEPAD_MOVE.to_vec(), 3),
(GAMEPAD_SPECIAL.to_vec(), 1),
];
let index: WeightedIndex<usize> =
WeightedIndex::new(lists.iter().map(|item: &(Vec<(&str, usize)>, usize)| item.1)).unwrap();
let list: &Vec<(&str, usize)> = &lists[index.sample(rng)].0;
let index2: WeightedIndex<usize> =
WeightedIndex::new(list.iter().map(|item: &(&str, usize)| item.1)).unwrap();
let action = list[index2.sample(rng)].0;
match action {
"Pressure" => {
pen.update_pressure(rng.gen_range(0.0..=1024.0));
}
"Rotation" => {
pen.update_rotation(rng.gen_range(0.0..=359.0));
}
"Tilt" => {
pen.update_tilt((rng.gen_range(-90..=90), rng.gen_range(-90..=90)));
}
"XY_Move" => {
let display = Screen::from_point(0, 0).unwrap().display_info;
pen.update_position((rng.gen_range(0..=display.width), rng.gen_range(0..=display.height)));
}
"X_Move" => {
let display = Screen::from_point(0, 0).unwrap().display_info;
pen.update_position((rng.gen_range(0..=display.width), -1));
}
"Y_Move" => {
let display = Screen::from_point(0, 0).unwrap().display_info;
pen.update_position((-1, rng.gen_range(0..=display.height)));
}
_=>{
pen.toggle_button(action);
}
}
pen.inject();
}

pub async fn main_logic_adv(options: &[(&str, usize)], tts: &mut Tts, enigo: &mut Enigo, gamepadobj: &mut GamepadInjector, penobj: &mut PenInjector) {
let mut rng: rand::prelude::ThreadRng = thread_rng();

let index: WeightedIndex<usize> =
WeightedIndex::new(options.iter().map(|item| item.1)).unwrap();
match options[index.sample(&mut rng)].0 {
"keyboard" => keyboard(enigo, &mut rng),
"gamepad" => gamepad(gamepadobj, &mut rng),
"pen" => pen(penobj, &mut rng),
"touch" => todo!(),
"mouse" => mouse(enigo, &mut rng),
"quote" => quote(tts, &mut rng),
"screenshot" => screenshot(tts),
Expand All @@ -304,4 +347,5 @@ pub async fn main_logic_adv(options: &[(&str, usize)], tts: &mut Tts, enigo: &mu
}

sleep(Duration::from_millis(1500)).await;
}
}
22 changes: 21 additions & 1 deletion src/lists.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,8 @@ pub static QUOTES_STATEMENT: [(&str, usize); 9] = [
("do a flip!", 1)
];

#[allow(dead_code)]
{
/* Gamepad action lists */
pub static GAMEPAD_BUTTONS: [(&str, usize); 12] = [
("A", 3),
Expand Down Expand Up @@ -228,6 +230,24 @@ pub static GAMEPAD_SPECIAL: [(&str, usize); 4] = [
];

/* Pen action lists */
pub static PEN_BUTTONS: [(&str, usize); 3] = [
("Barrel", 1),
("Eraser", 1),
("Inverted", 1),
];

pub static PEN_MOVE: [(&str, usize); 2] = [
("XY_Move", 2),
("X_Move", 1),
("Y_Move", 1)
];

pub static GAMEPAD_SPECIAL: [(&str, usize); 4] = [
("Pressure", 1),
("Tilt", 1),
("Rotation", 1)
];

/* Touch action lists */

/* Touch action lists */
}
6 changes: 3 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@ async fn main() {
};

let mut enigo: Enigo = Enigo::new(&Settings::default()).unwrap();
#[cfg(feature = "advanced")]
let mut gamepad = GamepadInjector::new();

#[cfg(feature = "advanced")]
{
let mut gamepad = GamepadInjector::new();
let mut pen = PenInjector::new();
loop {
main_logic_adv(&options, &mut tts, &mut enigo, &mut gamepad).await;
main_logic_adv(&options, &mut tts, &mut enigo, &mut gamepad, &mut pen).await;
}
}
#[allow(unreachable_code)]
Expand Down
114 changes: 104 additions & 10 deletions src/model.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
use windows::Gaming::Input::GamepadButtons;
use windows::UI::Input::Preview::Injection::InjectedInputGamepadInfo;
use windows::UI::Input::Preview::Injection::InputInjector;
use windows::UI::Input::Preview::Injection::{
InputInjector,
InjectedInputGamepadInfo,
InjectedInputPenInfo,
InjectedInputPenButtons
};
use std::collections::HashMap;

pub struct GamepadInjector {
Expand Down Expand Up @@ -46,12 +50,12 @@ impl GamepadInjector {
if !self.abs_buttons.get(button).unwrap() {
self.abs_buttons.insert(button.to_string(), true);
let mut buttons = self.buttons();
buttons |= get_value_of_button(button);
buttons |= self.get_value_of_button(button);
self.update_buttons(buttons);
} else {
self.abs_buttons.insert(button.to_string(), false);
let mut buttons = self.buttons();
buttons |= get_value_of_button(button);
buttons |= self.get_value_of_button(button);
self.update_buttons(buttons);
}
}
Expand Down Expand Up @@ -80,13 +84,7 @@ impl GamepadInjector {
.InjectGamepadInput(&self.gamepad_state)
.unwrap();
}
}

impl Drop for GamepadInjector {
fn drop(&mut self) {
self.injector.UninitializeGamepadInjection().unwrap();
}
}

fn get_value_of_button(button: &str) -> GamepadButtons {
match button {
Expand All @@ -106,4 +104,100 @@ fn get_value_of_button(button: &str) -> GamepadButtons {
"RightShoulder" => GamepadButtons::RightShoulder,
_ => GamepadButtons(0u32)
}
}
}

impl Drop for GamepadInjector {
fn drop(&mut self) {
self.injector.UninitializeGamepadInjection().unwrap();
}
}

pub struct PenInjector {
pen_state: InjectedInputPenInfo,
injector: InputInjector,
abs_buttons: HashMap<String, bool>
}

impl PenInjector {
pub fn new() -> Self {
let abs_buttons: HashMap<String, bool> = HashMap::from([
("Barrel".to_string(), false),
("Eraser".to_string(), false),
("Inverted".to_string(), false),
]);
let injector: InputInjector = InputInjector::TryCreate().unwrap();
injector.InitializePenInjection(Default::default()).unwrap();
let pen_state = InjectedInputPenInfo::new().unwrap();
Self {
pen_state,
injector,
abs_buttons
}
}

pub fn buttons(&self) -> InjectedInputPenButtons {
self.pen_state.PenButtons().unwrap()
}

pub fn update_buttons(&mut self, buttons: InjectedInputPenButtons) {
let _ = self.pen_state.SetPenButtons(buttons);
}

pub fn toggle_button(&mut self, button: &str) {
if self.abs_buttons.contains_key(button) {
if !self.abs_buttons.get(button).unwrap() {
self.abs_buttons.insert(button.to_string(), true);
let mut buttons = self.buttons();
buttons |= self.get_value_of_button(button);
self.update_buttons(buttons);
} else {
self.abs_buttons.insert(button.to_string(), false);
let mut buttons = self.buttons();
buttons |= self.get_value_of_button(button);
self.update_buttons(buttons);
}
}
}

pub fn update_tilt(&mut self, tilt: (i32, i32)) {
let _ = self.pen_state.SetTiltX(tilt.0.clamp(-90, 90));
let _ = self.pen_state.SetTiltY(tilt.1.clamp(-90, 90));
}

pub fn update_rotation(&mut self, rotation: f64) {
let _ = self.pen_state.SetRotation(tilt.clamp(0.0, 359.0));
}

pub fn update_pressure(&mut self, pressure: f64) {
let _ = self.pen_state.SetPressure(pressure.clamp(0.0, 1024.0));
}

pub fn update_position(&mut self, position: (i32,i32)) {
let mut info = self.pen_state.PointerInfo().unwrap();
if !position.0==-1 { info.PixelLocation.PositionX = position.0; }
if !position.1==-1 { info.PixelLocation.PositionY = position.1; }
let _ = self.pen_state.SetPointer(info);
}

pub fn inject(&mut self) {
self.injector
.InjectPenInput(&self.pen_state)
.unwrap();
}

fn get_value_of_button(button: &str) -> InjectedInputPenButtons {
match button {
"Barrel" => InjectedInputPenButtons::Barrel,
"Eraser" => InjectedInputPenButtons::Eraser,
"Inverted" => InjectedInputPenButtons::Inverted,
_ => InjectedInputPenButtons(0u32)
}
}
}

impl Drop for PenInjector {
fn drop(&mut self) {
self.injector.UninitializePenInjection().unwrap();
}
}

0 comments on commit 2a248d3

Please sign in to comment.