2020-03-28 RG350 PyMenu

PyMenu

Se ilustra a continuación el proceso de instalación y configuración del launcher PyMenu para RG350.

Aviso

PyMenu al contrario que SimpleMenu y EmulationStation, trata de autoconfigurarse localizando los emuladores, ports y aplicaciones que hay en la consola y contrastándolos con un fichero de configuración que contiene la mayoría de los sistemas. Desafortunadamente no es perfecto y no lo logra en todos los casos, haciendo que los que fallan sean más difíciles de configurar. En este artículo se desvelan algunas de las técnicas que usa el programa para que sepamos cómo terminar de adaptar la configuración.

Instalación

La instalación es sencilla ya que el programador ofrece un OPK para ello en las releases del repositorio. En concreto el OPK adecuado para instalar en RG350 es éste:

https://github.com/JackD83/PyMenu/releases/download/2.0.0-PRE/PyMenu-Installer-2.0.0.opk

Como con todos los OPKs sólo tenemos que copiarlo a uno de estos dos directorios:

  • /media/data/apps
  • /media/sdcard/apps

Preferiblemente en el segundo que corresponde al directorio apps de la tarjeta externa, ya que el OPK lo podremos borrar una vez hecha la instalación. En GMenu2X nos aparecerá este lanzador:

PyMenu Installer

Lo abriremos y veremos una pantalla de terminal en la que es posible que aparezcan algunos errores. Al principio creía que se trataba del proceso de búsqueda de OPKs para la autoconfiguración, pero analizando el script de instalación veo que sólo las últimas 4 líneas corresponden a la verdadera instalación:

PyMenu Installing

Las líneas anteriores pertenecen a GMenu2X y en mi caso indicaban que tenía ficheros residuales en /media/data/local/home/.gmenu2x/sections. Son lanzadores de aplicaciones que en su día instalé y borré. Haciendo limpieza de los ficheros correspondientes consigo un log de instalación más limpio:

PyMenu Installing Clean

En cualquier caso estos errores no son importantes.

El instalador copia todo el código y recursos de PyMenu en el directorio /media/data/pymenu. También copia un lanzador en /media/data/local/home/.gmenu2x/sections/applications, motivo por el que nos aparecerá lo siguiente:

PyMenu Launcher

Configuración

Una vez instalado, si ejecutamos PyMenu a través de su lanzador seguramente arrancará, no como SimpleMenu o EmulationStation que hasta que no tienen una configuración perfecta suelen cerrarse. Otra ventaja de PyMenu es que puede configurarse desde el propio interfaz gráfico del programa. Para ello basta situarse sobre el sistema a configurar y pulsar Select para seleccionar la entrada edit entry:

PyMenu Config1 PyMenu Config2

Allí veremos los parámetros que contiene el fichero de configuración para ese sistema. El fichero de configuración es /media/data/pymenu/config/config.json. Como vemos es un fichero JSON (mucho más amigable que los XML de SimpleMenu y EmulationStation). Al principio encontramos unos parámetros generales:

    "batteryHigh": 3900000,
    "batteryLow": 3300000,
    "firstStart": false,
    "lcd_backlight": 70,
    "linkPath": "/media/data/local/home/.gmenu2x/sections",

Los dos primeros controlan el comportamiento del indicador de batería. Según comunicación de su autor, los parámetros se ajustan automáticamente cargando completamente la batería y dejándo que se descargue del todo.

A continuación aparece la configuración de los sistemas. Por ejemplo éste sería el bloque correspondiente a la Game Boy:

        {
            "description": "Gameboy",
            "hideFolders": false,
            "limitSelection": null,
            "name": "GB",
            "overclock": "360",
            "previews": "/media/data/roms/GB/.previews",
            "selectionPath": "/media/data/roms/GB",
            "system": "gambatte",
            "type": "emulator",
            "useFileFilter": false,
            "useGamelist": false,
            "useSelection": true
        },

Como vemos se corresponde con lo que veíamos en el pantallazo anterior. Será por tanto equivalente modificar la configuración desde el programa o desde el fichero. Si PyMenu no encuentra un OPK compatible con la configuración del emulador correspondiente ocultará el sistema en el interfaz gráfico, pero podemos forzar su aparición activando la opción Show All en General Settings:

PyMenu Show All

A pesar de poder configurar los sistemas desde el propio frontend, prefiero hacerlo manipulando el fichero de configuración directamente, ya que permite ajustar todos los sistemas de una vez. Para editar este fichero, como siempre, podemos hacerlo conectando con la consola por SSH para manipularlo con vi o copiarlo con DinguxCmdr, FTP o SCP para editarlo desde el ordenador.

A continuación menciono algunos de los problemas que tuve haciendo la configuración.

Problema con la Identificador de sistema en ROGUE

En principio para indicar el emulador (o emuladores, ya que como veremos luego soporta varios en cada sistema) a utilizar en un sistema determinado basta indicar el nombre completo de dicho emulador (incluyendo espacios). Esto en BASE se aplicará directamente. En ROGUE se pueden editar los nombres de los emuladores, por lo que podemos perder de vista el nombre original que es el que necesitamos, ya que PyMenu extraerá este nombre del interior del OPK que no es alterado al modificar el nombre en el GMenu2X de ROGUE. Vamos a profundizar pues un poco en la manera en que son identificados los emuladores para ayudar a entender cómo debemos configurar PyMenu en ROGUE.

El parámetro donde debemos indicar el nombre original del emulador es system. Vamos a verlo por ejemplo con el caso de la Game Boy. Como vemos en la configuración anterior está definido en system el valor gambatte. Pues bien, para que el sistema Game Boy aparezca en PyMenu será comparado con dos cosas:

  • El parámetro Name de los ficheros .desktop que contienen los OPKs.
  • El parámetro title de los ficheros que hay en las distintas secciones que hay en /media/data/local/home/.gmenu2x/sections, a lo que PyMenu llama links.

No estoy seguro, pero creo que en el caso de emuladores en los que hay que seleccionar una ROM para lanzarlo (la mayoría), sólo sirve el primero de los dos tipos. Para aplicaciones sueltas o Ports pueden servir cualquiera de los dos.

Ahora la cosa se complica un poco. Por una parte el fichero .desktop (casi siempre se llama default.gcw0.desktop) se encuentra enterrado en el OPK que es una especie de ZIP (en realidad una especie de imagen de sistema de ficheros). Vamos a ver por ejemplo cómo accederíamos a él siguiendo con el ejemplo de Game Boy. En mi máquina el OPK de este emulador es gambatte-multi-r572u4-20200127.opk. Lo descargamos al PC y ejecutamos lo siguiente (sólo sé hacerlo con Linux):

$ unsquashfs gambatte-multi-r572u4-20200127.opk

Nos aparecerá un directorio de nombre squashfs-root con el contenido del OPK. Dentro de él encontramos un fichero llamado default.gcw0.desktop con el siguiente contenido:

[Desktop Entry]
Name=Gambatte
Comment=GB/GBC emulator
Exec=gambatte.opendingux %f
Terminal=false
Type=Application
StartupNotify=true
Icon=gambatte
Categories=emulators;
X-OD-Manual=manual.txt
MimeType=application/x-gameboy-rom;application/x-gbc-rom;application/x-gzip;application/zip;application/gzip;

Pues bien, el valor de Name será lo que tengamos que poner en el parámetro system de Game Boy en /media/data/pymenu/config/config.json. Las mayúsculas/minúsculas no son importantes ya que PyMenu convierte todo a minúsculas antes de hacer comparaciones. Como digo, en mi caso había modificado los nombres de los emuladores en GMenu2X. Por ejemplo el nombre original Gambatte lo había cambiado a Game Boy. Así, antes de entender que lo que se cogía era el Name dentro del .desktop probaba con Game Boy o con el nombre completo del OPK (gambatte-multi-r572u4-20200127.opk) sin éxito.

Luego está el segundo elemento que se compara con system, es decir el parámetro title de los ficheros de las distintas secciones que hay en /media/data/local/home/.gmenu2x/sections, a lo que PyMenu llama links. Curiosamente este parámetro sí que se adapta cuando en GMenu2X cambiamos el nombre del emulador, pero como se ha comentado antes, parece que este elemento no sirve para lanzar emuladores a los que tenemos que pasarles como parámetro la ROM a ejecutar. Por ejemplo, en mi caso el link de Gambatte es /usr/local/home/.gmenu2x/sections/emulators/gambatte-multi-r572u4-20200127_gambatte.opendinguxf y su contenido:

title=Game Boy
description=GB/GBC emulator
manual=manual.txt
icon=/media/data/apps/gambatte-multi-r572u4-20200127.opk#gambatte.png
selectorfilter=gb,gbc,gz,zip,gz
clock=360
selectordir=/media/data/local/home/roms/GB/

Como vemos el title no se corresponde con el Name del .desktop dentro del OPK por el motivo mencionado de que modifiqué los nombres de los emuladores en GMenu2X. Es mejor no hacerlo para no tener que abrir la lata del OPK en busca del .desktop, pero para mi ya era tarde.

En resumen, si queremos que un emulador sea reconocido en PyMenu, tenemos que averiguar el nombre original del emulador y colocarlo en el parámetro system del sistema correspondiente en el fichero de configuración de PyMenu.

Problema con determinados emuladores

Con el emulador de Intellivision hubo un problema particular. Por algún motivo el .desktop que contiene el OPK no era interpretado correctamente y al intentar entrar en la lista de ROMs PyMenu se reiniciaba. Tras depurar añadiendo trazas al código Python encontré que el problema estaba en el fichero default.gcw0.desktop. El original contenía esto:

#!/usr/bin/env xdg-open
[Desktop Entry]
Name=JzIntellivision
Type=Application
Exec=jzintv %F
Icon=dingux-int
Comment=Intellivision emulator
#Comment=Intellivision emulator
Terminal=false
Categories=emulators;
Mimetype=application/octet-stream;
X-OD-Manual=readmegcw.txt

La solución consiste en desempaquetar el OPK (con unsquashfs) y cambiar la F final del parámetro Exec del fichero default.gcw0.desktop poniéndola en minúsculas. Luego hay que volver a empaquetar en squashfs el OPK (mksquashfs).

Soporte de varios emuladores

Una cosa buena que tiene PyMenu es que admite varios valores en este parámetro separados por comas. Así se pueden escribir varias posibilidades para dar más oportunidades a PyMenu para encontrar los emuladores. Cuando lo hacemos nos permite seleccionar el emulador que queremos utilizar para lanzar el juego. Por ejemplo si tenemos instalado ReGBA y GPSP, al pulsar Start en la pantalla de selección de ROMs, nos aparecerá un desplegable en el que podremos seleccionar el emulador a utilizar:

PyMenu System Select

Como punto de partida dejo aquí mi fichero de configuración que contiene la mayoría de los emuladores que se utilizan habitualmente.

Arranque

Para conseguir que PyMenu arranque como lanzador predeterminado, al igual que con SimpleMenu y EmulationStation tenemos que incorporar un script de nombre frontend_start en el directorio /media/data/local/sbin. El contenido del script será el siguiente:

#!/bin/sh

export HOME=`cat /etc/passwd |head -1 |cut -d':' -f 6`

# Restore the framebuffer to a working state
/usr/sbin/unlockvt > /dev/null

# Reset the console
/usr/bin/reset

# Disactivate the console on framebuffer
echo 0 > /sys/devices/virtual/vtconsole/vtcon1/bind

# Disable downscaling for future apps
if [ -f /sys/devices/platform/jz-lcd.0/allow_downscaling ] ; then
        echo 0 > /sys/devices/platform/jz-lcd.0/allow_downscaling
fi

# Restore the regular key map
if [ -f /sys/devices/platform/linkdev/alt_key_map ] ; then
        echo 0 > /sys/devices/platform/linkdev/alt_key_map
fi

# Stop the gravity sensor if it's loaded
/usr/sbin/gsensor --stop

# Source /etc/profile to set the environment variables
. /etc/profile

exec /media/data/pymenu/pymenu.dge

Una vez instalado el script, debemos asignarle el permiso UNIX de ejecución. Para ello ejecutaremos a través de SSH o con la aplicación ST-SDL el siguiente comando:

# chmod +x /media/data/local/sbin/frontend_start

Para que el script anterior funcione, debemos modificar además el fichero /media/data/pymenu/pymenu.dge. En concreto modificar la línea 37 para incorporar la ruta completa del fichero pymenu.sh:

...
                echo "starting PyMenu"
                sh /media/data/pymenu/pymenu.sh
                #> /dev/ttyS1 2> /dev/ttyS1
...

Temas

PyMenu tiene un sistema de temas como EmulationStation. Se basa en unos ficheros JSON que hay en la ruta /media/data/pymenu/theme/themes. Internamente estos ficheros hacen referencia a recursos de imagen que pueden estar en cualquier lugar, aunque suelen estar bajo el directorio /media/data/pymenu/images. Por ejemplo lo siguiente es la definición del sistema GameBoy en el tema Pixel:

    "GAMEBOY": {
        "background": "images/pixel/backgrounds/gbc.png",
        "folderIcon": "images/pixel/icons/gbc.png",
        "icon": "images/pixel/systems/gbc.png"
    },

El tema se selecciona desde el icono de rueda dentada que hay abajo a la izquierda en la pantalla principal. Al pulsar sobre ella aparecen los General Settings, siendo el tema uno de ellos. Una vez seleccionado, como siempre en PyMenu, hay que confirmar los cambios pulsando Start:

PyMenu General Settings

Vamos a ver ejemplos de cada uno:

tft

PyMenu tft1 PyMenu tft2

pixel

PyMenu pixel1 PyMenu pixel2

default

PyMenu default1 PyMenu default2

Funcionalidades

PyMenu tiene un par de funcionalidades de las que carece EmulationStation (al menos en la versión compilada para RG350 que circula por ahí) y es que guarda un histórico de los juegos lanzados así como una lista de favoritos. Para añadir un juego a favoritos tenemos que pulsar Select cuando estemos seleccionando el juego. Aparecerá un desplegable con la opción Add to favourites:

PyMenu Favorites

También es operativo el menú para reiniciar y apagar la consola. Se obtiene pulsando en el típico símbolo de Power que hay abajo a la derecha en la pantalla principal:

PyMenu Power

La opción Exit to Gmenu2x la he incorporado yo modificando el código, es decir, no aparecerá si se instala el código original siguiendo este artículo.