1use crate::input::{GenericInput, Hotkey, KeyboardInput}; 2use gb_config::GameBoyButton; 3use gba_config::GbaButton; 4use genesis_config::{GenesisButton, GenesisControllerType}; 5use jgenesis_common::input::Player; 6use jgenesis_proc_macros::{ConfigDisplay, EnumAll, EnumDisplay}; 7use nes_config::NesButton; 8use pce_config::PceButton; 9use sdl3::keyboard::Keycode; 10use sdl3::mouse::MouseButton; 11use serde::{Deserialize, Serialize}; 12use smsgg_config::SmsGgButton; 13use snes_config::SnesButton; 14use std::fmt::Formatter; 15use std::sync::LazyLock; 16 17pub type ButtonMappingVec<'a, Button> = Vec<((Button, Player), &'a Vec<GenericInput>)>; 18pub type HotkeyMappingVec<'a> = Vec<(Hotkey, &'a Vec<GenericInput>)>; 19 20macro_rules! key_input { 21 ($key:ident) => { 22 Some(vec![GenericInput::Keyboard(KeyboardInput::Keycode(Keycode::$key))]) 23 }; 24} 25 26macro_rules! define_controller_mapping { 27 ( 28 $name:ident, 29 $button_enum:ident, 30 [$($field:ident: $enum_value:ident),* $(,)?] $(,)? 31 ) => { 32 #[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)] 33 pub struct $name { 34 $( 35 pub $field: Option<Vec<GenericInput>>, 36 )* 37 } 38 39 impl $name { 40 pub fn to_mapping_vec<'a>(&'a self, player: Player, out: &mut ButtonMappingVec<'a, $button_enum>) { 41 $( 42 if let Some(mapping) = &self.$field { 43 out.push((($button_enum::$enum_value, player), mapping)); 44 } 45 )* 46 } 47 48 #[must_use] 49 pub fn access_value(&mut self, button: $button_enum) -> Option<&mut Option<Vec<GenericInput>>> { 50 match button { 51 $( 52 $button_enum::$enum_value => Some(&mut self.$field), 53 )* 54 #[allow(unreachable_patterns)] 55 _ => None, 56 } 57 } 58 59 #[must_use] 60 pub fn access_value_shared(&self, button: $button_enum) -> Option<&Option<Vec<GenericInput>>> { 61 match button { 62 $( 63 $button_enum::$enum_value => Some(&self.$field), 64 )* 65 #[allow(unreachable_patterns)] 66 _ => None, 67 } 68 } 69 70 pub fn clone_from(&mut self, other: &Self, buttons: &[$button_enum]) { 71 for &button in buttons { 72 if let Some(value) = self.access_value(button) 73 && let Some(other_value) = other.access_value_shared(button) 74 { 75 *value = other_value.clone(); 76 } 77 } 78 } 79 } 80 81 impl std::fmt::Display for $name { 82 // Last `first_mapping = false` will be flagged as unused without this #[allow(..)] 83 #[allow(unused_assignments)] 84 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { 85 fmt_input_mapping(&[ 86 $( 87 ($button_enum::$enum_value, &self.$field), 88 )* 89 ], f) 90 } 91 } 92 } 93} 94 95fn fmt_input_mapping<Button: std::fmt::Display>( 96 buttons: &[(Button, &Option<Vec<GenericInput>>)], 97 f: &mut Formatter<'_>, 98) -> std::fmt::Result { 99 write!(f, "{{ ")?; 100 101 let mut first_mapping = true; 102 for (button, mapping) in buttons { 103 let Some(mapping) = mapping else { continue }; 104 if mapping.is_empty() { 105 continue; 106 } 107 108 if !first_mapping { 109 write!(f, ", ")?; 110 } 111 first_mapping = false; 112 113 write!(f, "{button} -> '")?; 114 fmt_input_mapping_field(mapping, f)?; 115 write!(f, "'")?; 116 } 117 118 write!(f, " }}") 119} 120 121fn fmt_input_mapping_field(mapping: &[GenericInput], f: &mut Formatter<'_>) -> std::fmt::Result { 122 if mapping.is_empty() { 123 return Ok(()); 124 } 125 126 let mut first_input = true; 127 for input in mapping { 128 if !first_input { 129 write!(f, " + ")?; 130 } 131 first_input = false; 132 133 write!(f, "{input}")?; 134 } 135 136 Ok(()) 137} 138 139macro_rules! impl_to_mapping_vec { 140 ($button:ty) => { 141 #[must_use] 142 pub fn to_mapping_vec(&self) -> ButtonMappingVec<'_, $button> { 143 let mut out = Vec::new(); 144 145 self.mapping_1.to_mapping_vec(&mut out); 146 self.mapping_2.to_mapping_vec(&mut out); 147 148 out 149 } 150 }; 151} 152 153macro_rules! impl_to_turbo_mapping_vec { 154 ($button:ty) => { 155 impl_to_turbo_mapping_vec!($button, [(One, p1_turbo), (Two, p2_turbo)]); 156 }; 157 ($button:ty, [$(($player:ident, $field:ident)),* $(,)?]) => { 158 #[must_use] 159 pub fn to_turbo_mapping_vec(&self) -> ButtonMappingVec<'_, $button> { 160 let mut out = Vec::new(); 161 162 for mapping in [&self.mapping_1, &self.mapping_2] { 163 $( 164 mapping.$field.to_mapping_vec(Player::$player, &mut out); 165 )* 166 } 167 168 out 169 } 170 }; 171} 172 173macro_rules! impl_player_mapping { 174 ($mapping:ty) => { 175 impl_player_mapping!($mapping, [(One, p1, p1_turbo), (Two, p2, p2_turbo)]); 176 }; 177 ($mapping:ty, [$(($player:ident, $field:ident, $turbo_field:ident)),* $(,)?]) => { 178 #[must_use] 179 pub fn player_mapping(&mut self, player: Player, turbo: bool) -> Option<&mut $mapping> { 180 match (player, turbo) { 181 $( 182 (Player::$player, false) => Some(&mut self.$field), 183 (Player::$player, true) => Some(&mut self.$turbo_field), 184 )* 185 _ => None, 186 } 187 } 188 }; 189} 190 191define_controller_mapping!(SmsGgControllerMapping, SmsGgButton, [ 192 up: Up, 193 left: Left, 194 right: Right, 195 down: Down, 196 button1: Button1, 197 button2: Button2, 198]); 199 200impl SmsGgControllerMapping { 201 #[must_use] 202 pub fn keyboard_arrows() -> Self { 203 Self { 204 up: key_input!(Up), 205 left: key_input!(Left), 206 right: key_input!(Right), 207 down: key_input!(Down), 208 button1: key_input!(S), 209 button2: key_input!(A), 210 } 211 } 212 213 #[must_use] 214 pub fn keyboard_wasd() -> Self { 215 Self { 216 up: key_input!(W), 217 left: key_input!(A), 218 right: key_input!(D), 219 down: key_input!(S), 220 button1: key_input!(K), 221 button2: key_input!(L), 222 } 223 } 224 225 #[must_use] 226 pub fn keyboard_pause() -> Option<Vec<GenericInput>> { 227 key_input!(Return) 228 } 229} 230 231#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize, ConfigDisplay)] 232#[serde(default)] 233pub struct SmsGgInputMapping { 234 pub p1: SmsGgControllerMapping, 235 pub p2: SmsGgControllerMapping, 236 pub p1_turbo: SmsGgControllerMapping, 237 pub p2_turbo: SmsGgControllerMapping, 238 #[cfg_display(debug_fmt)] 239 pub pause: Option<Vec<GenericInput>>, 240} 241 242impl SmsGgInputMapping { 243 impl_player_mapping!(SmsGgControllerMapping); 244 245 pub fn to_mapping_vec<'a>(&'a self, out: &mut ButtonMappingVec<'a, SmsGgButton>) { 246 self.p1.to_mapping_vec(Player::One, out); 247 self.p2.to_mapping_vec(Player::Two, out); 248 249 if let Some(pause) = &self.pause { 250 out.push(((SmsGgButton::Pause, Player::One), pause)); 251 } 252 } 253} 254 255#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, ConfigDisplay)] 256#[serde(default)] 257pub struct SmsGgInputConfig { 258 #[cfg_display(indent_nested)] 259 pub mapping_1: SmsGgInputMapping, 260 #[cfg_display(indent_nested)] 261 pub mapping_2: SmsGgInputMapping, 262} 263 264impl SmsGgInputConfig { 265 impl_to_mapping_vec!(SmsGgButton); 266 267 impl_to_turbo_mapping_vec!(SmsGgButton); 268} 269 270fn default_smsgg_mapping_1() -> SmsGgInputMapping { 271 SmsGgInputMapping { 272 p1: SmsGgControllerMapping::keyboard_arrows(), 273 p2: SmsGgControllerMapping::default(), 274 p1_turbo: SmsGgControllerMapping::default(), 275 p2_turbo: SmsGgControllerMapping::default(), 276 pause: key_input!(Return), 277 } 278} 279 280impl Default for SmsGgInputConfig { 281 fn default() -> Self { 282 Self { mapping_1: default_smsgg_mapping_1(), mapping_2: SmsGgInputMapping::default() } 283 } 284} 285 286define_controller_mapping!(GenesisControllerMapping, GenesisButton, [ 287 up: Up, 288 left: Left, 289 right: Right, 290 down: Down, 291 a: A, 292 b: B, 293 c: C, 294 x: X, 295 y: Y, 296 z: Z, 297 start: Start, 298 mode: Mode, 299 mega_mouse_left: MegaMouseLeft, 300 mega_mouse_right: MegaMouseRight, 301 mega_mouse_middle: MegaMouseMiddle, 302 mega_mouse_start: MegaMouseStart, 303 xe1ap_analog_left: Xe1apAnalogLeft, 304 xe1ap_analog_right: Xe1apAnalogRight, 305 xe1ap_analog_up: Xe1apAnalogUp, 306 xe1ap_analog_down: Xe1apAnalogDown, 307 xe1ap_slider_forward: Xe1apSliderForward, 308 xe1ap_slider_backward: Xe1apSliderBackward, 309 xe1ap_a: Xe1apA, 310 xe1ap_b: Xe1apB, 311 xe1ap_c: Xe1apC, 312 xe1ap_d: Xe1apD, 313 xe1ap_e1: Xe1apE1, 314 xe1ap_e2: Xe1apE2, 315 xe1ap_ap: Xe1apAp, 316 xe1ap_bp: Xe1apBp, 317 xe1ap_start: Xe1apStart, 318 xe1ap_select: Xe1apSelect, 319]); 320 321impl GenesisControllerMapping { 322 #[must_use] 323 pub fn keyboard_arrows() -> Self { 324 Self { 325 up: key_input!(Up), 326 left: key_input!(Left), 327 right: key_input!(Right), 328 down: key_input!(Down), 329 a: key_input!(A), 330 b: key_input!(S), 331 c: key_input!(D), 332 x: key_input!(Q), 333 y: key_input!(W), 334 z: key_input!(E), 335 start: key_input!(Return), 336 mode: key_input!(RShift), 337 mega_mouse_left: Some(vec![GenericInput::Mouse(MouseButton::Left)]), 338 mega_mouse_right: Some(vec![GenericInput::Mouse(MouseButton::Right)]), 339 mega_mouse_middle: Some(vec![GenericInput::Mouse(MouseButton::Middle)]), 340 mega_mouse_start: key_input!(Return), 341 xe1ap_analog_left: None, 342 xe1ap_analog_right: None, 343 xe1ap_analog_up: None, 344 xe1ap_analog_down: None, 345 xe1ap_slider_forward: None, 346 xe1ap_slider_backward: None, 347 xe1ap_a: None, 348 xe1ap_b: None, 349 xe1ap_c: None, 350 xe1ap_d: None, 351 xe1ap_e1: None, 352 xe1ap_e2: None, 353 xe1ap_ap: None, 354 xe1ap_bp: None, 355 xe1ap_start: None, 356 xe1ap_select: None, 357 } 358 } 359 360 #[must_use] 361 pub fn keyboard_wasd() -> Self { 362 Self { 363 up: key_input!(W), 364 left: key_input!(A), 365 right: key_input!(D), 366 down: key_input!(S), 367 a: key_input!(J), 368 b: key_input!(K), 369 c: key_input!(L), 370 x: key_input!(U), 371 y: key_input!(I), 372 z: key_input!(O), 373 start: key_input!(Return), 374 mode: key_input!(RShift), 375 mega_mouse_left: Some(vec![GenericInput::Mouse(MouseButton::Left)]), 376 mega_mouse_right: Some(vec![GenericInput::Mouse(MouseButton::Right)]), 377 mega_mouse_middle: Some(vec![GenericInput::Mouse(MouseButton::Middle)]), 378 mega_mouse_start: key_input!(Return), 379 xe1ap_analog_left: None, 380 xe1ap_analog_right: None, 381 xe1ap_analog_up: None, 382 xe1ap_analog_down: None, 383 xe1ap_slider_forward: None, 384 xe1ap_slider_backward: None, 385 xe1ap_a: None, 386 xe1ap_b: None, 387 xe1ap_c: None, 388 xe1ap_d: None, 389 xe1ap_e1: None, 390 xe1ap_e2: None, 391 xe1ap_ap: None, 392 xe1ap_bp: None, 393 xe1ap_start: None, 394 xe1ap_select: None, 395 } 396 } 397 398 pub fn clone_from_type(&mut self, other: &Self, controller_type: GenesisControllerType) { 399 static GAMEPAD_BUTTONS: LazyLock<Vec<GenesisButton>> = LazyLock::new(|| { 400 GenesisButton::ALL.into_iter().filter(|&button| button.is_gamepad()).collect() 401 }); 402 403 static MOUSE_BUTTONS: LazyLock<Vec<GenesisButton>> = LazyLock::new(|| { 404 GenesisButton::ALL.into_iter().filter(|&button| button.is_mouse()).collect() 405 }); 406 407 static XE1AP_BUTTONS: LazyLock<Vec<GenesisButton>> = LazyLock::new(|| { 408 GenesisButton::ALL.into_iter().filter(|&button| button.is_xe1ap()).collect() 409 }); 410 411 match controller_type { 412 GenesisControllerType::MegaMouse => self.clone_from(other, &MOUSE_BUTTONS), 413 GenesisControllerType::Xe1ap => self.clone_from(other, &XE1AP_BUTTONS), 414 GenesisControllerType::ThreeButton 415 | GenesisControllerType::SixButton 416 | GenesisControllerType::None => self.clone_from(other, &GAMEPAD_BUTTONS), 417 } 418 } 419} 420 421#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize, ConfigDisplay)] 422#[serde(default)] 423pub struct GenesisInputMapping { 424 #[cfg_display(indent_nested)] 425 pub p1: GenesisControllerMapping, 426 #[cfg_display(indent_nested)] 427 pub p2: GenesisControllerMapping, 428 #[cfg_display(indent_nested)] 429 pub p1_turbo: GenesisControllerMapping, 430 #[cfg_display(indent_nested)] 431 pub p2_turbo: GenesisControllerMapping, 432} 433 434impl GenesisInputMapping { 435 impl_player_mapping!(GenesisControllerMapping); 436 437 pub fn to_mapping_vec<'a>(&'a self, out: &mut ButtonMappingVec<'a, GenesisButton>) { 438 self.p1.to_mapping_vec(Player::One, out); 439 self.p2.to_mapping_vec(Player::Two, out); 440 } 441} 442 443#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, ConfigDisplay)] 444#[serde(default)] 445pub struct GenesisInputConfig { 446 pub p1_type: GenesisControllerType, 447 pub p2_type: GenesisControllerType, 448 #[cfg_display(indent_nested)] 449 pub mapping_1: GenesisInputMapping, 450 #[cfg_display(indent_nested)] 451 pub mapping_2: GenesisInputMapping, 452} 453 454impl GenesisInputConfig { 455 impl_to_mapping_vec!(GenesisButton); 456 457 impl_to_turbo_mapping_vec!(GenesisButton); 458} 459 460fn default_genesis_mapping_1() -> GenesisInputMapping { 461 GenesisInputMapping { 462 p1: GenesisControllerMapping::keyboard_arrows(), 463 p2: GenesisControllerMapping::default(), 464 p1_turbo: GenesisControllerMapping::default(), 465 p2_turbo: GenesisControllerMapping::default(), 466 } 467} 468 469impl Default for GenesisInputConfig { 470 fn default() -> Self { 471 Self { 472 p1_type: GenesisControllerType::default(), 473 p2_type: GenesisControllerType::None, 474 mapping_1: default_genesis_mapping_1(), 475 mapping_2: GenesisInputMapping::default(), 476 } 477 } 478} 479 480define_controller_mapping!(NesControllerMapping, NesButton, [ 481 up: Up, 482 left: Left, 483 right: Right, 484 down: Down, 485 a: A, 486 b: B, 487 start: Start, 488 select: Select, 489]); 490 491impl NesControllerMapping { 492 #[must_use] 493 pub fn keyboard_arrows() -> Self { 494 Self { 495 up: key_input!(Up), 496 left: key_input!(Left), 497 right: key_input!(Right), 498 down: key_input!(Down), 499 a: key_input!(A), 500 b: key_input!(S), 501 start: key_input!(Return), 502 select: key_input!(RShift), 503 } 504 } 505 506 #[must_use] 507 pub fn keyboard_wasd() -> Self { 508 Self { 509 up: key_input!(W), 510 left: key_input!(A), 511 right: key_input!(D), 512 down: key_input!(S), 513 a: key_input!(L), 514 b: key_input!(K), 515 start: key_input!(Return), 516 select: key_input!(RShift), 517 } 518 } 519} 520 521define_controller_mapping!(NesZapperMapping, NesButton, [ 522 fire: ZapperFire, 523 force_offscreen: ZapperForceOffscreen, 524]); 525 526impl NesZapperMapping { 527 #[must_use] 528 pub fn mouse() -> Self { 529 Self { 530 fire: Some(vec![GenericInput::Mouse(MouseButton::Left)]), 531 force_offscreen: Some(vec![GenericInput::Mouse(MouseButton::Right)]), 532 } 533 } 534} 535 536#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize, ConfigDisplay)] 537#[serde(default)] 538pub struct NesInputMapping { 539 #[cfg_display(indent_nested)] 540 pub p1: NesControllerMapping, 541 #[cfg_display(indent_nested)] 542 pub p2: NesControllerMapping, 543 #[cfg_display(indent_nested)] 544 pub p1_turbo: NesControllerMapping, 545 #[cfg_display(indent_nested)] 546 pub p2_turbo: NesControllerMapping, 547 #[cfg_display(indent_nested)] 548 pub zapper: NesZapperMapping, 549} 550 551impl NesInputMapping { 552 impl_player_mapping!(NesControllerMapping); 553 554 pub fn to_mapping_vec<'a>(&'a self, out: &mut ButtonMappingVec<'a, NesButton>) { 555 self.p1.to_mapping_vec(Player::One, out); 556 self.p2.to_mapping_vec(Player::Two, out); 557 self.zapper.to_mapping_vec(Player::One, out); 558 } 559} 560 561#[derive( 562 Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize, EnumDisplay, EnumAll, 563)] 564#[cfg_attr(feature = "clap", derive(jgenesis_proc_macros::CustomValueEnum))] 565pub enum NesControllerType { 566 #[default] 567 Gamepad, 568 Zapper, 569} 570 571#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, ConfigDisplay)] 572#[serde(default)] 573pub struct NesInputConfig { 574 pub p2_type: NesControllerType, 575 #[cfg_display(indent_nested)] 576 pub mapping_1: NesInputMapping, 577 #[cfg_display(indent_nested)] 578 pub mapping_2: NesInputMapping, 579} 580 581impl NesInputConfig { 582 impl_to_mapping_vec!(NesButton); 583 584 impl_to_turbo_mapping_vec!(NesButton); 585} 586 587fn default_nes_mapping_1() -> NesInputMapping { 588 NesInputMapping { 589 p1: NesControllerMapping::keyboard_arrows(), 590 p2: NesControllerMapping::default(), 591 p1_turbo: NesControllerMapping::default(), 592 p2_turbo: NesControllerMapping::default(), 593 zapper: NesZapperMapping::mouse(), 594 } 595} 596 597impl Default for NesInputConfig { 598 fn default() -> Self { 599 Self { 600 p2_type: NesControllerType::default(), 601 mapping_1: default_nes_mapping_1(), 602 mapping_2: NesInputMapping::default(), 603 } 604 } 605} 606 607define_controller_mapping!(SnesControllerMapping, SnesButton, [ 608 up: Up, 609 left: Left, 610 right: Right, 611 down: Down, 612 a: A, 613 b: B, 614 x: X, 615 y: Y, 616 l: L, 617 r: R, 618 start: Start, 619 select: Select, 620 mouse_left: MouseLeft, 621 mouse_right: MouseRight, 622 super_scope_fire: SuperScopeFire, 623 super_scope_cursor: SuperScopeCursor, 624 super_scope_pause: SuperScopePause, 625 super_scope_turbo_toggle: SuperScopeTurboToggle, 626]); 627 628impl SnesControllerMapping { 629 #[must_use] 630 pub fn keyboard_arrows() -> Self { 631 Self { 632 up: key_input!(Up), 633 left: key_input!(Left), 634 right: key_input!(Right), 635 down: key_input!(Down), 636 a: key_input!(S), 637 b: key_input!(X), 638 x: key_input!(A), 639 y: key_input!(Z), 640 l: key_input!(D), 641 r: key_input!(C), 642 start: key_input!(Return), 643 select: key_input!(RShift), 644 mouse_left: Some(vec![GenericInput::Mouse(MouseButton::Left)]), 645 mouse_right: Some(vec![GenericInput::Mouse(MouseButton::Right)]), 646 super_scope_fire: Some(vec![GenericInput::Mouse(MouseButton::Left)]), 647 super_scope_cursor: Some(vec![GenericInput::Mouse(MouseButton::Right)]), 648 super_scope_pause: Some(vec![GenericInput::Mouse(MouseButton::Middle)]), 649 super_scope_turbo_toggle: key_input!(T), 650 } 651 } 652 653 #[must_use] 654 pub fn keyboard_wasd() -> Self { 655 Self { 656 up: key_input!(W), 657 left: key_input!(A), 658 right: key_input!(D), 659 down: key_input!(S), 660 a: key_input!(L), 661 b: key_input!(K), 662 x: key_input!(I), 663 y: key_input!(J), 664 l: key_input!(U), 665 r: key_input!(O), 666 start: key_input!(Return), 667 select: key_input!(RShift), 668 mouse_left: Some(vec![GenericInput::Mouse(MouseButton::Left)]), 669 mouse_right: Some(vec![GenericInput::Mouse(MouseButton::Right)]), 670 super_scope_fire: Some(vec![GenericInput::Mouse(MouseButton::Left)]), 671 super_scope_cursor: Some(vec![GenericInput::Mouse(MouseButton::Right)]), 672 super_scope_pause: Some(vec![GenericInput::Mouse(MouseButton::Middle)]), 673 super_scope_turbo_toggle: key_input!(T), 674 } 675 } 676 677 #[must_use] 678 pub fn super_scope_only() -> Self { 679 Self { 680 up: None, 681 left: None, 682 right: None, 683 down: None, 684 a: None, 685 b: None, 686 x: None, 687 y: None, 688 l: None, 689 r: None, 690 start: None, 691 select: None, 692 mouse_left: None, 693 mouse_right: None, 694 super_scope_fire: Some(vec![GenericInput::Mouse(MouseButton::Left)]), 695 super_scope_cursor: Some(vec![GenericInput::Mouse(MouseButton::Right)]), 696 super_scope_pause: Some(vec![GenericInput::Mouse(MouseButton::Middle)]), 697 super_scope_turbo_toggle: key_input!(T), 698 } 699 } 700} 701 702#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize, ConfigDisplay)] 703#[serde(default)] 704pub struct SnesInputMapping { 705 #[cfg_display(indent_nested)] 706 pub p1: SnesControllerMapping, 707 #[cfg_display(indent_nested)] 708 pub p2: SnesControllerMapping, 709 #[cfg_display(indent_nested)] 710 pub p1_turbo: SnesControllerMapping, 711 #[cfg_display(indent_nested)] 712 pub p2_turbo: SnesControllerMapping, 713} 714 715impl SnesInputMapping { 716 impl_player_mapping!(SnesControllerMapping); 717 718 pub fn to_mapping_vec<'a>(&'a self, out: &mut ButtonMappingVec<'a, SnesButton>) { 719 self.p1.to_mapping_vec(Player::One, out); 720 self.p2.to_mapping_vec(Player::Two, out); 721 } 722} 723 724#[derive( 725 Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize, EnumDisplay, EnumAll, 726)] 727#[cfg_attr(feature = "clap", derive(jgenesis_proc_macros::CustomValueEnum))] 728pub enum SnesControllerType { 729 #[default] 730 Gamepad, 731 Mouse, 732 SuperScope, 733 None, 734} 735 736#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, ConfigDisplay)] 737#[serde(default)] 738pub struct SnesInputConfig { 739 pub p1_type: SnesControllerType, 740 pub p2_type: SnesControllerType, 741 #[cfg_display(indent_nested)] 742 pub mapping_1: SnesInputMapping, 743 #[cfg_display(indent_nested)] 744 pub mapping_2: SnesInputMapping, 745} 746 747impl SnesInputConfig { 748 impl_to_mapping_vec!(SnesButton); 749 750 impl_to_turbo_mapping_vec!(SnesButton); 751} 752 753fn default_snes_mapping_1() -> SnesInputMapping { 754 SnesInputMapping { 755 p1: SnesControllerMapping::keyboard_arrows(), 756 p2: SnesControllerMapping::super_scope_only(), 757 p1_turbo: SnesControllerMapping::default(), 758 p2_turbo: SnesControllerMapping::default(), 759 } 760} 761 762impl Default for SnesInputConfig { 763 fn default() -> Self { 764 Self { 765 p1_type: SnesControllerType::Gamepad, 766 p2_type: SnesControllerType::None, 767 mapping_1: default_snes_mapping_1(), 768 mapping_2: SnesInputMapping::default(), 769 } 770 } 771} 772 773define_controller_mapping!(GameBoyInputMapping, GameBoyButton, [ 774 up: Up, 775 left: Left, 776 right: Right, 777 down: Down, 778 a: A, 779 b: B, 780 start: Start, 781 select: Select, 782]); 783 784impl GameBoyInputMapping { 785 #[must_use] 786 pub fn keyboard_arrows() -> Self { 787 Self { 788 up: key_input!(Up), 789 left: key_input!(Left), 790 right: key_input!(Right), 791 down: key_input!(Down), 792 a: key_input!(A), 793 b: key_input!(S), 794 start: key_input!(Return), 795 select: key_input!(RShift), 796 } 797 } 798 799 #[must_use] 800 pub fn keyboard_wasd() -> Self { 801 Self { 802 up: key_input!(W), 803 left: key_input!(A), 804 right: key_input!(D), 805 down: key_input!(S), 806 a: key_input!(L), 807 b: key_input!(K), 808 start: key_input!(Return), 809 select: key_input!(RShift), 810 } 811 } 812} 813 814#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, ConfigDisplay)] 815#[serde(default)] 816pub struct GameBoyInputConfig { 817 #[cfg_display(indent_nested)] 818 pub mapping_1: GameBoyInputMapping, 819 #[cfg_display(indent_nested)] 820 pub mapping_2: GameBoyInputMapping, 821 #[cfg_display(indent_nested)] 822 pub mapping_1_turbo: GameBoyInputMapping, 823 #[cfg_display(indent_nested)] 824 pub mapping_2_turbo: GameBoyInputMapping, 825} 826 827impl GameBoyInputConfig { 828 #[must_use] 829 pub fn to_mapping_vec(&self) -> ButtonMappingVec<'_, GameBoyButton> { 830 let mut out = Vec::new(); 831 832 self.mapping_1.to_mapping_vec(Player::One, &mut out); 833 self.mapping_2.to_mapping_vec(Player::One, &mut out); 834 835 out 836 } 837 838 #[must_use] 839 pub fn to_turbo_mapping_vec(&self) -> ButtonMappingVec<'_, GameBoyButton> { 840 let mut out = Vec::new(); 841 842 self.mapping_1_turbo.to_mapping_vec(Player::One, &mut out); 843 self.mapping_2_turbo.to_mapping_vec(Player::One, &mut out); 844 845 out 846 } 847} 848 849fn default_gb_mapping_1() -> GameBoyInputMapping { 850 GameBoyInputMapping::keyboard_arrows() 851} 852 853impl Default for GameBoyInputConfig { 854 fn default() -> Self { 855 Self { 856 mapping_1: default_gb_mapping_1(), 857 mapping_2: GameBoyInputMapping::default(), 858 mapping_1_turbo: GameBoyInputMapping::default(), 859 mapping_2_turbo: GameBoyInputMapping::default(), 860 } 861 } 862} 863 864define_controller_mapping!(GbaJoypadMapping, GbaButton, [ 865 up: Up, 866 left: Left, 867 right: Right, 868 down: Down, 869 a: A, 870 b: B, 871 l: L, 872 r: R, 873 start: Start, 874 select: Select, 875]); 876 877impl GbaJoypadMapping { 878 #[must_use] 879 pub fn keyboard_arrows() -> Self { 880 Self { 881 up: key_input!(Up), 882 left: key_input!(Left), 883 right: key_input!(Right), 884 down: key_input!(Down), 885 a: key_input!(A), 886 b: key_input!(S), 887 l: key_input!(Q), 888 r: key_input!(W), 889 start: key_input!(Return), 890 select: key_input!(RShift), 891 } 892 } 893 894 #[must_use] 895 pub fn keyboard_wasd() -> Self { 896 Self { 897 up: key_input!(W), 898 left: key_input!(A), 899 right: key_input!(D), 900 down: key_input!(S), 901 a: key_input!(L), 902 b: key_input!(K), 903 l: key_input!(I), 904 r: key_input!(O), 905 start: key_input!(Return), 906 select: key_input!(RShift), 907 } 908 } 909} 910 911define_controller_mapping!(GbaSolarMapping, GbaButton, [ 912 increase_brightness: SolarIncreaseBrightness, 913 decrease_brightness: SolarDecreaseBrightness, 914 min_brightness: SolarMinBrightness, 915 max_brightness: SolarMaxBrightness, 916]); 917 918#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize, ConfigDisplay)] 919#[serde(default)] 920pub struct GbaInputMapping { 921 #[cfg_display(indent_nested)] 922 pub joypad: GbaJoypadMapping, 923 #[cfg_display(indent_nested)] 924 pub solar: GbaSolarMapping, 925} 926 927impl GbaInputMapping { 928 fn to_mapping_vec<'a>(&'a self, out: &mut ButtonMappingVec<'a, GbaButton>) { 929 self.joypad.to_mapping_vec(Player::One, out); 930 self.solar.to_mapping_vec(Player::One, out); 931 } 932} 933 934#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, ConfigDisplay)] 935#[serde(default)] 936pub struct GbaInputConfig { 937 #[cfg_display(indent_nested)] 938 pub mapping_1: GbaInputMapping, 939 #[cfg_display(indent_nested)] 940 pub mapping_2: GbaInputMapping, 941 #[cfg_display(indent_nested)] 942 pub mapping_1_turbo: GbaInputMapping, 943 #[cfg_display(indent_nested)] 944 pub mapping_2_turbo: GbaInputMapping, 945} 946 947impl GbaInputConfig { 948 #[must_use] 949 pub fn to_mapping_vec(&self) -> ButtonMappingVec<'_, GbaButton> { 950 let mut out = Vec::new(); 951 952 self.mapping_1.to_mapping_vec(&mut out); 953 self.mapping_2.to_mapping_vec(&mut out); 954 955 out 956 } 957 958 #[must_use] 959 pub fn to_turbo_mapping_vec(&self) -> ButtonMappingVec<'_, GbaButton> { 960 let mut out = Vec::new(); 961 962 self.mapping_1_turbo.to_mapping_vec(&mut out); 963 self.mapping_2_turbo.to_mapping_vec(&mut out); 964 965 out 966 } 967} 968 969fn default_gba_mapping_1() -> GbaInputMapping { 970 GbaInputMapping { 971 joypad: GbaJoypadMapping::keyboard_arrows(), 972 solar: GbaSolarMapping::default(), 973 } 974} 975 976impl Default for GbaInputConfig { 977 fn default() -> Self { 978 Self { 979 mapping_1: default_gba_mapping_1(), 980 mapping_2: GbaInputMapping::default(), 981 mapping_1_turbo: GbaInputMapping::default(), 982 mapping_2_turbo: GbaInputMapping::default(), 983 } 984 } 985} 986 987define_controller_mapping!(PceJoypadMapping, PceButton, [ 988 up: Up, 989 left: Left, 990 right: Right, 991 down: Down, 992 button1: Button1, 993 button2: Button2, 994 run: Run, 995 select: Select, 996]); 997 998impl PceJoypadMapping { 999 #[must_use] 1000 pub fn keyboard_arrows() -> Self { 1001 Self { 1002 up: key_input!(Up), 1003 left: key_input!(Left), 1004 right: key_input!(Right), 1005 down: key_input!(Down), 1006 button1: key_input!(A), 1007 button2: key_input!(S), 1008 run: key_input!(Return), 1009 select: key_input!(RShift), 1010 } 1011 } 1012 1013 #[must_use] 1014 pub fn keyboard_wasd() -> Self { 1015 Self { 1016 up: key_input!(W), 1017 left: key_input!(A), 1018 right: key_input!(S), 1019 down: key_input!(D), 1020 button1: key_input!(L), 1021 button2: key_input!(K), 1022 run: key_input!(Return), 1023 select: key_input!(RShift), 1024 } 1025 } 1026} 1027 1028#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize, ConfigDisplay)] 1029#[serde(default)] 1030pub struct PceInputMapping { 1031 #[cfg_display(indent_nested)] 1032 pub p1: PceJoypadMapping, 1033 #[cfg_display(indent_nested)] 1034 pub p2: PceJoypadMapping, 1035 #[cfg_display(indent_nested)] 1036 pub p3: PceJoypadMapping, 1037 #[cfg_display(indent_nested)] 1038 pub p4: PceJoypadMapping, 1039 #[cfg_display(indent_nested)] 1040 pub p5: PceJoypadMapping, 1041 #[cfg_display(indent_nested)] 1042 pub p1_turbo: PceJoypadMapping, 1043 #[cfg_display(indent_nested)] 1044 pub p2_turbo: PceJoypadMapping, 1045 #[cfg_display(indent_nested)] 1046 pub p3_turbo: PceJoypadMapping, 1047 #[cfg_display(indent_nested)] 1048 pub p4_turbo: PceJoypadMapping, 1049 #[cfg_display(indent_nested)] 1050 pub p5_turbo: PceJoypadMapping, 1051} 1052 1053impl PceInputMapping { 1054 impl_player_mapping!( 1055 PceJoypadMapping, 1056 [ 1057 (One, p1, p1_turbo), 1058 (Two, p2, p2_turbo), 1059 (Three, p3, p3_turbo), 1060 (Four, p4, p4_turbo), 1061 (Five, p5, p5_turbo), 1062 ] 1063 ); 1064 1065 pub fn to_mapping_vec<'a>(&'a self, out: &mut ButtonMappingVec<'a, PceButton>) { 1066 self.p1.to_mapping_vec(Player::One, out); 1067 self.p2.to_mapping_vec(Player::Two, out); 1068 self.p3.to_mapping_vec(Player::Three, out); 1069 self.p4.to_mapping_vec(Player::Four, out); 1070 self.p5.to_mapping_vec(Player::Five, out); 1071 } 1072} 1073 1074#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, ConfigDisplay)] 1075#[serde(default)] 1076pub struct PceInputConfig { 1077 #[cfg_display(indent_nested)] 1078 pub mapping_1: PceInputMapping, 1079 #[cfg_display(indent_nested)] 1080 pub mapping_2: PceInputMapping, 1081} 1082 1083impl PceInputConfig { 1084 impl_to_mapping_vec!(PceButton); 1085 1086 impl_to_turbo_mapping_vec!( 1087 PceButton, 1088 [(One, p1_turbo), (Two, p2_turbo), (Three, p3_turbo), (Four, p4_turbo), (Five, p5_turbo)] 1089 ); 1090} 1091 1092impl Default for PceInputConfig { 1093 fn default() -> Self { 1094 Self { 1095 mapping_1: PceInputMapping { 1096 p1: PceJoypadMapping::keyboard_arrows(), 1097 p2: PceJoypadMapping::default(), 1098 p3: PceJoypadMapping::default(), 1099 p4: PceJoypadMapping::default(), 1100 p5: PceJoypadMapping::default(), 1101 p1_turbo: PceJoypadMapping::default(), 1102 p2_turbo: PceJoypadMapping::default(), 1103 p3_turbo: PceJoypadMapping::default(), 1104 p4_turbo: PceJoypadMapping::default(), 1105 p5_turbo: PceJoypadMapping::default(), 1106 }, 1107 mapping_2: PceInputMapping::default(), 1108 } 1109 } 1110} 1111 1112macro_rules! define_hotkey_mapping { 1113 (@default none) => { 1114 None 1115 }; 1116 (@default $default:ident) => { 1117 Some(vec![GenericInput::Keyboard(KeyboardInput::Keycode(Keycode::$default))]) 1118 }; 1119 (@default ($($default:ident $(+)?)*)) => { 1120 Some(vec![ 1121 $( 1122 GenericInput::Keyboard(KeyboardInput::Keycode(Keycode::$default)), 1123 )* 1124 ]) 1125 }; 1126 ($($value:ident: $hotkey:ident $label:literal default $default:tt),* $(,)?) => { 1127 #[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)] 1128 pub struct HotkeyMapping { 1129 $( 1130 pub $value: Option<Vec<GenericInput>>, 1131 )* 1132 } 1133 1134 impl HotkeyMapping { 1135 #[must_use] 1136 pub fn default_keyboard() -> Self { 1137 Self { 1138 $( 1139 $value: define_hotkey_mapping!(@default $default), 1140 )* 1141 } 1142 } 1143 1144 pub fn to_mapping_vec<'a>(&'a self, out: &mut HotkeyMappingVec<'a>) { 1145 $( 1146 if let Some(mapping) = &self.$value { 1147 out.push((Hotkey::$hotkey, mapping)); 1148 } 1149 )* 1150 } 1151 1152 #[must_use] 1153 pub fn access_value(&mut self, hotkey: Hotkey) -> &mut Option<Vec<GenericInput>> { 1154 match hotkey { 1155 $( 1156 Hotkey::$hotkey => &mut self.$value, 1157 )* 1158 } 1159 } 1160 } 1161 1162 impl std::fmt::Display for HotkeyMapping { 1163 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 1164 fmt_input_mapping(&[ 1165 $( 1166 (Hotkey::$hotkey, &self.$value), 1167 )* 1168 ], f) 1169 } 1170 } 1171 1172 impl Hotkey { 1173 #[must_use] 1174 pub fn label(self) -> &'static str { 1175 match self { 1176 $( 1177 Self::$hotkey => $label, 1178 )* 1179 } 1180 } 1181 } 1182 }; 1183} 1184 1185define_hotkey_mapping!( 1186 power_off: PowerOff "Power off emulated system" default Escape, 1187 exit: Exit "Exit application" default (LCtrl + Q), 1188 toggle_fullscreen: ToggleFullscreen "Toggle fullscreen" default F9, 1189 save_state: SaveState "Save state to current slot" default F5, 1190 load_state: LoadState "Load state from current slot" default F6, 1191 next_save_state_slot: NextSaveStateSlot "Next save state slot" default RightBracket, 1192 prev_save_state_slot: PrevSaveStateSlot "Previous save state slot" default LeftBracket, 1193 soft_reset: SoftReset "Soft reset" default F1, 1194 hard_reset: HardReset "Hard reset" default F2, 1195 pause: Pause "Pause" default P, 1196 step_frame: StepFrame "Step to next frame" default N, 1197 fast_forward: FastForward "Fast forward" default Tab, 1198 rewind: Rewind "Rewind" default Grave, 1199 cancel_mouse_input: CancelMouseInput "Cancel mouse input" default O, 1200 toggle_overclocking: ToggleOverclocking "Toggle overclocking enabled" default Semicolon, 1201 open_debugger: OpenDebugger "Open memory viewer" default Apostrophe, 1202 save_state_slot_0: SaveStateSlot0 "Save state to slot 0" default none, 1203 save_state_slot_1: SaveStateSlot1 "Save state to slot 1" default none, 1204 save_state_slot_2: SaveStateSlot2 "Save state to slot 2" default none, 1205 save_state_slot_3: SaveStateSlot3 "Save state to slot 3" default none, 1206 save_state_slot_4: SaveStateSlot4 "Save state to slot 4" default none, 1207 save_state_slot_5: SaveStateSlot5 "Save state to slot 5" default none, 1208 save_state_slot_6: SaveStateSlot6 "Save state to slot 6" default none, 1209 save_state_slot_7: SaveStateSlot7 "Save state to slot 7" default none, 1210 save_state_slot_8: SaveStateSlot8 "Save state to slot 8" default none, 1211 save_state_slot_9: SaveStateSlot9 "Save state to slot 9" default none, 1212 load_state_slot_0: LoadStateSlot0 "Load state from slot 0" default none, 1213 load_state_slot_1: LoadStateSlot1 "Load state from slot 1" default none, 1214 load_state_slot_2: LoadStateSlot2 "Load state from slot 2" default none, 1215 load_state_slot_3: LoadStateSlot3 "Load state from slot 3" default none, 1216 load_state_slot_4: LoadStateSlot4 "Load state from slot 4" default none, 1217 load_state_slot_5: LoadStateSlot5 "Load state from slot 5" default none, 1218 load_state_slot_6: LoadStateSlot6 "Load state from slot 6" default none, 1219 load_state_slot_7: LoadStateSlot7 "Load state from slot 7" default none, 1220 load_state_slot_8: LoadStateSlot8 "Load state from slot 8" default none, 1221 load_state_slot_9: LoadStateSlot9 "Load state from slot 9" default none, 1222); 1223 1224#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, ConfigDisplay)] 1225#[serde(default)] 1226pub struct HotkeyConfig { 1227 #[cfg_display(indent_nested)] 1228 pub mapping_1: HotkeyMapping, 1229 #[cfg_display(indent_nested)] 1230 pub mapping_2: HotkeyMapping, 1231} 1232 1233impl HotkeyConfig { 1234 #[must_use] 1235 pub fn to_mapping_vec(&self) -> HotkeyMappingVec<'_> { 1236 let mut out = Vec::new(); 1237 1238 self.mapping_1.to_mapping_vec(&mut out); 1239 self.mapping_2.to_mapping_vec(&mut out); 1240 1241 out 1242 } 1243} 1244 1245impl Default for HotkeyConfig { 1246 fn default() -> Self { 1247 Self { mapping_1: HotkeyMapping::default_keyboard(), mapping_2: HotkeyMapping::default() } 1248 } 1249}