Journal Retro 0.1

Posté par  (site web personnel, Mastodon) . Licence CC By‑SA.
35
4
déc.
2014

Sommaire

Ce journal est une traduction d'un article publié sur mon blog il y a peu en anglais.

Je vous le livre ici traduit en français un peu à la va-vite, sans trop adapter les structures grammaticales.

Introduction

Lors du dernier GUADEC, j'ai eu la chance de présenter brièvement mon projet d'avoir un gestionnaire de jeux vidéo simple mais puissant pour GNOME. Afin d'en faire une réalité, beaucoup de travail fût nécessaire sur son backend.

Cet article présente la publication de la première version de ce backend, sous sa forme de candidat de version.

Libretro

Libretro est une API C/C++ utilisée par de nombreux émulateurs de consoles de jeux rétro et moteurs de jeux. Écrire un émulateur et écrire une application avec un GUI demandent des capacités différentes, utiliser Libretro permet d'isoler les backends (souvent appelés modules ou cœurs) implémentant l'API des frontends utilisant l'API afin de les manipuler, facilitant le port des émulateurs et moteurs et offrant une multiplicité de choix de cœurs aux développeurs d'applications.

Logo Libretro

Le frontend principal de Libretro est RetroArch et il a été porté sur de multiples systèmes.

Retro

Retro (ou retro-gobject) est une bibliothèque enveloppant Libretro, basée sur GObject et écrite en Vala. Elle facilite la création de frontends Libretro en utilisant la POO et la gestion de mémoire automatisée (grâce à Vala et GObject) ; elle permet la création de frontends Libretro dans d'autres langages que C/C++ via GObject Introspection ; et elle permet d'avoir de multiples cœurs Libretro chargés en même temps, via l'utilisation de variables globales afin de stocker l'identité du cœur appelant, et via la copie de fichier pour éviter la collision de variables globales dans des cœurs déjà utilisés.

L'API de Retro n'est pas à considérer comme stable pour le moment, mais elle est proche de l'être et ne devrait pas trop changer. Certains objets sont marqués temporairement avec une visibilité internal jusqu'à ce qu'ils soient testés et peaufinés et puissent faire partie de l'API publique.

Mais chose plus importante, ce que Retro n'est pas est un fork de Libretro. Tout ce qu'il fait est de l'envelopper dans une jolie couche orientée objet et est complètement compatible avec les modules implémentant Libretro.

Le dépôt git de Retro est trouvable ici : https://github.com/Kekun/retro-gobject

Retro version 0.1 RC est trouvable ici : https://github.com/Kekun/retro-gobject/releases/tag/v0.1-rc

Core

Core est la classe la plus importante de Retro. Elle représente les fonctionnalités associées à un module Libretro et vous permet de le faire marcher.
Un Core vous permet d'obtenir des informations à propos de son module, de définir des interfaces afin de gérer ses callbacks, et surtout, de le faire tourner.

Video

L'interface Video est utilisée par un Core afin de demander au frontend d'afficher de la vidéo et de définir les détails à propos de comment la vidéo doit être rendue, comme le format de pixels de la vidéo source.

Audio

L'interface Audio est utilisée par un Core afin de demander au frontend de lire du son.

Input

L'interface Input est utilisée par un Core afin de demander au frontend l'état des périphériques d'entrée, comme des manettes, des claviers et des souris.

Autres interfaces

Plein d'autres interfaces peuvent être définies par le frontend ou par le cœur afin de communiquer.
Quelques exemples sont l'interface Log, laissant le Core écrire des messages de journal sur la sortie standard ou un fichier par exemple ; l'interface DiskControl, laissant le frontend contrôller le lecteur de disques virtuel d'un Core (par exemple, pour échanger les disques d'un émulateur de console de jeux utilisant des CDs ; ou l'interface Variables afin de permettre au frontend de connaître et définir les options spéciales d'un Core.

RetroGtk

RetroGtk est une bibliothèque écrite en Vala qui lie Retro, afin de faire fonctionner des modules Libretro, et Gtk.
Il fournit des widgets Gtk implémentant diverses interfaces de Retro, permettant d'afficher facilement la vidéo d'un Core, de lui transmettre les événements clavier et souris, et de mimer des manettes via un clavier.

RetroGtk contient aussi des objets non liés à Gtk, comme des boucles aidant à faire fonctionner un Core, un interface transférant le journal d'un Core vers un FileStream, et une interface aidant à gérer les variables d'un Core.

Vous pouvez utiliser Clutter et ClutterGtk ou Cairo afin d'afficher la vidéo, et j'espère que l'inclusion d'un widget Gl dans Gtk+ 3.16 permettra de se débarrasser de la dépendance à Clutter.
It peut également aussi lire l'audio d'un Core via PulseAudio, mais cela pourrait être déplacé vers une bibliothèque "RetroPa".
Un support des joysticks en bonne et due forme est encore à venir, certainement dans une bibliothèque à part (RetroJs ?).

Le dépôt git de RetroGtk est trouvable ici : https://github.com/Kekun/retro-gtk

Collection de modules Libretro

Être capable de faire tourner, contrôler et afficher des implémentations de Libretro ne sert à rien si vous n'avez aucune de ces implémentations à faire tourner, contrôler et afficher.
Afin d'aider à résoudre ce problème, j'ai commencé à collecter des implémentations compatibles GPL dans un dépot git, ajoutant un makefile pour faciliter leur compilation et installation.

C'est encore balbutiant mais ça m'a déjà pas mal aidé.

Les machines actuellement émulées par la collection sont :

  • Nintendo Entertainment System
  • Super Nintendo Entertainment System
  • Game Boy Advance
  • Saturn
  • PC Engine
  • DOS

Le support de la PlayStation est à venir, mais un bug gênant dans l'émulateur doit être corrigé avant.

Vous pouvez trouver cette collection ici : https://github.com/Kekun/libretro-free

Applications

Démo

Afin de tester tout ça, j'ai écrit une application de démo, qui utilise Retro, RetroGtk et la collection de modules afin de faire tourner des jeux.
Elle permet d'ouvrir plusieurs types de fichiers (voir les modules dans la collection pour savoir ce qui peut fonctionner), de définir les options d'un Core, et elle supporte des entrées telles que le clavier, la souris, et peut utiliser le clavier comme une manette virtuelle. Vous pouvez définir la configuration de la manette via un bouton.

screenshot-dosbox.png
Theme Park fonctionnant sur DOSBox

screenshot-gamepad.png
Configuration de la manette virtuelle en faisant fonctionner PC Genjin 2 sur Mednafen

screenshot-options.png
Les options de Nestopia

screenshot-ungrab.png
bSNES faisant tourner Yoshi's Island, affichant le message "relâcher le pointeur"

Voici le dépôt git de la démo : https://github.com/Kekun/retro-gtk-demo

GNOME Games

Le but ultime de ce projet est d'écrire un gestionnaire et lecteur de jeux pour GNOME, ayant une interface similaire à celle de GNOME Music ou GNOME Video. Ce projet est similaire à OpenEmu pour les systèmes MacOS X.

  • # libretro

    Posté par  (Mastodon) . Évalué à 10.

    Pour ceux qui n'auraient pas compris comment ça fonctionne, je vais essayer d'éclaircir ce point parce que le journal est assez confus. J'ai mis pas mal de temps à bien comprendre comment ça fonctionnait donc je vais en faire profiter tout le monde.

    libretro est une API qui tient dans un .h et on a donc deux côtés à l'API : ceux qui vont implémenter l'API (les backends ou cores) et ceux qui vont l'utiliser (les frontends). Le frontend est chargé de fournir au backend via des callbacks tout un tas de service comme les entrées (clavier, souris, etc), le son, l'image, etc. C'est ce qui est fait dans le projet présenté dans ce journal. Le backend lui est l'implémentation générique d'un émulateur ou même d'un jeu. Il va utiliser les services génériques fournis par le frontend sans avoir à s'occuper de la plateforme sur laquelle il tourne. C'est donc le frontend qui assure la portabilité d'une plateforme à une autre. Comme libretro est orienté émulateur à la base, il y a la notion de rom qui est prise en charge nativement dans l'API. Le frontend de référence s'appelle RetroArch (un peu austère).

    Les possibilités sont énormes puisqu'au delà des émulateurs, il est également possible de demander au frontend un contexte OpenGL et donc, n'importe quel jeu moderne pourrait être implémenté en utilisant libretro. Je crois savoir que certains moteurs de jeu ont implémenté cette API et les jeux utilisant le moteur sont alors vu comme des roms. Il est également possible d'utiliser libretro pour implémenter des visionneurs de vidéo, il y a un portage de FFMPEG pour utiliser libretro. Bref, c'est une API à surveiller, avec beaucoup de projets très actifs qui tournent autour.

    L'API de Retro n'est pas à considérer comme stable pour le moment, mais elle est proche de l'être et ne devrait pas trop changer.

    Raté ! Après avoir freiné des quatre fers pour introduire des changements incompatibles, les auteurs de libretro ont décidé de travailler à une version 2 de l'API pour corriger tout un tas de choses bancales. Le travail se fait dans le dépôt git libretro-arb. Parmi les modifications, l'introduction d'un pointeur utilisateur dans toute l'API (ce qui permettra d'éviter les variables globales comme c'est le cas actuellement quand on implémente un core). Il y a encore du travail mais ça prend forme doucement.

    • [^] # Re: libretro

      Posté par  (site web personnel, Mastodon) . Évalué à 6.

      Merci pour les précisions, ça fait tellement longtemps que je bosse dessus que l'API est presque devenue naturelle et je n'ai pas vu combien j'étais clair ou non.

      Raté !

      Bien tenté, mais j'ai parlé de l'API de Retro (mon wrapper), pas de Libretro. =p

      J'ai vu ce dépôt ARB récement et l'inclusion d'un pointeur utilisateur était un de mes souhaits les plus chers pour une deuxième version de l'API, je suis content d'apprendre que ça viendra, je pourrai alors abandonner mes gros hacks ! =)

      • [^] # Re: libretro

        Posté par  (Mastodon) . Évalué à 4.

        Bien tenté, mais j'ai parlé de l'API de Retro (mon wrapper), pas de Libretro

        Le nom m'a induit en erreur, mea culpa ! ;)

        J'ai vu ce dépôt ARB récement et l'inclusion d'un pointeur utilisateur était un de mes souhaits les plus chers pour une deuxième version de l'API, je suis content d'apprendre que ça viendra, je pourrai alors abandonner mes gros hacks ! =)

        Ce n'est pas encore parfait. Pour l'instant, ils l'ont mis en dernière position. Or, il est plus intelligent de le mettre en première position de manière à pouvoir appeler directement une méthode d'un objet plutôt que de transférer l'appel en changeant l'ordre des arguments.

        Il y a eu aussi un débat sur ce qui devait faire partie de l'API (donc avec des fonctions ou des callbacks directs) et ce qui devait faire partie d'extensions (donc appelé via la fonction générique retro_environment avec ses multiples constantes). Là dessus je suis assez mitigé.

    • [^] # Re: libretro

      Posté par  (site web personnel) . Évalué à 2. Dernière modification le 06 décembre 2014 à 23:43.

      Je trouve que dommage que le projet libretro ne soit pas en C++. Une classe abstraite à implémenter pour proposer un jeu ou une appli, tout le monde* aurait compris sans trop avoir à faire de longues explications.

      *: enfin peut être pas tout le monde aujourd'hui, mais demain même Kevin Michu aura fait du C++ en CE1 sur sa tablette iHollande.

      Le post ci-dessus est une grosse connerie, ne le lisez pas sérieusement.

      • [^] # Re: libretro

        Posté par  (Mastodon) . Évalué à 2.

        Dans ce genre de cas, le C est beaucoup mieux. Parce que les cores sont chargés dynamiquement, donc va trouver le nom de la fonction à appeler en C++ avec le mangling ! Sans compter qu'il faut bien connaître l'objet sur lequel appliquer une méthode donc tu es obligé d'avoir au moins une méthode statique (ou une fonction C). Et ça, c'est sans parler du fait que de nombreux cores sont déjà implémentés en C et que je pense qu'ils n'ont pas envie de passer à C++. De toute façon, si l'API version 2 est bien foutu, ça pourra s'intégrer très bien avec du C++ (pour l'instant, ce n'est pas le cas).

  • # Interface RetroGtk

    Posté par  (site web personnel) . Évalué à 3.

    Y'a pas à dire, je suis vraiment très enthousiaste quand je vois les interfaces de GNOME 3 depuis l'arrivée de la headerbar et tout les concepts sous-jacents.

    Par contre, je pense que l'utilisation d'un interrupteur pour les items "enabled/disabled" dans le GtkPopover serait mieux ;)

    Voilà, en tout cas, très bon travail, merci!

    • [^] # Re: Interface RetroGtk

      Posté par  (site web personnel, Mastodon) . Évalué à 2.

      Le problème est que tout ce que fournit le cœur est une liste de chaînes de caractères sans plus d'informations, ça pourraît être déduit en effet. Cependant ce logiciel est juste une démo qui ne me sert qu'à tester les bibliothèques que j'écris, et dans le logiciel que j'écrirai une fois les bibliothèques plus développées, je ne compte pas utiliser ces variables (elles ont trop peu de sémantique associée pour être utilisable de manière intelligente par une application).

      D'ailleurs, je n'écris pas directement l'application que je souhaite réaliser à terme car il serait trop complexe pour moi seul (help wanted) de développer à la fois une application utilisant de nombreuses bibliothèques que je ne connais pas (Tracker notament) et ce backend qui m'est déjà très chronophage. Donc avoir une application de démo simple et un peu idiote est parfait pour moi pour le moment. =p

    • [^] # Re: Interface RetroGtk

      Posté par  (site web personnel, Mastodon) . Évalué à 3.

      Y'a pas à dire, je suis vraiment très enthousiaste quand je vois les interfaces de GNOME 3 depuis l'arrivée de la headerbar et tout les concepts sous-jacents.

      Tout comme toi ! Pour citer le journal de Kekun :

      Le but ultime de ce projet est d'écrire un gestionnaire et lecteur de jeux pour GNOME, ayant une interface similaire à celle de GNOME Music ou GNOME Video. Ce projet est similaire à OpenEmu pour les systèmes MacOS X.

      Et ça c'est énorme. Alors que nous avons des dizaines de lecteurs audio et de média centers en tout genre, libres, il n'existait guère d'alternative sérieuse à Steam pour ce qui est du classement des jeux vidéo. Jusqu'à récemment, avec OpenEmu (exclusivité OS X cependant), Lutris, et enfin ce futur GNOME Jeux que j'attends avec impatience (faute de pouvoir y contribuer efficacement :( ). Ça va devenir vraiment chouette de jouer sous Linux !

  • # Retro

    Posté par  (site web personnel) . Évalué à 2.

    Très intéressant, au début je pensais qu'il s'agissait d'un frontend pour Mamecab comme celui sur lequel je bricole pour le projet Livemamecab - cabrio-fe - , mais en fait le projet est très différent.

    Par contre ce que je ne comprends pas bien c'est pourquoi tu ne peux émuler que certaines machines, à cause des contrôles ?

    • [^] # Re: Retro

      Posté par  (site web personnel, Mastodon) . Évalué à 4. Dernière modification le 04 décembre 2014 à 15:53.

      Tu parles des machines listées dans la collection ?
      Si c'est le cas, c'est simplement les machines émulées par les modules que j'ai ajouté à ma collection et qui remplissent les prérequis suivants :
      - j'ai pensé à chercher un module pour la machine
      - j'ai effectivement cherché un module pour la machine
      - j'ai trouvé un module pour la machine
      - le module est compatible GPL (ça n'est pas le cas de MAME ou GenesisPlus GX qui sont des freewares open source : leur licence interdit toute utilisation commerciale)
      - j'ai réussi à compiler le module
      - j'ai réussi à faire fonctionner des jeux correctement avec le module

      Bien sûr plein d'autres machines sont émulables, de même que des moteurs de jeux (Cave Story, DOOM…) et des applications (ffmpeg) sont utilisables, mais n'ont pas rempli un des critère précédents… surtout les deux premiers en fait. =p

      PS: L'interface de Livemamecab a de la gueule, ça a l'air très adapté à une borne. =)

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.