From c68fedaa50e84e0208478dff3abbff51b4403d40 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sallai=20J=C3=B3zsef?= <jozsef@sallai.me>
Date: Sun, 31 Jul 2022 03:00:19 +0300
Subject: [PATCH] fix menu controller swap issues and handle jump/shoot rebind
 edge case

---
 src/menu/controls_menu.rs | 118 ++++++++++++++++++++++++++++++++++----
 src/menu/mod.rs           |  20 +++----
 2 files changed, 118 insertions(+), 20 deletions(-)

diff --git a/src/menu/controls_menu.rs b/src/menu/controls_menu.rs
index 6c69594..7e77d40 100644
--- a/src/menu/controls_menu.rs
+++ b/src/menu/controls_menu.rs
@@ -388,12 +388,12 @@ impl ControlsMenu {
     }
 
     fn is_key_occupied(&self, scan_code: ScanCode) -> bool {
-        let keymap = match self.selected_player {
+        let other_player_keymap = match self.selected_player {
             Player::Player1 => &self.player2_key_map,
             Player::Player2 => &self.player1_key_map,
         };
 
-        for (_, v) in keymap.iter() {
+        for (_, v) in other_player_keymap.iter() {
             if *v == scan_code {
                 return true;
             }
@@ -407,6 +407,8 @@ impl ControlsMenu {
             return Ok(());
         }
 
+        let mut jump_shoot_swapped = false;
+
         match self.selected_control.unwrap() {
             ControlEntry::Left => match self.selected_player {
                 Player::Player1 => state.settings.player1_key_map.left = scan_code,
@@ -433,12 +435,38 @@ impl ControlsMenu {
                 Player::Player2 => state.settings.player2_key_map.next_weapon = scan_code,
             },
             ControlEntry::Jump => match self.selected_player {
-                Player::Player1 => state.settings.player1_key_map.jump = scan_code,
-                Player::Player2 => state.settings.player2_key_map.jump = scan_code,
+                Player::Player1 => {
+                    if state.settings.player1_key_map.shoot == scan_code {
+                        state.settings.player1_key_map.shoot = state.settings.player1_key_map.jump;
+                        jump_shoot_swapped = true;
+                    }
+
+                    state.settings.player1_key_map.jump = scan_code;
+                }
+                Player::Player2 => {
+                    if state.settings.player2_key_map.shoot == scan_code {
+                        state.settings.player2_key_map.shoot = state.settings.player2_key_map.jump;
+                    }
+
+                    state.settings.player2_key_map.jump = scan_code;
+                }
             },
             ControlEntry::Shoot => match self.selected_player {
-                Player::Player1 => state.settings.player1_key_map.shoot = scan_code,
-                Player::Player2 => state.settings.player2_key_map.shoot = scan_code,
+                Player::Player1 => {
+                    if state.settings.player1_key_map.jump == scan_code {
+                        state.settings.player1_key_map.jump = state.settings.player1_key_map.shoot;
+                        jump_shoot_swapped = true;
+                    }
+
+                    state.settings.player1_key_map.jump = scan_code;
+                }
+                Player::Player2 => {
+                    if state.settings.player2_key_map.jump == scan_code {
+                        state.settings.player2_key_map.jump = state.settings.player2_key_map.shoot;
+                    }
+
+                    state.settings.player2_key_map.shoot = scan_code;
+                }
             },
             ControlEntry::Skip => match self.selected_player {
                 Player::Player1 => state.settings.player1_key_map.skip = scan_code,
@@ -469,6 +497,19 @@ impl ControlsMenu {
             if *entry == self.selected_control.unwrap() {
                 *value = scan_code;
             }
+
+            if jump_shoot_swapped {
+                let map = match self.selected_player {
+                    Player::Player1 => &state.settings.player1_key_map,
+                    Player::Player2 => &state.settings.player2_key_map,
+                };
+
+                if *entry == ControlEntry::Jump {
+                    *value = map.jump;
+                } else if *entry == ControlEntry::Shoot {
+                    *value = map.shoot;
+                }
+            }
         }
 
         Ok(())
@@ -484,6 +525,8 @@ impl ControlsMenu {
             return Ok(());
         }
 
+        let mut jump_shoot_swapped = false;
+
         match self.selected_control.unwrap() {
             ControlEntry::Left => match self.selected_player {
                 Player::Player1 => state.settings.player1_controller_button_map.left = input_type,
@@ -510,12 +553,44 @@ impl ControlsMenu {
                 Player::Player2 => state.settings.player2_controller_button_map.next_weapon = input_type,
             },
             ControlEntry::Jump => match self.selected_player {
-                Player::Player1 => state.settings.player1_controller_button_map.jump = input_type,
-                Player::Player2 => state.settings.player2_controller_button_map.jump = input_type,
+                Player::Player1 => {
+                    if state.settings.player1_controller_button_map.shoot == input_type {
+                        state.settings.player1_controller_button_map.shoot =
+                            state.settings.player1_controller_button_map.jump;
+                        jump_shoot_swapped = true;
+                    }
+
+                    state.settings.player1_controller_button_map.jump = input_type;
+                }
+                Player::Player2 => {
+                    if state.settings.player2_controller_button_map.shoot == input_type {
+                        state.settings.player2_controller_button_map.shoot =
+                            state.settings.player2_controller_button_map.jump;
+                        jump_shoot_swapped = true;
+                    }
+
+                    state.settings.player2_controller_button_map.jump = input_type;
+                }
             },
             ControlEntry::Shoot => match self.selected_player {
-                Player::Player1 => state.settings.player1_controller_button_map.shoot = input_type,
-                Player::Player2 => state.settings.player2_controller_button_map.shoot = input_type,
+                Player::Player1 => {
+                    if state.settings.player1_controller_button_map.jump == input_type {
+                        state.settings.player1_controller_button_map.jump =
+                            state.settings.player1_controller_button_map.shoot;
+                        jump_shoot_swapped = true;
+                    }
+
+                    state.settings.player1_controller_button_map.jump = input_type;
+                }
+                Player::Player2 => {
+                    if state.settings.player2_controller_button_map.jump == input_type {
+                        state.settings.player2_controller_button_map.jump =
+                            state.settings.player2_controller_button_map.shoot;
+                        jump_shoot_swapped = true;
+                    }
+
+                    state.settings.player2_controller_button_map.shoot = input_type;
+                }
             },
             ControlEntry::Skip => match self.selected_player {
                 Player::Player1 => state.settings.player1_controller_button_map.skip = input_type,
@@ -546,6 +621,19 @@ impl ControlsMenu {
             if *entry == self.selected_control.unwrap() {
                 *value = input_type;
             }
+
+            if jump_shoot_swapped {
+                let map = match self.selected_player {
+                    Player::Player1 => &state.settings.player1_controller_button_map,
+                    Player::Player2 => &state.settings.player2_controller_button_map,
+                };
+
+                if *entry == ControlEntry::Jump {
+                    *value = map.jump;
+                } else if *entry == ControlEntry::Shoot {
+                    *value = map.shoot;
+                }
+            }
         }
 
         Ok(())
@@ -651,6 +739,7 @@ impl ControlsMenu {
                     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);
@@ -687,6 +776,7 @@ impl ControlsMenu {
                     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);
@@ -732,6 +822,7 @@ impl ControlsMenu {
                             if pressed_keys.len() == 1 {
                                 if !self.input_busy {
                                     self.input_busy = true;
+                                    self.rebind.non_interactive = true;
 
                                     let key = **pressed_keys.first().unwrap();
 
@@ -757,6 +848,7 @@ impl ControlsMenu {
                             if pressed_gamepad_buttons.len() == 1 {
                                 if !self.input_busy {
                                     self.input_busy = true;
+                                    self.rebind.non_interactive = true;
 
                                     if self.selected_player.controller_type(state) != self.selected_controller {
                                         state.sound_manager.play_sfx(12);
@@ -779,6 +871,7 @@ impl ControlsMenu {
                             if active_axes.len() == 1 {
                                 if !self.input_busy {
                                     self.input_busy = true;
+                                    self.rebind.non_interactive = true;
 
                                     if self.selected_player.controller_type(state) != self.selected_controller {
                                         state.sound_manager.play_sfx(12);
@@ -820,6 +913,11 @@ impl ControlsMenu {
             }
 
             self.input_busy = input_busy;
+
+            if !self.input_busy {
+                self.controller.non_interactive = false;
+                self.rebind.non_interactive = false;
+            }
         }
 
         Ok(())
diff --git a/src/menu/mod.rs b/src/menu/mod.rs
index 3c0bd23..ea3e347 100644
--- a/src/menu/mod.rs
+++ b/src/menu/mod.rs
@@ -668,6 +668,16 @@ impl<T: std::cmp::PartialEq + std::default::Default + Copy> Menu<T> {
         controller: &mut CombinedMenuController,
         state: &mut SharedGameState,
     ) -> MenuSelectionResult<T> {
+        self.anim_wait += 1;
+        if self.anim_wait > 8 {
+            self.anim_wait = 0;
+
+            self.anim_num += 1;
+            if self.anim_num >= 4 as u16 {
+                self.anim_num = 0;
+            }
+        }
+
         if self.non_interactive {
             return MenuSelectionResult::None;
         }
@@ -772,16 +782,6 @@ impl<T: std::cmp::PartialEq + std::default::Default + Copy> Menu<T> {
             }
         }
 
-        self.anim_wait += 1;
-        if self.anim_wait > 8 {
-            self.anim_wait = 0;
-
-            self.anim_num += 1;
-            if self.anim_num >= 4 as u16 {
-                self.anim_num = 0;
-            }
-        }
-
         MenuSelectionResult::None
     }