From 595fd8b7e4f56a77e6857f352fb3b0015132780f Mon Sep 17 00:00:00 2001 From: jugeeya Date: Fri, 18 Aug 2023 02:05:32 -0700 Subject: [PATCH] Add support for raw inputs, menu option --- src/common/input.rs | 2 +- src/common/release.rs | 2 +- src/training/input_log.rs | 188 ++++++++++++++++++++++++++++++++++- src/training/ui/input_log.rs | 84 ++-------------- 4 files changed, 193 insertions(+), 83 deletions(-) diff --git a/src/common/input.rs b/src/common/input.rs index 1205db8..2c50720 100644 --- a/src/common/input.rs +++ b/src/common/input.rs @@ -55,7 +55,7 @@ pub struct ControlModuleStored { /// Re-ordered bitfield the game uses for buttons #[bitfield] -#[derive(Debug, Default, Copy, Clone)] +#[derive(Debug, Default, Copy, Clone, PartialEq, Eq)] #[repr(C)] pub struct ButtonBitfield { pub dpad_up: bool, diff --git a/src/common/release.rs b/src/common/release.rs index c707405..c2cda8a 100644 --- a/src/common/release.rs +++ b/src/common/release.rs @@ -12,7 +12,7 @@ use zip::ZipArchive; lazy_static! { pub static ref CURRENT_VERSION: Mutex = - Mutex::new(get_current_version().expect("Could not determine current version!")); + Mutex::new(get_current_version().unwrap_or("".to_string())); } #[derive(Debug)] diff --git a/src/training/input_log.rs b/src/training/input_log.rs index cd7612b..a7cba8f 100644 --- a/src/training/input_log.rs +++ b/src/training/input_log.rs @@ -1,9 +1,63 @@ +use itertools::Itertools; +use std::collections::VecDeque; + use crate::common::input::*; use lazy_static::lazy_static; use parking_lot::Mutex; +use skyline::nn::ui2d::ResColor; +use training_mod_consts::{InputDisplay, MENU}; use super::frame_counter; +const GREEN: ResColor = ResColor { + r: 0, + g: 255, + b: 0, + a: 255, +}; + +const RED: ResColor = ResColor { + r: 255, + g: 0, + b: 0, + a: 255, +}; + +const CYAN: ResColor = ResColor { + r: 0, + g: 255, + b: 255, + a: 255, +}; + +const BLUE: ResColor = ResColor { + r: 0, + g: 255, + b: 0, + a: 255, +}; + +const PURPLE: ResColor = ResColor { + r: 255, + g: 0, + b: 255, + a: 255, +}; + +pub const YELLOW: ResColor = ResColor { + r: 255, + g: 255, + b: 0, + a: 255, +}; + +pub const WHITE: ResColor = ResColor { + r: 255, + g: 255, + b: 255, + a: 255, +}; + static mut FRAME_COUNTER: usize = 0; pub fn init() { @@ -44,25 +98,146 @@ fn bin_stick_values(x: f32, y: f32) -> (DirectionStrength, f32) { } impl InputLog { - pub fn is_smash_different(&self, other: &InputLog) -> bool { + pub fn is_different(&self, other: &InputLog) -> bool { + unsafe { + match MENU.input_display { + InputDisplay::Smash => self.is_smash_different(other), + InputDisplay::Raw => self.is_raw_different(other), + InputDisplay::None => false, + } + } + } + + pub fn binned_lstick(&self) -> (DirectionStrength, f32) { + unsafe { + match MENU.input_display { + InputDisplay::Smash => self.smash_binned_lstick(), + InputDisplay::Raw => self.raw_binned_lstick(), + InputDisplay::None => panic!("Invalid input display to log"), + } + } + } + + pub fn binned_rstick(&self) -> (DirectionStrength, f32) { + unsafe { + match MENU.input_display { + InputDisplay::Smash => self.smash_binned_rstick(), + InputDisplay::Raw => self.raw_binned_rstick(), + InputDisplay::None => panic!("Invalid input display to log"), + } + } + } + + pub fn button_icons(&self) -> VecDeque<(&str, ResColor)> { + unsafe { + match MENU.input_display { + InputDisplay::Smash => self.smash_button_icons(), + InputDisplay::Raw => self.raw_button_icons(), + InputDisplay::None => panic!("Invalid input display to log"), + } + } + } + + fn smash_button_icons(&self) -> VecDeque<(&str, ResColor)> { + self.smash_inputs + .buttons + .to_vec() + .iter() + .filter_map(|button| { + Some(match *button { + Buttons::ATTACK | Buttons::ATTACK_RAW => ("A", GREEN), + Buttons::SPECIAL | Buttons::SPECIAL_RAW | Buttons::SPECIAL_RAW2 => ("B", RED), + Buttons::JUMP => ("X", CYAN), + Buttons::GUARD | Buttons::GUARD_HOLD => ("L", BLUE), + Buttons::CATCH => ("ZR", PURPLE), + Buttons::STOCK_SHARE => ("+", WHITE), + Buttons::APPEAL_HI => ("^", WHITE), + Buttons::APPEAL_LW => ("v", WHITE), + Buttons::APPEAL_SL => (">", WHITE), + Buttons::APPEAL_SR => ("<", WHITE), + _ => return None, + }) + }) + .unique_by(|(s, _)| *s) + .collect::>() + } + + fn raw_button_icons(&self) -> VecDeque<(&str, ResColor)> { + let buttons = self.raw_inputs.current_buttons; + let mut icons = VecDeque::new(); + if buttons.a() { + icons.push_front(("A", GREEN)); + } + if buttons.b() { + icons.push_front(("B", RED)); + } + if buttons.x() { + icons.push_front(("X", CYAN)); + } + if buttons.y() { + icons.push_front(("Y", CYAN)); + } + if buttons.l() || buttons.real_digital_l() { + icons.push_front(("L", BLUE)); + } + if buttons.r() || buttons.real_digital_r() { + icons.push_front(("R", BLUE)); + } + if buttons.zl() { + icons.push_front(("ZL", PURPLE)); + } + if buttons.zr() { + icons.push_front(("ZR", PURPLE)); + } + if buttons.plus() { + icons.push_front(("+", WHITE)); + } + if buttons.minus() { + icons.push_front(("-", WHITE)); + } + + icons + } + + fn is_smash_different(&self, other: &InputLog) -> bool { self.smash_inputs.buttons != other.smash_inputs.buttons || self.smash_binned_lstick() != other.smash_binned_lstick() || self.smash_binned_rstick() != other.smash_binned_rstick() } - pub fn smash_binned_lstick(&self) -> (DirectionStrength, f32) { + fn smash_binned_lstick(&self) -> (DirectionStrength, f32) { let x = self.smash_inputs.lstick_x as f32; let y = self.smash_inputs.lstick_y as f32; bin_stick_values(x, y) } - pub fn smash_binned_rstick(&self) -> (DirectionStrength, f32) { + fn smash_binned_rstick(&self) -> (DirectionStrength, f32) { let x = self.smash_inputs.rstick_x as f32; let y = self.smash_inputs.rstick_y as f32; bin_stick_values(x, y) } + + fn is_raw_different(&self, other: &InputLog) -> bool { + self.raw_inputs.current_buttons != other.raw_inputs.current_buttons + || self.raw_binned_lstick() != other.raw_binned_lstick() + || self.raw_binned_rstick() != other.raw_binned_rstick() + } + + fn raw_binned_lstick(&self) -> (DirectionStrength, f32) { + let x = self.raw_inputs.left_stick_x; + let y = self.raw_inputs.left_stick_y; + + bin_stick_values(x, y) + } + + fn raw_binned_rstick(&self) -> (DirectionStrength, f32) { + let x = self.raw_inputs.right_stick_x; + let y = self.raw_inputs.right_stick_y; + + bin_stick_values(x, y) + } } fn insert_in_place(array: &mut [T], value: T, index: usize) { @@ -85,6 +260,10 @@ pub fn handle_final_input_mapping( out: *mut MappedInputs, ) { unsafe { + if MENU.input_display == InputDisplay::None { + return; + } + if player_idx == 0 { let current_frame = frame_counter::get_frame_count(FRAME_COUNTER); // We should always be counting @@ -101,8 +280,7 @@ pub fn handle_final_input_mapping( let input_logs = &mut *P1_INPUT_LOGS.lock(); let latest_input_log = input_logs.first_mut().unwrap(); - // Use different "different" function depending on menu option - if latest_input_log.is_smash_different(&potential_input_log) { + if latest_input_log.is_different(&potential_input_log) { frame_counter::reset_frame_count(FRAME_COUNTER); // We should count this frame already frame_counter::tick_idx(FRAME_COUNTER); diff --git a/src/training/ui/input_log.rs b/src/training/ui/input_log.rs index 1362eb7..1c6de8d 100644 --- a/src/training/ui/input_log.rs +++ b/src/training/ui/input_log.rs @@ -1,13 +1,12 @@ use std::collections::VecDeque; -use itertools::Itertools; use skyline::nn::ui2d::*; use smash::ui2d::{SmashPane, SmashTextBox}; use training_mod_consts::{InputDisplay, MENU}; use crate::{ - common::{input::Buttons, menu::QUICK_MENU_ACTIVE}, - training::input_log::{DirectionStrength, InputLog, P1_INPUT_LOGS}, + common::menu::QUICK_MENU_ACTIVE, + training::input_log::{DirectionStrength, InputLog, P1_INPUT_LOGS, WHITE, YELLOW}, }; macro_rules! log_parent_fmt { @@ -16,80 +15,10 @@ macro_rules! log_parent_fmt { }; } -const GREEN: ResColor = ResColor { - r: 0, - g: 255, - b: 0, - a: 255, -}; - -const RED: ResColor = ResColor { - r: 255, - g: 0, - b: 0, - a: 255, -}; - -const CYAN: ResColor = ResColor { - r: 0, - g: 255, - b: 255, - a: 255, -}; - -const BLUE: ResColor = ResColor { - r: 0, - g: 255, - b: 0, - a: 255, -}; - -const PURPLE: ResColor = ResColor { - r: 255, - g: 0, - b: 255, - a: 255, -}; - -const YELLOW: ResColor = ResColor { - r: 255, - g: 255, - b: 0, - a: 255, -}; - -const WHITE: ResColor = ResColor { - r: 255, - g: 255, - b: 255, - a: 255, -}; - fn smash_inputs(log: &InputLog) -> VecDeque<(&str, ResColor)> { - let mut icons = log - .smash_inputs - .buttons - .to_vec() - .iter() - .filter_map(|button| { - Some(match *button { - Buttons::ATTACK | Buttons::ATTACK_RAW => ("A", GREEN), - Buttons::SPECIAL | Buttons::SPECIAL_RAW | Buttons::SPECIAL_RAW2 => ("B", RED), - Buttons::JUMP => ("X", CYAN), - Buttons::GUARD | Buttons::GUARD_HOLD => ("L", BLUE), - Buttons::CATCH => ("ZR", PURPLE), - Buttons::STOCK_SHARE => ("+", WHITE), - Buttons::APPEAL_HI => ("^", WHITE), - Buttons::APPEAL_LW => ("v", WHITE), - Buttons::APPEAL_SL => (">", WHITE), - Buttons::APPEAL_SR => ("<", WHITE), - _ => return None, - }) - }) - .unique_by(|(s, _)| *s) - .collect::>(); + let mut icons = log.button_icons(); - let (rstick_strength, _rstick_angle) = log.smash_binned_rstick(); + let (rstick_strength, _rstick_angle) = log.binned_rstick(); let rstick_icon = match rstick_strength { DirectionStrength::Strong => ">>", DirectionStrength::Weak => ">", @@ -100,7 +29,7 @@ fn smash_inputs(log: &InputLog) -> VecDeque<(&str, ResColor)> { icons.push_front((rstick_icon, YELLOW)); } - let (lstick_strength, _lstick_angle) = log.smash_binned_lstick(); + let (lstick_strength, _lstick_angle) = log.binned_lstick(); let lstick_icon = match lstick_strength { DirectionStrength::Strong => ">>", DirectionStrength::Weak => ">", @@ -120,6 +49,9 @@ unsafe fn draw_log(root_pane: &Pane, log_idx: usize, log: &InputLog) { .unwrap(); log_pane.set_visible(!QUICK_MENU_ACTIVE && MENU.input_display != InputDisplay::None); + if MENU.input_display == InputDisplay::None { + return; + } if log.ttl < 100 { // Fade out let alpha = (log.ttl as f32 / 100.0 * 255.0) as u8;