## TL;DR
Přibližně 15 let starý volant **Thrustmaster Ferrari GT Experience** na Linuxu fungoval, ale měl špatné mapování pro **Xbox Cloud Gaming**. Napsal jsem userspace driver v **Pythonu** (`evdev` + `uinput`), který mapuje vstupy na virtuální Xbox 360 ovladač. Celé to běželo na **Raspberry Pi**. Kód je na [GitHubu](https://github.com/thaubert/steering-wheel-driver).
---
O Vánocích 2025 jsem dostal chuť si "zavibovat" u nějakého technického projektu. Vytáhl jsem ze skříně starý volant **Thrustmaster Ferrari GT Experience** a připojil ho k **Raspberry Pi**. Cíl byl prostý: zkusit, jestli se dá přes svátky zprovoznit nějaká závodní hra přes cloud, aniž bych musel řešit herní PC.
Systém volant viděl (ověřeno přes `jstest`), ale mapování bylo nepoužitelné – tlačítka zpřeházená, pedály prohozené a s invertovanými hodnotami.
### Kudy cesta nevedla (Slepé uličky)
Samozřejmě jsem nejdřív zkusil "googlit". Fóra byla plná rad, které dnes už nefungovaly:
* **xboxdrv:** První volba, ale bohužel už je roky nevyvíjená a nefungovala spolehlivě.
* **Steam Input:** Funguje skvěle, ale já chtěl hrát v prohlížeči (Xbox Cloud), ne přes Steam.
### Technické řešení: Python to zachrání
Když selhaly hotové nástroje, otevřel jsem **Antigravity IDE** a s pomocí modelu **Gemini 3 Pro** jsme začali stavět vlastní řešení. Tedy... Gemini psalo, já jsem dělal testera a točil volantem při kalibraci.
Postupovali jsme v těchto krocích:
#### 1. Analýza "Co to vlastně posílá?"
Prvním krokem bylo zjistit, co volant vlastně systému říká. Pomocí `python-evdev` jsme četli raw data z `/dev/input/eventX`. Odtud jsme zjistili, že plyn i brzda posílají data na stejné ose (`ABS_Y`), jen s opačným znaménkem. To pro moderní hry (které chtějí dvě nezávislé osy) neexistuje.
#### 2. Virtuální podvodník (`uinput`)
Aby si Chrome (a v něm běžící Xbox Cloud) myslel, že má připojený Xbox ovladač, vytvořili jsme pomocí modulu `uinput` virtuální zařízení. Definoval jsem mu přesně tlačítka a osy, které má originální Xbox 360 controller.
#### 3. Překladová smyčka
Jádrem řešení je nekonečná smyčka, která běží na pozadí:
* Čte surová data z Thrustmasteru.
* Když přijde pohyb pedálu, matematicky ho rozdělí na plyn a brzdu.
* Když přijde tlačítko, přemapuje ho na správné místo (např. "řazení pod volantem" -> "LB/RB").
* Zapíše výsledek do virtuálního zařízení.
#### 4. Kalibrace (Třešnička na dortu)
Staré potenciometry už nejsou co bývaly – plný plyn dával jen 85% signálu. Proto jsme s Gemini dopsali i terminálový nástroj `fgt-calibrate`. Ten vás provede sérií úkonů ("Sešlápni plyn nadoraz"), změří reálné maximum vašeho kusu a uloží ho do configu, takže ve hře máte vždy 100% výkon.
---
Hru jsem předem vybranou neměl, prostě jsem chtěl zkusit "něco" závodního. Nakonec to vyhrála **Forza Horizon** na Xbox Cloud Gaming.
### Závěr
Fungovalo to překvapivě dobře. Vlastně až moc dobře – děti byly z ježdění tak nadšené, že jsem musel volant nakonec schovat zpátky do skříně :-)
👉 **[Zdrojový kód na GitHubu](https://github.com/tomashaubert/steering-wheel-driver)**