En este artículo, examinaremos el código de RetroArch en RetroPie y Libretro, para descubrir las diferencias entre la adaptación de RetroArch 1.18.0 de RetroPie y la versión oficial de RetroArch 1.18.0 de Libretro.
Nuestro objetivo es comprender a fondo estas implementaciones para obtener el conocimiento necesario que nos permita adaptar futuras versiones de RetroArch en RetroPie, o para agregar nuevo soporte a la versión actual.
A pesar de que ambas versiones ofrecen soporte para shaders y tienen similitudes, exploraremos en detalle las particularidades que las distinguen.
Es importante entender que RetroArch de RetroPie es una versión adaptada del RetroArch oficial desarrollado por The Libretro Team.
Nosotros descargaremos ambas implementaciones en su versión 1.18.0 y a continuación detallaré el proceso para identificar sus diferencias, que no son muchas.
Cabe mencionar que no es necesario tener conocimientos técnicos para seguir este artículo. Las porciones de código que proporcionaré serán explicadas a alto nivel para que sea fácil de entender por cualquier persona.
Todos los comandos que se utilizarán a continuación se pueden ejecutar tanto en entornos Windows como en Linux, pero como usuario de Linux que soy, me centraré en explicarlos como si estuvieras ejecutando los comandos en la propia Raspberry Pi.
Si estás en Windows, tu tarea es utilizar Git Bash o equivalente si quieres seguir mis pasos.
Sin más que decir, empecemos.
Descargando los proyectos
Lo primero es crear una carpeta donde descargaremos ambos proyectos para su posterior análisis.
mkdir retroarch
cd retroarch
El comando mkdir retroarch significa crear un directorio con el nombre retroarch. Mientras que con el comando cd retroarch nosotros entramos al directorio retroarch.
Ahora vamos a descargar ambos proyectos de RetroArch. Para ello necesitamos tener instalado Git en nuestro equipo.
Si estás en Windows ya te he mandado a instalarlo antes, y si estás en Linux, y estás leyendo este artículo, es muy probable que ya lo tengas instalado y si no es así, ya te estás tardando, ve e instala Git para que podamos continuar.
Ahora que ya tienes Git instalado, clonamos el repositorio de RetroArch de Libretro, que es la versión original, y le dejamos el mismo nombre.
git clone --branch v1.18.0 --single-branch https://github.com/libretro/RetroArch.git
Ahora que hemos descargado la versión de Libretro, continuemos con la de RetroPie ejecutando el siguiente comando. En este caso la nombraremos retropie-retroarch-v1.18.0 para evitar confusiones entre ambas versiones.
git clone --branch retropie-v1.18.0 --single-branch https://github.com/RetroPie/RetroArch.git retropie-retroarch-v1.18.0
Una vez descargados ambos proyectos, podemos ver ambas carpetas haciendo un simple ls -lh y deberías ver el siguiente resultado.
ls -lh
Salida esperada
total 24K
drwxr-xr-x 54 user group 12K Jun 6 19:06 RetroArch
drwxr-xr-x 54 user group 12K Jun 6 19:15 retropie-retroarch-v1.18.0
Buscando las diferencias
Comencemos a buscar las diferencias dentro del código.
Para esto, utilizaremos la herramienta del sistema Unix llamada diff, la cual es precisa para nuestra tarea de análisis.
diff --exclude .git -qr RetroArch retropie-retroarch-v1.18.0
Salida esperada
Files RetroArch/configuration.c and retropie-retroarch-v1.18.0/configuration.c differ
Files RetroArch/configuration.h and retropie-retroarch-v1.18.0/configuration.h differ
Files RetroArch/frontend/drivers/platform_unix.c and retropie-retroarch-v1.18.0/frontend/drivers/platform_unix.c differ
Files RetroArch/gfx/video_shader_parse.c and retropie-retroarch-v1.18.0/gfx/video_shader_parse.c differ
En la salida del comando anterior se pueden identificar los archivos con diferencias, los cuales se listan a continuación:
configuration.hconfiguration.cfrontend/drivers/platform_unix.cgfx/video_shader_parse.c
Ahora procedemos a analizar cada uno de ellos, para entender mejor la adaptación que ha realizado RetroPie e intentar entender el porqué de ello.
Veamos primero la diferencia del archivo gfx/video_shader_parse.c.
gfx/video_shader_parse.c
diff RetroArch/gfx/video_shader_parse.c retropie-retroarch-v1.18.0/gfx/video_shader_parse.c
Salida esperada
2785,2787c2785,2788
<
< fill_pathname_join(s, shader_directory, special_name, len);
< strlcat(s, video_shader_get_preset_extension(types[i]), len);
---
> if (strcmp(special_name, "config")!=0) {
> fill_pathname_join(s, shader_directory, special_name, len);
> strlcat(s, video_shader_get_preset_extension(types[i]), len);
> }
2890a2892,2902
> goto success;
> }
> /* Configuration file shader found ? */
> strlcpy(shader_path, settings->paths.path_shader, PATH_MAX_LENGTH);
> if (!string_is_empty(shader_path)) {
> RARCH_LOG("[Shaders/RetroPie]: Configuration file shader path found.\n");
> if(video_shader_load_shader_preset_internal(
> shader_path,
> sizeof(shader_path),
> NULL, NULL,
> "config"))
Vamos a explicar un poco la salida del comando diff.
Para no bajar tanto de nivel, explicaré un poco la primera línea 2785,2787c2785,2788.
La línea 2788 en el archivo gfx/video_shader_parse.c es donde se encuentra la primera diferencia.
El signo < indica que es código eliminado y el signo > indica que es código agregado.
Ahora, en la segunda diferencia que podemos observar 2890a2892,2902, que se encuentra en la línea 2902.
Sin embargo, creo que esta porción de código se entiende mejor si cambiamos el orden y lo separamos un poco para explicar qué es cada parte.
Vamos a verlo.
/* Configuration file shader found ? */
strlcpy(shader_path, settings->paths.path_shader, PATH_MAX_LENGTH);
if (!string_is_empty(shader_path)) {
RARCH_LOG("[Shaders/RetroPie]: Configuration file shader path found.\n");
if(video_shader_load_shader_preset_internal(
shader_path,
sizeof(shader_path),
NULL, NULL,
"config"))
goto success;
}
He copiado el código del archivo original para explicarlo por partes. Esta sección representa la segunda diferencia encontrada con el comando diff.
La siguiente parte del código valida si se ha configurado una ruta para los shaders de RetroPie.
Si no estás familiarizado con este término, puedes obtener más información en la documentación oficial de shaders.
strlcpy(shader_path, settings->paths.path_shader, PATH_MAX_LENGTH);
if (!string_is_empty(shader_path))
Si se encuentra una ruta válida configurada para los shaders en RetroPie, se aplicará el shader en RetroArch.
video_shader_load_shader_preset_internal(
shader_path,
sizeof(shader_path),
NULL, NULL,
"config"))
Podemos ver que el último argumento de la función es config y es un valor especial que ha asignado RetroPie para soportar su propia estructura de carpetas para sus shaders.
Podemos ver en la primera diferencia donde se valida que RetroArch solo ajuste la ruta del shader si el special_name es diferente de config.
if (strcmp(special_name, "config")!=0) {
fill_pathname_join(s, shader_directory, special_name, len);
strlcat(s, video_shader_get_preset_extension(types[i]), len);
}
Entonces, en el primer archivo analizado y modificado por RetroPie, se ha agregado soporte para una nueva ubicación para los shaders.
Según mi lógica, los archivos configuration.h y configuration.c deberían ser modificados para agregar el nuevo parámetro de configuración para esa nueva ruta de shaders.
Vamos a verlo.
configuration.h
diff RetroArch/configuration.h retropie-retroarch-v1.18.0/configuration.h
Salida esperada
548a549
> char path_shader[PATH_MAX_LENGTH];
configuration.c
diff RetroArch/configuration.c retropie-retroarch-v1.18.0/configuration.c
Salida esperada
1582a1583
> SETTING_PATH("video_shader", settings->paths.path_shader, false, NULL, true);
2952a2954
> *settings->paths.path_shader = '\0';
5169a5172,5175
> /* blacklist the 'video_shader' configuration path, better handled by shader presets */
> if (string_is_equal(path_settings[i].ident, "video_shader"))
> continue;
Como esperábamos, los archivos configuration.h y configuration.c simplemente añaden soporte a la nueva variable que controla la ubicación actualizada de los shaders.
Además, limpiaré un poco la última salida para ustedes, copiándola del archivo original.
SETTING_PATH("video_shader", settings->paths.path_shader, false, NULL, true);
*settings->paths.path_shader = '\0';
/* blacklist the 'video_shader' configuration path, better handled by shader presets */
if (string_is_equal(path_settings[i].ident, "video_shader"))
continue;
frontend/drivers/platform_unix.c
Ya solo falta un archivo por analizar: frontend/drivers/platform_unix.c.
Vamos a utilizar al protagonista de este artículo, diff, para realizar esta tarea.
diff RetroArch/frontend/drivers/platform_unix.c retropie-retroarch-v1.18.0/frontend/drivers/platform_unix.c
Salida esperada
1891,1896d1890
< fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SRAM], base_path,
< "saves", sizeof(g_defaults.dirs[DEFAULT_DIR_SRAM]));
< fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SAVESTATE], base_path,
< "states", sizeof(g_defaults.dirs[DEFAULT_DIR_SAVESTATE]));
< fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SYSTEM], base_path,
< "system", sizeof(g_defaults.dirs[DEFAULT_DIR_SYSTEM]));
Con la última salida, RetroPie ha eliminado las carpetas predeterminadas para saves, states y system, lo cual tiene total sentido, ya que buscan crear su propio ecosistema y dejar las rutas por defecto de RetroArch podría confundir al usuario final.
Conclusión
En resumen, la adaptación de RetroArch por RetroPie solo modifica la ruta de los shaders y elimina las rutas por defecto saves, states y system, logrando un entorno más limpio para todo tipo de usuarios.
Además, es fácil adaptar la nueva versión 1.19.1 de RetroArch a RetroPie para aprovechar las mejoras que trae consigo, como el soporte a botones multimedia del teclado, permitiendo usar periféricos como la Wireless Sensor DolphinBar en modo 2 con total compatibilidad.
Para finalizar, aquí están los enlaces a los commits originales realizados por el equipo de RetroPie y la descripción real del cambio:
- Revert «(Linux) Set default saves/save states/system paths»
- Add back the
video_shaderparameter.
Actualmente están trabajando en la adaptación de la versión 1.19.1 que cuenta con los siguientes cambios relevantes:
- Agrega soporte para teclas multimedia del teclado, necesario para el soporte total de DolphinBar.
- Implementación de input test para el Remote RetroPad.
- Fixed a crash that occurred when using threaded video.
También me gustaría compartir mi adaptación hasta que el equipo de RetroPie publique la versión oficial soportada por ellos mismos.
https://github.com/lowlevel-1989/RetroArch/tree/retropie-v1.19.1
https://github.com/RetroPie/RetroArch/pull/8