diff --git a/src/training/input_record.rs b/src/training/input_record.rs index 82ace20..ecccf36 100644 --- a/src/training/input_record.rs +++ b/src/training/input_record.rs @@ -48,9 +48,8 @@ use PossessionState::*; const STICK_NEUTRAL: f32 = 0.2; const STICK_CLAMP_MULTIPLIER: f32 = 1.0 / 120.0; // 120.0 = CLAMP_MAX -const FINAL_RECORD_MAX: usize = 150; // Maximum length for input recording sequences (capacity) +const FINAL_RECORD_MAX: usize = 600; // Maximum length for input recording sequences (capacity) const TOTAL_SLOT_COUNT: usize = 5; // Total number of input recording slots -pub static mut FINAL_RECORD_FRAME: usize = FINAL_RECORD_MAX; // The final frame to play back of the currently recorded sequence (size) pub static mut INPUT_RECORD: InputRecordState = InputRecordState::None; pub static mut INPUT_RECORD_FRAME: usize = 0; pub static mut POSSESSION: PossessionState = PossessionState::Player; @@ -62,10 +61,13 @@ pub static mut STARTING_STATUS: i32 = 0; // The first status entered in the reco // used to calculate if the input playback should begin before hitstun would normally end (hitstun cancel, monado art?) pub static mut CURRENT_RECORD_SLOT: usize = 0; // Which slot is being used for recording right now? Want to make sure this is synced with menu choices, maybe just use menu instead pub static mut CURRENT_PLAYBACK_SLOT: usize = 0; // Which slot is being used for playback right now? +pub static mut CURRENT_FRAME_LENGTH: usize = 60; lazy_static! { static ref P1_FINAL_MAPPING: Mutex<[[MappedInputs; FINAL_RECORD_MAX]; TOTAL_SLOT_COUNT]> = Mutex::new([[{ MappedInputs::default() }; FINAL_RECORD_MAX]; TOTAL_SLOT_COUNT]); + static ref P1_FRAME_LENGTH_MAPPING: Mutex<[usize; TOTAL_SLOT_COUNT]> = + Mutex::new([60usize; TOTAL_SLOT_COUNT]); static ref P1_STARTING_STATUSES: Mutex<[StartingStatus; TOTAL_SLOT_COUNT]> = Mutex::new([{ StartingStatus::Other }; TOTAL_SLOT_COUNT]); } @@ -182,23 +184,19 @@ pub unsafe fn get_command_flag_cat(module_accessor: &mut BattleObjectModuleAcces module_accessor, button_config::ButtonCombo::InputPlayback, ) { - //crate::common::raygun_printer::print_string(&mut *module_accessor, "PLAYBACK"); playback(MENU.playback_slot.get_random().into_idx().unwrap_or(0)); - println!("Playback Command Received!"); //debug } // Attack + Dpad Left: Record else if button_config::combo_passes_exclusive( module_accessor, button_config::ButtonCombo::InputRecord, ) { - //crate::common::raygun_printer::print_string(&mut *module_accessor, "RECORDING"); lockout_record(); - println!("Record Command Received!"); //debug } // may need to move this to another func if (INPUT_RECORD == Record || INPUT_RECORD == Playback) - && INPUT_RECORD_FRAME >= FINAL_RECORD_FRAME - 1 + && INPUT_RECORD_FRAME >= CURRENT_FRAME_LENGTH - 1 { INPUT_RECORD = None; POSSESSION = Player; @@ -282,6 +280,8 @@ pub unsafe fn lockout_record() { .for_each(|mapped_input| { *mapped_input = MappedInputs::default(); }); + CURRENT_FRAME_LENGTH = MENU.recording_frames.into_frames(); + P1_FRAME_LENGTH_MAPPING.lock()[CURRENT_RECORD_SLOT] = CURRENT_FRAME_LENGTH; LOCKOUT_FRAME = 30; // This needs to be this high or issues occur dropping shield - but does this cause problems when trying to record ledge? BUFFER_FRAME = 0; // Store the direction the CPU is facing when we initially record, so we can turn their inputs around if needed @@ -290,20 +290,6 @@ pub unsafe fn lockout_record() { CURRENT_LR = RECORDED_LR; } -pub unsafe fn _record() { - INPUT_RECORD = Record; - POSSESSION = Cpu; - // Reset mappings to nothing, and then start recording. Likely want to reset in case we cut off recording early. - P1_FINAL_MAPPING.lock()[CURRENT_RECORD_SLOT] - .iter_mut() - .for_each(|mapped_input| { - *mapped_input = MappedInputs::default(); - }); - INPUT_RECORD_FRAME = 0; - LOCKOUT_FRAME = 0; - BUFFER_FRAME = 0; -} - pub unsafe fn playback(slot: usize) { if INPUT_RECORD == Pause { println!("Tried to playback during lockout!"); @@ -328,6 +314,7 @@ pub unsafe fn playback(slot: usize) { ); CURRENT_PLAYBACK_SLOT = slot; + CURRENT_FRAME_LENGTH = P1_FRAME_LENGTH_MAPPING.lock()[CURRENT_PLAYBACK_SLOT]; INPUT_RECORD = Playback; POSSESSION = Player; INPUT_RECORD_FRAME = 0; @@ -360,6 +347,7 @@ pub unsafe fn playback_ledge(slot: usize) { ); CURRENT_PLAYBACK_SLOT = slot; + CURRENT_FRAME_LENGTH = P1_FRAME_LENGTH_MAPPING.lock()[CURRENT_PLAYBACK_SLOT]; INPUT_RECORD = Playback; POSSESSION = Player; @@ -524,7 +512,7 @@ unsafe fn set_cpu_controls(p_data: *mut *mut u8) { // When buffering an option, we keep inputting the first frame of input during the buffer window if BUFFER_FRAME > 0 { BUFFER_FRAME -= 1; - } else if INPUT_RECORD_FRAME < FINAL_RECORD_FRAME - 1 && POSSESSION != Standby { + } else if INPUT_RECORD_FRAME < CURRENT_FRAME_LENGTH - 1 && POSSESSION != Standby { INPUT_RECORD_FRAME += 1; } } diff --git a/training_mod_consts/src/lib.rs b/training_mod_consts/src/lib.rs index 3717258..00b6b47 100644 --- a/training_mod_consts/src/lib.rs +++ b/training_mod_consts/src/lib.rs @@ -77,6 +77,7 @@ pub struct TrainingModpackMenu { pub playback_slot: PlaybackSlot, pub playback_mash: OnOff, pub record_trigger: RecordTrigger, + pub recording_frames: RecordingFrames, pub hitstun_playback: HitstunPlayback, } @@ -173,6 +174,7 @@ pub static DEFAULTS_MENU: TrainingModpackMenu = TrainingModpackMenu { playback_slot: PlaybackSlot::S1, playback_mash: OnOff::On, record_trigger: RecordTrigger::None, //Command? + recording_frames: RecordingFrames::F150, hitstun_playback: HitstunPlayback::Hitstun, // TODO: alphabetize }; @@ -759,6 +761,13 @@ pub unsafe fn ui_menu(menu: TrainingModpackMenu) -> UiMenu<'static> { true, &(menu.record_trigger as u32), ); + input_tab.add_submenu_with_toggles::( + "Recording Frames", + "recording_frames", + "Recording Frames: Number of frames to record for in the current slot", + true, + &(menu.recording_frames as u32), + ); input_tab.add_submenu_with_toggles::( "Save State Playback", "save_state_playback", diff --git a/training_mod_consts/src/options.rs b/training_mod_consts/src/options.rs index 26c979c..1d3fa42 100644 --- a/training_mod_consts/src/options.rs +++ b/training_mod_consts/src/options.rs @@ -1410,3 +1410,72 @@ impl ToggleTrait for HitstunPlayback { HitstunPlayback::iter().map(|i| i as u32).collect() } } + +#[repr(u32)] +#[derive( + Debug, Clone, Copy, PartialEq, FromPrimitive, EnumIter, Serialize_repr, Deserialize_repr, +)] +pub enum RecordingFrames { + F60 = 0x1, + F90 = 0x2, + F120 = 0x4, + F150 = 0x8, + F180 = 0x10, + F210 = 0x20, + F240 = 0x40, + F270 = 0x80, + F300 = 0x100, + F330 = 0x200, + F360 = 0x400, + F390 = 0x800, + F420 = 0x1000, + F450 = 0x2000, + F480 = 0x4000, + F510 = 0x8000, + F540 = 0x10000, + F570 = 0x20000, + F600 = 0x40000, +} + +impl RecordingFrames { + pub fn as_str(self) -> Option<&'static str> { + use RecordingFrames::*; + Some(match self { + F60 => "60", + F90 => "90", + F120 => "120", + F150 => "150", + F180 => "180", + F210 => "210", + F240 => "240", + F270 => "270", + F300 => "300", + F330 => "330", + F360 => "360", + F390 => "390", + F420 => "420", + F450 => "450", + F480 => "480", + F510 => "510", + F540 => "540", + F570 => "570", + F600 => "600", + }) + } + + pub fn into_frames(self) -> usize { + (log_2(self as u32) as usize * 30) + 60 + } +} + +impl ToggleTrait for RecordingFrames { + fn to_toggle_strs() -> Vec<&'static str> { + RecordingFrames::iter() + .map(|i| i.as_str().unwrap_or("")) + .collect() + } + + fn to_toggle_vals() -> Vec { + RecordingFrames::iter().map(|i| i as u32).collect() + } +}