1
0
Fork 0
mirror of https://github.com/jugeeya/UltimateTrainingModpack.git synced 2024-11-20 00:46:34 +00:00

[Menu Input] Fixes to input hold + consistency (#586)

This commit is contained in:
jugeeya 2023-08-11 09:24:50 -07:00 committed by GitHub
parent a76808c838
commit 8abc20812e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 111 additions and 64 deletions

View file

@ -1,7 +1,10 @@
use crate::common::menu::P1_CONTROLLER_STATE;
use std::collections::HashMap;
use crate::common::*;
use crate::input::{ControllerStyle::*, *};
use lazy_static::lazy_static;
use parking_lot::Mutex;
use strum::IntoEnumIterator;
use strum_macros::EnumIter;
@ -43,7 +46,7 @@ pub fn button_mapping(
}
}
#[derive(Debug, EnumIter, PartialEq)]
#[derive(Debug, EnumIter, PartialEq, Eq, Hash, Copy, Clone)]
pub enum ButtonCombo {
OpenMenu,
SaveState,
@ -62,27 +65,32 @@ unsafe fn get_combo_keys(combo: ButtonCombo) -> ButtonConfig {
}
}
fn combo_passes(combo: ButtonCombo) -> bool {
lazy_static! {
static ref BUTTON_COMBO_REQUESTS: Mutex<HashMap<ButtonCombo, bool>> =
Mutex::new(HashMap::from([
(ButtonCombo::OpenMenu, false),
(ButtonCombo::SaveState, false),
(ButtonCombo::LoadState, false),
(ButtonCombo::InputRecord, false),
(ButtonCombo::InputPlayback, false),
]));
}
fn combo_passes(p1_controller: Controller, combo: ButtonCombo) -> bool {
unsafe {
let combo_keys = get_combo_keys(combo).to_vec();
let p1_controller_state = *P1_CONTROLLER_STATE.data_ptr();
let mut this_combo_passes = false;
for hold_button in &combo_keys[..] {
if button_mapping(
*hold_button,
p1_controller_state.style,
p1_controller_state.current_buttons,
p1_controller.style,
p1_controller.current_buttons,
) && combo_keys
.iter()
.filter(|press_button| **press_button != *hold_button)
.all(|press_button| {
button_mapping(
*press_button,
p1_controller_state.style,
p1_controller_state.just_down,
)
button_mapping(*press_button, p1_controller.style, p1_controller.just_down)
})
{
this_combo_passes = true;
@ -93,9 +101,39 @@ fn combo_passes(combo: ButtonCombo) -> bool {
}
}
pub fn combo_passes_exclusive(combo: ButtonCombo) -> bool {
pub fn _combo_passes_exclusive(p1_controller: Controller, combo: ButtonCombo) -> bool {
let other_combo_passes = ButtonCombo::iter()
.filter(|other_combo| *other_combo != combo)
.any(combo_passes);
combo_passes(combo) && !other_combo_passes
.any(|other_combo| combo_passes(p1_controller, other_combo));
combo_passes(p1_controller, combo) && !other_combo_passes
}
pub fn combo_passes_exclusive(combo: ButtonCombo) -> bool {
unsafe {
let button_combo_requests = &mut *BUTTON_COMBO_REQUESTS.data_ptr();
let passes = button_combo_requests.get_mut(&combo);
let mut did_pass = false;
if let Some(passes) = passes {
if *passes {
did_pass = true;
}
*passes = false;
}
did_pass
}
}
pub fn handle_final_input_mapping(player_idx: i32, controller_struct: &SomeControllerStruct) {
if player_idx == 0 {
let p1_controller = *controller_struct.controller;
let button_combo_requests = &mut *BUTTON_COMBO_REQUESTS.lock();
button_combo_requests
.iter_mut()
.for_each(|(combo, is_request)| {
if !*is_request {
*is_request = _combo_passes_exclusive(p1_controller, *combo);
}
})
}
}

View file

@ -78,18 +78,6 @@ pub fn spawn_menu() {
}
}
lazy_static! {
pub static ref QUICK_MENU_APP: Mutex<training_mod_tui::App<'static>> = Mutex::new(
training_mod_tui::App::new(unsafe { ui_menu(MENU) }, unsafe {
(
ui_menu(DEFAULTS_MENU),
serde_json::to_string(&DEFAULTS_MENU).unwrap(),
)
})
);
pub static ref P1_CONTROLLER_STATE: Mutex<Controller> = Mutex::new(Controller::default());
}
#[derive(Eq, PartialEq, Hash, Copy, Clone)]
enum DirectionButton {
DpadLeft,
@ -106,6 +94,36 @@ enum DirectionButton {
RUp,
}
lazy_static! {
pub static ref QUICK_MENU_APP: Mutex<training_mod_tui::App<'static>> = Mutex::new(
training_mod_tui::App::new(unsafe { ui_menu(MENU) }, unsafe {
(
ui_menu(DEFAULTS_MENU),
serde_json::to_string(&DEFAULTS_MENU).unwrap(),
)
})
);
pub static ref P1_CONTROLLER_STYLE: Mutex<ControllerStyle> =
Mutex::new(ControllerStyle::default());
static ref DIRECTION_HOLD_FRAMES: Mutex<HashMap<DirectionButton, u32>> = {
use DirectionButton::*;
Mutex::new(HashMap::from([
(DpadLeft, 0),
(LLeft, 0),
(RLeft, 0),
(DpadDown, 0),
(LDown, 0),
(RDown, 0),
(DpadRight, 0),
(LRight, 0),
(RRight, 0),
(DpadUp, 0),
(LUp, 0),
(RUp, 0),
]))
};
}
pub fn handle_final_input_mapping(
player_idx: i32,
controller_struct: &SomeControllerStruct,
@ -113,7 +131,8 @@ pub fn handle_final_input_mapping(
) {
unsafe {
if player_idx == 0 {
*P1_CONTROLLER_STATE.lock() = *controller_struct.controller;
let p1_controller = *controller_struct.controller;
*P1_CONTROLLER_STYLE.lock() = p1_controller.style;
if QUICK_MENU_ACTIVE {
// If we're here, remove all other presses
*out = MappedInputs::empty();
@ -122,12 +141,7 @@ pub fn handle_final_input_mapping(
const DIRECTION_HOLD_REPEAT_FRAMES: u32 = 20;
use DirectionButton::*;
let directions = [
DpadLeft, LLeft, RLeft, DpadDown, LDown, RDown, DpadRight, LRight, RRight,
DpadUp, LUp, RUp,
];
let mut direction_hold_frames: HashMap<DirectionButton, u32> =
directions.iter().map(|config| (*config, 0)).collect();
let direction_hold_frames = &mut *DIRECTION_HOLD_FRAMES.lock();
// Check for all controllers unplugged
let mut potential_controller_ids = (0..8).collect::<Vec<u32>>();
@ -140,41 +154,30 @@ pub fn handle_final_input_mapping(
return;
}
let p1_controller_state = *P1_CONTROLLER_STATE.data_ptr();
let style = p1_controller_state.style;
let button_presses = p1_controller_state.just_down;
let style = p1_controller.style;
let button_presses = p1_controller.just_down;
let button_current_held = p1_controller_state.current_buttons;
let button_released = p1_controller_state.just_release;
let button_current_held = p1_controller.current_buttons;
direction_hold_frames
.iter_mut()
.for_each(|(direction, frames)| {
let (still_held, released) = match direction {
DpadLeft => {
(button_current_held.dpad_left(), button_released.dpad_left())
}
LLeft => (button_current_held.l_left(), button_released.l_left()),
RLeft => (button_current_held.r_left(), button_released.r_left()),
DpadDown => {
(button_current_held.dpad_down(), button_released.dpad_down())
}
LDown => (button_current_held.l_down(), button_released.l_down()),
RDown => (button_current_held.r_down(), button_released.r_down()),
DpadRight => (
button_current_held.dpad_right(),
button_released.dpad_right(),
),
LRight => (button_current_held.l_right(), button_released.l_right()),
RRight => (button_current_held.r_right(), button_released.r_right()),
DpadUp => (button_current_held.dpad_up(), button_released.dpad_up()),
LUp => (button_current_held.l_up(), button_released.l_up()),
RUp => (button_current_held.r_up(), button_released.r_up()),
let still_held = match direction {
DpadLeft => button_current_held.dpad_left(),
LLeft => button_current_held.l_left(),
RLeft => button_current_held.r_left(),
DpadDown => button_current_held.dpad_down(),
LDown => button_current_held.l_down(),
RDown => button_current_held.r_down(),
DpadRight => button_current_held.dpad_right(),
LRight => button_current_held.l_right(),
RRight => button_current_held.r_right(),
DpadUp => button_current_held.dpad_up(),
LUp => button_current_held.l_up(),
RUp => button_current_held.r_up(),
};
if still_held {
*frames += 1;
}
if released {
} else {
*frames = 0;
}
});
@ -227,6 +230,7 @@ pub fn handle_final_input_mapping(
|| button_presses.r_left()
|| [DpadLeft, LLeft, RLeft].iter().any(hold_condition))
.then(|| {
received_input = true;
app.on_left();
});
(button_presses.dpad_right()
@ -234,6 +238,7 @@ pub fn handle_final_input_mapping(
|| button_presses.r_right()
|| [DpadRight, LRight, RRight].iter().any(hold_condition))
.then(|| {
received_input = true;
app.on_right();
});
(button_presses.dpad_up()
@ -241,6 +246,7 @@ pub fn handle_final_input_mapping(
|| button_presses.r_up()
|| [DpadUp, LUp, RUp].iter().any(hold_condition))
.then(|| {
received_input = true;
app.on_up();
});
(button_presses.dpad_down()
@ -248,10 +254,12 @@ pub fn handle_final_input_mapping(
|| button_presses.r_down()
|| [DpadDown, LDown, RDown].iter().any(hold_condition))
.then(|| {
received_input = true;
app.on_down();
});
if received_input {
direction_hold_frames.iter_mut().for_each(|(_, f)| *f = 0);
set_menu_from_json(&app.get_menu_selections());
}
}

View file

@ -1,3 +1,4 @@
use crate::common::button_config;
use crate::common::{
consts::BuffOption, consts::FighterId, consts::MENU, dev_config, get_module_accessor,
is_training_mode, menu, FIGHTER_MANAGER_ADDR, ITEM_MANAGER_ADDR, STAGE_MANAGER_ADDR,
@ -628,6 +629,7 @@ unsafe fn handle_final_input_mapping(
if !is_training_mode() {
return;
}
button_config::handle_final_input_mapping(player_idx, controller_struct);
menu::handle_final_input_mapping(player_idx, controller_struct, out);
dev_config::handle_final_input_mapping(player_idx, controller_struct);
input_delay::handle_final_input_mapping(player_idx, out);

View file

@ -405,8 +405,7 @@ pub unsafe fn draw(root_pane: &Pane) {
};
let tab_titles = [prev_tab, tab_selected, next_tab].map(|idx| app_tabs[idx]);
let is_gcc =
(*common::menu::P1_CONTROLLER_STATE.data_ptr()).style == ControllerStyle::GCController;
let is_gcc = (*common::menu::P1_CONTROLLER_STYLE.data_ptr()) == ControllerStyle::GCController;
let button_mapping = if is_gcc {
GCC_BUTTON_MAPPING.clone()
} else {