Compare commits

..

2 Commits

Author SHA1 Message Date
Simon Gellis 9dfc942dfc
CLI flag to give P2 the controller 2026-02-20 00:02:04 -05:00
Simon Gellis d269082c8b
CLI flag to open player 2 (thx Elrinth) 2026-02-19 23:52:52 -05:00
3 changed files with 26 additions and 4 deletions

View File

@ -74,7 +74,7 @@ impl Application {
) -> Self { ) -> Self {
let wgpu = WgpuState::new(); let wgpu = WgpuState::new();
let icon = load_icon().ok().map(Arc::new); let icon = load_icon().ok().map(Arc::new);
let mappings = MappingProvider::new(persistence.clone()); let mappings = MappingProvider::new(persistence.clone(), args.player2_controller);
let shortcuts = ShortcutProvider::new(persistence.clone()); let shortcuts = ShortcutProvider::new(persistence.clone());
let controllers = ControllerManager::new(client.clone(), &mappings); let controllers = ControllerManager::new(client.clone(), &mappings);
let memory = Arc::new(MemoryClient::new(client.clone())); let memory = Arc::new(MemoryClient::new(client.clone()));
@ -84,7 +84,7 @@ impl Application {
let proxy = proxy.clone(); let proxy = proxy.clone();
thread::spawn(|| process_gamepad_input(mappings, proxy)); thread::spawn(|| process_gamepad_input(mappings, proxy));
} }
Self { let app = Self {
icon, icon,
wgpu, wgpu,
client, client,
@ -106,7 +106,16 @@ impl Application {
init_framebuffers: args.frame_buffers, init_framebuffers: args.frame_buffers,
init_registers: args.registers, init_registers: args.registers,
init_terminal: args.terminal, init_terminal: args.terminal,
};
if args.player2 {
app.client
.send_command(EmulatorCommand::StartSecondSim(args.rom.clone()));
app.proxy
.send_event(UserEvent::OpenPlayer2)
.expect("Failed to open Player 2 window");
} }
app
} }
fn open(&mut self, event_loop: &ActiveEventLoop, window: Box<dyn AppWindow>) { fn open(&mut self, event_loop: &ActiveEventLoop, window: Box<dyn AppWindow>) {

View File

@ -40,6 +40,12 @@ pub struct CliArgs {
/// Watch ROM files for changes, automatically reload /// Watch ROM files for changes, automatically reload
#[arg(short, long)] #[arg(short, long)]
pub watch: bool, pub watch: bool,
/// Automatically open Player 2 for multiplayer
#[arg(long)]
pub player2: bool,
/// Map the first connected controller to Player 2
#[arg(long)]
pub player2_controller: bool,
} }
pub const COLOR_PRESETS: [[Color32; 2]; 3] = [ pub const COLOR_PRESETS: [[Color32; 2]; 3] = [

View File

@ -272,13 +272,14 @@ impl Mappings for InputMapping {
#[derive(Clone)] #[derive(Clone)]
pub struct MappingProvider { pub struct MappingProvider {
persistence: Persistence, persistence: Persistence,
first_gamepad_is_p2: bool,
device_mappings: Arc<RwLock<HashMap<DeviceId, Arc<RwLock<GamepadMapping>>>>>, device_mappings: Arc<RwLock<HashMap<DeviceId, Arc<RwLock<GamepadMapping>>>>>,
sim_mappings: HashMap<SimId, Arc<RwLock<InputMapping>>>, sim_mappings: HashMap<SimId, Arc<RwLock<InputMapping>>>,
gamepad_info: Arc<RwLock<HashMap<GamepadId, GamepadInfo>>>, gamepad_info: Arc<RwLock<HashMap<GamepadId, GamepadInfo>>>,
} }
impl MappingProvider { impl MappingProvider {
pub fn new(persistence: Persistence) -> Self { pub fn new(persistence: Persistence, first_gamepad_is_p2: bool) -> Self {
let mut sim_mappings = HashMap::new(); let mut sim_mappings = HashMap::new();
let mut device_mappings = HashMap::new(); let mut device_mappings = HashMap::new();
@ -307,6 +308,7 @@ impl MappingProvider {
device_mappings: Arc::new(RwLock::new(device_mappings)), device_mappings: Arc::new(RwLock::new(device_mappings)),
gamepad_info: Arc::new(RwLock::new(HashMap::new())), gamepad_info: Arc::new(RwLock::new(HashMap::new())),
sim_mappings, sim_mappings,
first_gamepad_is_p2,
} }
} }
@ -338,7 +340,12 @@ impl MappingProvider {
.clone(); .clone();
drop(lock); drop(lock);
let mut lock = self.gamepad_info.write().unwrap(); let mut lock = self.gamepad_info.write().unwrap();
let bound_to = SimId::values() let players = if self.first_gamepad_is_p2 {
vec![SimId::Player2, SimId::Player1]
} else {
vec![SimId::Player1, SimId::Player2]
};
let bound_to = players
.into_iter() .into_iter()
.find(|sim_id| lock.values().all(|info| info.bound_to != Some(*sim_id))); .find(|sim_id| lock.values().all(|info| info.bound_to != Some(*sim_id)));
if let Entry::Vacant(entry) = lock.entry(gamepad.id()) { if let Entry::Vacant(entry) = lock.entry(gamepad.id()) {