Skip to content

Instantly share code, notes, and snippets.

@sonicprod
Last active March 27, 2024 14:48
Show Gist options
  • Star 16 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save sonicprod/f5a7bb10fb9ed1cc5124766831e120c4 to your computer and use it in GitHub Desktop.
Save sonicprod/f5a7bb10fb9ed1cc5124766831e120c4 to your computer and use it in GitHub Desktop.
How to make a dedicated MAME Appliance on a Raspberry Pi 4B | Comment réaliser un système MAME dédié sur un Raspberry Pi 4/Pi 400

How to make a dedicated MAME Appliance on a Raspberry Pi 4/Pi 400

Note: the following steps are written in French. Feel free to translate to English.

However, please take notice that if you copy the scripts on this page from the version translated into English by Google Translate, it is possible that extra characters may appear within some scripts (this is caused by Google Translate), resulting in corruption of the impacted scripts. Consequently, it is better to copy the scripts from the original French version of this page.

Comment réaliser un système MAME dédié sur un Raspberry Pi 4/Pi 400

Pour la génération comme la mienne qui a connu l’époque des arcades, où nous nous retrouvions dans un local sombre, bruyant et souvent enfumé abritant des dizaines de cabinets de jeux vidéos de tous les styles, cette époque a laissée des traces dans la mémoire de plusieurs d'entre nous. Nous en gardons en général de bons souvenirs, parfois même avec une pointe de nostalgie d'une jeunesse, de son innocence ou de son insouciance et du sentiment de liberté qui y était jadis associé.

Aujourd’hui, beaucoup d’entre nous rêvent de pouvoir un jour ressusciter l’ambiance unique de ces lieux et pouvoir jouer à nouveau aux jeux de leur jeunesse avec comme avantage de pouvoir partager ce plaisir et ce bonheur avec leur famille et amis.

Avec l’arrivé du Raspberry Pi, petit ordinateur abordable au format carte de crédit, et tout particulièrement depuis la disponibilité de la version 4 (sortie à l’été 2019) et Pi 400 (sortie à l'automne 2020), il s’avère désormais possible de faire tourner, sur un système optimisé adéquatement, la grande majorité des jeux des années 80 et 90 et même certains jeux des années 2000 et plus récents.

La problématique ?

J'ai longtemps cherché une solution tout-en-un, simple et robuste qui serait dédiée exclusivement à l'émulation des systèmes d'arcade et basée sur le célèbre émulateur Multiple Arcade Machine Emulator (MAME). Pour répondre à mes besoins, cette solution se devait d'être compacte et optimisée. Malheureusement pour moi et à mon grand désarroi, rien de tel n'existait. D'un côté, on retrouve les solutions d'émulation rétro (RetroPie, Lakka, Recalbox) qui émulent des consoles de jeux domestiques et qui permettent également d'émuler les jeux d'arcades à l'aide de versions de MAME adaptées, mais qui toutefois introduisent, de mon opinion personnelle, leur lot de contraintes (devoir posséder les versions de ROMs précises, la configuration des manettes d'arcades n'est pas native, l'interface de navigation n'est pas adaptée spécifiquement à l'émulation d'arcade, etc.). D'un autre côté, on a AdvanceMAME qui est optimisé pour le Raspberry Pi, mais aucune mise à jour n'a été effectuée depuis novembre 2018. De plus, ce dernier est basé sur une version de MAME (0.106) remontant à 2006.

La solution ?

Le faire soi-même : utiliser un OS minimal, compiler la toute dernière version de MAME (0.248 au moment d'écrire ces lignes) satisfaire ses dépendances et configurer le système de sorte qu'il démarre directement dans MAME, rien de plus, rien de moins. De cette façon, on peut utiliser les versions de ROMs les plus récentes, le soutien pour les manettes d'arcade est non seulement possible, mais facile et on utilise l'interface de sélection des ROMs native à MAME, qui est simple et efficace (nul besoin de prévoir un quelconque frontend pour lancer les ROMs).

Ce projet s’inspire de la philosophie du Just Enough Operating System (JeOS) : un système compact et minimal pour faire tourner, de manière la plus optimisée possible, une application. À titre d’exemples de JeOS, mentionnons LibreELEC (media center Kodi), Lakka (émulation de consoles de jeux) et Volumio (lecteur de musique Hi-Fi pour audiophiles).

L’objectif de ce tutoriel est de vous guider à partir de zéro pour monter, étape par étape, un système tout-en-un, minimal, optimisé et dédié qui fera tourner exclusivement la plus récente version de MAME.

Caractéristiques et fonctionnalités :

  • Basé sur Raspberry Pi OS Lite Bookworm 64-bit (anciennement Raspbian Lite, édition de Linux minimale basée sur Debian) ;
  • Au démarrage, affichage d'un splash personnalisé (par exemple, le logo de MAME) ;
  • La version courante de l'émulateur MAME démarre automatiquement, puis affiche l'écran de sélection des ROMs (GUI) ;
  • Lorsque l'on quitte MAME, le système initie un arrêt (shutdown) ;
  • Pendant l'arrêt (shutdown), affichage d'un splash personnalisé (par exemple, le logo de MAME) ;
  • Lorsque les opérations d'arrêt sont complétées, le système s'éteint (power off) ;
  • Un mode (appelé AutoROM) permet le lancement automatique d'un ROM sélectionné au démarrage (utile pour les cabinets dédiés) ;
  • Pour préserver la durée de vie de la carte SD, le système de fichiers racine (root filesystem) est maintenu en mode lecture-seule ;
  • Les meilleurs pointages (hiscores) de chaque ROMs sont sauvegardés et sont persistants ;
  • Les réglages audio (volume) sont sauvegardés et sont persistants ;
  • Un mode pour la maintenance est proposé (appelé le mode Service) afin de permettre les mises à jour du système et effectuer la gestion des ROMs et des Snapshots (via un partage de fichiers Samba).
  • Gestion automatisée du matériel graphique associé aux ROMs dès l'ajout ou le retrait de ceux-ci au sein du système.

À noter que grâce aux optimisations proposées à travers ce guide, un Raspberry Pi 4/Pi 400 muni d'aussi peu que 1 Go de mémoire vive peut être considéré comme adéquat pour l'émulation. À noter toutefois que si vous compilez MAME depuis le Pi 4/Pi 400 lui-même, vous devrez posséder au minimum 2 Go de mémoire vive afin que la compilation puisse s'effectuer correctement.

Bien que je crois me débrouiller pas trop mal avec Linux, je ne me considère pas pour autant un expert. Dans ce contexte, il est toujours possible que des erreurs ou incohérences se soient glissées au sein de ce guide. Ce document est le fruit de deux mois d'expérimentations, d'essais et d'optimisations de manière itérative. Si vous relevez des incohérences ou des erreurs, n'hésitez pas à me le laisser savoir, question que je puisse apporter la ou les corrections.

En terminant, si vous décidez de suivre cette procédure, vous le faites à vos propres risques et je ne peux nullement être tenu responsable pour quelque préjudice que ce soit (notamment les pertes de données, mais sans s'y limiter).

Voici ci-dessous une brève démonstration :

Courte démonstration

-------------- DÉBUT DE LA PROCÉDURE --------------

Téléchargement de Raspberry Pi OS Lite Bookworm 64-bit et écriture sur carte microSD :

Page de téléchargement : https://www.raspberrypi.com/software/operating-systems/#raspberry-pi-os-64-bit

Les étapes ci-dessous sont destinées à un ordinateur tournant sous Linux :

wget https://downloads.raspberrypi.org/raspios_lite_arm64/images/raspios_lite_arm64-2024-03-15/2024-03-15-raspios-bookworm-arm64-lite.img.xz -O raspios-lite-arm64-latest.img.xz

Pour déterminer le nom du block device associé à la carte microSD :

lsblk

Si la carte était déjà formatée, il est possible que vous deviez démonter la (les) partition(s) présentes :

sudo umount /dev/sdd1	# Exemple : Carte SD détectée comme /dev/sdd, partition #1
sudo umount /dev/sdd2	# Exemple : Carte SD détectée comme /dev/sdd, partition #2

Décompression de l’archive .xz qui contient le fichier-image (.img)

xz -d raspios-lite-arm64-latest.img.xz

Écriture de l’image sur la carte microSD (remplacez /dev/sdd par le block device associé à votre carte) :

sudo dd if=raspios-lite-arm64-latest.img of=/dev/sdd status=progress bs=8192
sync

Retirer, puis réinsérez la carte SD au sein du lecteur. Si tout s'est bien déroulé à l'étape précédente, votre système Linux montera automatiquement les deux partitions boot et rootfs de la carte SD nouvellement écrite.

Activation de l’accès SSH

En placant un fichier vide nommé ssh au sein de la partition boot de la carte SD, ceci activera le serveur SSH au premier démarrage.

sudo touch $(findmnt -t vfat PARTUUID=0ee3e8a8-01 --output=target --noheadings)/ssh

Ajustement de la taille du système de fichiers racine à 15 Go

Démonter les partitions boot et rootfs à l'aide des commandes suivantes (remplacez /dev/sdd par le block device de votre carte) :

sudo umount /dev/sdd1
sudo umount /dev/sdd2

Ouverture du gestionnaire de partitions fdisk :

sudo fdisk /dev/sdd
  1. Afficher la table des partitions (p)
  2. Supprimer la seconde partition (d, 2)
  3. Re-créer la partition (n, p, 2)
  4. À l'étape First sector, spécifier l'ancienne valeur du premier secteur (vous référer à la table précédamment affichée)
  5. À l'étape Last sector, inscrire +15G (valeur de 15 Go recommandée) ou toute autre taille que vous jugez appropriée
  6. À la question Do you want to remove the signature?, répondez par non (N)
  7. Afficher la table des partitions (p)
  8. Créer une nouvelle partition (n, p, 3)
  9. À l'étape First sector, spécifier la valeur End de la partition #2, en y additionnant le nombre 1
  10. À l'étape Last sector, accepter la valeur par défaut afin d'allouer tout l'espace non-partitionné
  11. Sauvegarder la table des partitions et quitter (w).

Forcez le système à relie la nouvelle table des partitions (remplacez /dev/sdd par le block device de votre carte) :

sudo partprobe /dev/sdd

Effectuez une vérification du système de fichiers, puis ajustez-le à la nouvelle taille de partition (remplacez /dev/sdd par le block device de votre carte) :

sudo e2fsck -f /dev/sdd2
sudo resize2fs /dev/sdd2
sync

Premier démarrage

À ce stade, les périphériques suivants doivent avoir été branchés à votre Raspberry Pi 4/Pi 400 :

  • Un clavier USB dans un port USB libre (non-applicable à la Pi 400) ;
  • Un écran (téléviseur ou moniteur d'ordinateur) via un câble micro-HDMI vers HDMI ;
  • Un câble Ethernet branché au connecteur RJ-45.

Insérer la carte microSD dans la fente de votre Raspberry Pi 4/Pi 400 et mettez l'unité sous tension.

Lors du premier démarrage, le système vous indiquera le message suivant :

Root partition should be last partition

Ceci est normal, nous avons créé une partition qui est positionnée après la partition du système de fichiers racine (root filesystem). Veuillez simplement ignorer ce message, presser la touche ENTER et le système redémarrera.

[Optionnel] Première ouverture de session via la console

login: pi
password: raspberry

Activation de l’accès via SSH

sudo systemctl enable ssh
sudo systemctl start ssh

Pour obtenir l’adresse IP courante du système :

hostname -I

À partir de ce point, vous pouvez poursuivre à partir d’une session SSH.

Connexion via SSH au Raspberry Pi

Le mot de passe par défaut du compte pi est : raspberry

Depuis un hôte Linux :

ssh pi@<Adresse IP de votre Raspberry Pi>

Depuis Windows :

Téléchargez et exécutez un client SSH (comme PuTTY) et saisissez l'adresse IP de votre Raspberry Pi.

Changement du mot de passe pour le compte pi

passwd

Mise à jour des paquets

Mise à jour des paquets du système :

sudo apt-get update && sudo apt-get upgrade -y
# Cleanup
sudo apt-get clean -y
sudo apt-get autoclean -y

Création des alias

L’idée, c’est de créer deux modes :

  • Le mode Arcade (alias arcademode) : ce mode démarre automatiquement et directement l’émulateur MAME (et rien d'autre).
  • Le mode Service (alias servicemode) :
    • Aucun démmarrage automatique de MAME ;
    • Permet le login depuis la console ;
    • Active le partage de fichier réseau (via Samba) de la partition /data pour permettre la gestion des ROMs et Snapshots.
    • Surveille l'emplacement des fichiers de ROM et :
      • télécharge automatiquement le matériel graphique associé lors d'un ajout ;
      • supprime automatiquement le matériel graphique associé lors d'un retrait/suppression.

Édition du fichier de définition des alias du shell Bash :

nano ~/.bash_aliases

Ajouter ces lignes pour créer les alias dont nous avons besoin :

alias update='sudo apt-get update && sudo apt-get upgrade -y'
alias cputemp='/usr/bin/vcgencmd measure_temp'
alias cpufreq="echo Clock Speed=$(($(/usr/bin/vcgencmd measure_clock arm | awk -F '=' '{print $2}')/1000000)) MHz"
alias frontend='upd(){ grep -q $1= ~/settings && sed -i "s/^$1=.*$/$2/g" $(readlink -f ~/settings) || echo $2 | tee -a ~/settings;}; _frontend(){ if [[ "${1,,}" =~ ^(mame|attract|advance)$ ]]; then [ ! -f ~/settings ] && touch ~/settings; upd FRONTEND FRONTEND="${1,,}" && echo "Frontend set to: "${1,,}" (reboot to apply)."; case "${1,,}" in mame) [ -z "$2" ] && upd AUTOROM AUTOROM= || (upd AUTOROM AUTOROM="${2,,}"; echo "Automatic ROM Launch set to: "${2,,}".") ;; attract) EMUL=~/.attract/emulators/"$2".cfg; if ([ ! -z "$2" ] && [ ! -z "$3" ] && [ -f $EMUL ]); then (upd AUTOROM "AUTOROM=\""$2" "${3,,}"\""; echo "Automatic ROM Launch set to: "${3,,}" (emulator "$2")."); else [ ! -z "$2" ] && echo "Invalid emulator or missing rom."; upd AUTOROM AUTOROM=; fi; ;; esac; else echo "Invalid or missing argument. Try: mame [rom], attract [emulator rom] or advance"; fi;}; _frontend'

# Aliases to switch between Arcade Mode and Service Mode
alias arcademode='sudo systemctl enable mame-autostart.service'
alias servicemode='sudo systemctl disable mame-autostart.service'
alias mode='echo -n "The system is currently in "; systemctl -q is-active mame-autostart.service && echo -n ARCADE || echo -n SERVICE; echo " mode."'

Sauvegarder, logout et login à nouveau pour appliquer les nouveaux alias.

Supprimer l’avertissement (disclaimer) ci-dessous au login :

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.

À l’aide de cette commande :

sudo rm /etc/motd

Script de vérification de la plus récente version des émulateurs (MAME et Hypseus-Singe)

mkdir ~/scripts
nano ~/scripts/versions-check.sh

Coller les lignes ci-dessous, puis sauvegarder :

#!/bin/bash

function version { echo "$@" | awk -F. '{ printf("%d%03d%03d%03d\n", $1,$2,$3,$4); }'; }

# This function check the latest available version of MAME and display a notice if the current version is older.
function mame-check {
  CHECKURL=https://github.com/mamedev/mame/releases/latest
  HTMLTAG='<title>Release MAME'

  [ -x /home/pi/mame/mame ] && export MAMEVER=$(/home/pi/mame/mame -version | cut -d' ' -f1)
  if [ ! -z $MAMEVER ]; then
    LATESTMAMEVER=$(wget -q -O - $CHECKURL | grep "$HTMLTAG" | awk '{print $3}')

    if [ -z $LATESTMAMEVER ]; then echo $MAMEVER ERROR; exit; fi  # We make sure wget was successful

    if [ $(version $LATESTMAMEVER) -gt $(version $MAMEVER) ]; then
      echo $MAMEVER $LATESTMAMEVER
    else
      echo $MAMEVER Latest
    fi
  fi
  }

# This script check the latest available version of Hypseus-Singe and display a notice if the current version is older.
function hypseus-check {
  CHECKURL=https://github.com/DirtBagXon/hypseus-singe/releases/latest
  HTMLTAG='<title>Release hypseus-singe'
  HYPSEUSPATH=/home/pi/hypseus

  [ -x $HYPSEUSPATH/hypseus ] && export HYPSEUSVER=$($HYPSEUSPATH/hypseus -v | awk '/^\[version\]/{print $4}')
  if [ ! -z $HYPSEUSVER ]; then
    LATESTHYPSEUSVER=$(wget -q -O - $CHECKURL | grep "$HTMLTAG" | awk '{print $3}')

    if [ -z $LATESTHYPSEUSVER ]; then echo $HYPSEUSVER ERROR; exit; fi  # We make sure wget was successful

    LATESTHYPSEUSVER=${LATESTHYPSEUSVER##v}             # Strip the leading v
    HYPSEUSVER=$(echo $HYPSEUSVER | sed 's/^v*//; s/-RPi$//')    # Strip the leading v and trailing -RPi

    if [ $(version $LATESTHYPSEUSVER) -gt $(version $HYPSEUSVER) ]; then
      echo $HYPSEUSVER $LATESTHYPSEUSVER
    else
      echo $HYPSEUSVER Latest
    fi
  fi
  }

if [ -x $HOME/mame/mame ] || [ -x $HOME/hypseus/hypseus ]; then
  echo '+---------------+-----------+-----------+'
  echo '| EMULATOR      | CURRENT   | LATEST    |'
  echo '+---------------+-----------+-----------+'
  [ -x $HOME/mame/mame ]       && echo -n '| MAME          | '; mame-check    | awk '{ printf "%-9s | %-9s |\n", $1, $2}'
  [ -x $HOME/hypseus/hypseus ] && echo -n '| Hypseus-Singe | '; hypseus-check | awk '{ printf "%-9s | %-9s |\n", $1, $2}'
  echo '+---------------+-----------+-----------+'
fi

Ajustement des permissions pour permettre l’exécution du script :

chmod +x ~/scripts/versions-check.sh

Affichage des notices au login

sudo nano /etc/bash.bashrc

Pour afficher le Frontend courant ainsi que le ROM couramment émulé par MAME (si applicable), coller les lignes ci-dessous à la fin du fichier :

echo '----------------------------------------------------------------------'
# Load environment settings...
if [ -f /home/pi/settings ]; then
  while IFS="= " read var value; do
    [ ! -z $var ] && [ "${var:0:1}" != "#" ] && export $var="$value"
  done < /home/pi/settings
fi
MAMEROM=$(ps h -C mame -o cmd | awk '{print $2}'); [ "${MAMEROM:0:1}" == "-" ] && MAMEROM=
echo "Current Frontend: $(case $FRONTEND in \
  attract) echo "Attract Mode$([ -x /usr/local/bin/attract ] && attract -v | awk '/Attract-Mode/ {print " " $2}')" ;; \
  advance) echo AdvanceMENU ;; \
  mame) ([ ! -z $MAMEROM ] && [ "$MAMEROM" == "$AUTOROM" ]) && echo 'None/AutoROM Mode' || echo 'MAME GUI' ;; \
  *) echo 'NOT SET' ;; esac)."
[ ! -z $MAMEROM ] && echo Currently emulated ROM: \
  $(/home/pi/mame/mame -listfull $MAMEROM | awk -F '"' '!/Description:$/ {print $2}').

Pour afficher un tableau récapitulatif des versions de MAME et de Hypseus-Singe, coller la ligne ci-dessous à la suite de celles ci-dessus, puis sauvegarder :

[ -x $HOME/scripts/versions-check.sh ] && . $HOME/scripts/versions-check.sh

Pour afficher le mode actif (Service ou Arcade), coller la ligne ci-dessous à la suite de celle ci-dessus, puis sauvegarder :

echo "The system is currently in $(systemctl -q is-active mame-autostart.service && echo ARCADE || echo SERVICE) mode."

Ajouter la mention indiquant que le mode Service est en fonction lorsque le getty de la console (getty@tty1.service) est actif :

sudo nano /etc/issue

Ajouter les lignes SERVICE MODE et IP Address: \4 (tel qu'indiqué ci-dessous) sous le texte déjà présent (laisser deux lignes vides en dessous), puis sauvegarder :

Raspbian GNU/Linux 11 \n \l

S E R V I C E      M O D E

IP Address: \4

Personnalisations du système

Réglage du fuseau horaire :

sudo dpkg-reconfigure tzdata

[Optionnel] Configuration de la langue du clavier et de l'emplacement :

sudo dpkg-reconfigure keyboard-configuration
sudo dpkg-reconfigure locales

[Optionnel] Configuration du serveur de synchronisation de l'heure sur internet (NTP) :

sudo nano /etc/systemd/timesyncd.conf

À la ligne NTP=, spécifier le nom du serveur NTP (ou du pool de serveurs, selon NTP Pool Project) à utiliser, puis sauvegarder :

NTP=ca.pool.ntp.org

Changement du nom d’hôte :

sudo nano /etc/hostname
sudo nano /etc/hosts

Repérer la ligne qui débute par 127.0.0.1 et remplacer raspberrypi à droite par le nom désiré (par exemple : arcade), puis redémarrer à l'aide de la commande ci-dessous :

sudo reboot

Ajustement des privilèges du compte pi

Afin que SDL2 puisse accéder directement au noeud de rendu graphique DRM /dev/dri/renderD128, nous devons ajouter le groupe render au compte pi. Pour ce faire :

sudo usermod -a -G render pi

[Optionnel] Désactivation du Wi-Fi

Comme je ne compte utiliser que l’interface Ethernet filaire, je désactive Wi-Fi.

sudo nano /boot/config.txt

Coller les lignes ci-dessous, puis sauvegarder :

# Turns off WiFi (for those who use Ethernet only)
dtoverlay=disable-wifi

Désactiver WPA Supplicant (lié au Wi-Fi) :

sudo apt-get remove wpasupplicant -y

[Optionnel] Désactivation de Bluetooth

Comme je ne compte pas utiliser de périphériques Bluetooth, je le désactive et le désinstalle.

sudo nano /boot/config.txt

Coller les lignes ci-dessous, puis sauvegarder :

# Turns off Bluetooth
dtoverlay=disable-bt

Retrait des paquets liés à Bluetooth :

sudo apt-get remove bluez pi-bluetooth -y

[Optionnel] Désactivation de IPv6

Si vous n'utilisez pas IPv6, vous pouvez le désactiver comme suit :

sudo nano /boot/cmdline.txt

Ajoutez la commande suivante à la ligne de commande du kernel (sur la même ligne que les autres commandes), puis sauvegardez :

ipv6.disable=1

Éditez le fichier de configuration de dhcpd :

sudo nano /etc/dhcpcd.conf

Ajoutez les lignes suivantes à la fin du fichier, puis sauvegardez :

noarp
ipv4only
noipv6

Nous devons également ajuster le drop-in du client DHCP afin d'ignorer complètement IPv6 :

sudo nano /etc/systemd/system/dhcpcd.service.d/wait.conf

À la ligne :

ExecStart=/usr/lib/dhcpcd5/dhcpcd -q -w

Ajoutez -4 après dhcpcd, puis sauvegardez :

ExecStart=/usr/lib/dhcpcd5/dhcpcd -4 -q -w

Désactivation de Avahi (mDNS)

sudo apt-get remove avahi-daemon -y

Désactivation du client NFS

sudo apt-get remove nfs-common -y

Augmentation des performances (Overclocking)

IMPORTANT : votre Raspberry Pi 4 doit être adéquatement refroidi (soit passivement par des dissipateurs de chaleur ou encore par un boîtier en métal spécialement adapté avec contact sur le CPU et qui agit à titre de dissipateur, soit par une ventilation adéquate).

À NOTER que si vous décidez de faire ce changement, vous le faites à vos propres risques et périls, je ne peux être tenu responsable de quoi que ce soit.

sudo nano /boot/config.txt

Ajouter ce bloc à la fin du fichier, puis sauvegarder :

# Overclocking
arm_freq=2000
over_voltage=6

Pour appliquer le changement, redémarrer le système à l'aide de cette commande :

sudo reboot

Bascule du CPU Governor en mode Performance

Afin de prévenir l'abaissement automatique de la fréquence du CPU lorsque celui-ci est moins sollicité (c'est le comportement du mode On Demand), nous devons ajuster le réglage du Governor et l'affecter à la valeur Performance.

Pour ce faire :

sudo apt-get install cpufrequtils -y
grep -q GOVERNOR= /etc/init.d/cpufrequtils && sudo sed -i "s/GOVERNOR=.*$/GOVERNOR=\"performance\"/g" /etc/init.d/cpufrequtils

Appliquer les changements :

sudo systemctl daemon-reload
sudo systemctl restart cpufrequtils.service

Valider les changements :

cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor

La commande ci-dessus devrait retourner la valeur performance à 4 reprises (une pour chaque coeur de CPU).

cpufreq

L'invocation de l'alias ci-dessus (que nous avons défini plus haut) devrait retourner Clock Speed=1750 MHz, qui correspond à la fréquence d'overclocking que nous avons spécifiée plus haut.

Activation du pilote DRM VC4 V3D

sudo nano /boot/config.txt

Ajouter ce bloc à la fin du fichier, puis sauvegarder :

[pi4]
# Enable DRM VC4 V3D driver on top of the dispmanx display stack
dtoverlay=vc4-fkms-v3d
max_framebuffers=2

Compilation de SDL2 (optimisé, sans X11)

Comme nous utilisons un système Linux minimal sans système graphique de fenêtrage comme X11 et que nous voulons tirer parti au maximum des ressources du Raspberry Pi 4, nous devons compiler la librairie graphique SDL2 sans le soutien pour X11 et également lui indiquer d’offrir le soutien pour les pilotes de type Kernel Mode-Setting/Direct Rendering Manager (KMS/DRM).

Création du script automatisé de compilation de SDL2 :

nano ~/scripts/sdl2-latest.sh

Coller les lignes ci-dessous dans l'éditeur, puis sauvegarder :

#!/bin/bash

# This script build the latest SDL2 version without X11 dependency.

function sdl2-latest {
  CHECKURL=https://github.com/libsdl-org/SDL/releases/latest
  HTMLTAG='<title>Release '

  LATESTSDL2VER=$(wget -q -O - $CHECKURL | grep "$HTMLTAG" | awk '{print $2}')

  if [ -z $LATESTSDL2VER ]; then echo ERROR; exit; fi   # We make sure wget was successful

  echo $LATESTSDL2VER
  }

function sdl2-ttf-latest {
  CHECKURL=https://github.com/libsdl-org/SDL_ttf/releases/latest
  HTMLTAG='<title>Release '

  LATESTSDL2TTFVER=$(wget -q -O - $CHECKURL | grep "$HTMLTAG" | awk '{print $2}')

  if [ -z $LATESTSDL2TTFVER ]; then echo ERROR; exit; fi   # We make sure wget was successful

  echo $LATESTSDL2TTFVER
  }

VERSION=$(sdl2-latest)
TTFVERSION=$(sdl2-ttf-latest)

if [ "$(sdl2-config --version)" == "$VERSION" ]; then
  echo SDL2 is already at the latest version \($VERSION\).
  exit
else
  if [ "${1,,}" != "nodep" ]; then
    echo Installing SDL2 dependencies...
    sudo apt-get install libfreetype6-dev libdrm-dev libgbm-dev libudev-dev libdbus-1-dev libasound2-dev liblzma-dev libjpeg-dev libtiff-dev libwebp-dev -y
    echo OpenGL ES 2 dependencies...
    sudo apt-get install libgles2-mesa-dev -y
  fi
  echo Build dependencies...
  sudo apt-get install build-essential -y
  cd ~
  echo Buiding SDL2 $VERSION...
  # Based from "Compile SDL2 from source"
  # https://github.com/midwan/amiberry/wiki/Compile-SDL2-from-source
  wget https://libsdl.org/release/SDL2-${VERSION}.zip
  unzip SDL2-${VERSION}.zip
  rm SDL2-${VERSION}.zip
  cd SDL2-${VERSION}
  ./configure --disable-video-opengl --disable-video-opengles1 --disable-video-x11 --disable-pulseaudio --disable-esd --disable-video-wayland --disable-video-rpi --disable-video-vulkan --enable-video-kmsdrm --enable-video-opengles2 --enable-alsa --disable-joystick-virtual --enable-arm-neon --enable-arm-simd

  [ $(uname -m) == "armv7l" ] && make -j $(nproc) CFLAGS='-mtune=cortex-a72 -mfpu=neon-fp-armv8 -mfloat-abi=hard'
  [ $(uname -m) == "aarch64" ] && make -j $(nproc) CFLAGS='-mcpu=cortex-a72'

  sudo make install

  # SDL2_ttf
  wget https://libsdl.org/projects/SDL_ttf/release/SDL2_ttf-${TTFVERSION}.tar.gz
  tar zxvf SDL2_ttf-${TTFVERSION}.tar.gz
  rm SDL2_ttf-${TTFVERSION}.tar.gz
  cd SDL2_ttf-${TTFVERSION}
  ./configure
  make -j $(nproc)
  sudo make install
  sudo ldconfig -v

  cd ~
  sudo rm -R SDL2-${VERSION}
  sudo rm -R SDL2_ttf-${TTFVERSION}
  sudo apt-get remove build-essential -y
fi

Ajustement des permissions pour permettre l’exécution du script :

chmod +x ~/scripts/sdl2-latest.sh

Lancer la compilation de SDL2 :

~/scripts/sdl2-latest.sh

Compilation de MAME (optimisé, sans X11)

Nous devons d'abord créer une patch pour ajuster un fichier de définition de headers de MAME (au sein de BGFX, en lien avec l'option NO_X11=1 passée au compilateur).

Création du fichier de patch pour glimports.h :

nano ~/scripts/glimports.h.patch

Coller les lignes ci-dessous dans l'éditeur, puis sauvegarder :

--- a/3rdparty/bgfx/src/glimports.h	2023-06-27 11:49:47.000000000 -0400
+++ b/3rdparty/bgfx/src/glimports.h	2023-07-10 14:35:58.245066329 -0400
@@ -584,14 +584,14 @@
 GL_IMPORT_____x(true,  PFNGLBLENDFUNCIPROC,                        glBlendFunci);
 GL_IMPORT_____x(true,  PFNGLBLENDFUNCSEPARATEIPROC,                glBlendFuncSeparatei);
 
-GL_IMPORT______(true,  PFNGLDRAWBUFFERPROC,                        glDrawBuffer);
-GL_IMPORT______(true,  PFNGLREADBUFFERPROC,                        glReadBuffer);
-GL_IMPORT______(true,  PFNGLGENSAMPLERSPROC,                       glGenSamplers);
-GL_IMPORT______(true,  PFNGLDELETESAMPLERSPROC,                    glDeleteSamplers);
-GL_IMPORT______(true,  PFNGLBINDSAMPLERPROC,                       glBindSampler);
-GL_IMPORT______(true,  PFNGLSAMPLERPARAMETERFPROC,                 glSamplerParameterf);
-GL_IMPORT______(true,  PFNGLSAMPLERPARAMETERIPROC,                 glSamplerParameteri);
-GL_IMPORT______(true,  PFNGLSAMPLERPARAMETERFVPROC,                glSamplerParameterfv);
+// GL_IMPORT______(true,  PFNGLDRAWBUFFERPROC,                        glDrawBuffer);
+// GL_IMPORT______(true,  PFNGLREADBUFFERPROC,                        glReadBuffer);
+// GL_IMPORT______(true,  PFNGLGENSAMPLERSPROC,                       glGenSamplers);
+// GL_IMPORT______(true,  PFNGLDELETESAMPLERSPROC,                    glDeleteSamplers);
+// GL_IMPORT______(true,  PFNGLBINDSAMPLERPROC,                       glBindSampler);
+// GL_IMPORT______(true,  PFNGLSAMPLERPARAMETERFPROC,                 glSamplerParameterf);
+// GL_IMPORT______(true,  PFNGLSAMPLERPARAMETERIPROC,                 glSamplerParameteri);
+// GL_IMPORT______(true,  PFNGLSAMPLERPARAMETERFVPROC,                glSamplerParameterfv);
 
 GL_IMPORT_____x(true,  PFNGLBINDBUFFERBASEPROC,                    glBindBufferBase);
 GL_IMPORT_____x(true,  PFNGLBINDBUFFERRANGEPROC,                   glBindBufferRange);

Création du script automatisé de compilation de MAME :

nano ~/scripts/mame-updater.sh

Coller les lignes ci-dessous dans l'éditeur, puis sauvegarder :

#!/bin/bash

# This script update MAME to the latest version or a specific version.

# GCC compiler optimization for ARM-based systems : https://gist.github.com/fm4dd/c663217935dc17f0fc73c9c81b0aa845
#ARCHOPTS='-mcpu=cortex-a72 -mtune=cortex-a72 -mfpu=neon-fp-armv8 -mfloat-abi=hard -mneon-for-64bits -funsafe-math-optimizations -munaligned-access -fexpensive-optimizations'

# A tester.....
ARCHOPTS32='-march=armv8-a+crc+simd -mcpu=cortex-a72 -mtune=cortex-a72 -mfpu=neon-fp-armv8 -mfloat-abi=hard -funsafe-math-optimizations -fprefetch-loop-arrays -fexpensive-optimizations'
ARCHOPTS64='-march=armv8-a+crc+simd -mcpu=cortex-a72 -mtune=cortex-a72 -funsafe-math-optimizations -fprefetch-loop-arrays -fexpensive-optimizations'

MAKEOPTS='TARGETOS=linux NO_X11=1 NOWERROR=1 NO_USE_XINPUT=1 NO_USE_XINPUT_WII_LIGHTGUN_HACK=1 NO_OPENGL=1 USE_QTDEBUG=0 DEBUG=0 REGENIE=1 NO_BGFX=1 FORCE_DRC_C_BACKEND=1 NO_USE_PORTAUDIO=1 SYMBOLS=0'
MAXTHREAD=2    # From MAME version 0.227 and up, we should use a max. of 3 threads to avoid an out of memory error.

secs_to_human() {
    echo "$(( ${1} / 3600 ))h $(( (${1} / 60) % 60 ))m $(( ${1} % 60 ))s"
    }

fs_unlock() {   # Put root filesystem in read/write mode
    for o in $(findmnt -n -o OPTIONS / | sed 's/,/ /g'); do
        [ "${o,,}" = ro ] && sudo mount -o remount,rw /
    done
    }

fs_lock() {     # Put root filesystem in read-only mode
    for o in $(findmnt -n -o OPTIONS / | sed 's/,/ /g'); do
        [ "${o,,}" = rw ] && sudo mount -o remount,ro /
    done
    }

set_env() {     # Make an environment variable persistent
    local KEY=$(echo $1 | awk -F '=' '{print $1}')
    local VALUE=$(echo $1 | awk -F '=' '{print $2}')
    grep -q $KEY= /etc/environment && sudo sed -i "s/$KEY=.*$/$KEY=$VALUE/g" /etc/environment || echo "$KEY=$VALUE" | sudo tee -a /etc/environment
    }

get_history() {      # Grab the latest history.dat file
    local BASEURL=https://www.arcade-history.com
    local BASETAG='<a class="noir" rel="nofollow" href="../dats/'
    local REGEX='[^*]*(a class="noir" rel="nofollow" href="../dats/)(.*?)("><img src="images/design/download3.gif" height="40px" />)[^*]*'

    HISTORYFILE=$(wget -q -O - $BASEURL/index.php?page=download | grep "$BASETAG" | sed -r "s%$REGEX%\2%")
    wget -q $BASEURL/dats/$HISTORYFILE -P ~    # Download the file
    unzip -o ~/$HISTORYFILE history.dat -d ~/.mame
    if [ -L ~/.mame/history ]; then                # Symlink is present
        mv ~/.mame/history.dat ~/.mame/history
    fi
    rm ~/$HISTORYFILE                          # Cleanup
    }

mame-latest() {         # Get the latest version of MAME
  CHECKURL=https://github.com/mamedev/mame/releases/latest
  HTMLTAG='<title>Release MAME'

  LATESTMAMEVER=$(wget -q -O - $CHECKURL | grep "$HTMLTAG" | awk '{print $3}')

  if [ -z $LATESTMAMEVER ]; then echo ERROR; exit; fi  # We make sure wget was successful

  echo $LATESTMAMEVER
  }

if (systemctl -q is-active mame-autostart.service) then
    echo "The system must be put in SERVICE Mode first."
    exit
fi

if [ ! $1 ]; then
    echo Usage: $0 VER | Latest
    echo '  Where VER is the 4-digit version number of MAME to update (for example: 0224).'
    echo '  OR use the argument Latest to update to the latest available MAME version.'
else
    if [ $(free -g | awk '/^Mem:/{print $2}') -lt 3 ]; then
        echo You need 4 GB of RAM to compile MAME with multithread support.
        exit
    fi

    if [ "${1,,}" == "latest" ]; then
      MAMEVER=$(mame-latest)
      MAMEVER=${MAMEVER//./}    # Remove the dot
    else
      MAMEVER=$1
    fi
    MAMESRCPATH=/home/pi/mame${MAMEVER}
    SCRIPTPATH=${0%/*}

    echo Installing/uptading to MAME $MAMEVER...
    fs_unlock

    # Install MAME dependencies...
    sudo apt-get install fontconfig libfontconfig-dev libx11-dev libpulse-dev -y

    if [ ! -d $MAMESRCPATH ]; then
        cd ~
        if [ ! -f ~/mame${MAMEVER}.zip ]; then    # Not already downloaded
            wget https://github.com/mamedev/mame/archive/mame${MAMEVER}.zip
        fi

        if [ -f ~/mame${MAMEVER}.zip ]; then      # If download successful, uncompress ...
            unzip mame${MAMEVER}.zip
            mv mame-mame${MAMEVER} mame${MAMEVER}
            rm mame${MAMEVER}.zip
        fi
    fi

    if [ ! -x $MAMESRCPATH/mame ]; then         # We build only if not already built
        # Build of MAME

        # Dependencies
        # Swap requirement
        sudo apt-get install dphys-swapfile -y
        if [ "$(grep '^CONF_SWAPSIZE' /etc/dphys-swapfile | cut -d= -f2)" != "2048" ]; then
            sudo sed -i "s/^#\{0,1\}\s*CONF_SWAPSIZE=.*$/CONF_SWAPSIZE=2048/g" /etc/dphys-swapfile
        fi
        # The swap value should be 2048

        # Activate the swap...
        sudo systemctl stop dphys-swapfile.service
        sudo systemctl start dphys-swapfile.service
        # Build dependencies
        sudo apt-get install build-essential -y

        # Patching drawbgfx.cpp...
        if [ -f $SCRIPTPATH/drawbgfx.cpp.patch ]; then
            patch -r - -Ni $SCRIPTPATH/glimports.h.patch $MAMESRCPATH/3rdparty/bgfx/src/glimports.h
        fi
        cd $MAMESRCPATH
        [ "$(uname -m)" == "armv7l" ]  && echo MAKE CMDLINE=make -j$MAXTHREAD ARCHOPTS=\"$ARCHOPTS32\" $MAKEOPTS PLATFORM=arm
        [ "$(uname -m)" == "aarch64" ] && echo MAKE CMDLINE=make -j$MAXTHREAD ARCHOPTS=\"$ARCHOPTS64\" $MAKEOPTS PLATFORM=arm64 PTR64=1
        BUILDSTART=$(date +%s)
        echo Build start time: $(date +"%T")
        echo -----------------------------------------------------------------------------------
        echo Please wait until the build is completed \(about 10 hours\)...
        echo -----------------------------------------------------------------------------------
        [ "$(uname -m)" == "armv7l" ]  && make -j$MAXTHREAD ARCHOPTS="$ARCHOPTS32" $MAKEOPTS PLATFORM=arm
        [ "$(uname -m)" == "aarch64" ] && make -j$MAXTHREAD ARCHOPTS="$ARCHOPTS64" $MAKEOPTS PLATFORM=arm64 PTR64=1


        echo Build time took: $(secs_to_human "$(($(date +%s) - ${BUILDSTART}))").

        if [ -x $MAMESRCPATH/mame ]; then
            echo -----------------------------------------------------------------------------------
            echo Build Success!
            echo -----------------------------------------------------------------------------------
            # Successful build!
            # We make sure the MAME environment variable is persistent...
            set_env SDL_VIDEODRIVER=kmsdrm
            set_env SDL_RENDER_DRIVER=opengles2
            set_env SDL_RENDER_VSYNC=1
            set_env SDL_GRAB_KEYBOARD=1
            set_env SDL_VIDEO_GLES2=1

            # Install MAME True-Type Liberation Sans font
            if [ ! -d /usr/share/fonts/truetype/liberation-fonts ]; then
              echo Installing Liberation Sans font...
              cd ~
              wget -q https://dl.dafont.com/dl/?f=liberation_sans -O liberation_sans.zip
              if [ -f liberation_sans.zip ]; then
                sudo mkdir /usr/share/fonts/truetype/liberation-fonts
                sudo unzip -o /home/pi/liberation_sans.zip *.ttf -d /usr/share/fonts/truetype/liberation-fonts
                rm liberation_sans.zip
                sudo fc-cache -f -v
              fi
            fi

            # MAME binary symlink creation or update
            if [ -L ~/mame ]; then rm ~/mame; fi
            ln -s $MAMESRCPATH ~/mame

            if [ ! -L ~/.mame ] && [ ! -d ~/.mame ]; then   # MAME data path symlink creation
                [ -d /data/mame ] && ln -s /data/mame ~/.mame || mkdir ~/.mame
            fi

            if [ ! -f ~/.mame/mame.ini ]; then  # If mame.ini does not exist, let's create it
                cd ~/.mame
                $MAMESRCPATH/mame \
                  -hashpath '$HOME/mame/hash' \
                  -languagepath '$HOME/mame/language' \
                  -pluginspath '$HOME/mame/plugins' \
                  -artpath '$HOME/.mame/artwork' \
                  -ctrlrpath '$HOME/.mame/ctrlr' \
                  -inipath '$HOME/.mame/ini' \
                  -homepath '$HOME/.mame/lua' \
                  -rompath '$HOME/.mame/roms' \
                  -cfg_directory '$HOME/.mame/cfg' \
                  -diff_directory '$HOME/.mame/diff' \
                  -input_directory '$HOME/.mame/inp' \
                  -nvram_directory '$HOME/.mame/nvram' \
                  -snapshot_directory '$HOME/.mame/snap' \
                  -state_directory '$HOME/.mame/sta' \
                  -skip_gameinfo \
                  -video accel \
                  -videodriver kmsdrm \
                  -renderdriver opengles2 \
                  -audiodriver alsa \
                  -samplerate 22050 \
                  -createconfig
            fi

            if [ -z $FRONTEND ]; then
              if [ ! -f /home/pi/settings ]; then
                echo FRONTEND=mame>/home/pi/settings
              else
                grep -q FRONTEND= /home/pi/settings && sed -i "s/^FRONTEND=.*$/FRONTEND="${1,,}"/g" $(readlink /home/pi/settings) || (echo AUTOROM="${2,,}" | tee -a /home/pi/settings; echo | tee -a /home/pi/settings)
              fi
            fi

            if [ ! -L /home/pi/settings ] && [[ $(findmnt -n /data) ]]; then    # Symlink not found and /data is mounted...
              [ ! -f /data/.sys/env/settings ] && mkdir -p /data/.sys/env
              if [ ! -f /home/pi/settings ]; then
                touch /data/.sys/env/settings
                echo 'FRONTEND=mame'>/home/pi/settings
              else      # File settings already exist
                mv /home/pi/settings /data/.sys/env
              fi
              ln -s /data/.sys/env/settings /home/pi/settings
            fi

            # Get the latest history.dat file
            echo Applying latest history.dat...
            # get_history   # Broken, to be fixed

            # Freeing some space...
            for f in src build 3rdparty roms
            do
                rm -Rf $MAMESRCPATH/$f
            done

            # Removing dependencies
            echo Removing dependencies...
            # Removing swap...
            sudo systemctl stop dphys-swapfile.service
            sudo rm /var/swap
            sudo apt-get remove dphys-swapfile build-essential -y
            sudo apt-get autoremove -y
        else
            echo -----------------------------------------------------------------------------------
            echo Build FAILED.
            echo -----------------------------------------------------------------------------------
        fi
    fi
    fs_lock
fi

Ajustement des permissions pour permettre l’exécution du script :

chmod +x ~/scripts/mame-updater.sh

Compilation de la plus récente version de MAME :

./scripts/mame-updater.sh latest

Patienter environ 10 heures et demie (ce temps est obtenu avec un Raspberry Pi 4 et un maximum de 2 threads pour la compilation), afin que la compilation se complète…

À noter que des avertissements (de couleur cyan) apparaîtront, ici et là, lors de la compilation : il suffit de les ignorer, ils ne compromettent pas le processus.

[Optionnel] Personnalisations additionnelles de MAME

J’ajoute personnellement un filtre pour créer un effet semblable aux écrans cathodiques (scanlines). De plus, pour tester je possè un contrôleur X-Arcade Solo pour lequel je spécifie le fichier de mappings associé :

nano ~/.mame/mame.ini

Coller ces lignes :

effect                    scanlines
ctrlr                     xarcade

[Optionnel] Personnalisations X-Arcade Solo

J'apporte certains ajustements au fichier de mappings de ma manette X-Arcade Solo de sorte qu'aucun clavier ne soit nécessaire pour naviguer dans les menus et quitter MAME.

nano ~/mame/ctrlr/xarcade.cfg

Coller le texte ci-dessous pour UI_FOCUS_NEXT, UI_PAUSE et ajuster les éléments déjà présents UI_CONFIGURE et UI_CANCEL, puis sauvegarder :

                        <port type="UI_FOCUS_NEXT">     <!-- Custom remap to cycle through each section in main selection screen -->
                            <newseq type="standard">KEYCODE_TAB OR KEYCODE_LALT KEYCODE_4</newseq>
                        </port>

                        <port type="UI_PAUSE">          <!-- Custom remap to pause the game -->
                                <newseq type="standard">KEYCODE_P OR KEYCODE_3 KEYCODE_4</newseq>
                        </port>

                        <port type="UI_CONFIGURE">      <!-- Custom remap to get the in-game menu -->
                                <newseq type="standard">KEYCODE_TAB OR KEYCODE_LALT KEYCODE_4</newseq>
                        </port>

                        <port type="UI_CANCEL">         <!-- Custom remap to quit emulation and exit MAME if in the main selection screen -->
                                <newseq type="standard">KEYCODE_ESC OR KEYCODE_LALT KEYCODE_1</newseq>
                        </port>

Ajustements d'emplacements additionnels

Édition du fichier plugin.ini pour activer deux plugins (data et hiscore) :

nano ~/.mame/plugin.ini

Coller les lignes ci-dessous, puis sauvegarder :

#
# PLUGINS OPTIONS
#
cheat                     0
cheatfind                 0
console                   0
data                      1
dummy                     0
gdbstub                   0
hiscore                   1
layout                    0
portname                  0
timer                     0

Création du fichier hiscore.ini pour pouvoir ajuster le chemin des sauvegardes :

nano ~/.mame/hiscore.ini

Coller la ligne ci-dessous, puis sauvegarder :

hi_path                   $HOME/.mame/hi

Externalisation de dossiers additionnels au sein de ui.ini vers le profil :

nano ~/.mame/ui.ini

Ajuster les chemins ci-dessous en spécifiant le préfixe $HOME/.mame/ suivi du nom du dossier :

cabinets_directory        $HOME/.mame/cabinets
cpanels_directory         $HOME/.mame/cpanels
pcbs_directory            $HOME/.mame/pcb
flyers_directory          $HOME/.mame/flyers
historypath               $HOME/.mame/history
titles_directory          $HOME/.mame/titles
marquees_directory        $HOME/.mame/marquees
icons_directory           $HOME/.mame/icons
ui_path                   $HOME/.mame/ui

Compilation de Hypseus-Singe (émulateur de jeux Laser-Disc d'arcade)

Nous allons créer le script de compilation suivant :

nano ~/scripts/hypseus-build.sh

Coller les lignes ci-dessous, puis sauvegarder :

#!/bin/bash

# This script build and install the latest version of the laserdisc emulator Hypseus-Singe.

function hypseus-latest {
  CHECKURL=https://github.com/DirtBagXon/hypseus-singe/releases/latest
  HTMLTAG='<title>Release hypseus-singe'

  LATESTHYPSEUSVER=$(wget -q -O - $CHECKURL | grep "$HTMLTAG" | awk '{print $3}')

  if [ -z $LATESTHYPSEUSVER ]; then echo ERROR; exit; fi    # We make sure wget was successful

  LATESTHYPSEUSVER=${LATESTHYPSEUSVER##v}             # Strip the leading v
  echo $LATESTHYPSEUSVER
  }

if [ "${1,,}" != "nodep" ]; then
  echo Installing dependencies...
  # Hypseus-Singe dependencies...
  # SDL2_image
  cd ~
  wget https://libsdl.org/projects/SDL_image/release/SDL2_image-2.0.5.zip
  unzip -q SDL2_image-2.0.5.zip
  cd SDL2_image-2.0.5
  ./configure
  make -j $(nproc)
  sudo make install
  sudo ldconfig -v
  cd ../
  rm SDL2_image-2.0.5.zip
  rm -R SDL2_image-2.0.5

  sudo apt-get install libmpeg2-4-dev libvorbis-dev libogg-dev zlib1g-dev -y
fi

VERSION=$(hypseus-latest)
if [ ! -d ~/hypseus-singe-${VERSION}-RPi ]; then
  echo Downloading Hypseus-Singe $VERSION...
  cd ~
  wget https://github.com/DirtBagXon/hypseus-singe/archive/refs/tags/v${VERSION}-RPi.zip
  unzip -q v${VERSION}-RPi.zip
fi

if [ ! -x ~/hypseus-singe-${VERSION}-RPi/hypseus ]; then
  # Dependency to build
  sudo apt-get install cmake build-essential -y

  echo Building Hypseus-Singe $VERSION...
  cd ~/hypseus-singe-${VERSION}-RPi/
  mkdir build
  cd build
  cmake ../src
  make -j4
fi

if [ -x ./hypseus ]; then
  echo Hypseus-Singe $VERSION build succeeded.
  [ ! -d ~/hypseus ] && mkdir ~/hypseus
  cd ~/hypseus-singe-${VERSION}-RPi/build
  mv hypseus ~/hypseus
  [ ! -d /data/hypseus/framefile ] && mkdir /data/hypseus/framefile
  [ ! -d /data/hypseus/ram ] && mkdir /data/hypseus/ram
  cd ../
  [ ! -d ~/hypseus/sound ] && mv doc fonts pics scripts sound ~/hypseus
  [ ! -d ~/hypseus/roms ] && mv mv roms/ screenshots/ ~/.hypseus
  cd ~/hypseus
  [ ! -L ~/hypseus/ram ] && ln -s /data/hypseus/ram ram
  [ ! -L ~/hypseus/singe ] && ln -s /data/hypseus/framefile singe
  [ ! -L ~/hypseus/roms ]  && ln -s /data/hypseus/roms roms
  cd
  [ -d ~/hypseus-singe-${VERSION}-RPi ] && rm -R ~/hypseus-singe-${VERSION}-RPi
  [ -f ~/v${VERSION}-RPi.zip ] && rm ~/v${VERSION}-RPi.zip
  sudo apt-get remove cmake -y
  # Cleanup
  sudo rm -R build sfml-pi-R3
else
  echo Hypseus-Singe $VERSION build failed.
fi

Ajustement des permissions pour permettre l’exécution du script :

chmod +x ~/scripts/hypseus-build.sh

Lancement de la compilation de Hypseus-Singe :

~/scripts/hypseus-build.sh

Script de démarrage de MAME/Front-end

Le script de démarrage de MAME ou d'un Front-end relancera l’exécutable sélectionné tant et aussi longtemps que l’applicatif ne sera pas quitté de façon normale (code de sortie à 0).

Si le frontend sélectionné est MAME et que la variable AUTOROM est assignée à la valeur d'un ROM (sans son extension .zip), ce ROM sera alors passé à MAME et sera automatiquement démarré. Voir la commande frontend pour l'assignation de la variable AUTOROM.

Création du script :

nano ~/scripts/autostart.sh

Coller les lignes ci-dessous et sauvegarder :

#!/bin/bash

# This script launch the selected application (front-end or MAME emulator) and respawn it if quit unexpectedly.

if [ ! -z $FRONTEND ]; then
  while
    case ${FRONTEND,,} in
      attract)  # Attract Mode
        if [ ! -z "$AUTOROM" ] && [ $(wc -w <<< "$AUTOROM") == 2 ]; then
          read -r EMULNAME ROMNAME <<< "${AUTOROM//\"/}"
          CFGFILE=/home/pi/.attract/emulators/$EMULNAME.cfg
          if [ -f $CFGFILE ]; then
            while read VAR VALUE; do
              [ ! -z $VAR ] && [ "${VAR:0:1}" != '#' ] && export $VAR="$VALUE"
            done < $CFGFILE
            ARGS=${args//\[name\]/$ROMNAME}
            ARGS=${ARGS//\$HOME/$HOME}
            EXEC=${executable//\$HOME/$HOME}
            if [ "${EXEC##*/}" = hypseus ]; then	# Hypseus-Singe
              FRAMEFILE=$(sed 's/^.*\s-framefile\s\(\S*\)\s.*$/\1/' <<< $ARGS)
            fi
          fi
          if [ ! -z $FRAMEFILE ] && [ -f $FRAMEFILE ] && [ ! -z $EXEC ] && [ -x $EXEC ]; then	# Automatic ROM Launch mode
            $EXEC $ARGS -nolog >/dev/null 2>/dev/null
          else
            stty -echo
            /usr/local/bin/attract --loglevel silent >/dev/null 2>&1
          fi
        else
          stty -echo
          /usr/local/bin/attract --loglevel silent >/dev/null 2>&1
        fi
        ;;
      advance)  # AdvanceMENU
        /home/pi/frontend/advance/advmenu
        ;;
      mame)     # MAME GUI or Automatic ROM Launch mode if AUTOROM is set
        /home/pi/mame/mame $([ ! -z $AUTOROM ] && [ -f /home/pi/.mame/roms/$AUTOROM.zip ] && echo $AUTOROM) >/dev/null 2>/dev/null
        ;;
    esac
    (( $? != 0 ))
  do
    :
  done
else
    echo $0 - FRONTEND variable is not defined!
    read -n 1 -s -r -p 'Press any key to continue...'
    echo
fi

Ajustement des permissions pour permettre l’exécution du script :

chmod +x ~/scripts/autostart.sh

Démarrage automatique de l'émulateur MAME/Front-end

L'objectif est de créer un service systemd qui sera responsable de démarrer automatiquement l'émulateur MAME ou le Front-end sélectionné.

Lorsque ce service est activé, nous sommes en mode Arcade :

  • Désactivation du getty de la console (getty@tty1.service)
  • Désactivation du serveur Samba (smbd.service) afin maximiser les ressources pour l'émulation
  • Désactivation d'autres services pour maximiser les ressources
  • Démarrage automatique de l'émulateur MAME ou du Frond-end sélectionné

Lorsque ce service est désactivé, nous sommes en mode Service :

  • Activation du getty de la console (getty@tty1.service)
  • Activation du serveur Samba (smbd.service) afin de permettre la gestion des ROMs ainsi que le matériel graphique associé
  • Activation du service de gestion automatisé (mame-artwork-mgmt.service) du matériel graphique associé aux fichiers de ROM

Création du service systemd :

sudo systemctl edit mame-autostart.service --force --full

Coller les lignes ci-dessous et sauvegarder :

[Unit]
Description=MAME Appliance Autostart service
Conflicts=getty@tty1.service smbd.service nmbd.service rng-tools.service cron.service mame-artwork-mgmt.service
Requires=local-fs.target
After=local-fs.target
ConditionPathExists=/home/pi/settings

[Service]
User=pi
Group=pi
PAMName=login
Type=simple
EnvironmentFile=/home/pi/settings
ExecStart=/home/pi/scripts/autostart.sh
Restart=on-abort
RestartSec=5
TTYPath=/dev/tty1
StandardInput=tty

[Install]
WantedBy=multi-user.target
Also=shutdown.service

Puisque nous n'avons pas complété toutes les étapes, nous allons pour le moment désactiver le service :

sudo systemctl disable mame-autostart.service

Réactivation du curseur dans la console lorsque le getty@tty1 est activé (Service Mode) :

nano ~/.bashrc

Ajouter la ligne suivante à la fin, puis sauvegarder :

setterm --cursor on

Shutdown automatique du système dès qu’on quitte MAME

Dès que le service mame-autostart.service est arrêté, ceci déclenche le shutdown...

Création du service systemd :

sudo systemctl edit shutdown.service --force --full

Coller les lignes ci-dessous et sauvegarder :

[Unit]
Description=Shutdown and poweroff service
After=mame-autostart.service

[Service]
TTYPath=/dev/tty1
ExecStart=/sbin/poweroff
StandardInput=tty

[Install]
WantedBy=multi-user.target

Désactivation du service (pour le moment) :

sudo systemctl disable shutdown.service

Préparatifs pour l’écran de démarrage au logo de MAME

Retrait du splash en arc-en-ciel lors de la mise sous tension :

sudo nano /boot/config.txt

Ajouter cette ligne à la fin du fichier, puis sauvegarder :

disable_splash=1

Éditer le fichier associé à la ligne de commande passée au kernel :

sudo nano /boot/cmdline.txt

Ajouter les options ci-dessous à la ligne de commande passée au kernel :

Rediriger l’affichage des messages sur la console (tty1) vers tty3. Pour ce faire, changer console=tty1 pour console=tty3.

Cacher le logo du Raspberry Pi, ajouter :

logo.nologo

Cacher le curseur qui clignote, ajouter :

vt.global_cursor_default=0

Cacher l’affichage des messages et démarrage rapide, ajouter :

quiet fsck.mode=skip

Forcer Systemd en tant que système d'initialisation (init) :

init=/bin/systemd

Ce qui nous donne au final les options suivantes à ajouter à la ligne de commande :

console=tty3 logo.nologo vt.global_cursor_default=0 quiet fsck.mode=skip init=/bin/systemd

Affichage de l’écran de démarrage (Custom Boot Splash)

Installation du binaire FIM qui permet d’afficher une image :

sudo apt-get install fim -y

Création du dossier des images de splash et copie de l’image du logo de MAME (mame.jpg) :

mkdir ~/splash
sudo mv ~/mame.jpg ~/splash

Pour le moment j’utilise le même splash pour le boot et le shutdown :

ln -s ~/splash/mame.jpg ~/splash/mame-boot.jpg
ln -s ~/splash/mame.jpg ~/splash/mame-shutdown.jpg

Création du service systemd :

sudo systemctl edit mame-bootsplash.service --force --full

Coller le texte ci-dessous et sauvegarder :

[Unit]
Description=MAME Boot Splash Screen service
DefaultDependencies=no
After=local-fs.target

[Service]
Type=simple
StandardInput=tty
StandardOutput=tty
ExecStart=/usr/bin/fim -q --no-history /home/pi/splash/mame-boot.jpg
SuccessExitStatus=42

[Install]
WantedBy=sysinit.target

Activation du service :

sudo systemctl enable mame-bootsplash.service

Affichage de l’écran du shutdown (Custom Shutdown Splash)

Création du service systemd :

sudo systemctl edit mame-shutdownsplash.service --force --full

Coller le texte ci-dessous et sauvegarder :

[Unit]
Description=MAME Shutdown/Poweroff/Reboot Splash Screen service
DefaultDependencies=no
Before=halt.target
Conflicts=mame-bootsplash.service

[Service]
Type=simple
ExecStart=/usr/bin/fim -q --no-history /home/pi/splash/mame-shutdown.jpg
SuccessExitStatus=42

[Install]
WantedBy=reboot.target halt.target poweroff.target

Activation et démarrage du service :

sudo systemctl enable mame-shutdownsplash.service
sudo systemctl start mame-shutdownsplash.service

Pour afficher sommaire des unit files de systemd (avec hiérarchie) :

systemd-analyze critical-chain

Création de la partition séparée en lecture-écriture

La partition /data sera en lecture/écriture et utilisera le système de fichiers F2FS (Flash-Friendly File System).

Installer les binaires pour le système de fichiers F2FS :

sudo apt-get install f2fs-tools -y

Puisque la partition de données a été créée au début de la procédure, il ne nous reste plus qu'à la formater avec le système de fichiers F2FS :

sudo mkfs.f2fs -l data /dev/mmcblk0p3

Création du point de montage /data (et des sous-dossiers), ajustement des permissions, du propriétaire (owner) et du groupe :

sudo mkdir /data

Tester pour s'assurer qu'il n'y a pas eu d'erreur en montant manuellement la partition, puis valider le remontage :

sudo mount -t f2fs -o rw /dev/mmcblk0p3 /data
sudo mount -o remount,rw /data

Montage automatique dans fstab :

sudo nano /etc/fstab

Ajouter cette ligne à fstab :

/dev/mmcblk0p3        /data           f2fs    defaults,noatime    0    2

Ajustements au fichier de montage automatique systèmes de fichiers

Afin que le montage de /boot et / s'effectuent sans dépendre d'un identifiant, nous allons basculer l'identification des partitions par leur nom de device.

Pour ce faire, nous éditons /etc/fstab :

sudo nano /etc/fstab

Assurez-vous que /boot et / soient référencés par leur nom de device (/dev/mmcblk0pX) au lieu de l'identifiant PARTUUID :

/dev/mmcblk0p1        /boot           vfat    defaults,rw                 0    2
/dev/mmcblk0p2        /               ext4    defaults,noatime,rw         0    1

Éditer la ligne de commande du kernel Linux :

sudo nano /boot/cmdline.txt

Repérer sur la ligne de commande le paramètre root=PARTUUID=xxxxxxxx et le remplacer par :

root=/dev/mmcblk0p2

Partage de /data via Samba

Installation du serveur Samba et des binaires associés :

sudo apt-get install samba samba-common-bin -y

À la question ci-dessous, répondez par Oui :

Modify smb.conf to use WINS settings from DHCP?

À ce point, il est possible que le système effectue un shutdown, ceci est normal.

Dû au redémarrage, la configuration de Samba ne s'est pas complétée. Pour la compléter, exécutez la commande ci-dessous :

sudo dpkg --configure -a

Configuration du serveur Samba :

sudo nano /etc/samba/smb.conf

À la section [global], retirer le commentaire «;» au début des deux (2) ligne suivantes :

interfaces = 127.0.0.0/8 eth0
bind interfaces only = yes

Sous la directive server role = standalone server, ajouter les lignes suivantes :

local master = no
domain master = no
preferred master = no

Comme le partage de fichiers n’est activé qu’en mode Service, j’autorise les connexions au partage en mode anonyme (sans authentification).

Toujours à la section [global], ajouter ces deux lignes :

security = user
guest account = nobody

Commenter (désactiver) en préfixant avec «;» les sections qui définissent les partage suivants :

[homes] [netlogon] [profiles] [printers] [print$]

À la fin de la section des partages, coller ce bloc pour partager /data et sauvegarder :

[Data]
  path = /data
  comment = Raspberry Pi MAME Appliance - Persistent data share.
  available = yes
  browsable = yes
  writable = yes
  guest ok = yes
  create mask = 0644
  directory mask = 0755
  force user = pi

Application des nouveaux réglages en basculant en mode Service :

servicemode
sudo reboot

Valider que le service Samba est bien en exécution à l'aide de la commande suivante :

systemctl status smbd

Tester le partage Samba en tentant d'accéder au partage depuis un ordinateur distant (par exemple : \\arcade\data depuis Windows ou smb://arcade/data depuis Linux). Vous devriez être en mesure de copier des fichiers depuis/vers le partage, ainsi que de les supprimer sans devoir vous authentifier (accès de type anonyme).

Déplacement des données vers la partition persistante /data

Création des dossiers et ajustement des permissions sur la partition persistante :

cd /data
sudo mkdir mame hypseus attract advance
cd mame
sudo mkdir artwork cabinets cfg cpanels ctrlr diff flyers hi history icons ini inp lua marquees memcard pcb nvram roms snap sta titles ui
sudo chown -R pi:pi /data
sudo chmod -R 3774 /data

Déplacement des fichiers de configuration de MAME (ui.ini, mame.ini, plugin.ini et hiscore.ini) vers /data/mame/ini (rw)

cd ~/.mame
mv mame.ini ui.ini plugin.ini hiscore.ini /data/mame/ini

Si applicable, déplacer les autres éléments vers /data (rw)

mv ~/.mame/history.xml /data/mame/history
mv ~/mame/roms/*       /data/mame/roms/
mv ~/mame/snap/*       /data/mame/snap/
mv ~/mame/artwork/*    /data/mame/artwork/
mv ~/mame/ctrlr/*      /data/mame/ctrlr/

mv ~/.advance/*        /data/advance/
mv ~/.attract/*        /data/attract/
mv ~/.hypseus/*        /data/hypseus/

Création des symlinks…

Pour permettre à MAME de trouver son fichier de configuration mame.ini, un symlink est nécessaire :

ln -s ./ini/mame.ini /data/mame/mame.ini

Redirection des dossiers vers /data afin de permettre la persistence des réglages et données des jeux ainsi qu'une gestion facilitée des ROMs et du matériel graphique associé :

cd ~/mame
rm -R roms ctrlr snap nvram history artwork
cd ~; rmdir .mame .hypseus .advance .attract

ln -s /data/mame    ~/.mame
ln -s /data/attract ~/.attract
ln -s /data/advance ~/.advance
ln -s /data/hypseus ~/.hypseus

Ajustement pour l'emplacement des High Scores (MAME 0.237 et plus)

[ -f /data/mame/lua/hiscore/plugin.cfg ] && mv /data/mame/lua/hiscore/plugin.cfg /data/mame/hi
rmdir /data/mame/lua/hiscore
ln -s /data/mame/hi /data/mame/lua/hiscore

Script de téléchargement du matériel graphique de chaque ROMs

Je vous propose le script ci-dessous qui parcourt l'emplacement des fichiers de ROMs et tente de télécharger le matériel graphique associé à chaque ROM (snapshots, écran du titre, marquees, panneaux de commandes, cabinet).

nano ~/scripts/mame-scraper.sh
#!/bin/bash

# This script download the missing artwork files (snapshots, titles screens, marquees,
# control panels and cabinet pictures) based on the content of the ROMs path (ROM files).

# Usage: when a romname is passed (without the .zip extension), only the artwork for this
#        rom is downloaded.

URLPREFIX1=http://mamedb.blu-ferret.co.uk
URLPREFIX2=http://adb.arcadeitalia.net/media/mame.current

get_artworks() {
    # $1 is romname (without .zip)
    if [ ! $1 ]; then
        exit
    fi
    if [ -t 0 ]; then  echo -ne "\e[2K\rProcessing $1..."; fi
    for t in snap titles marquees cpanels cabinets flyers
      do
        if [ ! -f /home/pi/.mame/$t/$1.png ]; then
          wget -q $URLPREFIX1/$t/$1.png -P /home/pi/.mame/$t
          if [ $? = 0 ]; then	# Download OK
              echo -n .
          else		# Download failed, let's try with the 2nd URL...
              case $t in
                  snap)
                      wget -q $URLPREFIX2/ingames/$1.png -P /home/pi/.mame/$t && echo -n .
                      ;;
                  *)
                      wget -q $URLPREFIX2/$t/$1.png -P /home/pi/.mame/$t && echo -n .
                      ;;
              esac
          fi
        fi
      done
    }

shopt -s nullglob
cd /home/pi/.mame/roms

if [ $1 ]; then
    f=$1.zip
    if [ -f $f ]; then
        get_artworks ${f%.zip}
    fi
else
    for f in *.zip
        do
            get_artworks ${f%.zip}
        done
fi
if [ -t 0 ]; then echo -e '\e[2K\rCompleted!'; fi

Ajustement des permissions pour permettre l'exécution du script :

chmod +x ~/scripts/mame-scraper.sh

Utilitaire de nettoyage des ROMs invalides

Je vous propose le script ci-dessous pour nettoyer les ROMs (fichiers .zip) qui sont invalides pour MAME, c'est à dire qu'une version plus récente est nécessaire (un dump de meilleure qualité existe).

nano ~/scripts/mame-badromspurge.sh

Coller le texte ci-dessous, puis sauvegarder :

#!/bin/bash

# This script delete/purge bad or invalid ROMs files.

shopt -s nullglob

for r in $(/home/pi/mame/mame -verifyroms | grep 'is bad' | awk '{print $2 ".zip"}')
  do
    if [ -f /home/pi/.mame/roms/$r ]; then
      sudo rm /home/pi/.mame/roms/$r
      echo -n .
    fi
  done
echo Completed!

Ajustement des permissions pour permettre l'exécution du script :

chmod +x ~/scripts/mame-badromspurge.sh

Utilitaire pour lister le nom des ROMs présents

nano ~/scripts/mame-romlist.sh

Coller le texte ci-dessous, puis sauvegarder :

#!/bin/bash

# This script list the name of the current MAME ROMs.

cd /home/pi/.mame/roms

for f in *.zip; do
  echo -e "[${f%.*}]\t$(/home/pi/mame/mame -listfull ${f%.*} | awk -F '"' '!/Description:$/ {print $2}')"
done

Ajustement des permissions pour permettre l'exécution du script :

chmod +x ~/scripts/mame-romlist.sh

Utilitaire d'évaluation de la performance des ROMs

Je vous propose le script ci-dessous pour évaluer la vitesse moyenne de chacun des ROMs, puis optionnellement (lorsque l'argument purge est passé), supprimer les ROMs qui ont une vitesse inférieure à 100 %.

nano ~/scripts/mame-benchmark.sh

Coller le texte ci-dessous, puis sauvegarder :

#!/bin/bash

# This script test every ROMs with a 5 minutes benchmark and display the percentage of speed of the emulation.
# If the 'purge' argument is specified, the script will delete the ROM files that are under 100% of average speed.

shopt -s nullglob

if (systemctl -q is-active mame-autostart.service) then
    echo "The system must be put in SERVICE Mode first."
    exit
fi

cd ~/.mame/roms
for r in *.zip
  do
    FULLNAME=$(/home/pi/mame/mame -listfull ${r%.zip} | awk "/${r%.zip}/ { print $2 }")
    if [ ! -z $FULLNAME ]; then
        echo -n Benchmarking $FULLNAME for 5 minutes...
        RESULT=$(/home/pi/mame/mame -bench 300 ${r%.zip} 2>/dev/null)
        if [ ! -z $RESULT ]; then
            PERCENT=$(echo $RESULT | awk '/Average speed:/ { print $3 }')
            PERCENT=${PERCENT//%/}         # Remove the percentage
            echo " Average speed of $PERCENT %"
            if [ ${PERCENT%.*} -lt 100 ] && [ ${1,,} = 'purge' ]; then
                rm ~/.mame/roms/$r
                echo "  The ROM file $r has been purged."
            fi
        fi
    fi
  done

echo Completed!

Ajustement des permissions pour permettre l'exécution du script :

chmod +x ~/scripts/mame-benchmark.sh

Utilitaire de nettoyage des fichiers graphiques (artworks)

Je vous propose le script ci-dessous pour nettoyer les fichiers .png des fichiers graphiques (artworks) lorsque le fichier ROM correspondant n'existe pas.

nano ~/scripts/mame-delartwork.sh

Coller le texte ci-dessous, puis sauvegarder :

#!/bin/bash

# This script delete unused Artwork files if the corresponding ROM .zip file does not exist.

shopt -s nullglob

if [ $1 ]; then
  if [ ! -f /home/pi/.mame/roms/$1.zip ]; then
    for t in snap titles marquees cpanels cabinets icons
      do
          if [ -f /home/pi/.mame/$t/$1.png ]; then
            sudo rm /home/pi/.mame/$t/$1.png
          fi
      done
  fi
else	# Batch mode
  if [ -t 0 ]; then echo -ne "\e[2K\rProcessing $1..."; fi
  for t in snap titles marquees cpanels cabinets icons
    do
      cd /home/pi/.mame/$t
      for f in *.{png,ico}
        do
          if [ ! -f /home/pi/.mame/roms/${f%.*}.zip ]; then
            sudo rm /home/pi/.mame/$t/$f
            echo -n .
          fi
        done
    done
  if [ -t 0 ]; then echo -e '\e[2K\rCompleted!'; fi
fi

Ajustement des permissions pour permettre l'exécution du script :

chmod +x ~/scripts/mame-delartwork.sh

Gestion automatisée du matériel graphique des ROMs

Un service systemd ainsi qu'un script surveillera l'emplacement des fichiers de ROMs. Dès qu'un changement survient (ajout ou suppression), le matériel graphique associé sera automatiquement mis à jour.

Installation des dépendances :

sudo apt-get install inotify-tools -y

Création du script :

nano ~/scripts/mame-artwork-mgmt.sh

Coller le texte ci-dessous, puis sauvegarder :

#!/bin/bash

# This script watch the ROMs folder and add/remove the corresponding artwork automatically.

inotifywait -m /home/pi/.mame/roms -e create -e moved_to -e delete -e moved_from |
  while read dir action file; do
    case ${action,,} in
      create | moved_to)
        if [ ${file##*.} = zip ]; then /home/pi/scripts/mame-scraper.sh ${file%.zip}; fi
        ;;
      delete | moved_from)
        if [ ${file##*.} = zip ]; then /home/pi/scripts/mame-delartwork.sh ${file%.zip}; fi
        ;;
    esac
  done

Ajustement des permissions pour permettre l'exécution du script :

chmod +x ~/scripts/mame-artwork-mgmt.sh

Création du service systemd associé :

sudo systemctl edit mame-artwork-mgmt.service --force --full

Coller le texte ci-dessous, puis sauvegarder :

[Unit]
Description=MAME Automatic Artwork Management service
After=network.target mame-autostart.service

[Service]
Type=simple
ExecStart=/home/pi/scripts/mame-artwork-mgmt.sh
KillSignal=SIGINT
TimeoutStopSec=5
Restart=always

[Install]
WantedBy=sysinit.target

Activer le service :

sudo systemctl enable mame-artwork-mgmt.service 

Ajustement de la mémoire vidéo à 128 Mo

Ajuster la taille de la mémoire vidéo à 128 Mo en éditant le fichier /boot/config.txt :

sudo nano /boot/config.txt

Ajouter la ligne ci-dessous à la fin du fichier, puis sauvegarder :

gpu_mem=128

Mise en lecture-seule du Root FileSystem (Read-Only)

Afin de prolonger la vie la carte SD, nous allons mettre en lecture-seule les partitions suivantes :

/boot (vfat)
/     (ext4)

Pour ce faire, nous allons utiliser le script ci-dessous :

nano ~/scripts/read-only-rootfs.sh

Coller le script bash ci-dessous, puis sauvegarder :

#!/bin/bash

# This script put the root (/) and /boot filesystems in read-only mode.
# Based on: https://medium.com/swlh/make-your-raspberry-pi-file-system-read-only-raspbian-buster-c558694de79

# Check /etc/fstab to see if this script has already been executed
awk '/\/ /{print $4}' /etc/fstab | grep -q ro, && awk '/\/boot/{print $4}' /etc/fstab | grep -q ro, && echo 'This script has already been executed and your system is already in read-only mode.' && exit

echo ---------------------------------------------------------------------
echo This script will convert this system in read-only mode.
echo
echo The system will be automatically rebooted, once the script complete.
echo ---------------------------------------------------------------------
while true; do
    read -p "Do you wish to continue? " yn
    case ${yn,,} in
        y | yes) break;;
        n | no)  exit;;
        *) echo "Please answer yes or no.";;
    esac
done

# START
echo ---------------------------------------------------------------------
echo Applying the required changes to the system...
echo ---------------------------------------------------------------------

# Remove swap and other stuff
sudo apt-get remove --purge triggerhappy logrotate dphys-swapfile -y
sudo apt-get autoremove --purge -y

# Disable swap and filesystem check and set it to read-only
sudo sed -ie 's/^console=serial0,115200.*$/& fsck.mode=skip noswap ro/g' /boot/cmdline.txt

# Replace your log manager
sudo apt-get install busybox-syslogd -y
sudo apt-get remove --purge rsyslog -y
# From now on, use sudo logread to check your system logs.

# /etc/fstab: Add read-only mode to /boot or /boot/firmware filesystems
sudo sed -i '/\/boot/{/ro/!s/\S\S*/&,ro/4}' /etc/fstab

# /etc/fstab: Add read-only mode to / root filesystem
sudo sed -i '/\S\s\s*\/\s\s*/{/\(ro,\|,ro\)/!s/\S\S*/&,ro/4}' /etc/fstab

# We append the temporary file systems to fstab
sudo tee -a /etc/fstab << 'EOF'
tmpfs     /tmp                       tmpfs   nosuid,nodev              0       0
tmpfs     /var/log                   tmpfs   nosuid,nodev              0       0
tmpfs     /var/tmp                   tmpfs   nosuid,nodev              0       0
tmpfs     /var/spool                 tmpfs   nosuid,nodev              0       0
# Samba
tmpfs     /var/lib/samba             tmpfs   nosuid,mode=0755,nodev    0       0
tmpfs     /var/lib/samba/private     tmpfs   nosuid,mode=0755,nodev    0       0
tmpfs     /var/log/samba             tmpfs   nosuid,mode=0755,nodev    0       0
tmpfs     /var/cache/samba           tmpfs   nodev,nosuid              0       0
tmpfs     /var/spool/samba           tmpfs   nodev,nosuid              0       0
tmpfs     /var/run/samba             tmpfs   nodev,nosuid              0       0
EOF

# Move some system files to temp filesystem
sudo rm -rf /var/lib/dhcp /var/lib/dhcpcd5 /var/spool /etc/resolv.conf
sudo ln -s /tmp /var/lib/dhcp
sudo ln -s /tmp /var/lib/dhcpcd5
sudo touch /tmp/dhcpcd.resolv.conf
sudo ln -s /tmp/dhcpcd.resolv.conf /etc/resolv.conf

# Update the systemd random seed
[ -f /var/lib/systemd/random-seed ] && sudo rm /var/lib/systemd/random-seed
[ ! -L /var/lib/systemd/random-seed ] && sudo ln -s /tmp/random-seed /var/lib/systemd/random-seed

# Systemd drop-in to ajust systemd-random-seed.service
if [ ! -f /etc/systemd/system/systemd-random-seed.service.d/readonlyfs-fixup.conf ]; then
  [ ! -d /etc/systemd/system/systemd-random-seed.service.d ] && sudo mkdir /etc/systemd/system/systemd-random-seed.service.d
  echo '[Service]' | sudo tee -a /etc/systemd/system/systemd-random-seed.service.d/readonlyfs-fixup.conf
  echo 'ExecStartPre=/bin/echo "" >/tmp/random-seed' | sudo tee -a /etc/systemd/system/systemd-random-seed.service.d/readonlyfs-fixup.conf
fi

# Shell commands to switch between RO and RW modes
grep -q "alias ro=" /etc/bash.bashrc || sudo tee -a /etc/bash.bashrc << 'EOF'
set_bash_prompt() {
    fs_mode=$(mount | sed -n -e "s/^\/dev\/.* on \/ .*(\(r[w|o]\).*/\1/p")
    PS1='\[\033[01;32m\]\u@\h${fs_mode:+($fs_mode)}\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
    }

alias ro='sudo mount -o remount,ro / ; sudo mount -o remount,ro /boot'
alias rw='sudo mount -o remount,rw / ; sudo mount -o remount,rw /boot'

PROMPT_COMMAND=set_bash_prompt

EOF

# To make sure the file system goes back to read-only once you log out
grep -q "sudo mount -o remount,ro /"     /etc/bash.bash_logout || echo 'sudo mount -o remount,ro /' | sudo tee -a /etc/bash.bash_logout
grep -q "sudo mount -o remount,ro /boot" /etc/bash.bash_logout || echo 'sudo mount -o remount,ro /boot' | sudo tee -a /etc/bash.bash_logout

# Alias ajustments
sed -ie "s/^alias arcademode=.*$/alias arcademode=\'rw; sudo systemctl enable mame-autostart.service; ro\'/g" ~/.bash_aliases
sed -ie "s/^alias servicemode=.*$/alias servicemode=\'rw; sudo systemctl disable mame-autostart.service; ro\'/g" ~/.bash_aliases

# Swap file removal
[ -f /var/swap ] && sudo rm /var/swap

# Purge of mount points content that switch to tmpfs
sudo systemctl stop smbd.service nmbd.service systemd-timesyncd.service
sudo rm -R /var/lib/samba/*
sudo rm -R /var/cache/samba/*
sudo rm -R /tmp/*
sudo rm -R /var/lib/systemd/timesync/*
sudo rm -R /var/log/*

# Systemd drop-ins for read-only mode ajustments
for i in raspberrypi-net-mods.service \
         systemd-rfkill \
         sshswitch.service \
         rpi-eeprom-update.service
do
  if [ ! $(systemctl -q is-enabled $i) ]; then
    [ ! -d /etc/systemd/system/$i.d ] && sudo mkdir /etc/systemd/system/$i.d
    if [ -f /etc/systemd/system/$i.d/readonlyfs-fixup.conf ]; then
      grep -q [Service] /etc/systemd/system/$i.d/readonlyfs-fixup.conf || echo '[Service]' | sudo tee -a /etc/systemd/system/$i.d/readonlyfs-fixup.conf
    else
      echo '[Service]' | sudo tee -a /etc/systemd/system/$i.d/readonlyfs-fixup.conf
    fi
    echo 'ExecStartPre=/bin/sh  -c "mount -o remount,rw /boot; mount -o remount,rw /"' | sudo tee -a /etc/systemd/system/$i.d/readonlyfs-fixup.conf
    echo 'ExecStartPost=/bin/sh -c "mount -o remount,ro /boot; mount -o remount,ro /"' | sudo tee -a /etc/systemd/system/$i.d/readonlyfs-fixup.conf
  fi
done

# Systemd drop-in for ajustment for systemd-timesyncd.service
sudo tee -a /etc/fstab << 'EOF'
# Timesyncd
tmpfs     /var/lib/private           tmpfs   nosuid,mode=0755,nodev    0       0
tmpfs     /var/lib/systemd/timesync  tmpfs   nosuid,mode=0755,nodev    0       0

EOF

[ ! -d /etc/systemd/system/systemd-timesyncd.service.d ] && sudo mkdir /etc/systemd/system/systemd-timesyncd.service.d
if [ -f /etc/systemd/system/systemd-timesyncd.service.d/readonlyfs-fixup.conf ]; then
  grep -q [Service] /etc/systemd/system/systemd-timesyncd.service.d/readonlyfs-fixup.conf || echo '[Service]' | sudo tee -a /etc/systemd/system/systemd-timesyncd.service.d/readonlyfs-fixup.conf
else
  echo '[Service]' | sudo tee -a /etc/systemd/system/systemd-timesyncd.service.d/readonlyfs-fixup.conf
fi
echo 'PrivateTmp=no' | sudo tee -a /etc/systemd/system/systemd-timesyncd.service.d/readonlyfs-fixup.conf
echo 'RestartSec=5' | sudo tee -a /etc/systemd/system/systemd-timesyncd.service.d/readonlyfs-fixup.conf

# Disable auto-update daemons
sudo systemctl stop    systemd-tmpfiles-clean.timer apt-daily.timer apt-daily-upgrade.timer man-db.timer systemd-tmpfiles-clean.service apt-daily-upgrade.service
sudo systemctl disable systemd-tmpfiles-clean.timer apt-daily.timer apt-daily-upgrade.timer man-db.timer systemd-tmpfiles-clean.service apt-daily-upgrade.service
sudo systemctl mask    systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service apt-daily-upgrade.service

# Systemd daemon reload to update changes
sudo systemctl daemon-reload

echo ---------------------------------------------------------------------
echo Completed.
echo The system will reboot NOW.
echo ---------------------------------------------------------------------

sudo reboot

Ajustement des permissions pour permettre l'exécution du script, puis lancement du script :

chmod +x ~/scripts/read-only-rootfs.sh
~/scripts/read-only-rootfs.sh

Répondez par y à la demande de confirmation et patientez. Le système redémarrera automatiquement, lorsque les étapes du script seront complétées.

Deux alias (rw et ro) sont créés afin de basculer du mode lecture-écriture vers lecture-seule et vice-versa.

Ajustement pour permettre de sauvegarder les réglages audio (volume)

sudo mkdir -p /data/.sys/alsa
sudo chown -R root:pi /data/.sys

# We grant rw to owner pi and pi group
sudo chown -R pi:pi /data/.sys/emv
sudo chmod -R 664 /data/.sys/env/*

# We grant Read+Execute (for directory traversal) to Group+Other
sudo chmod -R 755 /data/.sys

rw
sudo mv /var/lib/alsa/asound.state /data/.sys/alsa

# We revoke the Execute for Group+Other to the files under alsa
sudo chmod -R 744 /data/.sys/alsa/*

sudo rmdir /var/lib/alsa
sudo ln -s /data/.sys/alsa /var/lib/alsa
ro

Vérification

Assurez-vous que la commande ci-dessous ne retourne pas d'erreur :

sudo alsactl store

Redémarrer le système :

sudo reboot

Une fois redémarré, valider que le système est bien en lecture-seule :

  1. Ouvrez une session (console ou SSH)
  2. Une fois logué, l'invite de commande devrait indiquer le suffixe (ro) (pour read-only)

Bascule en mode Arcade

Activer temporairement le mode lecture/écriture du Root FileSystem, basculer en mode Arcade (mode normal) et redémarrer :

arcademode
sudo reboot

Ajustements pour périphérique de sortie (TV ou moniteur)

[Optionnel/TV] Changement de l'identifiant CEC

Si vous utilisez un téléviseur branché via HDMI et que plusieurs sources y sont reliées, vous pouvez personnaliser l'identifiant CEC (Consumer Electronics Control) qui sera affiché pour la source (entrée HDMI) associée au Raspberry Pi :

sudo nano /boot/config.txt

Ajouter la ligne suivante (où Arcade est le nom/identifiant CEC qui sera affiché), puis sauvegarder :

cec_osd_name=Arcade

[Optionnel/Audio] Bascule de l'audio vers la sortie analogique

Si vous voulez utiliser la sortie analogique (audio jack 3.5mm) du Raspberry Pi pour l'aiguiller vers un amplificateur, procédez comme suit.

sudo nano /etc/asound.conf

Coller les lignes ci-dessous, puis sauvegarder :

pcm.!default {
type hw
card 1
}

ctl.!default {
type hw
card 1
}

[Optionnel/Audio] Réglage du volume de sortie audio

Pour régler (ajuster selon vos besoins) le volume de la sortie audio, exécutez la commande suivante :

alsamixer

Faites glisser le curseur du volume selon votre préférence, puis quittez (à l'aide de la touche ESC).

Pour sauvegarder de manière persistante le changement, exécutez :

sudo alsactl store

[Optionnel/Audio] Bascule du volume audio via un contrôle physique

Option #1 : Bouton physique relié aux broches GPIO

Nous allons relier un bouton à pression à GPIO 4 afin de contrôler le volume global du système. À l'initialisation, le niveau sonore est réglé à 85 % (niveau moyen). À chaque pression du bouton, le niveau baisse d'un cran, jusqu'au silence (mute), puis bascule au niveau maximal, et ainsi de suite.

nano ~/scripts/mame-volume-ctrl.sh

Coller les lignes ci-dessous, puis sauvegarder :

#!/bin/bash
#file:/home/pi/scripts/mame-vol.sh

function cleanup {
  # Deactivate GPIO pin
  echo $GPIOPIN >/sys/class/gpio/unexport 2>/dev/null
  exit 0
  }

function waitStateChange {
  while [ $(cat /sys/class/gpio/gpio${GPIOPIN}/value) != $1 ]; do
    inotifywait -q -e modify /sys/class/gpio/gpio${GPIOPIN}/value > /dev/null
  done
  }

# Clean up when exit
trap cleanup EXIT
trap cleanup SIGHUP
trap cleanup SIGQUIT
trap cleanup SIGINT
trap cleanup SIGTERM

HIGH='95%'
MED='85%'
LOW='72%'
MUTE='0%'

GPIOPIN=4   # We use GPIO 4

# Initialize GPIO pin
[ -d /sys/class/gpio/gpio${GPIOPIN} ] && echo $GPIOPIN > /sys/class/gpio/unexport  # Deactivate GPIO pin
echo $GPIOPIN > /sys/class/gpio/export    # Activate GPIO pin
sleep 0.1                                 # A small delay is required so that the system has time
                                          # to properly create and set the file's permission
echo in > /sys/class/gpio/gpio${GPIOPIN}/direction # Input signal
echo both > /sys/class/gpio/gpio${GPIOPIN}/edge    # We use the interrupt controller to avoid a CPU spin loop

waitStateChange 1      # Wait for button release
while true; do
  waitStateChange 0    # Wait for button press
  # Volume button pressed
  CHECK_VOL=$(amixer | awk -F'[\[\]]' '/Mono: Playback/ {print $2}')

  case $CHECK_VOL in
    $HIGH)
      # Setting volume to medium
      amixer -q cset numid=1 $MED ;;
    $MED)
      # Setting volume to low
      amixer -q cset numid=1 $LOW ;;
    $LOW)
      # Setting volume to mute
      amixer -q cset numid=1 "$MUTE" ;;
    $MUTE)
      # Setting volume to high
      amixer -q cset numid=1 $HIGH ;;
    *)
      # Setting volume to medium (default)
      amixer -q cset numid=1 $MED ;;
  esac
    waitStateChange 1  # Wait for button release
done

Option #2 : Encodeur rotatif relié aux broches GPIO

Nous allons relier un encodeur rotatif bon marché (https://www.aliexpress.com/item/1005002845325794.html) aux broches GPIO afin de contrôler le volume global du système. À chaque degré de rotation, le niveau baisse ou monte d'un cran, dépendamment de la direction.

Pour que l'encodeur rotatif soit utilisable au sein de Linux, nous devons ajouter un overlay au sein du fichier config.txt :

sudo nano /boot/config.txt

Copier les lignes ci-dessous, remplacer les numéros de broches GPIO selon vos sélections (ici, le terminal A de l'encodeur est reliée à la broche GPIO 17 et le terminal B de l'encodeur est relié à la broche GPIO 27), coller, puis sauvegarder :

# enable rotary encoder
dtoverlay=rotary-encoder,pin_a=17,pin_b=27,relative_axis=1

Réalisation du script qui sera exécuté au sein d'un service systemd :

nano ~/scripts/mame-volume-ctrl.sh

Coller les lignes ci-dessous, puis sauvegarder :

#!/bin/bash

# GPIO-connected Rotary Encoder
DEVICE='/dev/input/by-path/platform-rotary@1b-event'

EVENT_UP='* code 0 (REL_X), value 1'
EVENT_DOWN='* code 0 (REL_X), value -1'

INCREMENT=3
OUTPUT=Headphone
CURVOL=$(amixer sget $OUTPUT | awk '/Mono.+/ { print $4}' | tr -d '[%]')

evtest "$DEVICE" | while read line; do
  case $line in
    $EVENT_UP)
      # Volume increase
      [ $(($CURVOL+$INCREMENT)) -lt 100 ] && CURVOL=$(($CURVOL+$INCREMENT)) || CURVOL=100
      ;;
    $EVENT_DOWN)
      # Volume decrease
      [ $(($CURVOL-$INCREMENT)) -gt 0 ] && CURVOL=$(($CURVOL-$INCREMENT)) || CURVOL=0
      ;;
  esac
  amixer -q cset numid=1 ${CURVOL}%
done

SUITE DES ÉTAPES (après avoir réalisé l'option #1 ou #2) :

Ajustement des permissions pour permettre l’exécution du script :

chmod +x ~/scripts/mame-volume-ctrl.sh

Nous allons ajouter un service systemd afin d'exécuter en arrière-plan le script.

Pour ce faire, exécutez les étapes suivantes :

Création du service systemd :

sudo systemctl edit mame-volume-ctrl.service --force --full

Coller les lignes ci-dessous et sauvegarder :

[Unit]
Description=MAME Audio Volume Controller service
Before=mame-autostart.service
After=alsa-restore.service

[Service]
Type=simple
User=pi
Group=pi
ExecStart=/bin/bash /home/pi/scripts/mame-volume-ctrl.sh
KillSignal=SIGINT

[Install]
WantedBy=multi-user.target

Activation et démarrage du service :

sudo systemctl enable mame-volume-ctrl.service
sudo systemctl start mame-volume-ctrl.service

[Optionnel/GPIO] Bascule du système au Mode Service via bouton physique GPIO

Au démarrage du système, nous allons présenter une fenêtre temps (de quelques secondes) afin d'offrir le basculement vers le Mode Service, lorsqu'un bouton physique (via GPIO) est appuyé dans le temps imparti. Dès le bouton pressé, un son de confirmation sera émis. Si aucune pression du bouton n'est effectuée, le système va démarrer normalement en Mode Arcade.

Nous allons débuter par créer le script qui sera exécuté au démarrage du système, via un service systemd :

nano ~/scripts/mame-svcmode-check.sh

Coller les lignes ci-dessous et sauvegarder :

#!/bin/bash
#file: /home/pi/scripts/mame-svcmode-check.sh

function cleanup {
  # Deactivate GPIO pin
  echo $GPIOPIN >/sys/class/gpio/unexport 2>/dev/null
  exit 0
  }

# Clean up when exit
trap cleanup SIGHUP
trap cleanup SIGQUIT
trap cleanup SIGINT
trap cleanup SIGTERM

GPIOPIN=18   # We use GPIO 18 (pin #12)
BOOTSOUND=/home/pi/splash/boot.wav
SVCMSOUND=/home/pi/splash/service-mode.wav
TIMEOUT=5

raspi-gpio set $GPIOPIN pu      # Enable the internal pull-up resistor for this GPIO pin
aplay -q $BOOTSOUND &           # Play Boot sound

# Initialize GPIO pin
[ -d /sys/class/gpio/gpio${GPIOPIN} ] && echo $GPIOPIN > /sys/class/gpio/unexport  # Deactivate GPIO pin
echo $GPIOPIN > /sys/class/gpio/export    # Activate GPIO pin
sleep 0.1                                 # A small delay is required so that the system has time
                                          # to properly create and set the file's permission
echo in > /sys/class/gpio/gpio${GPIOPIN}/direction # Input signal
echo both > /sys/class/gpio/gpio${GPIOPIN}/edge    # We use the interrupt controller to avoid a CPU spin loop

read SIGNAL < /sys/class/gpio/gpio${GPIOPIN}/value
if [ $SIGNAL -eq 1 ]; then      # Button not pressed
  inotifywait -q -t $TIMEOUT -e modify /sys/class/gpio/gpio${GPIOPIN}/value > /dev/null
  if [ $? -eq 0 ]; then # Value has changed
    read SIGNAL < /sys/class/gpio/gpio${GPIOPIN}/value
  fi
fi

if [ $SIGNAL -eq 0 ]; then    # 1=Open/Arcade Mode, 0=Closed/Service Mode
  aplay -q $SVCMSOUND               # Service Mode
  touch /tmp/service-mode.flag
fi

Pour le son de démarrage (boot sound) et celui de confirmation du Mode Service, vous devez fournir les fichiers audio au format WAV. Placez-les où vous voulez et ajustez les deux variables ci-dessous en conséquence :

BOOTSOUND=/home/pi/splash/boot.wav
SVCMSOUND=/home/pi/splash/service-mode.wav

Le script utilise GPIO 18 (broche physique numéro 12) pour relier le bouton à une broche Ground. Vous pouvez changer le branchement, assurez-vous simplement d'utiliser un GPIO libre.

Ajustement des permissions pour permettre l’exécution du script :

chmod +x ~/scripts/mame-svcmode-check.sh

Création du service systemd :

sudo systemctl edit mame-svcmode-check.service --force --full

Coller les lignes ci-dessous et sauvegarder :

[Unit]
Description=Boot-time Service Mode Toggle Service
After=sound.target
Requires=sound.target

[Service]
Type=oneshot
RemainAfterExit=no
ExecStart=/bin/bash /home/pi/scripts/mame-svcmode-check.sh

[Install]
WantedBy=multi-user.target

Activation et démarrage du service :

sudo systemctl enable mame-svcmode-check.service
sudo systemctl start mame-svcmode-check.service

Ajustements des deux services du Mode Arcade :

sudo systemctl edit mame-autostart.service --force --full

À la section [Unit], sous la ligne After=mame-svcmode-check.service, ajouter la ligne ci-dessous :

ConditionPathExists=!/tmp/service-mode.flag

Retirer la ligne suivante, puis sauvegarder :

Conflicts=getty@tty1.service smbd.service nmbd.service rng-tools.service cron.service mame-artwork-mgmt.service

Nous devons ajuster les services que nous ne voulons pas lancer en Mode Arcade en ajoutant une condition à leur démarrage via un drop-in systemd.

Pour créer les drop-ins systemd pour chacun de ces services, exécutez cette ligne :

for i in getty@tty1.service \
         smbd.service \
         nmbd.service \
         rng-tools.service \
         cron.service \
         mame-artwork-mgmt.service; do \
sudo mkdir /etc/systemd/system/$i.d \
echo '[Unit]' | sudo tee -a /etc/systemd/system/$i.d/arcademode-fixup.conf; \
echo 'ConditionPathExists=/tmp/service-mode.flag' | sudo tee -a /etc/systemd/system/$i.d/servicemode-fixup.conf; \
done; \
echo 'After=' | sudo tee -a /etc/systemd/system/rng-tools.service.d/servicemode-fixup.conf; \
echo 'After=mame-svcmode-check.service' | sudo tee -a /etc/systemd/system/rng-tools.service.d/servicemode-fixup.conf

Appliquer les changements :

sudo systemctl daemon-reload

[Optionnel/TV] Désactivation des bordures noires (Overscan)

sudo nano /boot/config.txt

Décommenter la ligne ci-dessous :

disable_overscan=1

[Optionnel] Rotation de l'écran à 90 degrés

Si vous comptez utiliser votre système d'arcade pour les jeux verticaux (shoot 'em up, par exemple), suivez ces étapes.

Le fait d'utiliser le pilote DRM VC4 V3D (vc4-fkms-v3d) ne nous permet malheureusement pas (du moins en ce moment) d'utiliser la fonctionnalité de rotation de l'écran au niveau du pilote (par le biais du réglage display_hdmi_rotate= dans /boot/config.txt). Nous devrons contourner ce problème en appliquant la rotation à chacune des composantes individuellement (console en mode texte, splash de boot et shutdown et interface graphique de MAME).

Rotation de la console à 90 degrés :

sudo nano /boot/cmdline.txt

Ajouter ceci à la fin de ligne de commande du kernel, puis sauvegarder :

fbcon=rotate:1

Rotation des images de splash (boot et shutdown) :

sudo systemctl edit mame-bootsplash.service --force --full

Ajustez la ligne ExecStart en ajoutant -C _orientation=1, puis sauvegardez :

ExecStart=/usr/bin/fim -q --no-history -C _orientation=1 /home/pi/splash/mame-boot.jpg
sudo systemctl edit mame-shutdownsplash.service --force --full

Ajustez la ligne ExecStart en ajoutant -C _orientation=1, puis sauvegardez :

ExecStart=/usr/bin/fim -q --no-history -C _orientation=1 /home/pi/splash/mame-shutdown.jpg

Rotation de l'interface graphique de MAME :

nano ~/.mame/mame.ini

Ajustez la section ci-dessous, puis sauvegardez :

#
# CORE ROTATION OPTIONS
#
rotate                    1
ror                       1

Pour maximiser la visibilité du nom des ROMS, nous devons cacher le panneau de gauche qui affiche le filtre actif :

nano ~/.mame/ini/ui.ini

Ajustez le réglage ci-dessous à la valeur 1, puis sauvegardez :

hide_main_panel           1

Amélioration du rendu vidéo pour les téléviseurs

Afin d'améliorer le rendu vidéo, de permettre le bon fonctionnement de la synchronisation verticale (VSync) qui est activée au sein de cette procédure et également de minimiser le délai de latence des contrôles (manette, boutons), assurez-vous de sélectionner le Mode Jeu / Game Mode (ou équivalent) sur votre téléviseur.

C'est complété !

Voilà, c'est terminé ! Vous pouvez maintenant passer à l'étape de l'intégration de votre Raspberry Pi 4 à un projet d'arcade pour la maison : un cabinet de type comptoir (Bartop) ou encore pleine hauteur/format original.

Je vous souhaite la meilleure des chances pour votre projet d'arcade !

-------------- FIN DE LA PROCÉDURE --------------

Si vous appréciez le travail et le soin que j'ai mis à monter cette solution, je vous propose de m'offrir un café, ceci m'encouragera à maintenir cette procédure bien vivante et à jour. :-)

Buy me a coffee

@alejandrorusso
Copy link

Hi @sonicprod !

I am happy to see the integration! It looks good to me!

Keep pushing this amazing work!

My guest is that this project will get more and more fancy and we will need to start thinking about a configuration script that does a bunch of questions and deploys the right setting for the user — just some thoughts.

@sonicprod
Copy link
Author

sonicprod commented Jan 20, 2022

@alejandrorusso,

Thanks! Regarding your suggestion, do you mean creating a CI/CD pipeline? I am able to automate/script the entire process, but to a certain extent: I am not able to cross-compile from an x86 build PC/server to a Raspberry Pi 4B. I am not able to install Raspberry Pi OS (formerly Raspbian) in an emulated environment (with QEMU, for example), because no support is available, yet.

However, I have staging scripts to maintain the disk image I publish. Here they are:

inject-rootfs.raspios.mame.sh

#!/bin/bash

# Script pour extraire les partitions 'boot' et 'rootfs' de la carte micro-SD et les injecter dans le fichier-image
# pour pouvoir le publier en ligne.

if [ ! $1 ]; then
    echo Usage: $0 VER
    echo '  Where VER is the 4-digit version number of the MAME image file (for example: 0224).'
    exit
fi

IMGFILE=rpi4b.raspios.mame-$1.appliance.fe-edition.img
SDDEVICE=/dev/sdb

if [ ! -f ~/$IMGFILE ]; then
    echo $IMGFILE does not exist!
    exit
fi

echo INFO: Block size de ${SDDEVICE}1 = $(lsblk ${SDDEVICE}1 -nt | awk '{ print $6 }') octets.
echo INFO: Block size de ${SDDEVICE}2 = $(lsblk ${SDDEVICE}1 -nt | awk '{ print $6 }') octets.

# Démontage de la partition, si déjà montée
# if [ $(findmnt -n $PART | awk '{print $1}') = '/media/bbegin/rootfs' ]; then
#     sudo umount $PART
# fi

echo Démontage des partitions de la carte micro-SD...
sudo umount ${SDDEVICE}1
sudo umount ${SDDEVICE}2

# Extraction de la partition boot
sudo dd if=${SDDEVICE}1 of=boot.img status=progress bs=1M
# Extraction de la partition rootfs
sudo dd if=${SDDEVICE}2 of=rootfs.img status=progress bs=1M

# Montage du disque virtuel pour présenter les partitions sous /dev/mapper
sudo kpartx -av $IMGFILE
ls -la /dev/mapper

# Écriture de boot et rootfs vers le disque virtuel...
echo Écriture de boot.img vers le disque virtuel...
sudo dd if=boot.img   of=/dev/mapper/loop0p1 status=progress bs=1M
echo Écriture de rootfs.img vers le disque virtuel...
sudo dd if=rootfs.img of=/dev/mapper/loop0p2 status=progress bs=1M

# Retrait du disque virtuel
sync
sudo kpartx -dv $IMGFILE

sudo rm boot.img
sudo rm rootfs.img

echo Opération complétée !
ls -la $IMGFILE

mount-boot.rpi4b.raspios.mame.sh

#!/bin/sh

if [ ! $1 ]; then
    echo Usage: $0 VER
    echo '  Where VER is the 4-digit version number of MAME image file (for example: 0224).'
    exit
fi

# IMGNAME=rpi4b.raspios.mame-$1.appliance.img
IMGNAME=rpi4b.raspios.mame-$1.appliance.fe-edition.img

if [ ! -f ~/$IMGNAME ]; then
    echo $IMGNAME does not exist!
    exit
fi

if [ ! -d /tmp/boot.img ]; then
    sudo mkdir /tmp/boot.img
fi
sudo mount -t vfat -o loop,rw,sync,offset=4194304 ~/$IMGNAME /tmp/boot.img
cd /tmp/boot.img
echo -------------------------------------------
$SHELL
echo -------------------------------------------
echo Unmounting image.....
cd ~
sudo umount /tmp/boot.img
echo Done!

mount-data.rpi4b.raspios.mame.sh

#!/bin/sh

if [ ! $1 ]; then
    echo Usage: $0 VER
    echo '  Where VER is the 4-digit version number of MAME image file (for example: 0224).'
    exit
fi

#IMGNAME=rpi4b.raspios.mame-$1.appliance.img
IMGNAME=rpi4b.raspios.mame-$1.appliance.fe-edition.img

if [ ! -f ~/$IMGNAME ]; then
    echo $IMGNAME does not exist!
    exit
fi

if [ ! -d /tmp/data.img ]; then
    sudo mkdir /tmp/data.img
fi
sudo mount -o loop,rw,sync,offset=13157531648 ~/$IMGNAME /tmp/data.img
cd /tmp/data.img

if [ "$2" = "zero" ]; then
    echo Overwriting free space with zeros...
    dd if=/dev/zero of=zeros bs=8M status=progress
    rm zeros
else
    echo -------------------------------------------
    $SHELL
    echo -------------------------------------------
fi

echo Unmounting image.....
cd ~
sudo umount /tmp/data.img
echo Done!

mount-rootfs.rpi4b.raspios.mame.sh

#!/bin/sh

if [ ! $1 ]; then
    echo Usage: $0 VER
    echo '  Where VER is the 4-digit version number of MAME image file (for example: 0224).'
    exit
fi

# IMGNAME=rpi4b.raspios.mame-$1.appliance.img
IMGNAME=rpi4b.raspios.mame-$1.appliance.fe-edition.img

if [ ! -f ~/$IMGNAME ]; then
    echo $IMGNAME does not exist!
    exit
fi

if [ ! -d /tmp/rootfs.img ]; then
    sudo mkdir /tmp/rootfs.img
fi
sudo mount -o loop,rw,sync,offset=272629760 ~/$IMGNAME /tmp/rootfs.img
cd /tmp/rootfs.img/home/pi

if [ "$2" = "zero" ]; then
    echo Overwriting free space with zeros...
    dd if=/dev/zero of=zeros bs=8M status=progress
    rm zeros
else
    echo -------------------------------------------
    $SHELL
    echo -------------------------------------------
fi
echo Unmounting image.....
cd ~
sudo umount /tmp/rootfs.img
echo Done!

compress-image-file.sh

#!/bin/bash

if [ ! $1 ]; then
    echo Usage: $0 VER [zero]
    echo '  Where VER is the 4-digit version number of MAME to update (for example: 0224).'
    echo '  Where zero overwrite the free space with zeros to optimize compression.'
    exit
fi

# IMGNAME=rpi4b.raspios.mame-$1.appliance.img
IMGNAME=rpi4b.raspios.mame-$1.appliance.fe-edition.img

if [ ! -f ~/$IMGNAME ]; then
    echo $IMGNAME does not exist!
    exit
fi

if [ -f $IMGNAME.gz ]; then
    rm $IMGNAME.gz
fi

# Écrasement de l'espace libre de rootfs avec des zéros
if [ "$2" = "zero" ]; then
    ./mount-rootfs.rpi4b.raspios.mame.sh $1 zero
fi

echo -n "Compressing $IMGNAME..."
gzip -9 -k $IMGNAME
echo

ls -la $IMGNAME $IMGNAME.gz

@sonicprod
Copy link
Author

@fxlevy,

Merci pour les précisions concernant la version 64-bit du OS. :)

Concernant la nouvelle version du patch, je sais que celle-ci fonctionnait avec lews versions récentes de MAME, mais l'application de celle-ci donnait un avertissement. À la demande de @alejandrorusso, je l'ai recréée avec la version 0.239 de MAME. Je crois qu'elle pourraît tout de même fonctionner avec les plus anciennes versions, car le code n'a pas changé, seulement les numéros de ligne qui peuvent différer.

@fxlevy
Copy link

fxlevy commented Mar 13, 2022

Bonjour @sonicprod , je suis toujours en train de bricoler sur ma mini borne d'arcade "Picade". J'ai installé un système Bullseye 64 bit light. J'ai ensuite compilé Attract Mode Plus et MAME à partir des scripts que j'ai réalisé en me basant sur ton HowTo. Pour la compilation de SFML, je m'appuie sur le repo de Oomek et il faut choisir la version 2.6.0 qui est actuellement la seule qui fonctionne bien. C'est un peu compliqué car une nouvelle version officielle native DRM KMS est en cours d'élaboration. il y a une pull request pour se faire. En attendant il faut prendre la 2.6.0 de Oomek. Le Script que j'ai créé pour compiler SFML tient compte de tout ça.

Pour les layouts, j'ai installé Arcadeflow. Il fonctionne super bien. Il est un petit peu lent et il y a un bug lorsque l'on quitte Mame pour revenir sur Attract. C'est pourquoi j'utilise Silky pour le moment. Il est pratique et très bien conçu. Bref, je suis vraiment content du résultat.

J'ai cependant une question à propos de la compilation de MAME.
Bien que tout se passe bien lors de la compilation et de l'exécution du binary après compilation, j'ai une alerte avant la configuration du gmake lors de la compilation.

Package Qt5Widgets was not found in the pkg-config search path.
Perhaps you should add the directory containing `Qt5Widgets.pc'
to the PKG_CONFIG_PATH environment variable
No package 'Qt5Widgets' found
Package Qt5Widgets was not found in the pkg-config search path.
Perhaps you should add the directory containing `Qt5Widgets.pc'
to the PKG_CONFIG_PATH environment variable
No package 'Qt5Widgets' found
Package Qt5Widgets was not found in the pkg-config search path.
Perhaps you should add the directory containing `Qt5Widgets.pc'
to the PKG_CONFIG_PATH environment variable
No package 'Qt5Widgets' found
Package Qt5Widgets was not found in the pkg-config search path.
Perhaps you should add the directory containing `Qt5Widgets.pc'
to the PKG_CONFIG_PATH environment variable
No package 'Qt5Widgets' found
Building configurations...
Running action 'gmake'...

Je me demande pourquoi il me parle de Qt5 puique l'on ne l'utilise pas.

@sonicprod
Copy link
Author

Bonjour @fxlevy,

Content d'avoir de tes nouvelles et des développements sur ton projet.

Pour répondre à ta question, QT5 nécessite X11 et comme tu le sais, l'idée de ce projet c'est d'avoir la distro la plus légère et performante possible et dédiée à l'émulation d'arcade sur MAME. La seule dépendance de MAME pour QT5 est liée à son débugger (mode graphique), que nous excluons à l'aide de la directive USE_QTDEBUG=0 au sein de la ligne de commande « make ». J'en déduis que le makefile ne prend pas complètement correctement en compte la directive et affiche ces messages, qui sont bénins.

Laisses-moi savoir comment sont les performances de MAME 64-bit par rapport à MAME 32-bit sur le Raspberry Pi 4. :)

@fxlevy
Copy link

fxlevy commented Mar 14, 2022

Bonjour @sonicprod , je n'ai pas de version 32 bit d'installer mais ce que je constate c'est que la dernière distro de Bullseye en 64 bits de la fondation Raspberry a bénéficié d'évolutions importantes car aucune modification du boot config n'a été nécessaire pour faire fonctionner Attract et Mame. Aucun overcloacking ni utilisation de governor n'a été nécessaire. Tout fonctionne de base en compilant depuis mes scripts qui s'appuie à 100% sur les tiens et je ne te remercierai jamais assez d'avoir ouvert la voie. :)
Pour le moment tout est installé sur une SanDidk Extreme Pro de 512 Go. J'ai mis tout le contenu attract et mame dans des dossiers /data/mame et /data/attract avec des symlinks .mame et .attract qui pointent dessus. Je vais repoduire ma procédure sur une autre SD de 64 Go dont je dispose sans y mettre de contenu et faire une image avec. Sauf que je n'ai jamais fait ça et il va falloir que je comprenne comment on fait.

@sonicprod
Copy link
Author

sonicprod commented Mar 14, 2022

Allo @fxlevy,

Pour créer un fichier-image du contenu d'une carte SD, l'utilitaire dd sera assurément ton ami :)

Si tu veux, tu peux explorer les quelques scripts que j'ai réalisé pour gérer les mises à jour au sein du fichier image et le compresser efficacement :

  • mount-boot.rpi4b.raspios.mame.sh
  • mount-rootfs.rpi4b.raspios.mame.sh
  • mount-data.rpi4b.raspios.mame.sh
  • inject-rootfs.raspios.mame.sh
  • compress-image-file.sh

Les scripts sont plus haut, dans les commentaires.

@fxlevy
Copy link

fxlevy commented Apr 4, 2022

Bonjour @sonicprod , j'ai procédé hier à une full-upgrade du RaspiOS Bullseye de mon RPI 4. J'avais un MAME 0.241 qui tournait nickel. Après l'upgrade, lorsque je lançais MAME j'ai eu des "glitchs" de mon écran et après quelques secondes un freeze de l'écran avec un Kernel Error. J'ai passé du temps à essayer de comprendre. J'ai tout recompilé sans que celà change quoi que soit. Pire, la compilation de la dernière version de MAME 0.242 plantait. Je me suis rendu compte que le Patch ne marchait plus sur cette version. Et en effet le drawbgfx.cpp était très différent. Alors j'a créé un nouveau Patch. Il est ci-dessous:

--- drawbgfx.cpp.ori	2022-04-03 21:00:25.291487695 +0200
+++ drawbgfx.cpp.new	2022-04-03 21:03:47.621247497 +0200
@@ -238,7 +238,8 @@
 	}
 
 #   if BX_PLATFORM_LINUX || BX_PLATFORM_BSD || BX_PLATFORM_RPI
-	return (void*)wmi.info.x11.window;
+	// return (void*)wmi.info.x11.window;
+	return (void*)_window;
 #   elif BX_PLATFORM_OSX
 	return wmi.info.cocoa.window;
 #   elif BX_PLATFORM_WINDOWS
@@ -258,8 +259,10 @@
 	}
 
 #   if BX_PLATFORM_LINUX || BX_PLATFORM_BSD
-	platform_data.ndt          = wmi.info.x11.display;
-	platform_data.nwh          = (void*)(uintptr_t)wmi.info.x11.window;
+	// platform_data.ndt          = wmi.info.x11.display;
+	// platform_data.nwh          = (void*)(uintptr_t)wmi.info.x11.window;
+	platform_data.ndt          = NULL;
+	platform_data.nwh          = _window;
 #   elif BX_PLATFORM_OSX
 	platform_data.ndt          = NULL;
 	platform_data.nwh          = wmi.info.cocoa.window;

J'ai pu compilé MAME avec ce nouveau Patch. :)
Je ne comprends d'ailleurs pas pourquoi le problème n'a pas été corrigé et remonté dans la Release de MAME depuis tout ce temps.

Mais le problème n'était pas résolu.
Après quelques recherches, j'ai réglé le problème qui provenait du driver dtoverlay=vc4-kms-v3d que j'ai du remplacer par dtoverlay=vc4-fkms-v3d
Le pilote KMS n'est donc plus stable sur la dernière version du Kernel.

Pour info , voilà la version du système que j'utilise et qui est la dernière en date du 4 Avril 2022:

Operating System: Debian GNU/Linux 11 (bullseye)
Kernel: Linux 5.15.30-v8+
Architecture: arm64

Voilà pour la petite histoire. Mais l'information importante c'est qu'il faut adapter le Patch pour qu'il puisse s'appliquer sur une version MAME 0.242

@+
FX

@sonicprod
Copy link
Author

@fxlevy,

Merci beaucoup pour la mise à jour du patch, FX ! :)

J'ai mis à jour le gist avec celle-ci.

@sonicprod
Copy link
Author

@fxlevy,

De nouveaux développements au sein de ton adaptation du système sur Linux 64-bit avec les menus ?

@fxlevy
Copy link

fxlevy commented Sep 14, 2022

Bonjour Benoit,celà me fait plaisir que tu viennes prendre des nouvelles. Je n'ai pas travaillé sur les scripts depuis plusieurs semaines voir mois. :(
J'ai un boulot qui me prend beaucoup et qui me laisse peu de temps. L'été a aussi été propice à plein d'autres activités. Mais je pensais justement la semaine dernière à reprendre le développement de ces scripts afin d'avoir une réelle automatisation des mises à jour de tous les composants de la borne d'Arcade tout en restant pilotables avec des bôites de dialogues Mais je trouve que la mise en place du PI OS sans desktop correspond exactement à ce que doit être un système dédié à ce type de projet. Chose quue l'on ne voit qu'assez rarement alors que toutes les consoles de jeu fonctionnent sur ce principe. Pour moi le vrai challange est là. :)
Et de ton côté tu travailles toujours sur ce projet?

@sonicprod
Copy link
Author

sonicprod commented Sep 19, 2022

@fxlevy,

Content d'avoir des nouvelles ! C'est un peu pareil pour moi, disons que j'ai un peu mis de côté le projet depuis le début de l'été (emménagement dans une nouvelle maison, activité estivales, etc.). Je devrais être bon pour reprendre les mises à jour cet automne. Au menu, je veux ajuster le « How To » pour utiliser la version 64-bit de Raspberry Pi OS. Je vais également inclure les étapes pour compiler Attract Mode, ainsi que AdvancedMENU en 64-bit. Je vais le plus possible automatiser ces étapes au sein de scripts Bash, à l'instar de celui qui compile MAME.

En effet, le vrai challenge est de monter un système d'émulation d'arcade sans s'encombrer du système X-Window/X11. On boot en mode texte et hop, on bascule dans l'émulateur. On ne charge que ce qui est strictement nécessaire, rien de plus. :) Après, le mode « appliance » (démarrage automatique du front-end, arrêt du système lorsqu'on quitte le front-end) m'apparaît incontournable pour une borne d'arcade.

@fxlevy
Copy link

fxlevy commented Sep 21, 2022

Le souci c'est que faire des tests implique de souvent recommencer. Sur un environnement physique cela implique souvent de réinstaller l'OS. Le problème c'est que les cartes Micro SD ne sont pas fiables si on les sollicite trop en lecture/écriture avec un avec un volume de données important. J'ai déjà cramé 2 cartes SD haut de gamme dont une de 400GO. Donc mon premier projet est de pouvoir réaliser les tests dans un environnement virtualisé. Je suis en train d'étudier la virtualisation du Raspberry PI 4B avec QEMU. C'est assez compliqué mais cela me semble faisable. Mon objectif principal est de fiabiliser les scripts d'installation et de mises à jour des différents composants de la borne comme SDL2, MAME, SFML et AM+.

@alejandrorusso
Copy link

Hi @sonicprod !

Installing a new machine and it seems that the scripts for scrapping artwork are not working since the hardcoded URLs are down:

URLPREFIX1=http://mamedb.blu-ferret.co.uk
URLPREFIX2=http://adb.arcadeitalia.net/media/mame.current

@MauiPunter
Copy link

Hello @sonicprod

I am getting an error when I am in arcade mode, and attract mode is the front end. When I login when Attract Mode running, I am getting these errors and the Front End UI is frozen. Let me know your thoughts. I would post on the arcadecontrols, but their registration is broken. Sorry if this is not the appropriate venue to contact you. Here is a screen shot.

image

@MauiPunter
Copy link

Hi @sonicprod !

Installing a new machine and it seems that the scripts for scrapping artwork are not working since the hardcoded URLs are down:

URLPREFIX1=http://mamedb.blu-ferret.co.uk
URLPREFIX2=http://adb.arcadeitalia.net/media/mame.current

I noticed the mirror is still up.

http://www.mamedb.com/

@sonicprod
Copy link
Author

Hello @sonicprod

I am getting an error when I am in arcade mode, and attract mode is the front end. When I login when Attract Mode running, I am getting these errors and the Front End UI is frozen. Let me know your thoughts. I would post on the arcadecontrols, but their registration is broken. Sorry if this is not the appropriate venue to contact you. Here is a screen shot.

image

Make sure you executed this command:

sudo usermod -a -G render pi

Thanks,

Benoit

@sonicprod
Copy link
Author

sonicprod commented Dec 15, 2022

Thanks, I will update the script this evening with the mirror (http://www.mamedb.com/) and let you know here.

Benoit

@MauiPunter
Copy link

MauiPunter commented Dec 16, 2022

@sonicprod I ran that usermod command and am still getting this error when I login. Attract is still frozen upon boot.

image

Here are the user details for pi:
image

Also, you have a bug in mame-scraper.sh on line 29

should be:

*)

instead of

titles)

@sonicprod
Copy link
Author

sonicprod commented Dec 16, 2022

What is the content of your /boot/config.txt ?

Could you run:

ls -la /dev/dri

Thanks for the bug found in mame-scraper.sh on line 29 - fixed.

@MauiPunter
Copy link

MauiPunter commented Dec 16, 2022

@sonicprod config.txt

# For more options and information see
# http://rpf.io/configtxt
# Some settings may impact device functionality. See link above for details

# uncomment if you get no picture on HDMI for a default "safe" mode
#hdmi_safe=1

# uncomment this if your display has a black border of unused pixels visible
# and your display can output without overscan
disable_overscan=1

# uncomment the following to adjust overscan. Use positive numbers if console
# goes off screen, and negative if there is too much border
#overscan_left=16
#overscan_right=16
#overscan_top=16
#overscan_bottom=16

# uncomment to force a console size. By default it will be display's size minus
# overscan.
#framebuffer_width=1280
#framebuffer_height=720

# uncomment if hdmi display is not detected and composite is being output
#hdmi_force_hotplug=1

# uncomment to force a specific HDMI mode (this will force VGA)
#hdmi_group=1
#hdmi_mode=1

# uncomment to force a HDMI mode rather than DVI. This can make audio work in
# DMT (computer monitor) modes
#hdmi_drive=2

# uncomment to increase signal to HDMI, if you have interference, blanking, or
# no display
#config_hdmi_boost=4

# uncomment for composite PAL
#sdtv_mode=2

#uncomment to overclock the arm. 700 MHz is the default.
#arm_freq=800

# Uncomment some or all of these to enable the optional hardware interfaces
#dtparam=i2c_arm=on
#dtparam=i2s=on
#dtparam=spi=on

# Uncomment this to enable infrared communication.
#dtoverlay=gpio-ir,gpio_pin=17
#dtoverlay=gpio-ir-tx,gpio_pin=18

# Additional overlays and parameters are documented /boot/overlays/README

cec_osd_name=Arcade
disable_splash=1
gpu_mem=128

# Overclocking
# over_voltage=2
# arm_freq=1750

# Enable audio (loads snd_bcm2835)
dtparam=audio=on

[pi4]
# Enable DRM VC4 V3D driver on top of the dispmanx display stack
dtoverlay=vc4-fkms-v3d
max_framebuffers=2

[all]
#dtoverlay=vc4-fkms-v3d

image

@sonicprod
Copy link
Author

@sonicprod config.txt

# For more options and information see
# http://rpf.io/configtxt
# Some settings may impact device functionality. See link above for details

# uncomment if you get no picture on HDMI for a default "safe" mode
#hdmi_safe=1

# uncomment this if your display has a black border of unused pixels visible
# and your display can output without overscan
disable_overscan=1

# uncomment the following to adjust overscan. Use positive numbers if console
# goes off screen, and negative if there is too much border
#overscan_left=16
#overscan_right=16
#overscan_top=16
#overscan_bottom=16

# uncomment to force a console size. By default it will be display's size minus
# overscan.
#framebuffer_width=1280
#framebuffer_height=720

# uncomment if hdmi display is not detected and composite is being output
#hdmi_force_hotplug=1

# uncomment to force a specific HDMI mode (this will force VGA)
#hdmi_group=1
#hdmi_mode=1

# uncomment to force a HDMI mode rather than DVI. This can make audio work in
# DMT (computer monitor) modes
#hdmi_drive=2

# uncomment to increase signal to HDMI, if you have interference, blanking, or
# no display
#config_hdmi_boost=4

# uncomment for composite PAL
#sdtv_mode=2

#uncomment to overclock the arm. 700 MHz is the default.
#arm_freq=800

# Uncomment some or all of these to enable the optional hardware interfaces
#dtparam=i2c_arm=on
#dtparam=i2s=on
#dtparam=spi=on

# Uncomment this to enable infrared communication.
#dtoverlay=gpio-ir,gpio_pin=17
#dtoverlay=gpio-ir-tx,gpio_pin=18

# Additional overlays and parameters are documented /boot/overlays/README

cec_osd_name=Arcade
disable_splash=1
gpu_mem=128

# Overclocking
# over_voltage=2
# arm_freq=1750

# Enable audio (loads snd_bcm2835)
dtparam=audio=on

[pi4]
# Enable DRM VC4 V3D driver on top of the dispmanx display stack
dtoverlay=vc4-fkms-v3d
max_framebuffers=2

[all]
#dtoverlay=vc4-fkms-v3d

image

Ok, does MAME launch? Do you see the GUI? Are you able to successfully launch a ROM?

Maybe it's the SFML-Pi layer that is not working correctly. Did you build the system from scratch with the instructions from this Gist or did you grabbed the pre-built image file that I provide?

@MauiPunter
Copy link

MauiPunter commented Dec 16, 2022 via email

@MauiPunter
Copy link

MauiPunter commented Dec 16, 2022

@sonicprod Here are the exact steps I took for your reference:

0) flash image: rpi4b.raspios.mame-0243.appliance.fe-edition.img

1) ssh in

2) rw

3) passwd

4) ./expand-data-partition.sh

5) sudo usermod -a -G render pi

6) sudo nano /boot/cmdline.txt
	fbcon=rotate:1

7) sudo systemctl edit mame-bootsplash.service --force --full
	-C _orientation=1
	
8) sudo systemctl edit mame-shutdownsplash.service --force --full
	-C _orientation=1

9) nano ~/.mame/mame.ini
	ror                       1

10) nano ~/.mame/ini/ui.ini
	hide_main_panel           1

11) ro 

12) sudo reboot

13) rw 

14) Load ROMS: //arcade/data

15) arcademode

16) frontend attract

17) sudo reboot

18) ssh

19) after login, permission errors appear on login screen

@sonicprod
Copy link
Author

Thanks @MauiPunter for putting the exact steps you took since you flashed the image.

It tells me that the problem may be from the image itself...

I will try to publish a new image tonight. It will be 64-bit, instead of the 32-bit I used to provide. This will run smoothly on any Raspberry Pi 4. I will let you know, once the new image available.

I'm sorry for the inconvenience...

@MauiPunter
Copy link

It's no problem at all. I truly appreciate ALL your work on this project. It's ground breaking for sure!

@sonicprod
Copy link
Author

Thanks, @MauiPunter !

I have little SD card problems, I will fix this and publish the new image as soon as I can. Sorry for the inconvenience.

@sonicprod
Copy link
Author

Hi @MauiPunter,

Just to let you know the availability of the NEW disk image file with MAME 0.250 (please see the original post on the Arcade Controls forum for the download link).

Just let me know if everything works as intended.

@MauiPunter
Copy link

MauiPunter commented Dec 21, 2022

@sonicprod

Thank you for your new release. I am finding a new issue right away. The /data portion is getting corrupted it seems.

All I have done at this point is:

  1. flash sd card
  2. login
  3. rw
  4. ./expand-data-partition.sh

Is this expected output?

[migrate_block:  58] Migrate data block 7afa -> 12bfb
[migrate_block:  58] Migrate data block 7afb -> 12bfc
[migrate_block:  58] Migrate data block 7afc -> 12bfd
[migrate_block:  58] Migrate data block 7afd -> 12bfe
[migrate_block:  58] Migrate data block 7afe -> 12bff
Not enough space to migrate blocksTry to do defragement: Skip
[migrate_main: 201] Info: Done to migrate Main area: main_blkaddr = 0x1000 -> 0x                        7e00
[migrate_ssa: 266] Info: Done to migrate SSA blocks: sum_blkaddr = 0xe00 -> 0x5a                        00
[migrate_nat: 382] Info: Done to migrate NAT blocks: nat_blkaddr = 0xa00 -> 0xa0                        0
[migrate_sit: 440] Info: Done to restore new SIT blocks: 0x600
Info: Write valid nat_bits in checkpoint
[rebuild_checkpoint: 570] Info: Done to rebuild checkpoint blocks
[rebuild_superblock: 586] Info: Done to rebuild superblock

Done.
mount: /data: mount(2) system call failed: Structure needs cleaning.
---------------------------------------------
NEW size of /data:
---------------------------------------------
Expand operation completed.
pi@arcade(rw):~$

Also, samba share is not available: \\arcade\data

@sonicprod
Copy link
Author

sonicprod commented Dec 21, 2022

Thanks for your feedback, @MauiPunter!

For some reason, an fsck on /data was needed.

I just published an updated image file, the download link is the same.

Linux arcade 5.10.103-v7l+ #1529 SMP Tue Mar 8 12:24:00 GMT 2022 armv7l
----------------------------------------------------------------------
Current Frontend: MAME GUI.
+---------------+-----------+-----------+
| EMULATOR      | CURRENT   | LATEST    |
+---------------+-----------+-----------+
| MAME          | 0.250     | Latest    |
| Hypseus-Singe | 2.10.1    | Latest    |
+---------------+-----------+-----------+
The system is currently in SERVICE mode.

pi@arcade(ro):~$ ./expand-data-partition.sh
---------------------------------------------
CURRENT size of /data: 298M
---------------------------------------------
Info: Segments per section = 1
Info: Sections per zone = 1
Info: sector size = 512
Info: total sectors = 97898496 (47802 MB)
Info: MKFS version
  "Linux version 5.10.103-v7l+ (dom@buildbot) (arm-linux-gnueabihf-gcc-8 (Ubuntu/Linaro 8.4.0-3ubuntu1) 8.4.0, GNU ld (GNU Binutils for Ubuntu) 2.34) #1529 SMP Tue Mar 8 12:24:00 GMT 2022"
Info: FSCK version
  from "Linux version 5.4.0-135-generic (buildd@lcy02-amd64-066) (gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.1)) #152-Ubuntu SMP Wed Nov 23 20:19:22 UTC 2022"
    to "Linux version 5.10.103-v7l+ (dom@buildbot) (arm-linux-gnueabihf-gcc-8 (Ubuntu/Linaro 8.4.0-3ubuntu1) 8.4.0, GNU ld (GNU Binutils for Ubuntu) 2.34) #1529 SMP Tue Mar 8 12:24:00 GMT 2022"
Info: superblock features = 0 :
Info: superblock encrypt level = 0, salt = 00000000000000000000000000000000
Info: total FS sectors = 614400 (300 MB)
Info: CKPT version = 871e722
Info: Write valid nat_bits in checkpoint
[migrate_main: 201] Info: Done to migrate Main area: main_blkaddr = 0x1000 -> 0x13c00
[migrate_ssa: 266] Info: Done to migrate SSA blocks: sum_blkaddr = 0xe00 -> 0xde00
[migrate_nat: 382] Info: Done to migrate NAT blocks: nat_blkaddr = 0xa00 -> 0xa00
[migrate_sit: 440] Info: Done to restore new SIT blocks: 0x600
Info: Write valid nat_bits in checkpoint
[rebuild_checkpoint: 570] Info: Done to rebuild checkpoint blocks
[rebuild_superblock: 586] Info: Done to rebuild superblock

Done.
---------------------------------------------
NEW size of /data: 47G
---------------------------------------------
Expand operation completed.
pi@arcade(ro):~$

@MauiPunter
Copy link

MauiPunter commented Dec 21, 2022

@sonicprod
Having same issue...

[migrate_block:  58] Migrate data block 7bf9 -> 12bf9
[migrate_block:  58] Migrate data block 7bfa -> 12bfa
[migrate_block:  58] Migrate data block 7bfb -> 12bfb
[migrate_block:  58] Migrate data block 7bfc -> 12bfc
[migrate_block:  58] Migrate data block 7bfd -> 12bfd
[migrate_block:  58] Migrate data block 7bfe -> 12bfe
[migrate_block:  58] Migrate data block 7bff -> 12bff
Not enough space to migrate blocksTry to do defragement: Skip
[migrate_main: 201] Info: Done to migrate Main area: main_blkaddr = 0x1000 -> 0x                                             7e00
[migrate_ssa: 266] Info: Done to migrate SSA blocks: sum_blkaddr = 0xe00 -> 0x5a                                             00
[migrate_nat: 382] Info: Done to migrate NAT blocks: nat_blkaddr = 0xa00 -> 0xa0                                             0
[migrate_sit: 440] Info: Done to restore new SIT blocks: 0x600
Info: Write valid nat_bits in checkpoint
[rebuild_checkpoint: 570] Info: Done to rebuild checkpoint blocks
[rebuild_superblock: 586] Info: Done to rebuild superblock

Done.
mount: /data: mount(2) system call failed: Structure needs cleaning.
---------------------------------------------
NEW size of /data:
---------------------------------------------
Expand operation completed.

I tried running the fsck command and it didn't work either it seems

pi@arcade(ro):/$ sudo fsck /data
fsck from util-linux 2.33.1
Info: Segments per section = 1
Info: Sections per zone = 1
Info: sector size = 512
Info: total sectors = 36659200 (17900 MB)
Info: MKFS version
  "Linux version 5.10.103-v7l+ (dom@buildbot) (arm-linux-gnueabihf-gcc-8 (Ubuntu/Linaro 8.4.0-3ubuntu1) 8.4.0, GNU ld (GNU Binutils for Ubuntu) 2.34) #1529 SMP Tue Mar 8 12:24:00 GMT 2022"
Info: FSCK version
  from "Linux version 5.10.103-v7l+ (dom@buildbot) (arm-linux-gnueabihf-gcc-8 (Ubuntu/Linaro 8.4.0-3ubuntu1) 8.4.0, GNU ld (GNU Binutils for Ubuntu) 2.34) #1529 SMP Tue Mar 8 12:24:00 GMT 2022"
    to "Linux version 5.10.103-v7l+ (dom@buildbot) (arm-linux-gnueabihf-gcc-8 (Ubuntu/Linaro 8.4.0-3ubuntu1) 8.4.0, GNU ld (GNU Binutils for Ubuntu) 2.34) #1529 SMP Tue Mar 8 12:24:00 GMT 2022"
Info: superblock features = 0 :
Info: superblock encrypt level = 0, salt = 00000000000000000000000000000000
Info: total FS sectors = 36659200 (17900 MB)
[f2fs_crc_valid: 506] CRC validation failed: cal_crc = 4076150800, blk_crc = 0 buff_size = 0x0
Info: CKPT version = 871e723
Info: Checked valid nat_bits in checkpoint
Info: checkpoint state = 81 :  nat_bits unmount

[FSCK] Unreachable nat entries                        [Ok..] [0x0]
[FSCK] SIT valid block bitmap checking                [Ok..]
[FSCK] Hard link checking for regular file            [Ok..] [0x0]
[FSCK] valid_block_count matching with CP             [Ok..] [0xa995]
[FSCK] valid_node_count matcing with CP (de lookup)   [Ok..] [0xef]
[FSCK] valid_node_count matcing with CP (nat lookup)  [Ok..] [0xef]
[FSCK] valid_inode_count matched with CP              [Ok..] [0xc5]
[FSCK] free segment_count matched with CP             [Ok..] [0x225c]
[FSCK] next block offset is free                     [ASSERT] (check_curseg_offset:2021)  --> Next block offset is not free, type:0
 [Fail]
[FSCK] fixing SIT types
[FSCK] other corrupted bugs                           [Fail]
Do you want to fix this partition? [Y/N] y
Info: MKFS version
  "Linux version 5.10.103-v7l+ (dom@buildbot) (arm-linux-gnueabihf-gcc-8 (Ubuntu/Linaro 8.4.0-3ubuntu1) 8.4.0, GNU ld (GNU Binutils for Ubuntu) 2.34) #1529 SMP Tue Mar 8 12:24:00 GMT 2022"
Info: FSCK version
  from "Linux version 5.10.103-v7l+ (dom@buildbot) (arm-linux-gnueabihf-gcc-8 (Ubuntu/Linaro 8.4.0-3ubuntu1) 8.4.0, GNU ld (GNU Binutils for Ubuntu) 2.34) #1529 SMP Tue Mar 8 12:24:00 GMT 2022"
    to "Linux version 5.10.103-v7l+ (dom@buildbot) (arm-linux-gnueabihf-gcc-8 (Ubuntu/Linaro 8.4.0-3ubuntu1) 8.4.0, GNU ld (GNU Binutils for Ubuntu) 2.34) #1529 SMP Tue Mar 8 12:24:00 GMT 2022"
Info: superblock features = 0 :
Info: superblock encrypt level = 0, salt = 00000000000000000000000000000000
Info: total FS sectors = 36659200 (17900 MB)
[f2fs_crc_valid: 506] CRC validation failed: cal_crc = 4076150800, blk_crc = 0 buff_size = 0x0
Info: CKPT version = 871e723
Info: Checked valid nat_bits in checkpoint
Info: checkpoint state = 81 :  nat_bits unmount

[FSCK] Unreachable nat entries                        [Ok..] [0x0]
[FSCK] SIT valid block bitmap checking                [Ok..]
[FSCK] Hard link checking for regular file            [Ok..] [0x0]
[FSCK] valid_block_count matching with CP             [Ok..] [0xa995]
[FSCK] valid_node_count matcing with CP (de lookup)   [Ok..] [0xef]
[FSCK] valid_node_count matcing with CP (nat lookup)  [Ok..] [0xef]
[FSCK] valid_inode_count matched with CP              [Ok..] [0xc5]
[FSCK] free segment_count matched with CP             [Ok..] [0x225c]
[FSCK] next block offset is free                     [ASSERT] (check_curseg_offset:2021)  --> Next block offset is not free, type:0
 [Fail]
[FSCK] fixing SIT types
[FSCK] other corrupted bugs                           [Fail]
[ASSERT] (check_curseg_offset:2021)  --> Next block offset is not free, type:0
Info: Write valid nat_bits in checkpoint

Done.

Maybe you need to use a different download link if the old image is being cached some how? Maybe have a versioning scheme?

@sonicprod
Copy link
Author

@MauiPunter,

What is the total size/capacity of your SD card?

@MauiPunter
Copy link

@sonicprod
Copy link
Author

sonicprod commented Dec 22, 2022

@MauiPunter,

Ok, can you tell me if the resize operation (at the partition-level) ran successfully?

sudo fdisk -l /dev/mmcblk0

@MauiPunter
Copy link

image

@sonicprod
Copy link
Author

@MauiPunter,

Ok, partition-level resize worked successfully.

It looks like the partition table re-read maybe did not completed successfully.

For now, can you simply reboot the system, so we make sure that the updated partition table is taken care?

Once rebooted, please retry the filesystem-level resize with these commands:

sudo umount /data
sudo resize.f2fs /dev/mmcblk0p3

@MauiPunter
Copy link

@sonicprod
That seemed to have fixed things. After reboot, the /data is showing up correctly and I can access Samba. I was able to reboot into Mame. I wonder what was hanging things up. One thing that came to mind is, do you NEED to reboot after the resize? Or can you just start on setting up the roms? I had not rebooted AFTER doing the resize.

@MauiPunter
Copy link

MauiPunter commented Dec 22, 2022

@sonicprod
Just tried to set frontend to attract and got error:

image

I went into /data/.sys/env, and there is only a 'settings' file.

I was able to edit the 'settings' file manually and set the frontend to attract that way. But the automated script did not work.

@sonicprod
Copy link
Author

@MauiPunter,

Typically, no reboot is needed after the resize. I took care of this in the script (partprobe is forcing the Linux kernel to re-read the partition table with the new partition size). Maybe some SD cards brands/models are more picky, I don't know.

Have fun! :)

@sonicprod
Copy link
Author

sonicprod commented Dec 22, 2022

@MauiPunter,

Oh, I see for the error with frontend. Can you execute this (my mistake):

sudo chown -R pi:pi /data/.sys/env
sudo chmod -R 664   /data/.sys/env/*

@sonicprod
Copy link
Author

@MauiPunter,

Could you confirm that the Two (2) commands fixed the write issue with frontend?

@MauiPunter
Copy link

MauiPunter commented Dec 22, 2022 via email

@sonicprod
Copy link
Author

Yes. That did fix the issue. I am functional now.

Thanks for the feedback, I really appreciate.

@fxlevy
Copy link

fxlevy commented Mar 19, 2023

Bonjour @sonicprod , je vois que tu as réécrit ta page. J'en prends connaissance seulement maintenant. Super boulot... et en 64 bits en plus. 👍
De mon côté j'ai arrêté le développement des scripts que j'avais commencé sur la base de tes travaux. Cela devenait trop complexe mais j'ai une version qui fonctionne disponible sur git avec une gestion multilingue Français/Anglais. J'ai aussi écrit une page sur la réalisation d'une borne d'arcade où je fais référence à tes travaux bien sûr et une autre sur les outils que j'utilise dans ces scripts... le tout en Français. Je suis toujours admiratif de ce que tu as fait ici et qui, je le pense sincèrement, est la meilleure solution pour tous les fans de MAME dont je fais partie qui souhaitent faire fonctionner cet émulateur sur un Raspberry Pi 4B.

@fxlevy
Copy link

fxlevy commented Mar 20, 2023

Re bonjour @sonicprod , je suis en train de tester ta méthode qui est vraiment top.

J'ai 2 remarques:

La première concerne l'installation du système et l'activation du SSH. La fondation Raspberry met à la disposition de tous le Raspberry Pi Imager qui permet d'écrire un système PI OS sur une carte SD. Il fonctionne sur OSX, Windows et Linux. Cet outil est paramètrable et on peut définir avant l'installation le mot de passe du compte pi, l'activation du ssh, les paramètres d'accès wifi ou enore la configuration du clavier. On peut également installer un système que l'on a téléchargé au préalable.

La deuxième concerne la patch a appliquer sur MAME pour résoudre le bug de désactivation de X11. Ils ont l'air de l'avoir résolu avec la version 0.252. Tout du moins c'est que dit le dernier commentaire.

@fxlevy
Copy link

fxlevy commented Mar 20, 2023

Re bonjour @sonicprod , je suis en train de tester ta méthode qui est vraiment top.

J'ai 2 remarques:

La première concerne l'installation du système et l'activation du SSH. La fondation Raspberry met à la disposition de tous le Raspberry Pi Imager qui permet d'écrire un système PI OS sur une carte SD. Il fonctionne sur OSX, Windows et Linux. Cet outil est paramètrable et on peut définir avant l'installation le mot de passe du compte pi, l'activation du ssh, les paramètres d'accès wifi ou enore la configuration du clavier. On peut également installer un système que l'on a téléchargé au préalable.

La deuxième concerne la patch a appliquer sur MAME pour résoudre le bug de désactivation de X11. Ils ont l'air de l'avoir résolu avec la version 0.252. Tout du moins c'est que dit le dernier commentaire.

Apparemment après vérification, ça plante toujours à la compilation si on ne patche pas, même avec la version 0.252. Par contre, le patch sur la version 0.252 ne passe pas. J'essaye de voir ce qui se passe.

@fxlevy
Copy link

fxlevy commented Mar 20, 2023

Par contre, le patch sur la version 0.252 ne passe pas

Mais il passe sur la version 0.251

@sonicprod
Copy link
Author

sonicprod commented Apr 20, 2023

Bonjour @fxlevy,

Pour répondre à ta question sur les soucis de compilation à partir de la version 0.252 :

Pour résoudre les erreurs de compilation suivantes (extrait) :

error: redefinition of ‘void (* bgfx::gl::glDrawBuffer)(GLenum)’
error: redefinition of ‘void (* bgfx::gl::glReadBuffer)(GLenum)’
error: redefinition of ‘void (* bgfx::gl::glGenSamplers)(GLsizei, GLuint*)’
error: redefinition of ‘void (* bgfx::gl::glDeleteSamplers)(GLsizei, const GLuint*)’
error: redefinition of ‘void (* bgfx::gl::glSamplerParameterf)(GLuint, GLenum, GLfloat)’
error: redefinition of ‘void (* bgfx::gl::glSamplerParameteri)(GLuint, GLenum, GLint)’
cd mame0253
nano -l ./3rdparty/bgfx/src/glimports.h

Commenter les lignes #587 à #594 (en les préfixant par //), puis sauvegarder.

MAME 0.252 (et plus récent) devrait dès lors compiler sans problème.

Je n'ai malheureusement pas eu le temps de produire le fichier diff pour l'utiliser en guise de patch, mais sens-toi bien libre si tu veux le faire, je vais l'incorporer dans le How-To.

@sonicprod
Copy link
Author

@fxlevy,

Juste pour te mentionner que j'ai (finalement) mis à jour le patch pour que les versions de MAME 0.252 et subséquentes puissent compiler automatiquement sans erreur, via le script mame-updater.sh.

@fxlevy
Copy link

fxlevy commented Jul 17, 2023

Comme toujours @sonicprod , tu fais un super boulot. Même si nous ne sommes qu'une petite communauté qui essaye de faire perdureur cet esprit créatif et ludique qui foisonnait dans les années 80; Période qui a lancé l'électronique et l'informatique pour tous avec ces premiers micro ordinateurs (Apple II, ZX Spectrum, Atari 520, que j'ai bricolés et décortiqués), les premières consoles de jeu (Pong ou Atari 2600 auxqeulles j'ai joué), ou bornes d'arcade (Galaga, Moon Patrol, Bomb Jack dans lesquelles j'ai mis pas mal de pièces de 1F) et bien sur les flippers pour leur côté électro mécanique (Amazon Hunt ou le grand Eight Ball Deluxe en finissant dans les années 90 avec les excellents Cactus Canyon ou Medieval Madness), tu peux compter sur moi comme un grand fan de tes travaux qui nous permettent de faire renaitre tous ces petites perles de l'histoire des jeux électronique sur des ordi tout simples et pas cher et c'est ça qui est grand. :)
C'est vraiment avec ton blog que je me suis lancé dans le DIY technologique... et ... j'adore ça!!
Tout en bossant professionellement sur des projets informatiques très sérieux et malgré mes 57 ans, je reste un gamin avec des yeux qui pétillent dès que je vois ces petits pixels s'animer sur un écran.
Mais pour finir sur une note plus mécanique... une bonne partie de babyfoot c'est quand même pas mal non plus!
@+
Fixou

@loivire
Copy link

loivire commented Jul 26, 2023

Bonjour @sonicprod ,
Tout d'abord bravo et merci pour tout ce travail accompli qui m'a permis de me lancer dans un projet mini bartop à base de rpi4/bullseyes/mame/hypseus avec attract-mode.
Le résultat est assez bluffant et tout les composants peuvent être mis à jour via compilation.
Le seul bémol c'est le temps de compilation énorme de mame sur mon rip4 4Gb (entre 8h et 10h).
En faisant des recherches j'ai trouvé le moyen de compiler sur mon PC windows10 avec WSL et Ubuntu:
Il faut aller ici: https://github.com/danmons/mame_raspberrypi_cross_compile
C'est assez bien expliqué mais pour compiler la version qui nous intéresse il faut modifier quelques scripts.
Si cela t'intéresse pour l'incorporer dans ton tuto dis-le moi je ferais une explication plus complète.

Sinon je ne sais pas si vous compiliez avant avec la SUBTARGET=arcade mais il semble que depuis la version 0255 cela ne fonctionne plus:

...spberrypi_cross_compile/build/src/mame/scripts/genie.lua:555: Definition file for TARGET=mame SUBTARGET=arcade does not exist
stack traceback:
        [C]: in function 'error'
        ...spberrypi_cross_compile/build/src/mame/scripts/genie.lua:555: in main chunk
        [C]: in upvalue 'builtin_dofile'
        [string "premake = { }..."]:109: in function 'dofile'
        [string "_WORKING_DIR        = os.getcwd()..."]:46: in function '_premake_main'
make: *** [makefile:1268: build/projects/sdl/mamearcade/gmake-linux/Makefile] Error 1

@idfixe75
Copy link

Bonjour,
j'ai fais comme indiqué dans le tuto, mais arrivé au script de compilation de Mame, j'ai un message d'erreur.
pour être en adéquation, j'ai re formaté et re testé mais cette fois ci avec la version 0252 de Mame et non la lasted ....
mais j'ai la même erreur :


make[2]: *** [bgfx.make:531 : obj/Release/3rdparty/bgfx/src/glcontext_egl.o] Erreur 1
make[1]: *** [Makefile:73 : bgfx] Erreur 2
make[1]: *** Attente des tâches non terminées....
Compiling src/mame/bfm/bfm_sc45_helper.cpp...
Compiling src/mame/bfm/bfm_sc5.cpp...
Compiling src/mame/bfm/bfm_sc5sw.cpp...
Compiling src/mame/bfm/bfm_swp.cpp...
Compiling src/mame/bfm/bfmsys83.cpp...
Compiling src/mame/bfm/bfmsys85.cpp...
Compiling src/mame/bfm/rastersp.cpp...
Archiving libbfm.a...
make: *** [makefile:1296 : linux] Erreur 2
Build time took: 1h 4m 47s.


La seul différence c'est que je suis sur la version : 2023-05-03-raspios-bullseye-arm64-lite.img
Si quelqu'un a une solution je suis preneur :-)

@+
idfixe

@sonicprod
Copy link
Author

@idfixe75,

Le problème que tu rencontres est dû à l'espace insuffisant sur la carte SD lors de la compilation. Il faudrait supprimer /data, repartitionner / avec plus d'espace, étendre le filesystem ext4, refaire /data.

@sonicprod
Copy link
Author

@loivire,

Je vais tester la solution de cross-compilation mentionnée. Je n'utilise pas TARGET, ni SUBTARGET, car je prends le Target par défaut, qui compile MAME et MESS.

@sonicprod
Copy link
Author

sonicprod commented Jul 27, 2023

@fxlevy,

Merci pour ces commentaires qui m'ont fait retourner dans le temps! :)

Oui, une bonne partie de babyfoot entre amis, ça se prend toujours volontiers !

P.S. : y a un Français qui s'est fabriqué une machine Ice Cold Beer format bartop, elle est géniale ! J'adore ce jeu électro-mécanique.

@idfixe75
Copy link

@sonicprod
Déjà, merci pour ta réponse, après merci pour le tuto ^^
j'avais pensé a l'espace disque mais :


NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
mmcblk0 179:0 0 59.5G 0 disk
├─mmcblk0p1 179:1 0 256M 0 part /boot
└─mmcblk0p2 179:2 0 59.2G 0 part /


ou encore :


Sys. de fichiers Taille Utilisé Dispo Uti% Monté sur
/dev/root 59G 6.2G 50G 12% /
devtmpfs 3.6G 0 3.6G 0% /dev
tmpfs 3.9G 0 3.9G 0% /dev/shm
tmpfs 1.6G 1.1M 1.6G 1% /run
tmpfs 5.0M 4.0K 5.0M 1% /run/lock
/dev/mmcblk0p1 255M 31M 225M 13% /boot
tmpfs 782M 0 782M 0% /run/user/1000


@loivire
Copy link

loivire commented Jul 28, 2023

@idfixe75
As-tu appliqué le patch glimports.h.patch avant de lancer la compilation ?

@idfixe75
Copy link

@loivire
Oui appliqué .... au deuxième teste j'ai appliqué a la main :


Commenter les lignes #587 à #594 (en les préfixant par //), puis sauvegarder.

MAME 0.252 (et plus récent) devrait dès lors compiler sans problème.

Je n'ai malheureusement pas eu le temps de produire le fichier diff pour l'utiliser en guise de patch, mais sens-toi bien libre si tu veux le faire, je vais l'incorporer dans le How-To.


avec un MAME 0.252 pour être certain d'être dans la bonne conf ;-)

@TrevEB
Copy link

TrevEB commented Aug 4, 2023

First, sorry, yes I’m a newb to pi. I am having an issue where after I expand the partition and switch to arcademode, and reboot, the Mame Logo appears and never goes away. The pi appears to be locked up. I’ve tried single boot rom as well. Using a 256GB SD. No error messages after expansion. When you say copy roms to the /data/roms folder, I assume you mean create a roms folder and place roms inside. The roms folder does not exist on the image, only in the Mame folder. Ive tried placing roms in both locations. Do roms have to be copied over using samba for fetching of art to work? I’ve been using filezilla. Will try samba.

@sonicprod
Copy link
Author

Hi @TrevEB,

I will try to help you on your issue.

First question, did you followed the steps in this How-To or did you grabbed the already built image I provide on ArcadeControls.com forum?

I read that you posted a message in the thread related to this How-To and as I understand, you use a Raspberry Pi 3 with this image? Am I correct?

For a Pi 3 hardware, some adjustments are required (not tested):

  • Ignore the section about activating the DRM VC4 V3D driver
  • I think you don't need to add the "pi" user to the "render" group (sudo usermod -a -G render pi)
  • I think you can reduce the GPU memory to 64 MB ("gpu_mem=64" in /boot/config.txt)
  • The ARCHOPTS variable used to build MAME must use the specifics of the Pi 3B - Please refer to: https://gist.github.com/fm4dd/c663217935dc17f0fc73c9c81b0aa845
  • The screen can be rotated (if needed) very simply with "display_hdmi_rotate=1" in /boot/config.txt
  • I think you may be able to compile with less than 4 GB of RAM, but you definitely have to limit the build to 1 concurrent thread (just set MAXTHREAD=1 in the build script). As a result, it will take more time for the build process to complete.

@TrevEB
Copy link

TrevEB commented Aug 6, 2023

Hi Sonicprod
Thanks for reaching out.
Yes I have been using your image and I finally figured out today the issue with my having a Pi 3.
A pi 4 will arrive tomorrow and I predict success.
If however its possible to create a pi 3 image I would be happy to contribute for your efforts. This cab needs to be ready for California Extreme in 2 weeks so I am trying to wrap things up in the best way they can be, and I’ve overspent as usual. Long story short, if I can continue using a pi 3 that would be preferable. I have another cab to work on so making the build myself will be to time consuming. Hopefully others with Pi 3s would also find benefit in an available image. This is the custom Warlords cab which looks better here than its current location in the dining rm. ;) Thanks for bringing the current version of Mame to android. My collector friend and I are long time contributors to the mame artwork, providing scans of the bezels, shrouds, CPO, etc.
IMG_0696

@finoradin
Copy link

@sonicprod Merci beaucoup pour ce guide incroyable! Aimez vraiment votre approche et appréciez le niveau de détail que vous y avez mis.

Pour votre information - le correctif ne semblait pas fonctionner pour moi et je devais encore commenter manuellement ces lignes (ma première version a échoué)

Ma deuxième construction a également échoué avec l'erreur suivante :

Compiling src/frontend/mame/luaengine_input.cpp... {standard input}: Assembler messages: {standard input}:787143: Warning: end of file not at end of a line; newline inserted g++: fatal error: Killed signal terminated program cc1plus

J'ai ouvert src/frontend/mame/luaengine_input.cpp et ajouté une nouvelle ligne à la fin, donc j'espère que cela résoudra le problème. J'ai pensé que je partagerais ici cependant au cas où il y aurait quelque chose que je ferais mal et que d'autres rencontrant le même problème pourraient bénéficier d'entendre votre réponse. Merci pour toute aide!

@finoradin
Copy link

finoradin commented Aug 6, 2023

Ok, ajouter une nouvelle ligne à la fin de ce fichier a résolu ce problème, mais maintenant j'en ai un nouveau (après 7 heures de compilation).

Voici l'erreur :

luaengine.cpp:(.text.startup+0xc): undefined reference to `.LANCHOR7'
/usr/bin/ld: ../../../../../scripts/src/mame/libfrontend.a(luaengine.o): relocation R_AARCH64_ADR_PREL_PG_HI21 against symbol `.LANCHOR7' which may bind externally can not be used when making a shared object; recompile with -fPIC
luaengine.cpp:(.text.startup+0xc): dangerous relocation: unsupported relocation
/usr/bin/ld: luaengine.cpp:(.text.startup+0x10): undefined reference to `.LANCHOR7'
collect2: error: ld returned 1 exit status
make[2]: *** [mame.make:269: ../../../../../mame] Error 1
make[1]: *** [Makefile:1096: mame] Error 2
make: *** [makefile:1283: linux] Error 2

Est-ce que quelqu'un sait comment je peux résoudre ce problème?

@TrevEB
Copy link

TrevEB commented Aug 8, 2023

Hi Sonicprod

How do I set Mame to send audio to the Pi 4B audio plug?
I assume your image is set to use HDMI
An alternate option, how would I set mame to output to USB, and then use a USB 3D sound device for game audio.

I have confirmed that I do have audio working on the Pi 4 but at the moment Mame is silent but otherwise working perfectly.

@TrevEB
Copy link

TrevEB commented Aug 10, 2023

I cannot get sound to work in Mame.
From servicemode, with RW enabled, I can successfully run speaker-test and get sound from the pi4 audio jack and from HDMI. I have switched sound back and forth from headphones to HDMI in raspi-config. The speakers work. I have also tried USB sound. In every case sound works exactly like it should. Mame remains silent. Is there an ini file that needs to be edited for outputting sound to HDMI? Are you using a custom port setting in your image file? Please help. I am so close to having this completely done.

One other item that would be really helpful.
I have not been able to run Mame from servicemode. Your readme specifies how to do but the command does not work as written.
Thus I have to keep going back into arcademode to test.

@sonicprod
Copy link
Author

@TrevEB,

Typically, the sound from MAME should work with the default configuration. It may be related to the default volume of ALSA. Use alsamixer to ajust it and sudo alsactl store to save it.

Next, the default MAME master volume may be too low. You may test (from servicemode) with ~/mame/mame -volume -10.

@TrevEB
Copy link

TrevEB commented Aug 11, 2023

@sonicprod
the problem is somehow related to raspi-config.
raspi-config settings are not persistant or they are being overwritten.
This is with a keyboard attached to the Pi, though behavior is the same if I remote in.
After I set audio to HDMI or headphones and keyboard to logitech, I am then able to type a tilde, and launch mame by command line
Sound works in Mame. Hooray!
RW is required for the mame command line to work, if the system is in RO then I see a error for the soundcard and sound does not work.
If I reboot the pi, system settings are lost. keyboard and sound have to be set again.
Same issue if I,
service mode, RW, raspi-config, and then arcademode.
Sound settings are lost.

@sonicprod
Copy link
Author

sonicprod commented Aug 12, 2023

@TrevEB,

Could you send me the exact error you get when launching MAME in read-only mode?

The general idea is to put the system in read/write mode (RW) prior to make any changes. Then, you can configure the system with raspi-config and once done, put the system back in read-only (RO) mode.

The problem may be related to the fact that /etc/asound.conf is redirected to the read/write partition. If you ls -la /etc/asound.conf, you'll see that this file is linked to /data. Once you did the audio configuration changes in raspi-config, can you take a look at /etc/asound.conf (to do so, just type cat /etc/asound.conf)?

@TrevEB
Copy link

TrevEB commented Aug 13, 2023

@sonicprod
Good morning. 😁
Some new discoveries.
On first boot (power ON) while in servicemode.
The first run of mame yields an error message.
ALSA lib pulse.c:243:(pulse_connect) PulseAudio: Unable to connect: Connection terminated
the game starts up as usual with no sound.
When I exit and start mame again there is no error message and sound works.
Sound continues to work from this point forward until I switch to arcademode or powercycle the pi.

Checking asound.conf.
pi@arcade(rw):~$ cat /etc/asound.conf
pcm.!default {
type hw
card 1
}

ctl.!default {
type hw
card 1
}

These results are always the same, before and after the sound works.

Now, Entering Arcademode.
Sound does not work, trying several games, sound will not work.
Pressing escape shuts down the machine by your design, rather than dropping to terminal, so I am not able to run mame twice like in servicemode.
However,
While in arcademode in the mame GUI it is possible to crash mame by choosing system settings, then video options
This causes mame to crash with the following text at the top of the screen.

home/pi/scripts/autostart.sh:line7: 700 Segmentation fault home/pi/mame/mame $([ ! -z $AUTOROM ] && [ -f /home/pi/.mame/roms/$AUTOROM.zip ] && echo $AUTOROM) > /deu/nul1 2> /deu/null

mame automatically reboots and now sound works!
Sound continues to work until power is cycled, then the process must be repeated.
Run Mame, Crash Mame, Run Mame, everything works.

I’ve also tried
Frontend mame warlords

Mame in this case requires tab/select new system
In this case the mame GUI does not offer General Settings and System Settings so I cannot crash mame and get a restart, and fix the sound.

I’m going to try a fresh rebuild on another SD card but I am fairly certain the results will be the same.
Hopefully these results will help to resolve the problem.

Thanks
TrevEB

@sonicprod
Copy link
Author

@TrevEB,

Pretty strange issue...

Can you start MAME in Service Mode with the -v argument, so we get verbose details?

~/mame/mame -v

Can you also force ALSA audio subsystem with:

~/mame/mame -audiodriver alsa

@TrevEB
Copy link

TrevEB commented Aug 17, 2023

@sonicprod
Thank you for your help.
The fresh rebuild was the solution.
I think the problem from the beginning was the volume being turned down to almost zero and my mucking around made things worse.
If I may suggest, add a step in your readme to type alsamixer after the image expansion and turn the volume up on all channels to 90
Everything works great! Having all the latest artwork available along with superior emulation to mame from 20 years ago is excellent. I am surprised to find the Pi4 can handle sound emulation in the sega vector titles. Nice!

@sonicprod
Copy link
Author

@TrevEB,

Thanks for your feedback! As suggested, I will update the README file from the pre-built image.

@jasonpstokes
Copy link

jasonpstokes commented Dec 30, 2023

Merci beaucoup @sonicprod for your guide - incredible!

MAME's running well on Debian 12, with some notes from my experience, FYI:

  • Copying the scripts from the Google translated page can add extra characters, corrupting the scripts - may be worth noting this?
  • The default arm_freq appears to now be 1800
  • mame took ~10.5 hours to build (ran twice on diff images) - not sure if Debian 12, my SD card speed or something else. (using arm_freq 2000 and a Samsung EVO Plus)
  • References to /boot in fstab and read-only-rootfs.sh need to be /boot/firmware
  • The SDL_ttf version on Github is 2.20.2 (Feb 2023), so modify section in sdl2-latest.sh to:
  # SDL2_ttf
  wget https://github.com/libsdl-org/SDL_ttf/releases/download/release-2.20.2/SDL2_ttf-2.20.2.tar.gz
  tar zxvf SDL2_ttf-2.20.2.tar.gz
  rm SDL2_ttf-2.20.2.tar.gz
  cd SDL2_ttf-2.20.2
  ./configure
  make -j $(nproc)
  sudo make install
  sudo ldconfig -v

  cd ~
  sudo rm -R SDL2_ttf-2.20.2
  • MAME won't run on start-up if the getty@tty1.service is disabled by mame-autostart.service (i.e. delete the getty service from the conflicts= line).

  

One issue I couldn't resolve is how to get the frontend variable working for the provided autostart.sh script:

/home/pi/settings is

FRONTEND=mame

Manually running the command to set frontend returns:

Invalid or missing argument. Try: mame [rom], attract [emulator rom] or advance

...so my autostart.sh is simply:

#!/bin/bash

until /home/pi/mame/mame >/dev/null 2>&1; do
  sleep 1
done

Another one, I can't find what prints the My IP address is ... line on start up, for a completely blank screen! Oh well.

Thanks again!

@fxlevy
Copy link

fxlevy commented Dec 30, 2023

Many thanks for this feedback @jasonpstokes, I also completly reinstalled my Picade based on a Bookworm. You're right, the compilation of MAME takes around 10H. It's because the script specifies that only 2 cores are used. I'm quite sure that with RPI4B with 8Gb you can boost the compile to use the 4. I will try on my next compile. My biggest issue with Bookworm was to adapt the config.txt. At the end by reading the official documentation, the boot files like cmdline.txt or config.txt are located in /boot/firmware. Even if those files exist in the /boot folder they are not taken into account by the system. That's for sure with the config.txt. Perhaps you should take this into account @jasonpstokes . It took me a bit of time to solve an issue with the overlay that drives the Picade X Hat because of this.

Because I use this tutorial on a Picade, I don't have to deal with the scrips you mentioned. I use the "bind" command and "[whiptail] instead (https://manpages.debian.org/bookworm/whiptail/whiptail.1.en.html)" to display a selection menu.

Now my next challenge will be to replace the PI4B with a PI5 and add a NVME base with a SSD.

For the conclusion, I would like to thank you @sonicprod , this tutorial is just great.

Et en Français, un très grand merci à toi @sonicprod , tu as été une grande source d'inspiration pour me lancer dans tous ces projets.

@jasonpstokes
Copy link

Hi @fxlevy,

...the script specifies that only 2 cores are used. I'm quite sure that with RPI4B with 8Gb you can boost the compile to use the 4.

My Pi4 has 4Gb RAM but trying to build with 3 cores failed, so I stuck with 2. (Also I've read that more than 2Gb makes no diff for playing MAME.)

the boot files like cmdline.txt or config.txt are located in /boot/firmware. Even if those files exist in the /boot folder they are not taken into account by the system.

Strange, my /boot/config.txt (etc.) files are symlinked to /boot/firmware/...` - so I didn't have to do anything different there. 🤷‍♂️

@sonicprod
Copy link
Author

sonicprod commented Jan 4, 2024

Merci beaucoup @sonicprod for your guide - incredible!

My pleasure! :)

MAME's running well on Debian 12, with some notes from my experience, FYI:

* Copying the scripts from the Google translated page can add extra characters, corrupting the scripts - may be worth noting this?

Thanks for reporting it to me – I will add this notice :

Notice to English-speaking users:
If you copy the scripts on this page from the version translated into English by Google Translate, it is possible that excess characters may appear within the scripts (caused by Google Translate), causing corruption of the impacted scripts.
Consequently, it is better to copy the scripts from the original French version of this page.

* The default `arm_freq` appears to now be 1800

Updated to :
arm_freq=1800
over_voltage=2

* mame took ~10.5 hours to build (ran twice on diff images) - not sure if Debian 12, my SD card speed or something else. (using `arm_freq` 2000 and a Samsung EVO Plus)

This is normal, since we had to drop from 4 threads to 2 threads, since the build of MAME takes a lot of memory while a certain combinaison of files are compiled at the same time. This is to avoid an Out of memory error, while building MAME. You can try to increase to 3 threads with the latest version (0.261), I only tested it with 2 build threads.
I will update the build time specified in this page/in the build script to an average ou 10 hours (with a max of 2 build threads).

* References to `/boot` in fstab and `read-only-rootfs.sh` need to be `/boot/firmware`

Fixed (will match both /boot and /boot/firmware) :

sudo sed -i '/\/boot/{/ro/!s/\S\S*/&,ro/4}' /etc/fstab
* The [SDL_ttf version on Github](https://github.com/libsdl-org/SDL_ttf/releases/) is 2.20.2 (Feb 2023), so modify section in `sdl2-latest.sh` to:

Script ajusted with latest version grabbed from Github.

* MAME won't run on start-up if the `getty@tty1.service` is disabled by `mame-autostart.service` (i.e. delete the getty service from the conflicts= line).

Strange… My MAME is running fine with the getty@tty1.service disabled in Arcade Mode (conflicts= line).

One issue I couldn't resolve is how to get the frontend variable working for the provided autostart.sh script:

/home/pi/settings is

FRONTEND=mame

Make sure you modified the file /etc/bash.bashrc and you added this part (specifically) :

# Load environment settings...
if [ -f /home/pi/settings ]; then
  while IFS="= " read var value; do
    [ ! -z $var ] && [ "${var:0:1}" != "#" ] && export $var="$value"
  done < /home/pi/settings
fi

Manually running the command to set frontend returns:

Invalid or missing argument. Try: mame [rom], attract [emulator rom] or advance

What was the complete command line you did tried with the frontend alias?

Another one, I can't find what prints the My IP address is ... line on start up, for a completely blank screen! Oh well.

The output of this line comes from the /etc/rc.local script, wich is executed at the end of each multiuser runlevel.

@sonicprod
Copy link
Author

For the conclusion, I would like to thank you @sonicprod , this tutorial is just great.

Et en Français, un très grand merci à toi @sonicprod , tu as été une grande source d'inspiration pour me lancer dans tous ces projets.

Merci beaucoup @fxlevy ! :)

@jasonpstokes
Copy link

jasonpstokes commented Jan 4, 2024

You can try to increase to 3 threads with the latest version (0.261), I only tested it with 2 build threads.

Building 0.261 with 3 threads failed on my Rpi 4 with 4GB RAM - so suspect more RAM is needed to utilise 3+ threads.

Strange… My MAME is running fine with the getty@tty1.service disabled in Arcade Mode (conflicts= line).

Are you running Debian 12? Because if I keep getty@tty1.service in the conflicts= line, I get a blank screen on start up. Hitting break I see:

ioctl FBIOPUT USCREENINFO: No such device
ioctl FBIOGET_FSCREENINFO: No such device

I haven't found anything online to troubleshoot this. However, if I switch to another console (Alt+F2) and login, MAME UI loads!

The output of this line comes from the /etc/rc.local script, wich is executed at the end of each multiuser runlevel.

Ha! Too easy. (I'd tried several Google searches to find where it was coming from... but nothing!) Thanks. :-)

@sonicprod
Copy link
Author

Strange… My MAME is running fine with the getty@tty1.service disabled in Arcade Mode (conflicts= line).

Are you running Debian 12? Because if I keep getty@tty1.service in the conflicts= line, I get a blank screen on start up. Hitting break I see:

ioctl FBIOPUT USCREENINFO: No such device
ioctl FBIOGET_FSCREENINFO: No such device

I haven't found anything online to troubleshoot this. However, if I switch to another console (Alt+F2) and login, MAME UI loads!

I did not tried Debian 12 yet (2023-12-11-raspios-bookworm-arm64-lite.img.xz). I should make a fresh install from scratch to test it with the current How-To and ajust it accordingly. Stay tuned.

@fxlevy
Copy link

fxlevy commented Jan 5, 2024

Hello @sonicprod , i made a fresh install on a PI4B 8GB. I used your scripts to install main softwares, SDL and MAME. It works fine without any adaptation but took 10h to compile MAME. FreqUtils becomes useless because of the new configuration with a CPU freq at 1800 Mhz by default. Good news about Attract Mode, now ArcadeFlow works much better. It delivers a great User eXperience. A bit slow on RPI but really great. Before it was around 10 FPS, now it's around 20 FPS. And as a replacement I use Silky which is very good for a small screen(my Picade is in XGA format 1024x768). As I wrote it on a previous post I had to directly modify the config.tx and cmdline.txt at /boot/firmware as mentioned in the doc. But Jason wrote that files are symlink from /boot. Anyway it didn't worked for me. I had to directly make the modifications in /boot/firmware. For the Video the dtoverlay=vc4-fkms-v3d was still required to have better performances. Check this site for MAME content.

@jasonpstokes
Copy link

jasonpstokes commented Jan 6, 2024

@fxlevy can you please share how you built attract-mode plus? I'm having issues!

Got Attract-Mode Plus working. Thanks for the tips @fxlevy.

For anyone interested, here's how I built it:

sudo apt -y install git libsfml-dev libopenal-dev libavformat-dev libfontconfig1-dev libfreetype6-dev libswscale-dev libavresample-dev libarchive-dev libjpeg-dev libglu1-mesa-dev libxrandr-dev libosmesa6-dev libgl1-mesa-dev libglu1-mesa-dev

git clone https://github.com/oomek/attractplus ~/attract
cd ~/attract
make USE_DRM=1 -j4
sudo make install USE_DRM=1

Not sure if all these dependencies are needed, but it built. If anyone can confirm, let me know. :-)

@fxlevy
Copy link

fxlevy commented Jan 6, 2024

Hello @jasonpstokes , glad to hear you solved the issue.
I confirm your options, and as you wrote it I'm not sure that all the libraries are necessary.
But anyway it's not a big deal to download them and it doesn't generate any mismatch during compilation and execution.

I also compiled SFML.
I used the latest released version from git which was 2.6.1 at that moment.
Here are my commands (not sure x libs added in the apt list were necessay, but I deliver my command as it was):

sudo apt install libxrandr-dev libxcursor-dev libudev-dev libfreetype-dev libopenal-dev libflac-dev libvorbis-dev libgl1-mesa-dev libegl1-mesa-dev
wget https://github.com/SFML/SFML/archive/refs/tags/2.6.1.zip
unzip 2.6.1.zip
cd SFML-2.6.1/
mkdir build
cd build
cmake .. -DSFML_USE_DRM=TRUE
make -j4
sudo make install
sudo ldconfig -v

For Attract Mode Plus, i also downloaded the latest released version from git with was 3.0.7 at that moment.

sudo apt install libavutil-dev libavcodec-dev libavformat-dev libavfilter-dev libswscale-dev libavresample-dev libswresample-dev libgl1-mesa-dev libglu1-mesa-dev
wget https://github.com/oomek/attractplus/archive/refs/tags/3.0.7.zip
unzip 3.0.7.zip
cd attractplus-3.0.7/
make USE_DRM=1 USE_MMAL=1 USE_GLES=1
sudo make install

@jasonpstokes
Copy link

Thanks again @fxlevy, very helpful. I needed to install libcurl4-openssl-dev (and re-make) for image scraping. 👍

@fxlevy
Copy link

fxlevy commented Feb 15, 2024

Hello @sonicprod , j'ai réussi à faire fonctionner MAME sur mon Raspberry Pi 5 8Gb qui a une carte NVME Samsung installée sur un Bottom Hat. Ça marche nickel! Mais n'ayant pas ton niveau d'expertise sous Linux, j'ai un peu galéré pour la compilation. En me référant à la doc GCC et un Wiki j'ai quand même pu constuire les options de compilation. Les voici:

ARCHOPTS64='-march=armv8.2-a+crc+simd -mcpu=cortex-a76 -mtune=cortex-a76 -funsafe-math-optimizations -fprefetch-loop-arrays -fexpensive-optimizations'
MAKEOPTS='TARGETOS=linux NO_X11=1 NOWERROR=1 NO_USE_XINPUT=1 NO_USE_XINPUT_WII_LIGHTGUN_HACK=1 NO_OPENGL=1 USE_QTDEBUG=0 DEBUG=0 TOOLS=1 REGENIE=1 NO_BGFX=1 FORCE_DRC_C_BACKEND=1 NO_USE_PORTAUDIO=1 SYMBOLS=0'
MAXTHREAD=3

J'ai mis le MAXTHREAD à 3 et j'ai pu maniper en parallèle via SSH sans lenteur. Le Pi ne chauffait quasiment pas. Je n'ai pas atteint les 60°. Mais bon, il était à l'air libre avec l'active cooler.

La compilation complète se fait en moins de 3H!

Voilà pour mon peit retour d'expérience. :)
@+

@loivire
Copy link

loivire commented Mar 21, 2024

Pour ceux qui grâce à ce tuto ( encore merci @sonicprod ) veulent compiler MAME "sur mesure", il est possible encore maintenant d'utiliser l'option de compilation SUBTARGET=arcade qui a disparu du projet depuis la version 0253. Il suffit de mettre un fichier arcade.flt dans le répertoire source du projet dans ./src/mame
Il est possible de prendre comme base le fichier de la version 0252 du dépôt git: https://github.com/mamedev/mame/blob/mame0252/src/mame/arcade.flt
Mais le must, c'est de le générer automatiquement par script. Je me suis inspiré des scripts suivants:
http://www.mameworld.info/mameinfo/download/Compile%20MAME%20with%20Clang%20on%20Windows%2010%20(9th%20Mar).zip
disponible sur cette page : https://mameinfo.mameworld.info/
Facilement incorporable dans mame-updater.sh par exemple. Voici ce que j'utilise:

cd $MAMESRCPATH
SUBTGT=mame
if [ ! -f ./src/mame/arcade.flt ]
then
	echo "Generating arcade.flt"
	cd ./src/mame
	find . -name "*.cpp" -exec grep -Hl "GAME(" {} \; -print >> /tmp/arcadeflt.tmp 
	find . -name "*.cpp" -exec grep -Hl "GAMEL" {} \; -print >> /tmp/arcadeflt.tmp 
	sed "s/\.\///g" /tmp/arcadeflt.tmp > /tmp/arcadeflt.tmp1
	# Remove unnecessary drivers
	sed "/atari\/a2600.cpp/d;/sega\/dccons.cpp/d;/skeleton\/design.cpp/d;/virtual\/ldplayer.cpp/d" /tmp/arcadeflt.tmp1 > /tmp/arcadeflt.tmp
	# Remove Gambing Casino fruit machines pinball handheld LCD and not working
	sed "/barcrest\//d;/bfm\//d;/igt\//d;/merit\//d;/aristocrat\//d;/jpm\//d;/pinball\//d;/handheld\//d;/misc\//d" /tmp/arcadeflt.tmp > /tmp/arcadeflt.tmp1
	# Sort list and remove double lines
	cat /tmp/arcadeflt.tmp1 | sort | uniq > /tmp/arcadeflt.tmp		

	#Merge arcade.flt with Arcade Exceptions list
	cat /tmp/arcadeflt.tmp ~/.arcadeflt_exept.lst > ./arcade.flt
	rm -f /tmp/arcadeflt.tmp /tmp/arcadeflt.tmp1 > /dev/null
	SUBTGT=arcade
	echo "SUBTARGET=${SUBTGT}"
	cd ../..
fi
make SUBTARGET=${SUBTGT} -j$MAXTHREAD ARCHOPTS="$ARCHOPTS64" $MAKEOPTS PLATFORM=arm64

L'avantage n'est pas tant la performance (la taille du binaire est presque réduit de moitié) mais plutôt le temps de compilation plus court (presque moitié moins de fichiers à compiler).
Me concernant, j'ai complètement résolu ce problème avec la cross-compilation: 45 min sur mon PC avec option - j7 sur core i5 11400F 16Gb Ram sous WSL Ubuntu.

Bonne lecture :)

@fxlevy
Copy link

fxlevy commented Mar 22, 2024

Bonjour @loivire , je cherchais justement à pouvoir reprendre cette option qui existait sur les anciennes versions de compilation MAME. Merci beaucoup pour le script. :)

@24-7-testing
Copy link

Hi @sonicprod , just wondering if you have any progress you can share on the latest version of the prebuilt SD image you shared over on the ArcadeControls forum? Any luck building the latest version yet? https://forum.arcadecontrols.com/index.php/topic,162889.0.html

@fxlevy
Copy link

fxlevy commented Mar 25, 2024

Hello all, based on this marvelous work delivered by @sonicprod , I built a tool to install and update softwares to be used in their latest versions. They are currently deisgned to be executed on a Pi 5 running a Pi OS Bookworm 64 bits version. But I,think that anyone who read this blog is able to adapt the scripts I delivered to another PI model or system version. They include the installation of SDL2, Truetype fonts used with SDL, MAME, SFML, Atract Mode Plus and the ArcadeFlow theme for Attract Mode. They are available here rpi4mame.

@sonicprod
Copy link
Author

Hi @sonicprod , just wondering if you have any progress you can share on the latest version of the prebuilt SD image you shared over on the ArcadeControls forum? Any luck building the latest version yet? https://forum.arcadecontrols.com/index.php/topic,162889.0.html

Hi, just to let you know I will reply as soon as I have a new working fully-updated image file. I recently bought a Raspberry Pi 5 and I am testing this How-To to see where are the adaptations/adjustments needed, if any. Thanks for your support!

@fxlevy
Copy link

fxlevy commented Mar 27, 2024

Hi, just to let you know I will reply as soon as I have a new working fully-updated image file. I recently bought a Raspberry Pi 5 and I am testing this How-To to see where are the adaptations/adjustments needed, if any. Thanks for your support!

Hello @sonicprod , if you could test the tools I have created for the software installation and give me your feed back it would be great.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment