1
0
Fork 0
mirror of https://github.com/jugeeya/UltimateTrainingModpack.git synced 2024-12-11 02:49:49 +00:00

Add support for raw inputs, menu option

This commit is contained in:
jugeeya 2023-08-18 02:05:32 -07:00
parent 3b795c8362
commit 595fd8b7e4
4 changed files with 193 additions and 83 deletions

View file

@ -55,7 +55,7 @@ pub struct ControlModuleStored {
/// Re-ordered bitfield the game uses for buttons /// Re-ordered bitfield the game uses for buttons
#[bitfield] #[bitfield]
#[derive(Debug, Default, Copy, Clone)] #[derive(Debug, Default, Copy, Clone, PartialEq, Eq)]
#[repr(C)] #[repr(C)]
pub struct ButtonBitfield { pub struct ButtonBitfield {
pub dpad_up: bool, pub dpad_up: bool,

View file

@ -12,7 +12,7 @@ use zip::ZipArchive;
lazy_static! { lazy_static! {
pub static ref CURRENT_VERSION: Mutex<String> = pub static ref CURRENT_VERSION: Mutex<String> =
Mutex::new(get_current_version().expect("Could not determine current version!")); Mutex::new(get_current_version().unwrap_or("".to_string()));
} }
#[derive(Debug)] #[derive(Debug)]

View file

@ -1,9 +1,63 @@
use itertools::Itertools;
use std::collections::VecDeque;
use crate::common::input::*; use crate::common::input::*;
use lazy_static::lazy_static; use lazy_static::lazy_static;
use parking_lot::Mutex; use parking_lot::Mutex;
use skyline::nn::ui2d::ResColor;
use training_mod_consts::{InputDisplay, MENU};
use super::frame_counter; 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; static mut FRAME_COUNTER: usize = 0;
pub fn init() { pub fn init() {
@ -44,25 +98,146 @@ fn bin_stick_values(x: f32, y: f32) -> (DirectionStrength, f32) {
} }
impl InputLog { 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::<VecDeque<(&str, ResColor)>>()
}
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_inputs.buttons != other.smash_inputs.buttons
|| self.smash_binned_lstick() != other.smash_binned_lstick() || self.smash_binned_lstick() != other.smash_binned_lstick()
|| self.smash_binned_rstick() != other.smash_binned_rstick() || 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 x = self.smash_inputs.lstick_x as f32;
let y = self.smash_inputs.lstick_y as f32; let y = self.smash_inputs.lstick_y as f32;
bin_stick_values(x, y) 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 x = self.smash_inputs.rstick_x as f32;
let y = self.smash_inputs.rstick_y as f32; let y = self.smash_inputs.rstick_y as f32;
bin_stick_values(x, y) 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<T>(array: &mut [T], value: T, index: usize) { fn insert_in_place<T>(array: &mut [T], value: T, index: usize) {
@ -85,6 +260,10 @@ pub fn handle_final_input_mapping(
out: *mut MappedInputs, out: *mut MappedInputs,
) { ) {
unsafe { unsafe {
if MENU.input_display == InputDisplay::None {
return;
}
if player_idx == 0 { if player_idx == 0 {
let current_frame = frame_counter::get_frame_count(FRAME_COUNTER); let current_frame = frame_counter::get_frame_count(FRAME_COUNTER);
// We should always be counting // We should always be counting
@ -101,8 +280,7 @@ pub fn handle_final_input_mapping(
let input_logs = &mut *P1_INPUT_LOGS.lock(); let input_logs = &mut *P1_INPUT_LOGS.lock();
let latest_input_log = input_logs.first_mut().unwrap(); let latest_input_log = input_logs.first_mut().unwrap();
// Use different "different" function depending on menu option if latest_input_log.is_different(&potential_input_log) {
if latest_input_log.is_smash_different(&potential_input_log) {
frame_counter::reset_frame_count(FRAME_COUNTER); frame_counter::reset_frame_count(FRAME_COUNTER);
// We should count this frame already // We should count this frame already
frame_counter::tick_idx(FRAME_COUNTER); frame_counter::tick_idx(FRAME_COUNTER);

View file

@ -1,13 +1,12 @@
use std::collections::VecDeque; use std::collections::VecDeque;
use itertools::Itertools;
use skyline::nn::ui2d::*; use skyline::nn::ui2d::*;
use smash::ui2d::{SmashPane, SmashTextBox}; use smash::ui2d::{SmashPane, SmashTextBox};
use training_mod_consts::{InputDisplay, MENU}; use training_mod_consts::{InputDisplay, MENU};
use crate::{ use crate::{
common::{input::Buttons, menu::QUICK_MENU_ACTIVE}, common::menu::QUICK_MENU_ACTIVE,
training::input_log::{DirectionStrength, InputLog, P1_INPUT_LOGS}, training::input_log::{DirectionStrength, InputLog, P1_INPUT_LOGS, WHITE, YELLOW},
}; };
macro_rules! log_parent_fmt { 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)> { fn smash_inputs(log: &InputLog) -> VecDeque<(&str, ResColor)> {
let mut icons = log let mut icons = log.button_icons();
.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::<VecDeque<(&str, ResColor)>>();
let (rstick_strength, _rstick_angle) = log.smash_binned_rstick(); let (rstick_strength, _rstick_angle) = log.binned_rstick();
let rstick_icon = match rstick_strength { let rstick_icon = match rstick_strength {
DirectionStrength::Strong => ">>", DirectionStrength::Strong => ">>",
DirectionStrength::Weak => ">", DirectionStrength::Weak => ">",
@ -100,7 +29,7 @@ fn smash_inputs(log: &InputLog) -> VecDeque<(&str, ResColor)> {
icons.push_front((rstick_icon, YELLOW)); 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 { let lstick_icon = match lstick_strength {
DirectionStrength::Strong => ">>", DirectionStrength::Strong => ">>",
DirectionStrength::Weak => ">", DirectionStrength::Weak => ">",
@ -120,6 +49,9 @@ unsafe fn draw_log(root_pane: &Pane, log_idx: usize, log: &InputLog) {
.unwrap(); .unwrap();
log_pane.set_visible(!QUICK_MENU_ACTIVE && MENU.input_display != InputDisplay::None); log_pane.set_visible(!QUICK_MENU_ACTIVE && MENU.input_display != InputDisplay::None);
if MENU.input_display == InputDisplay::None {
return;
}
if log.ttl < 100 { if log.ttl < 100 {
// Fade out // Fade out
let alpha = (log.ttl as f32 / 100.0 * 255.0) as u8; let alpha = (log.ttl as f32 / 100.0 * 255.0) as u8;