From 14b76e3c2b043b152dab628cbc4ce8eab0c1f280 Mon Sep 17 00:00:00 2001 From: jugeeya Date: Thu, 7 Sep 2023 12:49:08 -0700 Subject: [PATCH] UI Optimizations: Reduce stutter in menu and input display (#627) * Initial * Small fix * Set drawn logs... * Mutable, formatting * Update lib.rs --- src/common/menu.rs | 2 ++ src/training/input_log.rs | 9 +++++++++ src/training/ui/input_log.rs | 18 +++++++++++++++--- src/training/ui/menu.rs | 10 +++++++++- training_mod_consts/src/lib.rs | 2 +- 5 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/common/menu.rs b/src/common/menu.rs index dac7a00..01ffca8 100644 --- a/src/common/menu.rs +++ b/src/common/menu.rs @@ -111,6 +111,7 @@ lazy_static! { (RUp, 0), ])) }; + pub static ref MENU_RECEIVED_INPUT: Mutex = Mutex::new(true); } pub static MENU_CLOSE_FRAME_COUNTER: Lazy = @@ -262,6 +263,7 @@ pub fn handle_final_input_mapping( if received_input { direction_hold_frames.iter_mut().for_each(|(_, f)| *f = 0); set_menu_from_json(&app.get_menu_selections()); + *MENU_RECEIVED_INPUT.lock() = true; } } } diff --git a/src/training/input_log.rs b/src/training/input_log.rs index 1773938..4d67594 100644 --- a/src/training/input_log.rs +++ b/src/training/input_log.rs @@ -85,6 +85,13 @@ pub struct InputLog { pub fighter_kind: i32, } +impl PartialEq for InputLog { + fn eq(&self, other: &Self) -> bool { + self.frames == other.frames && !self.is_different(other) + } +} +impl Eq for InputLog {} + const WALK_THRESHOLD_X: i8 = 20; const _DASH_THRESHOLD_X: i8 = 102; const DEADZONE_THRESHOLD_Y: i8 = 30; @@ -273,6 +280,8 @@ fn insert_in_front(array: &mut [T], value: T) { lazy_static! { pub static ref P1_INPUT_LOGS: Mutex<[InputLog; NUM_LOGS]> = Mutex::new([InputLog::default(); NUM_LOGS]); + pub static ref DRAWN_LOGS: Mutex<[InputLog; NUM_LOGS]> = + Mutex::new([InputLog::default(); NUM_LOGS]); } pub fn handle_final_input_mapping( diff --git a/src/training/ui/input_log.rs b/src/training/ui/input_log.rs index 8774d25..a562040 100644 --- a/src/training/ui/input_log.rs +++ b/src/training/ui/input_log.rs @@ -7,7 +7,7 @@ use training_mod_consts::{InputDisplay, MENU}; use crate::{ common::{consts::status_display_name, menu::QUICK_MENU_ACTIVE}, training::{ - input_log::{DirectionStrength, InputLog, P1_INPUT_LOGS, WHITE, YELLOW}, + input_log::{DirectionStrength, InputLog, DRAWN_LOGS, P1_INPUT_LOGS, WHITE, YELLOW}, ui::{fade_out, menu::VANILLA_MENU_ACTIVE}, }, }; @@ -66,7 +66,7 @@ fn get_input_icons(log: &InputLog) -> VecDeque<(&str, ResColor)> { icons } -unsafe fn draw_log(root_pane: &Pane, log_idx: usize, log: &InputLog) { +unsafe fn draw_log(root_pane: &Pane, log_idx: usize, log: &InputLog, drawn_log: &mut InputLog) { let log_pane = root_pane .find_pane_by_name_recursive(log_parent_fmt!(log_idx)) .unwrap(); @@ -80,6 +80,13 @@ unsafe fn draw_log(root_pane: &Pane, log_idx: usize, log: &InputLog) { const FADE_FRAMES: u32 = 200; fade_out(log_pane, log.ttl, FADE_FRAMES); + // Don't redraw + if *log == *drawn_log { + return; + } else { + *drawn_log = *log; + } + let icons = get_input_icons(log); // Empty them first @@ -171,8 +178,13 @@ pub unsafe fn draw(root_pane: &Pane) { return; } let logs = &*logs_ptr; + let drawn_logs_ptr = DRAWN_LOGS.data_ptr(); + if drawn_logs_ptr.is_null() { + return; + } + let drawn_logs = &mut *drawn_logs_ptr; for (log_idx, log) in logs.iter().enumerate() { - draw_log(root_pane, log_idx, log); + draw_log(root_pane, log_idx, log, &mut drawn_logs[log_idx]); } } diff --git a/src/training/ui/menu.rs b/src/training/ui/menu.rs index 419b4d9..58d8a9f 100644 --- a/src/training/ui/menu.rs +++ b/src/training/ui/menu.rs @@ -6,7 +6,7 @@ use smash::ui2d::{SmashPane, SmashTextBox}; use training_mod_tui::gauge::GaugeState; use training_mod_tui::{App, AppPage, NUM_LISTS}; -use crate::common::menu::{MENU_CLOSE_FRAME_COUNTER, MENU_CLOSE_WAIT_FRAMES}; +use crate::common::menu::{MENU_CLOSE_FRAME_COUNTER, MENU_CLOSE_WAIT_FRAMES, MENU_RECEIVED_INPUT}; use crate::training::frame_counter; use crate::{common, common::menu::QUICK_MENU_ACTIVE, input::*}; @@ -390,6 +390,14 @@ pub unsafe fn draw(root_pane: &Pane) { overall_parent_pane.global_alpha = 0; } + // Only submit updates if we have received input + let received_input = &mut *MENU_RECEIVED_INPUT.data_ptr(); + if !*received_input { + return; + } else { + *received_input = false; + } + // Make all invisible first (0..NUM_MENU_TEXT_OPTIONS).for_each(|idx| { let col_idx = idx % NUM_LISTS; diff --git a/training_mod_consts/src/lib.rs b/training_mod_consts/src/lib.rs index 4f92cab..8db3fca 100644 --- a/training_mod_consts/src/lib.rs +++ b/training_mod_consts/src/lib.rs @@ -144,7 +144,7 @@ pub static DEFAULTS_MENU: TrainingModpackMenu = TrainingModpackMenu { frame_advantage: OnOff::Off, full_hop: BoolFlag::TRUE, hitbox_vis: OnOff::Off, - input_display: InputDisplay::None, + input_display: InputDisplay::Smash, input_display_status: OnOff::Off, hud: OnOff::On, input_delay: Delay::D0,