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:
parent
3b795c8362
commit
595fd8b7e4
4 changed files with 193 additions and 83 deletions
|
@ -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,
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue