make menu ok/back remappable and fix jump/shoot rebind bug (#150)

This commit is contained in:
Sallai József 2022-07-31 14:50:46 +03:00
parent c68fedaa50
commit f74ec19cb5
7 changed files with 201 additions and 77 deletions

View File

@ -152,7 +152,9 @@
"inventory": "Inventory", "inventory": "Inventory",
"map": "Map system", "map": "Map system",
"skip": "Skip", "skip": "Skip",
"strafe": "Strafe" "strafe": "Strafe",
"menu_ok": "Menu select/confirm",
"menu_back": "Menu back/cancel"
}, },
"rebind_confirm_menu": { "rebind_confirm_menu": {

View File

@ -144,7 +144,9 @@
"inventory": "在庫", "inventory": "在庫",
"map": "マップシステム", "map": "マップシステム",
"skip": "スキップ", "skip": "スキップ",
"strafe": "ストレイフ" "strafe": "ストレイフ",
"menu_ok": "メニュー選択OK",
"menu_back": "メニュー残す/キャンセル"
}, },
"rebind_confirm_menu": { "rebind_confirm_menu": {

View File

@ -22,9 +22,10 @@ bitfield! {
pub next_weapon, set_next_weapon: 8; pub next_weapon, set_next_weapon: 8;
pub prev_weapon, set_prev_weapon: 9; pub prev_weapon, set_prev_weapon: 9;
pub escape, set_escape: 10; pub escape, set_escape: 10;
pub enter, set_enter: 11; pub skip, set_skip: 11;
pub skip, set_skip: 12; pub strafe, set_strafe: 12;
pub strafe, set_strafe: 13; pub menu_ok, set_menu_ok: 13;
pub menu_back, set_menu_back: 14;
} }
#[derive(Clone)] #[derive(Clone)]
@ -64,9 +65,10 @@ impl PlayerController for GamepadController {
self.gamepad_id, self.gamepad_id,
&PlayerControllerInputType::ButtonInput(Button::Start), &PlayerControllerInputType::ButtonInput(Button::Start),
)); ));
self.state.set_enter(gamepad::is_active(ctx, self.gamepad_id, &button_map.jump));
self.state.set_skip(gamepad::is_active(ctx, self.gamepad_id, &button_map.skip)); self.state.set_skip(gamepad::is_active(ctx, self.gamepad_id, &button_map.skip));
self.state.set_strafe(gamepad::is_active(ctx, self.gamepad_id, &button_map.strafe)); self.state.set_strafe(gamepad::is_active(ctx, self.gamepad_id, &button_map.strafe));
self.state.set_menu_ok(gamepad::is_active(ctx, self.gamepad_id, &button_map.menu_ok));
self.state.set_menu_back(gamepad::is_active(ctx, self.gamepad_id, &button_map.menu_back));
Ok(()) Ok(())
} }
@ -175,11 +177,11 @@ impl PlayerController for GamepadController {
} }
fn trigger_menu_ok(&self) -> bool { fn trigger_menu_ok(&self) -> bool {
self.trigger.jump() || self.trigger.enter() self.trigger.menu_ok()
} }
fn trigger_menu_back(&self) -> bool { fn trigger_menu_back(&self) -> bool {
self.trigger.shoot() || self.trigger.escape() self.trigger.menu_back() || self.trigger.escape()
} }
fn trigger_menu_pause(&self) -> bool { fn trigger_menu_pause(&self) -> bool {

View File

@ -26,6 +26,8 @@ bitfield! {
pub enter, set_enter: 11; pub enter, set_enter: 11;
pub skip, set_skip: 12; pub skip, set_skip: 12;
pub strafe, set_strafe: 13; pub strafe, set_strafe: 13;
pub menu_ok, set_menu_ok: 14;
pub menu_back, set_menu_back: 15;
} }
#[derive(Clone)] #[derive(Clone)]
@ -63,6 +65,8 @@ impl PlayerController for KeyboardController {
self.state.set_enter(keyboard::is_key_pressed(ctx, ScanCode::Return)); self.state.set_enter(keyboard::is_key_pressed(ctx, ScanCode::Return));
self.state.set_escape(keyboard::is_key_pressed(ctx, ScanCode::Escape)); self.state.set_escape(keyboard::is_key_pressed(ctx, ScanCode::Escape));
self.state.set_strafe(keyboard::is_key_pressed(ctx, keymap.strafe)); self.state.set_strafe(keyboard::is_key_pressed(ctx, keymap.strafe));
self.state.set_menu_ok(keyboard::is_key_pressed(ctx, keymap.menu_ok));
self.state.set_menu_back(keyboard::is_key_pressed(ctx, keymap.menu_back));
Ok(()) Ok(())
} }
@ -171,11 +175,11 @@ impl PlayerController for KeyboardController {
} }
fn trigger_menu_ok(&self) -> bool { fn trigger_menu_ok(&self) -> bool {
self.trigger.jump() || self.trigger.enter() self.trigger.menu_ok() || self.trigger.enter()
} }
fn trigger_menu_back(&self) -> bool { fn trigger_menu_back(&self) -> bool {
self.trigger.shoot() || self.trigger.escape() self.trigger.menu_back() || self.trigger.escape()
} }
fn trigger_menu_pause(&self) -> bool { fn trigger_menu_pause(&self) -> bool {

View File

@ -24,6 +24,8 @@ bitfield! {
pub enter, set_enter: 11; pub enter, set_enter: 11;
pub skip, set_skip: 12; pub skip, set_skip: 12;
pub strafe, set_strafe: 13; pub strafe, set_strafe: 13;
pub menu_ok, set_menu_ok: 14;
pub menu_back, set_menu_back: 15;
} }
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
@ -154,11 +156,11 @@ impl PlayerController for ReplayController {
} }
fn trigger_menu_ok(&self) -> bool { fn trigger_menu_ok(&self) -> bool {
self.trigger.jump() || self.trigger.enter() self.trigger.menu_ok() || self.trigger.enter()
} }
fn trigger_menu_back(&self) -> bool { fn trigger_menu_back(&self) -> bool {
self.trigger.shoot() || self.trigger.escape() self.trigger.menu_back() || self.trigger.escape()
} }
fn trigger_menu_pause(&self) -> bool { fn trigger_menu_pause(&self) -> bool {

View File

@ -55,7 +55,7 @@ enum RebindMenuEntry {
impl Default for RebindMenuEntry { impl Default for RebindMenuEntry {
fn default() -> Self { fn default() -> Self {
RebindMenuEntry::Control(ControlEntry::Up) RebindMenuEntry::Control(ControlEntry::MenuOk)
} }
} }
@ -88,6 +88,8 @@ enum ControlEntry {
Inventory, Inventory,
Map, Map,
Strafe, Strafe,
MenuOk,
MenuBack,
} }
impl ControlEntry { impl ControlEntry {
@ -105,6 +107,8 @@ impl ControlEntry {
ControlEntry::Inventory => state.t("menus.controls_menu.rebind_menu.inventory"), ControlEntry::Inventory => state.t("menus.controls_menu.rebind_menu.inventory"),
ControlEntry::Map => state.t("menus.controls_menu.rebind_menu.map"), ControlEntry::Map => state.t("menus.controls_menu.rebind_menu.map"),
ControlEntry::Strafe => state.t("menus.controls_menu.rebind_menu.strafe"), ControlEntry::Strafe => state.t("menus.controls_menu.rebind_menu.strafe"),
ControlEntry::MenuOk => state.t("menus.controls_menu.rebind_menu.menu_ok"),
ControlEntry::MenuBack => state.t("menus.controls_menu.rebind_menu.menu_back"),
} }
} }
} }
@ -207,6 +211,8 @@ impl ControlsMenu {
fn init_key_map(&self, settings_key_map: &PlayerKeyMap) -> Vec<(ControlEntry, ScanCode)> { fn init_key_map(&self, settings_key_map: &PlayerKeyMap) -> Vec<(ControlEntry, ScanCode)> {
let mut map = Vec::new(); let mut map = Vec::new();
map.push((ControlEntry::MenuOk, settings_key_map.menu_ok));
map.push((ControlEntry::MenuBack, settings_key_map.menu_back));
map.push((ControlEntry::Up, settings_key_map.up)); map.push((ControlEntry::Up, settings_key_map.up));
map.push((ControlEntry::Down, settings_key_map.down)); map.push((ControlEntry::Down, settings_key_map.down));
map.push((ControlEntry::Left, settings_key_map.left)); map.push((ControlEntry::Left, settings_key_map.left));
@ -229,6 +235,8 @@ impl ControlsMenu {
) -> Vec<(ControlEntry, PlayerControllerInputType)> { ) -> Vec<(ControlEntry, PlayerControllerInputType)> {
let mut map = Vec::new(); let mut map = Vec::new();
map.push((ControlEntry::MenuOk, settings_controller_button_map.menu_ok));
map.push((ControlEntry::MenuBack, settings_controller_button_map.menu_back));
map.push((ControlEntry::Up, settings_controller_button_map.up)); map.push((ControlEntry::Up, settings_controller_button_map.up));
map.push((ControlEntry::Down, settings_controller_button_map.down)); map.push((ControlEntry::Down, settings_controller_button_map.down));
map.push((ControlEntry::Left, settings_controller_button_map.left)); map.push((ControlEntry::Left, settings_controller_button_map.left));
@ -407,7 +415,7 @@ impl ControlsMenu {
return Ok(()); return Ok(());
} }
let mut jump_shoot_swapped = false; let mut did_swap_controls = false;
match self.selected_control.unwrap() { match self.selected_control.unwrap() {
ControlEntry::Left => match self.selected_player { ControlEntry::Left => match self.selected_player {
@ -436,36 +444,34 @@ impl ControlsMenu {
}, },
ControlEntry::Jump => match self.selected_player { ControlEntry::Jump => match self.selected_player {
Player::Player1 => { Player::Player1 => {
if state.settings.player1_key_map.shoot == scan_code { did_swap_controls = self.swap_if_same(
state.settings.player1_key_map.shoot = state.settings.player1_key_map.jump; &mut state.settings.player1_key_map.jump,
jump_shoot_swapped = true; &mut state.settings.player1_key_map.shoot,
} scan_code,
);
state.settings.player1_key_map.jump = scan_code;
} }
Player::Player2 => { Player::Player2 => {
if state.settings.player2_key_map.shoot == scan_code { did_swap_controls = self.swap_if_same(
state.settings.player2_key_map.shoot = state.settings.player2_key_map.jump; &mut state.settings.player2_key_map.jump,
} &mut state.settings.player2_key_map.shoot,
scan_code,
state.settings.player2_key_map.jump = scan_code; );
} }
}, },
ControlEntry::Shoot => match self.selected_player { ControlEntry::Shoot => match self.selected_player {
Player::Player1 => { Player::Player1 => {
if state.settings.player1_key_map.jump == scan_code { did_swap_controls = self.swap_if_same(
state.settings.player1_key_map.jump = state.settings.player1_key_map.shoot; &mut state.settings.player1_key_map.shoot,
jump_shoot_swapped = true; &mut state.settings.player1_key_map.jump,
} scan_code,
);
state.settings.player1_key_map.jump = scan_code;
} }
Player::Player2 => { Player::Player2 => {
if state.settings.player2_key_map.jump == scan_code { did_swap_controls = self.swap_if_same(
state.settings.player2_key_map.jump = state.settings.player2_key_map.shoot; &mut state.settings.player2_key_map.shoot,
} &mut state.settings.player2_key_map.jump,
scan_code,
state.settings.player2_key_map.shoot = scan_code; );
} }
}, },
ControlEntry::Skip => match self.selected_player { ControlEntry::Skip => match self.selected_player {
@ -484,6 +490,38 @@ impl ControlsMenu {
Player::Player1 => state.settings.player1_key_map.strafe = scan_code, Player::Player1 => state.settings.player1_key_map.strafe = scan_code,
Player::Player2 => state.settings.player2_key_map.strafe = scan_code, Player::Player2 => state.settings.player2_key_map.strafe = scan_code,
}, },
ControlEntry::MenuOk => match self.selected_player {
Player::Player1 => {
did_swap_controls = self.swap_if_same(
&mut state.settings.player1_key_map.menu_ok,
&mut state.settings.player1_key_map.menu_back,
scan_code,
);
}
Player::Player2 => {
did_swap_controls = self.swap_if_same(
&mut state.settings.player2_key_map.menu_ok,
&mut state.settings.player2_key_map.menu_back,
scan_code,
);
}
},
ControlEntry::MenuBack => match self.selected_player {
Player::Player1 => {
did_swap_controls = self.swap_if_same(
&mut state.settings.player1_key_map.menu_back,
&mut state.settings.player1_key_map.menu_ok,
scan_code,
);
}
Player::Player2 => {
did_swap_controls = self.swap_if_same(
&mut state.settings.player2_key_map.menu_back,
&mut state.settings.player2_key_map.menu_ok,
scan_code,
);
}
},
} }
state.settings.save(ctx)?; state.settings.save(ctx)?;
@ -498,16 +536,18 @@ impl ControlsMenu {
*value = scan_code; *value = scan_code;
} }
if jump_shoot_swapped { if did_swap_controls {
let map = match self.selected_player { let map = match self.selected_player {
Player::Player1 => &state.settings.player1_key_map, Player::Player1 => &state.settings.player1_key_map,
Player::Player2 => &state.settings.player2_key_map, Player::Player2 => &state.settings.player2_key_map,
}; };
if *entry == ControlEntry::Jump { match *entry {
*value = map.jump; ControlEntry::Jump => *value = map.jump,
} else if *entry == ControlEntry::Shoot { ControlEntry::Shoot => *value = map.shoot,
*value = map.shoot; ControlEntry::MenuOk => *value = map.menu_ok,
ControlEntry::MenuBack => *value = map.menu_back,
_ => {}
} }
} }
} }
@ -525,7 +565,7 @@ impl ControlsMenu {
return Ok(()); return Ok(());
} }
let mut jump_shoot_swapped = false; let mut did_swap_controls = false;
match self.selected_control.unwrap() { match self.selected_control.unwrap() {
ControlEntry::Left => match self.selected_player { ControlEntry::Left => match self.selected_player {
@ -554,42 +594,34 @@ impl ControlsMenu {
}, },
ControlEntry::Jump => match self.selected_player { ControlEntry::Jump => match self.selected_player {
Player::Player1 => { Player::Player1 => {
if state.settings.player1_controller_button_map.shoot == input_type { did_swap_controls = self.swap_if_same(
state.settings.player1_controller_button_map.shoot = &mut state.settings.player1_controller_button_map.jump,
state.settings.player1_controller_button_map.jump; &mut state.settings.player1_controller_button_map.shoot,
jump_shoot_swapped = true; input_type,
} );
state.settings.player1_controller_button_map.jump = input_type;
} }
Player::Player2 => { Player::Player2 => {
if state.settings.player2_controller_button_map.shoot == input_type { did_swap_controls = self.swap_if_same(
state.settings.player2_controller_button_map.shoot = &mut state.settings.player2_controller_button_map.jump,
state.settings.player2_controller_button_map.jump; &mut state.settings.player2_controller_button_map.shoot,
jump_shoot_swapped = true; input_type,
} );
state.settings.player2_controller_button_map.jump = input_type;
} }
}, },
ControlEntry::Shoot => match self.selected_player { ControlEntry::Shoot => match self.selected_player {
Player::Player1 => { Player::Player1 => {
if state.settings.player1_controller_button_map.jump == input_type { did_swap_controls = self.swap_if_same(
state.settings.player1_controller_button_map.jump = &mut state.settings.player1_controller_button_map.shoot,
state.settings.player1_controller_button_map.shoot; &mut state.settings.player1_controller_button_map.jump,
jump_shoot_swapped = true; input_type,
} );
state.settings.player1_controller_button_map.jump = input_type;
} }
Player::Player2 => { Player::Player2 => {
if state.settings.player2_controller_button_map.jump == input_type { did_swap_controls = self.swap_if_same(
state.settings.player2_controller_button_map.jump = &mut state.settings.player2_controller_button_map.shoot,
state.settings.player2_controller_button_map.shoot; &mut state.settings.player2_controller_button_map.jump,
jump_shoot_swapped = true; input_type,
} );
state.settings.player2_controller_button_map.shoot = input_type;
} }
}, },
ControlEntry::Skip => match self.selected_player { ControlEntry::Skip => match self.selected_player {
@ -608,6 +640,38 @@ impl ControlsMenu {
Player::Player1 => state.settings.player1_controller_button_map.strafe = input_type, Player::Player1 => state.settings.player1_controller_button_map.strafe = input_type,
Player::Player2 => state.settings.player2_controller_button_map.strafe = input_type, Player::Player2 => state.settings.player2_controller_button_map.strafe = input_type,
}, },
ControlEntry::MenuOk => match self.selected_player {
Player::Player1 => {
did_swap_controls = self.swap_if_same(
&mut state.settings.player1_controller_button_map.menu_ok,
&mut state.settings.player1_controller_button_map.menu_back,
input_type,
);
}
Player::Player2 => {
did_swap_controls = self.swap_if_same(
&mut state.settings.player2_controller_button_map.menu_ok,
&mut state.settings.player2_controller_button_map.menu_back,
input_type,
);
}
},
ControlEntry::MenuBack => match self.selected_player {
Player::Player1 => {
did_swap_controls = self.swap_if_same(
&mut state.settings.player1_controller_button_map.menu_back,
&mut state.settings.player1_controller_button_map.menu_ok,
input_type,
);
}
Player::Player2 => {
did_swap_controls = self.swap_if_same(
&mut state.settings.player2_controller_button_map.menu_back,
&mut state.settings.player2_controller_button_map.menu_ok,
input_type,
);
}
},
} }
state.settings.save(ctx)?; state.settings.save(ctx)?;
@ -622,16 +686,18 @@ impl ControlsMenu {
*value = input_type; *value = input_type;
} }
if jump_shoot_swapped { if did_swap_controls {
let map = match self.selected_player { let map = match self.selected_player {
Player::Player1 => &state.settings.player1_controller_button_map, Player::Player1 => &state.settings.player1_controller_button_map,
Player::Player2 => &state.settings.player2_controller_button_map, Player::Player2 => &state.settings.player2_controller_button_map,
}; };
if *entry == ControlEntry::Jump { match *entry {
*value = map.jump; ControlEntry::Jump => *value = map.jump,
} else if *entry == ControlEntry::Shoot { ControlEntry::Shoot => *value = map.shoot,
*value = map.shoot; ControlEntry::MenuOk => *value = map.menu_ok,
ControlEntry::MenuBack => *value = map.menu_back,
_ => {}
} }
} }
} }
@ -639,6 +705,19 @@ impl ControlsMenu {
Ok(()) Ok(())
} }
fn swap_if_same<T: Eq + Copy>(&mut self, fst: &mut T, snd: &mut T, value: T) -> bool {
let mut swapped = false;
if *snd == value {
*snd = *fst;
swapped = true;
}
*fst = value;
swapped
}
fn normalize_gamepad_input(&self, input: PlayerControllerInputType) -> PlayerControllerInputType { fn normalize_gamepad_input(&self, input: PlayerControllerInputType) -> PlayerControllerInputType {
match input { match input {
PlayerControllerInputType::ButtonInput(Button::DPadUp) => { PlayerControllerInputType::ButtonInput(Button::DPadUp) => {
@ -845,15 +924,24 @@ impl ControlsMenu {
let pressed_gamepad_buttons: Vec<_> = let pressed_gamepad_buttons: Vec<_> =
ctx.gamepad_context.pressed_buttons(idx).into_iter().collect(); ctx.gamepad_context.pressed_buttons(idx).into_iter().collect();
for button in pressed_gamepad_buttons.clone() {
if button == Button::Start {
state.sound_manager.play_sfx(5);
self.current = CurrentMenu::RebindMenu;
return Ok(());
}
}
if pressed_gamepad_buttons.len() == 1 { if pressed_gamepad_buttons.len() == 1 {
if !self.input_busy { if !self.input_busy {
self.input_busy = true; self.input_busy = true;
self.rebind.non_interactive = true; self.rebind.non_interactive = true;
let button = *pressed_gamepad_buttons.first().unwrap();
if self.selected_player.controller_type(state) != self.selected_controller { if self.selected_player.controller_type(state) != self.selected_controller {
state.sound_manager.play_sfx(12); state.sound_manager.play_sfx(12);
} else { } else {
let button = *pressed_gamepad_buttons.first().unwrap();
let normalized_input = self let normalized_input = self
.normalize_gamepad_input(PlayerControllerInputType::ButtonInput(button)); .normalize_gamepad_input(PlayerControllerInputType::ButtonInput(button));

View File

@ -82,7 +82,7 @@ fn default_true() -> bool {
#[inline(always)] #[inline(always)]
fn current_version() -> u32 { fn current_version() -> u32 {
15 16
} }
#[inline(always)] #[inline(always)]
@ -236,6 +236,20 @@ impl Settings {
self.pause_on_focus_loss = default_pause_on_focus_loss(); self.pause_on_focus_loss = default_pause_on_focus_loss();
} }
if self.version == 15 {
self.version = 16;
self.player1_key_map.menu_ok = self.player1_key_map.jump;
self.player1_key_map.menu_back = self.player1_key_map.shoot;
self.player1_controller_button_map.menu_ok = self.player1_controller_button_map.jump;
self.player1_controller_button_map.menu_back = self.player1_controller_button_map.shoot;
self.player2_key_map.menu_ok = self.player2_key_map.jump;
self.player2_key_map.menu_back = self.player2_key_map.shoot;
self.player2_controller_button_map.menu_ok = self.player2_controller_button_map.jump;
self.player2_controller_button_map.menu_back = self.player2_controller_button_map.shoot;
}
if self.version != initial_version { if self.version != initial_version {
log::info!("Upgraded configuration file from version {} to {}.", initial_version, self.version); log::info!("Upgraded configuration file from version {} to {}.", initial_version, self.version);
} }
@ -351,6 +365,8 @@ pub struct PlayerKeyMap {
pub inventory: ScanCode, pub inventory: ScanCode,
pub map: ScanCode, pub map: ScanCode,
pub strafe: ScanCode, pub strafe: ScanCode,
pub menu_ok: ScanCode,
pub menu_back: ScanCode,
} }
#[inline(always)] #[inline(always)]
@ -368,6 +384,8 @@ fn p1_default_keymap() -> PlayerKeyMap {
inventory: ScanCode::Q, inventory: ScanCode::Q,
map: ScanCode::W, map: ScanCode::W,
strafe: ScanCode::LShift, strafe: ScanCode::LShift,
menu_ok: ScanCode::Z,
menu_back: ScanCode::X,
} }
} }
@ -386,6 +404,8 @@ fn p2_default_keymap() -> PlayerKeyMap {
inventory: ScanCode::T, inventory: ScanCode::T,
map: ScanCode::Y, map: ScanCode::Y,
strafe: ScanCode::RShift, strafe: ScanCode::RShift,
menu_ok: ScanCode::B,
menu_back: ScanCode::N,
} }
} }
@ -409,6 +429,8 @@ pub struct PlayerControllerButtonMap {
pub inventory: PlayerControllerInputType, pub inventory: PlayerControllerInputType,
pub map: PlayerControllerInputType, pub map: PlayerControllerInputType,
pub strafe: PlayerControllerInputType, pub strafe: PlayerControllerInputType,
pub menu_ok: PlayerControllerInputType,
pub menu_back: PlayerControllerInputType,
} }
#[inline(always)] #[inline(always)]
@ -426,6 +448,8 @@ pub fn player_default_controller_button_map() -> PlayerControllerButtonMap {
strafe: PlayerControllerInputType::AxisInput(Axis::TriggerRight, AxisDirection::Either), strafe: PlayerControllerInputType::AxisInput(Axis::TriggerRight, AxisDirection::Either),
inventory: PlayerControllerInputType::ButtonInput(Button::North), inventory: PlayerControllerInputType::ButtonInput(Button::North),
map: PlayerControllerInputType::ButtonInput(Button::West), map: PlayerControllerInputType::ButtonInput(Button::West),
menu_ok: PlayerControllerInputType::ButtonInput(Button::South),
menu_back: PlayerControllerInputType::ButtonInput(Button::East),
} }
} }