Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ English (US) release notes, mirroring CHANGELOG.md (Brazilian Portuguese). Befor
### What's new
- Guided tour of the session menu: the first time the menu opens, it offers an optional tour that highlights each option and explains what it does, including the difference between **Back to the PC** (restores the desk and the app stays in the tray) and **Exit Console Mode** (restores and closes the app). To see it again, press Y (△) or F1 in the menu, or use Settings → Session menu tour. (#144)
- Revamped FPS counter: the numbers sit on a dark rounded card (it can be turned off) in three sizes, Small, Medium and Large. You can pick the screen corner it shows in (or keep RTSS's position) and tune it all from the session menu itself: A on "FPS counter" opens the list with style, size, position, background, color and, in Custom, the items. New styles: FPS only, Compact (FPS plus CPU, GPU and RAM usage on one line) and Detailed (FPS, frame time and API, plus CPU clock, GPU clock and temperature, VRAM and RAM). In Custom, the PC items can be picked one by one too. The data comes from Windows and the graphics driver, nothing to install; anyone already on "Compact" keeps seeing just the FPS. (#146)
- The mouse pointer stays out of the way: the session menu's "Hide the mouse pointer" row hides it (handy for emulators that leave it in the middle of the TV) until you turn it off or go back to the PC; nothing happens by itself. And for games and emulators whose menus ignore the controller, the session menu's "Control the mouse with the controller" row makes the left stick move the pointer, the right stick scroll, A click, A twice right-click and A held drag. It lasts until the session ends. (#145)

### Changes
- The session menu no longer shows the "Record the last 30 s · coming soon" row, which never worked. (#147)
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Notas em português do Brasil; a versão em inglês (Estados Unidos) fica em `CH
### Novidades
- Tour guiado do menu da sessão: na primeira vez que o menu abre, ele oferece um tour opcional que destaca cada opção e explica o que ela faz, incluindo a diferença entre **Voltar ao PC** (restaura a mesa e o app fica na bandeja) e **Sair do Console Mode** (restaura e fecha o app). Para ver de novo, aperte Y (△) ou F1 no menu, ou use Ajustes → Tour do menu da sessão. (#144)
- Contador de FPS repaginado: os números ficam num card escuro e arredondado (dá para desligar) em três tamanhos, Pequeno, Médio e Grande. Dá para escolher o canto da tela onde ele aparece (ou deixar a posição do RTSS) e ajustar tudo pelo próprio menu da sessão: A em "Contador de FPS" abre a lista com estilo, tamanho, posição, fundo, cor e, no Personalizado, os itens. Novos estilos: Apenas FPS, Compacto (FPS e uso de CPU, GPU e RAM numa linha) e Detalhado (FPS, tempo de quadro e API, mais clock da CPU, clock e temperatura da GPU, VRAM e RAM). No Personalizado, os itens do PC também podem ser escolhidos um a um. Os dados vêm do Windows e do driver de vídeo, sem instalar nada; quem já usava "Compacto" continua vendo só o FPS. (#146)
- Cursor do mouse fora do caminho: a linha "Ocultar o cursor do mouse" do menu da sessão esconde o cursor (útil em emuladores que deixam o cursor no meio da TV) até você desligá-la ou voltar ao PC; nada acontece sozinho. E, para jogos e emuladores cujos menus não aceitam o controle, a linha "Controlar o mouse com o controle" do menu da sessão faz o analógico esquerdo mover o cursor, o direito rolar, A clicar, A duas vezes clicar com o botão direito e A segurado arrastar. Vale até o fim da sessão. (#145)

### Mudanças
- O menu da sessão não mostra mais a linha "Gravar os últimos 30 s · em breve", que nunca funcionou. (#147)
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ You pick the controller shortcuts yourself: none is on at first, the app asks th
- [Turns the TV on and switches it to the PC's input](docs/GUIDE.md#tv-control) (Google TV / Android TV over the network), and can put it in standby afterwards
- Launches **Steam Big Picture**, **Playnite fullscreen** or **Xbox** mode, and sends Steam to the tray when you go back to the PC
- **Session menu** over the game: switch or close the open windows, change volume, resolution, audio, FPS and HDR, and browse your files with [ControlFS](https://github.com/nextestudios/ControlFS)
- **Mouse pointer out of the way:** hidden while it sits still, and driven by the controller from the session menu when a game or emulator ignores the pad
- Two interfaces: **Desktop** (mouse) and **Console** (full screen, Xbox and PlayStation pads, LB/RB tabs, your Steam covers as the background)
- Automation with `consolemode://start` / `stop` / `menu` links (Stream Deck, scripts) and a [local control API](docs/GUIDE.md#local-control-api)
- English, Portuguese and Spanish
Expand Down
1 change: 1 addition & 0 deletions README.pt-BR.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ Os atalhos do controle são você quem escolhe: nenhum vem ligado, o app pergunt
- [Liga a TV e troca para a entrada do PC](docs/GUIDE.pt-BR.md#controle-da-tv) (Google TV / Android TV pela rede), e pode colocá-la em espera no fim
- Abre **Steam Big Picture**, **Playnite em tela cheia** ou o **Modo Xbox**, e manda a Steam para a bandeja ao voltar ao PC
- **Menu da sessão** sobre o jogo: troque ou feche as janelas abertas, mude volume, resolução, áudio, FPS e HDR e navegue pelos seus arquivos com o [ControlFS](https://github.com/nextestudios/ControlFS)
- **Cursor do mouse fora do caminho:** some quando fica parado e pode ser movido pelo controle, pelo menu da sessão, quando um jogo ou emulador não aceita o controle
- Duas interfaces: **Desktop** (mouse) e **Console** (tela cheia, controles Xbox e PlayStation, abas no LB/RB, as capas da sua Steam como plano de fundo)
- Automação com os links `consolemode://start` / `stop` / `menu` (Stream Deck, scripts) e uma [API de controle local](docs/GUIDE.pt-BR.md#api-de-controle-local)
- Português, inglês e espanhol
Expand Down
25 changes: 25 additions & 0 deletions docs/TESTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,31 @@ Pré-condição: ControlFS instalado (https://github.com/nextestudios/ControlFS)
- [ ] Depois de instalado pelo menu, o ControlFS aparece em Configurações → Aplicativos instalados e nenhum `ControlFS-Setup-x64.exe` sobra em `%TEMP%ConsoleModeUpdate`. Resultado: ______
- [ ] Fora da sessão (prévia do menu) o painel funciona igual. Resultado: ______

## 1e. Cursor do mouse: ocultar e controlar pelo controle

Pré-condição: um emulador ou jogo que deixa o cursor visível (ex.: um emulador aberto pelo Playnite).

### Ocultar o cursor
- [ ] Menu da sessão: a linha "Ocultar o cursor do mouse" começa em Desativado, com a explicação embaixo inteira (sem cortar). Na prévia (fora da sessão) a linha não aparece. Resultado: ______
- [ ] A na linha: Ativado, e o cursor some da TV, também por cima do emulador. Resultado: ______
- [ ] Com ele oculto, deixe parado e depois mexa o mouse físico: o cursor **não** volta sozinho. Resultado: ______
- [ ] A na linha de novo: Desativado, e o cursor volta com o esquema de ponteiros do Windows de sempre (tamanho e cor de Configurações → Acessibilidade → Ponteiro do mouse). Resultado: ______
- [ ] Com o cursor oculto, ligar "Controlar o mouse com o controle" desliga "Ocultar o cursor" (o cursor aparece); ligar "Ocultar o cursor" desliga o controle do mouse. Resultado: ______
- [ ] Voltar ao PC com o cursor oculto: ele reaparece normal na mesa, e na próxima sessão a linha começa em Desativado. Resultado: ______
- [ ] Ajustes (PC e aba Sistema da interface Console) não têm mais a opção de ocultar o cursor. Resultado: ______
- [ ] Encerre o Console Mode à força (Gerenciador de Tarefas) com o cursor oculto: o cursor continua invisível até abrir o Console Mode de novo, que o restaura logo na abertura (log: `Cursor: restaurado após um encerramento inesperado`). Resultado: ______

### Controlar o mouse pelo controle (Xbox **e** PlayStation)
- [ ] Menu da sessão: a linha "Controlar o mouse com o controle" mostra Desativado e a ajuda com o botão certo do controle (A no Xbox, ✕ no PlayStation). Na prévia (fora da sessão) a linha não aparece. Resultado: ______
- [ ] A na linha: passa a Ativado. Enquanto o menu está aberto, os analógicos e o A continuam navegando no menu, sem mexer no cursor. Resultado: ______
- [ ] Fechar o menu (B ou "Voltar ao jogo"): o A que fechou o menu **não** vira clique. Resultado: ______
- [ ] Analógico esquerdo move o cursor com o jogo em primeiro plano; inclinação leve = movimento fino, inclinação total atravessa a TV em ~1 s, igual em 1080p e 4K. Resultado: ______
- [ ] Analógico direito para cima/baixo rola a página (navegador, lista do emulador); para os lados rola na horizontal onde houver. Resultado: ______
- [ ] A uma vez = clique esquerdo (com um pequeno atraso, ~¼ s); A duas vezes rápido = clique direito (abre o menu de contexto); A segurado = arrastar (solte para largar). Resultado: ______
- [ ] Com o DualSense/DualShock **sem** Steam Input (lido por HID) o cursor também se move e clica. Resultado: ______
- [ ] Voltar ao PC e iniciar outra sessão: a opção começa Desativada de novo. Resultado: ______
- [ ] Limitação esperada: o jogo também recebe o A e os analógicos. Em programas abertos como administrador o cursor não mexe (o Windows bloqueia a entrada vinda de um app comum). Resultado: ______

## 2. Links `consolemode://`

- [ ] `start consolemode://start` no `cmd` com o app **fechado**: abre e entra no modo console. Resultado: ______
Expand Down
1 change: 1 addition & 0 deletions src/ConsoleMode/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ protected override async void OnLaunched(LaunchActivatedEventArgs args)
try
{
AppPaths.Initialize();
CursorHider.RecoverAfterCrash();
LocalizationService.SetLanguage(LocalizationService.ResolveInitial(
ConfigService.Load().AppLanguage, StartupService.ReadInstallerLanguage(), CultureInfo.CurrentUICulture.Name));
ControllerInput.Warmup();
Expand Down
4 changes: 4 additions & 0 deletions src/ConsoleMode/Resources/Strings.en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@
"ShortcutsOnboardingDone": "Done",
"CloseSteamCard": "Send Steam to the tray when going back to the PC",
"CloseSteamDescription": "When you leave Big Picture, Steam receives a normal window-close request so it can move to the tray without exiting the process. If a game is running or its state cannot be checked, the window is left unchanged.",
"HideCursorCard": "Hide the mouse pointer",
"HideCursorDescription": "Stays hidden until you turn this off or go back to the PC. Handy for emulators and games that leave it in the middle of the screen.",
"ControllerMouseRow": "Control the mouse with the controller",
"ControllerMouseHint": "Left stick moves · {0} clicks · {0} twice: right click · right stick scrolls",
"AutoStartControllerCard": "Enter when a controller connects",
"AutoStartControllerDescription": "With the app in the tray, turning on or plugging in a controller enters console mode. Ignores the first 15 s after opening and 30 s after restoring.",
"HomeButtonShortPressCard": "Short press of the Xbox button",
Expand Down
4 changes: 4 additions & 0 deletions src/ConsoleMode/Resources/Strings.es-ES.json
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@
"ShortcutsOnboardingDone": "Listo",
"CloseSteamCard": "Enviar Steam a la bandeja al volver al PC",
"CloseSteamDescription": "Al salir de Big Picture, Steam recibe una solicitud normal para cerrar la ventana y pasar a la bandeja sin finalizar el proceso. Si hay un juego en ejecución o no se puede comprobar su estado, la ventana no se modifica.",
"HideCursorCard": "Ocultar el cursor del ratón",
"HideCursorDescription": "Queda oculto hasta que lo desactives aquí o vuelvas al PC. Útil en emuladores y juegos que lo dejan en el centro de la pantalla.",
"ControllerMouseRow": "Controlar el ratón con el mando",
"ControllerMouseHint": "Stick izquierdo mueve · {0} hace clic · {0} dos veces: clic derecho · stick derecho desplaza",
"AutoStartControllerCard": "Entrar al conectar un mando",
"AutoStartControllerDescription": "Con la aplicación en la bandeja, encender o conectar un mando entra en modo consola. Ignora los primeros 15 s tras abrir y 30 s tras restaurar.",
"HomeButtonShortPressCard": "Pulsación corta del botón Xbox",
Expand Down
4 changes: 4 additions & 0 deletions src/ConsoleMode/Resources/Strings.pt-BR.json
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@
"ShortcutsOnboardingDone": "Concluir",
"CloseSteamCard": "Mandar a Steam para a bandeja ao voltar ao PC",
"CloseSteamDescription": "Ao sair do Big Picture, envia o fechamento normal da janela da Steam para ela ir à bandeja, sem encerrar o processo. Se houver um jogo em execução ou não for possível verificar, a janela não é alterada.",
"HideCursorCard": "Ocultar o cursor do mouse",
"HideCursorDescription": "Fica oculto até você desligar aqui ou voltar ao PC. Útil em emuladores e jogos que deixam o cursor no meio da tela.",
"ControllerMouseRow": "Controlar o mouse com o controle",
"ControllerMouseHint": "Analógico esquerdo move · {0} clica · {0} duas vezes: botão direito · analógico direito rola",
"AutoStartControllerCard": "Entrar ao conectar um controle",
"AutoStartControllerDescription": "Com o app na bandeja, ligar ou conectar um controle entra no modo console. Ignora os primeiros 15 s após abrir e 30 s após restaurar.",
"HomeButtonShortPressCard": "Toque curto no botão Xbox",
Expand Down
36 changes: 26 additions & 10 deletions src/ConsoleMode/Services/ControllerMapping.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,7 @@ public static class ControllerMapping
/// </param>
public static ushort SonyButtons(ReadOnlySpan<byte> report, bool dualSense, int inputReportLength = 0)
{
if (report.Length == 0) return 0;
// Offset of the buttons byte (hat + face) and of the left stick X, per report layout.
var (start, stick) = report[0] switch
{
0x31 => (9, 2), // DualSense, Bluetooth
0x11 => (7, 3), // DS4, Bluetooth
0x01 when IsDualSenseUsbReport(report.Length, dualSense, inputReportLength) => (8, 1), // DualSense, USB
0x01 => (5, 1), // DS4 USB, or either pad's basic Bluetooth report
_ => (-1, -1)
};
var (start, stick) = SonyOffsets(report, dualSense, inputReportLength);
if (start < 0 || report.Length < start + 3) return 0;
var face = report[start];
var hat = face & 0x0F;
Expand Down Expand Up @@ -67,6 +58,31 @@ 0x01 when IsDualSenseUsbReport(report.Length, dualSense, inputReportLength) => (
return bits;
}

/// <summary>
/// Both sticks of a raw DS4/DualSense input report as bytes (0..255, 128 = center, Y grows downward):
/// left X, left Y, right X, right Y. Null for an unknown report. Read by ControllerMouse.
/// </summary>
public static (byte LeftX, byte LeftY, byte RightX, byte RightY)? SonySticks(ReadOnlySpan<byte> report, bool dualSense, int inputReportLength = 0)
{
var (_, stick) = SonyOffsets(report, dualSense, inputReportLength);
if (stick < 0 || report.Length < stick + 4) return null;
return (report[stick], report[stick + 1], report[stick + 2], report[stick + 3]);
}

/// <summary>Offset of the buttons byte (hat + face) and of the left stick X, per report layout; (-1, -1) when unknown.</summary>
private static (int Buttons, int Stick) SonyOffsets(ReadOnlySpan<byte> report, bool dualSense, int inputReportLength)
{
if (report.Length == 0) return (-1, -1);
return report[0] switch
{
0x31 => (9, 2), // DualSense, Bluetooth
0x11 => (7, 3), // DS4, Bluetooth
0x01 when IsDualSenseUsbReport(report.Length, dualSense, inputReportLength) => (8, 1), // DualSense, USB
0x01 => (5, 1), // DS4 USB, or either pad's basic Bluetooth report
_ => (-1, -1)
};
}

/// <summary>Report IDs <see cref="SonyButtons"/> reads: basic/USB (0x01), DS4 Bluetooth (0x11), DualSense Bluetooth (0x31).</summary>
public static bool IsKnownSonyReport(byte reportId) => reportId is 0x01 or 0x11 or 0x31;

Expand Down
Loading
Loading