diff --git a/src/input/combined_player_controller.rs b/src/input/combined_player_controller.rs new file mode 100644 index 0000000..bfdfa06 --- /dev/null +++ b/src/input/combined_player_controller.rs @@ -0,0 +1,169 @@ +use crate::{ + framework::{context::Context, error::GameResult}, + shared_game_state::SharedGameState, +}; + +use super::player_controller::PlayerController; + +#[derive(Clone)] +pub struct CombinedPlayerController { + controllers: Vec>, +} + +impl CombinedPlayerController { + pub fn new() -> CombinedPlayerController { + CombinedPlayerController { controllers: Vec::new() } + } + + pub fn add(&mut self, controller: Box) { + self.controllers.push(controller); + } +} + +impl PlayerController for CombinedPlayerController { + fn update(&mut self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult { + for cont in &mut self.controllers { + cont.update(state, ctx)?; + } + + Ok(()) + } + + fn move_up(&self) -> bool { + self.controllers.iter().any(|cont| cont.move_up()) + } + + fn move_down(&self) -> bool { + self.controllers.iter().any(|cont| cont.move_down()) + } + + fn move_left(&self) -> bool { + self.controllers.iter().any(|cont| cont.move_left()) + } + + fn move_right(&self) -> bool { + self.controllers.iter().any(|cont| cont.move_right()) + } + + fn prev_weapon(&self) -> bool { + self.controllers.iter().any(|cont| cont.prev_weapon()) + } + + fn next_weapon(&self) -> bool { + self.controllers.iter().any(|cont| cont.next_weapon()) + } + + fn shoot(&self) -> bool { + self.controllers.iter().any(|cont| cont.shoot()) + } + + fn jump(&self) -> bool { + self.controllers.iter().any(|cont| cont.jump()) + } + + fn map(&self) -> bool { + self.controllers.iter().any(|cont| cont.map()) + } + + fn inventory(&self) -> bool { + self.controllers.iter().any(|cont| cont.inventory()) + } + + fn skip(&self) -> bool { + self.controllers.iter().any(|cont| cont.skip()) + } + + fn strafe(&self) -> bool { + self.controllers.iter().any(|cont| cont.strafe()) + } + + fn trigger_up(&self) -> bool { + self.controllers.iter().any(|cont| cont.trigger_up()) + } + + fn trigger_down(&self) -> bool { + self.controllers.iter().any(|cont| cont.trigger_down()) + } + + fn trigger_left(&self) -> bool { + self.controllers.iter().any(|cont| cont.trigger_left()) + } + + fn trigger_right(&self) -> bool { + self.controllers.iter().any(|cont| cont.trigger_right()) + } + + fn trigger_prev_weapon(&self) -> bool { + self.controllers.iter().any(|cont| cont.trigger_prev_weapon()) + } + + fn trigger_next_weapon(&self) -> bool { + self.controllers.iter().any(|cont| cont.trigger_next_weapon()) + } + + fn trigger_shoot(&self) -> bool { + self.controllers.iter().any(|cont| cont.trigger_shoot()) + } + + fn trigger_jump(&self) -> bool { + self.controllers.iter().any(|cont| cont.trigger_jump()) + } + + fn trigger_map(&self) -> bool { + self.controllers.iter().any(|cont| cont.trigger_map()) + } + + fn trigger_inventory(&self) -> bool { + self.controllers.iter().any(|cont| cont.trigger_inventory()) + } + + fn trigger_skip(&self) -> bool { + self.controllers.iter().any(|cont| cont.trigger_skip()) + } + + fn trigger_strafe(&self) -> bool { + self.controllers.iter().any(|cont| cont.trigger_strafe()) + } + + fn trigger_menu_ok(&self) -> bool { + self.controllers.iter().any(|cont| cont.trigger_menu_ok()) + } + + fn trigger_menu_back(&self) -> bool { + self.controllers.iter().any(|cont| cont.trigger_menu_back()) + } + + fn trigger_menu_pause(&self) -> bool { + self.controllers.iter().any(|cont| cont.trigger_menu_pause()) + } + + fn look_up(&self) -> bool { + self.controllers.iter().any(|cont| cont.look_up()) + } + + fn look_down(&self) -> bool { + self.controllers.iter().any(|cont| cont.look_down()) + } + + fn look_left(&self) -> bool { + self.controllers.iter().any(|cont| cont.look_left()) + } + + fn look_right(&self) -> bool { + self.controllers.iter().any(|cont| cont.look_right()) + } + + fn update_trigger(&mut self) { + for cont in &mut self.controllers { + cont.update_trigger(); + } + } + + fn move_analog_x(&self) -> f64 { + self.controllers.iter().fold(0.0, |acc, cont| acc + cont.move_analog_x()) / self.controllers.len() as f64 + } + + fn move_analog_y(&self) -> f64 { + self.controllers.iter().fold(0.0, |acc, cont| acc + cont.move_analog_y()) / self.controllers.len() as f64 + } +} diff --git a/src/input/mod.rs b/src/input/mod.rs index c1901a5..f94a6d1 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -1,4 +1,5 @@ pub mod combined_menu_controller; +pub mod combined_player_controller; pub mod dummy_player_controller; pub mod gamepad_player_controller; pub mod keyboard_player_controller; diff --git a/src/settings.rs b/src/settings.rs index 364b3b5..518d04b 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -4,6 +4,7 @@ use crate::framework::filesystem::{user_create, user_open}; use crate::framework::gamepad::{Axis, AxisDirection, Button, PlayerControllerInputType}; use crate::framework::keyboard::ScanCode; use crate::graphics::VSyncMode; +use crate::input::combined_player_controller::CombinedPlayerController; use crate::input::gamepad_player_controller::GamepadController; use crate::input::keyboard_player_controller::KeyboardController; use crate::input::player_controller::PlayerController; @@ -256,14 +257,32 @@ impl Settings { match self.player1_controller_type { ControllerType::Keyboard => Box::new(KeyboardController::new(TargetPlayer::Player1)), - ControllerType::Gamepad(id) => Box::new(GamepadController::new(id, TargetPlayer::Player1)), + ControllerType::Gamepad(index) => { + let keyboard_controller = Box::new(KeyboardController::new(TargetPlayer::Player1)); + let gamepad_controller = Box::new(GamepadController::new(index, TargetPlayer::Player1)); + + let mut combined_player_controller = CombinedPlayerController::new(); + combined_player_controller.add(keyboard_controller); + combined_player_controller.add(gamepad_controller); + + Box::new(combined_player_controller) + } } } pub fn create_player2_controller(&self) -> Box { match self.player2_controller_type { ControllerType::Keyboard => Box::new(KeyboardController::new(TargetPlayer::Player2)), - ControllerType::Gamepad(id) => Box::new(GamepadController::new(id, TargetPlayer::Player2)), + ControllerType::Gamepad(index) => { + let keyboard_controller = Box::new(KeyboardController::new(TargetPlayer::Player2)); + let gamepad_controller = Box::new(GamepadController::new(index, TargetPlayer::Player2)); + + let mut combined_player_controller = CombinedPlayerController::new(); + combined_player_controller.add(keyboard_controller); + combined_player_controller.add(gamepad_controller); + + Box::new(combined_player_controller) + } } }