1
0
Fork 0
mirror of https://github.com/doukutsu-rs/doukutsu-rs synced 2025-07-18 10:02:20 +00:00

make controller selection its own menu

This commit is contained in:
Sallai József 2022-08-06 14:07:00 +03:00
parent 4cfbcc50ac
commit 1883045f75
3 changed files with 119 additions and 111 deletions

View file

@ -136,7 +136,7 @@
"player_2": "Player 2" "player_2": "Player 2"
}, },
"controller": { "controller": {
"entry": "Controller:", "entry": "Controller...",
"keyboard": "Keyboard" "keyboard": "Keyboard"
}, },
"rebind": "Rebind...", "rebind": "Rebind...",

View file

@ -128,7 +128,7 @@
"player_2": "プレーヤー 2" "player_2": "プレーヤー 2"
}, },
"controller": { "controller": {
"entry": "コントローラ", "entry": "コントローラ",
"keyboard": "キーボード" "keyboard": "キーボード"
}, },
"rebind": "再バインド", "rebind": "再バインド",

View file

@ -31,23 +31,37 @@ const FORBIDDEN_SCANCODES: [ScanCode; 12] = [
#[derive(PartialEq, Eq, Clone, Debug)] #[derive(PartialEq, Eq, Clone, Debug)]
#[repr(u8)] #[repr(u8)]
enum CurrentMenu { enum CurrentMenu {
ControllerMenu, MainMenu,
SelectControllerMenu,
RebindMenu, RebindMenu,
ConfirmRebindMenu, ConfirmRebindMenu,
ConfirmResetMenu, ConfirmResetMenu,
} }
#[derive(Debug, Clone, Copy, Eq, PartialEq)] #[derive(Debug, Clone, Copy, Eq, PartialEq)]
enum ControllerMenuEntry { enum MainMenuEntry {
SelectedPlayer, SelectedPlayer,
Controller, Controller,
Rebind, Rebind,
Back, Back,
} }
impl Default for ControllerMenuEntry { impl Default for MainMenuEntry {
fn default() -> Self { fn default() -> Self {
ControllerMenuEntry::SelectedPlayer MainMenuEntry::SelectedPlayer
}
}
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
enum SelectControllerMenuEntry {
Keyboard,
Gamepad(usize),
Back,
}
impl Default for SelectControllerMenuEntry {
fn default() -> Self {
SelectControllerMenuEntry::Keyboard
} }
} }
@ -133,7 +147,8 @@ impl ControlEntry {
pub struct ControlsMenu { pub struct ControlsMenu {
current: CurrentMenu, current: CurrentMenu,
controller: Menu<ControllerMenuEntry>, main: Menu<MainMenuEntry>,
select_controller: Menu<SelectControllerMenuEntry>,
rebind: Menu<RebindMenuEntry>, rebind: Menu<RebindMenuEntry>,
confirm_rebind: Menu<usize>, confirm_rebind: Menu<usize>,
confirm_reset: Menu<ConfirmResetMenuEntry>, confirm_reset: Menu<ConfirmResetMenuEntry>,
@ -152,14 +167,16 @@ pub struct ControlsMenu {
impl ControlsMenu { impl ControlsMenu {
pub fn new() -> ControlsMenu { pub fn new() -> ControlsMenu {
let controller = Menu::new(0, 0, 220, 0); let main = Menu::new(0, 0, 220, 0);
let select_controller = Menu::new(0, 0, 220, 0);
let rebind = Menu::new(0, 0, 220, 0); let rebind = Menu::new(0, 0, 220, 0);
let confirm_rebind = Menu::new(0, 0, 220, 0); let confirm_rebind = Menu::new(0, 0, 220, 0);
let confirm_reset = Menu::new(0, 0, 160, 0); let confirm_reset = Menu::new(0, 0, 160, 0);
ControlsMenu { ControlsMenu {
current: CurrentMenu::ControllerMenu, current: CurrentMenu::MainMenu,
controller, main,
select_controller,
rebind, rebind,
confirm_rebind, confirm_rebind,
confirm_reset, confirm_reset,
@ -178,8 +195,8 @@ impl ControlsMenu {
} }
pub fn init(&mut self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult { pub fn init(&mut self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult {
self.controller.push_entry( self.main.push_entry(
ControllerMenuEntry::SelectedPlayer, MainMenuEntry::SelectedPlayer,
MenuEntry::Options( MenuEntry::Options(
state.t("menus.controls_menu.select_player.entry"), state.t("menus.controls_menu.select_player.entry"),
self.selected_player as usize, self.selected_player as usize,
@ -190,10 +207,10 @@ impl ControlsMenu {
), ),
); );
self.controller.push_entry(ControllerMenuEntry::Controller, MenuEntry::Hidden); self.main
self.controller .push_entry(MainMenuEntry::Controller, MenuEntry::Active(state.t("menus.controls_menu.controller.entry")));
.push_entry(ControllerMenuEntry::Rebind, MenuEntry::Active(state.t("menus.controls_menu.rebind"))); self.main.push_entry(MainMenuEntry::Rebind, MenuEntry::Active(state.t("menus.controls_menu.rebind")));
self.controller.push_entry(ControllerMenuEntry::Back, MenuEntry::Active(state.t("common.back"))); self.main.push_entry(MainMenuEntry::Back, MenuEntry::Active(state.t("common.back")));
self.confirm_reset.push_entry( self.confirm_reset.push_entry(
ConfirmResetMenuEntry::Title, ConfirmResetMenuEntry::Title,
@ -220,10 +237,16 @@ impl ControlsMenu {
} }
fn update_sizes(&mut self, state: &SharedGameState) { fn update_sizes(&mut self, state: &SharedGameState) {
self.controller.update_width(state); self.main.update_width(state);
self.controller.update_height(); self.main.update_height();
self.controller.x = ((state.canvas_size.0 - self.controller.width as f32) / 2.0).floor() as isize; self.main.x = ((state.canvas_size.0 - self.main.width as f32) / 2.0).floor() as isize;
self.controller.y = ((state.canvas_size.1 - self.controller.height as f32) / 2.0).floor() as isize; self.main.y = ((state.canvas_size.1 - self.main.height as f32) / 2.0).floor() as isize;
self.select_controller.update_width(state);
self.select_controller.update_height();
self.select_controller.x = ((state.canvas_size.0 - self.select_controller.width as f32) / 2.0).floor() as isize;
self.select_controller.y =
((state.canvas_size.1 - self.select_controller.height as f32) / 2.0).floor() as isize;
self.rebind.update_width(state); self.rebind.update_width(state);
self.rebind.update_height(); self.rebind.update_height();
@ -357,8 +380,12 @@ impl ControlsMenu {
} }
fn update_controller_options(&mut self, state: &SharedGameState, ctx: &Context) { fn update_controller_options(&mut self, state: &SharedGameState, ctx: &Context) {
let mut controllers = Vec::new(); self.select_controller.entries.clear();
controllers.push(state.t("menus.controls_menu.controller.keyboard"));
self.select_controller.push_entry(
SelectControllerMenuEntry::Keyboard,
MenuEntry::Active(state.t("menus.controls_menu.controller.keyboard")),
);
let gamepads = gamepad::get_gamepads(ctx); let gamepads = gamepad::get_gamepads(ctx);
@ -377,9 +404,14 @@ impl ControlsMenu {
} }
} }
controllers.push(format!("{} {}", gamepads[i].get_gamepad_name(), i + 1)); self.select_controller.push_entry(
SelectControllerMenuEntry::Gamepad(i),
MenuEntry::Active(format!("{} {}", gamepads[i].get_gamepad_name(), i + 1)),
);
} }
self.select_controller.push_entry(SelectControllerMenuEntry::Back, MenuEntry::Active(state.t("common.back")));
let controller_type = match self.selected_player { let controller_type = match self.selected_player {
Player::Player1 => state.settings.player1_controller_type, Player::Player1 => state.settings.player1_controller_type,
Player::Player2 => state.settings.player2_controller_type, Player::Player2 => state.settings.player2_controller_type,
@ -395,19 +427,12 @@ impl ControlsMenu {
self.selected_controller = controller_type; self.selected_controller = controller_type;
} }
let controller_idx = match self.selected_controller { match self.selected_controller {
ControllerType::Keyboard => 0, ControllerType::Keyboard => self.select_controller.selected = SelectControllerMenuEntry::Keyboard,
ControllerType::Gamepad(idx) => idx as usize + 1, ControllerType::Gamepad(index) => {
}; self.select_controller.selected = SelectControllerMenuEntry::Gamepad(index as usize)
}
self.controller.set_entry( }
ControllerMenuEntry::Controller,
MenuEntry::Options(
state.t("menus.controls_menu.controller.entry"),
controller_idx as usize,
controllers.clone(),
),
);
} }
fn update_confirm_controls_menu(&mut self, state: &SharedGameState) { fn update_confirm_controls_menu(&mut self, state: &SharedGameState) {
@ -831,10 +856,10 @@ impl ControlsMenu {
self.update_sizes(state); self.update_sizes(state);
match self.current { match self.current {
CurrentMenu::ControllerMenu => match self.controller.tick(controller, state) { CurrentMenu::MainMenu => match self.main.tick(controller, state) {
MenuSelectionResult::Selected(ControllerMenuEntry::SelectedPlayer, toggle) MenuSelectionResult::Selected(MainMenuEntry::SelectedPlayer, toggle)
| MenuSelectionResult::Left(ControllerMenuEntry::SelectedPlayer, toggle, _) | MenuSelectionResult::Left(MainMenuEntry::SelectedPlayer, toggle, _)
| MenuSelectionResult::Right(ControllerMenuEntry::SelectedPlayer, toggle, _) => { | MenuSelectionResult::Right(MainMenuEntry::SelectedPlayer, toggle, _) => {
if let MenuEntry::Options(_, value, _) = toggle { if let MenuEntry::Options(_, value, _) = toggle {
let (new_player, new_value) = match *value { let (new_player, new_value) = match *value {
0 => (Player::Player2, 1), 0 => (Player::Player2, 1),
@ -851,88 +876,70 @@ impl ControlsMenu {
self.update_rebind_menu(state, ctx); self.update_rebind_menu(state, ctx);
} }
} }
MenuSelectionResult::Selected(ControllerMenuEntry::Controller, toggle) MenuSelectionResult::Selected(MainMenuEntry::Controller, _) => {
| MenuSelectionResult::Right(ControllerMenuEntry::Controller, toggle, _) => {
if self.input_busy { if self.input_busy {
return Ok(()); return Ok(());
} }
if let MenuEntry::Options(_, value, entries) = toggle { self.update_controller_options(state, ctx);
if *value == entries.len() - 1 { self.current = CurrentMenu::SelectControllerMenu;
self.selected_controller = ControllerType::Keyboard;
*value = 0;
} else {
self.selected_controller = ControllerType::Gamepad(*value as u32);
*value = *value + 1;
}
}
if self.selected_player == Player::Player1 {
state.settings.player1_controller_type = self.selected_controller;
} else {
state.settings.player2_controller_type = self.selected_controller;
}
let _ = state.settings.save(ctx);
let mut new_menu_controller = CombinedMenuController::new();
new_menu_controller.add(state.settings.create_player1_controller());
new_menu_controller.add(state.settings.create_player2_controller());
self.input_busy = true;
self.controller.non_interactive = true;
*controller = new_menu_controller;
self.update_rebind_menu(state, ctx);
} }
MenuSelectionResult::Left(ControllerMenuEntry::Controller, toggle, _) => { MenuSelectionResult::Selected(MainMenuEntry::Rebind, _) => {
if self.input_busy {
return Ok(());
}
if let MenuEntry::Options(_, value, entries) = toggle {
if *value == 1 {
self.selected_controller = ControllerType::Keyboard;
*value = 0;
} else {
self.selected_controller = ControllerType::Gamepad(*value as u32);
if *value == 0 {
*value = entries.len() - 1;
} else {
*value = *value - 1;
}
}
}
if self.selected_player == Player::Player1 {
state.settings.player1_controller_type = self.selected_controller;
} else {
state.settings.player2_controller_type = self.selected_controller;
}
let _ = state.settings.save(ctx);
let mut new_menu_controller = CombinedMenuController::new();
new_menu_controller.add(state.settings.create_player1_controller());
new_menu_controller.add(state.settings.create_player2_controller());
self.input_busy = true;
self.controller.non_interactive = true;
*controller = new_menu_controller;
self.update_rebind_menu(state, ctx);
}
MenuSelectionResult::Selected(ControllerMenuEntry::Rebind, _) => {
self.current = CurrentMenu::RebindMenu; self.current = CurrentMenu::RebindMenu;
} }
MenuSelectionResult::Selected(ControllerMenuEntry::Back, _) | MenuSelectionResult::Canceled => { MenuSelectionResult::Selected(MainMenuEntry::Back, _) | MenuSelectionResult::Canceled => exit_action(),
exit_action() _ => {}
},
CurrentMenu::SelectControllerMenu => match self.select_controller.tick(controller, state) {
MenuSelectionResult::Selected(SelectControllerMenuEntry::Keyboard, _) => {
if self.selected_player == Player::Player1 {
state.settings.player1_controller_type = ControllerType::Keyboard;
} else {
state.settings.player2_controller_type = ControllerType::Keyboard;
}
let _ = state.settings.save(ctx);
let mut new_menu_controller = CombinedMenuController::new();
new_menu_controller.add(state.settings.create_player1_controller());
new_menu_controller.add(state.settings.create_player2_controller());
self.input_busy = true;
self.main.non_interactive = true;
*controller = new_menu_controller;
self.update_rebind_menu(state, ctx);
self.current = CurrentMenu::MainMenu;
}
MenuSelectionResult::Selected(SelectControllerMenuEntry::Gamepad(idx), _) => {
if self.selected_player == Player::Player1 {
state.settings.player1_controller_type = ControllerType::Gamepad(idx as u32);
} else {
state.settings.player2_controller_type = ControllerType::Gamepad(idx as u32);
}
let _ = state.settings.save(ctx);
let mut new_menu_controller = CombinedMenuController::new();
new_menu_controller.add(state.settings.create_player1_controller());
new_menu_controller.add(state.settings.create_player2_controller());
self.input_busy = true;
self.main.non_interactive = true;
*controller = new_menu_controller;
self.update_rebind_menu(state, ctx);
self.current = CurrentMenu::MainMenu;
}
MenuSelectionResult::Selected(SelectControllerMenuEntry::Back, _) | MenuSelectionResult::Canceled => {
self.current = CurrentMenu::MainMenu;
} }
_ => {} _ => {}
}, },
CurrentMenu::RebindMenu => match self.rebind.tick(controller, state) { CurrentMenu::RebindMenu => match self.rebind.tick(controller, state) {
MenuSelectionResult::Selected(RebindMenuEntry::Back, _) | MenuSelectionResult::Canceled => { MenuSelectionResult::Selected(RebindMenuEntry::Back, _) | MenuSelectionResult::Canceled => {
if !self.input_busy { if !self.input_busy {
self.current = CurrentMenu::ControllerMenu; self.current = CurrentMenu::MainMenu;
} }
} }
MenuSelectionResult::Selected(RebindMenuEntry::Control(control), _) => { MenuSelectionResult::Selected(RebindMenuEntry::Control(control), _) => {
@ -1081,7 +1088,7 @@ impl ControlsMenu {
self.input_busy = input_busy; self.input_busy = input_busy;
if !self.input_busy { if !self.input_busy {
self.controller.non_interactive = false; self.main.non_interactive = false;
self.rebind.non_interactive = false; self.rebind.non_interactive = false;
} }
} }
@ -1091,7 +1098,8 @@ impl ControlsMenu {
pub fn draw(&self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult { pub fn draw(&self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult {
match self.current { match self.current {
CurrentMenu::ControllerMenu => self.controller.draw(state, ctx)?, CurrentMenu::MainMenu => self.main.draw(state, ctx)?,
CurrentMenu::SelectControllerMenu => self.select_controller.draw(state, ctx)?,
CurrentMenu::RebindMenu => self.rebind.draw(state, ctx)?, CurrentMenu::RebindMenu => self.rebind.draw(state, ctx)?,
CurrentMenu::ConfirmRebindMenu => self.confirm_rebind.draw(state, ctx)?, CurrentMenu::ConfirmRebindMenu => self.confirm_rebind.draw(state, ctx)?,
CurrentMenu::ConfirmResetMenu => self.confirm_reset.draw(state, ctx)?, CurrentMenu::ConfirmResetMenu => self.confirm_reset.draw(state, ctx)?,