Controls - juniorterin/fliperOS GitHub Wiki
Controllers on FliperOS: what the Setup offers in Joysticks and in System > Quirks and how the emulators see each controller. Using the controller in the Setup menus is covered in Installed system.
FliperOS plays light gun games on the tube with Namco's GunCon 2 (the PlayStation 2 gun, USB 0b9a:016a), with nothing to install. The gun reads the beam of the CRT, which is exactly the screen FliperOS is made for; on an LCD it doesn't aim. What ships with the system:
-
The driver. GunCon 2 has no driver in the mainline kernel. The build compiles beardypig/guncon2 through DKMS for the system's kernel and loads it at boot (
/etc/modules-load.d/fliperos-guncon2.conf): plug the gun into USB and it shows up as an input device. -
The calibration. The raw position the gun reports depends on the tube and on where the cabinet's gun sits, and evdev forgets the range on every reconnection. Setup > Joysticks > Calibrate GunCon 2 measures it on your monitor once (below), and the udev rule
99-fliperos-input.rulesreapplies it (fliperos-guncon2-calibrate) every time the gun is plugged in. - The menus. The controller-as-keyboard of the Setup menus leaves light guns out, so aiming doesn't move through the menu.
- The games. In the MAME ROM Cleaner, tell it the cabinet has a Light gun among its controls, and the gun games of the romset are kept along with the others.
Calibrators and the parallel port (config/fliperos-calibrate, screens/joysticks.sh):
The first question is what is wired to the panel. Keyboard encoder (MAME default keys) is for an encoder that types keys (I-PAC and the like) in MAME's layout: nothing is pressed, only the number of players is asked, and every emulator below gets MAME's default keys for each player (fliperos-buttons keyboard; player 1: arrows, Left Ctrl, Left Alt, Space, Left Shift, Z, X, 1 Start, 5 Coin; player 2: R F D G, A S Q W E, 2, 6; players 3 and 4 have only the stick and buttons 1 to 3, as in MAME). RetroArch's own shortcuts that sit on those keys (Space fast-forward, F fullscreen, K frame advance...) are turned off in buttons.cfg, and Supermodel drops its own default keys, which would be another player's. Controllers (press each control) is the mapping below.
Each player's panel, input by input: up, down, left, right, buttons 1 to 6 in panel order (1 2 3 on top, 4 5 6 below), Start and Coin. The first input pressed tells which controller belongs to the player (on a V-USB panel with two identical devices, one per player); with nothing pressed for 8 seconds the input is skipped; the controller-as-keyboard for the menu is off meanwhile. It is read through SDL (config/fliperos-buttons), and the result goes to both: in RetroArch, each player's binds in /etc/fliperos/retroarch/buttons.cfg, which fliperos-kms-run adds to the config (--appendconfig) on top of the controller's automatic profile, with the buttons in the arcade cores' layout (Y X L / B A R, Start and Select on the coin); in GroovyMAME, the ctrlr ~/.mame/ctrlr/fliperos.cfg (each player's JOYCODEs, together with MAME's default keys) and in mame.ini ctrlr fliperos and joystickprovider sdljoy — with sdlgame, the default, MAME sees the panel through SDL's game controller mapping (A, B, X, Y...), which doesn't follow the button order. It also applies to the other emulators: the device's SDL game controller mapping (GUID), in fight stick layout (X Y RB on top, A B RT below, coin on Back), in /var/lib/fliperos/gamecontrollerdb-user.txt, which fliperos-controllers puts last in gamecontrollerdb.txt (PCSX2, with Pad1/Pad2 on SDL through fliperos-x11-run while PCSX2 has no SDL bind; AntiMicroX); in Dolphin, GCPad1 to GCPad4 in GCPadNew.ini with that mapping (4 = A, 1 = B, 5 = X, 2 = Y, 3 = Z, 6 = R, coin on the Triforce Coin) and each player's port enabled in Dolphin.ini; Flycast by device name (Dreamcast through SDL; arcade, Naomi and Atomiswave, with the panel's button N on the game's button N and coin on D), and the same files in Fightcade's Flycast Dojo; Supermodel, Start, coin, directions and buttons 1 to 4 for players 1 and 2 in Supermodel.ini; Hypseus Singe, the [KEYBOARD] of ~/.hypseus/hypinput.ini (buttons 1 to 3 and skill 1 to 3, Start and coin for both players); and OpenBOR, in each player's keys of Saves/default.cfg and of each pak's .cfg (the s_savedata struct: 1 attack, 2 jump, 3 special, 4 to 6 the other attacks, coin on Esc). The map lives in /etc/fliperos/buttons.map, and a system update writes everything again.
Where the buttons of a game go on the panel, by how many buttons the game uses. Pick the number of buttons (1 to 5) and then, for button 1, button 2 and so on, its place on the panel (top row or bottom row; left, middle or right). The panel is drawn as you go, and the list shows the layout of each number:
3-button games [1][2][3] / [ ][ ][ ]
4-button games [1][2][ ] / [3][4][ ] or [1][3][ ] / [2][4][ ]
Without a layout, the game's button N is on the panel's button N (1 2 3 on top, 4 5 6 below); Default layout goes back to that. Six-button games always use the whole panel. It needs the Button mapping done first: the layout moves the buttons mapped there.
The choice is saved in /etc/fliperos/buttons.layout (one line per number of buttons: the panel position of button 1, of button 2...). How many buttons each game has comes from GroovyMAME's game list (-listxml) with the real counts of controls.xml on top (fliperos-romclean buttons writes the table /var/lib/fliperos/game-buttons.txt; the first time it reads the list, about a minute). The MAME 2010 core has a table of its own, game-buttons-mame2010.txt, from the game list of MAME 0.139: that version gives some games the generic button block of their board instead of the buttons the game has. Tekken 3 and the other System 12 games are buttons 1 2 4 5 of a block of 6 there, and 1 2 3 4 in today's MAME. Such a game (0.139 lists more buttons than the game has, and today's MAME lists only the game's) counts as its whole block, so no layout moves it: the punches stay on the top row and the kicks under them, as on the original panel. It applies where the panel's button N is the game's button N: in GroovyMAME, a <system> per game in the ctrlr fliperos.cfg (a clone follows its parent's); in RetroArch's MAME and MAME 2010 cores, a buttons-N.cfg next to buttons.cfg, which fliperos-kms-run adds to the config of a game with N buttons; in Supermodel (Model 3), the buttons of the game in its own section of Supermodel.ini ([ vf3 ]), which Supermodel adds to [ Global ] when the game opens — the fighting games (Punch, Kick, Guard, Escape), the Virtua Striker series (Short Pass, Long Pass, Shoot) and Spikeout (Shift, Beat, Charge, Jump), by the input type of each game in Games.xml; other settings you keep in that section stay; in SM2-Emu (Model 2), a game controller mapping of its own, /var/lib/fliperos/gamecontrollerdb-model2.txt and a gamecontrollerdb-model2-N.txt per layout, which fliperos-x11-run puts on top of the system's gamecontrollerdb.txt for that launch. SM2-Emu reads game buttons 1 to 4 from A B X Y and always takes RB as button 4, so the fight stick mapping of the other emulators put button 1 on the bottom row; its own mapping puts the panel's button N on the game's button N, layout or not. The Model 2 mapping is written with the panel connected (it goes by the device's GUID). The other emulators keep the Button mapping order: FBNeo arranges the buttons of each game by itself, and the others have one mapping for all games.
The screen turns white (the gun needs light where it aims) with a target in each corner; three shots at each (the median counts; a shot off the screen is rejected), and the calibrator computes the gun's real range on the tube — GunCon 2 is linear, so two known points give the edges. A shot at the center checks the result before saving /etc/fliperos/guncon2.conf, which the udev rule reapplies on every connection (evdev forgets the calibration).
The axes show live; turn the wheel from end to end and press each pedal all the way, then leave everything at rest. An axis that rests in the middle (wheel, analog stick) gets a symmetric range around the rest position — the center gives 0 and both sides reach the end — and a 1% dead zone; a pedal keeps the range seen. It goes to /etc/fliperos/calibration.conf (one line per axis) and udev reapplies it on every connection.
Joysticks and pads on the parallel port, through the kernel's own drivers: gamepad adapter (gamecon: NES, SNES, N64, PlayStation, DDR mat, Multisystem; up to 5 per port, on pins 10, 11, 12, 13 and 15), DB9 adapter (db9: Atari/Amiga/Master System, 3/5/6-button Genesis, Saturn, CD32; needs the port in EPP or ECP mode in the BIOS) and TurboGraFX interface (turbografx: up to 7 Multisystem joysticks). The adapter can't be detected: you say which one it is and what is connected to each input, and the setup writes /etc/modprobe.d/fliperos-lpt.conf (the module options, plus blacklist lp: the printer driver would claim the port, and the joystick drivers want it for themselves) and /etc/modules-load.d/fliperos-lpt.conf (loads at boot), loads the driver right away and shows the joysticks created. The kernel finds the port itself (parport_pc) when it exists — on the motherboard it often comes disabled in the BIOS (Super I/O > Parallel Port); without one, a PCI/PCIe parallel card. Parallel port joysticks also move the menus.
Kernel fixes for USB devices that arrive wrong. It sits in System, not in Joysticks, because it is about any USB device. Two kinds, told apart by the code:
-
Controllers, guns, keyboards (the
usbhid.quirksparameter): code0xVENDOR:0xPRODUCT:0xFLAGS; -
Disks and pen drives (the
usb-storage.quirksparameter): codeVENDOR:PRODUCT:LETTERS, without0x, for example152d:0578:u, whereuturns UAS off for a SATA adapter that hangs or drops off.
Each quirk has a name you give it and a code, for example 0x16c0:0x05e1:0x40 for a dual Xin-Mo encoder to show up as two players. Choosing one from the list deletes it; USB devices connected now shows the vendor:product of each connected device. Useful flags: 0x40 one device per player (MULTI_INPUT, dual encoders), 0x8 no GET requests (NOGET, an encoder that hangs), 0x400 always poll (ALWAYS_POLL). The kernel reads at most 4 controller quirks (disk quirks have no such limit), and only at boot: the list lives in /etc/fliperos/quirks.conf, goes into the kernel line (/etc/default/fliperos-boot) and applies after a reboot. Done on the installation media, it goes along to the disk.
AntiMicroX, PCSX2, Dolphin, Flycast and RetroArch use SDL2, which maps a controller outside its database automatically and incompletely: it leaves out the buttons without a counterpart on a modern controller (BTN_C, BTN_Z, extra buttons — in controller mode AntiMicroX doesn't even show them) and puts on the analog stick a digital D-pad that the device sends as axes from −1 to +1 (common in arcade encoders and V-USB projects), and then a game that moves with the D-pad doesn't move. fliperos-controllers (at boot and whenever a controller is connected, through udev) asks SDL itself how it sees each controller and, only for those with an automatic mapping or with no mapping and a digital D-pad, completes it: leftover buttons go to triggers, misc1 and paddles, and the digital axes become the D-pad. Controllers in SDL's database (Xbox, DualShock...) stay as they are; real analog ones (wheel, flight stick) too. The result goes to /var/lib/fliperos/gamecontrollerdb.txt (cumulative), pointed to by SDL_GAMECONTROLLERCONFIG_FILE in /etc/environment and in the launchers. Flycast builds its default mapping from SDL but doesn't understand a D-pad wired to a half axis; for those controllers it also gets mapping files (Dreamcast and arcade, in Flycast's own convention), only if there isn't one yet. It also ships with player 2 (port B) with a controller — its default leaves only player 1 — and with linear interpolation off (rend.LinearInterpolation = no in emu.cfg; the Linear Interpolation option in its settings): Flycast's default blurs the image when taking it to the tube's mode, and without the filter the pixels come out sharp. In an earlier emu.cfg, the option is only turned off if it isn't saved yet; once saved, the choice is yours. RetroArch is compiled with SDL2, so the sdl2 joypad driver shows in Drivers > Input next to udev, and the choice is kept (the system retroarch.cfg doesn't pin the joypad driver). The default is still udev, which shows in the menu the real number of each controller button; with sdl2 the same mappings as the other emulators apply, a controller without a profile falls back to the built-in "Standard Gamepad", and the numbers become SDL's (A = 0, B = 1...). SDL reads the mappings when it opens: a controller connected for the first time with RetroArch open only works correctly after reopening it. With udev, arcade panels and encoders were "not configured" (there's no factory profile for them); fliperos-controllers writes one in /opt/fliperos/retroarch/autoconfig/udev for every controller with a digital D-pad and no analog stick that no profile covers, with the buttons in panel order in the arcade cores' layout (FBNeo): 1 2 3 = Y X L (top row), 4 5 6 = B A R (bottom row) — the MAME cores read the RetroPad's Button 1-6 in another order (MAME, B A Y X L R; MAME 2010, A B X Y L R), and a core remap (config/retroarch-remaps, in ~/.config/retroarch/config/remaps/<core>; one saved from RetroArch's menu stays) takes the panel's button N to the game's Button N, as in GroovyMAME; on a panel with up to 9 buttons the 7th is Start and the 8th Select (coin); with 10 or more, 7 and 8 are L2/R2 and Select/Start move to 9 and 10, as on USB encoders. The profile carries the name and VID+PID (V-USB's VID+PID is the same across different projects) and isn't rewritten: one saved from the menu (Save Controller Profile) stays. RetroArch's menu always names the buttons after the RetroPad's (A, B, X, Y...); with an arcade core open, Quick Menu > Controls shows the game's names. An encoder whose D-pad is axes only and which the kernel merges into a single controller may need a quirk (Setup > System > Quirks).