summaryrefslogtreecommitdiff
path: root/platforms/tortuise-script-compiled/src/input.rs
blob: a7d7340828938bb509330fff45806c5ae03aca4c (plain)
use serde::{Deserialize, Serialize};

use crate::ScriptContext;

/// Represents a key.
#[derive(Debug, PartialOrd, PartialEq, Eq, Clone, Copy, Hash, Serialize, Deserialize)]
pub enum KeyCode {
	/// Backspace key (Delete on macOS, Backspace on other platforms).
	Backspace,
	/// Enter key.
	Enter,
	/// Left arrow key.
	Left,
	/// Right arrow key.
	Right,
	/// Up arrow key.
	Up,
	/// Down arrow key.
	Down,
	/// Home key.
	Home,
	/// End key.
	End,
	/// Page up key.
	PageUp,
	/// Page down key.
	PageDown,
	/// Tab key.
	Tab,
	/// Shift + Tab key.
	BackTab,
	/// Delete key. (Fn+Delete on macOS, Delete on other platforms)
	Delete,
	/// Insert key.
	Insert,
	/// F key.
	///
	/// `KeyCode::F(1)` represents F1 key, etc.
	F(u8),
	/// A character.
	///
	/// `KeyCode::Char('c')` represents `c` character, etc.
	Char(char),
	/// Null.
	Null,
	/// Escape key.
	Esc,
}

pub type Position = tortuise::input::Position;
pub type Direction = tortuise::input::Direction;

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Button {
	// Action Pad
	South = 1,
	East = 2,
	North = 4,
	West = 5,
	C = 3,
	Z = 6,
	// Triggers
	LeftTrigger = 7,
	LeftTrigger2 = 9,
	RightTrigger = 8,
	RightTrigger2 = 10,
	// Menu Pad
	Select = 11,
	Start = 12,
	Mode = 13,
	// Sticks
	LeftThumb = 14,
	RightThumb = 15,
	// D-Pad
	DPadUp = 16,
	DPadDown = 17,
	DPadLeft = 18,
	DPadRight = 19,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Axis {
	LeftStickX = 1,
	LeftStickY = 2,
	LeftZ = 3,
	RightStickX = 4,
	RightStickY = 5,
	RightZ = 6,
	DPadX = 7,
	DPadY = 8,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum PowerInfo {
	Wired,
	Discharging(u8),
	Charging(u8),
	Charged,
	Unknown,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Gamepad(usize);

impl From<Button> for gilrs::Button {
	fn from(value: Button) -> Self {
		match value {
			Button::South => gilrs::Button::South,
			Button::East => gilrs::Button::East,
			Button::North => gilrs::Button::North,
			Button::West => gilrs::Button::West,
			Button::C => gilrs::Button::C,
			Button::Z => gilrs::Button::Z,
			Button::LeftTrigger => gilrs::Button::LeftTrigger,
			Button::LeftTrigger2 => gilrs::Button::LeftTrigger2,
			Button::RightTrigger => gilrs::Button::RightTrigger,
			Button::RightTrigger2 => gilrs::Button::RightTrigger2,
			Button::Select => gilrs::Button::Select,
			Button::Start => gilrs::Button::Start,
			Button::Mode => gilrs::Button::Mode,
			Button::LeftThumb => gilrs::Button::LeftThumb,
			Button::RightThumb => gilrs::Button::RightThumb,
			Button::DPadUp => gilrs::Button::DPadUp,
			Button::DPadDown => gilrs::Button::DPadDown,
			Button::DPadLeft => gilrs::Button::DPadLeft,
			Button::DPadRight => gilrs::Button::DPadRight,
		}
	}
}

impl From<Axis> for gilrs::Axis {
	fn from(value: Axis) -> Self {
		match value {
			Axis::LeftStickX => gilrs::Axis::LeftStickX,
			Axis::LeftStickY => gilrs::Axis::LeftStickY,
			Axis::LeftZ => gilrs::Axis::LeftZ,
			Axis::RightStickX => gilrs::Axis::RightStickX,
			Axis::RightStickY => gilrs::Axis::RightStickY,
			Axis::RightZ => gilrs::Axis::RightZ,
			Axis::DPadX => gilrs::Axis::DPadX,
			Axis::DPadY => gilrs::Axis::DPadY,
		}
	}
}

impl From<Option<gilrs::PowerInfo>> for PowerInfo {
	fn from(value: Option<gilrs::PowerInfo>) -> Self {
		match value {
			Some(gilrs::PowerInfo::Wired) => PowerInfo::Wired,
			Some(gilrs::PowerInfo::Discharging(p)) => PowerInfo::Discharging(p),
			Some(gilrs::PowerInfo::Charging(p)) => PowerInfo::Charging(p),
			Some(gilrs::PowerInfo::Charged) => PowerInfo::Charged,
			Some(gilrs::PowerInfo::Unknown) => PowerInfo::Unknown,
			None => PowerInfo::Unknown,
		}
	}
}

impl From<KeyCode> for crossterm::event::KeyCode {
	fn from(value: KeyCode) -> Self {
		match value {
			KeyCode::Backspace => crossterm::event::KeyCode::Backspace,
			KeyCode::Enter => crossterm::event::KeyCode::Enter,
			KeyCode::Left => crossterm::event::KeyCode::Left,
			KeyCode::Right => crossterm::event::KeyCode::Right,
			KeyCode::Up => crossterm::event::KeyCode::Up,
			KeyCode::Down => crossterm::event::KeyCode::Down,
			KeyCode::Home => crossterm::event::KeyCode::Home,
			KeyCode::End => crossterm::event::KeyCode::End,
			KeyCode::PageUp => crossterm::event::KeyCode::PageUp,
			KeyCode::PageDown => crossterm::event::KeyCode::PageDown,
			KeyCode::Tab => crossterm::event::KeyCode::Tab,
			KeyCode::BackTab => crossterm::event::KeyCode::BackTab,
			KeyCode::Delete => crossterm::event::KeyCode::Delete,
			KeyCode::Insert => crossterm::event::KeyCode::Insert,
			KeyCode::F(f) => crossterm::event::KeyCode::F(f),
			KeyCode::Char(c) => crossterm::event::KeyCode::Char(c),
			KeyCode::Null => crossterm::event::KeyCode::Null,
			KeyCode::Esc => crossterm::event::KeyCode::Esc,
		}
	}
}

impl Gamepad {
	pub fn is_button_pressed_this_frame(&self, context: &ScriptContext, button: Button) -> bool {
		context
			.0
			.input
			.is_button_pressed_this_frame(self.0, button.into())
	}

	pub fn is_button_released_this_frame(&self, context: &ScriptContext, button: Button) -> bool {
		context
			.0
			.input
			.is_button_released_this_frame(self.0, button.into())
	}

	pub fn is_button_down(&self, context: &ScriptContext, button: Button) -> bool {
		context.0.input.is_button_down(self.0, button.into())
	}

	pub fn axis_value(&self, context: &ScriptContext, axis: Axis) -> f32 {
		context
			.0
			.input
			.axis_value(self.0, axis.into())
			.unwrap_or_default()
	}

	pub fn is_connected(&self, context: &ScriptContext) -> bool {
		context.0.input.is_gamepad_connected(self.0)
	}

	pub fn power_info(&self, context: &ScriptContext) -> PowerInfo {
		context.0.input.gamepad_power_info(self.0).into()
	}
}

impl ScriptContext<'_> {
	pub fn is_key_pressed_this_frame(&self, key_code: KeyCode) -> bool {
		puffin::profile_function!();
		self.0.input.is_key_pressed_this_frame(key_code.into())
	}

	pub fn is_mouse_clicked_this_frame(&self) -> bool {
		puffin::profile_function!();
		self.0.input.is_mouse_clicked_this_frame()
	}

	pub fn mouse_location(&self) -> Option<Position> {
		puffin::profile_function!();
		self.0.input.mouse_location()
	}

	pub fn scroll_direction_this_frame(&self) -> Option<Direction> {
		puffin::profile_function!();
		self.0.input.scroll_direction_this_frame()
	}

	pub fn is_gamepad_connected_this_frame(&self) -> Option<Gamepad> {
		puffin::profile_function!();
		self.0.input.is_gamepad_connected_this_frame().map(Gamepad)
	}

	pub fn is_focused(&self) -> bool {
		puffin::profile_function!();
		self.0.input.is_focused()
	}

	pub fn was_focused_this_frame(&self) -> bool {
		puffin::profile_function!();
		self.0.input.was_focused_this_frame()
	}

	pub fn was_unfocused_this_frame(&self) -> bool {
		puffin::profile_function!();
		self.0.input.was_unfocused_this_frame()
	}
}