Feat(Launcher): added the live control center (#1225)

EN-US

- Added live pictures of the DualSense, DualShock 4, Xbox and Switch Pro controllers, and of the keyboard and mouse
- Added automatic controller detection from the USB vendor and product
- Added remapping by clicking a part of the picture and pressing the new input
- Added dead zones, a stick drift measure and motor tests beside the controller
- Added a red glow on the part of the controller that vibrates
- Added control profiles with save, delete, import and export
- Added Kenney Input Prompts icons (CC0) for the mouse, keyboard and controllers
- Added the selected controller icon and the original PlayStation button to Pressed
- Added a warning when one input presses two game buttons
- Added lefttrigger, righttrigger and touchpad_left to the pad map
- Added radial dead zones to the game runtime, off at 0
- Moved the live SDL3 to its own thread, so the window never waits for it
- Updated the Controls snapshots and added one for each controller

---

PT-BR

- Adicionadas imagens ao vivo dos controles DualSense, DualShock 4, Xbox e Switch Pro, e do teclado e mouse
- Adicionada detecção automática do controle pelo fabricante e produto USB
- Adicionado remapeamento por clique na imagem e aperto da nova entrada
- Adicionados zonas mortas, medição de drift e teste dos motores ao lado do controle
- Adicionado brilho vermelho na parte do controle que vibra
- Adicionados perfis de controle com salvar, excluir, importar e exportar
- Adicionados ícones Kenney Input Prompts (CC0) para mouse, teclado e controles
- Adicionados o ícone do controle selecionado e o botão PlayStation original a Pressed
- Adicionado aviso quando uma entrada aperta dois botões do jogo
- Adicionados lefttrigger, righttrigger e touchpad_left ao mapa do controle
- Adicionadas zonas mortas radiais ao runtime do jogo, desligadas em 0
- Movido o SDL3 ao vivo para thread própria, para a janela nunca esperar por ele
- Atualizados os snapshots de Controles e adicionado um por controle
This commit is contained in:
Felipe Prado authored and GitHub committed 2026-11-04 22:16:11 -03:00
1 parent fbaf4b67da
commit 74b06dffa9
382 files changed
+5450 -141

No files matched your search

+1
View File
@@ -46,6 +46,7 @@ gamecontrollerdb.txt
# Rust launcher (docs/specs/2026-10-21-rust-launcher-design.md)
launcher-rust/target/
!launcher-rust/assets/*.png
!launcher-rust/assets/pads/**/*.png
!docs/specs/assets/**/*.png
# Brainstorming companion sessions
.superpowers/
+56
View File
@@ -2196,6 +2196,34 @@
"F12 in the game": "F12 no jogo",
"Saves the game's image, without the overlay, as a PNG in the screenshots folder of the saves.": "Salva a imagem do jogo, sem o overlay, em PNG na pasta screenshots dos saves.",
"Vibration": "Vibração",
"No game button uses this input.": "Nenhum botão do jogo usa esta entrada.",
"Connect a controller to remap by pressing a button.": "Conecte um controle para remapear apertando um botão.",
"SDL does not know this controller yet. Use Set up a controller first.": "O SDL ainda não conhece este controle. Use Configurar um controle primeiro.",
"No controller found. Connect one and it shows up here.": "Nenhum controle encontrado. Conecte um e ele aparece aqui.",
"Press any button on {}": "Aperte qualquer botão em {}",
"Press a key or click a key to change it": "Aperte uma tecla, ou clique nela para trocar",
"Press the new button for {} ({})": "Aperte o novo botão para {} ({})",
"{} presses more than one game button.": "{} aperta mais de um botão do jogo.",
"Measure stick drift": "Medir drift do analógico",
"Leave the sticks alone...": "Não toque nos analógicos...",
"Test left motor": "Testar motor esquerdo",
"Test right motor": "Testar motor direito",
"Suggested dead zone: left {}%, right {}%": "Zona morta sugerida: esquerda {}%, direita {}%",
"Apply": "Aplicar",
"New profile name": "Nome do novo perfil",
"Import": "Importar",
"Export": "Exportar",
"Control profiles": "Perfis de controle",
"Left stick dead zone": "Zona morta do analógico esquerdo",
"Right stick dead zone": "Zona morta do analógico direito",
"How far a stick must move before the game sees it. Raise it if the camera or Kratos moves by itself. 0% is the game's own stick. Applied when the game starts.": "Quanto o analógico precisa mover para o jogo perceber. Aumente se a câmera ou o Kratos se mexer sozinho. 0% é o analógico original. Aplicado ao iniciar o jogo.",
"Touchpad right opens the game's pause menu. Touchpad left (photo mode) is L1 + Touchpad right, or a button of its own if you choose one. R3+L2 always opens the port's menu. Applied when the game starts.": "Touchpad direito abre o menu de pausa do jogo. Touchpad esquerdo (modo foto) é L1 + Touchpad direito, ou um botão próprio se você escolher. R3+L2 sempre abre o menu do port. Aplicado ao iniciar o jogo.",
"Default": "Padrão",
"Mouse with side buttons": "Mouse com botões laterais",
"Could not read the profile file.": "Não foi possível ler o arquivo de perfis.",
"Could not save the profile file.": "Não foi possível salvar o arquivo de perfis.",
"This file is not a valid SpartanPort control profile.": "Este arquivo não é um perfil de controle válido do SpartanPort.",
"Enter a profile name of up to 40 characters.": "Digite um nome de perfil com até 40 caracteres.",
"Strength of the gamepad's vibration; 0% turns it off.": "Força da vibração do controle; 0% desliga.",
"Windows could not reserve the memory the game needs. Close other programs, or let the Windows page file grow (for example 16384 MB initial, 32768 MB maximum), and start again.": "O Windows não conseguiu reservar a memória que o jogo precisa. Feche outros programas, ou deixe o arquivo de paginação do Windows crescer (por exemplo 16384 MB inicial, 32768 MB máximo), e inicie de novo.",
"Linux could not allocate the memory the game needs. Close other programs, check available RAM, swap space, or /dev/shm, and start again.": "O Linux não conseguiu alocar a memória que o jogo precisa. Feche outros programas, verifique a memória RAM disponível, swap ou /dev/shm, e inicie de novo.",
@@ -2629,6 +2657,34 @@
"F12 in the game": "F12 en el juego",
"Saves the game's image, without the overlay, as a PNG in the screenshots folder of the saves.": "Guarda la imagen del juego, sin el overlay, como PNG en la carpeta screenshots de las partidas.",
"Vibration": "Vibración",
"No game button uses this input.": "Ningún botón del juego usa esta entrada.",
"Connect a controller to remap by pressing a button.": "Conecta un mando para reasignar pulsando un botón.",
"SDL does not know this controller yet. Use Set up a controller first.": "SDL aún no reconoce este mando. Usa Configurar un mando primero.",
"No controller found. Connect one and it shows up here.": "No se encontró ningún mando. Conecta uno y aparecerá aquí.",
"Press any button on {}": "Pulsa cualquier botón en {}",
"Press a key or click a key to change it": "Pulsa una tecla, o haz clic en ella para cambiarla",
"Press the new button for {} ({})": "Pulsa el nuevo botón para {} ({})",
"{} presses more than one game button.": "{} pulsa más de un botón del juego.",
"Measure stick drift": "Medir drift del stick",
"Leave the sticks alone...": "No toques los sticks...",
"Test left motor": "Probar motor izquierdo",
"Test right motor": "Probar motor derecho",
"Suggested dead zone: left {}%, right {}%": "Zona muerta sugerida: izquierda {}%, derecha {}%",
"Apply": "Aplicar",
"New profile name": "Nombre del nuevo perfil",
"Import": "Importar",
"Export": "Exportar",
"Control profiles": "Perfiles de control",
"Left stick dead zone": "Zona muerta del stick izquierdo",
"Right stick dead zone": "Zona muerta del stick derecho",
"How far a stick must move before the game sees it. Raise it if the camera or Kratos moves by itself. 0% is the game's own stick. Applied when the game starts.": "Cuánto debe moverse el stick para que el juego lo note. Súbelo si la cámara o Kratos se mueven solos. 0% es el stick original. Se aplica al iniciar el juego.",
"Touchpad right opens the game's pause menu. Touchpad left (photo mode) is L1 + Touchpad right, or a button of its own if you choose one. R3+L2 always opens the port's menu. Applied when the game starts.": "Touchpad derecho abre el menú de pausa del juego. Touchpad izquierdo (modo foto) es L1 + Touchpad derecho, o un botón propio si lo eliges. R3+L2 siempre abre el menú del port. Se aplica al iniciar el juego.",
"Default": "Predeterminado",
"Mouse with side buttons": "Ratón con botones laterales",
"Could not read the profile file.": "No se pudo leer el archivo de perfiles.",
"Could not save the profile file.": "No se pudo guardar el archivo de perfiles.",
"This file is not a valid SpartanPort control profile.": "Este archivo no es un perfil de control válido de SpartanPort.",
"Enter a profile name of up to 40 characters.": "Escribe un nombre de perfil de hasta 40 caracteres.",
"Strength of the gamepad's vibration; 0% turns it off.": "Fuerza de la vibración del mando; 0% la desactiva.",
"(none)": "(ninguna)",
"Adaptive mouse: how far the mouse moves for one step of a rotation. Also in the in-game menu.": "Ratón adaptativo: cuánto se mueve el ratón para cada paso de un giro. También en el menú del juego.",
+31
View File
@@ -0,0 +1,31 @@
Controller pictures, adapted for the launcher: recoloured, the makers' logos removed, each input
cut out as its own mask. The controllers themselves are the trademarks of their makers.
dualsense, dualshock4: design/dualsense.svg and design/dualshock.svg of
https://github.com/daidr/dualsense-tester, MIT License, Copyright (c) 2023 Xuezhou Dai (daidr)
xbox: xbox/template.svgz and xbox/base.svgz of https://github.com/mrmcpowned/gamepad-viewer,
MIT License, Copyright (c) 2021 Dracula Theme
switch_pro: src/Ryujinx/Assets/Icons/Controller_ProCon.svg of Ryujinx, MIT License,
Copyright (c) Ryujinx Team and Contributors
icons: Input Prompts 1.5 by Kenney (www.kenney.nl), https://kenney.nl/assets/input-prompts,
Creative Commons Zero, CC0 1.0.
The MIT License below covers dualsense, dualshock4, xbox and switch_pro:
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 777 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 401 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 323 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 728 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 607 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 926 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 949 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 613 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 976 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 958 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 605 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 614 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 852 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 835 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 936 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 915 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 586 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 594 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 804 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 784 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 943 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 939 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 718 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 714 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 949 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 941 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 928 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 905 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 853 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 830 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 758 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 759 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 623 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 635 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 643 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 655 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 634 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 655 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 651 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 637 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 625 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 829 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 796 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 592 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 573 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 593 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 588 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1012 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 717 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 728 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 911 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 873 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 810 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 805 B

Loaded 100 of 382 files, more files were not shown because too many files have changed in this diff. Show more