Advance Menu – Modificando as ações dos botões do gamepad

No post anterior você acompanhou como é possível usar o próprio Advance Menu para duas funções importantes em consoles com o Pi – Halt Reboot. Poder desligar ou reiniciar seu console é algo fundamental em ambientes que não se tem o teclado físico disponível, o que é exatamente o meu caso. Desligar da tomada seria muito arriscado além de ‘deselegante’.

Porém ainda temos um problema no console – o advmenu vem configurado de forma que o botão ‘1’ do gamepad encerre sua execução e retorne ao bash. Se o jogador distraído apertar o  botãozinho (no meu caso o vermelho) do gamepad ele será sumariamente colocado em um ambiente de texto. E sem teclado não será possível retornar ao advmenu nem dar um halt, ou seja, estamos na mesma barca furada de antes, só nos restando retirar o cabo de força e torcer para nada dar errado.

Procurei uma forma de fazer isso nas configurações do advmenu, mas confesso que não consegui. Comecei a achar que os eventos do gamepad estão hardcodeados no código no advmenu, e que a única alternativa seria uma alterada no código.

Antes vamos dar uma fuçada nos botões do gamepad e descobrir quem é quem. O primeiro passo é instalar o joystick  digitando

pi@raspberrypi ~ $ sudo apt-get install joystick

Depois vamos dar uma testada nesse joystick digitando o comando

pi@raspberrypi ~ $ jstest /dev/input/js0

Será exibida algumas informações referentes ao gamepad
Driver version is 2.1.0
Joystick (USB Gamepad) has 2 axes (X, Y)
and 10 buttons (Trigger, ThumbBtn, ThunbBtn2, TopBtn, TopBtn2, PinkieBTN, BaseBtn, BaseBtn2, BaseBtn3, BaseBtn4)
Axes: 0:-32767 1: 0 Buttons 0:off 1:off 2:off 3:off 4:off 5:off: 6:off 7:off: 8:off: 9:off

Brinque um pouco com os botões do seu joystick/gamepad para descobrir quem é quem. No meu caso a configuração ficou assim

gamepad_numerado

Olhá lá o botãozinho 1 (o vermelho) que encerra o advmenu e joga o usuário no bash. Pior lugar para estar não poderia. É colocar na mão de um jogador e ele vai acabar encerrando o menu e ficando no promptzão do bash.

Bom, vamos partir então para a alteração do código. Baixe os fontes do advmenu (caso você ainda não tenha). Eu prefiro usar a versão 2.5 que achei mais suave que a 2.6 (a última disponível). Baixe no sourceforge aqui. Descompacte o arquivo .tar com o comando tar -xvf advancemenu-2.5.0.tar.gz. Será criada uma pasta advancemenu-2.5.0.

O arquivo que queremos mudar é text.cc e está na pasta advancemenu-2.5.0/advance/menu. Use seu editor de textos preferido para editar o arquivo (no meu caso, o preferido como já dito é o joe´s own editor)

pi@raspberrypi ~/advancemenu-2.5.0/advance/menu $ joe text.cc

Procure pela linha static void int_joystick_button_raw_poll() e você encontrará um trecho de código onde cada botão do gamepad está associado a um evento. O código é algo assim

static void int_joystick_button_raw_poll()
{
for(int i=0;i<joystickb_count_get();++i) {
    for(int j=0;j<joystickb_button_count_get(i);++j) {
        if (joystickb_button_get(i, j)) {
            switch (j) {
            case 0 :
                event_push(EVENT_ENTER);
                break;
            case 1 :
                event_push(EVENT_ESC);
                break;
            case 2 :
                event_push(EVENT_MENU);
                break;
            case 3 :
                event_push(EVENT_PREVIEW);
                break;
            case 4 :
                event_push(EVENT_MODE);
                break;
               }
            }
        }
    }
}
}

Note que os botões 0, 1, 2, 3 e 4 do joystick/gamepad estão associados a eventos do advmenu. Dando uma fuçada no código-fonte, descobri alguns eventos do advmenu que você pode associar a botões do joystick. Os eventos são listados no arquivo menu.h

#define EVENT_NONE (1 << 16)
#define EVENT_UP (2 << 16)
#define EVENT_DOWN (3 << 16)
#define EVENT_LEFT (4 << 16)
#define EVENT_RIGHT (5 << 16)
#define EVENT_ENTER (6 << 16)
#define EVENT_ESC (7 << 16)
#define EVENT_SPACE (8 << 16)
#define EVENT_HOME (10 << 16)
#define EVENT_END (11 << 16)
#define EVENT_PGUP (12 << 16)
#define EVENT_PGDN (13 << 16)
#define EVENT_INS (25 << 16)
#define EVENT_DEL (26 << 16)
#define EVENT_MODE (9 << 16)
#define EVENT_HELP (14 << 16)
#define EVENT_GROUP (15 << 16)
#define EVENT_TYPE (16 << 16)
#define EVENT_ATTRIB (17 << 16)
#define EVENT_SORT (18 << 16)
#define EVENT_SETGROUP (19 << 16)
#define EVENT_SETTYPE (20 << 16)
#define EVENT_CLONE (21 << 16)
#define EVENT_IDLE_0 (22 << 16)
#define EVENT_IDLE_1 (23 << 16)
#define EVENT_COMMAND (27 << 16)
#define EVENT_OFF (28 << 16)
#define EVENT_MENU (29 << 16)
#define EVENT_EMU (30 << 16)
#define EVENT_ROTATE (31 << 16)
#define EVENT_LOCK (32 << 16)
#define EVENT_PREVIEW (34 << 16)
#define EVENT_MUTE (35 << 16)

Olha que legal, dá pra associar um botão para rodar um clone (EVENT_CLONE), para rotacionar a tela (EVENT_ROTATE), para trocar de emulador (EVENT_EMU),  para ordenar a lista (EVENT_SORT) e assim vai, bastando um pouco de interpretação do código mostrado acima. Vamos fazer então duas alterações – Retirar a opção de encerrar o advmenu do botão 1 e no lugar colocar a opção de rodar um clone (útil para jogar Popeye) e vamos criar uma nova opção – trocar de emulador pelo botão select do gamepad. Para tanto, nosso código original mostrado lá em cima deve ficar assim (note as diferenças marcadas em negrito)

static void int_joystick_button_raw_poll()
{
for(int i=0;i<joystickb_count_get();++i) {
    for(int j=0;j<joystickb_button_count_get(i);++j) {
        if (joystickb_button_get(i, j)) {
           switch (j) {
           case 0 :
               event_push(EVENT_ENTER);
               break;
           case 1 :
               //event_push(EVENT_ESC);
               event_push(EVENT_CLONE);
               break;
           case 2 :
               event_push(EVENT_MENU);
               break;
           case 3 :
               event_push(EVENT_PREVIEW);
               break;
           case 4 :
               event_push(EVENT_MODE);
               break;
           case 8 :
               event_push(EVENT_EMU);
               break;
               }
            }
        }
    }
}

Ou seja, poderiamos associar outros eventos aos botões do joystick de acordo com a nossa vontade. Lembra que eu falei lá em cima que os eventos pareciam hardcodeados no código ? Ai está o trecho que mostra isso.

No final da mudança salve tudo (CTRL+K+X no joe) e recompile o código estando na raiz que você descompactou os arquivos do advmenu

pi@raspberrupi ~/advancemenu-2.5.0 $ sudo make
pi@raspberrupi ~/advancemenu-2.5.0 $ sudo make install

Se der erro na compilação não precisa ficar nervoso. Basta uma lida no meu outro post sobre o advmenu que você encontrará a resposta lá 🙂

Rode o advmenu e você verá que agora o botão 1 não mais encerra a execução do programa, mas sim abre um menu listando as opções de clone dos jogos do Mame. E o botão select agora serve para selecionar entre os emuladores que você tem previamente configurados no seu arquivo advmenu.rc.

Claro que nosso querido usuário ainda pode sair do advmenu simplesmente selecionando a opção exit do menu do programa. Mas ai é tapa na orelha dele por ser tão teimoso. Numa próxima versão vamos ver se é possível tirar essa opção de lá também. Lembrando que caso vc precise alterar alguma coisa e ligar um teclado, a tecla ESC continua com sua função normal.

Gostaram ? Então mãos a obra e boa sorte para  todos.

Anúncios

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s