diff --git a/Cargo.toml b/Cargo.toml index f79445337c..73deb4ae4a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,15 +8,11 @@ version = "0.0.0-dev" authors = ["HDR Development Team"] edition = "2021" -[workspace.metadata.symbaker] -prefix = "hdr" - [workspace.dependencies] skyline = { git = "https://github.com/ultimate-research/skyline-rs" } skyline_smash = { git = "https://github.com/ultimate-research/skyline-smash", features = ["weak_l2cvalue"] } skyline-web = { git = "https://github.com/skyline-rs/skyline-web" } smashline = { git = "https://github.com/HDR-Development/smashline" } -# ssbusync = { git = "https://github.com/BlankMauser/ssbu-sync.git", tag = "1.0.3", default-features = false } proc-hitbox = { git = "https://github.com/HDR-Development/compile-time-smash-script" } proc-hitbox-macro = { git = "https://github.com/HDR-Development/compile-time-smash-script" } @@ -233,17 +229,17 @@ runtime-motion-patcher.git = "https://github.com/WuBoytH/runtime-motion-patcher" skyline.workspace = true skyline_smash.workspace = true smashline.workspace = true -# ssbusync = { git = "https://github.com/BlankMauser/ssbu-sync.git", tag = "1.0.3", default-features = false, features = ["disabler-symbol"] } skyline-web = { workspace = true, optional = true } utils.workspace = true hash40 = "1.2.0" smash-arc = { version = "0.6.0", features = ["rust-zstd", "smash-runtime"] } smash2 = { git = "https://github.com/WuBoytH/smash-rs", package = "smash"} rlua-lua53-sys = { git = "https://github.com/HDR-Development/rlua", branch = "smash" } +ultelier = { git = "https://github.com/BlankMauser/smash-ultelier.git", default-features = false, features = ["sync-guest"] } [patch.crates-io] +skyline = { git = "https://github.com/ultimate-research/skyline-rs" } nnsdk = { git = "https://github.com/ultimate-research/nnsdk-rs" } -libc = { git="https://github.com/rust-lang/libc", rev = "0.2.166"} [features] default = [ diff --git a/src/chara_select/match_load.rs b/src/chara_select/match_load.rs new file mode 100644 index 0000000000..97be979c28 --- /dev/null +++ b/src/chara_select/match_load.rs @@ -0,0 +1,97 @@ +use skyline::hooks::InlineCtx; +use smash2::app::FighterManager; +use smash::lib::lua_const::*; +use ultelier::sync_guest::{self as sync, BufferMode}; +static mut SYNC_GUEST_MISSING: bool = false; +static mut LAST_BUFFER_MODE: Option = None; + +unsafe fn update_ssbusync_buffer_mode() { + if SYNC_GUEST_MISSING { + return; + } + + let match_mode = utils::util::get_match_mode().0; + let player_count = if let Some(fighter_manager) = FighterManager::instance() { + fighter_manager.entry_count() + } else { + 0 + }; + + // only use double buffer mode for online modes with 2 or fewer players + // prioritize stability for offline matches + let online_modes = [ + 45, // online arena smash + 58 // local wireless smash + ]; + let desired_mode = if online_modes.contains(&match_mode) && player_count <= 2 { + BufferMode::Double + } else { + BufferMode::Triple + }; + + let current_mode = match sync::env_flags() { + Some(flags) => { + if flags.contains(sync::EnvironmentFlags::TRIPLE_ENABLED) { + BufferMode::Triple + } else { + BufferMode::Double + } + } + None => { + SYNC_GUEST_MISSING = true; + println!("SSBU Sync Guest is not running, skipping buffer mode update."); + return; + } + }; + + if current_mode == desired_mode { + LAST_BUFFER_MODE = Some(desired_mode); + println!("Buffer mode is already {:?}, no update needed.", desired_mode); + return; + } + println!("Updating buffer mode to {:?} from {:?} for match mode {} with {} active players", desired_mode, current_mode, match_mode, player_count); + + match sync::set_buffer_mode(desired_mode) { + Some(true) => { + LAST_BUFFER_MODE = Some(desired_mode); + } + Some(false) => {} + None => { + SYNC_GUEST_MISSING = true; + } + } +} + +#[skyline::hook(offset = 0x1b7b814, inline)] +unsafe fn match_load(ctx: &mut InlineCtx) { + update_ssbusync_buffer_mode(); + + if !utils::one_player::one_player_entry() { + return; + } + + let result_ptr = ctx.registers[22].x() as *const u64; + let pane = *result_ptr.add(1); + if pane == 0 { + return; + } + + let internal = *(pane as *const u64); + if internal == 0 { + return; + } + + let parent = *((internal as *const u8).add(0x18) as *const u64); + if parent == 0 { + return; + } + + // hide timer + *(parent as *mut u8).add(0x58) &= 0xFE; +} + +pub fn install() { + skyline::install_hooks!( + match_load, + ); +} diff --git a/src/chara_select/mod.rs b/src/chara_select/mod.rs index 54f6a6f701..8c87c298ea 100644 --- a/src/chara_select/mod.rs +++ b/src/chara_select/mod.rs @@ -18,6 +18,7 @@ use crate::CSS_FIRST; mod layout; mod random; mod player_port; +mod match_load; pub const KEY_MASK: u64 = 0xFFFFFF_0000000000; @@ -306,6 +307,7 @@ pub fn install() { layout::install(); random::install(); player_port::install(); + match_load::install(); // These patches are required to "undo" a stacked CSS diff --git a/src/chara_select/player_port.rs b/src/chara_select/player_port.rs index 79be9485f8..bba71c6ee5 100644 --- a/src/chara_select/player_port.rs +++ b/src/chara_select/player_port.rs @@ -1,7 +1,6 @@ use super::*; use ninput::*; use parking_lot::RwLock; -// use crate::vsync::SsbuSync; static ID_LIST: &[u32] = &[0, 1, 2, 3, 4, 5, 6, 7, 0x20]; @@ -220,19 +219,6 @@ unsafe fn css_main_loop(arg: *const CharaSelect) { data.enable_swap = true; data.root_card = instance.first_player as u64; } - - // TODO: implement buffer swap for >2 players - // if SsbuSync::ALLOW_BUFFER_SWAP() { - // let player_count = count_active_players(instance); - // crate::set_doubles_delay(player_count); - // ssbusync::Check_Buffer_Swap(); - // } - - // TODO: is this really the best way to check for online gamemodes? - // let is_online = (instance.max_players_allowed != 8 || instance.local_wireless != 0); - // if SsbuSync::SyncEnv::online_only() { - // SsbuSync::online::ToggleOnlineFix(is_online); - // } if !data.enable_swap || instance.ready_state != 0 { return original!()(arg); diff --git a/src/controls.rs b/src/controls.rs index d7a7f19ea1..4f38558574 100644 --- a/src/controls.rs +++ b/src/controls.rs @@ -1,5 +1,4 @@ use skyline::hooks::InlineCtx; -// use ssbusync::*; mod css; mod submenu; diff --git a/src/lib.rs b/src/lib.rs index 8c2c7b7358..e6be8c3adb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -39,8 +39,6 @@ mod online; #[cfg(feature = "main_nro")] mod matchup; -pub mod vsync; - use skyline::libc::c_char; use std::os::raw::c_void; #[cfg(feature = "main_nro")] @@ -446,7 +444,6 @@ fn save_report_stub(uid: *mut u8) { } pub fn main() { #[cfg(feature = "main_nro")] { - // vsync::setup_ssbu_sync(); quick_validate_install(); skyline::install_hooks!(change_version_string_hook); chara_select::install(); diff --git a/src/vsync.rs b/src/vsync.rs deleted file mode 100644 index 1cd18140b1..0000000000 --- a/src/vsync.rs +++ /dev/null @@ -1,50 +0,0 @@ -// pub use ssbusync as SsbuSync; -// use SsbuSync::*; - -// pub fn setup_ssbu_sync() { -// println!("[HDR] installing custom ssbusync path via Main \n"); -// let mut sync_config = SsbuSyncConfig::default(); -// sync_config.disable_vsync = true; -// sync_config.disable_pacer = false; -// sync_config.slow_pacer_bias = false; -// sync_config.enable_triple_buffer = false; -// sync_config.allow_buffer_swap = false; -// sync_config.smooth_ffa = false; -// sync_config.online_only = false; - -// // create a profile with ssbusync config -// // but we don't actually use the options that are stored in that profile if they are changed by the user -// SsbuSync::Get_Init_SsbuSync_Profile("HDR", &sync_config, 1.0); -// ssbusync::Install_SSBU_Sync(sync_config); - -// // if ssbusync::render::buffer_swap::subscribe_buffer_mode_change(on_buffer_switch) { -// // println!("[HDR] Subscribed to buffer switch \n"); -// // } else { -// // println!("[HDR] Failed to subscribe to buffer switch \n"); -// // } -// } - -// Work-around for setting input delay during doubles/FFAs -// pub fn set_doubles_delay(playercount: i32) -> bool { -// if (playercount > 2) { -// ssbusync::Enable_Triple_Buffer(); -// return true; -// } else { -// ssbusync::Enable_Double_Buffer(); -// return false; -// } -// } - -// fn on_buffer_switch(mode: ssbusync::render::buffer_swap::BufferMode) { -// println!("Buffer Successfully Switched: {:?} \n", mode) -// } - -// if ssbusync::SyncEnv::ALLOW_BUFFER_SWAP() { -// let player_count = count_active_players(instance); -// crate::set_doubles_delay(player_count); -// ssbusync::Check_Buffer_Swap(); -// } - -// if ssbusync::SyncEnv::online_only() { -// EmuNetplay::check_online_fix_emu(); -// } \ No newline at end of file diff --git a/symbaker.toml b/symbaker.toml deleted file mode 100644 index a57fe14190..0000000000 --- a/symbaker.toml +++ /dev/null @@ -1,6 +0,0 @@ -prefix = "hdr" -sep = "__" -priority = ["attr", "env_prefix", "config", "top_package", "workspace", "package", "crate"] - -[overrides] -# ssbusync = "hdr" diff --git a/utils/src/one_player.rs b/utils/src/one_player.rs index bd2c9f2de4..2b7dbe92b8 100644 --- a/utils/src/one_player.rs +++ b/utils/src/one_player.rs @@ -7,32 +7,6 @@ use utils_dyn::util::MATCH_EXITING; pub static IS_RULE_TIME: AtomicBool = AtomicBool::new(false); -#[skyline::hook(offset = 0x1b7b814, inline)] -unsafe fn match_load(ctx: &mut InlineCtx) { - if !one_player_entry() { - return; - } - - let result_ptr = ctx.registers[22].x() as *const u64; - let pane = *result_ptr.add(1); - if pane == 0 { - return; - } - - let internal = *(pane as *const u64); - if internal == 0 { - return; - } - - let parent = *((internal as *const u8).add(0x18) as *const u64); - if parent == 0 { - return; - } - - // hide timer - *(parent as *mut u8).add(0x58) &= 0xFE; -} - // Set the match timer to 99 minutes every frame in 1P mode so it never expires. #[skyline::hook(offset = 0x15812b8, inline)] unsafe fn once_per_frame(ctx: &mut InlineCtx) { @@ -93,7 +67,6 @@ pub fn install() { game_over_declare, prevent_match_end_transition, once_per_frame, - match_load, ); // Allow 0 CPUs in Training Mode menu