1
0
Fork 0
mirror of https://github.com/jugeeya/UltimateTrainingModpack.git synced 2025-02-26 02:50:23 +00:00

Add 10 input log spaces

This commit is contained in:
jugeeya 2023-08-15 15:09:10 -07:00
parent 37ac548d1d
commit c14b6cb4e2
6 changed files with 88 additions and 36 deletions

View file

@ -50,7 +50,8 @@ pub fn name_to_font_glyph(button: ButtonConfig, style: ControllerStyle) -> Optio
let is_gcc = style == ControllerStyle::GCController;
Some(match button {
ButtonConfig::A => 0xE0E0,
ButtonConfig::B => 0xE0E1,
// TODO: Find one that works in training...
ButtonConfig::B => 0xE0E0,
ButtonConfig::X => {
if is_gcc {
0xE206
@ -97,28 +98,28 @@ pub fn name_to_font_glyph(button: ButtonConfig, style: ControllerStyle) -> Optio
if is_gcc {
0xE209
} else {
0xE0EB
0xE079
}
}
ButtonConfig::DPAD_DOWN => {
if is_gcc {
0xE20A
} else {
0xE0EC
0xE07A
}
}
ButtonConfig::DPAD_LEFT => {
if is_gcc {
0xE20B
} else {
0xE0ED
0xE07B
}
}
ButtonConfig::DPAD_RIGHT => {
if is_gcc {
0xE20C
} else {
0xE0EE
0xE07C
}
}
ButtonConfig::PLUS => {

View file

@ -191,6 +191,7 @@ pub struct ControllerMapping {
//type Buttons = u32; // may need to actually implement (like label and such)? Not for now though
bitflags! {
#[derive(Default)]
pub struct Buttons: u32 {
const ATTACK = 0x1;
const SPECIAL = 0x2;
@ -278,7 +279,7 @@ pub struct SomeControllerStruct {
}
// Define struct used for final controller inputs
#[derive(Copy, Clone)]
#[derive(Copy, Clone, Default)]
#[repr(C)]
pub struct MappedInputs {
pub buttons: Buttons,

Binary file not shown.

View file

@ -1,23 +1,67 @@
use std::collections::VecDeque;
use crate::common::input::*;
use lazy_static::lazy_static;
use parking_lot::Mutex;
lazy_static! {
pub static ref P1_INPUT_MAPPINGS: Mutex<VecDeque<MappedInputs>> = Mutex::new(VecDeque::new());
pub const NUM_LOGS: usize = 10;
#[derive(Copy, Clone, Default)]
pub struct InputLog {
pub frames: u64,
pub raw_inputs: Controller,
pub smash_inputs: MappedInputs,
}
// TODO: how many
const NUM_INPUTS: usize = 120;
impl InputLog {
pub fn is_different(&self, other: &InputLog) -> bool {
// TODO: Vary raw vs smash based on menu option
pub fn handle_final_input_mapping(player_idx: i32, out: *mut MappedInputs) {
// TODO: Include direction binning checks
self.smash_inputs.buttons != other.smash_inputs.buttons
}
}
fn insert_in_place<T>(array: &mut [T], value: T, index: usize) {
array[index..].rotate_right(1);
array[index] = value;
}
fn insert_in_front<T>(array: &mut [T], value: T) {
insert_in_place(array, value, 0);
}
lazy_static! {
pub static ref P1_INPUT_LOGS: Mutex<[InputLog; NUM_LOGS]> =
Mutex::new([InputLog::default(); NUM_LOGS]);
}
pub fn handle_final_input_mapping(
player_idx: i32,
controller_struct: &SomeControllerStruct,
out: *mut MappedInputs,
) {
unsafe {
if player_idx == 0 {
let mut mappings = P1_INPUT_MAPPINGS.lock();
// TODO: Use frame counter to determine frame value
mappings.push_front(*out);
mappings.truncate(NUM_INPUTS);
let potential_input_log = InputLog {
frames: 1,
raw_inputs: *controller_struct.controller,
smash_inputs: *out,
};
let input_logs = &mut *P1_INPUT_LOGS.lock();
let latest_input_log = input_logs.first_mut();
if latest_input_log.is_none() {
insert_in_front(input_logs, potential_input_log);
return;
}
let latest_input_log = latest_input_log.unwrap();
if latest_input_log.is_different(&potential_input_log) {
insert_in_front(input_logs, potential_input_log);
} else {
latest_input_log.frames = std::cmp::min(latest_input_log.frames + 1, 99);
}
}
}
}

View file

@ -737,7 +737,7 @@ unsafe fn handle_final_input_mapping(
// MUTATES controller state
input_delay::handle_final_input_mapping(player_idx, out);
input_log::handle_final_input_mapping(player_idx, out);
input_log::handle_final_input_mapping(player_idx, controller_struct, out);
// Potentially apply input recording, thus with delay
// MUTATES controller state

View file

@ -9,7 +9,7 @@ use crate::{
input::Buttons,
menu::{P1_CONTROLLER_STYLE, QUICK_MENU_ACTIVE},
},
training::input_log::P1_INPUT_MAPPINGS,
training::input_log::{InputLog, P1_INPUT_LOGS},
};
use super::set_colored_icon_text;
@ -20,32 +20,21 @@ macro_rules! log_parent_fmt {
};
}
pub unsafe fn draw(root_pane: &Pane) {
let log_number = 0;
unsafe fn draw_log(root_pane: &Pane, log_idx: usize, log: &InputLog) {
let log_pane = root_pane
.find_pane_by_name_recursive(log_parent_fmt!(log_number))
.find_pane_by_name_recursive(log_parent_fmt!(log_idx))
.unwrap();
// TODO: And menu option for input log is on
log_pane.set_visible(!QUICK_MENU_ACTIVE);
let logs_ptr = P1_INPUT_MAPPINGS.data_ptr();
if logs_ptr.is_null() {
return;
}
let logs = &*logs_ptr;
let first_log = logs.front();
if first_log.is_none() {
return;
}
let first_log = first_log.unwrap();
let p1_style_ptr = P1_CONTROLLER_STYLE.data_ptr();
if p1_style_ptr.is_null() {
return;
}
let icons = first_log
let icons = log
.smash_inputs
.buttons
.to_vec()
.iter()
@ -69,10 +58,10 @@ pub unsafe fn draw(root_pane: &Pane) {
a: 255,
},
),
Buttons::JUMP | Buttons::FLICK_JUMP => (
Buttons::JUMP => (
name_to_font_glyph(ButtonConfig::X, *p1_style_ptr),
ResColor {
r: 255,
r: 0,
g: 255,
b: 255,
a: 255,
@ -179,9 +168,26 @@ pub unsafe fn draw(root_pane: &Pane) {
set_colored_icon_text(input_pane, &vec![icon.0], icon.1);
}
let frame_text = if log.frames > 0 {
format!("{}", log.frames)
} else {
"".to_string()
};
log_pane
.find_pane_by_name_recursive("FrameTxt")
.unwrap()
.as_textbox()
.set_text_string(format!("{}", logs.len()).as_str());
.set_text_string(frame_text.as_str());
}
pub unsafe fn draw(root_pane: &Pane) {
let logs_ptr = P1_INPUT_LOGS.data_ptr();
if logs_ptr.is_null() {
return;
}
let logs = &*logs_ptr;
for (log_idx, log) in logs.iter().enumerate() {
draw_log(root_pane, log_idx, log);
}
}