From 2f032c1fc0a690159ebdd662ea2d2ec440437458 Mon Sep 17 00:00:00 2001 From: jugeeya Date: Mon, 10 Oct 2022 17:17:20 -0700 Subject: [PATCH] Fix button config parsing --- src/common/button_config.rs | 123 +++++++++++++++++++----------------- src/common/menu.rs | 10 +-- src/lib.rs | 11 ++-- src/training/save_states.rs | 20 +----- 4 files changed, 76 insertions(+), 88 deletions(-) diff --git a/src/common/button_config.rs b/src/common/button_config.rs index 7667b5a..bc8b694 100644 --- a/src/common/button_config.rs +++ b/src/common/button_config.rs @@ -1,5 +1,7 @@ use lazy_static::lazy_static; use parking_lot::Mutex; +use smash::app::lua_bind::ControlModule; +use smash::lib::lua_const::*; use serde::Deserialize; use std::collections::HashMap; use toml; @@ -19,21 +21,27 @@ lazy_static! { ("SHARESTOCK", 0xD), // *CONTROL_PAD_BUTTON_STOCK_SHARE ("JUMPMINI", 0xA), // *CONTROL_PAD_BUTTON_JUMP_MINI ]); - pub static ref OPEN_MENU_BTN_HOLD: Mutex> = Mutex::new(vec![BUTTON_MAPPING["SPECIAL"]]); - pub static ref OPEN_MENU_BTN_PRESS: Mutex> = Mutex::new(vec![BUTTON_MAPPING["UPTAUNT"]]); - pub static ref SAVE_STATE_BTN_HOLD: Mutex> = Mutex::new(vec![BUTTON_MAPPING["GRAB"]]); - pub static ref SAVE_STATE_BTN_PRESS: Mutex> = Mutex::new(vec![BUTTON_MAPPING["DOWNTAUNT"]]); - pub static ref LOAD_STATE_BTN_HOLD: Mutex> = Mutex::new(vec![BUTTON_MAPPING["GRAB"]]); - pub static ref LOAD_STATE_BTN_PRESS: Mutex> = Mutex::new(vec![BUTTON_MAPPING["UPTAUNT"]]); +} +static mut BUTTON_COMBO_CONFIG: BtnComboConfig = BtnComboConfig{ + open_menu: BtnList{ hold: vec![], press: vec![] }, + save_state: BtnList{ hold: vec![], press: vec![] }, + load_state: BtnList{ hold: vec![], press: vec![] }, +}; + +#[derive(Debug)] +pub enum ButtonCombo { + OpenMenu, + SaveState, + LoadState } -#[derive(Deserialize)] +#[derive(Deserialize, Default)] struct BtnList { hold: Vec, press: Vec, } -#[derive(Deserialize)] +#[derive(Deserialize, Default)] struct BtnComboConfig { open_menu: BtnList, save_state: BtnList, @@ -45,67 +53,68 @@ struct TopLevelBtnComboConfig { button_config: BtnComboConfig, } -fn save_btn_config(btnlist: BtnList, mutex_hold: &Mutex>, mutex_press: &Mutex>) { - let bad_keys: Vec<&String> = btnlist - .hold - .iter() - .chain(btnlist.press.iter()) - .filter(|x| !BUTTON_MAPPING.contains_key(x.as_str())) - .collect(); +pub fn validate_config(data: &str) -> bool { + let conf: TopLevelBtnComboConfig = toml::from_str(data).unwrap(); + let conf = conf.button_config; + let configs = [conf.open_menu, conf.save_state, conf.load_state]; + let bad_keys = configs.iter().flat_map(|btn_list| { + btn_list.hold.iter() + .chain(btn_list.press.iter()) + .filter(|x| !BUTTON_MAPPING.contains_key(x.to_uppercase().as_str())) + }).collect::>(); + if !bad_keys.is_empty() { skyline::error::show_error( 0x71, - "Training Modpack custom button\nconfiguration is invalid!", - &format!("The following keys are invalid in\nsd:/TrainingModpack/training_modpack.toml:\n{:?}", &bad_keys) + "Training Modpack custom button\nconfiguration is invalid!\0", + &format!( + "The following keys are invalid in\nsd:/TrainingModpack/training_modpack.toml:\n\ + {:?}\n\nPossible Keys: {:#?}\0", &bad_keys, BUTTON_MAPPING.keys()) ); + false + } else { + true } +} - // HOLD - let mut global_hold = mutex_hold.lock(); - let vecopt_hold: Vec> = btnlist - .hold - .iter() - .map(|x| BUTTON_MAPPING.get(x.as_str())) - .collect(); - if vecopt_hold.iter().all(|x| x.is_some()) { - // All entries valid keys of BUTTON_MAPPING - global_hold.clear(); - global_hold.extend_from_slice( - &vecopt_hold - .into_iter() - .map(|x| *x.unwrap()) - .collect::>(), - ); - } - - // PRESS - let mut global_press = mutex_press.lock(); - let vecopt_press: Vec> = btnlist - .press - .into_iter() - .map(|x| BUTTON_MAPPING.get(x.as_str())) - .collect(); - if vecopt_press.iter().all(|x| x.is_some()) { - // All entries valid keys of BUTTON_MAPPING - global_press.clear(); - global_press.extend_from_slice( - &vecopt_press - .into_iter() - .map(|x| *x.unwrap()) - .collect::>(), - ); +pub fn save_all_btn_config_from_defaults() { + let conf = TopLevelBtnComboConfig { + button_config: BtnComboConfig { + open_menu: BtnList { hold: vec!["SPECIAL".to_string()], press: vec!["UPTAUNT".to_string()] }, + save_state: BtnList { hold: vec!["GRAB".to_string()], press: vec!["DOWNTAUNT".to_string()] }, + load_state: BtnList { hold: vec!["GRAB".to_string()], press: vec!["UPTAUNT".to_string()] }, + } + }; + unsafe { + // This println is necessary. Why?....... + println!("{:?}", &conf.button_config.load_state.press); + BUTTON_COMBO_CONFIG = conf.button_config; } } pub fn save_all_btn_config_from_toml(data: &str) { let conf: TopLevelBtnComboConfig = toml::from_str(data).unwrap(); - let open_menu_conf: BtnList = conf.button_config.open_menu; - let save_state_conf: BtnList = conf.button_config.save_state; - let load_state_conf: BtnList = conf.button_config.load_state; + unsafe { + // This println is necessary. Why?....... + println!("{:?}", &conf.button_config.load_state.press); + BUTTON_COMBO_CONFIG = conf.button_config; + } +} - save_btn_config(open_menu_conf, &OPEN_MENU_BTN_HOLD, &OPEN_MENU_BTN_PRESS); - save_btn_config(save_state_conf, &SAVE_STATE_BTN_HOLD, &SAVE_STATE_BTN_PRESS); - save_btn_config(load_state_conf, &LOAD_STATE_BTN_HOLD, &LOAD_STATE_BTN_PRESS); +pub fn combo_passes(module_accessor: *mut smash::app::BattleObjectModuleAccessor, combo: ButtonCombo) -> bool{ + unsafe { + let (hold, press) = match combo { + ButtonCombo::OpenMenu => (&BUTTON_COMBO_CONFIG.open_menu.hold, &BUTTON_COMBO_CONFIG.open_menu.press), + ButtonCombo::SaveState => (&BUTTON_COMBO_CONFIG.save_state.hold, &BUTTON_COMBO_CONFIG.save_state.press), + ButtonCombo::LoadState => (&BUTTON_COMBO_CONFIG.load_state.hold, &BUTTON_COMBO_CONFIG.load_state.press), + }; + hold.iter() + .map(|hold| *BUTTON_MAPPING.get(&*hold.to_uppercase()).unwrap()) + .all(|hold| ControlModule::check_button_on(module_accessor, hold)) + && press.iter() + .map(|press| *BUTTON_MAPPING.get(&*press.to_uppercase()).unwrap()) + .all(|press| ControlModule::check_button_trigger(module_accessor, press)) + } } pub const DEFAULT_BTN_CONFIG: &'static str = r#"[button_config] diff --git a/src/common/menu.rs b/src/common/menu.rs index 5d18fdd..295a409 100644 --- a/src/common/menu.rs +++ b/src/common/menu.rs @@ -36,15 +36,7 @@ pub unsafe fn menu_condition(module_accessor: &mut smash::app::BattleObjectModul // Only check for button combination if the counter is 0 (not locked out) match frame_counter::get_frame_count(FRAME_COUNTER_INDEX) { 0 => { - let open_menu_btn_hold = button_config::OPEN_MENU_BTN_HOLD.lock(); - let open_menu_btn_press = button_config::OPEN_MENU_BTN_PRESS.lock(); - let return_value: bool = open_menu_btn_hold - .iter() - .all(|btn| ControlModule::check_button_on(module_accessor, *btn)) - && open_menu_btn_press - .iter() - .all(|btn| ControlModule::check_button_trigger(module_accessor, *btn)); - return_value + button_config::combo_passes(module_accessor, button_config::ButtonCombo::OpenMenu) } 1..MENU_LOCKOUT_FRAMES => false, _ => { diff --git a/src/lib.rs b/src/lib.rs index 81f1433..92322ba 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -107,13 +107,16 @@ pub fn main() { if fs::metadata(combo_path).is_ok() { log!("Previous button combo settings found. Loading..."); let combo_conf = fs::read_to_string(&combo_path).unwrap(); - button_config::save_all_btn_config_from_toml(&combo_conf); + if button_config::validate_config(&combo_conf) { + button_config::save_all_btn_config_from_toml(&combo_conf); + } else { + button_config::save_all_btn_config_from_defaults(); + } } else { log!("No previous button combo file found. Creating..."); - std::fs::write(combo_path, button_config::DEFAULT_BTN_CONFIG) + fs::write(combo_path, button_config::DEFAULT_BTN_CONFIG) .expect("Failed to write button config conf file"); - // No need to run save_all_btn_config_from_toml() - // since the statics are preloaded with the defaults + button_config::save_all_btn_config_from_defaults(); } if is_emulator() { diff --git a/src/training/save_states.rs b/src/training/save_states.rs index cded56e..5d2aa2e 100644 --- a/src/training/save_states.rs +++ b/src/training/save_states.rs @@ -237,14 +237,7 @@ pub unsafe fn save_states(module_accessor: &mut app::BattleObjectModuleAccessor) && is_dead(module_accessor); let mut triggered_reset: bool = false; if !is_operation_cpu(module_accessor) { - let load_state_btn_hold = button_config::LOAD_STATE_BTN_HOLD.lock(); - let load_state_btn_press = button_config::LOAD_STATE_BTN_PRESS.lock(); - triggered_reset = load_state_btn_hold - .iter() - .all(|btn| ControlModule::check_button_on(module_accessor, *btn)) - && load_state_btn_press - .iter() - .all(|btn| ControlModule::check_button_trigger(module_accessor, *btn)); + triggered_reset = button_config::combo_passes(module_accessor, button_config::ButtonCombo::LoadState); } if (autoload_reset || triggered_reset) && !fighter_is_nana { if save_state.state == NoAction { @@ -430,16 +423,7 @@ pub unsafe fn save_states(module_accessor: &mut app::BattleObjectModuleAccessor) } // Grab + Dpad down: Save state - let save_state_btn_hold = button_config::SAVE_STATE_BTN_HOLD.lock(); - let save_state_btn_press = button_config::SAVE_STATE_BTN_PRESS.lock(); - let save_state_condition: bool = save_state_btn_hold - .iter() - .all(|btn| ControlModule::check_button_on(module_accessor, *btn)) - && save_state_btn_press - .iter() - .all(|btn| ControlModule::check_button_trigger(module_accessor, *btn)) - && !fighter_is_nana; - if save_state_condition { + if button_config::combo_passes(module_accessor, button_config::ButtonCombo::SaveState) { // Don't begin saving state if Nana's delayed input is captured MIRROR_STATE = 1.0; SAVE_STATE_PLAYER.state = Save;